1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include "aos/kernel.h"
6 #include "aos/vfs.h"
7 #include "aos_system.h"
8 #include "aos_fs.h"
9 #include "amp_platform.h"
10 #include "amp_config.h"
11 #include "amp_task.h"
12 #include "amp_defines.h"
13 #include "board_mgr.h"
14 #include "cJSON.h"
15 
16 #define MOD_STR "AMP_ENGINE"
17 #define APP_PACKAGE_FILE_NAME JSE_FS_ROOT_DIR "/package.json"
18 #define MAX_FILE_NAME_LEN 127
19 static char js_app_file_name[128];
20 
21 static int32_t g_console_log_enable = 1;
22 
23 aos_sem_t jse_task_exit_sem;
24 
25 extern void jsengine_init(void);
26 extern void jsengine_eval_file(const char *filename);
27 
bone_console_get_log_flag(void)28 int32_t bone_console_get_log_flag(void)
29 {
30     return g_console_log_enable;
31 }
bone_console_log_enable(void)32 void bone_console_log_enable(void)
33 {
34     g_console_log_enable = 1;
35 }
36 
bone_console_log_disable(void)37 void bone_console_log_disable(void)
38 {
39     g_console_log_enable = 0;
40 }
41 
42 /**
43  * 1. search js entry: /spiffs/index.js in spiffs
44  * 2. get [test] or [main] in /spiffs/package.json
45  */
search_js_app_main_entry(void)46 char *search_js_app_main_entry(void)
47 {
48     cJSON *root     = NULL;
49     cJSON *item     = NULL;
50     void *json_data = NULL;
51 
52     int js_app_fd = -1;
53     int file_len  = 0;
54     int json_fd   = -1;
55 
56     snprintf(js_app_file_name, 128, AMP_APP_MAIN_JS);
57 
58     /* use the currrent dir default index.js file to the main js entry programe
59      */
60     if ((js_app_fd = aos_open(js_app_file_name, O_RDONLY)) >= 0) {
61         aos_close(js_app_fd);
62         amp_debug(MOD_STR, "find the default file :%s", js_app_file_name);
63         return js_app_file_name;
64     }
65 
66     snprintf(js_app_file_name, 128, AMP_APP_MAIN_JSB);
67 
68     /* use the currrent dir default index.js file to the main js entry programe
69      */
70     if ((js_app_fd = aos_open(js_app_file_name, O_RDONLY)) >= 0) {
71         aos_close(js_app_fd);
72         amp_debug(MOD_STR, "find the default file :%s", js_app_file_name);
73         return js_app_file_name;
74     }
75 
76     snprintf(js_app_file_name, 128, AMP_APP_PACKAGE_JSON);
77     /* cannot find the index.js int current dir */
78     if ((json_fd = aos_open(js_app_file_name, O_RDONLY)) < 0) {
79         amp_error(MOD_STR, "cannot find the file :%s", js_app_file_name);
80         return NULL;
81     }
82 
83     /* read package config file to json_data buffer */
84     file_len = aos_lseek(json_fd, 0, SEEK_END);
85     json_data = amp_calloc(1, sizeof(char) * (file_len + 1));
86     if (NULL == json_data) {
87         aos_close(json_fd);
88         json_fd = -1;
89         return NULL;
90     }
91     aos_lseek(json_fd, 0, SEEK_SET);
92     aos_read(json_fd, json_data, file_len);
93     aos_close(json_fd);
94 
95     /* parser the package json data */
96     root = cJSON_Parse(json_data);
97     if (NULL == root) {
98         amp_free(json_data);
99         amp_error(MOD_STR, "cJSON_Parse failed");
100         return NULL;
101     }
102 
103     /* find the test/xxx.js */
104     item = cJSON_GetObjectItem(root, "test");
105     if (NULL != item && cJSON_String == item->type &&
106         strstr(item->valuestring, ".js")) {
107         snprintf(js_app_file_name, sizeof(js_app_file_name), "/%s", item->valuestring);
108         if ((js_app_fd = aos_open(js_app_file_name, O_RDONLY)) < 0) {
109             aos_close(js_app_fd);
110             amp_free(json_data);
111             cJSON_Delete(root);
112             amp_debug(MOD_STR, "find test index %s", js_app_file_name);
113             return js_app_file_name;
114         }
115     }
116 
117     /* find the main/xxx.js */
118     item = cJSON_GetObjectItem(root, "main");
119     if (NULL != item && cJSON_String == item->type &&
120         strstr(item->valuestring, ".js")) {
121         strncpy(js_app_file_name, item->valuestring, MAX_FILE_NAME_LEN);
122         amp_free(json_data);
123         cJSON_Delete(root);
124         amp_debug(MOD_STR, "find main index %s", js_app_file_name);
125         return js_app_file_name;
126     }
127 
128     amp_free(json_data);
129     cJSON_Delete(root);
130 
131     return NULL;
132 }
133 
be_jse_task_main_entrance(void * arg)134 void be_jse_task_main_entrance(void *arg)
135 {
136     amp_debug(MOD_STR, "jse main task start...");
137     amp_task_main();
138 
139     aos_task_exit(0);
140 
141     return;
142 }
143 
amp_task_main()144 void amp_task_main()
145 {
146     uint8_t ssdp_started = 0;
147     int app_running = 1;
148     char user_dir[128] = {0};
149 
150     snprintf(user_dir, sizeof(user_dir), AMP_APP_MAIN_JSON);
151     if (0 != board_mgr_init(user_dir)) {
152         amp_error(MOD_STR, "read %s error", user_dir);
153         app_running = 0;
154     }
155 
156     /* JSE task init */
157     amp_task_init();
158 
159     /* JSE init */
160     jsengine_init();
161     amp_debug(MOD_STR, "jsengine_init ok");
162 
163 #ifndef HAASUI_AMP_BUILD
164     /* run the js application */
165     char *filename = search_js_app_main_entry();
166     amp_debug(MOD_STR, "search_js_app_main_entry: %s", filename ? filename : "null");
167     if (filename && app_running) {
168         jsengine_eval_file(filename);
169     } else {
170         amp_error(MOD_STR, "Won't run app.js");
171     }
172 
173     while (1) {
174         /* loop for asynchronous operation */
175         jsengine_loop_once();
176         if(amp_task_yield(200) == 1) {
177             amp_debug(MOD_STR, "jsengine task yield exit!");
178             break;
179         }
180     }
181 
182     amp_task_deinit();
183     aos_sem_signal(&jse_task_exit_sem);
184     amp_memmgt_mem_show_rec();
185 #endif
186 }
187 
jsengine_main(void)188 void jsengine_main(void)
189 {
190     int ret = 0;
191     aos_task_t jsengine_task;
192 
193     amp_debug(MOD_STR, "jsengine start...");
194     if (aos_sem_new(&jse_task_exit_sem, 0) != 0) {
195         amp_error(MOD_STR, "create jse exit sem failed");
196         return;
197     }
198 
199 #ifndef HAASUI_AMP_BUILD
200     amp_debug(MOD_STR, "jse_task created");
201     aos_task_new_ext(&jsengine_task, "amp_jsengine_task", be_jse_task_main_entrance, NULL, JSENGINE_TASK_STACK_SIZE, AOS_DEFAULT_APP_PRI);
202 #else
203     amp_task_main();
204 #endif
205 }
206