class VLANRouter: def __init__(self, local_address, local_network): if _debug: VLANRouter._debug("__init__ %r %r", local_address, local_network) # 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) # create a BBMD, bound to the Annex J server # on the UDP multiplexer # self.bip = BIPBBMD(local_address) # self.annexj = AnnexJCodec() # self.mux = UDPMultiplexer(local_address) #ADDED #from WhoIsIAmForeign ForeignApplication # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPForeign(Address('BBMD_ADDR'), 30) self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(local_address, noBroadcast=True) #end # self.bip.add_peer(Address(BBMD_ADDR)) #ADDED # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to the local network self.nsap.bind(self.bip, local_network, local_address)
class _VLANRouter(Logable): def __init__(self, local_address: Address, local_network: int): if _debug: # pylint: disable=no-member # type: ignore _VLANRouter._debug("__init__ %r %r", local_address, local_network) # 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) # create a BIPSimple, bound to the Annex J server # on the UDP multiplexer self.bip = BIPSimple(local_address) self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(local_address) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to the local network self.nsap.bind(self.bip, local_network, local_address) def bind(self, node: Node, address: int) -> None: self.nsap.bind(node, address) def start(self) -> None: # send network topology deferred(self.nse.i_am_router_to_network)
class ApplicationNode(Application, StateMachine): def __init__(self, localDevice, vlan): if _debug: ApplicationNode._debug("__init__ %r %r", localDevice, vlan) # build an address and save it self.address = Address(localDevice.objectIdentifier[1]) if _debug: ApplicationNode._debug(" - address: %r", self.address) # continue with initialization Application.__init__(self, localDevice, self.address) StateMachine.__init__(self, name=localDevice.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(localDevice) # 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) # create a node, added to the network self.node = Node(self.address, vlan) # bind the network service to the node, no network number self.nsap.bind(self.node) def send(self, apdu): if _debug: ApplicationNode._debug("send(%s) %r", self.name, apdu) # send the apdu down the stack self.request(apdu) def indication(self, apdu): if _debug: ApplicationNode._debug("indication(%s) %r", self.name, apdu) # let the state machine know the request was received self.receive(apdu) # allow the application to process it super(ApplicationNode, self).indication(apdu) def confirmation(self, apdu): if _debug: ApplicationNode._debug("confirmation(%s) %r", self.name, apdu) # forward the confirmation to the state machine self.receive(apdu)
class VLANRouter: def __init__(self): if _debug: VLANRouter._debug("__init__") # 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) def bind(self, vlan, address, net): if _debug: VLANRouter._debug("bind %r %r %r", vlan, address, net) # create a VLAN node for the router with the given address vlan_node = Node(Address(address)) # add it to the VLAN vlan.add_node(vlan_node) # bind the router stack to the vlan network through this node self.nsap.bind(vlan_node, net) if _debug: _log.debug(" - bound to vlan")
class ApplicationLayerStateMachine(ClientStateMachine): def __init__(self, address, vlan): if _debug: ApplicationLayerStateMachine._debug("__init__ %r %r", address, vlan) ClientStateMachine.__init__(self) # build a name, save the address self.name = "app @ %s" % (address, ) self.address = Address(address) # a network service access point will be needed self.nsap = NetworkServiceAccessPoint() if _debug: ApplicationLayerStateMachine._debug(" - nsap: %r", self.nsap) # bind this as a client of the network service access point bind(self, self.nsap) # create a node, added to the network self.node = Node(self.address, vlan) if _debug: ApplicationLayerStateMachine._debug(" - node: %r", self.node) # bind the stack to the local network self.nsap.bind(self.node)
class TestRouter(Logging): def __init__(self, localNetwork, localAddress): if _debug: TestRouter._debug("__init__ %r", localAddress) # 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) # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPSimple() self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(localAddress) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to localNetwork self.nsap.bind(self.bip, localNetwork, localAddress) # create a multiplexer for the service self.mux = TCPClientMultiplexer() # create the service, use 90 as the "hidden" network self.r2rService = RouterToRouterService(self.mux, self.nsap, 90)
class VLANRouter: def __init__(self, local_address, local_network, vlan_address, vlan_network): if _debug: VLANRouter._debug("__init__ %r %r %r %r", local_address, local_network, vlan_address, vlan_network) # 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) # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPSimple() self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(local_address) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to the local network self.nsap.bind(self.bip, local_network, local_address) # create a vlan node self.vlan_node = Node(vlan_address) # bind the stack to the vlan network self.nsap.bind(self.vlan_node, vlan_network)
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)
class ApplicationLayerNode(ApplicationServiceElement, ClientStateMachine): def __init__(self, address, vlan): if _debug: ApplicationLayerNode._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', int(address)), vendorIdentifier=999, ) # build an address and save it self.address = Address(address) if _debug: ApplicationLayerNode._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) # create a node, added to the network self.node = Node(self.address, vlan) if _debug: ApplicationLayerNode._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) self.receive(apdu) def confirmation(self, apdu): if _debug: ApplicationLayerNode._debug("confirmation %r %r", apdu) self.receive(apdu)
class VLANApplication(Application, WhoIsIAmServices, ReadWritePropertyServices): def __init__(self, vlan_device, vlan_address, aseID=None): if _debug: VLANApplication._debug("__init__ %r %r aseID=%r", vlan_device, vlan_address, aseID) Application.__init__(self, vlan_device, aseID=aseID) # 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(vlan_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) # create a vlan node at the assigned address self.vlan_node = Node(vlan_address) # bind the stack to the node, no network number self.nsap.bind(self.vlan_node) def request(self, apdu): if _debug: VLANApplication._debug("[%s]request %r", self.vlan_node.address, apdu) Application.request(self, apdu) def indication(self, apdu): if _debug: VLANApplication._debug("[%s]indication %r", self.vlan_node.address, apdu) Application.indication(self, apdu) def response(self, apdu): if _debug: VLANApplication._debug("[%s]response %r", self.vlan_node.address, apdu) Application.response(self, apdu) def confirmation(self, apdu): if _debug: VLANApplication._debug("[%s]confirmation %r", self.vlan_node.address, apdu) Application.confirmation(self, apdu)
class ApplicationNode(Application, WhoIsIAmServices, ReadWritePropertyServices): _startup_disabled = True def __init__(self, address, vlan): if _debug: ApplicationNode._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', int(address)), vendorIdentifier=999, ) # build an address and save it self.address = Address(address) if _debug: ApplicationNode._debug(" - address: %r", self.address) # continue with initialization Application.__init__(self, local_device) # 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) # create a node, added to the network self.node = Node(self.address, vlan) if _debug: ApplicationNode._debug(" - node: %r", self.node) # bind the stack to the local network self.nsap.bind(self.node)
class MSTPSimpleApplication(ApplicationIOController, WhoIsIAmServices, ReadWritePropertyServices): def __init__(self, localDevice, localAddress, deviceInfoCache=None, aseID=None): if _debug: MSTPSimpleApplication._debug("__init__ %r %r deviceInfoCache=%r aseID=%r", localDevice, localAddress, deviceInfoCache, aseID) ApplicationIOController.__init__(self, localDevice, deviceInfoCache, aseID=aseID) # local address might be useful for subclasses if isinstance(localAddress, Address): self.localAddress = localAddress else: self.localAddress = Address(localAddress) self.localDevice = localDevice # 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(localDevice) # 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) # create a generic MSTP stack, bound to the Annex J server # on the MSTP multiplexer self.mstp = MSTPSimple() self.mux = MSTPMultiplexer(self.localDevice, self.localAddress) # bind the bottom layers bind(self.mstp, self.mux.annexH) # bind the MSTP stack to the network, no network number self.nsap.bind(self.mstp) def close_socket(self): if _debug: MSTPSimpleApplication._debug("close_socket") # pass to the multiplexer, then down to the sockets self.mux.close_socket()
class TestProxyApplication(Application, Logging): def __init__(self, localDevice, localAddress, aseID=None): if _debug: TestProxyApplication._debug("__init__ %r %r aseID=%r", localDevice, localAddress, aseID) Application.__init__(self, localDevice, localAddress, aseID) # 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(localDevice) # 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) # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPSimple() self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(self.localAddress) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to network 5, the 'local' network self.nsap.bind(self.bip, 5, self.localAddress) # create a multiplexer for the service self.mux = TCPServerMultiplexer(self.localAddress) # proxy connections are bound to the nsap self.proxyServer = TestProxyServer(self.mux, self.nsap) def request(self, apdu): if _debug: TestProxyApplication._debug("request %r", apdu) Application.request(self, apdu) def confirmation(self, apdu): if _debug: TestProxyApplication._debug("confirmation %r", apdu)
class VLANApplication(Application, WhoIsIAmServices, ReadWritePropertyServices): def __init__(self, vlan_device, vlan_address, aseID=None): if _debug: VLANApplication._debug("__init__ %r %r aseID=%r", vlan_device, vlan_address, aseID) Application.__init__(self, vlan_device, vlan_address, aseID) # 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(vlan_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) # create a vlan node at the assigned address self.vlan_node = Node(vlan_address) # bind the stack to the node, no network number self.nsap.bind(self.vlan_node) def request(self, apdu): if _debug: VLANApplication._debug("[%s]request %r", self.vlan_node.address, apdu) Application.request(self, apdu) def indication(self, apdu): if _debug: VLANApplication._debug("[%s]indication %r", self.vlan_node.address, apdu) Application.indication(self, apdu) def response(self, apdu): if _debug: VLANApplication._debug("[%s]response %r", self.vlan_node.address, apdu) Application.response(self, apdu) def confirmation(self, apdu): if _debug: VLANApplication._debug("[%s]confirmation %r", self.vlan_node.address, apdu) Application.confirmation(self, apdu)
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, local_addr) #== 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, global_addr)
class VLANConsoleApplication( ApplicationIOController, WhoIsIAmServices, ReadWritePropertyServices, ): def __init__(self, vlan_device, vlan_address, aseID=None): if _debug: VLANConsoleApplication._debug("__init__ %r %r aseID=%r", vlan_device, vlan_address, aseID) global args # normal initialization ApplicationIOController.__init__(self, vlan_device, aseID=aseID) # optional read property multiple if args.rpm: self.add_capability(ReadWritePropertyMultipleServices) # 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(vlan_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) # create a vlan node at the assigned address self.vlan_node = Node(vlan_address) # bind the stack to the node, no network number, no addresss self.nsap.bind(self.vlan_node)
class MQTT2IPRouter: def __init__(self, lan, addr1, net1, addr2, net2): if _debug: MQTT2IPRouter._debug("__init__ %r %r %r %r %r", lan, addr1, net1, addr2, net2) global args # 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 # create an MQTT client self.s1_msap = bacpypes_mqtt.MQTTClient(lan, addr1, args.host, port=args.port, keepalive=args.keepalive) # create a service element for the client self.s1_mse = bacpypes_mqtt.MQTTServiceElement() bind(self.s1_mse, self.s1_msap) # bind to the MQTT network self.nsap.bind(self.s1_msap, net1) #== Second stack # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.s2_bip = BIPSimple() self.s2_annexj = AnnexJCodec() self.s2_mux = UDPMultiplexer(addr2) # bind the bottom layers bind(self.s2_bip, self.s2_annexj, self.s2_mux.annexJ) # bind the BIP stack to the local network self.nsap.bind(self.s2_bip, net2)
class TestBBMD(BIPBBMD): def __init__(self, addr): if _debug: TestBBMD._debug("TestBBMD %r", addr) BIPBBMD.__init__(self, addr) # save the address self.address = addr # make the lower layers self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(self.address) # bind the bottom layers bind(self, self.annexj, self.mux.annexJ) # give this a generic network layer service access point and element self.nsap = NetworkServiceAccessPoint() self.nse = NetworkServiceElement() self.nsap.bind(self) bind(self.nse, self.nsap)
class IP2IPRouter: def __init__(self, addr1, net1, addr2, net2): if _debug: IP2IPRouter._debug("__init__ %r %r %r %r", addr1, net1, addr2, 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 # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.s1_bip = BIPSimple() self.s1_annexj = AnnexJCodec() self.s1_mux = UDPMultiplexer(addr1) # 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 # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.s2_bip = BIPSimple() self.s2_annexj = AnnexJCodec() self.s2_mux = UDPMultiplexer(addr2) # bind the bottom layers bind(self.s2_bip, self.s2_annexj, self.s2_mux.annexJ) # bind the BIP stack to the local network self.nsap.bind(self.s2_bip, net2, addr2)
class IP2IPRouter: def __init__(self, addr1, net1, addr2, net2): if _debug: IP2IPRouter._debug("__init__ %r %r %r %r", addr1, net1, addr2, 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 # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.s1_bip = BIPSimple() self.s1_annexj = AnnexJCodec() self.s1_mux = UDPMultiplexer(addr1) # 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 # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.s2_bip = BIPSimple() self.s2_annexj = AnnexJCodec() self.s2_mux = UDPMultiplexer(addr2) # bind the bottom layers bind(self.s2_bip, self.s2_annexj, self.s2_mux.annexJ) # bind the BIP stack to the local network self.nsap.bind(self.s2_bip, net2)
class VLANRouter: def __init__(self, local_address, local_network, foreign_address, bbmd_ttl=30, rebootQueue=None): if _debug: VLANRouter._debug("__init__ %r %r", local_address, local_network) if isinstance(local_address, Address): self.local_address = local_address else: self.local_address = Address(local_address) if isinstance(foreign_address, Address): self.foreign_address = foreign_address else: self.foreign_address = Address(foreign_address) # 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) # create a BBMD, bound to the Annex J server # on the UDP multiplexer # from WhoIsIAmForeign ForeignApplication # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPForeign(self.foreign_address, bbmd_ttl) # self.bip = BIPForeign(Address('10.166.1.72'), 30) # self.bip = BIPForeign(Address('192.168.1.10'), 30) # self.bip = BIPForeign(Address('130.91.139.99'), 30) self.annexj = AnnexJCodec() # noBroadcast=True stops bcast to local ntwrk self.mux = UDPMultiplexer(self.local_address, noBroadcast=True, rebootQueue=rebootQueue) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to the local network self.nsap.bind(self.bip, local_network, self.local_address)
class VLANRouter: def __init__(self, lan, addr1, net1): if _debug: VLANRouter._debug("__init__ %r %r %r", lan, addr1, net1) # 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) # create an MQTT client self.msap = bacpypes_mqtt.MQTTClient( lan, addr1, args.host, port=args.port, keepalive=args.keepalive ) # create a service element for the client self.mse = bacpypes_mqtt.MQTTServiceElement() bind(self.mse, self.msap) # bind to the MQTT network self.nsap.bind(self.msap, net1)
class VLANRouter: def __init__(self, local_address, local_network): if _debug: VLANRouter._debug("__init__ %r %r", local_address, local_network) # 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) # create a BBMD, bound to the Annex J server # on the UDP multiplexer self.bip = BIPBBMD(local_address) self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(local_address) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to the local network self.nsap.bind(self.bip, local_network, local_address)
class RouterNode: def __init__(self): if _debug: RouterNode._debug("__init__") # 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) def add_network(self, address, vlan, net): if _debug: RouterNode._debug("add_network %r %r %r", address, vlan, net) # convert the address to an Address address = Address(address) # create a node, added to the network node = Node(address, vlan) if _debug: RouterNode._debug(" - node: %r", node) # bind the BIP stack to the local network self.nsap.bind(node, net)
class VLANApplication(Application, WhoIsIAmServices, ReadWritePropertyServices, ReadWritePropertyMultipleServices): def __init__(self, vlan_device, vlan_address, aseID=None, register_reader=None): if _debug: VLANApplication._debug("__init__ %r %r aseID=%r", vlan_device, vlan_address, aseID) Application.__init__(self, vlan_device, vlan_address, aseID) # 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(vlan_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) # create a vlan node at the assigned address self.vlan_node = Node(vlan_address) # bind the stack to the node, no network number self.nsap.bind(self.vlan_node) # set register reader class that will look into block of registers for all associated slaves self.register_reader = register_reader def request(self, apdu): if _debug: VLANApplication._debug("[%s]request %r", self.vlan_node.address, apdu) Application.request(self, apdu) def indication(self, apdu): if _debug: VLANApplication._debug("[%s]indication %r", self.vlan_node.address, apdu) Application.indication(self, apdu) def response(self, apdu): if _debug: VLANApplication._debug("[%s]response %r", self.vlan_node.address, apdu) Application.response(self, apdu) def confirmation(self, apdu): if _debug: VLANApplication._debug("[%s]confirmation %r", self.vlan_node.address, apdu) Application.confirmation(self, apdu) #ADDED def do_WhoIsRequest(self, apdu): print('whoisrequest from', apdu.pduSource) if apdu.pduSource == Address('0:130.91.137.90'): apdu.pduSource = GlobalBroadcast() # apdu.pduSource = GlobalBroadcast() # global or local broadcast? WhoIsIAmServices.do_WhoIsRequest(self, apdu) def add_object(self, obj): Application.add_object(self, obj) if obj.__class__.__name__ == 'ModbusAnalogInputObject': obj.set_present_value_register_reader(self.register_reader)
class VLANApplication( ApplicationIOController, WhoIsIAmServices, ReadWritePropertyServices, ): def __init__(self, vlan_device, vlan_address, aseID=None): if _debug: VLANApplication._debug("__init__ %r %r aseID=%r", vlan_device, vlan_address, aseID) ApplicationIOController.__init__(self, vlan_device, vlan_address, aseID=aseID) # 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(vlan_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) # create a vlan node at the assigned address self.vlan_node = Node(vlan_address) # bind the stack to the node, no network number self.nsap.bind(self.vlan_node, address=vlan_address) # keep track of requests to line up responses self._request = None if _debug: VLANApplication._debug(" - nsap.local_address: %r", self.nsap.local_address) def request(self, apdu): if _debug: VLANApplication._debug("request %r", apdu) if _debug: VLANApplication._debug(" - nsap.local_address: %r", self.nsap.local_address) # save a copy of the request self._request = apdu # forward it along super(VLANApplication, self).request(apdu) def indication(self, apdu): if _debug: VLANApplication._debug("indication %r", apdu) if (isinstance(self._request, WhoIsRequest)) and (isinstance(apdu, IAmRequest)): device_type, device_instance = apdu.iAmDeviceIdentifier if device_type != 'device': raise DecodingError("invalid object type") if (self._request.deviceInstanceRangeLowLimit is not None) and \ (device_instance < self._request.deviceInstanceRangeLowLimit): pass elif (self._request.deviceInstanceRangeHighLimit is not None) and \ (device_instance > self._request.deviceInstanceRangeHighLimit): pass else: # print out the contents sys.stdout.write('pduSource = ' + repr(apdu.pduSource) + '\n') sys.stdout.write('iAmDeviceIdentifier = ' + str(apdu.iAmDeviceIdentifier) + '\n') sys.stdout.write('maxAPDULengthAccepted = ' + str(apdu.maxAPDULengthAccepted) + '\n') sys.stdout.write('segmentationSupported = ' + str(apdu.segmentationSupported) + '\n') sys.stdout.write('vendorID = ' + str(apdu.vendorID) + '\n') sys.stdout.flush() # forward it along super(VLANApplication, self).indication(apdu) def response(self, apdu): if _debug: VLANApplication._debug("[%s]response %r", self.vlan_node.address, apdu) super(VLANApplication, self).response(apdu) def confirmation(self, apdu): if _debug: VLANApplication._debug("[%s]confirmation %r", self.vlan_node.address, apdu) super(VLANApplication, self).confirmation(apdu)
class BAC0BBMDDeviceApplication( common_mixin, ApplicationIOController, WhoIsIAmServices, WhoHasIHaveServices, ReadWritePropertyServices, ReadWritePropertyMultipleServices, ChangeOfValueServices, ): """ Defines a basic BACnet/IP application to process BACnet requests. :param *args: local object device, local IP address See BAC0.scripts.BasicScript for more details. """ bdt = [] def __init__( self, localDevice, localAddress, bdtable=[], deviceInfoCache=None, aseID=None, iam_req=None, subscription_contexts=None, ): self.bdtable = bdtable null_client = NullClient() ApplicationIOController.__init__( self, localDevice, deviceInfoCache, aseID=aseID ) self.iam_req = iam_req # local address might be useful for subclasses if isinstance(localAddress, Address): self.localAddress = localAddress else: self.localAddress = Address(localAddress) # 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(localDevice) # 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 = NetworkServiceElementWithRequests() bind(self.nse, self.nsap) # bind the top layers bind(self, self.asap, self.smap, self.nsap) # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPBBMD(self.localAddress) self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(self.localAddress, noBroadcast=True) # bind the bottom layers # bind(self.bip, self.annexj, self.mux.annexJ) bind(null_client, self.bip, self.annexj, self.mux.annexJ) if self.bdtable: for bdtentry in self.bdtable: self.add_peer(bdtentry) # bind the NSAP to the stack, no network number self.nsap.bind(self.bip) self.i_am_counter = defaultdict(int) self.i_have_counter = defaultdict(int) self.who_is_counter = defaultdict(int) # keep track of requests to line up responses self._request = None self._last_i_am_received = [] self._last_i_have_received = [] # to support CoV self.subscription_contexts = subscription_contexts def add_peer(self, address): try: bdt_address = Address(address) self.bip.add_peer(bdt_address) except Exception: raise def remove_peer(self, address): try: bdt_address = Address(address) self.bip.remove_peer(bdt_address) except Exception: raise def close_socket(self): # pass to the multiplexer, then down to the sockets self.mux.close_socket()
class VLANApplication(Application, WhoIsIAmServices, ReadWritePropertyServices): def __init__(self, objectName, deviceInstance, address, aseID=None): if _debug: VLANApplication._debug("__init__ %r %r %r aseID=%r", objectName, deviceInstance, address, aseID) # make an address vlan_address = Address(address) _log.debug(" - vlan_address: %r", vlan_address) # make a device object vlan_device = LocalDeviceObject( objectName=objectName, objectIdentifier=("device", deviceInstance), maxApduLengthAccepted=1024, segmentationSupported="noSegmentation", vendorIdentifier=15, ) _log.debug(" - vlan_device: %r", vlan_device) # continue with the initialization Application.__init__(self, vlan_device, vlan_address, aseID) # 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(vlan_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) # create a vlan node at the assigned address self.vlan_node = Node(vlan_address) if _debug: VLANApplication._debug(" - vlan_node: %r", self.vlan_node) # bind the stack to the node, no network number self.nsap.bind(self.vlan_node) if _debug: VLANApplication._debug(" - node bound") def request(self, apdu): if _debug: VLANApplication._debug("[%s]request %r", self.localDevice.objectName, apdu) Application.request(self, apdu) def indication(self, apdu): if _debug: VLANApplication._debug("[%s]indication %r", self.localDevice.objectName, apdu) Application.indication(self, apdu) def response(self, apdu): if _debug: VLANApplication._debug("[%s]response %r", self.localDevice.objectName, apdu) Application.response(self, apdu) def confirmation(self, apdu): if _debug: VLANApplication._debug("[%s]confirmation %r", self.localDevice.objectName, apdu)
class ReadPointListApplication(Application, WhoIsIAmServices, ReadWritePropertyServices, RecurringTask): def __init__(self, localDevice, localAddress, deviceInfoCache=None, aseID=None): if _debug: ReadPointListApplication._debug( "__init__ %r %r deviceInfoCache=%r aseID=%r", localDevice, localAddress, deviceInfoCache, aseID) global args Application.__init__(self, localDevice, deviceInfoCache, aseID=aseID) RecurringTask.__init__(self, args.interval * 1000) # local address might be useful for subclasses if isinstance(localAddress, Address): self.localAddress = localAddress else: self.localAddress = Address(localAddress) # 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(localDevice) # 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) # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPSimple() self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(self.localAddress) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to the network, no network number self.nsap.bind(self.bip) # install the task self.install_task() # timer self.start_time = None # pending requests self.pending_requests = {} def process_task(self): if _debug: ReadPointListApplication._debug("process_task") global point_list # we might not have finished from the last round if self.pending_requests: if _debug: ReadPointListApplication._debug(" - %d pending", len(self.pending_requests)) return # start the clock self.start_time = _time() # make a copy of the point list and shuffle it point_list_copy = _copy(point_list) shuffle(point_list_copy) # loop through the points for addr, obj_type, obj_inst, prop_id in point_list_copy: # build a request request = ReadPropertyRequest( objectIdentifier=(obj_type, obj_inst), propertyIdentifier=prop_id, ) request.pduDestination = Address(addr) if _debug: ReadPointListApplication._debug(" - request: %r", request) # send the request self.request(request) # get the destination address from the pdu request_key = request.pduDestination, request.apduInvokeID if _debug: ReadPointListApplication._debug(" - request_key: %r", request_key) # make sure it's unused if request_key in self.pending_requests: raise RuntimeError("request key already used: %r" % (request_key, )) # add this to pending requests self.pending_requests[request_key] = request def confirmation(self, apdu): if _debug: ReadPointListApplication._debug("confirmation %r", apdu) # get the source address from the pdu request_key = apdu.pduSource, apdu.apduInvokeID if _debug: ReadPointListApplication._debug(" - request_key: %r", request_key) # make sure it's unused if request_key not in self.pending_requests: raise RuntimeError("request missing: %r" % (request_key, )) # this is no longer pending del self.pending_requests[request_key] # we could be done with this interval if not self.pending_requests: elapsed_time = _time() - self.start_time if _debug: ReadPointListApplication._debug( " - completed interval, %r seconds", elapsed_time)
class BAC0Application( ApplicationIOController, WhoIsIAmServices, ReadWritePropertyServices, ReadWritePropertyMultipleServices, ): """ Defines a basic BACnet/IP application to process BACnet requests. :param *args: local object device, local IP address See BAC0.scripts.BasicScript for more details. """ def __init__( self, localDevice, localAddress, bbmdAddress=None, bbmdTTL=0, deviceInfoCache=None, aseID=None, iam_req=None, ): ApplicationIOController.__init__(self, localDevice, deviceInfoCache, aseID=aseID) self.iam_req = iam_req # local address might be useful for subclasses if isinstance(localAddress, Address): self.localAddress = localAddress else: self.localAddress = Address(localAddress) # 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(localDevice) # 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 = NetworkServiceElementWithRequests() bind(self.nse, self.nsap) # bind the top layers bind(self, self.asap, self.smap, self.nsap) # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPSimple() self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(self.localAddress) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to the network, no network number self.nsap.bind(self.bip, address=self.localAddress) self.i_am_counter = defaultdict(int) self.who_is_counter = defaultdict(int) # keep track of requests to line up responses self._request = None self._last_i_am_received = [] def do_IAmRequest(self, apdu): """Given an I-Am request, cache it.""" self._log.debug("do_IAmRequest {!r}".format(apdu)) # build a key from the source, just use the instance number key = (str(apdu.pduSource), apdu.iAmDeviceIdentifier[1]) self.i_am_counter[key] += 1 self._last_i_am_received.append(key) def do_WhoIsRequest(self, apdu): """Respond to a Who-Is request.""" # build a key from the source and parameters key = ( str(apdu.pduSource), apdu.deviceInstanceRangeLowLimit, apdu.deviceInstanceRangeHighLimit, ) self._log.debug("do_WhoIsRequest from {} | {} to {}".format( key[0], key[1], key[2])) # count the times this has been received self.who_is_counter[key] += 1 low_limit = key[1] high_limit = key[2] # count the times this has been received self.who_is_counter[key] += 1 if low_limit is not None: if self.localDevice.objectIdentifier[1] < low_limit: return if high_limit is not None: if self.localDevice.objectIdentifier[1] > high_limit: return # generate an I-Am self._log.debug("Responding to Who is by a Iam") self.iam_req.pduDestination = apdu.pduSource iocb = IOCB(self.iam_req) # make an IOCB deferred(self.request_io, iocb) def close_socket(self): # pass to the multiplexer, then down to the sockets self.mux.close_socket() def request(self, apdu): # save a copy of the request self._request = apdu # forward it along super(BAC0Application, self).request(apdu)
class MQTTApplication(ApplicationIOController, WhoIsIAmServices, ReadWritePropertyServices): def __init__(self, localDevice, lan, localAddress, deviceInfoCache=None, aseID=None): if _debug: MQTTApplication._debug( "__init__ %r %r %r deviceInfoCache=%r aseID=%r", localDevice, lan, localAddress, deviceInfoCache, aseID) ApplicationIOController.__init__(self, localDevice, localAddress, deviceInfoCache, aseID=aseID) global args # local address might be useful for subclasses if isinstance(localAddress, str): localAddress = Address(localAddress) if len(localAddress.addrAddr) != bacpypes_mqtt.ADDRESS_LENGTH: raise ValueError("local address must be %d octets" % (bacpypes_mqtt.ADDRESS_LENGTH, )) self.localAddress = localAddress # 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(localDevice) # 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) # create an MQTT client self.msap = bacpypes_mqtt.MQTTClient(lan, localAddress, args.host, port=args.port, keepalive=args.keepalive) # create a service element for the client self.mse = bacpypes_mqtt.MQTTServiceElement() bind(self.mse, self.msap) # bind the stack to the virtual network, no network number self.nsap.bind(self.msap) # keep track of requests to line up responses self._request = None def request(self, apdu): if _debug: MQTTApplication._debug("request %r", apdu) # save a copy of the request self._request = apdu # forward it along super(MQTTApplication, self).request(apdu) def indication(self, apdu): if _debug: MQTTApplication._debug("indication %r", apdu) if (isinstance(self._request, WhoIsRequest)) and (isinstance( apdu, IAmRequest)): device_type, device_instance = apdu.iAmDeviceIdentifier if (self._request.deviceInstanceRangeLowLimit is not None) and \ (device_instance < self._request.deviceInstanceRangeLowLimit): pass elif (self._request.deviceInstanceRangeHighLimit is not None) and \ (device_instance > self._request.deviceInstanceRangeHighLimit): pass else: # print out the contents sys.stdout.write('pduSource = ' + repr(apdu.pduSource) + '\n') sys.stdout.write('iAmDeviceIdentifier = ' + str(apdu.iAmDeviceIdentifier) + '\n') sys.stdout.write('maxAPDULengthAccepted = ' + str(apdu.maxAPDULengthAccepted) + '\n') sys.stdout.write('segmentationSupported = ' + str(apdu.segmentationSupported) + '\n') sys.stdout.write('vendorID = ' + str(apdu.vendorID) + '\n') sys.stdout.flush() # forward it along super(MQTTApplication, self).indication(apdu) def response(self, apdu): if _debug: MQTTApplication._debug("response %r", apdu) # forward it along super(MQTTApplication, self).response(apdu) def confirmation(self, apdu): if _debug: MQTTApplication._debug("confirmation %r", apdu) # forward it along super(MQTTApplication, self).confirmation(apdu)
class DiscoverApplication(ApplicationIOController, WhoIsIAmServices, ReadWritePropertyServices): def __init__(self, localDevice, localAddress, deviceInfoCache=None, aseID=None): if _debug: DiscoverApplication._debug( "__init__ %r %r deviceInfoCache=%r aseID=%r", localDevice, localAddress, deviceInfoCache, aseID) ApplicationIOController.__init__(self, localDevice, localAddress, deviceInfoCache, aseID=aseID) # local address might be useful for subclasses if isinstance(localAddress, Address): self.localAddress = localAddress else: self.localAddress = Address(localAddress) # 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(localDevice) # 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 = DiscoverNetworkServiceElement() bind(self.nse, self.nsap) # bind the top layers bind(self, self.asap, self.smap, self.nsap) # create a generic BIP stack, bound to the Annex J server # on the UDP multiplexer self.bip = BIPSimple() self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(self.localAddress) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the BIP stack to the network, no network number self.nsap.bind(self.bip, address=self.localAddress) # keep track of requests to line up responses self._request = None def close_socket(self): if _debug: DiscoverApplication._debug("close_socket") # pass to the multiplexer, then down to the sockets self.mux.close_socket() def request(self, apdu): if _debug: DiscoverApplication._debug("request %r", apdu) # save a copy of the request self._request = apdu # forward it along super(DiscoverApplication, self).request(apdu) def indication(self, apdu): if _debug: DiscoverApplication._debug("indication %r", apdu) # forward it along super(DiscoverApplication, self).indication(apdu) def response(self, apdu): if _debug: DiscoverApplication._debug("response %r", apdu) # forward it along super(DiscoverApplication, self).response(apdu) def confirmation(self, apdu): if _debug: DiscoverApplication._debug("confirmation %r", apdu) # forward it along super(DiscoverApplication, self).confirmation(apdu) def do_IAmRequest(self, apdu): if _debug: DiscoverApplication._debug("do_IAmRequest %r", apdu) if not isinstance(self._request, WhoIsRequest): if _debug: DiscoverApplication._debug(" - no pending who-is") return device_instance = apdu.iAmDeviceIdentifier[1] if (self._request.deviceInstanceRangeLowLimit is not None) and \ (device_instance < self._request.deviceInstanceRangeLowLimit): return if (self._request.deviceInstanceRangeHighLimit is not None) and \ (device_instance > self._request.deviceInstanceRangeHighLimit): return # print out something if interactive: print("{} @ {}".format(device_instance, apdu.pduSource)) # update the snapshot database snapshot.upsert( apdu.iAmDeviceIdentifier[1], '-', 'address', str(apdu.pduSource), ) snapshot.upsert( apdu.iAmDeviceIdentifier[1], '-', 'maxAPDULengthAccepted', str(apdu.maxAPDULengthAccepted), ) snapshot.upsert( apdu.iAmDeviceIdentifier[1], '-', 'segmentationSupported', apdu.segmentationSupported, )
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)