Example #1
0
class BIPBBMDApplication(Application, WhoIsIAmServices, ReadWritePropertyServices):

    def __init__(self, address, vlan):
        if _debug: BIPBBMDApplication._debug("__init__ %r %r", address, vlan)

        # build a name, save the address
        self.name = "app @ %s" % (address,)
        self.address = Address(address)
        if _debug: BIPBBMDApplication._debug("    - address: %r", self.address)

        # build a local device object
        local_device = TestDeviceObject(
            objectName=self.name,
            objectIdentifier=('device', 999),
            vendorIdentifier=999,
            )

        # continue with initialization
        Application.__init__(self, local_device, self.address)

        # include a application decoder
        self.asap = ApplicationServiceAccessPoint()

        # pass the device object to the state machine access point so it
        # can know if it should support segmentation
        self.smap = StateMachineAccessPoint(local_device)

        # the segmentation state machines need access to the same device
        # information cache as the application
        self.smap.deviceInfoCache = self.deviceInfoCache

        # a network service access point will be needed
        self.nsap = NetworkServiceAccessPoint()

        # give the NSAP a generic network layer service element
        self.nse = NetworkServiceElement()
        bind(self.nse, self.nsap)

        # bind the top layers
        bind(self, self.asap, self.smap, self.nsap)

        # BACnet/IP interpreter
        self.bip = BIPBBMD(self.address)
        self.annexj = AnnexJCodec()

        # build an address, full mask
        bdt_address = "%s/32:%d" % self.address.addrTuple
        if _debug: BIPBBMDNode._debug("    - bdt_address: %r", bdt_address)

        # add itself as the first entry in the BDT
        self.bip.add_peer(Address(bdt_address))

        # fake multiplexer has a VLAN node in it
        self.mux = FauxMultiplexer(self.address, vlan)

        # bind the stack together
        bind(self.bip, self.annexj, self.mux)

        # bind the stack to the local network
        self.nsap.bind(self.bip)
Example #2
0
class BBMDNode(_repr, ClientStateMachine):

    def __init__(self, address, vlan):
        if _debug: BBMDNode._debug("__init__ %r %r", address, vlan)
        ClientStateMachine.__init__(self)

        # save the name and address
        self.name = address
        self.address = Address(address)

        # BACnet/IP interpreter
        self.bip = BIPBBMD(self.address)
        self.annexj = AnnexJCodec()

        # build an address, full mask
        bdt_address = "%s/32:%d" % self.address.addrTuple
        if _debug: BBMDNode._debug("    - bdt_address: %r", bdt_address)

        # add itself as the first entry in the BDT
        self.bip.add_peer(Address(bdt_address))

        # fake multiplexer has a VLAN node in it
        self.mux = FauxMultiplexer(self.address, vlan)

        # bind the stack together
        bind(self, self.bip, self.annexj, self.mux)
Example #3
0
class BIPBBMDNode:

    """This class is a BIPBBMD instance that is not bound to a state machine."""

    def __init__(self, address, vlan):
        if _debug: BIPBBMDNode._debug("__init__ %r %r", address, vlan)

        # save the name and address
        self.name = address
        self.address = Address(address)
        if _debug: BIPBBMDNode._debug("    - address: %r", self.address)

        # BACnet/IP interpreter
        self.bip = BIPBBMD(self.address)
        self.annexj = AnnexJCodec()

        # build an address, full mask
        bdt_address = "%s/32:%d" % self.address.addrTuple
        if _debug: BIPBBMDNode._debug("    - bdt_address: %r", bdt_address)

        # add itself as the first entry in the BDT
        self.bip.add_peer(Address(bdt_address))

        # fake multiplexer has a VLAN node in it
        self.mux = FauxMultiplexer(self.address, vlan)

        # bind the stack together
        bind(self.bip, self.annexj, self.mux)
Example #4
0
class BIPBBMDStateMachine(ClientStateMachine):

    """This class sits on a BIPBBMD instance, the send() and receive()
    parameters are NPDUs.
    """

    def __init__(self, address, vlan):
        if _debug: BIPBBMDStateMachine._debug("__init__ %r %r", address, vlan)
        ClientStateMachine.__init__(self)

        # save the name and address
        self.name = address
        self.address = Address(address)

        # BACnet/IP interpreter
        self.bip = BIPBBMD(self.address)
        self.annexj = AnnexJCodec()

        # build an address, full mask
        bdt_address = "%s/32:%d" % self.address.addrTuple
        if _debug: BIPBBMDStateMachine._debug("    - bdt_address: %r", bdt_address)

        # add itself as the first entry in the BDT
        self.bip.add_peer(Address(bdt_address))

        # fake multiplexer has a VLAN node in it
        self.mux = FauxMultiplexer(self.address, vlan)

        # bind the stack together
        bind(self, self.bip, self.annexj, self.mux)
Example #5
0
def main():
    # parse the command line arguments
    parser = ArgumentParser(description=__doc__)

    # add an argument for interval
    parser.add_argument(
        'localaddr',
        type=str,
        help='local address of the BBMD',
    )

    # add an argument for interval
    parser.add_argument(
        'bdtentry',
        type=str,
        nargs='*',
        help='list of addresses of peers',
    )

    # now parse the arguments
    args = parser.parse_args()

    if _debug: _log.debug("initialization")
    if _debug: _log.debug("    - args: %r", args)

    local_address = Address(args.localaddr)
    if _debug: _log.debug("    - local_address: %r", local_address)

    # create a null client that will accept, but do nothing with upstream
    # packets from the BBMD
    null_client = NullClient()
    if _debug: _log.debug("    - null_client: %r", null_client)

    # create a BBMD, bound to the Annex J server on a UDP multiplexer
    bbmd = BIPBBMD(local_address)
    annexj = AnnexJCodec()
    multiplexer = UDPMultiplexer(local_address)

    # bind the layers together
    bind(null_client, bbmd, annexj, multiplexer.annexJ)

    # loop through the rest of the addresses
    for bdtentry in args.bdtentry:
        if _debug: _log.debug("    - bdtentry: %r", bdtentry)

        bdt_address = Address(bdtentry)
        bbmd.add_peer(bdt_address)

    if _debug: _log.debug("    - bbmd: %r", bbmd)

    _log.debug("running")

    run()

    _log.debug("fini")
Example #6
0
def main():
    # parse the command line arguments
    parser = ArgumentParser(description=__doc__)

    # add an argument for interval
    parser.add_argument('localaddr', type=str,
          help='local address of the BBMD',
          )

    # add an argument for interval
    parser.add_argument('bdtentry', type=str, nargs='*',
          help='list of addresses of peers',
          )

    # now parse the arguments
    args = parser.parse_args()

    if _debug: _log.debug("initialization")
    if _debug: _log.debug("    - args: %r", args)

    local_address = Address(args.localaddr)
    if _debug: _log.debug("    - local_address: %r", local_address)

    # create a null client that will accept, but do nothing with upstream
    # packets from the BBMD
    null_client = NullClient()
    if _debug: _log.debug("    - null_client: %r", null_client)

    # create a BBMD, bound to the Annex J server on a UDP multiplexer
    bbmd = BIPBBMD(local_address)
    annexj = AnnexJCodec()
    multiplexer = UDPMultiplexer(local_address)

    # bind the layers together
    bind(null_client, bbmd, annexj, multiplexer.annexJ)

    # loop through the rest of the addresses
    for bdtentry in args.bdtentry:
        if _debug: _log.debug("    - bdtentry: %r", bdtentry)

        bdt_address = Address(bdtentry)
        bbmd.add_peer(bdt_address)

    if _debug: _log.debug("    - bbmd: %r", bbmd)

    _log.debug("running")

    run()

    _log.debug("fini")
Example #7
0
class BAC0BBMDDeviceApplication(
    common_mixin,
    ApplicationIOController,
    WhoIsIAmServices,
    WhoHasIHaveServices,
    ReadWritePropertyServices,
    ReadWritePropertyMultipleServices,
    ChangeOfValueServices,
):
    """
    Defines a basic BACnet/IP application to process BACnet requests.

    :param *args: local object device, local IP address
        See BAC0.scripts.BasicScript for more details.

    """

    bdt = []

    def __init__(
        self,
        localDevice,
        localAddress,
        bdtable=[],
        deviceInfoCache=None,
        aseID=None,
        iam_req=None,
        subscription_contexts=None,
    ):

        self.bdtable = bdtable

        null_client = NullClient()

        ApplicationIOController.__init__(
            self, localDevice, deviceInfoCache, aseID=aseID
        )

        self.iam_req = iam_req
        # local address might be useful for subclasses
        if isinstance(localAddress, Address):
            self.localAddress = localAddress
        else:
            self.localAddress = Address(localAddress)

        # include a application decoder
        self.asap = ApplicationServiceAccessPoint()

        # pass the device object to the state machine access point so it
        # can know if it should support segmentation
        self.smap = StateMachineAccessPoint(localDevice)

        # the segmentation state machines need access to the same device
        # information cache as the application
        self.smap.deviceInfoCache = self.deviceInfoCache

        # a network service access point will be needed
        self.nsap = NetworkServiceAccessPoint()

        # give the NSAP a generic network layer service element
        self.nse = NetworkServiceElementWithRequests()
        bind(self.nse, self.nsap)

        # bind the top layers
        bind(self, self.asap, self.smap, self.nsap)

        # create a generic BIP stack, bound to the Annex J server
        # on the UDP multiplexer
        self.bip = BIPBBMD(self.localAddress)
        self.annexj = AnnexJCodec()
        self.mux = UDPMultiplexer(self.localAddress, noBroadcast=True)

        # bind the bottom layers
        # bind(self.bip, self.annexj, self.mux.annexJ)
        bind(null_client, self.bip, self.annexj, self.mux.annexJ)

        if self.bdtable:
            for bdtentry in self.bdtable:
                self.add_peer(bdtentry)

        # bind the NSAP to the stack, no network number
        self.nsap.bind(self.bip)

        self.i_am_counter = defaultdict(int)
        self.i_have_counter = defaultdict(int)
        self.who_is_counter = defaultdict(int)
        # keep track of requests to line up responses
        self._request = None
        self._last_i_am_received = []
        self._last_i_have_received = []

        # to support CoV
        self.subscription_contexts = subscription_contexts

    def add_peer(self, address):
        try:
            bdt_address = Address(address)
            self.bip.add_peer(bdt_address)
        except Exception:
            raise

    def remove_peer(self, address):
        try:
            bdt_address = Address(address)
            self.bip.remove_peer(bdt_address)
        except Exception:
            raise

    def close_socket(self):
        # pass to the multiplexer, then down to the sockets
        self.mux.close_socket()