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 #define AWSS_CONNAP_MONITOR_TIMEOUT_MS (60 * 1000)
10 
11 static char g_awss_connectap_info_avaliable = 0;
12 static void *connectap_monitor_timer = NULL;
13 static void *connectap_monitor_mutex = NULL;
14 
awss_release_connectap_monitor()15 static void awss_release_connectap_monitor()
16 {
17     if (connectap_monitor_timer) {
18         HAL_Timer_Stop(connectap_monitor_timer);
19         HAL_Timer_Delete(connectap_monitor_timer);
20         connectap_monitor_timer = NULL;
21     }
22     if (connectap_monitor_mutex) {
23         HAL_MutexUnlock(connectap_monitor_mutex);
24         HAL_MutexDestroy(connectap_monitor_mutex);
25         connectap_monitor_mutex = NULL;
26     }
27 }
28 
awss_connectap_monitor(void * param)29 static void awss_connectap_monitor(void *param)
30 {
31     if (connectap_monitor_mutex) {
32         HAL_MutexLock(connectap_monitor_mutex);
33     }
34     g_awss_connectap_info_avaliable = 0;
35     awss_release_connectap_monitor();
36 }
37 
awss_stop_connectap_monitor()38 int awss_stop_connectap_monitor()
39 {
40     awss_connectap_monitor(NULL);
41     return 0;
42 }
43 
awss_start_connectap_monitor()44 int awss_start_connectap_monitor()
45 {
46     if (connectap_monitor_timer) {
47         awss_debug("connap-m exist");
48         return 0;
49     }
50 
51     if (connectap_monitor_mutex == NULL) {
52         connectap_monitor_mutex = HAL_MutexCreate();
53         if (connectap_monitor_mutex == NULL) {
54             awss_err("connap alloc-m fail");
55             goto CONNAP_M_FAIL;
56         }
57     }
58 
59     HAL_MutexLock(connectap_monitor_mutex);
60 
61     connectap_monitor_timer =
62         HAL_Timer_Create("connap_monitor", awss_connectap_monitor, NULL);
63     if (connectap_monitor_timer == NULL) {
64         awss_err("connap alloc-t fail");
65         goto CONNAP_M_FAIL;
66     }
67 
68     g_awss_connectap_info_avaliable = 1;
69     HAL_Timer_Stop(connectap_monitor_timer);
70     HAL_Timer_Start(connectap_monitor_timer, AWSS_CONNAP_MONITOR_TIMEOUT_MS);
71     HAL_MutexUnlock(connectap_monitor_mutex);
72     return 0;
73 
74 CONNAP_M_FAIL:
75     awss_release_connectap_monitor();
76     return -1;
77 }
78 
process_get_device_info(void * ctx,void * resource,void * remote,void * request,char is_mcast,int type)79 int process_get_device_info(void *ctx, void *resource, void *remote,
80                             void *request, char is_mcast, int type)
81 {
82     char *buf = NULL;
83     char *dev_info = NULL;
84     int len = 0, id_len = 0;
85     char *msg = NULL, *id = NULL;
86     const char *topic_fmt = NULL;
87     char topic[TOPIC_LEN_MAX] = { 0 };
88     char req_msg_id[MSG_REQ_ID_LEN] = { 0 };
89 
90     buf = awss_zalloc(DEV_INFO_LEN_MAX);
91     if (!buf) {
92         goto DEV_INFO_ERR;
93     }
94 
95     dev_info = awss_zalloc(DEV_INFO_LEN_MAX);
96     if (!dev_info) {
97         goto DEV_INFO_ERR;
98     }
99 
100     msg = awss_cmp_get_coap_payload(request, &len);
101     id = json_get_value_by_name(msg, len, "id", &id_len, 0);
102     if (id && id_len < MSG_REQ_ID_LEN) {
103         memcpy(req_msg_id, id, id_len);
104     }
105 
106     if (type == AWSS_NOTIFY_DEV_RAND_SIGN) {
107         topic_fmt = is_mcast ? TOPIC_AWSS_GETDEVICEINFO_MCAST
108                              : TOPIC_AWSS_GETDEVICEINFO_UCAST;
109     } else if (type == AWSS_NOTIFY_SUCCESS) {
110         topic_fmt = is_mcast ? TOPIC_AWSS_GET_CONNECTAP_INFO_MCAST
111                              : TOPIC_AWSS_GET_CONNECTAP_INFO_UCAST;
112     } else {
113         goto DEV_INFO_ERR;
114     }
115     awss_build_dev_info(type, buf, DEV_INFO_LEN_MAX);
116     HAL_Snprintf(dev_info, DEV_INFO_LEN_MAX - 1, "{%s}", buf);
117 
118     memset(buf, 0x00, DEV_INFO_LEN_MAX);
119     HAL_Snprintf(buf, DEV_INFO_LEN_MAX - 1, AWSS_ACK_FMT, req_msg_id, 200,
120                  dev_info);
121 
122     HAL_Free(dev_info);
123 
124     awss_info("tx msg to app: %s", buf);
125 
126     awss_build_topic(topic_fmt, topic, TOPIC_LEN_MAX);
127 
128     if (0 != awss_cmp_coap_send_resp(buf, strlen(buf), remote, topic, request,
129                                      NULL, NULL, 0)) {
130         awss_err("tx dev info rsp fail.");
131     }
132 
133     HAL_Free(buf);
134     return 0;
135 
136 DEV_INFO_ERR:
137     if (buf) {
138         HAL_Free(buf);
139     }
140     if (dev_info) {
141         HAL_Free(dev_info);
142     }
143 
144     return -1;
145 }
146 
awss_process_mcast_get_connectap_info(void * ctx,void * resource,void * remote,void * request)147 int awss_process_mcast_get_connectap_info(void *ctx, void *resource,
148                                           void *remote, void *request)
149 {
150     if (g_awss_connectap_info_avaliable == 0) {
151         return -1;
152     }
153     return process_get_device_info(ctx, resource, remote, request, 1,
154                                    AWSS_NOTIFY_SUCCESS);
155 }
156 
awss_process_ucast_get_connectap_info(void * ctx,void * resource,void * remote,void * request)157 int awss_process_ucast_get_connectap_info(void *ctx, void *resource,
158                                           void *remote, void *request)
159 {
160     if (g_awss_connectap_info_avaliable == 0) {
161         return -1;
162     }
163     return process_get_device_info(ctx, resource, remote, request, 0,
164                                    AWSS_NOTIFY_SUCCESS);
165 }
166 
167 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
168 }
169 #endif
170