blob: bc8a3992e2296a3bd7a4d556ef8899aeb3e4fa20 [file] [log] [blame]
LUOJian60136c32023-11-24 13:59:45 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <sys/types.h>
6#include <errno.h>
7#include <fcntl.h>
8#include <pthread.h>
9#include <libubox/blobmsg_json.h>
10#include "libubus.h"
11#include "mbtk_fota.h"
LUOJian09598702023-12-14 13:58:42 +080012#include <semaphore.h>
luojian49e53402024-06-05 15:37:57 +080013#include <cutils/properties.h>
LUOJian60136c32023-11-24 13:59:45 +080014
15
16#ifdef DEBUG
17 #define fota_log(...) printf(__VA_ARGS__)
18#else
19 #define fota_log(...)
20#endif
21
22#define UNUSEDPARAM(param) (void)param;
23#define OTA_MAX_STRING_LEN 128
24
25static struct ubus_context *fota_ubus_ctx = NULL;
26static uint32_t fota_request_id;
27static struct ubus_subscriber notification_event;
28static pthread_t fota_status_pthread;
29static struct blob_buf b;
30static fota_callback fota_cb = NULL;
LUOJian09598702023-12-14 13:58:42 +080031sem_t sem;
LUOJian9a2d3ba2024-01-05 17:14:41 +080032volatile int fota_dowload_flag = -1;
33//3: upding
34//4: updata success
35//5: updata fail
LUOJian60136c32023-11-24 13:59:45 +080036
37enum {
38 ATTR_SMSGPS,
39 ATTR_SMSGPS_MAX,
40};
41
42static const struct blobmsg_policy ota_info_attr_policy[] = {
43 [ATTR_SMSGPS] ={.name = "notification", .type = BLOBMSG_TYPE_STRING,},
44};
45
46/**
47 * \brief strstr_n
48 *
49 * find string return number
50 *
51 * \param param
52 * \return return type
53 */
54static int strstr_n(const char *s1, const char *s2)
55{
56 int n;
57 int strlen = 0;
58
59 if(*s2) {
60 while(*s1) {
61 for(n = 0; *(s1+n) == *(s2 + n); n++) {
62 if(!*(s2 + n + 1)) {
63 strlen++;
64 return strlen;
65 }
66 }
67 s1++;
68 strlen++;
69 }
70 return 0;
71 }
72 else
73 return 0;
74}
75
76static int otad_notify(struct ubus_context* ctx, struct ubus_object* obj,
77 struct ubus_request_data* req, const char* method,
78 struct blob_attr* msg)
79{
80 UNUSEDPARAM(ctx);
81 UNUSEDPARAM(obj);
82 UNUSEDPARAM(req);
83 UNUSEDPARAM(method);
84 // User can get downloading process information from here
85 int ret, len;
86 char progress[4] = {0};
87 char *notify_str;
88
89 struct blob_attr *tb[ATTR_SMSGPS_MAX];
90 ret = blobmsg_parse(ota_info_attr_policy, ARRAY_SIZE(ota_info_attr_policy), tb,
91 blob_data(msg), blob_len(msg));
92
93 if (ret || !tb[ATTR_SMSGPS]) {
94 printf("invalid SMS\n");
95 return -1;
96 }
97
98 notify_str = blobmsg_get_string(tb[ATTR_SMSGPS]);
99 len = strlen(notify_str);
100 fota_log("%s : %s\r\n", __FUNCTION__, notify_str);
LUOJian9a2d3ba2024-01-05 17:14:41 +0800101// printf("L11111%s : %s\r\n", __FUNCTION__, notify_str);
LUOJian60136c32023-11-24 13:59:45 +0800102 if (strstr_n(notify_str, "start")) {
103 fota_cb(0, 0);
104 } else if (strstr_n(notify_str, "end[1]")) {
105 fota_cb(0, 100);
LUOJian9a2d3ba2024-01-05 17:14:41 +0800106 fota_dowload_flag = 4;
LUOJian09598702023-12-14 13:58:42 +0800107// sem_post(&sem);
LUOJian60136c32023-11-24 13:59:45 +0800108 printf("download firmware success!\r\n");
109 } else if (strstr_n(notify_str, "end[0]")) {
110 fota_cb(1, 100);
LUOJian9a2d3ba2024-01-05 17:14:41 +0800111 fota_dowload_flag = 5;
LUOJian09598702023-12-14 13:58:42 +0800112// sem_post(&sem);
113 printf("download firmware fail!\r\n");
LUOJian60136c32023-11-24 13:59:45 +0800114 }
115 ret = strstr_n(notify_str, "progress");
116 if (ret) {
117 memcpy(progress, &notify_str[ret + 8], len - ret - 9);
118 fota_cb(0, atoi(progress));
119 }
120 return 0;
121}
122
123static void otad_subscriber_remove_cb(struct ubus_context* ctx,
124 struct ubus_subscriber* obj, uint32_t id)
125{
126 UNUSEDPARAM(ctx);
127 UNUSEDPARAM(obj);
128 UNUSEDPARAM(id);
129 fota_log("%s,%d\n", __FUNCTION__, __LINE__);
130}
131
132
133/*******************************************************************************
134* @brief write firmware package, the firmware package is written in segments.
135 and The result of the write is output by calling the callback function.
136 the firmware package size must less than 32MB
137 @param
138 fname: firmware package file
139 segment_size: the length of once write, recommending 3*1024*1024 bytes
140 @return
141 if success return 0, else return -1
142 *******************************************************************************/
143int mbtk_fota_fw_write(char* fname, int segment_size)
144{
LUOJian9a2d3ba2024-01-05 17:14:41 +0800145 fota_dowload_flag = 3;
LUOJian09598702023-12-14 13:58:42 +0800146 printf("mbtk_fota_fw_write start2\n");
147 int L = 1;
148 int ret = -1;
LUOJian60136c32023-11-24 13:59:45 +0800149 static struct ubus_request req;
150 int _segment_size;
151 blob_buf_init(&b, 0);
152 blobmsg_add_string(&b, "url", fname);
153 blobmsg_add_u32(&b, "type", 2);
154 blobmsg_add_u32(&b, "sync", 1);
155 _segment_size = segment_size;
156 if (_segment_size > 1024) {
157 blobmsg_add_u32(&b, "segment_size", _segment_size);
158 }
159 blobmsg_add_u32(&b, "sync", 1);
160 ubus_invoke_async(fota_ubus_ctx, fota_request_id, "download", b.head, &req);
161 ubus_complete_request_async(fota_ubus_ctx, &req);
LUOJian09598702023-12-14 13:58:42 +0800162#if 1
163 while(1)
164 {
165 if(L == 1)
166 {
LUOJian9a2d3ba2024-01-05 17:14:41 +0800167 // printf("%s, L:%d", __FUNCTION__,L);
LUOJian09598702023-12-14 13:58:42 +0800168 L++;
169 }
170 /* V2¨´¡Á¡Â */
171// sem_wait(&sem);
172// break;
LUOJian60136c32023-11-24 13:59:45 +0800173
LUOJian9a2d3ba2024-01-05 17:14:41 +0800174 if(fota_dowload_flag != 3)
LUOJian09598702023-12-14 13:58:42 +0800175 {
LUOJian9a2d3ba2024-01-05 17:14:41 +0800176 // printf("break while(), fota_dowload_flag:%d", fota_dowload_flag);
LUOJian09598702023-12-14 13:58:42 +0800177 break;
178 }
luojian360ccc02024-08-09 14:35:15 +0800179 sleep(1);
LUOJian09598702023-12-14 13:58:42 +0800180 }
181#endif
LUOJian9a2d3ba2024-01-05 17:14:41 +0800182// printf("%s, L:%d, fota_dowload_flag = :%d", __FUNCTION__,L, fota_dowload_flag);
183// printf("mbtk_fota_fw_write end \n");
184 if(fota_dowload_flag == 4)
LUOJian09598702023-12-14 13:58:42 +0800185 {
186 ret = 0;
187 }
188 return ret;
LUOJian60136c32023-11-24 13:59:45 +0800189}
190
LUOJian60136c32023-11-24 13:59:45 +0800191/*******************************************************************************
192* @brief download firmware by url, and write firmware package, the firmware
193 package is written in segments. The result of the write is output by
194 calling the callback function. the firmware package size must less than
195 32MB
196 @param
197 url: [IN] the address of download firmware package file, the url
198 support http or https protocol.
199 segment_size: [IN] the length of once write, recommending 3*1024*1024 bytes
200 conn_timeout: [IN] timeout to connect to the server, if set 0 that means
201 switch to the default build-in connection timeout(300s)
202 download_timeout: [IN] timeout for download the firmware file. if set 0 that means
203 it never time out
204 @return
205 if success return 0, else return -1
206 *******************************************************************************/
207int mbtk_fota_fw_write_by_url(char* url, int segment_size,
208 int conn_timeout, int download_timeout)
209{
luojian1b28b012024-07-31 10:49:16 +0800210 printf("mbtk_fota_fw_write_by_url start2\n");
LUOJian09598702023-12-14 13:58:42 +0800211 int ret = -1, L = 1;
LUOJian9a2d3ba2024-01-05 17:14:41 +0800212 fota_dowload_flag = 3;
LUOJian60136c32023-11-24 13:59:45 +0800213 static struct ubus_request req;
214 int _segment_size;
215 blob_buf_init(&b, 0);
216 blobmsg_add_string(&b, "url", url);
217 blobmsg_add_string(&b, "username", "user name");
218 blobmsg_add_u32(&b, "type", 0);
219 blobmsg_add_u32(&b, "sync", 1);
220 _segment_size = segment_size;
221 if (_segment_size > 1024) {
222 blobmsg_add_u32(&b, "segment_size", _segment_size);
223 }
224 blobmsg_add_u32(&b, "sync", 1);
225 ubus_invoke_async(fota_ubus_ctx, fota_request_id, "download", b.head, &req);
226 ubus_complete_request_async(fota_ubus_ctx, &req);
LUOJian09598702023-12-14 13:58:42 +0800227
228 while(1)
229 {
230 if(L == 1)
231 {
LUOJian9a2d3ba2024-01-05 17:14:41 +0800232 // printf("%s, L:%d", __FUNCTION__,L);
LUOJian09598702023-12-14 13:58:42 +0800233 L++;
234 }
235 /* V2¨´¡Á¡Â */
236// sem_wait(&sem);
237// break;
238
LUOJian9a2d3ba2024-01-05 17:14:41 +0800239 if(fota_dowload_flag != 3)
LUOJian09598702023-12-14 13:58:42 +0800240 {
LUOJian9a2d3ba2024-01-05 17:14:41 +0800241 // printf("break while(), fota_dowload_flag:%d", fota_dowload_flag);
LUOJian09598702023-12-14 13:58:42 +0800242 break;
243 }
luojian1b28b012024-07-31 10:49:16 +0800244 sleep(1);
LUOJian09598702023-12-14 13:58:42 +0800245 }
246
LUOJian9a2d3ba2024-01-05 17:14:41 +0800247 // printf("%s, L:%d, fota_dowload_flag = :%d", __FUNCTION__,L, fota_dowload_flag);
248 // printf("mbtk_fota_fw_write_by_url end \n");
249 if(fota_dowload_flag == 4)
LUOJian09598702023-12-14 13:58:42 +0800250 {
251 ret = 0;
252 }
253 return ret;
254
LUOJian60136c32023-11-24 13:59:45 +0800255}
256/*******************************************************************************
257* @brief reboot system and clear env
258 @param
259 is_reboot: if set 1, after fota success, reboot system
260 @return
261 if success return 0, else return -1
262 *******************************************************************************/
263int mbtk_fota_done(int is_reboot)
264{
265 int ret;
266
267 ret = pthread_cancel(fota_status_pthread);
268 fota_log("kill pthread : %d \n", ret);
269 pthread_join(fota_status_pthread, NULL);
270 do {
271 ret = pthread_kill(fota_status_pthread, 0);
272 fota_log("kill pthread: %d \n", ret);
273 if (ret == ESRCH) {
274 fota_log("The specified thread does not exist or has terminated\n");
275 } else if (ret == EINVAL) {
276 fota_log("Useless signal\n");
277 } else {
278 fota_log("The thread exists\n");
279 }
280 usleep(100000);
281 } while (0 == ret);
282
283
284 ubus_free(fota_ubus_ctx);
285 uloop_done();
286
287 fota_cb = NULL;
288
289 if (is_reboot) {
290 system("sync");
291 system("reboot");
292 }
293 return 0;
LUOJian9a2d3ba2024-01-05 17:14:41 +0800294
295}
296
297int mbtk_fota_done1(int is_reboot)
298{
299 if (is_reboot) {
300 system("sync");
301 system("reboot");
302 }
303 return 0;
LUOJian60136c32023-11-24 13:59:45 +0800304}
305
306void* mbtk_fota_thread(void* argc)
307{
308 int ret, retries = 0;
309 UNUSEDPARAM(argc);
310
LUOJian09598702023-12-14 13:58:42 +0800311 printf("mbtk_fota_thread() start\n");
312 pthread_detach(pthread_self());
LUOJian60136c32023-11-24 13:59:45 +0800313 //register for ril indication
314 ret = ubus_register_subscriber(fota_ubus_ctx, &notification_event);
315 if (ret) {
316 fota_log("%s,%d\n", __FUNCTION__, __LINE__);
317 pthread_exit(NULL);
318 }
319 notification_event.cb = otad_notify;
320 notification_event.remove_cb = otad_subscriber_remove_cb;
321
322 ubus_subscribe(fota_ubus_ctx, &notification_event, fota_request_id);
323 uloop_run();
324 ubus_unsubscribe(fota_ubus_ctx, &notification_event, fota_request_id);
325 pthread_exit(NULL);
326
327 return NULL;
328}
329
330
331int mbtk_fota_init(fota_callback cb)
332{
333 int id;
334 int retries = 0;
335
336 /*create ubus loop to listen to RIL event*/
337 uloop_init();
338 fota_ubus_ctx = ubus_connect(NULL);
339 if (!fota_ubus_ctx) {
340 fota_log("%s,%d\n", __FUNCTION__, __LINE__);
341 uloop_done();
342 return 0;
343 }
344
345 ubus_add_uloop(fota_ubus_ctx);
346
347 do {
348 //register for ril request
349 retries = 0;
350 if (ubus_lookup_id(fota_ubus_ctx, "ota", &fota_request_id)) {
351 fota_log("%s,%d\n", __FUNCTION__, __LINE__);
352 sleep(1);
353 } else {
354 break;
355 }
356 } while (retries++ < 20);
357 if (retries >= 20) {
358 printf("%s,%d\n", __FUNCTION__, __LINE__);
359 goto fail1;
360 }
361 pthread_create(&fota_status_pthread, NULL, (void*)mbtk_fota_thread, NULL);
362 fota_cb = cb;
LUOJian60136c32023-11-24 13:59:45 +0800363 return 0;
LUOJian09598702023-12-14 13:58:42 +0800364fail1:
365 return 1;
LUOJian60136c32023-11-24 13:59:45 +0800366}
367
luojian17de8c52024-05-31 09:46:11 +0800368int mbtk_fota_get_asr_reboot_cnt_flag(void)
luojianb72371a2024-04-23 17:47:46 +0800369{
luojian49e53402024-06-05 15:37:57 +0800370 int type = 0;
371 char time_type[] ={0};
372 property_get("persist.mbtk.reboot_cnt", time_type, "0");
luojianb72371a2024-04-23 17:47:46 +0800373
luojian49e53402024-06-05 15:37:57 +0800374 type = atoi(time_type);
luojianb72371a2024-04-23 17:47:46 +0800375
luojian49e53402024-06-05 15:37:57 +0800376 return type;
luojianb72371a2024-04-23 17:47:46 +0800377}
378
379
LUOJian9a2d3ba2024-01-05 17:14:41 +0800380int mbtk_fota_status(void)
381{
382 return fota_dowload_flag;
383}
384
385