1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 #include "dev_bind_internal.h"
5 
6 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
7 extern "C" {
8 #endif
9 
10 #define AWSS_CHECK_RESP_TIME (300)
11 #define AWSS_NOTIFY_PORT     (5683)
12 #define AWSS_NOTIFY_HOST     "255.255.255.255"
13 #define AWSS_DEV_NOTIFY_FMT \
14     "{\"id\":\"%u\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":{%s}}"
15 
16 struct notify_map_t {
17     uint8_t notify_type;
18     char *notify_method;
19     char *notify_topic;
20     void *cb;
21 };
22 
23 static uint8_t g_notify_id;
24 static char awss_notify_resp[AWSS_NOTIFY_TYPE_MAX] = { 0 };
25 static uint16_t g_notify_msg_id[AWSS_NOTIFY_TYPE_MAX] = { 0 };
26 
27 #ifdef WIFI_PROVISION_ENABLED
28 static void *success_notify_timer = NULL;
29 static void *devinfo_notify_timer = NULL;
30 static void *success_notify_mutex = NULL;
31 static void *devinfo_notify_mutex = NULL;
32 #endif
33 static void *dev_bind_notify_timer = NULL;
34 static void *get_devinfo_timer = NULL;
35 static void *dev_bind_notify_mutex = NULL;
36 
37 extern char awss_report_token_suc;
38 extern char awss_report_token_cnt;
39 
40 #ifndef DEV_BIND_DISABLE_NOTIFY
41 static int awss_dev_bind_notify_resp(void *context, int result, void *userdata,
42                                      void *remote, void *message);
43 int awss_dev_bind_notify();
44 #endif
45 
46 #ifdef WIFI_PROVISION_ENABLED
47 static int awss_devinfo_notify_resp(void *context, int result, void *userdata,
48                                     void *remote, void *message);
49 static int awss_suc_notify_resp(void *context, int result, void *userdata,
50                                 void *remote, void *message);
51 int awss_devinfo_notify();
52 int awss_suc_notify();
53 #endif
54 static int awss_notify_response(int type, int result, void *message);
55 static int awss_process_get_devinfo();
56 
57 static const struct notify_map_t notify_map[] = {
58 #ifndef DEV_BIND_DISABLE_NOTIFY
59     { AWSS_NOTIFY_DEV_BIND_TOKEN, METHOD_DEV_INFO_NOTIFY, TOPIC_NOTIFY,
60       awss_dev_bind_notify_resp },
61 #endif
62 #ifdef WIFI_PROVISION_ENABLED
63     { AWSS_NOTIFY_DEV_RAND_SIGN, METHOD_AWSS_DEV_INFO_NOTIFY, TOPIC_AWSS_NOTIFY,
64       awss_devinfo_notify_resp },
65     { AWSS_NOTIFY_SUCCESS, METHOD_AWSS_CONNECTAP_NOTIFY,
66       TOPIC_AWSS_CONNECTAP_NOTIFY, awss_suc_notify_resp }
67 #endif
68 };
69 
70 #ifdef WIFI_PROVISION_ENABLED
awss_devinfo_notify_resp(void * context,int result,void * userdata,void * remote,void * message)71 static int awss_devinfo_notify_resp(void *context, int result, void *userdata,
72                                     void *remote, void *message)
73 {
74     return awss_notify_response(AWSS_NOTIFY_DEV_RAND_SIGN, result, message);
75 }
76 
awss_suc_notify_resp(void * context,int result,void * userdata,void * remote,void * message)77 static int awss_suc_notify_resp(void *context, int result, void *userdata,
78                                 void *remote, void *message)
79 {
80     return awss_notify_response(AWSS_NOTIFY_SUCCESS, result, message);
81 }
82 #endif
83 
awss_notify_response(int type,int result,void * message)84 static int awss_notify_response(int type, int result, void *message)
85 {
86     uint8_t i = 0;
87 
88     awss_flow("%s, type:%d,result:%u\r\n", __func__, type, result);
89 
90     if (message == NULL) {
91         return -1;
92     }
93 
94     if (result != 0) {
95         return 0;
96     }
97 
98     if (awss_cmp_get_coap_code(message) >= 0x60) {
99         return 0;
100     }
101 
102     do {
103         int val = 0;
104         int len = 0, mlen = 0;
105         char *payload = NULL, *elem = NULL;
106 
107         payload = awss_cmp_get_coap_payload(message, &len);
108         if (payload == NULL ||
109             len > 0x40 || len == 0) {
110             return 0;
111         }
112 
113         awss_debug("payload:%s\r\n", payload);
114 
115         elem = json_get_value_by_name(payload, len, AWSS_JSON_ID, &mlen, 0);
116         if (elem == NULL) {
117             return 0;
118         }
119 
120         val = atoi(elem);
121         if (val != 123 && val > g_notify_id) {
122             return 0;
123         }
124 
125         elem = json_get_value_by_name(payload, len, AWSS_JSON_CODE, &mlen, 0);
126         if (elem == NULL) {
127             return 0;
128         }
129 
130         val = atoi(elem);
131         if (val != 200) {
132             return 0;
133         }
134     } while (0);
135 
136     for (i = 0; i < sizeof(notify_map) / sizeof(notify_map[0]); i++) {
137         if (notify_map[i].notify_type != type) {
138             continue;
139         }
140 
141         awss_notify_resp[type] = 1;
142         break;
143     }
144 
145     return awss_notify_resp[type];
146 }
147 
148 /**
149  * @brief alternate bcast addr
150  *
151  * @param bcast_addr[out] bcast addr output
152  * @param mask_level 0 ~ 4(255), 1 ~ 3(255), 2 ~ 2(255), 3 ~ 1(255), others ~
153  * invalid,
154  */
awss_get_broadcast_addr(platform_netaddr_t * bcast_addr)155 static int awss_get_broadcast_addr(platform_netaddr_t *bcast_addr)
156 {
157     static uint8_t mask_level = 3;
158     char ip[20] = { 0 };
159     uint8_t level = 0;
160 
161     if (bcast_addr == NULL) {
162         return -1;
163     }
164 
165     /* update mask_level */
166     if (++mask_level >= 4) {
167         mask_level = 0;
168     }
169 
170     /* setup port */
171     bcast_addr->port = AWSS_NOTIFY_PORT;
172 
173     /* setup ip */
174     HAL_Wifi_Get_IP(ip, NULL);
175 
176     if (ip[0] != '\0' && mask_level != 0) {
177         uint8_t i = 0;
178         for (i = 0; i < strlen(ip); i++) {
179             bcast_addr->host[i] = ip[i];
180             if (ip[i] == '.') {
181                 if (++level == mask_level) {
182                     break;
183                 }
184             }
185         }
186 
187         if (mask_level == 1) {
188             if (i + strlen("255.255.255") < 16) {
189                 memcpy(bcast_addr->host + strlen(bcast_addr->host),
190                        "255.255.255", strlen("255.255.255"));
191                 return 0;
192             }
193         } else if (mask_level == 2) {
194             if (i + strlen("255.255") < 16) {
195                 memcpy(bcast_addr->host + strlen(bcast_addr->host), "255.255",
196                        strlen("255.255"));
197                 return 0;
198             }
199         } else if (mask_level == 3) {
200             if (i + strlen("255") < 16) {
201                 memcpy(bcast_addr->host + strlen(bcast_addr->host), "255",
202                        strlen("255"));
203                 return 0;
204             }
205         }
206     }
207 
208     memcpy(bcast_addr->host, AWSS_NOTIFY_HOST, strlen(AWSS_NOTIFY_HOST));
209     return 0;
210 }
211 
awss_notify_dev_info(int type,int count)212 int awss_notify_dev_info(int type, int count)
213 {
214     char *buf = NULL;
215     char *dev_info = NULL;
216     int i;
217     platform_netaddr_t notify_sa;
218     memset(&notify_sa, 0, sizeof(notify_sa));
219 
220     do {
221         void *cb = NULL;
222         char *method = NULL, *topic = NULL;
223         for (i = 0; i < sizeof(notify_map) / sizeof(notify_map[0]); i++) {
224             if (notify_map[i].notify_type != type) {
225                 continue;
226             }
227 
228             method = notify_map[i].notify_method;
229             topic = notify_map[i].notify_topic;
230             cb = notify_map[i].cb;
231             break;
232         }
233         if (method == NULL || topic == NULL) {
234             awss_err("parametes invalid");
235             break;
236         }
237 
238         buf = awss_zalloc(DEV_INFO_LEN_MAX);
239         dev_info = awss_zalloc(DEV_INFO_LEN_MAX);
240         if (buf == NULL || dev_info == NULL) {
241             awss_err("alloc mem fail");
242             break;
243         }
244 
245         memset(&notify_sa, 0, sizeof(notify_sa));
246         memcpy(notify_sa.host, AWSS_NOTIFY_HOST, strlen(AWSS_NOTIFY_HOST));
247         notify_sa.port = AWSS_NOTIFY_PORT;
248 
249         awss_build_dev_info(type, dev_info, DEV_INFO_LEN_MAX);
250 
251         HAL_Snprintf(buf, DEV_INFO_LEN_MAX - 1, AWSS_DEV_NOTIFY_FMT,
252                      ++g_notify_id, method, dev_info);
253 
254         awss_info("topic:%s\n", topic);
255         awss_debug("payload:%s\n", buf);
256         for (i = 0; i < count; i++) {
257             int ret = awss_cmp_coap_send(buf, strlen(buf), &notify_sa, topic,
258                                          cb, &g_notify_msg_id[type]);
259             awss_info("send notify %s", ret == 0 ? "success" : "fail");
260             if (count > 1) {
261                 HAL_SleepMs(200 + 100 * i);
262             }
263 
264             if (awss_notify_resp[type]) {
265                 break;
266             }
267         }
268     } while (0);
269 
270     if (buf) {
271         HAL_Free(buf);
272     }
273     if (dev_info) {
274         HAL_Free(dev_info);
275     }
276 
277     return awss_notify_resp[type];
278 }
279 
280 #define AWSS_NOTIFY_CNT_MAX (30)
281 
282 static void *coap_session_ctx = NULL;
283 
awss_process_get_devinfo()284 static int awss_process_get_devinfo()
285 {
286     char *buf = NULL;
287     char *dev_info = NULL;
288 
289     if (awss_report_token_suc == 0) {
290         awss_debug("try to report token to cloud");
291         HAL_Timer_Start(get_devinfo_timer, AWSS_CHECK_RESP_TIME);
292         return 0;
293     }
294 
295     if (coap_session_ctx == NULL) {
296         awss_debug("no get req");
297         return -1;
298     }
299 
300     do {
301         int len = 0, id_len = 0;
302         char *msg = NULL, *id = NULL;
303         char req_msg_id[MSG_REQ_ID_LEN + 1];
304         char topic[TOPIC_LEN_MAX] = { 0 };
305         struct coap_session_ctx_t *ctx =
306             (struct coap_session_ctx_t *)coap_session_ctx;
307 
308         buf = awss_zalloc(DEV_INFO_LEN_MAX);
309         if (buf == NULL) {
310             goto GET_DEV_INFO_ERR;
311         }
312 
313         dev_info = awss_zalloc(DEV_INFO_LEN_MAX);
314         if (dev_info == NULL) {
315             goto GET_DEV_INFO_ERR;
316         }
317 
318         msg = awss_cmp_get_coap_payload(ctx->request, &len);
319         if (msg == NULL) {
320             goto GET_DEV_INFO_ERR;
321         }
322 
323         id = json_get_value_by_name(msg, len, "id", &id_len, 0);
324         memset(req_msg_id, 0, sizeof(req_msg_id));
325 
326         if (id_len > MSG_REQ_ID_LEN) {
327             goto GET_DEV_INFO_ERR;
328         }
329         memcpy(req_msg_id, id, id_len);
330 
331         awss_build_dev_info(AWSS_NOTIFY_DEV_BIND_TOKEN, buf, DEV_INFO_LEN_MAX);
332         HAL_Snprintf(dev_info, DEV_INFO_LEN_MAX - 1, "{%s}", buf);
333         memset(buf, 0x00, DEV_INFO_LEN_MAX);
334         HAL_Snprintf(buf, DEV_INFO_LEN_MAX - 1, AWSS_ACK_FMT, req_msg_id, 200,
335                      dev_info);
336         HAL_Free(dev_info);
337 
338         awss_info("sending message to app: %s", buf);
339         if (ctx->is_mcast) {
340             awss_build_topic((const char *)TOPIC_GETDEVICEINFO_MCAST, topic,
341                              TOPIC_LEN_MAX);
342         } else {
343             awss_build_topic((const char *)TOPIC_GETDEVICEINFO_UCAST, topic,
344                              TOPIC_LEN_MAX);
345         }
346 
347         /*before tx to app, clear token suc flag*/
348         awss_update_token();
349 
350         if (0 != awss_cmp_coap_send_resp(buf, strlen(buf), ctx->remote, topic,
351                                          ctx->request, NULL, NULL, 0)) {
352             awss_err("sending failed.");
353         }
354 
355         HAL_Free(buf);
356         awss_release_coap_ctx(coap_session_ctx);
357         coap_session_ctx = NULL;
358         awss_stop_timer(get_devinfo_timer);
359         get_devinfo_timer = NULL;
360     } while (0);
361 
362     return 0;
363 
364 GET_DEV_INFO_ERR:
365     awss_release_coap_ctx(coap_session_ctx);
366     coap_session_ctx = NULL;
367     awss_stop_timer(get_devinfo_timer);
368     get_devinfo_timer = NULL;
369 
370     if (buf) {
371         HAL_Free(buf);
372     }
373     if (dev_info) {
374         HAL_Free(dev_info);
375     }
376 
377     return -1;
378 }
379 
online_get_device_info(void * ctx,void * resource,void * remote,void * request,char is_mcast)380 static int online_get_device_info(void *ctx, void *resource, void *remote,
381                                   void *request, char is_mcast)
382 {
383     int timeout = 0;
384     /*
385      * if cloud is not ready, don't response token
386      */
387     if (awss_report_token_cnt == 0) {
388         return -1;
389     }
390 
391     if (awss_check_reset()) {
392         return -1;
393     }
394     /*
395      * if the last one is not finished, drop current request
396      */
397     if (coap_session_ctx != NULL) {
398         awss_debug("no req");
399         return -1;
400     }
401     /*
402      * copy coap session context
403      */
404     coap_session_ctx = awss_cpy_coap_ctx(request, remote, is_mcast);
405     if (coap_session_ctx == NULL) {
406         awss_err("cpy req ctx fail");
407         return -1;
408     }
409 
410     timeout = awss_token_timeout();
411     if (timeout) {
412         produce_random(aes_random, sizeof(aes_random));
413         awss_report_token();
414     }
415 
416     if (get_devinfo_timer == NULL) {
417         get_devinfo_timer = HAL_Timer_Create(
418             "get_devinfo", (void (*)(void *))awss_process_get_devinfo, NULL);
419     }
420     HAL_Timer_Stop(get_devinfo_timer);
421     HAL_Timer_Start(get_devinfo_timer, timeout ? AWSS_CHECK_RESP_TIME : 1);
422 
423     return 0;
424 }
425 
online_mcast_get_device_info(void * ctx,void * resource,void * remote,void * request)426 int online_mcast_get_device_info(void *ctx, void *resource, void *remote,
427                                  void *request)
428 {
429     return online_get_device_info(ctx, resource, remote, request, 1);
430 }
431 
online_ucast_get_device_info(void * ctx,void * resource,void * remote,void * request)432 int online_ucast_get_device_info(void *ctx, void *resource, void *remote,
433                                  void *request)
434 {
435     return online_get_device_info(ctx, resource, remote, request, 0);
436 }
437 
438 static int dev_bind_interval = 0;
439 static char dev_bind_cnt = 0;
440 
441 #ifndef DEV_BIND_DISABLE_NOTIFY
442 /*
443  * {
444  *  "id": "123",
445  *  "code": 200,
446  *  "data": {}
447  * }
448  */
awss_dev_bind_notify_resp(void * context,int result,void * userdata,void * remote,void * message)449 static int awss_dev_bind_notify_resp(void *context, int result, void *userdata,
450                                      void *remote, void *message)
451 {
452     int res = awss_notify_response(AWSS_NOTIFY_DEV_BIND_TOKEN, result, message);
453     if (res == 1) {
454         awss_update_token();
455 #ifdef DEV_BIND_TEST
456         HAL_Reboot();
457 #endif
458     }
459     return res;
460 }
461 
__awss_dev_bind_notify()462 static int __awss_dev_bind_notify()
463 {
464     /*
465      * wait for token is sent to cloud and rx reply from cloud
466      */
467     if (awss_report_token_suc == 0) {
468         if (dev_bind_notify_timer == NULL) {
469             dev_bind_notify_timer = HAL_Timer_Create(
470                 "dev_bind", (void (*)(void *))__awss_dev_bind_notify, NULL);
471         }
472         HAL_Timer_Stop(dev_bind_notify_timer);
473         HAL_Timer_Start(dev_bind_notify_timer, AWSS_CHECK_RESP_TIME);
474         return 0;
475     }
476 
477     if (dev_bind_notify_mutex == NULL) {
478         dev_bind_notify_mutex = HAL_MutexCreate();
479         if (dev_bind_notify_mutex == NULL) {
480             return -1;
481         }
482     }
483 
484     if (dev_bind_cnt == 0) {
485         awss_event_post(IOTX_AWSS_BIND_NOTIFY);
486     }
487 
488     HAL_MutexLock(dev_bind_notify_mutex);
489 
490     do {
491         uint8_t i = 0;
492 
493         if (awss_notify_resp[AWSS_NOTIFY_DEV_BIND_TOKEN] != 0) {
494             break;
495         }
496 
497         for (i = 0; i < RANDOM_MAX_LEN; i++)
498             if (aes_random[i] != 0x00) {
499                 break;
500             }
501 
502         if (i >= RANDOM_MAX_LEN) {
503             produce_random(aes_random, sizeof(aes_random));
504         }
505 
506         if (awss_token_timeout() == 0) {
507             awss_notify_dev_info(AWSS_NOTIFY_DEV_BIND_TOKEN, 1);
508             dev_bind_interval += 100;
509             dev_bind_cnt++;
510         }
511 #ifdef DEV_BIND_TEST
512         if (dev_bind_cnt > 3) {
513             HAL_Reboot();
514         }
515 #endif
516 
517         if (dev_bind_cnt < AWSS_NOTIFY_CNT_MAX &&
518             awss_notify_resp[AWSS_NOTIFY_DEV_BIND_TOKEN] == 0) {
519             if (dev_bind_notify_timer == NULL) {
520                 dev_bind_notify_timer = HAL_Timer_Create(
521                     "dev_bind", (void (*)(void *))awss_dev_bind_notify, NULL);
522             }
523             HAL_Timer_Stop(dev_bind_notify_timer);
524             HAL_Timer_Start(dev_bind_notify_timer, dev_bind_interval);
525             HAL_MutexUnlock(dev_bind_notify_mutex);
526             return 0;
527         }
528     } while (0);
529 
530     awss_cmp_coap_cancel_packet(g_notify_msg_id[AWSS_NOTIFY_DEV_BIND_TOKEN]);
531     g_notify_msg_id[AWSS_NOTIFY_DEV_BIND_TOKEN] = 0;
532     awss_notify_resp[AWSS_NOTIFY_DEV_BIND_TOKEN] = 0;
533     dev_bind_interval = 0;
534     dev_bind_cnt = 0;
535     if (dev_bind_notify_timer) {
536         awss_stop_timer(dev_bind_notify_timer);
537         dev_bind_notify_timer = NULL;
538     }
539     if (dev_bind_notify_mutex) {
540         HAL_MutexUnlock(dev_bind_notify_mutex);
541         HAL_MutexDestroy(dev_bind_notify_mutex);
542         dev_bind_notify_mutex = NULL;
543     }
544     return 1;
545 }
546 
awss_dev_bind_notify()547 int awss_dev_bind_notify()
548 {
549     dev_bind_cnt = 0;
550     dev_bind_interval = 0;
551     awss_notify_resp[AWSS_NOTIFY_DEV_BIND_TOKEN] = 0;
552 
553     return __awss_dev_bind_notify();
554 }
555 
awss_dev_bind_notify_stop()556 int awss_dev_bind_notify_stop()
557 {
558     if (dev_bind_notify_mutex) {
559         HAL_MutexLock(dev_bind_notify_mutex);
560     }
561 
562     do {
563         awss_notify_resp[AWSS_NOTIFY_DEV_BIND_TOKEN] = 1;
564         dev_bind_cnt = AWSS_NOTIFY_CNT_MAX;
565         if (dev_bind_notify_timer == NULL) {
566             break;
567         }
568 
569         awss_stop_timer(dev_bind_notify_timer);
570         dev_bind_notify_timer = NULL;
571     } while (0);
572 
573     awss_cmp_coap_cancel_packet(g_notify_msg_id[AWSS_NOTIFY_DEV_BIND_TOKEN]);
574     g_notify_msg_id[AWSS_NOTIFY_DEV_BIND_TOKEN] = 0;
575 
576     if (dev_bind_notify_mutex) {
577         HAL_MutexUnlock(dev_bind_notify_mutex);
578         HAL_MutexDestroy(dev_bind_notify_mutex);
579         dev_bind_notify_mutex = NULL;
580     }
581     return 0;
582 }
583 #endif
584 
585 #ifdef WIFI_PROVISION_ENABLED
586 static int suc_interval = 0;
587 static char suc_cnt = 0;
__awss_suc_notify()588 static int __awss_suc_notify()
589 {
590     awss_debug("resp:%d\r\n", awss_notify_resp[AWSS_NOTIFY_SUCCESS]);
591 
592     if (success_notify_mutex == NULL) {
593         success_notify_mutex = HAL_MutexCreate();
594         if (success_notify_mutex == NULL) {
595             return -1;
596         }
597     }
598 
599     if (suc_cnt == 0) {
600         awss_event_post(IOTX_AWSS_SUC_NOTIFY);
601     }
602 
603     HAL_MutexLock(success_notify_mutex);
604 
605     do {
606         if (awss_notify_resp[AWSS_NOTIFY_SUCCESS] != 0) {
607             break;
608         }
609 
610         awss_notify_dev_info(AWSS_NOTIFY_SUCCESS, 1);
611 
612         suc_interval += 100;
613         if (suc_cnt++ < AWSS_NOTIFY_CNT_MAX &&
614             awss_notify_resp[AWSS_NOTIFY_SUCCESS] == 0) {
615             if (success_notify_timer == NULL) {
616                 success_notify_timer = HAL_Timer_Create(
617                     "awss_suc", (void (*)(void *))__awss_suc_notify, NULL);
618             }
619             HAL_Timer_Stop(success_notify_timer);
620             HAL_Timer_Start(success_notify_timer, suc_interval);
621             HAL_MutexUnlock(success_notify_mutex);
622             return 0;
623         }
624     } while (0);
625 
626     awss_cmp_coap_cancel_packet(g_notify_msg_id[AWSS_NOTIFY_SUCCESS]);
627     g_notify_msg_id[AWSS_NOTIFY_SUCCESS] = 0;
628 
629     awss_notify_resp[AWSS_NOTIFY_SUCCESS] = 0;
630     suc_interval = 0;
631     suc_cnt = 0;
632     if (success_notify_timer) {
633         awss_stop_timer(success_notify_timer);
634         success_notify_timer = NULL;
635     }
636 
637     if (success_notify_mutex) {
638         HAL_MutexUnlock(success_notify_mutex);
639         HAL_MutexDestroy(success_notify_mutex);
640         success_notify_mutex = NULL;
641     }
642     return 1;
643 }
644 
awss_suc_notify()645 int awss_suc_notify()
646 {
647     suc_cnt = 0;
648     suc_interval = 0;
649     awss_notify_resp[AWSS_NOTIFY_SUCCESS] = 0;
650     return __awss_suc_notify();
651 }
652 
awss_suc_notify_stop()653 int awss_suc_notify_stop()
654 {
655     if (success_notify_mutex) {
656         HAL_MutexLock(success_notify_mutex);
657     }
658 
659     do {
660         awss_notify_resp[AWSS_NOTIFY_SUCCESS] = 1;
661         suc_cnt = AWSS_NOTIFY_CNT_MAX;
662         if (success_notify_timer == NULL) {
663             break;
664         }
665 
666         awss_stop_timer(success_notify_timer);
667         success_notify_timer = NULL;
668     } while (0);
669 
670     awss_cmp_coap_cancel_packet(g_notify_msg_id[AWSS_NOTIFY_SUCCESS]);
671     g_notify_msg_id[AWSS_NOTIFY_SUCCESS] = 0;
672 
673     if (success_notify_mutex) {
674         HAL_MutexUnlock(success_notify_mutex);
675         HAL_MutexDestroy(success_notify_mutex);
676         success_notify_mutex = NULL;
677     }
678     return 0;
679 }
680 
681 static int devinfo_interval = 0;
682 static char devinfo_cnt = 0;
__awss_devinfo_notify()683 static int __awss_devinfo_notify()
684 {
685     if (devinfo_notify_mutex == NULL) {
686         devinfo_notify_mutex = HAL_MutexCreate();
687         if (devinfo_notify_mutex == NULL) {
688             return -1;
689         }
690     }
691     HAL_MutexLock(devinfo_notify_mutex);
692 
693     do {
694         if (awss_notify_resp[AWSS_NOTIFY_DEV_RAND_SIGN] != 0) {
695             break;
696         }
697 
698         awss_notify_dev_info(AWSS_NOTIFY_DEV_RAND_SIGN, 1);
699 
700         devinfo_interval += 100;
701         if (devinfo_cnt++ < AWSS_NOTIFY_CNT_MAX &&
702             awss_notify_resp[AWSS_NOTIFY_DEV_RAND_SIGN] == 0) {
703             if (devinfo_notify_timer == NULL) {
704                 devinfo_notify_timer = HAL_Timer_Create(
705                     "devinfo", (void (*)(void *))__awss_devinfo_notify, NULL);
706             }
707             HAL_Timer_Stop(devinfo_notify_timer);
708             HAL_Timer_Start(devinfo_notify_timer, devinfo_interval);
709             HAL_MutexUnlock(devinfo_notify_mutex);
710             return 0;
711         }
712     } while (0);
713 
714     awss_cmp_coap_cancel_packet(g_notify_msg_id[AWSS_NOTIFY_DEV_RAND_SIGN]);
715     g_notify_msg_id[AWSS_NOTIFY_DEV_RAND_SIGN] = 0;
716 
717     awss_notify_resp[AWSS_NOTIFY_DEV_RAND_SIGN] = 0;
718     devinfo_interval = 0;
719     devinfo_cnt = 0;
720     if (devinfo_notify_timer) {
721         awss_stop_timer(devinfo_notify_timer);
722         devinfo_notify_timer = NULL;
723     }
724     if (devinfo_notify_mutex) {
725         HAL_MutexUnlock(devinfo_notify_mutex);
726         HAL_MutexDestroy(devinfo_notify_mutex);
727         devinfo_notify_mutex = NULL;
728     }
729     return 1;
730 }
731 
awss_devinfo_notify()732 int awss_devinfo_notify()
733 {
734     devinfo_cnt = 0;
735     devinfo_interval = 0;
736     awss_notify_resp[AWSS_NOTIFY_DEV_RAND_SIGN] = 0;
737     return __awss_devinfo_notify();
738 }
739 
awss_devinfo_notify_stop()740 int awss_devinfo_notify_stop()
741 {
742     if (devinfo_notify_mutex) {
743         HAL_MutexLock(devinfo_notify_mutex);
744     }
745 
746     do {
747         awss_notify_resp[AWSS_NOTIFY_DEV_RAND_SIGN] = 1;
748         devinfo_cnt = AWSS_NOTIFY_CNT_MAX;
749         if (devinfo_notify_timer == NULL) {
750             break;
751         }
752 
753         awss_stop_timer(devinfo_notify_timer);
754         devinfo_notify_timer = NULL;
755     } while (0);
756 
757     awss_cmp_coap_cancel_packet(g_notify_msg_id[AWSS_NOTIFY_DEV_RAND_SIGN]);
758     g_notify_msg_id[AWSS_NOTIFY_DEV_RAND_SIGN] = 0;
759 
760     if (devinfo_notify_mutex) {
761         HAL_MutexUnlock(devinfo_notify_mutex);
762         HAL_MutexDestroy(devinfo_notify_mutex);
763         devinfo_notify_mutex = NULL;
764     }
765     return 0;
766 }
767 
768 #endif
769 
770 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
771 }
772 #endif
773