Beispiel #1
0
    def iface(self):
        if hasattr(self, "_iface"):
            iface = self._iface
        else:
            iface_methods = []
            for method_name, (args_xform, returns_xform,
                              fn) in self.methods.items():
                iface_methods.append(
                    Method(
                        method_name,
                        arguments=args_xform.signature(),
                        returns=returns_xform.signature(),
                    ))

            iface_properties = []
            for prop_name, (xform, _, kwargs) in self.properties.items():
                iface_properties.append(
                    Property(prop_name, xform.signature(), **kwargs))

            iface_signals = []
            for signal_name, xform in self.signals.items():
                iface_signals.append(Signal(signal_name, xform.signature()))

            iface = DBusInterface(
                f"{self.service.namespace}.{self.iface_name}",
                *(iface_methods + iface_properties + iface_signals),
            )
            self._iface = iface
        return iface
Beispiel #2
0
class BlueZLEAdvertisement(DBusObject):
    """
    org.bluez.LEAdvertisement1 interface implementation
    """

    interface_name: str = "org.bluez.LEAdvertisement1"

    iface: DBusInterface = DBusInterface(
        interface_name, Method("Release"), Property("Type", "s"),
        Property("ServiceUUIDs", "as"), Property("ManufacturerData", "a{qay}"),
        Property("SolicitUUIDs", "as"), Property("ServiceData", "a{sv}"),
        Property("IncludeTxPower", "b"))

    dbusInterfaces: List[DBusInterface] = [iface]

    ad_type: DBusProperty = DBusProperty("Type")
    service_uuids: DBusProperty = DBusProperty("ServiceUUIDs")
    # manufacturer_data = DBusProperty("ManufacturerData")
    # solicit_uuids = DBusProperty("SolicitUUIDs")
    # service_data = DBusProperty("ServiceData")
    include_tx_power: DBusProperty = DBusProperty("IncludeTxPower")

    def __init__(
            self,
            advertising_type: Type,
            index: int,
            app: "BlueZGattApplication"  # noqa: F821
    ):
        """
        New Low Energy Advertisement

        Parameters
        ----------
        advertising_type : Type
            The type of advertisement
        index : int,
            The index of the advertisement
        app : BlueZGattApplication
            The Application that is responsible for this advertisement
        """
        self.ad_type: str = advertising_type.value
        self.path = app.base_path + "/advertisement" + str(index)

        self.service_uuids: List[str] = []
        self.manufacturer_data: Dict = {}
        self.solicit_uuids = ['']
        self.service_data = {'': 0}

        self.include_tx_power: bool = False

        self.data = None
        super(BlueZLEAdvertisement, self).__init__(self.path)

    @dbusMethod(interface_name, "Release")
    def Release(self):  # noqa: N802
        print("%s: Released!" % self.path)
