-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Conversation
2620bbe
to
98ba282
Compare
@dmaziec1, thank you for your changes. |
98ba282
to
ee453a6
Compare
TESTS/network/wifi/README.md
Outdated
@@ -385,7 +385,7 @@ Test `WiFiInterface::connect()` without parameters. Use `set_credentials()` for | |||
|
|||
`connect()` calls return `NSAPI_ERROR_OK`. | |||
|
|||
### WIFI_CONNECT_NONBLOCK | |||
### WIFI_NONBLOCK |
There was a problem hiding this comment.
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.
TESTS/network/wifi/README.md
Outdated
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: |
There was a problem hiding this comment.
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.
This comment was marked as off-topic.
Sorry, something went wrong.
ee453a6
to
31bdab7
Compare
@VeijoPesonen , your review remarks have been addressed :) |
TESTS/network/wifi/main.cpp
Outdated
@@ -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), |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()
?
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
31bdab7
to
2726b3f
Compare
@@ -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. |
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
2726b3f
to
f5ccbe7
Compare
There was a problem hiding this 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 :)
Ci started |
Test run: FAILEDSummary: 2 of 4 test jobs failed Failed test jobs:
|
@0xc0170 , I checked the failures, but I cannot see a relation to those changes... Is there some issue in CI now? |
CI restarted |
Test run: FAILEDSummary: 1 of 4 test jobs failed Failed test jobs:
|
CI restarted |
Test run: FAILEDSummary: 1 of 4 test jobs failed Failed test jobs:
|
test restarted |
Test run: SUCCESSSummary: 11 of 11 test jobs passed |
@adbridge Why was this moved to 6.0? |
Description
ESP8266Interface::connect()
andESP8266Interface::disconnect()
can be used in terms of asynchronous operations. Mainly, it is based on newly added private variable of typeesp_connection_software_status
which is used to keep tracking of state of connection.wifi_connect_nonblock
test was renamed and amended to test bothconnect()
anddisconnect()
operationPull request type
Reviewers
@SeppoTakalo
@michalpasztamobica
@VeijoPesonen
@teetak01
Release Notes
This release contains changes for ESP8266 non-blocking operations, which make them compliant with documentation:
connect()
anddisconnect()
will now return immediately in non-blocking mode and pass all blocking operations to asynchronous thread.connect()
(ordisconnect()
) returned value from the second one may beNSAPI_ERROR_BUSY
ESP8266Interface::set_credentials(...)
is called during connecting to the network, it is not executed andNSAPI_ERROR_BUSY
is returned.The change will not affect any users, unless they took advantage of the incorrect non-blocking behavior.