1 /*
2  * Copyright (C) 2015-2021 Alibaba Group Holding Limited
3  */
4 
5 #include "app_upgrade.h"
6 
7 #include "aiot_state_api.h"
8 #include "amp_platform.h"
9 #include "aos/kernel.h"
10 #include "aos_system.h"
11 #include "app_mgr.h"
12 #include "miniunz.h"
13 #include "ota_agent.h"
14 #include "py_defines.h"
15 
16 #define MOD_STR "APP_UPGRADE"
17 
18 #if defined(__ICCARM__)
19 #define AMP_WEAK __weak
20 #else
21 #define AMP_WEAK __attribute__((weak))
22 #endif
23 
24 static ota_store_module_info_t module_info[3];
25 static ota_service_t internal_ctx = { 0 };
26 static module_version[128];
27 
py_ota_get_module_ver(void * pctx,char * module_name)28 char *py_ota_get_module_ver(void *pctx, char *module_name)
29 {
30     return NULL;
31 }
32 
ota_get_py_install_path(char * store_file_full_path,char * path_buf,int path_buf_len)33 int ota_get_py_install_path(char *store_file_full_path, char *path_buf, int path_buf_len)
34 {
35     int ret = -1;
36     int store_file_path_len = 0;
37     int want_copy_len = 0;
38     if ((store_file_full_path != NULL) && (path_buf != NULL)) {
39         store_file_path_len = strlen(store_file_full_path);
40         for (want_copy_len = store_file_path_len - 1; want_copy_len > 0; want_copy_len--) {
41             if (store_file_full_path[want_copy_len] == '/') {
42                 break;
43             }
44         }
45         if (want_copy_len > 0) {
46             want_copy_len++;
47             if (want_copy_len < path_buf_len) {
48                 ret = 0;
49                 memset(path_buf, 0x00, path_buf_len);
50                 strncpy(path_buf, store_file_full_path, want_copy_len);
51                 amp_debug(MOD_STR, "get store file path:%s\n", path_buf);
52             } else {
53                 amp_error(MOD_STR, "get store file path failed, path buf too short\n");
54             }
55         }
56     }
57     return ret;
58 }
59 
pyamp_ota_file_plus_name(char * file_path1,char * file_path2,char * new_path,int new_path_len)60 int pyamp_ota_file_plus_name(char *file_path1, char *file_path2, char *new_path, int new_path_len)
61 {
62     int ret = -1;
63     int file_path1_len = 0;
64     int file_path2_len = 0;
65     if ((file_path1 == NULL) || (file_path2 == NULL) || (new_path == NULL)) {
66         return ret;
67     }
68     file_path1_len = strlen(file_path1);
69     file_path2_len = strlen(file_path2);
70     memset(new_path, 0x00, new_path_len);
71     if (file_path1_len + file_path2_len < new_path_len) {
72         strncpy(new_path, file_path1, file_path1_len);
73         if (new_path[file_path1_len - 1] != '/') {
74             new_path[file_path1_len++] = '/';
75         }
76         strncpy(&new_path[file_path1_len], file_path2, file_path2_len);
77         ret = 0;
78     }
79     return ret;
80 }
81 
fota_image_local_copy(char * image_name,int image_size)82 AMP_WEAK int fota_image_local_copy(char *image_name, int image_size)
83 {
84     return -1;
85 }
86 
87 /* system image upgrade */
internal_upgrade_cb(void * pctx,char * ver,char * module_name)88 static int32_t internal_upgrade_cb(void *pctx, char *ver, char *module_name)
89 {
90     int32_t ret = OTA_TRANSPORT_PAR_FAIL;
91     aos_task_t internal_ota_task;
92     char *current_ver = NULL;
93     if ((pctx == NULL) || (ver == NULL) || (module_name == NULL)) {
94         amp_error(MOD_STR, "amp:ota triggered param err!");
95         return ret;
96     }
97     if (strncmp(module_name, "default", strlen(module_name)) == 0) {
98         ret = STATE_SUCCESS;
99         current_ver = ota_get_module_ver(pctx, module_name);
100         if (strncmp(ver, current_ver, strlen(ver)) <= 0) {
101             ret = OTA_TRANSPORT_VER_FAIL;
102             amp_error(MOD_STR, "amp ota version too old!");
103         } else {
104             amp_debug(MOD_STR, "ota version:%s is coming, if OTA upgrade or not ?\n", ver);
105             /* clear jsengine timer, distory js app*/
106             amp_module_free();
107             app_js_stop();
108             if (aos_task_new_ext(&internal_ota_task, "amp_internal_ota", internal_sys_upgrade_start, (void *)pctx,
109                                  1024 * 8, AOS_DEFAULT_APP_PRI) != 0) {
110                 amp_debug(MOD_STR, "internal ota task create failed!");
111                 ret = OTA_TRANSPORT_PAR_FAIL;
112             }
113             amp_debug(MOD_STR, "app management center start");
114         }
115     } else {
116         // current_ver = ota_get_module_ver(pctx, module_name);
117         // if (current_ver != NULL) {
118         //     ret = STATE_SUCCESS;
119         //     if (strncmp(ver, current_ver, strlen(ver)) <= 0) {
120         //         ret = OTA_TRANSPORT_VER_FAIL;
121         //         amp_error(MOD_STR, "submodule jsapp ota version too old!");
122         //     } else {
123         //         amp_debug(MOD_STR, "ota module version:%s is coming, if OTA
124         //         module upgrade or not ?\n", ver);
125         //         /* clear jsengine timer, distory js app*/
126         //         amp_module_free();
127         //         app_js_stop();
128         //         if (aos_task_new_ext(&internal_ota_task, "amp_moudle_ota",
129         //         internal_module_upgrade_start, (void *)pctx, 1024 * 8,
130         //         AOS_DEFAULT_APP_PRI) != 0) {
131         //             amp_debug(MOD_STR, "internal ota task create failed!");
132         //             ret = OTA_TRANSPORT_PAR_FAIL;
133         //         }
134         //         amp_debug(MOD_STR, "app management center start");
135         //     }
136         // }
137     }
138     return ret;
139 }
140 
141 /* app upgrade service */
py_app_upgrade_service(void * mqtt_handle)142 int32_t py_app_upgrade_service(void *mqtt_handle)
143 {
144     int res = STATE_SUCCESS;
145     int productkey_len = IOTX_PRODUCT_KEY_LEN;
146     int productsecret_len = IOTX_PRODUCT_SECRET_LEN;
147     int devicename_len = IOTX_DEVICE_NAME_LEN;
148     int devicesecret_len = IOTX_DEVICE_SECRET_LEN;
149     char *current_ver = NULL;
150 
151     ota_service_param_reset(&internal_ctx);
152     memset(module_info, 0x00, sizeof(module_info));
153     ota_register_module_store(&internal_ctx, module_info, 3);
154     /* get device info */
155     aos_kv_get(AMP_INTERNAL_PRODUCTKEY, internal_ctx.pk, &productkey_len);
156     aos_kv_get(AMP_INTERNAL_PRODUCTSECRET, internal_ctx.ps, &productsecret_len);
157     aos_kv_get(AMP_INTERNAL_DEVICENAME, internal_ctx.dn, &devicename_len);
158     aos_kv_get(AMP_INTERNAL_DEVICESECRET, internal_ctx.ds, &devicesecret_len);
159 
160     ota_register_trigger_msg_cb(&internal_ctx, (void *)internal_upgrade_cb, NULL);
161     internal_ctx.mqtt_client = (void *)mqtt_handle;
162     ota_set_module_information(&internal_ctx, AMP_OTA_MODULE_NAME, SUBDEV_FILE_PATH, OTA_UPGRADE_CUST);
163     ota_set_module_information(&internal_ctx, "default", OS_APP_PATH, OTA_UPGRADE_ALL);
164     /* init ota service */
165     res = ota_service_init(&internal_ctx);
166     if (res < STATE_SUCCESS) {
167         amp_error(MOD_STR, "internal ota init failed!");
168     }
169     amp_warn(MOD_STR, "internal ota init success!");
170 
171     /*custom report version*/
172     current_ver = ota_get_module_ver(&internal_ctx, "default");
173     res = ota_report_module_version(&internal_ctx, "default", current_ver);
174     if (res < STATE_SUCCESS) {
175         amp_error(MOD_STR, "amp ota report ver failed!");
176     }
177     current_ver = ota_get_module_ver(&internal_ctx, AMP_OTA_MODULE_NAME);
178     res = ota_report_module_version(&internal_ctx, AMP_OTA_MODULE_NAME, current_ver);
179     if (res < STATE_SUCCESS) {
180         amp_error(MOD_STR, "amp jsota report ver failed!");
181         return -1;
182     }
183 
184     return STATE_SUCCESS;
185 }
186 
ota_install_pyapp(void * ota_ctx,char * store_file,int store_file_len,char * install_path)187 int ota_install_pyapp(void *ota_ctx, char *store_file, int store_file_len, char *install_path)
188 {
189     int ret = -1;
190     ota_service_t *ctx = ota_ctx;
191     amp_debug(MOD_STR, "upgrade sub module\n");
192     if ((store_file != NULL) && (install_path != NULL)) {
193         amp_debug(MOD_STR, "store_file:%s, install_file:%s\n", store_file, install_path);
194         // ret = data_file_unpack(store_file, store_file_len, install_path);
195         ret = miniUnzip(store_file, install_path);
196     }
197     if (ret < 0) {
198         amp_error(MOD_STR, "py app install failed\n");
199         if ((ctx != NULL) && (ctx->report_func.report_status_cb != NULL)) {
200             ctx->report_func.report_status_cb(ctx->report_func.param, ret);
201         }
202     }
203     if ((ctx != NULL) && (ctx->feedback_func.on_user_event_cb != NULL)) {
204         ctx->feedback_func.on_user_event_cb(OTA_EVENT_INSTALL, ret, ctx->feedback_func.param);
205     }
206     return ret;
207 }
208 
install_pyapp(char * store_file,char * install_path)209 int install_pyapp(char *store_file, char *install_path)
210 {
211     int ret = -1;
212     amp_debug(MOD_STR, "upgrade sub module\n");
213     if ((store_file != NULL) && (install_path != NULL)) {
214         amp_debug(MOD_STR, "store_file:%s, install_file:%s\n", store_file, install_path);
215         ret = miniUnzip(store_file, install_path);
216     }
217     if (ret < 0) {
218         amp_error(MOD_STR, "py app install failed\n");
219     }
220 
221     return ret;
222 }