Index: DialityCoreCanProtocol.py =================================================================== diff -u -r6c057347d02b98f98260ccefca3ffada9c7d628d -rc172ebf4d713b654fb5a75113c96bf7f5ef5d858 --- DialityCoreCanProtocol.py (.../DialityCoreCanProtocol.py) (revision 6c057347d02b98f98260ccefca3ffada9c7d628d) +++ DialityCoreCanProtocol.py (.../DialityCoreCanProtocol.py) (revision c172ebf4d713b654fb5a75113c96bf7f5ef5d858) @@ -19,6 +19,7 @@ import can import math from time import sleep +from ctypes import c_int8 class DenaliMessage: @@ -36,8 +37,30 @@ HEADER_LENGTH = 4 PACKET_LENGTH = 8 + CRC_LENGTH = 1 MAX_MSG_ID_NUMBER = 65535 + MAX_NUMBER_OF_PAYLOAD_BYTES = 254 + + CRC_LIST = [ + 0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46, + 67, 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109, + 134, 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168, + 197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235, + 61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19, + 126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80, + 187, 138, 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149, + 248, 201, 154, 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214, + 122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84, + 57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23, + 252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210, + 191, 142, 221, 236, 123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145, + 71, 118, 37, 20, 131, 178, 225, 208, 254, 207, 156, 173, 58, 11, 88, 105, + 4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238, 121, 72, 27, 42, + 193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239, + 130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172 + ] + @staticmethod def buildBasicMessage(channel_id=0, message=None): """ @@ -64,13 +87,13 @@ if payload is None: payload = [] - message = [DenaliCanMessenger.START_BYTE] + #message = [DenaliCanMessenger.START_BYTE] if 0 <= message_id <= DenaliMessage.MAX_MSG_ID_NUMBER: # Make sure an unsigned int was passed message_id_in_bytes = message_id.to_bytes(2, byteorder=DenaliMessage.BYTE_ORDER) - message += [message_id_in_bytes[0]] + message = [message_id_in_bytes[0]] message += [message_id_in_bytes[1]] else: @@ -81,19 +104,33 @@ payload_length = len(payload) # if payload is larger than 255 return nothing - if payload_length <= 255: + if payload_length <= DenaliMessage.MAX_NUMBER_OF_PAYLOAD_BYTES: # payload has to be a list message += [payload_length] else: return [] message += payload + message += DenaliMessage.crc8(message) + + message = [DenaliCanMessenger.START_BYTE] + message + message = DenaliMessage.__padMessageWithZeros(message) return DenaliMessage.buildBasicMessage(channel_id=channel_id, message=message) @staticmethod + def crc8(message): + crc = 0 + + for byte in message: + unsigned_byte = int(byte) ^ crc + crc = DenaliMessage.CRC_LIST[unsigned_byte] + + return bytes(c_int8(crc)) + + @staticmethod def __padMessageWithZeros(message): """ returns a packet padded with zeros that guarantees that the packet is a multiple of 8 bytes. @@ -177,7 +214,7 @@ the_message = message if is_array else message['message'] return math.ceil((the_message[DenaliMessage.PAYLOAD_LENGTH_INDEX] + - DenaliMessage.HEADER_LENGTH) / + DenaliMessage.HEADER_LENGTH + DenaliMessage.CRC_LENGTH) / DenaliMessage.PACKET_LENGTH) @@ -334,12 +371,12 @@ self.__dialinMessage = self.__longMessageBuilders[channel_id].push(can_data) elif can_data[0] == self.START_BYTE and \ - message_length <= DenaliMessage.PAYLOAD_LENGTH_FIRST_PACKET: # This is a short packet + message_length <= DenaliMessage.PAYLOAD_LENGTH_FIRST_PACKET: # This is a short packet # This is the first time that we are building a message self.__dialinMessage = can_data # deliver the packet elif can_data[0] == self.START_BYTE and \ - message_length > DenaliMessage.PAYLOAD_LENGTH_FIRST_PACKET: # Long packet start + message_length > DenaliMessage.PAYLOAD_LENGTH_FIRST_PACKET: # Long packet start # We are starting to build a long message, include it in the lonMsgChannelIDSet self.__longMsgChannelIDSet.add(channel_id) @@ -350,6 +387,8 @@ else: # if we do have a builder. This is the first time self.__dialinMessage = self.__longMessageBuilders[channel_id].push(can_data, first_packet=True) + # Need to verify CRC at this point + # At this point we have a complete (long or short) Diality Packet if self.__dialinMessage is not None: