diff --git a/docs/psoc6/quickref.rst b/docs/psoc6/quickref.rst index 51e0cfbc3120..c008bb692479 100644 --- a/docs/psoc6/quickref.rst +++ b/docs/psoc6/quickref.rst @@ -244,43 +244,64 @@ The :mod:`network` module See :ref:`network.WLAN ` -The network module is used to configure the WiFi connection.The WiFi interface for the station mode is only configured for -this port.Create WLAN interface object using :: +For some methods and constants, the PSoC6 network port implements certain specialization and slightly different behavior. This is explained in this section. - import network - wlan = network.WLAN(network.STA_IF) # create station interface +Methods +^^^^^^^ -Scan for the available wireless networks using +.. method:: WLAN.scan(ssid=None, bssid=None) -:: + The scan option accepts the following filters as keyword arguments, removing from scan results any network not matching these parameters values: - wlan.scan() - -Scan function returns a list of tuple information about access points -(ssid, bssid, channel, RSSI, security, hidden) .There are 7 levels of security: - - * ``0 - open``, - * ``1 - WEP``, - * ``2 - WPA``, - * ``3 - WPA2``, - * ``4 - WPA2_WPA``, - * ``5 - WPA3``, - * ``6 - WPS``, - * ``7 - Unknown security``. - -These are the other functions available in the network module + * ``ssid`` + * ``bssid`` + +.. method:: WLAN.status('param') + + .. warning:: + The function does not provide status of the connection. Use the ``active()`` for that purpose. Any errors or failure are communicated when using the corresponding enable/disable or connect/disconnect functions. + + The following query parameters are allowed: + * ``rssi``. Only for STA. + * ``stations``. List of connected stations (only for AP). + +.. method:: WLAN.config('param') + WLAN.config(param=value, ...) -:: + Among the suggested parameters of the general network WLAN API, for this port, only these are available: - wlan.active(True) # activate the interface - wlan.scan() # scan for access points - wlan.isconnected() # check if the station is connected to an AP - wlan.connect('ssid', 'key') # connect to an AP - wlan.disconnect() # disconnect from the connected AP - wlan.status() # check the link status and returns 1 for linkup & 0 for linkdown - wlan.ifconfig() # get the interface's IP/netmask/gateway/DNS addresses + * AP & STA query parameters + + - ``channel`` + - ``ssid`` + - ``security``` + - ``key/password``. Only for default AP key. + - ``mac`` + * AP set parameters + + - ``channel`` + - ``ssid`` + - ``security``` + - ``key/password``. Only for default AP key. + + * STA has no configurable parameter. + +Constants +^^^^^^^^^ + +Security modes constants: + +.. data:: WLAN.OPEN + WLAN.WEP + WLAN.WPA + WLAN.WPA2 + WLAN.WPA3 + WLAN.WPA2_WPA_PSK + WLAN.SEC_UNKNOWN + +.. note:: + Power modes configuration not implemented. - Here is a function you can run (or put in your boot.py file) to automatically connect to your WiFi network: :: diff --git a/ports/psoc6/modules/network/network_ifx_wcm.c b/ports/psoc6/modules/network/network_ifx_wcm.c index 52e266a7fa05..2e1453501543 100644 --- a/ports/psoc6/modules/network/network_ifx_wcm.c +++ b/ports/psoc6/modules/network/network_ifx_wcm.c @@ -50,14 +50,6 @@ extern uint8_t cy_wcm_is_ap_up(); -// Function prototypes -static void network_ifx_wcm_scan_cb(cy_wcm_scan_result_t *result_ptr, void *user_data, cy_wcm_scan_status_t status); - -cy_wcm_ip_address_t ip_address; -cy_wcm_ip_address_t net_mask_addr; -cy_wcm_ip_address_t gateway_addr; -cy_wcm_ip_setting_t ap_ip; - #define NETWORK_WLAN_DEFAULT_SSID "mpy-psoc6-wlan" #define NETWORK_WLAN_DEFAULT_PASSWORD "mpy_PSOC6_w3lc0me!" #define NETWORK_WLAN_DEFAULT_SECURITY CY_WCM_SECURITY_WPA2_AES_PSK @@ -84,7 +76,8 @@ typedef struct typedef struct { - uint32_t var; + cy_wcm_associated_ap_info_t ap_info; + uint8_t connect_retries; } network_ifx_wcm_sta_obj_t; typedef union { @@ -106,6 +99,10 @@ extern whd_interface_t whd_ifs[MAX_WHD_INTERFACE]; STATIC network_ifx_wcm_obj_t network_ifx_wcm_wl_sta = { { &mp_network_ifx_wcm_type }, CY_WCM_INTERFACE_TYPE_STA }; STATIC network_ifx_wcm_obj_t network_ifx_wcm_wl_ap = { { &mp_network_ifx_wcm_type }, CY_WCM_INTERFACE_TYPE_AP }; +#define wcm_get_ap_conf_ptr(net_obj) & (net_obj.itf_obj.ap_obj.ap_config) +#define wcm_get_sta_conf_ptr(net_obj) & (net_obj.itf_obj.sta_obj) +#define wcm_get_sta_ap_info_ptr(net_obj) & (net_obj.itf_obj.sta_obj.ap_info) + #define wcm_assert_raise(msg, ret) if (ret != CY_RSLT_SUCCESS) { \ mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT(msg), ret); \ } @@ -115,14 +112,11 @@ void network_deinit(void) { wcm_assert_raise("network deinit error (code: %d)", ret); } -#define MAX_WIFI_RETRY_COUNT (3u) -#define WIFI_CONN_RETRY_INTERVAL_MSEC (100u) - // Network Access Point initialization with default network parameters void network_ap_init() { cy_rslt_t ret = CY_RSLT_SUCCESS; - cy_wcm_ap_config_t *ap_conf = &(network_ifx_wcm_wl_ap.itf_obj.ap_obj.ap_config); - cy_wcm_ip_setting_t *ap_ip_settings = &(network_ifx_wcm_wl_ap.itf_obj.ap_obj.ap_config.ip_settings); + cy_wcm_ap_config_t *ap_conf = wcm_get_ap_conf_ptr(network_ifx_wcm_wl_ap); + cy_wcm_ip_setting_t *ap_ip_settings = &(ap_conf->ip_settings); ap_conf->channel = NETWORK_WLAN_DEFAULT_CHANNEL; memcpy(ap_conf->ap_credentials.SSID, NETWORK_WLAN_DEFAULT_SSID, strlen(NETWORK_WLAN_DEFAULT_SSID) + 1); @@ -133,6 +127,20 @@ void network_ap_init() { wcm_assert_raise("network ap ip setting error (code: %d)", ret); } +STATIC void restart_ap(cy_wcm_ap_config_t *ap_conf) { + if (cy_wcm_is_ap_up()) { + uint32_t ret = cy_wcm_stop_ap(); + wcm_assert_raise("network ap deactivate error (with code: %d)", ret); + ret = cy_wcm_start_ap(ap_conf); + wcm_assert_raise("network ap active error (with code: %d)", ret); + } +} + +void network_sta_init() { + network_ifx_wcm_sta_obj_t *sta_conf = wcm_get_sta_conf_ptr(network_ifx_wcm_wl_sta); + sta_conf->connect_retries = 3; // Default connect retries +} + // Network Initialization function (called from main.c) void network_init(void) { cy_rslt_t ret = CY_RSLT_SUCCESS; @@ -142,37 +150,41 @@ void network_init(void) { wcm_assert_raise("network init error (code: %d)", ret); network_ap_init(); + network_sta_init(); } // Print after constructor invoked STATIC void network_ifx_wcm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - // network_ifx_wcm_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // TODO: Implement print with following parameters - // - link status (requires tcpip stack integration) - // - get and print ip address - const char *status_str = "network status unknown. To be implemented in network.status()."; - - /*if (status == CYW43_LINK_DOWN) { - status_str = "down"; - } else if (status == CYW43_LINK_JOIN || status == CYW43_LINK_NOIP) { - status_str = "join"; - } else if (status == CYW43_LINK_UP) { - status_str = "up"; - } else if (status == CYW43_LINK_NONET) { - status_str = "nonet"; - } else if (status == CYW43_LINK_BADAUTH) { - status_str = "badauth"; + network_ifx_wcm_obj_t *self = MP_OBJ_TO_PTR(self_in); + + const char *status_str; + if (self->itf == CY_WCM_INTERFACE_TYPE_STA) { + if (cy_wcm_is_connected_to_ap()) { + status_str = "joined"; + } else { + status_str = "down"; + } } else { - status_str = "fail"; - }*/ + if (cy_wcm_is_ap_up()) { + status_str = "up"; + } else { + status_str = "down"; + } + } - mp_printf(print, "", + cy_wcm_ip_address_t ip_address; + cy_rslt_t ret = cy_wcm_get_ip_addr(self->itf, &ip_address); + if (ret != CY_RSLT_SUCCESS) { + ip_address.ip.v4 = 0; + } + + mp_printf(print, "", + self->itf == CY_WCM_INTERFACE_TYPE_STA ? "STA" : "AP", status_str, - 0, // netif->ip_addr.addr & 0xff, - 0, // netif->ip_addr.addr >> 8 & 0xff, - 0, // netif->ip_addr.addr >> 16 & 0xff, - 0 // netif->ip_addr.addr >> 24 + ip_address.ip.v4 & 0xff, + ip_address.ip.v4 >> 8 & 0xff, + ip_address.ip.v4 >> 16 & 0xff, + ip_address.ip.v4 >> 24 ); } @@ -187,24 +199,11 @@ STATIC mp_obj_t network_ifx_wcm_make_new(const mp_obj_type_t *type, size_t n_arg return mp_const_none; } -STATIC mp_obj_t network_ifx_wcm_send_ethernet(mp_obj_t self_in, mp_obj_t buf_in) { - network_ifx_wcm_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_buffer_info_t buf; - mp_get_buffer_raise(buf_in, &buf, MP_BUFFER_READ); - whd_buffer_t *whd_buff = (whd_buffer_t *)&buf; - int ret = whd_network_send_ethernet_data(whd_ifs[self->itf], *whd_buff); - wcm_assert_raise("network send ethernet error (code: %d)", ret); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(network_ifx_wcm_send_ethernet_obj, network_ifx_wcm_send_ethernet); - /*******************************************************************************/ // network API STATIC mp_obj_t network_ifx_wcm_deinit(mp_obj_t self_in) { - uint32_t ret = cy_wcm_deinit(); - wcm_assert_raise("network deinit error (code: %d)", ret); + network_deinit(); return mp_const_none; } @@ -223,7 +222,8 @@ STATIC mp_obj_t network_ifx_wcm_active(size_t n_args, const mp_obj_t *args) { return mp_obj_new_bool(cy_wcm_is_ap_up()); } else { if (mp_obj_is_true(args[1])) { - ret = cy_wcm_start_ap(&(self->itf_obj.ap_obj.ap_config)); + cy_wcm_ap_config_t *ap_conf = wcm_get_ap_conf_ptr(network_ifx_wcm_wl_ap); + ret = cy_wcm_start_ap(ap_conf); wcm_assert_raise("network ap active error (with code: %d)", ret); } else { ret = cy_wcm_stop_ap(); @@ -238,21 +238,23 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ifx_wcm_active_obj, 1, 2, net typedef struct { - mp_obj_t scan_list; + mp_obj_t *scan_list; cy_wcm_scan_status_t status; }scan_user_data_t; // Based on the scan result, get micropython defined equivalent security type (possible value 0-4, extended till 7 to include all cases) and security string (mapped to IFX stack) -void get_security_type(cy_wcm_scan_result_t *result, uint8_t *security_type) { - switch (result->security) +uint8_t get_mpy_security_type(cy_wcm_security_t wcm_sec) { + uint8_t mpy_sec_type = NET_IFX_WCM_SEC_UNKNOWN; + + switch (wcm_sec) { case CY_WCM_SECURITY_OPEN: - *security_type = NET_IFX_WCM_SEC_OPEN; + mpy_sec_type = NET_IFX_WCM_SEC_OPEN; break; case CY_WCM_SECURITY_WEP_PSK: case CY_WCM_SECURITY_WEP_SHARED: case CY_WCM_SECURITY_IBSS_OPEN: - *security_type = NET_IFX_WCM_SEC_WEP; + mpy_sec_type = NET_IFX_WCM_SEC_WEP; break; case CY_WCM_SECURITY_WPA_AES_PSK: case CY_WCM_SECURITY_WPA_MIXED_PSK: @@ -260,7 +262,7 @@ void get_security_type(cy_wcm_scan_result_t *result, uint8_t *security_type) { case CY_WCM_SECURITY_WPA_TKIP_ENT: case CY_WCM_SECURITY_WPA_AES_ENT: case CY_WCM_SECURITY_WPA_MIXED_ENT: - *security_type = NET_IFX_WCM_SEC_WPA; + mpy_sec_type = NET_IFX_WCM_SEC_WPA; break; case CY_WCM_SECURITY_WPA2_AES_PSK: case CY_WCM_SECURITY_WPA2_TKIP_PSK: @@ -270,28 +272,29 @@ void get_security_type(cy_wcm_scan_result_t *result, uint8_t *security_type) { case CY_WCM_SECURITY_WPA2_AES_ENT: case CY_WCM_SECURITY_WPA2_MIXED_ENT: case CY_WCM_SECURITY_WPA2_FBT_ENT: - *security_type = NET_IFX_WCM_SEC_WPA2; + mpy_sec_type = NET_IFX_WCM_SEC_WPA2; break; case CY_WCM_SECURITY_WPA2_WPA_AES_PSK: case CY_WCM_SECURITY_WPA2_WPA_MIXED_PSK: - *security_type = NET_IFX_WCM_SEC_WPA_WPA2; + mpy_sec_type = NET_IFX_WCM_SEC_WPA_WPA2; break; case CY_WCM_SECURITY_WPA3_SAE: case CY_WCM_SECURITY_WPA3_WPA2_PSK: - *security_type = NET_IFX_WCM_SEC_WPA3; + mpy_sec_type = NET_IFX_WCM_SEC_WPA3; break; case CY_WCM_SECURITY_WPS_SECURE: case CY_WCM_SECURITY_UNKNOWN: default: - *security_type = NET_IFX_WCM_SEC_UNKNOWN; + mpy_sec_type = NET_IFX_WCM_SEC_UNKNOWN; break; } + return mpy_sec_type; } // Callback function for scan method. After each scan result, the scan callback is executed. static void network_ifx_wcm_scan_cb(cy_wcm_scan_result_t *result_ptr, void *user_data, cy_wcm_scan_status_t status) { scan_user_data_t *scan_user_data = (scan_user_data_t *)user_data; - mp_obj_t *scan_list = scan_user_data->scan_list; + mp_obj_t scan_list = MP_OBJ_FROM_PTR(scan_user_data->scan_list); uint8_t hidden_status = 1; // HIDDEN uint8_t security_type = NET_IFX_WCM_SEC_OPEN; @@ -302,7 +305,7 @@ static void network_ifx_wcm_scan_cb(cy_wcm_scan_result_t *result_ptr, void *user } // Get security type as mapped in micropython function description - get_security_type(result_ptr, &security_type); + security_type = get_mpy_security_type(result_ptr->security); mp_obj_t tuple[6] = { mp_obj_new_bytes(result_ptr->SSID, strlen((const char *)result_ptr->SSID)), @@ -368,10 +371,10 @@ STATIC mp_obj_t network_ifx_wcm_scan(size_t n_args, const mp_obj_t *args, mp_map } } - // mp_obj_t res = mp_obj_new_list(0, NULL); - // void *ntwk_scan_result = MP_OBJ_TO_PTR(res); + mp_obj_t network_list = mp_obj_new_list(0, NULL); scan_user_data_t scan_user_params; - scan_user_params.scan_list = mp_obj_new_list(0, NULL); + scan_user_params.scan_list = MP_OBJ_TO_PTR(network_list); + scan_user_params.status = CY_WCM_SCAN_INCOMPLETE; cy_wcm_scan_filter_t *scan_filter_ptr = NULL; if (is_filter_used) { @@ -389,6 +392,8 @@ STATIC mp_obj_t network_ifx_wcm_scan(size_t n_args, const mp_obj_t *args, mp_map STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_ifx_wcm_scan_obj, 1, network_ifx_wcm_scan); STATIC mp_obj_t network_ifx_wcm_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + network_ifx_wcm_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + enum { ARG_ssid, ARG_key, ARG_bssid }; static const mp_arg_t allowed_args[] = { { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, @@ -396,6 +401,10 @@ STATIC mp_obj_t network_ifx_wcm_connect(size_t n_args, const mp_obj_t *pos_args, { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} } }; + if (self->itf != CY_WCM_INTERFACE_TYPE_STA) { + mp_raise_ValueError(MP_ERROR_TEXT("network STA required")); + } + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -431,7 +440,13 @@ STATIC mp_obj_t network_ifx_wcm_connect(size_t n_args, const mp_obj_t *pos_args, // Let the wcm driver discover the network security connect_param.ap_credentials.security = CY_WCM_SECURITY_UNKNOWN; - cy_rslt_t ret = cy_wcm_connect_ap(&connect_param, &ipaddress); + network_ifx_wcm_sta_obj_t *sta_conf = wcm_get_sta_conf_ptr(network_ifx_wcm_wl_sta); + uint8_t retries = sta_conf->connect_retries; + cy_rslt_t ret = CY_WCM_EVENT_CONNECT_FAILED; + do + { + ret = cy_wcm_connect_ap(&connect_param, &ipaddress); + } while (--retries < 0 && ret != CY_RSLT_SUCCESS); wcm_assert_raise("network sta connect error (with code: %d)", ret); return mp_const_none; @@ -445,7 +460,7 @@ STATIC mp_obj_t network_ifx_wcm_disconnect(mp_obj_t self_in) { mp_raise_ValueError(MP_ERROR_TEXT("network STA required")); } uint32_t ret = cy_wcm_disconnect_ap(); - wcm_assert_raise("msg tbd", ret); + wcm_assert_raise("network sta disconnect error (with code: %d)", ret); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_ifx_wcm_disconnect_obj, network_ifx_wcm_disconnect); @@ -478,9 +493,15 @@ STATIC mp_obj_t network_ifx_wcm_ifconfig(size_t n_args, const mp_obj_t *args) { network_ifx_wcm_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (n_args == 1) { const ip_addr_t *dns = dns_getserver(0); - cy_wcm_get_ip_addr(self->itf, &ip_address); - cy_wcm_get_gateway_ip_address(self->itf, &gateway_addr); - cy_wcm_get_ip_netmask(self->itf, &net_mask_addr); + cy_wcm_ip_address_t ip_address; + cy_wcm_ip_address_t net_mask_addr; + cy_wcm_ip_address_t gateway_addr; + cy_rslt_t ret = cy_wcm_get_ip_addr(self->itf, &ip_address); + wcm_assert_raise("network ifconfig error (with code: %d)", ret); + ret = cy_wcm_get_gateway_ip_address(self->itf, &gateway_addr); + wcm_assert_raise("network ifconfig error (with code: %d)", ret); + ret = cy_wcm_get_ip_netmask(self->itf, &net_mask_addr); + wcm_assert_raise("network ifconfig error (with code: %d)", ret); mp_obj_t tuple[4] = { mp_obj_new_str(ip4addr_ntoa((const ip4_addr_t *)&ip_address.ip.v4), strlen(ip4addr_ntoa((const ip4_addr_t *)&ip_address.ip.v4))), mp_obj_new_str(ip4addr_ntoa((const ip4_addr_t *)&net_mask_addr.ip.v4), strlen(ip4addr_ntoa((const ip4_addr_t *)&net_mask_addr.ip.v4))), @@ -489,15 +510,24 @@ STATIC mp_obj_t network_ifx_wcm_ifconfig(size_t n_args, const mp_obj_t *args) { }; return mp_obj_new_tuple(4, tuple); } else { - const mp_obj_t *argss = args + 1; - mp_obj_t *items; - mp_obj_get_array_fixed_n(argss[0], 4, &items); - cy_rslt_t res = cy_wcm_set_ap_ip_setting(&ap_ip, items[0], items[1], items[2], CY_WCM_IP_VER_V4); - ip_addr_t dns; - netutils_parse_ipv4_addr(items[3], (uint8_t *)&dns, NETUTILS_BIG); - dns_setserver(0, &dns); - if (res == CY_RSLT_SUCCESS) { - mp_printf(&mp_plat_print, "successfully configured"); + if (self->itf == CY_WCM_INTERFACE_TYPE_AP) { + const mp_obj_t *argss = args + 1; + mp_obj_t *items; + mp_obj_get_array_fixed_n(argss[0], 4, &items); + const char *ip_address = mp_obj_str_get_str(items[0]); + const char *net_mask_addr = mp_obj_str_get_str(items[1]); + const char *gateway_addr = mp_obj_str_get_str(items[2]); + cy_wcm_ap_config_t *ap_conf = wcm_get_ap_conf_ptr(network_ifx_wcm_wl_ap); + cy_rslt_t ret = cy_wcm_set_ap_ip_setting(&(ap_conf->ip_settings), ip_address, net_mask_addr, gateway_addr, CY_WCM_IP_VER_V4); + wcm_assert_raise("network ifconfig error (with code: %d)", ret); + + ip_addr_t dns; + netutils_parse_ipv4_addr(items[3], (uint8_t *)&dns, NETUTILS_BIG); + dns_setserver(0, &dns); + + restart_ap(ap_conf); + } else if (self->itf == CY_WCM_INTERFACE_TYPE_STA) { + mp_raise_ValueError(MP_ERROR_TEXT("network access point required")); } } @@ -527,10 +557,8 @@ STATIC mp_obj_t network_ifx_wcm_status(size_t n_args, const mp_obj_t *args) { } cy_wcm_mac_t sta_list[NETWORK_WLAN_MAX_AP_STATIONS]; - cy_wcm_mac_t not_conn_sta = {0, 0, 0, 0, 0, 0}; - uint32_t ret = cy_wcm_get_associated_client_list(&sta_list[0], NETWORK_WLAN_MAX_AP_STATIONS); wcm_assert_raise("network status error (with code: %d)", ret); @@ -548,184 +576,235 @@ STATIC mp_obj_t network_ifx_wcm_status(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ifx_wcm_status_obj, 1, 2, network_ifx_wcm_status); -static inline uint32_t nw_get_le32(const uint8_t *buf) { - return buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24; + +STATIC mp_obj_t network_ap_get_config_param(cy_wcm_ap_config_t *ap_conf, qstr query_opt) { + switch (query_opt) { + case MP_QSTR_channel: { + return MP_OBJ_NEW_SMALL_INT(ap_conf->channel); + } + + case MP_QSTR_ssid: + case MP_QSTR_essid: { + return mp_obj_new_str((const char *)ap_conf->ap_credentials.SSID, strlen((const char *)ap_conf->ap_credentials.SSID)); + } + + case MP_QSTR_security: { + return MP_OBJ_NEW_SMALL_INT(get_mpy_security_type(ap_conf->ap_credentials.security)); + } + + /* Only default password is exposed */ + case MP_QSTR_key: + case MP_QSTR_password: { + if (strcmp((const char *)ap_conf->ap_credentials.password, NETWORK_WLAN_DEFAULT_PASSWORD) == 0) { + return mp_obj_new_str((const char *)NETWORK_WLAN_DEFAULT_PASSWORD, strlen((const char *)NETWORK_WLAN_DEFAULT_PASSWORD)); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("network conf password only queryable for default password")); + } + break; + } + + case MP_QSTR_mac: { + cy_wcm_mac_t mac; + uint32_t ret = cy_wcm_get_mac_addr(CY_WCM_INTERFACE_TYPE_AP, &mac); + wcm_assert_raise("network config mac (code: %d)", ret); + + return mp_obj_new_bytes(mac, 6); + } + + case MP_QSTR_hostname: { + mp_raise_ValueError(MP_ERROR_TEXT("deprecated. use network.hostname() instead")); + break; + } + + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + } +} + +STATIC mp_obj_t network_sta_get_config_param(network_ifx_wcm_sta_obj_t *sta_conf, qstr query_opt) { + switch (query_opt) { + case MP_QSTR_channel: { + cy_wcm_associated_ap_info_t ap_info; + uint32_t ret = cy_wcm_get_associated_ap_info(&ap_info); + wcm_assert_raise("network config error (with code: %d)", ret); + return MP_OBJ_NEW_SMALL_INT(ap_info.channel); + } + + case MP_QSTR_mac: { + cy_wcm_mac_t mac; + uint32_t ret = cy_wcm_get_mac_addr(CY_WCM_INTERFACE_TYPE_STA, &mac); + wcm_assert_raise("network config mac (code: %d)", ret); + return mp_obj_new_bytes(mac, 6); + } + + case MP_QSTR_ssid: + case MP_QSTR_essid: { + cy_wcm_associated_ap_info_t ap_info; + uint32_t ret = cy_wcm_get_associated_ap_info(&ap_info); + wcm_assert_raise("network config error (with code: %d)", ret); + return mp_obj_new_str((const char *)ap_info.SSID, strlen((const char *)ap_info.SSID)); + } + + case MP_QSTR_security: { + cy_wcm_associated_ap_info_t ap_info; + uint32_t ret = cy_wcm_get_associated_ap_info(&ap_info); + wcm_assert_raise("network config error (with code: %d)", ret); + return MP_OBJ_NEW_SMALL_INT(get_mpy_security_type(ap_info.security)); + } + + case MP_QSTR_password: + case MP_QSTR_key: { + mp_raise_ValueError(MP_ERROR_TEXT("network access point required")); + break; + } + + case MP_QSTR_hostname: { + mp_raise_ValueError(MP_ERROR_TEXT("deprecated. use network.hostname() instead")); + break; + } + + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + } } -static inline void nw_put_le32(uint8_t *buf, uint32_t x) { - buf[0] = x; - buf[1] = x >> 8; - buf[2] = x >> 16; - buf[3] = x >> 24; +cy_wcm_security_t get_wm_security_type(mp_obj_t mpy_sec) { + switch (mp_obj_get_int(mpy_sec)) + { + case NET_IFX_WCM_SEC_OPEN: + return CY_WCM_SECURITY_OPEN; + + case NET_IFX_WCM_SEC_WPA: + return CY_WCM_SECURITY_WPA_MIXED_PSK; + + case NET_IFX_WCM_SEC_WPA2: + return CY_WCM_SECURITY_WPA2_MIXED_PSK; + + case NET_IFX_WCM_SEC_WPA3: + return CY_WCM_SECURITY_WPA3_SAE; + + case NET_IFX_WCM_SEC_WPA_WPA2: + return CY_WCM_SECURITY_WPA2_WPA_MIXED_PSK; + + default: + return CY_WCM_SECURITY_UNKNOWN; + } } -STATIC mp_obj_t network_ifx_wcm_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { - network_ifx_wcm_obj_t *self = MP_OBJ_TO_PTR(args[0]); +STATIC void network_ap_set_config_param(cy_wcm_ap_config_t *ap_conf, qstr opt, mp_obj_t opt_value, bool hold) { - if (kwargs->used == 0) { - // Get config value - if (n_args != 2) { - mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + static bool required_ap_restart = false; + + switch (opt) { + case MP_QSTR_channel: { + ap_conf->channel = mp_obj_get_int(opt_value); + required_ap_restart = true; + break; } - switch (mp_obj_str_get_qstr(args[1])) { - case MP_QSTR_antenna: { - uint8_t buf[4]; - uint32_t ret = whd_wifi_get_ioctl_buffer(whd_ifs[self->itf], WLC_GET_ANTDIV, buf, 4); - wcm_assert_raise("msg tbd", ret); + case MP_QSTR_ssid: + case MP_QSTR_essid: { + size_t len; + const char *ssid_str = mp_obj_str_get_data(opt_value, &len); + memset(ap_conf->ap_credentials.SSID, 0, CY_WCM_MAX_SSID_LEN + 1); + memcpy(ap_conf->ap_credentials.SSID, ssid_str, len); + required_ap_restart = true; + break; + } - return MP_OBJ_NEW_SMALL_INT(nw_get_le32(buf)); - } - case MP_QSTR_channel: { - uint32_t channel; - uint32_t ret = whd_wifi_get_channel(whd_ifs[self->itf], &channel); - wcm_assert_raise("msg tbd", ret); + case MP_QSTR_security: { + cy_wcm_security_t wcm_sec = get_wm_security_type(opt_value); + ap_conf->ap_credentials.security = wcm_sec; + required_ap_restart = true; + break; + } - return MP_OBJ_NEW_SMALL_INT(channel); - } - case MP_QSTR_ssid: - case MP_QSTR_essid: { - wl_bss_info_t bss_info; - uint32_t ret = whd_wifi_get_bss_info(whd_ifs[self->itf], &bss_info); - wcm_assert_raise("msg tbd", ret); + case MP_QSTR_key: + case MP_QSTR_password: { + size_t len; + const char *pass_str = mp_obj_str_get_data(opt_value, &len); + memset(ap_conf->ap_credentials.password, 0, CY_WCM_MAX_PASSPHRASE_LEN + 1); + memcpy(ap_conf->ap_credentials.password, pass_str, len); + break; + } - return mp_obj_new_str((const char *)bss_info.SSID, bss_info.SSID_len); - } + case MP_QSTR_hostname: { + mp_raise_ValueError(MP_ERROR_TEXT("deprecated. use network.hostname() instead")); + break; + } + + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + } - case MP_QSTR_security: { - whd_security_t security; - uint32_t ret = whd_wifi_get_ap_info(whd_ifs[self->itf], NULL, &security); - wcm_assert_raise("msg tbd", ret); + if (required_ap_restart && !hold) { + restart_ap(ap_conf); + required_ap_restart = false; + } +} - return MP_OBJ_NEW_SMALL_INT(security); - } +STATIC void network_sta_set_config_param(network_ifx_wcm_sta_obj_t *sta_conf, qstr opt, mp_obj_t opt_value) { + switch (opt) { + case MP_QSTR_channel: + case MP_QSTR_key: + case MP_QSTR_password: + case MP_QSTR_ssid: + case MP_QSTR_essid: { + mp_raise_ValueError(MP_ERROR_TEXT("network access point required")); + break; + } - case MP_QSTR_mac: { - cy_wcm_mac_t mac; - uint32_t ret = cy_wcm_get_mac_addr(self->itf, &mac); - wcm_assert_raise("network config mac (code: %d)", ret); + case MP_QSTR_hostname: { + mp_raise_ValueError(MP_ERROR_TEXT("deprecated. use network.hostname() instead")); + break; + } - return mp_obj_new_bytes(mac, 6); - } - case MP_QSTR_txpower: { - uint8_t buf[13]; - memcpy(buf, "qtxpower\x00\x00\x00\x00\x00", 13); - uint32_t ret = whd_wifi_get_ioctl_buffer(whd_ifs[self->itf], WLC_GET_VAR, buf, 13); - wcm_assert_raise("msg tbd", ret); + default: + mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + } +} - return MP_OBJ_NEW_SMALL_INT(nw_get_le32(buf) / 4); - } +STATIC mp_obj_t network_ifx_wcm_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + network_ifx_wcm_obj_t *self = MP_OBJ_TO_PTR(args[0]); - case MP_QSTR_hostname: { - mp_raise_ValueError(MP_ERROR_TEXT("deprecated. use network.hostname() instead.")); - break; - } + if (kwargs->used == 0) { + // Get config value + if (n_args != 2) { + mp_raise_TypeError(MP_ERROR_TEXT("must query one param")); + } - default: - mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + if (self->itf == CY_WCM_INTERFACE_TYPE_AP) { + cy_wcm_ap_config_t *ap_conf = wcm_get_ap_conf_ptr(network_ifx_wcm_wl_ap); + return network_ap_get_config_param(ap_conf, mp_obj_str_get_qstr(args[1])); + } else if (self->itf == CY_WCM_INTERFACE_TYPE_STA) { + network_ifx_wcm_sta_obj_t *sta_conf = wcm_get_sta_conf_ptr(network_ifx_wcm_wl_sta); + return network_sta_get_config_param(sta_conf, mp_obj_str_get_qstr(args[1])); } } else { // Set config value(s) if (n_args != 1) { mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args")); } - + size_t kwargs_num = kwargs->alloc; for (size_t i = 0; i < kwargs->alloc; ++i) { if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { mp_map_elem_t *e = &kwargs->table[i]; - switch (mp_obj_str_get_qstr(e->key)) { - case MP_QSTR_antenna: { - uint8_t buf[4]; - nw_put_le32(buf, mp_obj_get_int(e->value)); - uint32_t ret = whd_wifi_set_ioctl_buffer(whd_ifs[self->itf], WLC_SET_ANTDIV, buf, 4); - wcm_assert_raise("msg tbd", ret); - break; - } - case MP_QSTR_channel: { - uint32_t ret = whd_wifi_set_channel(whd_ifs[self->itf], mp_obj_get_int(e->value)); - wcm_assert_raise("msg tbd", ret); - break; - } - case MP_QSTR_ssid: - case MP_QSTR_essid: { - // TODO: Implement ssid/essid change. Explore WHD to change name - // managing the state. Only available in the API via whd_wifi_init_ap. - - // size_t len; - // const char *ssid_str = mp_obj_str_get_data(e->value, &len); - // whd_security_t security; - // wl_bss_info_t bss_info; - // uint32_t ret = whd_wifi_get_ap_info(itf, &bss_info, &security); - // if (ret != WHD_SUCCESS) { - // mp_raise_OSError(-ret); - // } - // whd_ssid_t whd_ssid; - // memcpy(whd_ssid.value, ssid_str, len); - // whd_ssid.length = len; - // uint32_t ret = whd_wifi_init_ap(itf, &whd_ssid, &security, ); - - break; - } - case MP_QSTR_monitor: { - mp_int_t value = mp_obj_get_int(e->value); - uint8_t buf[9 + 4]; - memcpy(buf, "allmulti\x00", 9); - nw_put_le32(buf + 9, value); - uint32_t ret = whd_wifi_set_ioctl_buffer(whd_ifs[self->itf], WLC_SET_VAR, buf, 9 + 4); - wcm_assert_raise("msg tbd", ret); - nw_put_le32(buf, value); - ret = whd_wifi_set_ioctl_buffer(whd_ifs[self->itf], WLC_SET_MONITOR, buf, 4); - wcm_assert_raise("msg tbd", ret); - // In cyw43 they keep the trace flags in a variable. - // TODO. Understand how are these trace flags used, and if - // an equivalent tracing feature can/should be enabled - // for the WHD. - // if (value) { - // self->cyw->trace_flags |= CYW43_TRACE_MAC; - // } else { - // self->cyw->trace_flags &= ~CYW43_TRACE_MAC; - // } - break; - } - case MP_QSTR_security: { - // TODO: Implement AP security change - break; - } - case MP_QSTR_key: - case MP_QSTR_password: { - // TODO: Implement AP password change - break; - } - case MP_QSTR_pm: { - // TODO: Implement pm? What is pm in the cyw43? power management - break; - } - case MP_QSTR_trace: { - // TODO: Implement tracing. - break; - } - case MP_QSTR_txpower: { - mp_int_t dbm = mp_obj_get_int(e->value); - uint8_t buf[9 + 4]; - memcpy(buf, "qtxpower\x00", 9); - nw_put_le32(buf + 9, dbm * 4); - uint32_t ret = whd_wifi_set_ioctl_buffer(whd_ifs[self->itf], WLC_SET_VAR, buf, 9 + 4); - wcm_assert_raise("msg tbd", ret); - break; - } - case MP_QSTR_hostname: { - mp_raise_ValueError(MP_ERROR_TEXT("deprecated. use network.hostname() instead.")); - break; - } - default: - mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); + if (self->itf == CY_WCM_INTERFACE_TYPE_AP) { + bool hold_config = true; + if (i == kwargs_num - 1) { + hold_config = false; + } + cy_wcm_ap_config_t *ap_conf = wcm_get_ap_conf_ptr(network_ifx_wcm_wl_ap); + network_ap_set_config_param(ap_conf, mp_obj_str_get_qstr(e->key), e->value, hold_config); + } else if (self->itf == CY_WCM_INTERFACE_TYPE_STA) { + network_ifx_wcm_sta_obj_t *sta_conf = wcm_get_sta_conf_ptr(network_ifx_wcm_wl_sta); + network_sta_set_config_param(sta_conf, mp_obj_str_get_qstr(e->key), e->value); } } } - - return mp_const_none; } + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_ifx_wcm_config_obj, 1, network_ifx_wcm_config); @@ -733,8 +812,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_ifx_wcm_config_obj, 1, network_ifx_wcm // class bindings STATIC const mp_rom_map_elem_t network_ifx_wcm_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_send_ethernet), MP_ROM_PTR(&network_ifx_wcm_send_ethernet_obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&network_ifx_wcm_deinit_obj) }, // shall this be part of the module ?? { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&network_ifx_wcm_active_obj) }, { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&network_ifx_wcm_scan_obj) }, @@ -747,27 +824,13 @@ STATIC const mp_rom_map_elem_t network_ifx_wcm_locals_dict_table[] = { // Network WCM constants // Security modes - { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(CY_WCM_SECURITY_OPEN) }, - // { MP_ROM_QSTR(MP_QSTR_WEP_PSK), MP_ROM_INT(CY_WCM_SECURITY_WEP_PSK) }, - // { MP_ROM_QSTR(MP_QSTR_WEP_SHARED), MP_ROM_INT(CY_WCM_SECURITY_WEP_SHARED) }, - // { MP_ROM_QSTR(MP_QSTR_WPA_TKIP_PSK), MP_ROM_INT(CY_WCM_SECURITY_WPA_TKIP_PSK) }, - // { MP_ROM_QSTR(MP_QSTR_WPA_AES_PSK), MP_ROM_INT(CY_WCM_SECURITY_WPA_AES_PSK) }, - { MP_ROM_QSTR(MP_QSTR_WPA), MP_ROM_INT(CY_WCM_SECURITY_WPA_MIXED_PSK) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_AES_PSK), MP_ROM_INT(CY_WCM_SECURITY_WPA2_AES_PSK) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_TKIP_PSK), MP_ROM_INT(CY_WCM_SECURITY_WPA2_TKIP_PSK) }, - { MP_ROM_QSTR(MP_QSTR_WPA2), MP_ROM_INT(CY_WCM_SECURITY_WPA2_MIXED_PSK) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_FBT_PSK), MP_ROM_INT(CY_WCM_SECURITY_WPA2_FBT_PSK) }, - { MP_ROM_QSTR(MP_QSTR_WPA3), MP_ROM_INT(CY_WCM_SECURITY_WPA3_SAE) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_WPA_AES_PSK), MP_ROM_INT(CY_WCM_SECURITY_WPA2_WPA_AES_PSK) }, - { MP_ROM_QSTR(MP_QSTR_WPA2_WPA_PSK), MP_ROM_INT(CY_WCM_SECURITY_WPA2_WPA_MIXED_PSK) }, - // { MP_ROM_QSTR(MP_QSTR_WPA3_WPA2_PSK), MP_ROM_INT(CY_WCM_SECURITY_WPA3_WPA2_PSK) }, - // { MP_ROM_QSTR(MP_QSTR_WPA_TKIP_ENT), MP_ROM_INT(CY_WCM_SECURITY_WPA_TKIP_ENT) }, - // { MP_ROM_QSTR(MP_QSTR_WPA_MIXED_ENT), MP_ROM_INT(CY_WCM_SECURITY_WPA_MIXED_ENT) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_TKIP_ENT), MP_ROM_INT(CY_WCM_SECURITY_WPA2_TKIP_ENT) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_MIXED_ENT), MP_ROM_INT(CY_WCM_SECURITY_WPA2_MIXED_ENT) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_FBT_ENT), MP_ROM_INT(CY_WCM_SECURITY_WPA2_FBT_ENT) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_IBSS_OPEN), MP_ROM_INT(CY_WCM_SECURITY_IBSS_OPEN) }, - // { MP_ROM_QSTR(MP_QSTR_WPA2_WPS_SECURE), MP_ROM_INT(CY_WCM_SECURITY_WPS_SECURE) }, + { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(NET_IFX_WCM_SEC_OPEN) }, + { MP_ROM_QSTR(MP_QSTR_WEP), MP_ROM_INT(NET_IFX_WCM_SEC_WEP) }, + { MP_ROM_QSTR(MP_QSTR_WPA), MP_ROM_INT(NET_IFX_WCM_SEC_WPA) }, + { MP_ROM_QSTR(MP_QSTR_WPA2), MP_ROM_INT(NET_IFX_WCM_SEC_WPA2) }, + { MP_ROM_QSTR(MP_QSTR_WPA3), MP_ROM_INT(NET_IFX_WCM_SEC_WPA3) }, + { MP_ROM_QSTR(MP_QSTR_WPA2_WPA_PSK), MP_ROM_INT(NET_IFX_WCM_SEC_WPA_WPA2) }, + { MP_ROM_QSTR(MP_QSTR_SEC_UNKNOWN), MP_ROM_INT(NET_IFX_WCM_SEC_UNKNOWN) }, }; STATIC MP_DEFINE_CONST_DICT(network_ifx_wcm_locals_dict, network_ifx_wcm_locals_dict_table); diff --git a/tests/psoc6/multi/network.py b/tests/psoc6/multi/network.py index 0b3f6c77dc03..e55743906a25 100644 --- a/tests/psoc6/multi/network.py +++ b/tests/psoc6/multi/network.py @@ -1,5 +1,10 @@ import binascii, network, time +channel_default = 9 +channel_new = 5 +ssid_default = "mpy-psoc6-wlan" +ssid_new = "mpy-test-conf-wlan" + # Access Point def instance0(): @@ -41,10 +46,6 @@ def instance0(): stations = ap_if.status("stations") print("ap status has stations: ", stations != []) - # ifconfig() - - # config() - # Station def instance1(): @@ -73,7 +74,7 @@ def instance1(): print("sta is not (yet) connected: ", sta_if.isconnected() == False) # connect() - sta_if.connect("mpy-psoc6-wlan", "mpy_PSOC6_w3lc0me!") + sta_if.connect(ssid_default, "mpy_PSOC6_w3lc0me!") print("sta attempt connection to ap") # active() @@ -83,6 +84,7 @@ def instance1(): print("sta is (now) connected: ", sta_if.isconnected() == True) # status() + # The test boards are placed next to each other (few cm range) print("sta status rssi in range: ", -70 < sta_if.status("rssi") < 0) print(" > yield access point") @@ -93,10 +95,6 @@ def instance1(): print("sta is disconnected: ", sta_if.active() == False) print("sta attempt connection to ap (with bssid)") - sta_if.connect("mpy-psoc6-wlan", "mpy_PSOC6_w3lc0me!", bssid=ap_mac) + sta_if.connect(ssid_default, "mpy_PSOC6_w3lc0me!", bssid=ap_mac) print("sta is active: ", sta_if.active() == True) - - # ifconfig() - - # config() diff --git a/tests/psoc6/multi/network_config.py b/tests/psoc6/multi/network_config.py new file mode 100644 index 000000000000..ca162ced7ae5 --- /dev/null +++ b/tests/psoc6/multi/network_config.py @@ -0,0 +1,92 @@ +import binascii, network, time + +channel_new = 5 +ssid_new = "mpy-test-conf-wlan" +pass_new = "alicessecret" +sec_new = network.WLAN.WPA2 + +ap_ip = "10.20.0.1" +gateway_ip = ap_ip +netmask_ip = "255.255.255.128" +dns_ip = "0.0.0.0" +ap_net_conf = (ap_ip, netmask_ip, gateway_ip, dns_ip) + + +# Access Point +def instance0(): + ap_if = network.WLAN(network.AP_IF) + print("ap instance created") + + # get config() + ap_if.config(channel=channel_new) + print("ap config get channel: ", ap_if.config("channel") == channel_new) + ap_if.config(ssid=ssid_new) + print("ap config get ssid: ", ap_if.config("ssid") == ssid_new) + ap_if.config(security=sec_new, key=pass_new) + print("ap config get security: ", ap_if.config("security") == sec_new) + try: + ap_if.config("password") # only if default + except ValueError as err: + print(err) + + # active() + ap_if.active(True) + while ap_if.active() == False: + pass + print("ap is activated") + + # set ifconfig() + ap_if.ifconfig(ap_net_conf) + + # get ifconfig() + print("ap ip settings: ", ap_if.ifconfig() == ap_net_conf) + + print(" > yield station") + multitest.next() + + while ap_if.isconnected() == False: + pass + print("ap has clients: ", ap_if.isconnected() == True) + + # status() + stations = ap_if.status("stations") + print("ap status has stations: ", stations != []) + + print(ap_if) + + +# Station +def instance1(): + sta_if = network.WLAN(network.STA_IF) + print("sta instance created") + + # connect() + sta_if.connect(ssid_new, pass_new) + print("sta attempt connection to ap") + + # active() + print("sta is (now) active: ", sta_if.active() == True) + + # isConnected() + print("sta is (now) connected: ", sta_if.isconnected() == True) + + # config() + print("sta assoc ap channel config: ", sta_if.config("channel") == channel_new) + print("sta assoc ap ssid config: ", sta_if.config("ssid") == ssid_new) + print("sta assoc ap security config: ", sta_if.config("security") == sec_new) + + try: + sta_if.config("key") # not for STA + except ValueError as err: + print(err) + + # ifconfig() + sta_net_conf = ("10.20.0.2", netmask_ip, ap_ip, ap_ip) + print("sta ip settings: ", sta_if.ifconfig() == sta_net_conf) + + try: + sta_if.ifconfig(sta_net_conf) # not for STA + except ValueError as err: + print(err) + + print(sta_if) diff --git a/tests/psoc6/multi/network_config.py.exp b/tests/psoc6/multi/network_config.py.exp new file mode 100644 index 000000000000..7985c2ac8e89 --- /dev/null +++ b/tests/psoc6/multi/network_config.py.exp @@ -0,0 +1,24 @@ +--- instance0 --- +ap instance created +ap config get channel: True +ap config get ssid: True +ap config get security: True +network conf password only queryable for default password +ap is activated +ap ip settings: True + > yield station +ap has clients: True +ap status has stations: True + +--- instance1 --- +sta instance created +sta attempt connection to ap +sta is (now) active: True +sta is (now) connected: True +sta assoc ap channel config: True +sta assoc ap ssid config: True +sta assoc ap security config: True +network access point required +sta ip settings: True +network access point required +