Example #1
0
    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)
Example #2
0
        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)
Example #3
0
 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)
Example #4
0
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
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
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
Example #8
0
    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']
Example #9
0
 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)
Example #10
0
    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)
Example #11
0
 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)
Example #12
0
    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
Example #13
0
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
Example #14
0
    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()
Example #15
0
    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()
Example #16
0
    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()
Example #17
0
    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()
Example #18
0
    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()
Example #19
0
    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)
Example #20
0
    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
Example #21
0
    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
Example #22
0
    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)
Example #23
0
    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
Example #24
0
    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()
Example #25
0
    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 []
Example #26
0
    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()
Example #27
0
    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 []
Example #28
0
    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()
Example #29
0
    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)
Example #30
0
    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}")
Example #32
0
    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)
Example #33
0
    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)
Example #34
0
    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)
Example #36
0
    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()
Example #37
0
    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()
Example #38
0
    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
Example #39
0
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
Example #40
0
    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()
Example #41
0
    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))
Example #43
0
        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")