Skip to content

esp8266 nonblocking connect/disconnect #11409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 13, 2019

Conversation

dmaziec
Copy link
Contributor

@dmaziec dmaziec commented Sep 4, 2019

Description

ESP8266Interface::connect() and ESP8266Interface::disconnect() can be used in terms of asynchronous operations. Mainly, it is based on newly added private variable of type esp_connection_software_status which is used to keep tracking of state of connection.
wifi_connect_nonblock test was renamed and amended to test both connect() and disconnect() operation

Pull request type

[ ] Fix
[ ] Refactor
[ ] Target update
[x] Functionality change
[ ] Docs update
[ ] Test update
[ ] Breaking change

Reviewers

@SeppoTakalo
@michalpasztamobica
@VeijoPesonen
@teetak01

Release Notes

This release contains changes for ESP8266 non-blocking operations, which make them compliant with documentation:

  • connect() and disconnect() will now return immediately in non-blocking mode and pass all blocking operations to asynchronous thread.
  • in case of consecutive calls of connect() (or disconnect()) returned value from the second one may be NSAPI_ERROR_BUSY
  • If ESP8266Interface::set_credentials(...) is called during connecting to the network, it is not executed and NSAPI_ERROR_BUSY is returned.

The change will not affect any users, unless they took advantage of the incorrect non-blocking behavior.

@dmaziec dmaziec force-pushed the esp8266-nonblocking branch 2 times, most recently from 2620bbe to 98ba282 Compare September 4, 2019 10:53
@ciarmcom
Copy link
Member

ciarmcom commented Sep 4, 2019

@dmaziec1, thank you for your changes.
@teetak01 @VeijoPesonen @SeppoTakalo @michalpasztamobica @ARMmbed/mbed-os-ipcore @ARMmbed/mbed-os-test @ARMmbed/mbed-os-maintainers please review.

@@ -385,7 +385,7 @@ Test `WiFiInterface::connect()` without parameters. Use `set_credentials()` for

`connect()` calls return `NSAPI_ERROR_OK`.

### WIFI_CONNECT_NONBLOCK
### WIFI_NONBLOCK
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe WIFI_CONNECT_DISCONNECT_NONBLOCK would be more descriptive.

7. `Call WiFiInterface::get_connection_status()`
8. `Call WiFiInterface::set_blocking(true)`
7. `disconnect()`
8. `Call WiFiInterface::set_blocking(true)`

**Expected result:**

In case of drivers which do not support asynchronous mode `set_blocking(false)` call returns `NSAPI_ERROR_UNSUPPORTED` and skips test case, otherwise:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be converted to list for readability.

IFACE_STATUS_DISCONNECTED = 0,
IFACE_STATUS_CONNECTING = 1,
IFACE_STATUS_CONNECTED = 2,
IFACE_STATUS_DISCONNECTING = 3

This comment was marked as off-topic.

@dmaziec dmaziec force-pushed the esp8266-nonblocking branch from ee453a6 to 31bdab7 Compare September 5, 2019 09:15
@michalpasztamobica
Copy link
Contributor

@VeijoPesonen , your review remarks have been addressed :)

@@ -75,7 +75,7 @@ Case cases[] = {
Case("WIFI-CONNECT-PARAMS-VALID-UNSECURE", wifi_connect_params_valid_unsecure),
Case("WIFI-CONNECT", wifi_connect),
//Most boards are not passing this test, but they should if they support non-blocking API.
//Case("WIFI-CONNECT-NONBLOCKING", wifi_connect_nonblock),
//Case("WIFI_CONNECT_DISCONNECT_NONBLOCK", wifi_nonblock),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function name should also be changed.

_connect_retval = NSAPI_ERROR_NO_CONNECTION;
}
// Power down the modem
_rst_pin.rst_assert();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having two separate pins to power down the modem is already confusing enough, so these two lines should be pushed on their own function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like a private ESP8266Interface::_power_off()?
off seems to be the stronger version of down, so let's use it for a function that would do both actions.
Or should we be explicit with _power_down_and_off()?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't see the semantic difference between those two - so _power_off() looks good to me. Function's comment section could include the explanation what is the difference between these two methods.

