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