def alignFileSize(filePath): alignSize = 16 # make sure the size is multiple of alignSize fileSize = getFileSize(filePath) print("fileSize ", fileSize) if fileSize % alignSize != 0: with open(filePath, "rb") as f: content = f.read() content = bytearray(content) pad = bytearray(alignSize - (fileSize % 16)) content.extend(pad) print("padSize: ", alignSize - (fileSize % 16)) with open(filePath, "wb") as f: f.write(content)
def printFactoryImageStruct(processedImagePath, trailerSize, numLinesImageContent, descripFixedSize): """ print structure of factory image :param processedImagePath: path of processed image :param trailerSize: size of trailer in bytes :param numLinesImageContent: number of lines of image content to output :param descripFixedSize: fixed size in bytes for storing signature type description :return: """ cuttingLine = "--------" subCuttingLine = "-----" # print magic code with open(processedImagePath, "rb") as f: print(cuttingLine + subCuttingLine + "Magic Code" + subCuttingLine + cuttingLine) byte = f.read(8) print(byte) # print [ota_descriptor + image content] printOTADescriptorImageStruct(processedImagePath, numLinesImageContent, 8) # print trailer fSize = getFileSize(processedImagePath) f = open(processedImagePath, "rb") f.seek(fSize - trailerSize) print(cuttingLine + cuttingLine + "Trailer" + cuttingLine + cuttingLine) try: print(subCuttingLine + " signature type " + subCuttingLine) byte = f.read(descripFixedSize) print(byte) print(subCuttingLine + " signature size " + subCuttingLine) byte = f.read(4) print(format32BitHexStr(hex(struct.unpack('<I', byte)[0]))) byte = f.read() print(subCuttingLine + " signature " + subCuttingLine) print(byte) finally: f.close()
def getOTADescriptor(userConfigFilePath, inputImagePath, ruleFolderPath, hardwarePlatform): """ parse and validate the parameters defined by user. calculate the end address If all parameters are valid, return them as ota descriptor. Otherwise, raise exeception. :param userConfigFilePath: path of the user config file :param inputImagePath: path of the input image, which will be used to calculate the end address :param ruleFolderPath: path of the folder which contains the validation rule file for the user config :param hardwarePlatform: hardware platform name :return: parameters to be used to generate the OTA descriptor. Each parameter will be formatted as a 10-character string to represent a 32-bit hexadecimal number, where the first two character is a prefix "0x". """ parsedParams = parseConfigFile(userConfigFilePath) # 1. validate the hardware platform is valid and corresponding rule file can be found validHardwarePlatforms = os.listdir(ruleFolderPath) if hardwarePlatform not in validHardwarePlatforms: raise Exception( "Invalid hardware platform! \nExpected hardware platforms: " + str( validHardwarePlatforms) + ". \nFound: " + hardwarePlatform) # 2. Make sure the rule file and the parameters defined in it are valid validationFileLocation = os.path.join(ruleFolderPath, hardwarePlatform) validateFilePath(validationFileLocation) ruleParams = parseConfigFile(validationFileLocation) if len(ruleParams.keys()) != 2: raise Exception("Invalid validation rule file : " + validationFileLocation + "\nExpected 2 parameters in this file. " + "\nFound: " + str(len(ruleParams.keys()))) if "MIN_ADDRESS" not in ruleParams: raise Exception("Error! parameter \"MIN_ADDRESS\" is not defined in " + validationFileLocation) minAddrHardwarePlatform = ruleParams["MIN_ADDRESS"] validate32BitHexParam(minAddrHardwarePlatform, "MIN_ADDRESS", validationFileLocation) minAddrHardwarePlatform = format32BitHexStr(minAddrHardwarePlatform) if "MAX_ADDRESS" not in ruleParams: raise Exception("Error! parameter \"MAX_ADDRESS\" is not defined in " + validationFileLocation) maxAddrHardwarePlatform = ruleParams["MAX_ADDRESS"] validate32BitHexParam(maxAddrHardwarePlatform, "MAX_ADDRESS", validationFileLocation) maxAddrHardwarePlatform = format32BitHexStr(maxAddrHardwarePlatform) if (int(maxAddrHardwarePlatform, 16) <= int(minAddrHardwarePlatform, 16)): raise Exception( "MAX_ADDRESS must be greater than the MIN_ADDRESS !" + " File location " + validationFileLocation) # 3. validate sequence number if "SEQUENCE_NUMBER" not in parsedParams: raise Exception("Error! parameter \"SEQUENCE_NUMBER\" is not defined in " + userConfigFilePath) sequenceNumber = parsedParams["SEQUENCE_NUMBER"] validate32BitUIntParam(sequenceNumber, "SEQUENCE_NUMBER", userConfigFilePath) # convert from string of 32-bit unsigned integer to string of 32-bit hexadecimal sequenceNumber = hex(int(sequenceNumber, 10)) sequenceNumber = format32BitHexStr(sequenceNumber) # 4. validate hardware id if "HARDWARE_ID" not in parsedParams: raise Exception("Error! parameter \"HARDWARE_ID\" is not defined in " + userConfigFilePath) hardwareID = parsedParams["HARDWARE_ID"] hardwareID = formatHardwareID(hardwareID, userConfigFilePath) hardwareID = format32BitHexStr(hardwareID) # 5. validate reserved bytes if "RESERVED_BYTES" not in parsedParams: raise Exception("Error! parameter \"RESERVED_BYTES\" is not defined in " + userConfigFilePath) reserves = parsedParams["RESERVED_BYTES"] validate32BitHexParam(reserves, "RESERVED_BYTES", userConfigFilePath) reserves = format32BitHexStr(reserves) # 6. validate start address if "START_ADDRESS" not in parsedParams: raise Exception("Error! parameter \"START_ADDRESS\" is not defined in " + userConfigFilePath) startAddress = parsedParams["START_ADDRESS"] validate32BitHexParam(startAddress, "START_ADDRESS", userConfigFilePath) startAddress = format32BitHexStr(startAddress) # make sure minAddrHardwarePlatform <= startAddress < maxAddressHardwarePlatform startMin = minAddrHardwarePlatform startMax = format32BitHexStr(hex(int(maxAddrHardwarePlatform, 16) - 1)) validate32BitHexParamRange(startAddress, "START_ADDRESS", startMin, startMax, userConfigFilePath) # 7. calculate and validate the end address fileSize = getFileSize(inputImagePath) endAddress = getEndAddress(fileSize, int(startAddress, 16)) # get end address in decimal format endAddress = hex(endAddress).upper() # convert to hexadecimal format # make sure minAddrHardwarePlatform < endAddress <= maxAddressHardwarePlatform endMin = format32BitHexStr(hex(int(minAddrHardwarePlatform, 16) + 1)) endMax = maxAddrHardwarePlatform if int(endAddress, 16) < int(endMin, 16) or int(endAddress, 16) > int(endMax, 16): raise Exception( "Invalid value of \"END_ADDRESS\"! Expected range : [" + endMin + "," + endMax + "]. Calculated Result : " + endAddress + "\nPossible reasons: START_ADDRESS is too large or image size is too large (END_ADDRESS = START_ADDRESS + 24 bytes + size of input image)" + "\n\nDebug Info: " + "\nImage size: " + str(fileSize) + "\nSTART_ADDRESS: " + startAddress + ". Config file location" + userConfigFilePath) endAddress = format32BitHexStr(endAddress) # 8. validate the execution address if "EXECUTION_ADDRESS" not in parsedParams: raise Exception("Error! parameter \"EXECUTION_ADDRESS\" is not defined in " + userConfigFilePath) executionAddress = parsedParams["EXECUTION_ADDRESS"] validate32BitHexParam(executionAddress, "EXECUTION_ADDRESS", userConfigFilePath) # make sure startAddress <= executionAddress <= endAddress execMin = startAddress execMax = endAddress validate32BitHexParamRange(executionAddress, "EXECUTION_ADDRESS", execMin, execMax, userConfigFilePath) executionAddress = format32BitHexStr(executionAddress) return OTADescriptor(sequenceNumber, startAddress, endAddress, executionAddress, hardwareID, reserves)