1 /*
2 * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
3 * Author: chad.ma <chad.ma@rock-chips.com>
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "update_recv.h"
19
20 DWORD m_fwOffset;
21 FILE* pImgFile;
22 long long m_fileSize = 0;
23 bool bCheck = false;
24 char mnt_point[256];
25
26 char* try_mount_point[10] = {
27 "/udisk/",
28 "/mnt/udisk/",
29 "/mnt/usb_storage/",
30 "/mnt/sdcard/",
31 "/mnt/external_sd/",
32
33 NULL,
34 };
35
GetFwSize(char * fwFilePath)36 long long GetFwSize(char* fwFilePath)
37 {
38 struct stat statBuf;
39 char szName[256];
40 memset(szName, 0, sizeof(szName));
41 strcpy(szName,fwFilePath);
42
43 memset(mnt_point, 0, sizeof(mnt_point));
44
45 if (access(szName, F_OK) == 0) {
46 if (stat(szName, &statBuf) < 0){
47 printf("%s : stat fail, try \n", szName);
48 return -1;
49 }
50
51 strcpy(mnt_point, szName);
52 m_fileSize = statBuf.st_size;
53 return m_fileSize;
54 } else {
55 //try
56 int i = 0;
57 while(try_mount_point[i] != NULL) {
58 memset(szName, 0, sizeof(szName));
59 strcpy(szName, try_mount_point[i]);
60 strcat(szName, UPDATE_IMG);
61 printf("===>>>>We will try: %s \n", szName);
62
63 if (access(szName, F_OK) == 0) {
64 //find valid mount point.
65 if (stat(szName, &statBuf) < 0){
66 printf("%s : stat fail, try again\n", szName);
67 return -1;
68 }
69
70 strcpy(mnt_point, szName);
71 m_fileSize = statBuf.st_size;
72 printf("Get Fw total Size = %lld Bytes\n", m_fileSize);
73 return m_fileSize;
74 }
75
76 i++;
77 }
78
79 printf("*** No find valid mount point for 'update.img' ***\n");
80 }
81
82 return m_fileSize;
83 }
84
GetData(long long dwOffset,DWORD dwSize,PBYTE lpBuffer)85 bool GetData(long long dwOffset,DWORD dwSize,PBYTE lpBuffer)
86 {
87 if ( dwOffset<0 || dwSize==0 )
88 return false;
89
90 if ( dwOffset + dwSize > m_fileSize)
91 return false;
92
93 //lseek64(pImgFile,dwOffset,SEEK_SET);
94 fseek(pImgFile, dwOffset, SEEK_SET);
95 UINT uiActualRead;
96 uiActualRead = fread(lpBuffer, 1, dwSize, pImgFile);
97 //uiActualRead = read(pImgFile, lpBuffer, dwSize);
98 if (dwSize != uiActualRead)
99 return false;
100
101 return true;
102 }
103
GetFwOffset(FILE * pImageFile)104 DWORD GetFwOffset(FILE* pImageFile)
105 {
106 int ret;
107 long long ulFwSize;
108 STRUCT_RKIMAGE_HEAD imageHead;
109 fseeko(pImageFile, 0, SEEK_SET);
110 ret = fread((PBYTE)(&imageHead),1,sizeof(STRUCT_RKIMAGE_HEAD),pImageFile);
111 //ret = read(pImageFile, (PBYTE)(&imageHead), sizeof(STRUCT_RKIMAGE_HEAD));
112 if (ret != sizeof(STRUCT_RKIMAGE_HEAD)){
113 printf("%s<%d> Read update.img failed!\n", __func__, __LINE__);
114 fclose(pImageFile);
115 return -1;
116 }
117
118 if ( imageHead.uiTag!=0x57464B52 ) {
119 bCheck = false;
120 return -1;
121 }
122
123 return imageHead.dwFWOffset;
124 }
125
ShowLog(char * fwImg,bool isCheck)126 static void ShowLog(char* fwImg, bool isCheck)
127 {
128 printf("===========================\n");
129 if (!isCheck)
130 printf(" update %s start\n", fwImg);
131 else
132 printf(" Check %s start\n", fwImg);
133 }
134
WriteFwData(char * imgPath,char * fwName)135 int WriteFwData(char* imgPath, char* fwName)
136 {
137 bool bRet;
138 long long fwSize = 0;
139 long long dwFwOffset;
140 STRUCT_RKIMAGE_HDR rkImageHead;
141 int idx,iHeadSize;
142 FILE* pRecvNode = NULL;
143 long long fileBufferSize;
144 long long EntryStartOffset;
145 UINT uiWriteByte = 0;
146 long long uiEntryOffset = 0;
147 PBYTE pBuffer = NULL;
148 UINT uiBufferSize = LBA_TRANSFER_SIZE;
149 printf("### %s() Enter \n", __func__);
150
151 ShowLog(fwName, false);
152
153 fwSize = GetFwSize(imgPath);
154 if (fwSize < 0) {
155 printf("GetFwSize %s Error\n", imgPath);
156 return -2;
157 }
158
159 if (mnt_point[0] == 0) {
160 printf("### Error : Not find update.img ### \n");
161 return -2;
162 }
163
164 pImgFile = fopen(mnt_point, "rb");
165 if (pImgFile == NULL)
166 {
167 printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__,
168 mnt_point, strerror(errno));
169 return -2;
170 }
171
172 m_fwOffset = GetFwOffset(pImgFile);
173 if (bCheck == false && m_fwOffset < 0) {
174 printf("GetFwOffset %s Error\n", imgPath);
175 return -2;
176 }
177 printf("m_fwOffset = 0x%08x \n", m_fwOffset);
178
179 dwFwOffset = m_fwOffset;
180 iHeadSize = sizeof(STRUCT_RKIMAGE_HDR);
181 bRet = GetData(dwFwOffset, iHeadSize, (PBYTE)&rkImageHead);
182 if ( !bRet )
183 {
184 printf("### GetData error ###\n");
185 return -2;
186 }
187
188 if (rkImageHead.item_count <= 0)
189 {
190 printf("### ERROR:DownloadImage-->No Found item ###\n");
191 return -2;
192 }
193
194 for (idx = 0; idx < rkImageHead.item_count; idx++) {
195 if (strcmp(rkImageHead.item[idx].name, fwName) != 0)
196 continue;
197 else
198 break;
199 }
200
201 if (idx == rkImageHead.item_count) {
202 printf("## Not found %s in update.img ##\n", fwName);
203 goto ERR;
204 }
205
206 pRecvNode = fopen(DEV_RECOVERY_NODE, "wb");
207 if (pRecvNode == NULL)
208 {
209 printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__,
210 DEV_RECOVERY_NODE, strerror(errno));
211 return -1;
212 }
213
214 //lseek(pRecvNode, 0, SEEK_SET);
215 fseek(pRecvNode, 0, SEEK_SET);
216
217 for (idx = 0; idx < rkImageHead.item_count; idx++ )
218 {
219 if (strcmp(rkImageHead.item[idx].name, fwName) != 0)
220 continue;
221
222 if (rkImageHead.item[idx].file[55]=='H') {
223 fileBufferSize = *((DWORD *)(&rkImageHead.item[idx].file[56]));
224 fileBufferSize <<= 32;
225 fileBufferSize += rkImageHead.item[idx].size;
226 }
227 else
228 fileBufferSize = rkImageHead.item[idx].size;
229
230 printf("fileBufferSize = 0x%08x \n", fileBufferSize);
231
232 if (fileBufferSize > 0) {
233 DWORD dwFWOffset;
234 dwFWOffset = m_fwOffset;
235
236 if (rkImageHead.item[idx].file[50]=='H') {
237 EntryStartOffset = *((DWORD *)(rkImageHead.item[idx].file[51]));
238 EntryStartOffset <<= 32;
239 EntryStartOffset += rkImageHead.item[idx].offset;
240 EntryStartOffset += dwFWOffset;
241 } else {
242 EntryStartOffset = dwFWOffset;
243 EntryStartOffset += rkImageHead.item[idx].offset;
244 }
245
246 pBuffer = (PBYTE)malloc(uiBufferSize * sizeof(BYTE));
247 if (pBuffer == NULL) {
248 printf("Error, No enough memory!!!\n");
249 return -1;
250 }
251
252 while ( fileBufferSize > 0 ) {
253 memset(pBuffer,0,uiBufferSize);
254
255 if ( fileBufferSize < uiBufferSize ) {
256 uiWriteByte = fileBufferSize;
257 } else {
258 uiWriteByte = uiBufferSize;
259 }
260
261 bRet = GetData(dwFWOffset + rkImageHead.item[idx].offset + uiEntryOffset,
262 uiWriteByte,pBuffer);
263 if ( !bRet ) {
264 printf("ERROR:RKA_File_Download-->GetFileData failed\n");
265 goto ERR;
266 }
267
268 size_t sizeWr = fwrite(pBuffer, 1, uiWriteByte, pRecvNode);
269 //size_t sizeWr = write(recvNode_fd, pBuffer, uiWriteByte);
270 if (sizeWr != uiWriteByte) {
271 printf("### Write Error !!!\n");
272 goto ERR;
273 }
274
275 printf("=");
276 fileBufferSize -= uiWriteByte;
277 uiEntryOffset += uiWriteByte;
278 }
279 }
280
281 printf("\n\n");
282 printf("================== Update %s Success ==============\n", fwName);
283
284 }
285
286 if (pRecvNode != NULL) {
287 fclose(pRecvNode);
288 pRecvNode = NULL;
289 }
290 if (pImgFile != NULL) {
291 fclose(pImgFile);
292 pImgFile = NULL;
293 }
294
295 return 0;
296
297 ERR:
298 if (pBuffer) {
299 free(pBuffer);
300 pBuffer = NULL;
301 }
302
303 if (pRecvNode != NULL) {
304 fclose(pRecvNode);
305 pRecvNode = NULL;
306 }
307 if (pImgFile != NULL) {
308 fclose(pImgFile);
309 pImgFile = NULL;
310 }
311 printf("\n\n");
312 printf("================== Update %s Fail ==============\n", fwName);
313 return -1;
314 }
315
CheckFwData(char * imgPath,char * fwName)316 bool CheckFwData(char* imgPath, char* fwName)
317 {
318 bool bRet;
319 long long dwFwOffset;
320 STRUCT_RKIMAGE_HDR rkImageHead;
321 int idx,iHeadSize;
322 FILE* pRecvNode = NULL;
323 long long fileBufferSize;
324 long long EntryStartOffset;
325 UINT uiReadByte = 0;
326 long long uiEntryOffset = 0;
327 PBYTE pBufferFromImg = NULL;
328 PBYTE pBufferFromFlash = NULL;
329 UINT uiBufferSize = LBA_TRANSFER_SIZE;
330
331 printf("### %s() Enter \n", __func__);
332
333 ShowLog(fwName, true);
334
335 if (m_fileSize < 0) {
336 printf("get %s file size Error\n", imgPath);
337 return false;
338 }
339
340 if (mnt_point[0] == 0) {
341 printf("### Error : Not find update.img ### \n");
342 return false;
343 }
344
345 pImgFile = fopen(mnt_point, "rb");
346 if (pImgFile == NULL)
347 {
348 printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__,
349 mnt_point, strerror(errno));
350 return false;
351 }
352
353 if (bCheck == false && m_fwOffset < 0) {
354 printf("GetFwOffset %s Error\n", imgPath);
355 return false;
356 }
357 printf("m_fwOffset = 0x%08x \n", m_fwOffset);
358
359 dwFwOffset = m_fwOffset;
360 iHeadSize = sizeof(STRUCT_RKIMAGE_HDR);
361 bRet = GetData(dwFwOffset, iHeadSize, (PBYTE)&rkImageHead);
362 if ( !bRet )
363 {
364 printf("### GetData error ###\n");
365 return false;
366 }
367
368 pRecvNode = fopen(DEV_RECOVERY_NODE, "rb");
369 if (pRecvNode == NULL)
370 {
371 printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__,
372 DEV_RECOVERY_NODE, strerror(errno));
373 return false;
374 }
375
376 //lseek(pRecvNode, 0, SEEK_SET);
377 fseek(pRecvNode, 0, SEEK_SET);
378
379 for (idx = 0; idx < rkImageHead.item_count; idx++ )
380 {
381 if (strcmp(rkImageHead.item[idx].name, fwName) != 0)
382 continue;
383
384 if (rkImageHead.item[idx].file[55]=='H') {
385 fileBufferSize = *((DWORD *)(&rkImageHead.item[idx].file[56]));
386 fileBufferSize <<= 32;
387 fileBufferSize += rkImageHead.item[idx].size;
388 }
389 else
390 fileBufferSize = rkImageHead.item[idx].size;
391
392 printf("fileBufferSize = 0x%08x \n", fileBufferSize);
393
394 if (fileBufferSize > 0) {
395 DWORD dwFWOffset;
396 dwFWOffset = m_fwOffset;
397
398 if (rkImageHead.item[idx].file[50]=='H') {
399 EntryStartOffset = *((DWORD *)(rkImageHead.item[idx].file[51]));
400 EntryStartOffset <<= 32;
401 EntryStartOffset += rkImageHead.item[idx].offset;
402 EntryStartOffset += dwFWOffset;
403 } else {
404 EntryStartOffset = dwFWOffset;
405 EntryStartOffset += rkImageHead.item[idx].offset;
406 }
407
408 pBufferFromImg = (PBYTE)malloc(uiBufferSize * sizeof(BYTE));
409 if (pBufferFromImg == NULL) {
410 printf("Error, No enough memory!!!\n");
411 return false;
412 }
413
414 pBufferFromFlash = (PBYTE)malloc(uiBufferSize * sizeof(BYTE));
415 if (pBufferFromFlash == NULL) {
416 printf("Error, No enough memory!!!\n");
417 return false;
418 }
419
420 while ( fileBufferSize > 0 ) {
421 memset(pBufferFromImg, 0, uiBufferSize);
422 memset(pBufferFromFlash, 0, uiBufferSize);
423
424 if ( fileBufferSize < uiBufferSize ) {
425 uiReadByte = fileBufferSize;
426 } else {
427 uiReadByte = uiBufferSize;
428 }
429
430 bRet = GetData(dwFWOffset + rkImageHead.item[idx].offset + uiEntryOffset,
431 uiReadByte,pBufferFromImg);
432 if ( !bRet ) {
433 printf("ERROR:RKA_File_Download-->GetFileData failed\n");
434 goto ERR;
435 }
436
437 size_t sizeRd = fread(pBufferFromFlash, 1, uiReadByte, pRecvNode);
438 //size_t sizeRd = read(recvNode_fd, pBuffer, uiWriteByte);
439 if (sizeRd != uiReadByte) {
440 printf("### Read from flash Error !!!\n");
441 goto ERR;
442 }
443
444 if (memcmp(pBufferFromImg, pBufferFromFlash, uiReadByte) != 0) {
445 goto ERR;
446 }
447
448 printf("=");
449 fileBufferSize -= uiReadByte;
450 uiEntryOffset += uiReadByte;
451 }
452 }
453
454 printf("\n\n");
455 printf("================== Check %s Success ==============\n", fwName);
456 }
457
458 if (pRecvNode != NULL) {
459 fclose(pRecvNode);
460 pRecvNode = NULL;
461 }
462 if (pImgFile != NULL) {
463 fclose(pImgFile);
464 pImgFile = NULL;
465 }
466
467 return true;
468
469 ERR:
470 if (pBufferFromImg) {
471 free(pBufferFromImg);
472 pBufferFromImg = NULL;
473 }
474 if (pBufferFromFlash) {
475 free(pBufferFromFlash);
476 pBufferFromFlash = NULL;
477 }
478
479 if (pRecvNode != NULL) {
480 fclose(pRecvNode);
481 pRecvNode = NULL;
482 }
483 if (pImgFile != NULL) {
484 fclose(pImgFile);
485 pImgFile = NULL;
486 }
487 printf("\n\n");
488 printf("================== Check %s Fail ==================\n", fwName);
489 return false;
490 }
491
492
493