nsapi_error_t status = _conn_status_to_error();
if (status == NSAPI_ERROR_NO_CONNECTION) {
return NSAPI_ERROR_NO_CONNECTION;
if (!_if_blocking) {
Copy link
Contributor

@VeijoPesonen VeijoPesonen Sep 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to acquire the lock so late? Earlier it was done immediatelly at the beginning of this function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. The mutex should protect the queue - we need to move the lock up, before line 432.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be acquired already before first check of _software_conn_stat as it is modified from elsewhere. That's at least my gut feeling.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, we haven't been protecting _conn_stat with a mutex so far, I think _software_conn_stat could be handled similarly?
I was looking into the documentation but I see no clear indication if ESP8266Interface or NetworkInterface are meant to be thread-safe or not. If so - then we would probably need to protect even further than we do right now and I would suggest to create a separate task and take care of this outside of this PR.
For example: we'd have to protect the set_credentials() and get_ip_address().
I also wonder if those functions should or shouldn't become properly non-blocking in case set_blocking(false) gets called? Somehow the documentation only mentioned connect() and disconnect()...
What do you think @VeijoPesonen ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking into the documentation but I see no clear indication if ESP8266Interface or NetworkInterface are meant to be thread-safe or not. If so - then we would probably need to protect even further than we do right now and I would suggest to create a separate task and take care of this outside of this PR.

A fair point and I would say we don't need to go so far. What I was thinking here was the interaction between disconnect_async() and disconnect() when same the caller calls disconnet() twice in a row.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've agreed to put the mutex lock after the _softwatre_conn_stat checks, as the result will be the same (return of NSAPI_ERROR_BUSY either due to failed lock or _software_conn_stat value check) and we don't protect that variable elsewhere in the code... Is this ok?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

if (_conn_stat_cb) {
_conn_stat_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _conn_stat);
}
_software_conn_stat = IFACE_STATUS_DISCONNECTED;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be updated before executing the callback? Better to have the internal state in order before calling any external code.

@dmaziec dmaziec force-pushed the esp8266-nonblocking branch from 31bdab7 to 2726b3f Compare September 9, 2019 12:22
@@ -403,6 +412,11 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface {
mbed::DigitalOut _pwr_pin;
} _pwr_pin;

/** Assert the reset and power pins
* ESP8266 has two pins serving similar purpose and this function asserts them both if they are configured in mbed_app.json.
Copy link
Contributor

@VeijoPesonen VeijoPesonen Sep 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation. Lline length shouldn't exceed 120 characters [Docs › Contributing › Style]. Otherwise this PR looks good to me :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I guess astyle config is taking advantage of that preferably keyword :D

Each line preferably has at most 120 characters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess so too :D As we know opinions start to differ once you go beyond 80 characters.

`ESP8266Interface::connect()` and `ESP8266Interface::disconnect()` can be used in terms of asynchronous operations. Mainly, it is based on newly added private variable of type  `esp_connection_software_status` which is used to keep tracking of state of connection.`wifi_connect_nonblock` test was renamed and amended to test both `connect()` and `disconnect()` operation
@dmaziec dmaziec force-pushed the esp8266-nonblocking branch from 2726b3f to f5ccbe7 Compare September 10, 2019 07:38
Copy link
Contributor

@VeijoPesonen VeijoPesonen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me :)

@0xc0170
Copy link
Contributor

0xc0170 commented Sep 11, 2019

Ci started

@mbed-ci
Copy link

mbed-ci commented Sep 11, 2019

Test run: FAILED

Summary: 2 of 4 test jobs failed
Build number : 1
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_build-ARM
  • jenkins-ci/mbed-os-ci_build-IAR

@michalpasztamobica
Copy link
Contributor

@0xc0170 , I checked the failures, but I cannot see a relation to those changes... Is there some issue in CI now?

@0xc0170
Copy link
Contributor

0xc0170 commented Sep 12, 2019

CI restarted

@mbed-ci
Copy link

mbed-ci commented Sep 12, 2019

Test run: FAILED

Summary: 1 of 4 test jobs failed
Build number : 2
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_build-IAR

@0xc0170
Copy link
Contributor

0xc0170 commented Sep 12, 2019

CI restarted

@mbed-ci
Copy link

mbed-ci commented Sep 12, 2019

Test run: FAILED

Summary: 1 of 4 test jobs failed
Build number : 3
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_build-IAR

@0xc0170
Copy link
Contributor

0xc0170 commented Sep 13, 2019

test restarted

@mbed-ci
Copy link

mbed-ci commented Sep 13, 2019

Test run: SUCCESS

Summary: 11 of 11 test jobs passed
Build number : 4
Build artifacts

@0xc0170
Copy link
Contributor

0xc0170 commented Oct 16, 2019

@adbridge Why was this moved to 6.0?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants