From 8d6508a8539a953e4a286f1ce5fe4a6893b00008 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Fri, 31 Jul 2015 23:23:44 -0400 Subject: [PATCH 1/4] turn the first byte into an int, then pass to str() --- py34/bacpypes/pdu.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py34/bacpypes/pdu.py b/py34/bacpypes/pdu.py index 09f5d09..f09704e 100755 --- a/py34/bacpypes/pdu.py +++ b/py34/bacpypes/pdu.py @@ -265,7 +265,7 @@ class Address: elif self.addrType == Address.localStationAddr: rslt = '' if self.addrLen == 1: - rslt += str(self.addrAddr) + rslt += str(self.addrAddr[0]) else: port = struct.unpack('!H', self.addrAddr[-2:])[0] if (len(self.addrAddr) == 6) and (port >= 47808) and (port <= 47823): @@ -282,7 +282,7 @@ class Address: elif self.addrType == Address.remoteStationAddr: rslt = '%d:' % (self.addrNet,) if self.addrLen == 1: - rslt += str(self.addrAddr) + rslt += str(self.addrAddr[0]) else: port = struct.unpack('!H', self.addrAddr[-2:])[0] if (len(self.addrAddr) == 6) and (port >= 47808) and (port <= 47823): From 85a8ce955818c7bd9288b6da752f0357534d0dfe Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Sun, 2 Aug 2015 22:17:11 -0400 Subject: [PATCH 2/4] fixes #10 --- py25/bacpypes/consolelogging.py | 3 +-- py27/bacpypes/consolelogging.py | 3 +-- py34/bacpypes/consolelogging.py | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/py25/bacpypes/consolelogging.py b/py25/bacpypes/consolelogging.py index ead9041..4442961 100755 --- a/py25/bacpypes/consolelogging.py +++ b/py25/bacpypes/consolelogging.py @@ -115,8 +115,7 @@ class ArgumentParser(_ArgumentParser): # check to dump labels if result_args.buggers: - loggers = logging.Logger.manager.loggerDict.keys() - loggers.sort() + loggers = sorted(logging.Logger.manager.loggerDict.keys()) for loggerName in loggers: sys.stdout.write(loggerName + '\n') sys.exit(0) diff --git a/py27/bacpypes/consolelogging.py b/py27/bacpypes/consolelogging.py index e2b0bf6..9f022b6 100755 --- a/py27/bacpypes/consolelogging.py +++ b/py27/bacpypes/consolelogging.py @@ -106,8 +106,7 @@ class ArgumentParser(argparse.ArgumentParser): # check to dump labels if result_args.buggers: - loggers = logging.Logger.manager.loggerDict.keys() - loggers.sort() + loggers = sorted(logging.Logger.manager.loggerDict.keys()) for loggerName in loggers: sys.stdout.write(loggerName + '\n') sys.exit(0) diff --git a/py34/bacpypes/consolelogging.py b/py34/bacpypes/consolelogging.py index 89cc12c..8c8349f 100755 --- a/py34/bacpypes/consolelogging.py +++ b/py34/bacpypes/consolelogging.py @@ -106,8 +106,7 @@ class ArgumentParser(argparse.ArgumentParser): # check to dump labels if result_args.buggers: - loggers = logging.Logger.manager.loggerDict.keys() - loggers.sort() + loggers = sorted(logging.Logger.manager.loggerDict.keys()) for loggerName in loggers: sys.stdout.write(loggerName + '\n') sys.exit(0) From 9c8ec379387476c8c8c57aa01bfbcaec85c424d6 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Sun, 2 Aug 2015 23:12:58 -0400 Subject: [PATCH 3/4] change all the signed octet pack/unpack to unsigned --- py25/bacpypes/pdu.py | 26 +++++++++++++------------- py25/bacpypes/primitivedata.py | 2 +- py27/bacpypes/bvllservice.py | 2 +- py27/bacpypes/pdu.py | 10 +++++----- py27/bacpypes/primitivedata.py | 2 +- py34/bacpypes/bvllservice.py | 2 +- py34/bacpypes/pdu.py | 10 +++++----- py34/bacpypes/primitivedata.py | 2 +- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/py25/bacpypes/pdu.py b/py25/bacpypes/pdu.py index 954802c..6bcb179 100755 --- a/py25/bacpypes/pdu.py +++ b/py25/bacpypes/pdu.py @@ -83,7 +83,7 @@ class Address: if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif isinstance(addr, str): @@ -133,7 +133,7 @@ class Address: if (addr > 255): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif re.match(r"^\d+:[*]$", addr): @@ -161,7 +161,7 @@ class Address: self.addrType = Address.remoteStationAddr self.addrNet = net - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif re.match(r"^0x([0-9A-Fa-f][0-9A-Fa-f])+$",addr): @@ -337,17 +337,17 @@ class LocalStation(Address): if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 - elif isinstance(addr, (bytes, bytearray)): - if _debug: Address._debug(" - bytes or bytearray") + elif isinstance(addr, str): + if _debug: Address._debug(" - string (bytes)") - self.addrAddr = bytes(addr) + self.addrAddr = addr self.addrLen = len(addr) else: - raise TypeError("integer, bytes or bytearray required") + raise TypeError("integer or string (bytes) required") # # RemoteStation @@ -366,17 +366,17 @@ class RemoteStation(Address): if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 - elif isinstance(addr, (bytes, bytearray)): - if _debug: Address._debug(" - bytes or bytearray") + elif isinstance(addr, str): + if _debug: Address._debug(" - string (bytes)") - self.addrAddr = bytes(addr) + self.addrAddr = addr self.addrLen = len(addr) else: - raise TypeError("integer, bytes or bytearray required") + raise TypeError("integer or string (bytes) required") # # LocalBroadcast diff --git a/py25/bacpypes/primitivedata.py b/py25/bacpypes/primitivedata.py index 55afe72..83f4ebf 100755 --- a/py25/bacpypes/primitivedata.py +++ b/py25/bacpypes/primitivedata.py @@ -189,7 +189,7 @@ class Tag(object): # context booleans have value in data if (dataType == Tag.booleanAppTag): - return Tag(Tag.applicationTagClass, Tag.booleanAppTag, struct.unpack('b', self.tagData)[0], '') + return Tag(Tag.applicationTagClass, Tag.booleanAppTag, struct.unpack('B', self.tagData)[0], '') else: return ApplicationTag(dataType, self.tagData) diff --git a/py27/bacpypes/bvllservice.py b/py27/bacpypes/bvllservice.py index b81f4eb..ffbfb25 100755 --- a/py27/bacpypes/bvllservice.py +++ b/py27/bacpypes/bvllservice.py @@ -141,7 +141,7 @@ class UDPMultiplexer: return # extract the first octet - msg_type = struct.unpack('b', pdu.pduData[:1])[0] + msg_type = struct.unpack('B', pdu.pduData[:1])[0] # check for the message type if msg_type == 0x01: diff --git a/py27/bacpypes/pdu.py b/py27/bacpypes/pdu.py index 0e4f8fa..a275eec 100755 --- a/py27/bacpypes/pdu.py +++ b/py27/bacpypes/pdu.py @@ -84,7 +84,7 @@ class Address: if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif isinstance(addr, str): @@ -134,7 +134,7 @@ class Address: if (addr > 255): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif re.match(r"^\d+:[*]$", addr): @@ -162,7 +162,7 @@ class Address: self.addrType = Address.remoteStationAddr self.addrNet = net - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif re.match(r"^0x([0-9A-Fa-f][0-9A-Fa-f])+$",addr): @@ -336,7 +336,7 @@ class LocalStation(Address): if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif isinstance(addr, (bytes, bytearray)): @@ -365,7 +365,7 @@ class RemoteStation(Address): if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif isinstance(addr, (bytes, bytearray)): diff --git a/py27/bacpypes/primitivedata.py b/py27/bacpypes/primitivedata.py index 5a10246..c9464a6 100755 --- a/py27/bacpypes/primitivedata.py +++ b/py27/bacpypes/primitivedata.py @@ -189,7 +189,7 @@ class Tag(object): # context booleans have value in data if (dataType == Tag.booleanAppTag): - return Tag(Tag.applicationTagClass, Tag.booleanAppTag, struct.unpack('b', self.tagData)[0], b'') + return Tag(Tag.applicationTagClass, Tag.booleanAppTag, struct.unpack('B', self.tagData)[0], b'') else: return ApplicationTag(dataType, self.tagData) diff --git a/py34/bacpypes/bvllservice.py b/py34/bacpypes/bvllservice.py index b81f4eb..ffbfb25 100755 --- a/py34/bacpypes/bvllservice.py +++ b/py34/bacpypes/bvllservice.py @@ -141,7 +141,7 @@ class UDPMultiplexer: return # extract the first octet - msg_type = struct.unpack('b', pdu.pduData[:1])[0] + msg_type = struct.unpack('B', pdu.pduData[:1])[0] # check for the message type if msg_type == 0x01: diff --git a/py34/bacpypes/pdu.py b/py34/bacpypes/pdu.py index 09f5d09..9089e36 100755 --- a/py34/bacpypes/pdu.py +++ b/py34/bacpypes/pdu.py @@ -84,7 +84,7 @@ class Address: if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif isinstance(addr, (bytes, bytearray)): @@ -150,7 +150,7 @@ class Address: if (addr > 255): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif re.match(r"^\d+:[*]$", addr): @@ -178,7 +178,7 @@ class Address: self.addrType = Address.remoteStationAddr self.addrNet = net - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif re.match(r"^0x([0-9A-Fa-f][0-9A-Fa-f])+$",addr): @@ -351,7 +351,7 @@ class LocalStation(Address): if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif isinstance(addr, (bytes, bytearray)): @@ -380,7 +380,7 @@ class RemoteStation(Address): if (addr < 0) or (addr >= 256): raise ValueError("address out of range") - self.addrAddr = struct.pack('b', addr) + self.addrAddr = struct.pack('B', addr) self.addrLen = 1 elif isinstance(addr, (bytes, bytearray)): diff --git a/py34/bacpypes/primitivedata.py b/py34/bacpypes/primitivedata.py index 6539e3a..7425a49 100755 --- a/py34/bacpypes/primitivedata.py +++ b/py34/bacpypes/primitivedata.py @@ -189,7 +189,7 @@ class Tag(object): # context booleans have value in data if (dataType == Tag.booleanAppTag): - return Tag(Tag.applicationTagClass, Tag.booleanAppTag, struct.unpack('b', self.tagData)[0], b'') + return Tag(Tag.applicationTagClass, Tag.booleanAppTag, struct.unpack('B', self.tagData)[0], b'') else: return ApplicationTag(dataType, self.tagData) From 2c0280c6c442d1f5f0cf8144499ad4b4bb548ffb Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Mon, 3 Aug 2015 00:56:20 -0400 Subject: [PATCH 4/4] add some address testing --- tests/test_pdu/__init__.py | 7 +++ tests/test_pdu/test_address.py | 95 ++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 tests/test_pdu/__init__.py create mode 100644 tests/test_pdu/test_address.py diff --git a/tests/test_pdu/__init__.py b/tests/test_pdu/__init__.py new file mode 100644 index 0000000..65a2c45 --- /dev/null +++ b/tests/test_pdu/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/python + +""" +Test BACpypes PDU Module +""" + +from . import test_address diff --git a/tests/test_pdu/test_address.py b/tests/test_pdu/test_address.py new file mode 100644 index 0000000..4c40d5d --- /dev/null +++ b/tests/test_pdu/test_address.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Nose Test PDU Address +--------------------- +""" + +import unittest + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger, btox, xtob +from bacpypes.pdu import Address, LocalStation, RemoteStation, \ + LocalBroadcast, RemoteBroadcast, GlobalBroadcast + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + + +class TestAddress(unittest.TestCase): + + def assertMatch(self, addr, t, n, l, a): + assert addr.addrType == t + assert addr.addrNet == n + assert addr.addrLen == l + assert addr.addrAddr == (a and xtob(a)) + + def test_address(self): + if _debug: TestAddress._debug("test_address") + + def test_local_station(self): + if _debug: TestAddress._debug("test_local_station") + + # one parameter + with self.assertRaises(TypeError): + LocalStation() + + # test integer + test_addr = LocalStation(1) + self.assertMatch(test_addr, 2, None, 1, '01') + assert str(test_addr) == "1" + + test_addr = LocalStation(254) + self.assertMatch(test_addr, 2, None, 1, 'fe') + assert str(test_addr) == "254" + + # test bad integer + with self.assertRaises(ValueError): + LocalStation(-1) + LocalStation(256) + + # test bytes + test_addr = LocalStation(xtob('01')) + self.assertMatch(test_addr, 2, None, 1, '01') + assert str(test_addr) == "1" + + test_addr = LocalStation(xtob('fe')) + self.assertMatch(test_addr, 2, None, 1, 'fe') + assert str(test_addr) == "254" + + # multi-byte strings are hex encoded + test_addr = LocalStation(xtob('0102')) + self.assertMatch(test_addr, 2, None, 2, '0102') + assert str(test_addr) == "0x0102" + + test_addr = LocalStation(xtob('010203')) + self.assertMatch(test_addr, 2, None, 3, '010203') + assert str(test_addr) == "0x010203" + + # match with an IPv4 address + test_addr = LocalStation(xtob('01020304bac0')) + self.assertMatch(test_addr, 2, None, 6, '01020304bac0') + assert str(test_addr) == "1.2.3.4" + + def test_remote_station(self): + if _debug: TestAddress._debug("test_remote_station") + + def test_local_broadcast(self): + if _debug: TestAddress._debug("test_local_broadcast") + + test_addr = LocalBroadcast() + self.assertMatch(test_addr, 1, None, None, None) + assert str(test_addr) == "*" + + def test_remote_broadcast(self): + if _debug: TestAddress._debug("test_remote_broadcast") + + def test_global_broadcast(self): + if _debug: TestAddress._debug("test_global_broadcast") + + test_addr = GlobalBroadcast() + self.assertMatch(test_addr, 5, None, None, None) + assert str(test_addr) == "*:*" + +bacpypes_debugging(TestAddress)