wlan_cmd.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  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_STA_NAME
  38. #define WIFI_DEVICE_STA_NAME "w0"
  39. #endif
  40. #ifndef WIFI_DEVICE_AP_NAME
  41. #define WIFI_DEVICE_AP_NAME "ap"
  42. #endif
  43. #ifdef RT_USING_DFS
  44. #include <dfs_posix.h>
  45. #ifdef PKG_USING_CJSON
  46. #include <cJSON_util.h>
  47. #endif
  48. static char wifi_ssid[32] = {0};
  49. static char wifi_key[32] = {0};
  50. static int network_mode = WIFI_STATION;
  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. wifi_save_cfg(WIFI_SETTING_FN);
  209. return 0;
  210. }
  211. #endif
  212. int wifi_softap_setup_netif(struct netif *netif)
  213. {
  214. if (netif)
  215. {
  216. ip_addr_t *ip;
  217. ip_addr_t addr;
  218. #ifdef RT_LWIP_DHCP
  219. /* Stop DHCP Client */
  220. dhcp_stop(netif);
  221. #endif
  222. /* set ipaddr, gw, netmask */
  223. ip = (ip_addr_t *)&addr;
  224. /* set ip address */
  225. if (ipaddr_aton("192.168.169.1", &addr))
  226. {
  227. netif_set_ipaddr(netif, ip);
  228. }
  229. /* set gateway address */
  230. if ( ipaddr_aton("192.168.169.1", &addr))
  231. {
  232. netif_set_gw(netif, ip);
  233. }
  234. /* set netmask address */
  235. if ( ipaddr_aton("255.255.255.0", &addr))
  236. {
  237. netif_set_netmask(netif, ip);
  238. }
  239. netif_set_up(netif);
  240. #ifdef LWIP_USING_DHCPD
  241. {
  242. char name[8];
  243. memset(name, 0, sizeof(name));
  244. strncpy(name, netif->name, sizeof(name)>sizeof(netif->name)? sizeof(netif->name) : sizeof(name));
  245. dhcpd_start(name);
  246. }
  247. #endif
  248. }
  249. return 0;
  250. }
  251. int wifi_default(void)
  252. {
  253. int result = 0;
  254. struct rt_wlan_device *wlan;
  255. /* read default setting for wifi */
  256. wifi_read_cfg(WIFI_SETTING_FN);
  257. if (network_mode == WIFI_STATION)
  258. {
  259. /* get wlan device */
  260. wlan = (struct rt_wlan_device*)rt_device_find(WIFI_DEVICE_STA_NAME);
  261. if (!wlan)
  262. {
  263. rt_kprintf("no wlan:%s device\n", WIFI_DEVICE_STA_NAME);
  264. return -1;
  265. }
  266. /* wifi station */
  267. rt_wlan_info_init(&info, WIFI_STATION, SECURITY_WPA2_MIXED_PSK, wifi_ssid);
  268. result =rt_wlan_init(wlan, WIFI_STATION);
  269. if (result == RT_EOK)
  270. {
  271. result = rt_wlan_connect(wlan, &info, wifi_key);
  272. }
  273. }
  274. else
  275. {
  276. /* wifi AP */
  277. /* get wlan device */
  278. wlan = (struct rt_wlan_device*)rt_device_find(WIFI_DEVICE_AP_NAME);
  279. if (!wlan)
  280. {
  281. rt_kprintf("no wlan:%s device\n", WIFI_DEVICE_AP_NAME);
  282. return -1;
  283. }
  284. rt_wlan_info_init(&info, WIFI_AP, SECURITY_WPA2_AES_PSK, wifi_ssid);
  285. info.channel = 11;
  286. /* wifi soft-AP */
  287. result =rt_wlan_init(wlan, WIFI_AP);
  288. if (result == RT_EOK)
  289. {
  290. result = rt_wlan_softap(wlan, &info, wifi_key);
  291. }
  292. }
  293. return result;
  294. }
  295. static void wifi_usage(void)
  296. {
  297. rt_kprintf("wifi wlan_dev - do the default wifi action\n");
  298. rt_kprintf("wifi wlan_dev join SSID PASSWORD\n");
  299. rt_kprintf("wifi wlan_dev ap SSID [PASSWORD]\n");
  300. rt_kprintf("wifi cfg SSID PASSWORD\n");
  301. rt_kprintf("wifi wlan_dev up\n");
  302. rt_kprintf("wifi wlan_dev down\n");
  303. rt_kprintf("wifi wlan_dev rssi\n");
  304. }
  305. int wifi(int argc, char** argv)
  306. {
  307. struct rt_wlan_device *wlan;
  308. if (argc == 1)
  309. {
  310. wifi_default();
  311. return 0;
  312. }
  313. if (strcmp(argv[1], "help") == 0)
  314. {
  315. wifi_usage();
  316. return 0;
  317. }
  318. if (strcmp(argv[1], "cfg") == 0)
  319. {
  320. /* configure wifi setting */
  321. memset(wifi_ssid, 0x0, sizeof(wifi_ssid));
  322. rt_strncpy(wifi_ssid, argv[2], sizeof(wifi_ssid) - 1);
  323. memset(wifi_key, 0x0, sizeof(wifi_key));
  324. rt_strncpy(wifi_key, argv[3], sizeof(wifi_key) - 1);
  325. network_mode = WIFI_STATION;
  326. wifi_save_cfg(WIFI_SETTING_FN);
  327. return 0;
  328. }
  329. /* get wlan device */
  330. wlan = (struct rt_wlan_device*)rt_device_find(argv[1]);
  331. if (!wlan)
  332. {
  333. rt_kprintf("no wlan:%s device\n", argv[1]);
  334. return 0;
  335. }
  336. if (argc < 3)
  337. {
  338. wifi_usage();
  339. return 0;
  340. }
  341. if (strcmp(argv[2], "join") == 0)
  342. {
  343. rt_wlan_init(wlan, WIFI_STATION);
  344. network_mode = WIFI_STATION;
  345. /* TODO: use easy-join to replace */
  346. rt_wlan_info_init(&info, WIFI_STATION, SECURITY_WPA2_MIXED_PSK, argv[3]);
  347. rt_wlan_connect(wlan, &info, argv[4]);
  348. }
  349. else if (strcmp(argv[2], "up") == 0)
  350. {
  351. /* the key was saved in wlan device */
  352. rt_wlan_connect(wlan, RT_NULL, wlan->key);
  353. }
  354. else if (strcmp(argv[2], "down") == 0)
  355. {
  356. rt_wlan_disconnect(wlan);
  357. }
  358. else if (strcmp(argv[2], "scan") == 0)
  359. {
  360. struct rt_wlan_info *infos;
  361. infos = (struct rt_wlan_info*)rt_malloc(sizeof(struct rt_wlan_info) * 12);
  362. if (infos)
  363. {
  364. int index, num;
  365. memset(infos, 0x0, sizeof(struct rt_wlan_info) * 12);
  366. num = rt_wlan_scan(wlan, infos, 12);
  367. for (index = 0; index < num; index ++)
  368. {
  369. rt_kprintf("----Wi-Fi AP[%d] Information----\n", index);
  370. rt_kprintf("SSID: %-.32s\n", infos[index].ssid);
  371. rt_kprintf("rssi: %d\n", infos[index].rssi);
  372. rt_kprintf(" chn: %d\n", infos[index].channel);
  373. rt_kprintf("rate: %d\n", infos[index].datarate);
  374. rt_kprintf("\n");
  375. }
  376. /* de-initialize info */
  377. for (index = 0; index < num; index ++)
  378. {
  379. rt_wlan_info_deinit(&infos[index]);
  380. }
  381. rt_free(infos);
  382. }
  383. }
  384. else if (strcmp(argv[2], "rssi") == 0)
  385. {
  386. int rssi;
  387. rssi = rt_wlan_get_rssi(wlan);
  388. rt_kprintf("rssi=%d\n", rssi);
  389. }
  390. else if (strcmp(argv[2], "ap") == 0)
  391. {
  392. rt_err_t result = RT_EOK;
  393. if (argc == 4)
  394. {
  395. // open soft-AP
  396. rt_wlan_info_init(&info, WIFI_AP, SECURITY_OPEN, argv[3]);
  397. info.channel = 11;
  398. result =rt_wlan_init(wlan, WIFI_AP);
  399. /* start soft ap */
  400. result = rt_wlan_softap(wlan, &info, NULL);
  401. if (result == RT_EOK)
  402. {
  403. network_mode = WIFI_AP;
  404. }
  405. }
  406. else if (argc == 5)
  407. {
  408. // WPA2 with password
  409. rt_wlan_info_init(&info, WIFI_AP, SECURITY_WPA2_AES_PSK, argv[3]);
  410. info.channel = 11;
  411. result =rt_wlan_init(wlan, WIFI_AP);
  412. /* start soft ap */
  413. result = rt_wlan_softap(wlan, &info, argv[4]);
  414. if (result == RT_EOK)
  415. {
  416. network_mode = WIFI_AP;
  417. }
  418. }
  419. else
  420. {
  421. wifi_usage();
  422. }
  423. if (result != RT_EOK)
  424. {
  425. rt_kprintf("wifi start failed! result=%d\n", result);
  426. }
  427. }
  428. else if (strcmp(argv[2], "status") == 0)
  429. {
  430. int rssi;
  431. if (netif_is_link_up(wlan->parent.netif))
  432. {
  433. rssi = rt_wlan_get_rssi(wlan);
  434. rt_kprintf("Wi-Fi AP: %-.32s\n", wlan->info->ssid);
  435. rt_kprintf("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n", wlan->info->bssid[0],
  436. wlan->info->bssid[1],
  437. wlan->info->bssid[2],
  438. wlan->info->bssid[3],
  439. wlan->info->bssid[4],
  440. wlan->info->bssid[5]);
  441. rt_kprintf(" Channel: %d\n", wlan->info->channel);
  442. rt_kprintf("DataRate: %dMbps\n", wlan->info->datarate/1000);
  443. rt_kprintf(" RSSI: %d\n", rssi);
  444. }
  445. else
  446. {
  447. rt_kprintf("wifi disconnected!\n");
  448. }
  449. return 0;
  450. }
  451. return 0;
  452. }
  453. MSH_CMD_EXPORT(wifi, wifi command);