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 BBMDNode(_repr, ClientStateMachine): def __init__(self, address, vlan): if _debug: BBMDNode._debug("__init__ %r %r", address, vlan) ClientStateMachine.__init__(self) # save the name and address self.name = address self.address = Address(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: BBMDNode._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, self.bip, self.annexj, self.mux)
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)
class BIPBBMDStateMachine(ClientStateMachine): """This class sits on a BIPBBMD instance, the send() and receive() parameters are NPDUs. """ def __init__(self, address, vlan): if _debug: BIPBBMDStateMachine._debug("__init__ %r %r", address, vlan) ClientStateMachine.__init__(self) # save the name and address self.name = address self.address = Address(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: BIPBBMDStateMachine._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, self.bip, self.annexj, self.mux)
def main(): # parse the command line arguments parser = ArgumentParser(description=__doc__) # add an argument for interval parser.add_argument( 'localaddr', type=str, help='local address of the BBMD', ) # add an argument for interval parser.add_argument( 'bdtentry', type=str, nargs='*', help='list of addresses of peers', ) # now parse the arguments args = parser.parse_args() if _debug: _log.debug("initialization") if _debug: _log.debug(" - args: %r", args) local_address = Address(args.localaddr) if _debug: _log.debug(" - local_address: %r", local_address) # create a null client that will accept, but do nothing with upstream # packets from the BBMD null_client = NullClient() if _debug: _log.debug(" - null_client: %r", null_client) # create a BBMD, bound to the Annex J server on a UDP multiplexer bbmd = BIPBBMD(local_address) annexj = AnnexJCodec() multiplexer = UDPMultiplexer(local_address) # bind the layers together bind(null_client, bbmd, annexj, multiplexer.annexJ) # loop through the rest of the addresses for bdtentry in args.bdtentry: if _debug: _log.debug(" - bdtentry: %r", bdtentry) bdt_address = Address(bdtentry) bbmd.add_peer(bdt_address) if _debug: _log.debug(" - bbmd: %r", bbmd) _log.debug("running") run() _log.debug("fini")
def main(): # parse the command line arguments parser = ArgumentParser(description=__doc__) # add an argument for interval parser.add_argument('localaddr', type=str, help='local address of the BBMD', ) # add an argument for interval parser.add_argument('bdtentry', type=str, nargs='*', help='list of addresses of peers', ) # now parse the arguments args = parser.parse_args() if _debug: _log.debug("initialization") if _debug: _log.debug(" - args: %r", args) local_address = Address(args.localaddr) if _debug: _log.debug(" - local_address: %r", local_address) # create a null client that will accept, but do nothing with upstream # packets from the BBMD null_client = NullClient() if _debug: _log.debug(" - null_client: %r", null_client) # create a BBMD, bound to the Annex J server on a UDP multiplexer bbmd = BIPBBMD(local_address) annexj = AnnexJCodec() multiplexer = UDPMultiplexer(local_address) # bind the layers together bind(null_client, bbmd, annexj, multiplexer.annexJ) # loop through the rest of the addresses for bdtentry in args.bdtentry: if _debug: _log.debug(" - bdtentry: %r", bdtentry) bdt_address = Address(bdtentry) bbmd.add_peer(bdt_address) if _debug: _log.debug(" - bbmd: %r", bbmd) _log.debug("running") run() _log.debug("fini")
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()