diff --git a/README.md b/README.md index caba97b..15acf04 100644 --- a/README.md +++ b/README.md @@ -285,9 +285,8 @@ The UNI protocol is principally defined in the modules `unitypes_*.py` as a seri ``` 1. attribute names must be unique within each message class -2. attribute types must be one of the valid types (S1, U2, X4, etc.) -3. if the attribute is scaled, attribute type is list of [attribute type as string (S1, U2, etc.), scaling factor as float] e.g. {"lat": [R4, 1e-7]} -4. repeating or bitfield groups must be defined as a tuple ('numr', {dict}), where: +2. attribute types must be one of the valid types (S1, U2, X4, etc.). A suffix of "*f" signifies a scaling factor of f is to be applied to the raw value. +3. repeating or bitfield groups must be defined as a tuple ('numr', {dict}), where: 'numr' is either: a. an integer representing a fixed number of repeats e.g. 32 b. a string representing the name of a preceding attribute containing the number of repeats e.g. 'numsat' diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 218b00d..d51fe53 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,10 @@ # pyunigps Release Notes +### RELEASE 0.1.5 + +1. Fix OBSVM, OBSVMCMP `psr` & `adr` attribute scaling. +1. Add additional navigation bitmask decodes. + ### RELEASE 0.1.4 1. Split SATELLITE `prn` definition into `glofreq` (MSB) and `prn` (LSB). diff --git a/examples/benchmark.py b/examples/benchmark.py index c3a8ee3..e99e410 100644 --- a/examples/benchmark.py +++ b/examples/benchmark.py @@ -62,6 +62,16 @@ b"\xaaD\xb5YC\x08L\x03\x00\xa0e\t\xd0_\x80\x04\x00\x00\x00\x00\x00\x12\x0f\x00\x15\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00l\xaf\x84K\xb4C\xacJc&\x93K\x03\xea\xc3G|\xa7\xc7?.\n\x1e@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\xbf\xee\x93K?'cK\xf2\x98.K\x0c\xec F'\xa7\x10@5\xe5o@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\xd9\xfa\x86Kq\xa2\x92\xca\x93\xd9\x90K\xd3k(H\xa1\x1b\xc4?\xe7Q\x1a@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x1c\xfc8K\x03v\xb1\xcb\xb9$;J\xc4\xc8VH\xcea\xdf@\x9c\xc0dA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\xe2:\x1dK-'Q\xcb\xcc\x14\x9eK\xb2W\x85\xc6f\xd2\x04@'TA@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\xa9\x93\x8aGl\x9fi\xcbs&\xa5K&\xcfIHS;=@\xd6*\x94@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\xae\t\x08KPi\xb2\xcbU\xd3\x13K\xdc\"e\xc6\xdc\x85\x9f@Q\x08\xf6@\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00&\x00\x00\x00\x8cT\xc6\xc7\xedt,KI\x85\xaeK\xe6\x938G\xe2\xd3\x1a@&\xf4\x88@\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'\x00\x00\x00$B}K\x94\xc5\x85J\x03\x90\x90Ks\x84fEg\x98\xbe?\xd1`\x1b@\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x006\x00\x00\x00W\x07\x82K|\xbf\x89J\xfc\x92\x8cKz.\x9dGm\x8a\xbf?\xe1h\x1c@\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x007\x00\x00\x00p\xc1\xc2JBg\x03\xcb\xe9\xb2\xb0K\xd4+\x90G\x16\x0f\xde?\x03\xcb8@\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\r\x00\x00\x00\xae\x18\x88K\x81\x00\x17K\x0f\xc1\xa3Kf\x07a\xc6\xa2#\xd1?\xd4\xf6&@\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x17\x00\x00\x00z\xe3&K\n\xa5\xbd\xcb\xa4m3K\x9c\x92\xe6\xc52\x9f\x87@\x83\xb9\xc1@\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x19\x05?K\xd9\x1e7\xcb\xc9\x14\xb7KQ\xb3{G&6\xe8?\x94(-@\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1f\x00\x00\x00\xb9\xa1\xc4\xca\xb1\x1f\x83\xcb\xaf)\xb1K\x965\n\xc7\xfe\x1ao@\xbe\xa3\xe0@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x13\x00\x00\x00kS\xa4K\xe3\"\x0eJ\x81=\x86K\x92I\x8e\xc8\x8c\x12\xcc?\x17\xc3\x1e@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x14\x00\x00\x00\xe7\xb5\xcaJ\xbd\xafSKO\xb8\xb1K\x9b&\x8d\xc8H\xd4\x06@r\x01X@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x16\x00\x00\x00_\x96\xc1KNz/\xcb\x843\xa2I\xf7\xe9\xffG\x1e\x1b\x82@~\xcf\xb5@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x1d\x00\x00\x00}\xe8\xbcK\xe3`@Kl\x08 JFW$H\x97\xaeA@W\xc8\xb3@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00#\x00\x00\x00\xa8$\x9bK\xf5\x0b[\xca\xc6/\x8fKo\r\x9a\xc7\xee\x8d\xc8?\xdf5\x1b@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00,\x00\x00\x00c\xd2\xa9Jq,n\xcb\xc0\x1f\xabKK\x1c\x81Hhs\x1c@h\x83b@\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x1d\xe0\xb6", b"\xaaD\xb5Y\x11\x04T\x01\x00\xa0e\t\xd0_\x80\x04\x00\x00\x00\x00\x00\x12\x0f\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x08\x00&\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00'\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x0b\x006\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x04\x007\x00\x00\x00\x00\x00\x03\x00\x00\x00\x05\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00m\x00\x00\x00\x06\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00-\x00\x00\x00\x06\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00m\x00\x00\x00\x06\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00%\x00\x00\x00\xdf\xcf\xc2*", b"\xaaD\xb5Y\x11\x04T\x01\x00\xa0e\t\xd0_\x80\x04\x00\x00\x00\x00\x00\x12\x0f\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x08\x00&\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00'\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x0b\x006\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x04\x007\x00\x00\x00\x00\x00\x03\x00\x00\x00\x05\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00m\x00\x00\x00\x06\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00-\x00\x00\x00\x06\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00m\x00\x00\x00\x06\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00%\x00\x00\x00\xdf\xcf\xc2*", + b"\xaaD\xb5Y\x07\x02\x0c\x00\x00\xa0e\t\xe8[\x80\x04\x00\x00\x00\x00\x00\x12\x13\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?s\x9b<", + b"\xaaD\xb5Y\xda\x00(\x00\x00\xa0e\t\xe8[\x80\x04\x00\x00\x00\x00\x00\x12\x13\x00\xbb\xef\x00\x00\x00\x00j?\x00@\x83?\x00\x00\xea?\x01\x00\x00\x00\x01\x1c\xfa>\x00\x00\x00\x00\x84\x01p\x03\x00\x00\x00\x00\x00\x00\x00\x00\xe2ijj", + b"\xaaD\xb5Yj\x00\xe0\x00\x00\xa0e\t\xe8[\x80\x04\x00\x00\x00\x00\x00\x12\x15\x00\x01\x00\x00\x00\x00\x00\x00\x00\xe0\xa4\xf1@\x00\x00\x00\x00\x1c\x00\x00\x00\x1c\x00\x00\x00e\t\x00\x00e\t\x00\x00\x00\x00\x00\x00\x00V\xf3@\xf1n\x18*ZTyA\xdeq\x94R\x9f\xf43>^\xeeb\xa49a\x04@\x00\x00\x00\xe0\x96bX?K'\xec\x85\xfb\x1f\xa3?\x00\x00\x00\x00\x00\xf0\xb4\xbe\x00\x00\x00\x00\x00\xfa\xd5>\x00\x00\x00\x00\x00Rq@\x00\x00\x00\x00\x00X8\xc0\x00\x00\x00\x00\x00\x00\\\xbe\x00\x00\x00\x00\x00\x00`>\xec\xc7\xe6{?\xab\xee?C\xcc\x85sQ\x18\xe3\xbd:\xc1\xdd\x16e'\x06\xc0\xc5\xaf\x88\xd28\x9aA\xbe\x1c\x02\x00\x00\x00\x00\x00\x00\x00V\xf3@\x00\x00\x00\x00\x00\x00C\xbe\x00\x00\x00\x00\x1c\xed5?\x00\x00\x00\x00\x00\x00\x96\xbd\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x0012wES\x1e#?\x00\x00\x00\x00\x00\x00\x10@\x14\x8aN\xa3", + b"\xaaD\xb5Yl\x00\xe8\x00\x00\xa0e\t\xe8[\x80\x04\x00\x00\x00\x00\x00\x12\x16\x00\x13\x00\x00\x00\x00\x00\x00\x00\xa0\xa8\xf1@\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00e\t\x00\x00e\t\x00\x00\x00\x00\x00\x00\x00\x94\xf1@m4\n\x1d\x0b\x9dzA\xa4\xff}T\x99',>\x1b\xb8\xcb\\`2\xf3?\x00\x00\x00\xc0n\xa5P?\x9b@X/\tB\xea\xbf\x00\x00\x00\x00\x00\x88\xbc\xbe\x00\x00\x00\x00\x80X\xdd>\x00\x00\x00\x00\x00\x14m@\x00\x00\x00\x00\x00\xf6@\xc0\x00\x00\x00\x00\x00\x80q>\x00\x00\x00\x00\x00\x00F>S@\xb9\xc0\x8d\x97\xef?\xc5\x01\xa1\xean\x97\xf0=__=\x08\xd1\xc3\xf3\xbf\xe6\xb2\x8e\x07\x1b\x17<\xbe\x01\x00\x00\x00\x00\x00\x00\x00\x00\x94\xf1@\xda\xbfF\xa4\xba\xf8C>\xda\xbfF\xa4\xba\xf8C>\x00\x00\x00\x00\xac\xd9O\xbf\x00\x00\x00\x00\x00\xe4\x93\xbd\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xb1\xe7\xbbLi\xc0!?\x00\x00\x00\x00\x00\x00\x10@\xd1\x9e\x81'", + b"\xaaD\xb5Yk\x00\x90\x00\x00\xa0e\t\xe8[\x80\x04\x00\x00\x00\x00\x00\x12\x16\x00&\x00\x08\x00\x01\x00e\t0\x1bt\x04\x1e*\x00\x00\x02\x03\x00\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80R\xef\xb8AA\x00\x00\xc0\x7f\xc9(dA\x00\x00`\x16\xed\x08vA\x00\x00\x00\xb40\xe0\xa7\xc0\x00\x00\x004\xa9w\x89@\x00\x00\x00\x80\x8c\x10P\xc0\x00\x00\x00\x00\x00@\xaf>\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00@\xbf\xbe\x00\x00\x00\x00\x08\xa9$\xbf\x00\x00\x00\x00\x00\x00D>\x00\x00\x00\x00\x00\x00p=\x96J\x01\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\xcc=L\x1e", + b"\xaaD\xb5Ym\x00\xdc\x00\x00\xa0e\t\xe8[\x80\x04\x00\x00\x00\x00\x00\x12\x16\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x00|\x00\x00\x00\xa0\"\x01\x00\x00\x00\x00Q\x9b@\xb5@\xce\xf0\x82\x87\xb4\xbc)>\xed}\x1dx\xa4p\xe3?\x00\x00\x00\x80\xf9\x9c1?\xad\x14P\x1d\xbfJ\xb3?\x00\x00\x00\x00\x00\xdc\xc3\xbe\x00\x00\x00\x00\x00\xce\xda>\x00\x00\x00\x00\x00=j@\x00\x00\x00\x00\x00\x10J\xc0\x00\x00\x00\x00\x00\x80p\xbe\x00\x00\x00\x00\x00\x00a>\x1b\x19E{\xe5#\xef?\x99\xe9\xf7{ZL\xe8=!\x8cg\xc9\xe9\x90\xe2\xbf\x9f\x9dqv\xcdg7\xbe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\"\x01\x00\x00\x00\x00\x00\xce'\x17\xbf\x00\x00\x00\x00\x00\x00\x9e\xbd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\xbe\x00\x00\x00\x00\x00\x006\xbe\xd4\x90'j", + b'\xaaD\xb5Y\xb7\x0b\x08\x01\x00\xa0e\t\xe8[\x80\x04\x00\x00\x00\x00\x00\x12\x16\x00\x13\x00\x03\x0f\x14\x00\x14\x00e\te\t\x00\x00\x00\x00\x00\x1b\xf2@\x00\x00\x00\x00\x00\x94\xf1@\x00\x00\x00\x00\xd0\xa6`@\x00\x00\x00\x00\x00\xc4s\xbf\x12D\xf5\xbc\x0b\xfa+>\x8d\xd8"\xfd\x11F(=\xf4\xf5\xa7\x14\x863\xf3?\x00\x00\x00\xc0\xa8\xacP?\xa2\x97\xfcF[D\xea\xbf\x00\x00\x00\x00\x00|\xbe\xbe\x00\x00\x00\x00\x006\xdc>\x00\x00\x00\x00\xa0\xd5m@\x00\x00\x00\x00\x00CB\xc0\x00\x00\x00\x00\x00\x80m>\x00\x00\x00\x00\x00\x00c>\x01\xc8}\xed\x8d\x97\xef?\xfc&\xfc\x18q\xc2\xef=\x8fqu\xfc\xd0\xc3\xf3\xbf\xf7r\xd7"o\x05<\xbe\x00\x00\x00\x00\x00\x94\xf1@\x00\x00\x00\x00\x00`D>\x00\x00\x00\x00\x00\x00\x15>\x00\x00\x00\x00\x00\x80 >\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\'\xbe\x00\x00\x00\x00\x00\x00\x0e\xbe\x00\x00\x00\x00\xac\xd9O\xbf\x00\x00\x00\x00\x00\xe4\x93\xbd\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x00\x00\x00\x00\x1e\x07\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00dn\n\x03', + b"\xaaD\xb5YC\x08L\x03\x00\xa0e\t\xd0_\x80\x04\x00\x00\x00\x00\x00\x12\x0f\x00\x15\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00l\xaf\x84K\xb4C\xacJc&\x93K\x03\xea\xc3G|\xa7\xc7?.\n\x1e@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\xbf\xee\x93K?'cK\xf2\x98.K\x0c\xec F'\xa7\x10@5\xe5o@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\xd9\xfa\x86Kq\xa2\x92\xca\x93\xd9\x90K\xd3k(H\xa1\x1b\xc4?\xe7Q\x1a@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x1c\xfc8K\x03v\xb1\xcb\xb9$;J\xc4\xc8VH\xcea\xdf@\x9c\xc0dA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\xe2:\x1dK-'Q\xcb\xcc\x14\x9eK\xb2W\x85\xc6f\xd2\x04@'TA@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\xa9\x93\x8aGl\x9fi\xcbs&\xa5K&\xcfIHS;=@\xd6*\x94@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\xae\t\x08KPi\xb2\xcbU\xd3\x13K\xdc\"e\xc6\xdc\x85\x9f@Q\x08\xf6@\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00&\x00\x00\x00\x8cT\xc6\xc7\xedt,KI\x85\xaeK\xe6\x938G\xe2\xd3\x1a@&\xf4\x88@\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'\x00\x00\x00$B}K\x94\xc5\x85J\x03\x90\x90Ks\x84fEg\x98\xbe?\xd1`\x1b@\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x006\x00\x00\x00W\x07\x82K|\xbf\x89J\xfc\x92\x8cKz.\x9dGm\x8a\xbf?\xe1h\x1c@\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x007\x00\x00\x00p\xc1\xc2JBg\x03\xcb\xe9\xb2\xb0K\xd4+\x90G\x16\x0f\xde?\x03\xcb8@\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\r\x00\x00\x00\xae\x18\x88K\x81\x00\x17K\x0f\xc1\xa3Kf\x07a\xc6\xa2#\xd1?\xd4\xf6&@\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x17\x00\x00\x00z\xe3&K\n\xa5\xbd\xcb\xa4m3K\x9c\x92\xe6\xc52\x9f\x87@\x83\xb9\xc1@\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x19\x05?K\xd9\x1e7\xcb\xc9\x14\xb7KQ\xb3{G&6\xe8?\x94(-@\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1f\x00\x00\x00\xb9\xa1\xc4\xca\xb1\x1f\x83\xcb\xaf)\xb1K\x965\n\xc7\xfe\x1ao@\xbe\xa3\xe0@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x13\x00\x00\x00kS\xa4K\xe3\"\x0eJ\x81=\x86K\x92I\x8e\xc8\x8c\x12\xcc?\x17\xc3\x1e@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x14\x00\x00\x00\xe7\xb5\xcaJ\xbd\xafSKO\xb8\xb1K\x9b&\x8d\xc8H\xd4\x06@r\x01X@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x16\x00\x00\x00_\x96\xc1KNz/\xcb\x843\xa2I\xf7\xe9\xffG\x1e\x1b\x82@~\xcf\xb5@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x1d\x00\x00\x00}\xe8\xbcK\xe3`@Kl\x08 JFW$H\x97\xaeA@W\xc8\xb3@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00#\x00\x00\x00\xa8$\x9bK\xf5\x0b[\xca\xc6/\x8fKo\r\x9a\xc7\xee\x8d\xc8?\xdf5\x1b@\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00,\x00\x00\x00c\xd2\xa9Jq,n\xcb\xc0\x1f\xabKK\x1c\x81Hhs\x1c@h\x83b@\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x1d\xe0\xb6", + b"\xaaD\xb5Y\x11\x04T\x01\x00\xa0e\t\xd0_\x80\x04\x00\x00\x00\x00\x00\x12\x0f\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x08\x00&\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00'\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x0b\x006\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x04\x007\x00\x00\x00\x00\x00\x03\x00\x00\x00\x05\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00m\x00\x00\x00\x06\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00-\x00\x00\x00\x06\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00m\x00\x00\x00\x06\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00%\x00\x00\x00\xdf\xcf\xc2*", + b"\xaaD\xb5Y\x11\x04T\x01\x00\xa0e\t\xd0_\x80\x04\x00\x00\x00\x00\x00\x12\x0f\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x08\x00&\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00'\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x0b\x006\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x04\x007\x00\x00\x00\x00\x00\x03\x00\x00\x00\x05\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00m\x00\x00\x00\x06\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00-\x00\x00\x00\x06\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00m\x00\x00\x00\x06\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00%\x00\x00\x00\xdf\xcf\xc2*", ] msgb = b"" diff --git a/src/pyunigps/_version.py b/src/pyunigps/_version.py index 9cc7704..0c1eeef 100644 --- a/src/pyunigps/_version.py +++ b/src/pyunigps/_version.py @@ -8,4 +8,4 @@ :license: BSD 3-Clause """ -__version__ = "0.1.4" +__version__ = "0.1.5" diff --git a/src/pyunigps/unimessage.py b/src/pyunigps/unimessage.py index 8bf9be6..0607bc4 100644 --- a/src/pyunigps/unimessage.py +++ b/src/pyunigps/unimessage.py @@ -12,10 +12,9 @@ # pylint: disable=too-many-positional-arguments, too-many-locals, too-many-arguments, too-many-instance-attributes -import struct from types import NoneType -from pyunigps.exceptions import UNIMessageError, UNITypeError +from pyunigps.exceptions import UNIMessageError from pyunigps.unihelpers import ( attsiz, bytes2val, @@ -37,6 +36,7 @@ UNI_HDR, UNI_MSGIDS, ) +from pyunigps.unitypes_decodes import PSRSTD from pyunigps.unitypes_get import UNI_PAYLOADS_GET from pyunigps.unitypes_poll import UNI_PAYLOADS_POLL from pyunigps.unitypes_set import UNI_PAYLOADS_SET @@ -91,6 +91,9 @@ def __init__( :raises: UNITypeError, UNIMessageError """ + if msgmode not in (GET, SET, POLL): + raise UNIMessageError(f"Invalid msgmode {msgmode} - must be 0, 1 or 2") + # object is mutable during initialisation only super().__setattr__("_immutable", False) self.cpuidle = cpuidle @@ -113,64 +116,20 @@ def __init__( self.leapsecond = leapsecond self.delay = delay self._mode = msgmode - self._payload = b"" + self._payload = kwargs.get("payload", b"") self._parsebf = parsebitfield # parsing bitfields Y/N? + self._offset = 0 # payload offset in bytes + self._index = [] # array of (nested) group indices + self._suffix = "" # attribute index suffix ("_01", "_02", etc.) - if msgmode not in (GET, SET, POLL): - raise UNIMessageError(f"Invalid msgmode {msgmode} - must be 0, 1 or 2") - - self._do_attributes(**kwargs) + pdict = self._get_dict(**kwargs) # get appropriate payload dict + for anam in pdict: # process each attribute in dict + self._set_attribute(anam, pdict, **kwargs) + self._do_len_checksum() self._immutable = True # once initialised, object is immutable - def _do_attributes(self, **kwargs): - """ - Populate UNIMessage from named attribute keywords. - Where a named attribute is absent, set to a nominal value (zeros or blanks). - - :param kwargs: optional payload key/value pairs - :raises: UNITypeError - - """ - - offset = 0 # payload offset in bytes - index = [] # array of (nested) group indices - - try: - if len(kwargs) == 0: # if no kwargs, assume null payload - self._payload = None - else: - self._payload = kwargs.get("payload", b"") - pdict = self._get_dict(**kwargs) # get appropriate payload dict - for anam in pdict: # process each attribute in dict - offset, index = self._set_attribute( - anam, pdict, offset, index, **kwargs - ) - self._do_len_checksum() - - except ( - AttributeError, - struct.error, - TypeError, - ValueError, - ) as err: - raise UNITypeError( - ( - f"Incorrect type for attribute '{anam}' " - f"in {['GET', 'SET', 'POLL'][self._mode]} message class {self.identity}" - ) - ) from err - except (OverflowError,) as err: - raise UNITypeError( - ( - f"Overflow error for attribute '{anam}' " - f"in {['GET', 'SET', 'POLL'][self._mode]} message class {self.identity}" - ) - ) from err - - def _set_attribute( - self, anam: str, pdict: dict, offset: int, index: list, **kwargs - ) -> tuple: + def _set_attribute(self, anam: str, pdict: dict, **kwargs): # -> tuple: """ Recursive routine to set individual or grouped payload attributes. @@ -191,23 +150,15 @@ def _set_attribute( numr, _ = adef if numr[0] == "X": # bitfield if self._parsebf: # if we're parsing bitfields - offset, index = self._set_attribute_bitfield( - adef, offset, index, **kwargs - ) + self._set_attribute_bitfield(adef, **kwargs) else: # treat bitfield as a single byte array - offset = self._set_attribute_single( - anam, numr, offset, index, **kwargs - ) + self._set_attribute_single(anam, numr, **kwargs) else: # repeating group of attributes - offset, index = self._set_attribute_group(adef, offset, index, **kwargs) + self._set_attribute_group(adef, **kwargs) else: # single attribute - offset = self._set_attribute_single(anam, adef, offset, index, **kwargs) - - return (offset, index) + self._set_attribute_single(anam, adef, **kwargs) - def _set_attribute_group( - self, adef: tuple, offset: int, index: list, **kwargs - ) -> tuple: + def _set_attribute_group(self, adef: tuple, **kwargs): """ Process (nested) group of attributes. @@ -220,36 +171,30 @@ def _set_attribute_group( """ - index.append(0) # add a (nested) group index + self._index.append(0) # add a (nested) group index anam, gdict = adef # attribute signifying group size, group dictionary # derive or retrieve number of items in group if isinstance(anam, int): # fixed number of repeats gsiz = anam elif anam == FREQNO: # SATSINFO frequency group (assumes always at least 1) if "payload" in kwargs: - gsiz = bytes2val(self._payload[offset + 3 : offset + 4], U1) + gsiz = bytes2val(self._payload[self._offset + 3 : self._offset + 4], U1) else: - gsiz = kwargs.get(f"{FREQNO}_{index[0]:02d}_01", 1) + gsiz = kwargs.get(f"{FREQNO}_{self._index[0]:02d}_01", 1) elif anam == "None": # number of repeats 'variable by size' - gsiz = self._calc_num_repeats(gdict, self._payload, offset, 0) + gsiz = self._calc_num_repeats(gdict, self._payload, self._offset, 0) else: # number of repeats is defined in named attribute gsiz = getattr(self, anam) # recursively process each group attribute, # incrementing the payload offset and index as we go for i in range(gsiz): - index[-1] = i + 1 + self._index[-1] = i + 1 for key1 in gdict: - offset, index = self._set_attribute( - key1, gdict, offset, index, **kwargs - ) - - index.pop() # remove this (nested) group index + self._set_attribute(key1, gdict, **kwargs) - return (offset, index) + self._index.pop() # remove this (nested) group index - def _set_attribute_single( - self, anam: str, adef: str | list, offset: int, index: list, **kwargs - ) -> int: + def _set_attribute_single(self, anam: str, adef: str | list, **kwargs): """ Set individual attribute value, applying scaling where appropriate. @@ -265,15 +210,9 @@ def _set_attribute_single( """ # pylint: disable=no-member - # if attribute is scaled - ares = 1 - if isinstance(adef, list): - ares = adef[1] # attribute resolution (i.e. scaling factor) - adef = adef[0] # attribute definition - # if attribute is part of a (nested) repeating group, suffix name with index anami = anam - for i in index: # one index for each nested level + for i in self._index: # one index for each nested level if i > 0: anami += f"_{i:02d}" @@ -283,32 +222,36 @@ def _set_attribute_single( # - payload length - offset asiz = attsiz(adef) + # if attribute is scaled + if "*" in adef: + adef, scaling = adef.split("*", 1) + scaling = float(scaling) + else: + scaling = 1 + # if payload keyword has been provided, # use the appropriate offset of the payload if "payload" in kwargs: - valb = self._payload[offset : offset + asiz] - if ares == 1: + valb = self._payload[self._offset : self._offset + asiz] + if scaling == 1: val = bytes2val(valb, adef) else: - val = round(bytes2val(valb, adef) * ares, SCALROUND) + val = round(bytes2val(valb, adef) / scaling, SCALROUND) else: # if individual keyword has been provided, # set to provided value, else set to # nominal value val = kwargs.get(anami, nomval(adef)) - if ares == 1: + if scaling == 1: valb = val2bytes(val, adef) else: - valb = val2bytes(int(val / ares), adef) + valb = val2bytes(int(val * scaling), adef) self._payload += valb setattr(self, anami, val) + self._offset += asiz - return offset + asiz - - def _set_attribute_bitfield( - self, atyp: str, offset: int, index: list, **kwargs - ) -> tuple: + def _set_attribute_bitfield(self, atyp: str, **kwargs): """ Parse bitfield attribute (type 'X'). @@ -329,21 +272,23 @@ def _set_attribute_bitfield( # if payload keyword has been provided, # use the appropriate offset of the payload if "payload" in kwargs: - bitfield = int.from_bytes(self._payload[offset : offset + bsiz], "little") + bitfield = int.from_bytes( + self._payload[self._offset : self._offset + bsiz], "little" + ) else: bitfield = 0 # process each flag in bitfield for key, keyt in bdict.items(): bitfield, bfoffset = self._set_attribute_bits( - bitfield, bfoffset, key, keyt, index, **kwargs + bitfield, bfoffset, key, keyt, self._index, **kwargs ) # update payload if "payload" not in kwargs: self._payload += bitfield.to_bytes(bsiz, "little") - return (offset + bsiz, index) + self._offset += bsiz def _set_attribute_bits( self, @@ -375,12 +320,30 @@ def _set_attribute_bits( if i > 0: keyr += f"_{i:02d}" + # if attribute is scaled + if "*" in keyt: + keyt, scaling = keyt.split("*", 1) + scaling = float(scaling) + else: + scaling = 1 + atts = attsiz(keyt) # determine flag size in bits if "payload" in kwargs: val = (bitfield >> bfoffset) & ((1 << atts) - 1) + if self.identity in ("OBSVMCMP", "OBSVHCMP") and key == "psrstd": + val = PSRSTD[val] + elif self.identity in ("OBSVMCMP", "OBSVHCMP") and key == "adrstd": + val = round((val + 1) / 512, SCALROUND) + elif self.identity in ("OBSVMCMP", "OBSVHCMP") and key == "cno": + val += 20 + elif scaling != 1: + val = round(val / scaling, SCALROUND) else: - val = kwargs.get(keyr, 0) + if scaling == 1: + val = kwargs.get(keyr, 0) + else: + val = int(kwargs.get(keyr, 0) * scaling) bitfield = bitfield | (val << bfoffset) if key[0:8] != "reserved": # don't bother to set reserved bits diff --git a/src/pyunigps/unitypes_decodes.py b/src/pyunigps/unitypes_decodes.py index e0acf23..5932c41 100644 --- a/src/pyunigps/unitypes_decodes.py +++ b/src/pyunigps/unitypes_decodes.py @@ -112,3 +112,32 @@ 7: "Input a fixed position", } """ Rover Position Status""" + +PSRSTD = { + 0: 0.050, + 1: 0.075, + 2: 0.113, + 3: 0.169, + 4: 0.253, + 5: 0.380, + 6: 0.570, + 7: 0.854, + 8: 1.281, + 9: 2.375, + 10: 4.750, + 11: 9.500, + 12: 19.000, + 13: 38.000, + 14: 76.000, + 15: 152.000, +} +"""OBSVMCMP Pseudorange Standard Deviation Lookup""" + +PSRIONOCORR = { + 0: "Unknown", + 1: "Klobuchareph", + 2: "SBASionogrid", + 3: "Multifreq", + 4: "Psrdiff", +} +"""EXTSOLSTAT Pseudorange Ionospheric Correction""" diff --git a/src/pyunigps/unitypes_get.py b/src/pyunigps/unitypes_get.py index 9a01b53..3db0d0a 100644 --- a/src/pyunigps/unitypes_get.py +++ b/src/pyunigps/unitypes_get.py @@ -33,6 +33,49 @@ X24, ) +EXTSOLSTAT = { + "groupextsolstat": ( + X1, + { + "rtkverify": U1, + "psrionocorr": U3, # see PSRIONOCORR decode + "reserved50": U4, + }, + ), +} + +GPSGLOBDS2SIGMASK = { + "groupgpsmask": ( + X1, + { + "gpsl1": U1, + "gpsl2": U1, + "gpsl5": U1, + "bdsb3l": U1, + "glol1": U1, + "glol2": U1, + "bdsb1l": U1, + "bdsb2l": U1, + }, + ), +} + +GALBDS3SIGMASK = { + "groupgalmask": ( + X1, + { + "gale1": U1, + "gale5b": U1, + "gale5a": U1, + "reserved51": U1, + "bdsb1l": U1, + "bdsb3l": U1, + "bdsb2a": U1, + "bdsb1c": U1, + }, + ), +} + UNI_PAYLOADS_GET = { "VERSION": { "device": U4, @@ -49,12 +92,12 @@ { "glofreq": U2, "prn": U2, - "psr": U8, - "adr": U8, - "psrstd": [U2, 100], - "adrstd": [U2, 10000], + "psr": R8, + "adr": R8, + "psrstd": U2 + "*100", + "adrstd": U2 + "*10000", "doppfreq": R4, - "cno": [U2, 100], + "cno": U2 + "*100", "reserved1": U2, "locktime": R4, "trstatus": ( @@ -96,14 +139,14 @@ "sigtype": U5, "L2Cflag": U1, "reserved6": U5, - "doppler": "U028", - "psr": "U036", - "adr": "U032", - "psrstd": U4, - "adrstd": U4, + "doppler": "U028*256", + "psr": "U036*128", + "adr": "U032*256", + "psrstd": U4, # special processing see PSRSTD decode + "adrstd": U4, # special processing (n+1)/512 "prn": U8, - "locktime": "U021", - "cno": U5, + "locktime": "U021*32", + "cno": U5, # special processing 20+ "glofreq": U6, "reserved7": U16, }, @@ -554,9 +597,9 @@ "reserved1": U1, "reserved2": U1, "reserved3": U1, - "extsolstat": U1, - "galbds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, "vsolstatus": U4, "veltype": U4, "latency": R4, @@ -593,9 +636,9 @@ "numggl1": U1, "numsolnmultisvs": U1, "reserved1": U4, - "extsolstat": U1, - "galbds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, }, # "BESTNAVH": {}, # same as BESTNAV, see below # "BESTNAVXYZH": {}, # same as BESTNAVXYX, see below @@ -630,9 +673,9 @@ "reserved1": U1, "reserved2": U1, "reserved3": U1, - "extsolstat": U1, - "galbds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, "solstatus2": U4, "veltype": U4, "latency": R4, @@ -663,9 +706,9 @@ "reserved1": U1, "reserved2": U1, "reserved3": U1, - "extsolstat": U1, - "galbds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, }, "SPPNAV": { "solstatus": U4, @@ -686,9 +729,9 @@ "reserved1": U1, "reserved2": U1, "reserved3": U1, - "extsolstat": U1, - "galbds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, "solstatus2": U4, "veltype": U4, "latency": R4, @@ -802,7 +845,7 @@ { "prn": U1, "azi": S2, - "elev": S1, # TODO signed? + "elev": S1, "groupfreq": ( FREQNO, # calculated by 'look ahead' at run time {"sysstatus": U1, "cno": U1, "freqstatus": U1, FREQNO: U1}, @@ -829,9 +872,9 @@ "reserved1": U1, "reserved2": U1, "reserved3": U1, - "extsolstat": U1, - "galbds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, "vsolstatus": U4, "veltype": U4, "latency": R4, @@ -905,9 +948,9 @@ "numobs": U1, "nummulti": U1, "reserved2": U1, - "extsolstat": U1, - "galds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, }, "UNIHEADING2": { "solstat": U4, @@ -924,9 +967,9 @@ "numobs": U1, "nummulti": U1, "reserved2": U1, - "extsolstat": U1, - "galbds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, }, "HEADINGSTATUS": { "cfglength": R4, @@ -1101,7 +1144,7 @@ "iodp": U1, "sow": U4, "prnmask": "U032", - }, # TODO check mask struct + }, "PPPB2BINFO2": { "prn": U2, "iodssr": U1, @@ -1113,7 +1156,7 @@ "orbitcorr": "U012", }, ), - }, # TODO check orbitcorr struct + }, "PPPB2BINFO3": { "prn": U2, "iodssr": U1, @@ -1125,7 +1168,7 @@ "codebias": "U064", }, ), - }, # TODO double check codebias length, struct + }, "PPPB2BINFO4": { "prn": U2, "iodssr": U1, @@ -1139,7 +1182,7 @@ "clkcorr": U4, }, ), - }, # TODO check clkcorr struct + }, "PPPB2BINFO5": { "prn": U2, "iodssr": U1, @@ -1155,21 +1198,21 @@ "urai": U2, }, ), - }, # TODO check urai struct + }, "PPPB2BINFO6": { "prn": U2, "numc": U1, "numo": U1, "rawnumc": "U096", "rawnumo": "U080", - }, # TODO check raw structs + }, "PPPB2BINFO7": { "prn": U2, "numc": U1, "numo": U1, "rawnumc": "U128", "rawnumo": "U080", - }, # TODO check raw structs + }, "E6MASKBLOCK": { "toh": U4, "blockflag": U1, @@ -1301,9 +1344,9 @@ "reserved1": U1, "reserved2": U1, "reserved3": U1, - "extsolstat": U1, - "galbdssigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, }, "BSLNXYZHD2": { "solstatus": U4, @@ -1321,9 +1364,9 @@ "reserved1": U1, "reserved2": U1, "reserved3": U1, - "extsolstat": U1, - "galbds3sigmask": U1, - "gpsglobds2sigmask": U1, + **EXTSOLSTAT, + **GALBDS3SIGMASK, + **GPSGLOBDS2SIGMASK, }, "DOPHD2": { "gdop": R4, diff --git a/tests/test_parse.py b/tests/test_parse.py index fdf9679..9fa4b7f 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -34,7 +34,7 @@ DIRNAME = os.path.dirname(__file__) -class StreamTest(unittest.TestCase): +class ParseTest(unittest.TestCase): def setUp(self): self.maxDiff = None @@ -46,13 +46,13 @@ def testparseum981(self): "", "", "", - "", + "", "", "", - "", - "", + "", + "", "", - "", + "", "", "", "", @@ -60,8 +60,8 @@ def testparseum981(self): "", "", "", - "", - "", + "", + "", "", "", "", @@ -89,18 +89,18 @@ def testparseum981(self): i = 0 for raw, parsed in unr: # print(f'"{parsed}",') - print(f"{raw},") + # print(f"{raw},") # fout.write(f'"{str(parsed)}",\r\n') self.assertEqual(str(parsed), EXPECTED_RESULTS[i]) self.assertEqual(parsed.msgmode, 0) self.assertEqual(isvalid_checksum(raw), True) - self.assertIsInstance(unr.datastream,BufferedReader) + self.assertIsInstance(unr.datastream, BufferedReader) i += 1 self.assertEqual(i, len(EXPECTED_RESULTS)) def testparseSATSINFO(self): DATA = [ - b'\xaa\x44\xb5\x60\x4c\x08\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2f' + b"\xaa\x44\xb5\x60\x4c\x08\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2f" ] EXPECTED_PARSED = [ "", @@ -120,7 +120,7 @@ def testparseSATSINFO(self): def testparseSATSINFOnobitfield(self): DATA = [ - b'\xaa\x44\xb5\x60\x4c\x08\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2f' + b"\xaa\x44\xb5\x60\x4c\x08\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2f" ] EXPECTED_PARSED = [ "" @@ -128,7 +128,7 @@ def testparseSATSINFOnobitfield(self): stream = b"" for msg in DATA: stream += msg - unr = UNIReader(BytesIO(stream),parsebitfield=False) + unr = UNIReader(BytesIO(stream), parsebitfield=False) i = 0 for raw, parsed in unr: # print(f'"{parsed}",') @@ -138,7 +138,7 @@ def testparseSATSINFOnobitfield(self): def testparsenominal(self): DATA = [ - b'\xaa\x44\xb5\x60\x4c\x99\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\xad\x4f\x1d\x4d' + b"\xaa\x44\xb5\x60\x4c\x99\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\xad\x4f\x1d\x4d" ] EXPECTED_PARSED = [ "", @@ -146,7 +146,7 @@ def testparsenominal(self): stream = b"" for msg in DATA: stream += msg - unr = UNIReader(BytesIO(stream),parsebitfield=False) + unr = UNIReader(BytesIO(stream), parsebitfield=False) i = 0 for raw, parsed in unr: # print(f'"{parsed}",') @@ -259,16 +259,33 @@ def testconstructpvtsln(self): self.assertEqual(msg.identity, "PVTSLN") def testconstructbadtype(self): - with self.assertRaisesRegex(une.UNITypeError, "Incorrect type for attribute 'pdop' in GET message class PVTSLN"): - msg = UNIMessage(msgid="PVTSLN", psrposlat=67.1234, prposlon=102.3412, pdop="xxxx") + with self.assertRaisesRegex( + TypeError, + "Attribute type R004 value xxxx must be , not ", + ): + msg = UNIMessage( + msgid="PVTSLN", psrposlat=67.1234, prposlon=102.3412, pdop="xxxx" + ) def testconstructoverflow(self): - with self.assertRaisesRegex(une.UNITypeError, "Overflow error for attribute 'pdop' in GET message class PVTSLN"): - msg = UNIMessage(msgid="PVTSLN", psrposlat=67.1234, prposlon=102.3412, pdop=1.2345e55) + with self.assertRaisesRegex( + OverflowError, "float too large to pack with f format" + ): + msg = UNIMessage( + msgid="PVTSLN", psrposlat=67.1234, prposlon=102.3412, pdop=1.2345e55 + ) def testconstructbadmsgmode(self): - with self.assertRaisesRegex(une.UNIMessageError, "Invalid msgmode 7 - must be 0, 1 or 2"): - msg = UNIMessage(msgid="PVTSLN", msgmode=7, psrposlat=67.1234, prposlon=102.3412, pdop=1.2345e55) + with self.assertRaisesRegex( + une.UNIMessageError, "Invalid msgmode 7 - must be 0, 1 or 2" + ): + msg = UNIMessage( + msgid="PVTSLN", + msgmode=7, + psrposlat=67.1234, + prposlon=102.3412, + pdop=1.2345e55, + ) def testconstructbadmsgid(self): with self.assertRaisesRegex(une.UNIMessageError, "Unknown msgname TEST34"): @@ -382,7 +399,9 @@ def testmixedfilteredrtcm(self): # test mixed protocol parsing with protfilters i += 1 self.assertEqual(i, 7) - def testmixednoparse(self): # test mixed protocol parsing with protfilters, no parsing + def testmixednoparse( + self, + ): # test mixed protocol parsing with protfilters, no parsing i = 0 with open(os.path.join(DIRNAME, "pygpsdata_mixed.log"), "rb") as stream: ubr = UNIReader( @@ -399,46 +418,65 @@ def testmixednoparse(self): # test mixed protocol parsing with protfilters, no def testparsebadmsgmode(self): data = b"\xaaD\xb5`L\x08\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x002\x00\x00\x00\x00+\x02.\x013\x00-\x00\x02\x00*\t\x02\x040\x00\x11\x00%\x00\x03\x00+\x0e\x03\x00'\t\x03\x05\xe1\x00\x0e\x00*\x00\x02\x00%\t\x02\x06#\x00@\x00/\x00\x03\x004\x0e\x03\x000\t\x03\tP\x00!\x00*\x00\x03\x00,\x0e\x03\x00(\t\x03\x0b,\x018\x00.\x00\x03\x002\x0e\x03\x00.\t\x03\x0c\x15\x01%\x00*\x00\x02\x00)\t\x02\x11\x86\x00\x1f\x00,\x00\x02\x00)\t\x02\x13\x82\x005\x00.\x00\x02\x00+\t\x02\x14\xe8\x00/\x00.\x00\x02\x00*\t\x02\x19<\x01\x0f\x00&\x00\x03\x00-\x0e\x03\x00(\t\x03\x1c\x00\x00\x00\x00%\x00\x02\x00\x1f\t\x02\xc2\xaa\x00\x08\x05&\x00\x03\x05)\x0e\x03\x05%\t\x03\xc3p\x00C\x05-\x00\x03\x051\x0e\x03\x05/\t\x03\xc4\x84\x00=\x05*\x00\x03\x050\x0e\x03\x05.\t\x03\xc7\xa3\x00+\x05$\x00\x03\x05.\x0e\x03\x05,\t\x03't\x00@\x01+\x00\x02\x011\x05\x027<\x01\x1e\x01+\x00\x02\x01.\x05\x024\xf2\x00\n\x01'\x00\x02\x01'\x05\x02&#\x00\x1c\x01(\x00\x02\x01)\x05\x02=]\x00\x1d\x01*\x00\x02\x01-\x05\x026\x16\x00>\x01/\x00\x02\x012\x05\x02(\xb4\x00\x1b\x01*\x00\x02\x01-\x05\x02.V\x01\x04\x01\"\x00\x02\x01'\x05\x02\x0b]\x00=\x04!\x00\x03\x044\x11\x03\x042\x15\x03*r\x00C\x04\"\x00\x04\x043\x15\x04\x040\x08\x04\x041\x0c\x04\x02\xe0\x00!\x04-\x11\x02\x04)\x15\x02\n\xd6\x004\x04\x1d\x00\x03\x04.\x11\x03\x04-\x15\x03\x1c2\x01\x1c\x04\x1d\x00\x04\x04,\x15\x04\x04)\x08\x04\x04*\x0c\x04(\xb4\x00*\x04\x1f\x00\x04\x04,\x15\x04\x04+\x08\x04\x04+\x0c\x04\x08!\x01?\x04\x1f\x00\x03\x040\x11\x03\x04.\x15\x03+\x08\x00O\x04$\x00\x04\x043\x15\x04\x04/\x08\x04\x042\x0c\x04\x07\xc5\x00.\x04\x1c\x00\x03\x04/\x11\x03\x04-\x15\x03\x15/\x00\x1e\x04\x1f\x00\x04\x04+\x15\x04\x04+\x08\x04\x04+\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04{\x00\x1a\x04+\x11\x02\x04)\x15\x02\x05\xf8\x00\x10\x04&\x11\x02\x04#\x15\x02\x01\x8b\x00$\x04\x1c\x00\x03\x04.\x11\x03\x04+\x15\x03\"o\x00(\x04 \x00\x04\x040\x15\x04\x04,\x08\x04\x04)\x0c\x04&=\x01J\x04#\x00\x04\x041\x15\x04\x04/\x08\x04\x041\x0c\x04\x027\x01\x12\x03'\x02\x03\x03-\x11\x03\x03+\x0c\x03\x04\x88\x00&\x03+\x02\x03\x030\x11\x03\x03.\x0c\x03\n\x00\x00\x00\x03/\x02\x03\x035\x11\x03\x032\x0c\x03\x0bE\x01?\x03+\x02\x03\x03/\x11\x03\x03-\x0c\x03\x0cG\x00-\x03*\x02\x03\x03-\x11\x03\x03*\x0c\x03\x13?\x00 \x03(\x02\x03\x03(\x11\x03\x03&\x0c\x03\x18\xcb\x00\x0f\x03%\x02\x03\x03+\x11\x03\x03(\x0c\x03\x19\x04\x01 \x03*\x02\x03\x03.\x11\x03\x03,\x0c\x03\t\xb5\x00\x07\x03%\x02\x03\x03)\x11\x03\x03'\x0c\x03$\x1e\x01\x13\x03\"\x02\x03\x03*\x11\x03\x03&\x0c\x03\x87\xcb\xe8/" - with self.assertRaisesRegex(une.UNIParseError, "Invalid message mode 4 - must be 0, 1, 2 or 3"): + with self.assertRaisesRegex( + une.UNIParseError, "Invalid message mode 4 - must be 0, 1, 2 or 3" + ): msg = UNIReader.parse(data, msgmode=4) def testparsebadheader(self): - data = b'\xab\x44\xb5\x60\x4c\x08\xf6\x03\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2f' - with self.assertRaisesRegex(une.UNIParseError, "Invalid message header b'\\\\xab\\\\x44\\\\xb5' - should be b'\\\\xaa\\\\x44\\\\xb5'"): + data = b"\xab\x44\xb5\x60\x4c\x08\xf6\x03\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2f" + with self.assertRaisesRegex( + une.UNIParseError, + "Invalid message header b'\\\\xab\\\\x44\\\\xb5' - should be b'\\\\xaa\\\\x44\\\\xb5'", + ): msg = UNIReader.parse(data) def testparsebadlength(self): - data = b'\xaa\x44\xb5\x60\x4c\x08\xf6\x03\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2f' - with self.assertRaisesRegex(une.UNIParseError, "Invalid payload length 1014 - should be 758"): + data = b"\xaa\x44\xb5\x60\x4c\x08\xf6\x03\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2f" + with self.assertRaisesRegex( + une.UNIParseError, "Invalid payload length 1014 - should be 758" + ): msg = UNIReader.parse(data) def testparsebadcrc(self): - data = b'\xaa\x44\xb5\x60\x4c\x08\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2e' - with self.assertRaisesRegex(une.UNIParseError, "Message checksum b'\\\\x87\\\\xcb\\\\xe8\\\\x2e' invalid - should be b'\\\\x87\\\\xcb\\\\xe8\\\\x2f'"): + data = b"\xaa\x44\xb5\x60\x4c\x08\xf6\x02\x01\x01\xa7\x08\x18\x03\xe3\x15\x00\x00\x00\x00\x00\x12\x10\x00\x32\x00\x00\x00\x00\x2b\x02\x2e\x01\x33\x00\x2d\x00\x02\x00\x2a\x09\x02\x04\x30\x00\x11\x00\x25\x00\x03\x00\x2b\x0e\x03\x00\x27\x09\x03\x05\xe1\x00\x0e\x00\x2a\x00\x02\x00\x25\x09\x02\x06\x23\x00\x40\x00\x2f\x00\x03\x00\x34\x0e\x03\x00\x30\x09\x03\x09\x50\x00\x21\x00\x2a\x00\x03\x00\x2c\x0e\x03\x00\x28\x09\x03\x0b\x2c\x01\x38\x00\x2e\x00\x03\x00\x32\x0e\x03\x00\x2e\x09\x03\x0c\x15\x01\x25\x00\x2a\x00\x02\x00\x29\x09\x02\x11\x86\x00\x1f\x00\x2c\x00\x02\x00\x29\x09\x02\x13\x82\x00\x35\x00\x2e\x00\x02\x00\x2b\x09\x02\x14\xe8\x00\x2f\x00\x2e\x00\x02\x00\x2a\x09\x02\x19\x3c\x01\x0f\x00\x26\x00\x03\x00\x2d\x0e\x03\x00\x28\x09\x03\x1c\x00\x00\x00\x00\x25\x00\x02\x00\x1f\x09\x02\xc2\xaa\x00\x08\x05\x26\x00\x03\x05\x29\x0e\x03\x05\x25\x09\x03\xc3\x70\x00\x43\x05\x2d\x00\x03\x05\x31\x0e\x03\x05\x2f\x09\x03\xc4\x84\x00\x3d\x05\x2a\x00\x03\x05\x30\x0e\x03\x05\x2e\x09\x03\xc7\xa3\x00\x2b\x05\x24\x00\x03\x05\x2e\x0e\x03\x05\x2c\x09\x03\x27\x74\x00\x40\x01\x2b\x00\x02\x01\x31\x05\x02\x37\x3c\x01\x1e\x01\x2b\x00\x02\x01\x2e\x05\x02\x34\xf2\x00\x0a\x01\x27\x00\x02\x01\x27\x05\x02\x26\x23\x00\x1c\x01\x28\x00\x02\x01\x29\x05\x02\x3d\x5d\x00\x1d\x01\x2a\x00\x02\x01\x2d\x05\x02\x36\x16\x00\x3e\x01\x2f\x00\x02\x01\x32\x05\x02\x28\xb4\x00\x1b\x01\x2a\x00\x02\x01\x2d\x05\x02\x2e\x56\x01\x04\x01\x22\x00\x02\x01\x27\x05\x02\x0b\x5d\x00\x3d\x04\x21\x00\x03\x04\x34\x11\x03\x04\x32\x15\x03\x2a\x72\x00\x43\x04\x22\x00\x04\x04\x33\x15\x04\x04\x30\x08\x04\x04\x31\x0c\x04\x02\xe0\x00\x21\x04\x2d\x11\x02\x04\x29\x15\x02\x0a\xd6\x00\x34\x04\x1d\x00\x03\x04\x2e\x11\x03\x04\x2d\x15\x03\x1c\x32\x01\x1c\x04\x1d\x00\x04\x04\x2c\x15\x04\x04\x29\x08\x04\x04\x2a\x0c\x04\x28\xb4\x00\x2a\x04\x1f\x00\x04\x04\x2c\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x08\x21\x01\x3f\x04\x1f\x00\x03\x04\x30\x11\x03\x04\x2e\x15\x03\x2b\x08\x00\x4f\x04\x24\x00\x04\x04\x33\x15\x04\x04\x2f\x08\x04\x04\x32\x0c\x04\x07\xc5\x00\x2e\x04\x1c\x00\x03\x04\x2f\x11\x03\x04\x2d\x15\x03\x15\x2f\x00\x1e\x04\x1f\x00\x04\x04\x2b\x15\x04\x04\x2b\x08\x04\x04\x2b\x0c\x04\x17\xf3\x00\x04\x04\x18\x08\x02\x04\x1e\x0c\x02\x04\x7b\x00\x1a\x04\x2b\x11\x02\x04\x29\x15\x02\x05\xf8\x00\x10\x04\x26\x11\x02\x04\x23\x15\x02\x01\x8b\x00\x24\x04\x1c\x00\x03\x04\x2e\x11\x03\x04\x2b\x15\x03\x22\x6f\x00\x28\x04\x20\x00\x04\x04\x30\x15\x04\x04\x2c\x08\x04\x04\x29\x0c\x04\x26\x3d\x01\x4a\x04\x23\x00\x04\x04\x31\x15\x04\x04\x2f\x08\x04\x04\x31\x0c\x04\x02\x37\x01\x12\x03\x27\x02\x03\x03\x2d\x11\x03\x03\x2b\x0c\x03\x04\x88\x00\x26\x03\x2b\x02\x03\x03\x30\x11\x03\x03\x2e\x0c\x03\x0a\x00\x00\x00\x03\x2f\x02\x03\x03\x35\x11\x03\x03\x32\x0c\x03\x0b\x45\x01\x3f\x03\x2b\x02\x03\x03\x2f\x11\x03\x03\x2d\x0c\x03\x0c\x47\x00\x2d\x03\x2a\x02\x03\x03\x2d\x11\x03\x03\x2a\x0c\x03\x13\x3f\x00\x20\x03\x28\x02\x03\x03\x28\x11\x03\x03\x26\x0c\x03\x18\xcb\x00\x0f\x03\x25\x02\x03\x03\x2b\x11\x03\x03\x28\x0c\x03\x19\x04\x01\x20\x03\x2a\x02\x03\x03\x2e\x11\x03\x03\x2c\x0c\x03\x09\xb5\x00\x07\x03\x25\x02\x03\x03\x29\x11\x03\x03\x27\x0c\x03\x24\x1e\x01\x13\x03\x22\x02\x03\x03\x2a\x11\x03\x03\x26\x0c\x03\x87\xcb\xe8\x2e" + with self.assertRaisesRegex( + une.UNIParseError, + "Message checksum b'\\\\x87\\\\xcb\\\\xe8\\\\x2e' invalid - should be b'\\\\x87\\\\xcb\\\\xe8\\\\x2f'", + ): msg = UNIReader.parse(data) def teststreambadmsgmode(self): - with self.assertRaisesRegex(une.UNIStreamError, "Invalid stream mode 4 - must be 0, 1, 2 or 3"): + with self.assertRaisesRegex( + une.UNIStreamError, "Invalid stream mode 4 - must be 0, 1, 2 or 3" + ): with open(os.path.join(DIRNAME, "pygpsdata_um981.log"), "rb") as stream: - unr = UNIReader(stream,msgmode=4) + unr = UNIReader(stream, msgmode=4) - def testterminatedraise(self): # unexpected stream termination, raise error - with self.assertRaisesRegex(une.UNIStreamError, "Serial stream terminated unexpectedly. 848 bytes requested, 299 bytes returned."): - with open(os.path.join(DIRNAME, "pygpsdata_um981terminated.log"), "rb") as stream: + def testterminatedraise(self): # unexpected stream termination, raise error + with self.assertRaisesRegex( + une.UNIStreamError, + "Serial stream terminated unexpectedly. 848 bytes requested, 299 bytes returned.", + ): + with open( + os.path.join(DIRNAME, "pygpsdata_um981terminated.log"), "rb" + ) as stream: unr = UNIReader(stream, quitonerror=ERR_RAISE) for raw, parsed in unr: pass # print(parsed) - def testbadprotocol(self): # unexpected protocol header, raise error - with self.assertRaisesRegex(une.UNIParseError, "Unknown protocol header b'\\\\xaaC'"): + def testbadprotocol(self): # unexpected protocol header, raise error + with self.assertRaisesRegex( + une.UNIParseError, "Unknown protocol header b'\\\\xaaC'" + ): with open(os.path.join(DIRNAME, "pygpsdata_badhdr.log"), "rb") as stream: unr = UNIReader(stream, quitonerror=ERR_RAISE) for raw, parsed in unr: pass # print(parsed) - def testunihdr(self): # unexpected UNI header, ignore and continue + def testunihdr(self): # unexpected UNI header, ignore and continue with open(os.path.join(DIRNAME, "pygpsdata_badunihdr.log"), "rb") as stream: unr = UNIReader(stream, quitonerror=ERR_RAISE) count = 0 @@ -446,30 +484,43 @@ def testunihdr(self): # unexpected UNI header, ignore and continue count += 1 self.assertEqual(count, 27) - def testterminatedloghandler(self): # unexpected stream termination, log error and continue + def testterminatedloghandler( + self, + ): # unexpected stream termination, log error and continue def printerr(err): print(err) + with StringIO() as savederr: with contextlib.redirect_stdout(savederr): - with open(os.path.join(DIRNAME, "pygpsdata_um981terminated.log"), "rb") as stream: - unr = UNIReader(stream, quitonerror=ERR_LOG,errorhandler=printerr) + with open( + os.path.join(DIRNAME, "pygpsdata_um981terminated.log"), "rb" + ) as stream: + unr = UNIReader(stream, quitonerror=ERR_LOG, errorhandler=printerr) count = 0 for raw, parsed in unr: - count +=1 - self.assertEqual(count,37) - self.assertEqual(savederr.getvalue().strip(), "Serial stream terminated unexpectedly. 848 bytes requested, 299 bytes returned.") + count += 1 + self.assertEqual(count, 37) + self.assertEqual( + savederr.getvalue().strip(), + "Serial stream terminated unexpectedly. 848 bytes requested, 299 bytes returned.", + ) - def testterminatedlog(self): # unexpected stream termination, log error and continue + def testterminatedlog( + self, + ): # unexpected stream termination, log error and continue with StringIO() as savederr: with contextlib.redirect_stdout(savederr): - with open(os.path.join(DIRNAME, "pygpsdata_um981terminated.log"), "rb") as stream: + with open( + os.path.join(DIRNAME, "pygpsdata_um981terminated.log"), "rb" + ) as stream: unr = UNIReader(stream, quitonerror=ERR_LOG) count = 0 for raw, parsed in unr: - count +=1 - self.assertEqual(count,37) + count += 1 + self.assertEqual(count, 37) # self.assertEqual(savederr.getvalue().strip(), "Serial stream terminated unexpectedly. 848 bytes requested, 299 bytes returned.") + if __name__ == "__main__": # import sys;sys.argv = ['', 'Test.testName'] unittest.main()