1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #include <stddef.h>
6 #include <string.h>
7 
8 #include "alcs_internal.h"
9 #include "linkkit/alcs_api.h"
10 #include "alcs_coap.h"
11 #include "alcs_mqtt.h"
12 #include "CoAPInternal.h"
13 #include "CoAPExport.h"
14 #include "CoAPServer.h"
15 #include "alcs_adapter.h"
16 #include "alcs_mqtt.h"
17 #include "alcs_localsetup.h"
18 #include "CoAPPlatform.h"
19 
20 static iotx_alcs_adapter_t g_alcs_adapter;
21 
22 static void alcs_heartbeat(void *handle);
23 
__iotx_alcs_get_ctx(void)24 static iotx_alcs_adapter_t *__iotx_alcs_get_ctx(void)
25 {
26     return &g_alcs_adapter;
27 }
28 
iotx_alcs_topic_parse_pk(char * topic,uint16_t * length)29 static char *iotx_alcs_topic_parse_pk(char *topic, uint16_t *length)
30 {
31     char *pos = NULL;
32     uint8_t slash_count = 0;
33     uint16_t idx = 0;
34     uint16_t topic_len = 0;
35 
36     if (topic == NULL || length == NULL) {
37         COAP_ERR("Invalid Parameter");
38         return NULL;
39     }
40 
41     topic_len = strlen(topic);
42 
43     while (idx < topic_len) {
44         if (topic[idx] == '/') {
45             slash_count++;
46             if (slash_count == 2) {
47                 pos = topic + idx + 1;
48             }
49             if (slash_count == 3) {
50                 *length = topic + idx - pos;
51             }
52         }
53         idx++;
54     }
55 
56     return pos;
57 }
58 
iotx_alcs_topic_parse_dn(char * topic,uint16_t * length)59 static char *iotx_alcs_topic_parse_dn(char *topic, uint16_t *length)
60 {
61     char *pos = NULL;
62     uint8_t slash_count = 0;
63     uint16_t idx = 0;
64     uint16_t topic_len = 0;
65 
66     if (topic == NULL || length == NULL) {
67         COAP_ERR("Invalid Parameter");
68         return NULL;
69     }
70 
71     topic_len = strlen(topic);
72 
73     while (idx < topic_len) {
74         if (topic[idx] == '/') {
75             slash_count++;
76             if (slash_count == 3) {
77                 pos = topic + idx + 1;
78             }
79             if (slash_count == 4) {
80                 *length = topic + idx - pos;
81             }
82         }
83         idx++;
84     }
85 
86     return pos;
87 }
88 
_iotx_alcs_send_list_search_and_remove(iotx_alcs_adapter_t * adapter,CoAPMessage * message,iotx_alcs_send_msg_t ** send_msg)89 static int _iotx_alcs_send_list_search_and_remove(
90     iotx_alcs_adapter_t *adapter, CoAPMessage *message,
91     iotx_alcs_send_msg_t **send_msg)
92 {
93     iotx_alcs_send_msg_t *node = NULL;
94     iotx_alcs_send_msg_t *next = NULL;
95 
96     list_for_each_entry_safe(node, next, &adapter->alcs_send_list, linked_list,
97                              iotx_alcs_send_msg_t)
98     {
99         if (message->header.tokenlen == node->token_len &&
100             memcmp(message->token, node->token, node->token_len) == 0) {
101             *send_msg = node;
102             list_del(&node->linked_list);
103             return SUCCESS_RETURN;
104         }
105     }
106 
107     return FAIL_RETURN;
108 }
109 
iotx_alcs_coap_adapter_send_msg_handle(CoAPContext * context,CoAPReqResult result,void * userdata,NetworkAddr * remote,CoAPMessage * message)110 void iotx_alcs_coap_adapter_send_msg_handle(CoAPContext *context,
111                                             CoAPReqResult result,
112                                             void *userdata, NetworkAddr *remote,
113                                             CoAPMessage *message)
114 {
115     int res = 0;
116     iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)userdata;
117     iotx_alcs_event_msg_t event;
118     memset(&event, 0, sizeof(iotx_alcs_event_msg_t));
119 
120     switch (result) {
121     case COAP_REQUEST_SUCCESS:
122         {
123             iotx_alcs_transfer_msg_t transfer_msg;
124             iotx_alcs_send_msg_t *send_msg = NULL;
125 
126             memset(&transfer_msg, 0, sizeof(iotx_alcs_transfer_msg_t));
127 
128             transfer_msg.ip = (char *)remote->addr;
129             transfer_msg.port = remote->port;
130             HAL_MutexLock(adapter->mutex);
131             res = _iotx_alcs_send_list_search_and_remove(adapter, message,
132                                                          &send_msg);
133             HAL_MutexUnlock(adapter->mutex);
134 
135             if (res < SUCCESS_RETURN) {
136                 return;
137             }
138 
139             transfer_msg.uri = send_msg->uri;
140             transfer_msg.token_len = send_msg->token_len;
141             transfer_msg.token = send_msg->token;
142             transfer_msg.payload_len = message->payloadlen;
143             transfer_msg.payload = message->payload;
144 
145             event.event_type = IOTX_ALCS_EVENT_MSG_SEND_MESSAGE_SUCCESS;
146             event.msg = &transfer_msg;
147 
148             adapter->alcs_event_handle->h_fp(
149                 adapter->alcs_event_handle->pcontext, (void *)adapter, &event);
150 
151             ALCS_free(send_msg->token);
152             ALCS_free(send_msg->uri);
153             ALCS_free(send_msg);
154         }
155         break;
156     case COAP_RECV_RESP_TIMEOUT:
157         {
158             iotx_alcs_transfer_msg_t transfer_msg;
159             iotx_alcs_send_msg_t *send_msg = NULL;
160 
161             memset(&transfer_msg, 0, sizeof(iotx_alcs_transfer_msg_t));
162 
163             transfer_msg.ip = (char *)remote->addr;
164             transfer_msg.port = remote->port;
165             HAL_MutexLock(adapter->mutex);
166             res = _iotx_alcs_send_list_search_and_remove(adapter, message,
167                                                          &send_msg);
168             HAL_MutexUnlock(adapter->mutex);
169 
170             if (res < SUCCESS_RETURN) {
171                 return;
172             }
173 
174             transfer_msg.uri = send_msg->uri;
175             transfer_msg.token_len = send_msg->token_len;
176             transfer_msg.token = send_msg->token;
177             transfer_msg.payload_len = 0;
178             transfer_msg.payload = NULL;
179 
180             event.event_type = IOTX_ALCS_EVENT_MSG_SEND_MESSAGE_RESP_TIMEOUT;
181             event.msg = &transfer_msg;
182 
183             adapter->alcs_event_handle->h_fp(
184                 adapter->alcs_event_handle->pcontext, (void *)adapter, &event);
185 
186             ALCS_free(send_msg->token);
187             ALCS_free(send_msg->uri);
188             ALCS_free(send_msg);
189         }
190         break;
191     default:
192         COAP_WRN("Unknown Coap Request Result: %d", result);
193         break;
194     }
195 }
196 
iotx_alcs_coap_adapter_event_notifier(unsigned int event,NetworkAddr * remote,void * message)197 void iotx_alcs_coap_adapter_event_notifier(unsigned int event,
198                                            NetworkAddr *remote, void *message)
199 {
200     COAP_INFO(
201         "ALCS Coap Event: %d, Remote Device Address: %s, Remote Device Port: "
202         "%d",
203         event, remote->addr, remote->port);
204 }
205 
iotx_alcs_adapter_list_init(iotx_alcs_adapter_t * adapter)206 int iotx_alcs_adapter_list_init(iotx_alcs_adapter_t *adapter)
207 {
208     /* initialze send list */
209     INIT_LIST_HEAD(&adapter->alcs_send_list);
210     INIT_LIST_HEAD(&adapter->alcs_subdev_list);
211 
212     return SUCCESS_RETURN;
213 }
214 
_iotx_alcs_adapter_send_list_destroy(iotx_alcs_adapter_t * adapter)215 static void _iotx_alcs_adapter_send_list_destroy(iotx_alcs_adapter_t *adapter)
216 {
217     iotx_alcs_send_msg_t *node = NULL;
218     iotx_alcs_send_msg_t *next = NULL;
219 
220     list_for_each_entry_safe(node, next, &adapter->alcs_send_list, linked_list,
221                              iotx_alcs_send_msg_t)
222     {
223         list_del(&node->linked_list);
224         ALCS_free(node->token);
225         ALCS_free(node->uri);
226         ALCS_free(node);
227     }
228 }
229 
_iotx_alcs_adapter_subdev_list_destroy(iotx_alcs_adapter_t * adapter)230 static void _iotx_alcs_adapter_subdev_list_destroy(iotx_alcs_adapter_t *adapter)
231 {
232     iotx_alcs_subdev_item_t *node = NULL;
233     iotx_alcs_subdev_item_t *next = NULL;
234 
235     list_for_each_entry_safe(node, next, &adapter->alcs_subdev_list,
236                              linked_list, iotx_alcs_subdev_item_t)
237     {
238         list_del(&node->linked_list);
239         ALCS_free(node);
240     }
241 }
242 
iotx_alcs_adapter_deinit(void)243 int iotx_alcs_adapter_deinit(void)
244 {
245     char product_key[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
246     char device_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
247     iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
248 
249     HAL_GetProductKey(product_key);
250     HAL_GetDeviceName(device_name);
251 
252     HAL_MutexLock(adapter->mutex);
253     _iotx_alcs_adapter_send_list_destroy(adapter);
254     _iotx_alcs_adapter_subdev_list_destroy(adapter);
255     HAL_MutexUnlock(adapter->mutex);
256 
257     if (adapter->alcs_event_handle) {
258         ALCS_free(adapter->alcs_event_handle);
259     }
260 
261     HAL_MutexDestroy(adapter->mutex);
262 
263     alcs_mqtt_deinit(adapter->coap_ctx, product_key, device_name);
264 
265     /* if (adapter->coap_ctx) CoAPContext_free(adapter->coap_ctx); */
266 
267     alcs_context_deinit();
268     alcs_deinit();
269     alcs_auth_deinit();
270 
271     return SUCCESS_RETURN;
272 }
273 
iotx_alcs_adapter_init(iotx_alcs_adapter_t * adapter,iotx_alcs_param_t * param)274 int iotx_alcs_adapter_init(iotx_alcs_adapter_t *adapter,
275                            iotx_alcs_param_t *param)
276 {
277     int res;
278     CoAPInitParam coap_param;
279     CoAPContext *coap_ctx = NULL;
280     char product_key[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
281     char device_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
282 
283     COAP_INFO("iotx_alcs_adapter_init");
284     memset(&coap_param, 0, sizeof(CoAPInitParam));
285 
286     adapter->mutex = HAL_MutexCreate();
287     if (adapter->mutex == NULL) {
288         COAP_ERR("Mutex Init Failed");
289         return FAIL_RETURN;
290     }
291 
292     coap_param.send_maxcount = param->send_maxcount;
293     coap_param.obs_maxcount = param->obs_maxcount;
294     coap_param.port = param->port;
295     coap_param.group = param->group;
296     coap_param.waittime = param->waittime;
297     coap_param.res_maxcount = param->res_maxcount;
298     coap_param.appdata = NULL;
299     coap_param.notifier = iotx_alcs_coap_adapter_event_notifier;
300 
301     coap_ctx = alcs_context_init(&coap_param);
302     if (coap_ctx == NULL) {
303         COAP_ERR("Coap Context Init Failed");
304         HAL_MutexDestroy(adapter->mutex);
305         return FAIL_RETURN;
306     }
307     adapter->coap_ctx = coap_ctx;
308 
309     res = HAL_GetProductKey(product_key);
310     if (res <= 0 || res > IOTX_PRODUCT_KEY_LEN + 1 - 1) {
311         iotx_alcs_adapter_deinit();
312         COAP_ERR("Get Product Key Failed");
313         return FAIL_RETURN;
314     }
315 
316     res = HAL_GetDeviceName(device_name);
317     if (res <= 0 || res > IOTX_DEVICE_NAME_LEN + 1 - 1) {
318         iotx_alcs_adapter_deinit();
319         COAP_ERR("Get Device Name Failed");
320         return FAIL_RETURN;
321     }
322 
323     alcs_init();
324 
325     res = alcs_auth_init(coap_ctx, product_key, device_name, param->role);
326     if (res != COAP_SUCCESS) {
327         iotx_alcs_adapter_deinit();
328         COAP_ERR("ALCS Auth Init Failed");
329         return FAIL_RETURN;
330     }
331     adapter->role = param->role;
332 #ifdef ALCS_SERVER_ENABLED
333     {
334         extern void on_svr_auth_timer(CoAPContext *);
335         if (adapter->role & IOTX_ALCS_ROLE_SERVER) {
336             adapter->alcs_server_auth_timer_func = on_svr_auth_timer;
337         }
338     }
339 #endif
340 
341 #ifdef ALCS_CLIENT_ENABLED
342     {
343         extern void on_client_auth_timer(CoAPContext *);
344         if (adapter->role & IOTX_ALCS_ROLE_CLIENT) {
345             adapter->alcs_client_auth_timer_func = on_client_auth_timer;
346         }
347     }
348 #endif
349 
350     adapter->alcs_event_handle =
351         (iotx_alcs_event_handle_t *)ALCS_ADAPTER_malloc(
352             sizeof(iotx_alcs_event_handle_t));
353     if (adapter->alcs_event_handle == NULL) {
354         iotx_alcs_adapter_deinit();
355         COAP_ERR("ALCS Event Handle Init Failed");
356         return FAIL_RETURN;
357     }
358     memcpy(adapter->alcs_event_handle, param->handle_event,
359            sizeof(iotx_alcs_event_handle_t));
360 
361     if (iotx_alcs_adapter_list_init(adapter) != SUCCESS_RETURN) {
362         iotx_alcs_adapter_deinit();
363         COAP_ERR("ALCS Linked List Init Failed");
364         return FAIL_RETURN;
365     }
366 
367     alcs_localsetup_init(adapter, coap_ctx, product_key, device_name);
368 
369     return SUCCESS_RETURN;
370 }
371 
_iotx_alcs_subdev_list_search(const char * pk,const char * dn,iotx_alcs_subdev_item_t ** subdev_item)372 static int _iotx_alcs_subdev_list_search(const char *pk, const char *dn,
373                                          iotx_alcs_subdev_item_t **subdev_item)
374 {
375     iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
376     iotx_alcs_subdev_item_t *node = NULL;
377 
378     if (pk == NULL || dn == NULL) {
379         COAP_ERR("Invalid Parameter");
380         return FAIL_RETURN;
381     }
382 
383     list_for_each_entry(node, &adapter->alcs_subdev_list, linked_list,
384                         iotx_alcs_subdev_item_t)
385     {
386         if (strlen(node->product_key) == strlen(pk) &&
387             memcmp(node->product_key, pk, strlen(pk)) == 0 &&
388             strlen(node->device_name) == strlen(dn) &&
389             memcmp(node->device_name, dn, strlen(dn)) == 0) {
390             *subdev_item = node;
391             return SUCCESS_RETURN;
392         }
393     }
394 
395     return FAIL_RETURN;
396 }
397 
iotx_alcs_subdev_remove(const char * pk,const char * dn)398 int iotx_alcs_subdev_remove(const char *pk, const char *dn)
399 {
400     int res = 0;
401     iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
402     iotx_alcs_subdev_item_t *subdev_item = NULL;
403 
404     if (pk == NULL || dn == NULL) {
405         COAP_ERR("Invalid Parameter");
406         return FAIL_RETURN;
407     }
408 
409     HAL_MutexLock(adapter->mutex);
410     res = _iotx_alcs_subdev_list_search(pk, dn, &subdev_item);
411     if (res < SUCCESS_RETURN) {
412         COAP_ERR("No Matched Item");
413         HAL_MutexUnlock(adapter->mutex);
414         return FAIL_RETURN;
415     }
416 
417     list_del(&subdev_item->linked_list);
418     HAL_MutexUnlock(adapter->mutex);
419 
420     ALCS_free(subdev_item);
421 
422     return SUCCESS_RETURN;
423 }
424 
iotx_alcs_subdev_update_stage(iotx_alcs_subdev_item_t * item)425 int iotx_alcs_subdev_update_stage(iotx_alcs_subdev_item_t *item)
426 {
427     int res = 0;
428     iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
429     iotx_alcs_subdev_item_t *subdev_item = NULL;
430 
431     if (item == NULL) {
432         COAP_ERR("Invalid Parameter");
433         return FAIL_RETURN;
434     }
435 
436     HAL_MutexLock(adapter->mutex);
437     res = _iotx_alcs_subdev_list_search(item->product_key, item->device_name,
438                                         &subdev_item);
439 
440     if (res < SUCCESS_RETURN) {
441         COAP_WRN("No Matched Item");
442         HAL_MutexUnlock(adapter->mutex);
443         return FAIL_RETURN;
444     }
445 
446     subdev_item->stage = item->stage;
447 
448     HAL_MutexUnlock(adapter->mutex);
449     return SUCCESS_RETURN;
450 }
451 
iotx_alcs_subdev_stage_check(void)452 void iotx_alcs_subdev_stage_check(void)
453 {
454     iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
455     iotx_alcs_subdev_item_t *node = NULL;
456     uint64_t time_now = HAL_UptimeMs();
457 
458     HAL_MutexLock(adapter->mutex);
459     list_for_each_entry(node, &adapter->alcs_subdev_list, linked_list,
460                         iotx_alcs_subdev_item_t)
461     {
462         if (node->stage == IOTX_ALCS_SUBDEV_DISCONNCET_CLOUD) {
463             if (((time_now > node->retry_ms) &&
464                  (time_now - node->retry_ms >=
465                   IOTX_ALCS_SUBDEV_RETRY_INTERVAL_MS)) ||
466                 ((time_now <= node->retry_ms) &&
467                  ((0xFFFFFFFFFFFFFFFF - node->retry_ms) + time_now >=
468                   IOTX_ALCS_SUBDEV_RETRY_INTERVAL_MS))) {
469                 /* Get Prefix And Secret From Cloud */
470                 alcs_mqtt_subdev_prefix_get(node->product_key,
471                                             node->device_name);
472                 node->retry_ms = time_now;
473             }
474         }
475     }
476     HAL_MutexUnlock(adapter->mutex);
477 }
478 
iotx_alcs_construct(iotx_alcs_param_t * params)479 void *iotx_alcs_construct(iotx_alcs_param_t *params)
480 {
481     int res = 0;
482     iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
483 
484     COAP_INFO("iotx_alcs_construct enter");
485 
486     if (params == NULL || params->group == NULL || strlen(params->group) == 0) {
487         return NULL;
488     }
489 
490     memset(adapter, 0, sizeof(iotx_alcs_adapter_t));
491 
492     res = iotx_alcs_adapter_init(adapter, params);
493     if (res != SUCCESS_RETURN) {
494         COAP_ERR("Adapter Init Failed");
495         return NULL;
496     }
497 
498     return (void *)adapter;
499 }
500 
iotx_alcs_cloud_init(void * handle)501 int iotx_alcs_cloud_init(void *handle)
502 {
503     int res = 0;
504     iotx_alcs_adapter_t *adapter = __iotx_alcs_get_ctx();
505     char product_key[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
506     char device_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
507 
508     COAP_INFO("Start ALCS Cloud Init");
509 
510     if (adapter->local_cloud_inited == 1) {
511         return SUCCESS_RETURN;
512     }
513 
514     if (handle == NULL) {
515         return FAIL_RETURN;
516     }
517 
518     res = HAL_GetProductKey(product_key);
519     if (res <= 0 || res > IOTX_PRODUCT_KEY_LEN + 1 - 1) {
520         iotx_alcs_adapter_deinit();
521         COAP_ERR("Get Product Key Failed");
522         return FAIL_RETURN;
523     }
524 
525     res = HAL_GetDeviceName(device_name);
526     if (res <= 0 || res > IOTX_DEVICE_NAME_LEN + 1 - 1) {
527         iotx_alcs_adapter_deinit();
528         COAP_ERR("Get Device Name Failed");
529         return FAIL_RETURN;
530     }
531 
532     if (alcs_mqtt_init(adapter->coap_ctx, product_key, device_name) !=
533         ALCS_MQTT_STATUS_SUCCESS) {
534         /*solve the prpblem of hard fault when mqtt connection fails once*/
535         COAP_ERR("ALCS MQTT Init Failed");
536         return FAIL_RETURN;
537     }
538 
539     adapter->local_cloud_inited = 1;
540 
541     return SUCCESS_RETURN;
542 }
543 
iotx_alcs_destroy(void ** phandle)544 int iotx_alcs_destroy(void **phandle)
545 {
546     if (phandle == NULL || *phandle == NULL) {
547         return NULL_VALUE_ERROR;
548     }
549 
550     iotx_alcs_adapter_deinit();
551 
552     return SUCCESS_RETURN;
553 }
554 
alcs_heartbeat(void * handle)555 static void alcs_heartbeat(void *handle)
556 {
557     iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
558 
559     if (adapter->role & IOTX_ALCS_ROLE_SERVER &&
560         adapter->alcs_server_auth_timer_func != NULL) {
561         adapter->alcs_server_auth_timer_func(adapter->coap_ctx);
562     }
563 
564     if (adapter->role & IOTX_ALCS_ROLE_CLIENT &&
565         adapter->alcs_client_auth_timer_func != NULL) {
566         adapter->alcs_client_auth_timer_func(adapter->coap_ctx);
567     }
568 }
iotx_alcs_yield(void * handle)569 int iotx_alcs_yield(void *handle)
570 {
571     int res = 0;
572     iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
573 
574     if (adapter == NULL || adapter->coap_ctx == NULL) {
575         return NULL_VALUE_ERROR;
576     }
577 
578     alcs_heartbeat(handle);
579 
580     iotx_alcs_subdev_stage_check();
581 
582     return res;
583 }
584 
iotx_alcs_send(void * handle,iotx_alcs_msg_t * msg)585 int iotx_alcs_send(void *handle, iotx_alcs_msg_t *msg)
586 {
587     int res = 0;
588     iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
589     CoAPMessage coap_msg;
590     CoAPLenString coap_payload;
591     NetworkAddr network_addr;
592 
593     AlcsDeviceKey devKey;
594     char productKey[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
595     char deviceName[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
596     char *uri_pk = NULL;
597     char *uri_dn = NULL;
598     uint16_t uri_pk_len = 0;
599     uint16_t uri_dn_len = 0;
600     iotx_alcs_send_msg_t *alcs_send_msg = NULL;
601 
602     if (adapter == NULL || adapter->coap_ctx || msg == NULL ||
603         msg->payload == NULL || msg->ip == NULL || strlen(msg->ip) == 0 ||
604         msg->uri == NULL || strlen(msg->uri) == 0) {
605         return NULL_VALUE_ERROR;
606     }
607 
608     if (strlen(msg->ip) > NETWORK_ADDR_LEN) {
609         COAP_ERR("Invalid Ip Address Length");
610         return FAIL_RETURN;
611     }
612 
613     memset(&coap_msg, 0, sizeof(CoAPMessage));
614     memset(&coap_payload, 0, sizeof(CoAPLenString));
615 
616     coap_payload.len = msg->payload_len;
617     coap_payload.data = msg->payload;
618 
619     alcs_msg_init(adapter->coap_ctx, &coap_msg, msg->msg_code, msg->msg_type, 0,
620                   &coap_payload, (void *)adapter);
621 
622     res = alcs_msg_setAddr(&coap_msg, msg->uri, NULL);
623     if (res != COAP_SUCCESS) {
624         COAP_ERR("ALCS Message Set URI Failed");
625         return FAIL_RETURN;
626     }
627 
628     memset(&network_addr, 0, sizeof(NetworkAddr));
629     memcpy(network_addr.addr, msg->ip, strlen(msg->ip));
630     network_addr.port = msg->port;
631 
632     memset(&devKey, 0, sizeof(AlcsDeviceKey));
633     memcpy(&devKey.addr, &network_addr, sizeof(NetworkAddr));
634 
635     uri_pk = iotx_alcs_topic_parse_pk(msg->uri, &uri_pk_len);
636     uri_dn = iotx_alcs_topic_parse_dn(msg->uri, &uri_dn_len);
637 
638     if (uri_pk == NULL || uri_pk_len >= IOTX_PRODUCT_KEY_LEN + 1 ||
639         uri_dn == NULL || uri_dn_len >= IOTX_DEVICE_NAME_LEN + 1) {
640         COAP_ERR("Invalid Parameter");
641         return FAIL_RETURN;
642     }
643     memcpy(productKey, uri_pk, uri_pk_len);
644     memcpy(deviceName, uri_dn, uri_dn_len);
645 
646     devKey.pk = productKey;
647     devKey.dn = deviceName;
648 
649     res = alcs_sendmsg_secure(adapter->coap_ctx, &devKey, &coap_msg, 2,
650                               iotx_alcs_coap_adapter_send_msg_handle);
651     alcs_msg_deinit(&coap_msg);
652 
653     if (res != COAP_SUCCESS) {
654         COAP_ERR("ALCS Message Send Message Failed");
655         return FAIL_RETURN;
656     }
657 
658     alcs_send_msg = (iotx_alcs_send_msg_t *)ALCS_ADAPTER_malloc(
659         sizeof(iotx_alcs_send_msg_t));
660     if (alcs_send_msg == NULL) {
661         COAP_WRN("Not Enough Memory");
662         return FAIL_RETURN;
663     }
664     memset(alcs_send_msg, 0, sizeof(iotx_alcs_send_msg_t));
665 
666     alcs_send_msg->token =
667         (uint8_t *)ALCS_ADAPTER_malloc(coap_msg.header.tokenlen + 1);
668     if (alcs_send_msg->token == NULL) {
669         ALCS_free(alcs_send_msg);
670         COAP_WRN("Not Enough Memory");
671         return FAIL_RETURN;
672     }
673     alcs_send_msg->token_len = coap_msg.header.tokenlen;
674 
675     memset(alcs_send_msg->token, 0, alcs_send_msg->token_len + 1);
676     memcpy(alcs_send_msg->token, coap_msg.token, alcs_send_msg->token_len);
677 
678     alcs_send_msg->uri = (char *)ALCS_ADAPTER_malloc(strlen(msg->uri) + 1);
679     if (alcs_send_msg->uri == NULL) {
680         ALCS_free(alcs_send_msg->token);
681         ALCS_free(alcs_send_msg);
682         COAP_WRN("ALCS Message Buffer Failed");
683         return FAIL_RETURN;
684     }
685     memset(alcs_send_msg->uri, 0, strlen(msg->uri) + 1);
686     memcpy(alcs_send_msg->uri, msg->uri, strlen(msg->uri));
687     INIT_LIST_HEAD(&alcs_send_msg->linked_list);
688 
689     HAL_MutexLock(adapter->mutex);
690     list_add_tail(&alcs_send_msg->linked_list, &adapter->alcs_send_list);
691     HAL_MutexUnlock(adapter->mutex);
692 
693     return SUCCESS_RETURN;
694 }
695 
iotx_alcs_send_Response(void * handle,iotx_alcs_msg_t * msg,uint8_t token_len,uint8_t * token)696 int iotx_alcs_send_Response(void *handle, iotx_alcs_msg_t *msg,
697                             uint8_t token_len, uint8_t *token)
698 {
699     int res = 0;
700     iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
701     CoAPMessage coap_msg;
702     CoAPLenString coap_payload;
703     CoAPLenString token_payload;
704     NetworkAddr network_addr;
705 
706     AlcsDeviceKey devKey;
707     char productKey[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
708     char deviceName[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
709     char *uri_pk = NULL;
710     char *uri_dn = NULL;
711     uint16_t uri_pk_len = 0;
712     uint16_t uri_dn_len = 0;
713 
714     if (adapter == NULL || adapter->coap_ctx == NULL || msg == NULL ||
715         msg->payload == NULL || msg->ip == NULL || strlen(msg->ip) == 0 ||
716         msg->uri == NULL || strlen(msg->uri) == 0) {
717         return NULL_VALUE_ERROR;
718     }
719 
720     if (token_len == 0 || token == NULL) {
721         return FAIL_RETURN;
722     }
723 
724     if (strlen(msg->ip) > NETWORK_ADDR_LEN) {
725         COAP_ERR("Invalid Ip Address Length");
726         return FAIL_RETURN;
727     }
728 
729     memset(&coap_msg, 0, sizeof(CoAPMessage));
730     memset(&coap_payload, 0, sizeof(CoAPLenString));
731     memset(&token_payload, 0, sizeof(CoAPLenString));
732 
733     coap_payload.len = msg->payload_len;
734     coap_payload.data = msg->payload;
735 
736     alcs_msg_init(adapter->coap_ctx, &coap_msg, msg->msg_code, msg->msg_type, 0,
737                   &coap_payload, (void *)adapter);
738 
739     res = alcs_msg_setAddr(&coap_msg, msg->uri, NULL);
740     if (res != COAP_SUCCESS) {
741         COAP_ERR("ALCS Message Set URI Failed");
742         return FAIL_RETURN;
743     }
744 
745     memset(&network_addr, 0, sizeof(NetworkAddr));
746     memcpy(network_addr.addr, msg->ip, strlen(msg->ip));
747     network_addr.port = msg->port;
748 
749     token_payload.len = token_len;
750     token_payload.data = token;
751 
752     memset(&devKey, 0, sizeof(AlcsDeviceKey));
753     memcpy(&devKey.addr, &network_addr, sizeof(NetworkAddr));
754 
755     uri_pk = iotx_alcs_topic_parse_pk(msg->uri, &uri_pk_len);
756     uri_dn = iotx_alcs_topic_parse_dn(msg->uri, &uri_dn_len);
757 
758     if (uri_pk == NULL || uri_pk_len >= IOTX_PRODUCT_KEY_LEN + 1 ||
759         uri_dn == NULL || uri_dn_len >= IOTX_DEVICE_NAME_LEN + 1) {
760         COAP_ERR("Invalid Parameter");
761         return FAIL_RETURN;
762     }
763     memcpy(productKey, uri_pk, uri_pk_len);
764     memcpy(deviceName, uri_dn, uri_dn_len);
765 
766     devKey.pk = productKey;
767     devKey.dn = deviceName;
768 
769     if (alcs_resource_need_auth(adapter->coap_ctx, msg->uri)) {
770         res = alcs_sendrsp_secure(adapter->coap_ctx, &devKey, &coap_msg, 0, 0,
771                                   &token_payload);
772     } else {
773         res = alcs_sendrsp(adapter->coap_ctx, &network_addr, &coap_msg, 0, 0,
774                            &token_payload);
775     }
776 
777     alcs_msg_deinit(&coap_msg);
778 
779     if (res != COAP_SUCCESS) {
780         COAP_ERR("ALCS Message Send Message Failed");
781         return FAIL_RETURN;
782     }
783 
784     return SUCCESS_RETURN;
785 }
786 
iotx_alcs_register_resource(void * handle,iotx_alcs_res_t * resource)787 int iotx_alcs_register_resource(void *handle, iotx_alcs_res_t *resource)
788 {
789     int res = 0;
790     iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
791     char productKey[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
792     char deviceName[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
793     char *uri_pk = NULL;
794     char *uri_dn = NULL;
795     uint16_t uri_pk_len = 0;
796     uint16_t uri_dn_len = 0;
797     int needAuth = 0;
798 
799     if (adapter == NULL || adapter->coap_ctx == NULL || resource->uri == NULL ||
800         strlen(resource->uri) == 0) {
801         return NULL_VALUE_ERROR;
802     }
803 
804     uri_pk = iotx_alcs_topic_parse_pk(resource->uri, &uri_pk_len);
805     uri_dn = iotx_alcs_topic_parse_dn(resource->uri, &uri_dn_len);
806 
807     if (uri_pk == NULL || uri_pk_len >= IOTX_PRODUCT_KEY_LEN + 1 ||
808         uri_dn == NULL || uri_dn_len >= IOTX_DEVICE_NAME_LEN + 1) {
809         COAP_ERR("Invalid Parameter");
810         return FAIL_RETURN;
811     }
812     memcpy(productKey, uri_pk, uri_pk_len);
813     memcpy(deviceName, uri_dn, uri_dn_len);
814 
815     COAP_INFO("alcs register resource, uri:%s", resource->uri);
816     needAuth =
817         resource
818             ->need_auth; /* strcmp (resource->uri, "/dev/core/service/dev"); */
819 
820     res = alcs_resource_register(
821         adapter->coap_ctx, productKey, deviceName, resource->uri,
822         resource->msg_perm, resource->msg_ct, resource->maxage, needAuth,
823         (void (*)(CoAPContext *context, const char *paths, NetworkAddr *remote,
824                   CoAPMessage *message)) resource->callback);
825 
826     if (res != COAP_SUCCESS) {
827         COAP_ERR("ALCS Register Resource Failed, Code: %d", res);
828         return FAIL_RETURN;
829     }
830 
831     return SUCCESS_RETURN;
832 }
833 
iotx_alcs_observe_notify(void * handle,const char * uri,uint32_t payload_len,uint8_t * payload)834 int iotx_alcs_observe_notify(void *handle, const char *uri,
835                              uint32_t payload_len, uint8_t *payload)
836 {
837     int res = 0;
838     iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
839     CoAPLenString coap_payload;
840 
841     coap_payload.len = (int32_t)payload_len;
842     coap_payload.data = payload;
843 
844     res = alcs_observe_notify(adapter->coap_ctx, uri, &coap_payload);
845     if (res != COAP_SUCCESS) {
846         COAP_ERR("ALCS Observe Notify Failed, Code: %d", res);
847         return FAIL_RETURN;
848     }
849 
850     return SUCCESS_RETURN;
851 }
852 
iotx_alcs_unregister_resource(void * handle,char * uri)853 int iotx_alcs_unregister_resource(void *handle, char *uri)
854 {
855     return SUCCESS_RETURN;
856 }
857 
iotx_alcs_add_sub_device(void * handle,const char * pk,const char * dn)858 int iotx_alcs_add_sub_device(void *handle, const char *pk, const char *dn)
859 {
860     int res = 0;
861     iotx_alcs_adapter_t *adapter = (iotx_alcs_adapter_t *)handle;
862     iotx_alcs_subdev_item_t *subdev_item = NULL;
863     char prefix[ALCS_MQTT_PREFIX_MAX_LEN] = { 0 };
864     char secret[ALCS_MQTT_SECRET_MAX_LEN] = { 0 };
865 
866     if (handle == NULL || pk == NULL ||
867         strlen(pk) >= IOTX_PRODUCT_KEY_LEN + 1 || dn == NULL ||
868         strlen(dn) >= IOTX_DEVICE_NAME_LEN + 1) {
869         COAP_ERR("Invalid Argument");
870         return FAIL_RETURN;
871     }
872 
873     if (adapter->coap_ctx != NULL) {
874         alcs_auth_subdev_init(adapter->coap_ctx, pk, dn);
875     }
876 
877     /* Search Subdev In Linked List */
878     HAL_MutexLock(adapter->mutex);
879     res = _iotx_alcs_subdev_list_search(pk, dn, &subdev_item);
880     if (res == SUCCESS_RETURN) {
881         COAP_INFO("This Product Key And Device Name Have Been Added");
882         HAL_MutexUnlock(adapter->mutex);
883         return SUCCESS_RETURN;
884     }
885     HAL_MutexUnlock(adapter->mutex);
886 
887     /* Insert New Subdev Into Linked List */
888     subdev_item = (iotx_alcs_subdev_item_t *)ALCS_ADAPTER_malloc(
889         sizeof(iotx_alcs_subdev_item_t));
890     if (subdev_item == NULL) {
891         COAP_ERR("No Enough Memory");
892         return FAIL_RETURN;
893     }
894     memset(subdev_item, 0, sizeof(iotx_alcs_subdev_item_t));
895 
896     /* Set Product Key And Device Name */
897     memcpy(subdev_item->product_key, pk, strlen(pk));
898     memcpy(subdev_item->device_name, dn, strlen(dn));
899     subdev_item->stage = IOTX_ALCS_SUBDEV_DISCONNCET_CLOUD;
900     subdev_item->retry_ms = HAL_UptimeMs();
901     INIT_LIST_HEAD(&subdev_item->linked_list);
902 
903     HAL_MutexLock(adapter->mutex);
904     list_add_tail(&subdev_item->linked_list, &adapter->alcs_subdev_list);
905     HAL_MutexUnlock(adapter->mutex);
906 
907     alcs_localsetup_add_sub_device(adapter, subdev_item->product_key,
908                                    subdev_item->device_name);
909 
910     /* Get Prefix And Secret From KV */
911     res = alcs_mqtt_prefix_secret_load(pk, strlen(pk), dn, strlen(dn), prefix,
912                                        secret);
913     if (res == SUCCESS_RETURN) {
914         memcpy(subdev_item->prefix, prefix, strlen(prefix));
915         memcpy(subdev_item->secret, secret, strlen(secret));
916         alcs_mqtt_add_srv_key(prefix, secret);
917     }
918 
919     /* Get Prefix And Secret From Cloud */
920     alcs_mqtt_subdev_prefix_get(pk, dn);
921 
922     return SUCCESS_RETURN;
923 }
924 
iotx_alcs_remove_sub_device(void * handle,const char * pk,const char * dn)925 int iotx_alcs_remove_sub_device(void *handle, const char *pk, const char *dn)
926 {
927     int res = 0;
928 
929     if (handle == NULL || pk == NULL ||
930         strlen(pk) >= IOTX_PRODUCT_KEY_LEN + 1 || dn == NULL ||
931         strlen(dn) >= IOTX_DEVICE_NAME_LEN + 1) {
932         COAP_ERR("Invalid Parameter");
933         return FAIL_RETURN;
934     }
935 
936     res = iotx_alcs_subdev_remove(pk, dn);
937     if (res != SUCCESS_RETURN) {
938         return FAIL_RETURN;
939     }
940 
941     /* Remove Subdev Item From KV */
942     alcs_mqtt_prefix_secret_del(pk, strlen(pk), dn, strlen(dn));
943     return SUCCESS_RETURN;
944 }
945