diff options
author | Daniel Campora <daniel@wipy.io> | 2015-08-05 13:36:29 +0200 |
---|---|---|
committer | Daniel Campora <daniel@wipy.io> | 2015-08-09 19:22:12 +0200 |
commit | 00c4d6562ec2dbb494e9c26dce86f99f95a82d70 (patch) | |
tree | c53a499a65a1d16c310b1d8bb7f44347950aeaa5 | |
parent | e86b47175fb0dc0992e46f48117d29e3f40969c1 (diff) | |
download | micropython-00c4d6562ec2dbb494e9c26dce86f99f95a82d70.tar.gz micropython-00c4d6562ec2dbb494e9c26dce86f99f95a82d70.zip |
cc3200: Add nic.iwconfig() to set/get WLAN configuration.
Changes are based on this post:
https://github.com/micropython/micropython/issues/876#issuecomment-115255551
The constructor can optionally take the same params of iwconfig in
order to configure WiFi when creating the object. Params are
keyworkd only. The WiPy accepts:
- mode (int -> WLAN.AP or WLAN.STA)
- ssdi (string)
- security (int -> WLAN.OPEN, WLAN.WEP, WLAN.WPA, WLAN.WPA2)
- key (string)
- channel (int (1-11))
- antenna (int -> WLAN.INTERNAL, WLAN.EXTERNAL)
-rw-r--r-- | cc3200/mods/modwlan.c | 492 | ||||
-rw-r--r-- | cc3200/mods/modwlan.h | 6 | ||||
-rw-r--r-- | cc3200/qstrdefsport.h | 14 | ||||
-rw-r--r-- | docs/library/network.rst | 86 |
4 files changed, 293 insertions, 305 deletions
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c index 3c61004709..6a03fdbb85 100644 --- a/cc3200/mods/modwlan.c +++ b/cc3200/mods/modwlan.c @@ -86,32 +86,31 @@ typedef enum{ STATUS_BIT_PING_DONE // If this bit is set: the device has completed // the ping operation -}e_StatusBits; +} e_StatusBits; typedef struct _wlan_obj_t { mp_obj_base_t base; - SlWlanMode_t mode; uint32_t status; uint32_t ip; - uint32_t gateway; - uint32_t dns; -#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) - bool servers_enabled; -#endif + int8_t mode; uint8_t security; + uint8_t channel; + uint8_t antenna; - // my own name and mac + // my own ssid, key and mac uint8_t ssid[33]; + uint8_t key[65]; uint8_t mac[SL_MAC_ADDR_LEN]; - // the name and mac of the other device + // the sssid (or name) and mac of the other device uint8_t ssid_o[33]; uint8_t bssid[6]; - bool staconnected; - +#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) + bool servers_enabled; +#endif } wlan_obj_t; /****************************************************************************** @@ -141,16 +140,13 @@ typedef struct _wlan_obj_t { #define MODWLAN_SCAN_PERIOD_S 3600 // 1 hour #define MODWLAN_WAIT_FOR_SCAN_MS 1050 -#define ASSERT_ON_ERROR( x ) ASSERT((x) >= 0 ) +#define ASSERT_ON_ERROR(x) ASSERT((x) >= 0) #define IPV4_ADDR_STR_LEN_MAX (16) #define WLAN_MAX_RX_SIZE 16000 #define WLAN_MAX_TX_SIZE 1476 -#define MODWLAN_IP_MODE_DYNAMIC 0 -#define MODWLAN_IP_MODE_STATIC 1 - #define MAKE_SOCKADDR(addr, ip, port) sockaddr addr; \ addr.sa_family = AF_INET; \ addr.sa_data[0] = port >> 8; \ @@ -173,17 +169,16 @@ STATIC wlan_obj_t wlan_obj = { .mode = -1, .status = 0, .ip = 0, - .gateway = 0, - .dns = 0, + .security = MICROPY_PORT_WLAN_AP_SECURITY, + .channel = MICROPY_PORT_WLAN_AP_CHANNEL, + .ssid = MICROPY_PORT_WLAN_AP_SSID, + .key = MICROPY_PORT_WLAN_AP_KEY, + .mac = {0}, + .ssid_o = {0}, + .bssid = {0}, #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) .servers_enabled = false, #endif - .security = SL_SEC_TYPE_OPEN, - .ssid = {0}, - .bssid = {0}, - .mac = {0}, - .ssid_o = {0}, - .staconnected = false }; STATIC const mp_cb_methods_t wlan_cb_methods; @@ -196,7 +191,7 @@ OsiLockObj_t wlan_LockObj; /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ -STATIC void wlan_initialize_data (void); +STATIC void wlan_clear_data (void); STATIC void wlan_reenable (SlWlanMode_t mode); STATIC void wlan_servers_start (void); STATIC void wlan_servers_stop (void); @@ -252,7 +247,7 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) { memcpy(wlan_obj.bssid, pEventData->mac, SL_BSSID_LENGTH); memcpy(wlan_obj.ssid_o, pEventData->go_peer_device_name, pEventData->go_peer_device_name_len); wlan_obj.ssid_o[pEventData->go_peer_device_name_len] = '\0'; - wlan_obj.staconnected = true; + SET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION); #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) // we must reset the servers in case that the last connection // was lost without any notification being received @@ -261,7 +256,7 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) { } break; case SL_WLAN_STA_DISCONNECTED_EVENT: - wlan_obj.staconnected = false; + CLR_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION); #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP) servers_reset(); #endif @@ -306,10 +301,8 @@ void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) { // Ip Acquired Event Data pEventData = &pNetAppEvent->EventData.ipAcquiredV4; - // Get ip, gateway and dns - wlan_obj.gateway = pEventData->gateway; + // Get the ip wlan_obj.ip = pEventData->ip; - wlan_obj.dns = pEventData->dns; } break; case SL_NETAPP_IPV6_IPACQUIRED_EVENT: @@ -416,7 +409,7 @@ void wlan_pre_init (void) { void wlan_first_start (void) { if (wlan_obj.mode < 0) { - wlan_initialize_data(); + CLR_STATUS_BIT_ALL(wlan_obj.status); wlan_obj.mode = sl_Start(0, 0, 0); sl_LockObjUnlock (&wlan_LockObj); } @@ -425,122 +418,118 @@ void wlan_first_start (void) { wlan_get_sl_mac(); } -modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ssid_len, uint8_t sec, - const char *key, uint8_t key_len, uint8_t channel, bool append_mac) { +void wlan_sl_enable (int8_t mode, const char *ssid, uint8_t ssid_len, uint8_t sec, + const char *key, uint8_t key_len, uint8_t channel, bool append_mac) { - if (mode == ROLE_STA || mode == ROLE_AP || mode == ROLE_P2P) { - // stop the servers - wlan_servers_stop(); + // stop the servers + wlan_servers_stop(); - // do a basic start - wlan_first_start(); + // do a basic start + wlan_first_start(); - // Device in station-mode. Disconnect previous connection if any - // The function returns 0 if 'Disconnected done', negative number if already - // disconnected Wait for 'disconnection' event if 0 is returned, Ignore - // other return-codes - if (0 == sl_WlanDisconnect()) { - while (IS_CONNECTED (wlan_obj.status)) { - HAL_Delay (5); - wlan_update(); - } + // Device in station-mode. Disconnect previous connection if any + // The function returns 0 if 'Disconnected done', negative number if already + // disconnected Wait for 'disconnection' event if 0 is returned, Ignore + // other return-codes + if (0 == sl_WlanDisconnect()) { + while (IS_CONNECTED (wlan_obj.status)) { + HAL_Delay (5); + wlan_update(); } + } - // Remove all profiles - ASSERT_ON_ERROR(sl_WlanProfileDel(0xFF)); - - // Enable the DHCP client - uint8_t value = 1; - ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE, 1, 1, &value)); - - // Set PM policy to normal - ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_PM, SL_NORMAL_POLICY, NULL, 0)); - - // Unregister mDNS services - ASSERT_ON_ERROR(sl_NetAppMDNSUnRegisterService(0, 0)); - - // Stop the internal HTTP server - sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID); - - // Remove all 64 filters (8 * 8) - _WlanRxFilterOperationCommandBuff_t RxFilterIdMask; - memset ((void *)&RxFilterIdMask, 0 ,sizeof(RxFilterIdMask)); - memset(RxFilterIdMask.FilterIdMask, 0xFF, 8); - ASSERT_ON_ERROR(sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask, sizeof(_WlanRxFilterOperationCommandBuff_t))); - - // Set Tx power level for station or AP mode - // Number between 0-15, as dB offset from max power - 0 will set max power - uint8_t ucPower = 0; - if (mode == ROLE_AP) { - // Switch to AP mode - ASSERT_ON_ERROR(sl_WlanSetMode(mode)); - ASSERT (ssid != NULL && key != NULL); - ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_AP_TX_POWER, sizeof(ucPower), - (unsigned char *)&ucPower)); - memcpy(wlan_obj.ssid, (unsigned char *)ssid, ssid_len); - // append the last 2 bytes of the MAC address, since the use of this functionality is under our controll - // we can assume that the lenght of the ssid is less than (32 - 5) - if (append_mac) { - snprintf((char *)&wlan_obj.ssid[ssid_len], sizeof(wlan_obj.ssid) - ssid_len, "-%02x%02x", wlan_obj.mac[4], wlan_obj.mac[5]); - ssid_len += 5; - } - ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, ssid_len, (unsigned char *)wlan_obj.ssid)); - ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, sizeof(uint8_t), &sec)); - ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, key_len, (unsigned char *)key)); - _u8* country = (_u8*)"EU"; - ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE, 2, country)); - ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_CHANNEL, 1, (_u8 *)&channel)); - - // stop and start again - wlan_reenable(mode); - ASSERT (wlan_obj.mode == mode); - - SlNetCfgIpV4Args_t ipV4; - ipV4.ipV4 = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 IP address - ipV4.ipV4Mask = (_u32)SL_IPV4_VAL(255,255,255,0); // _u32 Subnet mask for this AP - ipV4.ipV4Gateway = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 Default gateway address - ipV4.ipV4DnsServer = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 DNS server address - ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, - sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4)); - - // stop and start again - wlan_reenable(mode); - - SlNetAppDhcpServerBasicOpt_t dhcpParams; - dhcpParams.lease_time = 4096; // lease time (in seconds) of the IP Address - dhcpParams.ipv4_addr_start = SL_IPV4_VAL(192,168,1,2); // first IP Address for allocation. - dhcpParams.ipv4_addr_last = SL_IPV4_VAL(192,168,1,254); // last IP Address for allocation. - ASSERT_ON_ERROR(sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID)); // Stop DHCP server before settings - ASSERT_ON_ERROR(sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT, - sizeof(SlNetAppDhcpServerBasicOpt_t), (_u8* )&dhcpParams)); // set parameters - ASSERT_ON_ERROR(sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID)); // Start DHCP server with new settings - - // stop and start again - wlan_reenable(mode); - - // save the security type - wlan_obj.security = sec; - } - // STA and P2P modes - else { - ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, - sizeof(ucPower), (unsigned char *)&ucPower)); - ASSERT_ON_ERROR(sl_WlanSetMode(mode)); - // stop and start again - wlan_reenable(mode); - // set connection policy to Auto + Fast (tries to connect to the last connected AP) - ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_CONNECTION,SL_CONNECTION_POLICY(1, 1, 0, 0, 0), NULL, 0)); + // Remove all profiles + ASSERT_ON_ERROR(sl_WlanProfileDel(0xFF)); + + // Enable the DHCP client + uint8_t value = 1; + ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE, 1, 1, &value)); + + // Set PM policy to normal + ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_PM, SL_NORMAL_POLICY, NULL, 0)); + + // Unregister mDNS services + ASSERT_ON_ERROR(sl_NetAppMDNSUnRegisterService(0, 0)); + + // Stop the internal HTTP server + sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID); + + // Remove all 64 filters (8 * 8) + _WlanRxFilterOperationCommandBuff_t RxFilterIdMask; + memset ((void *)&RxFilterIdMask, 0 ,sizeof(RxFilterIdMask)); + memset(RxFilterIdMask.FilterIdMask, 0xFF, 8); + ASSERT_ON_ERROR(sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask, sizeof(_WlanRxFilterOperationCommandBuff_t))); + + // Set Tx power level for station or AP mode + // Number between 0-15, as dB offset from max power - 0 will set max power + uint8_t ucPower = 0; + if (mode == ROLE_AP) { + // switch to AP mode + ASSERT_ON_ERROR(sl_WlanSetMode(mode)); + ASSERT (ssid != NULL && key != NULL); + ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_AP_TX_POWER, sizeof(ucPower), + (unsigned char *)&ucPower)); + memcpy(wlan_obj.ssid, (unsigned char *)ssid, ssid_len); + // append the last 2 bytes of the MAC address, since the use of this functionality is under our controll + // we can assume that the lenght of the ssid is less than (32 - 5) + if (append_mac) { + snprintf((char *)&wlan_obj.ssid[ssid_len], sizeof(wlan_obj.ssid) - ssid_len, "-%02x%02x", wlan_obj.mac[4], wlan_obj.mac[5]); + ssid_len += 5; } + wlan_obj.ssid[ssid_len] = '\0'; + ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, ssid_len, (unsigned char *)wlan_obj.ssid)); + ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, sizeof(uint8_t), &sec)); + ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, key_len, (unsigned char *)key)); + _u8* country = (_u8*)"EU"; + ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE, 2, country)); + ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_CHANNEL, 1, (_u8 *)&channel)); + + // stop and start again + wlan_reenable(mode); + ASSERT (wlan_obj.mode == mode); - // set current time and date (needed to validate certificates) - wlan_set_current_time (pybrtc_get_seconds()); + SlNetCfgIpV4Args_t ipV4; + ipV4.ipV4 = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 IP address + ipV4.ipV4Mask = (_u32)SL_IPV4_VAL(255,255,255,0); // _u32 Subnet mask for this AP + ipV4.ipV4Gateway = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 Default gateway address + ipV4.ipV4DnsServer = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 DNS server address + ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, + sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4)); + + // stop and start again + wlan_reenable(mode); + + SlNetAppDhcpServerBasicOpt_t dhcpParams; + dhcpParams.lease_time = 4096; // lease time (in seconds) of the IP Address + dhcpParams.ipv4_addr_start = SL_IPV4_VAL(192,168,1,2); // first IP Address for allocation. + dhcpParams.ipv4_addr_last = SL_IPV4_VAL(192,168,1,254); // last IP Address for allocation. + ASSERT_ON_ERROR(sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID)); // Stop DHCP server before settings + ASSERT_ON_ERROR(sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT, + sizeof(SlNetAppDhcpServerBasicOpt_t), (_u8* )&dhcpParams)); // set parameters + ASSERT_ON_ERROR(sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID)); // Start DHCP server with new settings + + // stop and start again + wlan_reenable(mode); + + // save the security type + wlan_obj.security = sec; + } + // STA and P2P modes + else { + ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, + sizeof(ucPower), (unsigned char *)&ucPower)); + ASSERT_ON_ERROR(sl_WlanSetMode(mode)); + // stop and start again + wlan_reenable(mode); + // set connection policy to Auto + Fast (tries to connect to the last connected AP) + ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_CONNECTION,SL_CONNECTION_POLICY(1, 1, 0, 0, 0), NULL, 0)); + } - // start the servers before returning - wlan_servers_start(); + // set current time and date (needed to validate certificates) + wlan_set_current_time (pybrtc_get_seconds()); - return MODWLAN_OK; - } - return MODWLAN_ERROR_INVALID_PARAMS; + // start the servers before returning + wlan_servers_start(); } void wlan_update(void) { @@ -553,6 +542,7 @@ void wlan_stop (uint32_t timeout) { wlan_servers_stop(); sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER); sl_Stop(timeout); + wlan_clear_data(); wlan_obj.mode = -1; } @@ -575,8 +565,8 @@ void wlan_get_ip (uint32_t *ip) { } bool wlan_is_connected (void) { - return ((GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION) && - GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED)) || wlan_obj.staconnected); + return (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION) && + (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED) || wlan_obj.mode != ROLE_STA)); } void wlan_set_current_time (uint32_t seconds_since_2000) { @@ -597,14 +587,9 @@ void wlan_set_current_time (uint32_t seconds_since_2000) { // DEFINE STATIC FUNCTIONS //***************************************************************************** -STATIC void wlan_initialize_data (void) { +STATIC void wlan_clear_data (void) { CLR_STATUS_BIT_ALL(wlan_obj.status); - wlan_obj.dns = 0; - wlan_obj.gateway = 0; wlan_obj.ip = 0; - wlan_obj.security = SL_SEC_TYPE_OPEN; - wlan_obj.staconnected = false; - memset(wlan_obj.ssid, 0, sizeof(wlan_obj.ssid)); memset(wlan_obj.ssid_o, 0, sizeof(wlan_obj.ssid)); memset(wlan_obj.bssid, 0, sizeof(wlan_obj.bssid)); } @@ -613,8 +598,7 @@ STATIC void wlan_reenable (SlWlanMode_t mode) { // stop and start again sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER); sl_Stop(SL_STOP_TIMEOUT); - CLR_STATUS_BIT_ALL(wlan_obj.status); - wlan_obj.staconnected = false; + wlan_clear_data(); wlan_obj.mode = sl_Start(0, 0, 0); sl_LockObjUnlock (&wlan_LockObj); ASSERT (wlan_obj.mode == mode); @@ -667,7 +651,7 @@ STATIC void wlan_get_sl_mac (void) { sl_NetCfgGet(SL_MAC_ADDRESS_GET, NULL, &macAddrLen, wlan_obj.mac); } -/// \method init(mode, ssid=None, *, security=wlan.OPEN, key=None, channel=5) +/// \method iwconfig(*, mode, ssid, security, key, channel, antenna) /// /// Initialise the WLAN engine with the given parameters: /// @@ -676,39 +660,103 @@ STATIC void wlan_get_sl_mac (void) { /// - `security` is the security type for AP mode /// - `key` is the key when in AP mode /// - `channel` is the channel to use for the AP network -STATIC const mp_arg_t wlan_init_args[] = { - { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = ROLE_STA} }, - { MP_QSTR_ssid, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SL_SEC_TYPE_OPEN} }, - { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5} }, +/// - `antenna` selects between the internal or the external one +STATIC const mp_arg_t wlan_iwconfig_args[] = { + { MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_ssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_antenna, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; -STATIC mp_obj_t wlan_init_helper(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t wlan_iwconfig(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(wlan_init_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(wlan_init_args), wlan_init_args, args); + mp_arg_val_t args[MP_ARRAY_SIZE(wlan_iwconfig_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(wlan_iwconfig_args), wlan_iwconfig_args, args); + + bool config = false; + // all params are kw only, so check 'em one by one + if (args[0].u_obj != MP_OBJ_NULL) { + int8_t mode = mp_obj_get_int(args[0].u_obj); + if (mode != ROLE_AP && mode != ROLE_STA && mode != ROLE_P2P) { + goto arg_error; + } + wlan_obj.mode = mode; + config = true; + } + if (args[1].u_obj != MP_OBJ_NULL) { + // get the ssid + mp_uint_t ssid_len; + const char *ssid = mp_obj_str_get_data(args[1].u_obj, &ssid_len); + if (ssid_len > 32) { + goto arg_error; + } + memcpy (wlan_obj.ssid, ssid, ssid_len); + wlan_obj.ssid[ssid_len] = '\0'; + config = true; + } + if (args[2].u_obj != MP_OBJ_NULL) { + int8_t security = mp_obj_get_int(args[2].u_obj); + if (security != SL_SEC_TYPE_OPEN && security != SL_SEC_TYPE_WEP && security != SL_SEC_TYPE_WPA_WPA2) { + goto arg_error; + } + wlan_obj.security = security; + config = true; + } + if (args[3].u_obj != MP_OBJ_NULL) { + // get the key + mp_uint_t key_len; + const char *key = mp_obj_str_get_data(args[3].u_obj, &key_len); + if (key_len < 5 || key_len > 64) { + goto arg_error; + } + memcpy (wlan_obj.key, key, key_len); + wlan_obj.key[key_len] = '\0'; + config = true; + } + if (args[4].u_obj != MP_OBJ_NULL) { + int8_t channel = mp_obj_get_int(args[4].u_obj); + if (channel < 1 || channel > 11) { + goto arg_error; + } + wlan_obj.channel = channel; + config = true; + } - // get the ssid - mp_uint_t ssid_len; - const char *ssid = mp_obj_str_get_data(args[1].u_obj, &ssid_len); - if (ssid_len > 32) { - goto arg_error; + if (config) { + wlan_sl_enable (wlan_obj.mode, (const char *)wlan_obj.ssid, strlen((const char *)wlan_obj.ssid), wlan_obj.security, + (const char *)wlan_obj.key, strlen((const char *)wlan_obj.key), wlan_obj.channel, false); } - // get the key - mp_uint_t key_len; - const char *key = mp_obj_str_get_data(args[3].u_obj, &key_len); - if (key_len < 8) { - goto arg_error; + if (args[5].u_obj != MP_OBJ_NULL) { + #if MICROPY_HW_ANTENNA_DIVERSITY + int8_t antenna = mp_obj_get_int(args[5].u_obj); + if (antenna != ANTENNA_TYPE_INTERNAL && antenna != ANTENNA_TYPE_EXTERNAL) { + goto arg_error; + } + wlan_obj.antenna = antenna; + antenna_select (antenna); + #endif + config = true; } - // force the channel to be between 1-11 - uint8_t channel = args[4].u_int; - channel = (channel > 0 && channel != 12) ? channel % 12 : 1; + if (!config) { + // return the current configuration + STATIC const qstr iwconfig_fields[] = { + MP_QSTR_mode, MP_QSTR_ssid, + MP_QSTR_security, MP_QSTR_key, + MP_QSTR_channel, MP_QSTR_antenna + }; - if (MODWLAN_OK != wlan_sl_enable (args[0].u_int, ssid, ssid_len, args[2].u_int, key, key_len, channel, false)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + mp_obj_t iwconfig[6]; + iwconfig[0] = mp_obj_new_int(wlan_obj.mode); + iwconfig[1] = mp_obj_new_str((const char *)wlan_obj.ssid, strlen((const char *)wlan_obj.ssid), false); + iwconfig[2] = mp_obj_new_int(wlan_obj.security); + iwconfig[3] = mp_obj_new_str((const char *)wlan_obj.key, strlen((const char *)wlan_obj.key), false); + iwconfig[4] = mp_obj_new_int(wlan_obj.channel); + iwconfig[5] = mp_obj_new_int(wlan_obj.antenna); + return mp_obj_new_attrtuple(iwconfig_fields, MP_ARRAY_SIZE(iwconfig), iwconfig); } return mp_const_none; @@ -716,6 +764,7 @@ STATIC mp_obj_t wlan_init_helper(mp_uint_t n_args, const mp_obj_t *pos_args, mp_ arg_error: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_iwconfig_obj, 1, wlan_iwconfig); STATIC void wlan_lpds_callback_enable (mp_obj_t self_in) { mp_obj_t _callback = mpcallback_find(self_in); @@ -740,36 +789,19 @@ STATIC bool wlan_scan_result_is_unique (const mp_obj_list_t *nets, _u8 *bssid) { /******************************************************************************/ // Micro Python bindings; WLAN class -/// \class WLAN - driver for the WLAN functionality of the SoC +/// \class WLAN - WiFi driver /// \classmethod \constructor() -/// Create a wlan obecjt and initialise the simplelink engine -// +/// Create a wlan object. See iwconfig for parameters of initialization. STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { // check arguments - mp_arg_check_num(n_args, n_kw, 0, MP_ARRAY_SIZE(wlan_init_args), true); - - if (n_args > 0) { - // get the mode - SlWlanMode_t mode = mp_obj_get_int(args[0]); - if (mode == ROLE_AP) { - // start the peripheral - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - wlan_init_helper(n_args, args, &kw_args); - } - // TODO only STA mode supported for the moment. What if P2P? - else if (n_args == 1) { - if (MODWLAN_OK != wlan_sl_enable (mode, NULL, 0, 0, NULL, 0, 0, false)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); - } - } - else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments)); - } - } - + mp_arg_check_num(n_args, n_kw, 0, MP_ARRAY_SIZE(wlan_iwconfig_args), true); wlan_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wlan; + if (n_kw > 0) { + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args); + wlan_iwconfig(1, (const mp_obj_t *)&wlan_obj, &kw_args); + } return &wlan_obj; } @@ -977,7 +1009,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_urn_obj, 1, 2, wlan_urn); #endif /// \method wlan_netlist() -/// Return a list of tuples with all the acces points within range +/// Return a list of tuples with all the access points within range STATIC mp_obj_t wlan_scan(mp_obj_t self_in) { STATIC const qstr wlan_scan_info_fields[] = { MP_QSTR_ssid, MP_QSTR_bssid, @@ -1032,7 +1064,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_scan_obj, wlan_scan); /// \method callback(handler, pwrmode) /// Create a callback object associated with WLAN -/// min num of arguments is 1 (pwrmode) +/// min num of arguments is 1 (wakes) STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_arg_val_t args[mpcallback_INIT_NUM_ARGS]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args); @@ -1057,23 +1089,12 @@ STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_callback_obj, 1, wlan_callback); -/// \method info() -/// returns (mode, ssid, security, mac) -STATIC mp_obj_t wlan_info (mp_obj_t self_in) { - STATIC const qstr wlan_info_fields[] = { - MP_QSTR_mode, MP_QSTR_ssid, - MP_QSTR_security, MP_QSTR_mac - }; - - mp_obj_t wlan_info[4]; - wlan_info[0] = mp_obj_new_int(wlan_obj.mode); - wlan_info[1] = wlan_obj.mode != ROLE_STA ? - mp_obj_new_str((const char *)wlan_obj.ssid, strlen((const char *)wlan_obj.ssid), false) : MP_OBJ_NEW_QSTR(MP_QSTR_); - wlan_info[2] = mp_obj_new_int(wlan_obj.security); - wlan_info[3] = mp_obj_new_bytes((const byte *)wlan_obj.mac, SL_BSSID_LENGTH); - return mp_obj_new_attrtuple(wlan_info_fields, MP_ARRAY_SIZE(wlan_info), wlan_info); +/// \method mac() +/// returns the MAC address +STATIC mp_obj_t wlan_mac (mp_obj_t self_in) { + return mp_obj_new_bytes((const byte *)wlan_obj.mac, SL_BSSID_LENGTH); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_info_obj, wlan_info); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_mac_obj, wlan_mac); /// \method connections() /// returns (ssid/name, bssi), name is the P2P name if in this mode @@ -1091,52 +1112,29 @@ STATIC mp_obj_t wlan_connections (mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_connections_obj, wlan_connections); -#if MICROPY_HW_ANTENNA_DIVERSITY -/// \method antenna() -/// select the antenna type to use (internal or external) -STATIC mp_obj_t wlan_antenna (mp_obj_t self_in, mp_obj_t antenna_o) { - antenna_type_t _antenna = mp_obj_get_int(antenna_o); - - if (_antenna != ANTENNA_TYPE_INTERNAL && _antenna != ANTENNA_TYPE_EXTERNAL) { - // invalid antenna type - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); - } - - antenna_select (_antenna); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(wlan_antenna_obj, wlan_antenna); -#endif - STATIC const mp_map_elem_t wlan_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&wlan_connect_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_iwconfig), (mp_obj_t)&wlan_iwconfig_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&wlan_scan_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&wlan_connect_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_disconnect), (mp_obj_t)&wlan_disconnect_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_isconnected), (mp_obj_t)&wlan_isconnected_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_ifconfig), (mp_obj_t)&wlan_ifconfig_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&wlan_info_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mac), (mp_obj_t)&wlan_mac_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_connections), (mp_obj_t)&wlan_connections_obj }, -#if MICROPY_HW_ANTENNA_DIVERSITY - { MP_OBJ_NEW_QSTR(MP_QSTR_antenna), (mp_obj_t)&wlan_antenna_obj }, -#endif #if MICROPY_PORT_WLAN_URN { MP_OBJ_NEW_QSTR(MP_QSTR_urn), (mp_obj_t)&wlan_urn_obj }, #endif { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&wlan_callback_obj }, // class constants - { MP_OBJ_NEW_QSTR(MP_QSTR_OPEN), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_OPEN) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WEP), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WEP) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WPA_WPA2), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WPA_WPA2) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WPA_ENT), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WPA_ENT) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WPS_PBC), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WPS_PBC) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WPS_PIN), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WPS_PIN) }, { MP_OBJ_NEW_QSTR(MP_QSTR_STA), MP_OBJ_NEW_SMALL_INT(ROLE_STA) }, { MP_OBJ_NEW_QSTR(MP_QSTR_AP), MP_OBJ_NEW_SMALL_INT(ROLE_AP) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_P2P), MP_OBJ_NEW_SMALL_INT(ROLE_P2P) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_INT_ANTENNA), MP_OBJ_NEW_SMALL_INT(ANTENNA_TYPE_INTERNAL) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_EXT_ANTENNA), MP_OBJ_NEW_SMALL_INT(ANTENNA_TYPE_EXTERNAL) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_OPEN), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_OPEN) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WEP), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WEP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WPA), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WPA_WPA2) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WPA2), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_WPA_WPA2) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_INTERNAL), MP_OBJ_NEW_SMALL_INT(ANTENNA_TYPE_INTERNAL) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EXTERNAL), MP_OBJ_NEW_SMALL_INT(ANTENNA_TYPE_EXTERNAL) }, }; STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table); diff --git a/cc3200/mods/modwlan.h b/cc3200/mods/modwlan.h index 5d8ca893d4..6693209d71 100644 --- a/cc3200/mods/modwlan.h +++ b/cc3200/mods/modwlan.h @@ -43,7 +43,7 @@ typedef enum { MODWLAN_ERROR_INVALID_PARAMS = -1, MODWLAN_ERROR_TIMEOUT = -2, MODWLAN_ERROR_UNKNOWN = -3, -}modwlan_Status_t; +} modwlan_Status_t; /****************************************************************************** DECLARE PUBLIC DATA @@ -54,8 +54,8 @@ extern _SlLockObj_t wlan_LockObj; DECLARE PUBLIC FUNCTIONS ******************************************************************************/ extern void wlan_pre_init (void); -extern modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ssid_len, uint8_t sec, - const char *key, uint8_t key_len, uint8_t channel, bool append_mac); +extern void wlan_sl_enable (int8_t mode, const char *ssid, uint8_t ssid_len, uint8_t sec, + const char *key, uint8_t key_len, uint8_t channel, bool append_mac); extern void wlan_first_start (void); extern void wlan_update(void); extern void wlan_stop (uint32_t timeout); diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h index feda980ee0..c67c9064d8 100644 --- a/cc3200/qstrdefsport.h +++ b/cc3200/qstrdefsport.h @@ -264,6 +264,7 @@ Q(server_timeout) // for WLAN class Q(WLAN) +Q(iwconfig) Q(key) Q(security) Q(ssid) @@ -277,7 +278,9 @@ Q(rssi) Q(ifconfig) Q(info) Q(connections) +#if MICROPY_PORT_WLAN_URN Q(urn) +#endif Q(mode) Q(ip) Q(subnet) @@ -287,15 +290,12 @@ Q(mac) Q(antenna) Q(STA) Q(AP) -Q(P2P) Q(OPEN) Q(WEP) -Q(WPA_WPA2) -Q(WPA_ENT) -Q(WPS_PBC) -Q(WPS_PIN) -Q(INT_ANTENNA) -Q(EXT_ANTENNA) +Q(WPA) +Q(WPA2) +Q(INTERNAL) +Q(EXTERNAL) // for WDT class Q(WDT) diff --git a/docs/library/network.rst b/docs/library/network.rst index adea373842..8957b263c8 100644 --- a/docs/library/network.rst +++ b/docs/library/network.rst @@ -242,8 +242,8 @@ class WLAN import network # setup as a station - nic = network.WLAN(WLAN.STA) - nic.connect('your-ssid', security=WLAN.WPA_WPA2, key='your-key') + nic = network.WLAN(mode=WLAN.STA) + nic.connect('your-ssid', security=WLAN.WPA2, key='your-key') while not nic.isconnected(): pyb.delay(50) print(nic.ifconfig()) @@ -254,33 +254,42 @@ class WLAN Constructors ------------ - .. class:: WLAN(mode, ssid, \*, security=WLAN.OPEN, key=None, channel=5) + .. class:: WLAN(..) + + Create a WLAN object, and optionally configure it. See ``iwconfig`` for params of configuration. + + Methods + ------- + + .. method:: iwconfig(\*, mode, ssid, security, key, channel, antenna) - Create a WLAN driver object, initialise the WLAN engine in station or AP mode. + Set or get the WiFi network processor configuration. Arguments are: - ``mode`` can be either ``WLAN.STA`` or ``WLAN.AP``. - ``ssid`` is a string with the ssid name. Only needed when mode is ``WLAN.AP``. - - ``security`` can be ``WLAN.OPEN``, ``WLAN.WEP`` or ``WLAN.WPA_WPA2``. + - ``security`` can be ``WLAN.OPEN``, ``WLAN.WEP``, ``WLAN.WPA`` or ``WLAN.WPA2``. Only needed when mode is ``WLAN.AP``. - - ``key`` is a string with the ``WLAN.WPA_WPA2`` key or a byte array with the - ``WLAN.WEP`` key. Not needed when mode is ``WLAN.STA`` or security is ``WLAN.OPEN``. + - ``key`` is a string with the network password. Not needed when mode is ``WLAN.STA`` + or security is ``WLAN.OPEN``. - ``channel`` a number in the range 1-11. Only needed when mode is ``WLAN.AP``. + - ``antenna`` selects between the internal and the external antenna. Can be either + ``WLAN.INTERNAL`` or ``WLAN.EXTERNAL``. - For example, you can use:: + For example, you can do:: - # configure as an access point - nic = network.WLAN(WLAN.AP, 'wipy-wlan', security=WLAN.WPA_WPA2, key='www.wipy.io', channel=7) + # create and configure as an access point + nic.iwconfig(mode=WLAN.AP, ssid='wipy-wlan', security=WLAN.WPA2, key='www.wipy.io', channel=7, antenna=WLAN.INTERNAL) or:: # configure as an station - nic = network.WLAN(WLAN.STA) - - Methods - ------- - + nic.iwconfig(mode=WLAN.STA) + + With no arguments given, the current configuration is returned as a namedtuple that looks like this: + ``(mode=2, ssid='wipy-wlan', security=2, key='www.wipy.io', channel=5, antenna=0)`` + .. method:: wlan.connect(ssid, \*, security=WLAN.OPEN, key=None, bssid=None, timeout=5000) Connect to a wifi access point using the given SSID, and other security @@ -301,8 +310,8 @@ class WLAN .. method:: wlan.isconnected() - Returns True if connected to a wifi access point and has a valid IP address, - False otherwise. + In case of STA mode, returns ``True`` if connected to a wifi access point and has a valid IP address. + In AP mode returns ``True`` when a station is connected. Returns ``False`` otherwise. .. method:: wlan.ifconfig(['dhcp' or configtuple]) @@ -315,25 +324,14 @@ class WLAN nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8')) - .. method:: wlan.info() - - Provides information about the current WLAN configuration. Returns a named tuple - of (mode, ssid, security, mac) - - - ``mode`` can be either ``WLAN.STA`` or ``WLAN.AP``. - - ``ssid`` is a string with our ssid if in AP mode, ``None`` oterwise. - - ``security`` security type currently used. - - ``mac`` our MAC address. + .. method:: wlan.mac() + Returns a 6-byte long bytes object with the MAC address. + .. method:: wlan.connections() Returns a list of the devices currently connected. Each item in the list is a tuple of ``(ssid, mac)``. - - .. method:: wlan.antenna(antenna_type) - - Selects the antenna type to be used. Must be either ``WLAN.INT_ANTENNA`` or - ``WLAN.EXT_ANTENNA``. .. method:: wlan.callback(wakes) @@ -348,29 +346,21 @@ class WLAN --------- .. data:: WLAN.STA - + WiFi station mode - + .. data:: WLAN.AP WiFi access point mode .. data:: WLAN.OPEN - - open network (no security) - .. data:: WLAN.WEP - - WEP network security - - .. data:: WLAN.WPA_WPA2 - - WPA/WPA2 network security + .. data:: WLAN.WPA + .. data:: WLAN.WPA2 - .. data:: WLAN.INT_ANTENNA - - selects the internal antenna - - .. data:: WLAN.EXT_ANTENNA + selects the network security + + .. data:: WLAN.INTERNAL + .. data:: WLAN.EXTERNAL - selects the external antenna + selects the antenna type |