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