airkiss_demo.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. #include <rtthread.h>
  2. #include <rtdevice.h>
  3. #include <sys/socket.h>
  4. #include "../../airkiss.h"
  5. #include <stdlib.h>
  6. #define AKDEMO_BUFSZ 16
  7. static rt_list_t _bflist;
  8. static struct rt_mailbox _bfready;
  9. static int _akrun = 0;
  10. typedef struct
  11. {
  12. rt_list_t list;
  13. short fmlen;
  14. char f[24];
  15. } akbuf_t;
  16. typedef struct
  17. {
  18. char n;
  19. unsigned char tm;
  20. unsigned short cnt;
  21. } akchn_t;
  22. static akbuf_t *ak_bufinit(int cnt)
  23. {
  24. int i;
  25. akbuf_t *buf, *p;
  26. rt_list_init(&_bflist);
  27. buf = (akbuf_t *)rt_calloc(cnt, sizeof(akbuf_t));
  28. p = buf;
  29. for (i = 0; (i < cnt) && buf; i++)
  30. {
  31. p->fmlen = 0;
  32. rt_list_init(&p->list);
  33. rt_list_insert_after(&_bflist, &p->list);
  34. p++;
  35. }
  36. return buf;
  37. }
  38. static int _airkiss_filter(const void *f, int len)
  39. {
  40. int ret = 0;
  41. unsigned char *da, *p;
  42. int i;
  43. p = (unsigned char *)f;
  44. if ((len < 25) || (p[0] != 0x08))
  45. return 1;
  46. da = p + 4;
  47. for (i = 0; i < 6; i++)
  48. {
  49. if (da[i] != 0xFF)
  50. {
  51. ret = 1;
  52. break;
  53. }
  54. }
  55. return ret;
  56. }
  57. static void prom_callback(struct rt_wlan_device *device, void *d, int s)
  58. {
  59. akbuf_t *buf;
  60. if (_airkiss_filter(d, s))
  61. return;
  62. if (rt_list_isempty(&_bflist))
  63. {
  64. rt_kprintf("ak no buf\n");
  65. return;
  66. }
  67. buf = rt_list_first_entry(&_bflist, akbuf_t, list);
  68. rt_list_remove(&buf->list);
  69. rt_memcpy(buf->f, d, 24);
  70. buf->fmlen = s;
  71. if (rt_mb_send(&_bfready, (rt_ubase_t)buf) != 0)
  72. {
  73. rt_list_insert_before(&_bflist, &buf->list);
  74. rt_kprintf("ak send fail\n");
  75. }
  76. }
  77. static int ak_recv(airkiss_context_t *ac, int ms, int *rcnt)
  78. {
  79. akbuf_t *buf = 0;
  80. int status = AIRKISS_STATUS_CONTINUE;
  81. rt_tick_t st, max;
  82. int len = 0;
  83. st = rt_tick_get();
  84. while (1)
  85. {
  86. if (rt_mb_recv(&_bfready, (rt_ubase_t *)&buf, rt_tick_from_millisecond(10)) == 0)
  87. {
  88. status = airkiss_recv(ac, buf->f, buf->fmlen);
  89. rt_list_insert_after(&_bflist, &buf->list);
  90. if (status != AIRKISS_STATUS_CONTINUE)
  91. break;
  92. if (rcnt && (buf->fmlen != len))
  93. {
  94. (*rcnt)++;
  95. len = buf->fmlen;
  96. if (ms < 180)
  97. ms += 12;
  98. }
  99. }
  100. else
  101. {
  102. if ((ms > 30) && rcnt)
  103. ms -= 2;
  104. }
  105. max = rt_tick_from_millisecond(ms);
  106. if ((rt_tick_get() - st) > max)
  107. break;
  108. }
  109. return status;
  110. }
  111. static int ak_recv_chn(struct rt_wlan_device *dev,
  112. airkiss_context_t *ac, akchn_t *chn)
  113. {
  114. int status;
  115. int t;
  116. int rcnt = 0;
  117. rt_wlan_dev_set_channel(dev, chn->n);
  118. airkiss_change_channel(ac);
  119. status = ak_recv(ac, chn->tm, &rcnt);
  120. if (status == AIRKISS_STATUS_CHANNEL_LOCKED)
  121. {
  122. rt_kprintf("airkiss locked chn %d\n", chn->n);
  123. status = ak_recv(ac, 1000 * 30, RT_NULL);
  124. }
  125. chn->cnt += rcnt;
  126. if (chn->cnt > 5)
  127. chn->cnt -= 3;
  128. t = chn->cnt * chn->cnt * chn->cnt;
  129. if (t)
  130. {
  131. if (t > 170)
  132. t = 170;
  133. chn->tm = 30 + t;
  134. rt_kprintf("tm(%d) cnt(%d) on chn %d\n", chn->tm, chn->cnt, chn->n);
  135. }
  136. return status;
  137. }
  138. static void akchn_init(akchn_t *chn, int n)
  139. {
  140. int i;
  141. for (i = 0; i < n; i++)
  142. {
  143. chn[i].n = i + 1;
  144. chn[i].cnt = 0;
  145. chn[i].tm = 20;
  146. }
  147. }
  148. static int ak_wifi_connetct(char *ssid, char *passwd)
  149. {
  150. int result = RT_EOK;
  151. rt_uint8_t time_cnt = 0;
  152. #define NET_READY_TIME_OUT (rt_tick_from_millisecond(8 * 1000))
  153. result = rt_wlan_connect(ssid, passwd);
  154. if (result != RT_EOK)
  155. {
  156. rt_kprintf("\nconnect ssid %s error:%d!\n", ssid, result);
  157. return result;
  158. };
  159. do
  160. {
  161. rt_thread_mdelay(1000);
  162. time_cnt++;
  163. if (rt_wlan_is_ready())
  164. {
  165. break;
  166. }
  167. } while (time_cnt <= (NET_READY_TIME_OUT / 1000));
  168. if (time_cnt <= (NET_READY_TIME_OUT / 1000))
  169. {
  170. rt_kprintf("networking ready!\n");
  171. }
  172. else
  173. {
  174. rt_kprintf("wait ip got timeout!\n");
  175. result = -1;
  176. }
  177. return result;
  178. }
  179. static void airkiss_send_notification(uint8_t random)
  180. {
  181. int sock = -1;
  182. int udpbufsize = 2;
  183. struct sockaddr_in UDPBCAddr, UDPBCServerAddr;
  184. sock = socket(AF_INET, SOCK_DGRAM, 0);
  185. if (sock < 0)
  186. {
  187. rt_kprintf("notify create socket error!\n");
  188. goto _exit;
  189. }
  190. UDPBCAddr.sin_family = AF_INET;
  191. UDPBCAddr.sin_port = htons(10000);
  192. UDPBCAddr.sin_addr.s_addr = htonl(0xffffffff);
  193. rt_memset(&(UDPBCAddr.sin_zero), 0, sizeof(UDPBCAddr.sin_zero));
  194. UDPBCServerAddr.sin_family = AF_INET;
  195. UDPBCServerAddr.sin_port = htons(10000);
  196. UDPBCServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  197. rt_memset(&(UDPBCServerAddr.sin_zero), 0, sizeof(UDPBCServerAddr.sin_zero));
  198. if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &udpbufsize, sizeof(int)) != 0)
  199. {
  200. rt_kprintf("notify socket setsockopt error\n");
  201. goto _exit;
  202. }
  203. if (bind(sock, (struct sockaddr *)&UDPBCServerAddr, sizeof(UDPBCServerAddr)) != 0)
  204. {
  205. rt_kprintf("notify socket bind error\n");
  206. goto _exit;
  207. }
  208. for (int i = 0; i <= 20; i++)
  209. {
  210. int ret = sendto(sock, (char *)&random, 1, 0, (struct sockaddr *)&UDPBCAddr, sizeof(UDPBCAddr));
  211. rt_thread_mdelay(10);
  212. }
  213. _exit:
  214. if (sock >= 0)
  215. {
  216. closesocket(sock);
  217. }
  218. }
  219. static void do_airkiss_configwifi(void)
  220. {
  221. airkiss_context_t ac;
  222. struct rt_wlan_device *dev;
  223. akbuf_t *pbuf;
  224. int n;
  225. akchn_t chns[13];
  226. int round = 120;
  227. airkiss_config_t acfg =
  228. {
  229. (airkiss_memset_fn)&rt_memset,
  230. (airkiss_memcpy_fn)&rt_memcpy,
  231. (airkiss_memcmp_fn)&rt_memcmp,
  232. (airkiss_printf_fn)&rt_kprintf};
  233. int _mbuf[AKDEMO_BUFSZ];
  234. rt_kprintf("airkiss thread start\n");
  235. if ((pbuf = ak_bufinit(AKDEMO_BUFSZ)) == RT_NULL)
  236. {
  237. rt_kprintf("akdemo init buf err\n");
  238. return;
  239. }
  240. airkiss_init(&ac, &acfg);
  241. rt_mb_init(&_bfready, "ak", _mbuf, AKDEMO_BUFSZ, 0);
  242. rt_wlan_config_autoreconnect(0);
  243. rt_wlan_disconnect();
  244. dev = (struct rt_wlan_device *)rt_device_find(RT_WLAN_DEVICE_STA_NAME);
  245. rt_wlan_dev_set_promisc_callback(dev, prom_callback);
  246. rt_wlan_dev_enter_promisc(dev);
  247. akchn_init(chns, sizeof(chns) / sizeof(chns[0]));
  248. rt_kprintf("%s\n", airkiss_version());
  249. while (round-- > 0)
  250. {
  251. //rt_kprintf("ak round\n");
  252. for (n = 0; n < sizeof(chns) / sizeof(chns[0]); n++)
  253. {
  254. if (ak_recv_chn(dev, &ac, &chns[n]) == AIRKISS_STATUS_COMPLETE)
  255. {
  256. airkiss_result_t res;
  257. rt_wlan_dev_exit_promisc(dev);
  258. airkiss_get_result(&ac, &res);
  259. rt_kprintf("pwd %s ssid %s\n", res.pwd, res.ssid);
  260. if (ak_wifi_connetct(res.ssid, res.pwd) == 0)
  261. {
  262. airkiss_send_notification(res.random);
  263. }
  264. goto _out;
  265. }
  266. }
  267. }
  268. rt_wlan_dev_exit_promisc(dev);
  269. _out:
  270. rt_wlan_dev_set_promisc_callback(dev, RT_NULL);
  271. rt_wlan_config_autoreconnect(1);
  272. rt_mb_detach(&_bfready);
  273. rt_free(pbuf);
  274. _akrun = 0;
  275. rt_kprintf("airkiss exit\n");
  276. }
  277. static void airkiss_thread(void *p)
  278. {
  279. do_airkiss_configwifi();
  280. }
  281. int airkiss_demo_start(void)
  282. {
  283. rt_thread_t tid;
  284. int ret = -1;
  285. if (_akrun)
  286. return ret;
  287. tid = rt_thread_create("airkiss",
  288. airkiss_thread,
  289. 0,
  290. 2048,
  291. 22,
  292. 20);
  293. if (tid)
  294. {
  295. ret = rt_thread_startup(tid);
  296. }
  297. _akrun = (ret == 0);
  298. return ret;
  299. }
  300. #ifdef RT_USING_FINSH
  301. /* 用于测试 */
  302. typedef struct
  303. {
  304. char isrun;
  305. char schn;
  306. char echn;
  307. char omode;
  308. } akcap_t;
  309. static void showakbuf(akbuf_t *buf, int mode)
  310. {
  311. char str[58];
  312. int i, pos = 0;
  313. int fs = mode & 0x1f;
  314. if (fs < 24)
  315. {
  316. for (i = fs; i < 24; i++)
  317. {
  318. rt_sprintf(str + pos, "%02X", buf->f[i]);
  319. pos += 2;
  320. }
  321. rt_sprintf(str + pos, ":%d\n", buf->fmlen);
  322. if (mode & 0x80)
  323. {
  324. pos = rt_strlen(str) - 1;
  325. rt_sprintf(str + pos, ":%d\n", rt_tick_get());
  326. }
  327. rt_kprintf(str);
  328. }
  329. }
  330. static int recv_no_change(airkiss_context_t *ac, int omode)
  331. {
  332. akbuf_t *buf = 0;
  333. int status;
  334. if (rt_mb_recv(&_bfready, (rt_ubase_t *)&buf, rt_tick_from_millisecond(10)) == 0)
  335. {
  336. status = airkiss_recv(ac, buf->f, buf->fmlen);
  337. showakbuf(buf, omode);
  338. rt_list_insert_after(&_bflist, &buf->list);
  339. }
  340. return (status == AIRKISS_STATUS_COMPLETE);
  341. }
  342. static void airkiss_thread_cap(void *p)
  343. {
  344. akcap_t *cap = (akcap_t *)p;
  345. airkiss_context_t ac;
  346. struct rt_wlan_device *dev;
  347. akbuf_t *pbuf;
  348. akchn_t chns[14];
  349. int _mbuf[AKDEMO_BUFSZ];
  350. if ((pbuf = ak_bufinit(AKDEMO_BUFSZ)) == RT_NULL)
  351. {
  352. rt_kprintf("akdemo init buf err\n");
  353. return;
  354. }
  355. airkiss_init(&ac, RT_NULL);
  356. rt_mb_init(&_bfready, "ak", _mbuf, AKDEMO_BUFSZ, 0);
  357. rt_wlan_disconnect();
  358. rt_wlan_config_autoreconnect(0);
  359. dev = (struct rt_wlan_device *)rt_device_find(RT_WLAN_DEVICE_STA_NAME);
  360. rt_wlan_dev_set_promisc_callback(dev, prom_callback);
  361. rt_wlan_dev_enter_promisc(dev);
  362. akchn_init(chns, sizeof(chns) / sizeof(chns[0]));
  363. rt_kprintf("airkiss cap start\n");
  364. if (cap->schn == cap->echn)
  365. {
  366. rt_wlan_dev_set_channel(dev, cap->schn);
  367. while (cap->isrun)
  368. {
  369. if (recv_no_change(&ac, cap->omode))
  370. {
  371. airkiss_result_t res;
  372. rt_wlan_dev_exit_promisc(dev);
  373. airkiss_get_result(&ac, &res);
  374. rt_kprintf("pwd %s ssid %s\n", res.pwd, res.ssid);
  375. break;
  376. }
  377. }
  378. }
  379. else
  380. {
  381. }
  382. rt_wlan_dev_exit_promisc(dev);
  383. rt_wlan_dev_set_promisc_callback(dev, RT_NULL);
  384. rt_mb_detach(&_bfready);
  385. rt_free(pbuf);
  386. _akrun = 0;
  387. rt_kprintf("airkiss exit\n");
  388. }
  389. static int airkiss_cap_start(akcap_t *cap)
  390. {
  391. rt_thread_t tid;
  392. int ret = -1;
  393. if (_akrun)
  394. return ret;
  395. tid = rt_thread_create("airkiss",
  396. airkiss_thread_cap,
  397. cap,
  398. 2048,
  399. 22,
  400. 20);
  401. if (tid)
  402. {
  403. ret = rt_thread_startup(tid);
  404. }
  405. _akrun = (ret == 0);
  406. return ret;
  407. }
  408. static void airkiss(int c, char **v)
  409. {
  410. static akcap_t cap = {0};
  411. int chn = 0;
  412. int op = 0;
  413. while (c)
  414. {
  415. switch (c)
  416. {
  417. case 5:
  418. if (v[4][0] == 't')
  419. cap.omode = 0x80;
  420. break;
  421. case 4:
  422. cap.omode |= atoi(&(v[3][1]));
  423. break;
  424. case 3:
  425. chn = atoi(v[2]);
  426. break;
  427. case 2:
  428. op = v[1][0];
  429. break;
  430. }
  431. c--;
  432. }
  433. if (op == 0)
  434. {
  435. airkiss_demo_start();
  436. }
  437. else if (op == 'c')
  438. {
  439. if (chn == 0)
  440. {
  441. cap.schn = 1;
  442. cap.echn = 13;
  443. }
  444. else
  445. {
  446. cap.schn = chn;
  447. cap.echn = chn;
  448. }
  449. cap.isrun = 1;
  450. airkiss_cap_start(&cap);
  451. }
  452. }
  453. MSH_CMD_EXPORT(airkiss, start airkiss);
  454. #endif