wlan_cmd.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /*
  2. * File : wlan_cmd.c
  3. * Wi-Fi common commands
  4. * This file is part of RT-Thread RTOS
  5. * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Change Logs:
  22. * Date Author Notes
  23. * 2016-03-12 Bernard first version
  24. */
  25. #include <rtthread.h>
  26. #include <wlan_dev.h>
  27. #include <finsh.h>
  28. #include <lwip/dhcp.h>
  29. #include "wlan_cmd.h"
  30. #ifdef LWIP_USING_DHCPD
  31. #include <dhcp_server.h>
  32. #endif
  33. struct rt_wlan_info info;
  34. static char wifi_ssid[32] = {0};
  35. static char wifi_key[32] = {0};
  36. static int network_mode = WIFI_STATION;
  37. #define WLAN_DEBUG 1
  38. #if WLAN_DEBUG
  39. #define WLAN_DBG(...) rt_kprintf("[WLAN]"),rt_kprintf(__VA_ARGS__)
  40. #else
  41. #define WLAN_DBG(...)
  42. #endif
  43. #ifndef WIFI_SETTING_FN
  44. #define WIFI_SETTING_FN "/appfs/setting.json"
  45. #endif
  46. #ifndef WIFI_DEVICE_STA_NAME
  47. #define WIFI_DEVICE_STA_NAME "w0"
  48. #endif
  49. #ifndef WIFI_DEVICE_AP_NAME
  50. #define WIFI_DEVICE_AP_NAME "ap"
  51. #endif
  52. #ifdef RT_USING_DFS
  53. #include <dfs_posix.h>
  54. #ifdef PKG_USING_CJSON
  55. #include <cJSON_util.h>
  56. #endif
  57. int wifi_get_mode(void)
  58. {
  59. return network_mode;
  60. }
  61. int wifi_set_mode(int mode)
  62. {
  63. network_mode = mode;
  64. return network_mode;
  65. }
  66. int wifi_set_setting(const char *ssid, const char *pwd)
  67. {
  68. if (!ssid) return -1;
  69. strncpy(wifi_ssid, ssid, sizeof(wifi_ssid));
  70. wifi_ssid[sizeof(wifi_ssid) - 1] = '\0';
  71. if (pwd)
  72. {
  73. strncpy(wifi_key, pwd, sizeof(wifi_key));
  74. wifi_key[sizeof(wifi_key) - 1] = '\0';
  75. }
  76. else wifi_key[0] = '\0';
  77. return 0;
  78. }
  79. #ifdef PKG_USING_CJSON
  80. int wifi_read_cfg(const char *filename)
  81. {
  82. int fd;
  83. cJSON *json = RT_NULL;
  84. fd = open(filename, O_RDONLY, 0);
  85. if (fd < 0)
  86. {
  87. /* no setting file */
  88. return -1;
  89. }
  90. if (fd >= 0)
  91. {
  92. int length;
  93. length = lseek(fd, 0, SEEK_END);
  94. if (length)
  95. {
  96. char *json_str = (char *) rt_malloc(length);
  97. if (json_str)
  98. {
  99. lseek(fd, 0, SEEK_SET);
  100. read(fd, json_str, length);
  101. json = cJSON_Parse(json_str);
  102. rt_free(json_str);
  103. }
  104. }
  105. close(fd);
  106. }
  107. if (json)
  108. {
  109. cJSON *wifi = cJSON_GetObjectItem(json, "wifi");
  110. cJSON *ssid = cJSON_GetObjectItem(wifi, "SSID");
  111. cJSON *key = cJSON_GetObjectItem(wifi, "Key");
  112. cJSON *mode = cJSON_GetObjectItem(wifi, "Mode");
  113. if (ssid)
  114. {
  115. memset(wifi_ssid, 0x0, sizeof(wifi_ssid));
  116. rt_strncpy(wifi_ssid, ssid->valuestring, sizeof(wifi_ssid) - 1);
  117. }
  118. if (key)
  119. {
  120. memset(wifi_key, 0x0, sizeof(wifi_key));
  121. rt_strncpy(wifi_key, key->valuestring, sizeof(wifi_key) - 1);
  122. }
  123. if (mode)
  124. {
  125. network_mode = mode->valueint;
  126. }
  127. cJSON_Delete(json);
  128. }
  129. return 0;
  130. }
  131. int wifi_save_cfg(const char *filename)
  132. {
  133. int fd;
  134. cJSON *json = RT_NULL;
  135. fd = open(filename, O_RDONLY, 0);
  136. if (fd >= 0)
  137. {
  138. int length;
  139. length = lseek(fd, 0, SEEK_END);
  140. if (length)
  141. {
  142. char *json_str = (char *) rt_malloc(length);
  143. if (json_str)
  144. {
  145. lseek(fd, 0, SEEK_SET);
  146. read(fd, json_str, length);
  147. json = cJSON_Parse(json_str);
  148. rt_free(json_str);
  149. }
  150. }
  151. close(fd);
  152. }
  153. else
  154. {
  155. /* create a new setting.json */
  156. fd = open(filename, O_WRONLY | O_TRUNC, 0);
  157. if (fd >= 0)
  158. {
  159. json = cJSON_CreateObject();
  160. if (json)
  161. {
  162. cJSON *wifi = cJSON_CreateObject();
  163. if (wifi)
  164. {
  165. char *json_str;
  166. cJSON_AddItemToObject(json, "wifi", wifi);
  167. cJSON_AddStringToObject(wifi, "SSID", wifi_ssid);
  168. cJSON_AddStringToObject(wifi, "Key", wifi_key);
  169. cJSON_AddNumberToObject(wifi, "Mode", network_mode);
  170. json_str = cJSON_Print(json);
  171. if (json_str)
  172. {
  173. write(fd, json_str, rt_strlen(json_str));
  174. cJSON_free(json_str);
  175. }
  176. }
  177. }
  178. }
  179. close(fd);
  180. return 0;
  181. }
  182. if (json)
  183. {
  184. cJSON *wifi = cJSON_GetObjectItem(json, "wifi");
  185. if (!wifi)
  186. {
  187. wifi = cJSON_CreateObject();
  188. cJSON_AddItemToObject(json, "wifi", wifi);
  189. }
  190. if (cJSON_GetObjectItem(wifi, "SSID"))cJSON_ReplaceItemInObject(wifi, "SSID", cJSON_CreateString(wifi_ssid));
  191. else cJSON_AddStringToObject(wifi, "SSID", wifi_ssid);
  192. if (cJSON_GetObjectItem(wifi, "Key")) cJSON_ReplaceItemInObject(wifi, "Key", cJSON_CreateString(wifi_key));
  193. else cJSON_AddStringToObject(wifi, "Key", wifi_key);
  194. if (cJSON_GetObjectItem(wifi, "Mode")) cJSON_ReplaceItemInObject(wifi, "Mode", cJSON_CreateNumber(network_mode));
  195. else cJSON_AddNumberToObject(wifi, "Mode", network_mode);
  196. fd = open(filename, O_WRONLY | O_TRUNC, 0);
  197. if (fd >= 0)
  198. {
  199. char *json_str = cJSON_Print(json);
  200. if (json_str)
  201. {
  202. write(fd, json_str, rt_strlen(json_str));
  203. cJSON_free(json_str);
  204. }
  205. close(fd);
  206. }
  207. cJSON_Delete(json);
  208. }
  209. return 0;
  210. }
  211. #endif
  212. int wifi_save_setting(void)
  213. {
  214. #ifdef PKG_USING_CJSON
  215. wifi_save_cfg(WIFI_SETTING_FN);
  216. #endif
  217. return 0;
  218. }
  219. #endif
  220. int wifi_softap_setup_netif(struct netif *netif)
  221. {
  222. if (netif)
  223. {
  224. #ifdef RT_LWIP_DHCP
  225. /* Stop DHCP Client */
  226. dhcp_stop(netif);
  227. #endif
  228. #ifdef LWIP_USING_DHCPD
  229. {
  230. char name[8];
  231. memset(name, 0, sizeof(name));
  232. strncpy(name, netif->name, sizeof(name) > sizeof(netif->name) ? sizeof(netif->name) : sizeof(name));
  233. dhcpd_start(name);
  234. }
  235. #endif
  236. }
  237. return 0;
  238. }
  239. int wifi_default(void)
  240. {
  241. int result = 0;
  242. struct rt_wlan_device *wlan;
  243. #ifdef PKG_USING_CJSON
  244. /* read default setting for wifi */
  245. wifi_read_cfg(WIFI_SETTING_FN);
  246. #endif
  247. if (network_mode == WIFI_STATION)
  248. {
  249. /* get wlan device */
  250. wlan = (struct rt_wlan_device *)rt_device_find(WIFI_DEVICE_STA_NAME);
  251. if (!wlan)
  252. {
  253. rt_kprintf("no wlan:%s device\n", WIFI_DEVICE_STA_NAME);
  254. return -1;
  255. }
  256. /* wifi station */
  257. rt_wlan_info_init(&info, WIFI_STATION, SECURITY_WPA2_MIXED_PSK, wifi_ssid);
  258. result = rt_wlan_init(wlan, WIFI_STATION);
  259. if (result == RT_EOK)
  260. {
  261. result = rt_wlan_connect(wlan, &info, wifi_key);
  262. }
  263. }
  264. else
  265. {
  266. /* wifi AP */
  267. /* get wlan device */
  268. wlan = (struct rt_wlan_device *)rt_device_find(WIFI_DEVICE_AP_NAME);
  269. if (!wlan)
  270. {
  271. rt_kprintf("no wlan:%s device\n", WIFI_DEVICE_AP_NAME);
  272. return -1;
  273. }
  274. rt_wlan_info_init(&info, WIFI_AP, SECURITY_WPA2_AES_PSK, wifi_ssid);
  275. info.channel = 11;
  276. /* wifi soft-AP */
  277. result = rt_wlan_init(wlan, WIFI_AP);
  278. if (result == RT_EOK)
  279. {
  280. result = rt_wlan_softap(wlan, &info, wifi_key);
  281. }
  282. }
  283. return result;
  284. }
  285. static void wifi_usage(void)
  286. {
  287. rt_kprintf("wifi help - Help information\n");
  288. rt_kprintf("wifi cfg SSID PASSWORD - Setting your router AP ssid and pwd\n");
  289. rt_kprintf("wifi - Do the default wifi action\n");
  290. rt_kprintf("wifi wlan_dev scan\n");
  291. rt_kprintf("wifi wlan_dev join SSID PASSWORD\n");
  292. rt_kprintf("wifi wlan_dev ap SSID [PASSWORD]\n");
  293. rt_kprintf("wifi wlan_dev up\n");
  294. rt_kprintf("wifi wlan_dev down\n");
  295. rt_kprintf("wifi wlan_dev rssi\n");
  296. rt_kprintf("wifi wlan_dev status\n");
  297. }
  298. int wifi(int argc, char **argv)
  299. {
  300. struct rt_wlan_device *wlan;
  301. if (argc == 1)
  302. {
  303. wifi_default();
  304. return 0;
  305. }
  306. if (strcmp(argv[1], "help") == 0)
  307. {
  308. wifi_usage();
  309. return 0;
  310. }
  311. if (strcmp(argv[1], "cfg") == 0)
  312. {
  313. /* configure wifi setting */
  314. memset(wifi_ssid, 0x0, sizeof(wifi_ssid));
  315. rt_strncpy(wifi_ssid, argv[2], sizeof(wifi_ssid) - 1);
  316. memset(wifi_key, 0x0, sizeof(wifi_key));
  317. rt_strncpy(wifi_key, argv[3], sizeof(wifi_key) - 1);
  318. network_mode = WIFI_STATION;
  319. #ifdef PKG_USING_CJSON
  320. wifi_save_cfg(WIFI_SETTING_FN);
  321. #endif
  322. return 0;
  323. }
  324. /* get wlan device */
  325. wlan = (struct rt_wlan_device *)rt_device_find(argv[1]);
  326. if (!wlan)
  327. {
  328. rt_kprintf("no wlan:%s device\n", argv[1]);
  329. return 0;
  330. }
  331. if (argc < 3)
  332. {
  333. wifi_usage();
  334. return 0;
  335. }
  336. if (strcmp(argv[2], "join") == 0)
  337. {
  338. rt_wlan_init(wlan, WIFI_STATION);
  339. network_mode = WIFI_STATION;
  340. /* TODO: use easy-join to replace */
  341. rt_wlan_info_init(&info, WIFI_STATION, SECURITY_WPA2_MIXED_PSK, argv[3]);
  342. rt_wlan_connect(wlan, &info, argv[4]);
  343. rt_wlan_info_deinit(&info);
  344. }
  345. else if (strcmp(argv[2], "up") == 0)
  346. {
  347. /* the key was saved in wlan device */
  348. rt_wlan_connect(wlan, RT_NULL, wlan->key);
  349. }
  350. else if (strcmp(argv[2], "down") == 0)
  351. {
  352. rt_wlan_disconnect(wlan);
  353. rt_wlan_info_deinit(&info);
  354. }
  355. else if (strcmp(argv[2], "scan") == 0)
  356. {
  357. struct rt_wlan_scan_result *scan_result = RT_NULL;
  358. rt_wlan_scan(wlan, &scan_result);
  359. if (scan_result)
  360. {
  361. int index, num;
  362. num = scan_result->ap_num;
  363. rt_kprintf(" SSID MAC rssi chn Mbps\n");
  364. rt_kprintf("------------------------------- ----------------- ---- --- ----\n");
  365. for (index = 0; index < num; index ++)
  366. {
  367. rt_kprintf("%-32.32s", scan_result->ap_table[index].ssid);
  368. rt_kprintf("%02x:%02x:%02x:%02x:%02x:%02x ",
  369. scan_result->ap_table[index].bssid[0],
  370. scan_result->ap_table[index].bssid[1],
  371. scan_result->ap_table[index].bssid[2],
  372. scan_result->ap_table[index].bssid[3],
  373. scan_result->ap_table[index].bssid[4],
  374. scan_result->ap_table[index].bssid[5]
  375. );
  376. rt_kprintf("%4d ", scan_result->ap_table[index].rssi);
  377. rt_kprintf("%2d ", scan_result->ap_table[index].channel);
  378. rt_kprintf("%d\n", scan_result->ap_table[index].datarate / 1000000);
  379. }
  380. }
  381. rt_wlan_release_scan_result(&scan_result);
  382. }
  383. else if (strcmp(argv[2], "rssi") == 0)
  384. {
  385. int rssi;
  386. rssi = rt_wlan_get_rssi(wlan);
  387. rt_kprintf("rssi=%d\n", rssi);
  388. }
  389. else if (strcmp(argv[2], "ap") == 0)
  390. {
  391. rt_err_t result = RT_EOK;
  392. if (argc == 4)
  393. {
  394. // open soft-AP
  395. rt_wlan_info_init(&info, WIFI_AP, SECURITY_OPEN, argv[3]);
  396. info.channel = 11;
  397. result = rt_wlan_init(wlan, WIFI_AP);
  398. /* start soft ap */
  399. result = rt_wlan_softap(wlan, &info, NULL);
  400. if (result == RT_EOK)
  401. {
  402. network_mode = WIFI_AP;
  403. }
  404. }
  405. else if (argc == 5)
  406. {
  407. // WPA2 with password
  408. rt_wlan_info_init(&info, WIFI_AP, SECURITY_WPA2_AES_PSK, argv[3]);
  409. info.channel = 11;
  410. result = rt_wlan_init(wlan, WIFI_AP);
  411. /* start soft ap */
  412. result = rt_wlan_softap(wlan, &info, argv[4]);
  413. if (result == RT_EOK)
  414. {
  415. network_mode = WIFI_AP;
  416. }
  417. }
  418. else
  419. {
  420. wifi_usage();
  421. }
  422. if (result != RT_EOK)
  423. {
  424. rt_kprintf("wifi start failed! result=%d\n", result);
  425. }
  426. }
  427. else if (strcmp(argv[2], "status") == 0)
  428. {
  429. int rssi;
  430. if (netif_is_link_up(wlan->parent.netif))
  431. {
  432. rssi = rt_wlan_get_rssi(wlan);
  433. rt_kprintf("Wi-Fi AP: %-.32s\n", wlan->info->ssid);
  434. rt_kprintf("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n", wlan->info->bssid[0],
  435. wlan->info->bssid[1],
  436. wlan->info->bssid[2],
  437. wlan->info->bssid[3],
  438. wlan->info->bssid[4],
  439. wlan->info->bssid[5]);
  440. rt_kprintf(" Channel: %d\n", wlan->info->channel);
  441. rt_kprintf("DataRate: %dMbps\n", wlan->info->datarate / 1000000);
  442. rt_kprintf(" RSSI: %d\n", rssi);
  443. }
  444. else
  445. {
  446. rt_kprintf("wifi disconnected!\n");
  447. }
  448. return 0;
  449. }
  450. return 0;
  451. }
  452. MSH_CMD_EXPORT(wifi, wifi command);