# Copyright 2021-2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ----------------------------------------------------------------------------- # Imports # ----------------------------------------------------------------------------- import asyncio import logging import struct import os import socket import ctypes import collections from .common import Transport, ParserSource # ----------------------------------------------------------------------------- # Logging # ----------------------------------------------------------------------------- logger = logging.getLogger(__name__) # ----------------------------------------------------------------------------- async def open_hci_socket_transport(spec): ''' Open an HCI Socket (only available on some platforms). The parameter string is either empty (to use the first/default Bluetooth adapter) or a 0-based integer to indicate the adapter number. ''' HCI_CHANNEL_USER = 1 # pylint: disable=invalid-name # Create a raw HCI socket try: hci_socket = socket.socket( socket.AF_BLUETOOTH, socket.SOCK_RAW | socket.SOCK_NONBLOCK, socket.BTPROTO_HCI, ) except AttributeError as error: # Not supported on this platform logger.info("HCI sockets not supported on this platform") raise Exception( 'Bluetooth HCI sockets not supported on this platform' ) from error # Compute the adapter index if spec is None: adapter_index = 0 else: adapter_index = int(spec) # Bind the socket # NOTE: since Python doesn't support binding with the required address format (yet), # we need to go directly to the C runtime... try: ctypes.cdll.LoadLibrary('libc.so.6') libc = ctypes.CDLL('libc.so.6', use_errno=True) except OSError as error: logger.info("HCI sockets not supported on this platform") raise Exception( 'Bluetooth HCI sockets not supported on this platform' ) from error libc.bind.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_char), ctypes.c_int) libc.bind.restype = ctypes.c_int bind_address = struct.pack( # pylint: disable=no-member '