1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4
5
6 #include "alcs_internal.h"
7 #include "alcs_api_internal.h"
8 #include "CoAPPlatform.h"
9 #include "CoAPResource.h"
10
11 #ifdef ALCS_CLIENT_ENABLED
12 static int default_heart_interval = 30000;
match_key(const char * accesskey,const char * keyprefix)13 char match_key(const char *accesskey, const char *keyprefix)
14 {
15 if (strlen(keyprefix) == KEYPREFIX_LEN &&
16 strstr(accesskey, keyprefix) == accesskey) {
17 return 1;
18 }
19
20 return 0;
21 }
22
23 int do_auth(CoAPContext *ctx, NetworkAddr *addr, ctl_key_item *ctl_item,
24 void *userdata, AuthHandler handler);
res_parse(const char * payload,int len,int * seq,ResponseMsg * res_msg,char ** data,int * datalen)25 bool res_parse(const char *payload, int len, int *seq, ResponseMsg *res_msg,
26 char **data, int *datalen)
27 {
28 if (!payload || !len || !seq || !res_msg || !data) {
29 return 0;
30 }
31
32 COAP_DEBUG("payload:%.*s", len, payload);
33
34 int tmplen;
35 char *tmp;
36
37 tmp = json_get_value_by_name((char *)payload, len, "id", &tmplen, NULL);
38 if (!tmp) {
39 return 0;
40 }
41
42 char back;
43 backup_json_str_last_char(tmp, tmplen, back);
44 *seq = atoi(tmp);
45 restore_json_str_last_char(tmp, tmplen, back);
46
47 tmp = json_get_value_by_name((char *)payload, len, "code", &tmplen, NULL);
48 if (!tmp) {
49 return 0;
50 }
51
52 backup_json_str_last_char(tmp, tmplen, back);
53 res_msg->code = atoi(tmp);
54 restore_json_str_last_char(tmp, tmplen, back);
55
56 tmp = json_get_value_by_name((char *)payload, len, "msg", &tmplen, NULL);
57 if (tmp && tmplen) {
58 res_msg->msg = (char *)coap_malloc(tmplen);
59 memcpy(res_msg->msg, tmp, tmplen);
60 } else {
61 res_msg->msg = NULL;
62 }
63
64 *data = json_get_value_by_name((char *)payload, len, "data", datalen, NULL);
65 return 1;
66 }
67
fillAccessKey(CoAPContext * ctx,char * buf)68 bool fillAccessKey(CoAPContext *ctx, char *buf)
69 {
70 auth_list *lst = get_list(ctx);
71 if (!lst) {
72 return 0;
73 }
74
75 HAL_MutexLock(lst->list_mutex);
76
77 if (list_empty(&lst->lst_ctl)) {
78 HAL_MutexUnlock(lst->list_mutex);
79 return 0;
80 }
81 strcpy(buf, ",\"accessKeys\":[");
82 ctl_key_item *node = NULL, *next = NULL;
83 list_for_each_entry_safe(node, next, &lst->lst_ctl, lst, ctl_key_item)
84 {
85 char *format;
86 if (lst->ctl_group_count || !list_is_last(&node->lst, &lst->lst_ctl)) {
87 format = "\"%s\",";
88 } else {
89 format = "\"%s\"]";
90 }
91 sprintf(buf + strlen(buf), format, node->accessKey);
92 }
93
94 ctl_group_item *gnode = NULL, *gnext = NULL;
95 list_for_each_entry_safe(gnode, gnext, &lst->lst_ctl_group, lst,
96 ctl_group_item)
97 {
98 char *format;
99 if (!list_is_last(&gnode->lst, &lst->lst_ctl_group)) {
100 format = "\"%s\",";
101 } else {
102 format = "\"%s\"]";
103 }
104 sprintf(buf + strlen(buf), format, gnode->accessKey);
105 }
106
107 HAL_MutexUnlock(lst->list_mutex);
108 return 1;
109 }
110
111 #define payload_format \
112 "{\"version\":\"1.0\",\"method\":\"%s\",\"id\":%d,\"params\":{" \
113 "\"prodKey\":\"%s\", \"deviceName\":\"%s\"%s}}"
nego_cb(CoAPContext * ctx,CoAPReqResult result,void * userdata,NetworkAddr * remote,CoAPMessage * message)114 void nego_cb(CoAPContext *ctx, CoAPReqResult result, void *userdata,
115 NetworkAddr *remote, CoAPMessage *message)
116 {
117 COAP_INFO("nego_cb, message addr:%p, networkaddr:%p!", message, remote);
118 AuthParam *auth_param = (AuthParam *)userdata;
119
120 if (COAP_RECV_RESP_TIMEOUT == result) {
121 ResponseMsg msg = { -1, "response time!" };
122 auth_param->handler(ctx, remote, auth_param->user_data, &msg);
123 coap_free(auth_param->productKey);
124 coap_free(auth_param->deviceName);
125 coap_free(auth_param);
126
127 } else {
128 COAP_DEBUG("recv response message");
129 int seq, datalen;
130 ResponseMsg msg;
131 char *data;
132
133 res_parse((const char *)message->payload, message->payloadlen, &seq,
134 &msg, &data, &datalen);
135 do {
136 if (msg.code != 200) {
137 break;
138 }
139
140 int keylen;
141 char *accessKey = json_get_value_by_name(data, datalen, "accessKey",
142 &keylen, NULL);
143 if (!accessKey || !keylen) {
144 break;
145 }
146 COAP_DEBUG("accesskey:%.*s", keylen, accessKey);
147
148 auth_list *lst = get_list(ctx);
149 ctl_key_item *node = NULL, *next = NULL;
150 char *accessTokenFound = NULL;
151 HAL_MutexLock(lst->list_mutex);
152
153 list_for_each_entry_safe(node, next, &lst->lst_ctl, lst,
154 ctl_key_item)
155 {
156 COAP_DEBUG("node:%s", node->accessKey);
157 if (strncmp(node->accessKey, accessKey, keylen) == 0) {
158 accessTokenFound = node->accessToken;
159 break;
160 }
161 }
162
163 if (!accessTokenFound) {
164 ctl_group_item *gnode = NULL, *gnext = NULL;
165 list_for_each_entry_safe(gnode, gnext, &lst->lst_ctl_group, lst,
166 ctl_group_item)
167 {
168 COAP_DEBUG("node:%s", gnode->accessKey);
169 if (strncmp(gnode->accessKey, accessKey, keylen) == 0) {
170 accessTokenFound = gnode->accessKey;
171 break;
172 }
173 }
174 }
175
176 HAL_MutexUnlock(lst->list_mutex);
177
178 if (accessTokenFound) {
179 ctl_key_item item;
180 item.deviceName = auth_param->deviceName;
181 item.productKey = auth_param->productKey;
182
183 item.accessKey = accessKey;
184 item.accessToken = accessTokenFound;
185 char back;
186 backup_json_str_last_char(accessKey, keylen, back);
187 do_auth(ctx, remote, &item, auth_param->user_data,
188 auth_param->handler);
189 restore_json_str_last_char(accessKey, keylen, back);
190
191 coap_free(auth_param->productKey);
192 coap_free(auth_param->deviceName);
193 coap_free(auth_param);
194 return;
195 }
196 } while (0);
197
198 /* todo */
199 ResponseMsg tmp = { -1, "" };
200 auth_param->handler(ctx, remote, auth_param->user_data, &tmp);
201 coap_free(auth_param->productKey);
202 coap_free(auth_param->deviceName);
203 coap_free(auth_param);
204 }
205 }
206
CoAPServerPath_2_option(char * uri,CoAPMessage * message)207 static int CoAPServerPath_2_option(char *uri, CoAPMessage *message)
208 {
209 char *ptr = NULL;
210 char *pstr = NULL;
211 char path[COAP_MSG_MAX_PATH_LEN] = { 0 };
212
213 if (NULL == uri || NULL == message) {
214 COAP_ERR("Invalid paramter p_path %p, p_message %p", uri, message);
215 return COAP_ERROR_INVALID_PARAM;
216 }
217 if (256 < strlen(uri)) {
218 COAP_ERR("The uri length is too loog,len = %d", (int)strlen(uri));
219 return COAP_ERROR_INVALID_LENGTH;
220 }
221 COAP_DEBUG("The uri is %s", uri);
222 ptr = pstr = uri;
223 while ('\0' != *ptr) {
224 if ('/' == *ptr) {
225 if (ptr != pstr) {
226 memset(path, 0x00, sizeof(path));
227 strncpy(path, pstr, ptr - pstr);
228 COAP_DEBUG("path: %s,len=%d", path, (int)(ptr - pstr));
229 CoAPStrOption_add(message, COAP_OPTION_URI_PATH,
230 (unsigned char *)path, (int)strlen(path));
231 }
232 pstr = ptr + 1;
233 }
234 if ('\0' == *(ptr + 1) && '\0' != *pstr) {
235 memset(path, 0x00, sizeof(path));
236 strncpy(path, pstr, sizeof(path) - 1);
237 COAP_DEBUG("path: %s,len=%d", path, (int)strlen(path));
238 CoAPStrOption_add(message, COAP_OPTION_URI_PATH,
239 (unsigned char *)path, (int)strlen(path));
240 }
241 ptr++;
242 }
243 return COAP_SUCCESS;
244 }
245
auth_cb(CoAPContext * ctx,CoAPReqResult result,void * userdata,NetworkAddr * remote,CoAPMessage * message)246 void auth_cb(CoAPContext *ctx, CoAPReqResult result, void *userdata,
247 NetworkAddr *remote, CoAPMessage *message)
248 {
249 AlcsDeviceKey devKey;
250 COAP_DEBUG("recv auth_cb response message");
251
252 AuthParam *auth_param = (AuthParam *)userdata;
253 memset(&devKey, 0x00, sizeof(AlcsDeviceKey));
254 memcpy(&devKey.addr, remote, sizeof(NetworkAddr));
255 devKey.pk = auth_param->productKey;
256 devKey.dn = auth_param->deviceName;
257 session_item *session = get_ctl_session(ctx, &devKey);
258
259 if (!session) {
260 COAP_INFO("receive unknown auth_cb response, pk:%s, dn:%s", devKey.pk,
261 devKey.dn);
262 ResponseMsg msg = { -1, "no session found!" };
263 auth_param->handler(ctx, remote, auth_param->user_data, &msg);
264 } else if (COAP_RECV_RESP_TIMEOUT == result) {
265 COAP_ERR("response time!");
266 ResponseMsg msg = { -1, "response time!" };
267 auth_param->handler(ctx, remote, auth_param->user_data, &msg);
268 remove_session(ctx, session);
269 } else {
270 int seq, datalen;
271 ResponseMsg msg;
272 char *data;
273
274 res_parse((const char *)message->payload, message->payloadlen, &seq,
275 &msg, &data, &datalen);
276 if (msg.code == 200) {
277 do {
278 int tmplen;
279 char *tmp;
280
281 tmp = json_get_value_by_name(data, datalen, "sessionId",
282 &tmplen, NULL);
283 if (!tmp) {
284 msg.code = -1;
285 msg.msg = "sessionid = NULL!";
286 COAP_ERR("sessionid = NULL!");
287 auth_param->handler(ctx, remote, auth_param->user_data,
288 &msg);
289 break;
290 }
291 char back;
292 backup_json_str_last_char(tmp, tmplen, back);
293 session->sessionId = atoi(tmp);
294 restore_json_str_last_char(tmp, tmplen, back);
295 COAP_INFO("sessionId:%d", session->sessionId);
296
297 tmp = json_get_value_by_name(data, datalen, "randomKey",
298 &tmplen, NULL);
299 if (!tmp) {
300 msg.code = -1;
301 msg.msg = "randomKey = NULL!";
302 COAP_ERR("randomKey = NULL!");
303 auth_param->handler(ctx, remote, auth_param->user_data,
304 &msg);
305 break;
306 }
307
308 char buf[32];
309 HAL_Snprintf(buf, sizeof(buf), "%s%.*s", session->randomKey,
310 tmplen, tmp);
311 utils_hmac_sha1_hex(buf, strlen(buf), session->sessionKey,
312 auth_param->accessToken,
313 strlen(auth_param->accessToken));
314 session->authed_time = HAL_UptimeMs();
315 session->heart_time = session->authed_time;
316 session->interval = default_heart_interval;
317 COAP_INFO("sessionKey is created");
318 } while (0);
319 } else {
320 remove_session(ctx, session);
321 COAP_ERR("message code :%d", msg.code);
322 }
323 auth_param->handler(ctx, remote, auth_param->user_data, &msg);
324 }
325
326 coap_free(auth_param->productKey);
327 coap_free(auth_param->deviceName);
328 coap_free(auth_param->accessToken);
329 coap_free(auth_param);
330 }
331
332 #define auth_payload_format \
333 "{\"version\":\"1.0\",\"method\":\"core/service/" \
334 "auth\",\"id\":%d,\"params\":{\"prodKey\":\"%s\", " \
335 "\"deviceName\":\"%s\",\"encrypt\":\"payload\",\"randomKey\":\"%s\"," \
336 "\"sign\":\"%s\",\"accessKey\":\"%s\"}}"
337
do_auth(CoAPContext * ctx,NetworkAddr * addr,ctl_key_item * ctl_item,void * user_data,AuthHandler handler)338 int do_auth(CoAPContext *ctx, NetworkAddr *addr, ctl_key_item *ctl_item,
339 void *user_data, AuthHandler handler)
340 {
341 int ret = COAP_SUCCESS;
342 AlcsDeviceKey devKey;
343 device_auth_list *dev = get_device(ctx);
344 if (!dev) {
345 return COAP_ERROR_INVALID_PARAM;
346 }
347
348 memset(&devKey, 0x00, sizeof(AlcsDeviceKey));
349 memcpy(&devKey.addr, addr, sizeof(NetworkAddr));
350 devKey.pk = ctl_item->productKey;
351 devKey.dn = ctl_item->deviceName;
352
353 session_item *session = get_ctl_session(ctx, &devKey);
354 if (session) {
355 if (session->sessionId) {
356 COAP_INFO("no need to reauth!");
357 ResponseMsg res = { COAP_SUCCESS, NULL };
358 handler(ctx, addr, user_data, &res);
359 return COAP_SUCCESS;
360 } else {
361 COAP_INFO("is authing, no need to reauth!");
362 return ALCS_ERR_AUTH_AUTHING;
363 }
364 }
365
366 /* create&save session item */
367 {
368 session = (session_item *)coap_malloc(sizeof(session_item));
369 memset(session, 0, sizeof(session_item));
370
371 char path[100] = { 0 };
372 strncpy(path, ctl_item->productKey, sizeof(path) - 1);
373 strncat(path, ctl_item->deviceName, sizeof(path) - strlen(path) - 1);
374 CoAPPathMD5_sum(path, strlen(path), session->pk_dn, PK_DN_CHECKSUM_LEN);
375 COAP_INFO("pk:%s, dn:%s, checksum:%s", devKey.pk, devKey.dn,
376 session->pk_dn);
377 memcpy(&session->addr, addr, sizeof(NetworkAddr));
378 gen_random_key((unsigned char *)session->randomKey, RANDOMKEY_LEN);
379
380 struct list_head *ctl_head = get_ctl_session_list(ctx);
381 list_add_tail(&session->lst, ctl_head);
382 }
383
384 char sign[64] = { 0 };
385 int sign_len = sizeof(sign);
386 utils_hmac_sha1_base64(session->randomKey, RANDOMKEY_LEN,
387 ctl_item->accessToken, strlen(ctl_item->accessToken),
388 sign, &sign_len);
389 COAP_INFO("calc randomKey:%s,token:%s,sign:%.*s", session->randomKey,
390 ctl_item->accessToken, sign_len, sign);
391
392 char payloadbuf[512];
393 sprintf(payloadbuf, auth_payload_format, ++dev->seq, ctl_item->productKey,
394 ctl_item->deviceName, session->randomKey, sign,
395 ctl_item->accessKey);
396 COAP_INFO("payload:%s", payloadbuf);
397
398 CoAPLenString payload;
399 payload.data = (unsigned char *)payloadbuf;
400 payload.len = strlen(payloadbuf);
401 CoAPMessage message;
402 alcs_msg_init(ctx, &message, COAP_MSG_CODE_GET, COAP_MESSAGE_TYPE_CON, 0,
403 &payload, NULL);
404
405 char path[120];
406 sprintf(path, "/dev/%s/%s/core/service/auth", ctl_item->productKey,
407 ctl_item->deviceName);
408 CoAPServerPath_2_option(path, &message);
409
410 AuthParam *authParam = (AuthParam *)coap_malloc(sizeof(AuthParam));
411 authParam->handler = handler;
412 authParam->user_data = user_data;
413 authParam->productKey =
414 (char *)coap_malloc(strlen(ctl_item->productKey) + 1);
415 strcpy(authParam->productKey, ctl_item->productKey);
416 authParam->deviceName =
417 (char *)coap_malloc(strlen(ctl_item->deviceName) + 1);
418 strcpy(authParam->deviceName, ctl_item->deviceName);
419 authParam->accessToken =
420 (char *)coap_malloc(strlen(ctl_item->accessToken) + 1);
421 strcpy(authParam->accessToken, ctl_item->accessToken);
422 message.user = authParam;
423 message.handler = auth_cb;
424
425 ret = CoAPMessage_send(ctx, addr, &message);
426 CoAPMessage_destory(&message);
427
428 return ret;
429 }
430
alcs_auth_has_key(CoAPContext * ctx,NetworkAddr * addr,AuthParam * auth_param)431 void alcs_auth_has_key(CoAPContext *ctx, NetworkAddr *addr,
432 AuthParam *auth_param)
433 {
434 ctl_key_item item;
435 item.accessKey = auth_param->accessKey;
436 item.deviceName = auth_param->deviceName;
437 item.productKey = auth_param->productKey;
438 item.accessToken =
439 auth_param->accessToken; /* (char*) coap_malloc
440 (strlen(auth_param->accessToken) + 1); */
441 /* strcpy (item.accessToken, auth_param->accessToken); */
442 do_auth(ctx, addr, &item, auth_param->user_data, auth_param->handler);
443 }
444
alcs_auth_nego_key(CoAPContext * ctx,AlcsDeviceKey * devKey,AuthHandler handler)445 void alcs_auth_nego_key(CoAPContext *ctx, AlcsDeviceKey *devKey,
446 AuthHandler handler)
447 {
448 COAP_DEBUG("alcs_auth_nego_key");
449
450 device_auth_list *dev = get_device(ctx);
451 if (!dev) {
452 COAP_INFO("no device!");
453 return;
454 }
455
456 char accesskeys[1024] = { 0 };
457 if (!fillAccessKey(ctx, accesskeys)) {
458 COAP_INFO("no ctl key!");
459 return;
460 }
461 COAP_INFO("accesskeys:%s", accesskeys);
462
463 const char *method = "core/service/auth/select";
464 char payloadbuf[1024];
465 sprintf(payloadbuf, payload_format, method, ++dev->seq, devKey->pk,
466 devKey->dn, accesskeys);
467
468 CoAPLenString payload;
469 payload.data = (unsigned char *)payloadbuf;
470 payload.len = strlen(payloadbuf);
471 CoAPMessage message;
472 alcs_msg_init(ctx, &message, COAP_MSG_CODE_GET, COAP_MESSAGE_TYPE_CON, 0,
473 &payload, NULL);
474
475 char path[120];
476 sprintf(path, "/dev/%s/%s/core/service/auth/select", devKey->pk,
477 devKey->dn);
478 CoAPServerPath_2_option(path, &message);
479
480 AuthParam *authParam = (AuthParam *)coap_malloc(sizeof(AuthParam));
481 memset(authParam, 0, sizeof(AuthParam));
482
483 authParam->handler = handler;
484 authParam->productKey = (char *)coap_malloc(strlen(devKey->pk) + 1);
485 strcpy(authParam->productKey, devKey->pk);
486 authParam->deviceName = (char *)coap_malloc(strlen(devKey->dn) + 1);
487 strcpy(authParam->deviceName, devKey->dn);
488
489 message.user = authParam;
490 message.handler = nego_cb;
491 CoAPMessage_send(ctx, &devKey->addr, &message);
492 CoAPMessage_destory(&message);
493 }
494
alcs_add_client_key(CoAPContext * ctx,const char * accesskey,const char * accesstoken,const char * productKey,const char * deviceName)495 int alcs_add_client_key(CoAPContext *ctx, const char *accesskey,
496 const char *accesstoken, const char *productKey,
497 const char *deviceName)
498 {
499 auth_list *lst = get_list(ctx);
500 if (!lst || lst->ctl_count >= KEY_MAXCOUNT) {
501 return COAP_ERROR_INVALID_LENGTH;
502 }
503
504 ctl_key_item *item = (ctl_key_item *)coap_malloc(sizeof(ctl_key_item));
505 if (!item) {
506 return COAP_ERROR_MALLOC;
507 }
508 item->accessKey = (char *)coap_malloc(strlen(accesskey) + 1);
509 item->accessToken = (char *)coap_malloc(strlen(accesstoken) + 1);
510
511 if (!item->accessKey || !item->accessToken) {
512 coap_free(item);
513 return COAP_ERROR_MALLOC;
514 }
515 strcpy(item->accessKey, accesskey);
516 strcpy(item->accessToken, accesstoken);
517
518 if (deviceName) {
519 item->deviceName = (char *)coap_malloc(strlen(deviceName) + 1);
520 strcpy(item->deviceName, deviceName);
521 }
522
523 HAL_MutexLock(lst->list_mutex);
524 list_add_tail(&item->lst, &lst->lst_ctl);
525 ++lst->ctl_count;
526 HAL_MutexUnlock(lst->list_mutex);
527
528 return COAP_SUCCESS;
529 }
530
alcs_remove_client_key(CoAPContext * ctx,const char * key,char isfullkey)531 int alcs_remove_client_key(CoAPContext *ctx, const char *key, char isfullkey)
532 {
533 auth_list *lst = get_list(ctx);
534 if (!lst) {
535 return COAP_ERROR_NULL;
536 }
537
538 ctl_key_item *node = NULL, *next = NULL;
539 HAL_MutexLock(lst->list_mutex);
540
541 list_for_each_entry_safe(node, next, &lst->lst_ctl, lst, ctl_key_item)
542 {
543 if (match_key(node->accessKey, key)) {
544 coap_free(node->accessKey);
545 coap_free(node->accessToken);
546 list_del(&node->lst);
547 coap_free(node);
548 break;
549 }
550 }
551 HAL_MutexUnlock(lst->list_mutex);
552 return COAP_SUCCESS;
553 }
554
alcs_device_online(CoAPContext * ctx,AlcsDeviceKey * devKey)555 bool alcs_device_online(CoAPContext *ctx, AlcsDeviceKey *devKey)
556 {
557 session_item *session = get_ctl_session(ctx, devKey);
558 return session && session->sessionId ? 1 : 0;
559 }
560
heart_beat_cb(CoAPContext * ctx,CoAPReqResult result,void * userdata,NetworkAddr * remote,CoAPMessage * message)561 void heart_beat_cb(CoAPContext *ctx, CoAPReqResult result, void *userdata,
562 NetworkAddr *remote, CoAPMessage *message)
563 {
564 COAP_DEBUG("heart_beat_cb, message addr:%p, networkaddr:%p!", message,
565 remote);
566
567 struct list_head *ctl_head = get_ctl_session_list(ctx);
568 if (!ctl_head || list_empty(ctl_head)) {
569 return;
570 }
571
572 if (result == COAP_RECV_RESP_TIMEOUT) {
573 COAP_ERR("heart beat timeout");
574 session_item *node = NULL, *next = NULL;
575 list_for_each_entry_safe(node, next, ctl_head, lst, session_item)
576 {
577 if (node->sessionId && is_networkadd_same(&node->addr, remote)) {
578 remove_session(ctx, node);
579 }
580 }
581 } else {
582 session_item *node = NULL, *next = NULL;
583 list_for_each_entry_safe(node, next, ctl_head, lst, session_item)
584 {
585 if (node->sessionId && is_networkadd_same(&node->addr, remote)) {
586 unsigned int sessionId = 0;
587 CoAPUintOption_get(message, COAP_OPTION_SESSIONID, &sessionId);
588
589 if (node->sessionId != sessionId) {
590 COAP_INFO("receive stale heart beat response");
591 remove_session(ctx, node);
592 } else {
593 node->heart_time = HAL_UptimeMs();
594 }
595 }
596 }
597 }
598 }
599
on_client_auth_timer(CoAPContext * ctx)600 void on_client_auth_timer(CoAPContext *ctx)
601 {
602 struct list_head *ctl_head = get_ctl_session_list(ctx);
603 if (!ctl_head || list_empty(ctl_head)) {
604 return;
605 }
606 COAP_DEBUG("on_client_auth_timer:%d", (int)HAL_UptimeMs());
607
608 device_auth_list *dev = get_device(ctx);
609 char payloadbuf[64];
610 sprintf(payloadbuf,
611 "{\"id\":%d,\"version\":\"1.0\",\"params\":{\"delayTime\":%d}}",
612 ++dev->seq, 5000);
613
614 CoAPLenString payload;
615 payload.data = (unsigned char *)payloadbuf;
616 payload.len = strlen(payloadbuf);
617 int tick = HAL_UptimeMs();
618
619 session_item *node = NULL, *next = NULL;
620 list_for_each_entry_safe(node, next, ctl_head, lst, session_item)
621 {
622 if (!node->sessionId) {
623 continue;
624 }
625
626 if (node->heart_time + node->interval > tick) {
627 CoAPMessage message;
628 alcs_msg_init(ctx, &message, COAP_MSG_CODE_GET,
629 COAP_MESSAGE_TYPE_CON, 0, &payload, NULL);
630 CoAPServerPath_2_option("/dev/core/service/heartBeat", &message);
631 message.handler = heart_beat_cb;
632 CoAPMessage_send(ctx, &node->addr, &message);
633 COAP_DEBUG("send heartbeat to :%s", node->addr.addr);
634 CoAPMessage_destory(&message);
635 }
636 }
637 }
638
639 #endif
640