1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "alcs_internal.h"
10 #include "alcs_api_internal.h"
11 #include "CoAPExport.h"
12 #include "linkkit/alcs_api.h"
13 #include "alcs_adapter.h"
14 #include "alcs_mqtt.h"
15 #include "alcs_adapter.h"
16 #include "CoAPPlatform.h"
17 
18 static alcs_mqtt_ctx_t g_alcs_mqtt_ctx;
19 
__alcs_mqtt_get_ctx(void)20 static alcs_mqtt_ctx_t *__alcs_mqtt_get_ctx(void)
21 {
22     return &g_alcs_mqtt_ctx;
23 }
24 
__alcs_mqtt_publish(char * topic,int qos,void * data,int len)25 static alcs_mqtt_status_e __alcs_mqtt_publish(char *topic, int qos, void *data,
26                                               int len)
27 {
28     return (IOT_MQTT_Publish_Simple(NULL, topic, qos, data, len) < 0)
29                ? ALCS_MQTT_STATUS_ERROR
30                : ALCS_MQTT_STATUS_SUCCESS;
31 }
32 
__alcs_mqtt_send_response(char * topic,int id,int code,char * data)33 static alcs_mqtt_status_e __alcs_mqtt_send_response(char *topic, int id,
34                                                     int code, char *data)
35 {
36     char *msg_pub = NULL;
37     uint16_t msg_len = 0;
38     alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
39 
40     if (data == NULL || strlen(data) == 0) {
41         data = "{}";
42     }
43 
44     msg_len =
45         strlen(ALCS_MQTT_THING_LAN_PREFIX_RESPONSE_FMT) + 20 + strlen(data) + 1;
46 
47     msg_pub = ALCS_ADAPTER_malloc(msg_len);
48     if (msg_pub == NULL) {
49         return ALCS_MQTT_STATUS_ERROR;
50     }
51 
52     HAL_Snprintf(msg_pub, msg_len, ALCS_MQTT_THING_LAN_PREFIX_RESPONSE_FMT, id,
53                  code, data);
54 
55     status = __alcs_mqtt_publish(topic, 1, msg_pub, strlen(msg_pub));
56 
57     ALCS_free(msg_pub);
58 
59     return status;
60 }
61 
__alcs_mqtt_kv_set(const char * key,const void * val,int len,int sync)62 static alcs_mqtt_status_e __alcs_mqtt_kv_set(const char *key, const void *val,
63                                              int len, int sync)
64 {
65     if (HAL_Kv_Set(key, val, len, sync) != 0) {
66         return ALCS_MQTT_STATUS_ERROR;
67     }
68 
69     COAP_INFO("ALCS KV Set, Key: %s, Val: %s, Len: %d", key, (char *)val, len);
70     return ALCS_MQTT_STATUS_SUCCESS;
71 }
72 
__alcs_mqtt_kv_get(const char * key,void * buffer,int * buffer_len)73 static alcs_mqtt_status_e __alcs_mqtt_kv_get(const char *key, void *buffer,
74                                              int *buffer_len)
75 {
76     if (HAL_Kv_Get(key, buffer, buffer_len) != 0) {
77         return ALCS_MQTT_STATUS_ERROR;
78     }
79 
80     COAP_INFO("ALCS KV Get, Key: %s", key);
81 
82     return ALCS_MQTT_STATUS_SUCCESS;
83 }
84 
__alcs_mqtt_kv_del(const char * key)85 static alcs_mqtt_status_e __alcs_mqtt_kv_del(const char *key)
86 {
87     if (HAL_Kv_Del(key) != 0) {
88         return ALCS_MQTT_STATUS_ERROR;
89     }
90 
91     COAP_INFO("ALCS KV Del, Key: %s", key);
92 
93     return ALCS_MQTT_STATUS_SUCCESS;
94 }
95 
__alcs_mqtt_prefix_secret_save(const char * pk,uint16_t pk_len,const char * dn,uint16_t dn_len,const char * prefix,uint16_t prefix_len,const char * secret,uint16_t secret_len)96 alcs_mqtt_status_e __alcs_mqtt_prefix_secret_save(
97     const char *pk, uint16_t pk_len, const char *dn, uint16_t dn_len,
98     const char *prefix, uint16_t prefix_len, const char *secret,
99     uint16_t secret_len)
100 {
101     char *key_source = NULL;
102     uint8_t key_md5[16] = { 0 };
103     char key_md5_hexstr[33] = { 0 };
104     char *value = NULL;
105 
106     if (pk == NULL || pk_len >= IOTX_PRODUCT_KEY_LEN + 1 || dn == NULL ||
107         dn_len >= IOTX_DEVICE_NAME_LEN + 1 || prefix == NULL ||
108         secret == NULL) {
109         COAP_ERR("Invalid Parameter");
110         return ALCS_MQTT_STATUS_ERROR;
111     }
112 
113     /* Calculate Key */
114     key_source = ALCS_ADAPTER_malloc(pk_len + dn_len + 1);
115     if (key_source == NULL) {
116         COAP_ERR("No Enough Memory");
117         return ALCS_MQTT_STATUS_ERROR;
118     }
119     memset(key_source, 0, pk_len + dn_len + 1);
120 
121     HAL_Snprintf(key_source, pk_len + dn_len + 1, "%.*s%.*s", pk_len, pk,
122                  dn_len, dn);
123 
124     utils_md5((const unsigned char *)key_source, strlen(key_source), key_md5);
125     alcs_utils_md5_hexstr(key_md5, (unsigned char *)key_md5_hexstr);
126 
127     /* Calculate Value */
128     value = ALCS_ADAPTER_malloc(prefix_len + secret_len + 3);
129     if (value == NULL) {
130         COAP_ERR("No Enough Memory");
131         ALCS_free(key_source);
132         return ALCS_MQTT_STATUS_ERROR;
133     }
134     memset(value, 0, prefix_len + secret_len + 3);
135 
136     value[0] = prefix_len;
137     value[1] = secret_len;
138     HAL_Snprintf(&value[2], prefix_len + secret_len + 1, "%.*s%.*s", prefix_len,
139                  prefix, secret_len, secret);
140 
141     if (ALCS_MQTT_STATUS_SUCCESS !=
142         __alcs_mqtt_kv_set(key_md5_hexstr, value, prefix_len + secret_len + 3,
143                            1)) {
144         COAP_ERR("ALCS KV Set Prefix And Secret Fail");
145         ALCS_free(key_source);
146         ALCS_free(value);
147         return ALCS_MQTT_STATUS_ERROR;
148     }
149 
150     ALCS_free(key_source);
151     ALCS_free(value);
152     return ALCS_MQTT_STATUS_SUCCESS;
153 }
154 
alcs_mqtt_prefix_secret_load(const char * pk,uint16_t pk_len,const char * dn,uint16_t dn_len,char * prefix,char * secret)155 alcs_mqtt_status_e alcs_mqtt_prefix_secret_load(const char *pk, uint16_t pk_len,
156                                                 const char *dn, uint16_t dn_len,
157                                                 char *prefix, char *secret)
158 {
159     char *key_source = NULL;
160     uint8_t key_md5[16] = { 0 };
161     char key_md5_hexstr[33] = { 0 };
162     char value[128] = { 0 };
163     int value_len = sizeof(value);
164 
165     if (pk == NULL || strlen(pk) >= IOTX_PRODUCT_KEY_LEN + 1 || dn == NULL ||
166         strlen(dn) >= IOTX_DEVICE_NAME_LEN + 1 || prefix == NULL ||
167         secret == NULL) {
168         COAP_ERR("Invalid Parameter");
169         return ALCS_MQTT_STATUS_ERROR;
170     }
171 
172     /* Calculate Key */
173     key_source = ALCS_ADAPTER_malloc(pk_len + dn_len + 1);
174     if (key_source == NULL) {
175         COAP_ERR("No Enough Memory");
176         return ALCS_MQTT_STATUS_ERROR;
177     }
178     memset(key_source, 0, pk_len + dn_len + 1);
179 
180     HAL_Snprintf(key_source, pk_len + dn_len + 1, "%.*s%.*s", pk_len, pk,
181                  dn_len, dn);
182 
183     utils_md5((const unsigned char *)key_source, strlen(key_source), key_md5);
184     alcs_utils_md5_hexstr(key_md5, (unsigned char *)key_md5_hexstr);
185 
186     /* Get Value */
187     if (ALCS_MQTT_STATUS_SUCCESS !=
188         __alcs_mqtt_kv_get(key_md5_hexstr, value, &value_len)) {
189         COAP_ERR("ALCS KV Get Prefix And Secret Fail");
190         ALCS_free(key_source);
191         return ALCS_MQTT_STATUS_ERROR;
192     }
193 
194     memcpy(prefix, &value[2], value[0]);
195     memcpy(secret, &value[2 + value[0]], value[1]);
196     ALCS_free(key_source);
197 
198     return ALCS_MQTT_STATUS_SUCCESS;
199 }
200 
alcs_mqtt_prefix_secret_del(const char * pk,uint16_t pk_len,const char * dn,uint16_t dn_len)201 alcs_mqtt_status_e alcs_mqtt_prefix_secret_del(const char *pk, uint16_t pk_len,
202                                                const char *dn, uint16_t dn_len)
203 {
204     char *key_source = NULL;
205     uint8_t key_md5[16] = { 0 };
206     char key_md5_hexstr[33] = { 0 };
207 
208     if (pk == NULL || strlen(pk) >= IOTX_PRODUCT_KEY_LEN + 1 || dn == NULL ||
209         strlen(dn) >= IOTX_DEVICE_NAME_LEN + 1) {
210         COAP_ERR("Invalid Parameter");
211         return ALCS_MQTT_STATUS_ERROR;
212     }
213 
214     /* Calculate Key */
215     key_source = ALCS_ADAPTER_malloc(pk_len + dn_len + 1);
216     if (key_source == NULL) {
217         COAP_ERR("No Enough Memory");
218         return ALCS_MQTT_STATUS_ERROR;
219     }
220     memset(key_source, 0, pk_len + dn_len + 1);
221 
222     HAL_Snprintf(key_source, pk_len + dn_len + 1, "%.*s%.*s", pk_len, pk,
223                  dn_len, dn);
224 
225     utils_md5((const unsigned char *)key_source, strlen(key_source), key_md5);
226     alcs_utils_md5_hexstr(key_md5, (unsigned char *)key_md5_hexstr);
227 
228     if (ALCS_MQTT_STATUS_SUCCESS != __alcs_mqtt_kv_del(key_md5_hexstr)) {
229         COAP_ERR("ALCS KV Get Prefix And Secret Fail");
230         ALCS_free(key_source);
231         return ALCS_MQTT_STATUS_ERROR;
232     }
233 
234     ALCS_free(key_source);
235     return ALCS_MQTT_STATUS_SUCCESS;
236 }
237 
__alcs_mqtt_subscribe_callback(void * pcontext,void * pclient,iotx_mqtt_event_msg_pt msg)238 static void __alcs_mqtt_subscribe_callback(void *pcontext, void *pclient,
239                                            iotx_mqtt_event_msg_pt msg)
240 {
241     char topic_compare[ALCS_MQTT_TOPIC_MAX_LEN] = { 0 };
242     char reqid[16] = { 0 };
243     char *topic;
244     int topic_len;
245     void *payload;
246     int payload_len;
247     alcs_mqtt_ctx_t *alcs_mqtt_ctx = NULL;
248     iotx_mqtt_topic_info_pt ptopic_info = NULL;
249 
250     if (msg == NULL) {
251         return;
252     }
253     alcs_mqtt_ctx = (alcs_mqtt_ctx_t *)pcontext;
254     ptopic_info = (iotx_mqtt_topic_info_pt)msg->msg;
255 
256     switch (msg->event_type) {
257     case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS:
258         return;
259     case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT:
260         return;
261     case IOTX_MQTT_EVENT_SUBCRIBE_NACK:
262         return;
263     case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
264         topic = (char *)ptopic_info->ptopic;
265         topic_len = ptopic_info->topic_len;
266         payload = (char *)ptopic_info->payload;
267         payload_len = ptopic_info->payload_len;
268         break;
269     default:
270         return;
271     }
272 
273     if (topic == NULL || payload == NULL || topic_len == 0 ||
274         payload_len == 0) {
275         return;
276     }
277 
278     memset(topic_compare, 0, ALCS_MQTT_TOPIC_MAX_LEN);
279     HAL_Snprintf(topic_compare, ALCS_MQTT_TOPIC_MAX_LEN,
280                  ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_REPLY_FMT,
281                  alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
282 
283     COAP_INFO("Receivce Message, Topic: %.*s\n", topic_len, topic);
284 
285     if ((strlen(topic_compare) == topic_len) &&
286         (strncmp(topic_compare, topic, topic_len) == 0)) {
287         int data_len = 0, prefix_len = 0, secret_len = 0, productKey_len = 0,
288             deviceName_len = 0;
289         char *data = NULL, *prefix = NULL, *secret = NULL, *productKey = NULL,
290              *deviceName = NULL;
291         data = json_get_value_by_name((char *)payload, payload_len, "data",
292                                       &data_len, NULL);
293 
294         if (NULL != data && 0 != data_len) {
295             char back1, back2;
296             prefix = json_get_value_by_name(
297                 data, data_len, ALCS_MQTT_JSON_KEY_PREFIX, &prefix_len, NULL);
298             secret = json_get_value_by_name(
299                 data, data_len, ALCS_MQTT_JSON_KEY_SECRET, &secret_len, NULL);
300             productKey = json_get_value_by_name(data, data_len,
301                                                 ALCS_MQTT_JSON_KEY_PRODUCT_KEY,
302                                                 &productKey_len, NULL);
303             deviceName = json_get_value_by_name(data, data_len,
304                                                 ALCS_MQTT_JSON_KEY_DEVICE_NAME,
305                                                 &deviceName_len, NULL);
306 
307             COAP_INFO("Get Reply, Product Key: %.*s, Device Name: %.*s\n",
308                       productKey_len, productKey, deviceName_len, deviceName);
309 
310             if (NULL != alcs_mqtt_ctx->coap_ctx && prefix && secret) {
311                 back1 = prefix[prefix_len];
312                 prefix[prefix_len] = 0;
313                 back2 = secret[secret_len];
314                 secret[secret_len] = 0;
315                 alcs_add_svr_key(alcs_mqtt_ctx->coap_ctx, prefix, secret,
316                                  FROMCLOUDSVR);
317                 prefix[prefix_len] = back1;
318                 secret[secret_len] = back2;
319 
320                 if (productKey && deviceName) {
321                     if (__alcs_mqtt_prefix_secret_save(
322                             productKey, productKey_len, deviceName,
323                             deviceName_len, prefix, prefix_len, secret,
324                             secret_len) == ALCS_MQTT_STATUS_SUCCESS) {
325                         iotx_alcs_subdev_item_t subdev_item;
326                         memset(&subdev_item, 0,
327                                sizeof(iotx_alcs_subdev_item_t));
328 
329                         memcpy(subdev_item.product_key, productKey,
330                                productKey_len);
331                         memcpy(subdev_item.device_name, deviceName,
332                                deviceName_len);
333                         subdev_item.stage = IOTX_ALCS_SUBDEV_CONNECT_CLOUD;
334 
335                         iotx_alcs_subdev_update_stage(&subdev_item);
336                     }
337                 } else {
338                     iotx_alcs_subdev_remove(alcs_mqtt_ctx->product_key,
339                                             alcs_mqtt_ctx->device_name);
340                     if (ALCS_MQTT_STATUS_SUCCESS !=
341                         __alcs_mqtt_kv_set(ALCS_MQTT_JSON_KEY_PREFIX, prefix,
342                                            prefix_len, 1)) {
343                         COAP_ERR("ALCS KV Set Prefix Fail");
344                     }
345                     if (ALCS_MQTT_STATUS_SUCCESS !=
346                         __alcs_mqtt_kv_set(ALCS_MQTT_JSON_KEY_SECRET, secret,
347                                            secret_len, 1)) {
348                         COAP_ERR("ALCS KV Set Secret Fail");
349                     }
350                 }
351             }
352         } else {
353             if (ALCS_MQTT_STATUS_SUCCESS ==
354                     __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_PREFIX, prefix,
355                                        &prefix_len) &&
356                 ALCS_MQTT_STATUS_SUCCESS ==
357                     __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_SECRET, secret,
358                                        &secret_len)) {
359                 if (NULL != alcs_mqtt_ctx->coap_ctx && prefix_len &&
360                     secret_len) {
361                     alcs_add_svr_key(alcs_mqtt_ctx->coap_ctx, prefix, secret,
362                                      FROMCLOUDSVR);
363                 }
364             }
365         }
366         return;
367     }
368 
369     memset(topic_compare, 0, ALCS_MQTT_TOPIC_MAX_LEN);
370     HAL_Snprintf(topic_compare, ALCS_MQTT_TOPIC_MAX_LEN,
371                  ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_UPDATE_FMT,
372                  alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
373 
374     if ((strlen(topic_compare) == topic_len) &&
375         (strncmp(topic_compare, topic, topic_len) == 0)) {
376         int param_len = 0, prefix_len = 0, id_len = 0;
377         char *param = NULL, *prefix = NULL, *id = NULL;
378         id = json_get_value_by_name((char *)payload, payload_len, "id", &id_len,
379                                     NULL);
380 
381         if (NULL != id && 0 != id_len) {
382             strncpy(reqid, id, sizeof(reqid) - 1);
383         }
384         param = json_get_value_by_name((char *)payload, payload_len, "params",
385                                        &param_len, NULL);
386         if (NULL != param && 0 != param_len) {
387             char reply_topic[ALCS_MQTT_TOPIC_MAX_LEN] = { 0 };
388             prefix = json_get_value_by_name(
389                 param, param_len, ALCS_MQTT_JSON_KEY_PREFIX, &prefix_len, NULL);
390 
391             if (NULL != alcs_mqtt_ctx->coap_ctx && prefix) {
392                 char mprefix[ALCS_MQTT_PREFIX_MAX_LEN + 1] = { 0 };
393                 char msecret[ALCS_MQTT_SECRET_MAX_LEN + 1] = { 0 };
394                 char mpk[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
395                 char mdn[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
396                 uint16_t mpk_len = 0, mdn_len = 0;
397                 HAL_GetProductKey(mpk);
398                 HAL_GetDeviceName(mdn);
399                 mpk_len = strlen(mpk);
400                 mdn_len = strlen(mdn);
401                 if (alcs_mqtt_prefix_secret_load(mpk, mpk_len, mdn, mdn_len,
402                                                  mprefix, msecret) ==
403                     ALCS_MQTT_STATUS_SUCCESS) {
404                     char back1 = prefix[prefix_len];
405                     prefix[prefix_len] = 0;
406                     alcs_add_svr_key(alcs_mqtt_ctx->coap_ctx, prefix, msecret,
407                                      FROMCLOUDSVR);
408                     prefix[prefix_len] = back1;
409                     if (__alcs_mqtt_prefix_secret_save(
410                             mpk, mpk_len, mdn, mdn_len, prefix, prefix_len,
411                             msecret,
412                             strlen(msecret)) == ALCS_MQTT_STATUS_SUCCESS) {
413                         COAP_INFO("prefix saved\n");
414                     } else {
415                         COAP_ERR("prefix save failed\n");
416                     }
417                 } else {
418                     COAP_ERR("update prefix_secret_load failed\n");
419                 }
420             } else {
421                 COAP_ERR("prefix not found, prefix update failed\n");
422             }
423 
424             HAL_Snprintf(
425                 reply_topic, ALCS_MQTT_TOPIC_MAX_LEN,
426                 ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_UPDATE_REPLY_FMT,
427                 alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
428             __alcs_mqtt_send_response(reply_topic, atoi(reqid), 200, NULL);
429         }
430         return;
431     }
432 
433     memset(topic_compare, 0, ALCS_MQTT_TOPIC_MAX_LEN);
434     HAL_Snprintf(
435         topic_compare, ALCS_MQTT_TOPIC_MAX_LEN,
436         ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_FMT,
437         alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
438 
439     if ((strlen(topic_compare) == topic_len) &&
440         (strncmp(topic_compare, topic, topic_len) == 0)) {
441         int param_len = 0, blacklist_len = 0, id_len = 0;
442         char *param = NULL, *blacklist = NULL, *id = NULL;
443         id = json_get_value_by_name((char *)payload, payload_len, "id", &id_len,
444                                     NULL);
445 
446         if (NULL != id && 0 != id_len) {
447             strncpy(reqid, id, sizeof(reqid) - 1);
448         }
449         param = json_get_value_by_name((char *)payload, payload_len, "params",
450                                        &param_len, NULL);
451         if (NULL != param && 0 != param_len) {
452             char reply_topic[ALCS_MQTT_TOPIC_MAX_LEN] = { 0 };
453             blacklist = json_get_value_by_name(param, param_len,
454                                                ALCS_MQTT_JSON_KEY_BLACK,
455                                                &blacklist_len, NULL);
456             if (NULL != alcs_mqtt_ctx->coap_ctx && blacklist) {
457                 alcs_set_revocation(alcs_mqtt_ctx->coap_ctx, blacklist);
458                 if (ALCS_MQTT_STATUS_SUCCESS !=
459                     __alcs_mqtt_kv_set(ALCS_MQTT_JSON_KEY_BLACK, blacklist,
460                                        blacklist_len, 1)) {
461                     COAP_ERR("aos_kv_set set blacklist fail");
462                     ;
463                 }
464             }
465 
466             HAL_Snprintf(
467                 reply_topic, ALCS_MQTT_TOPIC_MAX_LEN,
468                 ALCS_MQTT_PREFIX
469                     ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_REPLY_FMT,
470                 alcs_mqtt_ctx->product_key, alcs_mqtt_ctx->device_name);
471             __alcs_mqtt_send_response(reply_topic, atoi(reqid), 200, NULL);
472         } else {
473             if (ALCS_MQTT_STATUS_SUCCESS ==
474                 __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_BLACK, blacklist,
475                                    &blacklist_len)) {
476                 if (NULL != alcs_mqtt_ctx->coap_ctx) {
477                     alcs_set_revocation(alcs_mqtt_ctx->coap_ctx, blacklist);
478                 }
479             }
480         }
481         return;
482     }
483 }
484 
__alcs_mqtt_subscribe(void * ctx,char * topic)485 static alcs_mqtt_status_e __alcs_mqtt_subscribe(void *ctx, char *topic)
486 {
487     return (IOT_MQTT_Subscribe(NULL, topic, 0, __alcs_mqtt_subscribe_callback,
488                                ctx) < 0)
489                ? ALCS_MQTT_STATUS_ERROR
490                : ALCS_MQTT_STATUS_SUCCESS;
491 }
492 
alcs_mqtt_init(void * handle,char * product_key,char * device_name)493 alcs_mqtt_status_e alcs_mqtt_init(void *handle, char *product_key,
494                                   char *device_name)
495 {
496     char topic[ALCS_MQTT_TOPIC_MAX_LEN] = { 0 };
497     alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
498     alcs_mqtt_ctx_t *ctx = __alcs_mqtt_get_ctx();
499 
500     if (handle == NULL || product_key == NULL ||
501         strlen(product_key) > IOTX_PRODUCT_KEY_LEN || device_name == NULL ||
502         strlen(device_name) > IOTX_DEVICE_NAME_LEN) {
503         return ALCS_MQTT_STATUS_ERROR;
504     }
505 
506     memset(ctx, 0, sizeof(alcs_mqtt_ctx_t));
507     ctx->coap_ctx = (CoAPContext *)handle;
508     memcpy(ctx->product_key, product_key, strlen(product_key));
509     memcpy(ctx->device_name, device_name, strlen(device_name));
510 
511     memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
512     HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN,
513                  ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_REPLY_FMT,
514                  ctx->product_key, ctx->device_name);
515     if (__alcs_mqtt_subscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
516         COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
517         status = ALCS_MQTT_STATUS_ERROR;
518     }
519 
520     memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
521     HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN,
522                  ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_UPDATE_FMT,
523                  ctx->product_key, ctx->device_name);
524     if (__alcs_mqtt_subscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
525         COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
526         status = ALCS_MQTT_STATUS_ERROR;
527     }
528 
529     memset(topic, 0, ALCS_MQTT_TOPIC_MAX_LEN);
530     HAL_Snprintf(
531         topic, ALCS_MQTT_TOPIC_MAX_LEN,
532         ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_BLACKLIST_UPDATE_FMT,
533         ctx->product_key, ctx->device_name);
534     if (__alcs_mqtt_subscribe((void *)ctx, topic) != ALCS_MQTT_STATUS_SUCCESS) {
535         COAP_ERR("ALCS Subscribe Failed, Topic: %s", topic);
536         status = ALCS_MQTT_STATUS_ERROR;
537     }
538 
539     alcs_mqtt_prefixkey_update((void *)ctx->coap_ctx);
540     alcs_mqtt_blacklist_update((void *)ctx->coap_ctx);
541 
542     alcs_prefixkey_get(ctx->product_key, ctx->device_name);
543 
544     return status;
545 }
546 
alcs_mqtt_deinit(void * handle,char * product_key,char * device_name)547 alcs_mqtt_status_e alcs_mqtt_deinit(void *handle, char *product_key,
548                                     char *device_name)
549 {
550     return ALCS_MQTT_STATUS_SUCCESS;
551 }
552 
alcs_mqtt_add_srv_key(const char * prefix,const char * secret)553 void alcs_mqtt_add_srv_key(const char *prefix, const char *secret)
554 {
555     alcs_mqtt_ctx_t *alcs_mqtt_ctx = __alcs_mqtt_get_ctx();
556     alcs_add_svr_key(alcs_mqtt_ctx->coap_ctx, prefix, secret, FROMCLOUDSVR);
557 }
558 
alcs_mqtt_blacklist_update(void * ctx)559 alcs_mqtt_status_e alcs_mqtt_blacklist_update(void *ctx)
560 {
561     CoAPContext *context = (CoAPContext *)ctx;
562     char blacklist[ALCS_MQTT_BLACK_MAX_LEN] = { 0 };
563     int blacklist_len = ALCS_MQTT_BLACK_MAX_LEN;
564 
565     if (NULL == context) {
566         return -1;
567     }
568 
569     if (ALCS_MQTT_STATUS_SUCCESS == __alcs_mqtt_kv_get(ALCS_MQTT_JSON_KEY_BLACK,
570                                                        blacklist,
571                                                        &blacklist_len)) {
572         COAP_INFO("The blacklist is %.*s", blacklist_len, blacklist);
573         if (blacklist_len) {
574             alcs_set_revocation(context, blacklist);
575             return ALCS_MQTT_STATUS_SUCCESS;
576         }
577     }
578 
579     return ALCS_MQTT_STATUS_ERROR;
580 }
581 
alcs_mqtt_prefixkey_update(void * ctx)582 alcs_mqtt_status_e alcs_mqtt_prefixkey_update(void *ctx)
583 {
584     CoAPContext *context = (CoAPContext *)ctx;
585     char prefix[ALCS_MQTT_PREFIX_MAX_LEN + 1] = { 0 };
586     char secret[ALCS_MQTT_SECRET_MAX_LEN + 1] = { 0 };
587     char product_key[IOTX_PRODUCT_KEY_LEN + 1] = { 0 };
588     char device_name[IOTX_DEVICE_NAME_LEN + 1] = { 0 };
589     uint16_t prodkey_len = 0, devname_len = 0;
590 
591     if (NULL == context) {
592         return ALCS_MQTT_STATUS_ERROR;
593     }
594 
595     COAP_INFO("start alcs_prefixkey_update\n");
596 
597     HAL_GetProductKey(product_key);
598     HAL_GetDeviceName(device_name);
599     prodkey_len = strlen(product_key);
600     devname_len = strlen(device_name);
601     if (alcs_mqtt_prefix_secret_load(product_key, prodkey_len, device_name,
602                                      devname_len, prefix,
603                                      secret) == ALCS_MQTT_STATUS_SUCCESS) {
604         alcs_add_svr_key(context, prefix, secret, FROMCLOUDSVR);
605         return ALCS_MQTT_STATUS_SUCCESS;
606     } else {
607         COAP_INFO("alcs_prefixkey_update failed\n");
608     }
609 
610     return ALCS_MQTT_STATUS_ERROR;
611 }
612 
alcs_prefixkey_get(const char * product_key,const char * device_name)613 alcs_mqtt_status_e alcs_prefixkey_get(const char *product_key,
614                                       const char *device_name)
615 {
616     /* int ret = 0; */
617     char *msg_pub = NULL;
618     uint16_t msg_len = 0;
619     char topic[ALCS_MQTT_TOPIC_MAX_LEN] = { 0 };
620     alcs_mqtt_ctx_t *ctx = __alcs_mqtt_get_ctx();
621     alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
622     int id = ctx->send_id++;
623 
624     if (product_key == NULL || strlen(product_key) > IOTX_PRODUCT_KEY_LEN ||
625         device_name == NULL || strlen(device_name) > IOTX_DEVICE_NAME_LEN) {
626         return ALCS_MQTT_STATUS_ERROR;
627     }
628     HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN,
629                  ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_FMT,
630                  product_key, device_name);
631 
632     msg_len = strlen(ALCS_MQTT_THING_ALCS_REQUEST) + 10 + 1;
633     msg_pub = ALCS_ADAPTER_malloc(msg_len);
634     if (msg_pub == NULL) {
635         return ALCS_MQTT_STATUS_ERROR;
636     }
637 
638     HAL_Snprintf(msg_pub, msg_len, ALCS_MQTT_THING_ALCS_REQUEST, id);
639 
640     COAP_INFO("ALCS Prefix Get, Topic: %s, Payload: %s", topic, msg_pub);
641     status = __alcs_mqtt_publish(topic, 1, msg_pub, strlen(msg_pub));
642 
643     ALCS_free(msg_pub);
644 
645     return status;
646 }
647 
alcs_mqtt_subdev_prefix_get(const char * product_key,const char * device_name)648 alcs_mqtt_status_e alcs_mqtt_subdev_prefix_get(const char *product_key,
649                                                const char *device_name)
650 {
651     /* int ret = 0; */
652     char *msg_pub = NULL;
653     uint16_t msg_len = 0;
654     char topic[ALCS_MQTT_TOPIC_MAX_LEN] = { 0 };
655     alcs_mqtt_ctx_t *ctx = __alcs_mqtt_get_ctx();
656     alcs_mqtt_status_e status = ALCS_MQTT_STATUS_SUCCESS;
657     int id = ctx->send_id++;
658 
659     if (product_key == NULL || strlen(product_key) > IOTX_PRODUCT_KEY_LEN ||
660         device_name == NULL || strlen(device_name) > IOTX_DEVICE_NAME_LEN) {
661         return ALCS_MQTT_STATUS_ERROR;
662     }
663 
664     COAP_INFO("Subdevice, PK: %s, DN: %s\n", product_key, device_name);
665     HAL_Snprintf(topic, ALCS_MQTT_TOPIC_MAX_LEN,
666                  ALCS_MQTT_PREFIX ALCS_MQTT_THING_LAN_PREFIX_GET_FMT,
667                  ctx->product_key, ctx->device_name);
668 
669     msg_len = strlen(ALCS_MQTT_THING_ALCS_SUBDEV_REQUEST) + 10 +
670               strlen(product_key) + strlen(device_name) + 1;
671     msg_pub = ALCS_ADAPTER_malloc(msg_len));
672     if (msg_pub == NULL) {
673         return ALCS_MQTT_STATUS_ERROR;
674     }
675 
676     HAL_Snprintf(msg_pub, msg_len, ALCS_MQTT_THING_ALCS_SUBDEV_REQUEST, id,
677                  (int)strlen(product_key), product_key,
678                  (int)strlen(device_name), device_name);
679 
680     COAP_ERR("ALCS Prefix Get, Topic: %s, Payload: %s", topic, msg_pub);
681     status = __alcs_mqtt_publish(topic, 1, msg_pub, strlen(msg_pub));
682 
683     ALCS_free(msg_pub);
684 
685     return status;
686 }
687