modwlan.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2015 Daniel Campora
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdint.h>
  27. #include <stdbool.h>
  28. #include <stdio.h>
  29. #include "simplelink.h"
  30. #include "py/mpconfig.h"
  31. #include "py/obj.h"
  32. #include "py/objstr.h"
  33. #include "py/runtime.h"
  34. #include "py/stream.h"
  35. #include "py/mphal.h"
  36. #include "lib/timeutils/timeutils.h"
  37. #include "lib/netutils/netutils.h"
  38. #include "modnetwork.h"
  39. #include "modusocket.h"
  40. #include "modwlan.h"
  41. #include "pybrtc.h"
  42. #include "debug.h"
  43. #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
  44. #include "serverstask.h"
  45. #endif
  46. #include "mpexception.h"
  47. #include "mpirq.h"
  48. #include "pybsleep.h"
  49. #include "antenna.h"
  50. /******************************************************************************
  51. DEFINE TYPES
  52. ******************************************************************************/
  53. // Status bits - These are used to set/reset the corresponding bits in a given variable
  54. typedef enum{
  55. STATUS_BIT_NWP_INIT = 0, // If this bit is set: Network Processor is
  56. // powered up
  57. STATUS_BIT_CONNECTION, // If this bit is set: the device is connected to
  58. // the AP or client is connected to device (AP)
  59. STATUS_BIT_IP_LEASED, // If this bit is set: the device has leased IP to
  60. // any connected client
  61. STATUS_BIT_IP_ACQUIRED, // If this bit is set: the device has acquired an IP
  62. STATUS_BIT_SMARTCONFIG_START, // If this bit is set: the SmartConfiguration
  63. // process is started from SmartConfig app
  64. STATUS_BIT_P2P_DEV_FOUND, // If this bit is set: the device (P2P mode)
  65. // found any p2p-device in scan
  66. STATUS_BIT_P2P_REQ_RECEIVED, // If this bit is set: the device (P2P mode)
  67. // found any p2p-negotiation request
  68. STATUS_BIT_CONNECTION_FAILED, // If this bit is set: the device(P2P mode)
  69. // connection to client(or reverse way) is failed
  70. STATUS_BIT_PING_DONE // If this bit is set: the device has completed
  71. // the ping operation
  72. } e_StatusBits;
  73. /******************************************************************************
  74. DEFINE CONSTANTS
  75. ******************************************************************************/
  76. #define CLR_STATUS_BIT_ALL(status) (status = 0)
  77. #define SET_STATUS_BIT(status, bit) (status |= ( 1 << (bit)))
  78. #define CLR_STATUS_BIT(status, bit) (status &= ~(1 << (bit)))
  79. #define GET_STATUS_BIT(status, bit) (0 != (status & (1 << (bit))))
  80. #define IS_NW_PROCSR_ON(status) GET_STATUS_BIT(status, STATUS_BIT_NWP_INIT)
  81. #define IS_CONNECTED(status) GET_STATUS_BIT(status, STATUS_BIT_CONNECTION)
  82. #define IS_IP_LEASED(status) GET_STATUS_BIT(status, STATUS_BIT_IP_LEASED)
  83. #define IS_IP_ACQUIRED(status) GET_STATUS_BIT(status, STATUS_BIT_IP_ACQUIRED)
  84. #define IS_SMART_CFG_START(status) GET_STATUS_BIT(status, STATUS_BIT_SMARTCONFIG_START)
  85. #define IS_P2P_DEV_FOUND(status) GET_STATUS_BIT(status, STATUS_BIT_P2P_DEV_FOUND)
  86. #define IS_P2P_REQ_RCVD(status) GET_STATUS_BIT(status, STATUS_BIT_P2P_REQ_RECEIVED)
  87. #define IS_CONNECT_FAILED(status) GET_STATUS_BIT(status, STATUS_BIT_CONNECTION_FAILED)
  88. #define IS_PING_DONE(status) GET_STATUS_BIT(status, STATUS_BIT_PING_DONE)
  89. #define MODWLAN_SL_SCAN_ENABLE 1
  90. #define MODWLAN_SL_SCAN_DISABLE 0
  91. #define MODWLAN_SL_MAX_NETWORKS 20
  92. #define MODWLAN_MAX_NETWORKS 20
  93. #define MODWLAN_SCAN_PERIOD_S 3600 // 1 hour
  94. #define MODWLAN_WAIT_FOR_SCAN_MS 1050
  95. #define MODWLAN_CONNECTION_WAIT_MS 2
  96. #define ASSERT_ON_ERROR(x) ASSERT((x) >= 0)
  97. /******************************************************************************
  98. DECLARE PRIVATE DATA
  99. ******************************************************************************/
  100. STATIC wlan_obj_t wlan_obj = {
  101. .mode = -1,
  102. .status = 0,
  103. .ip = 0,
  104. .auth = MICROPY_PORT_WLAN_AP_SECURITY,
  105. .channel = MICROPY_PORT_WLAN_AP_CHANNEL,
  106. .ssid = MICROPY_PORT_WLAN_AP_SSID,
  107. .key = MICROPY_PORT_WLAN_AP_KEY,
  108. .mac = {0},
  109. //.ssid_o = {0},
  110. //.bssid = {0},
  111. #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
  112. .servers_enabled = false,
  113. #endif
  114. };
  115. STATIC const mp_irq_methods_t wlan_irq_methods;
  116. /******************************************************************************
  117. DECLARE PUBLIC DATA
  118. ******************************************************************************/
  119. #ifdef SL_PLATFORM_MULTI_THREADED
  120. OsiLockObj_t wlan_LockObj;
  121. #endif
  122. /******************************************************************************
  123. DECLARE PRIVATE FUNCTIONS
  124. ******************************************************************************/
  125. STATIC void wlan_clear_data (void);
  126. STATIC void wlan_reenable (SlWlanMode_t mode);
  127. STATIC void wlan_servers_start (void);
  128. STATIC void wlan_servers_stop (void);
  129. STATIC void wlan_reset (void);
  130. STATIC void wlan_validate_mode (uint mode);
  131. STATIC void wlan_set_mode (uint mode);
  132. STATIC void wlan_validate_ssid_len (uint32_t len);
  133. STATIC void wlan_set_ssid (const char *ssid, uint8_t len, bool add_mac);
  134. STATIC void wlan_validate_security (uint8_t auth, const char *key, uint8_t len);
  135. STATIC void wlan_set_security (uint8_t auth, const char *key, uint8_t len);
  136. STATIC void wlan_validate_channel (uint8_t channel);
  137. STATIC void wlan_set_channel (uint8_t channel);
  138. #if MICROPY_HW_ANTENNA_DIVERSITY
  139. STATIC void wlan_validate_antenna (uint8_t antenna);
  140. STATIC void wlan_set_antenna (uint8_t antenna);
  141. #endif
  142. STATIC void wlan_sl_disconnect (void);
  143. STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec,
  144. const char* key, uint32_t key_len, int32_t timeout);
  145. STATIC void wlan_get_sl_mac (void);
  146. STATIC void wlan_wep_key_unhexlify (const char *key, char *key_out);
  147. STATIC void wlan_lpds_irq_enable (mp_obj_t self_in);
  148. STATIC void wlan_lpds_irq_disable (mp_obj_t self_in);
  149. STATIC bool wlan_scan_result_is_unique (const mp_obj_list_t *nets, _u8 *bssid);
  150. //*****************************************************************************
  151. //
  152. //! \brief The Function Handles WLAN Events
  153. //!
  154. //! \param[in] pWlanEvent - Pointer to WLAN Event Info
  155. //!
  156. //! \return None
  157. //!
  158. //*****************************************************************************
  159. void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) {
  160. if (!pWlanEvent) {
  161. return;
  162. }
  163. switch(pWlanEvent->Event)
  164. {
  165. case SL_WLAN_CONNECT_EVENT:
  166. {
  167. //slWlanConnectAsyncResponse_t *pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected;
  168. // copy the new connection data
  169. //memcpy(wlan_obj.bssid, pEventData->bssid, SL_BSSID_LENGTH);
  170. //memcpy(wlan_obj.ssid_o, pEventData->ssid_name, pEventData->ssid_len);
  171. //wlan_obj.ssid_o[pEventData->ssid_len] = '\0';
  172. SET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION);
  173. #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
  174. // we must reset the servers in case that the last connection
  175. // was lost without any notification being received
  176. servers_reset();
  177. #endif
  178. }
  179. break;
  180. case SL_WLAN_DISCONNECT_EVENT:
  181. CLR_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION);
  182. CLR_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED);
  183. #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
  184. servers_reset();
  185. servers_wlan_cycle_power();
  186. #endif
  187. break;
  188. case SL_WLAN_STA_CONNECTED_EVENT:
  189. {
  190. //slPeerInfoAsyncResponse_t *pEventData = &pWlanEvent->EventData.APModeStaConnected;
  191. // get the mac address and name of the connected device
  192. //memcpy(wlan_obj.bssid, pEventData->mac, SL_BSSID_LENGTH);
  193. //memcpy(wlan_obj.ssid_o, pEventData->go_peer_device_name, pEventData->go_peer_device_name_len);
  194. //wlan_obj.ssid_o[pEventData->go_peer_device_name_len] = '\0';
  195. SET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION);
  196. #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
  197. // we must reset the servers in case that the last connection
  198. // was lost without any notification being received
  199. servers_reset();
  200. #endif
  201. }
  202. break;
  203. case SL_WLAN_STA_DISCONNECTED_EVENT:
  204. CLR_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION);
  205. #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
  206. servers_reset();
  207. servers_wlan_cycle_power();
  208. #endif
  209. break;
  210. case SL_WLAN_P2P_DEV_FOUND_EVENT:
  211. // TODO
  212. break;
  213. case SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT:
  214. // TODO
  215. break;
  216. case SL_WLAN_CONNECTION_FAILED_EVENT:
  217. // TODO
  218. break;
  219. default:
  220. break;
  221. }
  222. }
  223. //*****************************************************************************
  224. //
  225. //! \brief This function handles network events such as IP acquisition, IP
  226. //! leased, IP released etc.
  227. //!
  228. //! \param[in] pNetAppEvent - Pointer to NetApp Event Info
  229. //!
  230. //! \return None
  231. //!
  232. //*****************************************************************************
  233. void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) {
  234. if(!pNetAppEvent) {
  235. return;
  236. }
  237. switch(pNetAppEvent->Event)
  238. {
  239. case SL_NETAPP_IPV4_IPACQUIRED_EVENT:
  240. {
  241. SlIpV4AcquiredAsync_t *pEventData = NULL;
  242. SET_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED);
  243. // Ip Acquired Event Data
  244. pEventData = &pNetAppEvent->EventData.ipAcquiredV4;
  245. // Get the ip
  246. wlan_obj.ip = pEventData->ip;
  247. }
  248. break;
  249. case SL_NETAPP_IPV6_IPACQUIRED_EVENT:
  250. break;
  251. case SL_NETAPP_IP_LEASED_EVENT:
  252. break;
  253. case SL_NETAPP_IP_RELEASED_EVENT:
  254. break;
  255. default:
  256. break;
  257. }
  258. }
  259. //*****************************************************************************
  260. //
  261. //! \brief This function handles HTTP server events
  262. //!
  263. //! \param[in] pServerEvent - Contains the relevant event information
  264. //! \param[in] pServerResponse - Should be filled by the user with the
  265. //! relevant response information
  266. //!
  267. //! \return None
  268. //!
  269. //****************************************************************************
  270. void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerResponse_t *pHttpResponse) {
  271. if (!pHttpEvent) {
  272. return;
  273. }
  274. switch (pHttpEvent->Event) {
  275. case SL_NETAPP_HTTPGETTOKENVALUE_EVENT:
  276. break;
  277. case SL_NETAPP_HTTPPOSTTOKENVALUE_EVENT:
  278. break;
  279. default:
  280. break;
  281. }
  282. }
  283. //*****************************************************************************
  284. //
  285. //! \brief This function handles General Events
  286. //!
  287. //! \param[in] pDevEvent - Pointer to General Event Info
  288. //!
  289. //! \return None
  290. //!
  291. //*****************************************************************************
  292. void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent) {
  293. if (!pDevEvent) {
  294. return;
  295. }
  296. }
  297. //*****************************************************************************
  298. //
  299. //! This function handles socket events indication
  300. //!
  301. //! \param[in] pSock - Pointer to Socket Event Info
  302. //!
  303. //! \return None
  304. //!
  305. //*****************************************************************************
  306. void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) {
  307. if (!pSock) {
  308. return;
  309. }
  310. switch( pSock->Event ) {
  311. case SL_SOCKET_TX_FAILED_EVENT:
  312. switch( pSock->socketAsyncEvent.SockTxFailData.status) {
  313. case SL_ECLOSE:
  314. break;
  315. default:
  316. break;
  317. }
  318. break;
  319. case SL_SOCKET_ASYNC_EVENT:
  320. switch(pSock->socketAsyncEvent.SockAsyncData.type) {
  321. case SSL_ACCEPT:
  322. break;
  323. case RX_FRAGMENTATION_TOO_BIG:
  324. break;
  325. case OTHER_SIDE_CLOSE_SSL_DATA_NOT_ENCRYPTED:
  326. break;
  327. default:
  328. break;
  329. }
  330. break;
  331. default:
  332. break;
  333. }
  334. }
  335. //*****************************************************************************
  336. // SimpleLink Asynchronous Event Handlers -- End
  337. //*****************************************************************************
  338. __attribute__ ((section (".boot")))
  339. void wlan_pre_init (void) {
  340. // create the wlan lock
  341. #ifdef SL_PLATFORM_MULTI_THREADED
  342. ASSERT(OSI_OK == sl_LockObjCreate(&wlan_LockObj, "WlanLock"));
  343. #endif
  344. }
  345. void wlan_first_start (void) {
  346. if (wlan_obj.mode < 0) {
  347. CLR_STATUS_BIT_ALL(wlan_obj.status);
  348. wlan_obj.mode = sl_Start(0, 0, 0);
  349. #ifdef SL_PLATFORM_MULTI_THREADED
  350. sl_LockObjUnlock (&wlan_LockObj);
  351. #endif
  352. }
  353. // get the mac address
  354. wlan_get_sl_mac();
  355. }
  356. void wlan_sl_init (int8_t mode, const char *ssid, uint8_t ssid_len, uint8_t auth, const char *key, uint8_t key_len,
  357. uint8_t channel, uint8_t antenna, bool add_mac) {
  358. // stop the servers
  359. wlan_servers_stop();
  360. // do a basic start
  361. wlan_first_start();
  362. // close any active connections
  363. wlan_sl_disconnect();
  364. // Remove all profiles
  365. ASSERT_ON_ERROR(sl_WlanProfileDel(0xFF));
  366. // Enable the DHCP client
  367. uint8_t value = 1;
  368. ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE, 1, 1, &value));
  369. // Set PM policy to normal
  370. ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_PM, SL_NORMAL_POLICY, NULL, 0));
  371. // Unregister mDNS services
  372. ASSERT_ON_ERROR(sl_NetAppMDNSUnRegisterService(0, 0));
  373. // Stop the internal HTTP server
  374. sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID);
  375. // Remove all 64 filters (8 * 8)
  376. _WlanRxFilterOperationCommandBuff_t RxFilterIdMask;
  377. memset ((void *)&RxFilterIdMask, 0 ,sizeof(RxFilterIdMask));
  378. memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
  379. ASSERT_ON_ERROR(sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask, sizeof(_WlanRxFilterOperationCommandBuff_t)));
  380. #if MICROPY_HW_ANTENNA_DIVERSITY
  381. // set the antenna type
  382. wlan_set_antenna (antenna);
  383. #endif
  384. // switch to the requested mode
  385. wlan_set_mode(mode);
  386. // stop and start again (we need to in the propper mode from now on)
  387. wlan_reenable(mode);
  388. // Set Tx power level for station or AP mode
  389. // Number between 0-15, as dB offset from max power - 0 will set max power
  390. uint8_t ucPower = 0;
  391. if (mode == ROLE_AP) {
  392. ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_AP_TX_POWER, sizeof(ucPower),
  393. (unsigned char *)&ucPower));
  394. // configure all parameters
  395. wlan_set_ssid (ssid, ssid_len, add_mac);
  396. wlan_set_security (auth, key, key_len);
  397. wlan_set_channel (channel);
  398. // set the country
  399. _u8* country = (_u8*)"EU";
  400. ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE, 2, country));
  401. SlNetCfgIpV4Args_t ipV4;
  402. ipV4.ipV4 = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 IP address
  403. ipV4.ipV4Mask = (_u32)SL_IPV4_VAL(255,255,255,0); // _u32 Subnet mask for this AP
  404. ipV4.ipV4Gateway = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 Default gateway address
  405. ipV4.ipV4DnsServer = (_u32)SL_IPV4_VAL(192,168,1,1); // _u32 DNS server address
  406. ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4,
  407. sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4));
  408. SlNetAppDhcpServerBasicOpt_t dhcpParams;
  409. dhcpParams.lease_time = 4096; // lease time (in seconds) of the IP Address
  410. dhcpParams.ipv4_addr_start = SL_IPV4_VAL(192,168,1,2); // first IP Address for allocation.
  411. dhcpParams.ipv4_addr_last = SL_IPV4_VAL(192,168,1,254); // last IP Address for allocation.
  412. ASSERT_ON_ERROR(sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID)); // Stop DHCP server before settings
  413. ASSERT_ON_ERROR(sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT,
  414. sizeof(SlNetAppDhcpServerBasicOpt_t), (_u8* )&dhcpParams)); // set parameters
  415. ASSERT_ON_ERROR(sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID)); // Start DHCP server with new settings
  416. // stop and start again
  417. wlan_reenable(mode);
  418. } else { // STA and P2P modes
  419. ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER,
  420. sizeof(ucPower), (unsigned char *)&ucPower));
  421. // set connection policy to Auto + Fast (tries to connect to the last connected AP)
  422. ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 1, 0, 0, 0), NULL, 0));
  423. }
  424. // set current time and date (needed to validate certificates)
  425. wlan_set_current_time (pyb_rtc_get_seconds());
  426. // start the servers before returning
  427. wlan_servers_start();
  428. }
  429. void wlan_update(void) {
  430. #ifndef SL_PLATFORM_MULTI_THREADED
  431. _SlTaskEntry();
  432. #endif
  433. }
  434. void wlan_stop (uint32_t timeout) {
  435. wlan_servers_stop();
  436. #ifdef SL_PLATFORM_MULTI_THREADED
  437. sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
  438. #endif
  439. sl_Stop(timeout);
  440. wlan_clear_data();
  441. wlan_obj.mode = -1;
  442. }
  443. void wlan_get_mac (uint8_t *macAddress) {
  444. if (macAddress) {
  445. memcpy (macAddress, wlan_obj.mac, SL_MAC_ADDR_LEN);
  446. }
  447. }
  448. void wlan_get_ip (uint32_t *ip) {
  449. if (ip) {
  450. *ip = IS_IP_ACQUIRED(wlan_obj.status) ? wlan_obj.ip : 0;
  451. }
  452. }
  453. bool wlan_is_connected (void) {
  454. return (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION) &&
  455. (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED) || wlan_obj.mode != ROLE_STA));
  456. }
  457. void wlan_set_current_time (uint32_t seconds_since_2000) {
  458. timeutils_struct_time_t tm;
  459. timeutils_seconds_since_2000_to_struct_time(seconds_since_2000, &tm);
  460. SlDateTime_t sl_datetime = {0};
  461. sl_datetime.sl_tm_day = tm.tm_mday;
  462. sl_datetime.sl_tm_mon = tm.tm_mon;
  463. sl_datetime.sl_tm_year = tm.tm_year;
  464. sl_datetime.sl_tm_hour = tm.tm_hour;
  465. sl_datetime.sl_tm_min = tm.tm_min;
  466. sl_datetime.sl_tm_sec = tm.tm_sec;
  467. sl_DevSet(SL_DEVICE_GENERAL_CONFIGURATION, SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME, sizeof(SlDateTime_t), (_u8 *)(&sl_datetime));
  468. }
  469. void wlan_off_on (void) {
  470. // no need to lock the WLAN object on every API call since the servers and the MicroPtyhon
  471. // task have the same priority
  472. wlan_reenable(wlan_obj.mode);
  473. }
  474. //*****************************************************************************
  475. // DEFINE STATIC FUNCTIONS
  476. //*****************************************************************************
  477. STATIC void wlan_clear_data (void) {
  478. CLR_STATUS_BIT_ALL(wlan_obj.status);
  479. wlan_obj.ip = 0;
  480. //memset(wlan_obj.ssid_o, 0, sizeof(wlan_obj.ssid));
  481. //memset(wlan_obj.bssid, 0, sizeof(wlan_obj.bssid));
  482. }
  483. STATIC void wlan_reenable (SlWlanMode_t mode) {
  484. // stop and start again
  485. #ifdef SL_PLATFORM_MULTI_THREADED
  486. sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
  487. #endif
  488. sl_Stop(SL_STOP_TIMEOUT);
  489. wlan_clear_data();
  490. wlan_obj.mode = sl_Start(0, 0, 0);
  491. #ifdef SL_PLATFORM_MULTI_THREADED
  492. sl_LockObjUnlock (&wlan_LockObj);
  493. #endif
  494. ASSERT (wlan_obj.mode == mode);
  495. }
  496. STATIC void wlan_servers_start (void) {
  497. #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
  498. // start the servers if they were enabled before
  499. if (wlan_obj.servers_enabled) {
  500. servers_start();
  501. }
  502. #endif
  503. }
  504. STATIC void wlan_servers_stop (void) {
  505. #if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
  506. // Stop all other processes using the wlan engine
  507. if ((wlan_obj.servers_enabled = servers_are_enabled())) {
  508. servers_stop();
  509. }
  510. #endif
  511. }
  512. STATIC void wlan_reset (void) {
  513. wlan_servers_stop();
  514. wlan_reenable (wlan_obj.mode);
  515. wlan_servers_start();
  516. }
  517. STATIC void wlan_validate_mode (uint mode) {
  518. if (mode != ROLE_STA && mode != ROLE_AP) {
  519. mp_raise_ValueError(mpexception_value_invalid_arguments);
  520. }
  521. }
  522. STATIC void wlan_set_mode (uint mode) {
  523. wlan_obj.mode = mode;
  524. ASSERT_ON_ERROR(sl_WlanSetMode(mode));
  525. }
  526. STATIC void wlan_validate_ssid_len (uint32_t len) {
  527. if (len > MODWLAN_SSID_LEN_MAX) {
  528. mp_raise_ValueError(mpexception_value_invalid_arguments);
  529. }
  530. }
  531. STATIC void wlan_set_ssid (const char *ssid, uint8_t len, bool add_mac) {
  532. if (ssid != NULL) {
  533. // save the ssid
  534. memcpy(&wlan_obj.ssid, ssid, len);
  535. // append the last 2 bytes of the MAC address, since the use of this functionality is under our control
  536. // we can assume that the lenght of the ssid is less than (32 - 5)
  537. if (add_mac) {
  538. snprintf((char *)&wlan_obj.ssid[len], sizeof(wlan_obj.ssid) - len, "-%02x%02x", wlan_obj.mac[4], wlan_obj.mac[5]);
  539. len += 5;
  540. }
  541. wlan_obj.ssid[len] = '\0';
  542. ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, len, (unsigned char *)wlan_obj.ssid));
  543. }
  544. }
  545. STATIC void wlan_validate_security (uint8_t auth, const char *key, uint8_t len) {
  546. if (auth != SL_SEC_TYPE_WEP && auth != SL_SEC_TYPE_WPA_WPA2) {
  547. goto invalid_args;
  548. }
  549. if (auth == SL_SEC_TYPE_WEP) {
  550. for (mp_uint_t i = strlen(key); i > 0; i--) {
  551. if (!unichar_isxdigit(*key++)) {
  552. goto invalid_args;
  553. }
  554. }
  555. }
  556. return;
  557. invalid_args:
  558. mp_raise_ValueError(mpexception_value_invalid_arguments);
  559. }
  560. STATIC void wlan_set_security (uint8_t auth, const char *key, uint8_t len) {
  561. wlan_obj.auth = auth;
  562. ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, sizeof(uint8_t), &auth));
  563. if (key != NULL) {
  564. memcpy(&wlan_obj.key, key, len);
  565. wlan_obj.key[len] = '\0';
  566. if (auth == SL_SEC_TYPE_WEP) {
  567. _u8 wep_key[32];
  568. wlan_wep_key_unhexlify(key, (char *)&wep_key);
  569. key = (const char *)&wep_key;
  570. len /= 2;
  571. }
  572. ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, len, (unsigned char *)key));
  573. } else {
  574. wlan_obj.key[0] = '\0';
  575. }
  576. }
  577. STATIC void wlan_validate_channel (uint8_t channel) {
  578. if (channel < 1 || channel > 11) {
  579. mp_raise_ValueError(mpexception_value_invalid_arguments);
  580. }
  581. }
  582. STATIC void wlan_set_channel (uint8_t channel) {
  583. wlan_obj.channel = channel;
  584. ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_CHANNEL, 1, &channel));
  585. }
  586. #if MICROPY_HW_ANTENNA_DIVERSITY
  587. STATIC void wlan_validate_antenna (uint8_t antenna) {
  588. if (antenna != ANTENNA_TYPE_INTERNAL && antenna != ANTENNA_TYPE_EXTERNAL) {
  589. mp_raise_ValueError(mpexception_value_invalid_arguments);
  590. }
  591. }
  592. STATIC void wlan_set_antenna (uint8_t antenna) {
  593. wlan_obj.antenna = antenna;
  594. antenna_select(antenna);
  595. }
  596. #endif
  597. STATIC void wlan_sl_disconnect (void) {
  598. // Device in station-mode. Disconnect previous connection if any
  599. // The function returns 0 if 'Disconnected done', negative number if already
  600. // disconnected Wait for 'disconnection' event if 0 is returned, Ignore
  601. // other return-codes
  602. if (0 == sl_WlanDisconnect()) {
  603. while (IS_CONNECTED(wlan_obj.status)) {
  604. mp_hal_delay_ms(MODWLAN_CONNECTION_WAIT_MS);
  605. wlan_update();
  606. }
  607. }
  608. }
  609. STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec,
  610. const char* key, uint32_t key_len, int32_t timeout) {
  611. SlSecParams_t secParams;
  612. secParams.Key = (_i8*)key;
  613. secParams.KeyLen = ((key != NULL) ? key_len : 0);
  614. secParams.Type = sec;
  615. // first close any active connections
  616. wlan_sl_disconnect();
  617. if (!sl_WlanConnect((_i8*)ssid, ssid_len, (_u8*)bssid, &secParams, NULL)) {
  618. // wait for the WLAN Event
  619. uint32_t waitForConnectionMs = 0;
  620. while (timeout && !IS_CONNECTED(wlan_obj.status)) {
  621. mp_hal_delay_ms(MODWLAN_CONNECTION_WAIT_MS);
  622. waitForConnectionMs += MODWLAN_CONNECTION_WAIT_MS;
  623. if (timeout > 0 && waitForConnectionMs > timeout) {
  624. return MODWLAN_ERROR_TIMEOUT;
  625. }
  626. wlan_update();
  627. }
  628. return MODWLAN_OK;
  629. }
  630. return MODWLAN_ERROR_INVALID_PARAMS;
  631. }
  632. STATIC void wlan_get_sl_mac (void) {
  633. // Get the MAC address
  634. uint8_t macAddrLen = SL_MAC_ADDR_LEN;
  635. sl_NetCfgGet(SL_MAC_ADDRESS_GET, NULL, &macAddrLen, wlan_obj.mac);
  636. }
  637. STATIC void wlan_wep_key_unhexlify (const char *key, char *key_out) {
  638. byte hex_byte = 0;
  639. for (mp_uint_t i = strlen(key); i > 0 ; i--) {
  640. hex_byte += unichar_xdigit_value(*key++);
  641. if (i & 1) {
  642. hex_byte <<= 4;
  643. } else {
  644. *key_out++ = hex_byte;
  645. hex_byte = 0;
  646. }
  647. }
  648. }
  649. STATIC void wlan_lpds_irq_enable (mp_obj_t self_in) {
  650. wlan_obj_t *self = self_in;
  651. self->irq_enabled = true;
  652. }
  653. STATIC void wlan_lpds_irq_disable (mp_obj_t self_in) {
  654. wlan_obj_t *self = self_in;
  655. self->irq_enabled = false;
  656. }
  657. STATIC int wlan_irq_flags (mp_obj_t self_in) {
  658. wlan_obj_t *self = self_in;
  659. return self->irq_flags;
  660. }
  661. STATIC bool wlan_scan_result_is_unique (const mp_obj_list_t *nets, _u8 *bssid) {
  662. for (int i = 0; i < nets->len; i++) {
  663. // index 1 in the list is the bssid
  664. mp_obj_str_t *_bssid = (mp_obj_str_t *)((mp_obj_tuple_t *)nets->items[i])->items[1];
  665. if (!memcmp (_bssid->data, bssid, SL_BSSID_LENGTH)) {
  666. return false;
  667. }
  668. }
  669. return true;
  670. }
  671. /******************************************************************************/
  672. // MicroPython bindings; WLAN class
  673. /// \class WLAN - WiFi driver
  674. STATIC mp_obj_t wlan_init_helper(wlan_obj_t *self, const mp_arg_val_t *args) {
  675. // get the mode
  676. int8_t mode = args[0].u_int;
  677. wlan_validate_mode(mode);
  678. // get the ssid
  679. size_t ssid_len = 0;
  680. const char *ssid = NULL;
  681. if (args[1].u_obj != NULL) {
  682. ssid = mp_obj_str_get_data(args[1].u_obj, &ssid_len);
  683. wlan_validate_ssid_len(ssid_len);
  684. }
  685. // get the auth config
  686. uint8_t auth = SL_SEC_TYPE_OPEN;
  687. size_t key_len = 0;
  688. const char *key = NULL;
  689. if (args[2].u_obj != mp_const_none) {
  690. mp_obj_t *sec;
  691. mp_obj_get_array_fixed_n(args[2].u_obj, 2, &sec);
  692. auth = mp_obj_get_int(sec[0]);
  693. key = mp_obj_str_get_data(sec[1], &key_len);
  694. wlan_validate_security(auth, key, key_len);
  695. }
  696. // get the channel
  697. uint8_t channel = args[3].u_int;
  698. wlan_validate_channel(channel);
  699. // get the antenna type
  700. uint8_t antenna = 0;
  701. #if MICROPY_HW_ANTENNA_DIVERSITY
  702. antenna = args[4].u_int;
  703. wlan_validate_antenna(antenna);
  704. #endif
  705. // initialize the wlan subsystem
  706. wlan_sl_init(mode, (const char *)ssid, ssid_len, auth, (const char *)key, key_len, channel, antenna, false);
  707. return mp_const_none;
  708. }
  709. STATIC const mp_arg_t wlan_init_args[] = {
  710. { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
  711. { MP_QSTR_mode, MP_ARG_INT, {.u_int = ROLE_STA} },
  712. { MP_QSTR_ssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  713. { MP_QSTR_auth, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
  714. { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
  715. #if MICROPY_HW_ANTENNA_DIVERSITY
  716. { MP_QSTR_antenna, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ANTENNA_TYPE_INTERNAL} },
  717. #endif
  718. };
  719. STATIC mp_obj_t wlan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
  720. // parse args
  721. mp_map_t kw_args;
  722. mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
  723. mp_arg_val_t args[MP_ARRAY_SIZE(wlan_init_args)];
  724. mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), wlan_init_args, args);
  725. // setup the object
  726. wlan_obj_t *self = &wlan_obj;
  727. self->base.type = (mp_obj_t)&mod_network_nic_type_wlan;
  728. // give it to the sleep module
  729. pyb_sleep_set_wlan_obj(self);
  730. if (n_args > 1 || n_kw > 0) {
  731. // check the peripheral id
  732. if (args[0].u_int != 0) {
  733. mp_raise_OSError(MP_ENODEV);
  734. }
  735. // start the peripheral
  736. wlan_init_helper(self, &args[1]);
  737. }
  738. return (mp_obj_t)self;
  739. }
  740. STATIC mp_obj_t wlan_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  741. // parse args
  742. mp_arg_val_t args[MP_ARRAY_SIZE(wlan_init_args) - 1];
  743. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &wlan_init_args[1], args);
  744. return wlan_init_helper(pos_args[0], args);
  745. }
  746. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_init_obj, 1, wlan_init);
  747. STATIC mp_obj_t wlan_scan(mp_obj_t self_in) {
  748. STATIC const qstr wlan_scan_info_fields[] = {
  749. MP_QSTR_ssid, MP_QSTR_bssid, MP_QSTR_sec, MP_QSTR_channel, MP_QSTR_rssi
  750. };
  751. // check for correct wlan mode
  752. if (wlan_obj.mode == ROLE_AP) {
  753. mp_raise_OSError(MP_EPERM);
  754. }
  755. Sl_WlanNetworkEntry_t wlanEntry;
  756. mp_obj_t nets = mp_obj_new_list(0, NULL);
  757. uint8_t _index = 0;
  758. // trigger a new network scan
  759. uint32_t scanSeconds = MODWLAN_SCAN_PERIOD_S;
  760. ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_SCAN , MODWLAN_SL_SCAN_ENABLE, (_u8 *)&scanSeconds, sizeof(scanSeconds)));
  761. // wait for the scan to complete
  762. mp_hal_delay_ms(MODWLAN_WAIT_FOR_SCAN_MS);
  763. do {
  764. if (sl_WlanGetNetworkList(_index++, 1, &wlanEntry) <= 0) {
  765. break;
  766. }
  767. // we must skip any duplicated results
  768. if (!wlan_scan_result_is_unique(nets, wlanEntry.bssid)) {
  769. continue;
  770. }
  771. mp_obj_t tuple[5];
  772. tuple[0] = mp_obj_new_str((const char *)wlanEntry.ssid, wlanEntry.ssid_len);
  773. tuple[1] = mp_obj_new_bytes((const byte *)wlanEntry.bssid, SL_BSSID_LENGTH);
  774. // 'normalize' the security type
  775. if (wlanEntry.sec_type > 2) {
  776. wlanEntry.sec_type = 2;
  777. }
  778. tuple[2] = mp_obj_new_int(wlanEntry.sec_type);
  779. tuple[3] = mp_const_none;
  780. tuple[4] = mp_obj_new_int(wlanEntry.rssi);
  781. // add the network to the list
  782. mp_obj_list_append(nets, mp_obj_new_attrtuple(wlan_scan_info_fields, 5, tuple));
  783. } while (_index < MODWLAN_SL_MAX_NETWORKS);
  784. return nets;
  785. }
  786. STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_scan_obj, wlan_scan);
  787. STATIC mp_obj_t wlan_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  788. STATIC const mp_arg_t allowed_args[] = {
  789. { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, },
  790. { MP_QSTR_auth, MP_ARG_OBJ, {.u_obj = mp_const_none} },
  791. { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
  792. { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
  793. };
  794. // check for the correct wlan mode
  795. if (wlan_obj.mode == ROLE_AP) {
  796. mp_raise_OSError(MP_EPERM);
  797. }
  798. // parse args
  799. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  800. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  801. // get the ssid
  802. size_t ssid_len;
  803. const char *ssid = mp_obj_str_get_data(args[0].u_obj, &ssid_len);
  804. wlan_validate_ssid_len(ssid_len);
  805. // get the auth config
  806. uint8_t auth = SL_SEC_TYPE_OPEN;
  807. size_t key_len = 0;
  808. const char *key = NULL;
  809. if (args[1].u_obj != mp_const_none) {
  810. mp_obj_t *sec;
  811. mp_obj_get_array_fixed_n(args[1].u_obj, 2, &sec);
  812. auth = mp_obj_get_int(sec[0]);
  813. key = mp_obj_str_get_data(sec[1], &key_len);
  814. wlan_validate_security(auth, key, key_len);
  815. // convert the wep key if needed
  816. if (auth == SL_SEC_TYPE_WEP) {
  817. _u8 wep_key[32];
  818. wlan_wep_key_unhexlify(key, (char *)&wep_key);
  819. key = (const char *)&wep_key;
  820. key_len /= 2;
  821. }
  822. }
  823. // get the bssid
  824. const char *bssid = NULL;
  825. if (args[2].u_obj != mp_const_none) {
  826. bssid = mp_obj_str_get_str(args[2].u_obj);
  827. }
  828. // get the timeout
  829. int32_t timeout = -1;
  830. if (args[3].u_obj != mp_const_none) {
  831. timeout = mp_obj_get_int(args[3].u_obj);
  832. }
  833. // connect to the requested access point
  834. modwlan_Status_t status;
  835. status = wlan_do_connect (ssid, ssid_len, bssid, auth, key, key_len, timeout);
  836. if (status == MODWLAN_ERROR_TIMEOUT) {
  837. mp_raise_OSError(MP_ETIMEDOUT);
  838. } else if (status == MODWLAN_ERROR_INVALID_PARAMS) {
  839. mp_raise_ValueError(mpexception_value_invalid_arguments);
  840. }
  841. return mp_const_none;
  842. }
  843. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_connect_obj, 1, wlan_connect);
  844. STATIC mp_obj_t wlan_disconnect(mp_obj_t self_in) {
  845. wlan_sl_disconnect();
  846. return mp_const_none;
  847. }
  848. STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_disconnect_obj, wlan_disconnect);
  849. STATIC mp_obj_t wlan_isconnected(mp_obj_t self_in) {
  850. return wlan_is_connected() ? mp_const_true : mp_const_false;
  851. }
  852. STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_isconnected_obj, wlan_isconnected);
  853. STATIC mp_obj_t wlan_ifconfig(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  854. STATIC const mp_arg_t wlan_ifconfig_args[] = {
  855. { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
  856. { MP_QSTR_config, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  857. };
  858. // parse args
  859. mp_arg_val_t args[MP_ARRAY_SIZE(wlan_ifconfig_args)];
  860. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), wlan_ifconfig_args, args);
  861. // check the interface id
  862. if (args[0].u_int != 0) {
  863. mp_raise_OSError(MP_EPERM);
  864. }
  865. // get the configuration
  866. if (args[1].u_obj == MP_OBJ_NULL) {
  867. // get
  868. unsigned char len = sizeof(SlNetCfgIpV4Args_t);
  869. unsigned char dhcpIsOn;
  870. SlNetCfgIpV4Args_t ipV4;
  871. sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO, &dhcpIsOn, &len, (uint8_t *)&ipV4);
  872. mp_obj_t ifconfig[4] = {
  873. netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4, NETUTILS_LITTLE),
  874. netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4Mask, NETUTILS_LITTLE),
  875. netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4Gateway, NETUTILS_LITTLE),
  876. netutils_format_ipv4_addr((uint8_t *)&ipV4.ipV4DnsServer, NETUTILS_LITTLE)
  877. };
  878. return mp_obj_new_tuple(4, ifconfig);
  879. } else { // set the configuration
  880. if (MP_OBJ_IS_TYPE(args[1].u_obj, &mp_type_tuple)) {
  881. // set a static ip
  882. mp_obj_t *items;
  883. mp_obj_get_array_fixed_n(args[1].u_obj, 4, &items);
  884. SlNetCfgIpV4Args_t ipV4;
  885. netutils_parse_ipv4_addr(items[0], (uint8_t *)&ipV4.ipV4, NETUTILS_LITTLE);
  886. netutils_parse_ipv4_addr(items[1], (uint8_t *)&ipV4.ipV4Mask, NETUTILS_LITTLE);
  887. netutils_parse_ipv4_addr(items[2], (uint8_t *)&ipV4.ipV4Gateway, NETUTILS_LITTLE);
  888. netutils_parse_ipv4_addr(items[3], (uint8_t *)&ipV4.ipV4DnsServer, NETUTILS_LITTLE);
  889. if (wlan_obj.mode == ROLE_AP) {
  890. ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4));
  891. SlNetAppDhcpServerBasicOpt_t dhcpParams;
  892. dhcpParams.lease_time = 4096; // lease time (in seconds) of the IP Address
  893. dhcpParams.ipv4_addr_start = ipV4.ipV4 + 1; // first IP Address for allocation.
  894. dhcpParams.ipv4_addr_last = (ipV4.ipV4 & 0xFFFFFF00) + 254; // last IP Address for allocation.
  895. ASSERT_ON_ERROR(sl_NetAppStop(SL_NET_APP_DHCP_SERVER_ID)); // stop DHCP server before settings
  896. ASSERT_ON_ERROR(sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT,
  897. sizeof(SlNetAppDhcpServerBasicOpt_t), (_u8* )&dhcpParams)); // set parameters
  898. ASSERT_ON_ERROR(sl_NetAppStart(SL_NET_APP_DHCP_SERVER_ID)); // start DHCP server with new settings
  899. } else {
  900. ASSERT_ON_ERROR(sl_NetCfgSet(SL_IPV4_STA_P2P_CL_STATIC_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4));
  901. }
  902. } else {
  903. // check for the correct string
  904. const char *mode = mp_obj_str_get_str(args[1].u_obj);
  905. if (strcmp("dhcp", mode)) {
  906. mp_raise_ValueError(mpexception_value_invalid_arguments);
  907. }
  908. // only if we are not in AP mode
  909. if (wlan_obj.mode != ROLE_AP) {
  910. _u8 val = 1;
  911. sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE, IPCONFIG_MODE_ENABLE_IPV4, 1, &val);
  912. }
  913. }
  914. // config values have changed, so reset
  915. wlan_reset();
  916. // set current time and date (needed to validate certificates)
  917. wlan_set_current_time (pyb_rtc_get_seconds());
  918. return mp_const_none;
  919. }
  920. }
  921. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_ifconfig_obj, 1, wlan_ifconfig);
  922. STATIC mp_obj_t wlan_mode(size_t n_args, const mp_obj_t *args) {
  923. wlan_obj_t *self = args[0];
  924. if (n_args == 1) {
  925. return mp_obj_new_int(self->mode);
  926. } else {
  927. uint mode = mp_obj_get_int(args[1]);
  928. wlan_validate_mode(mode);
  929. wlan_set_mode(mode);
  930. wlan_reset();
  931. return mp_const_none;
  932. }
  933. }
  934. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_mode_obj, 1, 2, wlan_mode);
  935. STATIC mp_obj_t wlan_ssid(size_t n_args, const mp_obj_t *args) {
  936. wlan_obj_t *self = args[0];
  937. if (n_args == 1) {
  938. return mp_obj_new_str((const char *)self->ssid, strlen((const char *)self->ssid));
  939. } else {
  940. size_t len;
  941. const char *ssid = mp_obj_str_get_data(args[1], &len);
  942. wlan_validate_ssid_len(len);
  943. wlan_set_ssid(ssid, len, false);
  944. wlan_reset();
  945. return mp_const_none;
  946. }
  947. }
  948. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_ssid_obj, 1, 2, wlan_ssid);
  949. STATIC mp_obj_t wlan_auth(size_t n_args, const mp_obj_t *args) {
  950. wlan_obj_t *self = args[0];
  951. if (n_args == 1) {
  952. if (self->auth == SL_SEC_TYPE_OPEN) {
  953. return mp_const_none;
  954. } else {
  955. mp_obj_t security[2];
  956. security[0] = mp_obj_new_int(self->auth);
  957. security[1] = mp_obj_new_str((const char *)self->key, strlen((const char *)self->key));
  958. return mp_obj_new_tuple(2, security);
  959. }
  960. } else {
  961. // get the auth config
  962. uint8_t auth = SL_SEC_TYPE_OPEN;
  963. size_t key_len = 0;
  964. const char *key = NULL;
  965. if (args[1] != mp_const_none) {
  966. mp_obj_t *sec;
  967. mp_obj_get_array_fixed_n(args[1], 2, &sec);
  968. auth = mp_obj_get_int(sec[0]);
  969. key = mp_obj_str_get_data(sec[1], &key_len);
  970. wlan_validate_security(auth, key, key_len);
  971. }
  972. wlan_set_security(auth, key, key_len);
  973. wlan_reset();
  974. return mp_const_none;
  975. }
  976. }
  977. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_auth_obj, 1, 2, wlan_auth);
  978. STATIC mp_obj_t wlan_channel(size_t n_args, const mp_obj_t *args) {
  979. wlan_obj_t *self = args[0];
  980. if (n_args == 1) {
  981. return mp_obj_new_int(self->channel);
  982. } else {
  983. uint8_t channel = mp_obj_get_int(args[1]);
  984. wlan_validate_channel(channel);
  985. wlan_set_channel(channel);
  986. wlan_reset();
  987. return mp_const_none;
  988. }
  989. }
  990. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_channel_obj, 1, 2, wlan_channel);
  991. STATIC mp_obj_t wlan_antenna(size_t n_args, const mp_obj_t *args) {
  992. wlan_obj_t *self = args[0];
  993. if (n_args == 1) {
  994. return mp_obj_new_int(self->antenna);
  995. } else {
  996. #if MICROPY_HW_ANTENNA_DIVERSITY
  997. uint8_t antenna = mp_obj_get_int(args[1]);
  998. wlan_validate_antenna(antenna);
  999. wlan_set_antenna(antenna);
  1000. #endif
  1001. return mp_const_none;
  1002. }
  1003. }
  1004. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_antenna_obj, 1, 2, wlan_antenna);
  1005. STATIC mp_obj_t wlan_mac(size_t n_args, const mp_obj_t *args) {
  1006. wlan_obj_t *self = args[0];
  1007. if (n_args == 1) {
  1008. return mp_obj_new_bytes((const byte *)self->mac, SL_BSSID_LENGTH);
  1009. } else {
  1010. mp_buffer_info_t bufinfo;
  1011. mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
  1012. if (bufinfo.len != 6) {
  1013. mp_raise_ValueError(mpexception_value_invalid_arguments);
  1014. }
  1015. memcpy(self->mac, bufinfo.buf, SL_MAC_ADDR_LEN);
  1016. sl_NetCfgSet(SL_MAC_ADDRESS_SET, 1, SL_MAC_ADDR_LEN, (_u8 *)self->mac);
  1017. wlan_reset();
  1018. return mp_const_none;
  1019. }
  1020. }
  1021. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_mac_obj, 1, 2, wlan_mac);
  1022. STATIC mp_obj_t wlan_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  1023. mp_arg_val_t args[mp_irq_INIT_NUM_ARGS];
  1024. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mp_irq_INIT_NUM_ARGS, mp_irq_init_args, args);
  1025. wlan_obj_t *self = pos_args[0];
  1026. // check the trigger, only one type is supported
  1027. if (mp_obj_get_int(args[0].u_obj) != MODWLAN_WIFI_EVENT_ANY) {
  1028. goto invalid_args;
  1029. }
  1030. // check the power mode
  1031. if (mp_obj_get_int(args[3].u_obj) != PYB_PWR_MODE_LPDS) {
  1032. goto invalid_args;
  1033. }
  1034. // create the callback
  1035. mp_obj_t _irq = mp_irq_new (self, args[2].u_obj, &wlan_irq_methods);
  1036. self->irq_obj = _irq;
  1037. // enable the irq just before leaving
  1038. wlan_lpds_irq_enable(self);
  1039. return _irq;
  1040. invalid_args:
  1041. mp_raise_ValueError(mpexception_value_invalid_arguments);
  1042. }
  1043. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
  1044. //STATIC mp_obj_t wlan_connections (mp_obj_t self_in) {
  1045. // mp_obj_t device[2];
  1046. // mp_obj_t connections = mp_obj_new_list(0, NULL);
  1047. //
  1048. // if (wlan_is_connected()) {
  1049. // device[0] = mp_obj_new_str((const char *)wlan_obj.ssid_o, strlen((const char *)wlan_obj.ssid_o));
  1050. // device[1] = mp_obj_new_bytes((const byte *)wlan_obj.bssid, SL_BSSID_LENGTH);
  1051. // // add the device to the list
  1052. // mp_obj_list_append(connections, mp_obj_new_tuple(MP_ARRAY_SIZE(device), device));
  1053. // }
  1054. // return connections;
  1055. //}
  1056. //STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_connections_obj, wlan_connections);
  1057. //STATIC mp_obj_t wlan_urn (uint n_args, const mp_obj_t *args) {
  1058. // char urn[MAX_DEVICE_URN_LEN];
  1059. // uint8_t len = MAX_DEVICE_URN_LEN;
  1060. //
  1061. // // an URN is given, so set it
  1062. // if (n_args == 2) {
  1063. // const char *p = mp_obj_str_get_str(args[1]);
  1064. // uint8_t len = strlen(p);
  1065. //
  1066. // // the call to sl_NetAppSet corrupts the input string URN=args[1], so we copy into a local buffer
  1067. // if (len > MAX_DEVICE_URN_LEN) {
  1068. // mp_raise_ValueError(mpexception_value_invalid_arguments);
  1069. // }
  1070. // strcpy(urn, p);
  1071. //
  1072. // if (sl_NetAppSet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, len, (unsigned char *)urn) < 0) {
  1073. // mp_raise_OSError(MP_EIO);
  1074. // }
  1075. // }
  1076. // else {
  1077. // // get the URN
  1078. // if (sl_NetAppGet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, &len, (uint8_t *)urn) < 0) {
  1079. // mp_raise_OSError(MP_EIO);
  1080. // }
  1081. // return mp_obj_new_str(urn, (len - 1));
  1082. // }
  1083. //
  1084. // return mp_const_none;
  1085. //}
  1086. //STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_urn_obj, 1, 2, wlan_urn);
  1087. STATIC mp_obj_t wlan_print_ver(void) {
  1088. SlVersionFull ver;
  1089. byte config_opt = SL_DEVICE_GENERAL_VERSION;
  1090. byte config_len = sizeof(ver);
  1091. sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &config_opt, &config_len, (byte*)&ver);
  1092. printf("NWP: %d.%d.%d.%d\n", (int)ver.NwpVersion[0], (int)ver.NwpVersion[1], (int)ver.NwpVersion[2], (int)ver.NwpVersion[3]);
  1093. printf("MAC: %d.%d.%d.%d\n", (int)ver.ChipFwAndPhyVersion.FwVersion[0], (int)ver.ChipFwAndPhyVersion.FwVersion[1],
  1094. (int)ver.ChipFwAndPhyVersion.FwVersion[2], (int)ver.ChipFwAndPhyVersion.FwVersion[3]);
  1095. printf("PHY: %d.%d.%d.%d\n", ver.ChipFwAndPhyVersion.PhyVersion[0], ver.ChipFwAndPhyVersion.PhyVersion[1],
  1096. ver.ChipFwAndPhyVersion.PhyVersion[2], ver.ChipFwAndPhyVersion.PhyVersion[3]);
  1097. return mp_const_none;
  1098. }
  1099. STATIC MP_DEFINE_CONST_FUN_OBJ_0(wlan_print_ver_fun_obj, wlan_print_ver);
  1100. STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(wlan_print_ver_obj, MP_ROM_PTR(&wlan_print_ver_fun_obj));
  1101. STATIC const mp_rom_map_elem_t wlan_locals_dict_table[] = {
  1102. { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&wlan_init_obj) },
  1103. { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&wlan_scan_obj) },
  1104. { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&wlan_connect_obj) },
  1105. { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&wlan_disconnect_obj) },
  1106. { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wlan_isconnected_obj) },
  1107. { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wlan_ifconfig_obj) },
  1108. { MP_ROM_QSTR(MP_QSTR_mode), MP_ROM_PTR(&wlan_mode_obj) },
  1109. { MP_ROM_QSTR(MP_QSTR_ssid), MP_ROM_PTR(&wlan_ssid_obj) },
  1110. { MP_ROM_QSTR(MP_QSTR_auth), MP_ROM_PTR(&wlan_auth_obj) },
  1111. { MP_ROM_QSTR(MP_QSTR_channel), MP_ROM_PTR(&wlan_channel_obj) },
  1112. { MP_ROM_QSTR(MP_QSTR_antenna), MP_ROM_PTR(&wlan_antenna_obj) },
  1113. { MP_ROM_QSTR(MP_QSTR_mac), MP_ROM_PTR(&wlan_mac_obj) },
  1114. { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&wlan_irq_obj) },
  1115. //{ MP_ROM_QSTR(MP_QSTR_connections), MP_ROM_PTR(&wlan_connections_obj) },
  1116. //{ MP_ROM_QSTR(MP_QSTR_urn), MP_ROM_PTR(&wlan_urn_obj) },
  1117. { MP_ROM_QSTR(MP_QSTR_print_ver), MP_ROM_PTR(&wlan_print_ver_obj) },
  1118. // class constants
  1119. { MP_ROM_QSTR(MP_QSTR_STA), MP_ROM_INT(ROLE_STA) },
  1120. { MP_ROM_QSTR(MP_QSTR_AP), MP_ROM_INT(ROLE_AP) },
  1121. { MP_ROM_QSTR(MP_QSTR_WEP), MP_ROM_INT(SL_SEC_TYPE_WEP) },
  1122. { MP_ROM_QSTR(MP_QSTR_WPA), MP_ROM_INT(SL_SEC_TYPE_WPA_WPA2) },
  1123. { MP_ROM_QSTR(MP_QSTR_WPA2), MP_ROM_INT(SL_SEC_TYPE_WPA_WPA2) },
  1124. #if MICROPY_HW_ANTENNA_DIVERSITY
  1125. { MP_ROM_QSTR(MP_QSTR_INT_ANT), MP_ROM_INT(ANTENNA_TYPE_INTERNAL) },
  1126. { MP_ROM_QSTR(MP_QSTR_EXT_ANT), MP_ROM_INT(ANTENNA_TYPE_EXTERNAL) },
  1127. #endif
  1128. { MP_ROM_QSTR(MP_QSTR_ANY_EVENT), MP_ROM_INT(MODWLAN_WIFI_EVENT_ANY) },
  1129. };
  1130. STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table);
  1131. const mod_network_nic_type_t mod_network_nic_type_wlan = {
  1132. .base = {
  1133. { &mp_type_type },
  1134. .name = MP_QSTR_WLAN,
  1135. .make_new = wlan_make_new,
  1136. .locals_dict = (mp_obj_t)&wlan_locals_dict,
  1137. },
  1138. };
  1139. STATIC const mp_irq_methods_t wlan_irq_methods = {
  1140. .init = wlan_irq,
  1141. .enable = wlan_lpds_irq_enable,
  1142. .disable = wlan_lpds_irq_disable,
  1143. .flags = wlan_irq_flags,
  1144. };