airkiss_demo.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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. st = rt_tick_get();
  83. while (1)
  84. {
  85. if (rt_mb_recv(&_bfready, (rt_ubase_t *)&buf, rt_tick_from_millisecond(10)) == 0)
  86. {
  87. //rt_kprintf("%d\n", buf->fmlen);
  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. (*rcnt)++;
  93. /* 收到数据奖励时间 */
  94. if (ms < 140)
  95. ms += 12;
  96. }
  97. else
  98. {
  99. /* 超时后进行时间惩罚 */
  100. if (ms > 40)
  101. ms -= 2;
  102. }
  103. max = rt_tick_from_millisecond(ms);
  104. if ((rt_tick_get() - st) > max)
  105. break;
  106. }
  107. return status;
  108. }
  109. static int ak_recv_chn(struct rt_wlan_device *dev,
  110. airkiss_context_t *ac, akchn_t *chn)
  111. {
  112. int status;
  113. int t;
  114. int rcnt = 0;
  115. rt_wlan_dev_set_channel(dev, chn->n);
  116. airkiss_change_channel(ac);
  117. status = ak_recv(ac, chn->tm, &rcnt);
  118. if (status == AIRKISS_STATUS_CHANNEL_LOCKED)
  119. {
  120. rt_kprintf("airkiss locked chn %d\n", chn->n);
  121. status = ak_recv(ac, 1000 * 30, &rcnt);
  122. }
  123. chn->cnt += rcnt;
  124. t = chn->cnt * chn->cnt * chn->cnt;
  125. if (t)
  126. {
  127. if (t > 170)
  128. t = 170;
  129. chn->tm = 30 + t;
  130. rt_kprintf("tm %d on chn %d\n", chn->tm, chn->n);
  131. }
  132. if (chn->cnt > 4)
  133. {
  134. chn->cnt -= 2;
  135. chn->tm -= (chn->tm/8);
  136. }
  137. return status;
  138. }
  139. static void akchn_init(akchn_t *chn, int n)
  140. {
  141. int i;
  142. for (i = 0; i < n; i++)
  143. {
  144. chn[i].n = i + 1;
  145. chn[i].cnt = 0;
  146. chn[i].tm = 20;
  147. }
  148. }
  149. static int ak_wifi_connetct(char *ssid, char *passwd)
  150. {
  151. int result = RT_EOK;
  152. rt_uint8_t time_cnt = 0;
  153. #define NET_READY_TIME_OUT (rt_tick_from_millisecond(8 * 1000))
  154. result = rt_wlan_connect(ssid, passwd);
  155. if (result != RT_EOK)
  156. {
  157. rt_kprintf("\nconnect ssid %s error:%d!\n", ssid, result);
  158. return result;
  159. };
  160. do
  161. {
  162. rt_thread_mdelay(1000);
  163. time_cnt++;
  164. if (rt_wlan_is_ready())
  165. {
  166. break;
  167. }
  168. } while (time_cnt <= (NET_READY_TIME_OUT / 1000));
  169. if (time_cnt <= (NET_READY_TIME_OUT / 1000))
  170. {
  171. rt_kprintf("networking ready!\n");
  172. }
  173. else
  174. {
  175. rt_kprintf("wait ip got timeout!\n");
  176. result = -1;
  177. }
  178. return result;
  179. }
  180. static void airkiss_send_notification(uint8_t random)
  181. {
  182. int sock = -1;
  183. int udpbufsize = 2;
  184. struct sockaddr_in UDPBCAddr, UDPBCServerAddr;
  185. sock = socket(AF_INET, SOCK_DGRAM, 0);
  186. if (sock < 0)
  187. {
  188. rt_kprintf("notify create socket error!\n");
  189. goto _exit;
  190. }
  191. UDPBCAddr.sin_family = AF_INET;
  192. UDPBCAddr.sin_port = htons(10000);
  193. UDPBCAddr.sin_addr.s_addr = htonl(0xffffffff);
  194. rt_memset(&(UDPBCAddr.sin_zero), 0, sizeof(UDPBCAddr.sin_zero));
  195. UDPBCServerAddr.sin_family = AF_INET;
  196. UDPBCServerAddr.sin_port = htons(10000);
  197. UDPBCServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  198. rt_memset(&(UDPBCServerAddr.sin_zero), 0, sizeof(UDPBCServerAddr.sin_zero));
  199. if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &udpbufsize, sizeof(int)) != 0)
  200. {
  201. rt_kprintf("notify socket setsockopt error\n");
  202. goto _exit;
  203. }
  204. if (bind(sock, (struct sockaddr *)&UDPBCServerAddr, sizeof(UDPBCServerAddr)) != 0)
  205. {
  206. rt_kprintf("notify socket bind error\n");
  207. goto _exit;
  208. }
  209. for (int i = 0; i <= 20; i++)
  210. {
  211. int ret = sendto(sock, (char *)&random, 1, 0, (struct sockaddr *)&UDPBCAddr, sizeof(UDPBCAddr));
  212. rt_thread_mdelay(10);
  213. }
  214. _exit:
  215. if (sock >= 0)
  216. {
  217. closesocket(sock);
  218. }
  219. }
  220. static void do_airkiss_configwifi(void)
  221. {
  222. airkiss_context_t ac;
  223. struct rt_wlan_device *dev;
  224. akbuf_t *pbuf;
  225. int n;
  226. akchn_t chns[13];
  227. int round = 120;
  228. airkiss_config_t acfg =
  229. {
  230. (airkiss_memset_fn)&rt_memset,
  231. (airkiss_memcpy_fn)&rt_memcpy,
  232. (airkiss_memcmp_fn)&rt_memcmp,
  233. (airkiss_printf_fn)&rt_kprintf
  234. };
  235. int _mbuf[AKDEMO_BUFSZ];
  236. rt_kprintf("airkiss thread start\n");
  237. if ((pbuf = ak_bufinit(AKDEMO_BUFSZ)) == RT_NULL)
  238. {
  239. rt_kprintf("akdemo init buf err\n");
  240. return;
  241. }
  242. airkiss_init(&ac, &acfg);
  243. rt_mb_init(&_bfready, "ak", _mbuf, AKDEMO_BUFSZ, 0);
  244. rt_wlan_disconnect();
  245. dev = (struct rt_wlan_device *)rt_device_find(RT_WLAN_DEVICE_STA_NAME);
  246. rt_wlan_dev_set_promisc_callback(dev, prom_callback);
  247. rt_wlan_dev_enter_promisc(dev);
  248. akchn_init(chns, sizeof(chns) / sizeof(chns[0]));
  249. rt_kprintf("%s\n", airkiss_version());
  250. while (round-- > 0)
  251. {
  252. //rt_kprintf("ak round\n");
  253. for (n = 0; n < sizeof(chns) / sizeof(chns[0]); n++)
  254. {
  255. if (ak_recv_chn(dev, &ac, &chns[n]) == AIRKISS_STATUS_COMPLETE)
  256. {
  257. airkiss_result_t res;
  258. rt_wlan_dev_exit_promisc(dev);
  259. airkiss_get_result(&ac, &res);
  260. rt_kprintf("pwd %s ssid %s\n", res.pwd, res.ssid);
  261. if (ak_wifi_connetct(res.ssid, res.pwd) == 0)
  262. {
  263. airkiss_send_notification(res.random);
  264. }
  265. goto _out;
  266. }
  267. }
  268. }
  269. rt_wlan_dev_exit_promisc(dev);
  270. _out:
  271. rt_wlan_dev_set_promisc_callback(dev, RT_NULL);
  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. dev = (struct rt_wlan_device *)rt_device_find(RT_WLAN_DEVICE_STA_NAME);
  359. rt_wlan_dev_set_promisc_callback(dev, prom_callback);
  360. rt_wlan_dev_enter_promisc(dev);
  361. akchn_init(chns, sizeof(chns) / sizeof(chns[0]));
  362. rt_kprintf("airkiss cap start\n");
  363. if (cap->schn == cap->echn)
  364. {
  365. rt_wlan_dev_set_channel(dev, cap->schn);
  366. while (cap->isrun)
  367. {
  368. if (recv_no_change(&ac, cap->omode))
  369. {
  370. airkiss_result_t res;
  371. rt_wlan_dev_exit_promisc(dev);
  372. airkiss_get_result(&ac, &res);
  373. rt_kprintf("pwd %s ssid %s\n", res.pwd, res.ssid);
  374. break;
  375. }
  376. }
  377. }
  378. else
  379. {
  380. }
  381. rt_wlan_dev_exit_promisc(dev);
  382. rt_wlan_dev_set_promisc_callback(dev, RT_NULL);
  383. rt_mb_detach(&_bfready);
  384. rt_free(pbuf);
  385. _akrun = 0;
  386. rt_kprintf("airkiss exit\n");
  387. }
  388. static int airkiss_cap_start(akcap_t *cap)
  389. {
  390. rt_thread_t tid;
  391. int ret = -1;
  392. if (_akrun)
  393. return ret;
  394. tid = rt_thread_create("airkiss",
  395. airkiss_thread_cap,
  396. cap,
  397. 2048,
  398. 22,
  399. 20);
  400. if (tid)
  401. {
  402. ret = rt_thread_startup(tid);
  403. }
  404. _akrun = (ret == 0);
  405. return ret;
  406. }
  407. static void airkiss(int c, char **v)
  408. {
  409. static akcap_t cap = {0};
  410. int chn = 0;
  411. int op = 0;
  412. while (c)
  413. {
  414. switch (c)
  415. {
  416. case 5:
  417. if (v[4][0] == 't')
  418. cap.omode = 0x80;
  419. break;
  420. case 4:
  421. cap.omode |= atoi(&(v[3][1]));
  422. break;
  423. case 3:
  424. chn = atoi(v[2]);
  425. break;
  426. case 2:
  427. op = v[1][0];
  428. break;
  429. }
  430. c--;
  431. }
  432. if (op == 0)
  433. {
  434. airkiss_demo_start();
  435. }
  436. else if (op == 'c')
  437. {
  438. if (chn == 0)
  439. {
  440. cap.schn = 1;
  441. cap.echn = 13;
  442. }
  443. else
  444. {
  445. cap.schn = chn;
  446. cap.echn = chn;
  447. }
  448. cap.isrun = 1;
  449. airkiss_cap_start(&cap);
  450. }
  451. }
  452. MSH_CMD_EXPORT(airkiss, start airkiss);
  453. #endif