/* * Copyright (c) 2018 Rockchip Electronics Co. Ltd. * Author: chad.ma * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "update_recv.h" DWORD m_fwOffset; FILE* pImgFile; long long m_fileSize = 0; bool bCheck = false; char mnt_point[256]; char* try_mount_point[10] = { "/udisk/", "/mnt/udisk/", "/mnt/usb_storage/", "/mnt/sdcard/", "/mnt/external_sd/", NULL, }; long long GetFwSize(char* fwFilePath) { struct stat statBuf; char szName[256]; memset(szName, 0, sizeof(szName)); strcpy(szName,fwFilePath); memset(mnt_point, 0, sizeof(mnt_point)); if (access(szName, F_OK) == 0) { if (stat(szName, &statBuf) < 0){ printf("%s : stat fail, try \n", szName); return -1; } strcpy(mnt_point, szName); m_fileSize = statBuf.st_size; return m_fileSize; } else { //try int i = 0; while(try_mount_point[i] != NULL) { memset(szName, 0, sizeof(szName)); strcpy(szName, try_mount_point[i]); strcat(szName, UPDATE_IMG); printf("===>>>>We will try: %s \n", szName); if (access(szName, F_OK) == 0) { //find valid mount point. if (stat(szName, &statBuf) < 0){ printf("%s : stat fail, try again\n", szName); return -1; } strcpy(mnt_point, szName); m_fileSize = statBuf.st_size; printf("Get Fw total Size = %lld Bytes\n", m_fileSize); return m_fileSize; } i++; } printf("*** No find valid mount point for 'update.img' ***\n"); } return m_fileSize; } bool GetData(long long dwOffset,DWORD dwSize,PBYTE lpBuffer) { if ( dwOffset<0 || dwSize==0 ) return false; if ( dwOffset + dwSize > m_fileSize) return false; //lseek64(pImgFile,dwOffset,SEEK_SET); fseek(pImgFile, dwOffset, SEEK_SET); UINT uiActualRead; uiActualRead = fread(lpBuffer, 1, dwSize, pImgFile); //uiActualRead = read(pImgFile, lpBuffer, dwSize); if (dwSize != uiActualRead) return false; return true; } DWORD GetFwOffset(FILE* pImageFile) { int ret; long long ulFwSize; STRUCT_RKIMAGE_HEAD imageHead; fseeko(pImageFile, 0, SEEK_SET); ret = fread((PBYTE)(&imageHead),1,sizeof(STRUCT_RKIMAGE_HEAD),pImageFile); //ret = read(pImageFile, (PBYTE)(&imageHead), sizeof(STRUCT_RKIMAGE_HEAD)); if (ret != sizeof(STRUCT_RKIMAGE_HEAD)){ printf("%s<%d> Read update.img failed!\n", __func__, __LINE__); fclose(pImageFile); return -1; } if ( imageHead.uiTag!=0x57464B52 ) { bCheck = false; return -1; } return imageHead.dwFWOffset; } static void ShowLog(char* fwImg, bool isCheck) { printf("===========================\n"); if (!isCheck) printf(" update %s start\n", fwImg); else printf(" Check %s start\n", fwImg); } int WriteFwData(char* imgPath, char* fwName) { bool bRet; long long fwSize = 0; long long dwFwOffset; STRUCT_RKIMAGE_HDR rkImageHead; int idx,iHeadSize; FILE* pRecvNode = NULL; long long fileBufferSize; long long EntryStartOffset; UINT uiWriteByte = 0; long long uiEntryOffset = 0; PBYTE pBuffer = NULL; UINT uiBufferSize = LBA_TRANSFER_SIZE; printf("### %s() Enter \n", __func__); ShowLog(fwName, false); fwSize = GetFwSize(imgPath); if (fwSize < 0) { printf("GetFwSize %s Error\n", imgPath); return -2; } if (mnt_point[0] == 0) { printf("### Error : Not find update.img ### \n"); return -2; } pImgFile = fopen(mnt_point, "rb"); if (pImgFile == NULL) { printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__, mnt_point, strerror(errno)); return -2; } m_fwOffset = GetFwOffset(pImgFile); if (bCheck == false && m_fwOffset < 0) { printf("GetFwOffset %s Error\n", imgPath); return -2; } printf("m_fwOffset = 0x%08x \n", m_fwOffset); dwFwOffset = m_fwOffset; iHeadSize = sizeof(STRUCT_RKIMAGE_HDR); bRet = GetData(dwFwOffset, iHeadSize, (PBYTE)&rkImageHead); if ( !bRet ) { printf("### GetData error ###\n"); return -2; } if (rkImageHead.item_count <= 0) { printf("### ERROR:DownloadImage-->No Found item ###\n"); return -2; } for (idx = 0; idx < rkImageHead.item_count; idx++) { if (strcmp(rkImageHead.item[idx].name, fwName) != 0) continue; else break; } if (idx == rkImageHead.item_count) { printf("## Not found %s in update.img ##\n", fwName); goto ERR; } pRecvNode = fopen(DEV_RECOVERY_NODE, "wb"); if (pRecvNode == NULL) { printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__, DEV_RECOVERY_NODE, strerror(errno)); return -1; } //lseek(pRecvNode, 0, SEEK_SET); fseek(pRecvNode, 0, SEEK_SET); for (idx = 0; idx < rkImageHead.item_count; idx++ ) { if (strcmp(rkImageHead.item[idx].name, fwName) != 0) continue; if (rkImageHead.item[idx].file[55]=='H') { fileBufferSize = *((DWORD *)(&rkImageHead.item[idx].file[56])); fileBufferSize <<= 32; fileBufferSize += rkImageHead.item[idx].size; } else fileBufferSize = rkImageHead.item[idx].size; printf("fileBufferSize = 0x%08x \n", fileBufferSize); if (fileBufferSize > 0) { DWORD dwFWOffset; dwFWOffset = m_fwOffset; if (rkImageHead.item[idx].file[50]=='H') { EntryStartOffset = *((DWORD *)(rkImageHead.item[idx].file[51])); EntryStartOffset <<= 32; EntryStartOffset += rkImageHead.item[idx].offset; EntryStartOffset += dwFWOffset; } else { EntryStartOffset = dwFWOffset; EntryStartOffset += rkImageHead.item[idx].offset; } pBuffer = (PBYTE)malloc(uiBufferSize * sizeof(BYTE)); if (pBuffer == NULL) { printf("Error, No enough memory!!!\n"); return -1; } while ( fileBufferSize > 0 ) { memset(pBuffer,0,uiBufferSize); if ( fileBufferSize < uiBufferSize ) { uiWriteByte = fileBufferSize; } else { uiWriteByte = uiBufferSize; } bRet = GetData(dwFWOffset + rkImageHead.item[idx].offset + uiEntryOffset, uiWriteByte,pBuffer); if ( !bRet ) { printf("ERROR:RKA_File_Download-->GetFileData failed\n"); goto ERR; } size_t sizeWr = fwrite(pBuffer, 1, uiWriteByte, pRecvNode); //size_t sizeWr = write(recvNode_fd, pBuffer, uiWriteByte); if (sizeWr != uiWriteByte) { printf("### Write Error !!!\n"); goto ERR; } printf("="); fileBufferSize -= uiWriteByte; uiEntryOffset += uiWriteByte; } } printf("\n\n"); printf("================== Update %s Success ==============\n", fwName); } if (pRecvNode != NULL) { fclose(pRecvNode); pRecvNode = NULL; } if (pImgFile != NULL) { fclose(pImgFile); pImgFile = NULL; } return 0; ERR: if (pBuffer) { free(pBuffer); pBuffer = NULL; } if (pRecvNode != NULL) { fclose(pRecvNode); pRecvNode = NULL; } if (pImgFile != NULL) { fclose(pImgFile); pImgFile = NULL; } printf("\n\n"); printf("================== Update %s Fail ==============\n", fwName); return -1; } bool CheckFwData(char* imgPath, char* fwName) { bool bRet; long long dwFwOffset; STRUCT_RKIMAGE_HDR rkImageHead; int idx,iHeadSize; FILE* pRecvNode = NULL; long long fileBufferSize; long long EntryStartOffset; UINT uiReadByte = 0; long long uiEntryOffset = 0; PBYTE pBufferFromImg = NULL; PBYTE pBufferFromFlash = NULL; UINT uiBufferSize = LBA_TRANSFER_SIZE; printf("### %s() Enter \n", __func__); ShowLog(fwName, true); if (m_fileSize < 0) { printf("get %s file size Error\n", imgPath); return false; } if (mnt_point[0] == 0) { printf("### Error : Not find update.img ### \n"); return false; } pImgFile = fopen(mnt_point, "rb"); if (pImgFile == NULL) { printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__, mnt_point, strerror(errno)); return false; } if (bCheck == false && m_fwOffset < 0) { printf("GetFwOffset %s Error\n", imgPath); return false; } printf("m_fwOffset = 0x%08x \n", m_fwOffset); dwFwOffset = m_fwOffset; iHeadSize = sizeof(STRUCT_RKIMAGE_HDR); bRet = GetData(dwFwOffset, iHeadSize, (PBYTE)&rkImageHead); if ( !bRet ) { printf("### GetData error ###\n"); return false; } pRecvNode = fopen(DEV_RECOVERY_NODE, "rb"); if (pRecvNode == NULL) { printf("%s<%d> Open %s failed! Error:%s\n", __func__, __LINE__, DEV_RECOVERY_NODE, strerror(errno)); return false; } //lseek(pRecvNode, 0, SEEK_SET); fseek(pRecvNode, 0, SEEK_SET); for (idx = 0; idx < rkImageHead.item_count; idx++ ) { if (strcmp(rkImageHead.item[idx].name, fwName) != 0) continue; if (rkImageHead.item[idx].file[55]=='H') { fileBufferSize = *((DWORD *)(&rkImageHead.item[idx].file[56])); fileBufferSize <<= 32; fileBufferSize += rkImageHead.item[idx].size; } else fileBufferSize = rkImageHead.item[idx].size; printf("fileBufferSize = 0x%08x \n", fileBufferSize); if (fileBufferSize > 0) { DWORD dwFWOffset; dwFWOffset = m_fwOffset; if (rkImageHead.item[idx].file[50]=='H') { EntryStartOffset = *((DWORD *)(rkImageHead.item[idx].file[51])); EntryStartOffset <<= 32; EntryStartOffset += rkImageHead.item[idx].offset; EntryStartOffset += dwFWOffset; } else { EntryStartOffset = dwFWOffset; EntryStartOffset += rkImageHead.item[idx].offset; } pBufferFromImg = (PBYTE)malloc(uiBufferSize * sizeof(BYTE)); if (pBufferFromImg == NULL) { printf("Error, No enough memory!!!\n"); return false; } pBufferFromFlash = (PBYTE)malloc(uiBufferSize * sizeof(BYTE)); if (pBufferFromFlash == NULL) { printf("Error, No enough memory!!!\n"); return false; } while ( fileBufferSize > 0 ) { memset(pBufferFromImg, 0, uiBufferSize); memset(pBufferFromFlash, 0, uiBufferSize); if ( fileBufferSize < uiBufferSize ) { uiReadByte = fileBufferSize; } else { uiReadByte = uiBufferSize; } bRet = GetData(dwFWOffset + rkImageHead.item[idx].offset + uiEntryOffset, uiReadByte,pBufferFromImg); if ( !bRet ) { printf("ERROR:RKA_File_Download-->GetFileData failed\n"); goto ERR; } size_t sizeRd = fread(pBufferFromFlash, 1, uiReadByte, pRecvNode); //size_t sizeRd = read(recvNode_fd, pBuffer, uiWriteByte); if (sizeRd != uiReadByte) { printf("### Read from flash Error !!!\n"); goto ERR; } if (memcmp(pBufferFromImg, pBufferFromFlash, uiReadByte) != 0) { goto ERR; } printf("="); fileBufferSize -= uiReadByte; uiEntryOffset += uiReadByte; } } printf("\n\n"); printf("================== Check %s Success ==============\n", fwName); } if (pRecvNode != NULL) { fclose(pRecvNode); pRecvNode = NULL; } if (pImgFile != NULL) { fclose(pImgFile); pImgFile = NULL; } return true; ERR: if (pBufferFromImg) { free(pBufferFromImg); pBufferFromImg = NULL; } if (pBufferFromFlash) { free(pBufferFromFlash); pBufferFromFlash = NULL; } if (pRecvNode != NULL) { fclose(pRecvNode); pRecvNode = NULL; } if (pImgFile != NULL) { fclose(pImgFile); pImgFile = NULL; } printf("\n\n"); printf("================== Check %s Fail ==================\n", fwName); return false; }