1 /*
2  * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3  */
4 
5 #include <string.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include "uagent.h"
10 #include "uagent_inner_api.h"
11 #include "aos/kernel.h"
12 #include "aos/errno.h"
13 #include "k_config.h"
14 #include "cJSON.h"
15 
16 typedef struct {
17     ua_mod_t            mod;
18     ua_func_t           func;
19     on_customer_service service;
20     void*               arg;
21 } uagent_service_node;
22 
23 typedef struct {
24     ua_mod_t       mod;
25     ua_func_t      func;
26     unsigned long  id;
27     ua_mod_t       src;  /* not apply to down stream */
28     unsigned short len;
29 }uagent_exchange_header_t;
30 
31 typedef struct {
32     ua_func_t            func;
33     char                 func_name[UAGENT_FUNC_NAME_SIZE];
34     on_customer_service  service;
35     void*                arg;
36 }uagent_exchange_service_t;
37 
38 uagent_service_attr_t uagent_service_attr = { 0, 0 };
39 
40 static uagent_service_node *uagent_service_tb[UAGENT_SERVICE_SIZE] = { NULL };
41 
42 static mod_func_t *mod_func[UAGENT_MOD_SIZE] = { NULL };
43 
44 static aos_queue_t uagent_queue;
45 static uint8_t*    uagent_queue_buffer;
46 static aos_task_t uagent_task;
47 
48 static aos_timer_t timer_request_cloud_connect;
49 static aos_timer_t timer_monitor_output_queue;
50 
51 /* Private Operation Declaration */
52 static int update_create_uagent_service_node(const ua_mod_t mod, const ua_func_t func,
53                                              on_customer_service service, void *arg,
54                                              const char add);
55 
56 static int uagent_on_recv_handler(const unsigned short len, const char *str);
57 
58 static void uagent_routine(void *para);
59 
60 /* pre-define service of uAgent */
61 static void service_check_connect(void);
62 static void service_report_func_list(void);
63 static void service_update_delay_send_param(const unsigned short len, void *str);
64 
uagent_timer_service(void * timer,void * para)65 static void uagent_timer_service(void *timer, void *para)
66 {
67     if (NULL != timer) {
68         if (timer == (&timer_request_cloud_connect)) {
69             uagent_request_service(UAGENT_MOD_UAGENT, UAGENT_MOD_UAGENT, UAGENT_FUNC_UA_RQST_CONN, 0, NULL);
70         } else if (timer == (&timer_monitor_output_queue)) {
71             uagent_request_service(UAGENT_MOD_UAGENT, UAGENT_MOD_UAGENT, UAGENT_FUNC_UA_DUMP_DELAY_SEND, 0, NULL);
72         }
73     }
74 }
75 
start_monitor_delay_out(void)76 void start_monitor_delay_out(void)
77 {
78     aos_timer_start(&timer_monitor_output_queue);
79 }
80 
stop_monitor_delay_out(void)81 void stop_monitor_delay_out(void)
82 {
83     aos_timer_stop(&timer_monitor_output_queue);
84 }
85 
86 /* Public Operation Implementation */
uagent_init(void)87 int uagent_init(void)
88 {
89     int rc = 0;
90 
91     if (!UAGENT_INITED_FINISH) {
92         uagent_init_mutex();
93         rc = -1;
94         /* initial uagent queue */
95         uagent_queue_buffer = aos_malloc(UAGENT_PAYLOAD_CMD_SIZE*UAGENT_QUEUE_COUNT);
96         if (NULL != uagent_queue_buffer) {
97             if (0 == aos_queue_new(&uagent_queue,
98                 uagent_queue_buffer,
99                 UAGENT_PAYLOAD_CMD_SIZE*UAGENT_QUEUE_COUNT,
100                 UAGENT_PAYLOAD_CMD_SIZE)) {
101                 if (0 == aos_task_new_ext(&uagent_task, "uagent", uagent_routine,
102                     NULL, UAGENT_ROUTINE_TASK_STACK_DEPTH,
103                     RHINO_CONFIG_USER_PRI_MAX - 2)) {
104                     uagent_service_attr.initd = UAGENT_INITED;
105                     rc = 0;
106                 } else {
107                     aos_queue_free(&uagent_queue);
108                     aos_free(uagent_queue_buffer);
109                     uagent_queue_buffer = NULL;
110                 }
111             } else {
112                 aos_free(uagent_queue_buffer);
113                 uagent_queue_buffer = NULL;
114             }
115         }
116     }
117     return rc;
118 }
119 
uagent_ext_comm_start(const char * pk,const char * dn)120 int uagent_ext_comm_start(const char *pk, const char *dn)
121 {
122     int rc = -EINVAL;
123     if (uagent_service_attr.service_started==0 && NULL != pk && NULL != dn && strlen(pk)>0 && strlen(dn)>0 && UAGENT_INITED_FINISH) {
124         strncpy(uagent_service_attr.pk, pk, sizeof(uagent_service_attr.pk) - 1);
125         strncpy(uagent_service_attr.dn, dn, sizeof(uagent_service_attr.dn) - 1);
126         rc = uagent_ext_comm_init(uagent_service_attr.pk, uagent_service_attr.dn, uagent_on_recv_handler);
127         /* todo: re-try in routine if start fail */
128 #if UAGENT_CHECK_COMM_CYCLE!=0
129         if (0 != aos_timer_new(&timer_request_cloud_connect,
130             uagent_timer_service,
131             NULL,
132             UAGENT_CHECK_COMM_CYCLE,
133             1)) {
134             UAGENT_ERR("[uA]uagent start timer fail\n");
135         }
136 #endif
137         if (0 != aos_timer_new_ext(&timer_monitor_output_queue,
138             uagent_timer_service,
139             NULL,
140             UAGENT_WAIT_BUFFER,
141             0,
142             0)) {
143             UAGENT_ERR("[uA]uagent start timer fail\n");
144         }
145         uagent_service_attr.service_started = 1;
146     }
147     return rc;
148 }
149 
uagent_register(const ua_mod_t mod,const char * mod_name,char * version,const ua_func_t func,const char * func_name,on_customer_service cb,void * arg)150 int uagent_register(const ua_mod_t mod, const char *mod_name,  char *version,
151                     const ua_func_t func, const char *func_name,
152                     on_customer_service cb, void *arg)
153 {
154     if (UAGENT_INITED_FINISH) {
155         /* pre handle special event require */
156         switch (func)
157         {
158         case UAGENT_FUNC_NOTIFY_CLOUD_CONN:
159         {
160             char buf[UAGENT_PAYLOAD_CMD_STR_SIZE];
161             snprintf(buf, UAGENT_PAYLOAD_CMD_STR_SIZE, UAGENT_NOTICE_CONNECT, uagent_service_attr.cloud_connect);
162             if (NULL != cb) {
163                 cb(arg, strlen(buf) + 1, buf);
164             }
165         }
166         break;
167         default:
168             break;
169         }
170         uagent_exchange_service_t uagent_exchange_service = { func, "", cb, arg };
171         memset(uagent_exchange_service.func_name, 0, sizeof(uagent_exchange_service.func_name));
172         strncpy(uagent_exchange_service.func_name, func_name==NULL?"":func_name, sizeof(uagent_exchange_service.func_name) - 1);
173         if (func >= UAGENT_FUNC_USER_BASE) {
174             if (NULL != mod_name && NULL != version) {
175                 unsigned char i = 0;
176                 for (; i < UAGENT_MOD_SIZE; i++) {
177                     if (mod_func[i] == NULL) {
178                         mod_func[i] = (mod_func_t*)aos_malloc(sizeof(mod_func_t));
179                         if (mod_func[i] != NULL) {
180                             mod_func[i]->header = NULL;
181                             mod_func[i]->mod_info.mod = mod;
182                             mod_func[i]->mod_info.func_count = 0;
183                             mod_func[i]->mod_info.name = (char*)aos_malloc(strlen(mod_name) + 1);
184                             if (NULL != mod_func[i]->mod_info.name) {
185                                 strncpy(mod_func[i]->mod_info.name, mod_name, strlen(mod_name));
186                                 mod_func[i]->mod_info.name[strlen(mod_name)] = '\0';
187                             }
188                             mod_func[i]->mod_info.version = (char*)aos_malloc(strlen(version) + 1);
189                             if (NULL != mod_func[i]->mod_info.version) {
190                                 strncpy(mod_func[i]->mod_info.version, version, strlen(mod_name));
191                                 mod_func[i]->mod_info.version[strlen(version)] = '\0';
192                             }
193                         }
194                         break;
195                     } else {
196                         if (mod_func[i]->mod_info.mod == mod) { /* already exist */
197                             break;
198                         }
199                     }
200                 }
201             }
202         }
203 
204         return uagent_request_service(mod, UAGENT_MOD_UAGENT, UAGENT_FUNC_UA_REGISTER, sizeof(uagent_exchange_service), &uagent_exchange_service);
205     }
206     return -1;
207 }
208 
uagent_unregister(const ua_mod_t mod,const ua_func_t func)209 int uagent_unregister(const ua_mod_t mod, const ua_func_t func)
210 {
211     if (UAGENT_INITED_FINISH) {
212         uagent_exchange_service_t uagent_exchange_service = { func, "", NULL, NULL };
213         return uagent_request_service(mod, UAGENT_MOD_UAGENT, UAGENT_FUNC_UA_UNREGISTER, sizeof(uagent_exchange_service), &uagent_exchange_service);
214     }
215     return -1;
216 }
217 
uagent_request_service(const ua_mod_t src,const ua_mod_t target,const ua_func_t func,const unsigned short len,const void * data)218 int uagent_request_service(const ua_mod_t src, const ua_mod_t target,
219                            const ua_func_t func, const unsigned short len,
220                            const void *data)
221 {
222     int rc = -EINVAL;
223     if (len == 0 || NULL != data) {
224         rc = -1;
225         if (UAGENT_INITED_FINISH) {
226             /* make uagent info */
227             char tmp_buf[UAGENT_PAYLOAD_CMD_SIZE];
228             uagent_exchange_header_t *p = (uagent_exchange_header_t *)tmp_buf;
229             p->src = src;
230             p->mod = target;
231             p->id = UAGENT_MSG_IDX_INVALID;
232             p->func = func;
233             p->len = len < UAGENT_PAYLOAD_CMD_SIZE - sizeof(uagent_exchange_header_t) - 1 ? len : UAGENT_PAYLOAD_CMD_SIZE - sizeof(uagent_exchange_header_t) - 1;
234 
235             memcpy(&tmp_buf[sizeof(uagent_exchange_header_t)], data, p->len);
236             if (UAGENT_MOD_UAGENT != target && UAGENT_FUNC_UA_RQST_CONN != func) {
237                 UAGENT_INFO("[uA]call %s src 0x%x func 0x%x len %d\n", __func__, p->src, p->func, p->len);
238             }
239             tmp_buf[p->len + sizeof(uagent_exchange_header_t)] = 0;
240             rc = aos_queue_send(&uagent_queue, p, p->len + sizeof(uagent_exchange_header_t) + 1);
241         }
242     }
243 
244     return rc;
245 }
246 
247 /**
248  * update or create uagent service node
249  *
250  *
251  * @param[in]  mod     Module type, reference @ua_mod_t
252  * @param[in]  func    Service Name
253  * @param[in]  service Service routine
254  * @param[in]  add     add(update) or remove
255  *
256  * @return >=0: Success, -EINVAL: invalid parameter, -ENOMEN: no enough to malloc -EIO: Table is full
257  *
258  */
update_create_uagent_service_node(const ua_mod_t mod,const ua_func_t func,on_customer_service service,void * arg,const char add)259 static int update_create_uagent_service_node(const ua_mod_t mod,
260     const ua_func_t func,
261     on_customer_service service,
262     void *arg,
263     const char add)
264 {
265     int rc = -EIO;
266     unsigned char i = 0;
267     while (i < UAGENT_SERVICE_SIZE) {
268         if (uagent_service_tb[i] != NULL) {
269             if (uagent_service_tb[i]->mod == mod && uagent_service_tb[i]->func == func) {
270                 break;
271             }
272         }
273         i++;
274     }
275     UAGENT_INFO("[uA]Register Service mod 0x%x func 0x%x\n", mod, func);
276     if (UAGENT_SERVICE_SIZE == i) { /* no found it */
277         if (add != 0) { /* create it */
278             i = 0;
279             while (i < UAGENT_SERVICE_SIZE) {
280                 if (uagent_service_tb[i] == NULL) {
281                     break;
282                 }
283                 i++;
284             }
285             if (i < UAGENT_SERVICE_SIZE) {
286                 uagent_service_tb[i] = (uagent_service_node*)aos_malloc(sizeof(uagent_service_node));
287                 if (uagent_service_tb[i] == NULL) {
288                     rc = -ENOMEM;
289                 } else {
290                     uagent_service_tb[i]->mod = mod;
291                     uagent_service_tb[i]->func = func;
292                     uagent_service_tb[i]->service = service;
293                     uagent_service_tb[i]->arg = arg;
294                     rc = i;
295                 }
296             } else {
297                 rc = -EIO;
298             }
299         } else {
300             rc = 0;
301         }
302     } else { /* found it in list, */
303         if (add != 0) { /* update call back */
304             uagent_service_tb[i]->service = service;
305             uagent_service_tb[i]->arg = arg;
306             rc = i;
307         } else {
308             aos_free(uagent_service_tb[i]);
309             uagent_service_tb[i] = NULL;
310             rc = i;
311         }
312     }
313     return rc;
314 }
315 
update_func_list(const ua_mod_t mod,const ua_func_t func,char * func_name,const char add)316 static void update_func_list(const ua_mod_t mod, const ua_func_t func, char *func_name, const char add)
317 {
318     unsigned char i = 0;
319     while (mod_func[i] != NULL) {
320         if (mod_func[i]->mod_info.mod == mod) {
321             if (add) {
322                 add_list(mod_func[i], func, func_name);
323             } else {
324                 del_list(mod_func[i], func);
325             }
326         }
327         i++;
328     }
329 }
330 
ext_request_service(const ua_mod_t src,const ua_mod_t target,const ua_func_t func,const unsigned long id,const unsigned short len,const void * data)331 static int ext_request_service(const ua_mod_t src,
332     const ua_mod_t target,
333     const ua_func_t func,
334     const unsigned long id,
335     const unsigned short len,
336     const void *data)
337 {
338     int rc = -1;
339     if (UAGENT_INITED_FINISH) {
340         /* make uagent info */
341         char tmp_buf[UAGENT_PAYLOAD_CMD_SIZE];
342         uagent_exchange_header_t* p = (uagent_exchange_header_t*)tmp_buf;
343         p->src = src;
344         p->mod = target;
345         p->id = id;
346         p->func = func;
347         p->len = len < UAGENT_PAYLOAD_CMD_SIZE - sizeof(uagent_exchange_header_t) - 1 ? len : UAGENT_PAYLOAD_CMD_SIZE - sizeof(uagent_exchange_header_t) - 1;
348 
349         memcpy(&tmp_buf[sizeof(uagent_exchange_header_t)], data, p->len);
350         if (UAGENT_MOD_UAGENT != target && UAGENT_FUNC_UA_RQST_CONN != func) {
351             UAGENT_DEBUG("[uA]%s src 0x%x func 0x%x len %d\n", __func__, p->src, p->func, p->len);
352         }
353         tmp_buf[p->len + sizeof(uagent_exchange_header_t)] = 0;
354         rc = aos_queue_send(&uagent_queue, p, p->len + sizeof(uagent_exchange_header_t) + 1);
355     }
356 
357     return rc;
358 }
359 
uagent_routine(void * para)360 static void uagent_routine(void *para)
361 {
362     char tmp_buf[UAGENT_PAYLOAD_CMD_SIZE];
363     unsigned int rcv_size = 0;
364 
365     while (true) {
366         if (0 == aos_queue_recv(&uagent_queue, AOS_WAIT_FOREVER, tmp_buf, &rcv_size)) {
367             if (rcv_size >= sizeof(uagent_exchange_header_t)) {
368                 const uagent_exchange_header_t* p = (uagent_exchange_header_t*)tmp_buf;
369 
370                 /* handle on pre-define service by UAGENT self */
371                 if (UAGENT_MOD_UAGENT == p->mod) {
372 
373                     int rc = -1;
374                     switch (p->func)
375                     {
376                     case UAGENT_FUNC_UA_REGISTER:
377                         if (sizeof(uagent_exchange_service_t) == p->len) {
378                             uagent_exchange_service_t* service_info =
379                                 (uagent_exchange_service_t*)&tmp_buf[sizeof(uagent_exchange_header_t)];
380                             if (0 > (rc = update_create_uagent_service_node(p->src,
381                                 service_info->func, service_info->service, service_info->arg, UAGENT_REGISTER))) {
382                                 UAGENT_ERR("[uA]register mod 0x%x, func str %s fail %d\n",
383                                     p->src, service_info->func_name, rc);
384                             } else {
385                                 update_func_list(p->src, service_info->func, service_info->func_name, UAGENT_FUNC_UA_REGISTER);
386                             }
387                         }
388                         break;
389 
390                     case UAGENT_FUNC_UA_UNREGISTER:
391                         if (sizeof(uagent_exchange_service_t) == p->len) {
392                             uagent_exchange_service_t* service_info =
393                                 (uagent_exchange_service_t*)&tmp_buf[sizeof(uagent_exchange_header_t)];
394                             if (0 > (rc = update_create_uagent_service_node(p->src,
395                                 service_info->func, NULL, NULL, UAGENT_UNREGISTER))) {
396                                 UAGENT_ERR("[uA]un-register mod 0x%x, func %d fail %d\n",
397                                     p->src, service_info->func, rc);
398                             } else {
399                                 update_func_list(p->src, service_info->func, service_info->func_name, UAGENT_FUNC_UA_UNREGISTER);
400                             }
401                         }
402                         break;
403 
404                     case UAGENT_FUNC_UA_RQST_CONN:
405                         service_check_connect();
406                         break;
407 
408                     case UAGENT_FUNC_UA_SHOW_LIST:
409                         UAGENT_DEBUG("[uA]call %s get request show list plen %d", __func__, p->len);
410                         if (p->len > 0) {
411                             if (strncmp(&tmp_buf[sizeof(uagent_exchange_header_t)], "?", 2) == 0) {
412                                 service_report_func_list();
413                             } else {
414                                 UAGENT_ERR("[uA]call %s illegal cmd str %s\n",
415                                     __func__, &tmp_buf[sizeof(uagent_exchange_header_t)]);
416                             }
417                         }
418 
419                         break;
420 
421                     case UAGENT_FUNC_UA_DUMP_DELAY_SEND:
422                         uagent_send(UAGENT_MOD_CLI, UAGENT_FUNC_USER_BASE, 0, NULL, send_policy_delay_dump | send_policy_delay);
423                         break;
424 
425                     case UAGENT_FUNC_UA_DUMP_DELAY_SEND_PARAM:
426                         service_update_delay_send_param(p->len,
427                             &tmp_buf[sizeof(uagent_exchange_header_t)]);
428                         break;
429                     default:
430                         break;
431                     }
432 
433                 } else {
434                     unsigned char i = 0;
435                     while (i < UAGENT_SERVICE_SIZE) {
436                         if (NULL != uagent_service_tb[i]) {
437                             /* no break for broadcast function */
438                             if (p->mod == UAGENT_MOD_BROAD_CAST) {
439                                 if (p->func == uagent_service_tb[i]->func) {
440                                     UAGENT_DEBUG("handler mod 0x%x, func 0x%x, str %s @ %d\n",
441                                         p->mod, p->func, &tmp_buf[sizeof(uagent_exchange_header_t)], i);
442                                     if (NULL != uagent_service_tb[i]->service) {
443                                         uagent_service_tb[i]->service(uagent_service_tb[i]->arg,
444                                             p->len,
445                                             &tmp_buf[sizeof(uagent_exchange_header_t)]);
446                                     }
447                                 }
448                             } else if ((p->mod == uagent_service_tb[i]->mod) &&
449                                 (p->func == uagent_service_tb[i]->func)) {
450 
451                                 UAGENT_DEBUG("handler mod 0x%x, func 0x%x, str %s @ %d\n",
452                                     p->mod, p->func, &tmp_buf[sizeof(uagent_exchange_header_t)], i);
453                                 if (NULL != uagent_service_tb[i]->service) {
454                                     uagent_service_tb[i]->service(uagent_service_tb[i]->arg,
455                                         p->len,
456                                         &tmp_buf[sizeof(uagent_exchange_header_t)]);
457                                     if (UAGENT_MSG_IDX_INVALID != p->id) {
458                                         uagent_ack(SERVICE_AGENT_OK, p->id, p->mod, p->func, NULL);
459                                     }
460                                 } else {
461                                     if (UAGENT_MSG_IDX_INVALID != p->id) {
462                                         uagent_ack(SERVICE_AGENT_FAIL, p->id, p->mod, p->func, "no service");
463                                     }
464                                     UAGENT_ERR("[uA]found mod 0x%x func 0x%x but service is null\n", p->mod, p->func);
465                                 }
466                                 break;
467                             }
468                         }
469                         i++;
470                     }
471                     if (p->mod != UAGENT_MOD_BROAD_CAST && (UAGENT_SERVICE_SIZE == i)) {
472                         UAGENT_ERR("[uA]no found mod 0x%x func 0x%x id %ld\n", p->mod, p->func, p->id);
473                         if (UAGENT_MSG_IDX_INVALID != p->id) {
474                             uagent_ack(SERVICE_AGENT_FAIL, p->id, p->mod, p->func, "no service");
475                         }
476                     }
477                 }
478             }
479         } else {
480             UAGENT_ERR("[uA]uagent routine recv msg fail\n");
481         }
482     }
483 }
484 
uagent_on_recv_handler(const unsigned short len,const char * str)485 static int uagent_on_recv_handler(const unsigned short len, const char *str)
486 {
487     int rc = -1;
488     cJSON *root = NULL;
489     root = cJSON_Parse(str);
490     if (NULL != root) {
491         cJSON *params = cJSON_GetObjectItem(root, "params");
492         if (params != NULL) {
493             cJSON *value_text = cJSON_GetObjectItem(params, "value");
494             if (value_text != NULL) {
495                 cJSON *msgid = cJSON_GetObjectItem(value_text, "id");
496                 /* even no id can call service, w/o ack */
497                 unsigned long id = UAGENT_MSG_IDX_INVALID;
498                 if (NULL != msgid) {
499                     if(cJSON_IsNumber(msgid)) {
500                         id = msgid->valueint;
501                     } else if(cJSON_IsString(msgid)) {
502                         id = strtoul(msgid->valuestring, NULL, 10);
503                     }
504                 } else {
505                     UAGENT_ERR("[uA]call %s no id in payload\n", __func__);
506                 }
507 
508                 cJSON *mod = cJSON_GetObjectItem(value_text, "mod");
509                 cJSON *func = cJSON_GetObjectItem(value_text, "func");
510 
511                 if (NULL != mod && NULL != func) {
512 
513                         cJSON *param = cJSON_GetObjectItem(value_text, "param");
514                         if (NULL != param) {
515                             if (cJSON_IsObject(param)) {/* param is json object */
516                                 UAGENT_INFO("Json object\n");
517                                 char* value_str = cJSON_PrintUnformatted(param);
518                                 if (NULL != value_str) {
519                                     rc = 0;
520                                     ext_request_service(UAGENT_MOD_CLOUD,
521                                         mod->valueint,
522                                         func->valueint,
523                                         id,
524                                         strlen(value_str),
525                                         value_str);
526                                     cJSON_free(value_str);
527                                     value_str = NULL;
528                                 }
529                             } else if (cJSON_IsString(param)) {/* param is string */
530                                 UAGENT_INFO("String %s\n", param->valuestring);
531 
532                                 rc = 0;
533                                 ext_request_service(UAGENT_MOD_CLOUD,
534                                     mod->valueint,
535                                     func->valueint,
536                                     id,
537                                     strlen(param->valuestring),
538                                     param->valuestring);
539                             } else {
540                                 UAGENT_ERR("[uA]Not support format\n");
541                             }
542                         } else {
543                             UAGENT_ERR("[uA]missing param\n");
544                         }
545 
546                 } else {
547                     /* print topic name and topic message */
548                     char* json_str = cJSON_Print(value_text);
549 
550                     if (NULL != json_str) {
551                         UAGENT_ERR("[uA]LLEGAL FORMAT %s\n", json_str);
552                         cJSON_free(json_str);
553                         json_str = NULL;
554                     }
555                 }
556             } else {
557                 UAGENT_ERR("[uA]call %s no value in payload\n", __func__);
558             }
559         } else {
560             UAGENT_ERR("[uA]call %s no params in payload\n", __func__);
561         }
562         cJSON_Delete(root);
563         root = NULL;
564     } else {
565         UAGENT_ERR("[uA]ILLEGAL FORMAT, Not Json Object\n");
566     }
567     return rc;
568 }
569 
service_check_connect()570 static void service_check_connect()
571 {
572     if (uagent_service_attr.cloud_connect != check_connect()) {
573         UAGENT_INFO("[uA]cloud connect change %d->%d\n",
574             uagent_service_attr.cloud_connect, check_connect());
575         uagent_service_attr.cloud_connect = check_connect();
576         /* make connect string */
577         char buf[32];
578         sprintf(buf, UAGENT_NOTICE_CONNECT, uagent_service_attr.cloud_connect);
579         uagent_request_service(UAGENT_MOD_UAGENT,
580             UAGENT_MOD_BROAD_CAST,
581             UAGENT_FUNC_NOTIFY_CLOUD_CONN,
582             strlen(buf) + 1,
583             buf);
584         if (uagent_service_attr.cloud_connect) {
585             service_report_func_list();
586         }
587     }
588 }
589 
service_report_func_list()590 static void service_report_func_list()
591 {
592     unsigned char mod_idx = 0;
593     cJSON *root = NULL;
594     char *out = NULL;
595     cJSON *mod_obj[UAGENT_MOD_SIZE];
596     char init_mod_report = 0;
597 
598     root = cJSON_CreateObject();
599     if (NULL == root) {
600         UAGENT_ERR("[uA] creat root json fail \r\n");
601         return ;
602     }
603     while (NULL != mod_func[mod_idx]) {
604         init_mod_report = 0;
605         UAGENT_INFO("[uA]mod %s have func %d\n", mod_func[mod_idx]->mod_info.name, mod_func[mod_idx]->mod_info.func_count);
606         uagent_func_node_t *p = mod_func[mod_idx]->header;
607         cJSON *arr = NULL, *json = NULL;
608         while (NULL != p) {
609             if (p->func >= UAGENT_FUNC_USER_BASE) {
610                 UAGENT_INFO("[uA]Summit func %d name %s\n", p->func, p->func_name);
611                 if (0 == init_mod_report) {
612                     init_mod_report = 1;
613                     cJSON_AddItemToObject(root, mod_func[mod_idx]->mod_info.name, mod_obj[mod_idx] = cJSON_CreateObject());
614                     cJSON_AddNumberToObject(mod_obj[mod_idx], "module", mod_func[mod_idx]->mod_info.mod);
615                     cJSON_AddStringToObject(mod_obj[mod_idx], "version", mod_func[mod_idx]->mod_info.version);
616                     cJSON_AddItemToObject(mod_obj[mod_idx], "funclist", arr = cJSON_CreateArray());
617                 }
618                 json = cJSON_CreateObject();
619 
620                 cJSON_AddNumberToObject(json, "func", p->func);
621                 cJSON_AddStringToObject(json, "funcname", p->func_name);
622                 cJSON_AddItemToArray(arr, json);
623 
624             } else {
625                 UAGENT_DEBUG("[uA]call %s Not summit func %d name %s\n", __func__, p->func, p->func_name);
626             }
627             p = p->next;
628         }
629 
630         mod_idx++;
631     }
632 
633     out = cJSON_PrintUnformatted(root);
634     if (out == NULL) {
635         UAGENT_ERR("[uA] %s %d json print unformate fail\r\n", __FILE__, __LINE__);
636         return ;
637     }
638 
639     UAGENT_INFO("[uA]up uA List %s\n", out);
640     uagent_send(UAGENT_MOD_UAGENT, UAGENT_FUNC_UA_SHOW_LIST,
641         strlen(out),
642         out,
643         send_policy_trans_guarantee | send_policy_object);
644     cJSON_free(out);
645     cJSON_Delete(root);
646 }
647 
service_update_delay_send_param(const unsigned short len,void * str)648 static void service_update_delay_send_param(const unsigned short len, void *str)
649 {
650     if (len > 0 && NULL != str) {
651         char* str_value = NULL;
652         if (NULL != (str_value = strstr(str, "cli cloud timeout="))) {
653             UAGENT_DEBUG("call %s str value %s\n", __func__, str_value);
654             const int timeout = strtoul(&str_value[strlen("cli cloud timeout=")], NULL, 10);
655             if (timeout >= 20 && timeout <= 5000) {
656                 UAGENT_DEBUG("call %s delay timeout %d\n", __func__, timeout);
657                 aos_timer_change(&timer_monitor_output_queue, timeout);
658             }
659         }
660     }
661 }
662