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 }