blob: bbe4cb8c697955d3206dc043c19fc646359269df [file] [log] [blame]
b.liua76c9612025-03-28 13:58:09 +08001#include <sys/socket.h>
2#include <sys/un.h>
3#include <sys/stat.h>
4#include <sys/uio.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <signal.h>
8#include <stdio.h>
9#include <unistd.h>
10#include <fcntl.h>
11#include <sys/prctl.h>
12
13#include <libubox/blob.h>
14#include <libubox/uloop.h>
15#include <libubox/usock.h>
16#include <libubox/list.h>
17#include <libubus.h>
18#if 0
19#include <curl/curl.h>
20#include <curl/easy.h>
21#endif
22#include <uci.h>
23
24#include <sys/ioctl.h>
25#include <mtd/mtd-user.h>
26
27#include "libhttpclient/libhttpclient.h"
28#include "otad.h"
29
b.liu9e96ffe2025-04-03 13:28:05 +080030#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +080031#define MEMLOCKPRIV _IO('M', 25)
32#define MEMUNLOCKPRIV _IO('M', 26)
33
b.liu9e96ffe2025-04-03 13:28:05 +080034#define OTA_ADDR_DEF 0x2a60000
35
36#ifndef TRUE
37#define TRUE 1
38#endif
39
40#ifndef FALSE
41#define FALSE 0
42#endif
43
b.liua76c9612025-03-28 13:58:09 +080044static int complete_read(int fd, char *buf, int size);
45static int complete_write(int fd, char *buf, int size);
46#include "tim.h"
b.liu49596152025-03-31 14:02:15 +080047
b.liu9e96ffe2025-04-03 13:28:05 +080048//#if !defined(CONFIG_AB_SYSTEM_DFOTA)
b.liua76c9612025-03-28 13:58:09 +080049#include "tim.c"
b.liu9e96ffe2025-04-03 13:28:05 +080050//#endif
b.liu49596152025-03-31 14:02:15 +080051
b.liua76c9612025-03-28 13:58:09 +080052#include "getfotav.c"
53
54#if 0
55/* support dfota upgrade */
56#define CONFIG_AB_SYSTEM_DFOTA
57#endif
58
59/* the main bootloader */
60const char *tmp_obm_main_file = "/tmp/obm_main.bin";
61const char *tmp_timh_main_file = "/tmp/timh_main.bin";
62/* the backup bootloader */
63const char *tmp_obm_bk_file = "/tmp/obm_bk.bin";
64const char *tmp_timh_bk_file = "/tmp/timh_bk.bin";
65/* the target timh for the specific ddr */
66const char *tmp_timh_main_target_file = "/tmp/timh_main_target.bin";
67const char *tmp_timh_bk_target_file = "/tmp/timh_bk_target.bin";
68
69static unsigned int obm_real_size = 0;
70#endif
71
72#define OTA_MAX_STRING_LEN 128
73#define OEMDDENTIFIER 0x4F454D44 /* "OEMD" */
74
75enum {
76 UPDATE_STATE_IDLE,
77 UPDATE_STATE_UPDATING,
78 UPDATE_STATE_UPDATED,
79 UPDATE_STATE_FAILED,
80};
81static int update_state = UPDATE_STATE_IDLE;
82static int update_oemd;
b.liu9e96ffe2025-04-03 13:28:05 +080083static bool is_dfota = FALSE; // Default not dfota.
b.liua76c9612025-03-28 13:58:09 +080084
85struct version_info {
86 char version[OTA_MAX_STRING_LEN];
87 char url[OTA_MAX_STRING_LEN];
88 char * release_note;
89};
90
b.liu9e96ffe2025-04-03 13:28:05 +080091#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +080092#define MIN_RLS_VERSION 846
93
b.liu9e96ffe2025-04-03 13:28:05 +080094//#if !defined(CONFIG_AB_SYSTEM_DFOTA)
b.liua76c9612025-03-28 13:58:09 +080095static int upgrade_precheck(char *fotav)
96{
97 char *p;
98 int ver;
99
100 OTA_DEBUG("%s: %s\n", __func__, fotav);
101 p = strstr(fotav, "_rls");
102 if (!p) {
103 OTA_ERR("not found rls version.\n", __func__);
104 return -1;
105 }
106
107 p += 4;
108 ver = atoi(p);
109 if (ver < MIN_RLS_VERSION) {
110 OTA_DEBUG("%s: don't support upgrade to rls%d, min: rls%d\n", __func__, ver, MIN_RLS_VERSION);
111 return -1;
112 }
113
114 /* support upgrade */
115 return 0;
116}
b.liu9e96ffe2025-04-03 13:28:05 +0800117//#endif
b.liua76c9612025-03-28 13:58:09 +0800118
119static int complete_read(int fd, char *buf, int size);
120static int complete_write(int fd, char *buf, int size);
121
122// Change by liubin
123#define MAX_MTD_PARTITION_CNT 35
124#define FBF_FILE_SECTOR_SIZE (4*1024)
125struct image_mtd_info {
126 char name[32];
127 char dev[16];
128 unsigned int flash_start_offset;
129 unsigned int size;
130 unsigned int erasesize;
131 unsigned int flag;
132};
133
134enum {
135 SYSTEM_SINGLE = 0,
136 SYSTEM_A = 'a',
137 SYSTEM_B = 'b'
138};
139
140static int gInActiveSystem = SYSTEM_SINGLE;
141static int gSystemHasRollbackFlag = 0;
142#endif
143
144struct ota_server {
145 char server_url[OTA_MAX_STRING_LEN];
146 int download_immediately;
147 int progress_notify;
148 int interval;
149 int first_interval;
150 unsigned int fbf_length;
151 unsigned int block_size;
152 unsigned int pagesize;
153 unsigned int emmc_block_size; /* 512B */
154 unsigned int fbf_addr;
155 char mtd_asrflag[64];
b.liu9e96ffe2025-04-03 13:28:05 +0800156#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +0800157 int mtd_cnt;
158 struct image_mtd_info image_mtd_info[MAX_MTD_PARTITION_CNT];
159 unsigned int cpuid;
160 unsigned int ddrid;
161 unsigned int max_timh_size;
162 unsigned int fotav_offset_in_fbf;
163 char fotav[128];
164#endif
b.liu49596152025-03-31 14:02:15 +0800165 char mtd_fbf[300];
b.liua76c9612025-03-28 13:58:09 +0800166 struct version_info ver;
167};
168struct ota_server server_cfg;
169
170static struct ubus_context *ctx;
171static struct blob_buf b;
172static struct ubus_object ota_object;
173
174enum {
175 DOWNLOAD_TYPE,
176 DOWNLOAD_FILE_SIZE,
177 DOWNLOAD_URL,
178 DOWNLOAD_NAME,
179 DOWNLOAD_PSW,
180 DOWNLOAD_SYNC,
181 DOWNLOAD_SEGMENT_SIZE,
182 __DOWNLOAD_MAX
183};
184
185static const struct blobmsg_policy download_policy[] = {
186 [DOWNLOAD_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 },
187 [DOWNLOAD_FILE_SIZE] = { .name = "size", .type = BLOBMSG_TYPE_INT32 },
188 [DOWNLOAD_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING },
189 [DOWNLOAD_NAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING },
190 [DOWNLOAD_PSW] = { .name = "password", .type = BLOBMSG_TYPE_STRING },
191 [DOWNLOAD_SYNC] = { .name = "sync", .type = BLOBMSG_TYPE_INT32 },
192 [DOWNLOAD_SEGMENT_SIZE] = { .name = "segment_size", .type = BLOBMSG_TYPE_INT32 },
193};
194
195#if 0
196static size_t curl_cb(void *buffer, size_t size, size_t nmemb, void *stream)
197{
198 //OTA_ERR(" response: %s(%d:%d)\n", (char *)buffer, size, nmemb);
199 OTA_ERR(" response:%d:%d\n", size, nmemb);
200 return size * nmemb;
201}
202#endif
203// FBF file related definition
204static int _ota_download_progress = 0;
205static int ota_download_progress = 0;
206char * fbf_version_string = NULL;
207// Add by mbtk
208int Download_flag = 0;
209#define TR069_FBF_HEADER_SIZE 13
210#define DLCMD_IMAGE_TYPE_FIELD_BIT 4
211#define DLCMD_IMAGE_TYPE_FIELD_SIZE_BITS 4
212#define MAX_NUMBER_OF_FLASH_DEVICES_IN_MASTER_HEADER 4
213#define MAX_NUMBER_OF_FLASH_DEVICES_IN_DEVICE_HEADER 150
214#define BLOCK_DEVICE_SECTOR_SIZE (8*1024)
215#define MAX_RESEVERD_LEN 4
216#define MAX_NUM_SKIP_BLOCKS 32
217#define UNIQUE_SIZE 24
218#define NUM_OF_SUPPORTED_FLASH_DEVS 4
219#define RSA_IMAGE_ID 0x52534149
220#define MINI_SIZE (128)
221#define CHECKSUM_CACHE_SIZE (128)
222#define FILE_VERIFY_RAM_SIZE (server_cfg.block_size)
223
224struct version_check_context {
225 char * url;
226 int size;
227 int used;
228 char version[OTA_MAX_STRING_LEN];
229};
230
231typedef struct {
232 unsigned int Image_ID;
233 unsigned int Image_In_TIM;
234 unsigned int Flash_partition;
235 unsigned int Flash_erase_size;
236 unsigned int commands;
237 unsigned int First_Sector;
238 unsigned int length;
239 unsigned int Flash_Start_Address;
240 unsigned int reserve[MAX_RESEVERD_LEN];
241 unsigned int ChecksumFormatVersion2;
242} __attribute__((packed)) ImageStruct_11;
243
244typedef ImageStruct_11 * PImageStruct_11;
245
246typedef struct {
247 unsigned int Total_Number_Of_SkipBlocks;
248 unsigned int Size_of_Block[MAX_NUM_SKIP_BLOCKS];
249} SkipBlocksInfoStruct;
250
251typedef struct {
252 unsigned int EraseAll;
253 unsigned int ResetBBT;
254 unsigned int NandID;
255 unsigned int Reserved[MAX_RESEVERD_LEN - 1];
256 SkipBlocksInfoStruct SkipBlocksInfoStruct;
257} FlashOptStruct;
258
259typedef struct {
260 unsigned int DeviceFlags;
261 unsigned int DeviceParametes[16];
262 FlashOptStruct FlashOpt;
263 unsigned int ProductionMode; // production mode
264 unsigned char OptValue; // choice: 0 - Not reset after download, 1 - Reset after download
265 unsigned char ChipID;
266 unsigned char BBCS_EN;
267 unsigned char CRCS_EN;
268 unsigned int Reserved[MAX_RESEVERD_LEN-2];
269 unsigned int nOfImages;
270 ImageStruct_11 imageStruct_11[MAX_NUMBER_OF_FLASH_DEVICES_IN_MASTER_HEADER];
271} __attribute__((packed)) DeviceHeader_11;
272
273typedef DeviceHeader_11 * PDeviceHeader_11;
274
275typedef struct {
276 char Unique[UNIQUE_SIZE];
277 unsigned short int Flash_Device_Spare_Area_Size[NUM_OF_SUPPORTED_FLASH_DEVS];
278 unsigned short int Format_Version;
279 unsigned short int Size_of_Block;
280 unsigned int Bytes_To_Program;
281 unsigned int Bytes_To_Verify;
282 unsigned int Number_of_Bytes_To_Erase;
283 unsigned int Main_Commands;
284 unsigned int nOfDevices;
285 unsigned int DLerVeriosn;
286 unsigned int deviceHeaderOffset[MAX_NUMBER_OF_FLASH_DEVICES_IN_MASTER_HEADER];
287} __attribute__((packed)) MasterBlockHeader;
288
289typedef MasterBlockHeader * PMasterBlockHeader;
290
291struct imginfo_table {
292 unsigned int Img_Len;
293 unsigned int Img_Commands;
294 unsigned int Img_Start_Address;
295 unsigned int Img_Checksum;
296 unsigned int Flash_Start_Address;
297 unsigned int Flash_Erase_Size;
298 unsigned int Img_ID;
299 unsigned int Image_In_TIM;
b.liu9e96ffe2025-04-03 13:28:05 +0800300#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +0800301 int fd;
302 char name[32];
303 char dev[16];
304 unsigned int Img_Remain_Len;
305 unsigned int cs;
306 unsigned int Block_Start_Address;
307 unsigned int partition_size;
308 int erased;
309#endif
310 struct imginfo_table * next;
311};
312
313typedef struct imginfo_table ImginfoTable;
314
315enum {
316 HEADER,
317 CONTENT,
318};
319
320struct image_state {
321 struct imginfo_table * image_info;
322 struct image_state * next_image;
323 int result;
324};
325
326struct image_process_context {
327 ImginfoTable * image_info_table;
328 ImginfoTable * current_process;
329 unsigned int processed_cnt;
330 int state;
331 char * flash_cache;
332 int flash_cache_index;
333 int (*flash_cb)(struct image_process_context *, char *, int);
334 unsigned char * checksum_cache;
335 int checksum_cache_index;
336 unsigned int image_checksum;
337 int ota_download_notification_cnt;
338 struct image_state * image_state_list;
339 int download_result;
340 int fd;
341 int upgrade_method;
342 int dual_tim;
343 int same_tim;
344 int upgrade_bootloader;
345};
346
347typedef struct{
348 unsigned int CurImageID;
349 unsigned int ImageType;
350 unsigned int ImageState; /* 1: new image is backed up, 0: not backed up */
351 unsigned int ImageBkAddr;
352 unsigned int ImageBkLen;
353 unsigned int SegState;
354 unsigned int SegIndex;
355 unsigned int SegDestBkAddr;
356 unsigned int SegDestBkLen;
357 unsigned int PreTailAddr;
358 unsigned int PreTailLen;
359 unsigned int NextHeadAddr;
360 unsigned int NextHeadLen;
361 unsigned int NextSegWriteOffset;
362 unsigned int NextSegReadOffset;
363 unsigned int NextSegEraseOffset;
364}SDfotaState, *pSDfotaState;
365
366struct DeviceHeader_11_tr069 {
367 unsigned int DeviceFlags;
368 unsigned int DeviceParameters[16]; /* Device Parameters, reserve 16 U32 here, will be defined depending on different devices */
369 FlashOptStruct FlashOpt;
370 unsigned int ProductionMode; // production mode
371 unsigned char OptValue; // choice: 0 - Not reset after download, 1 - Reset after download
372 unsigned char ChipID;
373 unsigned char BBCS_EN;
374 unsigned char CRCS_EN;
375 unsigned int Reserved[MAX_RESEVERD_LEN-2];
376 unsigned int nOfImages; /* number of images */
377 ImageStruct_11 imageStruct_11[0]; /* array of image structs */
378} __attribute__((packed)); // Same as struct 'DeviceHeader_11' but the ImageStruct cnt is zero
379
380struct DDRT_STATE{
381 unsigned int test_proc :1; //1: start, 0: done
382 unsigned int last_res :1; //1: fail, 0: pass
383 unsigned int total_times :15;
384 unsigned int fail_times :15;
385};
386
387typedef union{
388 unsigned int value;
389 struct DDRT_STATE bits;
390}DDRTestState, *pDDRTestState;
391
392struct tr069_firmware_flag {
393 unsigned int header;
394 unsigned int upgrade_flag; //1,upgrade; 2, backup boot
395 unsigned int fbf_flash_address;
396 unsigned int fbf_file_size;
397 unsigned int erase_psm;
398 unsigned int erase_psm_address;
399 unsigned int erase_psm_size;
400 unsigned int erase_fs;
401 unsigned int fs_erase_address;
402 unsigned int fs_erase_size;
403 unsigned int upgrade_method; //1,TR069; 2, SD; 3,WebUI
404 unsigned int UnlockKeyFlag;
405 unsigned int production_mode_flag; //for production mode
406 unsigned int eehP[2];
407 unsigned int cpsr[2];
408 unsigned int hawk[2];
409 unsigned int imsd[2];
410 unsigned int pipe[2];
411 unsigned int fast[2];
412 unsigned int apmf[2];
413 unsigned int pid[2];
414 unsigned int vid[2];
415 unsigned int obmdl[2];
416 unsigned int dlflag[2];
417 unsigned int ramdump[2];
418 unsigned int dfota_n_of_images;
419 unsigned int dfota_need_copy_only;
420 unsigned int dfota_conpy_len;
b.liu9e96ffe2025-04-03 13:28:05 +0800421#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +0800422 unsigned int active_slot; /* prev active slot */
423 unsigned int temp_active_slot; /* current active slot */
424 unsigned int reboot_cnt;
425 unsigned int synced;
426 unsigned int rsvd[16];
427#endif
428 unsigned int nocp[2];
429 unsigned int TrustBootStatus;
430 char mversion[128];
431 SDfotaState SDfotaInfo;
432 unsigned int ref_count;
433 unsigned int flag_len;
434 unsigned int version;
435 unsigned int DDR_ID;
436 unsigned int Flash_ID;
437 unsigned int cplog[2];
438 DDRTestState ddrt_state;
439 unsigned int svc_state;
440 char MVersion_B[128]; /* only use for AB system */
441 unsigned int Reserved[68]; /* reserved for asr */
442 unsigned int ReservedForCustomer[35]; /* reserved for customer */
443 /* reserve to make the ASR_Flag length as 1KB */
444
445 unsigned int crc;
446 /* NOTICE !!!
447 * If you change this structure, you must also sync the change to OBM/Uboot/OTA/Telephony
448 * OBM: obm/Common/Misc/asr_flag.h
449 * Uboot: uboot/board/Marvell/common/asr_flag.h
450 * OTA: services/ota/otad.c
451 * Telephony: lte_telephony/apps/cp_load/cploader.h
452 * If add a new member to this structure, must decrease the size of Reserved[]
453 */
454};
455
456#define ASRFLAG_HEADER 0x464F5441
457
458/* ASR Flag version history
459* 1.0.0.1: support dual asr flag
460* 1.0.0.2: support asr flag crc
461*/
462#define ASRFLAG_VERSION_LEGACY 0xFFFFFFFF
463#define ASRFLAG_VERSION_DAF 0x31303031
464#define ASRFLAG_VERSION_CRC 0x31303032
465#define ASRFLAG_VERSION ASRFLAG_VERSION_CRC
466
467struct download_timer_context {
468 int type;
469 int size;
470 int segment_size;
471 char * url;
472 char * username;
473 char * pwd;
474 int file_size;
475 int received_size;
476};
477
478struct download_timer_context download_method_ctx = {0};
479static struct tr069_firmware_flag gAsrFlag;
480
481static int asrflag_daf_enabled(struct tr069_firmware_flag * p_asrflag)
482{
483 if(p_asrflag->version != ASRFLAG_VERSION_LEGACY &&
484 p_asrflag->version >= ASRFLAG_VERSION_DAF)
485 return 1;
486
487 return 0;
488}
489
490static int asrflag_crc_enabled(struct tr069_firmware_flag * p_asrflag)
491{
492 if(p_asrflag->version != ASRFLAG_VERSION_LEGACY &&
493 p_asrflag->version >= ASRFLAG_VERSION_CRC)
494 return 1;
495
496 return 0;
497}
498
499static unsigned int malbrain_crc32(unsigned int crcu32, const unsigned char *ptr, unsigned int buf_len)
500{
501 static const unsigned int s_crc32[16] = {
502 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
503 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
504 };
505 if (!ptr)
506 return 0;
507 crcu32 = ~crcu32;
508 while (buf_len--)
509 {
510 unsigned char b = *ptr++;
511 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
512 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
513 }
514 return ~crcu32;
515}
516
517static void asrflag_update_crc(struct tr069_firmware_flag * p_asrflag)
518{
519 unsigned int crc_len, crc_val;
520 crc_len = sizeof(struct tr069_firmware_flag) - 4; /* 4 bytes is CRC itself */
521
522 crc_val = malbrain_crc32(0, (unsigned char *)p_asrflag, crc_len);
523
524 p_asrflag->crc = crc_val;
525
526 return;
527}
528
529static int asrflag_is_invalid(struct tr069_firmware_flag * p_asrflag)
530{
531 unsigned int crc_len, crc_val;
532
533 if(p_asrflag->header != ASRFLAG_HEADER)
534 return 1;
535
536 if(!asrflag_crc_enabled(p_asrflag))
537 return 0;
538
539 crc_len = sizeof(struct tr069_firmware_flag) - 4; /* 4 bytes is CRC itself */
540 crc_val = malbrain_crc32(0, (unsigned char *)p_asrflag, crc_len);
541
542 if(p_asrflag->crc != crc_val) {
543 OTA_ERR("asr flag mismatch: 0x%x 0x%x\n", crc_val, p_asrflag->crc);
544 return 1;
545 }
546
547 return 0;
548}
549
550static int get_asr_flag(struct tr069_firmware_flag *p_asrflag)
551{
552 int fd = 0, ret = 0;
553 unsigned int step = 0, offset = 0, flaglen = 0;
554 struct tr069_firmware_flag *main_asrflag = NULL;
555 struct tr069_firmware_flag *backup_asrflag = NULL;
556 flaglen = sizeof(struct tr069_firmware_flag);
557
558 main_asrflag = malloc(flaglen);
559 if(main_asrflag == NULL) {
560 OTA_ERR("Fail to malloc\n");
561 return -1;
562 }
563
564 fd = open(server_cfg.mtd_asrflag, O_RDONLY);
565 if (fd < 0) {
566 free(main_asrflag);
567 OTA_ERR("Fatal error: can't open asr flag %s\n", server_cfg.mtd_asrflag);
568 return -1;
569 }
570
571 if (read(fd, main_asrflag, flaglen) < 0)
572 goto error;
573 if ( asrflag_is_invalid(main_asrflag) ) {
574 backup_asrflag = main_asrflag;
575 main_asrflag = NULL;
576
577 step = (server_cfg.block_size)?server_cfg.block_size:0x1000;
578 offset = step;
579
580 while (1) {
581 if(lseek(fd, offset, SEEK_SET) < 0 )
582 goto error;
583 ret = read(fd, backup_asrflag, flaglen);
584 if(ret < 0)
585 goto error;
586
587 if(ret == 0 || !asrflag_is_invalid(backup_asrflag) )
588 break;
589
590 offset += step;
591 }
592
593 /* can't find valid backup ASR Flag */
594 if ( asrflag_is_invalid(backup_asrflag) ) {
595 free(backup_asrflag); backup_asrflag = NULL;
596 }
597 } else {
598 if( asrflag_daf_enabled(main_asrflag) ) {
599 backup_asrflag = malloc(flaglen);
600 if(backup_asrflag != NULL)
601 {
602 if(lseek(fd, main_asrflag->flag_len, SEEK_SET) < 0)
603 goto error;
604
605 if (read(fd, backup_asrflag, flaglen) < 0)
606 goto error;
607
608 if( asrflag_is_invalid(backup_asrflag) )
609 {
610 free(backup_asrflag);
611 backup_asrflag = NULL;
612 }
613 }
614 } else {
615 /* old way which doesn't support backup */
616 memcpy(p_asrflag, main_asrflag, flaglen);
617 close(fd);
618 free(main_asrflag);
619 return 0;
620 }
621 }
622
623 if(main_asrflag == NULL && backup_asrflag == NULL) {
624 goto error;
625 } else if(main_asrflag == NULL) {
626 memcpy(p_asrflag, backup_asrflag, flaglen);
627 } else if (backup_asrflag == NULL) {
628 memcpy(p_asrflag, main_asrflag, flaglen);
629 } else {
630 if(memcmp(main_asrflag, backup_asrflag, flaglen))
631 OTA_ERR("Main asr flag mismatch with backup\n");
632 if(backup_asrflag->ref_count > main_asrflag->ref_count)
633 memcpy(p_asrflag, backup_asrflag, flaglen);
634 else
635 memcpy(p_asrflag, main_asrflag, flaglen);
636 }
637
638 close(fd);
639 if(main_asrflag) free(main_asrflag);
640 if(backup_asrflag) free(backup_asrflag);
641 return 0;
642
643error:
644 close(fd);
645 if(main_asrflag) free(main_asrflag);
646 if(backup_asrflag) free(backup_asrflag);
647 return -1;
648}
649
650static int write_asr_flag(struct tr069_firmware_flag *p_asrflag)
651{
652 unsigned int flaglen = 0;
653 int n = 0;
654 int fd = open(server_cfg.mtd_asrflag, O_RDWR);
655 if (fd < 0) {
656 OTA_ERR("Fatal error: can't open asr flag %s\n", server_cfg.mtd_asrflag);
657 return -1;
658 }
659
660 flaglen = sizeof(struct tr069_firmware_flag);
661 if (p_asrflag->ref_count ++ == 0xFFFFFFFF)
662 p_asrflag->ref_count = 0;
663
664 asrflag_update_crc(p_asrflag);
665
666 n = write(fd, p_asrflag, flaglen);
667 if (n != flaglen) {
668 OTA_ERR("Fatal error: write %d bytes(expect %d) to asr flag\n", n, sizeof(gAsrFlag));
669 close(fd);
670 return -1;
671 }
672
673 if( asrflag_daf_enabled(p_asrflag) ) {
674 lseek(fd, p_asrflag->flag_len, SEEK_SET);
675
676 n = write(fd, p_asrflag, flaglen);
677 if (n != flaglen) {
678 OTA_ERR("Fatal error: write %d bytes(expect %d) to asr flag\n", n, sizeof(gAsrFlag));
679 close(fd);
680 return -1;
681 }
682 }
683
684 close(fd);
685 return 0;
686}
687
b.liu9e96ffe2025-04-03 13:28:05 +0800688#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +0800689static int get_inactive_system()
690{
691 if (get_asr_flag(&gAsrFlag)) {
692 OTA_ERR("Fatal error: can't read asr flag %s\n", server_cfg.mtd_asrflag);
693 return -1;
694 }
695
696 OTA_DEBUG("Asr Flag: active_slot: %c(0x%x), temp_active_slot: %c(0x%x), reboot_cnt: %d, synced: %d\n",
697 gAsrFlag.active_slot, gAsrFlag.active_slot,
698 gAsrFlag.temp_active_slot, gAsrFlag.temp_active_slot,
699 gAsrFlag.reboot_cnt, gAsrFlag.synced);
700
701 if (gAsrFlag.active_slot != gAsrFlag.temp_active_slot) {
702 OTA_DEBUG("System %c is valid, now update the active slot...\n", gAsrFlag.temp_active_slot);
703 gAsrFlag.active_slot = gAsrFlag.temp_active_slot;
704 gAsrFlag.reboot_cnt = 0;
705 gAsrFlag.synced = 0;
706 if (write_asr_flag(&gAsrFlag)) {
707 OTA_ERR("Fatal error: fail to write asr flag\n");
708 return -1;
709 }
710 } else {
711 if (gAsrFlag.synced == 0) {
712 /* if active_slot == temp_active_slot & synced = 0, the system rollback must happened */
713 gSystemHasRollbackFlag = 1;
714 }
715 }
716 if (gAsrFlag.temp_active_slot == SYSTEM_B)
717 return SYSTEM_A;
718 return SYSTEM_B;
719}
720
721static int complete_read(int fd, char *buf, int size)
722{
723 int pos = 0;
724 while (pos != size) {
725 int n = read(fd, buf + pos, size - pos);
726 if (n < 0) {
727 OTA_ERR("Fatal error: read failed: %d...\n", n);
728 return -1;
729 }
730 pos += n;
731 }
732
733 return pos;
734}
735
736static int complete_write(int fd, char *buf, int size)
737{
738 int pos = 0;
739 while (pos != size) {
740 int n = write(fd, buf + pos, size - pos);
741 if (n < 0) {
742 OTA_ERR("Fatal error: write failed: %d...\n", n);
743 return -1;
744 }
745 pos += n;
746 }
747
748 return pos;
749}
750
751static int __system_compare(char *src, char *dst, int size, int erasesize)
752{
753 char sdev[32] = {0}, ddev[32] = {0};
754 sprintf(sdev, "/dev/%s", src);
755 sprintf(ddev, "/dev/%s", dst);
756 int fdSrc = open(sdev, O_RDWR | O_SYNC);
757 int fdDst = open(ddev, O_RDWR | O_SYNC);
758
759 int ret = -1;
760 char *sbuf = NULL, *dbuf = NULL;
761 if (fdSrc < 0 || fdDst < 0) {
762 OTA_ERR("Fatal error: can't open dev, src: %s, fdSrc: %d, dst: %s, fdDst: %d\n",
763 src, fdSrc, dst, fdDst);
764 goto err;
765 }
766
767 sbuf = malloc(erasesize);
768 if (!sbuf) {
769 OTA_ERR("Fatal error: can't malloc 0x%x for src buf\n", erasesize);
770 goto err;
771 }
772
773 dbuf = malloc(erasesize);
774 if (!dbuf) {
775 OTA_ERR("Fatal error: can't malloc 0x%x for dst buf\n", erasesize);
776 goto err;
777 }
778
779 OTA_DEBUG("Src: %s, Dst: %s, Size: 0x%x...\n", sdev, ddev, size);
780 while (size) {
781 int n = erasesize;
782 if (size < erasesize)
783 n = size;
784 memset(sbuf, 0, erasesize);
785 memset(dbuf, 0, erasesize);
786
787 if (complete_read(fdSrc, sbuf, n) < 0)
788 goto err;
789 if (complete_read(fdDst, dbuf, n) < 0)
790 goto err;
791
792 if (memcmp(sbuf, dbuf, n) != 0) {
793 OTA_ERR("Src: %s, Dst: %s, are not same, NEED to sync\n", sdev, ddev);
794 goto err;
795 }
796 size -= n;
797 }
798
799 ret = 0;
800 OTA_DEBUG("Src: %s, Dst: %s, are same, NO NEED to sync\n", sdev, ddev);
801err:
802 if (fdSrc >= 0)
803 close(fdSrc);
804 if (fdDst >= 0)
805 close(fdDst);
806 if (sbuf)
807 free(sbuf);
808 if (dbuf)
809 free(dbuf);
810 return ret;
811}
812
813static int __system_sync(char *src, char *dst, int size, int erasesize)
814{
815 if (__system_compare(src, dst, size, erasesize) == 0)
816 return 0;
817
818 int ret = -1;
819 char *buf = NULL;
820 char sdev[32] = {0}, ddev[32] = {0};
821 sprintf(sdev, "/dev/%s", src);
822 sprintf(ddev, "/dev/%s", dst);
823 int fdSrc = open(sdev, O_RDWR | O_SYNC);
824 int fdDst = open(ddev, O_RDWR | O_SYNC);
b.liu9e96ffe2025-04-03 13:28:05 +0800825#if 1//ndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +0800826 struct erase_info_user mtdEraseInfo;
827 struct mtd_info_user mtdInfo;
828 if (ioctl(fdDst, MEMGETINFO, &mtdInfo)) {
829 OTA_ERR("Could not get MTD device info from %s\n", ddev);
830 goto err;
831 }
832 mtdEraseInfo.start = 0;
833 mtdEraseInfo.length = mtdInfo.erasesize;
834#endif
835 if (fdSrc < 0 || fdDst < 0) {
836 OTA_ERR("Fatal error: can't open dev, src: %s, fdSrc: %d, dst: %s, fdDst: %d\n",
837 src, fdSrc, dst, fdDst);
838 goto err;
839 }
840
841 buf = malloc(erasesize);
842 if (!buf) {
843 OTA_ERR("Fatal error: can't malloc 0x%x\n", erasesize);
844 goto err;
845 }
846
847 OTA_DEBUG("Sync Src: %s to Dst: %s, Size: 0x%x...\n", sdev, ddev, size);
848 while (size) {
849 int n = erasesize;
850 if (size < erasesize)
851 n = size;
852 memset(buf, 0, erasesize);
853
854 if (complete_read(fdSrc, buf, n) < 0)
855 goto err;
b.liu9e96ffe2025-04-03 13:28:05 +0800856//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +0800857 ioctl(fdDst, MEMUNLOCK, &mtdEraseInfo);
858 ioctl(fdDst, MEMERASE, &mtdEraseInfo);
b.liu9e96ffe2025-04-03 13:28:05 +0800859//#endif
b.liua76c9612025-03-28 13:58:09 +0800860 if (complete_write(fdDst, buf, n) < 0)
861 goto err;
862 size -= n;
b.liu9e96ffe2025-04-03 13:28:05 +0800863//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +0800864 mtdEraseInfo.start += mtdInfo.erasesize;
b.liu9e96ffe2025-04-03 13:28:05 +0800865//#endif
b.liua76c9612025-03-28 13:58:09 +0800866 }
867
868 ret = 0;
869err:
870 if (fdSrc >= 0)
871 close(fdSrc);
872 if (fdDst >= 0)
873 close(fdDst);
874 if (buf)
875 free(buf);
876 return ret;
877}
878
b.liu9e96ffe2025-04-03 13:28:05 +0800879#if 1//!defined(CONFIG_AB_SYSTEM_DFOTA)
b.liua76c9612025-03-28 13:58:09 +0800880static int get_file_size(const char *path)
881{
882 int filesize = -1;
883 struct stat statbuff;
884 if(stat(path, &statbuff) < 0)
885 return filesize;
886 else
887 filesize = statbuff.st_size;
888 return filesize;
889}
b.liu49596152025-03-31 14:02:15 +0800890#endif
b.liua76c9612025-03-28 13:58:09 +0800891
892static int system_sync()
893{
894 int changed = 0;
895
896 OTA_DEBUG("Start to sync system %c to %c...\n", gAsrFlag.temp_active_slot, gInActiveSystem);
897 for (int i = 0; i < server_cfg.mtd_cnt; i++) {
898 struct image_mtd_info *pSrc = &server_cfg.image_mtd_info[i];
899 if (pSrc->flag == gAsrFlag.active_slot) {
900 for (int j = 0; j < server_cfg.mtd_cnt; j++) {
901 struct image_mtd_info *pDst = &server_cfg.image_mtd_info[j];
902 if (pDst->flag == gInActiveSystem) {
903 if (strlen(pSrc->name) == strlen(pDst->name)) {
904 int len = strlen(pSrc->name);
905 if (strncmp(pSrc->name, pDst->name, len - 3) == 0) {
906 /* remove the suffix "-a\n" or "-b\n", 3 bytes */
907 OTA_DEBUG("Start to sync %s to %s...\n", pSrc->name, pDst->name);
908 if (__system_sync(pSrc->dev, pDst->dev, pDst->size, pDst->erasesize) < 0) {
909 OTA_ERR("Fatal error: sync failed...\n");
910 return -1;
911 }
912 OTA_DEBUG("Sync %s to %s OK...\n", pSrc->name, pDst->name);
913 break;
914 }
915 }
916 }
917 }
918 }
919 }
920
921 if (strncmp(gAsrFlag.mversion, gAsrFlag.MVersion_B, 128) != 0) {
922 changed = 1;
923 OTA_DEBUG("diff mversion a: %s, mversion b: %s\n", gAsrFlag.mversion, gAsrFlag.MVersion_B);
924 if (gInActiveSystem == SYSTEM_A) {
925 OTA_DEBUG("mversion b -> a\n");
926 memset(gAsrFlag.mversion, 0, 128);
927 strncpy(gAsrFlag.mversion, gAsrFlag.MVersion_B, 128);
928 } else {
929 OTA_DEBUG("mversion a -> b\n");
930 memset(gAsrFlag.MVersion_B, 0, 128);
931 strncpy(gAsrFlag.MVersion_B, gAsrFlag.mversion, 128);
932 }
933 }
934
935 OTA_DEBUG("System sync done, update the synced flag...\n");
936 if (!changed && gAsrFlag.synced == 1) {
937 /* no need to save flag to flash if synced flag is 1
938 * directly return to decrease write flash */
939 OTA_DEBUG("The synced flag was set already, no need to update.\n");
940 return 0;
941 }
942
943 gAsrFlag.synced = 1;
944 gAsrFlag.reboot_cnt = 0;
945
946 OTA_DEBUG("Save Asr Flag: active_slot: %c(0x%x), temp_active_slot: %c(0x%x), reboot_cnt: %d, synced: %d\n",
947 gAsrFlag.active_slot, gAsrFlag.active_slot,
948 gAsrFlag.temp_active_slot, gAsrFlag.temp_active_slot,
949 gAsrFlag.reboot_cnt, gAsrFlag.synced);
950 return write_asr_flag(&gAsrFlag);
951}
952
953#endif
954
955
956static int tr069_fbf_parse(void * img_addr, int len, struct image_process_context * context)
957{
958 MasterBlockHeader* pMasterHeader = NULL;
959 PDeviceHeader_11 pDevHeader_11=NULL;
960 PImageStruct_11 pImage_11=NULL;
961 ImginfoTable * image_table = NULL, * temp_table = NULL;
962
963 unsigned int * temp_p = NULL;
964 unsigned int img_num,img_start;
965
966 pMasterHeader = (MasterBlockHeader*)img_addr;
967 if ((pMasterHeader->Format_Version != 11)) {
968 OTA_ERR("Bad version\n");
969 return -1;
970 }
971
972 if (pMasterHeader->nOfDevices != 1) {
973 OTA_ERR("Bad content\n");
974 return -1;
975 }
976
977 if ((len + context->processed_cnt) < sizeof(MasterBlockHeader)) {
978 return len;
979 }
980
981 if ((len + context->processed_cnt) <
982 (pMasterHeader->deviceHeaderOffset[0] + sizeof(struct DeviceHeader_11_tr069))) {
983 OTA_ERR("length less than device offset[%d:%d]\n",
984 pMasterHeader->deviceHeaderOffset[0], sizeof(struct DeviceHeader_11_tr069));
985 return len;
986 }
987
988 {
989 // Checking FBF vesion string, if present
990 const char * version = (const char *)&pMasterHeader->Unique[12];
991 if (strlen(version)) OTA_DEBUG("Handle FBF version: %s\n", version);
992 if (fbf_version_string) {
993 if (strcmp(fbf_version_string, version)) {
994 OTA_ERR("Version not match: %s\n", fbf_version_string);
995 return -1;
996 }
997 }
998 }
999
1000 temp_p = (unsigned int *)(pMasterHeader->deviceHeaderOffset[0] + (unsigned int)img_addr);
1001 pDevHeader_11 = (PDeviceHeader_11)temp_p;
1002 OTA_DEBUG("parsed image number is :%d\n", pDevHeader_11->nOfImages);
1003 if ((len + context->processed_cnt) <
1004 (pMasterHeader->deviceHeaderOffset[0] + sizeof(struct DeviceHeader_11_tr069) +
1005 sizeof(ImageStruct_11) * pDevHeader_11->nOfImages)) {
1006 return len;
1007 }
1008
1009 update_oemd = 0;
1010 for(img_num = 0; img_num < pDevHeader_11->nOfImages; img_num ++) {
1011 temp_p = (unsigned int*)&pDevHeader_11->imageStruct_11[img_num];
1012 pImage_11 = (PImageStruct_11)temp_p;
1013 img_start = pImage_11->First_Sector<<TR069_FBF_HEADER_SIZE;
1014
1015 temp_table = image_table;
b.liu9e96ffe2025-04-03 13:28:05 +08001016#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08001017 if (pImage_11->Image_ID == FOTA_FBFVERSION_IMAGEID) {
1018 server_cfg.fotav_offset_in_fbf = img_start;
1019 OTA_DEBUG("%s: fotav_offset_in_fbf = 0x%x\n", __func__, server_cfg.fotav_offset_in_fbf);
1020 }
1021
1022 if (pImage_11->reserve[0] != 0) {
1023 OTA_DEBUG("Found A/B Image, ID: 0x%x, InTim: %d, "
1024 "Partition: 0x%x, EraseSize: 0x%x, "
1025 "CMD: 0x%x, FirstSector: 0x%x, Len: 0x%x, "
1026 "FlashStartAddress(A): 0x%x, FlashStartAddress(B): 0x%x, "
1027 "CheckSum: 0x%x\n",
1028 pImage_11->Image_ID, pImage_11->Image_In_TIM,
1029 pImage_11->Flash_partition, pImage_11->Flash_erase_size,
1030 pImage_11->commands, pImage_11->First_Sector, pImage_11->length,
1031 pImage_11->Flash_Start_Address, pImage_11->reserve[0],
1032 pImage_11->ChecksumFormatVersion2);
1033
1034 if (gInActiveSystem == SYSTEM_B) {
1035 /* there are no flash address B for obm & timh */
1036 if (pImage_11->Image_ID != IMAGE_ID_TIMH && pImage_11->Image_ID != IMAGE_ID_OBM)
1037 pImage_11->Flash_Start_Address = pImage_11->reserve[0];
1038 }
1039 }
1040
1041 if (pImage_11->Image_ID == IMAGE_ID_OBM)
1042 obm_real_size = pImage_11->length;
1043
b.liu9e96ffe2025-04-03 13:28:05 +08001044#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08001045 /* the unit of address in fbf was: block */
1046 pImage_11->Flash_Start_Address *= server_cfg.emmc_block_size;
1047#endif
1048
1049 int i;
1050 struct image_mtd_info *pImageMtdInfo = NULL;
1051 for (i = 0; i < server_cfg.mtd_cnt; i++) {
1052 pImageMtdInfo = &server_cfg.image_mtd_info[i];
1053 if (pImage_11->Image_ID == IMAGE_ID_TIMH || pImage_11->Image_ID == IMAGE_ID_OBM) {
1054 context->upgrade_bootloader = 1;
1055 #ifdef CONFIG_PARTITION_EMMC
1056 if (pImage_11->Image_In_TIM == TIMH_INC) {
1057 if (strstr(pImageMtdInfo->name, "bootloader0"))
1058 goto found_bootloader;
1059 } else if (pImage_11->Image_In_TIM == TIMH_RECOVERY_INC) {
1060 if (strstr(pImageMtdInfo->name, "bootloader1"))
1061 goto found_bootloader;
1062 } else {
1063 exit(-1);
1064 }
1065 #else
1066 if (strstr(pImageMtdInfo->name, "bootloader"))
1067 goto found_bootloader;
1068 #endif
1069 }
1070
1071 if (gInActiveSystem != pImageMtdInfo->flag)
1072 /* skip the active system mtd */
1073 continue;
1074 if ((pImageMtdInfo->flash_start_offset == pImage_11->Flash_Start_Address) ||
1075 (
1076 /* handle cpimage */
1077 (pImage_11->Flash_Start_Address > pImageMtdInfo->flash_start_offset) &&
1078 (pImage_11->Flash_Start_Address < (pImageMtdInfo->flash_start_offset + pImageMtdInfo->size))
1079 )) {
1080 break;
1081 }
1082 }
1083
1084 if (i == server_cfg.mtd_cnt) {
1085 OTA_ERR("FBF is not match the current system...(0x%x)\n", pImage_11->Flash_Start_Address);
1086 continue;
1087 }
1088found_bootloader:
1089#endif
1090 image_table = (ImginfoTable *)malloc(sizeof(ImginfoTable));
1091 if (!image_table) {
1092 OTA_ERR("Failed! cannot malloc memory for image infor table\n");
1093 return -1;
1094 }
1095
1096 image_table->Img_Len= pImage_11->length;
1097 image_table->Img_Commands = pImage_11->commands;
1098 image_table->Img_Checksum = pImage_11->ChecksumFormatVersion2;
1099 image_table->Flash_Erase_Size = pImage_11->Flash_erase_size;
1100 image_table->Img_Start_Address = img_start;
1101 image_table->Flash_Start_Address = pImage_11->Flash_Start_Address;
1102 image_table->Img_ID = pImage_11->Image_ID;
1103 image_table->Image_In_TIM = pImage_11->Image_In_TIM;
1104 if (pImage_11->Image_ID == OEMDDENTIFIER)
1105 update_oemd = 1;
1106 image_table->next = temp_table;
b.liu9e96ffe2025-04-03 13:28:05 +08001107#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08001108 char dev[32] = {0};
1109 sprintf(dev, "/dev/%s", pImageMtdInfo->dev);
1110 if (image_table->Img_ID == IMAGE_ID_OBM) {
1111 if (image_table->Image_In_TIM == TIMH_INC)
1112 image_table->fd = open(tmp_obm_main_file, O_CREAT | O_RDWR | O_SYNC, 777);
1113 else if (image_table->Image_In_TIM == TIMH_RECOVERY_INC) {
1114 image_table->fd = open(tmp_obm_bk_file, O_CREAT | O_RDWR | O_SYNC, 777);
1115 context->dual_tim = 1;
1116 } else {
1117 OTA_ERR("%s %d: fatal error, unkown Image_In_TIM: %d\n",
1118 __func__, __LINE__, image_table->Image_In_TIM);
1119 exit(-1);
1120 }
1121 } else if (image_table->Img_ID == IMAGE_ID_TIMH) {
1122 if (image_table->Image_In_TIM == TIMH_INC)
1123 image_table->fd = open(tmp_timh_main_file, O_CREAT | O_RDWR | O_SYNC, 777);
1124 else if (image_table->Image_In_TIM == TIMH_RECOVERY_INC) {
1125 image_table->fd = open(tmp_timh_bk_file, O_CREAT | O_RDWR | O_SYNC, 777);
1126 context->dual_tim = 1;
1127 } else {
1128 OTA_ERR("%s %d: fatal error, unkown Image_In_TIM: %d\n",
1129 __func__, __LINE__, image_table->Image_In_TIM);
1130 exit(-1);
1131 }
1132 } else {
1133 image_table->fd = open(dev, O_RDWR | O_SYNC);
1134 }
1135 image_table->partition_size = pImageMtdInfo->size;
1136 image_table->erased = 0;
1137 memset(image_table->dev, 0, sizeof(image_table->dev));
1138 memset(image_table->name, 0, sizeof(image_table->name));
1139 sprintf(image_table->dev, "%s", pImageMtdInfo->dev);
1140 sprintf(image_table->name, "%s", pImageMtdInfo->name);
1141 /* 4K align */
1142 image_table->Img_Remain_Len = ((image_table->Img_Len + FBF_FILE_SECTOR_SIZE - 1) & (~ (FBF_FILE_SECTOR_SIZE - 1)));
1143 image_table->Block_Start_Address = pImageMtdInfo->flash_start_offset;
1144 OTA_DEBUG("Parse new image: start: 0x%08x, len: 0x%08x(flash offset: 0x%08x, %s)\n", img_start, image_table->Img_Len,
1145 image_table->Flash_Start_Address, pImageMtdInfo->name);
1146#else
1147 OTA_DEBUG("Parse new image: 0x%08x~0x%08x\n", img_start, img_start + image_table->Img_Len);
1148#endif
1149 }
1150
1151 context->image_info_table = image_table;
1152 if(pDevHeader_11->Reserved[0] == 1){ //DFota
1153 context->upgrade_method = 4;
1154 }
1155 else{
1156 context->upgrade_method = 0;
1157 }
1158
1159 OTA_DEBUG(" first offset: %d\n", pMasterHeader->deviceHeaderOffset[0]);
1160 OTA_DEBUG(" all header size: %d\n", (pMasterHeader->deviceHeaderOffset[0] + sizeof(struct DeviceHeader_11_tr069) +
1161 sizeof(ImageStruct_11) * pDevHeader_11->nOfImages));
1162 OTA_DEBUG(" already processed: %d\n", context->processed_cnt);
b.liu9e96ffe2025-04-03 13:28:05 +08001163//#ifdef CONFIG_AB_SYSTEM
1164//#ifndef CONFIG_AB_SYSTEM_DFOTA
b.liua76c9612025-03-28 13:58:09 +08001165 /* once parse image ok, clear the synced flag immediately */
b.liu9e96ffe2025-04-03 13:28:05 +08001166 if(!is_dfota) {
1167 gAsrFlag.synced = 0;
1168 write_asr_flag(&gAsrFlag);
1169 }
1170//#endif
1171//#endif
b.liua76c9612025-03-28 13:58:09 +08001172 return (pMasterHeader->deviceHeaderOffset[0] + sizeof(struct DeviceHeader_11_tr069) +
1173 sizeof(ImageStruct_11) * pDevHeader_11->nOfImages) - context->processed_cnt;
1174}
1175
1176static void dump_table(struct image_process_context * context)
1177{
1178 ImginfoTable * temp = context->image_info_table;
1179 while (temp) {
b.liu9e96ffe2025-04-03 13:28:05 +08001180#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08001181 OTA_DEBUG("Get Image from start: 0x%08x, len: 0x%08x, flashoffset: 0x%08x(%s)\n",
1182 temp->Img_Start_Address, temp->Img_Len, temp->Flash_Start_Address, temp->name);
1183#else
1184 OTA_DEBUG("Get Image from 0x%08x to 0x%08x\n", temp->Img_Start_Address, temp->Img_Start_Address + temp->Img_Len);
1185#endif
1186 temp = temp->next;
1187 }
1188}
1189
1190static int build_image_list(struct image_process_context * context)
1191{
1192 struct imginfo_table * table = context->image_info_table;
1193
1194 while (table) {
1195 struct image_state * temp = malloc(sizeof(struct image_state));
1196 struct image_state * backup = context->image_state_list;
1197 if (!temp) {
1198 OTA_ERR("Cannot malloc memory..\n");
1199 return -1;
1200 }
1201 temp->result = 0; // Mask this image is not download
1202 temp->next_image = backup;
1203 temp->image_info = table;
1204 context->image_state_list = temp;
1205 table = table->next;
1206 }
1207 return 0;
1208}
1209
1210static int free_image_list(struct image_process_context * context)
1211{
1212 struct image_state * temp = context->image_state_list;
1213 while (temp) {
1214 struct image_state * backup = temp->next_image;
b.liu9e96ffe2025-04-03 13:28:05 +08001215//#if defined(CONFIG_AB_SYSTEM) && !defined(CONFIG_AB_SYSTEM_DFOTA)
1216 if(!is_dfota) {
1217 close(temp->image_info->fd);
1218 temp->image_info->fd = -1;
1219 }
1220//#endif
b.liua76c9612025-03-28 13:58:09 +08001221 free(temp);
1222 temp = backup;
1223 }
1224 return 0;
1225}
1226
1227static unsigned int fbf_checksum(unsigned char * src, unsigned int len, unsigned int checksum)
1228{
1229 unsigned int * start = (unsigned int *)src;
1230 unsigned int * end = (unsigned int *)(src + len);
1231 while (start < end) {
1232 checksum ^= (*start++);
1233 }
1234 return checksum;
1235}
1236
b.liu9e96ffe2025-04-03 13:28:05 +08001237#if 1//!defined(CONFIG_AB_SYSTEM) || defined(CONFIG_AB_SYSTEM_DFOTA)
b.liua76c9612025-03-28 13:58:09 +08001238static int mark_current_image_processed(struct image_process_context * context)
1239{
1240 struct image_state * temp = context->image_state_list;
1241 while (temp) {
1242 if (temp->image_info == context->current_process) {
1243 temp->result = 1; // Mark it be processed
1244 return 0;
1245 }
1246 temp = temp->next_image;
1247 }
1248 OTA_ERR("Why cannot find the processed image?\n");
1249 return -1;
1250}
1251
1252static int image_check(struct image_process_context * context, char * data, int len)
1253{
1254 int size, cnt;
1255 // First check the data belong to same image
1256 size = (context->processed_cnt + len - context->current_process->Img_Start_Address) >= context->current_process->Img_Len ?
1257 context->current_process->Img_Start_Address + context->current_process->Img_Len - context->processed_cnt : len;
1258 cnt = size;
1259
1260 while (cnt) {
1261 if ((context->checksum_cache_index + cnt) >= CHECKSUM_CACHE_SIZE) {
1262 int space = CHECKSUM_CACHE_SIZE - context->checksum_cache_index;
1263 memcpy(context->checksum_cache + context->checksum_cache_index, data, space);
1264 context->image_checksum = fbf_checksum(context->checksum_cache, CHECKSUM_CACHE_SIZE, context->image_checksum);
1265 data += space;
1266 cnt -= space;
1267 context->checksum_cache_index = 0;
1268 } else {
1269 memcpy(context->checksum_cache + context->checksum_cache_index, data, cnt);
1270 context->checksum_cache_index += cnt;
1271 cnt -= cnt;
1272 }
1273 }
1274
1275 if ((context->processed_cnt + len - context->current_process->Img_Start_Address) >= context->current_process->Img_Len) {
1276 OTA_DEBUG("Handle image end...\n");
1277 if (context->checksum_cache_index != 0) {
1278 context->image_checksum = fbf_checksum(context->checksum_cache, context->checksum_cache_index, context->image_checksum);
1279 }
1280 OTA_DEBUG(" Image[%08x] checksum 0x%08x:0x%08x\n", context->current_process->Img_ID, context->current_process->Img_Checksum, context->image_checksum);
1281 if (context->current_process->Img_Checksum == context->image_checksum) {
1282 mark_current_image_processed(context);
1283 } else if (context->current_process->Img_ID == RSA_IMAGE_ID) {
1284 OTA_DEBUG(" RSA image, always mark to pass\n");
1285 mark_current_image_processed(context);
1286 } if (context->current_process->Img_Checksum == 0) {
1287 OTA_DEBUG(" RAW checksum is zero, always mark to pass\n");
1288 mark_current_image_processed(context);
1289 }
1290 context->checksum_cache_index = 0;
1291 context->current_process = 0;
1292 context->image_checksum = 0;
1293 }
1294 context->processed_cnt += size;
1295 return size;
1296}
1297#endif
1298static void notify_progress(int progress)
1299{
1300 char buf[128] = {0};
1301 snprintf(buf, 128, "progress[%d]", progress);
1302 blob_buf_init(&b, 0);
1303 blobmsg_add_string(&b, "notification", buf);
1304 ubus_notify(ctx, &ota_object, "notification", b.head, -1);
1305}
1306
1307static void notify_download_start(void)
1308{
1309 blob_buf_init(&b, 0);
1310 blobmsg_add_string(&b, "notification", "start");
1311 ubus_notify(ctx, &ota_object, "notification", b.head, -1);
1312}
1313
1314static void notify_download_end(int success)
1315{
1316 char buf[128] = {0};
1317 snprintf(buf, 128, "end[%d]", !!success);
1318 blob_buf_init(&b, 0);
1319 blobmsg_add_string(&b, "notification", buf);
1320 ubus_notify(ctx, &ota_object, "notification", b.head, -1);
1321}
1322
1323static int firmware_download_cb(char * data, int len, int num, void *cbdata)
1324{
1325 struct image_process_context * context = (struct image_process_context *)cbdata;
1326 int ret = 0;
1327 unsigned int temp = 0;
1328 int total=0;
1329 if(download_method_ctx.type == OTA_TYPE_UDP){
1330 download_method_ctx.received_size +=len;
1331 _ota_download_progress = download_method_ctx.received_size;
1332 total = download_method_ctx.file_size;
1333 }else{
1334 _ota_download_progress += len;
1335 total = num;
1336 }
1337 temp = (_ota_download_progress * 100);
1338 ota_download_progress = (temp / total);
1339 if (ota_download_progress >= 100) {
1340 ota_download_progress = 99;
1341 }
1342 if ((ota_download_progress - context->ota_download_notification_cnt) >= server_cfg.progress_notify) {
1343 OTA_DEBUG("OTA download progress %d\n", context->ota_download_notification_cnt);
1344 context->ota_download_notification_cnt = ota_download_progress;
1345 notify_progress(context->ota_download_notification_cnt);
1346 }
b.liu9e96ffe2025-04-03 13:28:05 +08001347// #if defined(CONFIG_AB_SYSTEM) && !defined(CONFIG_AB_SYSTEM_DFOTA)
1348 if(!is_dfota) {
1349 /* len = 4096 for every packet except for the last one */
1350 if (total <= FBF_FILE_SECTOR_SIZE) {
1351 OTA_ERR("Error file total size %d...\n", total);
1352 return -1;
1353 }
b.liua76c9612025-03-28 13:58:09 +08001354
b.liu9e96ffe2025-04-03 13:28:05 +08001355 /* 1. FBF Head sit one the first sector of the FBF file, check it */
1356 if (context->state == HEADER) {
1357 ret = tr069_fbf_parse(data, len, context);
1358 if (ret < 0) {
1359 OTA_ERR("Failed, fbf parse failed...\n");
1360 return -1;
1361 }
b.liua76c9612025-03-28 13:58:09 +08001362
b.liu9e96ffe2025-04-03 13:28:05 +08001363 if (context->image_info_table) {
1364 context->state = CONTENT;
1365 dump_table(context);
1366 // Build image list for trace all image download result
1367 build_image_list(context);
1368 }
1369 context->processed_cnt = len;
1370 } else if (context->state == CONTENT) {
1371 if (context->processed_cnt < 0x2000) {
1372 OTA_DEBUG("skip 2nd 4K...\n");
1373 // Add by liubin
1374 revision_out_find(data, len, context->processed_cnt);
1375 // End by liubin
b.liua76c9612025-03-28 13:58:09 +08001376
b.liu9e96ffe2025-04-03 13:28:05 +08001377 context->processed_cnt += len;
1378 return 0;
1379 }
b.liua76c9612025-03-28 13:58:09 +08001380
b.liu9e96ffe2025-04-03 13:28:05 +08001381 if (context->flash_cache_index < server_cfg.block_size) {
1382 /* flash_cache_index increase by 4096 */
1383 char *pos = context->flash_cache + context->flash_cache_index;
1384 memcpy(pos, data, len); // len = 4096 here
1385 context->flash_cache_index += len;
1386 context->processed_cnt += len;
1387 }
b.liua76c9612025-03-28 13:58:09 +08001388
b.liu9e96ffe2025-04-03 13:28:05 +08001389 if (server_cfg.fotav_offset_in_fbf &&
1390 context->processed_cnt == (server_cfg.fotav_offset_in_fbf + 0x1000))
1391 {
1392 memcpy(server_cfg.fotav, context->flash_cache, 128);
1393 temp = strlen(server_cfg.fotav);
1394 if (server_cfg.fotav[temp - 1] == ';')
1395 server_cfg.fotav[temp - 1] = 0; /* remove last ; */
1396 OTA_DEBUG("%s: got fota version: %s\n", __func__, server_cfg.fotav);
1397 if (upgrade_precheck(server_cfg.fotav))
1398 exit(-1);
1399 }
b.liua76c9612025-03-28 13:58:09 +08001400
b.liu9e96ffe2025-04-03 13:28:05 +08001401 //if (context->flash_cache_index == server_cfg.block_size) {
1402 /* flush the cache to flash */
1403 ImginfoTable *p;
1404 p = context->image_info_table;
1405 while (p)
1406 {
1407 int image_len = p->Img_Len;
1408 // bool flush_cache = false;
1409 /* FBF_FILE_SECTOR_SIZE alignment */
1410 image_len = ((image_len + FBF_FILE_SECTOR_SIZE - 1) & (~ (FBF_FILE_SECTOR_SIZE - 1)));
1411 int total_block = ((image_len + server_cfg.block_size - 1) & (~ (server_cfg.block_size - 1))) / server_cfg.block_size;
1412 if (context->processed_cnt > p->Img_Start_Address) {
1413 if (context->processed_cnt < (p->Img_Start_Address + image_len)) {
1414 if (context->flash_cache_index < server_cfg.block_size) {
1415 break;
1416 }
1417 }
1418 if (context->processed_cnt == (p->Img_Start_Address + image_len) ||
1419 context->flash_cache_index == server_cfg.block_size) {
1420 p->cs = fbf_checksum((unsigned char *)context->flash_cache, context->flash_cache_index, p->cs);
1421 int offset = context->processed_cnt - p->Img_Start_Address;
1422 struct erase_info_user mtdEraseInfo;
1423 offset += p->Flash_Start_Address - p->Block_Start_Address;
1424 int block = ((offset + server_cfg.block_size - 1) & (~ (server_cfg.block_size - 1))) / server_cfg.block_size;
1425 int start = server_cfg.block_size * (block - 1);
1426 OTA_DEBUG("@ context->processed_cnt: 0x%x, p->Img_Start_Address: 0x%x, len: 0x%x, start: 0x%x\n",
1427 context->processed_cnt, p->Img_Start_Address, image_len, start);
1428 OTA_DEBUG("@ found, dev: %s, name: %s, block: %d(total: %d), cs: 0x%x(expect: 0x%x), index: 0x%x\n",
1429 p->dev, p->name, block - 1,total_block,p->cs, p->Img_Checksum, context->flash_cache_index);
b.liua76c9612025-03-28 13:58:09 +08001430
b.liu9e96ffe2025-04-03 13:28:05 +08001431 if (p->fd < 0) {
1432 OTA_ERR("mtd device open failed...\n");
1433 return -1;
1434 }
b.liua76c9612025-03-28 13:58:09 +08001435
b.liu9e96ffe2025-04-03 13:28:05 +08001436 if (p->erased == 0 && strstr(p->name, "oem_data")) {
1437 OTA_DEBUG("Need to Erase all of %s(%s)\n", p->dev, p->name);
1438 mtdEraseInfo.length = p->partition_size;
1439 mtdEraseInfo.start = 0;
1440 #ifndef CONFIG_PARTITION_EMMC
1441 ioctl(p->fd, MEMUNLOCK, &mtdEraseInfo);
1442 ioctl(p->fd, MEMERASE, &mtdEraseInfo);
1443 #endif
1444 p->erased = 1;
1445 }
b.liua76c9612025-03-28 13:58:09 +08001446
b.liu9e96ffe2025-04-03 13:28:05 +08001447 if (p->Img_ID != IMAGE_ID_OBM && p->Img_ID != IMAGE_ID_TIMH) {
1448 ret = lseek(p->fd, start, SEEK_SET);
1449 if (ret < 0)
1450 {
1451 OTA_ERR("seek failed\n");
1452 return -1;
1453 }
b.liua76c9612025-03-28 13:58:09 +08001454
b.liu9e96ffe2025-04-03 13:28:05 +08001455 mtdEraseInfo.length = server_cfg.block_size;
1456 mtdEraseInfo.start = start;
1457 #ifndef CONFIG_PARTITION_EMMC
1458 ioctl(p->fd, MEMUNLOCK, &mtdEraseInfo);
1459 ioctl(p->fd, MEMERASE, &mtdEraseInfo);
1460 #endif
1461 }
b.liua76c9612025-03-28 13:58:09 +08001462
b.liu9e96ffe2025-04-03 13:28:05 +08001463 ret = write(p->fd, context->flash_cache, context->flash_cache_index);
1464 if (ret != context->flash_cache_index) {
1465 OTA_ERR("error: write incomplete! %d/%d\n", ret, context->flash_cache_index);
1466 return -1;
1467 }
b.liua76c9612025-03-28 13:58:09 +08001468
b.liu9e96ffe2025-04-03 13:28:05 +08001469 memset(context->flash_cache, 0, server_cfg.block_size);
1470 context->flash_cache_index = 0;
1471 break;
1472 }
1473 }
1474 p = p->next;
1475 }
b.liua76c9612025-03-28 13:58:09 +08001476
b.liu9e96ffe2025-04-03 13:28:05 +08001477 if (!p) {
1478 //OTA_ERR("not found image, ignore, %d...\n", context->processed_cnt);
1479 memset(context->flash_cache, 0, server_cfg.block_size);
1480 context->flash_cache_index = 0;
1481 }
1482 //}
1483 }
1484 }
1485//#else
1486 else {
1487 if (context->flash_cb) context->flash_cb(context, data, len);
1488 while (len > 0) {
1489 switch (context->state) {
1490 case HEADER: {
1491 OTA_DEBUG("Header cosume %d, len %d\n", context->processed_cnt,len);
1492 if ((context->processed_cnt + len) < MINI_SIZE) {
1493 OTA_DEBUG("FBF header not complete, continue recv\n");
1494 context->processed_cnt += len;
1495 return 0;
1496 }
1497 ret = tr069_fbf_parse(context->flash_cache, len, context);
1498 if (ret < 0) {
1499 OTA_ERR("Failed, fbf parse failed...\n");
1500 context->processed_cnt += len;
1501 len -= len;
1502 return -1;
1503 }
1504 len -= ret;
1505 data += ret;
1506 context->processed_cnt += ret;
1507 if (context->image_info_table) {
1508 context->state = CONTENT;
1509 dump_table(context);
1510 // Build image list for trace all image download result
1511 build_image_list(context);
1512 }
1513 break;
1514 }
1515 case CONTENT:
1516 default: {
1517 ImginfoTable * temp;
1518 if (!context->current_process) {
1519 int discard;
1520 temp = context->image_info_table;
1521 while (temp) {
1522 if (temp->Img_Start_Address <= (context->processed_cnt + len) &&
1523 temp->Img_Start_Address >= context->processed_cnt) {
1524 OTA_DEBUG("Find new image: start_address 0x%08x, image length %d, write to 0x%08x\n",
1525 temp->Img_Start_Address, temp->Img_Len, temp->Flash_Start_Address);
1526 if(temp->Img_Len!=0){
1527 break;
1528 }
1529 }
1530 temp = temp->next;
1531 }
1532 if (!temp) {
1533 OTA_DEBUG("Current data[0x%08x~0x%08x] not contain any content\n",
1534 context->processed_cnt, context->processed_cnt + len);
1535 context->processed_cnt += len;
1536 return 0;
1537 }
1538 discard = temp->Img_Start_Address - context->processed_cnt;
1539 if (discard) OTA_DEBUG("Have discard %d...\n", discard);
1540 len -= discard;
1541 data += discard;
1542 context->processed_cnt += discard;
1543 context->current_process = temp;
1544 }
1545 ret = image_check(context, data, len);
1546 len -= ret;
1547 data += ret;
1548 }
1549 }
1550 };
1551 }
1552//#endif
b.liua76c9612025-03-28 13:58:09 +08001553 return 0;
1554}
1555
b.liu9e96ffe2025-04-03 13:28:05 +08001556#if 1//defined(CONFIG_AB_SYSTEM) && !defined(CONFIG_AB_SYSTEM_DFOTA)
b.liua76c9612025-03-28 13:58:09 +08001557static char *gTempbuf = NULL;
1558static int gTempbufPos = 0;
1559static int gTotalBytes = 0;
1560/* this wrapper function is to guarantee 4K size each package */
1561static int firmware_download_cb_ab(char * data, int len, int num, void *cbdata)
1562{
1563 int bytes = 0, pos = 0, ret = 0;
1564 if (!gTempbuf)
1565 gTempbuf = malloc(4096);
1566
1567 while (len) {
1568 bytes = len;
1569 if ((gTempbufPos + len) > 4096)
1570 bytes = 4096 - gTempbufPos;
1571 memcpy(gTempbuf + gTempbufPos, data + pos, bytes);
1572 len -= bytes;
1573 pos += bytes;
1574 gTempbufPos += bytes;
1575 gTotalBytes += bytes;
1576 if (gTempbufPos == 4096 || gTotalBytes == num) {
1577 ret = firmware_download_cb(gTempbuf, gTempbufPos, num, cbdata);
1578 gTempbufPos = 0;
1579 if (ret) {
1580 OTA_ERR("%s: failed, ret = %d\n", __func__, ret);
1581 return ret;
1582 }
1583 }
1584 }
1585
1586 if(gTotalBytes == num) {
1587 struct image_process_context * context = (struct image_process_context *)cbdata;
1588 context->download_result = 1;
1589 free(gTempbuf);
1590 gTempbuf = NULL;
1591 }
1592 return 0;
1593}
1594#endif
1595
1596static int push2flash(struct image_process_context * context, char * data, int len)
1597{
1598 int ret;
1599 int block_cnt = 0;
1600 struct erase_info_user mtdEraseInfo;
1601
1602 while (len && context->flash_cache) {
1603 if ((context->flash_cache_index + len) >= server_cfg.block_size) {
1604 int space = server_cfg.block_size - context->flash_cache_index;
1605 memcpy(context->flash_cache + context->flash_cache_index, data, space);
1606 data += space;
1607 len -= space;
1608 context->flash_cache_index = 0;
1609 block_cnt = ((context->processed_cnt + space) / server_cfg.block_size);
1610 OTA_DEBUG(" write to block %d\n", block_cnt);
1611 // Write to flash
1612 ret = lseek(context->fd, server_cfg.block_size * block_cnt, SEEK_SET);
1613 if (ret < 0) {
1614 OTA_ERR("seek failed\n");
1615 return -1;
1616 }
1617 if (context->processed_cnt + space >= server_cfg.fbf_length) {
1618 OTA_ERR("!!! FILE TOO LARGE !!!\n");
1619 return 0;
1620 }
1621 mtdEraseInfo.length = server_cfg.block_size;
1622 mtdEraseInfo.start = server_cfg.block_size * ((context->processed_cnt + space) / server_cfg.block_size);
1623 ioctl(context->fd, MEMUNLOCK, &mtdEraseInfo);
1624 ioctl(context->fd, MEMERASE, &mtdEraseInfo);
1625 ret = write(context->fd, context->flash_cache, server_cfg.block_size);
1626 if (ret != server_cfg.block_size) {
1627 OTA_ERR("error: write incomplete!\n");
1628 }
1629 //memset(context->flash_cache, 0, server_cfg.block_size);
1630 } else {
1631 memcpy(context->flash_cache + context->flash_cache_index, data, len);
1632 context->flash_cache_index += len;
1633 len -= len;
1634 }
1635 };
1636
1637 return 0;
1638}
1639
1640static int flush_flash(struct image_process_context * context)
1641{
b.liu9e96ffe2025-04-03 13:28:05 +08001642//#if !defined(CONFIG_AB_SYSTEM) || defined(CONFIG_AB_SYSTEM_DFOTA)
1643 if(is_dfota) {
1644 int ret;
1645 int block_cnt;
1646 if (context->flash_cache_index && context->flash_cache) {
1647 block_cnt = ((context->processed_cnt) / server_cfg.block_size);
1648 if (((context->processed_cnt) % server_cfg.block_size) != 0) {
1649 block_cnt++;;
1650 }
1651 OTA_DEBUG("flush at block %d\n", block_cnt);
1652 ret = lseek(context->fd, server_cfg.block_size * block_cnt, SEEK_SET);
1653 if (ret < 0) {
1654 OTA_ERR("seek failed!\n");
1655 return -1;
1656 }
1657 write(context->fd, context->flash_cache, server_cfg.block_size);
1658 }
1659 }
1660//#endif
b.liua76c9612025-03-28 13:58:09 +08001661 sync();
1662 return 0;
1663}
1664
1665static void __download_throgh_sd(const char * url, struct image_process_context * context)
1666{
1667 int fd = -1;
1668 int total = 0, all = 0;
1669 char * buf = NULL;
1670
1671 if (url == NULL || context == NULL) {
1672 OTA_ERR("Bad parameters!\n");
1673 // Add by mbtk
1674 Download_flag = -1;
1675 return;
1676 }
1677 fd = open(url, O_RDONLY);
1678 if (fd < 0) {
1679 OTA_ERR("open for SD download failed!\n");
1680 // Add by mbtk
1681 Download_flag = -1;
1682 goto done;
1683 }
1684 total = lseek(fd, 0, SEEK_END);
1685 if (total < 0) {
1686 OTA_ERR("seek failed!\n");
1687 // Add by mbtk
1688 Download_flag = -1;
1689 goto done;
1690 }
1691
1692 buf = malloc(4096);
1693 if (buf == NULL) {
1694 OTA_ERR("malloc failed!\n");
1695 // Add by mbtk
1696 Download_flag = -1;
1697 goto done;
1698 }
1699
1700 all = total;
1701 lseek(fd, 0, SEEK_SET);
1702 while (total) {
1703 int remain = total > 4096 ? 4096 : total;
1704 int size = 0;
1705 //OTA_ERR("SD download size: %d:%d\n", total, remain);
1706 memset(buf, 0, 4096);
1707 size = read(fd, buf, remain);
1708 if (size != remain) {
1709 OTA_ERR("read firmware failed!\n");
1710 // Add by mbtk
1711 Download_flag = -1;
1712 goto done;
1713 }
1714 firmware_download_cb(buf, remain, all, context);
1715 total -= remain;
1716 }
1717 flush_flash(context);
1718 context->download_result = 1;
1719done:
1720 if (fd >= 0) {
1721 close(fd);
1722 fd = -1;
1723 }
1724 if (buf) {
1725 free(buf);
1726 buf = NULL;
1727 }
1728 return;
1729}
1730
1731
1732static void __download_throgh_http(const char * url, struct image_process_context * context)
1733{
1734#if 0
1735 CURL *curl = curl_easy_init();
1736 unsigned int response_code;
1737 double firmware_size;
1738 char * temp = NULL;
1739 *temp = 2;
1740
1741 OTA_ERR("Try access %s through curl\n", url);
1742 curl_easy_setopt(curl, CURLOPT_URL, url);
1743 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20);
1744 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_cb);
1745
1746 curl_easy_perform(curl);
1747 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
1748 curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &firmware_size);
1749 OTA_ERR("Get response code: %d and firmware size: %d\n", response_code, firmware_size);
1750
1751 curl_easy_cleanup(curl);
1752#else
1753 struct http_client * client = NULL;
1754 int http_response_code = 0;
1755 client = http_client_init();
1756 if (client == NULL) {
1757 OTA_ERR("HTTP client init failed!\n");
1758 return;
1759 }
1760
1761 OTA_DEBUG("Try access %s through http\n", url);
1762 http_client_setopt(client, HTTPCLIENT_OPT_URL, url);
b.liu9e96ffe2025-04-03 13:28:05 +08001763//#if defined(CONFIG_AB_SYSTEM) && !defined(CONFIG_AB_SYSTEM_DFOTA)
1764 if(!is_dfota) {
1765 http_client_setopt(client, HTTPCLIENT_OPT_RESPONSECB, firmware_download_cb_ab);
1766 }
1767//#else
1768 else {
1769 http_client_setopt(client, HTTPCLIENT_OPT_RESPONSECB, firmware_download_cb);
1770 }
1771//#endif
b.liua76c9612025-03-28 13:58:09 +08001772 http_client_setopt(client, HTTPCLIENT_OPT_METHOD, HTTPCLIENT_REQUEST_GET);
1773 http_client_setopt(client, HTTPCLIENT_OPT_RESPONSECB_DATA, context);
1774 http_client_perform(client);
1775 flush_flash(context);
1776 http_client_getinfo(client, HTTPCLIENT_GETINFO_RESPONSE_CODE, &http_response_code);
1777 OTA_DEBUG("HTTP result: %d\n", http_response_code);
1778 if (http_response_code == 200) {
1779 context->download_result = 1;
1780 }
1781 if (client) http_client_shutdown(client);
1782#endif
1783}
1784
b.liu9e96ffe2025-04-03 13:28:05 +08001785#if 1//!defined(CONFIG_AB_SYSTEM) || defined(CONFIG_AB_SYSTEM_DFOTA)
b.liua76c9612025-03-28 13:58:09 +08001786static int push2ram(struct image_process_context * context, char * data, int len)
1787{
1788 while (len && context->flash_cache) {
1789 if ((context->flash_cache_index + len) >= FILE_VERIFY_RAM_SIZE) {
1790 int space = FILE_VERIFY_RAM_SIZE - context->flash_cache_index;
1791 memcpy(context->flash_cache + context->flash_cache_index, data, space);
1792 data += space;
1793 len -= space;
1794 context->flash_cache_index = 0;
1795 } else {
1796 memcpy(context->flash_cache + context->flash_cache_index, data, len);
1797 context->flash_cache_index += len;
1798 len -= len;
1799 }
1800 };
1801 return 0;
1802}
1803
1804static int verify_flash_image(struct image_process_context * context, int * file_size)
1805{
1806 // Handle all data, try read it from flash, and verify again
1807 int error = 0;
1808 unsigned int i;
1809 int total = context->processed_cnt;
1810 struct image_process_context new_context = {0};
1811 char * temp = malloc(server_cfg.block_size);
1812 struct image_state * temp_list;
1813 int fd = -1;
1814 struct mtd_info_user mtdInfo;
1815 unsigned int ofs;
1816
1817 new_context.ota_download_notification_cnt = context->ota_download_notification_cnt;
1818 fd = open(server_cfg.mtd_fbf, O_RDWR | O_SYNC);
1819 if (fd < 0) {
1820 OTA_ERR("Open MTD device failed!\n");
1821 return -1;
1822 }
1823 if (ioctl(fd, MEMGETINFO, &mtdInfo)) {
1824 OTA_ERR("Could not get MTD device info from %s\n", server_cfg.mtd_fbf);
1825 } else {
1826 struct erase_info_user mtdEraseInfo;
1827 OTA_DEBUG(" MTD size: %d\n", mtdInfo.size);
1828 OTA_DEBUG(" MTD erase size: %d\n", mtdInfo.erasesize);
1829 OTA_DEBUG(" MTD type: %d\n", mtdInfo.type);
1830 mtdEraseInfo.length = mtdInfo.erasesize;;
1831 if (mtdInfo.type == MTD_NANDFLASH) {
1832 for (mtdEraseInfo.start = 0; mtdEraseInfo.start < mtdInfo.size; mtdEraseInfo.start += mtdInfo.erasesize) {
1833 ofs = mtdEraseInfo.start;
1834 if (ioctl(fd, MEMGETBADBLOCK, &ofs)) {
1835 OTA_ERR("Has bad block at %08x\n", (unsigned int)ofs);
1836 }
1837 }
1838 }
1839 }
1840 sync();
1841 lseek(fd, server_cfg.block_size, SEEK_SET);
1842
1843 if (!temp) {
1844 OTA_ERR("Cannot malloc memory for image verify");
1845 return -1;
1846 }
1847
1848 new_context.checksum_cache = malloc(CHECKSUM_CACHE_SIZE);
1849 if (!new_context.checksum_cache) goto done;
1850 new_context.flash_cache = malloc(FILE_VERIFY_RAM_SIZE);
1851 if (!new_context.flash_cache) goto done;
1852 new_context.flash_cb = push2ram;
1853 i = 1;
1854 *file_size = context->processed_cnt;
1855 while (total) {
1856 int remain_size = total > server_cfg.block_size ? server_cfg.block_size : total;
1857 int sub_total = remain_size;
1858 int ret = 0;
1859 OTA_DEBUG("Verify block %d\n", i);
1860 ret = read(fd, temp, server_cfg.block_size);
1861 if (ret != server_cfg.block_size) {
1862 OTA_ERR("error: data incomplete!\n");
1863 }
1864 while (remain_size) {
1865 int space = remain_size > 4096 ? 4096 : remain_size;
1866 firmware_download_cb(temp + (sub_total - remain_size), space, context->processed_cnt, &new_context);
1867 remain_size -= space;
1868 }
1869 total -= sub_total;
1870 i++;
1871 }
1872 free(temp);
1873 temp = NULL;
1874 temp_list = new_context.image_state_list;
1875 while (temp_list) {
1876 OTA_DEBUG("The verify image(0x%08x) process result %d\n",
1877 temp_list->image_info->Img_Checksum, temp_list->result);
1878 if (!temp_list->result) error = 1;
1879 temp_list = temp_list->next_image;
1880 }
1881done:
1882 if (temp) free(temp);
1883 temp = NULL;
1884 if (new_context.flash_cache) free(new_context.flash_cache);
1885 new_context.flash_cache = NULL;
1886 if (new_context.checksum_cache) free(new_context.checksum_cache);
1887 new_context.checksum_cache = NULL;
1888 temp = NULL;
1889 free_image_list(&new_context);
1890 close(fd);
1891 return error;
1892}
1893#endif
1894
1895
b.liu9e96ffe2025-04-03 13:28:05 +08001896#if 1//defined(CONFIG_AB_SYSTEM) && !defined(CONFIG_AB_SYSTEM_DFOTA)
1897#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08001898static int emmc_boot_lock_unlock(int no, int lock)
1899{
1900 char cmd[64] = {0};
1901 sprintf(cmd, "echo %d > /sys/block/mmcblk1boot%d/force_ro", lock, no);
1902 system(cmd);
1903 return 0;
1904}
1905#endif
1906
1907static int mtd_erase(int fd, unsigned int offset, unsigned int length)
1908{
b.liu9e96ffe2025-04-03 13:28:05 +08001909//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08001910 struct erase_info_user erase;
1911 OTA_DEBUG("%s: offset: 0x%x, length: 0x%x\n", __func__, offset, length);
1912 if (lseek(fd, offset, SEEK_SET) < 0) {
1913 OTA_ERR("%s: seek failed. err: %d\n", __func__, errno);
1914 return -1;
1915 }
1916
1917 erase.length = length;
1918 erase.start = offset;
1919
1920 ioctl(fd, MEMUNLOCK, &erase);
1921 if (ioctl(fd, MEMERASE, &erase) < 0) {
1922 OTA_ERR("%s: erase failed. err: %d\n", __func__, errno);
1923 return -1;
1924 }
b.liu9e96ffe2025-04-03 13:28:05 +08001925//#endif
b.liua76c9612025-03-28 13:58:09 +08001926 return 0;
1927}
1928
b.liu9e96ffe2025-04-03 13:28:05 +08001929//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08001930static int is_all_ff(char *buf, int size)
1931{
1932 for (int i = 0; i < size; i++) {
1933 if (0xff != (unsigned char)buf[i])
1934 return 0;
1935 }
1936 return 1;
1937}
b.liu9e96ffe2025-04-03 13:28:05 +08001938//#endif
b.liua76c9612025-03-28 13:58:09 +08001939
1940static int __upgrade_timh(int fd, unsigned int offset, const char *file,
1941 unsigned int size, char *dst_buf, unsigned int dst_buf_size, unsigned int pagesize)
1942{
1943 int srcfd = -1, r = -1;
1944 char *buf = NULL, *dst = NULL;
1945 int dstsize, off;
1946
1947 OTA_DEBUG("%s: offset: 0x%x, file: %s, size: 0x%x, dst_buf_size: %d, "
1948 "pagesize: %d, max_timh_size: %d\n",
1949 __func__, offset, file, size, dst_buf_size, pagesize, server_cfg.max_timh_size);
1950 if ((srcfd = open(file, O_RDONLY)) < 0) {
1951 OTA_ERR("%s: failed to open file: %s\n", __func__, file);
1952 goto err;
1953 }
1954
1955 buf = malloc(size);
1956 if (!buf) {
1957 OTA_ERR("%s: no mem\n", __func__);
1958 goto err;
1959 }
1960
1961 if (complete_read(srcfd, buf, size) < 0) {
1962 OTA_ERR("%s: read failed\n", __func__);
1963 goto err;
1964 }
1965
1966 if (lseek(fd, offset, SEEK_SET) < 0) {
1967 OTA_ERR("%s: seek failed. err: %d\n", __func__, errno);
1968 goto err;
1969 }
1970
1971 if (dst_buf) {
1972 dst = dst_buf;
1973 dstsize = dst_buf_size;
1974 memcpy(dst, buf, size);
1975 } else {
1976 dst = buf;
1977 dstsize = size;
1978 }
1979
b.liu9e96ffe2025-04-03 13:28:05 +08001980//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08001981 if (dstsize > server_cfg.max_timh_size) {
1982 /* 1. write all timh */
1983 if (complete_write(fd, dst, server_cfg.max_timh_size) < 0) {
1984 OTA_ERR("%s: write all timh failed\n", __func__);
1985 goto err;
1986 }
1987
1988 /* 2. write bbt */
1989 for (off = server_cfg.max_timh_size; off < dstsize; off += pagesize) {
1990 if (!is_all_ff(dst + off, pagesize)) {
1991 if (complete_write(fd, dst + off, pagesize) < 0) {
1992 OTA_ERR("%s: write bbt page failed\n", __func__);
1993 goto err;
1994 }
1995 } else {
1996 OTA_DEBUG("0x%x + 0x%x is all FF, skip write.\n", offset, off);
1997 }
1998 }
1999 } else {
b.liu9e96ffe2025-04-03 13:28:05 +08002000//#endif
b.liua76c9612025-03-28 13:58:09 +08002001 if (complete_write(fd, dst, dstsize) < 0) {
2002 OTA_ERR("%s: write failed\n", __func__);
2003 goto err;
2004 }
b.liu9e96ffe2025-04-03 13:28:05 +08002005//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08002006 }
b.liu9e96ffe2025-04-03 13:28:05 +08002007//#endif
b.liua76c9612025-03-28 13:58:09 +08002008
2009 r = 0;
2010err:
2011 if (srcfd >= 0)
2012 close(srcfd);
2013 if (buf)
2014 free(buf);
2015 return r;
2016}
2017
2018static int write_to_file(void *buf, int size, const char *file)
2019{
2020 int fd;
2021 int r = -1;
2022 fd = open(file, O_CREAT | O_RDWR | O_SYNC | O_TRUNC, 777);
2023 if (fd < 0) {
2024 OTA_ERR("%s: failed to open %s\n", __func__, file);
2025 return r;
2026 }
2027
2028 if (complete_write(fd, buf, size) < 0) {
2029 OTA_ERR("%s: write failed\n", __func__);
2030 goto err;
2031 }
2032
2033 r = 0;
2034err:
2035 if (fd >= 0)
2036 close(fd);
2037 return r;
2038}
2039
2040static int retrive_timh_by_ddrid(const char *file, unsigned int *ddr_id, const char *target_file)
2041{
2042 int size, fd = -1, r = -1;
2043 char *buf = NULL;
2044 TIM tim;
2045
2046 OTA_DEBUG("%s: ddr id: 0x%x\n", __func__, *ddr_id);
2047 size = get_file_size(file);
2048 if (size <= 0) {
2049 OTA_ERR("failed to get size of file: %s\n", file);
2050 return r;
2051 }
2052
2053 buf = malloc(size);
2054 if (!buf) {
2055 OTA_ERR("%s: failed to malloc for file: %s, size: %d\n",
2056 __func__, file, size);
2057 return r;
2058 }
2059
2060 fd = open(file, O_RDONLY);
2061 if (fd < 0) {
2062 OTA_ERR("%s: failed to open file: %s\n",
2063 __func__, file);
2064 r = -1;
2065 goto err;
2066 }
2067
2068 if (complete_read(fd, buf, size) < 0)
2069 goto err;
2070
2071 SetTIMPointers(buf, &tim);
2072 if (__retrive_timh_by_ddrid(&tim, ddr_id, &size) != NoError) {
2073 OTA_ERR("%s: failed to retrive timh\n", __func__);
2074 goto err;
2075 }
2076
2077 if (write_to_file(tim.pConsTIM, size, target_file) < 0)
2078 goto err;
2079 OTA_DEBUG("%s: OK.\n", __func__);
2080 r = 0;
2081err:
2082 if (buf)
2083 free(buf);
2084 if (fd >= 0)
2085 close(fd);
2086 return r;
2087}
2088
2089static int __upgrade_obm(int fd, unsigned int offset, const char *obm_file, const char *timh_file)
2090{
2091 int obm_fd = -1, timh_fd = -1, r = -1;
2092 char *buf = NULL;
2093 int obm_size = 0, timh_size = 0;
2094
2095 if (obm_file)
2096 obm_size = get_file_size(obm_file);
2097 if (timh_file)
2098 timh_size = get_file_size(timh_file);
2099
2100 OTA_DEBUG("%s: offset: 0x%x, obm file: %s, obm_size: %d(%d), timh file: %s, timh_size: %d\n",
2101 __func__, offset, obm_file, obm_size, obm_real_size, timh_file, timh_size);
2102 obm_size = obm_real_size;
2103
2104 if ((obm_fd = open(obm_file, O_RDONLY)) < 0) {
2105 OTA_ERR("%s: failed to open obm file: %s\n", __func__, obm_file);
2106 goto err;
2107 }
2108
2109 if (timh_file) {
2110 if ((timh_fd = open(timh_file, O_RDONLY)) < 0) {
2111 OTA_ERR("%s: failed to open timh file: %s\n", __func__, timh_file);
2112 goto err;
2113 }
2114 }
2115
2116 buf = malloc(obm_size + timh_size);
2117 if (!buf) {
2118 OTA_ERR("%s: no mem\n", __func__);
2119 goto err;
2120 }
2121
2122 if (complete_read(obm_fd, buf, obm_size) < 0) {
2123 OTA_ERR("%s: read obm failed\n", __func__);
2124 goto err;
2125 }
2126
2127 if (timh_file) {
2128 if (complete_read(timh_fd, buf + obm_size, timh_size) < 0) {
2129 OTA_ERR("%s: read timh failed\n", __func__);
2130 goto err;
2131 }
2132 }
2133
2134 /* write obm + timh backup */
2135 if (lseek(fd, offset, SEEK_SET) < 0) {
2136 OTA_ERR("%s: seek failed. err: %d\n", __func__, errno);
2137 goto err;
2138 }
2139
2140 if (complete_write(fd, buf, obm_size + timh_size) < 0) {
2141 OTA_ERR("%s: write failed\n", __func__);
2142 goto err;
2143 }
2144
2145 r = 0;
2146err:
2147 if (obm_fd >= 0) close(obm_fd);
2148 if (timh_fd >= 0) close(timh_fd);
2149 if (buf) free(buf);
2150 return r;
2151}
2152
2153static int __upgrade_bootloader(struct image_process_context * context, int Image_In_Tim)
2154{
2155 ImginfoTable *obm = NULL, *timh = NULL, *p;
2156 int fd = -1, r = -1;
2157 char *bootdev = NULL;
2158 char *block0 = NULL;
2159 char *obm_file = NULL, *timh_file = NULL;
2160 /* put this file right after the obm */
2161 char *timh_bk_file = NULL;
2162
b.liu9e96ffe2025-04-03 13:28:05 +08002163#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08002164 int emmc_boot_part = 0;
2165 if (Image_In_Tim == TIMH_INC) {
2166 bootdev = "/dev/mmcblk1boot0";
2167 emmc_boot_part = 0;
2168 } else if (Image_In_Tim == TIMH_RECOVERY_INC) {
2169 bootdev = "/dev/mmcblk1boot1";
2170 emmc_boot_part = 1;
2171 }
2172#else
2173 bootdev = "/dev/mtd0";
2174#endif
2175
2176 if (Image_In_Tim == TIMH_INC) {
2177 obm_file = (char *)tmp_obm_main_file;
2178 timh_file = (char *)tmp_timh_main_target_file;
2179 if (context->dual_tim)
2180 timh_bk_file = (char *)tmp_timh_bk_target_file;
2181 } else if (Image_In_Tim == TIMH_RECOVERY_INC) {
2182 obm_file = (char *)tmp_obm_bk_file;
2183 timh_file = (char *)tmp_timh_bk_target_file;
2184 timh_bk_file = (char *)tmp_timh_main_target_file;
2185 } else {
2186 OTA_ERR("%s: unsupport %d\n", __func__, Image_In_Tim);
2187 exit(-1);
2188 }
2189
2190 if (context->same_tim) {
2191 timh_file = (char *)tmp_timh_main_target_file; /* always use the main tim */
2192 timh_bk_file = NULL; /* no need to append tim to obm */
2193 }
2194
2195 p = context->image_info_table;
2196 while (p) {
2197 if (p->Img_ID == IMAGE_ID_OBM && p->Image_In_TIM == Image_In_Tim)
2198 obm = p;
2199 else if (p->Img_ID == IMAGE_ID_TIMH && p->Image_In_TIM == Image_In_Tim)
2200 timh = p;
2201 p = p->next;
2202 }
2203
2204 if (!obm || !timh) {
2205 OTA_ERR("no obm or timh.\n");
2206 goto err;
2207 }
2208
2209 OTA_DEBUG("%s: start %d...\n", __func__, Image_In_Tim);
2210 fd = open(bootdev, O_RDWR | O_SYNC);
2211 if (fd < 0) {
2212 OTA_ERR("failed to open %s.\n", bootdev);
2213 goto err;
2214 }
2215
b.liu9e96ffe2025-04-03 13:28:05 +08002216#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08002217 // no bbm for emmc
2218#else
2219 ioctl(fd, MEMUNLOCKPRIV, NULL);
2220
2221 // bbm related things were in block 0, so we need to backup them
2222 // 1. load block 0
2223 block0 = malloc(server_cfg.block_size);
2224 if (!block0) {
2225 OTA_ERR("%s: no mem\n", __func__);
2226 goto err;
2227 }
2228
2229 if (lseek(fd, timh->Flash_Start_Address, SEEK_SET) < 0) {
2230 OTA_ERR("%s: seek failed. err: %d\n", __func__, errno);
2231 goto err;
2232 }
2233
2234 if (complete_read(fd, block0, server_cfg.block_size) < 0) {
2235 OTA_ERR("%s: load block0 failed\n", __func__);
2236 goto err;
2237 }
2238#endif
2239
2240 // 2. erase timh
2241 if (mtd_erase(fd, timh->Flash_Start_Address, server_cfg.block_size) < 0) {
2242 OTA_ERR("erase timh failed\n");
2243 goto err;
2244 }
2245
2246 // 3. erase obm
2247 if (mtd_erase(fd, obm->Flash_Start_Address, server_cfg.block_size) < 0) {
2248 OTA_ERR("erase obm failed\n");
2249 goto err;
2250 }
2251
b.liu9e96ffe2025-04-03 13:28:05 +08002252#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08002253 /* unlock */
2254 emmc_boot_lock_unlock(emmc_boot_part, 0);
2255#endif
2256
2257 // 4. write obm
2258 if (__upgrade_obm(fd, obm->Flash_Start_Address, obm_file, timh_bk_file) < 0) {
2259 OTA_ERR("update obm failed\n");
2260 goto err;
2261 }
2262
2263 // 5. write timh
2264 if (__upgrade_timh(fd, timh->Flash_Start_Address, timh_file,
2265 get_file_size(timh_file), block0, server_cfg.block_size, server_cfg.pagesize) < 0) {
2266 OTA_ERR("update timh failed\n");
2267 goto err;
2268 }
2269
b.liu9e96ffe2025-04-03 13:28:05 +08002270#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08002271 /* unlock */
2272 emmc_boot_lock_unlock(emmc_boot_part, 1);
2273#endif
2274 OTA_DEBUG("%s: successfully...\n", __func__);
2275
2276 r = 0;
2277err:
2278 if (fd >= 0) {
b.liu9e96ffe2025-04-03 13:28:05 +08002279//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08002280 ioctl(fd, MEMLOCKPRIV, NULL);
b.liu9e96ffe2025-04-03 13:28:05 +08002281//#endif
b.liua76c9612025-03-28 13:58:09 +08002282 close(fd);
2283 }
2284
2285 if (block0) free(block0);
2286 return r;
2287}
2288
2289static int get_soc_id(unsigned int *ddrid, unsigned int *cpuid)
2290{
2291#define CPUID_STR "chip_id: "
2292#define DDRID_STR "ddr_id: "
2293 const char *file = "/dev/soc_id";
2294 int fd = -1, ret = -1;
2295 char buf[64], *p;
2296
2297 fd = open(file, O_RDONLY);
2298 if (fd < 0) {
2299 OTA_ERR("%s: open %s failed.\n", __func__, file);
2300 goto err;
2301 }
2302
2303 memset(buf, 0, sizeof(buf));
2304 if (read(fd, buf, 64) < 0) {
2305 OTA_ERR("%s: read failed.\n", __func__);
2306 goto err;
2307 }
2308
2309 OTA_DEBUG("%s: soc: %s\n", __func__, buf);
2310 p = strstr(buf, CPUID_STR);
2311 if (!p) {
2312 OTA_ERR("%s: not found chip id.\n", __func__);
2313 goto err;
2314 }
2315 *cpuid = strtoul(p + strlen(CPUID_STR), NULL, 16);
2316
2317 p = strstr(buf, DDRID_STR);
2318 if (!p) {
2319 OTA_ERR("%s: not found ddr id.\n", __func__);
2320 goto err;
2321 }
2322 *ddrid = strtoul(p + strlen(DDRID_STR), NULL, 16);
2323
2324 OTA_DEBUG("%s: got cpudid: 0x%x, ddrid: 0x%x\n", __func__, *cpuid, *ddrid);
2325err:
2326 if (fd >= 0) close(fd);
2327 return ret;
2328}
2329
2330/*
2331 block0 = main timh + bbt
2332 block1 = backup timh + bbt
2333 block2 = main obm + backup timh
2334 block3 = backup obm + main timh
2335*/
2336static int upgrade_bootloader(struct image_process_context * context)
2337{
2338 int r = -1;
2339 int cpuid, revision;
2340 if (context->upgrade_bootloader != 1)
2341 /* no bootloader */
2342 return 0;
2343
2344 get_soc_id(&server_cfg.ddrid, &server_cfg.cpuid);
2345 cpuid = server_cfg.cpuid & 0xffff;
2346 revision = (server_cfg.cpuid >> 16) & 0xff;
2347 context->same_tim = 0;
2348
b.liu9e96ffe2025-04-03 13:28:05 +08002349//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08002350 switch (cpuid) {
2351 case 0x1802:
2352 case 0x1826:
2353 server_cfg.max_timh_size = 4 * 1024;
2354 break;
2355 case 0x1803:
2356 case 0x1828:
2357 server_cfg.max_timh_size = 8 * 1024;
2358 break;
2359 case 0x1903:
2360 if (context->dual_tim && (revision == 0xA0 || revision == 0xB0))
2361 context->same_tim = 1;
2362 case 0x1901:
2363 case 0x1906:
2364 case 0x1806:
2365 server_cfg.max_timh_size = 16 * 1024;
2366 break;
2367 default:
2368 OTA_DEBUG("%s: default cpuid: 0x%x\n", __func__, server_cfg.cpuid);
2369 server_cfg.max_timh_size = 16 * 1024;
2370 break;
2371 }
b.liu9e96ffe2025-04-03 13:28:05 +08002372//#endif
b.liua76c9612025-03-28 13:58:09 +08002373
2374 OTA_DEBUG("%s: dual tim: %d, same tim: %d\n", __func__, context->dual_tim, context->same_tim);
2375 if (access(tmp_obm_main_file, F_OK) || access(tmp_timh_main_file, F_OK)) {
2376 OTA_ERR("%s: missing main.\n", __func__);
2377 goto err;
2378 }
2379
2380 if (context->dual_tim) {
2381 if (access(tmp_obm_bk_file, F_OK) || access(tmp_timh_bk_file, F_OK)) {
2382 OTA_ERR("%s: missing backup.\n", __func__);
2383 goto err;
2384 }
2385 }
2386
2387 if (gAsrFlag.DDR_ID == 0 || gAsrFlag.DDR_ID == 0xFFFFFFFF) {
2388 gAsrFlag.DDR_ID = server_cfg.ddrid;
2389 OTA_DEBUG("%s: invalid ddrid in asrflag, use current ddrid.\n", __func__);
2390 }
2391
2392 if (gAsrFlag.DDR_ID != server_cfg.ddrid)
2393 OTA_DEBUG("%s: Warning: mismatch ddrid, in asrflag: 0x%x, current ddrid: 0x%x\n",
2394 __func__, gAsrFlag.DDR_ID, server_cfg.ddrid);
2395
2396 if (retrive_timh_by_ddrid(tmp_timh_main_file, &gAsrFlag.DDR_ID, tmp_timh_main_target_file) < 0) {
2397 OTA_ERR("failed to retrive timh for ddr: 0x%x to %s.\n", gAsrFlag.DDR_ID, tmp_timh_main_target_file);
2398 goto err;
2399 }
2400
2401 if (context->dual_tim) {
2402 if (retrive_timh_by_ddrid(tmp_timh_bk_file, &gAsrFlag.DDR_ID, tmp_timh_bk_target_file) < 0) {
2403 OTA_ERR("failed to retrive timh for ddr: 0x%x to %s.\n", gAsrFlag.DDR_ID, tmp_timh_bk_target_file);
2404 goto err;
2405 }
2406 }
2407
2408 if (context->dual_tim) {
2409 /* upgrade the backup bootloader */
2410 if (__upgrade_bootloader(context, TIMH_RECOVERY_INC) < 0)
2411 goto err;
2412 }
2413
2414 /* then upgrade the main bootloader */
2415 if (__upgrade_bootloader(context, TIMH_INC) < 0)
2416 goto err;
2417
2418 r = 0;
2419err:
2420 remove(tmp_obm_main_file);
2421 remove(tmp_timh_main_file);
2422 remove(tmp_timh_main_target_file);
2423 if (context->dual_tim) {
2424 remove(tmp_obm_bk_file);
2425 remove(tmp_timh_bk_file);
2426 remove(tmp_timh_bk_target_file);
2427 }
2428 return r;
2429}
2430#endif
2431
2432static int image_recheck(struct image_process_context * context)
2433{
b.liu9e96ffe2025-04-03 13:28:05 +08002434//#if defined(CONFIG_AB_SYSTEM) && !defined(CONFIG_AB_SYSTEM_DFOTA)
2435 if(!is_dfota) {
2436 ImginfoTable *p = context->image_info_table;
2437 char *cache = malloc(FBF_FILE_SECTOR_SIZE);
2438 int flag = 0;
2439 if (!cache) {
2440 OTA_ERR("no memory\n");
2441 return -1;
2442 }
b.liua76c9612025-03-28 13:58:09 +08002443
b.liu9e96ffe2025-04-03 13:28:05 +08002444 ImginfoTable *tmp = p;
2445 while (tmp) {
2446 lseek(tmp->fd, 0, SEEK_SET);
2447 tmp = tmp->next;
2448 }
b.liua76c9612025-03-28 13:58:09 +08002449
b.liu9e96ffe2025-04-03 13:28:05 +08002450 while (p) {
2451 p->cs = 0;
2452 OTA_DEBUG("recheck %s, %s, %d\n", p->dev, p->name, p->Flash_Start_Address - p->Block_Start_Address);
2453 if (p->Img_ID == IMAGE_ID_OBM || p->Img_ID == IMAGE_ID_TIMH)
2454 lseek(p->fd, 0, SEEK_SET);
2455 else
2456 lseek(p->fd, p->Flash_Start_Address - p->Block_Start_Address, SEEK_SET);
2457 /*
2458 int ret = lseek(p->fd, 0, SEEK_SET);
2459 if (ret < 0)
2460 {
2461 OTA_ERR("seek failed, %s\n", p->name);
2462 flag = -1;
2463 goto next;
2464 }
2465 */
2466 int remain = p->Img_Len;
2467 while (remain > 0) {
2468 int size = remain > FBF_FILE_SECTOR_SIZE ? FBF_FILE_SECTOR_SIZE : remain;
2469 memset(cache, 0, FBF_FILE_SECTOR_SIZE);
2470 int n = read(p->fd, cache, size);
2471 if (n != size) {
2472 OTA_ERR("read failed, read %d(expect %d), %s\n", n, size, p->name);
2473 flag = -1;
2474 goto next;
2475 }
2476 p->cs = fbf_checksum((unsigned char *)cache, FBF_FILE_SECTOR_SIZE, p->cs);
2477 remain -= n;
2478 }
b.liua76c9612025-03-28 13:58:09 +08002479
b.liu9e96ffe2025-04-03 13:28:05 +08002480 if (p->cs != p->Img_Checksum) {
2481 OTA_ERR("%s, cs: 0x%x(expect 0x%x)\n", p->name, p->cs, p->Img_Checksum);
2482 flag = -1;
2483 goto next;
2484 } else {
2485 OTA_DEBUG("recheck %s, %s OK, cs: 0x%x(expect 0x%x)...\n", p->dev, p->name, p->cs, p->Img_Checksum);
2486 }
2487 next:
2488 p = p->next;
2489 }
b.liua76c9612025-03-28 13:58:09 +08002490
b.liu9e96ffe2025-04-03 13:28:05 +08002491 if (flag == 0) {
2492 if (upgrade_bootloader(context) < 0) {
2493 flag = -1;
2494 OTA_ERR("%s: upgrade bootloader failed, don't reboot or powerdown...\n",
2495 __func__);
2496 return flag;
2497 }
b.liua76c9612025-03-28 13:58:09 +08002498
b.liu9e96ffe2025-04-03 13:28:05 +08002499 /* all image write ok, update the active system slot */
2500 //#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
2501 int slot = gInActiveSystem == SYSTEM_A ? 'a' : 'b';
2502 /* tell boot to update NVM files from oemd */
2503 if (update_oemd)
2504 system("touch /NVM/oemd && sync");
2505 gAsrFlag.temp_active_slot = slot;
2506 gAsrFlag.reboot_cnt = 0;
2507 gAsrFlag.synced = 0;
b.liua76c9612025-03-28 13:58:09 +08002508
b.liu9e96ffe2025-04-03 13:28:05 +08002509 if (gInActiveSystem == SYSTEM_A) {
2510 OTA_DEBUG("prev mversion a: %s updated to %s\n", gAsrFlag.mversion, server_cfg.fotav);
2511 memset(gAsrFlag.mversion, 0, 128);
2512 strncpy(gAsrFlag.mversion, server_cfg.fotav, 128);
2513 } else {
2514 OTA_DEBUG("prev mversion b: %s updated to %s\n", gAsrFlag.mversion, server_cfg.fotav);
2515 memset(gAsrFlag.MVersion_B, 0, 128);
2516 strncpy(gAsrFlag.MVersion_B, server_cfg.fotav, 128);
2517 }
b.liua76c9612025-03-28 13:58:09 +08002518
b.liu9e96ffe2025-04-03 13:28:05 +08002519 write_asr_flag(&gAsrFlag);
2520 }
2521 return flag;
2522 }
2523//#else
2524 else {
2525 struct image_state * image_state_list, * image_state_list_org;
2526 int file_size = 0;
2527 image_state_list_org = image_state_list = context->image_state_list;
2528 if ((context->image_state_list == NULL) || (context->download_result != 1)) {
2529 return -1;
2530 }
b.liua76c9612025-03-28 13:58:09 +08002531
b.liu9e96ffe2025-04-03 13:28:05 +08002532 while (image_state_list) {
2533 OTA_DEBUG("The image(0x%08x) process result %d\n",
2534 image_state_list->image_info->Img_Checksum, image_state_list->result);
2535 if (!image_state_list->result) return -1;;
2536 image_state_list = image_state_list->next_image;
2537 }
b.liua76c9612025-03-28 13:58:09 +08002538
b.liu9e96ffe2025-04-03 13:28:05 +08002539 if (!image_state_list && image_state_list_org) {
2540 if (verify_flash_image(context, &file_size)) {
2541 return -1;
2542 }
2543 }
2544 /* set dlflag for non-AB */
2545 /* tell boot to update NVM files from oemd */
2546 if (update_oemd)
2547 system("touch /NVM/oemd && sync");
b.liua76c9612025-03-28 13:58:09 +08002548
b.liu9e96ffe2025-04-03 13:28:05 +08002549 if(get_asr_flag(&gAsrFlag)) {
2550 OTA_ERR("Fail to get asr flag\n");
2551 return -1;
2552 }
2553 gAsrFlag.upgrade_flag = 1;
2554 gAsrFlag.fbf_flash_address = server_cfg.fbf_addr + server_cfg.block_size;
2555 gAsrFlag.fbf_file_size = context->processed_cnt;
2556 gAsrFlag.upgrade_method = context->upgrade_method;
2557 gAsrFlag.dfota_n_of_images = 0xFFFFFFFF;
b.liua76c9612025-03-28 13:58:09 +08002558
b.liu9e96ffe2025-04-03 13:28:05 +08002559 if(write_asr_flag(&gAsrFlag)) {
2560 OTA_ERR("Fail to write asr flag\n");
2561 return -1;
2562 }
2563 }
2564//#endif
b.liua76c9612025-03-28 13:58:09 +08002565 return 0;
2566}
2567
2568static int build_udp_server(const char * path)
2569{
2570 int fd = -1;
2571 struct timeval timeout = {10, 0};
2572 struct sockaddr_un un = {0};
2573 int size;
2574
2575 unlink(path);
2576 un.sun_family = AF_UNIX;
2577 sprintf(un.sun_path, "%s", path);
2578 OTA_DEBUG("Will create socket at %s\n", un.sun_path);
2579 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
2580 OTA_ERR("Build socket failed!\n");
2581 return -1;
2582 }
2583 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout))) {
2584 OTA_ERR("Set timeout failed!\n");
2585 goto failed;
2586 }
2587
2588 size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
2589 if (bind(fd, (struct sockaddr*)&un, size)) {
2590 OTA_ERR("Bind failed!\n");
2591 goto failed;
2592 }
2593 //(void)chmod(un.sun_path, 0777);
2594 OTA_DEBUG("will listen on %d\n", fd);
2595 if (listen(fd, 5) < 0) {
2596 OTA_ERR("Listen failed!\n");
2597 goto failed;
2598 }
2599 return fd;
2600
2601failed:
2602 if (fd > 0) {
2603 close(fd);
2604 }
2605 return -1;
2606}
2607
2608static int accept_udp(int fd)
2609{
2610 struct timeval timeout = {10, 0};
2611 int client;
2612
2613 client = accept(fd, NULL, 0);
2614 if (client < 0) {
2615 OTA_ERR("Accept failed!\n");
2616 } else {
2617 setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
2618 }
2619 return client;
2620}
2621
2622static void __download_throgh_udp(int fd, int size, struct image_process_context * context)
2623{
2624 int total = size;
2625 char * buf = malloc(4096);
2626 int res=0;
2627
2628 if (buf == NULL) {
2629 OTA_ERR("memory issue at __download_through_udp!\n");
2630 return;
2631 }
2632
2633 // for debug
2634 OTA_DEBUG("size: %d.\n", size);
2635
2636 while (total) {
2637 int recved = 0;
2638 memset(buf, 0, 4096);
2639
2640 int n = total > 4096 ? 4096 : total;
2641 int ret;
2642repeat:
2643 ret = recv(fd, buf + recved, n, 0);
2644 if (ret <= 0) {
2645 OTA_ERR("recv failed! errno: %d, %s\n", errno, strerror(errno));
2646 if (errno == EAGAIN) {
2647 sleep(1);
2648 OTA_DEBUG("try again.\n");
2649 goto repeat;
2650 }
2651 goto done;
2652 }
2653 recved += ret;
2654 n -= ret;
2655 if (n != 0) {
2656 //OTA_DEBUG("recved: %d, n: %d, ret: %d\n", recved, n, ret);
2657 goto repeat;
2658 }
2659
2660 res=firmware_download_cb(buf, recved, size, context);
2661 if(res<0){
2662 goto done;
2663 }
2664 total -= recved;
2665 };
2666 OTA_DEBUG("__download_throgh_udp received_size[%d],file_size[%d]\n", download_method_ctx.received_size,download_method_ctx.file_size);
2667 if(download_method_ctx.received_size == download_method_ctx.file_size){
b.liu9e96ffe2025-04-03 13:28:05 +08002668//#if !defined(CONFIG_AB_SYSTEM) || defined(CONFIG_AB_SYSTEM_DFOTA)
2669 if(is_dfota) {
2670 flush_flash(context);
2671 }
2672//#endif
b.liua76c9612025-03-28 13:58:09 +08002673 context->download_result = 1;
2674 }
2675done:
2676 if (buf) {
2677 free(buf);
2678 buf = NULL;
2679 }
2680 return;
2681}
2682
2683
2684
2685
2686static int erase_ota_fbf_area(void)
2687{
b.liu9e96ffe2025-04-03 13:28:05 +08002688//#if defined(CONFIG_AB_SYSTEM) && !defined(CONFIG_AB_SYSTEM_DFOTA)
2689 if(!is_dfota) {
2690 return 0;
2691 }
2692//#else
2693 else {
b.liua76c9612025-03-28 13:58:09 +08002694 struct erase_info_user mtdEraseInfo;
2695 struct mtd_info_user mtdInfo;
2696 int fd = open(server_cfg.mtd_fbf, O_RDWR | O_SYNC);
2697 if (ioctl(fd, MEMGETINFO, &mtdInfo)) {
2698 OTA_ERR("Could not get MTD FBF device info from %s\n", server_cfg.mtd_fbf);
2699 close(fd);
2700 update_state = UPDATE_STATE_FAILED;
2701 return -1;
2702 }
2703 mtdEraseInfo.length = mtdInfo.erasesize;
2704 for (mtdEraseInfo.start = 0; mtdEraseInfo.start < mtdInfo.size; mtdEraseInfo.start += mtdInfo.erasesize) {
2705 ioctl(fd, MEMUNLOCK, &mtdEraseInfo);
2706 ioctl(fd, MEMERASE, &mtdEraseInfo);
2707 }
2708 close(fd);
2709 fd = -1;
2710 sync();
b.liu9e96ffe2025-04-03 13:28:05 +08002711 }
2712//#endif
b.liua76c9612025-03-28 13:58:09 +08002713 return 0;
2714
2715}
2716
2717static struct image_process_context *udp_context=NULL;
2718static int udp_download_cb(struct uloop_timeout *timeout)
2719{
2720 //int type = download_method_ctx.type;
2721 int size = download_method_ctx.size;
2722 int segment_size = download_method_ctx.segment_size;
2723 char * url = download_method_ctx.url;
2724 char * username = download_method_ctx.username;
2725 char * psw = download_method_ctx.pwd;
2726 int ret = -1;
2727 struct image_process_context *context=NULL;
2728
2729 if(size==0 && udp_context==NULL){
2730 OTA_ERR("ubus call donwload paramer abnormal!\n");//rm60362
2731 notify_download_end(0);
2732 update_state = UPDATE_STATE_FAILED;
2733 goto exit;
2734 }
2735
2736 if(size!=0){
2737 if(udp_context){
2738 if (udp_context->flash_cache) free(udp_context->flash_cache);
2739 udp_context->flash_cache = NULL;
2740 if (udp_context->checksum_cache) free(udp_context->checksum_cache);
2741 udp_context->checksum_cache = NULL;
2742 if(udp_context->fd!=-1){
2743 close(udp_context->fd);
2744 udp_context->fd = -1;
2745 }
2746
2747 if (udp_context->image_state_list) {
2748 free_image_list(udp_context);
2749 udp_context->image_state_list=NULL;
2750 }
2751 if(udp_context){
2752 free(udp_context);
2753 udp_context = NULL;
2754 }
2755
2756 }
2757
2758 udp_context = (struct image_process_context *)malloc(sizeof(struct image_process_context));
2759 memset(udp_context,0,sizeof(struct image_process_context));
2760 }
2761 context = udp_context;
2762
2763 if(size!=0){
b.liu9e96ffe2025-04-03 13:28:05 +08002764//#if !defined(CONFIG_AB_SYSTEM) || defined(CONFIG_AB_SYSTEM_DFOTA)
2765 if(is_dfota) {
2766 context->fd = open(server_cfg.mtd_fbf, O_RDWR | O_SYNC);
2767 if (context->fd < 0) {
2768 OTA_ERR("Cannot open MTD device!\n");
2769 notify_download_end(0);
2770 update_state = UPDATE_STATE_FAILED;
2771 return ret;
2772 }
2773 }
2774//#endif
b.liua76c9612025-03-28 13:58:09 +08002775 notify_download_start();
2776 _ota_download_progress = ota_download_progress = 0;
2777
2778 download_method_ctx.file_size = size;
2779 download_method_ctx.received_size = 0;
2780 // Init firmware download context
2781 context->flash_cache = malloc(server_cfg.block_size);
2782 if (!context->flash_cache) {
2783 OTA_ERR("Cannot malloc memory for download cache\n");
2784 goto done;
2785 }
b.liu9e96ffe2025-04-03 13:28:05 +08002786//#ifdef CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08002787 memset(context->flash_cache, 0, server_cfg.block_size);
b.liu9e96ffe2025-04-03 13:28:05 +08002788//#endif
b.liua76c9612025-03-28 13:58:09 +08002789 context->checksum_cache = malloc(CHECKSUM_CACHE_SIZE);
2790 if (!context->checksum_cache) {
2791 OTA_ERR("Cannot malloc memory for download cache\n");
2792 goto done;
2793 }
2794 context->flash_cb = push2flash;
2795 }
2796
2797 // download from UDP
2798 int s = -1, c = -1;
2799 OTA_DEBUG("Download through UDP\n");
2800 s = build_udp_server(url);
2801 if (s >= 0) {
2802 c = accept_udp(s);
2803 if (c >= 0) {
2804
2805 if(size!=0){
2806 if(erase_ota_fbf_area())
2807 goto done;
2808 }
2809
2810 __download_throgh_udp(c, segment_size, context);
2811
2812 }else{
2813 OTA_ERR("accept_udp failed\n");
2814 }
2815 }else{
2816 OTA_ERR("build_udp_server failed\n");
2817 return 0;
2818 }
2819 if (s >= 0) close(s);
2820 if (c >= 0) close(c);
2821 ret = 0;
2822
2823done:
2824 if(download_method_ctx.file_size == download_method_ctx.received_size){
2825 // Clear context
2826 if (context->flash_cache) free(context->flash_cache);
2827 context->flash_cache = NULL;
2828 if (context->checksum_cache) free(context->checksum_cache);
2829 context->checksum_cache = NULL;
2830 close(context->fd);
2831 context->fd = -1;
2832 if (image_recheck(context) == 0) {
2833 update_state = UPDATE_STATE_UPDATED;
2834 OTA_ERR("%s: Image download succssful.\n", __func__);
2835 notify_download_end(1);
2836 ret = 0;
2837 } else {
2838 update_state = UPDATE_STATE_FAILED;
2839 OTA_ERR("Image download failed\n");
2840 notify_download_end(0);
2841 ret = -1;
2842 }
2843 if (context->image_state_list) {
2844 free_image_list(context);
2845 context->image_state_list=NULL;
2846 }
2847 if(udp_context){
2848 free(udp_context);
2849 udp_context = NULL;
2850 }
2851
2852
2853 }
2854 else{
2855 //update_state = UPDATE_STATE_IDLE;
2856 //notify_download_end(1);
2857 }
2858exit:
2859
2860 if (url) free(url);
2861 url = NULL;
2862 if (username) free(username);
2863 username = NULL;
2864 if (psw) free(psw);
2865 psw = NULL;
2866 return ret;
2867}
2868
2869
2870static int download_cb(struct uloop_timeout *timeout)
2871{
2872 int type = download_method_ctx.type;
2873 int size = download_method_ctx.size;
2874 char * url = download_method_ctx.url;
2875 char * username = download_method_ctx.username;
2876 char * psw = download_method_ctx.pwd;
2877 struct image_process_context context = {0};
2878 int ret = -1;
2879
b.liu9e96ffe2025-04-03 13:28:05 +08002880//#if !defined(CONFIG_AB_SYSTEM) || defined(CONFIG_AB_SYSTEM_DFOTA)
2881 if(is_dfota) {
2882 context.fd = open(server_cfg.mtd_fbf, O_RDWR | O_SYNC);
2883 if (context.fd < 0) {
2884 OTA_ERR("Cannot open MTD device!\n");
2885 notify_download_end(0);
2886 update_state = UPDATE_STATE_FAILED;
2887 return ret;
2888 }
2889 }
2890//#endif
b.liua76c9612025-03-28 13:58:09 +08002891 notify_download_start();
2892
2893 _ota_download_progress = ota_download_progress = 0;
2894 // Init firmware download context
2895 context.flash_cache = malloc(server_cfg.block_size);
2896 if (!context.flash_cache) {
2897 OTA_ERR("Cannot malloc memory for download cache\n");
2898 goto done;
2899 }
b.liu9e96ffe2025-04-03 13:28:05 +08002900//#ifdef CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08002901 memset(context.flash_cache, 0, server_cfg.block_size);
b.liu9e96ffe2025-04-03 13:28:05 +08002902//#endif
b.liua76c9612025-03-28 13:58:09 +08002903 context.checksum_cache = malloc(CHECKSUM_CACHE_SIZE);
2904 if (!context.checksum_cache) {
2905 OTA_ERR("Cannot malloc memory for download cache\n");
2906 goto done;
2907 }
2908 context.flash_cb = push2flash;
2909
2910 if (type == OTA_TYPE_HTTP) {
2911 // download from http
2912 if(erase_ota_fbf_area())
2913 goto done;
2914 __download_throgh_http(url, &context);
2915 } else if (type == OTA_TYPE_UDP) {
2916 // download from UDP
2917 int s = -1, c = -1;
2918 OTA_DEBUG("Download through UDP\n");
2919 s = build_udp_server(url);
2920 if (s >= 0) {
2921 c = accept_udp(s);
2922 if (c >= 0) {
2923 if(erase_ota_fbf_area())
2924 goto done;
2925 __download_throgh_udp(c, size, &context);
2926 }
2927 }
2928 if (s >= 0) close(s);
2929 if (c >= 0) close(c);
2930 } else if (type == OTA_TYPE_SD) {
2931 // download from SD
2932 if(erase_ota_fbf_area())
2933 goto done;
2934 __download_throgh_sd(url, &context);
2935 } else {
2936 // assert?
2937 OTA_ERR("Unknow download type\n");
2938 }
2939
2940done:
2941 // Clear context
2942 if (context.flash_cache) free(context.flash_cache);
2943 context.flash_cache = NULL;
2944 if (context.checksum_cache) free(context.checksum_cache);
2945 context.checksum_cache = NULL;
2946 if (url) free(url);
2947 url = NULL;
2948 if (username) free(username);
2949 username = NULL;
2950 if (psw) free(psw);
2951 psw = NULL;
b.liu9e96ffe2025-04-03 13:28:05 +08002952//#if !defined(CONFIG_AB_SYSTEM) || defined(CONFIG_AB_SYSTEM_DFOTA)
2953 if(is_dfota) {
2954 close(context.fd);
2955 context.fd = -1;
2956 }
2957//#endif
b.liua76c9612025-03-28 13:58:09 +08002958 // Change by mbtk
2959 if ((image_recheck(&context) == 0) && !Download_flag) {
2960 update_state = UPDATE_STATE_UPDATED;
2961 OTA_DEBUG("Image download succssful\n");
2962
2963 // Add by liubin
2964 revision_out_update();
2965 // End by liubin
2966
2967 notify_download_end(1);
2968 ret = 0;
2969 } else {
2970 update_state = UPDATE_STATE_FAILED;
2971 OTA_ERR("Image download failed\n");
2972 notify_download_end(0);
2973 ret = -1;
2974 }
2975
2976 if (context.image_state_list) {
2977 free_image_list(&context);
2978 }
2979 return ret;
2980}
2981
2982static struct uloop_timeout download_timer = { .cb = (void*)download_cb };
2983static struct uloop_timeout udp_download_timer = { .cb = (void*)udp_download_cb };
2984
2985
2986static int download_func(struct ubus_context *ctx, struct ubus_object *obj,
2987 struct ubus_request_data *req, const char *method,
2988 struct blob_attr *msg)
2989{
2990 struct blob_attr *tb[__DOWNLOAD_MAX];
2991 int ret = -1;
2992 int sync = 0; /* default is no sync */
2993 int type=-1;
2994 blob_buf_init(&b, 0);
2995
2996 blobmsg_parse(download_policy, ARRAY_SIZE(download_policy), tb, blob_data(msg), blob_len(msg));
2997 if (tb[DOWNLOAD_TYPE]) type = blobmsg_get_u32(tb[DOWNLOAD_TYPE]);
2998
2999
3000 if ((update_state == UPDATE_STATE_IDLE ||update_state == UPDATE_STATE_FAILED) ||
3001 (type == OTA_TYPE_UDP && update_state == UPDATE_STATE_UPDATING)) {
3002 update_state = UPDATE_STATE_UPDATING;
3003
3004 OTA_DEBUG("Method call: %s\n", method);
3005 //memset(&download_method_ctx, 0, sizeof(download_method_ctx));
3006 download_method_ctx.url = download_method_ctx.username = download_method_ctx.pwd =NULL;
3007 download_method_ctx.type = download_method_ctx.size = download_method_ctx.segment_size= 0;
3008 if (tb[DOWNLOAD_URL]) download_method_ctx.url = strdup(blobmsg_data(tb[DOWNLOAD_URL]));
3009 if (tb[DOWNLOAD_NAME]) download_method_ctx.username = strdup(blobmsg_data(tb[DOWNLOAD_NAME]));
3010 if (tb[DOWNLOAD_PSW]) download_method_ctx.pwd = strdup(blobmsg_data(tb[DOWNLOAD_PSW]));
3011 if (tb[DOWNLOAD_TYPE]) download_method_ctx.type = blobmsg_get_u32(tb[DOWNLOAD_TYPE]);
3012 if (tb[DOWNLOAD_FILE_SIZE]) download_method_ctx.size = blobmsg_get_u32(tb[DOWNLOAD_FILE_SIZE]);
3013 if (tb[DOWNLOAD_SYNC]) sync = blobmsg_get_u32(tb[DOWNLOAD_SYNC]);
3014 if (tb[DOWNLOAD_SEGMENT_SIZE]) download_method_ctx.segment_size = blobmsg_get_u32(tb[DOWNLOAD_SEGMENT_SIZE]);
3015
3016 if (download_method_ctx.url) OTA_DEBUG(" url: %s\n", download_method_ctx.url);
3017 if (download_method_ctx.username) OTA_DEBUG(" username: %s\n", download_method_ctx.username);
3018 if (download_method_ctx.pwd) OTA_DEBUG(" password: %s\n", download_method_ctx.pwd);
3019 OTA_DEBUG(" type: %d, size: %d ,segment size: %d\n", download_method_ctx.type, download_method_ctx.size,download_method_ctx.segment_size);
3020
3021 if (sync != 1) {
3022 if(download_method_ctx.type == OTA_TYPE_UDP){
3023 uloop_timeout_set(&udp_download_timer, 1);
3024 }else{
3025 uloop_timeout_set(&download_timer, 1);
3026 }
3027 blobmsg_add_string(&b, "response", "download ready");
3028 ret = 0;
3029 } else {
3030 if(download_method_ctx.type == OTA_TYPE_UDP){
3031 ret = udp_download_cb(&udp_download_timer);
3032 }else{
3033 ret = download_cb(&download_timer);
3034 }
3035 if (ret == 0) {
3036 blobmsg_add_string(&b, "response", "image download succssful");
3037 } else {
3038 blobmsg_add_string(&b, "response", "image download failed");
3039 }
3040 }
3041 } else {
3042 OTA_ERR("Error! update already in processing or be processed\n");
3043 blobmsg_add_string(&b, "response", "download failed (update already in processing or be processed)");
3044 ret = -1;
3045 }
3046
3047 ubus_send_reply(ctx, req, b.head);
3048 return ret;
3049}
3050
3051// Version check
3052struct xml_parse_context {
3053 const char * file;
3054 int i;
3055 char tag[OTA_MAX_STRING_LEN];
3056 char * value;
3057 int value_size;
3058 int state;
3059};
3060enum {
3061 XML_STATE_NULL,
3062 XML_STATE_TAG,
3063 XML_STATE_VALUE,
3064};
3065static int get_next_tag(struct xml_parse_context * context)
3066{
3067 int len = 0;
3068 int i = context->i;
3069 int start = 0;
3070 if (context->file[i++] != '<') {
3071 return -1;
3072 }
3073 if (context->file[i] == '/') {
3074 return -1;
3075 }
3076 start = i;
3077 while (context->file[i] != '\0') {
3078 if (context->file[i] == '>') {
3079 memset(context->tag, 0, OTA_MAX_STRING_LEN);
3080 if (len > OTA_MAX_STRING_LEN) {
3081 OTA_ERR("Memory issue in get_next_tag(%d)!\n", len);
3082 return -1;
3083 }
3084 memcpy(context->tag, &context->file[start], len);
3085 context->i += (len + 2);
3086 OTA_DEBUG("Tag: %s\n", context->tag);
3087 return 0;
3088 }
3089 len++;
3090 i++;
3091 }
3092 return -1;
3093}
3094static int get_next_value(struct xml_parse_context * context)
3095{
3096 int len = 0;
3097 int i = context->i;
3098 int start = 0;
3099 if (context->file[i] == '<') {
3100 return -1;
3101 }
3102 while (context->file[i] == '\r' || context->file[i] == '\t' || context->file[i] == '\n') {
3103 i++;
3104 }
3105 start = i;
3106 while (context->file[i] != '\0') {
3107 if (context->file[i] == '<') {
3108 if (context->file[i + 1] != '/') {
3109 OTA_ERR("Bad file!\n");
3110 return -1;
3111 }
3112 if (strncmp(&context->file[i + 2], context->tag, strlen(context->tag))) {
3113 OTA_ERR("tag not match!\n");
3114 return -1;
3115 }
3116 memset(context->value, 0, context->value_size);
3117 if (len > context->value_size) {
3118 OTA_ERR("Memory issue in get_next_vale(%d:%d)!\n", len, context->value_size);
3119 return -1;
3120 }
3121 memcpy(context->value, &context->file[start], len);
3122 context->i += (len + 3 + strlen(context->tag));
3123 OTA_DEBUG("Value: %s\n", context->value);
3124 return 0;
3125 }
3126 len++;
3127 i++;
3128 }
3129 return -1;
3130}
3131
3132static int version_parse(const char * string, struct version_info * ver)
3133{
3134 #define OTA_MARVELL_VERSION_TAG "Marvell"
3135 #define OTA_MARVELL_VERSION_TAG_VER "Version"
3136 #define OTA_MARVELL_VERSION_TAG_URL "URL"
3137 #define OTA_MARVELL_VERSION_TAG_NOTE "ReleaseNote"
3138 struct xml_parse_context context = {0};
3139 #define MAX_XML_VALUE_SIZE 4096
3140 int ret = 0;
3141
3142 if (string == NULL || ver == NULL) {
3143 OTA_ERR("Invalid parameters!\n");
3144 return -1;
3145 }
3146
3147 context.file = string;
3148 context.value = malloc(MAX_XML_VALUE_SIZE);
3149 if (context.value == NULL) {
3150 OTA_ERR("Malloc for context buffer failed!\n");
3151 return -1;
3152 }
3153 context.value_size = MAX_XML_VALUE_SIZE;
3154
3155 if (get_next_tag(&context) < 0) {
3156 OTA_ERR("Parse first tag failed!\n");
3157 ret = -1;
3158 goto done;
3159 }
3160 if (strcmp(context.tag, OTA_MARVELL_VERSION_TAG)) {
3161 OTA_ERR("First tag is not %s\n", OTA_MARVELL_VERSION_TAG);
3162 ret = -1;
3163 goto done;
3164 }
3165 while (get_next_tag(&context) == 0) {
3166 if (get_next_value(&context) == 0) {
3167 if (!strcmp(context.tag, OTA_MARVELL_VERSION_TAG_VER)) {
3168 OTA_DEBUG("Handle version: %s\n", context.value);
3169 snprintf(ver->version, OTA_MAX_STRING_LEN, "%s", context.value);
3170 } else if (!strcmp(context.tag, OTA_MARVELL_VERSION_TAG_URL)) {
3171 OTA_DEBUG("Handle URL: %s\n", context.value);
3172 snprintf(ver->url, OTA_MAX_STRING_LEN, "%s", context.value);
3173 } else if (!strcmp(context.tag, OTA_MARVELL_VERSION_TAG_NOTE)) {
3174 OTA_DEBUG("Handle release note: %s\n", context.value);
3175 if (ver->release_note) {
3176 free(ver->release_note);
3177 ver->release_note = NULL;
3178 }
3179 ver->release_note = strdup(context.value);
3180 }
3181 }
3182 }
3183done:
3184 if (context.value) {
3185 free(context.value);
3186 }
3187 return ret;
3188}
3189
3190static int version_check_cb(char * data, int len, int num, void *cbdata)
3191{
3192 struct version_check_context * context = (struct version_check_context *)cbdata;
3193 if ((context->size - context->used) < len) {
3194 char * buf = realloc(context->url, context->size + num);
3195 if (buf == NULL) {
3196 OTA_ERR("Memory issue at version_check_cb\n");
3197 return -1;
3198 }
3199 context->size += num;
3200 context->url = buf;
3201 memcpy(context->url + context->used, data, len);
3202 context->used += len;
3203 } else {
3204 memcpy(context->url + context->used, data, len);
3205 context->used += len;
3206 }
3207 return 0;
3208}
3209struct version_check_context version_check_context = {0};
3210static int detect_new_version(struct ota_server * server, char ** firmwar_url)
3211{
3212 struct http_client * client = NULL;
3213 struct http_client_list * header = NULL;
3214 int http_response_code = 0;
3215 int ret = -1;
3216 char buf[OTA_MAX_STRING_LEN + 30] = {0};
3217
3218 OTA_DEBUG("Try access %s for version check\n", server->server_url);
3219
3220 client = http_client_init();
3221 if (client == NULL) {
3222 OTA_ERR("HTTP client init failed!\n");
3223 return -1;
3224 }
3225
3226 version_check_context.url = malloc(OTA_MAX_STRING_LEN);
3227 if (version_check_context.url == NULL) {
3228 OTA_ERR("Malloc failed!\n");
3229 goto done;
3230 }
3231 memset(version_check_context.url, 0, OTA_MAX_STRING_LEN);
3232 version_check_context.size = OTA_MAX_STRING_LEN;
3233 version_check_context.used = 0;
3234
3235 http_client_setopt(client, HTTPCLIENT_OPT_URL, server->server_url);
3236 http_client_setopt(client, HTTPCLIENT_OPT_RESPONSECB, version_check_cb);
3237 http_client_setopt(client, HTTPCLIENT_OPT_METHOD, HTTPCLIENT_REQUEST_POST);
3238 http_client_setopt(client, HTTPCLIENT_OPT_RESPONSECB_DATA, &version_check_context);
3239 snprintf(buf, sizeof(buf), "MarvellOTA: version=%s\r\n", version_check_context.version);
3240 header = http_client_list_append(header, buf);
3241 http_client_setopt(client, HTTPCLIENT_OPT_HTTPHEADER, header);
3242 http_client_perform(client);
3243 http_client_getinfo(client, HTTPCLIENT_GETINFO_RESPONSE_CODE, &http_response_code);
3244
3245 OTA_DEBUG("Version check result: %d\n", http_response_code);
3246 if (http_response_code == 200) {
3247 version_parse(version_check_context.url, &server_cfg.ver);
3248 OTA_DEBUG("Detected new version at: %s\n", server_cfg.ver.url);
3249 *firmwar_url = strdup(server_cfg.ver.url);
3250 } else {
3251 // Free memory
3252 // If http response is HTTP 200 OK, version checking caller should free this memory
3253 free(version_check_context.url);
3254 version_check_context.url = NULL;
3255 version_check_context.size = 0;
3256 version_check_context.used = 0;
3257 }
3258 ret = 0;
3259done:
3260 if (client) http_client_shutdown(client);
3261 return ret;
3262}
3263
3264enum {
3265 QUERY_TYPE,
3266 __QUERY_MAX
3267};
3268
3269static const struct blobmsg_policy query_policy[] = {
3270 [QUERY_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING },
3271};
3272
3273static int query_func(struct ubus_context *ctx, struct ubus_object *obj,
3274 struct ubus_request_data *req, const char *method,
3275 struct blob_attr *msg)
3276{
3277 struct blob_attr *tb[__QUERY_MAX];
3278 char * type = NULL;
3279 const char * string = NULL;
3280
3281 OTA_DEBUG("enter: %s\n", __func__);
3282 blobmsg_parse(query_policy, ARRAY_SIZE(query_policy), tb, blob_data(msg), blob_len(msg));
3283
3284 if (tb[QUERY_TYPE]) type = blobmsg_data(tb[QUERY_TYPE]);
3285 if (type == NULL) {
3286 blob_buf_init(&b, 0);
3287 blobmsg_add_string(&b, "response", "failed");
3288 ubus_send_reply(ctx, req, b.head);
3289 OTA_ERR("Failed query type\n");
3290 return 0;
3291 }
3292 if (*type == '1') {
3293 // Download states
3294 switch (update_state) {
3295 case UPDATE_STATE_UPDATING:
3296 string = "updating";
3297 break;
3298 case UPDATE_STATE_UPDATED:
3299 string = "success";
3300 break;
3301 case UPDATE_STATE_FAILED:
3302 string = "failed";
3303 break;
3304 case UPDATE_STATE_IDLE:
3305 default:
3306 string = "not start";
3307 break;
3308 }
3309 blob_buf_init(&b, 0);
3310 blobmsg_add_string(&b, "response", string);
3311 ubus_send_reply(ctx, req, b.head);
3312 return 0;
3313 } else if (*type == '0' ) {
3314 // Query new version
3315 int len = strlen(server_cfg.ver.version);
3316 if (len != 0) {
3317 char * buf = malloc(len + 50);
3318 if (buf == NULL) {
3319 OTA_ERR("Malloc failed!\n");
3320 blob_buf_init(&b, 0);
3321 blobmsg_add_string(&b, "response", "failed:memory issue");
3322 ubus_send_reply(ctx, req, b.head);
3323 return 0;
3324 }
3325 memset(buf, 0, len + 30);
3326 sprintf(buf, "has new version:[%s]", server_cfg.ver.version);
3327 blob_buf_init(&b, 0);
3328 blobmsg_add_string(&b, "response", buf);
3329 ubus_send_reply(ctx, req, b.head);
3330 free(buf);
3331 buf = NULL;
3332 return 0;
3333 } else {
3334 blob_buf_init(&b, 0);
3335 blobmsg_add_string(&b, "response", "no new version");
3336 ubus_send_reply(ctx, req, b.head);
3337 return 0;
3338 }
3339 } else {
3340 blob_buf_init(&b, 0);
3341 blobmsg_add_string(&b, "response", "unkonw");
3342 ubus_send_reply(ctx, req, b.head);
3343 OTA_ERR("unkonw query type %s\n", type);
3344 return 0;
3345 }
3346}
3347
3348static const struct ubus_method otad_method[] = {
3349 UBUS_METHOD("download", download_func, download_policy),
3350 UBUS_METHOD("query", query_func, query_policy),
3351};
3352
3353static struct ubus_object_type otad_object_type = UBUS_OBJECT_TYPE("ota", otad_method);
3354
3355static struct ubus_object ota_object = {
3356 .name = "ota",
3357 .type = &otad_object_type,
3358 .methods = otad_method,
3359 .n_methods = ARRAY_SIZE(otad_method),
3360};
3361
3362static void version_check(struct uloop_timeout *timeout);
3363static struct uloop_timeout version_check_timer = { .cb = version_check };
3364
3365
3366static void version_check(struct uloop_timeout *timeout)
3367{
3368 char * firmware = NULL;
3369 OTA_DEBUG("Try checking new version\n");
3370
3371 if (update_state == UPDATE_STATE_UPDATING) {
3372 OTA_ERR("Firmware updating... Reset timer.\n");
3373 goto reset_timer;
3374 } else if (update_state == UPDATE_STATE_UPDATED) {
3375 OTA_ERR("Firmware already be updated, not need detect again\n");
3376 return;
3377 }
3378
3379 detect_new_version(&server_cfg, &firmware);
3380 if (firmware && strlen(firmware) && server_cfg.download_immediately != 0) {
3381 OTA_DEBUG("New firmware at: %s\n", firmware);
3382 do {
3383 unsigned int id;
3384 static struct ubus_request req;
3385 char firmare_url[OTA_MAX_STRING_LEN + 1] = {0};
3386 snprintf(firmare_url, sizeof(firmare_url), "%s/%s", server_cfg.server_url, firmware);
3387 if (ubus_lookup_id(ctx, "ota", &id)) {
3388 OTA_ERR("Cannot found object...\n");
3389 break;
3390 }
3391 blob_buf_init(&b, 0);
3392 blobmsg_add_string(&b, "url", firmare_url);
3393 blobmsg_add_string(&b, "username", "user name");
3394 blobmsg_add_u32(&b, "type", 0);
3395 ubus_invoke_async(ctx, id, "download", b.head, &req);
3396 ubus_complete_request_async(ctx, &req);
3397 } while (0);
3398 free(firmware);
3399 firmware = NULL;
3400 if (update_state == UPDATE_STATE_UPDATED) {
3401 //1TODO: Post system reset for new image install
3402 OTA_DEBUG("Firmware download success, will post system reboot\n");
3403 return;
3404 } else {
3405 uloop_timeout_set(&version_check_timer, server_cfg.interval * 2);
3406 }
3407 }
3408reset_timer:
3409 uloop_timeout_set(&version_check_timer, server_cfg.interval * 1000);
3410}
3411
3412static unsigned int get_mtd_offset(int mtd)
3413{
3414 char file[64] = {0};
3415 char content[32] = {0};
3416 int fd;
3417 sprintf(file, "/sys/class/mtd/mtd%d/offset", mtd);
3418 fd = open(file, O_RDONLY);
3419 if (fd < 0) {
3420 OTA_ERR("%s: failed to open %s\n", __func__, file);
3421 return -1;
3422 }
3423
3424 read(fd, content, 32);
3425 close(fd);
3426 return atoi(content);
3427}
3428
b.liu9e96ffe2025-04-03 13:28:05 +08003429//#ifdef CONFIG_AB_SYSTEM
3430//#ifndef CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08003431static int get_mtd_pagesize(int mtd, unsigned int *pagesize)
3432{
3433 struct mtd_info_user mtdinfo;
3434 char dev[32];
3435 int fd;
3436
3437 memset(dev, 0, sizeof(dev));
3438 sprintf(dev, "/dev/mtd%d", mtd);
3439 fd = open(dev, O_RDONLY);
3440 if (fd < 0) {
3441 OTA_ERR("%s: failed to open %s.\n", __func__, dev);
3442 return -1;
3443 }
3444
3445 if (ioctl(fd, MEMGETINFO, &mtdinfo)) {
3446 OTA_ERR("%s: Could not get MTD device info from %s\n", __func__, dev);
3447 close(fd);
3448 return -1;
3449 }
3450
3451 *pagesize = mtdinfo.writesize;
3452 OTA_DEBUG("%s: %s, pagesize: %d\n", __func__, dev, *pagesize);
3453
3454 return 0;
3455}
b.liu9e96ffe2025-04-03 13:28:05 +08003456//#endif
3457//#endif
b.liua76c9612025-03-28 13:58:09 +08003458
3459static int init_cfg(const char * uci_path)
3460{
3461 FILE * fp = NULL;
3462 #define MAX_LINE_SIZE 128
3463 char buf[MAX_LINE_SIZE] = {0};
3464
b.liu49596152025-03-31 14:02:15 +08003465#if 0
b.liua76c9612025-03-28 13:58:09 +08003466 /*
3467 ota.@ota[0]=ota
3468 ota.@ota[0].fbf_address='0x2A60000'
3469 ota.@ota[0].progress_notify='10'
3470 ota.@ota[0].interval='5'
3471 ota.@ota[0].first_interval='1'
3472 */
3473 if (uci_path) { /* If UCI file exist parse it */
3474 struct uci_context *uci_ctx = NULL;
3475 struct uci_package *p = NULL;
3476 struct uci_section *s = NULL;
3477 struct uci_element *e1 = NULL, *e2 = NULL;
3478 uci_ctx = uci_alloc_context();
3479 if (uci_load(uci_ctx, uci_path, &p)) {
3480 OTA_ERR("uci load failed\n");
3481 uci_free_context(uci_ctx);
3482 return -1;
3483 }
3484
3485 uci_foreach_element(&p->sections, e1) {
3486 s = uci_to_section(e1);
3487 if (strcmp(s->type, "ota")) {
3488 continue;
3489 }
3490
3491 uci_foreach_element(&s->options, e2) {
3492 if (!strcmp((uci_to_option(e2))->e.name, "server_url")) {
3493 OTA_DEBUG("OTA server URL: %s\n", (uci_to_option(e2))->v.string);
3494 snprintf(server_cfg.server_url, OTA_MAX_STRING_LEN, "%s", (uci_to_option(e2))->v.string);
3495 } else if (!strcmp((uci_to_option(e2))->e.name, "progress_nofity")) {
3496 OTA_DEBUG("Download notify interval: %s\n", (uci_to_option(e2))->v.string);
3497 sscanf((uci_to_option(e2))->v.string, "%d", &server_cfg.progress_notify);
3498 } else if (!strcmp((uci_to_option(e2))->e.name, "interval")) {
3499 OTA_DEBUG("Download version detect interval: %s\n", (uci_to_option(e2))->v.string);
3500 sscanf((uci_to_option(e2))->v.string, "%d", &server_cfg.interval);
3501 } else if (!strcmp((uci_to_option(e2))->e.name, "first_interval")) {
3502 OTA_DEBUG("Download first version detect interval: %s\n", (uci_to_option(e2))->v.string);
3503 sscanf((uci_to_option(e2))->v.string, "%d", &server_cfg.first_interval);
3504 } else if (!strcmp((uci_to_option(e2))->e.name, "download_immediately")) {
3505 OTA_DEBUG("Download firmware immediately: %s\n", (uci_to_option(e2))->v.string);
3506 sscanf((uci_to_option(e2))->v.string, "%d", &server_cfg.download_immediately);
3507 }
3508 }
3509 }
3510
3511 uci_free_context(uci_ctx);
3512 uci_ctx = NULL;
3513 }
3514#endif
3515
b.liu9e96ffe2025-04-03 13:28:05 +08003516#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08003517 fp = fopen("/proc/emmc", "r");
3518#else
3519 fp = fopen("/proc/mtd", "r");
3520#endif
3521 if (fp == NULL) {
3522 OTA_ERR("Open MTD failed!\n");
3523 return -1;
3524 }
3525
b.liu9e96ffe2025-04-03 13:28:05 +08003526//#ifdef CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08003527 server_cfg.mtd_cnt = 0;
3528 OTA_DEBUG("Start to retrive the mtd partition info...\n");
b.liu9e96ffe2025-04-03 13:28:05 +08003529 #if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08003530 server_cfg.emmc_block_size = 512; /* emmc */
3531 server_cfg.block_size = 0x20000; /* only used for buffer cache size */
3532
3533 struct image_mtd_info *bootdev;
3534 /* the main bootloader */
3535 bootdev = &server_cfg.image_mtd_info[0];
3536 sprintf(bootdev->dev, "%s", "mmcblk1boot0");
3537 sprintf(bootdev->name, "%s", "bootloader0");
3538 bootdev->flag = SYSTEM_SINGLE;
3539 bootdev->flash_start_offset = 0;
3540
3541 /* the backup bootloader */
3542 bootdev = &server_cfg.image_mtd_info[1];
3543 sprintf(bootdev->dev, "%s", "mmcblk1boot1");
3544 sprintf(bootdev->name, "%s", "bootloader1");
3545 bootdev->flag = SYSTEM_SINGLE;
3546 bootdev->flash_start_offset = 0;
3547
3548 server_cfg.mtd_cnt = 2;
3549 #else
3550 server_cfg.block_size = 0x20000; /* nand flash */
3551 if (get_mtd_pagesize(0, &server_cfg.pagesize) < 0) {
3552 fclose(fp);
3553 return -1;
3554 }
3555 #endif
b.liu9e96ffe2025-04-03 13:28:05 +08003556//#endif
b.liua76c9612025-03-28 13:58:09 +08003557
3558 /*
3559 root@OpenWrt:~# cat /proc/mtd
3560 dev: size erasesize name
3561 mtd0: 000a0000 00020000 "bootloader"
3562 mtd1: 00020000 00020000 "cp_reliabledata"
3563 mtd2: 00020000 00020000 "ap_reliabledata"
3564 mtd3: 00020000 00020000 "cp_reliabledata_backup"
3565 mtd4: 00020000 00020000 "ap_reliabledata_backup"
3566 mtd5: 00020000 00020000 "mep-ota"
3567 mtd6: 00020000 00020000 "mep-ota_backup"
3568 mtd7: 00100000 00020000 "asr_flag"
3569 mtd8: 00040000 00020000 "dtim-a"
3570 mtd9: 00040000 00020000 "dtim-b"
3571 mtd10: 00de0000 00020000 "cpimage-a"
3572 mtd11: 00de0000 00020000 "cpimage-b"
3573 mtd12: 000c0000 00020000 "u-boot-a"
3574 mtd13: 000c0000 00020000 "u-boot-b"
3575 mtd14: 00500000 00020000 "kernel-a"
3576 mtd15: 00500000 00020000 "kernel-b"
3577 mtd16: 00040000 00020000 "device_info"
3578 mtd17: 02800000 00020000 "OTA"
3579 mtd18: 00040000 00020000 "cust_info"
3580 mtd19: 00020000 00020000 "rootfs-a-sdtim"
3581 mtd20: 013e0000 00020000 "rootfs-a-mount"
3582 mtd21: 01400000 00020000 "rootfs-a"
3583 mtd22: 00020000 00020000 "rootfs-b-sdtim"
3584 mtd23: 013e0000 00020000 "rootfs-b-mount"
3585 mtd24: 01400000 00020000 "rootfs-b"
3586 mtd25: 00020000 00020000 "oem_data-a-sdtim"
3587 mtd26: 006e0000 00020000 "oem_data-a-mount"
3588 mtd27: 00700000 00020000 "oem_data-a"
3589 mtd28: 00020000 00020000 "oem_data-b-sdtim"
3590 mtd29: 006e0000 00020000 "oem_data-b-mount"
3591 mtd30: 00700000 00020000 "oem_data-b"
3592 mtd31: 01400000 00020000 "rootfs_data"
3593 mtd32: 05640000 00020000 "user_data"
3594 mtd33: 00d20000 00020000 "MRVL_BBM"
3595 */
3596 while (fgets(buf, MAX_LINE_SIZE, fp) != NULL) {
3597 char name[200] = {0};
3598 char size[200] = {0};
3599 char erasesize[200] = {0};
3600 char tag[64] = {0};
3601 int cnt = 0;
3602 int index = 0;
3603 char * p = buf;
b.liu9e96ffe2025-04-03 13:28:05 +08003604#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08003605 /* skip prev ' ' */
3606 while ((index < (MAX_LINE_SIZE-1)) && (buf[index] == ' '))
3607 index++;
3608 p = &buf[index];
3609#endif
3610 while ((index < (MAX_LINE_SIZE-1)) && (buf[index] != '\0')) {
3611 if (buf[index] == ' ') {
3612 buf[index] = '\0';
3613 if (cnt == 0) {
3614 snprintf(name, sizeof(name), "%s", p);
3615 } else if (cnt == 1) {
3616 snprintf(size, sizeof(size), "%s", p);
3617 } else if (cnt == 2) {
3618 snprintf(erasesize, sizeof(erasesize), "%s", p);
3619 snprintf(tag, 64, "%s", &buf[index + 1]);
3620 break;
3621 }
3622 cnt++;
3623 p = &buf[index + 1];
3624 }
3625 index++;
3626 }
b.liu9e96ffe2025-04-03 13:28:05 +08003627#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08003628 if (strncmp(name, "dev", 3) == 0)
3629 continue;
3630 /* retrive the mtd partition info */
3631 struct image_mtd_info *pCurrentMtdInfo = &server_cfg.image_mtd_info[server_cfg.mtd_cnt];
3632 int j = strlen(name);
3633 if (name[j - 1] == ':')
3634 name[j - 1] = '\0';
3635 sprintf(pCurrentMtdInfo->dev, "%s", name);
3636 sprintf(pCurrentMtdInfo->name, "%s", tag);
3637
3638 pCurrentMtdInfo->flag = SYSTEM_SINGLE;
3639 j = strlen(tag);
3640 /* the last tow chars for tag are "\n */
3641 if (tag[j - 4] == '-') {
3642 if (tag[j - 3] == 'a')
3643 pCurrentMtdInfo->flag = SYSTEM_A;
3644 else if (tag[j - 3] == 'b')
3645 pCurrentMtdInfo->flag = SYSTEM_B;
3646 }
3647
3648 /* remove the last \n */
3649 pCurrentMtdInfo->name[strlen(pCurrentMtdInfo->name) - 1] = 0;
3650
3651 sscanf(size, "%x", &pCurrentMtdInfo->size);
3652 sscanf(erasesize, "%x", &pCurrentMtdInfo->erasesize);
3653
b.liu9e96ffe2025-04-03 13:28:05 +08003654#if 0//def CONFIG_PARTITION_EMMC
b.liua76c9612025-03-28 13:58:09 +08003655 /* dev: size start name */
3656 /* the "erasesize" field represent "start" block in emmc */
3657 pCurrentMtdInfo->flash_start_offset = pCurrentMtdInfo->erasesize * server_cfg.emmc_block_size;
3658 pCurrentMtdInfo->size *= server_cfg.emmc_block_size;
3659#else
3660 pCurrentMtdInfo->flash_start_offset = get_mtd_offset(server_cfg.mtd_cnt);
3661#endif
3662 OTA_DEBUG(" Dev: %s, FlashOffset: 0x%x, Size: 0x%x, EraseSize: 0x%x, Name: %s\n",
3663 pCurrentMtdInfo->dev, pCurrentMtdInfo->flash_start_offset, pCurrentMtdInfo->size,
3664 pCurrentMtdInfo->erasesize, pCurrentMtdInfo->name);
3665 if (strstr(pCurrentMtdInfo->name, "asr_flag")) {
3666 int bln=0;
3667 #ifdef CONFIG_PARTITION_EMMC
3668 sscanf(name, "mmcblk1p%d", &bln);
3669 snprintf(server_cfg.mtd_asrflag, 64, "/dev/mmcblk1p%d", bln);
3670 #else
3671 sscanf(name, "mtd%d", &bln);
3672 snprintf(server_cfg.mtd_asrflag, 64, "/dev/mtdblock%d", bln);
3673 #endif
3674 }
b.liu9e96ffe2025-04-03 13:28:05 +08003675//#ifdef CONFIG_AB_SYSTEM_DFOTA
3676 else if (is_dfota && strstr(pCurrentMtdInfo->name, "OTA")) {
b.liua76c9612025-03-28 13:58:09 +08003677 sscanf(size, "%x", &server_cfg.fbf_length);
3678 #ifndef CONFIG_PARTITION_EMMC
3679 sscanf(erasesize, "%x", &server_cfg.block_size);
3680 #endif
b.liu49596152025-03-31 14:02:15 +08003681 snprintf(server_cfg.mtd_fbf, 300, "/dev/%s", name);
b.liua76c9612025-03-28 13:58:09 +08003682 server_cfg.fbf_addr = pCurrentMtdInfo->flash_start_offset;
3683 OTA_DEBUG("Get MTD info: 0x%x\n", server_cfg.fbf_addr);
3684 OTA_DEBUG(" name: %s\n", server_cfg.mtd_fbf);
3685 OTA_DEBUG(" size: %08x\n", server_cfg.fbf_length);
3686 OTA_DEBUG(" erasesize: %08x\n", server_cfg.block_size);
3687 OTA_DEBUG(" tag: %s\n", tag);
3688 }
b.liu9e96ffe2025-04-03 13:28:05 +08003689//#endif
b.liua76c9612025-03-28 13:58:09 +08003690 server_cfg.mtd_cnt++;
3691#else
3692 if (strncmp(tag, "\"asr_flag\"", 10) == 0) {
3693 int j = strlen(name);
3694 unsigned int asr_size;
3695 unsigned int asr_erasesize;
3696 sscanf(size, "%x", &asr_size);
3697 sscanf(erasesize, "%x", &asr_erasesize);
3698 if (name[j - 1] == ':') {
3699 name[j - 1] = '\0';
3700 }
3701 int bln=0;
3702 sscanf(name, "mtd%d", &bln);
3703 //sprintf(asr_flag_path, "/dev/mtdblock%d", bln);
3704
3705 snprintf(server_cfg.mtd_asrflag, 64, "/dev/mtdblock%d", bln);
3706 OTA_DEBUG("Get MTD info:\n");
3707 OTA_DEBUG(" name: %s\n", name);
3708 OTA_DEBUG(" mtd_asrflag: %s\n", server_cfg.mtd_asrflag);
3709 OTA_DEBUG(" size: %08x\n", asr_size);
3710 OTA_DEBUG(" erasesize: %08x\n", asr_erasesize);
3711 OTA_DEBUG(" tag: %s\n", tag);
3712 }else if (strncmp(tag, "\"OTA\"", 5) == 0) {
3713 int j = strlen(name);
3714 sscanf(size, "%x", &server_cfg.fbf_length);
3715 sscanf(erasesize, "%x", &server_cfg.block_size);
3716 if (name[j - 1] == ':') {
3717 name[j - 1] = '\0';
3718 }
3719
3720 int bln=0;
3721 sscanf(name, "mtd%d", &bln);
3722 server_cfg.fbf_addr = get_mtd_offset(bln);
b.liu49596152025-03-31 14:02:15 +08003723 snprintf(server_cfg.mtd_fbf, 300, "/dev/%s", name);
b.liua76c9612025-03-28 13:58:09 +08003724 OTA_DEBUG("Get MTD info:\n");
3725 OTA_DEBUG(" name: %s\n", server_cfg.mtd_fbf);
3726 OTA_DEBUG(" size: %08x\n", server_cfg.fbf_length);
3727 OTA_DEBUG(" erasesize: %08x\n", server_cfg.block_size);
3728 OTA_DEBUG(" tag: %s\n", tag);
3729 OTA_DEBUG(" fbf_addr: 0x%08x\n", server_cfg.fbf_addr);
3730 }
3731#endif
3732 memset(buf, 0, MAX_LINE_SIZE);
3733 }
3734 fclose(fp);
b.liu9e96ffe2025-04-03 13:28:05 +08003735#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08003736 gInActiveSystem = get_inactive_system();
3737 if (gInActiveSystem != SYSTEM_B && gInActiveSystem != SYSTEM_A) {
3738 OTA_ERR("FATAL ERROR, no legal inactive system flag exist...");
3739 return -1;
3740 }
3741 OTA_DEBUG("Inactive System is %c...\n", gInActiveSystem);
3742 system_sync();
3743#endif
3744 return 0;
3745}
3746
3747static int sync_mversion(void)
3748{
3749 int ret = 0, i;
3750 int fd_asrflag, fd_mversion;
3751 int len_asrflag, len_mversion, len;
3752 char mversion[128];
3753 struct tr069_firmware_flag AsrFlag;
3754 char *p_mversion;
3755 p_mversion = AsrFlag.mversion;
3756
b.liu9e96ffe2025-04-03 13:28:05 +08003757#if 1//def CONFIG_AB_SYSTEM
b.liua76c9612025-03-28 13:58:09 +08003758 if (gInActiveSystem == SYSTEM_A)
3759 p_mversion = AsrFlag.MVersion_B;
3760#endif
3761
3762 memset(mversion, 0, 128);
3763
3764 fd_asrflag = open(server_cfg.mtd_asrflag, O_RDWR);
3765 if (fd_asrflag < 0) {
3766 OTA_ERR("Fatal error: can't open asr flag %s\n", server_cfg.mtd_asrflag);
3767 return -1;
3768 }
3769
3770 len_asrflag = read(fd_asrflag, &AsrFlag, sizeof(AsrFlag));
3771 if (len_asrflag != sizeof(AsrFlag)) {
3772 OTA_ERR("Fatal error: read %d bytes(expect %d)\n", len_asrflag, sizeof(AsrFlag));
3773 close(fd_asrflag);
3774 return -1;
3775 }
3776
3777 fd_mversion = open("/etc/mversion", O_RDWR);
3778 if (fd_mversion < 0) {
3779 OTA_ERR("Fatal error: can't open /etc/mversion\n");
3780 close(fd_asrflag);
3781 return -1;
3782 }
3783 len_mversion = read(fd_mversion, mversion, 128);
3784 if(len_mversion <= 0)
3785 {
3786 OTA_ERR("Fatal error: read mversion\n");
3787 ret = -1;
3788 goto sync_done;
3789 }
3790
3791 for (i = len_mversion - 1; i >= 0; i--)
3792 {
3793 if(mversion[i] == '\n' || mversion[i] == '\r'){
3794 len_mversion -- ;
3795 mversion[i] = 0;
3796 }
3797 else
3798 break;
3799 }
3800
3801 if(p_mversion[0] == 0xFF || p_mversion[0] == 0x0)
3802 {
3803 OTA_ERR("There is no mversion in asr flag\n");
3804 goto sync_done;
3805 }
3806
3807 if(memcmp(mversion, p_mversion, len_mversion) != 0)
3808 {
3809 memset(mversion, 0, 128);
3810 strncpy(mversion, p_mversion, 128);
3811 mversion[127]=0;
3812 lseek(fd_mversion, 0, SEEK_SET);
3813 len = write(fd_mversion, mversion, 128);
3814 if (len != 128) {
3815 OTA_ERR("Fail to write mversion: write %d bytes(expected %d)\n", len, 128);
3816 ret = -1;
3817 }
3818 write(fd_mversion, "\n", 1);
3819 goto sync_done;
3820 }
3821
3822sync_done:
3823 close(fd_asrflag);
3824 close(fd_mversion);
3825 return ret;
3826}
3827
b.liu9e96ffe2025-04-03 13:28:05 +08003828// mbtk_otad -a fota/dfota -b 0x00000000
b.liua76c9612025-03-28 13:58:09 +08003829int main(int argc, char **argv)
3830{
3831 int ret;
3832// char * uci_path = NULL;
3833
3834 mbtk_log_init("radio", "MBTK_OTAD");
3835 //set_service_log_tag("OTAD");
3836 prctl(PR_SET_NAME, "otad");
3837
3838#if 0
3839 if (argc > 1) { /* UCI file exist */
3840#ifdef CONFIG_AB_SYSTEM
3841 if (strncmp(argv[1], "-f", 2) == 0) {
3842 switch (argc) {
3843 case 2:
3844 OTA_ERR("miss fota path.\n");
3845 return -1;
3846 case 4:
3847 default:
3848 /* go through */
3849 uci_path = argv[3];
3850 OTA_DEBUG("OTA service start(%s)\n", uci_path);
3851 case 3:
3852 ret = get_fota_version(argv[2], server_cfg.fotav, 128);
3853 if (ret > 0) {
3854 OTA_ERR("get_fota_version failed, ret: %d\n", ret);
3855 return -1;
3856 }
3857 OTA_DEBUG("got fotav: %s\n", server_cfg.fotav);
3858 if (upgrade_precheck(server_cfg.fotav) < 0)
3859 return -1;
3860 break;
3861 }
3862 } else
3863#endif
3864 {
3865 uci_path = argv[1];
3866 OTA_DEBUG("OTA service start(%s)\n", uci_path);
3867 }
3868 } else { /* No UCI file - use default values */
3869 OTA_DEBUG("OTA service start\n");
3870 }
3871#endif
3872
3873 uloop_init();
3874 ctx = ubus_connect(UBUS_UNIX_SOCKET);
3875 if (ctx == NULL) {
3876 OTA_ERR("Connect to UBUSD failed!\n");
3877 ret = -1;
3878 goto done;
3879 }
3880 ubus_add_uloop(ctx);
3881 ret = ubus_add_object(ctx, &ota_object);
3882
3883 memset(&server_cfg, 0, sizeof(server_cfg));
b.liu9e96ffe2025-04-03 13:28:05 +08003884
3885 if(argc > 1) {
3886 int ch;
3887 while((ch = getopt(argc, argv, "a:b:"))!= -1) {
3888 switch(ch)
3889 {
3890 case 'a':
3891 if(strcmp(optarg, "fota") == 0) {
3892 is_dfota = FALSE;
3893 } else if(strcmp(optarg, "dfota") == 0) {
3894 is_dfota = TRUE;
3895 } else {
3896 LOGE("Must be fota/dfota.\n");
3897 return -1;
3898 }
3899 break;
3900 case 'b':
3901 if(strlen(optarg) > 0)
3902 server_cfg.fbf_addr = (unsigned int)strtoul(optarg, NULL, 0);
3903 break;
3904 default:
3905 LOGD("mbtk_otad -a fota/dfota -b 0x00000000");
3906 return -1;
3907 }
3908 }
3909 }
3910
b.liua76c9612025-03-28 13:58:09 +08003911 // ota
3912 init_cfg(NULL);
b.liu9e96ffe2025-04-03 13:28:05 +08003913//#if !defined(CONFIG_AB_SYSTEM) || defined(CONFIG_AB_SYSTEM_DFOTA)
3914 if(is_dfota) {
3915 if (server_cfg.fbf_length == 0 || server_cfg.block_size == 0) {
3916 OTA_ERR("Config file incorrect!\n");
3917 return -1;
3918 }
3919 }
3920//#endif
b.liua76c9612025-03-28 13:58:09 +08003921 if (server_cfg.progress_notify == 0) {
3922 server_cfg.progress_notify = 10;
3923 }
3924 if (server_cfg.interval == 0) {
3925 server_cfg.interval = 5;
3926 }
3927 if (server_cfg.first_interval == 0) {
3928 server_cfg.first_interval = 1;
3929 }
3930 if (server_cfg.fbf_addr == 0) {
b.liu9e96ffe2025-04-03 13:28:05 +08003931 server_cfg.fbf_addr = OTA_ADDR_DEF;
b.liua76c9612025-03-28 13:58:09 +08003932 }
3933
3934 if (strlen(server_cfg.server_url) != 0) {
3935 int fd = open("/etc/mversion", O_RDONLY);
3936 if (fd < 0) {
3937 OTA_ERR("Read version failed!\n");
3938 return -1;
3939 }
3940 read(fd, version_check_context.version, OTA_MAX_STRING_LEN);
3941 close(fd);
3942 uloop_timeout_set(&version_check_timer, 1000 * server_cfg.first_interval);
3943 }
3944
3945 if(sync_mversion() != 0)
3946 OTA_ERR("Sync mversion error\n");
3947
3948 uloop_run();
3949done:
3950
3951 return ret;
3952}
3953