1 /*
2  * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3  */
4 
5 #include <string.h>
6 #include <stdarg.h>
7 
8 #include "amp_config.h"
9 #include "aos_system.h"
10 #include "amp_defines.h"
11 #include "ota_agent.h"
12 #include "ota_import.h"
13 #include "module_aiot.h"
14 #include "app_upgrade.h"
15 #include "quickjs.h"
16 #include "quickjs_addon_common.h"
17 #include "amp_task.h"
18 
19 #define MOD_STR        "APP_OTA"
20 
21 static ota_service_t customer_ota_ctx = {0};
22 static ota_store_module_info_t customer_module_info[3];
23 static aos_task_t user_module_ota_task = NULL;
24 
25 typedef struct ota_package_info {
26     int res;
27     JSValue js_cb_ref;
28     unsigned int length;
29     char version[64];
30     char module_name[64];
31     int hash_type;
32     char hash[64];
33     char store_path[64];
34     char install_path[64];
35     char url[256];
36 } ota_package_info_t;
37 
38 static JSClassID js_appota_class_id;
39 
40 #ifndef countof
41 #define countof(x) (sizeof(x) / sizeof((x)[0]))
42 #endif
43 
ota_release_notify(void * pdata)44 static void ota_release_notify(void *pdata)
45 {
46     ota_package_info_t *ota_package_info = (ota_package_info_t *)pdata;
47     if (!ota_package_info) {
48         return;
49     }
50     JSContext *ctx = js_get_context();
51     if (ctx) {
52         JS_FreeValue(ctx, ota_package_info->js_cb_ref);
53     }
54     aos_free(ota_package_info);
55 }
56 
ota_install_notify(void * pdata)57 static void ota_install_notify(void *pdata)
58 {
59     ota_package_info_t *ota_package_info = (ota_package_info_t *)pdata;
60     if (!ota_package_info) {
61         amp_error(MOD_STR, "ota_package_info null!");
62         return;
63     }
64     JSContext *ctx = js_get_context();
65     if (!ctx) {
66         amp_error(MOD_STR, "JSContext null!");
67         return;
68     }
69 
70     JSValue ret = JS_NewInt32(ctx, ota_package_info->res);
71     JSValue v = JS_Call(ctx, ota_package_info->js_cb_ref, JS_UNDEFINED, 1, &ret);
72     if (JS_IsException(v)) {
73         amp_error(MOD_STR, "ota_install_notify callback error!");
74     }
75     JS_FreeValue(ctx, ret);
76     JS_FreeValue(ctx, v);
77 
78     JS_FreeValue(ctx, ota_package_info->js_cb_ref);
79     aos_free(ota_package_info);
80 }
81 
ota_install_handler(void * pdata)82 static void ota_install_handler(void *pdata)
83 {
84     amp_warn(MOD_STR, "ota_install_handler!");
85     int res = -1;
86     ota_package_info_t *ota_package_info = (ota_package_info_t *)pdata;
87     /* clear jsengine timer, distory js app*/
88     amp_module_free();
89     app_js_stop();
90 
91     res = ota_install_jsapp(&customer_ota_ctx, ota_package_info->store_path, ota_package_info->length, ota_package_info->install_path);
92     if (res < 0) {
93         amp_error(MOD_STR, "module install failed!");
94     } else {
95         /*启动app.js*/
96         res = ota_load_jsapp(&customer_ota_ctx);
97         if(res < 0) {
98             amp_error(MOD_STR, "module load failed!");
99         }
100     }
101 
102     ota_package_info->res = res;
103 
104     amp_task_schedule_call(ota_install_notify, ota_package_info);
105     aos_task_exit(0);
106 }
107 
native_ota_upgrade(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)108 static JSValue native_ota_upgrade(JSContext *ctx, JSValueConst this_val,
109                           int argc, JSValueConst *argv)
110 {
111     int res = -1;
112     aos_task_t ota_install_task;
113     ota_package_info_t *ota_package_info = NULL;
114 
115     if (argc < 2 || !JS_IsObject(argv[0]) || !JS_IsFunction(ctx, argv[1])) {
116         amp_warn(MOD_STR, "parameter must be (object and function)");
117         goto out;
118     }
119     ota_package_info = aos_malloc(sizeof(ota_package_info_t));
120     if (!ota_package_info) {
121         amp_error(MOD_STR, "alloc device notify param fail");
122         goto out;
123     }
124 
125     JSValue l = JS_GetPropertyStr(ctx, argv[0], "length");
126     JSValue sp = JS_GetPropertyStr(ctx, argv[0], "store_path");
127     JSValue ip = JS_GetPropertyStr(ctx, argv[0], "install_path");
128     unsigned int length = 0;
129     JS_ToUint32(ctx, &length, l);
130     const char* store_path = JS_ToCString(ctx, sp);
131     const char* install_path = JS_ToCString(ctx, ip);
132 
133     ota_package_info->length = length;
134     ota_package_info->js_cb_ref = JS_DupValue(ctx, argv[1]);
135     strncpy(ota_package_info->store_path, store_path, sizeof(ota_package_info->store_path));
136     strncpy(ota_package_info->install_path, install_path, sizeof(ota_package_info->install_path));
137 
138     res = aos_task_new_ext(&ota_install_task, "amp ota install task", ota_install_handler, ota_package_info, 1024 * 10, AOS_DEFAULT_APP_PRI);
139     if (res != 0) {
140         amp_warn(MOD_STR, "iot create task failed");
141         JS_FreeValue(ctx, ota_package_info->js_cb_ref);
142         aos_free(ota_package_info);
143     }
144 
145     JS_FreeValue(ctx, l);
146     JS_FreeValue(ctx, sp);
147     JS_FreeValue(ctx, ip);
148     JS_FreeCString(ctx, store_path);
149     JS_FreeCString(ctx, install_path);
150 out:
151     return JS_NewInt32(ctx, res);
152 }
153 
ota_verify_notify(void * pdata)154 static void ota_verify_notify(void *pdata)
155 {
156     ota_package_info_t *ota_package_info = (ota_package_info_t *)pdata;
157     if (!ota_package_info) {
158         amp_error(MOD_STR, "ota_package_info null!");
159         return;
160     }
161     JSContext *ctx = js_get_context();
162     if (!ctx) {
163         amp_error(MOD_STR, "JSContext null!");
164         return;
165     }
166 
167     JSValue ret = JS_NewInt32(ctx, ota_package_info->res);
168     JSValue v = JS_Call(ctx, ota_package_info->js_cb_ref, JS_UNDEFINED, 1, &ret);
169     if (JS_IsException(v)) {
170         amp_error(MOD_STR, "ota_verify_notify callback error!");
171     }
172     JS_FreeValue(ctx, ret);
173     JS_FreeValue(ctx, v);
174 
175     JS_FreeValue(ctx, ota_package_info->js_cb_ref);
176     aos_free(ota_package_info);
177 }
178 
ota_verify_handler(void * pdata)179 static void ota_verify_handler(void *pdata)
180 {
181     int res = -1;
182     ota_boot_param_t ota_param = {0};
183     ota_package_info_t *ota_package_info = (ota_package_info_t *)pdata;
184 
185     memset(&ota_param, 0, sizeof(ota_boot_param_t));
186 
187     ota_param.len = ota_package_info->length;
188     ota_param.hash_type = ota_package_info->hash_type;
189     strncpy(ota_param.hash, ota_package_info->hash, strlen(ota_package_info->hash));
190     res = ota_verify_fsfile(&ota_param, ota_package_info->store_path);
191     if (res < 0) {
192         amp_error(MOD_STR, "amp jsota report ver failed!");
193     }
194     ota_package_info->res = res;
195     amp_task_schedule_call(ota_verify_notify, ota_package_info);
196     aos_task_exit(0);
197 }
198 
native_ota_verify(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)199 static JSValue native_ota_verify(JSContext *ctx, JSValueConst this_val,
200                           int argc, JSValueConst *argv)
201 {
202     int res = -1;
203     aos_task_t ota_verify_task;
204     ota_package_info_t *ota_package_info = NULL;
205 
206     if (argc < 2 || !JS_IsObject(argv[0]) || !JS_IsFunction(ctx, argv[1])) {
207         amp_warn(MOD_STR, "parameter must be (object and function)");
208         goto out;
209     }
210     ota_package_info = aos_malloc(sizeof(ota_package_info_t));
211     if (!ota_package_info) {
212         amp_error(MOD_STR, "alloc device notify param fail");
213         goto out;
214     }
215 
216     JSValue l = JS_GetPropertyStr(ctx, argv[0], "length");
217     JSValue ht = JS_GetPropertyStr(ctx, argv[0], "hash_type");
218     JSValue h = JS_GetPropertyStr(ctx, argv[0], "hash");
219     JSValue sp = JS_GetPropertyStr(ctx, argv[0], "store_path");
220     unsigned int length = 0;
221     const char *hash_type_string = JS_ToCString(ctx, ht);
222     const char *hash = JS_ToCString(ctx, h);
223     const char *store_path = JS_ToCString(ctx, sp);
224     JS_ToUint32(ctx, &length, l);
225     ota_package_info->length = length;
226     if (strcmp(hash_type_string, "null") == 0) {
227         ota_package_info->hash_type = 0;
228     } else if(strcmp(hash_type_string, "md5") == 0) {
229         ota_package_info->hash_type = 2;
230     } else if(strcmp(hash_type_string, "sha256") == 0) {
231         ota_package_info->hash_type = 1;
232     } else {
233         ota_package_info->hash_type = 3;
234     }
235     ota_package_info->js_cb_ref = JS_DupValue(ctx, argv[1]);
236     strncpy(ota_package_info->hash, hash, sizeof(ota_package_info->hash));
237     strncpy(ota_package_info->store_path, store_path, sizeof(ota_package_info->store_path));
238 
239     res = aos_task_new_ext(&ota_verify_task, "amp ota verify task", ota_verify_handler, ota_package_info, 1024 * 10, AOS_DEFAULT_APP_PRI);
240     if (res != 0) {
241         amp_warn(MOD_STR, "iot create task failed");
242         JS_FreeValue(ctx, ota_package_info->js_cb_ref);
243         aos_free(ota_package_info);
244     }
245 
246     JS_FreeValue(ctx, l);
247     JS_FreeValue(ctx, ht);
248     JS_FreeValue(ctx, h);
249     JS_FreeValue(ctx, sp);
250     JS_FreeCString(ctx, hash);
251     JS_FreeCString(ctx, store_path);
252     JS_FreeCString(ctx, hash_type_string);
253 
254 out:
255     return JS_NewInt32(ctx, res);
256 }
257 
ota_download_notify(void * pdata)258 static void ota_download_notify(void *pdata)
259 {
260     ota_package_info_t *ota_package_info = (ota_package_info_t *)pdata;
261     if (!ota_package_info) {
262         amp_error(MOD_STR, "ota_package_info null!");
263         return;
264     }
265     JSContext *ctx = js_get_context();
266     if (!ctx) {
267         amp_error(MOD_STR, "JSContext null!");
268         return;
269     }
270 
271     JSValue ret = JS_NewInt32(ctx, ota_package_info->res);
272     JSValue v = JS_Call(ctx, ota_package_info->js_cb_ref, JS_UNDEFINED, 1, &ret);
273     if (JS_IsException(v)) {
274         amp_error(MOD_STR, "ota_download_notify callback error!");
275     }
276     JS_FreeValue(ctx, ret);
277     JS_FreeValue(ctx, v);
278 
279     JS_FreeValue(ctx, ota_package_info->js_cb_ref);
280     aos_free(ota_package_info);
281 }
282 
ota_download_handler(void * pdata)283 static void ota_download_handler(void *pdata)
284 {
285     int res = -1;
286     int js_cb_ref;
287     ota_package_info_t *ota_package_info = (ota_package_info_t *)pdata;
288 
289     res = ota_download_store_fs_start(ota_package_info->url, strlen(ota_package_info->url), ota_package_info->store_path,
290                                       customer_ota_ctx.report_func.report_status_cb, customer_ota_ctx.report_func.param);
291     if (res < 0) {
292         amp_error(MOD_STR, "amp jsota report ver failed!");
293     }
294 
295     ota_package_info->res = res;
296 
297     amp_task_schedule_call(ota_download_notify, ota_package_info);
298     aos_task_exit(0);
299 }
300 
native_ota_download(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)301 static JSValue native_ota_download(JSContext *ctx, JSValueConst this_val,
302                           int argc, JSValueConst *argv)
303 {
304     int res = -1;
305     aos_task_t ota_download_task;
306     ota_package_info_t *ota_package_info = NULL;
307 
308     if (argc < 2 || !JS_IsObject(argv[0]) || !JS_IsFunction(ctx, argv[1])) {
309         amp_warn(MOD_STR, "parameter must be (object and function)");
310         goto out;
311     }
312     ota_package_info = aos_malloc(sizeof(ota_package_info_t));
313     if (!ota_package_info) {
314         amp_error(MOD_STR, "alloc device notify param fail");
315         goto out;
316     }
317 
318     /* get report info */
319     JSValue u = JS_GetPropertyStr(ctx, argv[0], "url");
320     JSValue sp = JS_GetPropertyStr(ctx, argv[0], "store_path");
321     const char* url = JS_ToCString(ctx, u);
322     const char* store_path = JS_ToCString(ctx, sp);
323     ota_package_info->js_cb_ref = JS_DupValue(ctx, argv[1]);
324     strncpy(ota_package_info->url, url, sizeof(ota_package_info->url));
325     strncpy(ota_package_info->store_path, store_path, sizeof(ota_package_info->store_path));
326 
327     res = aos_task_new_ext(&ota_download_task, "amp ota download task", ota_download_handler, ota_package_info, 1024 * 10, AOS_DEFAULT_APP_PRI);
328     if (res != 0) {
329         amp_warn(MOD_STR, "iot create task failed");
330         JS_FreeValue(ctx, ota_package_info->js_cb_ref);
331         aos_free(ota_package_info);
332     }
333 
334     JS_FreeValue(ctx, u);
335     JS_FreeValue(ctx, sp);
336     JS_FreeCString(ctx, url);
337     JS_FreeCString(ctx, store_path);
338 out:
339     return JS_NewInt32(ctx, res);
340 }
341 
native_ota_report(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)342 static JSValue native_ota_report(JSContext *ctx, JSValueConst this_val,
343                           int argc, JSValueConst *argv)
344 {
345     int res = -1;
346     iot_device_handle_t* dev_handle = NULL;
347     if (argc < 1 || !JS_IsObject(argv[0])) {
348         amp_warn(MOD_STR, "parameter must be (pointer and function)");
349         goto out;
350     }
351     /* get report info */
352 
353     JSValue jd_handle = JS_GetPropertyStr(ctx, argv[0], "device_handle");
354     JSValue jpk = JS_GetPropertyStr(ctx, argv[0], "product_key");
355     JSValue jdn = JS_GetPropertyStr(ctx, argv[0], "device_name");
356     JSValue jmn = JS_GetPropertyStr(ctx, argv[0], "module_name");
357     JSValue jver = JS_GetPropertyStr(ctx, argv[0], "version");
358 
359     unsigned int tmp_ptr_addr = 0;
360     tmp_ptr_addr = JS_GetOpaque(jd_handle, js_aiot_device_class_id);
361     if (!tmp_ptr_addr) {
362         amp_error(MOD_STR, "no iot_device_handle");
363         goto out;
364     }
365     dev_handle = (iot_device_handle_t *)tmp_ptr_addr;
366     amp_error(MOD_STR, "%s: handle 0x%x", __func__, (unsigned int)dev_handle);
367     amp_error(MOD_STR, "%s: mqtthandle 0x%x", __func__, (unsigned int)dev_handle->mqtt_handle);
368     const char* productkey = JS_ToCString(ctx, jpk);
369     const char* devicename = JS_ToCString(ctx, jdn);
370     const char* modulename = JS_ToCString(ctx, jmn);
371     const char* version = JS_ToCString(ctx, jver);
372 
373     res = ota_transport_inform(dev_handle->mqtt_handle, productkey, devicename, modulename, version);
374     if (res < 0) {
375         amp_error(MOD_STR, "amp jsota report ver failed!");
376     }
377     JS_FreeCString(ctx, productkey);
378     JS_FreeCString(ctx, devicename);
379     JS_FreeCString(ctx, modulename);
380     JS_FreeCString(ctx, version);
381 
382     JS_FreeValue(ctx, jd_handle);
383     JS_FreeValue(ctx, jpk);
384     JS_FreeValue(ctx, jdn);
385     JS_FreeValue(ctx, jmn);
386     JS_FreeValue(ctx, jver);
387 out:
388     return JS_NewInt32(ctx, res);
389 }
390 
ota_trigger_notify(void * pdata)391 static void ota_trigger_notify(void *pdata)
392 {
393     ota_package_info_t *ota_package_info = (ota_package_info_t *)pdata;
394     if (!ota_package_info) {
395         amp_error(MOD_STR, "ota_package_info null!");
396         return;
397     }
398     JSContext *ctx = js_get_context();
399     if (!ctx) {
400         amp_error(MOD_STR, "JSContext null!");
401         return;
402     }
403     JSValue ret = JS_NewObject(ctx);
404     JS_SetPropertyStr(ctx, ret, "length", JS_NewUint32(ctx, (unsigned int)ota_package_info->length));
405     JS_SetPropertyStr(ctx, ret, "module_name", JS_NewString(ctx, ota_package_info->module_name));
406     JS_SetPropertyStr(ctx, ret, "version", JS_NewString(ctx, ota_package_info->version));
407     JS_SetPropertyStr(ctx, ret, "url", JS_NewString(ctx, ota_package_info->url));
408     JS_SetPropertyStr(ctx, ret, "hash", JS_NewString(ctx, ota_package_info->hash));
409     if (ota_package_info->hash_type == 0) {
410         JS_SetPropertyStr(ctx, ret, "hash_type", JS_NewString(ctx, "null"));
411     } else if (ota_package_info->hash_type == 1) {
412         JS_SetPropertyStr(ctx, ret, "hash_type", JS_NewString(ctx, "sha256"));
413     } else if (ota_package_info->hash_type == 2) {
414         JS_SetPropertyStr(ctx, ret, "hash_type", JS_NewString(ctx, "md5"));
415     } else {
416         JS_SetPropertyStr(ctx, ret, "hash_type", JS_NewString(ctx, "sha512"));
417     }
418     JSValue v = JS_Call(ctx, ota_package_info->js_cb_ref, JS_UNDEFINED, 1, &ret);
419     if (JS_IsException(v)) {
420         amp_error(MOD_STR, "ota_trigger_notify callback error!");
421     }
422     JS_FreeValue(ctx, ret);
423     JS_FreeValue(ctx, v);
424 
425     JS_FreeValue(ctx, ota_package_info->js_cb_ref);
426     aos_free(ota_package_info);
427 }
428 
429 /* system image upgrade */
customer_upgrade_cb(void * pctx,char * ver,char * module_name,void * args)430 static int32_t customer_upgrade_cb(void *pctx, char *ver, char *module_name, void *args)
431 {
432     int32_t ret = OTA_TRANSPORT_PAR_FAIL;
433     ota_package_info_t *ota_package_info = (ota_package_info_t *) args;
434     ota_boot_param_t ota_param = {0};
435     aos_task_t customer_ota_task;
436     if ((pctx == NULL) || (ver == NULL) || (module_name == NULL) || (args == NULL)) {
437         amp_error(MOD_STR, "amp:ota triggered param err!");
438         return ret;
439     }
440     if (strncmp(module_name, "system", strlen(module_name)) == 0) {
441         ret = 0;
442         const char *current_ver = aos_app_version_get();
443         if (strncmp(ver, current_ver, strlen(ver)) <= 0) {
444             ret = OTA_TRANSPORT_VER_FAIL;
445             amp_error(MOD_STR, "amp ota version too old!");
446         } else {
447             amp_debug(MOD_STR, "ota version:%s is coming, begin to upgrade\n", ver);
448             /* clear jsengine timer, distory js app*/
449             if (aos_task_new_ext(&customer_ota_task, "amp_customer_ota", internal_sys_upgrade_start, (void *)pctx, 1024 * 8, AOS_DEFAULT_APP_PRI) != 0) {
450                 amp_debug(MOD_STR, "internal ota task create failed!");
451                 ret = OTA_TRANSPORT_PAR_FAIL;
452             }
453             amp_debug(MOD_STR, "app management center start");
454         }
455         amp_task_schedule_call(ota_release_notify, ota_package_info);
456     } else {
457         /*读取ota 触发时云端下发的文件信息*/
458         ret = ota_read_parameter(&ota_param);
459         if (ret < 0) {
460             amp_error(MOD_STR, "get store ota param info failed\n");
461             amp_task_schedule_call(ota_release_notify, ota_package_info);
462         } else {
463             ret = 0;
464             ota_package_info->length = ota_param.len;
465             ota_package_info->hash_type = ota_param.hash_type;
466             strncpy(ota_package_info->url, ota_param.url, sizeof(ota_package_info->url));
467             strncpy(ota_package_info->version, ver, strlen(ver));
468             strncpy(ota_package_info->module_name, module_name, strlen(module_name));
469             strncpy(ota_package_info->hash, ota_param.hash, sizeof(ota_package_info->hash));
470             amp_task_schedule_call(ota_trigger_notify, ota_package_info);
471         }
472     }
473     return ret;
474 }
475 
native_ota_init(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)476 static JSValue native_ota_init(JSContext *ctx, JSValueConst this_val,
477                           int argc, JSValueConst *argv)
478 {
479     int res = -1;
480     int productkey_len = IOTX_PRODUCT_KEY_LEN;
481     int productsecret_len = IOTX_PRODUCT_SECRET_LEN;
482     int devicename_len = IOTX_DEVICE_NAME_LEN;
483     int devicesecret_len = IOTX_DEVICE_SECRET_LEN;
484     iot_device_handle_t *iot_device_handle = NULL;
485     ota_package_info_t *ota_package_info = NULL;
486 
487     if (argc < 2 || !JS_IsObject(argv[0]) || !JS_IsFunction(ctx, argv[1])) {
488         amp_warn(MOD_STR, "parameter must be (object and function)");
489         goto out;
490     }
491     ota_service_param_reset(&customer_ota_ctx);
492     /* get device info */
493     aos_kv_get(AMP_CUSTOMER_PRODUCTKEY, customer_ota_ctx.pk, &productkey_len);
494     aos_kv_get(AMP_CUSTOMER_PRODUCTSECRET, customer_ota_ctx.ps, &productsecret_len);
495     aos_kv_get(AMP_CUSTOMER_DEVICENAME, customer_ota_ctx.dn, &devicename_len);
496     aos_kv_get(AMP_CUSTOMER_DEVICESECRET, customer_ota_ctx.ds, &devicesecret_len);
497 
498     memset(customer_module_info, 0x00, sizeof(customer_module_info));
499     iot_device_handle = JS_GetOpaque(argv[0], js_aiot_device_class_id);
500     if (!iot_device_handle) {
501         amp_error(MOD_STR, "no iot_device_handle");
502         goto out;
503     }
504     amp_error(MOD_STR, "%s: handle 0x%x", __func__, (unsigned int)iot_device_handle);
505     amp_error(MOD_STR, "%s: mqtthandle 0x%x", __func__, (unsigned int)iot_device_handle->mqtt_handle);
506     customer_ota_ctx.mqtt_client = (void *)iot_device_handle->mqtt_handle;
507 
508     ota_package_info = aos_malloc(sizeof(ota_package_info_t));
509     if (!ota_package_info) {
510         amp_error(MOD_STR, "alloc device notify param fail");
511         goto out;
512     }
513     memset(ota_package_info, 0, sizeof(ota_package_info_t));
514     ota_package_info->js_cb_ref = JS_DupValue(ctx, argv[1]);
515     ota_register_module_store(&customer_ota_ctx, customer_module_info, 3);
516     ota_register_trigger_msg_cb(&customer_ota_ctx, (void *)customer_upgrade_cb, ota_package_info);
517 
518     ota_set_module_information(&customer_ota_ctx, "system", OS_APP_PATH, OTA_UPGRADE_ALL);
519     /* init ota service */
520     res = ota_service_init(&customer_ota_ctx);
521     if (res < 0) {
522         amp_error(MOD_STR, "customer ota init failed!");
523     } else {
524         amp_warn(MOD_STR, "customer ota init success!");
525     }
526     const char *current_ver =  aos_app_version_get();
527     res = ota_report_module_version(&customer_ota_ctx, "system", current_ver);
528     if (res < 0) {
529         amp_error(MOD_STR, "amp ota report ver failed!");
530     }
531 
532 out:
533     if (res < 0) {
534         // todo:ota_package_info->js_cb_ref 是否需要free?
535         if (ota_package_info != NULL) {
536             aos_free(ota_package_info);
537         }
538         return JS_EXCEPTION;
539     }
540     return JS_NewInt32(ctx, res);
541 }
542 
543 static JSClassDef js_appota_class = {
544     "APPOTA",
545 };
546 
547 static const JSCFunctionListEntry js_appota_funcs[] = {
548     JS_CFUNC_DEF("otaInit", 1, native_ota_init ),
549     JS_CFUNC_DEF("otaDownload", 1, native_ota_download ),
550     JS_CFUNC_DEF("otaVerify", 1, native_ota_verify ),
551     JS_CFUNC_DEF("otaReport", 1, native_ota_report ),
552     JS_CFUNC_DEF("otaUpgrade", 1, native_ota_upgrade ),
553 };
554 
js_appota_init(JSContext * ctx,JSModuleDef * m)555 static int js_appota_init(JSContext *ctx, JSModuleDef *m)
556 {
557     JSValue proto;
558 
559     JS_NewClassID(&js_appota_class_id);
560 
561     JS_NewClass(JS_GetRuntime(ctx), js_appota_class_id, &js_appota_class);
562     proto = JS_NewObject(ctx);
563     JS_SetPropertyFunctionList(ctx, proto, js_appota_funcs,
564                                countof(js_appota_funcs));
565     JS_SetClassProto(ctx, js_appota_class_id, proto);
566 
567     return JS_SetModuleExportList(ctx, m, js_appota_funcs,
568                                   countof(js_appota_funcs));
569 }
570 
js_init_module_appota(JSContext * ctx,const char * module_name)571 JSModuleDef *js_init_module_appota(JSContext *ctx, const char *module_name)
572 {
573     JSModuleDef *m;
574     m = JS_NewCModule(ctx, module_name, js_appota_init);
575     if (!m)
576         return NULL;
577     JS_AddModuleExportList(ctx, m, js_appota_funcs, countof(js_appota_funcs));
578     return m;
579 }
580 
module_app_ota_register(void)581 void module_app_ota_register(void)
582 {
583     amp_debug(MOD_STR, "module_ota_register");
584 
585     JSContext *ctx = js_get_context();
586 
587     amp_debug(MOD_STR, "module appota register");
588     js_init_module_appota(ctx, "APPOTA");
589 }
590 
591