Source code for bt_manager.media
from __future__ import unicode_literals
from interface import BTSimpleInterface, BTInterface
from manager import BTManager
from adapter import BTAdapter
from exceptions import BTDeviceNotSpecifiedException
import dbus.service
[docs]class BTMedia(BTSimpleInterface):
"""
Wrapper around dbus to encapsulate org.bluez.Media
interface.
The media interface allows media endpoints to be
established in accordance with the capabilities
of a specific media service profile.
For example, an A2DP media endpoint could be
created allowing data from a remote device
to be streamed to/from the sender.
Each media endpoint is associated with a service
object instance that implements the required
behaviours of the endpoint. The service object
must be created at a given path before it
is registered.
See also: :py:class:`.GenericEndpoint`
"""
def __init__(self, adapter_id=None):
manager = BTManager()
if (adapter_id is None):
adapter_path = manager.default_adapter()
else:
adapter_path = manager.find_adapter(adapter_id)
BTSimpleInterface.__init__(self, adapter_path, 'org.bluez.Media')
[docs] def register_endpoint(self, path, properties):
"""
Register a local end point to sender, the sender can
register as many end points as it likes.
The properties dictionary parameter may take the
following fields:
* UUID(str): UUID of the profile which the endpoint is
for e.g., ``SERVICES['AudioSource']``
* Codec(byte): Assigned mumber of codec that the
endpoint implements. The values should match the profile
specification which is indicated by the UUID
e.g., ``A2DP_CODECS['SBC']``
* Capabilities(array{byte}): Capabilities blob, it is used
as it is so the size and byte order must match.
See also: :py:data:`.A2DP_CODECS` and :py:data:`.SERVICES`
If the sender disconnects the end points are
automatically unregistered.
:param: str path: a freely definable path name for
registering the endpoint e.g., '/endpoint/a2dpsource'.
:param: dict properties: a dictionary defining the
endpoints properties which may contain.
:return:
:raises dbus.Exception: org.bluez.Error.InvalidArguments
:raises dbus.Exception: org.bluez.Error.NotSupported
"""
self._interface.RegisterEndpoint(path, properties)
[docs] def unregister_endpoint(self, path):
"""
Unregister sender end point.
:param: str path: a freely definable path name previously
used for registering via :py:meth:`register_endpoint`
:return:
"""
self._interface.UnregisterEndpoint(path)
[docs]class BTMediaTransport(BTInterface):
"""
Wrapper around dbus to encapsulate the org.bluez.MediaTransport
interface.
A media transport instance provides a mechanism by which
data streamed to/from a device can be sent/received via
the L2 transport.
This is done by `acquiring` a transport file descriptor
object which then allows the underlying file to be
read from or written to.
When finished, the file descriptor should be closed using
a normal UNIX **close()** operation before `releasing` the
media transport back again.
.. warning:: The media transport interface does not implement
any CODECs and should be regarded as providing direct
access to the underlying data transport.
:param: str path: [Optional] Absolute object path to the
device's file descriptor node carrying the media transport.
:param: str dev_path: [Optional] Device's object path. The
file descriptor node will be provided via `fd` argument.
:param: int fd: [Optional] File number for the file descriptor
node associated with the device given by either `dev_path`
or `dev_id`
:param: str adapter_id: [Optional] Adapter identifier from
which to look-up the `dev_id`
:param: str dev_id: [Optional] Device identifier of the form
e.g., '11:22:33:44:55:66'.
:raises BTDeviceNotSpecifiedException: if the device path could
not be determined unambiguously from the supplied parameters.
:Properties:
* **Device(str) [readonly]**: Device object which the transport
is connected to.
* **UUID(str) [readonly]**: UUID of the profile which the
transport is for.
* **Codec(byte) [readonly]**: Assigned mumber of codec that the
transport support. The value should match the profile
specification which is indicated by the UUID.
* **Configuration(byte) [readonly]**: Configuration blob, it is
used as it is so the size and byte order must match.
* **Delay(uint16) [readwrite]**: Optional. Transport delay in
1/10 of milisecond, this property is only writeable when
the transport was acquired by the sender.
* **NREC(boolean) [readwrite]**: Optional. Indicates if echo
cancelling and noise reduction functions are active in the
transport, this property is only writeable when the transport
was acquired by the sender.
* **InbandRingtone(boolean) [readwrite]**: Optional. Indicates
if the transport support sending ringtones, this property
is only writeable when the transport was acquired by the
sender.
* **Routing(str) [readonly]**: Optional. Indicates where is the
transport being routed and may be 'HCI' or 'PCM'.
"""
def __init__(self, path, fd=None, adapter_id=None,
dev_path=None, dev_id=None):
if (not path):
fd_suffix = '/fd' + str(fd)
if (dev_path):
path = dev_path + fd_suffix
elif (dev_id):
if (adapter_id):
adapter = BTAdapter(adapter_id)
else:
adapter = BTAdapter()
path = adapter.find_device(dev_id) + fd_suffix
else:
raise BTDeviceNotSpecifiedException
BTInterface.__init__(self, path, 'org.bluez.MediaTransport')
[docs] def acquire(self, access_type):
"""
Acquire transport file descriptor and the MTU for read
and/or write respectively. Possible access_type:
* "r" : Read only access
* "w" : Write only access
* "rw": Read and write access
:param str access_type: as defined above.
:return: A tuple of the form (fd, write_mtu, read_mtu)
:rtype: tuple
"""
return self._interface.Acquire(access_type)
[docs] def release(self, access_type):
"""
Releases file descriptor.
Possible access_type:
* "r" : Read only access
* "w" : Write only access
* "rw": Read and write access
:param str access_type: as defined above.
"""
return self._interface.Release(access_type)
[docs]class GenericEndpoint(dbus.service.Object):
"""
Generic media endpoint service object class.
.. note:: GenericEndpoint can't be directly instantiated.
It should be sub-classed and provides a template for
implementing an endpoint service object.
:param str path: Freely definable object path for the
media endpoint e.g., '/endpoint/a2dpsink'.
"""
def __init__(self, path):
bus = dbus.SystemBus()
super(GenericEndpoint, self).__init__(bus, path)
[docs] def get_properties(self):
"""
Returns the properties of the endpoint. These should
be initialized by a suitable subclass implementation
by setting the `properties` class attribute.
:return properties: dictionary of endpoint's capabilties
:rtype: dict
"""
return self.properties
# Service object entry points defined below here --
# you will need to implement these in your subclass
@dbus.service.method("org.bluez.MediaEndpoint",
in_signature="", out_signature="")
[docs] def Release(self):
"""
Called by bluez to let us know our registration
has been released and the endpoint no longer exists
:return:
"""
pass
@dbus.service.method("org.bluez.MediaEndpoint",
in_signature="", out_signature="")
[docs] def ClearConfiguration(self):
"""
Called by bluez to let us know that the audio
streaming process has been reset, for whatever reason,
and we should now perform clean-up.
:return:
"""
pass
@dbus.service.method("org.bluez.MediaEndpoint",
in_signature="oay", out_signature="")
[docs] def SetConfiguration(self, transport, config):
"""
Provides a path to the media transport to use and
the active configuration that was negotiated.
:param str transport: Path to a device's file descriptor node
which can be used to acquire the media transport e.g.,
'/org/bluez/985/hci0/dev_00_11_67_D2_AB_EE/fd0'
:param array{byte} config: The configuration being used for
the media transport.
See also: :py:class:`.BTMediaTransport`
"""
pass
@dbus.service.method("org.bluez.MediaEndpoint",
in_signature="ay", out_signature="ay")
[docs] def SelectConfiguration(self, caps):
"""
Initiates negotiations of the capabilities which should
be resolved by this method.
:param dict caps: Dictionary of device's capabilities
for resolving capability negotiation by comparing
to own capabilities.
:return config: The resolved configuration
to be used for the media transport.
:rtype: array{byte}
"""
pass