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