Beispiel #3
0
to run on every PC but serves as a reference.
"""

from twisted.internet import reactor, defer
from txdbus import client, error
from txdbus.interface import DBusInterface, Method, Signal
import time

dbus_name = 'fi.w1.wpa_supplicant1'
root_iface_str = 'fi.w1.wpa_supplicant1'
root_iface_obj_path = "/" + root_iface_str.replace('.', '/')

interface_iface_str = root_iface_str + ".Interface"
interface_iface = DBusInterface(
    interface_iface_str, Signal('ScanDone', 'b'),
    Method('Scan', arguments='a{sv}'),
    Method('AddNetwork', arguments='a{sv}', returns='o'),
    Method('RemoveNetwork', arguments='o'),
    Method('SelectNetwork', arguments='o'))


@defer.inlineCallbacks
def set_mode_example():
    cli = yield client.connect(reactor, busAddress='system')

    root_obj = yield cli.getRemoteObject(dbus_name, root_iface_obj_path)
    print "Root Object: %s" % root_obj

    wlan0_obj_path = yield root_obj.callRemote('GetInterface', 'wlan1')
    print "WLAN0 Object Path: %s" % wlan0_obj_path
Beispiel #4
0
from si446xact import Si446xFsmActionHandlers
from si446xradio import Si446xRadio
from si446xdef import *
import si446xtrace

__all__ = [
    'BUS_NAME', 'OBJECT_PATH', 'si446x_dbus_interface', 'Si446xDbus',
    'reactor_loop'
]

BUS_NAME = 'org.tagnet.si446x'
OBJECT_PATH = '/org/tagnet/si446x/0/0'  # object name includes device id/port numbers

si446x_dbus_interface = DBusInterface(
    BUS_NAME,
    Method('cca', returns='u'),
    Method('clear_status', returns='s'),
    Method('control', arguments='s', returns='s'),
    Method('dump_radio', arguments='s', returns='s'),
    Method('dump_trace', arguments='sissu', returns='a(dyssay)'),
    Method('send', arguments='ayu', returns='s'),
    Method('spi_send', arguments='ays', returns='s'),
    Method('spi_send_recv', arguments='ayuss', returns='ay'),
    Method('status', returns='s'),
    Signal('new_status', 's'),
    Signal('receive', 'ayu'),
    Signal('send_cmp', 's'),
)


class Si446xDbus(objects.DBusObject):
Beispiel #5
0
class Interface(BaseIface):
    """Interface implemented by objects related to network interface added to wpa_supplicant"""

    INTERFACE_PATH = 'fi.w1.wpa_supplicant1.Interface'

    iface = DBusInterface(
        INTERFACE_PATH,
        Method('Scan', arguments='a{sv}'),
        Method('AddNetwork', arguments='a{sv}', returns='o'),
        Method('RemoveNetwork', arguments='o'),
        Method('SelectNetwork', arguments='o'),
        Method('Disconnect'),
        Signal('ScanDone', 'b'),
        Signal('PropertiesChanged', 'a{sv}')
    )

    def __repr__(self):
        return str(self)

    def __str__(self):
        return "Interface(Path: %s, Name: %s, State: %s)" % (self.get_path(),
                                                             self.get_ifname(),
                                                             self.get_state())

    #
    # Methods
    #
    def scan(self, type='active', ssids=None, ies=None, channels=None, block=False):
        """Triggers a scan

        :returns: List of `BSS` objects if block=True else None
        :raises InvalidArgs: Invalid argument format
        :raises MethodTimeout: Scan has timed out (only if block=True)
        :raises UnknownError: An unknown error occurred
        """

        # TODO: Handle the other arguments
        scan_options = {
            'Type': type
        }

        # If blocking, register for the ScanDone signal and return BSSs
        if block:
            deferred_queue = self.register_signal_once('ScanDone')
            self._call_remote('Scan', scan_options)  # Trigger scan
            success = deferred_queue.get(timeout=10)
            if success:
                return [BSS(path, self._conn, self._reactor) for path in self.get_all_bss()]
            else:
                raise UnknownError('ScanDone signal received without success')
        else:
            self._call_remote('Scan', scan_options)  # Trigger scan

    def add_network(self, network_cfg):
        """Adds a new network to the interface

        :param network_cfg: Dictionary of config, see wpa_supplicant.conf for k/v pairs
        :returns: `Network` object that was registered w/ wpa_supplicant
        :raises InvalidArgs: Invalid argument format
        :raises UnknownError: An unknown error occurred
        """

        network_path = self._call_remote('AddNetwork', network_cfg)
        return Network(network_path, self._conn, self._reactor)

    def remove_network(self, network_path):
        """Removes a configured network from the interface

        :param network_path: D-Bus object path to the desired network
        :returns: None
        :raises NetworkUnknown: The specified `network_path` is invalid
        :raises InvalidArgs: Invalid argument format
        :raises UnknownError: An unknown error occurred
        """

        self._call_remote('RemoveNetwork', network_path)

    def select_network(self, network_path):
        """Attempt association with a configured network

        :param network_path: D-Bus object path to the desired network
        :returns: None
        :raises NetworkUnknown: The specified `network_path` has not been added
        :raises InvalidArgs: Invalid argument format
        """

        self._call_remote('SelectNetwork', network_path)

    def disconnect_network(self):
        """Disassociates the interface from current network

        :returns: None
        :raises NotConnected: The interface is not currently connected to a network
        """

        self._call_remote('Disconnect')

    #
    # Properties
    #
    def get_ifname(self):
        """Name of network interface controlled by the interface, e.g., wlan0"""

        return self.get('Ifname')

    def get_current_bss(self):
        """BSS object path which wpa_supplicant is associated with

                Returns "/" if is not associated at all
        """

        bss_path = self.get('CurrentBSS')
        if bss_path == '/' or bss_path is None:
            return None
        else:
            return BSS(bss_path, self._conn, self._reactor)

    def get_current_network(self):
        """The `Network` object which wpa_supplicant is associated with

                Returns `None` if is not associated at all
        """

        network_path = self.get('CurrentNetwork')
        if network_path == '/' or network_path is None:
            return None
        else:
            return Network(network_path, self._conn, self._reactor)

    def get_networks(self):
        """List of `Network` objects representing configured networks"""

        networks = list()
        paths = self.get('Networks')
        for network_path in paths:
            if network_path == '/':
                networks.append(None)
            else:
                networks.append(Network(network_path, self._conn, self._reactor))
        return networks

    def get_state(self):
        """A state of the interface.

            Possible values are: "disconnected"
                                 "inactive"
                                 "scanning"
                                 "authenticating"
                                 "associating"
                                 "associated"
                                 "4way_handshake"
                                 "group_handshake"
                                 "completed"
                                 "unknown"
        """

        return self.get('State')

    def get_scanning(self):
        """Determines if the interface is already scanning or not"""

        return self.get('Scanning')

    def get_scan_interval(self):
        """Time (in seconds) between scans for a suitable AP. Must be >= 0"""

        return self.get('ScanInterval')

    def get_fast_reauth(self):
        """Identical to fast_reauth entry in wpa_supplicant.conf"""

        return self.get('FastReauth')

    def get_all_bss(self):
        """List of D-Bus objects paths representing BSSs known to the interface"""

        return self.get('BSSs')

    def get_driver(self):
        """Name of driver used by the interface, e.g., nl80211"""

        return self.get('Driver')

    def get_country(self):
        """Identical to country entry in wpa_supplicant.conf"""

        return self.get('Country')

    def get_bridge_ifname(self):
        """Name of bridge network interface controlled by the interface, e.g., br0"""

        return self.get('BridgeIfname')

    def get_bss_expire_age(self):
        """Identical to bss_expiration_age entry in wpa_supplicant.conf file"""

        return self.get('BSSExpireAge')

    def get_bss_expire_count(self):
        """Identical to bss_expiration_scan_count entry in wpa_supplicant.conf file"""

        return self.get('BSSExpireCount')

    def get_ap_scan(self):
        """Identical to ap_scan entry in wpa_supplicant configuration file.

                Possible values are 0, 1 or 2.
        """

        return self.get('ApScan')

    def set_country(self, country_code):
        self.set('Country', country_code)
Beispiel #6
0
class WpaSupplicant(BaseIface):
    """Interface implemented by the main wpa_supplicant D-Bus object

            Registered in the bus as "fi.w1.wpa_supplicant1"
    """

    INTERFACE_PATH = 'fi.w1.wpa_supplicant1'

    iface = DBusInterface(
        INTERFACE_PATH,
        Method('CreateInterface', arguments='a{sv}', returns='o'),
        Method('GetInterface', arguments='s', returns='o'),
        Method('RemoveInterface', arguments='o'),
        Signal('InterfaceAdded', 'o,a{sv}'),
        Signal('InterfaceRemoved', 'o'),
        Signal('PropertiesChanged', 'a{sv}')
    )

    def __init__(self, *args, **kwargs):
        BaseIface.__init__(self, *args, **kwargs)
        self._interfaces_cache = dict()

    def __repr__(self):
        return str(self)

    def __str__(self):
        return "WpaSupplicant(Interfaces: %s)" % self.get_interfaces()

    #
    # Methods
    #
    def get_interface(self, interface_name):
        """Get D-Bus object related to an interface which wpa_supplicant already controls

        :returns: Interface object that implements the wpa_supplicant Interface API.
        :rtype: :class:`~Interface`
        :raises InterfaceUnknown: wpa_supplicant doesn't know anything about `interface_name`
        :raises UnknownError: An unknown error occurred
        """

        interface_path = self._call_remote_without_introspection('GetInterface',
                                                                 interface_name)
        interface = self._interfaces_cache.get(interface_path, None)
        if interface is not None:
            return interface
        else:
            interface = Interface(interface_path, self._conn, self._reactor)
            self._interfaces_cache[interface_path] = interface
            return interface

    def create_interface(self, interface_name, driver=None):
        """Registers a wireless interface in wpa_supplicant

        :returns: Interface object that implements the wpa_supplicant Interface API
        :raises InterfaceExists: The `interface_name` specified is already registered
        :raises UnknownError: An unknown error occurred
        """

        interface_path = self._call_remote_without_introspection('CreateInterface',
                                                                 {'Ifname': interface_name,
                                                                  'Driver': driver})
        return Interface(interface_path, self._conn, self._reactor)

    def remove_interface(self, interface_path):
        """Deregisters a wireless interface from wpa_supplicant

        :param interface_path: D-Bus object path to the interface to be removed
        :returns: None
        :raises InterfaceUnknown: wpa_supplicant doesn't know anything about `interface_name`
        :raises UnknownError: An unknown error occurred
        """

        self._call_remote_without_introspection('RemoveInterface', interface_path)

    #
    # Properties
    #
    def get_debug_level(self):
        """Global wpa_supplicant debugging level

        :returns:  Possible values: "msgdump" (verbose debugging)
                                    "debug" (debugging)
                                    "info" (informative)
                                    "warning" (warnings)
                                    "error" (errors)
        :rtype: str
        """

        return self.get('DebugLevel')

    def get_debug_timestamp(self):
        """ Determines if timestamps are shown in debug logs"""

        return self.get('DebugTimestamp')

    def get_debug_showkeys(self):
        """Determines if secrets are shown in debug logs"""

        return self.get('DebugShowKeys')

    def get_interfaces(self):
        """An array with paths to D-Bus objects representing controlled interfaces"""

        return self.get('Interfaces')

    def get_eap_methods(self):
        """An array with supported EAP methods names"""

        return self.get('EapMethods')
Beispiel #7
0
class Bus(objects.DBusObject):
    """
    DBus Bus implementation.

    @ivar stdIface: L{interface.DBusInterface} containing the standard bus interface
    @type stdIface: L{interface.DBusInterface}
    """
    stdIface = DBusInterface(
        'org.freedesktop.DBus',
        Method('Hello', arguments='', returns='s'),
        Method('GetId', arguments='', returns='s'),
        Method('RequestName', arguments='su', returns='u'),
        Method('ReleaseName', arguments='s', returns='u'),
        Method('ListQueuedOwners', arguments='s', returns='as'),
        Method('AddMatch', arguments='s', returns=''),
        Method('RemoveMatch', arguments='s', returns=''),
        Method('GetNameOwner', arguments='s', returns='s'),
        Method('GetConnectionUnixUser', arguments='s', returns='u'),

        #Not Implemented Methods
        Method('GetConnectionUnixProcessId', arguments='s', returns='u'),
        Method('ListActivatableNames', arguments='', returns='as'),
        Method('UpdateActivationEnvironment', arguments='a{ss}', returns=''),
        Method('StartServiceByName', arguments='su', returns='u'),
        Method('GetAdtAuditSessionData', arguments='s', returns='u'),
        Method('GetConnectionSELinuxSecurityContext',
               arguments='su',
               returns='ay'),
        Method('ReloadConfig'),
        Signal('NameAcquired', arguments='s'),
        Signal('NameLost', arguments='s'),
        Signal('NameOwnerChanged', arguments='sss'))

    dbusInterfaces = [stdIface]

    def __init__(self):
        objects.DBusObject.__init__(self, '/org/freedesktop/DBus')
        self.uuid = binascii.hexlify(os.urandom(16))
        self.clients = dict()  # maps unique_bus_id to client connection
        self.busNames = dict()  # maps name to list of queued connections
        self.router = router.MessageRouter()
        self.next_id = 1
        self.obj_handler = objects.DBusObjectHandler(self)

        self.obj_handler.exportObject(self)

    # returns the new unique bus name for the client connection
    def clientConnected(self, proto):
        """
        Called when a client connects to the bus. This method assigns the
        new connection a unique bus name.
        """
        proto.uniqueName = ':1.%d' % (self.next_id, )
        self.next_id += 1
        self.clients[proto.uniqueName] = proto

    def clientDisconnected(self, proto):
        """
        Called when a client disconnects from the bus
        """
        for rule_id in proto.matchRules:
            self.router.delMatch(rule_id)

        for busName in proto.busNames.iterkeys():
            self.dbus_ReleaseName(busName, proto.uniqueName)

        if proto.uniqueName:
            del self.clients[proto.uniqueName]

    def sendMessage(self, msg):
        """
        Sends the supplied message to the correct destination. The 
        @type msg: L{message.DBusMessage}
        @param msg: The 'destination' field of the message must be set for
                    method calls and returns
        """
        if msg._messageType in (1, 2):
            assert msg.destination, 'Failed to specify a message destination'

        if msg.destination is not None:
            if msg.destination[0] == ':':
                p = self.clients.get(msg.destination, None)
            else:
                p = self.busNames.get(msg.destination, None)
                if p:
                    p = p[0]

            #print 'SND: ', msg._messageType, ' to ',  p.uniqueName, 'serial', msg.serial,

            if p:
                p.sendMessage(msg)
            else:
                log.msg('Invalid bus name in msg.destination: ' +
                        msg.destination)
        else:
            self.router.routeMessage(msg)

    def messageReceived(self, p, msg):
        mt = msg._messageType

        #print 'MSG: ', mt, ' from ', p.uniqueName, ' to ', msg.destination

        try:
            if mt == 1:
                self.methodCallReceived(p, msg)
            elif mt == 2:
                self.methodReturnReceived(p, msg)
            elif mt == 3:
                self.errorReceived(p, msg)
            elif mt == 4:
                self.signalReceived(p, msg)

            if msg.destination and not msg.destination == 'org.freedesktop.DBus':
                self.sendMessage(msg)

            self.router.routeMessage(msg)
        except DError, e:
            sig = None
            body = None
            if e.errorMessage:
                sig = 's'
                body = [e.errorMessage]

            r = message.ErrorMessage(e.errorName,
                                     msg.serial,
                                     signature=sig,
                                     body=body)
            p.sendMessage(r)
Beispiel #8
0
class Bus(objects.DBusObject):
    """
    DBus Bus implementation.

    @ivar stdIface: L{interface.DBusInterface} containing the standard bus interface
    @type stdIface: L{interface.DBusInterface}
    """
    stdIface = DBusInterface(
        'org.freedesktop.DBus',
        Method('Hello', arguments='', returns='s'),
        Method('GetId', arguments='', returns='s'),
        Method('RequestName', arguments='su', returns='u'),
        Method('ReleaseName', arguments='s', returns='u'),
        Method('ListQueuedOwners', arguments='s', returns='as'),
        Method('AddMatch', arguments='s', returns=''),
        Method('RemoveMatch', arguments='s', returns=''),
        Method('GetNameOwner', arguments='s', returns='s'),
        Method('GetConnectionUnixUser', arguments='s', returns='u'),

        #Not Implemented Methods
        Method('GetConnectionUnixProcessId', arguments='s', returns='u'),
        Method('ListActivatableNames', arguments='', returns='as'),
        Method('UpdateActivationEnvironment', arguments='a{ss}', returns=''),
        Method('StartServiceByName', arguments='su', returns='u'),
        Method('GetAdtAuditSessionData', arguments='s', returns='u'),
        Method('GetConnectionSELinuxSecurityContext',
               arguments='su',
               returns='ay'),
        Method('ReloadConfig'),
        Signal('NameAcquired', arguments='s'),
        Signal('NameLost', arguments='s'),
        Signal('NameOwnerChanged', arguments='sss'))

    dbusInterfaces = [stdIface]

    def __init__(self):
        objects.DBusObject.__init__(self, '/org/freedesktop/DBus')
        self.uuid = binascii.hexlify(os.urandom(16))
        self.clients = dict()  # maps unique_bus_id to client connection
        self.busNames = dict()  # maps name to list of queued connections
        self.router = router.MessageRouter()
        self.next_id = 1
        self.obj_handler = objects.DBusObjectHandler(self)

        self.obj_handler.exportObject(self)

    # returns the new unique bus name for the client connection
    def clientConnected(self, proto):
        """
        Called when a client connects to the bus. This method assigns the
        new connection a unique bus name.
        """
        proto.uniqueName = ':1.%d' % (self.next_id, )
        self.next_id += 1
        self.clients[proto.uniqueName] = proto

    def clientDisconnected(self, proto):
        """
        Called when a client disconnects from the bus
        """
        for rule_id in proto.matchRules:
            self.router.delMatch(rule_id)

        for busName in proto.busNames.iterkeys():
            self.dbus_ReleaseName(busName, proto.uniqueName)

        if proto.uniqueName:
            del self.clients[proto.uniqueName]

    def sendMessage(self, msg):
        """
        Sends the supplied message to the correct destination. The 
        @type msg: L{message.DBusMessage}
        @param msg: The 'destination' field of the message must be set for
                    method calls and returns
        """
        if msg._messageType in (1, 2):
            assert msg.destination, 'Failed to specify a message destination'

        if msg.destination is not None:
            if msg.destination[0] == ':':
                p = self.clients.get(msg.destination, None)
            else:
                p = self.busNames.get(msg.destination, None)
                if p:
                    p = p[0]

            #print 'SND: ', msg._messageType, ' to ',  p.uniqueName, 'serial', msg.serial,

            if p:
                p.sendMessage(msg)
            else:
                log.msg('Invalid bus name in msg.destination: ' +
                        msg.destination)
        else:
            self.router.routeMessage(msg)

    def messageReceived(self, p, msg):
        mt = msg._messageType

        #print 'MSG: ', mt, ' from ', p.uniqueName, ' to ', msg.destination

        try:
            if mt == 1:
                self.methodCallReceived(p, msg)
            elif mt == 2:
                self.methodReturnReceived(p, msg)
            elif mt == 3:
                self.errorReceived(p, msg)
            elif mt == 4:
                self.signalReceived(p, msg)

            if msg.destination and not msg.destination == 'org.freedesktop.DBus':
                self.sendMessage(msg)

            self.router.routeMessage(msg)
        except DError as e:
            sig = None
            body = None
            if e.errorMessage:
                sig = 's'
                body = [e.errorMessage]

            r = message.ErrorMessage(e.errorName,
                                     msg.serial,
                                     signature=sig,
                                     body=body)
            p.sendMessage(r)

    def methodCallReceived(self, p, msg):
        if msg.destination == 'org.freedesktop.DBus':
            self.obj_handler.handleMethodCallMessage(msg)

    def methodReturnReceived(self, p, msg):
        pass

    def errorReceived(self, p, msg):
        pass

    def signalReceived(self, p, msg):
        pass

    def sendSignal(self,
                   p,
                   member,
                   signature=None,
                   body=None,
                   path='/org/freedesktop/DBus',
                   interface='org.freedesktop.DBus'):
        """
        Sends a signal to a specific connection
        
        @type p: L{BusProtocol}
        @param p: L{BusProtocol} instance to send a signal to

        @type member: C{string}
        @param member: Name of the signal to send

        @type path: C{string}
        @param path: Path of the object emitting the signal. Defaults to
                     'org/freedesktop/DBus'
        
        @type interface: C{string}
        @param interface: If specified, this specifies the interface containing the
                          desired method. Defaults to 'org.freedesktop.DBus'

        @type body: None or C{list}
        @param body: If supplied, this is a list of signal arguments. The contents
                     of the list must match the signature.

        @type signature: None or C{string}
        @param signature: If specified, this specifies the DBus signature of the
                          body of the DBus Signal message. This string must
                          be a valid Signature string as defined by the DBus
                          specification. If the body argumnent is supplied ,\
                          this parameter must be provided.
        """
        if not isinstance(body, (list, tuple)):
            body = [body]

        s = message.SignalMessage(path, member, interface, p.uniqueName,
                                  signature, body)
        p.sendMessage(s)

    def broadcastSignal(self,
                        member,
                        signature=None,
                        body=None,
                        path='/org/freedesktop/DBus',
                        interface='org.freedesktop.DBus'):
        """
        Sends a signal to all connections with registered interest
        
        @type member: C{string}
        @param member: Name of the signal to send

        @type path: C{string}
        @param path: Path of the object emitting the signal. Defaults to
                     'org/freedesktop/DBus'
        
        @type interface: C{string}
        @param interface: If specified, this specifies the interface containing the
                          desired method. Defaults to 'org.freedesktop.DBus'

        @type body: None or C{list}
        @param body: If supplied, this is a list of signal arguments. The contents
                     of the list must match the signature.

        @type signature: None or C{string}
        @param signature: If specified, this specifies the DBus signature of the
                          body of the DBus Signal message. This string must
                          be a valid Signature string as defined by the DBus
                          specification. If the body argumnent is supplied ,\
                          this parameter must be provided.
        """
        if not isinstance(body, (list, tuple)):
            body = [body]

        s = message.SignalMessage(path, member, interface, None, signature,
                                  body)
        self.router.routeMessage(s)

    #----------------------------------------------------------------
    # DBus Object Interface
    #
    def dbus_Hello(self, dbusCaller=None):
        raise DError('org.freedesktop.DBus.Error.Failed',
                     'Already handled an Hello message')

    def dbus_GetId(self):
        return self.uuid

    def dbus_RequestName(self, name, flags, dbusCaller=None):
        caller = self.clients[dbusCaller]

        allow_replacement = bool(flags & 0x1)
        replace_existing = bool(flags & 0x2)
        do_not_queue = bool(flags & 0x4)

        if not name:
            raise DError('org.freedesktop.DBus.Error.InvalidArgs',
                         'Empty string is not a valid bus name')

        if name[0] == ':':
            raise DError(
                'org.freedesktop.DBus.Error.InvalidArgs',
                'Cannot acquire a service starting with \':\' such as "%s"' %
                (name, ))

        try:
            marshal.validateBusName(name)
        except error.MarshallingError as e:
            raise DError('org.freedesktop.DBus.Error.InvalidArgs', str(e))

        def signalAcq(old_owner_name):
            self.sendSignal(caller, 'NameAcquired', 's', name)
            self.broadcastSignal('NameOwnerChanged', 'sss',
                                 [name, old_owner_name, caller.uniqueName])

        if not name in self.busNames:
            self.busNames[name] = [
                caller,
            ]
            caller.busNames[name] = allow_replacement

            signalAcq('')

            return client.NAME_ACQUIRED
        else:
            queue = self.busNames[name]
            owner = queue[0]

            if owner is caller:
                # Update the replacement flag
                owner.busNames[name] = allow_replacement

                return client.NAME_ALREADY_OWNER
            else:
                if not replace_existing:
                    return client.NAME_IN_USE

                if owner.busNames[name]:
                    del queue[0]
                    queue.insert(0, caller)
                    del owner.busNames[name]
                    caller.busNames[name] = allow_replacement
                    self.sendSignal(owner, 'NameLost', 's', name)
                    signalAcq(owner.uniqueName)
                    return client.NAME_ACQUIRED
                else:
                    if do_not_queue:
                        return client.NAME_IN_USE

                    queue.append(caller)
                    caller.busNames[name] = allow_replacement

                    return client.NAME_IN_QUEUE

    def dbus_ReleaseName(self, name, dbusCaller=None):
        caller = self.clients[dbusCaller]

        queue = self.busNames.get(name, None)

        if queue is None:
            return client.NAME_NON_EXISTENT

        owner = queue[0]

        if not caller is owner:
            return client.NAME_NOT_OWNER

        del queue[0]

        if caller.isConnected:
            self.sendSignal(caller, 'NameLost', 's', name)

        if queue:
            self.sendSignal(queue[0], 'NameAcquired', 's', name)
        else:
            del self.busNames[name]

        return client.NAME_RELEASED

    def dbus_ListQueuedOwners(self, name):
        queue = self.busNames.get(name, None)
        if queue:
            return [p.uniqueName for p in queue]
        else:
            raise DError(
                'org.freedesktop.DBus.Error.NameHasNoOwner',
                'Could not get owners of name \'%s\': no such name' % (name, ))

    def dbus_AddMatch(self, rule, dbusCaller=None):
        caller = self.clients[dbusCaller]

        kwargs = dict(mtype=None,
                      sender=None,
                      interface=None,
                      member=None,
                      path=None,
                      path_namespace=None,
                      destination=None,
                      args=None,
                      arg_paths=None,
                      arg0namespace=None)

        for item in rule.split(','):
            k, v = item.split('=')

            value = v[1:-1]

            if k == 'type':
                k = 'mtype'

            if k in kwargs:
                kwargs[k] = value

            elif k.startswith('arg'):
                if k.endswith('path'):
                    if kwargs['arg_paths'] is None:
                        kwargs['arg_paths'] = list()
                    kwargs['arg_paths'].append((int(k[3:-4]), value))
                else:
                    if kwargs['args'] is None:
                        kwargs['args'] = list()
                    kwargs['args'].append((int(k[3:]), value))

        self.router.addMatch(caller.sendMessage, **kwargs)

    def dbus_GetNameOwner(self, busName):
        if busName.startswith(':'):
            conn = self.clients.get(busName, None)
        else:
            conn = self.busNames.get(busName, None)
            if conn:
                conn = conn[0]

        if conn is None:
            raise DError(
                "org.freedesktop.DBus.Error.NameHasNoOwner",
                "Could not get UID of name '%s': no such name" % (busName, ))

        return conn.uniqueName

    def dbus_GetConnectionUnixUser(self, busName):
        if busName.startswith(':'):
            conn = self.clients.get(busName, None)
        else:
            conn = self.busNames.get(busName, None)
            if conn:
                conn = conn[0]

        if conn is None:
            raise DError(
                "org.freedesktop.DBus.Error.NameHasNoOwner",
                "Could not get UID of name '%s': no such name" % (busName, ))

        try:
            import pwd
            return pwd.getpwnam(conn.username).pw_uid
        except:
            raise DError(
                'org.freedesktop.DBus.Error',
                "Unable to determine unix user for bus '%s'" % (busName, ))
Beispiel #9
0
class Rfm69DBusService(objects.DBusObject):
	
	class NotImplementedError(Exception):
		dbusErrorName = "org.agile-rfm69.NotImplemented"
	
	class IOError(Exception):
		dbusErrorName = "org.agile-rfm69.IOError"
	
	class ValueError(Exception):
		dbusErrorName = "org.agile-rfm69.ValueError"
	
	class TypeError(Exception):
		dbusErrorName = "org.agile-rfm69.TypeError"
	
	iface = DBusInterface("iot.agile.Protocol",
					Method("Connect"),
					Method("Connected", returns="b"),
					Method("Disconnect"),
					Method("Setup", arguments="a{sv}"),
					Method("Send", arguments="a{sv}"),
					Method("Receive", returns="a{sv}"),
					Method("Subscribe", arguments="a{sv}"),
					Method("StartDiscovery"),
					Method("StopDiscovery"),
					Property("Devices", "av", writeable=False),
					Property("Name", "s", writeable=False),
					Property("Driver", "s", writeable=False),
					Property("Data", "a{sv}", writeable=False),
					Property("Status", "n", writeable=False)
					)
	
	_devices = DBusProperty("Devices")
	_name = DBusProperty("Name")
	_driver = DBusProperty("Driver")
	_lastRecord = DBusProperty("Data")
	_status = DBusProperty("Status")
	
	dbusInterfaces = [iface]
	
	def __init__(self, objectPath):
		super(Rfm69DBusService, self).__init__(objectPath)
		
		self._lastRecord = {"STATUS": "TIMEOUT"}
		self._status = 0
		self._driver = "No driver"
		self._name = PROTOCOL_NAME
		self._devices = ["None"]
		
		self._logger = logging.getLogger()
		self._full_path = PROTOCOL_PATH
		self._connected = False
		self._setup = {
			"MODEM_CONFIG_TABLE": MODEM_CONFIG_TABLE,
			"MODEM_CONFIG": MODEM_CONFIG,
			"key": MODEM_KEY,
			"channel": CHANNEL
		}

	def _setModemConfig(self):
		# Set RFM69 registers as per config
		settings = MODEM_CONFIG_TABLE[self._setup["MODEM_CONFIG"]]
		addresses = [0x02, 0x03, 0x04, 0x05, 0x06, 0x19, 0x1a, 0x37]
		for value, address in zip(settings, addresses):
			self._rfm69.spi_write(address, value)
			
	def _setModemKey(self):
		self._logger.debug("enabling ecryption")
		self._rfm69.set_encryption(self._setup["key"])
		
	def _getConnected(self):
		return self._connected
	
	def _setConnected(self, status):
		if status:
			self._connected = True
		else:
			self._connected = False 
	
	def dbus_Connect(self):
		self._logger.debug(
			"%s@Connect: Connect INIT", self._full_path)
		if self._getConnected():
			self._logger.debug(
				"%s@Connect: Module is already connected", self._full_path)
			raise self.IOError("Module is already connected.")
		
		self._logger.debug(
			"%s@Connect: MODE=%s", self._full_path, self._setup["MODEM_CONFIG"])
		self._rfm69 = rfm69.RFM69(25, 24, 0, rfm69.RFM69Configuration(), True)
		self._rfm69.set_channel(self._setup["channel"])
		self._rfm69.set_address(1)
		
		self._logger.debug("Class initialized")
		self._logger.debug("Calibrating RSSI")
		# self._rfm69.calibrate_rssi_threshold()
		self._logger.debug("Checking temperature")
		self._logger.debug(self._rfm69.read_temperature())
		
		# Make sure settings are correct to talk to other radios
		self._setModemConfig()
		self._setModemKey()
		
		self._logger.debug("reading all registers")
		for result in self._rfm69.read_registers():
			self._logger.debug(result)
		
		# Won't get here if something went wrong reading temps etc.
		self._setConnected(True)
		self._logger.debug("%s@Connect: Connect OK", self._full_path)
		
	def dbus_Connected(self):
		return self._connected

	def dbus_Disconnect(self):
		self._logger.debug(
			"%s@Disconnect: Disconnect INIT", self._full_path)
		self._setConnected(False)
		self._rfm69.disconnect()
		self._logger.debug("%s@Disconnect: Disconnect OK", self._full_path) 

	def dbus_Setup(self, args):
		self._logger.debug("%s@Setup: Setup INIT", self._full_path)
		self._setup.clear()
		self._setup = {}
		
		modemConfigTable = args.pop("MODEM_CONFIG_TABLE", MODEM_CONFIG_TABLE)
		self._setup["MODEM_CONFIG_TABLE"] = modemConfigTable
		
		modemConfig = args.pop("MODEM_CONFIG", MODEM_CONFIG)
		self._setup["MODEM_CONFIG"] = modemConfig
			
		modemKey = args.pop("key", MODEM_KEY)
		self._setup["key"] = modemKey
		
		channel = args.pop("channel", CHANNEL)
		self._setup["channel"] = channel
		
		self._logger.debug(
			"%s@Setup: Parameters=%s", self._full_path, self._setup)
		self._logger.debug(
			"%s@Setup: Setup OK", self._full_path)

	def dbus_Send(self, args):
		self._logger.debug(
			"%s@Send: Send INIT", self._full_path)
		
		if not self._getConnected():
			self._logger.debug(
				"%s@Send: Module is not connected", self._full_path)
			raise self.IOError("Module is not connected.")
		
		sendData = args.pop("DATA", "")
		
		if not sendData:
			self._logger.debug(
				"%s@Send/Rfm69: No data provided", self._full_path)
			raise self.ValueError("You must provide the data.")
		
		if not type(sendData) is list:
			self._logger.debug(
				"%s@Send/Rfm69: Data in wrong format", self._full_path)
			raise self.TypeError("You must provide the data as a list of values.")
		
		# Turn it back into bytes again, since D-Bus turns it into a list
		sendData = struct.pack("B"*len(sendData), *sendData)
		self._rfm69.send_packet(sendData)
	
	def dbus_Receive(self):
		self._logger.debug("%s@Receive: Receive INIT", self._full_path)
		if not self._getConnected():
			self._logger.debug(
				"%s@Receive: Module is not connected", self._full_path)
			raise self.IOError("Module is not connected.")
		
		response = self._rfm69.wait_for_packet(timeout=60)
		if response:
			(data, rssi) = response
			self._logger.debug("%s@Receive: receiveDone()", self._full_path)
			self._lastRecord = {"DATA": data, "RSSI": rssi, "STATUS": "OK"}
		else:
			self._lastRecord = {"STATUS": "TIMEOUT"}
		
		return self._lastRecord
		
	def dbus_Subscribe(self, args):
		raise self.NotImplementedError("Function not supported.")
	
	def dbus_StartDiscovery(self):
		pass
	
	def dbus_StopDiscovery(self):
		pass
Beispiel #10
0
    ))

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

# global list of tag devices that are currently within radio range
#
taglist = dict()

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

TAGNET_BUS_NAME = 'org.tagnet.tagmaster'  # bus name for tagnet forwarder
TAGNET_OBJECT_PATH = '/org/tagnet/tagmaster'

tagmaster_dbus_interface = DBusInterface(
    TAGNET_BUS_NAME,
    Method('tag_list', arguments='s', returns='ay'),
    Signal('tag_found', 'ay'),  # report new tag
    Signal('tag_lost', 'ay'),  # report tag out of range
    Signal('tag_events', 'ay'),  # report new tag events
    Signal('tagnet_status', 'ay'),
)


class TagNetDbus(objects.DBusObject):
    """
    provides the interface for accessing the tagnet port
    """
    dbusInterfaces = [tagmaster_dbus_interface]

    def __init__(self, object_path):
        super(TagNetDbus, self).__init__(object_path)
Beispiel #11
0
class BlueZGattCharacteristic(DBusObject):
    """
    org.bluez.GattCharacteristic1 interface implementation
    """

    interface_name: str = defs.GATT_CHARACTERISTIC_INTERFACE

    iface: DBusInterface = DBusInterface(
        interface_name,
        Method("ReadValue", arguments="a{sv}", returns="ay"),
        Method("WriteValue", arguments="aya{sv}"),
        Method("StartNotify"),
        Method("StopNotify"),
        Property("UUID", "s"),
        Property("Service", "o"),
        Property("Value", "ay"),
        Property("Notifying", "b"),
        Property("Flags", "as"),
    )

    dbusInterfaces: List[DBusInterface] = [iface]

    uuid: DBusProperty = DBusProperty("UUID")
    service: DBusProperty = DBusProperty("Service")
    flags: DBusProperty = DBusProperty("Flags")
    value: DBusProperty = DBusProperty("Value")
    notifying: DBusProperty = DBusProperty("Notifying")

    def __init__(
            self,
            uuid: str,
            flags: List[Flags],
            index: int,
            service: "BlueZGattService",  # noqa: F821
    ):
        """
        Create a BlueZ Gatt Characteristic

        Parameters
        ----------
        uuid : str
            The unique identifier for the characteristic
        flags : List[Flags]
            A list of strings that represent the properties of the
            characteristic
        index : int
            The index number for this characteristic in the service
        service : BlueZService
            The Gatt Service that owns this characteristic
        """
        self.path: str = service.path + "/char" + f"{index:04d}"
        self.uuid: str = uuid
        self.flags: List[str] = [x.value for x in flags]
        self.service: str = service.path  # noqa: F821
        self._service: "BlueZGattService" = service  # noqa: F821

        self.value: bytes = b""
        self.notifying: bool = False
        self.descriptors: List["BlueZGattDescriptor"] = []  # noqa: F821

        super(BlueZGattCharacteristic, self).__init__(self.path)

    @dbusMethod(interface_name, "ReadValue")
    def ReadValue(self, options: Dict) -> bytearray:  # noqa: N802
        """
        Read the value of the characteristic.
        This is to be fully implemented at the application level

        Parameters
        ----------
        options : Dict
            A list of options

        Returns
        -------
        bytearray
            The bytearray that is the value of the characteristic
        """
        f = self._service.app.Read
        if f is None:
            raise NotImplementedError()
        return f(self)

    @dbusMethod(interface_name, "WriteValue")
    def WriteValue(self, value: bytearray, options: Dict):  # noqa: N802
        """
        Write a value to the characteristic
        This is to be fully implemented at the application level

        Parameters
        ----------
        value : bytearray
            The value to set
        options : Dict
            Some options for you to select from
        """
        f = self._service.app.Write
        if f is None:
            raise NotImplementedError()
        f(self, value)

    @dbusMethod(interface_name, "StartNotify")
    def StartNotify(self):  # noqa: N802
        """
        Begin a subscription to the characteristic
        """
        f = self._service.app.StartNotify
        if f is None:
            raise NotImplementedError()
        f(None)
        self._service.app.subscribed_characteristics.append(self.uuid)

    @dbusMethod(interface_name, "StopNotify")
    def StopNotify(self):  # noqa: N802
        """
        Stop a subscription to the characteristic
        """
        f = self._service.app.StopNotify
        if f is None:
            raise NotImplementedError()
        f(None)
        self._service.app.subscribed_characteristics.remove(self.uuid)

    async def get_obj(self) -> Dict:
        """
        Obtain the underlying dictionary within the BlueZ API that describes
        the characteristic

        Returns
        -------
        Dict
            The dictionary that describes the characteristic
        """
        dbus_obj: RemoteDBusObject = await self._service.app.bus.getRemoteObject(
            self._service.app.destination,
            self.path).asFuture(self._service.app.loop)
        dict_obj: Dict = await dbus_obj.callRemote(
            "GetAll",
            defs.GATT_CHARACTERISTIC_INTERFACE,
            interface=defs.PROPERTIES_INTERFACE,
        ).asFuture(self._service.app.loop)
        return dict_obj
Beispiel #12
0
from construct                import *

from dockcomFSM               import Events, Actions, States, table
from dockcomact               import DockcomFsmActionHandlers
from dockcomserial            import DockcomSerial
from dockcomdef               import *
import dockcomtrace

__all__ = ['BUS_NAME', 'OBJECT_PATH', 'dockcom_dbus_interface', 'DockcomDbus', 'reactor_loop']

BUS_NAME = 'org.tagnet.dockcom'
OBJECT_PATH = '/org/tagnet/dockcom/0/0'   # object name includes device id/port numbers

dockcom_dbus_interface = DBusInterface( BUS_NAME,
                            Method('clear_status', returns='s'),
                            Method('control', arguments='s', returns='s'),
                            Method('dump', arguments='s', returns='s'),
                            Method('dump_trace', arguments='s', returns='a(dyssay)'),
                            Method('send', arguments='ayu', returns='s'),
                            Method('status', returns='s'),
                            Signal('new_status', 's'),
                            Signal('receive', 'ayu'),
                            Signal('send_cmp', 's'),
                         )

class DockcomDbus(objects.DBusObject):
    """
    provides the interface for accessing the Dockcom Serial Chip Driver
    """
    dbusInterfaces = [dockcom_dbus_interface]