-
Notifications
You must be signed in to change notification settings - Fork 93
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
Add new function to obtain connection RSSI info #1138
Conversation
Nice, I wonder if an percentage see eg. it's somewhat hard to reason between -25 or -45 which is better and are any of them of marginal quality? |
With RF signals a smaller deviation from the theoretical perfect 0 represents a stronger signal to noise ratio, the point where the network becomes unusable varies by equipment and environmental factors, but typically below -70 the network will be unusable... in fact the esp-idf has a default lower limit where it will terminate the connection and emit a network disconnected event. An interesting future feature to add would be the ability to adjust the RSSI threshold. The ESP-IDF documentation and the function name itself is misleading... it actually returns the dBm of the signal, not a true RSSI, but I stuck with the IDF naming so that it would be familiar. The same is true for Pico-SDK. |
libs/eavmlib/src/network.erl
Outdated
%% @doc Get the rssi information of AP to which the device is associated with. | ||
%% @end | ||
%%----------------------------------------------------------------------------- | ||
-spec sta_rssi() -> Rssi :: db() | {error, Reason :: term()}. |
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'd rather have {ok, db()}
than just db()
. It's easier to match.
term config = term_get_tuple_element(cmd, 1); | ||
if (term_is_atom(cmd)) { | ||
cmd_term = cmd; | ||
UNUSED(config); |
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'm not sure what this UNUSED is here for.
@@ -761,6 +763,32 @@ static void start_network(Context *ctx, term pid, term ref, term config) | |||
port_send_reply(ctx, pid, ref, OK_ATOM); | |||
} | |||
|
|||
static void get_sta_rssi(Context *ctx, term pid, term ref) | |||
{ | |||
int sta_rssi = -999; |
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.
0 seems a better way to silence esp-idf compiler.
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.
Indeed. That makes sense, I had set it to 0 originally, but changed that to an impossible value during early testing to be sure the value was being changed, because 0 being returned is an indication of error, even if the actual error returned is ESP_OK.
@@ -31,6 +31,7 @@ | |||
#pragma GCC diagnostic ignored "-Wpedantic" | |||
|
|||
#include <cyw43.h> | |||
#include <cyw43_ll.h> |
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.
Instead of including this header to access low-level interface (what ll
stands for I believe) because code needs CYW43_IOCTL_GET_RSSI
, get_sta_rssi
probably could call cyw43_wifi_get_rssi
that is defined in cyw43.h
.
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 don't know how I missed that! Thanks!
return; | ||
} | ||
// {Ref, {rssi, -25}} | ||
BEGIN_WITH_STACK_HEAP(PORT_REPLY_SIZE + TUPLE_SIZE(2) + sizeof(int), heap); |
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.
See comments on esp32 driver.
if ((term_is_tuple(cmd) && term_get_tuple_arity(cmd) == 2) || term_is_atom(cmd)) { | ||
if (term_is_atom(cmd)) { | ||
cmd_term = cmd; | ||
UNUSED(config); |
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.
See comments on esp32 driver.
enum network_cmd cmd = interop_atom_term_select_int(cmd_table, cmd_term, ctx->global); | ||
switch (cmd) { | ||
case NetworkStartCmd: | ||
enum network_cmd command = interop_atom_term_select_int(cmd_table, cmd_term, ctx->global); |
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.
Thank you for this.
return; | ||
} | ||
// {Ref, {rssi, -25}} | ||
BEGIN_WITH_STACK_HEAP(PORT_REPLY_SIZE + TUPLE_SIZE(2) + sizeof(int), heap); |
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 message is {reference(), {rssi, integer()}
, so the required size is PORT_REPLY_SIZE + TUPLE_SIZE(2)
.
Here, the function could also use port_ensure_available
. The current code (a) allocates sizeof(int) which does not make sense, (b) builds a tuple on a stack heap and then another one on the context heap (port_send_reply
does create a tuple), without ensuring there is space in the context heap : it may crash.
esp_err_t err = esp_wifi_sta_get_rssi(&sta_rssi); | ||
if (UNLIKELY(err != ESP_OK)) { | ||
size_t heap_size = TUPLE_SIZE(2); | ||
if (UNLIKELY(memory_ensure_free(ctx, heap_size) != MEMORY_GC_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.
Reviewing port.h and port.c, I think :
- function get_sta_rssi takes a Context *ctx as a parameter, so it should only be called directly from
consume_mailbox
function (which it is) - as a result, it can and probably should use the ctx' heap to send messages
- this function should call
port_ensure_available
instead ofmemory_ensure_free
, but this doesn't hurt.port_ensure_available
doesn't GC, but the function is not referring to anything that could be moved by GC. The driver already calledmemory_ensure_free
so I think it's ok to keep that. - the actual message is
{reference(), {error, integer()}}
, soheap_size
should beTUPLE_SIZE(2) + REF_SIZE + TUPLE_SIZE(2)
orPORT_REPLY_SIZE + TUPLE_SIZE(2)
(PORT_REPLY_SIZE
probably should eventually go to port.h).
|
||
if (UNLIKELY(err != 0)) { | ||
size_t heap_size = TUPLE_SIZE(2); | ||
if (UNLIKELY(memory_ensure_free(ctx, heap_size) != MEMORY_GC_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.
See comments on esp32 driver.
Adds the ability to get the signal strength, in decibels, of the connection to the access point the device is connected to. Signed-off-by: Winford <winford@object.stream>
Adds the ability to get the signal strength, in decibels, of the connection to the access point the pico-w is connected to. Signed-off-by: Winford <winford@object.stream>
These changes add support for both ESP32 and Pico-W to obtain the current signal strength (in decibels) of the connection to the associated access point using
network:sta_rssi/0
.These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).
SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later