class PartitionCreator: """ Class to create nrfconnect partition containing FactoryData :param offset: This is a partition offset where data will be stored in device's flash memory :param length: This is a maximum partition size :param input: This is a path to input JSON file :param output: This is a path to output directory """ def __init__(self, offset: int, length: int, input: str, output: str) -> None: self._ih = IntelHex() self._length = length self._offset = offset self._data_ready = False self._output = output self._input = input try: self.__data_to_save = self._convert_to_dict(self._load_json()) except IOError: sys.exit(-1) def generate_cbor(self): """ Generates .cbor file using cbor2 library. It generate a CBORTag 55799 which is user-specific tag """ if self.__data_to_save: # prepare raw data from Json cbor_data = cbor.dumps(self.__data_to_save) return cbor_data def create_hex(self, data: bytes): """ Creates .hex file from CBOR. This file can be write directly to device. """ if len(data) > self._length: raise ValueError( "generated CBOR file exceeds declared maximum partition size! {} > {}" .format(len(data), self._length)) self._ih.putsz(self._offset, data) self._ih.write_hex_file(self._output + ".hex", True) self._data_ready = True return True def create_bin(self): """ Creates raw binary data of created previously .hex file """ if not self._data_ready: log.error("Please create hex file first!") return False self._ih.tobinfile(self._output + ".bin") return True @staticmethod def _convert_to_dict(data): """ Converts a list containing tuples ("key_name", "key_value") to a dictionary If "key_value" of data entry is a string-type variable and contains a HEX_PREFIX algorithm decodes it to hex format to be sure that a cbor file will contain proper bytes. If "key_value" of data entry is a dictionary, algorithm appends it to the created dictionary. """ output_dict = dict() for entry in data: if not isinstance(entry, dict): log.debug("Processing entry {}".format(entry)) if isinstance(data[entry], str) and data[entry].startswith(HEX_PREFIX): output_dict[entry] = codecs.decode( data[entry][len(HEX_PREFIX):], "hex") elif isinstance(data[entry], str): output_dict[entry] = data[entry].encode("utf-8") else: output_dict[entry] = data[entry] else: output_dict[entry] = entry return output_dict def _load_json(self): """ Loads file containing a JSON data and converts it to JSON format :raises IOError: if provided JSON file can not be read out. """ try: with open(self._input, "rb") as json_file: return json.loads(json_file.read()) except IOError as e: log.error("Can not read Json file {}".format(self._input)) raise e