def cobsr_overhead_measure(num_bytes): # TODO: review value NUM_TESTS = 10000 overhead = 0 for _i in xrange(NUM_TESTS): output = cobsr.encode(np.random.bytes(num_bytes)) overhead += (len(output) - num_bytes) return overhead / float(NUM_TESTS)
def test_non_zeros(self): for length in xrange(1, 1000): test_string = non_zero_bytes(length) encoded = cobsr.encode(test_string) expected_encoded = self.cobsr_encode_final_non_zeros_only( test_string) self.assertEqual( encoded, expected_encoded, "encoded != expected_encoded for length %d\nencoded: %s\nexpected_encoded: %s" % (length, repr(encoded), repr(expected_encoded)))
def serialize(self): header = struct.pack("<BHH", self.log_type.value, 0, self.tick) data = "".join([p.serialize() for p in self]) if len(data) + len(header) > FCS_LOG_MAX_LENGTH: raise ValueError("Log too long to serialize (%d bytes)" % (len(data) + len(header))) crc = struct.pack("<L" , binascii.crc32(header + data) & 0xFFFFFFFF) return "\x00" + cobsr.encode(header + data + crc) + "\x00"
def test_zeros(self): for length in xrange(520): test_string = '\x00' * length encoded = cobsr.encode(test_string) expected_encoded = '\x01' * (length + 1) self.assertEqual(encoded, expected_encoded, "encoding zeros failed for length %d" % length) decoded = cobsr.decode(encoded) self.assertEqual(decoded, test_string, "decoding zeros failed for length %d" % length)
def serialize(self): header = struct.pack("<BHH", self.log_type.value, 0, self.tick) data = "".join([p.serialize() for p in self]) if len(data) + len(header) > FCS_LOG_MAX_LENGTH: raise ValueError("Log too long to serialize (%d bytes)" % (len(data) + len(header))) crc = struct.pack("<L", binascii.crc32(header + data) & 0xFFFFFFFF) return "\x00" + cobsr.encode(header + data + crc) + "\x00"
def frame(data): """ Frame data using COBS for transmission """ crc = crc_func(data) framed = bytearray(data) framed.append(crc) if IS_PY2: framed = bytes(framed) framed = cobs.encode(framed) framed = bytearray(framed) framed.append(FRAME_END) return framed
def test_non_zeros_and_trailing_zero(self): for length in xrange(1, 1000): non_zeros_string = non_zero_bytes(length) test_string = non_zeros_string + '\x00' encoded = cobsr.encode(test_string) if (len(non_zeros_string) % 254) == 0: expected_encoded = self.simple_encode_non_zeros_only( non_zeros_string) + '\x01\x01' else: expected_encoded = self.simple_encode_non_zeros_only( non_zeros_string) + '\x01' self.assertEqual( encoded, expected_encoded, "encoded != expected_encoded for length %d\nencoded: %s\nexpected_encoded: %s" % (length, repr(encoded), repr(expected_encoded)))
def buildpacket(self, _id, _device, _sequence, _payload): """Construct a packet based on the networkID, deviceID, timestamp and payload. Returns a series of bytes prepended with the header""" if (len(_id) != 32 or _device < -64 or _device > 64 or not isinstance(_sequence, int) or len(_payload) < 1): return None # create the message pkt_struct = dict(fields=dict(value=dict(NetworkID=_id, DeviceID=_device, Sequence=_sequence, Payload_length=len(_payload), Payload=_payload))) raw = self.message_format.build(pkt_struct) # put the message through cobs/r and put a header on the message return self.protocol_header + cobsr.encode(raw) + self.protocol_header
def test_random(self): try: for _test_num in xrange(self.NUM_TESTS): length = random.randint(0, self.MAX_LENGTH) test_string = ''.join( chr(random.randint(0, 255)) for x in xrange(length)) encoded = cobsr.encode(test_string) self.assertTrue( '\x00' not in encoded, "encoding contains zero byte(s):\noriginal: %s\nencoded: %s" % (repr(test_string), repr(encoded))) self.assertTrue( len(encoded) <= len(test_string) + 1 + (len(test_string) // 254), "encoding too big:\noriginal: %s\nencoded: %s" % (repr(test_string), repr(encoded))) decoded = cobsr.decode(encoded) self.assertEqual( decoded, test_string, "encoding and decoding random data failed:\noriginal: %s\ndecoded: %s" % (repr(test_string), repr(decoded))) except KeyboardInterrupt: pass
def test_predefined_encodings(self): for (test_string, expected_encoded_string) in self.predefined_encodings: encoded = cobsr.encode(test_string) self.assertEqual(encoded, expected_encoded_string)
def cobsr_overhead_measure(num_bytes): overhead = 0 for _i in range(NUM_TESTS): output = cobsr.encode(np.random.bytes(num_bytes)) overhead += (len(output) - num_bytes) return overhead / float(NUM_TESTS)
def main(): parser = argparse.ArgumentParser( description='Upload an update over SerialOTA') parser.add_argument('binary', help='path to binary to upload over SerialOTA') parser.add_argument('port', help='Serial port to use for SerialOTA') args = parser.parse_args() # Create the OTA serial ser = serial.Serial(args.port, 115200, timeout=0.1) binary_size = os.path.getsize(args.binary) # Open the binary with open(args.binary, 'rb') as f: # Start by sending 0 bytes until we get a response while True: ser.write(bytes([0])) rx = ser.read() print("received: {}".format(rx)) if rx == bytes([1]): print("Received bootloader ACK -- waiting for ready") break while True: # Wait until the bootloader sends another response rx = ser.read() print("received: {}".format(rx)) if rx == bytes([2]): print("Bootloader ready -- begin upload") break ser.flushInput() sequence_num = 0 for chunk in read_in_chunks(f, CHUNK_SIZE): bytes_written_after = sequence_num * (CHUNK_SIZE + 1) if len(chunk) != CHUNK_SIZE or bytes_written_after >= binary_size: sequence_num = 0xFFFF # Pack the header tx_buf = struct.pack(HEADER_FORMAT, sequence_num, len(chunk)) + chunk # Calculate the CRC16 of the chunk and the header info #print(tx_buf.hex()) crc = crc16(bytes(tx_buf)) print("Sending chunk: crc({}), seq num({}), size({})".format( crc, sequence_num, len(chunk))) tx_buf = struct.pack("<H", crc) + tx_buf # Encode with COBS tx_cobs = cobsr.encode(tx_buf) + bytes([0]) #print(type(tx_cobs)) #ser.write(tx_cobs) #print(tx_cobs.hex()) for b in tx_cobs: ser.write(bytes([b])) sleep(0.001) while (True): # Wait until the bootloader is ready c = ser.read() print("rx:{}".format(c)) if c == bytes([0]): break sequence_num = sequence_num + 1 ser.close() ser = serial.Serial(args.port, 9600) while (True): print(ser.readline())
def write(string): res = cobs.encode(string) ser.write(res) print res