espnow_slave.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /******************************************************************************
  2. * Copyright 2013-2014 Espressif Systems (Wuxi)
  3. *
  4. * FileName: user_main.c
  5. *
  6. * Description: entry file of user application
  7. *
  8. * Modification history:
  9. * 2015/7/3, v1.0 create this file.
  10. *******************************************************************************/
  11. #include "osapi.h"
  12. #include "user_interface.h"
  13. #include "driver/uart.h"
  14. #include "driver/key.h"
  15. #include "user_json.h"
  16. #include "espnow.h"
  17. #include "mem.h"
  18. #include "simple_pair.h"
  19. #if ESPNOW_SLAVE
  20. /*******************************************************************************
  21. * open AS_STA to compile sta test code
  22. * open AS_AP to compile ap test code
  23. * don't open both
  24. * ****************************************************************************/
  25. #define AS_AP
  26. #define AP_SSID "MyIoTDemo"
  27. #define AP_PASSWORD "12345678"
  28. #define PWLDEV_ESP_NOW_CHANNEL_NUM 1
  29. // wifi socket v1.0 2015-10-14
  30. #define KEY_NUM 1
  31. #define KEY_0_IO_MUX PERIPHS_IO_MUX_MTDI_U
  32. #define KEY_0_IO_NUM 12
  33. #define KEY_0_IO_FUNC FUNC_GPIO12
  34. #define PWM_CHANNEL 1
  35. #define LED_0_OUT_IO_MUX PERIPHS_IO_MUX_GPIO5_U
  36. #define LED_0_OUT_IO_NUM 5
  37. #define LED_0_OUT_IO_FUNC FUNC_GPIO5
  38. LOCAL struct keys_param keys;
  39. LOCAL struct single_key_param *single_key[KEY_NUM];
  40. LOCAL os_timer_t dev_espnow_timer;
  41. LOCAL uint8 ap_channel = 1;
  42. static u8 simple_pair_stat = 0;
  43. static u8 esp_now_stat = 0;
  44. /* STA & AP use the same tmpkey to encrypt Simple Pair communication */
  45. static u8 tmpkey[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  46. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
  47. #ifdef AS_AP
  48. /* since the ex_key transfer from AP to STA, so AP's ex_key must be set */
  49. static u8 ex_key[16] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
  50. 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00};
  51. #endif /* AS_AP */
  52. void ICACHE_FLASH_ATTR
  53. show_espnow_cnt(void)
  54. {
  55. u8 all_cnt, encrypt_cnt;
  56. if (esp_now_get_cnt_info(&all_cnt, &encrypt_cnt))
  57. os_printf("get_cnt_info failed\r\n");
  58. os_printf("client:%d, encrypted client:%d\r\n", all_cnt, encrypt_cnt);
  59. }
  60. void ICACHE_FLASH_ATTR
  61. sp_status(u8 *sa, u8 status)
  62. {
  63. #ifdef AS_AP
  64. if(sa)
  65. os_printf("Simple Pair: from " MACSTR "\n", MAC2STR(sa));
  66. switch (status) {
  67. case SP_ST_AP_FINISH:
  68. simple_pair_get_peer_ref(NULL, NULL, ex_key);
  69. os_printf("Simple Pair: AP FINISH\n");
  70. /* TODO: Wait STA use the ex-key communicate with AP, for example use ESP-NOW */
  71. os_printf("SP_ST_STA_FINISH @t %d\n", system_get_time());
  72. if(esp_now_stat)
  73. {
  74. if(esp_now_add_peer(sa, ESP_NOW_ROLE_CONTROLLER, ap_channel, ex_key, 16) == 0)
  75. {
  76. os_printf("add remote peer addr success\n");
  77. char *pbuf = NULL;
  78. pbuf = (char *)os_zalloc(jsonSize);
  79. os_sprintf(pbuf, "hello controller.");
  80. // json_ws_send((struct jsontree_value *)&set_pwl_tree, "light", pbuf);
  81. if (esp_now_send(sa, pbuf, os_strlen(pbuf)))
  82. os_printf("fail\r\n");
  83. else
  84. os_printf("ok\r\n");
  85. // EPIT_DBG("ctrl:%s\n", pbuf);
  86. os_free(pbuf);
  87. }
  88. show_espnow_cnt();
  89. }
  90. /* if test ok , deinit simple pair */
  91. simple_pair_deinit();
  92. simple_pair_stat = 0;
  93. os_timer_disarm(&dev_espnow_timer);
  94. break;
  95. case SP_ST_AP_RECV_NEG:
  96. /* AP recv a STA's negotiate request */
  97. os_printf("Simple Pair: Recv STA Negotiate Request\n");
  98. /* set peer must be called, because the simple pair need to know what peer mac is */
  99. simple_pair_set_peer_ref(sa, tmpkey, ex_key);
  100. /* TODO:In this phase, the AP can interaction with Smart Phone,
  101. if the Phone agree, call start_neg or refuse */
  102. simple_pair_ap_start_negotiate();
  103. //simple_pair_ap_refuse_negotiate();
  104. /* TODO:if refuse, maybe call simple_pair_deinit() to ending the simple pair */
  105. break;
  106. case SP_ST_WAIT_TIMEOUT:
  107. /* In negotiate, timeout , so re-enter in to announce mode*/
  108. os_printf("Simple Pair: Neg Timeout\n");
  109. os_printf(" @t %d\n", system_get_time());
  110. simple_pair_state_reset();
  111. simple_pair_ap_enter_announce_mode();
  112. break;
  113. case SP_ST_SEND_ERROR:
  114. os_printf("Simple Pair: Send Error\n");
  115. /* maybe the simple_pair_set_peer_ref() haven't called, it send to a wrong mac address */
  116. break;
  117. case SP_ST_KEY_INSTALL_ERR:
  118. os_printf("Simple Pair: Key Install Error\n");
  119. /* 1. maybe something argument error.
  120. 2. maybe the key number is full in system*/
  121. /* TODO: Check other modules which use lots of keys
  122. Example: ESPNOW and STA/AP use lots of keys */
  123. break;
  124. case SP_ST_KEY_OVERLAP_ERR:
  125. os_printf("Simple Pair: Key Overlap Error\n");
  126. /* 1. maybe something argument error.
  127. 2. maybe the MAC Address is already use in ESP-NOW or other module
  128. the same MAC Address has multi key*/
  129. /* TODO: Check if the same MAC Address used already,
  130. Example: del MAC item of ESPNOW or other module */
  131. esp_now_del_peer(sa);
  132. break;
  133. case SP_ST_OP_ERROR:
  134. os_printf("Simple Pair: Operation Order Error\n");
  135. /* 1. maybe the function call order has something wrong */
  136. /* TODO: Adjust your function call order */
  137. break;
  138. default:
  139. os_printf("Simple Pair: Unknown Error\n");
  140. break;
  141. }
  142. #endif /* AS_AP */
  143. }
  144. LOCAL void ICACHE_FLASH_ATTR
  145. slave_simple_pair_time_cb(void)
  146. {
  147. os_printf("%s\n", __FUNCTION__);
  148. os_timer_disarm(&dev_espnow_timer);
  149. if(simple_pair_stat)
  150. {
  151. simple_pair_deinit();
  152. simple_pair_stat = 0;
  153. }
  154. }
  155. LOCAL void ICACHE_FLASH_ATTR
  156. slave_start_simple_pair(void)
  157. {
  158. int ret;
  159. #ifdef AS_AP
  160. os_printf("dev chn %d\n", wifi_get_channel());
  161. os_printf(" @t %d\n", system_get_time());
  162. // show_espnow_cnt();
  163. if(simple_pair_stat)
  164. {
  165. simple_pair_deinit();
  166. simple_pair_stat = 0;
  167. }
  168. /* init simple pair */
  169. ret = simple_pair_init();
  170. if (ret) {
  171. os_printf("Simple Pair: init error, %d\n", ret);
  172. // return;
  173. goto WAIT_PAIR;
  174. }
  175. simple_pair_stat = 1;
  176. /* register simple pair status callback function */
  177. ret = register_simple_pair_status_cb(sp_status);
  178. if (ret) {
  179. os_printf("Simple Pair: register status cb error, %d\n", ret);
  180. // return;
  181. goto WAIT_PAIR;
  182. }
  183. simple_pair_stat = 2;
  184. os_printf("Simple Pair: AP Enter Announce Mode ...\n");
  185. /* ap must enter announce mode , so the sta can know which ap is ready to simple pair */
  186. ret = simple_pair_ap_enter_announce_mode();
  187. if (ret) {
  188. os_printf("Simple Pair: AP Enter Announce Mode Error, %d\n", ret);
  189. // return;
  190. goto WAIT_PAIR;
  191. }
  192. simple_pair_stat = 3;
  193. WAIT_PAIR:
  194. os_timer_disarm(&dev_espnow_timer);
  195. os_timer_setfn(&dev_espnow_timer, (os_timer_func_t *)slave_simple_pair_time_cb, NULL);
  196. os_timer_arm(&dev_espnow_timer, 30000, 0);
  197. #endif
  198. }
  199. void esp_now_recv_cb(u8 *mac_addr, u8 *data, u8 len)
  200. {
  201. u8 all_cnt, encrypt_cnt;
  202. if (esp_now_get_cnt_info(&all_cnt, &encrypt_cnt))
  203. os_printf("get_cnt_info failed\r\n");
  204. os_printf("client:%d, encrypted client:%d\r\n", all_cnt, encrypt_cnt);
  205. os_printf("esp_now_recv_cb_t %d from " MACSTR "\n", len, MAC2STR(mac_addr));
  206. data[len-1] = '\0';
  207. os_printf("esp_now_recv_cb_date: %s\n",data);
  208. // user_printbuf(data, len, "nowin");
  209. }
  210. void esp_now_send_cb(u8 *mac_addr, u8 status)
  211. {
  212. os_printf("esp_now_send_cb_t\n");
  213. }
  214. void ICACHE_FLASH_ATTR
  215. init_done(void)
  216. {
  217. slave_start_simple_pair();
  218. if(esp_now_init() == 0)
  219. {
  220. os_printf("esp_now_init ok\n");
  221. esp_now_stat = 1;
  222. esp_now_register_recv_cb(esp_now_recv_cb);
  223. esp_now_register_send_cb(esp_now_send_cb);
  224. uint8 ch = PWLDEV_ESP_NOW_CHANNEL_NUM;
  225. wifi_set_channel(ch);
  226. ch = wifi_get_channel();
  227. os_printf("wifi channel is %d\n",ch);
  228. if(esp_now_set_self_role(ESP_NOW_ROLE_SLAVE) == 0)
  229. os_printf("set myself as slave\n");
  230. // u8 key[16]= {0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44, 0x33, 0x44};
  231. // if(esp_now_add_peer(hwaddr, ESP_NOW_ROLE_CONTROLLER, ch, key, 16) == 0)
  232. // os_printf("add local peer addr success\n");
  233. os_printf("esp config success\n");
  234. }
  235. else
  236. {
  237. os_printf("esp_now_init fail\n");
  238. }
  239. }
  240. /******************************************************************************
  241. * FunctionName : user_set_softap_config
  242. * Description : set SSID and password of ESP8266 softAP
  243. * Parameters : none
  244. * Returns : none
  245. *******************************************************************************/
  246. void ICACHE_FLASH_ATTR
  247. user_set_softap_config(void)
  248. {
  249. struct softap_config config;
  250. if(wifi_get_opmode() != SOFTAP_MODE)
  251. wifi_set_opmode(SOFTAP_MODE);
  252. os_memset(&config, 0, sizeof(config));
  253. wifi_softap_get_config(&config); // Get config first.
  254. os_sprintf(config.ssid, AP_SSID);
  255. os_sprintf(config.password, AP_PASSWORD);
  256. config.ssid_len = os_strlen(config.ssid);
  257. config.authmode = AUTH_WPA_WPA2_PSK;
  258. config.channel = ap_channel;
  259. config.beacon_interval = 100;
  260. config.max_connection = 4; // how many stations can connect to ESP8266 softAP at most.
  261. wifi_softap_set_config(&config);// Set ESP8266 softap config .
  262. }
  263. LOCAL void ICACHE_FLASH_ATTR
  264. slave_key_long_press(void)
  265. {
  266. os_printf("%s\n", __FUNCTION__);
  267. slave_start_simple_pair();
  268. }
  269. LOCAL void ICACHE_FLASH_ATTR
  270. slave_key_short_press(void)
  271. {
  272. os_printf("%s\n", __FUNCTION__);
  273. ap_channel = (ap_channel+1)%12;
  274. if(ap_channel == 0)
  275. ap_channel = 12;
  276. user_set_softap_config();
  277. os_printf("set chn %d\n", ap_channel);
  278. }
  279. LOCAL void ICACHE_FLASH_ATTR
  280. device_io_init(void)
  281. {
  282. PIN_FUNC_SELECT(KEY_0_IO_MUX, KEY_0_IO_FUNC);
  283. PIN_FUNC_SELECT(LED_0_OUT_IO_MUX, LED_0_OUT_IO_FUNC);
  284. GPIO_OUTPUT_SET(GPIO_ID_PIN(LED_0_OUT_IO_NUM), 0);
  285. }
  286. void ICACHE_FLASH_ATTR
  287. device_init(void)
  288. {
  289. device_io_init();
  290. single_key[0] = key_init_single(KEY_0_IO_NUM, KEY_0_IO_MUX, KEY_0_IO_FUNC,
  291. slave_key_long_press, slave_key_short_press);
  292. keys.key_num = KEY_NUM;
  293. keys.single_key = single_key;
  294. key_init(&keys);
  295. user_set_softap_config();
  296. system_init_done_cb(init_done);
  297. }
  298. #endif // ESPNOW_SLAVE device