1 /*
2  * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3  */
4 
5 #define CONFIG_LOGMACRO_DETAILS
6 
7 #include "board_mgr.h"
8 
9 #include <fcntl.h>
10 #include <stdarg.h>
11 #include <stdbool.h>
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include "aos/list.h"
18 #include "aos_hal_adc.h"
19 #include "aos_hal_gpio.h"
20 #include "aos_hal_i2c.h"
21 #include "aos_hal_pwm.h"
22 #include "aos_hal_spi.h"
23 #include "aos_hal_uart.h"
24 #include "board_config.h"
25 #include "cJSON.h"
26 #include "ulog/ulog.h"
27 
28 #define LOG_TAG     "BOARD_MGR"
29 
30 #define DRIVER_NAME "driver.json"
31 
32 // extern int py_repl_config;
33 int py_repl_config = 0;
34 
35 typedef struct parse_json {
36     char *marker_name;
37     addon_module_m module;
38     int8_t (*fn)(cJSON *, char *);
39 } parse_json_t;
40 
41 typedef struct board_item {
42     addon_module_m module;
43     item_handle_t handle;
44     char *name_id;
45     void *node;
46     uint8_t status;
47 } board_item_t;
48 
49 typedef struct board_mgr {
50     uint32_t item_size;
51     board_item_t **item;
52 } board_mgr_t;
53 
54 typedef struct page_entry {
55     char *page;
56     dlist_t node;
57 } page_entry_t;
58 
59 static board_mgr_t g_board_mgr = { 0, NULL };
60 
61 static dlist_t g_pages_list;
62 
63 static int8_t board_add_new_item(addon_module_m module, char *name_id, void *node);
64 
board_get_handle(void)65 static board_mgr_t *board_get_handle(void)
66 {
67     return &g_board_mgr;
68 }
69 
board_set_gpio_default(gpio_dev_t * gpio_device)70 static void board_set_gpio_default(gpio_dev_t *gpio_device)
71 {
72     gpio_params_t *priv = (gpio_params_t *)gpio_device->priv;
73     if (NULL == gpio_device || NULL == priv) {
74         return;
75     }
76 
77     gpio_device->port = -1;
78     gpio_device->config = OUTPUT_PUSH_PULL;
79     gpio_device->gpioc = NULL;
80     gpio_device->gpioc_index = 0;
81     gpio_device->pin_index = 0;
82     priv->irq_mode = 0;
83     priv->js_cb_ref = 0;
84     priv->reserved = NULL;
85 }
86 
board_parse_gpio(cJSON * gpio,char * id)87 static int8_t board_parse_gpio(cJSON *gpio, char *id)
88 {
89     int index = 0;
90     int8_t ret = -1;
91     cJSON *port = NULL;
92     cJSON *item = NULL;
93     cJSON *dir = NULL;
94     cJSON *pull = NULL;
95     cJSON *intMode = NULL;
96     gpio_dev_t device;
97     gpio_params_t *priv = NULL;
98     gpio_config_t *config = (gpio_config_t *)&device.config;
99     int8_t size = 1;
100 
101     if (size <= 0) {
102         return BOARD_ERR_SIZE_INVALID;
103     }
104     while (index < size) {
105         if ((priv = (gpio_params_t *)aos_calloc(1, sizeof(gpio_params_t))) == NULL) {
106             LOGE(LOG_TAG, "malloc failed");
107             return BOARD_ERR_NO_MEM;
108         }
109         item = gpio;
110         index += 1;
111         if (NULL == item || NULL == id) {
112             continue;
113         }
114         port = cJSON_GetObjectItem(item, MARKER_PORT);
115         if (NULL == port || cJSON_Number != port->type) {
116             continue;
117         }
118 
119         device.priv = priv;
120         board_set_gpio_default(&device);
121         dir = cJSON_GetObjectItem(item, GPIO_DIR);
122         pull = cJSON_GetObjectItem(item, GPIO_PULL);
123         intMode = cJSON_GetObjectItem(item, GPIO_INTMODE);
124         if (NULL != dir && cJSON_String == dir->type && NULL != pull && cJSON_String == pull->type) {
125             if (strcmp(dir->valuestring, GPIO_DIR_INPUT) == 0) {
126                 if (strcmp(GPIO_PULL_DOWN, pull->valuestring) == 0)
127                     *config = INPUT_PULL_DOWN;
128                 else if (strcmp(GPIO_PULL_UP, pull->valuestring) == 0)
129                     *config = INPUT_PULL_UP;
130                 else if (strcmp(GPIO_PULL_OPEN, pull->valuestring) == 0)
131                     *config = INPUT_HIGH_IMPEDANCE;
132             }
133 
134             else if (strcmp(dir->valuestring, GPIO_DIR_OUTPUT) == 0) {
135                 if (strcmp(GPIO_PULL_DOWN, pull->valuestring) == 0)
136                     *config = OUTPUT_PUSH_PULL;
137                 else if (strcmp(GPIO_PULL_UP, pull->valuestring) == 0)
138                     *config = OUTPUT_OPEN_DRAIN_PULL_UP;
139                 else if (strcmp(GPIO_PULL_OPEN, pull->valuestring) == 0)
140                     *config = OUTPUT_OPEN_DRAIN_NO_PULL;
141             }
142             else if (strcmp(dir->valuestring, GPIO_DIR_IRQ) == 0) {
143                 *config = IRQ_MODE;
144 
145                 if (strcmp(GPIO_PULL_DOWN, pull->valuestring) == 0)
146                     *config = INPUT_PULL_DOWN;
147                 else if (strcmp(GPIO_PULL_UP, pull->valuestring) == 0)
148                     *config = INPUT_PULL_UP;
149                 else if (strcmp(GPIO_PULL_OPEN, pull->valuestring) == 0)
150                     *config = INPUT_HIGH_IMPEDANCE;
151 
152                 if (strcmp(GPIO_INT_RISING, intMode->valuestring) == 0)
153                     priv->irq_mode = IRQ_TRIGGER_RISING_EDGE;
154                 else if (strcmp(GPIO_INT_FALLING, intMode->valuestring) == 0)
155                     priv->irq_mode = IRQ_TRIGGER_FALLING_EDGE;
156                 else if (strcmp(GPIO_INT_BOTH, intMode->valuestring) == 0)
157                     priv->irq_mode = IRQ_TRIGGER_BOTH_EDGES;
158                 else if (strcmp(GPIO_INT_HIGH_LEVEL, intMode->valuestring) == 0)
159                     priv->irq_mode = IRQ_TRIGGER_LEVEL_HIGH;
160                 else if (strcmp(GPIO_INT_LOW_LEVEL, intMode->valuestring) == 0)
161                     priv->irq_mode = IRQ_TRIGGER_LEVEL_LOW;
162             }
163 
164             else if (strcmp(dir->valuestring, GPIO_DIR_ANALOG) == 0) {
165                 *config = ANALOG_MODE;
166             }
167         }
168         gpio_dev_t *new_gpio = aos_calloc(1, sizeof(*new_gpio));
169         if (NULL == new_gpio) {
170             continue;
171         }
172         device.port = port->valueint;
173         char *gpio_id = strdup(id);
174         memcpy(new_gpio, &device, sizeof(gpio_dev_t));
175         ret = board_add_new_item(MODULE_GPIO, gpio_id, new_gpio);
176         if (0 == ret) {
177             continue;
178         }
179         if (NULL != gpio_id) {
180             aos_free(gpio_id);
181             gpio_id = NULL;
182         }
183         if (NULL != new_gpio) {
184             aos_free(new_gpio);
185             new_gpio = NULL;
186             aos_free(priv);
187             priv = NULL;
188         }
189     }
190     return BOARD_ERR_NONE;
191 }
192 
board_set_uart_default(uart_dev_t * uart_device)193 static void board_set_uart_default(uart_dev_t *uart_device)
194 {
195     if (NULL == uart_device) {
196         return;
197     }
198     uart_device->port = 0;
199     uart_device->priv = NULL;
200     uart_device->config.baud_rate = 115200;
201     uart_device->config.data_width = DATA_WIDTH_8BIT;
202     uart_device->config.flow_control = FLOW_CONTROL_DISABLED;
203     uart_device->config.parity = NO_PARITY;
204     uart_device->config.stop_bits = STOP_BITS_1;
205     uart_device->config.mode = MODE_TX_RX;
206 }
207 
board_parse_uart(cJSON * uart,char * id)208 static int8_t board_parse_uart(cJSON *uart, char *id)
209 {
210     int index = 0;
211     int8_t ret = -1;
212     cJSON *port = NULL;
213     cJSON *item = NULL;
214     cJSON *temp = NULL;
215     uart_dev_t device;
216     uart_config_t *config = (uart_config_t *)&device.config;
217     int8_t size = 1;
218 
219     if (size <= 0) {
220         return BOARD_ERR_SIZE_INVALID;
221     }
222     while (index < size) {
223         item = uart;
224         index += 1;
225         if (NULL == item) {
226             continue;
227         }
228         port = cJSON_GetObjectItem(item, MARKER_PORT);
229         if (NULL == port || cJSON_Number != port->type) {
230             continue;
231         }
232         board_set_uart_default(&device);
233         temp = cJSON_GetObjectItem(item, UART_DATA_WIDTH);
234         if (NULL != temp && cJSON_Number == temp->type) {
235             int32_t width = temp->valueint;
236             switch (width) {
237             case 5:
238                 config->data_width = DATA_WIDTH_5BIT;
239                 break;
240             case 6:
241                 config->data_width = DATA_WIDTH_6BIT;
242                 break;
243             case 7:
244                 config->data_width = DATA_WIDTH_7BIT;
245                 break;
246             case 8:
247                 config->data_width = DATA_WIDTH_8BIT;
248                 break;
249 
250             default:
251                 break;
252             }
253         }
254         temp = cJSON_GetObjectItem(item, UART_BAUD_RATE);
255         if (NULL != temp && cJSON_Number == temp->type) {
256             config->baud_rate = temp->valueint;
257         }
258         temp = cJSON_GetObjectItem(item, UART_STOP_BITS);
259         if (NULL != temp && cJSON_Number == temp->type) {
260             int32_t stopbits = temp->valueint;
261             switch (stopbits) {
262             case 1:
263                 config->stop_bits = STOP_BITS_1;
264                 break;
265             case 2:
266                 config->stop_bits = STOP_BITS_2;
267 
268             default:
269                 break;
270             }
271         }
272         temp = cJSON_GetObjectItem(item, UART_FLOW_CONTROL);
273         if (NULL != temp && cJSON_String == temp->type) {
274             if (strcmp(temp->valuestring, UART_FC_DISABLE) == 0) {
275                 config->flow_control = FLOW_CONTROL_DISABLED;
276             }
277 
278             else if (strcmp(temp->valuestring, UART_FC_CTS) == 0) {
279                 config->flow_control = FLOW_CONTROL_CTS;
280             }
281 
282             else if (strcmp(temp->valuestring, UART_FC_RTS) == 0) {
283                 config->flow_control = FLOW_CONTROL_RTS;
284             }
285 
286             else if (strcmp(temp->valuestring, UART_FC_RTSCTS) == 0) {
287                 config->flow_control = FLOW_CONTROL_CTS_RTS;
288             }
289         }
290         temp = cJSON_GetObjectItem(item, UART_PARITY_CONFIG);
291         if (NULL != temp && cJSON_String == temp->type) {
292             if (strcmp(temp->valuestring, UART_PARITY_NONE) == 0) {
293                 config->parity = NO_PARITY;
294             }
295 
296             else if (strcmp(temp->valuestring, UART_PARITY_ODD) == 0) {
297                 config->parity = ODD_PARITY;
298             }
299 
300             else if (strcmp(temp->valuestring, UART_PARITY_EVEN) == 0) {
301                 config->parity = EVEN_PARITY;
302             }
303         }
304         uart_dev_t *new_uart = aos_calloc(1, sizeof(*new_uart));
305         if (NULL == new_uart) {
306             continue;
307         }
308         device.port = port->valueint;
309         char *uart_id = strdup(id);
310         *new_uart = device;
311         ret = board_add_new_item(MODULE_UART, uart_id, new_uart);
312         LOGD(LOG_TAG, "*** add item: %s", uart_id);
313         if (0 == ret) {
314             continue;
315         }
316         if (NULL != uart_id) {
317             aos_free(uart_id);
318             uart_id = NULL;
319         }
320         if (NULL != new_uart) {
321             aos_free(new_uart);
322             new_uart = NULL;
323         }
324     }
325 
326     return BOARD_ERR_NONE;
327 }
328 
board_set_i2c_default(i2c_dev_t * i2c_device)329 static void board_set_i2c_default(i2c_dev_t *i2c_device)
330 {
331     if (NULL == i2c_device) {
332         return;
333     }
334     i2c_device->port = 0;
335     i2c_device->priv = NULL;
336     i2c_device->config.address_width = 7;
337     i2c_device->config.freq = 100000;
338     i2c_device->config.mode = I2C_MODE_MASTER;
339     i2c_device->config.dev_addr = 0xFF;
340 }
341 
board_parse_i2c(cJSON * i2c,char * id)342 static int8_t board_parse_i2c(cJSON *i2c, char *id)
343 {
344     int index = 0;
345     int8_t ret = -1;
346     cJSON *port = NULL;
347     cJSON *item = NULL;
348     cJSON *temp = NULL;
349     uint32_t timeout;
350     i2c_dev_t device;
351     i2c_config_t *config = (i2c_config_t *)&device.config;
352     int8_t size = 1;
353 
354     if (size <= 0) {
355         return BOARD_ERR_SIZE_INVALID;
356     }
357     while (index < size) {
358         item = i2c;
359         index += 1;
360         if (NULL == item) {
361             continue;
362         }
363         port = cJSON_GetObjectItem(item, MARKER_PORT);
364         if (NULL == port || cJSON_Number != port->type) {
365             continue;
366         }
367         board_set_i2c_default(&device);
368 
369         temp = cJSON_GetObjectItem(item, I2C_ADDR_WIDTH);
370         if (NULL != temp && cJSON_Number == temp->type) {
371             switch (temp->valueint) {
372             case 7:
373                 config->address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
374                 break;
375             case 10:
376                 config->address_width = I2C_HAL_ADDRESS_WIDTH_10BIT;
377                 break;
378 
379             default:
380                 break;
381             }
382         }
383         temp = cJSON_GetObjectItem(item, I2C_FREQ);
384         if (NULL != temp && cJSON_Number == temp->type) {
385             config->freq = temp->valueint;
386         }
387         temp = cJSON_GetObjectItem(item, I2C_MODE);
388         if (NULL != temp && cJSON_String == temp->type) {
389             if (strcmp(temp->valuestring, I2C_MASTER) == 0) {
390                 config->mode = I2C_MODE_MASTER;
391             } else if (strcmp(temp->valuestring, I2C_SLAVE) == 0) {
392                 config->mode = I2C_MODE_SLAVE;
393             }
394         }
395         temp = cJSON_GetObjectItem(item, I2C_TIMEOUT);
396         if (NULL != temp && cJSON_Number == temp->type) {
397             timeout = temp->valueint;
398         }
399         temp = cJSON_GetObjectItem(item, I2C_ADDR_DEV);
400         if (NULL != temp && cJSON_Number == temp->type) {
401             config->dev_addr = temp->valueint;
402         }
403 
404         i2c_dev_t *new_i2c = aos_calloc(1, sizeof(*new_i2c));
405         if (NULL == new_i2c) {
406             continue;
407         }
408         device.port = port->valueint;
409         char *i2c_id = strdup(id);
410         *new_i2c = device;
411         ret = board_add_new_item(MODULE_I2C, i2c_id, new_i2c);
412         if (0 == ret) {
413             continue;
414         }
415         if (NULL != i2c_id) {
416             aos_free(i2c_id);
417             i2c_id = NULL;
418         }
419         if (NULL != new_i2c) {
420             aos_free(new_i2c);
421             new_i2c = NULL;
422         }
423     }
424 
425     return BOARD_ERR_NONE;
426 }
427 
board_set_spi_default(spi_dev_t * spi_device)428 static void board_set_spi_default(spi_dev_t *spi_device)
429 {
430     if (NULL == spi_device) {
431         return;
432     }
433     spi_device->port = 0;
434     spi_device->priv = NULL;
435     spi_device->config.data_size = SPI_DATA_SIZE_8BIT;
436     spi_device->config.mode = SPI_WORK_MODE_3;
437     spi_device->config.cs = SPI_CS_DIS;
438     spi_device->config.role = SPI_ROLE_MASTER;
439     spi_device->config.serial_len = 0;
440     spi_device->config.firstbit = SPI_FIRSTBIT_MSB;
441     spi_device->config.t_mode = SPI_TRANSFER_NORMAL;
442     spi_device->config.freq = 2000000;
443 }
444 
board_parse_spi(cJSON * spi,char * id)445 static int8_t board_parse_spi(cJSON *spi, char *id)
446 {
447     int index = 0;
448     int8_t ret = -1;
449     cJSON *port = NULL;
450     cJSON *item = NULL;
451     cJSON *temp = NULL;
452     spi_dev_t device;
453     spi_config_t *config = (spi_config_t *)&device.config;
454     int8_t size = 1;
455 
456     if (size <= 0) {
457         return BOARD_ERR_SIZE_INVALID;
458     }
459     while (index < size) {
460         item = spi;
461         index += 1;
462         if (NULL == item) {
463             continue;
464         }
465         port = cJSON_GetObjectItem(item, MARKER_PORT);
466         if (NULL == port || cJSON_Number != port->type) {
467             continue;
468         }
469         board_set_spi_default(&device);
470 
471         temp = cJSON_GetObjectItem(item, SPI_MODE);
472         if (NULL != temp && cJSON_String == temp->type) {
473             if (strcmp(temp->valuestring, SPI_MODE_MASTER) == 0) {
474                 config->role = HAL_SPI_MODE_MASTER;
475             }
476 
477             else if (strcmp(temp->valuestring, SPI_MODE_SLAVE) == 0) {
478                 config->role = HAL_SPI_MODE_SLAVE;
479             }
480         }
481 
482         temp = cJSON_GetObjectItem(item, SPI_FREQ);
483         if (NULL != temp && cJSON_Number == temp->type) {
484             config->freq = temp->valueint;
485         }
486 
487         temp = cJSON_GetObjectItem(item, SPI_CPOL_CPHA);
488         if (NULL != temp && cJSON_Number == temp->type) {
489             config->mode = temp->valueint;
490         }
491 
492         spi_dev_t *new_spi = aos_calloc(1, sizeof(*new_spi));
493         if (NULL == new_spi) {
494             continue;
495         }
496         device.port = port->valueint;
497         char *spi_id = strdup(id);
498         *new_spi = device;
499         ret = board_add_new_item(MODULE_SPI, spi_id, new_spi);
500         if (0 == ret) {
501             continue;
502         }
503         if (NULL != spi_id) {
504             aos_free(spi_id);
505             spi_id = NULL;
506         }
507         if (NULL != new_spi) {
508             aos_free(new_spi);
509             new_spi = NULL;
510         }
511     }
512 
513     return BOARD_ERR_NONE;
514 }
515 
board_set_pwm_default(pwm_dev_t * pwm_device)516 static void board_set_pwm_default(pwm_dev_t *pwm_device)
517 {
518     if (NULL == pwm_device) {
519         return;
520     }
521     pwm_device->port = 0;
522     pwm_device->priv = NULL;
523     pwm_device->config.freq = 1;
524     pwm_device->config.duty_cycle = 100;
525 }
526 
board_parse_pwm(cJSON * pwm,char * id)527 static int8_t board_parse_pwm(cJSON *pwm, char *id)
528 {
529     int index = 0;
530     int8_t ret = -1;
531     cJSON *port = NULL;
532     cJSON *item = NULL;
533     cJSON *temp = NULL;
534     pwm_dev_t device;
535     pwm_config_t *config = (pwm_config_t *)&device.config;
536     int8_t size = 1;
537 
538     if (size <= 0) {
539         return BOARD_ERR_SIZE_INVALID;
540     }
541     while (index < size) {
542         item = pwm;
543         index += 1;
544         if (NULL == item) {
545             continue;
546         }
547         port = cJSON_GetObjectItem(item, MARKER_PORT);
548         if (NULL == port || cJSON_Number != port->type) {
549             continue;
550         }
551         board_set_pwm_default(&device);
552         pwm_dev_t *new_pwm = aos_calloc(1, sizeof(*new_pwm));
553         if (NULL == new_pwm) {
554             continue;
555         }
556         device.port = port->valueint;
557         char *pwm_id = strdup(id);
558         *new_pwm = device;
559         ret = board_add_new_item(MODULE_PWM, pwm_id, new_pwm);
560         if (0 == ret) {
561             continue;
562         }
563 
564         if (NULL != pwm_id) {
565             aos_free(pwm_id);
566             pwm_id = NULL;
567         }
568         if (NULL != new_pwm) {
569             aos_free(new_pwm);
570             new_pwm = NULL;
571         }
572     }
573 
574     return BOARD_ERR_NONE;
575 }
576 
board_set_adc_default(adc_dev_t * adc_device)577 static void board_set_adc_default(adc_dev_t *adc_device)
578 {
579     if (NULL == adc_device) {
580         return;
581     }
582     adc_device->port = 0;
583     adc_device->priv = NULL;
584     adc_device->config.sampling_cycle = 12000000;
585 }
586 
board_parse_adc(cJSON * adc,char * id)587 static int8_t board_parse_adc(cJSON *adc, char *id)
588 {
589     int index = 0;
590     int8_t ret = -1;
591     cJSON *port = NULL;
592     cJSON *item = NULL;
593     cJSON *temp = NULL;
594     adc_dev_t device;
595     adc_config_t *config = (adc_config_t *)&device.config;
596     int8_t size = 1;
597 
598     if (size <= 0) {
599         return BOARD_ERR_SIZE_INVALID;
600     }
601     while (index < size) {
602         item = adc;
603         index += 1;
604         if (NULL == item) {
605             continue;
606         }
607         port = cJSON_GetObjectItem(item, MARKER_PORT);
608         if (NULL == port || cJSON_Number != port->type) {
609             continue;
610         }
611         board_set_adc_default(&device);
612 
613         temp = cJSON_GetObjectItem(item, ADC_SAMPLING);
614         if (NULL != temp && cJSON_Number == temp->type) {
615             config->sampling_cycle = temp->valueint;
616         }
617 
618         adc_dev_t *new_adc = aos_calloc(1, sizeof(*new_adc));
619         if (NULL == new_adc) {
620             continue;
621         }
622         device.port = port->valueint;
623         char *adc_id = strdup(id);
624         *new_adc = device;
625         ret = board_add_new_item(MODULE_ADC, adc_id, new_adc);
626         if (0 == ret) {
627             continue;
628         }
629 
630         if (NULL != adc_id) {
631             aos_free(adc_id);
632             adc_id = NULL;
633         }
634         if (NULL != new_adc) {
635             aos_free(new_adc);
636             new_adc = NULL;
637         }
638     }
639 
640     return BOARD_ERR_NONE;
641 }
642 
board_get_json_buff(const char * json_path)643 char *board_get_json_buff(const char *json_path)
644 {
645     void *json_data = NULL;
646     int len = 0;
647     int32_t curpos = -1;
648     int json_fd = -1;
649 
650     if (NULL == json_path) {
651         LOGE(LOG_TAG, "json_path NULL\n");
652         return (NULL);
653     }
654 
655     json_fd = aos_open(json_path, O_RDONLY);
656     if (json_fd < 0) {
657         LOGE(LOG_TAG, "failed to open json file:%s\n", json_path);
658         return (NULL);
659     }
660 
661     len = aos_lseek(json_fd, 0, SEEK_END);
662     if (len < 0) {
663         LOGE(LOG_TAG, "failed to seek file\n");
664         return (NULL);
665     }
666 
667     json_data = aos_calloc(1, sizeof(char) * (len + 1));
668     if (NULL == json_data) {
669         aos_close(json_fd);
670         LOGE(LOG_TAG, "failed to calloc data for json_data\n");
671         return (NULL);
672     }
673     aos_lseek(json_fd, 0, SEEK_SET);
674     aos_read(json_fd, json_data, len);
675     aos_close(json_fd);
676     return json_data;
677 }
678 
679 static parse_json_t g_parse_json[] = {
680     { MARKER_UART, MODULE_UART, board_parse_uart },
681 
682     { MARKER_GPIO, MODULE_GPIO, board_parse_gpio },
683 
684     { MARKER_PWM, MODULE_PWM, board_parse_pwm },
685 
686     { MARKER_I2C, MODULE_I2C, board_parse_i2c },
687 
688     { MARKER_SPI, MODULE_SPI, board_parse_spi },
689 
690     { MARKER_ADC, MODULE_ADC, board_parse_adc },
691 
692     { NULL, MODULE_NUMS, NULL },
693 };
694 
board_parse_json_buff(const char * json_buff)695 static int32_t board_parse_json_buff(const char *json_buff)
696 {
697     cJSON *root = NULL;
698     cJSON *page = NULL, *pages = NULL;
699     cJSON *io = NULL;
700     cJSON *debug = NULL;
701     cJSON *repl = NULL;
702     cJSON *item = NULL;
703     cJSON *child = NULL;
704     parse_json_t *parser_handle = NULL;
705 
706     if (NULL == json_buff) {
707         LOGE(LOG_TAG, "json_buff NULL\n");
708         return BOARD_ERR_INVALID_ARG;
709     }
710     root = cJSON_Parse(json_buff);
711     if (NULL == root) {
712         LOGE(LOG_TAG, "json parse fail\n");
713         return BOARD_ERR_JSON_PARSE;
714     }
715 
716     /* debugLevel configuration */
717     if ((debug = cJSON_GetObjectItem(root, APP_CONFIG_DEBUG)) != NULL) {
718         /* parsing debugLevel configuration */
719         if (!cJSON_IsString(debug)) {
720             LOGE(LOG_TAG, "debugLevel not string");
721             goto parse_end;
722         }
723 
724         LOGD(LOG_TAG, "get debugLevel:%s\n", debug->valuestring);
725         if (strcmp(debug->valuestring, "DEBUG") == 0) {
726             aos_set_log_level(LOG_DEBUG);
727         } else if (strcmp(debug->valuestring, "INFO") == 0) {
728             aos_set_log_level(LOG_INFO);
729         } else if (strcmp(debug->valuestring, "WARN") == 0) {
730             aos_set_log_level(LOG_WARNING);
731         } else if (strcmp(debug->valuestring, "ERROR") == 0) {
732             aos_set_log_level(LOG_ERR);
733         } else if (strcmp(debug->valuestring, "FATAL") == 0) {
734             aos_set_log_level(LOG_CRIT);
735         } else {
736             LOGD(LOG_TAG, "debugLevel error, set to default: 'ERROR'");
737             aos_set_log_level(LOG_ERR);
738         }
739     } else {
740         LOGD(LOG_TAG, "No debugLevel configuration in app.json, set to default: 'ERROR'");
741     }
742 
743     /* page configuration */
744     if ((pages = cJSON_GetObjectItem(root, APP_CONFIG_PAGES)) != NULL) {
745         /* parsing io configuration */
746         if (!cJSON_IsArray(pages)) {
747             LOGE(LOG_TAG, "Pages entries need array");
748             goto parse_end;
749         }
750 
751         dlist_init(&g_pages_list);
752         cJSON_ArrayForEach(page, pages)
753         {
754             if (!cJSON_IsString(page)) {
755                 LOGE(LOG_TAG, "page not string");
756                 goto parse_end;
757             }
758 
759             LOGD(LOG_TAG, "get page:%s", page->valuestring);
760 
761             /* add page to dlink */
762             page_entry_t *page_entry = aos_malloc(sizeof(page_entry_t));
763             page_entry->page = strdup(page->valuestring); /* don't forget to free */
764             dlist_add_tail(&page_entry->node, &g_pages_list);
765         }
766     } else {
767         LOGD(LOG_TAG, "No pages configuration in app.json");
768     }
769 
770     /* repl configuration */
771     if ((repl = cJSON_GetObjectItem(root, APP_CONFIG_REPL)) != NULL) {
772         /* parsing debugLevel configuration */
773         if (!cJSON_IsString(repl)) {
774             LOGE(LOG_TAG, "repl not string");
775             goto parse_end;
776         }
777 
778         LOGD(LOG_TAG, "get app repl config is:%s", repl->valuestring);
779         if (strcmp(repl->valuestring, "disable") == 0) {
780             py_repl_config = 0;
781         } else if (strcmp(repl->valuestring, "enable") == 0) {
782             py_repl_config = 1;
783         } else {
784             LOGD(LOG_TAG, "repl configuration is wrong, set to default: 'enable'");
785             py_repl_config = 1;
786         }
787     } else {
788         LOGD(LOG_TAG, "No repl configuration in app.json, set to default: 'enable'");
789     }
790 
791     /* net configuration */
792     /* TODO */
793 
794     /* io configuration */
795     if ((io = cJSON_GetObjectItem(root, APP_CONFIG_IO)) != NULL) {
796         /* parsing io configuration */
797         child = io->child;
798         while (NULL != child) {
799             item = cJSON_GetObjectItem(child, MARKER_ID);
800             if (NULL == item || cJSON_String != item->type) {
801                 child = child->next;
802                 continue;
803             }
804             parser_handle = &g_parse_json[0];
805             while (NULL != parser_handle->marker_name) {
806                 if (0 == strcmp(item->valuestring, parser_handle->marker_name)) {
807                     parser_handle->fn(child, child->string);
808                 }
809                 parser_handle += 1;
810             }
811             child = child->next;
812         }
813     } else {
814         LOGE(LOG_TAG, "No io configuration in app.json");
815     }
816 
817     cJSON_Delete(root);
818     return BOARD_ERR_NONE;
819 
820 parse_end:
821     cJSON_Delete(root);
822     return BOARD_ERR_JSON_PARSE;
823 }
824 
board_get_items(addon_module_m module,item_handle_t * handle,const char * name_id)825 static void *board_get_items(addon_module_m module, item_handle_t *handle, const char *name_id)
826 {
827     board_mgr_t *mgr_handle = board_get_handle();
828     board_item_t *item = NULL;
829     if (NULL == handle && NULL == name_id) {
830         LOGE(LOG_TAG, "handle or name_id null\n");
831         return (NULL);
832     }
833     uint32_t i = 0;
834     for (i = 0; i < mgr_handle->item_size; ++i) {
835         item = mgr_handle->item[i];
836         if (module != item->module) {
837             continue;
838         }
839         if (NULL != handle && item->handle.handle != handle->handle) {
840             continue;
841         }
842         if (NULL != name_id && 0 != strcmp(item->name_id, name_id)) {
843             continue;
844         }
845         return (item);
846     }
847 
848     return (NULL);
849 }
850 
board_add_new_item(addon_module_m module,char * name_id,void * node)851 static int8_t board_add_new_item(addon_module_m module, char *name_id, void *node)
852 {
853     board_item_t *item = NULL;
854     board_mgr_t *mgr_handle = board_get_handle();
855     if (NULL == name_id || NULL == node) {
856         return BOARD_ERR_INVALID_ARG;
857     }
858     if (NULL != board_get_items(module, NULL, name_id)) {
859         LOGE(LOG_TAG, "board_get_items failed, name_id = %s\n", name_id);
860         return BOARD_ERR_NODE_NOT_EXIST;
861     }
862     board_item_t *new_item = aos_calloc(1, sizeof(*new_item));
863     if (NULL == new_item) {
864         return BOARD_ERR_NO_MEM;
865     }
866     void *addr = aos_realloc(mgr_handle->item, sizeof(board_item_t *) * (mgr_handle->item_size + 1));
867     if (NULL == addr) {
868         goto out;
869     }
870 
871     new_item->module = module;
872     new_item->name_id = name_id;
873     new_item->handle.handle = (void *)new_item;
874     new_item->node = node;
875     new_item->status = 0;
876     mgr_handle->item = addr;
877     mgr_handle->item[mgr_handle->item_size] = new_item;
878     mgr_handle->item_size += 1;
879 
880     return BOARD_ERR_NONE;
881 out:
882     if (NULL != new_item) {
883         aos_free(new_item);
884         new_item = NULL;
885     }
886     return BOARD_ERR_NO_MEM;
887 }
888 
py_board_attach_item(addon_module_m module,const char * name_id,item_handle_t * out)889 int8_t py_board_attach_item(addon_module_m module, const char *name_id, item_handle_t *out)
890 {
891     board_item_t *item = NULL;
892     if (NULL == name_id) {
893         return BOARD_ERR_INVALID_ARG;
894     }
895     item = board_get_items(module, NULL, name_id);
896     if (NULL == item || 1 == item->status) {
897         LOGE(LOG_TAG, "board_get_items failed, name_id = %s\n", name_id);
898         return BOARD_ERR_NODE_NOT_EXIST;
899     }
900     item->status = 1;
901     *out = item->handle;
902 
903     return BOARD_ERR_NONE;
904 }
905 
py_board_disattach_item(addon_module_m module,item_handle_t * handle)906 int8_t py_board_disattach_item(addon_module_m module, item_handle_t *handle)
907 {
908     board_item_t *item = NULL;
909     if (NULL == handle) {
910         return BOARD_ERR_INVALID_ARG;
911     }
912     item = board_get_items(module, handle, NULL);
913     if (NULL == item) {
914         return BOARD_ERR_NODE_NOT_EXIST;
915     }
916     item->status = 0;
917 
918     return BOARD_ERR_NONE;
919 }
920 
py_board_check_attach_status(addon_module_m module,item_handle_t * handle)921 int8_t py_board_check_attach_status(addon_module_m module, item_handle_t *handle)
922 {
923     board_item_t *item = NULL;
924     if (NULL == handle) {
925         return BOARD_ERR_NONE;
926     }
927     item = board_get_items(module, handle, NULL);
928     if (NULL == item) {
929         return BOARD_ERR_NONE;
930     }
931 
932     return item->status;
933 }
934 
py_board_get_node_by_name(addon_module_m module,const char * name_id)935 void *py_board_get_node_by_name(addon_module_m module, const char *name_id)
936 {
937     board_item_t *item = NULL;
938     if (NULL == name_id) {
939         return NULL;
940     }
941     item = board_get_items(module, NULL, name_id);
942     if (NULL == item || 0 == item->status) {
943         LOGE(LOG_TAG, "board_get_items failed, name_id = %s\n", name_id);
944         return NULL;
945     }
946 
947     return item->node;
948 }
949 
py_board_get_node_by_handle(addon_module_m module,item_handle_t * handle)950 void *py_board_get_node_by_handle(addon_module_m module, item_handle_t *handle)
951 {
952     board_item_t *item = NULL;
953     if (NULL == handle)
954         return NULL;
955     item = board_get_items(module, handle, NULL);
956     if (NULL == item || 0 == item->status) {
957         return NULL;
958     }
959 
960     return item->node;
961 }
962 
963 static bool board_init_flag = false;
py_board_mgr_init()964 int32_t py_board_mgr_init()
965 {
966     int32_t ret = -1;
967     char *json = NULL;
968     int json_fd = -1;
969     char *board_json_path = NULL;
970     char *sdcard_root_path = AMP_FS_EXT_ROOT_DIR "/board.json";
971     char *data_root_path = AMP_FS_ROOT_DIR "/board.json";
972     char *sdcard_board_json_path = MP_FS_EXT_ROOT_DIR "/python-apps/driver/board.json";
973     char *data_board_json_path = MP_FS_ROOT_DIR "/python-apps/driver/board.json";
974 
975     if (board_init_flag != false) {
976         LOGD(LOG_TAG, "board config haas been loaded\n");
977         return BOARD_ERR_NONE;
978     }
979 
980     memset(&g_board_mgr, 0x00, sizeof(g_board_mgr));
981     json_fd = aos_open(sdcard_root_path, O_RDONLY);
982     if (json_fd >= 0) {
983         aos_close(json_fd);
984         board_json_path = sdcard_root_path;
985     }
986 
987     if (board_json_path == NULL) {
988         json_fd = aos_open(data_root_path, O_RDONLY);
989         if (json_fd >= 0) {
990             aos_close(json_fd);
991             board_json_path = data_root_path;
992         }
993     }
994 
995     if (board_json_path == NULL) {
996         json_fd = aos_open(sdcard_board_json_path, O_RDONLY);
997         if (json_fd >= 0) {
998             aos_close(json_fd);
999             board_json_path = sdcard_board_json_path;
1000         }
1001     }
1002 
1003     if (board_json_path == NULL) {
1004         board_json_path = data_board_json_path;
1005     }
1006 
1007     LOGD(LOG_TAG, "board_json_path = %s;\n", board_json_path);
1008     json = board_get_json_buff(board_json_path);
1009 
1010     if (NULL == json) {
1011         LOGD(LOG_TAG, "default board config is null");
1012         return ret;
1013     }
1014     // return BOARD_ERR_NONE;
1015     ret = board_parse_json_buff(json);
1016     aos_free(json);
1017     json = NULL;
1018 
1019     if (0 == ret) {
1020         board_init_flag = true;
1021     }
1022     return ret;
1023 }
1024