1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4 #include "dev_bind_internal.h"
5 #ifdef WIFI_PROVISION_ENABLED
6 #if defined(AWSS_SUPPORT_AHA)
7 #include "awss_wifimgr.h"
8 #endif
9 #endif
10
11 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
12 extern "C" {
13 #endif
14
15 static void *g_coap_ctx = NULL;
16
awss_release_coap_ctx(void * session)17 int awss_release_coap_ctx(void *session)
18 {
19 struct coap_session_ctx_t *ctx = (struct coap_session_ctx_t *)session;
20 if (ctx == NULL) {
21 return 0;
22 }
23
24 if (ctx->request) {
25 void *payload = ((struct CoAPMessage *)ctx->request)->payload;
26 if (payload) {
27 HAL_Free(payload);
28 }
29 HAL_Free(ctx->request);
30 }
31 if (ctx->remote) {
32 HAL_Free(ctx->remote);
33 }
34 HAL_Free(ctx);
35 return 0;
36 }
37
awss_cpy_coap_ctx(void * request,void * remote,char mcast)38 void *awss_cpy_coap_ctx(void *request, void *remote, char mcast)
39 {
40 struct coap_session_ctx_t *ctx =
41 awss_zalloc(sizeof(struct coap_session_ctx_t));
42 if (ctx == NULL) {
43 goto CPY_CTX_FAIL;
44 }
45
46 ctx->request = awss_zalloc(sizeof(struct CoAPMessage));
47 if (ctx->request == NULL) {
48 goto CPY_CTX_FAIL;
49 }
50
51 memcpy(ctx->request, request, sizeof(struct CoAPMessage));
52 do {
53 char *payload = NULL;
54 int len = 0;
55 struct CoAPMessage *req = (struct CoAPMessage *)ctx->request;
56
57 payload = awss_cmp_get_coap_payload(request, &len);
58 req->payloadlen = len;
59 if (payload == NULL) {
60 break;
61 }
62
63 req->payload = awss_zalloc(len + 1);
64 if (req->payload == NULL) {
65 goto CPY_CTX_FAIL;
66 }
67
68 memcpy(req->payload, payload, len);
69 } while (0);
70
71 ctx->remote = awss_zalloc(sizeof(platform_netaddr_t));
72 if (ctx->remote == NULL) {
73 goto CPY_CTX_FAIL;
74 }
75
76 memcpy(ctx->remote, remote, sizeof(platform_netaddr_t));
77 ctx->is_mcast = mcast;
78
79 return ctx;
80
81 CPY_CTX_FAIL:
82 awss_release_coap_ctx(ctx);
83 return NULL;
84 }
85
awss_cmp_get_coap_code(void * request)86 uint8_t awss_cmp_get_coap_code(void *request)
87 {
88 struct CoAPMessage *msg = NULL;
89 if (request == NULL) {
90 return 0x60;
91 }
92 msg = (struct CoAPMessage *)request;
93 return msg->header.code;
94 }
95
awss_cmp_get_coap_payload(void * request,int * payload_len)96 char *awss_cmp_get_coap_payload(void *request, int *payload_len)
97 {
98 struct CoAPMessage *msg = (struct CoAPMessage *)request;
99 if (request == NULL) {
100 return NULL;
101 }
102
103 msg = (struct CoAPMessage *)request;
104 if (payload_len) {
105 *payload_len = msg->payloadlen;
106 }
107 return (char *)msg->payload;
108 }
109
awss_cmp_coap_register_cb(char * topic,void * cb)110 int awss_cmp_coap_register_cb(char *topic, void *cb)
111 {
112 if (g_coap_ctx == NULL) {
113 g_coap_ctx = (void *)CoAPServer_init();
114 }
115
116 if (g_coap_ctx == NULL) {
117 return -1;
118 }
119 if (topic == NULL) {
120 return -1;
121 }
122
123 CoAPServer_register(g_coap_ctx, (const char *)topic,
124 (CoAPRecvMsgHandler)cb);
125 return 0;
126 }
127
awss_cmp_coap_cancel_packet(uint16_t msgid)128 int awss_cmp_coap_cancel_packet(uint16_t msgid)
129 {
130 if (g_coap_ctx == NULL) {
131 return -1;
132 }
133 return CoAPMessageId_cancel(g_coap_ctx, msgid);
134 }
135
awss_cmp_coap_send(void * buf,uint32_t len,void * sa,const char * uri,void * cb,uint16_t * msgid)136 int awss_cmp_coap_send(void *buf, uint32_t len, void *sa, const char *uri,
137 void *cb, uint16_t *msgid)
138 {
139 if (g_coap_ctx == NULL) {
140 g_coap_ctx = (void *)CoAPServer_init();
141 } else {
142 CoAPMessageId_cancel(g_coap_ctx, *msgid);
143 }
144 return CoAPServerMultiCast_send(g_coap_ctx, (NetworkAddr *)sa, uri,
145 (uint8_t *)buf, (uint16_t)len,
146 (CoAPSendMsgHandler)cb, msgid);
147 }
148
awss_cmp_coap_send_resp(void * buf,uint32_t len,void * sa,const char * uri,void * req,void * cb,uint16_t * msgid,char qos)149 int awss_cmp_coap_send_resp(void *buf, uint32_t len, void *sa, const char *uri,
150 void *req, void *cb, uint16_t *msgid, char qos)
151 {
152 if (g_coap_ctx == NULL) {
153 g_coap_ctx = (void *)CoAPServer_init();
154 }
155
156 return CoAPServerResp_send(g_coap_ctx, (NetworkAddr *)sa, (uint8_t *)buf,
157 (uint16_t)len, req, uri, (CoAPSendMsgHandler)cb,
158 msgid, qos);
159 }
160
awss_cmp_coap_ob_send(void * buf,uint32_t len,void * sa,const char * uri,void * cb)161 int awss_cmp_coap_ob_send(void *buf, uint32_t len, void *sa, const char *uri,
162 void *cb)
163 {
164 if (g_coap_ctx == NULL) {
165 g_coap_ctx = (void *)CoAPServer_init();
166 }
167
168 return CoAPObsServer_notify(g_coap_ctx, uri, (uint8_t *)buf, (uint16_t)len,
169 cb);
170 }
171
awss_cmp_coap_deinit()172 int awss_cmp_coap_deinit()
173 {
174 void *coap_ctx = g_coap_ctx;
175 g_coap_ctx = NULL;
176
177 if (coap_ctx) {
178 CoAPServer_deinit(coap_ctx);
179 }
180
181 return 0;
182 }
183
184 const struct awss_cmp_couple awss_local_couple[] = {
185 #ifdef WIFI_PROVISION_ENABLED
186 #if defined(AWSS_SUPPORT_AHA)
187 { AWSS_LC_INIT_PAP, TOPIC_AWSS_SWITCHAP,
188 wifimgr_process_switch_ap_request },
189 { AWSS_LC_INIT_ROUTER | AWSS_LC_INIT_PAP, TOPIC_AWSS_GETDEVICEINFO_MCAST,
190 wifimgr_process_mcast_get_device_info },
191 { AWSS_LC_INIT_ROUTER | AWSS_LC_INIT_PAP, TOPIC_AWSS_GETDEVICEINFO_UCAST,
192 wifimgr_process_ucast_get_device_info },
193 #endif
194 #ifdef AWSS_SUPPORT_DEV_AP
195 { AWSS_LC_INIT_DEV_AP, TOPIC_AWSS_DEV_AP_SWITCHAP,
196 wifimgr_process_dev_ap_switchap_request },
197 #endif
198 { AWSS_LC_INIT_SUC, TOPIC_AWSS_GET_CONNECTAP_INFO_MCAST,
199 awss_process_mcast_get_connectap_info },
200 { AWSS_LC_INIT_SUC, TOPIC_AWSS_GET_CONNECTAP_INFO_UCAST,
201 awss_process_ucast_get_connectap_info },
202 #ifndef AWSS_DISABLE_REGISTRAR
203 { AWSS_LC_INIT_BIND, TOPIC_NOTIFY, online_dev_bind_monitor },
204 { AWSS_LC_INIT_BIND, TOPIC_AWSS_CONNECTAP_NOTIFY, online_dev_bind_monitor },
205 #endif
206 #endif
207 { AWSS_LC_INIT_SUC | AWSS_LC_INIT_BIND, TOPIC_GETDEVICEINFO_MCAST,
208 online_mcast_get_device_info },
209 { AWSS_LC_INIT_SUC | AWSS_LC_INIT_BIND, TOPIC_GETDEVICEINFO_UCAST,
210 online_ucast_get_device_info },
211 };
212
awss_cmp_local_init(int init_stage)213 int awss_cmp_local_init(int init_stage)
214 {
215 char topic[TOPIC_LEN_MAX] = { 0 };
216 int i;
217
218 for (i = 0; i < sizeof(awss_local_couple) / sizeof(awss_local_couple[0]);
219 i++) {
220 if ((awss_local_couple[i].init_stage & init_stage) == 0) {
221 continue;
222 }
223 memset(topic, 0, sizeof(topic));
224 awss_build_topic(awss_local_couple[i].topic, topic, TOPIC_LEN_MAX);
225 awss_cmp_coap_register_cb(topic, awss_local_couple[i].cb);
226 }
227
228 return 0;
229 }
230
awss_cmp_local_deinit(int force)231 int awss_cmp_local_deinit(int force)
232 {
233 if (g_coap_ctx == NULL) {
234 return 0;
235 }
236 #ifdef WIFI_PROVISION_ENABLED
237 #if defined(AWSS_SUPPORT_AHA)
238 awss_devinfo_notify_stop();
239 #endif
240 awss_suc_notify_stop();
241 #endif
242 if (force) {
243 awss_cmp_coap_deinit();
244 }
245
246 return 0;
247 }
248 #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
249 }
250 #endif
251