def test_global_broadcast(self): if _debug: TestGlobalBroadcast._debug("test_global_broadcast") # no parameters with self.assertRaises(TypeError): GlobalBroadcast(1) test_addr = GlobalBroadcast() self.match_address(test_addr, 5, None, None, None) assert str(test_addr) == "*:*"
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 iam(self): """ Build an IAm response. IAm are sent in response to a WhoIs request that; matches our device ID, whose device range includes us, or is a broadcast. Content is defined by the script (deviceId, vendor, etc...) :returns: bool Example:: iam() """ log_debug(WhoisIAm, "do_iam") try: # build a response request = IAmRequest() request.pduDestination = GlobalBroadcast() # fill the response with details about us (from our device object) request.iAmDeviceIdentifier = self.this_device.objectIdentifier request.maxAPDULengthAccepted = self.this_device.maxApduLengthAccepted request.segmentationSupported = self.this_device.segmentationSupported request.vendorID = self.this_device.vendorIdentifier log_debug(WhoisIAm, " - request: %r" % request) iocb = self.this_application.request(request) # pass to the BACnet stack iocb.wait() return True except Exception as error: log_exception("exception: %r" % error) return False
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 do_iam(self, args): """iam [ <addr> ]""" args = args.split() if _debug: TestConsoleCmd._debug("do_iam %r", args) try: # build a request request = IAmRequest() if (len(args) == 1): request.pduDestination = Address(args[0]) del args[0] else: request.pduDestination = GlobalBroadcast() # set the parameters from the device object request.iAmDeviceIdentifier = this_device.objectIdentifier request.maxAPDULengthAccepted = this_device.maxApduLengthAccepted request.segmentationSupported = this_device.segmentationSupported request.vendorID = this_device.vendorIdentifier 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_iam(self, args): """iam""" args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_iam %r", args) try: # build a request request = IAmRequest() request.pduDestination = GlobalBroadcast() # set the parameters from the device object request.iAmDeviceIdentifier = this_device.objectIdentifier request.maxAPDULengthAccepted = this_device.maxApduLengthAccepted request.segmentationSupported = this_device.segmentationSupported request.vendorID = this_device.vendorIdentifier 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 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 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 iam(self): """ Creation of a iam request Iam requests are sent when whois requests ask for it Content is defined by the script (deviceId, vendor, etc...) :returns: bool Example:: iam() """ if _debug: WhoisIAm._debug("do_iam") try: # build a request request = IAmRequest() request.pduDestination = GlobalBroadcast() # set the parameters from the device object request.iAmDeviceIdentifier = self.this_device.objectIdentifier request.maxAPDULengthAccepted = self.this_device.maxApduLengthAccepted request.segmentationSupported = self.this_device.segmentationSupported request.vendorID = self.this_device.vendorIdentifier if _debug: WhoisIAm._debug(" - request: %r" % request) # give it to the application self.this_application.request(request) return True except Exception as e: WhoisIAm._exception("exception: %r" % e) return False
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: VLANConsoleCmd._debug("do_whois %r", args) try: # gather the parameters 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: VLANConsoleCmd._exception("exception: %r", error)
def test_readProperty(self): request = ReadPropertyRequest( objectIdentifier=("analogInput", 14), propertyIdentifier=85 ) request.apduMaxResp = 1024 request.apduInvokeID = 101 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 = ReadPropertyACK() expected.pduDestination = GlobalBroadcast() expected.apduInvokeID = 101 expected.objectIdentifier = 14 expected.objectName = "AI 01" expected.propertyIdentifier = 85 expected.propertyValue = Any(Real(68.0)) exp_apdu = APDU() expected.encode(exp_apdu) exp_pdu = PDU() exp_apdu.encode(exp_pdu) self.assertEqual(exp_pdu.pduData, received_data)
def start(self): if self.mqtt is None: self.mqtt = MQTT(self.credentials) self.who_is(None, None, GlobalBroadcast()) timer = threading.Timer(self.interval, self.start) timer.daemon = True timer.start()
def whoIs(self, request, address, invoke_key, device): # Limits are optional (but if used, must be paired) execute = False try: if (request.deviceInstanceRangeLowLimit is not None) and \ (request.deviceInstanceRangeHighLimit is not None): if (request.deviceInstanceRangeLowLimit > list( self.objectIdentifier.keys())[0][1] > request.deviceInstanceRangeHighLimit): logger.info('Bacnet WhoHasRequest out of range') else: execute = True else: execute = True except AttributeError: execute = True if execute: self._response_service = 'IAmRequest' self._response = IAmRequest() self._response.pduDestination = GlobalBroadcast() self._response.iAmDeviceIdentifier = self.deviceIdentifier # self._response.objectIdentifier = list(self.objectIdentifier.keys())[0][1] self._response.maxAPDULengthAccepted = int( getattr(self.localDevice, 'maxApduLengthAccepted')) self._response.segmentationSupported = getattr( self.localDevice, 'segmentationSupported') self._response.vendorID = int( getattr(self.localDevice, 'vendorIdentifier'))
def whoHas(self, request, address, invoke_key, device): execute = False try: if (request.deviceInstanceRangeLowLimit is not None) and \ (request.deviceInstanceRangeHighLimit is not None): if (request.deviceInstanceRangeLowLimit > list( self.objectIdentifier.keys())[0][1] > request.deviceInstanceRangeHighLimit): logger.info('Bacnet WhoHasRequest out of range') else: execute = True else: execute = True except AttributeError: execute = True if execute: for obj in device.objectList.value[2:]: if int(request.object.objectIdentifier[1]) == obj[1] and \ request.object.objectIdentifier[0] == obj[0]: objName = self.objectIdentifier[obj].objectName self._response_service = 'IHaveRequest' self._response = IHaveRequest() self._response.pduDestination = GlobalBroadcast() # self._response.deviceIdentifier = list(self.objectIdentifier.keys())[0][1] self._response.deviceIdentifier = self.deviceIdentifier self._response.objectIdentifier = obj[1] self._response.objectName = objName break else: logger.info('Bacnet WhoHasRequest: no object found')
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 do_iam(self, args): """ iam [ <addr> ] Send an I-Am request. If the address is unspecified the message is locally broadcast. """ args = args.split() if _debug: DiscoverConsoleCmd._debug("do_iam %r", args) try: # build a request request = IAmRequest() if (len(args) == 1): request.pduDestination = Address(args[0]) else: request.pduDestination = GlobalBroadcast() # set the parameters from the device object request.iAmDeviceIdentifier = this_device.objectIdentifier request.maxAPDULengthAccepted = this_device.maxApduLengthAccepted request.segmentationSupported = this_device.segmentationSupported request.vendorID = this_device.vendorIdentifier if _debug: DiscoverConsoleCmd._debug(" - request: %r", request) # make an IOCB iocb = IOCB(request) if _debug: DiscoverConsoleCmd._debug(" - iocb: %r", iocb) # give it to the application this_application.request_io(iocb) except Exception as err: DiscoverConsoleCmd._exception("exception: %r", err)
def test_whoHas(self): request_object = WhoHasObject() request_object.objectIdentifier = ('binaryInput', 12) request = WhoHasRequest(object=request_object) 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 = IHaveRequest() expected.pduDestination = GlobalBroadcast() expected.deviceIdentifier = 36113 expected.objectIdentifier = 12 expected.objectName = 'BI 01' exp_apdu = APDU() expected.encode(exp_apdu) exp_pdu = PDU() exp_apdu.encode(exp_pdu) self.assertEquals(exp_pdu.pduData, received_data)
def test_whoHas(self): request_object = WhoHasObject() request_object.objectIdentifier = ("binaryInput", 12) request = WhoHasRequest(object=request_object) 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 = IHaveRequest() expected.pduDestination = GlobalBroadcast() expected.deviceIdentifier = 36113 expected.objectIdentifier = 12 expected.objectName = "BI 01" exp_apdu = APDU() expected.encode(exp_apdu) exp_pdu = PDU() exp_apdu.encode(exp_pdu) self.assertEqual(exp_pdu.pduData, received_data)
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 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 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 test_address_equality(self): if _debug: TestAddressEquality._debug("test_address_equality") assert Address(1) == LocalStation(1) assert Address("2") == LocalStation(2) assert Address("*") == LocalBroadcast() assert Address("3:4") == RemoteStation(3, 4) assert Address("5:*") == RemoteBroadcast(5) assert Address("*:*") == GlobalBroadcast()
def test_global_broadcast_routed(self): if _debug: TestGlobalBroadcast._debug("test_global_broadcast_routed") if not settings.route_aware: if _debug: TestGlobalBroadcast._debug(" - not route aware") return test_addr = GlobalBroadcast(route=Address("1.2.3.4")) self.match_address(test_addr, 5, None, None, None) assert str(test_addr) == "*:*@1.2.3.4"
def test_address_equality_str_routed(self): if _debug: TestAddressEquality._debug("test_address_equality_str_routed") if not settings.route_aware: if _debug: TestAddressEquality._debug(" - not route aware") return assert Address("3:[email protected]") == RemoteStation(3, 4, route=Address("6.7.8.9")) assert Address("5:*@6.7.8.9") == RemoteBroadcast(5, route=Address("6.7.8.9")) assert Address("*:*@6.7.8.9") == GlobalBroadcast(route=Address("6.7.8.9"))
def WhoIsRequest(self, low_limit=1, high_limit=2000): # # WhoIsRequest の レスポンス(IAmRequest) を保存するキューをクリア # #self.application.clear() # # WhoIsRequest の 送信 # self.application.who_is(low_limit, high_limit, GlobalBroadcast())
def whohas( self, object_id=None, object_name=None, instance_range_low_limit=0, instance_range_high_limit=4194303, destination=None, global_broadcast=False, ): """ Object ID : analogInput:1 Object Name : string Instance Range Low Limit : 0 Instance Range High Limit : 4194303 destination (optional) : If empty, local broadcast will be used. global_broadcast : False """ obj_id = ObjectIdentifier(object_id) if object_name and not object_id: obj_name = CharacterString(object_name) obj = WhoHasObject(objectName=obj_name) elif object_id and not object_name: obj = WhoHasObject(objectIdentifier=obj_id) else: obj = WhoHasObject(objectIdentifier=obj_id, objectName=obj_name) limits = WhoHasLimits( deviceInstanceRangeLowLimit=instance_range_low_limit, deviceInstanceRangeHighLimit=instance_range_high_limit, ) request = WhoHasRequest(object=obj, limits=limits) if destination: request.pduDestination = Address(destination) else: if global_broadcast: request.pduDestination = GlobalBroadcast() else: request.pduDestination = LocalBroadcast() iocb = IOCB(request) # make an IOCB iocb.set_timeout(2) deferred(self.this_application.request_io, iocb) iocb.wait() iocb = IOCB(request) # make an IOCB self.this_application._last_i_have_received = [] if iocb.ioResponse: # successful response apdu = iocb.ioResponse if iocb.ioError: # unsuccessful: error/reject/abort pass time.sleep(3) # self.discoveredObjects = self.this_application.i_am_counter return self.this_application._last_i_have_received
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 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_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()