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 __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)
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)
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)
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)
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 __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)
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)
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)
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 __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)
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)
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 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()
indx = sys.argv.index('--port') addr += ':' + sys.argv[indx + 1] del sys.argv[indx:indx + 2] _log.debug(" - addr: %r", addr) # a network service access point will be needed nsap = NetworkServiceAccessPoint() # give the NSAP a generic network layer service element nse = NetworkServiceElement() bind(nse, nsap) # create a generic BIP stack, bound to the Annex J server on the UDP multiplexer bip = BIPSimple() annexj = AnnexJCodec() udpmux = UDPMultiplexer(Address(addr)) # we need a way to make outgoing TCP connections and manage the proxy client service state tcpmux = TCPClientMultiplexer() # get the address of the server server_address = Address(sys.argv[1]) _log.debug(" - server_address: %r", server_address) # create a ProxyClientService proxy_client = ProxyClientService(tcpmux, server_address, testUser) # bind everything together bind(proxy_client, bip, annexj, udpmux.annexJ) _log.debug("running")
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 = {}
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)
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 = BIPForeign(bbmdAddress, bbmdTTL) self.annexj = AnnexJCodec() self.mux = UDPMultiplexer(self.localAddress, noBroadcast=True) # bind the bottom layers bind(self.bip, self.annexj, self.mux.annexJ) # bind the NSAP to the stack, no network number self.nsap.bind(self.bip) 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 = []