def calculate(self, msg: array.array) -> array.array: """ Get the checksum for a WSP message. There are three hashes possible: 1) 4 Bit Checksum - For Switch Telegram (RORG=5 or 6 and STATUS = 0x20 or 0x30) 2) 8 Bit Checksum: STATUS bit 2^7 = 0 3) 8 Bit CRC: STATUS bit 2^7 = 1 :param msg: the message without Preamble/SOF and EOF. Message starts with RORG and ends with CRC """ try: if self.mode == self.ChecksumMode.auto: if msg[0:4] == util.hex2bit("5") or msg[0:4] == util.hex2bit( "6"): # Switch telegram return self.checksum4(msg) status = msg[-16:-8] if status[0]: return self.crc8(msg[:-8]) # ignore trailing hash else: return self.checksum8(msg[:-8]) # ignore trailing hash elif self.mode == self.ChecksumMode.checksum4: return self.checksum4(msg) elif self.mode == self.ChecksumMode.checksum8: return self.checksum8(msg[:-8]) elif self.mode == self.ChecksumMode.crc8: return self.crc8(msg[:-8]) except IndexError: return None
def calculate(self, msg: array.array) -> array.array: """ Get the checksum for a WSP message. There are three hashes possible: 1) 4 Bit Checksum - For Switch Telegram (RORG=5 or 6 and STATUS = 0x20 or 0x30) 2) 8 Bit Checksum: STATUS bit 2^7 = 0 3) 8 Bit CRC: STATUS bit 2^7 = 1 :param msg: the message without Preamble/SOF and EOF. Message starts with RORG and ends with CRC """ try: if self.mode == self.ChecksumMode.auto: if msg[0:4] == util.hex2bit("5") or msg[0:4] == util.hex2bit("6"): # Switch telegram return self.checksum4(msg) status = msg[-16:-8] if status[0]: return self.crc8(msg[:-8]) # ignore trailing hash else: return self.checksum8(msg[:-8]) # ignore trailing hash elif self.mode == self.ChecksumMode.checksum4: return self.checksum4(msg) elif self.mode == self.ChecksumMode.checksum8: return self.checksum8(msg[:-8]) elif self.mode == self.ChecksumMode.crc8: return self.crc8(msg[:-8]) except IndexError: return None
def test_whitening(self): e = Encoding() # Test 1 e.data_whitening_sync = util.hex2bit("67686768") original_inpt = util.hex2bit("aaaaaaaa67686768f9ca03909567ba76a8") + array.array("B", [False]) # Korrektes Signal, bitgenau inpt = copy.copy(original_inpt) #print (util.bit2hex(inpt)) output, err, _ = e.apply_data_whitening(True, inpt) #print (util.bit2hex(output), err) newinpt, err, _ = e.apply_data_whitening(False, output) #print (util.bit2hex(newinpt), newinpt, err) self.assertEqual(original_inpt, newinpt)
def test_whitening(self): e = Encoding() # Test 1 e.data_whitening_sync = util.hex2bit("67686768") original_inpt = util.hex2bit( "aaaaaaaa67686768f9ca03909567ba76a8") + array.array( "B", [False]) # Korrektes Signal, bitgenau inpt = copy.copy(original_inpt) #print (util.bit2hex(inpt)) output, err, _ = e.apply_data_whitening(True, inpt) #print (util.bit2hex(output), err) newinpt, err, _ = e.apply_data_whitening(False, output) #print (util.bit2hex(newinpt), newinpt, err) self.assertEqual(original_inpt, newinpt)
def __initialize_standard_checksums(cls): for name in cls.STANDARD_CHECKSUMS: polynomial = cls.STANDARD_CHECKSUMS[name]["polynomial"] if isinstance(polynomial, str): polynomial = array.array("B", [1]) + util.hex2bit(polynomial) cls.STANDARD_CHECKSUMS[name]["polynomial"] = polynomial n = len(polynomial) - 1 try: start_val = cls.STANDARD_CHECKSUMS[name]["start_value"] except KeyError: start_val = 0 if isinstance(start_val, int): cls.STANDARD_CHECKSUMS[name]["start_value"] = array.array( "B", [start_val] * n) try: final_xor = cls.STANDARD_CHECKSUMS[name]["final_xor"] except KeyError: final_xor = 0 if isinstance(final_xor, int): cls.STANDARD_CHECKSUMS[name]["final_xor"] = array.array( "B", [final_xor] * n)
def test_configure_crc_parameters(self): crc_label = ChecksumLabel("crc_label", 25, 120, 0, FieldType("crc", FieldType.Function.CHECKSUM)) crc_widget_controller = ChecksumWidgetController(crc_label, Message([0] * 150, 0, MessageType("test")), 0) crc = GenericCRC(polynomial=list(GenericCRC.DEFAULT_POLYNOMIALS.keys())[0]) self.assertEqual(crc_widget_controller.ui.lineEditCRCPolynomial.text(), crc.polynomial_as_hex_str) self.assertEqual(crc_widget_controller.ui.lineEditStartValue.text(), util.bit2hex(crc.start_value)) self.assertEqual(crc_widget_controller.ui.lineEditFinalXOR.text(), util.bit2hex(crc.final_xor)) crc_widget_controller.ui.comboBoxCRCFunction.setCurrentIndex(2) crc.polynomial = crc.choose_polynomial(2) self.assertEqual(crc_widget_controller.ui.lineEditCRCPolynomial.text(), crc.polynomial_as_hex_str) crc_widget_controller.ui.lineEditCRCPolynomial.setText("abcde") crc_widget_controller.ui.lineEditCRCPolynomial.editingFinished.emit() self.assertEqual(crc_label.checksum.polynomial, array.array("B", [1]) + util.hex2bit("abcde")) crc_widget_controller.ui.lineEditStartValue.setText("12345") crc_widget_controller.ui.lineEditStartValue.editingFinished.emit() self.assertEqual(util.bit2hex(crc_label.checksum.start_value), "12345") crc_widget_controller.ui.lineEditFinalXOR.setText("cccaa") crc_widget_controller.ui.lineEditFinalXOR.editingFinished.emit() self.assertEqual(util.bit2hex(crc_label.checksum.final_xor), "cccaa")
def test_configure_crc_parameters(self): crc_label = ChecksumLabel( "crc_label", 25, 120, 0, FieldType("crc", FieldType.Function.CHECKSUM)) crc_widget_controller = ChecksumWidgetController( crc_label, Message([0] * 150, 0, MessageType("test")), 0) crc = GenericCRC( polynomial=list(GenericCRC.DEFAULT_POLYNOMIALS.keys())[0]) self.assertEqual(crc_widget_controller.ui.lineEditCRCPolynomial.text(), crc.polynomial_as_hex_str) self.assertEqual(crc_widget_controller.ui.lineEditStartValue.text(), util.bit2hex(crc.start_value)) self.assertEqual(crc_widget_controller.ui.lineEditFinalXOR.text(), util.bit2hex(crc.final_xor)) crc_widget_controller.ui.comboBoxCRCFunction.setCurrentIndex(2) crc.polynomial = crc.choose_polynomial(2) self.assertEqual(crc_widget_controller.ui.lineEditCRCPolynomial.text(), crc.polynomial_as_hex_str) crc_widget_controller.ui.lineEditCRCPolynomial.setText("abcde") crc_widget_controller.ui.lineEditCRCPolynomial.editingFinished.emit() self.assertEqual(crc_label.checksum.polynomial, array.array("B", [1]) + util.hex2bit("abcde")) crc_widget_controller.ui.lineEditStartValue.setText("12345") crc_widget_controller.ui.lineEditStartValue.editingFinished.emit() self.assertEqual(util.bit2hex(crc_label.checksum.start_value), "12345") crc_widget_controller.ui.lineEditFinalXOR.setText("cccaa") crc_widget_controller.ui.lineEditFinalXOR.editingFinished.emit() self.assertEqual(util.bit2hex(crc_label.checksum.final_xor), "cccaa")
def on_line_edit_final_xor_editing_finished(self): crc = self.checksum_label.checksum final_xor = util.hex2bit(self.ui.lineEditFinalXOR.text()) final_xor = array.array("B", [0] * (crc.poly_order - 1 - len(final_xor))) + final_xor crc.final_xor = final_xor[0:crc.poly_order-1] self.ui.lineEditFinalXOR.setText(util.bit2hex(crc.final_xor)) self.__set_crc_info_label()
def test_enocean_crc_polynomial(self): e = Encoding() msg1 = "aa9a6d201006401009802019e411e8035b" msg2 = "aa9a6d2010000ffdaaf01019e411e8071b" # Remove Preamble + SOF + EOF for CRC calculation msg1 = util.hex2bit("a6d201006401009802019e411e8035") crc1 = util.hex2bit("35") msg2 = util.hex2bit("a6d2010000ffdaaf01019e411e8071") crc2 = util.hex2bit("71") wsp_checker = WSPChecksum() calc_crc1 = wsp_checker.calculate(msg1) calc_crc2 = wsp_checker.calculate(msg2) self.assertTrue(calc_crc1 == crc1) self.assertTrue(calc_crc2 == crc2)
def on_line_edit_start_value_editing_finished(self): crc = self.checksum_label.checksum start_value = util.hex2bit(self.ui.lineEditStartValue.text()) # pad with zeros at front start_value = array.array("B", [0]*(crc.poly_order - 1 - len(start_value))) + start_value crc.start_value = start_value[0:crc.poly_order-1] self.ui.lineEditStartValue.setText(util.bit2hex(crc.start_value)) self.__set_crc_info_label()
def on_line_edit_final_xor_editing_finished(self): crc = self.checksum_label.checksum final_xor = util.hex2bit(self.ui.lineEditFinalXOR.text()) final_xor = array.array( "B", [0] * (crc.poly_order - 1 - len(final_xor))) + final_xor crc.final_xor = final_xor[0:crc.poly_order - 1] self.ui.lineEditFinalXOR.setText(util.bit2hex(crc.final_xor)) self.__set_crc_info_label()
def on_line_edit_start_value_editing_finished(self): crc = self.checksum_label.checksum start_value = util.hex2bit(self.ui.lineEditStartValue.text()) # pad with zeros at front start_value = array.array( "B", [0] * (crc.poly_order - 1 - len(start_value))) + start_value crc.start_value = start_value[0:crc.poly_order - 1] self.ui.lineEditStartValue.setText(util.bit2hex(crc.start_value)) self.__set_crc_info_label()
def test_crc8(self): messages = ["aabbcc", "abcdee", "dacafe"] expected = ["7d", "24", "33"] crc = GenericCRC(polynomial=GenericCRC.DEFAULT_POLYNOMIALS["8_ccitt"]) for msg, expect in zip(messages, expected): bits = util.hex2bit(msg) self.assertEqual(util.bit2hex(crc.crc(bits)), expect)
def align_messages(self, pattern: str, view_type: int, use_decoded=True): if view_type == 0: bit_pattern = pattern elif view_type == 1: bit_pattern = "".join(map(str, urh_util.hex2bit(pattern))) elif view_type == 2: bit_pattern = "".join(map(str, urh_util.ascii2bit(pattern))) else: raise ValueError("Unknown view type {}".format(view_type)) indices = [msg.decoded_bits_str.find(bit_pattern) if use_decoded else msg.plain_bits_str.find(bit_pattern) for msg in self.messages] max_index = max(indices) for i, msg in enumerate(self.messages): msg.alignment_offset = 0 if indices[i] == -1 else max_index - indices[i]
def test_enocean_crc8_message(self): e = Encoding() received = util.hex2bit("aacbac4cddd5ddd3bddd5ddcc5ddcddd4c2d5d5c2cdddab200000") preamble, sof, eof = "aa", "9", "b" decoded, err, state = e.code_enocean(decoding=True, inpt=received) self.assertEqual(err, 0) self.assertEqual(state, e.ErrorState.SUCCESS) self.assertIn(preamble, util.bit2hex(decoded)) self.assertIn(sof, util.bit2hex(decoded)) self.assertIn(eof, util.bit2hex(decoded)) reencoded, errors, state = e.code_enocean(decoding=False, inpt=decoded) self.assertEqual(errors, 0) self.assertEqual(state, e.ErrorState.SUCCESS) redecoded, errors, state = e.code_enocean(decoding=True, inpt=reencoded) self.assertEqual(errors, 0) self.assertEqual(state, e.ErrorState.SUCCESS) self.assertEqual(decoded, redecoded)
def code(self, decoding, inputbits: array.array): temp = array.array("B", inputbits) output = temp errors = 0 error_states = [] # operation order if decoding: i = 0 ops = len(self.chain) step = 1 else: i = len(self.chain) - 1 ops = -1 step = -1 # do operations while i != ops: operation = self.chain[i] while not callable(operation) and i + step != ops: i += step operation = self.chain[i] # Ops with parameters if self.code_redundancy == operation: self.multiple = int(self.chain[i + 1]) elif self.code_carrier == operation: self.carrier = self.chain[i + 1] elif self.code_substitution == operation: self.src = self.chain[i + 1][0] self.dst = self.chain[i + 1][1] elif self.code_externalprogram == operation: if self.chain[i + 1] != "": try: self.external_decoder, self.external_encoder = self.chain[i + 1].split(";") except ValueError: pass else: self.external_decoder, self.external_encoder = "", "" elif self.code_data_whitening == operation: if self.chain[i + 1].count(';') == 2: self.data_whitening_sync, self.data_whitening_polynomial, overwrite_crc = self.chain[i + 1].split(";") if (len(self.data_whitening_sync) > 0 and len(self.data_whitening_polynomial) > 0 and len(overwrite_crc) > 0): self.data_whitening_sync = util.hex2bit(self.data_whitening_sync) self.data_whitening_polynomial = util.hex2bit(self.data_whitening_polynomial) self.cc1101_overwrite_crc = True if overwrite_crc == "1" else False elif self.chain[i + 1].count(';') == 1: self.data_whitening_sync, self.data_whitening_polynomial = self.chain[i + 1].split(";") if (len(self.data_whitening_sync) > 0 and len(self.data_whitening_polynomial) > 0): self.data_whitening_sync = util.hex2bit(self.data_whitening_sync) self.data_whitening_polynomial = util.hex2bit(self.data_whitening_polynomial) self.cc1101_overwrite_crc = False elif self.code_cut == operation: if self.chain[i + 1] != "" and self.chain[i + 1].count(';') == 1: self.cutmode, tmp = self.chain[i + 1].split(";") self.cutmode = int(self.cutmode) if self.cutmode < 0 or self.cutmode > 3: self.cutmode = 0 if self.cutmode == 0 or self.cutmode == 1: self.cutmark = self.str2bit(tmp) if len(self.cutmark) == 0: self.cutmark = array.array("B", [True, False, True, False]) else: try: self.cutmark = int(tmp) except ValueError: self.cutmark = 1 elif self.code_morse == operation: if self.chain[i + 1] != "" and self.chain[i + 1].count(';') == 2: try: l, h, w = self.chain[i + 1].split(";") self.morse_low = int(l) self.morse_high = int(h) self.morse_wait = int(w) except ValueError: self.morse_low, self.morse_high, self.morse_wait = (1, 3, 1) # Execute Ops if callable(operation) and len(temp) > 0: output, temp_errors, state = operation(decoding, temp) errors += temp_errors if state != self.ErrorState.SUCCESS and state not in error_states: error_states.append(state) # Loop Footer i += step temp = output if len(inputbits): self.__symbol_len = len(output) / len(inputbits) if error_states: error_state = error_states[0] else: error_state = self.ErrorState.SUCCESS return output, errors, error_state
def set_polynomial_from_hex(self, hex_str: str): self.polynomial = array.array("B", [1]) + util.hex2bit(hex_str)
def set_polynomial_from_hex(self, hex_str: str): old = self.polynomial self.polynomial = array.array("B", [1]) + util.hex2bit(hex_str) if self.polynomial != old: self.cache = [] self.__cache_bits = 8
def code(self, decoding, inputbits: array.array): temp = array.array("B", inputbits) output = temp errors = 0 error_states = [] # operation order if decoding: i = 0 ops = len(self.chain) step = 1 else: i = len(self.chain) - 1 ops = -1 step = -1 # do operations while i != ops: operation = self.chain[i] while not callable(operation) and i + step != ops: i += step operation = self.chain[i] # Ops with parameters if self.code_redundancy == operation: self.multiple = int(self.chain[i + 1]) elif self.code_carrier == operation: self.carrier = self.chain[i + 1] elif self.code_substitution == operation: self.src = self.chain[i + 1][0] self.dst = self.chain[i + 1][1] elif self.code_externalprogram == operation: if self.chain[i + 1] != "": try: self.external_decoder, self.external_encoder = self.chain[ i + 1].split(";") except ValueError: pass else: self.external_decoder, self.external_encoder = "", "" elif self.code_data_whitening == operation: if self.chain[i + 1].count(';') == 2: self.data_whitening_sync, self.data_whitening_polynomial, overwrite_crc = self.chain[ i + 1].split(";") if (len(self.data_whitening_sync) > 0 and len(self.data_whitening_polynomial) > 0 and len(overwrite_crc) > 0): self.data_whitening_sync = util.hex2bit( self.data_whitening_sync) self.data_whitening_polynomial = util.hex2bit( self.data_whitening_polynomial) self.cc1101_overwrite_crc = True if overwrite_crc == "1" else False elif self.chain[i + 1].count(';') == 1: self.data_whitening_sync, self.data_whitening_polynomial = self.chain[ i + 1].split(";") if (len(self.data_whitening_sync) > 0 and len(self.data_whitening_polynomial) > 0): self.data_whitening_sync = util.hex2bit( self.data_whitening_sync) self.data_whitening_polynomial = util.hex2bit( self.data_whitening_polynomial) self.cc1101_overwrite_crc = False elif self.code_cut == operation: if self.chain[i + 1] != "" and self.chain[i + 1].count(';') == 1: self.cutmode, tmp = self.chain[i + 1].split(";") self.cutmode = int(self.cutmode) if self.cutmode < 0 or self.cutmode > 3: self.cutmode = 0 if self.cutmode == 0 or self.cutmode == 1: self.cutmark = self.str2bit(tmp) if len(self.cutmark) == 0: self.cutmark = array.array( "B", [True, False, True, False]) else: try: self.cutmark = int(tmp) except ValueError: self.cutmark = 1 elif self.code_morse == operation: if self.chain[i + 1] != "" and self.chain[i + 1].count(';') == 2: try: l, h, w = self.chain[i + 1].split(";") self.morse_low = int(l) self.morse_high = int(h) self.morse_wait = int(w) except ValueError: self.morse_low, self.morse_high, self.morse_wait = (1, 3, 1) # Execute Ops if callable(operation) and len(temp) > 0: output, temp_errors, state = operation(decoding, temp) errors += temp_errors if state != self.ErrorState.SUCCESS and state not in error_states: error_states.append(state) # Loop Footer i += step temp = output if len(inputbits): self.__symbol_len = len(output) / len(inputbits) if error_states: error_state = error_states[0] else: error_state = self.ErrorState.SUCCESS return output, errors, error_state