Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
walchko committed Nov 26, 2023
1 parent e7ab918 commit 058b01e
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 47 deletions.
16 changes: 15 additions & 1 deletion cpp/gtests/main-gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ TEST(yivo, pack_unpack) {
msg_t m{105, 1000};

yivopkt_t msg;
msg.pack(10, reinterpret_cast<uint8_t *>(&m), sizeof(m));
msg.pack(10, (uint8_t*)&m, sizeof(m));
EXPECT_TRUE(msg.valid_msg());

msg_t m2 = msg.unpack<msg_t>();
Expand Down Expand Up @@ -72,4 +72,18 @@ TEST(yivo, read) {
msg_t m2 = p.unpack<msg_t>();
EXPECT_EQ(m.a, m2.a);
EXPECT_EQ(m.b, m2.b);
}

TEST(yivo, bad_packets) {
uint8_t a[]{'X','X',5,0,20,1,2,33};
yivopkt_t p;
p.fill(a, sizeof(a));
EXPECT_FALSE(p.valid_msg());

p.clear();
EXPECT_EQ(p.size(), 0);

uint8_t b[]{'$','K',5,0,20,1,2,33}; // correct checksum = 18
p.fill(b, sizeof(b));
EXPECT_FALSE(p.has_valid_checksum());
}
61 changes: 60 additions & 1 deletion cpp/src/crc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,66 @@ SOFTWARE.
******************************************************************************/
#pragma once

#include <cstdint>
/*
Thinking about doing some thing better for a checksum than what I am currently
doing ... not sure it is really worth it.
*/

// #include <cstdint>
// http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
// 0x00 0x07 0x0E 0x09 0x1C 0x1B 0x12 0x15 0x38 0x3F 0x36 0x31 0x24 0x23 0x2A 0x2D
// 0x70 0x77 0x7E 0x79 0x6C 0x6B 0x62 0x65 0x48 0x4F 0x46 0x41 0x54 0x53 0x5A 0x5D
// 0xE0 0xE7 0xEE 0xE9 0xFC 0xFB 0xF2 0xF5 0xD8 0xDF 0xD6 0xD1 0xC4 0xC3 0xCA 0xCD
// 0x90 0x97 0x9E 0x99 0x8C 0x8B 0x82 0x85 0xA8 0xAF 0xA6 0xA1 0xB4 0xB3 0xBA 0xBD
// 0xC7 0xC0 0xC9 0xCE 0xDB 0xDC 0xD5 0xD2 0xFF 0xF8 0xF1 0xF6 0xE3 0xE4 0xED 0xEA
// 0xB7 0xB0 0xB9 0xBE 0xAB 0xAC 0xA5 0xA2 0x8F 0x88 0x81 0x86 0x93 0x94 0x9D 0x9A
// 0x27 0x20 0x29 0x2E 0x3B 0x3C 0x35 0x32 0x1F 0x18 0x11 0x16 0x03 0x04 0x0D 0x0A
// 0x57 0x50 0x59 0x5E 0x4B 0x4C 0x45 0x42 0x6F 0x68 0x61 0x66 0x73 0x74 0x7D 0x7A
// 0x89 0x8E 0x87 0x80 0x95 0x92 0x9B 0x9C 0xB1 0xB6 0xBF 0xB8 0xAD 0xAA 0xA3 0xA4
// 0xF9 0xFE 0xF7 0xF0 0xE5 0xE2 0xEB 0xEC 0xC1 0xC6 0xCF 0xC8 0xDD 0xDA 0xD3 0xD4
// 0x69 0x6E 0x67 0x60 0x75 0x72 0x7B 0x7C 0x51 0x56 0x5F 0x58 0x4D 0x4A 0x43 0x44
// 0x19 0x1E 0x17 0x10 0x05 0x02 0x0B 0x0C 0x21 0x26 0x2F 0x28 0x3D 0x3A 0x33 0x34
// 0x4E 0x49 0x40 0x47 0x52 0x55 0x5C 0x5B 0x76 0x71 0x78 0x7F 0x6A 0x6D 0x64 0x63
// 0x3E 0x39 0x30 0x37 0x22 0x25 0x2C 0x2B 0x06 0x01 0x08 0x0F 0x1A 0x1D 0x14 0x13
// 0xAE 0xA9 0xA0 0xA7 0xB2 0xB5 0xBC 0xBB 0x96 0x91 0x98 0x9F 0x8A 0x8D 0x84 0x83
// 0xDE 0xD9 0xD0 0xD7 0xC2 0xC5 0xCC 0xCB 0xE6 0xE1 0xE8 0xEF 0xFA 0xFD 0xF4 0xF3

// https://stackoverflow.com/questions/51752284/how-to-calculate-crc8-in-c
// const uint8_t crc8x_table[256] = {
// 0x00,0x31,0x62,0x53,0xC4,0xF5,0xA6,0x97,0xB9,0x88,0xDB,0xEA,0x7D,0x4C,0x1F,0x2E,
// 0x43,0x72,0x21,0x10,0x87,0xB6,0xE5,0xD4,0xFA,0xCB,0x98,0xA9,0x3E,0x0F,0x5C,0x6D,
// 0x86,0xB7,0xE4,0xD5,0x42,0x73,0x20,0x11,0x3F,0x0E,0x5D,0x6C,0xFB,0xCA,0x99,0xA8,
// 0xC5,0xF4,0xA7,0x96,0x01,0x30,0x63,0x52,0x7C,0x4D,0x1E,0x2F,0xB8,0x89,0xDA,0xEB,
// 0x3D,0x0C,0x5F,0x6E,0xF9,0xC8,0x9B,0xAA,0x84,0xB5,0xE6,0xD7,0x40,0x71,0x22,0x13,
// 0x7E,0x4F,0x1C,0x2D,0xBA,0x8B,0xD8,0xE9,0xC7,0xF6,0xA5,0x94,0x03,0x32,0x61,0x50,
// 0xBB,0x8A,0xD9,0xE8,0x7F,0x4E,0x1D,0x2C,0x02,0x33,0x60,0x51,0xC6,0xF7,0xA4,0x95,
// 0xF8,0xC9,0x9A,0xAB,0x3C,0x0D,0x5E,0x6F,0x41,0x70,0x23,0x12,0x85,0xB4,0xE7,0xD6,
// 0x7A,0x4B,0x18,0x29,0xBE,0x8F,0xDC,0xED,0xC3,0xF2,0xA1,0x90,0x07,0x36,0x65,0x54,
// 0x39,0x08,0x5B,0x6A,0xFD,0xCC,0x9F,0xAE,0x80,0xB1,0xE2,0xD3,0x44,0x75,0x26,0x17,
// 0xFC,0xCD,0x9E,0xAF,0x38,0x09,0x5A,0x6B,0x45,0x74,0x27,0x16,0x81,0xB0,0xE3,0xD2,
// 0xBF,0x8E,0xDD,0xEC,0x7B,0x4A,0x19,0x28,0x06,0x37,0x64,0x55,0xC2,0xF3,0xA0,0x91,
// 0x47,0x76,0x25,0x14,0x83,0xB2,0xE1,0xD0,0xFE,0xCF,0x9C,0xAD,0x3A,0x0B,0x58,0x69,
// 0x04,0x35,0x66,0x57,0xC0,0xF1,0xA2,0x93,0xBD,0x8C,0xDF,0xEE,0x79,0x48,0x1B,0x2A,
// 0xC1,0xF0,0xA3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1A,0x2B,0xBC,0x8D,0xDE,0xEF,
// 0x82,0xB3,0xE0,0xD1,0x46,0x77,0x24,0x15,0x3B,0x0A,0x59,0x68,0xFF,0xCE,0x9D,0xAC };

// uint8_t calculate_cr8x_fast(uint8_t* data, size_t len) {
// uint8_t crc = 0xFF; // init value
// for (size_t i = 0; i < len; i++) {
// crc = crc8x_table[data[i] ^ crc];
// }
// return crc;
// }

// unsigned crc8x_fast(uint8_t crc, uint8_t const *mem, size_t len) {
// unsigned char const *data = mem;
// if (data == NULL)
// return 0xff;
// crc = 0xff;
// while (len--)
// crc = crc8x_table[crc ^ *data++];
// return crc;
// }

// // CRC-8 polynomial (0x07)
// #define CRC8_POLYNOMIAL 0x07
Expand Down
4 changes: 2 additions & 2 deletions cpp/src/yivopkt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ class yivopkt_t {

uint8_t calc_checksum() {
// XOR all bytes EXCEPT header and checksum
uint8_t cs = 0;
uint32_t cs = 0;
for (uint16_t i = 2; i < (buffer_size - 1); ++i) cs ^= buffer[i];
return cs;
return (uint8_t)(cs & 0x000000FF);
}

uint8_t* buffer=nullptr;
Expand Down
4 changes: 0 additions & 4 deletions python/tests/test_yivo.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ def test_pack_n_unpack():
A = namedtuple("A","x y")
B = namedtuple("B", "x y z t")

# msgdb = {
# 1: (make_Struct("2f"), A), # 2 floats
# 2: (make_Struct("4f"), B) # 4 floats
# }
msgdb = MsgInfo()
msgdb[1] = ("2f", A) # 2 floats
msgdb[2] = ("4f", B) # 4 floats
Expand Down
77 changes: 40 additions & 37 deletions python/yivo/packet.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def str(val):
elif (val == Errors.INVALID_COMMAND): return "INVALID_COMMAND"
elif (val == Errors.INVALID_MSGID): return "INVALID_MSGID"
elif (val == Errors.NO_DATA): return "NO_DATA"
return "UNKNOWN"
return f"UNKNOWN({val})"



Expand All @@ -89,7 +89,7 @@ def checksum(msg):
for m in msg:
cs ^= m
# print("cs", cs, cs.to_bytes(1,'little'))
return cs
return cs & 0xFF

def chunk(msg):
size = msg[2] + (msg[3] << 8) # messages sent little endian
Expand Down Expand Up @@ -150,23 +150,25 @@ def pack(self, msgID, data):
msg = msg[:-1] + self.pack_cs.pack(cs) #cs.to_bytes(1,'little')
return msg

def unpack(self, msg=None):
if msg is None:
return self.__unpack()
self.data = msg
return self.__unpack()

def dump(self, msg):
if msg is None:
return
size, msgid, payload, cs = chunk(msg)
payload = [x for x in payload]
print(f"{Fore.CYAN}==============================================")
print(f"Msg: {msg}")
print(f"Size: {size} payload size: {len(payload)}")
print(f"{Fore.GREEN}Msg: {msg}{Fore.CYAN}")
print(f"Size: {size} payload actual size: {len(payload)}")
print(f"msgid: {msgid}")
print(f"payload: {payload}")
print(f"checksum: {cs} calc: {checksum(msg[2:-1])}")
print(f"checksum: {cs} calc checksum: {checksum(msg[2:-1])}")
print(f"==================================================={Fore.RESET}")

def unpack(self, msg=None):
if msg is None:
return self.__unpack()
self.data = msg
return self.__unpack()

def __unpack(self):
"""
Unpacks a binary yivo packet
Expand All @@ -175,57 +177,58 @@ def __unpack(self):
Errors
Message
"""
# clear = False # doesn't cleanup if failure
# if msg is None:
# msg = self.data
# clear = True
msg = self.data
if msg is None:
return Errors.NO_DATA, None

size, msgid, payload, cs = chunk(msg)
err = self.valid_msg(msg)
if err != Errors.NONE:
self.dump(msg)
return err, None

msgid = msg[4]
try:
fmt, obj = self.msgInfo[msgid]
except KeyError:
return Errors.INVALID_MSGID, None

# print(f">> size: {size}\n id: {msgid}\n pl: {payload}\n cs: {cs}")
info = fmt.unpack(msg)
# print(f"{Fore.YELLOW}{info}{Fore.RESET}")
val = obj(*info[4:-1])

return Errors.NONE, val

def valid_msg(self, msg):
size, msgid, payload, cs = chunk(msg)

val = None
a = ord(self.header[0])
b = ord(self.header[1])
if (msg[0] != a) or (msg[1] != b):
# print(msg[:2], self.header)
return Errors.INVALID_HEADER, None
return Errors.INVALID_HEADER

if msgid not in self.valid_msgids:
# print(f"invalid id: {msgid}")
return Errors.INVALID_MSGID, None
return Errors.INVALID_MSGID

if (size == 0) or (size != len(payload)):
# print(len(payload),"!=", size)
return Errors.INVALID_LENGTH, None
return Errors.INVALID_LENGTH
# print(size, len(payload))

# if checksum(size, msgid, payload) != cs:
if checksum(msg[2:-1]) != cs:
# print("checksum failure", cs, "!=", checksum(size, msgid, payload))
self.dump(msg)
return Errors.INVALID_CHECKSUM, None
# self.dump(msg)
return Errors.INVALID_CHECKSUM
# print(cs, checksum(size, msgid, payload))

try:
fmt, obj = self.msgInfo[msgid]
except KeyError:
return Errors.INVALID_MSGID, None

if size > 0:
info = fmt.unpack(msg)
# print("info", info)
# print(type(obj))
# if isinstance(tuple, obj): val = tuple(info[4:-1])
# else: val = obj(*info[4:-1])
val = obj(*info[4:-1])
else:
val = REQUEST(msgid)
# if clear:
# self.data = None
return Errors.INVALID_MSGID

return Errors.NONE, val
return Errors.NONE

def parse(self, c):
if self.parser.parse(c):
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ Trying to standardize the way I access sensors.

## Todo

- [ ] Should I move to a 16b checksum?
- [ ] Should I use a 16b message id instead of 8b?
- [ ] Make C and python functions/objects match ... they are different right now
- [ ] Should I move to a readl CRC-8 checksum?
- [x] Remove messages from library. This is just a binary packer and
not dependant on the message format other than, it is a `struct`
- [x] c++: Make a header only library
Expand Down

0 comments on commit 058b01e

Please sign in to comment.