wlan_cmd.c 13 KB

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