Home | History | Annotate | Download | only in bluetooth
      1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import array
      6 import btsocket
      7 import fcntl
      8 import logging
      9 import socket
     10 import struct
     11 
     12 
     13 # Constants from lib/mgmt.h in BlueZ source
     14 MGMT_INDEX_NONE = 0xFFFF
     15 
     16 MGMT_HDR_SIZE = 6
     17 
     18 MGMT_STATUS_SUCCESS            = 0x00
     19 MGMT_STATUS_UNKNOWN_COMMAND    = 0x01
     20 MGMT_STATUS_NOT_CONNECTED      = 0x02
     21 MGMT_STATUS_FAILED             = 0x03
     22 MGMT_STATUS_CONNECT_FAILED     = 0x04
     23 MGMT_STATUS_AUTH_FAILED        = 0x05
     24 MGMT_STATUS_NOT_PAIRED         = 0x06
     25 MGMT_STATUS_NO_RESOURCES       = 0x07
     26 MGMT_STATUS_TIMEOUT            = 0x08
     27 MGMT_STATUS_ALREADY_CONNECTED  = 0x09
     28 MGMT_STATUS_BUSY               = 0x0a
     29 MGMT_STATUS_REJECTED           = 0x0b
     30 MGMT_STATUS_NOT_SUPPORTED      = 0x0c
     31 MGMT_STATUS_INVALID_PARAMS     = 0x0d
     32 MGMT_STATUS_DISCONNECTED       = 0x0e
     33 MGMT_STATUS_NOT_POWERED        = 0x0f
     34 MGMT_STATUS_CANCELLED          = 0x10
     35 MGMT_STATUS_INVALID_INDEX      = 0x11
     36 MGMT_STATUS_RFKILLED           = 0x12
     37 
     38 MGMT_OP_READ_VERSION           = 0x0001
     39 MGMT_OP_READ_COMMANDS          = 0x0002
     40 MGMT_OP_READ_INDEX_LIST        = 0x0003
     41 MGMT_OP_READ_INFO              = 0x0004
     42 MGMT_OP_SET_POWERED            = 0x0005
     43 MGMT_OP_SET_DISCOVERABLE       = 0x0006
     44 MGMT_OP_SET_CONNECTABLE        = 0x0007
     45 MGMT_OP_SET_FAST_CONNECTABLE   = 0x0008
     46 MGMT_OP_SET_PAIRABLE           = 0x0009
     47 MGMT_OP_SET_LINK_SECURITY      = 0x000A
     48 MGMT_OP_SET_SSP                = 0x000B
     49 MGMT_OP_SET_HS                 = 0x000C
     50 MGMT_OP_SET_LE                 = 0x000D
     51 MGMT_OP_SET_DEV_CLASS          = 0x000E
     52 MGMT_OP_SET_LOCAL_NAME         = 0x000F
     53 MGMT_OP_ADD_UUID               = 0x0010
     54 MGMT_OP_REMOVE_UUID            = 0x0011
     55 MGMT_OP_LOAD_LINK_KEYS         = 0x0012
     56 MGMT_OP_LOAD_LONG_TERM_KEYS    = 0x0013
     57 MGMT_OP_DISCONNECT             = 0x0014
     58 MGMT_OP_GET_CONNECTIONS        = 0x0015
     59 MGMT_OP_PIN_CODE_REPLY         = 0x0016
     60 MGMT_OP_PIN_CODE_NEG_REPLY     = 0x0017
     61 MGMT_OP_SET_IO_CAPABILITY      = 0x0018
     62 MGMT_OP_PAIR_DEVICE            = 0x0019
     63 MGMT_OP_CANCEL_PAIR_DEVICE     = 0x001A
     64 MGMT_OP_UNPAIR_DEVICE          = 0x001B
     65 MGMT_OP_USER_CONFIRM_REPLY     = 0x001C
     66 MGMT_OP_USER_CONFIRM_NEG_REPLY = 0x001D
     67 MGMT_OP_USER_PASSKEY_REPLY     = 0x001E
     68 MGMT_OP_USER_PASSKEY_NEG_REPLY = 0x001F
     69 MGMT_OP_READ_LOCAL_OOB_DATA    = 0x0020
     70 MGMT_OP_ADD_REMOTE_OOB_DATA    = 0x0021
     71 MGMT_OP_REMOVE_REMOTE_OOB_DATA = 0x0022
     72 MGMT_OP_START_DISCOVERY        = 0x0023
     73 MGMT_OP_STOP_DISCOVERY         = 0x0024
     74 MGMT_OP_CONFIRM_NAME           = 0x0025
     75 MGMT_OP_BLOCK_DEVICE           = 0x0026
     76 MGMT_OP_UNBLOCK_DEVICE         = 0x0027
     77 MGMT_OP_SET_DEVICE_ID          = 0x0028
     78 MGMT_OP_SET_ADVERTISING        = 0x0029
     79 MGMT_OP_SET_BREDR              = 0x002A
     80 MGMT_OP_SET_STATIC_ADDRESS     = 0x002B
     81 MGMT_OP_SET_SCAN_PARAMS        = 0x002C
     82 MGMT_OP_SET_SECURE_CONN        = 0x002D
     83 MGMT_OP_SET_DEBUG_KEYS         = 0x002E
     84 MGMT_OP_SET_PRIVACY            = 0x002F
     85 MGMT_OP_LOAD_IRKS              = 0x0030
     86 MGMT_OP_GET_CONN_INFO          = 0x0031
     87 MGMT_OP_GET_CLOCK_INFO         = 0x0032
     88 MGMT_OP_ADD_DEVICE             = 0x0033
     89 MGMT_OP_REMOVE_DEVICE          = 0x0034
     90 MGMT_OP_LOAD_CONN_PARAM        = 0x0035
     91 MGMT_OP_READ_UNCONF_INDEX_LIST = 0x0036
     92 MGMT_OP_READ_CONFIG_INFO       = 0x0037
     93 MGMT_OP_SET_EXTERNAL_CONFIG    = 0x0038
     94 MGMT_OP_SET_PUBLIC_ADDRESS     = 0x0039
     95 
     96 MGMT_EV_CMD_COMPLETE           = 0x0001
     97 MGMT_EV_CMD_STATUS             = 0x0002
     98 MGMT_EV_CONTROLLER_ERROR       = 0x0003
     99 MGMT_EV_INDEX_ADDED            = 0x0004
    100 MGMT_EV_INDEX_REMOVED          = 0x0005
    101 MGMT_EV_NEW_SETTINGS           = 0x0006
    102 MGMT_EV_CLASS_OF_DEV_CHANGED   = 0x0007
    103 MGMT_EV_LOCAL_NAME_CHANGED     = 0x0008
    104 MGMT_EV_NEW_LINK_KEY           = 0x0009
    105 MGMT_EV_NEW_LONG_TERM_KEY      = 0x000A
    106 MGMT_EV_DEVICE_CONNECTED       = 0x000B
    107 MGMT_EV_DEVICE_DISCONNECTED    = 0x000C
    108 MGMT_EV_CONNECT_FAILED         = 0x000D
    109 MGMT_EV_PIN_CODE_REQUEST       = 0x000E
    110 MGMT_EV_USER_CONFIRM_REQUEST   = 0x000F
    111 MGMT_EV_USER_PASSKEY_REQUEST   = 0x0010
    112 MGMT_EV_AUTH_FAILED            = 0x0011
    113 MGMT_EV_DEVICE_FOUND           = 0x0012
    114 MGMT_EV_DISCOVERING            = 0x0013
    115 MGMT_EV_DEVICE_BLOCKED         = 0x0014
    116 MGMT_EV_DEVICE_UNBLOCKED       = 0x0015
    117 MGMT_EV_DEVICE_UNPAIRED        = 0x0016
    118 MGMT_EV_PASSKEY_NOTIFY         = 0x0017
    119 MGMT_EV_NEW_IRK                = 0x0018
    120 MGMT_EV_NEW_CSRK               = 0x0019
    121 MGMT_EV_DEVICE_ADDED           = 0x001a
    122 MGMT_EV_DEVICE_REMOVED         = 0x001b
    123 MGMT_EV_NEW_CONN_PARAM         = 0x001c
    124 MGMT_EV_UNCONF_INDEX_ADDED     = 0x001d
    125 MGMT_EV_UNCONF_INDEX_REMOVED   = 0x001e
    126 MGMT_EV_NEW_CONFIG_OPTIONS     = 0x001f
    127 
    128 # Settings returned by MGMT_OP_READ_INFO
    129 MGMT_SETTING_POWERED            = 0x00000001
    130 MGMT_SETTING_CONNECTABLE        = 0x00000002
    131 MGMT_SETTING_FAST_CONNECTABLE   = 0x00000004
    132 MGMT_SETTING_DISCOVERABLE       = 0x00000008
    133 MGMT_SETTING_PAIRABLE           = 0x00000010
    134 MGMT_SETTING_LINK_SECURITY      = 0x00000020
    135 MGMT_SETTING_SSP                = 0x00000040
    136 MGMT_SETTING_BREDR              = 0x00000080
    137 MGMT_SETTING_HS                 = 0x00000100
    138 MGMT_SETTING_LE                 = 0x00000200
    139 MGMT_SETTING_ADVERTISING        = 0x00000400
    140 MGMT_SETTING_SECURE_CONNECTIONS = 0x00000800
    141 MGMT_SETTING_DEBUG_KEYS         = 0x00001000
    142 MGMT_SETTING_PRIVACY            = 0x00002000
    143 MGMT_SETTING_CONTROLLER_CONFIG  = 0x00004000
    144 
    145 # Options returned by MGMT_OP_READ_CONFIG_INFO
    146 MGMT_OPTION_EXTERNAL_CONFIG    = 0x00000001
    147 MGMT_OPTION_PUBLIC_ADDRESS     = 0x00000002
    148 
    149 # Disconnect reason returned in MGMT_EV_DEVICE_DISCONNECTED
    150 MGMT_DEV_DISCONN_UNKNOWN       = 0x00
    151 MGMT_DEV_DISCONN_TIMEOUT       = 0x01
    152 MGMT_DEV_DISCONN_LOCAL_HOST    = 0x02
    153 MGMT_DEV_DISCONN_REMOTE        = 0x03
    154 
    155 # Flags returned in MGMT_EV_DEVICE_FOUND
    156 MGMT_DEV_FOUND_CONFIRM_NAME    = 0x01
    157 MGMT_DEV_FOUND_LEGACY_PAIRING  = 0x02
    158 
    159 
    160 # EIR Data field types
    161 EIR_FLAGS                      = 0x01
    162 EIR_UUID16_SOME                = 0x02
    163 EIR_UUID16_ALL                 = 0x03
    164 EIR_UUID32_SOME                = 0x04
    165 EIR_UUID32_ALL                 = 0x05
    166 EIR_UUID128_SOME               = 0x06
    167 EIR_UUID128_ALL                = 0x07
    168 EIR_NAME_SHORT                 = 0x08
    169 EIR_NAME_COMPLETE              = 0x09
    170 EIR_TX_POWER                   = 0x0A
    171 EIR_CLASS_OF_DEV               = 0x0D
    172 EIR_SSP_HASH                   = 0x0E
    173 EIR_SSP_RANDOMIZER             = 0x0F
    174 EIR_DEVICE_ID                  = 0x10
    175 EIR_GAP_APPEARANCE             = 0x19
    176 
    177 
    178 # Derived from lib/hci.h
    179 HCIGETDEVLIST                  = 0x800448d2
    180 HCIGETDEVINFO                  = 0x800448d3
    181 
    182 HCI_UP                         = 1 << 0
    183 HCI_INIT                       = 1 << 1
    184 HCI_RUNNING                    = 1 << 2
    185 HCI_PSCAN                      = 1 << 3
    186 HCI_ISCAN                      = 1 << 4
    187 HCI_AUTH                       = 1 << 5
    188 HCI_ENCRYPT                    = 1 << 6
    189 HCI_INQUIRY                    = 1 << 7
    190 HCI_RAW                        = 1 << 8
    191 
    192 
    193 def parse_eir(eirdata):
    194     """Parse Bluetooth Extended Inquiry Result (EIR) data structuree.
    195 
    196     @param eirdata: Encoded eir data structure.
    197 
    198     @return Dictionary equivalent to the expanded structure keyed by EIR_*
    199             fields, with any data members parsed to useful formats.
    200 
    201     """
    202     fields = {}
    203     pos = 0
    204     while pos < len(eirdata):
    205         # Byte at the current position is the field length, which should be
    206         # zero at the end of the structure.
    207         (field_len,) = struct.unpack('B', buffer(eirdata, pos, 1))
    208         if field_len == 0:
    209             break
    210         # Next byte is the field type, and the rest of the field is the data.
    211         # Note that the length field doesn't include itself so that's why the
    212         # offsets and lengths look a little odd.
    213         (field_type,) = struct.unpack('B', buffer(eirdata, pos + 1, 1))
    214         data = eirdata[pos+2:pos+field_len+1]
    215         pos += field_len + 1
    216         # Parse the individual fields to make the data meaningful.
    217         if field_type == EIR_NAME_SHORT or field_type == EIR_NAME_COMPLETE:
    218             data = data.rstrip('\0')
    219         # Place in the dictionary keyed by type.
    220         fields[field_type] = data
    221 
    222     return fields
    223 
    224 
    225 
    226 class BluetoothSocketError(Exception):
    227     """Error raised for general issues with BluetoothSocket."""
    228     pass
    229 
    230 class BluetoothInvalidPacketError(Exception):
    231     """Error raised when an invalid packet is received from the socket."""
    232     pass
    233 
    234 class BluetoothControllerError(Exception):
    235     """Error raised when the Controller Error event is received."""
    236     pass
    237 
    238 
    239 class BluetoothSocket(btsocket.socket):
    240     """Bluetooth Socket.
    241 
    242     BluetoothSocket wraps the btsocket.socket() class, and thus the system
    243     socket.socket() class, to implement the necessary send and receive methods
    244     for the HCI Control and Monitor protocols (aka mgmt_ops) of the
    245     Linux Kernel.
    246 
    247     Instantiate either BluetoothControlSocket or BluetoothRawSocket rather
    248     than this class directly.
    249 
    250     See bluez/doc/mgmt_api.txt for details.
    251 
    252     """
    253 
    254     def __init__(self):
    255         super(BluetoothSocket, self).__init__(family=btsocket.AF_BLUETOOTH,
    256                                               type=socket.SOCK_RAW,
    257                                               proto=btsocket.BTPROTO_HCI)
    258         self.events = []
    259 
    260 
    261     def send_command(self, code, index, data=''):
    262         """Send a command to the socket.
    263 
    264         To send a command, wait for the reply event, and parse it use
    265         send_command_and_wait() instead.
    266 
    267         @param code: Command Code.
    268         @param index: Controller index, may be MGMT_INDEX_NONE.
    269         @param data: Parameters as bytearray or str (optional).
    270 
    271         """
    272         # Send the command to the kernel
    273         msg = struct.pack('<HHH', code, index, len(data)) + data
    274 
    275         length = self.send(msg)
    276         if length != len(msg):
    277             raise BluetoothSocketError('Short write on socket')
    278 
    279 
    280     def recv_event(self):
    281         """Receive a single event from the socket.
    282 
    283         The event data is not parsed; in the case of command complete events
    284         this means it includes both the data for the event and the response
    285         for the command.
    286 
    287         Use settimeout() to set whether this method will block if there is no
    288         data, return immediately or wait for a specific length of time before
    289         timing out and raising TimeoutError.
    290 
    291         @return tuple of (event, index, data)
    292 
    293         """
    294         # Read the message from the socket
    295         hdr = bytearray(MGMT_HDR_SIZE)
    296         data = bytearray(512)
    297         try:
    298             (nbytes, ancdata, msg_flags, address) = self.recvmsg_into(
    299                     (hdr, data))
    300         except btsocket.timeout as e:
    301             raise BluetoothSocketError('Error receiving event: %s' % e)
    302         if nbytes < MGMT_HDR_SIZE:
    303             raise BluetoothInvalidPacketError('Packet shorter than header')
    304 
    305         # Parse the header
    306         (event, index, length) = struct.unpack_from('<HHH', buffer(hdr))
    307         if nbytes < MGMT_HDR_SIZE + length:
    308             raise BluetoothInvalidPacketError('Packet shorter than length')
    309 
    310         return (event, index, data[:length])
    311 
    312 
    313     def send_command_and_wait(self, cmd_code, cmd_index, cmd_data='',
    314                               expected_length=None):
    315         """Send a command to the socket and wait for the reply.
    316 
    317         Additional events are appended to the events list of the socket object.
    318 
    319         @param cmd_code: Command Code.
    320         @param cmd_index: Controller index, may be btsocket.HCI_DEV_NONE.
    321         @param cmd_data: Parameters as bytearray or str.
    322         @param expected_length: May be set to verify the length of the data.
    323 
    324         Use settimeout() to set whether this method will block if there is no
    325         reply, return immediately or wait for a specific length of time before
    326         timing out and raising TimeoutError.
    327 
    328         @return tuple of (status, data)
    329 
    330         """
    331         self.send_command(cmd_code, cmd_index, cmd_data)
    332 
    333         while True:
    334             (event, index, data) = self.recv_event()
    335 
    336             if event == MGMT_EV_CMD_COMPLETE:
    337                 if index != cmd_index:
    338                     raise BluetoothInvalidPacketError(
    339                             ('Response for wrong controller index received: ' +
    340                              '0x%04d (expected 0x%04d)' % (index, cmd_index)))
    341                 if len(data) < 3:
    342                     raise BluetoothInvalidPacketError(
    343                             ('Incorrect command complete event data length: ' +
    344                              '%d (expected at least 3)' % len(data)))
    345 
    346                 (code, status) = struct.unpack_from('<HB', buffer(data, 0, 3))
    347                 logging.debug('[0x%04x] command 0x%04x complete: 0x%02x',
    348                               index, code, status)
    349 
    350                 if code != cmd_code:
    351                     raise BluetoothInvalidPacketError(
    352                             ('Response for wrong command code received: ' +
    353                              '0x%04d (expected 0x%04d)' % (code, cmd_code)))
    354 
    355                 response_length = len(data) - 3
    356                 if (expected_length is not None and
    357                     response_length != expected_length):
    358                     raise BluetoothInvalidPacketError(
    359                             ('Incorrect length of data for response: ' +
    360                              '%d (expected %d)' % (response_length,
    361                                                    expected_length)))
    362 
    363                 return (status, data[3:])
    364 
    365             elif event == MGMT_EV_CMD_STATUS:
    366                 if index != cmd_index:
    367                     raise BluetoothInvalidPacketError(
    368                             ('Response for wrong controller index received: ' +
    369                              '0x%04d (expected 0x%04d)' % (index, cmd_index)))
    370                 if len(data) != 3:
    371                     raise BluetoothInvalidPacketError(
    372                             ('Incorrect command status event data length: ' +
    373                              '%d (expected 3)' % len(data)))
    374 
    375                 (code, status) = struct.unpack_from('<HB', buffer(data, 0, 3))
    376                 logging.debug('[0x%04x] command 0x%02x status: 0x%02x',
    377                               index, code, status)
    378 
    379                 if code != cmd_code:
    380                     raise BluetoothInvalidPacketError(
    381                             ('Response for wrong command code received: ' +
    382                              '0x%04d (expected 0x%04d)' % (code, cmd_code)))
    383 
    384                 return (status, None)
    385 
    386             elif event == MGMT_EV_CONTROLLER_ERROR:
    387                 if len(data) != 1:
    388                     raise BluetoothInvalidPacketError(
    389                         ('Incorrect controller error event data length: ' +
    390                          '%d (expected 1)' % len(data)))
    391 
    392                 (error_code) = struct.unpack_from('<B', buffer(data, 0, 1))
    393 
    394                 raise BluetoothControllerError('Controller error: %d' %
    395                                                error_code)
    396 
    397             else:
    398                 logging.debug('[0x%04x] event 0x%02x length: %d',
    399                               index, event, len(data))
    400                 self.events.append((event, index, data))
    401 
    402 
    403     def wait_for_events(self, index, events):
    404         """Wait for and return the first of a set of events specified.
    405 
    406         @param index: Controller index of event, may be btsocket.HCI_DEV_NONE.
    407         @param events: List of event codes to wait for.
    408 
    409         Use settimeout() to set whether this method will block if there is no
    410         event received, return immediately or wait for a specific length of
    411         time before timing out and raising TimeoutError.
    412 
    413         @return Tuple of (event, data)
    414 
    415         """
    416         while True:
    417             for idx, (event, event_index, data) in enumerate(self.events):
    418                 if event_index == index and event in events:
    419                     self.events.pop(idx)
    420                     return (event, data)
    421 
    422             (event, event_index, data) = self.recv_event()
    423             if event_index == index and event in events:
    424                 return (event, data)
    425             elif event == MGMT_EV_CMD_COMPLETE:
    426                 if len(data) < 3:
    427                     raise BluetoothInvalidPacketError(
    428                             ('Incorrect command complete event data length: ' +
    429                              '%d (expected at least 3)' % len(data)))
    430 
    431                 (code, status) = struct.unpack_from('<HB', buffer(data, 0, 3))
    432                 logging.debug('[0x%04x] command 0x%04x complete: 0x%02x '
    433                               '(Ignored)', index, code, status)
    434 
    435             elif event == MGMT_EV_CMD_STATUS:
    436                 if len(data) != 3:
    437                     raise BluetoothInvalidPacketError(
    438                             ('Incorrect command status event data length: ' +
    439                              '%d (expected 3)' % len(data)))
    440 
    441                 (code, status) = struct.unpack_from('<HB', buffer(data, 0, 3))
    442                 logging.debug('[0x%04x] command 0x%02x status: 0x%02x '
    443                               '(Ignored)', index, code, status)
    444 
    445             elif event == MGMT_EV_CONTROLLER_ERROR:
    446                 if len(data) != 1:
    447                     raise BluetoothInvalidPacketError(
    448                         ('Incorrect controller error event data length: ' +
    449                          '%d (expected 1)' % len(data)))
    450 
    451                 (error_code) = struct.unpack_from('<B', buffer(data, 0, 1))
    452                 logging.debug('[0x%04x] controller error: %d (Ignored)',
    453                               index, error_code)
    454 
    455             else:
    456                 self.events.append((event, index, data))
    457 
    458 
    459 class BluetoothControlSocket(BluetoothSocket):
    460     """Bluetooth Control Socket.
    461 
    462     BluetoothControlSocket provides convenient methods mapping to each mgmt_ops
    463     command that send an appropriately formatted command and parse the response.
    464 
    465     """
    466 
    467     DEFAULT_TIMEOUT = 15
    468 
    469     def __init__(self):
    470         super(BluetoothControlSocket, self).__init__()
    471         self.bind((btsocket.HCI_DEV_NONE, btsocket.HCI_CHANNEL_CONTROL))
    472         self.settimeout(self.DEFAULT_TIMEOUT)
    473 
    474         # Certain features will depend on the management version and revision,
    475         # so check those now.
    476         (version, revision) = self.read_version()
    477         logging.debug('MGMT API %d.%d', version, revision)
    478         self._kernel_confirms_name = (
    479                 (version > 1) or ((version == 1) and (revision >= 5)))
    480 
    481     def read_version(self):
    482         """Read the version of the management interface.
    483 
    484         @return tuple (version, revision) on success, None on failure.
    485 
    486         """
    487         (status, data) = self.send_command_and_wait(
    488                 MGMT_OP_READ_VERSION,
    489                 MGMT_INDEX_NONE,
    490                 expected_length=3)
    491         if status != MGMT_STATUS_SUCCESS:
    492             return None
    493 
    494         (version, revision) = struct.unpack_from('<BH', buffer(data))
    495         return (version, revision)
    496 
    497 
    498     def read_supported_commands(self):
    499         """Read the supported management commands and events.
    500 
    501         @return tuple (commands, events) on success, None on failure.
    502 
    503         """
    504         (status, data) = self.send_command_and_wait(
    505                 MGMT_OP_READ_COMMANDS,
    506                 MGMT_INDEX_NONE)
    507         if status != MGMT_STATUS_SUCCESS:
    508             return None
    509         if len(data) < 4:
    510             raise BluetoothInvalidPacketError(
    511                     ('Incorrect length of data for response: ' +
    512                      '%d (expected at least 4)' % len(data)))
    513 
    514         (ncommands, nevents) = struct.unpack_from('<HH', buffer(data, 0, 4))
    515         offset = 4
    516         expected_length = offset + (ncommands * 2) + (nevents * 2)
    517         if len(data) != expected_length:
    518             raise BluetoothInvalidPacketError(
    519                     ('Incorrect length of data for response: ' +
    520                      '%d (expected %d)' % (len(data), expected_length)))
    521 
    522         commands = []
    523         while len(commands) < ncommands:
    524             commands.extend(struct.unpack_from('<H', buffer(data, offset, 2)))
    525             offset += 2
    526 
    527         events = []
    528         while len(events) < nevents:
    529             events.extend(struct.unpack_from('<H', buffer(data, offset, 2)))
    530             offset += 2
    531 
    532         return (commands, events)
    533 
    534 
    535     def read_index_list(self):
    536         """Read the list of currently known controllers.
    537 
    538         @return array of controller indexes on success, None on failure.
    539 
    540         """
    541         (status, data) = self.send_command_and_wait(
    542                 MGMT_OP_READ_INDEX_LIST,
    543                 MGMT_INDEX_NONE)
    544         if status != MGMT_STATUS_SUCCESS:
    545             return None
    546         if len(data) < 2:
    547             raise BluetoothInvalidPacketError(
    548                     ('Incorrect length of data for response: ' +
    549                      '%d (expected at least 2)' % len(data)))
    550 
    551         (nindexes,) = struct.unpack_from('<H', buffer(data, 0, 2))
    552         offset = 2
    553         expected_length = offset + (nindexes * 2)
    554         if len(data) != expected_length:
    555             raise BluetoothInvalidPacketError(
    556                     ('Incorrect length of data for response: ' +
    557                      '%d (expected %d)' % (len(data), expected_length)))
    558 
    559         indexes = []
    560         while len(indexes) < nindexes:
    561             indexes.extend(struct.unpack_from('<H', buffer(data, offset, 2)))
    562             offset += 2
    563 
    564         return indexes
    565 
    566 
    567     def read_info(self, index):
    568         """Read the state and basic information of a controller.
    569 
    570         Address is returned as a string in upper-case hex to match the
    571         BlueZ property.
    572 
    573         @param index: Controller index.
    574 
    575         @return tuple (address, bluetooth_version, manufacturer,
    576                        supported_settings, current_settings,
    577                        class_of_device, name, short_name) on success,
    578                 None on failure.
    579 
    580         """
    581         (status, data) = self.send_command_and_wait(
    582                 MGMT_OP_READ_INFO,
    583                 index,
    584                 expected_length=280)
    585         if status != MGMT_STATUS_SUCCESS:
    586             return None
    587 
    588         (address, bluetooth_version, manufacturer,
    589          supported_settings, current_settings,
    590          class_of_device_lo, class_of_device_mid, class_of_device_hi,
    591          name, short_name) = struct.unpack_from(
    592                 '<6sBHLL3B249s11s',
    593                 buffer(data))
    594 
    595         return (
    596                 ':'.join('%02X' % x
    597                          for x in reversed(struct.unpack('6B', address))),
    598                 bluetooth_version,
    599                 manufacturer,
    600                 supported_settings,
    601                 current_settings,
    602                 (class_of_device_lo |(class_of_device_mid << 8) |
    603                         (class_of_device_hi << 16)),
    604                 name.rstrip('\0'),
    605                 short_name.rstrip('\0'))
    606 
    607 
    608     def set_powered(self, index, powered):
    609         """Set the powered state of a controller.
    610 
    611         @param index: Controller index.
    612         @param powered: Whether controller radio should be powered.
    613 
    614         @return New controller settings on success, None on failure.
    615 
    616         """
    617         msg_data = struct.pack('<B', bool(powered))
    618         (status, data) = self.send_command_and_wait(
    619                 MGMT_OP_SET_POWERED,
    620                 index,
    621                 msg_data,
    622                 expected_length=4)
    623         if status != MGMT_STATUS_SUCCESS:
    624             return None
    625 
    626         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    627         return current_settings
    628 
    629 
    630     def set_discoverable(self, index, discoverable, timeout=0):
    631         """Set the discoverable state of a controller.
    632 
    633         @param index: Controller index.
    634         @param discoverable: Whether controller should be discoverable.
    635         @param timeout: Timeout in seconds before disabling discovery again,
    636                 ignored when discoverable is False, must not be zero when
    637                 discoverable is True.
    638 
    639         @return New controller settings on success, 0 if the feature is not
    640                 supported and the parameter was False, None otherwise.
    641 
    642         """
    643         msg_data = struct.pack('<BH', bool(discoverable), timeout)
    644         (status, data) = self.send_command_and_wait(
    645                 MGMT_OP_SET_DISCOVERABLE,
    646                 index,
    647                 msg_data,
    648                 expected_length=4)
    649         if status == MGMT_STATUS_NOT_SUPPORTED and not discoverable:
    650             return 0
    651         elif status != MGMT_STATUS_SUCCESS:
    652             return None
    653 
    654         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    655         return current_settings
    656 
    657 
    658     def set_connectable(self, index, connectable):
    659         """Set the connectable state of a controller.
    660 
    661         @param index: Controller index.
    662         @param connectable: Whether controller should be connectable.
    663 
    664         @return New controller settings on success, 0 if the feature is not
    665                 supported and the parameter was False, None otherwise.
    666 
    667         """
    668         msg_data = struct.pack('<B', bool(connectable))
    669         (status, data) = self.send_command_and_wait(
    670                 MGMT_OP_SET_CONNECTABLE,
    671                 index,
    672                 msg_data,
    673                 expected_length=4)
    674         if status == MGMT_STATUS_NOT_SUPPORTED and not connectable:
    675             return 0
    676         elif status != MGMT_STATUS_SUCCESS:
    677             return None
    678 
    679         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    680         return current_settings
    681 
    682 
    683     def set_fast_connectable(self, index, connectable):
    684         """Set the fast connectable state of a controller.
    685 
    686         Fast Connectable is a state where page scan parameters are set to favor
    687         faster connect times at the expense of higher power consumption.
    688 
    689         Unlike most other set_* commands, this may only be used when the
    690         controller is powered.
    691 
    692         @param index: Controller index.
    693         @param connectable: Whether controller should be fast connectable.
    694 
    695         @return New controller settings on success, 0 if the feature is not
    696                 supported and the parameter was False or the controller is
    697                 powered down, None otherwise.
    698 
    699         """
    700         msg_data = struct.pack('<B', bool(connectable))
    701         (status, data) = self.send_command_and_wait(
    702                 MGMT_OP_SET_FAST_CONNECTABLE,
    703                 index,
    704                 msg_data)
    705         if status == MGMT_STATUS_NOT_SUPPORTED and not connectable:
    706             return 0
    707         elif status != MGMT_STATUS_SUCCESS:
    708             return None
    709         # This is documented as returning current settings, but doesn't in
    710         # our kernel version (probably a bug), so if no data is returned,
    711         # pretend that was success.
    712         if len(data) == 0:
    713             return 0
    714         elif len(data) != 4:
    715             raise BluetoothInvalidPacketError(
    716                     ('Incorrect length of data for response: ' +
    717                      '%d (expected 4)' % len(data)))
    718 
    719         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    720         return current_settings
    721 
    722 
    723     def set_pairable(self, index, pairable):
    724         """Set the pairable state of a controller.
    725 
    726         @param index: Controller index.
    727         @param pairable: Whether controller should be pairable.
    728 
    729         @return New controller settings on success, 0 if the feature is not
    730                 supported and the parameter was False, None otherwise.
    731 
    732         """
    733         msg_data = struct.pack('<B', bool(pairable))
    734         (status, data) = self.send_command_and_wait(
    735                 MGMT_OP_SET_PAIRABLE,
    736                 index,
    737                 msg_data,
    738                 expected_length=4)
    739         if status != MGMT_STATUS_SUCCESS:
    740             return None
    741 
    742         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    743         return current_settings
    744 
    745 
    746     def set_link_security(self, index, link_security):
    747         """Set the link security state of a controller.
    748 
    749         Toggles the use of link level security (aka Security Mode 3) for a
    750         controller.
    751 
    752         @param index: Controller index.
    753         @param link_security: Whether controller should be link_security.
    754 
    755         @return New controller settings on success, 0 if the feature is not
    756                 supported and the parameter was False, None otherwise.
    757 
    758         """
    759         msg_data = struct.pack('<B', bool(link_security))
    760         (status, data) = self.send_command_and_wait(
    761                 MGMT_OP_SET_LINK_SECURITY,
    762                 index,
    763                 msg_data,
    764                 expected_length=4)
    765         if status == MGMT_STATUS_NOT_SUPPORTED and not link_security:
    766             return 0
    767         elif status != MGMT_STATUS_SUCCESS:
    768             return None
    769 
    770         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    771         return current_settings
    772 
    773 
    774     def set_ssp(self, index, ssp):
    775         """Set the whether a controller supports Simple Secure Pairing.
    776 
    777         @param index: Controller index.
    778         @param ssp: Whether controller should support SSP.
    779 
    780         @return New controller settings on success, 0 if the feature is not
    781                 supported and the parameter was False, None otherwise.
    782 
    783         """
    784         msg_data = struct.pack('<B', bool(ssp))
    785         (status, data) = self.send_command_and_wait(
    786                 MGMT_OP_SET_SSP,
    787                 index,
    788                 msg_data,
    789                 expected_length=4)
    790         if status == MGMT_STATUS_NOT_SUPPORTED and not ssp:
    791             return 0
    792         elif status != MGMT_STATUS_SUCCESS:
    793             return None
    794 
    795         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    796         return current_settings
    797 
    798 
    799     def set_hs(self, index, hs):
    800         """Set the whether a controller supports Bluetooth High Speed.
    801 
    802         @param index: Controller index.
    803         @param hs: Whether controller should support High Speed.
    804 
    805         @return New controller settings on success, 0 if the feature is not
    806                 supported and the parameter was False, None otherwise.
    807 
    808         """
    809         msg_data = struct.pack('<B', bool(hs))
    810         (status, data) = self.send_command_and_wait(
    811                 MGMT_OP_SET_HS,
    812                 index,
    813                 msg_data,
    814                 expected_length=4)
    815         if status == MGMT_STATUS_NOT_SUPPORTED and not hs:
    816             return 0
    817         elif status != MGMT_STATUS_SUCCESS:
    818             return None
    819 
    820         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    821         return current_settings
    822 
    823 
    824     def set_le(self, index, le):
    825         """Set the whether a controller supports Bluetooth Low Energy.
    826 
    827         @param index: Controller index.
    828         @param le: Whether controller should support Low Energy.
    829 
    830         @return New controller settings on success, 0 if the feature is not
    831                 supported and the parameter was False, None otherwise.
    832 
    833         """
    834         msg_data = struct.pack('<B', bool(le))
    835         (status, data) = self.send_command_and_wait(
    836                 MGMT_OP_SET_LE,
    837                 index,
    838                 msg_data,
    839                 expected_length=4)
    840         if status == MGMT_STATUS_NOT_SUPPORTED and not le:
    841             return 0
    842         elif status != MGMT_STATUS_SUCCESS:
    843             return None
    844 
    845         (current_settings, ) = struct.unpack_from('<L', buffer(data))
    846         return current_settings
    847 
    848 
    849     def set_device_class(self, index, major, minor):
    850         """Set the device class of the controller.
    851 
    852         Consult the Bluetooth Baseband Assigned Numbers specification for valid
    853         values, in general both values are bit fields defined by that
    854         specification.
    855 
    856         If the device class is set while the controller is powered off, 0 will
    857         be returned, but the new class will be set by the host subsystem after
    858         the controller is powered on.
    859 
    860         @param index: Controller index.
    861         @param major: Major device class.
    862         @param minor: Minor device class.
    863 
    864         @return New three-octet device class on success, None on failure.
    865 
    866         """
    867         msg_data = struct.pack('<BB', major, minor)
    868         (status, data) = self.send_command_and_wait(
    869                 MGMT_OP_SET_DEV_CLASS,
    870                 index,
    871                 msg_data,
    872                 expected_length=3)
    873         if status != MGMT_STATUS_SUCCESS:
    874             return None
    875 
    876         (class_of_device_lo, class_of_device_mid,
    877          class_of_device_hi) = struct.unpack_from('<3B', buffer(data))
    878         return (class_of_device_lo |(class_of_device_mid << 8) |
    879                 (class_of_device_hi << 16))
    880 
    881 
    882     def set_local_name(self, index, name, short_name):
    883         """Set the local name of the controller.
    884 
    885         @param index: Controller index.
    886         @param name: Full length name, up to 248 characters.
    887         @param short_name: Short name, up to 10 characters.
    888 
    889         @return Tuple of (name, short_name) on success, None on failure.
    890 
    891         """
    892         # Truncate the provided parameters and then zero-pad using struct
    893         # so we pass a fixed-length null-terminated string to the kernel.
    894         msg_data = struct.pack('<249s11s', name[:248], short_name[:10])
    895         (status, data) = self.send_command_and_wait(
    896                 MGMT_OP_SET_LOCAL_NAME,
    897                 index,
    898                 msg_data,
    899                 expected_length=260)
    900         if status != MGMT_STATUS_SUCCESS:
    901             return None
    902 
    903         (name, short_name) = struct.unpack_from('<249s11s', buffer(data))
    904         return (name.rstrip('\0'), short_name.rstrip('\0'))
    905 
    906 
    907     def start_discovery(self, index, address_type):
    908         """Start discovering remote devices.
    909 
    910         Call get_discovered_devices() to retrieve the list of devices found.
    911 
    912         @param index: Controller index.
    913         @param address_type: Address types to discover.
    914 
    915         @return Address types discovery was started for on success,
    916                 None on failure.
    917 
    918         """
    919         msg_data = struct.pack('<B', address_type)
    920         (status, data) = self.send_command_and_wait(
    921                 MGMT_OP_START_DISCOVERY,
    922                 index,
    923                 msg_data,
    924                 expected_length=1)
    925         if status != MGMT_STATUS_SUCCESS:
    926             return None
    927 
    928         (address_type,) = struct.unpack_from('<B', buffer(data))
    929         return address_type
    930 
    931 
    932     def stop_discovery(self, index, address_type):
    933         """Stop discovering remote devices.
    934 
    935         There is usually no need to call this method explicitly as discovery
    936         is automatically stopped once it has iterated through the necessary
    937         channels.
    938 
    939         @param index: Controller index.
    940         @param address_type: Address types to stop discovering.
    941 
    942         @return Address types discovery was stopped for on success,
    943                 None on failure.
    944 
    945         """
    946         msg_data = struct.pack('<B', address_type)
    947         (status, data) = self.send_command_and_wait(
    948                 MGMT_OP_STOP_DISCOVERY,
    949                 index,
    950                 msg_data,
    951                 expected_length=1)
    952         if status != MGMT_STATUS_SUCCESS:
    953             return None
    954 
    955         (address_type,) = struct.unpack_from('<B', buffer(data))
    956         return address_type
    957 
    958 
    959     def get_discovered_devices(self, index):
    960         """Return list of discovered remote devices.
    961 
    962         This method may be called any time after start_discovery() and will
    963         wait until the full list of devices has been returned, there is usually
    964         no need to call stop_discovery() explicitly.
    965 
    966         Use settimeout() to set whether this method will block if there are no
    967         events, return immediately or wait for a specific length of time before
    968         timing out and raising TimeoutError.
    969 
    970         @param index: Controller index.
    971 
    972         @return List of devices found as tuples with the format
    973                 (address, address_type, rssi, flags, eirdata)
    974 
    975         """
    976         devices = []
    977         discovering = True
    978         while discovering:
    979             (event, data) = self.wait_for_events(
    980                     index,
    981                     ( MGMT_EV_DISCOVERING, MGMT_EV_DEVICE_FOUND ))
    982 
    983             if event == MGMT_EV_DISCOVERING:
    984                 if len(data) != 2:
    985                     raise BluetoothInvalidPacketError(
    986                             ('Incorrect discovering event data length: ' +
    987                              '%d (expected 2)' % len(data)))
    988 
    989                 (address_type,
    990                  discovering) = struct.unpack_from('<BB', buffer(data))
    991 
    992             elif event == MGMT_EV_DEVICE_FOUND:
    993                 if len(data) < 14:
    994                     raise BluetoothInvalidPacketError(
    995                             ('Incorrect device found event data length: ' +
    996                              '%d (expected at least 14)' % len(data)))
    997 
    998                 (address, address_type, rssi,
    999                  flags, eir_len) = struct.unpack_from('<6sBbLH',
   1000                                                       buffer(data, 0, 14))
   1001 
   1002                 if len(data) != 14 + eir_len:
   1003                     raise BluetoothInvalidPacketError(
   1004                             ('Incorrect device found event data length: ' +
   1005                              '%d (expected %d)' % (len(data), 14 + eir_len)))
   1006 
   1007                 devices.append((
   1008                         ':'.join('%02X' % x
   1009                                  for x in reversed(
   1010                                         struct.unpack('6B', address))),
   1011                         address_type,
   1012                         rssi,
   1013                         flags,
   1014                         bytes(data[14:])
   1015                 ))
   1016 
   1017                 # The kernel might want us to confirm whether or not we
   1018                 # know the name of the device. We don't really care whether
   1019                 # or not this works, we just have to do it to get the EIR
   1020                 # Request.
   1021                 if flags & MGMT_DEV_FOUND_CONFIRM_NAME:
   1022                     msg_data = struct.pack('<6sBB',
   1023                                            address, address_type, False)
   1024                     if self._kernel_confirms_name:
   1025                         self.send_command_and_wait(
   1026                                 MGMT_OP_CONFIRM_NAME,
   1027                                 index,
   1028                                 msg_data)
   1029                     else:
   1030                         self.send_command(
   1031                                 MGMT_OP_CONFIRM_NAME,
   1032                                 index,
   1033                                 msg_data)
   1034 
   1035 
   1036         return devices
   1037 
   1038 
   1039     def set_advertising(self, index, advertising):
   1040         """Set the whether a controller is advertising via LE.
   1041 
   1042         @param index: Controller index.
   1043         @param advertising: Whether controller should advertise via LE.
   1044 
   1045         @return New controller settings on success, 0 if the feature is not
   1046                 supported and the parameter was False, None otherwise.
   1047 
   1048         """
   1049         msg_data = struct.pack('<B', bool(advertising))
   1050         (status, data) = self.send_command_and_wait(
   1051                 MGMT_OP_SET_ADVERTISING,
   1052                 index,
   1053                 msg_data,
   1054                 expected_length=4)
   1055         if status == MGMT_STATUS_NOT_SUPPORTED and not advertising:
   1056             return 0
   1057         elif status != MGMT_STATUS_SUCCESS:
   1058             return None
   1059 
   1060         (current_settings, ) = struct.unpack_from('<L', buffer(data))
   1061         return current_settings
   1062 
   1063 
   1064     def set_bredr(self, index, bredr):
   1065         """Set the whether a controller supports Bluetooth BR/EDR (classic).
   1066 
   1067         @param index: Controller index.
   1068         @param bredr: Whether controller should support BR/EDR.
   1069 
   1070         @return New controller settings on success, 0 if the feature is not
   1071                 supported and the parameter was False, None otherwise.
   1072 
   1073         """
   1074         msg_data = struct.pack('<B', bool(bredr))
   1075         (status, data) = self.send_command_and_wait(
   1076                 MGMT_OP_SET_BREDR,
   1077                 index,
   1078                 msg_data,
   1079                 expected_length=4)
   1080         if status == MGMT_STATUS_NOT_SUPPORTED and not bredr:
   1081             return 0
   1082         elif status != MGMT_STATUS_SUCCESS:
   1083             return None
   1084 
   1085         (current_settings, ) = struct.unpack_from('<L', buffer(data))
   1086         return current_settings
   1087 
   1088 
   1089     def add_device(self, index, address, address_type, action):
   1090         """Add a device to the action list.
   1091 
   1092         @param index: Controller index.
   1093         @param address: Address of the device to add.
   1094         @param address_type: Type of device in @address.
   1095         @param action: Action to take.
   1096 
   1097         @return Tuple of ( address, address_type ) on success,
   1098                 None on failure.
   1099 
   1100         """
   1101         msg_data = struct.pack('<6sBB', address, address_type, action)
   1102         (status, data) = self.send_command_and_wait(
   1103                 MGMT_OP_ADD_DEVICE,
   1104                 index,
   1105                 msg_data,
   1106                 expected_length=7)
   1107         if status != MGMT_STATUS_SUCCESS:
   1108             return None
   1109 
   1110         (address, address_type,) = struct.unpack_from('<6sB', buffer(data))
   1111         return (address, address_type)
   1112 
   1113 
   1114     def remove_device(self, index, address, address_type):
   1115         """Remove a device from the action list.
   1116 
   1117         @param index: Controller index.
   1118         @param address: Address of the device to remove.
   1119         @param address_type: Type of device in @address.
   1120 
   1121         @return Tuple of ( address, address_type ) on success,
   1122                 None on failure.
   1123 
   1124         """
   1125         msg_data = struct.pack('<6sB', address, address_type)
   1126         (status, data) = self.send_command_and_wait(
   1127                 MGMT_OP_REMOVE_DEVICE,
   1128                 index,
   1129                 msg_data,
   1130                 expected_length=7)
   1131         if status != MGMT_STATUS_SUCCESS:
   1132             return None
   1133 
   1134         (address, address_type,) = struct.unpack_from('<6sB', buffer(data))
   1135         return (address, address_type)
   1136 
   1137 
   1138 class BluetoothRawSocket(BluetoothSocket):
   1139     """Bluetooth Raw HCI Socket.
   1140 
   1141     BluetoothRawSocket is a subclass of BluetoothSocket representing raw access
   1142     to the HCI controller and providing commands corresponding to ioctls that
   1143     can be made on that kind of socket.
   1144 
   1145     """
   1146 
   1147     def get_dev_info(self, index):
   1148         """Read HCI device information.
   1149 
   1150         This method uses the same underlying ioctl as the hciconfig tool.
   1151 
   1152         Address is returned as a string in upper-case hex to match the
   1153         BlueZ property.
   1154 
   1155         @param index: Device index.
   1156 
   1157         @return tuple (index, name, address, flags, device_type, bus_type,
   1158                        features, pkt_type, link_policy, link_mode,
   1159                        acl_mtu, acl_pkts, sco_mtu, sco_pkts,
   1160                        err_rx, err_tx, cmd_tx, evt_rx, acl_tx, acl_rx,
   1161                        sco_tx, sco_rx, byte_rx, byte_tx) on success,
   1162                 None on failure.
   1163 
   1164         """
   1165         buf = array.array('B', [0] * 96)
   1166         fcntl.ioctl(self.fileno(), HCIGETDEVINFO, buf, 1)
   1167 
   1168         ( dev_id, name, address, flags, dev_type, features, pkt_type,
   1169           link_policy, link_mode, acl_mtu, acl_pkts, sco_mtu, sco_pkts,
   1170           err_rx, err_tx, cmd_tx, evt_rx, acl_tx, acl_rx, sco_tx, sco_rx,
   1171           byte_rx, byte_tx ) = struct.unpack_from(
   1172                 '@H8s6sIBQIIIHHHHIIIIIIIIII', buf)
   1173 
   1174         return (
   1175                 dev_id,
   1176                 name.rstrip('\0'),
   1177                 ':'.join('%02X' % x
   1178                          for x in reversed(struct.unpack('6B', address))),
   1179                 flags,
   1180                 (dev_type & 0x30) >> 4,
   1181                 dev_type & 0x0f,
   1182                 features,
   1183                 pkt_type,
   1184                 link_policy,
   1185                 link_mode,
   1186                 acl_mtu,
   1187                 acl_pkts,
   1188                 sco_mtu,
   1189                 sco_pkts,
   1190                 err_rx,
   1191                 err_tx,
   1192                 cmd_tx,
   1193                 evt_rx,
   1194                 acl_tx,
   1195                 acl_rx,
   1196                 sco_tx,
   1197                 sco_rx,
   1198                 byte_rx,
   1199                 byte_tx)
   1200