def test_whoIs(self): request = WhoIsRequest( deviceInstanceRangeLowLimit=500, deviceInstanceRangeHighLimit=50000 ) apdu = APDU() request.encode(apdu) pdu = PDU() apdu.encode(pdu) buf_size = 1024 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto(pdu.pduData, self.address) data = s.recvfrom(buf_size) s.close() received_data = data[0] expected = IAmRequest() expected.pduDestination = GlobalBroadcast() expected.iAmDeviceIdentifier = 36113 expected.maxAPDULengthAccepted = 1024 expected.segmentationSupported = "segmentedBoth" expected.vendorID = 15 exp_apdu = APDU() expected.encode(exp_apdu) exp_pdu = PDU() exp_apdu.encode(exp_pdu) self.assertEqual(exp_pdu.pduData, received_data)
def ping_device(self, target_address): """Ping a device with a whois to potentially setup routing.""" request = WhoIsRequest() request.pduDestination = Address(target_address) iocb = IOCB(request, self.async_call) self.this_application.submit_request(iocb)
def whois_request(args, console=None): """ This function creates a whois request. Usage: whois [ <address> ] [ <lowlimit> <highlimit> ] :param args: list of parameters :param console: console object :return: request """ # create request request = WhoIsRequest() # check if address was set if len(args) in (1, 3): request.pduDestination = Address(args[0]) del args[0] # send broadcast otherwise else: request.pduDestination = GlobalBroadcast() # check if limits were set if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[0]) # return created request return request
def test_whoIs(self): request = WhoIsRequest(deviceInstanceRangeLowLimit=500, deviceInstanceRangeHighLimit=50000) apdu = APDU() request.encode(apdu) pdu = PDU() apdu.encode(pdu) buf_size = 1024 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto(pdu.pduData, ('127.0.0.1', self.bacnet_server.server.server_port)) data = s.recvfrom(buf_size) received_data = data[0] expected = IAmRequest() expected.pduDestination = GlobalBroadcast() expected.iAmDeviceIdentifier = 36113 expected.maxAPDULengthAccepted = 1024 expected.segmentationSupported = 'segmentedBoth' expected.vendorID = 15 exp_apdu = APDU() expected.encode(exp_apdu) exp_pdu = PDU() exp_apdu.encode(exp_pdu) self.assertEquals(exp_pdu.pduData, received_data)
def do_whois(self, args): """whois [ <addr>] [ <lolimit> <hilimit> ]""" args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_whois %r", args) try: # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) if _debug: WhoIsIAmConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: WriteSomethingConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) except Exception as err: WhoIsIAmConsoleCmd._exception("exception: %r", err)
def broadcast(): try: device_list = list() localaddress = list() ips = getIPs() print "found local ip as ", ips for ip in ips: str(ip) localaddress = ip + "/24" # make a device object this_device = LocalDeviceObject( objectName="BEMOSS", objectIdentifier= 599, #change if there exists a bacnet device with same identifier maxApduLengthAccepted=1024, segmentationSupported="segmentedBoth", vendorIdentifier=99, ) # Device application this_application = Application(this_device, localaddress) request = WhoIsRequest() request.pduDestination = GlobalBroadcast() def time_out(): time.sleep(5) stop() thread = threading.Thread(target=time_out) thread.start() this_application.request(request) this_application.found_address = list() this_application.found_deviceidentifier = list() run() #time.sleep(10) this_application.release = True this_application.update = False address, deviceidentifier = this_application.updator() todelete = list() for i in range(0, len(deviceidentifier)): if deviceidentifier[i] == 0: todelete.append(i) for i in todelete: del address[i], deviceidentifier[ i] #Deleting identified bacnet router Remote_address = list(set(address)) #Removing repeatition Identifier = list(set(deviceidentifier)) #Removing repeatition print "destination address list is ", Remote_address print "object instance of that address", Identifier return this_application, Remote_address, Identifier except Exception, e: _log.exception("an error has occurred: %s", e) return None
def get_device(self, address): """ This function returns device identifier if known. :param address: device address :return: device identifier """ # check if address is known if not 'id' in self.known_devices.get(address, {}): # create request request = WhoIsRequest() # set destination to address request.pduDestination = Address(address) self._debug(' - request: %s', request) # queue request self.requests.put(request) # exit return # get device device = self.known_devices[address] # return device return device['id']
def ping_device(self, target_address, device_id): """Ping a device with a whois to potentially setup routing.""" _log.debug("Pinging " + target_address) request = WhoIsRequest() request.deviceInstanceRangeLowLimit = device_id request.deviceInstanceRangeHighLimit = device_id request.pduDestination = GlobalBroadcast() iocb = IOCB(request, self.async_call) self.this_application.submit_request(iocb)
def ping_target(self, address): #Some devices (mostly RemoteStation addresses behind routers) will not be reachable without # first establishing the route to the device. Sending a directed WhoIsRequest is will # settle that for us when the response comes back. request = WhoIsRequest() request.pduDestination = address iocb = IOCB(request) this_application.submit_request(iocb)
def whois(self, *args): """ Build a WhoIs request :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional** :returns: discoveredDevices as a defaultdict(int) Example:: whois() # WhoIs broadcast globally. Every device will respond with an IAm whois('2:5') # WhoIs looking for the device at (Network 2, Address 5) whois('10 1000') # WhoIs looking for devices in the ID range (10 - 1000) """ if not self._started: raise ApplicationNotStarted("BACnet stack not running - use startApp()") if args: args = args[0].split() msg = args if args else "any" self._log.debug("do_whois {!r}".format(msg)) # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) self._log.debug("{:>12} {}".format("- request:", request)) iocb = IOCB(request) # make an IOCB # pass to the BACnet stack self.this_application.request_io(iocb) iocb.wait() # Wait for BACnet response if iocb.ioResponse: # successful response apdu = iocb.ioResponse if iocb.ioError: # unsuccessful: error/reject/abort pass self.discoveredDevices = self.this_application.i_am_counter return self.discoveredDevices
def get_iam(app, device_id, target_address = None): request = WhoIsRequest() request.deviceInstanceRangeLowLimit = device_id request.deviceInstanceRangeHighLimit = device_id if target_address is not None: request.pduDestination = Address(target_address) else: request.pduDestination = GlobalBroadcast() result = app.make_request(request, expected_device_id=device_id) return result
def test_local_broadcast(self): """Local broadcast, no matching device.""" if _debug: TestUnconfirmedRequests._debug("test_local_broadcast") # create a network tnet = TNetwork() # test device sends request, no response tnet.td.start_state.doc("1-1-0") \ .send(WhoIsRequest( destination=LocalBroadcast(), )).doc("1-1-1") \ .timeout(3).doc("1-1-2") \ .success() # sniffer on network 1 sees the request and nothing else tnet.sniffer1.start_state.doc("1-2-0") \ .receive(PDU, pduData=xtob('01.00' # version, application layer '10 08' # unconfirmed Who-Is ) ).doc("1-2-1") \ .timeout(3).doc("1-2-2") \ .success() # no acitivity on network 2 tnet.sniffer2.start_state.success() # run the group tnet.run()
def test_remote_broadcast_3(self): """Remote broadcast, nonexistent network.""" if _debug: TestUnconfirmedRequests._debug("test_remote_broadcast_3") # create a network tnet = TNetwork() # test device sends request and sees the response tnet.td.start_state.doc("3-1-0") \ .send(WhoIsRequest( destination=RemoteBroadcast(3), )).doc("3-1-1") \ .success() # sniffer on network 1 sees the request and the response tnet.sniffer1.start_state.doc("3-2-0") \ .receive(PDU, pduData=xtob('01.80.00.00.03' # who is router to network ) ).doc("3-2-1") \ .timeout(3).doc("3-2-3") \ .success() # network 2 sees local broadcast looking for network 3 tnet.sniffer2.start_state.doc('3-3-0') \ .receive(PDU, pduData=xtob('01.88.00.01.01.01.00.00.03' ) ).doc("3-3-1") \ .timeout(3).doc("3-3-2") \ .success() # run the group tnet.run()
def test_disable(self): """Test.""" if _debug: TestDeviceCommunicationControl._debug("test_disable") # create a network anet = ApplicationNetwork("test_disable") # add the service capability to the IUT anet.iut.add_capability(WhoIsIAmServices) anet.iut.add_capability(DeviceCommunicationControlServices) # test sequence anet.td.start_state.doc("7-2-0") \ .send(DeviceCommunicationControlRequest( destination=anet.iut.address, enableDisable='disable', )).doc("7-2-1") \ .receive(SimpleAckPDU).doc("7-2-2") \ .send(WhoIsRequest(destination=anet.vlan.broadcast_address)).doc("7-2-3") \ .timeout(10).doc("7-2-4") \ .success() # no IUT application layer matching anet.iut.start_state.success() # run the group anet.run()
def test_disable_initiation(self): """Test disabling initiation. After the DCC request send the IUT a WhoIsRequest and verify that the IAmRequest makes it back. """ if _debug: TestDeviceCommunicationControl._debug("test_disable_initiation") # create a network anet = ApplicationNetwork("test_disable_initiation") # add the service capability to the IUT anet.iut.add_capability(WhoIsIAmServices) anet.iut.add_capability(DeviceCommunicationControlServices) # test sequence anet.td.start_state.doc("7-3-0") \ .send(DeviceCommunicationControlRequest( destination=anet.iut.address, enableDisable='disableInitiation', )).doc("7-3-1") \ .receive(SimpleAckPDU).doc("7-3-2") \ .send(WhoIsRequest(destination=anet.vlan.broadcast_address)).doc("7-3-3") \ .receive(IAmRequest, pduSource=anet.iut.address).doc("7-3-4") \ .success() # no IUT application layer matching anet.iut.start_state.success() # run the group anet.run()
def test_whois_range(self): """Test a WhoIs, included range.""" if _debug: TestWhoIsIAm._debug("test_whois_range") # create a network anet = ApplicationNetwork("test_whois_range") # add the service capability to the IUT anet.iut.add_capability(WhoIsIAmServices) # send a Who-Is, get back an I-Am anet.td.start_state.doc("4-1-0") \ .send(WhoIsRequest( destination=anet.vlan.broadcast_address, deviceInstanceRangeLowLimit=19, deviceInstanceRangeHighLimit=21, )).doc("4-1-1") \ .receive(IAmRequest, pduSource=anet.iut.address).doc("4-1-2") \ .success() # no IUT application layer matching anet.iut.start_state.success() # run the group anet.run()
def do_whois(self, args): """whois [ <addr> ] [ <lolimit> <hilimit> ]""" args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_whois %r", args) try: # gather the parameters request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): addr = Address(args[0]) del args[0] else: addr = GlobalBroadcast() if len(args) == 2: lolimit = int(args[0]) hilimit = int(args[1]) else: lolimit = hilimit = None # code lives in the device service this_application.who_is(lolimit, hilimit, addr) except Exception as error: WhoIsIAmConsoleCmd._exception("exception: %r", error)
def discover_devices(self, timeout=5): """ Send a WhoIsRequest and wait for timeout seconds to receive all responses. """ self.devices = {} req = WhoIsRequest( ) # How does this know it needs to store at devices? req.pduDestination = Address( "255.255.255.255") # Global Broadcast address iocb = IOCB(req) self.request_io(iocb) iocb.set_timeout(5) iocb.wait() time.sleep( timeout) # wait for 5 seconds so all the responses are received. self.update_device_metadata(self.devices) return self.devices
def whois(self, *args): """ Creation of a whois requests Requets is given to the app :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional** :returns: discoveredDevices as a defaultdict(int) Example:: whois() #will create a broadcast whois request and every device will response by a Iam whois('2:5') #will create a whois request aimed at device 5 whois('10 1000') #will create a whois request looking for device ID 10 to 1000 """ if args: args = args[0].split() if _debug: WhoisIAm._debug("do_whois %r" % args) try: # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) if _debug: WhoisIAm._debug(" - request: %r" % request) # give it to the application self.this_application.request(request) except Exception as e: WhoisIAm._exception("exception: %r" % e) self.discoveredDevices = self.this_application.i_am_counter return self.discoveredDevices
def who_is(self, low_device_id=None, high_device_id=None, target_address=None): _log.debug("Sending WhoIs: low_id: {low} high: {high} address: {address}".format(low=low_device_id, high=high_device_id, address=target_address)) request = WhoIsRequest() if low_device_id is not None: request.deviceInstanceRangeLowLimit = low_device_id if high_device_id is not None: request.deviceInstanceRangeHighLimit = high_device_id if target_address is not None: request.pduDestination = Address(target_address) else: request.pduDestination = GlobalBroadcast() iocb = self.iocb_class(request) self.this_application.submit_request(iocb)
def whois(self, *args, global_broadcast=False): """ Build a WhoIs request :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional** :returns: discoveredDevices as a defaultdict(int) Example:: whois(global_broadcast=True) # WhoIs broadcast globally. Every device will respond with an IAm whois('2:5') # WhoIs looking for the device at (Network 2, Address 5) whois('10 1000') # WhoIs looking for devices in the ID range (10 - 1000) """ if not self._started: raise ApplicationNotStarted( "BACnet stack not running - use startApp()") if args: args = args[0].split() msg = args if args else "any" self._log.debug("do_whois {!r}".format(msg)) # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: if global_broadcast: request.pduDestination = GlobalBroadcast() else: request.pduDestination = LocalBroadcast() if len(args) == 2: try: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) except ValueError: pass self._log.debug("{:>12} {}".format("- request:", request)) iocb = IOCB(request) # make an IOCB self.this_application._last_i_am_received = [] # pass to the BACnet stack deferred(self.this_application.request_io, iocb) iocb.wait() # Wait for BACnet response if iocb.ioResponse: # successful response apdu = iocb.ioResponse if iocb.ioError: # unsuccessful: error/reject/abort pass time.sleep(3) self.discoveredDevices = self.this_application.i_am_counter return self.this_application._last_i_am_received
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. The packet will be sent upstream which # will generate the original unicast going back, then it will be # re-broadcast on the local LAN. Fail if there's anything after that. s241 = listener.start_state.doc("2-4-0") \ .receive(ForwardedNPDU).doc("2-4-1") # look for the original unicast going back, followed by the rebroadcast # of the forwarded NPDU on the local LAN both = s241 \ .receive(OriginalUnicastNPDU).doc("2-4-1-a") \ .receive(ForwardedNPDU).doc("2-4-1-b") # fail if anything is received after both packets both.timeout(3).doc("2-4-4") \ .success() # allow the two packets in either order s241.receive(ForwardedNPDU).doc("2-4-2-a") \ .receive(OriginalUnicastNPDU, next_state=both).doc("2-4-2-b") # run the group tnet.run()
def broadcast(self): try: request = WhoIsRequest() request.pduDestination = GlobalBroadcast() self.this_application.request(request) thread = threading.Thread(target=10) self.this_application.request(request) self.this_application.release = True self.this_application.update = False addresslist = self.this_application.found_address addresslist = list(set(addresslist)) return addresslist except Exception as e: _log.exception("an error has occurred during bacnet discovery: %s", e) return []
def setup_device(self, address, max_apdu_len=1024, seg_supported='segmentedBoth', obj_id=599, obj_name='sMap BACnet driver', ven_id=15): _log.info('seg_supported ' + str(seg_supported)) _log.info('max_apdu_len ' + str(max_apdu_len)) _log.info('obj_id ' + str(obj_id)) _log.info('obj_name ' + str(obj_name)) _log.info('ven_id ' + str(ven_id)) # Check to see if they gave a valid apdu length. if encode_max_apdu_response(max_apdu_len) is None: raise ValueError( 'Invalid max_apdu_len: {} Valid options are 50, 128, 206, 480, 1024, and 1476' .format(max_apdu_len)) this_device = LocalDeviceObject( objectName=obj_name, objectIdentifier=obj_id, maxApduLengthAccepted=max_apdu_len, segmentationSupported=seg_supported, vendorIdentifier=ven_id, ) # build a bit string that knows about the bit names and leave it empty. We respond to NOTHING. pss = ServicesSupported() # set the property value to be just the bits this_device.protocolServicesSupported = pss.value self.this_application = BACnet_application(this_device, address) server_thread = threading.Thread(target=bacpypes.core.run) # exit the BACnet App thread when the main thread terminates server_thread.daemon = True request = WhoIsRequest() request.pduDestination = GlobalBroadcast() server_thread.start()
def broadcast(self,sender,topic,message): try: return_pipe = self.extract_pipe(message["reduced_return_pipe"]) request = WhoIsRequest() request.pduDestination = GlobalBroadcast() self.this_application.request(request) self.this_application.release = True self.this_application.update = False addresslist = self.this_application.found_address addresslist=list(set(addresslist)) #self.bemoss_publish(target=sender,topic='broadcast_response',message=addresslist) print "Printing address" print addresslist return_pipe.send(addresslist) except Exception as e: _log.exception("an error has occurred during bacnet discovery: %s", e) return []
def test_remote_broadcast_2(self): """Remote broadcast, matching device.""" if _debug: TestUnconfirmedRequests._debug("test_remote_broadcast_2") # create a network tnet = TNetwork() # test device sends request and sees the response tnet.td.start_state.doc("2-1-0") \ .send(WhoIsRequest( destination=RemoteBroadcast(2), )).doc("2-1-1") \ .success() # sniffer on network 1 sees the request and the response tnet.sniffer1.start_state.doc("2-2-0") \ .receive(PDU, pduData=xtob('01.80.00.00.02' # who is router to network ) ).doc("2-2-1") \ .receive(PDU, pduData=xtob('01.80.01.00.02' # I am router to network ) ).doc("2-2-1") \ .receive(PDU, pduData=xtob('01.20.00.02.00.ff' # remote broadcast goes out '10.08' ) ).doc("2-2-1") \ .receive(PDU, pduData=xtob('01.08.00.02.01.04' # unicast response '10.00.c4.02.00.00.04.22.04.00.91.00.22.03.e7' ) ).doc("2-2-2") \ .timeout(3).doc("2-2-3") \ .success() # network 2 sees local broadcast request and unicast response tnet.sniffer2.start_state.doc('2-3-0') \ .receive(PDU, pduData=xtob('01.08.00.01.01.01' # local broadcast '10.08' ) ).doc("2-3-1") \ .receive(PDU, pduData=xtob('01.20.00.01.01.01.ff' # unicast response '10.00.c4.02.00.00.04.22.04.00.91.00.22.03.e7' ) ).doc("2-3-1") \ .timeout(3).doc("2-3-2") \ .success() # run the group tnet.run()
def do_whois(self, addr=None, lolimit=None, hilimit=None): """whois [ <addr>] [ <lolimit> <hilimit> ]""" try: # build a request request = WhoIsRequest() if (addr is None): request.pduDestination = GlobalBroadcast() else: request.pduDestination = Address(addr) if lolimit is not None: request.deviceInstanceRangeLowLimit = int(lolimit) if hilimit is not None: request.deviceInstanceRangeHighLimit = int(hilimit) if _debug: logger.debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: logger.debug(" - iocb: %r", iocb) # give it to the application self.request_io(iocb) except Exception as err: logger.debug("exception: %r", err)
def do_whois(self, args): """whois [ <addr>] [ <lolimit> <hilimit> ]""" args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_whois %r", args) try: # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) if _debug: WhoIsIAmConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: WhoIsIAmConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) except Exception as err: WhoIsIAmConsoleCmd._exception("exception: %r", err)
def ping(self) -> None: try: # build a request request = WhoIsRequest() # ping all devices on network request.pduDestination = GlobalBroadcast() # make an IOCB (input output callback) iocb = IOCB(request) self.app.request_io(iocb) self.logger.debug("ping: waiting for responses...") loopCount = 0 while loopCount < 20 and not iocb.ioResponse: loopCount += 1 run_once() asyncore.loop(timeout=0.2, count=1) time.sleep(0.2) self.logger.debug(f"ping: loopy {loopCount}") stop() # handle responses if iocb.ioResponse: self.logger.debug(f"ping: iocb response success!") apdu = iocb.ioResponse if not isinstance(apdu, IAmRequest): self.logger.error(f"ping: Not an IAmRequest") return device_type, device_instance = apdu.iAmDeviceIdentifier if device_type != 'device': raise DecodingError("ping: invalid object type") self.logger.info(f"ping: pduSource={repr(apdu.pduSource)}") self.logger.info(f"ping: deviceId={str(apdu.iAmDeviceIdentifier)}") # do something for error/reject/abort if iocb.ioError: self.logger.error(f"ping: {str(iocb.ioError)}") except Exception as err: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_tb(exc_traceback, file=sys.stdout) self.logger.critical(f"ping: {err}")
def do_whois(self, args): """whois [ <addr> ] [ <lolimit> <hilimit> ]""" args = args.split() if _debug: TestConsoleCmd._debug("do_whois %r", args) try: # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: loLimit = int(args[0]) hiLimit = int(args[1]) request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) if _debug: TestConsoleCmd._debug(" - request: %r", request) # give it to the application this_application.Request(request) except Exception, e: TestConsoleCmd._exception("exception: %r", e)
def do_whois(self, args): if _debug: ThreadedHTTPRequestHandler._debug("do_whois %r", args) try: # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) if _debug: ThreadedHTTPRequestHandler._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: ThreadedHTTPRequestHandler._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) # no result -- it would be nice if these were the matching I-Am's result = {} except Exception as err: ThreadedHTTPRequestHandler._exception("exception: %r", err) result = { "exception": str(err) } # write the result json.dump(result, self.wfile)
def test_disable_time_duration(self): """Test disabling communication for a specific amount of time in minutes. After turning off communications, wait for 30 seconds and send a request and nothing should come back. Wait an additional 30 seconds and try again, this time receiving the response.""" if _debug: TestDeviceCommunicationControl._debug("test_disable_time_duration") # create a network anet = ApplicationNetwork("test_disable_time_duration") # add the service capability to the IUT anet.iut.add_capability(WhoIsIAmServices) anet.iut.add_capability(DeviceCommunicationControlServices) # test sequence anet.td.start_state.doc("7-4-0") \ .send(DeviceCommunicationControlRequest( destination=anet.iut.address, enableDisable='disable', timeDuration=1, )).doc("7-4-1") \ .receive(SimpleAckPDU).doc("7-4-2") \ .timeout(30).doc("7-4-3") \ .send(WhoIsRequest( destination=anet.vlan.broadcast_address, )).doc("7-4-4") \ .timeout(30.1).doc("7-4-5") \ .send(WhoIsRequest( destination=anet.vlan.broadcast_address, )).doc("7-4-6") \ .receive(IAmRequest, pduSource=anet.iut.address).doc("7-4-7") \ .success() # no IUT application layer matching anet.iut.start_state.success() # run the group a little longer than a minute anet.run(61)
def do_whois(self, args): """whois [ <addr>] [ <lolimit> <hilimit> ]""" args = args.split() if _debug: BacnetConsoleCmd._debug("do_whois %r", args) try: # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) if _debug: BacnetConsoleCmd._debug(" - request: %r", request) # give it to the application thisApplication.request(request) except Exception, e: BacnetConsoleCmd._exception("exception: %r", e)
def test_global_broadcast(self): """Global broadcast, matching device.""" if _debug: TestUnconfirmedRequests._debug("test_global_broadcast") # create a network tnet = TNetwork() # test device sends request and sees the response tnet.td.start_state.doc("4-1-0") \ .send(WhoIsRequest( destination=GlobalBroadcast(), )).doc("4-1-1") \ .receive(IAmRequest).doc("4-1-2") \ .success() # sniffer on network 1 sees the request and the response tnet.sniffer1.start_state.doc("4-2-0") \ .receive(PDU, pduData=xtob('01.20.ff.ff.00.ff' '10.08' ) ).doc("4-2-1") \ .receive(PDU, pduData=xtob('01.08.00.02.01.04' '10.00.c4.02.00.00.04.22.04.00.91.00.22.03.e7' ) ).doc("4-2-2") \ .timeout(3).doc("4-2-3") \ .success() # network 2 sees local broadcast request and unicast response tnet.sniffer2.start_state.doc('4-3-0') \ .receive(PDU, pduData=xtob('01.28.ff.ff.00.00.01.01.01.fe' '10.08' ) ).doc("4-3-1") \ .receive(PDU, pduData=xtob('01.20.00.01.01.01.ff' '10.00.c4.02.00.00.04.22.04.00.91.00.22.03.e7' ) ).doc("4-3-3") \ .timeout(3).doc("4-3-3") \ .success() # run the group tnet.run()
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 whois(self, *args): """ Creation of a whois requests Requets is given to the app :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional** :returns: discoveredDevices as a defaultdict(int) Example:: whois() #will create a broadcast whois request and every device will response by a Iam whois('2:5') #will create a whois request aimed at device 5 whois('10 1000') #will create a whois request looking for device ID 10 to 1000 """ if args: args = args[0].split() if not args: msg = "any" else: msg = args log_debug("do_whois %r" % msg) try: # build a request request = WhoIsRequest() if (len(args) == 1) or (len(args) == 3): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() if len(args) == 2: request.deviceInstanceRangeLowLimit = int(args[0]) request.deviceInstanceRangeHighLimit = int(args[1]) log_debug(" - request: %r" % request) # give it to the application self.this_application.request(request) except Exception as error: log_exception("exception: %r" % error) self.discoveredDevices = self.this_application.i_am_counter return self.discoveredDevices
def test_whois_unconstrained(self): """Test an unconstrained WhoIs, all devices respond.""" if _debug: TestWhoIsIAm._debug("test_whois_unconstrained") # create a network anet = ApplicationNetwork("test_whois_unconstrained") # add the service capability to the IUT anet.iut.add_capability(WhoIsIAmServices) # send a WhoIs, get back an IAm anet.td.start_state.doc("1-1-0") \ .send(WhoIsRequest(destination=anet.vlan.broadcast_address)).doc("1-1-1") \ .receive(IAmRequest, pduSource=anet.iut.address).doc("1-1-2") \ .success() # no IUT application layer matching anet.iut.start_state.success() # run the group anet.run()
def who_is(self, low_device_id=None, high_device_id=None, target_address=None): _log.debug("Sending WhoIs: low_id: {low} high: {high} address: {address}".format( low=low_device_id, high=high_device_id, address=target_address)) request = WhoIsRequest() if low_device_id is not None: request.deviceInstanceRangeLowLimit = low_device_id if high_device_id is not None: request.deviceInstanceRangeHighLimit = high_device_id if target_address is not None: request.pduDestination = Address(target_address) else: request.pduDestination = GlobalBroadcast() iocb = self.iocb_class(request) self.bacnet_application.submit_request(iocb)
objectName=args.ini.objectname, objectIdentifier=int(args.ini.objectidentifier), maxApduLengthAccepted=int(args.ini.maxapdulengthaccepted), segmentationSupported=args.ini.segmentationsupported, vendorIdentifier=int(args.ini.vendoridentifier), ) # make a simple application this_application = SynchronousApplication(this_device, args.ini.address) _log.debug("starting build") target_address = Address(args.address) request = WhoIsRequest() request.pduDestination = target_address result = this_application.make_request(request) if not isinstance(result, IAmRequest): result.debug_contents() raise TypeError("Error making WhoIs request") device_type, device_instance = result.iAmDeviceIdentifier if device_type != 'device': raise DecodingError("invalid object type") _log.debug('pduSource = ' + repr(result.pduSource)) _log.debug('iAmDeviceIdentifier = ' + str(result.iAmDeviceIdentifier)) _log.debug('maxAPDULengthAccepted = ' + str(result.maxAPDULengthAccepted))
vendorIdentifier=int(args.ini.vendoridentifier), ) # build a bit string that knows about the bit names pss = ServicesSupported() pss['whoIs'] = 1 pss['iAm'] = 1 # set the property value to be just the bits this_device.protocolServicesSupported = pss.value # make a simple application this_application = WhoIsIAmApplication(this_device, args.ini.address) _log.debug("running") request = WhoIsRequest() if args.address is not None: request.pduDestination = Address(args.address) else: request.pduDestination = GlobalBroadcast() if args.range is not None: request.deviceInstanceRangeLowLimit = int(args.range[0]) request.deviceInstanceRangeHighLimit = int(args.range[1]) #set timeout timer def time_out(): time.sleep(args.timeout) stop()
test_asap = ApplicationServiceAccessPoint() # pass the device object to the state machine access point so it # can know if it should support segmentation test_smap = StateMachineAccessPoint(test_device) # state machine test_server = ServerStateMachine() # bind everything together bind(test_application, test_asap, test_smap, test_server) # ============================================================================== who_is_request = WhoIsRequest( deviceInstanceRangeLowLimit=0, deviceInstanceRangeHighLimit=4194303, ) print("who_is_request") who_is_request.debug_contents() print("") test_apdu = APDU() who_is_request.encode(test_apdu) print("test_apdu") test_apdu.debug_contents() print("") print("modify test_apdu") test_apdu.pduData = test_apdu.pduData[:-1] # test_apdu.pduData = xtob('7509006869207468657265') # CharacterString("hi there")