From 9475cc59e63c451f9d3fd4bad3290a55785b02be Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 30 Mar 2016 11:35:03 +0300 Subject: [PATCH] esp8266: Support synchronous wifi scanning. That is: aps = if0.scan() TODO: make sure that returned list has tuple with values in "standard" order (whatever that standard is). --- esp8266/esp_mphal.h | 1 + esp8266/modnetwork.c | 36 ++++++++++++++++++++++++++---------- esp8266/mpconfigport.h | 4 ---- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/esp8266/esp_mphal.h b/esp8266/esp_mphal.h index 873bfec371..9a08f5a14d 100644 --- a/esp8266/esp_mphal.h +++ b/esp8266/esp_mphal.h @@ -44,5 +44,6 @@ uint32_t mp_hal_get_cpu_freq(void); void uart_task_init(); void ets_event_poll(void); +#define ETS_POLL_WHILE(cond) { while (cond) ets_event_poll(); } #endif // _INCLUDED_MPHAL_H_ diff --git a/esp8266/modnetwork.c b/esp8266/modnetwork.c index 0391c992ad..d0a7bd2373 100644 --- a/esp8266/modnetwork.c +++ b/esp8266/modnetwork.c @@ -32,12 +32,13 @@ #include "py/nlr.h" #include "py/objlist.h" #include "py/runtime.h" +#include "py/mphal.h" #include "netutils.h" #include "queue.h" #include "user_interface.h" #include "espconn.h" #include "spi_flash.h" -#include "utils.h" +#include "ets_alt_task.h" #define MODNETWORK_INCLUDE_CONSTANTS (1) @@ -127,9 +128,15 @@ STATIC mp_obj_t esp_status(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_status_obj, esp_status); +STATIC mp_obj_t *esp_scan_list = NULL; + STATIC void esp_scan_cb(scaninfo *si, STATUS status) { - struct bss_info *bs; - if (si->pbss) { + if (esp_scan_list == NULL) { + // called unexpectedly + return; + } + if (si->pbss && status == 0) { + struct bss_info *bs; STAILQ_FOREACH(bs, si->pbss, next) { mp_obj_tuple_t *t = mp_obj_new_tuple(6, NULL); t->items[0] = mp_obj_new_bytes(bs->ssid, strlen((char*)bs->ssid)); @@ -138,21 +145,30 @@ STATIC void esp_scan_cb(scaninfo *si, STATUS status) { t->items[3] = MP_OBJ_NEW_SMALL_INT(bs->rssi); t->items[4] = MP_OBJ_NEW_SMALL_INT(bs->authmode); t->items[5] = MP_OBJ_NEW_SMALL_INT(bs->is_hidden); - call_function_1_protected(MP_STATE_PORT(scan_cb_obj), t); + mp_obj_list_append(*esp_scan_list, MP_OBJ_FROM_PTR(t)); } + } else { + // indicate error + *esp_scan_list = MP_OBJ_NULL; } + esp_scan_list = NULL; } -STATIC mp_obj_t esp_scan(mp_obj_t self_in, mp_obj_t cb_in) { - MP_STATE_PORT(scan_cb_obj) = cb_in; +STATIC mp_obj_t esp_scan(mp_obj_t self_in) { if (wifi_get_opmode() == SOFTAP_MODE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "Scan not supported in AP mode")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + "scan unsupported in AP mode")); } + mp_obj_t list = mp_obj_new_list(0, NULL); + esp_scan_list = &list; wifi_station_scan(NULL, (scan_done_cb_t)esp_scan_cb); - return mp_const_none; + ETS_POLL_WHILE(esp_scan_list != NULL); + if (list == MP_OBJ_NULL) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "scan failed")); + } + return list; } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_scan_obj, esp_scan); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_scan_obj, esp_scan); /// \method isconnected() /// Return True if connected to an AP and an IP address has been assigned, diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h index 52dbc18f52..30b49d4075 100644 --- a/esp8266/mpconfigport.h +++ b/esp8266/mpconfigport.h @@ -127,10 +127,6 @@ extern const struct _mp_obj_module_t onewire_module; #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ mp_obj_t mp_kbd_exception; \ - \ - /* Singleton instance of scan callback, meaning that there can - be only one concurrent AP scan. */ \ - mp_obj_t scan_cb_obj; \ // We need to provide a declaration/definition of alloca() #include