mirror of
https://github.com/JoelBender/bacpypes
synced 2025-09-28 22:15:23 +08:00
merge #181 with additional tests
This commit is contained in:
parent
68bcfc869d
commit
3ee0cbd0dd
|
@ -546,19 +546,31 @@ class BIPForeign(BIPSAP, Client, Server, OneShotTask, DebugContents):
|
|||
|
||||
return
|
||||
|
||||
elif isinstance(pdu, OriginalUnicastNPDU):
|
||||
# check the BBMD registration status, we may not be registered
|
||||
if self.registrationStatus != 0:
|
||||
if _debug: BIPForeign._debug(" - packet dropped, unregistered")
|
||||
return
|
||||
|
||||
if isinstance(pdu, OriginalUnicastNPDU):
|
||||
# build a vanilla PDU
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
# check the BBMD registration status, we may not be registered
|
||||
if self.registrationStatus != 0:
|
||||
if _debug: BIPForeign._debug(" - packet dropped, unregistered")
|
||||
return
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# make sure the forwarded PDU from the bbmd
|
||||
if pdu.pduSource != self.bbmdAddress:
|
||||
if _debug: BIPForeign._debug(" - packet dropped, not from the BBMD")
|
||||
return
|
||||
|
||||
if isinstance(pdu, ReadBroadcastDistributionTableAck):
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, ReadBroadcastDistributionTableAck):
|
||||
# send this to the service access point
|
||||
self.sap_response(pdu)
|
||||
|
||||
|
@ -566,13 +578,6 @@ class BIPForeign(BIPSAP, Client, Server, OneShotTask, DebugContents):
|
|||
# send this to the service access point
|
||||
self.sap_response(pdu)
|
||||
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, WriteBroadcastDistributionTable):
|
||||
# build a response
|
||||
xpdu = Result(code=0x0010, user_data=pdu.pduUserData)
|
||||
|
@ -696,7 +701,7 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
# make an original unicast PDU
|
||||
xpdu = OriginalUnicastNPDU(pdu, user_data=pdu.pduUserData)
|
||||
xpdu.pduDestination = pdu.pduDestination
|
||||
if _debug: BIPBBMD._debug(" - xpdu: %r", xpdu)
|
||||
if _debug: BIPBBMD._debug(" - original unicast xpdu: %r", xpdu)
|
||||
|
||||
# send it downstream
|
||||
self.request(xpdu)
|
||||
|
@ -719,13 +724,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte != self.bbmdAddress:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
else:
|
||||
|
@ -741,8 +746,9 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
|
||||
elif isinstance(pdu, WriteBroadcastDistributionTable):
|
||||
# build a response
|
||||
xpdu = Result(code=99, user_data=pdu.pduUserData)
|
||||
xpdu = Result(code=0x0010, user_data=pdu.pduUserData)
|
||||
xpdu.pduDestination = pdu.pduSource
|
||||
if _debug: BIPBBMD._debug(" - xpdu: %r", xpdu)
|
||||
|
||||
# send it downstream
|
||||
self.request(xpdu)
|
||||
|
@ -761,27 +767,38 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
self.sap_response(pdu)
|
||||
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# build a forwarded NPDU to send out
|
||||
xpdu = ForwardedNPDU(pdu.bvlciAddress, pdu, destination=None, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - forwarded xpdu: %r", xpdu)
|
||||
|
||||
# look for self as first entry in the BDT
|
||||
if self.bbmdBDT and (self.bbmdBDT[0] == self.bbmdAddress):
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
# if this was unicast to us, do next hop
|
||||
if pdu.pduDestination.addrType == Address.localStationAddr:
|
||||
if _debug: BIPBBMD._debug(" - unicast message")
|
||||
|
||||
# if this BBMD is listed in its BDT, send a local broadcast
|
||||
if self.bbmdAddress in self.bbmdBDT:
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
|
||||
elif pdu.pduDestination.addrType == Address.localBroadcastAddr:
|
||||
if _debug: BIPBBMD._debug(" - directed broadcast message")
|
||||
|
||||
else:
|
||||
BIPBBMD._warning("invalid destination address: %r", pdu.pduDestination)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, RegisterForeignDevice):
|
||||
|
@ -820,12 +837,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, DistributeBroadcastToNetwork):
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# build a forwarded NPDU to send out
|
||||
xpdu = ForwardedNPDU(pdu.pduSource, pdu, user_data=pdu.pduUserData)
|
||||
|
@ -835,35 +853,37 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte == self.bbmdAddress:
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
else:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the other registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
if fdte.fdAddress != pdu.pduSource:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, OriginalUnicastNPDU):
|
||||
# build a vanilla PDU
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, OriginalBroadcastNPDU):
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# make a forwarded PDU
|
||||
xpdu = ForwardedNPDU(pdu.pduSource, pdu, user_data=pdu.pduUserData)
|
||||
|
@ -873,13 +893,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte != self.bbmdAddress:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
else:
|
||||
|
@ -929,7 +949,7 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
del self.bbmdFDT[i]
|
||||
break
|
||||
else:
|
||||
stat = 99 ### entry not found
|
||||
stat = 0x0050 ### entry not found
|
||||
|
||||
# return status
|
||||
return stat
|
||||
|
@ -956,10 +976,6 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
else:
|
||||
raise TypeError("addr must be a string or an Address")
|
||||
|
||||
# if it's this BBMD, make it the first one
|
||||
if self.bbmdBDT and (addr == self.bbmdAddress):
|
||||
raise RuntimeError("add self to BDT as first address")
|
||||
|
||||
# see if it's already there
|
||||
for bdte in self.bbmdBDT:
|
||||
if addr == bdte:
|
||||
|
|
|
@ -161,9 +161,9 @@ class IPNetwork(Network):
|
|||
('1.2.3.255', 5) and the other nodes must have the same tuple.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, name=''):
|
||||
if _debug: IPNetwork._debug("__init__")
|
||||
Network.__init__(self)
|
||||
Network.__init__(self, name=name)
|
||||
|
||||
def add_node(self, node):
|
||||
if _debug: IPNetwork._debug("add_node %r", node)
|
||||
|
@ -213,7 +213,7 @@ bacpypes_debugging(IPNode)
|
|||
|
||||
class IPRouterNode(Client):
|
||||
|
||||
def __init__(self, router, addr, lan=None):
|
||||
def __init__(self, router, addr, lan):
|
||||
if _debug: IPRouterNode._debug("__init__ %r %r lan=%r", router, addr, lan)
|
||||
|
||||
# save the reference to the router
|
||||
|
@ -238,6 +238,9 @@ class IPRouterNode(Client):
|
|||
# pass it downstream
|
||||
self.request(pdu)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s for %s>" % (self.__class__.__name__, self.lan.name)
|
||||
|
||||
bacpypes_debugging(IPRouterNode)
|
||||
|
||||
#
|
||||
|
|
|
@ -542,20 +542,31 @@ class BIPForeign(BIPSAP, Client, Server, OneShotTask, DebugContents):
|
|||
|
||||
return
|
||||
|
||||
elif isinstance(pdu, OriginalUnicastNPDU):
|
||||
# build a vanilla PDU
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
return
|
||||
|
||||
# check the BBMD registration status, we may not be registered
|
||||
if self.registrationStatus != 0:
|
||||
if _debug: BIPForeign._debug(" - packet dropped, unregistered")
|
||||
return
|
||||
|
||||
if isinstance(pdu, ReadBroadcastDistributionTableAck):
|
||||
if isinstance(pdu, OriginalUnicastNPDU):
|
||||
# build a vanilla PDU
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# make sure the forwarded PDU from the bbmd
|
||||
if pdu.pduSource != self.bbmdAddress:
|
||||
if _debug: BIPForeign._debug(" - packet dropped, not from the BBMD")
|
||||
return
|
||||
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, ReadBroadcastDistributionTableAck):
|
||||
# send this to the service access point
|
||||
self.sap_response(pdu)
|
||||
|
||||
|
@ -563,13 +574,6 @@ class BIPForeign(BIPSAP, Client, Server, OneShotTask, DebugContents):
|
|||
# send this to the service access point
|
||||
self.sap_response(pdu)
|
||||
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, WriteBroadcastDistributionTable):
|
||||
# build a response
|
||||
xpdu = Result(code=0x0010, user_data=pdu.pduUserData)
|
||||
|
@ -692,7 +696,7 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
# make an original unicast PDU
|
||||
xpdu = OriginalUnicastNPDU(pdu, user_data=pdu.pduUserData)
|
||||
xpdu.pduDestination = pdu.pduDestination
|
||||
if _debug: BIPBBMD._debug(" - xpdu: %r", xpdu)
|
||||
if _debug: BIPBBMD._debug(" - original unicast xpdu: %r", xpdu)
|
||||
|
||||
# send it downstream
|
||||
self.request(xpdu)
|
||||
|
@ -715,13 +719,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte != self.bbmdAddress:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
else:
|
||||
|
@ -737,8 +741,9 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
|
||||
elif isinstance(pdu, WriteBroadcastDistributionTable):
|
||||
# build a response
|
||||
xpdu = Result(code=99, user_data=pdu.pduUserData)
|
||||
xpdu = Result(code=0x0010, user_data=pdu.pduUserData)
|
||||
xpdu.pduDestination = pdu.pduSource
|
||||
if _debug: BIPBBMD._debug(" - xpdu: %r", xpdu)
|
||||
|
||||
# send it downstream
|
||||
self.request(xpdu)
|
||||
|
@ -757,27 +762,38 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
self.sap_response(pdu)
|
||||
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# build a forwarded NPDU to send out
|
||||
xpdu = ForwardedNPDU(pdu.bvlciAddress, pdu, destination=None, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - forwarded xpdu: %r", xpdu)
|
||||
|
||||
# look for self as first entry in the BDT
|
||||
if self.bbmdBDT and (self.bbmdBDT[0] == self.bbmdAddress):
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
# if this was unicast to us, do next hop
|
||||
if pdu.pduDestination.addrType == Address.localStationAddr:
|
||||
if _debug: BIPBBMD._debug(" - unicast message")
|
||||
|
||||
# if this BBMD is listed in its BDT, send a local broadcast
|
||||
if self.bbmdAddress in self.bbmdBDT:
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
|
||||
elif pdu.pduDestination.addrType == Address.localBroadcastAddr:
|
||||
if _debug: BIPBBMD._debug(" - directed broadcast message")
|
||||
|
||||
else:
|
||||
BIPBBMD._warning("invalid destination address: %r", pdu.pduDestination)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, RegisterForeignDevice):
|
||||
|
@ -816,12 +832,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, DistributeBroadcastToNetwork):
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# build a forwarded NPDU to send out
|
||||
xpdu = ForwardedNPDU(pdu.pduSource, pdu, user_data=pdu.pduUserData)
|
||||
|
@ -831,35 +848,37 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte == self.bbmdAddress:
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
else:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the other registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
if fdte.fdAddress != pdu.pduSource:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, OriginalUnicastNPDU):
|
||||
# build a vanilla PDU
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, OriginalBroadcastNPDU):
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# make a forwarded PDU
|
||||
xpdu = ForwardedNPDU(pdu.pduSource, pdu, user_data=pdu.pduUserData)
|
||||
|
@ -869,13 +888,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte != self.bbmdAddress:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
else:
|
||||
|
@ -925,7 +944,7 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
del self.bbmdFDT[i]
|
||||
break
|
||||
else:
|
||||
stat = 99 ### entry not found
|
||||
stat = 0x0050 ### entry not found
|
||||
|
||||
# return status
|
||||
return stat
|
||||
|
@ -952,10 +971,6 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
else:
|
||||
raise TypeError("addr must be a string or an Address")
|
||||
|
||||
# if it's this BBMD, make it the first one
|
||||
if self.bbmdBDT and (addr == self.bbmdAddress):
|
||||
raise RuntimeError("add self to BDT as first address")
|
||||
|
||||
# see if it's already there
|
||||
for bdte in self.bbmdBDT:
|
||||
if addr == bdte:
|
||||
|
|
|
@ -161,9 +161,9 @@ class IPNetwork(Network):
|
|||
('1.2.3.255', 5) and the other nodes must have the same tuple.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, name=''):
|
||||
if _debug: IPNetwork._debug("__init__")
|
||||
Network.__init__(self)
|
||||
Network.__init__(self, name=name)
|
||||
|
||||
def add_node(self, node):
|
||||
if _debug: IPNetwork._debug("add_node %r", node)
|
||||
|
@ -213,7 +213,7 @@ class IPNode(Node):
|
|||
@bacpypes_debugging
|
||||
class IPRouterNode(Client):
|
||||
|
||||
def __init__(self, router, addr, lan=None):
|
||||
def __init__(self, router, addr, lan):
|
||||
if _debug: IPRouterNode._debug("__init__ %r %r lan=%r", router, addr, lan)
|
||||
|
||||
# save the reference to the router
|
||||
|
@ -238,6 +238,9 @@ class IPRouterNode(Client):
|
|||
# pass it downstream
|
||||
self.request(pdu)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s for %s>" % (self.__class__.__name__, self.lan.name)
|
||||
|
||||
#
|
||||
# IPRouter
|
||||
#
|
||||
|
|
|
@ -541,19 +541,31 @@ class BIPForeign(BIPSAP, Client, Server, OneShotTask, DebugContents):
|
|||
|
||||
return
|
||||
|
||||
elif isinstance(pdu, OriginalUnicastNPDU):
|
||||
# check the BBMD registration status, we may not be registered
|
||||
if self.registrationStatus != 0:
|
||||
if _debug: BIPForeign._debug(" - packet dropped, unregistered")
|
||||
return
|
||||
|
||||
if isinstance(pdu, OriginalUnicastNPDU):
|
||||
# build a vanilla PDU
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
# check the BBMD registration status, we may not be registered
|
||||
if self.registrationStatus != 0:
|
||||
if _debug: BIPForeign._debug(" - packet dropped, unregistered")
|
||||
return
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# make sure the forwarded PDU from the bbmd
|
||||
if pdu.pduSource != self.bbmdAddress:
|
||||
if _debug: BIPForeign._debug(" - packet dropped, not from the BBMD")
|
||||
return
|
||||
|
||||
if isinstance(pdu, ReadBroadcastDistributionTableAck):
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, ReadBroadcastDistributionTableAck):
|
||||
# send this to the service access point
|
||||
self.sap_response(pdu)
|
||||
|
||||
|
@ -561,13 +573,6 @@ class BIPForeign(BIPSAP, Client, Server, OneShotTask, DebugContents):
|
|||
# send this to the service access point
|
||||
self.sap_response(pdu)
|
||||
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, WriteBroadcastDistributionTable):
|
||||
# build a response
|
||||
xpdu = Result(code=0x0010, user_data=pdu.pduUserData)
|
||||
|
@ -690,7 +695,7 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
# make an original unicast PDU
|
||||
xpdu = OriginalUnicastNPDU(pdu, user_data=pdu.pduUserData)
|
||||
xpdu.pduDestination = pdu.pduDestination
|
||||
if _debug: BIPBBMD._debug(" - xpdu: %r", xpdu)
|
||||
if _debug: BIPBBMD._debug(" - original unicast xpdu: %r", xpdu)
|
||||
|
||||
# send it downstream
|
||||
self.request(xpdu)
|
||||
|
@ -713,13 +718,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte != self.bbmdAddress:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
else:
|
||||
|
@ -735,8 +740,9 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
|
||||
elif isinstance(pdu, WriteBroadcastDistributionTable):
|
||||
# build a response
|
||||
xpdu = Result(code=99, user_data=pdu.pduUserData)
|
||||
xpdu = Result(code=0x0010, user_data=pdu.pduUserData)
|
||||
xpdu.pduDestination = pdu.pduSource
|
||||
if _debug: BIPBBMD._debug(" - xpdu: %r", xpdu)
|
||||
|
||||
# send it downstream
|
||||
self.request(xpdu)
|
||||
|
@ -755,27 +761,38 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
self.sap_response(pdu)
|
||||
|
||||
elif isinstance(pdu, ForwardedNPDU):
|
||||
# build a PDU with the source from the real source
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.bvlciAddress, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# build a forwarded NPDU to send out
|
||||
xpdu = ForwardedNPDU(pdu.bvlciAddress, pdu, destination=None, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - forwarded xpdu: %r", xpdu)
|
||||
|
||||
# look for self as first entry in the BDT
|
||||
if self.bbmdBDT and (self.bbmdBDT[0] == self.bbmdAddress):
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
# if this was unicast to us, do next hop
|
||||
if pdu.pduDestination.addrType == Address.localStationAddr:
|
||||
if _debug: BIPBBMD._debug(" - unicast message")
|
||||
|
||||
# if this BBMD is listed in its BDT, send a local broadcast
|
||||
if self.bbmdAddress in self.bbmdBDT:
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
|
||||
elif pdu.pduDestination.addrType == Address.localBroadcastAddr:
|
||||
if _debug: BIPBBMD._debug(" - directed broadcast message")
|
||||
|
||||
else:
|
||||
BIPBBMD._warning("invalid destination address: %r", pdu.pduDestination)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, RegisterForeignDevice):
|
||||
|
@ -814,12 +831,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, DistributeBroadcastToNetwork):
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# build a forwarded NPDU to send out
|
||||
xpdu = ForwardedNPDU(pdu.pduSource, pdu, user_data=pdu.pduUserData)
|
||||
|
@ -829,35 +847,37 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte == self.bbmdAddress:
|
||||
xpdu.pduDestination = LocalBroadcast()
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
if _debug: BIPBBMD._debug(" - local broadcast")
|
||||
self.request(xpdu)
|
||||
else:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the other registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
if fdte.fdAddress != pdu.pduSource:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
elif isinstance(pdu, OriginalUnicastNPDU):
|
||||
# build a vanilla PDU
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=pdu.pduDestination, user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
elif isinstance(pdu, OriginalBroadcastNPDU):
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
# send it upstream if there is a network layer
|
||||
if self.serverPeer:
|
||||
# build a PDU with a local broadcast address
|
||||
xpdu = PDU(pdu.pduData, source=pdu.pduSource, destination=LocalBroadcast(), user_data=pdu.pduUserData)
|
||||
if _debug: BIPBBMD._debug(" - upstream xpdu: %r", xpdu)
|
||||
|
||||
# send it upstream
|
||||
self.response(xpdu)
|
||||
self.response(xpdu)
|
||||
|
||||
# make a forwarded PDU
|
||||
xpdu = ForwardedNPDU(pdu.pduSource, pdu, user_data=pdu.pduUserData)
|
||||
|
@ -867,13 +887,13 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
for bdte in self.bbmdBDT:
|
||||
if bdte != self.bbmdAddress:
|
||||
xpdu.pduDestination = Address( ((bdte.addrIP|~bdte.addrMask), bdte.addrPort) )
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to peer: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
# send it to the registered foreign devices
|
||||
for fdte in self.bbmdFDT:
|
||||
xpdu.pduDestination = fdte.fdAddress
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
if _debug: BIPBBMD._debug(" - sending to foreign device: %r", xpdu.pduDestination)
|
||||
self.request(xpdu)
|
||||
|
||||
else:
|
||||
|
@ -923,7 +943,7 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
del self.bbmdFDT[i]
|
||||
break
|
||||
else:
|
||||
stat = 99 ### entry not found
|
||||
stat = 0x0050 ### entry not found
|
||||
|
||||
# return status
|
||||
return stat
|
||||
|
@ -950,10 +970,6 @@ class BIPBBMD(BIPSAP, Client, Server, RecurringTask, DebugContents):
|
|||
else:
|
||||
raise TypeError("addr must be a string or an Address")
|
||||
|
||||
# if it's this BBMD, make it the first one
|
||||
if self.bbmdBDT and (addr == self.bbmdAddress):
|
||||
raise RuntimeError("add self to BDT as first address")
|
||||
|
||||
# see if it's already there
|
||||
for bdte in self.bbmdBDT:
|
||||
if addr == bdte:
|
||||
|
|
|
@ -161,9 +161,9 @@ class IPNetwork(Network):
|
|||
('1.2.3.255', 5) and the other nodes must have the same tuple.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, name=''):
|
||||
if _debug: IPNetwork._debug("__init__")
|
||||
Network.__init__(self)
|
||||
Network.__init__(self, name=name)
|
||||
|
||||
def add_node(self, node):
|
||||
if _debug: IPNetwork._debug("add_node %r", node)
|
||||
|
@ -213,7 +213,7 @@ class IPNode(Node):
|
|||
@bacpypes_debugging
|
||||
class IPRouterNode(Client):
|
||||
|
||||
def __init__(self, router, addr, lan=None):
|
||||
def __init__(self, router, addr, lan):
|
||||
if _debug: IPRouterNode._debug("__init__ %r %r lan=%r", router, addr, lan)
|
||||
|
||||
# save the reference to the router
|
||||
|
@ -238,6 +238,9 @@ class IPRouterNode(Client):
|
|||
# pass it downstream
|
||||
self.request(pdu)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s for %s>" % (self.__class__.__name__, self.lan.name)
|
||||
|
||||
#
|
||||
# IPRouter
|
||||
#
|
||||
|
|
139
samples/NATRouter.py
Normal file
139
samples/NATRouter.py
Normal file
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
This sample application presents itself as a router between an "inside" network
|
||||
that sits behind a NAT and a "global" network of other NAT router peers.
|
||||
|
||||
$ python NATRouter.py addr1 port1 net1 addr2 port2 net2
|
||||
|
||||
addr1 - local address like 192.168.1.10/24
|
||||
port1 - local port
|
||||
net1 - local network number
|
||||
addr2 - global address like 201.1.1.1:47809
|
||||
port2 - local mapped port
|
||||
net2 - global network number
|
||||
|
||||
The sample addresses are like running BR1 from Figure J-8, Clause J.7.5.
|
||||
"""
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger
|
||||
from bacpypes.consolelogging import ArgumentParser
|
||||
|
||||
from bacpypes.core import run
|
||||
from bacpypes.comm import bind
|
||||
|
||||
from bacpypes.pdu import Address
|
||||
from bacpypes.netservice import NetworkServiceAccessPoint, NetworkServiceElement
|
||||
from bacpypes.bvllservice import BIPBBMD, BIPNAT, AnnexJCodec, UDPMultiplexer
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
#
|
||||
# NATRouter
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class NATRouter:
|
||||
|
||||
def __init__(self, addr1, port1, net1, addr2, port2, net2):
|
||||
if _debug: NATRouter._debug("__init__ %r %r %r %r %r %r", addr1, port1, net1, addr2, port2, net2)
|
||||
|
||||
# a network service access point will be needed
|
||||
self.nsap = NetworkServiceAccessPoint()
|
||||
|
||||
# give the NSAP a generic network layer service element
|
||||
self.nse = NetworkServiceElement()
|
||||
bind(self.nse, self.nsap)
|
||||
|
||||
#== First stack
|
||||
|
||||
# local address
|
||||
local_addr = Address("{}:{}".format(addr1, port1))
|
||||
|
||||
# create a BBMD stack
|
||||
self.s1_bip = BIPBBMD(local_addr)
|
||||
self.s1_annexj = AnnexJCodec()
|
||||
self.s1_mux = UDPMultiplexer(local_addr)
|
||||
|
||||
# bind the bottom layers
|
||||
bind(self.s1_bip, self.s1_annexj, self.s1_mux.annexJ)
|
||||
|
||||
# bind the BIP stack to the local network
|
||||
self.nsap.bind(self.s1_bip, net1, addr1)
|
||||
|
||||
#== Second stack
|
||||
|
||||
# global address
|
||||
global_addr = Address(addr2)
|
||||
nat_addr = Address("{}:{}".format(addr1, port2))
|
||||
|
||||
# create a NAT stack
|
||||
self.s2_bip = BIPNAT(global_addr)
|
||||
self.s2_annexj = AnnexJCodec()
|
||||
self.s2_mux = UDPMultiplexer(nat_addr)
|
||||
|
||||
# bind the bottom layers
|
||||
bind(self.s2_bip, self.s2_annexj, self.s2_mux.annexJ)
|
||||
|
||||
# bind the BIP stack to the global network
|
||||
self.nsap.bind(self.s2_bip, net2)
|
||||
|
||||
#
|
||||
# __main__
|
||||
#
|
||||
|
||||
def main():
|
||||
# parse the command line arguments
|
||||
parser = ArgumentParser(description=__doc__)
|
||||
|
||||
# add an argument for local address
|
||||
parser.add_argument('addr1', type=str,
|
||||
help='address of first network',
|
||||
)
|
||||
|
||||
# add an argument for local port
|
||||
parser.add_argument('port1', type=int,
|
||||
help='port number of local network',
|
||||
)
|
||||
|
||||
# add an argument for interval
|
||||
parser.add_argument('net1', type=int,
|
||||
help='network number of local network',
|
||||
)
|
||||
|
||||
# add an argument for interval
|
||||
parser.add_argument('addr2', type=str,
|
||||
help='address of global network (outside NAT)',
|
||||
)
|
||||
|
||||
# add an argument for local port
|
||||
parser.add_argument('port2', type=int,
|
||||
help='port number of global forwarded port',
|
||||
)
|
||||
|
||||
# add an argument for interval
|
||||
parser.add_argument('net2', type=int,
|
||||
help='network number of global network',
|
||||
)
|
||||
|
||||
# now parse the arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
if _debug: _log.debug("initialization")
|
||||
if _debug: _log.debug(" - args: %r", args)
|
||||
|
||||
# create the router
|
||||
router = NATRouter(args.addr1, args.port1, args.net1, args.addr2, args.port2, args.net2)
|
||||
if _debug: _log.debug(" - router: %r", router)
|
||||
|
||||
_log.debug("running")
|
||||
|
||||
run()
|
||||
|
||||
_log.debug("fini")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -6,10 +6,19 @@ B/IP VLAN Helper Classes
|
|||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger
|
||||
|
||||
from bacpypes.comm import Client, Server, bind
|
||||
from bacpypes.comm import Client, Server, ApplicationServiceElement, bind
|
||||
from bacpypes.pdu import Address, LocalBroadcast, PDU, unpack_ip_addr
|
||||
from bacpypes.vlan import IPNode
|
||||
|
||||
from bacpypes.app import DeviceInfoCache, Application
|
||||
from bacpypes.appservice import StateMachineAccessPoint, ApplicationServiceAccessPoint
|
||||
from bacpypes.netservice import NetworkServiceAccessPoint, NetworkServiceElement
|
||||
|
||||
from bacpypes.object import register_object_type
|
||||
from bacpypes.local.device import LocalDeviceObject
|
||||
from bacpypes.service.device import WhoIsIAmServices
|
||||
from bacpypes.service.object import ReadWritePropertyServices
|
||||
|
||||
from ..state_machine import ClientStateMachine
|
||||
|
||||
from bacpypes.bvllservice import BIPSimple, BIPForeign, BIPBBMD, AnnexJCodec
|
||||
|
@ -26,6 +35,12 @@ _log = ModuleLogger(globals())
|
|||
@bacpypes_debugging
|
||||
class FauxMultiplexer(Client, Server):
|
||||
|
||||
"""This class is a placeholder for UDPMultiplexer without the code that
|
||||
determines if the upstream packets are Annex-H or Annex-J packets, it
|
||||
assumes they are all Annex-J. It creates and binds itself to an IPNode
|
||||
which is added to an IPNetwork.
|
||||
"""
|
||||
|
||||
def __init__(self, addr, network=None, cid=None, sid=None):
|
||||
if _debug: FauxMultiplexer._debug("__init__")
|
||||
|
||||
|
@ -81,37 +96,54 @@ class FauxMultiplexer(Client, Server):
|
|||
self.response(PDU(pdu, source=src, destination=dest))
|
||||
|
||||
#
|
||||
# SnifferNode
|
||||
# SnifferStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class SnifferNode(ClientStateMachine):
|
||||
class SnifferStateMachine(ClientStateMachine):
|
||||
|
||||
"""This class acts as a sniffer for BVLL messages. The client state
|
||||
machine sits above an Annex-J codec so the send and receive PDUs are
|
||||
BVLL PDUs.
|
||||
"""
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: SnifferNode._debug("__init__ %r %r", address, vlan)
|
||||
if _debug: SnifferStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
ClientStateMachine.__init__(self)
|
||||
|
||||
# save the name and address
|
||||
self.name = address
|
||||
self.address = Address(address)
|
||||
|
||||
# create a promiscuous node, added to the network
|
||||
self.node = IPNode(self.address, vlan, promiscuous=True)
|
||||
if _debug: SnifferNode._debug(" - node: %r", self.node)
|
||||
# BACnet/IP interpreter
|
||||
self.annexj = AnnexJCodec()
|
||||
|
||||
# bind this to the node
|
||||
bind(self, self.node)
|
||||
# fake multiplexer has a VLAN node in it
|
||||
self.mux = FauxMultiplexer(self.address, vlan)
|
||||
|
||||
# might receive all packets and allow spoofing
|
||||
self.mux.node.promiscuous = True
|
||||
self.mux.node.spoofing = True
|
||||
|
||||
# bind the stack together
|
||||
bind(self, self.annexj, self.mux)
|
||||
|
||||
|
||||
#
|
||||
# CodecNode
|
||||
# BIPStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class CodecNode(ClientStateMachine):
|
||||
class BIPStateMachine(ClientStateMachine):
|
||||
|
||||
"""This class is an application layer for BVLL messages that has no BVLL
|
||||
processing like the 'simple', 'foreign', or 'bbmd' versions. The client
|
||||
state machine sits above and Annex-J codec so the send and receive PDUs are
|
||||
BVLL PDUs.
|
||||
"""
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: CodecNode._debug("__init__ %r %r", address, vlan)
|
||||
if _debug: BIPStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
ClientStateMachine.__init__(self)
|
||||
|
||||
# save the name and address
|
||||
|
@ -129,14 +161,18 @@ class CodecNode(ClientStateMachine):
|
|||
|
||||
|
||||
#
|
||||
# SimpleNode
|
||||
# BIPSimpleStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class SimpleNode(ClientStateMachine):
|
||||
class BIPSimpleStateMachine(ClientStateMachine):
|
||||
|
||||
"""This class sits on a BIPSimple instance, the send() and receive()
|
||||
parameters are NPDUs.
|
||||
"""
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: SimpleNode._debug("__init__ %r %r", address, vlan)
|
||||
if _debug: BIPSimpleStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
ClientStateMachine.__init__(self)
|
||||
|
||||
# save the name and address
|
||||
|
@ -155,14 +191,18 @@ class SimpleNode(ClientStateMachine):
|
|||
|
||||
|
||||
#
|
||||
# ForeignNode
|
||||
# BIPForeignStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class ForeignNode(ClientStateMachine):
|
||||
class BIPForeignStateMachine(ClientStateMachine):
|
||||
|
||||
"""This class sits on a BIPForeign instance, the send() and receive()
|
||||
parameters are NPDUs.
|
||||
"""
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: ForeignNode._debug("__init__ %r %r", address, vlan)
|
||||
if _debug: BIPForeignStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
ClientStateMachine.__init__(self)
|
||||
|
||||
# save the name and address
|
||||
|
@ -180,14 +220,18 @@ class ForeignNode(ClientStateMachine):
|
|||
bind(self, self.bip, self.annexj, self.mux)
|
||||
|
||||
#
|
||||
# BBMDNode
|
||||
# BIPBBMDStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class BBMDNode(ClientStateMachine):
|
||||
class BIPBBMDStateMachine(ClientStateMachine):
|
||||
|
||||
"""This class sits on a BIPBBMD instance, the send() and receive()
|
||||
parameters are NPDUs.
|
||||
"""
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: BBMDNode._debug("__init__ %r %r", address, vlan)
|
||||
if _debug: BIPBBMDStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
ClientStateMachine.__init__(self)
|
||||
|
||||
# save the name and address
|
||||
|
@ -200,7 +244,7 @@ class BBMDNode(ClientStateMachine):
|
|||
|
||||
# build an address, full mask
|
||||
bdt_address = "%s/32:%d" % self.address.addrTuple
|
||||
if _debug: BBMDNode._debug(" - bdt_address: %r", bdt_address)
|
||||
if _debug: BIPBBMDStateMachine._debug(" - bdt_address: %r", bdt_address)
|
||||
|
||||
# add itself as the first entry in the BDT
|
||||
self.bip.add_peer(Address(bdt_address))
|
||||
|
@ -211,3 +255,209 @@ class BBMDNode(ClientStateMachine):
|
|||
# bind the stack together
|
||||
bind(self, self.bip, self.annexj, self.mux)
|
||||
|
||||
#
|
||||
# BIPSimpleNode
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class BIPSimpleNode:
|
||||
|
||||
"""This class is a BIPSimple instance that is not bound to a state machine."""
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: BIPSimpleNode._debug("__init__ %r %r", address, vlan)
|
||||
|
||||
# save the name and address
|
||||
self.name = address
|
||||
self.address = Address(address)
|
||||
|
||||
# BACnet/IP interpreter
|
||||
self.bip = BIPSimple()
|
||||
self.annexj = AnnexJCodec()
|
||||
|
||||
# fake multiplexer has a VLAN node in it
|
||||
self.mux = FauxMultiplexer(self.address, vlan)
|
||||
|
||||
# bind the stack together
|
||||
bind(self.bip, self.annexj, self.mux)
|
||||
|
||||
#
|
||||
# BIPBBMDNode
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class BIPBBMDNode:
|
||||
|
||||
"""This class is a BIPBBMD instance that is not bound to a state machine."""
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: BIPBBMDNode._debug("__init__ %r %r", address, vlan)
|
||||
|
||||
# save the name and address
|
||||
self.name = address
|
||||
self.address = Address(address)
|
||||
if _debug: BIPBBMDNode._debug(" - address: %r", self.address)
|
||||
|
||||
# BACnet/IP interpreter
|
||||
self.bip = BIPBBMD(self.address)
|
||||
self.annexj = AnnexJCodec()
|
||||
|
||||
# build an address, full mask
|
||||
bdt_address = "%s/32:%d" % self.address.addrTuple
|
||||
if _debug: BIPBBMDNode._debug(" - bdt_address: %r", bdt_address)
|
||||
|
||||
# add itself as the first entry in the BDT
|
||||
self.bip.add_peer(Address(bdt_address))
|
||||
|
||||
# fake multiplexer has a VLAN node in it
|
||||
self.mux = FauxMultiplexer(self.address, vlan)
|
||||
|
||||
# bind the stack together
|
||||
bind(self.bip, self.annexj, self.mux)
|
||||
|
||||
|
||||
#
|
||||
# TestDeviceObject
|
||||
#
|
||||
|
||||
@register_object_type(vendor_id=999)
|
||||
class TestDeviceObject(LocalDeviceObject):
|
||||
|
||||
pass
|
||||
|
||||
#
|
||||
# BIPSimpleApplicationLayerStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class BIPSimpleApplicationLayerStateMachine(ApplicationServiceElement, ClientStateMachine):
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: BIPSimpleApplicationLayerStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
|
||||
# build a name, save the address
|
||||
self.name = "app @ %s" % (address,)
|
||||
self.address = Address(address)
|
||||
|
||||
# build a local device object
|
||||
local_device = TestDeviceObject(
|
||||
objectName=self.name,
|
||||
objectIdentifier=('device', 998),
|
||||
vendorIdentifier=999,
|
||||
)
|
||||
|
||||
# build an address and save it
|
||||
self.address = Address(address)
|
||||
if _debug: BIPSimpleApplicationLayerStateMachine._debug(" - address: %r", self.address)
|
||||
|
||||
# continue with initialization
|
||||
ApplicationServiceElement.__init__(self)
|
||||
ClientStateMachine.__init__(self, name=local_device.objectName)
|
||||
|
||||
# include a application decoder
|
||||
self.asap = ApplicationServiceAccessPoint()
|
||||
|
||||
# pass the device object to the state machine access point so it
|
||||
# can know if it should support segmentation
|
||||
self.smap = StateMachineAccessPoint(local_device)
|
||||
|
||||
# the segmentation state machines need access to some device
|
||||
# information cache, usually shared with the application
|
||||
self.smap.deviceInfoCache = DeviceInfoCache()
|
||||
|
||||
# a network service access point will be needed
|
||||
self.nsap = NetworkServiceAccessPoint()
|
||||
|
||||
# give the NSAP a generic network layer service element
|
||||
self.nse = NetworkServiceElement()
|
||||
bind(self.nse, self.nsap)
|
||||
|
||||
# bind the top layers
|
||||
bind(self, self.asap, self.smap, self.nsap)
|
||||
|
||||
# BACnet/IP interpreter
|
||||
self.bip = BIPSimple()
|
||||
self.annexj = AnnexJCodec()
|
||||
|
||||
# fake multiplexer has a VLAN node in it
|
||||
self.mux = FauxMultiplexer(self.address, vlan)
|
||||
|
||||
# bind the stack together
|
||||
bind(self.bip, self.annexj, self.mux)
|
||||
|
||||
# bind the stack to the local network
|
||||
self.nsap.bind(self.bip)
|
||||
|
||||
def indication(self, apdu):
|
||||
if _debug: BIPSimpleApplicationLayerStateMachine._debug("indication %r", apdu)
|
||||
self.receive(apdu)
|
||||
|
||||
def confirmation(self, apdu):
|
||||
if _debug: BIPSimpleApplicationLayerStateMachine._debug("confirmation %r %r", apdu)
|
||||
self.receive(apdu)
|
||||
|
||||
#
|
||||
# BIPBBMDApplication
|
||||
#
|
||||
|
||||
class BIPBBMDApplication(Application, WhoIsIAmServices, ReadWritePropertyServices):
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: BIPBBMDApplication._debug("__init__ %r %r", address, vlan)
|
||||
|
||||
# build a name, save the address
|
||||
self.name = "app @ %s" % (address,)
|
||||
self.address = Address(address)
|
||||
if _debug: BIPBBMDApplication._debug(" - address: %r", self.address)
|
||||
|
||||
# build a local device object
|
||||
local_device = TestDeviceObject(
|
||||
objectName=self.name,
|
||||
objectIdentifier=('device', 999),
|
||||
vendorIdentifier=999,
|
||||
)
|
||||
|
||||
# continue with initialization
|
||||
Application.__init__(self, local_device, self.address)
|
||||
|
||||
# include a application decoder
|
||||
self.asap = ApplicationServiceAccessPoint()
|
||||
|
||||
# pass the device object to the state machine access point so it
|
||||
# can know if it should support segmentation
|
||||
self.smap = StateMachineAccessPoint(local_device)
|
||||
|
||||
# the segmentation state machines need access to the same device
|
||||
# information cache as the application
|
||||
self.smap.deviceInfoCache = self.deviceInfoCache
|
||||
|
||||
# a network service access point will be needed
|
||||
self.nsap = NetworkServiceAccessPoint()
|
||||
|
||||
# give the NSAP a generic network layer service element
|
||||
self.nse = NetworkServiceElement()
|
||||
bind(self.nse, self.nsap)
|
||||
|
||||
# bind the top layers
|
||||
bind(self, self.asap, self.smap, self.nsap)
|
||||
|
||||
# BACnet/IP interpreter
|
||||
self.bip = BIPBBMD(self.address)
|
||||
self.annexj = AnnexJCodec()
|
||||
|
||||
# build an address, full mask
|
||||
bdt_address = "%s/32:%d" % self.address.addrTuple
|
||||
if _debug: BIPBBMDNode._debug(" - bdt_address: %r", bdt_address)
|
||||
|
||||
# add itself as the first entry in the BDT
|
||||
self.bip.add_peer(Address(bdt_address))
|
||||
|
||||
# fake multiplexer has a VLAN node in it
|
||||
self.mux = FauxMultiplexer(self.address, vlan)
|
||||
|
||||
# bind the stack together
|
||||
bind(self.bip, self.annexj, self.mux)
|
||||
|
||||
# bind the stack to the local network
|
||||
self.nsap.bind(self.bip)
|
||||
|
||||
|
|
|
@ -1 +1,302 @@
|
|||
# placeholder
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test BBMD
|
||||
---------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
|
||||
from bacpypes.pdu import Address, PDU, LocalBroadcast
|
||||
from bacpypes.vlan import IPNetwork, IPRouter
|
||||
from bacpypes.bvll import (
|
||||
Result,
|
||||
WriteBroadcastDistributionTable,
|
||||
ReadBroadcastDistributionTable, ReadBroadcastDistributionTableAck,
|
||||
ForwardedNPDU,
|
||||
RegisterForeignDevice,
|
||||
ReadForeignDeviceTable, ReadForeignDeviceTableAck,
|
||||
DeleteForeignDeviceTableEntry,
|
||||
DistributeBroadcastToNetwork,
|
||||
OriginalUnicastNPDU,
|
||||
OriginalBroadcastNPDU,
|
||||
)
|
||||
|
||||
from bacpypes.apdu import (
|
||||
WhoIsRequest, IAmRequest,
|
||||
ReadPropertyRequest, ReadPropertyACK,
|
||||
AbortPDU,
|
||||
)
|
||||
|
||||
from ..state_machine import StateMachineGroup, TrafficLog
|
||||
from ..time_machine import reset_time_machine, run_time_machine
|
||||
|
||||
from .helpers import (
|
||||
SnifferStateMachine, BIPStateMachine, BIPSimpleStateMachine,
|
||||
BIPForeignStateMachine, BIPBBMDStateMachine,
|
||||
BIPSimpleNode, BIPBBMDNode,
|
||||
BIPSimpleApplicationLayerStateMachine,
|
||||
BIPBBMDApplication,
|
||||
)
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
#
|
||||
# TNetwork
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class TNetwork(StateMachineGroup):
|
||||
|
||||
def __init__(self, count):
|
||||
if _debug: TNetwork._debug("__init__ %r", count)
|
||||
StateMachineGroup.__init__(self)
|
||||
|
||||
# reset the time machine
|
||||
reset_time_machine()
|
||||
if _debug: TNetwork._debug(" - time machine reset")
|
||||
|
||||
# create a traffic log
|
||||
self.traffic_log = TrafficLog()
|
||||
|
||||
# make a router
|
||||
self.router = IPRouter()
|
||||
|
||||
# make the networks
|
||||
self.vlan = []
|
||||
for net in range(1, count + 1):
|
||||
# make a network and set the traffic log
|
||||
ip_network = IPNetwork("192.168.{}.0/24".format(net))
|
||||
ip_network.traffic_log = self.traffic_log
|
||||
|
||||
# make a router
|
||||
router_address = Address("192.168.{}.1/24".format(net))
|
||||
self.router.add_network(router_address, ip_network)
|
||||
|
||||
self.vlan.append(ip_network)
|
||||
|
||||
def run(self, time_limit=60.0):
|
||||
if _debug: TNetwork._debug("run %r", time_limit)
|
||||
|
||||
# run the group
|
||||
super(TNetwork, self).run()
|
||||
|
||||
# run it for some time
|
||||
run_time_machine(time_limit)
|
||||
if _debug: TNetwork._debug(" - time machine finished")
|
||||
|
||||
# check for success
|
||||
all_success, some_failed = super(TNetwork, self).check_for_success()
|
||||
if _debug:
|
||||
TNetwork._debug(" - all_success, some_failed: %r, %r", all_success, some_failed)
|
||||
for state_machine in self.state_machines:
|
||||
if state_machine.running:
|
||||
TNetwork._debug(" %r (running)", state_machine)
|
||||
elif not state_machine.current_state:
|
||||
TNetwork._debug(" %r (not started)", state_machine)
|
||||
else:
|
||||
TNetwork._debug(" %r", state_machine)
|
||||
for direction, pdu in state_machine.transaction_log:
|
||||
TNetwork._debug(" %s %r", direction, pdu)
|
||||
|
||||
# traffic log has what was processed on each vlan
|
||||
self.traffic_log.dump(TNetwork._debug)
|
||||
|
||||
assert all_success
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestNonBBMD(unittest.TestCase):
|
||||
|
||||
def setup_method(self, method):
|
||||
"""This function is called before each test method is called and is
|
||||
given a reference to the test method."""
|
||||
if _debug: TestNonBBMD._debug("setup_method %r", method)
|
||||
|
||||
# create a network
|
||||
self.tnet = TNetwork(1)
|
||||
|
||||
# test device
|
||||
self.td = BIPStateMachine("192.168.1.2/24", self.tnet.vlan[0])
|
||||
self.tnet.append(self.td)
|
||||
|
||||
# implementation under test
|
||||
self.iut = BIPSimpleNode("192.168.1.3/24", self.tnet.vlan[0])
|
||||
|
||||
def test_write_bdt_fail(self):
|
||||
"""Test writing a BDT."""
|
||||
if _debug: TestNonBBMD._debug("test_write_bdt_fail")
|
||||
|
||||
# read the broadcast distribution table, get a nack
|
||||
self.td.start_state.doc("1-1-0") \
|
||||
.send(WriteBroadcastDistributionTable(destination=self.iut.address)).doc("1-1-1") \
|
||||
.receive(Result, bvlciResultCode=0x0010).doc("1-1-2") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
self.tnet.run()
|
||||
|
||||
def test_read_bdt_fail(self):
|
||||
"""Test reading a BDT."""
|
||||
if _debug: TestNonBBMD._debug("test_read_bdt_fail")
|
||||
|
||||
# read the broadcast distribution table, get a nack
|
||||
self.td.start_state.doc("1-2-0") \
|
||||
.send(ReadBroadcastDistributionTable(destination=self.iut.address)).doc("1-2-1") \
|
||||
.receive(Result, bvlciResultCode=0x0020).doc("1-2-2") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
self.tnet.run()
|
||||
|
||||
def test_register_fail(self):
|
||||
"""Test registering as a foreign device to a non-BBMD."""
|
||||
if _debug: TestNonBBMD._debug("test_read_fdt_success")
|
||||
|
||||
# read the broadcast distribution table, get a nack
|
||||
self.td.start_state.doc("1-3-0") \
|
||||
.send(RegisterForeignDevice(10, destination=self.iut.address)).doc("1-3-1") \
|
||||
.receive(Result, bvlciResultCode=0x0030).doc("1-3-2") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
self.tnet.run()
|
||||
|
||||
def test_read_fdt_fail(self):
|
||||
"""Test reading an FDT from a non-BBMD."""
|
||||
if _debug: TestNonBBMD._debug("test_read_fdt_success")
|
||||
|
||||
# read the broadcast distribution table, get a nack
|
||||
self.td.start_state.doc("1-4-0") \
|
||||
.send(ReadForeignDeviceTable(destination=self.iut.address)).doc("1-4-1") \
|
||||
.receive(Result, bvlciResultCode=0x0040).doc("1-4-2") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
self.tnet.run()
|
||||
|
||||
def test_delete_fail(self):
|
||||
"""Test deleting an FDT entry from a non-BBMD."""
|
||||
if _debug: TestNonBBMD._debug("test_delete_fail")
|
||||
|
||||
# read the broadcast distribution table, get a nack
|
||||
self.td.start_state.doc("1-5-0") \
|
||||
.send(DeleteForeignDeviceTableEntry(Address("1.2.3.4"), destination=self.iut.address)).doc("1-5-1") \
|
||||
.receive(Result, bvlciResultCode=0x0050).doc("1-5-2") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
self.tnet.run()
|
||||
|
||||
def test_distribute_fail(self):
|
||||
"""Test asking a non-BBMD to distribute a broadcast."""
|
||||
if _debug: TestNonBBMD._debug("test_delete_fail")
|
||||
|
||||
# read the broadcast distribution table, get a nack
|
||||
self.td.start_state.doc("1-6-0") \
|
||||
.send(DistributeBroadcastToNetwork(xtob('deadbeef'), destination=self.iut.address)).doc("1-6-1") \
|
||||
.receive(Result, bvlciResultCode=0x0060).doc("1-6-2") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
self.tnet.run()
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestBBMD(unittest.TestCase):
|
||||
|
||||
def test_14_2_1_1(self):
|
||||
"""14.2.1.1 Execute Forwarded-NPDU (One-hop Distribution)."""
|
||||
if _debug: TestBBMD._debug("test_14_2_1_1")
|
||||
|
||||
# create a network
|
||||
tnet = TNetwork(2)
|
||||
|
||||
# implementation under test
|
||||
iut = BIPBBMDApplication("192.168.1.2/24", tnet.vlan[0])
|
||||
if _debug: TestBBMD._debug(" - iut.bip: %r", iut.bip)
|
||||
|
||||
# BBMD on net 2
|
||||
bbmd1 = BIPBBMDNode("192.168.2.2/24", tnet.vlan[1])
|
||||
|
||||
# add the IUT as a one-hop peer
|
||||
bbmd1.bip.add_peer(Address("192.168.1.2/24"))
|
||||
if _debug: TestBBMD._debug(" - bbmd1.bip: %r", bbmd1.bip)
|
||||
|
||||
# test device
|
||||
td = BIPSimpleApplicationLayerStateMachine("192.168.2.3/24", tnet.vlan[1])
|
||||
tnet.append(td)
|
||||
|
||||
# listener looks for extra traffic
|
||||
listener = BIPStateMachine("192.168.1.3/24", tnet.vlan[0])
|
||||
listener.mux.node.promiscuous = True
|
||||
tnet.append(listener)
|
||||
|
||||
# broadcast a forwarded NPDU
|
||||
td.start_state.doc("2-1-0") \
|
||||
.send(WhoIsRequest(destination=LocalBroadcast())).doc("2-1-1") \
|
||||
.receive(IAmRequest).doc("2-1-2") \
|
||||
.success()
|
||||
|
||||
# listen for the directed broadcast, then the original unicast,
|
||||
# then fail if there's anything else
|
||||
listener.start_state.doc("2-2-0") \
|
||||
.receive(ForwardedNPDU).doc("2-2-1") \
|
||||
.receive(OriginalUnicastNPDU).doc("2-2-2") \
|
||||
.timeout(3).doc("2-2-3") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
tnet.run()
|
||||
|
||||
def test_14_2_1_2(self):
|
||||
"""14.2.1.1 Execute Forwarded-NPDU (Two-hop Distribution)."""
|
||||
if _debug: TestBBMD._debug("test_14_2_1_2")
|
||||
|
||||
# create a network
|
||||
tnet = TNetwork(2)
|
||||
|
||||
# implementation under test
|
||||
iut = BIPBBMDApplication("192.168.1.2/24", tnet.vlan[0])
|
||||
if _debug: TestBBMD._debug(" - iut.bip: %r", iut.bip)
|
||||
|
||||
# BBMD on net 2
|
||||
bbmd1 = BIPBBMDNode("192.168.2.2/24", tnet.vlan[1])
|
||||
|
||||
# add the IUT as a two-hop peer
|
||||
bbmd1.bip.add_peer(Address("192.168.1.2/32"))
|
||||
if _debug: TestBBMD._debug(" - bbmd1.bip: %r", bbmd1.bip)
|
||||
|
||||
# test device
|
||||
td = BIPSimpleApplicationLayerStateMachine("192.168.2.3/24", tnet.vlan[1])
|
||||
tnet.append(td)
|
||||
|
||||
# listener looks for extra traffic
|
||||
listener = BIPStateMachine("192.168.1.3/24", tnet.vlan[0])
|
||||
listener.mux.node.promiscuous = True
|
||||
tnet.append(listener)
|
||||
|
||||
# broadcast a forwarded NPDU
|
||||
td.start_state.doc("2-3-0") \
|
||||
.send(WhoIsRequest(destination=LocalBroadcast())).doc("2-3-1") \
|
||||
.receive(IAmRequest).doc("2-3-2") \
|
||||
.success()
|
||||
|
||||
# listen for the forwarded NPDU, then the re-braodcast on the local LAN
|
||||
# then the original unicast going back, then fail if there's anything else
|
||||
listener.start_state.doc("2-4-0") \
|
||||
.receive(ForwardedNPDU).doc("2-4-1") \
|
||||
.receive(ForwardedNPDU).doc("2-4-2") \
|
||||
.receive(OriginalUnicastNPDU).doc("2-4-3") \
|
||||
.timeout(3).doc("2-4-4") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
tnet.run()
|
||||
|
||||
|
|
|
@ -12,12 +12,20 @@ from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
|||
|
||||
from bacpypes.pdu import Address, PDU, LocalBroadcast
|
||||
from bacpypes.vlan import IPNetwork, IPRouter
|
||||
from bacpypes.bvll import ReadForeignDeviceTable, ReadForeignDeviceTableAck
|
||||
from bacpypes.bvll import (
|
||||
Result, RegisterForeignDevice,
|
||||
ReadForeignDeviceTable, ReadForeignDeviceTableAck,
|
||||
DistributeBroadcastToNetwork, ForwardedNPDU,
|
||||
OriginalUnicastNPDU, OriginalBroadcastNPDU,
|
||||
)
|
||||
|
||||
from ..state_machine import StateMachineGroup
|
||||
from ..state_machine import StateMachineGroup, TrafficLog
|
||||
from ..time_machine import reset_time_machine, run_time_machine
|
||||
|
||||
from .helpers import SnifferNode, CodecNode, SimpleNode, ForeignNode, BBMDNode
|
||||
from .helpers import (
|
||||
SnifferStateMachine, BIPStateMachine,
|
||||
BIPSimpleStateMachine, BIPForeignStateMachine, BIPBBMDStateMachine,
|
||||
)
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
|
@ -39,23 +47,28 @@ class TNetwork(StateMachineGroup):
|
|||
reset_time_machine()
|
||||
if _debug: TNetwork._debug(" - time machine reset")
|
||||
|
||||
# create a traffic log
|
||||
self.traffic_log = TrafficLog()
|
||||
|
||||
# make a router
|
||||
self.router = IPRouter()
|
||||
|
||||
# make a home LAN
|
||||
self.home_vlan = IPNetwork()
|
||||
self.router.add_network(Address("192.168.5.1/24"), self.home_vlan)
|
||||
self.vlan_5 = IPNetwork("192.168.5.0/24")
|
||||
self.vlan_5.traffic_log = self.traffic_log
|
||||
self.router.add_network(Address("192.168.5.1/24"), self.vlan_5)
|
||||
|
||||
# make a remote LAN
|
||||
self.remote_vlan = IPNetwork()
|
||||
self.router.add_network(Address("192.168.6.1/24"), self.remote_vlan)
|
||||
self.vlan_6 = IPNetwork("192.168.6.0/24")
|
||||
self.vlan_6.traffic_log = self.traffic_log
|
||||
self.router.add_network(Address("192.168.6.1/24"), self.vlan_6)
|
||||
|
||||
# the foreign device
|
||||
self.fd = ForeignNode("192.168.6.2/24", self.remote_vlan)
|
||||
self.fd = BIPForeignStateMachine("192.168.6.2/24", self.vlan_6)
|
||||
self.append(self.fd)
|
||||
|
||||
# bbmd
|
||||
self.bbmd = BBMDNode("192.168.5.3/24", self.home_vlan)
|
||||
self.bbmd = BIPBBMDStateMachine("192.168.5.3/24", self.vlan_5)
|
||||
self.append(self.bbmd)
|
||||
|
||||
def run(self, time_limit=60.0):
|
||||
|
@ -70,6 +83,22 @@ class TNetwork(StateMachineGroup):
|
|||
|
||||
# check for success
|
||||
all_success, some_failed = super(TNetwork, self).check_for_success()
|
||||
|
||||
if _debug:
|
||||
TNetwork._debug(" - all_success, some_failed: %r, %r", all_success, some_failed)
|
||||
for state_machine in self.state_machines:
|
||||
if state_machine.running:
|
||||
TNetwork._debug(" %r (running)", state_machine)
|
||||
elif not state_machine.current_state:
|
||||
TNetwork._debug(" %r (not started)", state_machine)
|
||||
else:
|
||||
TNetwork._debug(" %r", state_machine)
|
||||
for direction, pdu in state_machine.transaction_log:
|
||||
TNetwork._debug(" %s %s", direction, str(pdu))
|
||||
|
||||
# traffic log has what was processed on each vlan
|
||||
self.traffic_log.dump(TNetwork._debug)
|
||||
|
||||
assert all_success
|
||||
|
||||
|
||||
|
@ -97,58 +126,46 @@ class TestForeign(unittest.TestCase):
|
|||
# create a network
|
||||
tnet = TNetwork()
|
||||
|
||||
# add an addition codec node to the home vlan
|
||||
cnode = CodecNode("192.168.5.2/24", tnet.home_vlan)
|
||||
tnet.append(cnode)
|
||||
|
||||
# home sniffer node
|
||||
home_sniffer = SnifferNode("192.168.5.254/24", tnet.home_vlan)
|
||||
tnet.append(home_sniffer)
|
||||
|
||||
# remote sniffer node
|
||||
remote_sniffer = SnifferNode("192.168.6.254/24", tnet.remote_vlan)
|
||||
tnet.append(remote_sniffer)
|
||||
|
||||
# tell the B/IP layer of the foreign device to register
|
||||
tnet.fd.start_state \
|
||||
.call(tnet.fd.bip.register, tnet.bbmd.address, 30) \
|
||||
.success()
|
||||
|
||||
# sniffer pieces
|
||||
registration_request = xtob('81.05.0006' # bvlci
|
||||
'001e' # time-to-live
|
||||
)
|
||||
registration_ack = xtob('81.00.0006.0000') # simple ack
|
||||
# remote sniffer node
|
||||
remote_sniffer = SnifferStateMachine("192.168.6.254/24", tnet.vlan_6)
|
||||
tnet.append(remote_sniffer)
|
||||
|
||||
# remote sniffer sees registration
|
||||
# sniffer traffic
|
||||
remote_sniffer.start_state.doc("1-1-0") \
|
||||
.receive(PDU, pduData=registration_request).doc("1-1-1") \
|
||||
.receive(PDU, pduData=registration_ack).doc("1-1-2") \
|
||||
.receive(RegisterForeignDevice).doc("1-1-1") \
|
||||
.receive(Result).doc("1-1-2") \
|
||||
.set_event('fd-registered').doc("1-1-3") \
|
||||
.success()
|
||||
|
||||
# the bbmd is idle
|
||||
tnet.bbmd.start_state.success()
|
||||
|
||||
# read the FDT
|
||||
cnode.start_state.doc("1-2-0") \
|
||||
# home snooper node
|
||||
home_snooper = BIPStateMachine("192.168.5.2/24", tnet.vlan_5)
|
||||
tnet.append(home_snooper)
|
||||
|
||||
# snooper will read the foreign device table
|
||||
home_snooper.start_state.doc("1-2-0") \
|
||||
.wait_event('fd-registered').doc("1-2-1") \
|
||||
.send(ReadForeignDeviceTable(destination=tnet.bbmd.address)).doc("1-2-2") \
|
||||
.receive(ReadForeignDeviceTableAck).doc("1-2-3") \
|
||||
.success()
|
||||
|
||||
# the tnode reads the registration table
|
||||
read_fdt_request = xtob('81.06.0004') # bvlci
|
||||
read_fdt_ack = xtob('81.07.000e' # read-ack
|
||||
'c0.a8.06.02.ba.c0 001e 0023' # address, ttl, remaining
|
||||
)
|
||||
# home sniffer node
|
||||
home_sniffer = SnifferStateMachine("192.168.5.254/24", tnet.vlan_5)
|
||||
tnet.append(home_sniffer)
|
||||
|
||||
# home sniffer sees registration
|
||||
# sniffer traffic
|
||||
home_sniffer.start_state.doc("1-3-0") \
|
||||
.receive(PDU, pduData=registration_request).doc("1-3-1") \
|
||||
.receive(PDU, pduData=registration_ack).doc("1-3-2") \
|
||||
.receive(PDU, pduData=read_fdt_request).doc("1-3-3") \
|
||||
.receive(PDU, pduData=read_fdt_ack).doc("1-3-4") \
|
||||
.receive(RegisterForeignDevice).doc("1-3-1") \
|
||||
.receive(Result).doc("1-3-2") \
|
||||
.receive(ReadForeignDeviceTable).doc("1-3-3") \
|
||||
.receive(ReadForeignDeviceTableAck).doc("1-3-4") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
|
@ -170,21 +187,15 @@ class TestForeign(unittest.TestCase):
|
|||
tnet.bbmd.start_state.success()
|
||||
|
||||
# remote sniffer node
|
||||
remote_sniffer = SnifferNode("192.168.6.254/24", tnet.remote_vlan)
|
||||
remote_sniffer = SnifferStateMachine("192.168.6.254/24", tnet.vlan_6)
|
||||
tnet.append(remote_sniffer)
|
||||
|
||||
# sniffer pieces
|
||||
registration_request = xtob('81.05.0006' # bvlci
|
||||
'000a' # time-to-live
|
||||
)
|
||||
registration_ack = xtob('81.00.0006.0000') # simple ack
|
||||
|
||||
# remote sniffer sees registration
|
||||
# sniffer traffic
|
||||
remote_sniffer.start_state.doc("2-1-0") \
|
||||
.receive(PDU, pduData=registration_request).doc("2-1-1") \
|
||||
.receive(PDU, pduData=registration_ack).doc("2-1-2") \
|
||||
.receive(PDU, pduData=registration_request).doc("2-1-3") \
|
||||
.receive(PDU, pduData=registration_ack).doc("2-1-4") \
|
||||
.receive(RegisterForeignDevice).doc("2-1-1") \
|
||||
.receive(Result).doc("2-1-2") \
|
||||
.receive(RegisterForeignDevice).doc("2-1-3") \
|
||||
.receive(Result).doc("2-1-4") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
|
@ -205,7 +216,7 @@ class TestForeign(unittest.TestCase):
|
|||
# register, wait for ack, send some beef
|
||||
tnet.fd.start_state.doc("3-1-0") \
|
||||
.call(tnet.fd.bip.register, tnet.bbmd.address, 60).doc("3-1-1") \
|
||||
.wait_event('fd-registered').doc("3-1-2") \
|
||||
.wait_event('3-registered').doc("3-1-2") \
|
||||
.send(pdu).doc("3-1-3") \
|
||||
.success()
|
||||
|
||||
|
@ -215,24 +226,15 @@ class TestForeign(unittest.TestCase):
|
|||
.success()
|
||||
|
||||
# remote sniffer node
|
||||
remote_sniffer = SnifferNode("192.168.6.254/24", tnet.remote_vlan)
|
||||
remote_sniffer = SnifferStateMachine("192.168.6.254/24", tnet.vlan_6)
|
||||
tnet.append(remote_sniffer)
|
||||
|
||||
# sniffer pieces
|
||||
registration_request = xtob('81.05.0006' # bvlci
|
||||
'003c' # time-to-live (60)
|
||||
)
|
||||
registration_ack = xtob('81.00.0006.0000') # simple ack
|
||||
unicast_pdu = xtob('81.0a.0008' # original unicast bvlci
|
||||
'dead.beef' # PDU being unicast
|
||||
)
|
||||
|
||||
# remote sniffer sees registration
|
||||
# sniffer traffic
|
||||
remote_sniffer.start_state.doc("3-2-0") \
|
||||
.receive(PDU, pduData=registration_request).doc("3-2-1") \
|
||||
.receive(PDU, pduData=registration_ack).doc("3-2-2") \
|
||||
.set_event('fd-registered').doc("3-2-3") \
|
||||
.receive(PDU, pduData=unicast_pdu).doc("3-2-4") \
|
||||
.receive(RegisterForeignDevice).doc("3-2-1") \
|
||||
.receive(Result).doc("3-2-2") \
|
||||
.set_event('3-registered').doc("3-2-3") \
|
||||
.receive(OriginalUnicastNPDU).doc("3-2-4") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
|
@ -258,38 +260,29 @@ class TestForeign(unittest.TestCase):
|
|||
.success()
|
||||
|
||||
# the bbmd is happy when it gets the pdu
|
||||
tnet.bbmd.start_state \
|
||||
.receive(PDU, pduSource=tnet.fd.address, pduData=pdu_data) \
|
||||
.success()
|
||||
|
||||
# home sniffer node
|
||||
home_node = SimpleNode("192.168.5.254/24", tnet.home_vlan)
|
||||
tnet.append(home_node)
|
||||
|
||||
# home node happy when getting the pdu, broadcast by the bbmd
|
||||
home_node.start_state.doc("4-2-0") \
|
||||
tnet.bbmd.start_state.doc("4-2-0") \
|
||||
.receive(PDU, pduSource=tnet.fd.address, pduData=pdu_data).doc("4-2-1") \
|
||||
.success()
|
||||
|
||||
# home simple node
|
||||
home_node = BIPSimpleStateMachine("192.168.5.254/24", tnet.vlan_5)
|
||||
tnet.append(home_node)
|
||||
|
||||
# home node happy when getting the pdu, broadcast by the bbmd
|
||||
home_node.start_state.doc("4-3-0") \
|
||||
.receive(PDU, pduSource=tnet.fd.address, pduData=pdu_data).doc("4-3-1") \
|
||||
.success()
|
||||
|
||||
# remote sniffer node
|
||||
remote_sniffer = SnifferNode("192.168.6.254/24", tnet.remote_vlan)
|
||||
remote_sniffer = SnifferStateMachine("192.168.6.254/24", tnet.vlan_6)
|
||||
tnet.append(remote_sniffer)
|
||||
|
||||
# sniffer pieces
|
||||
registration_request = xtob('81.05.0006' # bvlci
|
||||
'003c' # time-to-live (60)
|
||||
)
|
||||
registration_ack = xtob('81.00.0006.0000') # simple ack
|
||||
distribute_pdu = xtob('81.09.0008' # bvlci
|
||||
'deadbeef' # PDU to broadcast
|
||||
)
|
||||
|
||||
# remote sniffer sees registration
|
||||
remote_sniffer.start_state.doc("4-3-0") \
|
||||
.receive(PDU, pduData=registration_request).doc("4-3-1") \
|
||||
.receive(PDU, pduData=registration_ack).doc("4-3-2") \
|
||||
# remote traffic
|
||||
remote_sniffer.start_state.doc("4-4-0") \
|
||||
.receive(RegisterForeignDevice).doc("4-4-1") \
|
||||
.receive(Result).doc("4-4-2") \
|
||||
.set_event('4-registered') \
|
||||
.receive(PDU, pduData=distribute_pdu).doc("4-3-3") \
|
||||
.receive(DistributeBroadcastToNetwork).doc("4-4-3") \
|
||||
.success()
|
||||
|
||||
# run the group
|
||||
|
|
|
@ -11,12 +11,15 @@ import unittest
|
|||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
|
||||
from bacpypes.pdu import PDU, LocalBroadcast
|
||||
from bacpypes.bvll import OriginalUnicastNPDU, OriginalBroadcastNPDU
|
||||
from bacpypes.vlan import IPNetwork
|
||||
|
||||
from ..state_machine import match_pdu, StateMachineGroup
|
||||
from ..time_machine import reset_time_machine, run_time_machine
|
||||
|
||||
from .helpers import SnifferNode, SimpleNode
|
||||
from .helpers import (
|
||||
SnifferStateMachine, BIPSimpleStateMachine,
|
||||
)
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
|
@ -42,15 +45,15 @@ class TNetwork(StateMachineGroup):
|
|||
self.vlan = IPNetwork()
|
||||
|
||||
# test device
|
||||
self.td = SimpleNode("192.168.4.1/24", self.vlan)
|
||||
self.td = BIPSimpleStateMachine("192.168.4.1/24", self.vlan)
|
||||
self.append(self.td)
|
||||
|
||||
# implementation under test
|
||||
self.iut = SimpleNode("192.168.4.2/24", self.vlan)
|
||||
self.iut = BIPSimpleStateMachine("192.168.4.2/24", self.vlan)
|
||||
self.append(self.iut)
|
||||
|
||||
# sniffer node
|
||||
self.sniffer = SnifferNode("192.168.4.254/24", self.vlan)
|
||||
self.sniffer = SnifferStateMachine("192.168.4.254/24", self.vlan)
|
||||
self.append(self.sniffer)
|
||||
|
||||
|
||||
|
@ -109,12 +112,10 @@ class TestSimple(unittest.TestCase):
|
|||
tnet.iut.start_state.receive(PDU, pduSource=tnet.td.address).success()
|
||||
|
||||
# sniffer sees message on the wire
|
||||
tnet.sniffer.start_state.receive(PDU,
|
||||
tnet.sniffer.start_state.receive(OriginalUnicastNPDU,
|
||||
pduSource=tnet.td.address.addrTuple,
|
||||
pduDestination=tnet.iut.address.addrTuple,
|
||||
pduData=xtob('81.0a.0008' # original unicast bvlci
|
||||
'deadbeef' # PDU being unicast
|
||||
),
|
||||
pduData=pdu_data,
|
||||
).timeout(1.0).success()
|
||||
|
||||
# run the group
|
||||
|
@ -137,12 +138,10 @@ class TestSimple(unittest.TestCase):
|
|||
tnet.iut.start_state.receive(PDU, pduSource=tnet.td.address).success()
|
||||
|
||||
# sniffer sees message on the wire
|
||||
tnet.sniffer.start_state.receive(PDU,
|
||||
pduSource=tnet.td.address.addrTuple,
|
||||
pduDestination=('192.168.4.255', 47808),
|
||||
pduData=xtob('81.0b.0008' # original broadcast bvlci
|
||||
'deadbeef' # PDU being unicast
|
||||
),
|
||||
tnet.sniffer.start_state.receive(OriginalBroadcastNPDU,
|
||||
pduSource=tnet.td.address.addrTuple,
|
||||
# pduDestination=('192.168.4.255', 47808),
|
||||
pduData=pdu_data,
|
||||
).timeout(1.0).success()
|
||||
|
||||
# run the group
|
||||
|
|
|
@ -71,14 +71,14 @@ class NPDUCodec(Client, Server):
|
|||
|
||||
|
||||
#
|
||||
# SnifferNode
|
||||
# SnifferStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class SnifferNode(ClientStateMachine):
|
||||
class SnifferStateMachine(ClientStateMachine):
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: SnifferNode._debug("__init__ %r %r", address, vlan)
|
||||
if _debug: SnifferStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
ClientStateMachine.__init__(self)
|
||||
|
||||
# save the name and address
|
||||
|
@ -87,20 +87,20 @@ class SnifferNode(ClientStateMachine):
|
|||
|
||||
# create a promiscuous node, added to the network
|
||||
self.node = Node(self.address, vlan, promiscuous=True)
|
||||
if _debug: SnifferNode._debug(" - node: %r", self.node)
|
||||
if _debug: SnifferStateMachine._debug(" - node: %r", self.node)
|
||||
|
||||
# bind this to the node
|
||||
bind(self, self.node)
|
||||
|
||||
#
|
||||
# NetworkLayerNode
|
||||
# NetworkLayerStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class NetworkLayerNode(ClientStateMachine):
|
||||
class NetworkLayerStateMachine(ClientStateMachine):
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: NetworkLayerNode._debug("__init__ %r %r", address, vlan)
|
||||
if _debug: NetworkLayerStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
ClientStateMachine.__init__(self)
|
||||
|
||||
# save the name and address
|
||||
|
@ -109,11 +109,11 @@ class NetworkLayerNode(ClientStateMachine):
|
|||
|
||||
# create a network layer encoder/decoder
|
||||
self.codec = NPDUCodec()
|
||||
if _debug: SnifferNode._debug(" - codec: %r", self.codec)
|
||||
if _debug: SnifferStateMachine._debug(" - codec: %r", self.codec)
|
||||
|
||||
# create a node, added to the network
|
||||
self.node = Node(self.address, vlan)
|
||||
if _debug: SnifferNode._debug(" - node: %r", self.node)
|
||||
if _debug: SnifferStateMachine._debug(" - node: %r", self.node)
|
||||
|
||||
# bind this to the node
|
||||
bind(self, self.codec, self.node)
|
||||
|
@ -158,14 +158,14 @@ class TestDeviceObject(LocalDeviceObject):
|
|||
pass
|
||||
|
||||
#
|
||||
# ApplicationLayerNode
|
||||
# ApplicationLayerStateMachine
|
||||
#
|
||||
|
||||
@bacpypes_debugging
|
||||
class ApplicationLayerNode(ApplicationServiceElement, ClientStateMachine):
|
||||
class ApplicationLayerStateMachine(ApplicationServiceElement, ClientStateMachine):
|
||||
|
||||
def __init__(self, address, vlan):
|
||||
if _debug: ApplicationLayerNode._debug("__init__ %r %r", address, vlan)
|
||||
if _debug: ApplicationLayerStateMachine._debug("__init__ %r %r", address, vlan)
|
||||
|
||||
# build a name, save the address
|
||||
self.name = "app @ %s" % (address,)
|
||||
|
@ -180,7 +180,7 @@ class ApplicationLayerNode(ApplicationServiceElement, ClientStateMachine):
|
|||
|
||||
# build an address and save it
|
||||
self.address = Address(address)
|
||||
if _debug: ApplicationLayerNode._debug(" - address: %r", self.address)
|
||||
if _debug: ApplicationLayerStateMachine._debug(" - address: %r", self.address)
|
||||
|
||||
# continue with initialization
|
||||
ApplicationServiceElement.__init__(self)
|
||||
|
@ -209,17 +209,17 @@ class ApplicationLayerNode(ApplicationServiceElement, ClientStateMachine):
|
|||
|
||||
# create a node, added to the network
|
||||
self.node = Node(self.address, vlan)
|
||||
if _debug: ApplicationLayerNode._debug(" - node: %r", self.node)
|
||||
if _debug: ApplicationLayerStateMachine._debug(" - node: %r", self.node)
|
||||
|
||||
# bind the stack to the local network
|
||||
self.nsap.bind(self.node)
|
||||
|
||||
def indication(self, apdu):
|
||||
if _debug: ApplicationLayerNode._debug("indication %r", apdu)
|
||||
if _debug: ApplicationLayerStateMachine._debug("indication %r", apdu)
|
||||
self.receive(apdu)
|
||||
|
||||
def confirmation(self, apdu):
|
||||
if _debug: ApplicationLayerNode._debug("confirmation %r %r", apdu)
|
||||
if _debug: ApplicationLayerStateMachine._debug("confirmation %r %r", apdu)
|
||||
self.receive(apdu)
|
||||
|
||||
#
|
||||
|
|
|
@ -29,7 +29,7 @@ from bacpypes.npdu import (
|
|||
from ..state_machine import match_pdu, StateMachineGroup
|
||||
from ..time_machine import reset_time_machine, run_time_machine
|
||||
|
||||
from .helpers import SnifferNode, NetworkLayerNode, RouterNode
|
||||
from .helpers import SnifferStateMachine, NetworkLayerStateMachine, RouterNode
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
|
@ -58,11 +58,11 @@ class TNetwork(StateMachineGroup):
|
|||
self.vlan1 = Network(name="vlan1", broadcast_address=LocalBroadcast())
|
||||
|
||||
# test device
|
||||
self.td = NetworkLayerNode("1", self.vlan1)
|
||||
self.td = NetworkLayerStateMachine("1", self.vlan1)
|
||||
self.append(self.td)
|
||||
|
||||
# sniffer node
|
||||
self.sniffer1 = SnifferNode("2", self.vlan1)
|
||||
self.sniffer1 = SnifferStateMachine("2", self.vlan1)
|
||||
self.append(self.sniffer1)
|
||||
|
||||
# add the network
|
||||
|
@ -72,7 +72,7 @@ class TNetwork(StateMachineGroup):
|
|||
self.vlan2 = Network(name="vlan2", broadcast_address=LocalBroadcast())
|
||||
|
||||
# sniffer node
|
||||
self.sniffer2 = SnifferNode("4", self.vlan2)
|
||||
self.sniffer2 = SnifferStateMachine("4", self.vlan2)
|
||||
self.append(self.sniffer2)
|
||||
|
||||
# add the network
|
||||
|
@ -82,7 +82,7 @@ class TNetwork(StateMachineGroup):
|
|||
self.vlan3 = Network(name="vlan3", broadcast_address=LocalBroadcast())
|
||||
|
||||
# sniffer node
|
||||
self.sniffer3 = SnifferNode("6", self.vlan3)
|
||||
self.sniffer3 = SnifferStateMachine("6", self.vlan3)
|
||||
self.append(self.sniffer3)
|
||||
|
||||
# add the network
|
||||
|
|
|
@ -30,7 +30,7 @@ from bacpypes.npdu import (
|
|||
from ..state_machine import match_pdu, StateMachineGroup, TrafficLog
|
||||
from ..time_machine import reset_time_machine, run_time_machine
|
||||
|
||||
from .helpers import SnifferNode, NetworkLayerNode, RouterNode
|
||||
from .helpers import SnifferStateMachine, NetworkLayerStateMachine, RouterNode
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
|
@ -64,11 +64,11 @@ class TNetwork(StateMachineGroup):
|
|||
self.vlan1.traffic_log = self.traffic_log
|
||||
|
||||
# test device
|
||||
self.td = NetworkLayerNode("1", self.vlan1)
|
||||
self.td = NetworkLayerStateMachine("1", self.vlan1)
|
||||
self.append(self.td)
|
||||
|
||||
# sniffer node
|
||||
self.sniffer1 = SnifferNode("2", self.vlan1)
|
||||
self.sniffer1 = SnifferStateMachine("2", self.vlan1)
|
||||
self.append(self.sniffer1)
|
||||
|
||||
# connect vlan1 to iut1
|
||||
|
@ -79,7 +79,7 @@ class TNetwork(StateMachineGroup):
|
|||
self.vlan2.traffic_log = self.traffic_log
|
||||
|
||||
# sniffer node
|
||||
self.sniffer2 = SnifferNode("4", self.vlan2)
|
||||
self.sniffer2 = SnifferStateMachine("4", self.vlan2)
|
||||
self.append(self.sniffer2)
|
||||
|
||||
# connect vlan2 to both routers
|
||||
|
@ -91,7 +91,7 @@ class TNetwork(StateMachineGroup):
|
|||
self.vlan3.traffic_log = self.traffic_log
|
||||
|
||||
# sniffer node
|
||||
self.sniffer3 = SnifferNode("7", self.vlan3)
|
||||
self.sniffer3 = SnifferStateMachine("7", self.vlan3)
|
||||
self.append(self.sniffer3)
|
||||
|
||||
# connect vlan3 to the second router
|
||||
|
|
|
@ -38,7 +38,7 @@ from ..state_machine import match_pdu, StateMachineGroup
|
|||
from ..time_machine import reset_time_machine, run_time_machine
|
||||
|
||||
from .helpers import (
|
||||
SnifferNode, NetworkLayerNode, RouterNode, ApplicationLayerNode,
|
||||
SnifferStateMachine, NetworkLayerStateMachine, RouterNode, ApplicationLayerStateMachine,
|
||||
ApplicationNode,
|
||||
)
|
||||
|
||||
|
@ -69,11 +69,11 @@ class TNetwork(StateMachineGroup):
|
|||
self.vlan1 = Network(name="vlan1", broadcast_address=LocalBroadcast())
|
||||
|
||||
# test device
|
||||
self.td = ApplicationLayerNode("1", self.vlan1)
|
||||
self.td = ApplicationLayerStateMachine("1", self.vlan1)
|
||||
self.append(self.td)
|
||||
|
||||
# sniffer node
|
||||
self.sniffer1 = SnifferNode("2", self.vlan1)
|
||||
self.sniffer1 = SnifferStateMachine("2", self.vlan1)
|
||||
self.append(self.sniffer1)
|
||||
|
||||
# add the network
|
||||
|
@ -86,7 +86,7 @@ class TNetwork(StateMachineGroup):
|
|||
self.app2 = ApplicationNode("4", self.vlan2)
|
||||
|
||||
# sniffer node
|
||||
self.sniffer2 = SnifferNode("5", self.vlan2)
|
||||
self.sniffer2 = SnifferStateMachine("5", self.vlan2)
|
||||
self.append(self.sniffer2)
|
||||
|
||||
# add the network
|
||||
|
|
|
@ -346,6 +346,30 @@ class TestRouter(unittest.TestCase):
|
|||
csm_10_3.start_state.timeout(1).success()
|
||||
csm_20_2.start_state.timeout(1).success()
|
||||
|
||||
def test_local_broadcast(self):
|
||||
"""Test that a node can send a message to all of the other nodes on
|
||||
the same network.
|
||||
"""
|
||||
if _debug: TestRouter._debug("test_local_broadcast")
|
||||
|
||||
# unpack the state machines
|
||||
csm_10_2, csm_10_3, csm_20_2, csm_20_3 = self.smg.state_machines
|
||||
|
||||
# make a broadcast PDU from network 10 node 1
|
||||
pdu = PDU(b'data',
|
||||
source=('192.168.10.2', 47808),
|
||||
destination=('192.168.10.255', 47808),
|
||||
)
|
||||
if _debug: TestVLAN._debug(" - pdu: %r", pdu)
|
||||
|
||||
# node 10-2 sends the pdu, node 10-3 gets pdu, nodes 20-2 and 20-3 dont
|
||||
csm_10_2.start_state.send(pdu).success()
|
||||
csm_10_3.start_state.receive(PDU,
|
||||
pduSource=('192.168.10.2', 47808),
|
||||
).success()
|
||||
csm_20_2.start_state.timeout(1).success()
|
||||
csm_20_3.start_state.timeout(1).success()
|
||||
|
||||
def test_remote_broadcast(self):
|
||||
"""Test that a node can send a message to all of the other nodes on
|
||||
a different network.
|
||||
|
|
Loading…
Reference in New Issue
Block a user