1# Copyright 2021-2022 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# ----------------------------------------------------------------------------- 16# Imports 17# ----------------------------------------------------------------------------- 18import asyncio 19import sys 20import os 21import logging 22from bumble.colors import color 23from bumble.device import Device, Peer 24from bumble.hci import Address 25from bumble.profiles.device_information_service import DeviceInformationServiceProxy 26from bumble.transport import open_transport 27 28 29# ----------------------------------------------------------------------------- 30async def main() -> None: 31 if len(sys.argv) != 3: 32 print( 33 'Usage: device_information_client.py <transport-spec> <bluetooth-address>' 34 ) 35 print('example: device_information_client.py usb:0 E1:CA:72:48:C4:E8') 36 return 37 38 print('<<< connecting to HCI...') 39 async with await open_transport(sys.argv[1]) as hci_transport: 40 print('<<< connected') 41 42 # Create and start a device 43 device = Device.with_hci( 44 'Bumble', 45 Address('F0:F1:F2:F3:F4:F5'), 46 hci_transport.source, 47 hci_transport.sink, 48 ) 49 await device.power_on() 50 51 # Connect to the peer 52 target_address = sys.argv[2] 53 print(f'=== Connecting to {target_address}...') 54 connection = await device.connect(target_address) 55 print(f'=== Connected to {connection}') 56 57 # Discover the Device Information service 58 peer = Peer(connection) 59 print('=== Discovering Device Information Service') 60 device_information_service = await peer.discover_service_and_create_proxy( 61 DeviceInformationServiceProxy 62 ) 63 64 # Check that the service was found 65 if device_information_service is None: 66 print('!!! Service not found') 67 return 68 69 # Read and print the fields 70 if device_information_service.manufacturer_name is not None: 71 print( 72 color('Manufacturer Name: ', 'green'), 73 await device_information_service.manufacturer_name.read_value(), 74 ) 75 if device_information_service.model_number is not None: 76 print( 77 color('Model Number: ', 'green'), 78 await device_information_service.model_number.read_value(), 79 ) 80 if device_information_service.serial_number is not None: 81 print( 82 color('Serial Number: ', 'green'), 83 await device_information_service.serial_number.read_value(), 84 ) 85 if device_information_service.hardware_revision is not None: 86 print( 87 color('Hardware Revision: ', 'green'), 88 await device_information_service.hardware_revision.read_value(), 89 ) 90 if device_information_service.firmware_revision is not None: 91 print( 92 color('Firmware Revision: ', 'green'), 93 await device_information_service.firmware_revision.read_value(), 94 ) 95 if device_information_service.software_revision is not None: 96 print( 97 color('Software Revision: ', 'green'), 98 await device_information_service.software_revision.read_value(), 99 ) 100 if device_information_service.system_id is not None: 101 print( 102 color('System ID: ', 'green'), 103 await device_information_service.system_id.read_value(), 104 ) 105 if ( 106 device_information_service.ieee_regulatory_certification_data_list 107 is not None 108 ): 109 print( 110 color('Regulatory Certification:', 'green'), 111 ( 112 # pylint: disable-next=line-too-long 113 await device_information_service.ieee_regulatory_certification_data_list.read_value() 114 ).hex(), 115 ) 116 117 118# ----------------------------------------------------------------------------- 119logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper()) 120asyncio.run(main()) 121