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