blob: 3cc79bbb153587e73eeb427a11a1ba9bad2b5fa0 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#include "fota.h"
2#include "obm2osl.h"
3#include "Flash.h"
4#include "malloc.h"
5
6extern SkipBlocksInfoStruct *pSkipAddress;
7extern UINT_T All_FF_flag;
8extern FOTA_Info FOTAInfo;
9
10static UINT_T DFota_ParseBsdiffPatch(CHAR *BsdiffPatch, UINT_T PatchLen, pBsdiffInfo pBsdiff_h)
11{
12 UINT_T SegNum, i;
13 CHAR *PatchPtr;
14 PatchPtr = BsdiffPatch;
15 if (memcmp(PatchPtr, "BSDIFF40", 8) == 0) {
16 pBsdiff_h->Version = 40;
17 } else {
18 pBsdiff_h->Version = 0;
19 }
20
21 pBsdiff_h->Patch = BsdiffPatch;
22 pBsdiff_h->PatchLen = PatchLen;
23
24 return NoError;
25}
26
27UINT_T ImageDFotaProcess(pTIM pTIM_h, PImageStruct_11 pImage_11,
28 pBsdiffInfo pBsdiff_h, P_FOTA_Firmware pFOTA_T)
29{
30
31 CHAR *Patch = NULL, *OldBuff = NULL, *NewBuff = NULL;
32 UINT_T NewLen = 0, EraseLen = 0, OldLen = 0, PatchLen;
33 UINT_T Retval = NoError;
34 P_FlashProperties_T pFlashP = GetFlashProperties(BOOT_FLASH);
35 UINT_T BlockSize = pFlashP->BlockSize;
36 UINT_T NumBlocks = pFlashP->NumBlocks;
37 UINT_T FlashSize = BlockSize * NumBlocks;
38 UINT_T FlashAddr = 0;
39 UINT_T BackupFlashAddr = 0;
40
41 FlashAddr = pImage_11->Flash_Start_Address;
42
43 obm_printf("Upgrade Image, ID: %s, Address: 0x%x, Length: 0x%x\r\n",
44 ImageID2String(pImage_11->Image_ID), FlashAddr, pImage_11->length);
45
46 BackupFlashAddr = pFOTA_T->FBF_Flash_Address + pFOTA_T->FBF_Size;
47 BackupFlashAddr = ALIGN_UP(BackupFlashAddr, BlockSize);
48
49 Patch = pBsdiff_h->Patch;
50 PatchLen = pBsdiff_h->PatchLen;
51
52 if ( TIM_TYPE == (pImage_11->Image_ID & 0xFFFFFF00) ) {
53 NewLen = PatchLen; /* TIMs don't use dfota, patch is new tim */
54 goto write_new_img;
55 }
56
57 if(pFOTA_T->Dfota_NeedCopyOnly) {
58 NewLen = ALIGN_UP(pFOTA_T->Dfota_CopyLen, BlockSize);
59 NewBuff = malloc(NewLen);
60 if(NewBuff == NULL)
61 return HeapExhaustedError;
62 memset(NewBuff, 0xFF, NewLen);
63 Retval = ReadFlash(BackupFlashAddr, (UINT_T)NewBuff, pFOTA_T->Dfota_CopyLen, BOOT_FLASH);
64 if(Retval != NoError) goto dfota_process_exit;
65 goto write_new_img;
66 }
67
68 OldLen = get_oldsize(Patch);
69 NewLen = get_newsize(Patch);
70 if(OldLen == 0 || NewLen == 0)
71 return DfotaDecodeError;
72
73 OldLen = ALIGN_UP(OldLen, BlockSize);
74 NewLen = ALIGN_UP(NewLen, BlockSize);
75
76 OldBuff = malloc(OldLen);
77 if(OldBuff == NULL)
78 return HeapExhaustedError;
79
80 NewBuff = malloc(NewLen);
81 if(NewBuff == NULL) {
82 free(OldBuff);
83 return HeapExhaustedError;
84 }
85
86 memset(NewBuff, 0xFF, NewLen);
87 memset(OldBuff, 0xFF, OldLen);
88
89 Retval = ReadFlash(FlashAddr, (UINT_T)OldBuff, OldLen, BOOT_FLASH);
90 if (Retval != NoError) goto dfota_process_exit;
91
92 Retval = bzpacth(OldBuff, OldLen, NewBuff, &NewLen, Patch, PatchLen);
93 if(Retval != 0 || NewLen == 0) goto dfota_process_exit;
94
95#if TRUSTED
96 if (pTIM_h->pConsTIM->VersionBind.Trusted) {
97 Retval = Fota_ValidateImage(NewBuff, pImage_11, pTIM_h);
98 if(Retval != NoError)
99 goto dfota_process_exit;
100 }
101#endif
102
103 if((BackupFlashAddr + NewLen) > FlashSize)
104 {
105 Retval = DFOTA_PartitionTooSmall;
106 goto dfota_process_exit;
107 }
108
109 EraseLen = ALIGN_UP(NewLen, BlockSize);
110 Retval = EraseFlash(BackupFlashAddr, EraseLen, BOOT_FLASH );
111 if(Retval != NoError) goto dfota_process_exit;
112 Retval = WriteFlash( BackupFlashAddr, (UINT_T)NewBuff, NewLen, BOOT_FLASH );
113 if(Retval != NoError) goto dfota_process_exit;
114
115 //power off protection
116 pFOTA_T->Dfota_NeedCopyOnly =1;
117 pFOTA_T->Dfota_CopyLen = NewLen;
118 OTA_Save_Config(pTIM_h);
119
120write_new_img:
121 EraseLen = (pImage_11->Flash_erase_size > NewLen) ? pImage_11->Flash_erase_size : NewLen;
122
123#if DUAL_TIM
124 if ( pImage_11->Image_ID == OBMIDENTIFIER && DualTimEnabled() ) {
125 if(!DualTimIsEqual())
126 EraseLen += MainTimSize;
127 }
128#endif
129
130 EraseLen = ALIGN_UP(EraseLen, BlockSize);
131
132 Retval = EraseFlash(FlashAddr, EraseLen, BOOT_FLASH);
133 if(Retval != NoError) goto dfota_process_exit;
134
135#if DUAL_TIM
136 if ( pImage_11->Image_ID == OBMIDENTIFIER && DualTimEnabled()) {
137 if (!DualTimIsEqual()) {
138 UINT8_T *ObmTimBuff = NULL;
139 ObmTimBuff = malloc(EraseLen);
140 if(ObmTimBuff == NULL) {
141 Retval = HeapExhaustedError;
142 goto dfota_process_exit;
143 }
144 if(pImage_11->Image_In_TIM == TIMH_RECOVERY_INC) {
145 memcpy(ObmTimBuff, NewBuff, NewLen);
146 if(pTIM_h_Main)
147 memcpy(ObmTimBuff+NewLen, pTIM_h_Main->pConsTIM, MainTimSize);
148 Retval = WriteFlash(FlashAddr, ObmTimBuff, NewLen + MainTimSize, BOOT_FLASH);
149 } else {
150 memcpy(ObmTimBuff, NewBuff, NewLen);
151 if(pTIM_h_Backup)
152 memcpy(ObmTimBuff+NewLen, pTIM_h_Backup->pConsTIM, MainTimSize);
153 Retval = WriteFlash(FlashAddr, ObmTimBuff, NewLen + BackupTimSize, BOOT_FLASH);
154 }
155 free(ObmTimBuff);
156 } else {
157 Retval = WriteFlash(FlashAddr, NewBuff, NewLen, BOOT_FLASH);
158 }
159 goto dfota_process_exit;
160 }
161#endif
162
163 if(pImage_11->Image_ID == TIMIDENTIFIER) {
164 #if DUAL_TIM
165 if(pImage_11->Image_In_TIM == TIMH_RECOVERY_INC && DualTimEnabled() ){
166 if(!DualTimIsEqual()) {
167 if(pTIM_h_Backup == NULL) {
168 Retval = TIMNotFound;
169 goto dfota_process_exit;
170 }
171 Retval = WriteFlash( FlashAddr, pTIM_h_Backup->pConsTIM, BackupTimSize, BOOT_FLASH );
172 }else {
173 if(pTIM_h_Main == NULL) {
174 Retval = TIMNotFound;
175 goto dfota_process_exit;
176 }
177 Retval = WriteFlash( FlashAddr, pTIM_h_Main->pConsTIM, MainTimSize, BOOT_FLASH );
178 }
179 }
180 else
181 #endif
182 {
183 if(pTIM_h_Main == NULL) {
184 Retval = TIMNotFound;
185 goto dfota_process_exit;
186 }
187 Retval = WriteFlash( FlashAddr, pTIM_h_Main->pConsTIM, MainTimSize, BOOT_FLASH );
188 }
189 goto dfota_process_exit;
190 }
191
192 if ( TIM_TYPE != (pImage_11->Image_ID & 0xFFFFFF00) ) /* other TIMs */
193 Retval = WriteFlash( FlashAddr, (UINT_T)NewBuff, NewLen, BOOT_FLASH );
194 else //All other TIMs
195 Retval = WriteFlash( FlashAddr, (UINT_T)Patch, PatchLen, BOOT_FLASH );
196
197dfota_process_exit:
198 if(NewBuff) { free(NewBuff); NewBuff = NULL; }
199 if(OldBuff) { free(OldBuff); OldBuff = NULL; }
200 return Retval;
201}
202
203UINT_T DFOTA_Upgrade(P_FOTA_Firmware pFOTA_T, pTIM pTIM_h)
204{
205 UINT_T Retval = GeneralError;
206 UINT_T LoadAddr = 0;
207 MasterBlockHeader *pMasterHeader = NULL;
208 PDeviceHeader_11 pDevHeader_11=NULL;
209 PImageStruct_11 pImage_11 = NULL;
210 UINT_T temp_p = NULL;
211 UINT_T i, ImageAddr;
212 INT_T imagenum;
213 P_FOTA_Info pFOTAInfo = &FOTAInfo;
214 BsdiffInfo BsdiffInfo;
215 pBsdiffInfo pBsdiff_h = &BsdiffInfo;
216
217 LoadAddr = (UINT_T)malloc(pFOTA_T->FBF_Size);
218 if(LoadAddr == 0){
219 obm_printf("malloc error %s %d\n\r", __FUNCTION__, __LINE__);
220 return HeapExhaustedError;
221 }
222
223 Retval = ReadFlash(pFOTA_T->FBF_Flash_Address, LoadAddr, pFOTA_T->FBF_Size, BOOT_FLASH);
224 if (Retval != NoError){
225 goto error;
226 }
227
228 pMasterHeader = (MasterBlockHeader *)LoadAddr;
229 temp_p = pMasterHeader->deviceHeaderOffset[0] + LoadAddr;
230 pDevHeader_11 = (PDeviceHeader_11)temp_p;
231
232 Retval = Fota_CommonPreprocess(pTIM_h, pMasterHeader, pFOTA_T, 4);
233 if(Retval != NoError) {
234 goto error;
235 }
236
237 if (pFOTA_T->DFota_nOfImages == 0xFFFFFFFF) {
238 pFOTA_T->DFota_nOfImages= pDevHeader_11->nOfImages;
239 }
240
241 for ( imagenum = pFOTA_T->DFota_nOfImages; imagenum > 0; imagenum -- )
242 {
243 temp_p = (UINT_T)&pDevHeader_11->imageStruct_11[imagenum - 1];
244 pImage_11 = (PImageStruct_11)temp_p;
245 ImageAddr = LoadAddr+(pImage_11->First_Sector<<13);
246
247 Retval = Fota_ImagePreprocess(ImageAddr, pImage_11, 4);
248 if(Retval == FOTA_DummyImage) {
249 Retval = NoError; /* Dummy Image, do nothing and continue */
250 continue;
251 } else if(Retval != NoError){
252 goto error;
253 }
254
255 DFota_ParseBsdiffPatch((CHAR *)ImageAddr, pImage_11->length, pBsdiff_h);
256 Retval = ImageDFotaProcess(pTIM_h, pImage_11, pBsdiff_h, pFOTA_T);
257 if(Retval != NoError) goto error;
258 //power off protection
259
260 pFOTA_T->DFota_nOfImages = imagenum - 1;
261 pFOTA_T->Dfota_NeedCopyOnly = 0;
262 pFOTA_T->Dfota_CopyLen = 0;
263 OTA_Save_Config(pTIM_h);
264 } //for loop
265
266 Fota_CommonPostprocess(pTIM_h, pMasterHeader, pFOTA_T, 4);
267
268error:
269 //free buffers
270 if(LoadAddr) free((VOID *)LoadAddr);
271
272 return Retval;
273}
274