wlan_cmd.c 13 KB

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