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