modnetwork_wlan.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2019 SummerGift <SummerGift@qq.com>
  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 <stdio.h>
  27. #include <stdint.h>
  28. #include <string.h>
  29. #include "py/objlist.h"
  30. #include "py/runtime.h"
  31. #include "py/mphal.h"
  32. #include "lib/netutils/netutils.h"
  33. #if MICROPY_PY_WLAN
  34. #include <rtdbg.h>
  35. #include <rtthread.h>
  36. #include <wlan_mgnt.h>
  37. #include <wlan_cfg.h>
  38. #include <wlan_prot.h>
  39. #include <arpa/inet.h>
  40. #include <netdev.h>
  41. #include "modnetwork.h"
  42. extern struct netdev *netdev_default;
  43. typedef struct _wlan_if_obj_t {
  44. mp_obj_base_t base;
  45. int if_id;
  46. } wlan_if_obj_t;
  47. enum {
  48. STATION_IDLE = 0,
  49. STATION_CONNECTING,
  50. STATION_WRONG_PASSWORD,
  51. STATION_NO_AP_FOUND,
  52. STATION_CONNECT_FAIL,
  53. STATION_GOT_IP,
  54. };
  55. const mp_obj_type_t wlan_if_type;
  56. STATIC struct rt_wlan_info _ap_info;
  57. STATIC char _ap_password[RT_WLAN_PASSWORD_MAX_LENGTH];
  58. STATIC void error_check(bool status, const char *msg) {
  59. if (!status) {
  60. nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, msg));
  61. }
  62. }
  63. STATIC const wlan_if_obj_t wlan_objs[] = {
  64. {{&wlan_if_type}, STATION_IF},
  65. {{&wlan_if_type}, SOFTAP_IF},
  66. };
  67. STATIC void require_if(mp_obj_t wlan_if, int if_no) {
  68. wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if);
  69. if (self->if_id != if_no) {
  70. error_check(false, if_no == STATION_IF ? "STA required" : "AP required");
  71. }
  72. }
  73. STATIC mp_obj_t get_wlan(size_t n_args, const mp_obj_t *args) {
  74. int idx = 0;
  75. if (n_args > 0) {
  76. idx = mp_obj_get_int(args[0]);
  77. if (idx < 0 || idx >= sizeof(wlan_objs)) {
  78. mp_raise_ValueError(NULL);
  79. }
  80. }
  81. return MP_OBJ_FROM_PTR(&wlan_objs[idx]);
  82. }
  83. MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(get_wlan_obj, 0, 1, get_wlan);
  84. STATIC mp_obj_t wlan_active(size_t n_args, const mp_obj_t *args) {
  85. wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
  86. if (n_args > 1) {
  87. if (self->if_id == STATION_IF)
  88. {
  89. if (mp_obj_get_int(args[1]) == RT_TRUE)
  90. {
  91. error_check(netdev_set_up(netdev_default) == RT_EOK, "Cannot active wlan device");
  92. }
  93. else
  94. {
  95. error_check(netdev_set_down(netdev_default) == RT_EOK, "Cannot disable wlan device");
  96. }
  97. }
  98. else
  99. {
  100. if (mp_obj_get_int(args[1]) == RT_TRUE)
  101. {
  102. error_check(rt_wlan_start_ap((char *)&_ap_info.ssid.val, _ap_password) == RT_EOK, "Cannot start AP");
  103. }
  104. else
  105. {
  106. error_check(rt_wlan_ap_stop() == RT_EOK, "Cannot stop AP");
  107. }
  108. }
  109. return mp_const_none;
  110. }
  111. if (self->if_id == STATION_IF)
  112. {
  113. return mp_obj_new_bool(rt_wlan_get_mode("wlan0") == RT_WLAN_STATION);
  114. }
  115. else
  116. {
  117. return mp_obj_new_bool(rt_wlan_get_mode("wlan1") == RT_WLAN_AP);
  118. }
  119. }
  120. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_active_obj, 1, 2, wlan_active);
  121. STATIC mp_obj_t wlan_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  122. enum { ARG_ssid, ARG_password, ARG_bssid };
  123. static const mp_arg_t allowed_args[] = {
  124. { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
  125. { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
  126. { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
  127. };
  128. // parse args
  129. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  130. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  131. require_if(pos_args[0], STATION_IF);
  132. const char *ssid = RT_NULL;
  133. const char *key = RT_NULL;
  134. size_t len;
  135. const char *p;
  136. // set parameters based on given args
  137. if (args[ARG_ssid].u_obj != mp_const_none) {
  138. p = mp_obj_str_get_data(args[ARG_ssid].u_obj, &len);
  139. ssid = p;
  140. }
  141. if (args[ARG_password].u_obj != mp_const_none) {
  142. p = mp_obj_str_get_data(args[ARG_password].u_obj, &len);
  143. key = p;
  144. }
  145. error_check(rt_wlan_connect(ssid, key) == RT_EOK, "Cannot connect to AP");
  146. return mp_const_none;
  147. }
  148. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_connect_obj, 1, wlan_connect);
  149. STATIC mp_obj_t wlan_disconnect(mp_obj_t self_in) {
  150. require_if(self_in, STATION_IF);
  151. error_check(rt_wlan_disconnect() == RT_EOK, "Cannot disconnect from AP");
  152. return mp_const_none;
  153. }
  154. STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_disconnect_obj, wlan_disconnect);
  155. STATIC mp_obj_t wlan_status(size_t n_args, const mp_obj_t *args) {
  156. wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
  157. if (n_args == 1) {
  158. // Get link status
  159. if (self->if_id == STATION_IF) {
  160. if(rt_wlan_is_ready() == RT_EOK)
  161. {
  162. return MP_OBJ_NEW_SMALL_INT(STATION_GOT_IP);
  163. }
  164. else
  165. {
  166. return MP_OBJ_NEW_SMALL_INT(STATION_IDLE);
  167. }
  168. }
  169. return MP_OBJ_NEW_SMALL_INT(-1);
  170. } else {
  171. // Get specific status parameter
  172. switch (mp_obj_str_get_qstr(args[1])) {
  173. case MP_QSTR_rssi:
  174. if (self->if_id == STATION_IF) {
  175. return MP_OBJ_NEW_SMALL_INT(rt_wlan_get_rssi());
  176. }
  177. }
  178. mp_raise_ValueError("unknown status param");
  179. }
  180. }
  181. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_status_obj, 1, 2, wlan_status);
  182. #if (RTTHREAD_VERSION >= RT_VERSION_CHECK(4, 1, 0)) && defined(RT_USING_WIFI)
  183. #include <wlan_mgnt.h>
  184. #include <wlan_prot.h>
  185. #include <wlan_cfg.h>
  186. static struct rt_semaphore scan_done;
  187. struct rt_wlan_scan_result *scan_result_cache = RT_NULL;
  188. static void wlan_scan_report_hander(int event,struct rt_wlan_buff *buff,void *parameter)
  189. {
  190. struct rt_wlan_info *info = RT_NULL;
  191. int index = 0;
  192. int ret = RT_EOK;
  193. RT_ASSERT(event == RT_WLAN_EVT_SCAN_REPORT);
  194. RT_ASSERT(buff != RT_NULL);
  195. RT_ASSERT(parameter != RT_NULL);
  196. info = (struct rt_wlan_info *)buff->data;
  197. index = *((int *)(parameter));
  198. if (scan_result_cache == RT_NULL)
  199. {
  200. RT_ASSERT(index == 0);
  201. scan_result_cache = rt_malloc(sizeof(struct rt_wlan_scan_result) + (rt_ubase_t)sizeof(struct rt_wlan_info));
  202. scan_result_cache->num = 0;
  203. scan_result_cache->info = (struct rt_wlan_info *)(rt_ubase_t)((rt_ubase_t)&scan_result_cache->info + sizeof(struct rt_wlan_info *));
  204. }
  205. else
  206. {
  207. scan_result_cache = rt_realloc(scan_result_cache, sizeof(struct rt_wlan_scan_result) +
  208. (uint32_t)sizeof(struct rt_wlan_info) * (index + 1));
  209. scan_result_cache->info = (struct rt_wlan_info *)(rt_ubase_t)((rt_ubase_t)&scan_result_cache->info + sizeof(struct rt_wlan_info *));
  210. }
  211. if (scan_result_cache == RT_NULL)
  212. {
  213. LOG_E("malloc failed!");
  214. }
  215. rt_memcpy(&(scan_result_cache->info)[index], info, sizeof(struct rt_wlan_info));
  216. scan_result_cache->num = index + 1;
  217. ++ *((int *)(parameter));
  218. }
  219. static void wlan_scan_done_hander(int event,struct rt_wlan_buff *buff,void *parameter)
  220. {
  221. RT_ASSERT(event == RT_WLAN_EVT_SCAN_DONE);
  222. rt_sem_release(&scan_done);
  223. }
  224. struct rt_wlan_scan_result *rt_wlan_scan_sync(void)
  225. {
  226. static int _init = 0;
  227. static int i = 0;
  228. LOG_D("start to scan ap ...");
  229. if (!_init)
  230. {
  231. _init = 1;
  232. rt_sem_init(&scan_done, "scan_done", 0 , RT_IPC_FLAG_FIFO);
  233. }
  234. rt_wlan_register_event_handler(RT_WLAN_EVT_SCAN_REPORT, wlan_scan_report_hander,&i);
  235. rt_wlan_register_event_handler(RT_WLAN_EVT_SCAN_DONE, wlan_scan_done_hander,RT_NULL);
  236. if(rt_wlan_scan() == RT_EOK)
  237. {
  238. LOG_D("the scan is started... ");
  239. }
  240. else
  241. {
  242. LOG_E("scan failed");
  243. }
  244. rt_sem_take(&scan_done, RT_WAITING_FOREVER);
  245. i = 0;
  246. return scan_result_cache;
  247. }
  248. void rt_wlan_scan_result_clean(void)
  249. {
  250. if(scan_result_cache)
  251. {
  252. rt_free(scan_result_cache);
  253. scan_result_cache = 0;
  254. }
  255. }
  256. #endif
  257. STATIC mp_obj_t *wlan_scan_list = NULL;
  258. void wlan_station_scan(void)
  259. {
  260. if (wlan_scan_list == NULL) {
  261. // called unexpectedly
  262. return;
  263. }
  264. struct rt_wlan_scan_result *scan_result = RT_NULL;
  265. /* scan ap info */
  266. scan_result = rt_wlan_scan_sync();
  267. if (scan_result)
  268. {
  269. int index, num;
  270. char *security;
  271. num = scan_result->num;
  272. for (index = 0; index < num; index ++)
  273. {
  274. switch (scan_result->info[index].security)
  275. {
  276. case SECURITY_OPEN:
  277. security = "OPEN";
  278. break;
  279. case SECURITY_WEP_PSK:
  280. security = "WEP_PSK";
  281. break;
  282. case SECURITY_WEP_SHARED:
  283. security = "WEP_SHARED";
  284. break;
  285. case SECURITY_WPA_TKIP_PSK:
  286. security = "WPA_TKIP_PSK";
  287. break;
  288. case SECURITY_WPA_AES_PSK:
  289. security = "WPA_AES_PSK";
  290. break;
  291. case SECURITY_WPA2_AES_PSK:
  292. security = "WPA2_AES_PSK";
  293. break;
  294. case SECURITY_WPA2_TKIP_PSK:
  295. security = "WPA2_TKIP_PSK";
  296. break;
  297. case SECURITY_WPA2_MIXED_PSK:
  298. security = "WPA2_MIXED_PSK";
  299. break;
  300. case SECURITY_WPS_OPEN:
  301. security = "WPS_OPEN";
  302. break;
  303. case SECURITY_WPS_SECURE:
  304. security = "WPS_SECURE";
  305. break;
  306. default:
  307. security = "UNKNOWN";
  308. break;
  309. }
  310. mp_obj_tuple_t *t = mp_obj_new_tuple(6, NULL);
  311. t->items[0] = mp_obj_new_bytes(&scan_result->info[index].ssid.val[0], strlen((char *)(&scan_result->info[index].ssid.val[0])));
  312. t->items[1] = mp_obj_new_bytes(&scan_result->info[index].bssid[0], strlen((char *)(&scan_result->info[index].bssid[0])));
  313. t->items[2] = MP_OBJ_NEW_SMALL_INT(scan_result->info[index].channel);
  314. t->items[3] = MP_OBJ_NEW_SMALL_INT(scan_result->info[index].rssi);
  315. t->items[4] = mp_obj_new_bytes((const byte *)security, strlen(security));
  316. t->items[5] = MP_OBJ_NEW_SMALL_INT(scan_result->info[index].hidden);
  317. mp_obj_list_append(*wlan_scan_list, MP_OBJ_FROM_PTR(t));
  318. }
  319. rt_wlan_scan_result_clean();
  320. }
  321. else
  322. {
  323. mp_printf(&mp_plat_print, ("wifi scan result is null\n"));
  324. *wlan_scan_list = MP_OBJ_NULL;
  325. }
  326. }
  327. STATIC mp_obj_t wlan_scan(mp_obj_t self_in) {
  328. require_if(self_in, STATION_IF);
  329. mp_obj_t list = mp_obj_new_list(0, NULL);
  330. wlan_scan_list = &list;
  331. wlan_station_scan();
  332. if (list == MP_OBJ_NULL) {
  333. nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "scan failed"));
  334. }
  335. return list;
  336. }
  337. STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_scan_obj, wlan_scan);
  338. /// \method isconnected()
  339. /// Return True if connected to an AP and an IP address has been assigned,
  340. /// false otherwise.
  341. STATIC mp_obj_t wlan_isconnected(mp_obj_t self_in) {
  342. wlan_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
  343. if (self->if_id == STATION_IF) {
  344. if (rt_wlan_is_connected() == RT_TRUE) {
  345. return mp_const_true;
  346. }
  347. } else {
  348. if (rt_wlan_ap_get_sta_num() > 0) {
  349. return mp_const_true;
  350. }
  351. }
  352. return mp_const_false;
  353. }
  354. STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_isconnected_obj, wlan_isconnected);
  355. STATIC mp_obj_t wlan_ifconfig(size_t n_args, const mp_obj_t *args) {
  356. wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
  357. struct netdev *netdev = netdev_default;
  358. if (netdev == RT_NULL)
  359. {
  360. mp_printf(&mp_plat_print, ("not find wlan interface device.\n"));
  361. return MP_OBJ_NEW_SMALL_INT(-1);
  362. }
  363. if (n_args == 1) {
  364. // get
  365. mp_obj_t tuple[4] = {
  366. mp_obj_new_str((const char *)inet_ntoa(netdev->ip_addr), strlen((char *)(inet_ntoa(netdev->ip_addr)))),
  367. mp_obj_new_str((const char *)inet_ntoa(netdev->netmask), strlen((char *)(inet_ntoa(netdev->netmask)))),
  368. mp_obj_new_str((const char *)inet_ntoa(netdev->gw), strlen((char *)(inet_ntoa(netdev->gw)))),
  369. mp_obj_new_str((const char *)inet_ntoa(netdev->dns_servers), strlen((char *)(inet_ntoa(netdev->dns_servers)))),
  370. };
  371. return mp_obj_new_tuple(4, tuple);
  372. }
  373. else
  374. {
  375. // set
  376. mp_obj_t *items;
  377. uint8_t ip_addr[4];
  378. uint8_t netmask[4];
  379. uint8_t gw[4];
  380. uint8_t dns_server[4];
  381. mp_obj_get_array_fixed_n(args[1], 4, &items);
  382. netutils_parse_ipv4_addr(items[0], (uint8_t *)ip_addr, NETUTILS_BIG);
  383. netutils_parse_ipv4_addr(items[1], (uint8_t *)netmask, NETUTILS_BIG);
  384. netutils_parse_ipv4_addr(items[2], (uint8_t *)gw , NETUTILS_BIG);
  385. netutils_parse_ipv4_addr(items[3], (uint8_t *)dns_server, NETUTILS_BIG);
  386. // To set a static IP we have to disable DHCP first
  387. if (self->if_id == STATION_IF) {
  388. if(netdev_dhcp_enabled(netdev, 0) == RT_EOK)
  389. {
  390. if (netdev_set_ipaddr(netdev, (const ip_addr_t *)ip_addr) != RT_EOK)
  391. {
  392. nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "netdev_set_ipaddr() failed"));
  393. }
  394. }
  395. else
  396. {
  397. nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "netdev_dhcp_enabled() failed"));
  398. }
  399. }
  400. else
  401. {
  402. // TODO modify IP netmask gw under AP mode
  403. netdev_set_dns_server(netdev, 0, (const ip_addr_t *)dns_server);
  404. return mp_const_none;
  405. }
  406. netdev_set_netmask(netdev, (const ip_addr_t *)netmask);
  407. netdev_set_gw(netdev, (const ip_addr_t *)gw);
  408. netdev_set_dns_server(netdev, 0, (const ip_addr_t *)dns_server);
  409. }
  410. return mp_const_none;
  411. }
  412. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_ifconfig_obj, 1, 2, wlan_ifconfig);
  413. STATIC mp_obj_t wlan_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
  414. if (n_args != 1 && kwargs->used != 0) {
  415. mp_raise_TypeError("either pos or kw args are allowed");
  416. }
  417. wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
  418. struct rt_wlan_info cfg = {0};
  419. if (self->if_id == STATION_IF) {
  420. error_check(rt_wlan_get_info(&cfg) == RT_EOK, "can't get STA config");
  421. } else {
  422. error_check(rt_wlan_ap_get_info(&cfg) == RT_EOK, "can't get AP config");
  423. }
  424. int req_if = -1;
  425. if (kwargs->used != 0) {
  426. for (mp_uint_t i = 0; i < kwargs->alloc; i++) {
  427. if (mp_map_slot_is_filled(kwargs, i)) {
  428. #define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x)
  429. switch ((uintptr_t)kwargs->table[i].key) {
  430. case QS(MP_QSTR_mac): {
  431. mp_buffer_info_t bufinfo;
  432. mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ);
  433. if (bufinfo.len != 6) {
  434. mp_raise_ValueError("invalid buffer length");
  435. }
  436. error_check(rt_wlan_set_mac((rt_uint8_t *)bufinfo.buf) == RT_EOK, "can't set MAC");
  437. break;
  438. }
  439. case QS(MP_QSTR_essid): {
  440. req_if = SOFTAP_IF;
  441. size_t len;
  442. const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len);
  443. len = MIN(len, sizeof(_ap_info.ssid.val));
  444. memcpy(_ap_info.ssid.val, s, len);
  445. _ap_info.ssid.len = len;
  446. break;
  447. }
  448. case QS(MP_QSTR_hidden): {
  449. req_if = SOFTAP_IF;
  450. _ap_info.hidden = mp_obj_is_true(kwargs->table[i].value);
  451. break;
  452. }
  453. // case QS(MP_QSTR_authmode): {
  454. // req_if = SOFTAP_IF;
  455. // cfg.ap.authmode = mp_obj_get_int(kwargs->table[i].value);
  456. // break;
  457. // }
  458. case QS(MP_QSTR_password): {
  459. req_if = SOFTAP_IF;
  460. size_t len;
  461. const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len);
  462. len = MIN(len, sizeof(_ap_password) - 1);
  463. memcpy(_ap_password, s, len);
  464. _ap_password[len] = 0;
  465. break;
  466. }
  467. case QS(MP_QSTR_channel): {
  468. req_if = SOFTAP_IF;
  469. _ap_info.channel = mp_obj_get_int(kwargs->table[i].value);
  470. break;
  471. }
  472. // case QS(MP_QSTR_dhcp_hostname): {
  473. // req_if = STATION_IF;
  474. // if (self->if_id == STATION_IF) {
  475. // const char *s = mp_obj_str_get_str(kwargs->table[i].value);
  476. // wifi_station_set_hostname((char*)s);
  477. // }
  478. // break;
  479. // }
  480. default:
  481. goto unknown;
  482. }
  483. #undef QS
  484. }
  485. }
  486. // We post-check interface requirements to save on code size
  487. if (req_if >= 0) {
  488. require_if(args[0], req_if);
  489. }
  490. return mp_const_none;
  491. }
  492. // Get config
  493. if (n_args != 2) {
  494. mp_raise_TypeError("can query only one param");
  495. }
  496. mp_obj_t val;
  497. qstr key = mp_obj_str_get_qstr(args[1]);
  498. switch (key) {
  499. case MP_QSTR_mac: {
  500. uint8_t mac[6];
  501. error_check(rt_wlan_get_mac(mac) == RT_EOK, "can't get mac config");
  502. return mp_obj_new_bytes(mac, sizeof(mac));
  503. }
  504. case MP_QSTR_essid:
  505. if (self->if_id == STATION_IF) {
  506. val = mp_obj_new_str((char*)cfg.ssid.val, strlen((char*)cfg.ssid.val));
  507. } else {
  508. val = mp_obj_new_str((char*)_ap_info.ssid.val, _ap_info.ssid.len);
  509. }
  510. break;
  511. case MP_QSTR_hidden:
  512. req_if = SOFTAP_IF;
  513. val = mp_obj_new_bool(cfg.hidden);
  514. break;
  515. // case MP_QSTR_authmode:
  516. // req_if = SOFTAP_IF;
  517. // val = MP_OBJ_NEW_SMALL_INT(cfg.ap.authmode);
  518. // break;
  519. case MP_QSTR_channel:
  520. req_if = SOFTAP_IF;
  521. val = MP_OBJ_NEW_SMALL_INT(cfg.channel);
  522. break;
  523. // case MP_QSTR_dhcp_hostname: {
  524. // req_if = STATION_IF;
  525. // char* s = wifi_station_get_hostname();
  526. // if (s == NULL) {
  527. // val = MP_OBJ_NEW_QSTR(MP_QSTR_);
  528. // } else {
  529. // val = mp_obj_new_str(s, strlen(s));
  530. // }
  531. // break;
  532. // }
  533. default:
  534. goto unknown;
  535. }
  536. // We post-check interface requirements to save on code size
  537. if (req_if >= 0) {
  538. require_if(args[0], req_if);
  539. }
  540. return val;
  541. unknown:
  542. mp_raise_ValueError("unknown config param");
  543. }
  544. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_config_obj, 1, wlan_config);
  545. STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = {
  546. { MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&wlan_active_obj) },
  547. { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&wlan_connect_obj) },
  548. { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&wlan_disconnect_obj) },
  549. { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&wlan_status_obj) },
  550. { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&wlan_scan_obj) },
  551. { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wlan_isconnected_obj) },
  552. { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&wlan_config_obj) },
  553. { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wlan_ifconfig_obj) },
  554. #if MODNETWORK_INCLUDE_CONSTANTS
  555. { MP_ROM_QSTR(MP_QSTR_STAT_IDLE), MP_ROM_INT(STATION_IDLE)},
  556. { MP_ROM_QSTR(MP_QSTR_STAT_CONNECTING), MP_ROM_INT(STATION_CONNECTING)},
  557. { MP_ROM_QSTR(MP_QSTR_STAT_WRONG_PASSWORD), MP_ROM_INT(STATION_WRONG_PASSWORD)},
  558. { MP_ROM_QSTR(MP_QSTR_STAT_NO_AP_FOUND), MP_ROM_INT(STATION_NO_AP_FOUND)},
  559. { MP_ROM_QSTR(MP_QSTR_STAT_CONNECT_FAIL), MP_ROM_INT(STATION_CONNECT_FAIL)},
  560. { MP_ROM_QSTR(MP_QSTR_STAT_GOT_IP), MP_ROM_INT(STATION_GOT_IP)},
  561. // { MP_ROM_QSTR(MP_QSTR_MODE_11B), MP_ROM_INT(PHY_MODE_11B) },
  562. // { MP_ROM_QSTR(MP_QSTR_MODE_11G), MP_ROM_INT(PHY_MODE_11G) },
  563. // { MP_ROM_QSTR(MP_QSTR_MODE_11N), MP_ROM_INT(PHY_MODE_11N) },
  564. // { MP_ROM_QSTR(MP_QSTR_AUTH_OPEN), MP_ROM_INT(AUTH_OPEN) },
  565. // { MP_ROM_QSTR(MP_QSTR_AUTH_WEP), MP_ROM_INT(AUTH_WEP) },
  566. // { MP_ROM_QSTR(MP_QSTR_AUTH_WPA_PSK), MP_ROM_INT(AUTH_WPA_PSK) },
  567. // { MP_ROM_QSTR(MP_QSTR_AUTH_WPA2_PSK), MP_ROM_INT(AUTH_WPA2_PSK) },
  568. // { MP_ROM_QSTR(MP_QSTR_AUTH_WPA_WPA2_PSK), MP_ROM_INT(AUTH_WPA_WPA2_PSK) },
  569. #endif
  570. };
  571. STATIC MP_DEFINE_CONST_DICT(wlan_if_locals_dict, wlan_if_locals_dict_table);
  572. const mp_obj_type_t wlan_if_type = {
  573. { &mp_type_type },
  574. .name = MP_QSTR_WLAN,
  575. .locals_dict = (mp_obj_dict_t*)&wlan_if_locals_dict,
  576. };
  577. #endif