2023-07-19 03:27:59 -04:00
|
|
|
# SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
|
2022-06-07 12:16:23 -04:00
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
2018-07-30 12:10:10 -04:00
|
|
|
#
|
|
|
|
|
|
|
|
from . import ble_cli
|
2021-01-25 21:49:01 -05:00
|
|
|
from .transport import Transport
|
2018-07-30 12:10:10 -04:00
|
|
|
|
2018-12-04 07:46:48 -05:00
|
|
|
|
2018-07-30 12:10:10 -04:00
|
|
|
class Transport_BLE(Transport):
|
2022-06-07 12:16:23 -04:00
|
|
|
def __init__(self, service_uuid, nu_lookup):
|
|
|
|
self.nu_lookup = nu_lookup
|
|
|
|
self.service_uuid = service_uuid
|
2022-06-22 05:44:19 -04:00
|
|
|
self.name_uuid_lookup = None
|
2018-07-30 12:10:10 -04:00
|
|
|
# Expect service UUID like '0000ffff-0000-1000-8000-00805f9b34fb'
|
|
|
|
for name in nu_lookup.keys():
|
|
|
|
# Calculate characteristic UUID for each endpoint
|
|
|
|
nu_lookup[name] = service_uuid[:4] + '{:02x}'.format(
|
|
|
|
int(nu_lookup[name], 16) & int(service_uuid[4:8], 16)) + service_uuid[8:]
|
|
|
|
|
|
|
|
# Get BLE client module
|
|
|
|
self.cli = ble_cli.get_client()
|
|
|
|
|
2022-06-07 12:16:23 -04:00
|
|
|
async def connect(self, devname):
|
2018-07-30 12:10:10 -04:00
|
|
|
# Use client to connect to BLE device and bind to service
|
2022-06-07 12:16:23 -04:00
|
|
|
if not await self.cli.connect(devname=devname, iface='hci0',
|
|
|
|
chrc_names=self.nu_lookup.keys(),
|
|
|
|
fallback_srv_uuid=self.service_uuid):
|
2021-01-25 21:49:01 -05:00
|
|
|
raise RuntimeError('Failed to initialize transport')
|
2018-07-30 12:10:10 -04:00
|
|
|
|
2019-05-09 17:36:56 -04:00
|
|
|
# Irrespective of provided parameters, let the client
|
|
|
|
# generate a lookup table by reading advertisement data
|
|
|
|
# and characteristic user descriptors
|
|
|
|
self.name_uuid_lookup = self.cli.get_nu_lookup()
|
|
|
|
|
|
|
|
# If that doesn't work, use the lookup table provided as parameter
|
|
|
|
if self.name_uuid_lookup is None:
|
2022-06-07 12:16:23 -04:00
|
|
|
self.name_uuid_lookup = self.nu_lookup
|
2019-05-09 17:36:56 -04:00
|
|
|
# Check if expected characteristics are provided by the service
|
|
|
|
for name in self.name_uuid_lookup.keys():
|
|
|
|
if not self.cli.has_characteristic(self.name_uuid_lookup[name]):
|
2022-06-22 05:44:19 -04:00
|
|
|
raise RuntimeError(f"'{name}' endpoint not found")
|
2018-07-30 12:10:10 -04:00
|
|
|
|
2022-06-07 12:16:23 -04:00
|
|
|
async def disconnect(self):
|
|
|
|
await self.cli.disconnect()
|
2018-07-30 12:10:10 -04:00
|
|
|
|
2022-06-07 12:16:23 -04:00
|
|
|
async def send_data(self, ep_name, data):
|
2018-07-30 12:10:10 -04:00
|
|
|
# Write (and read) data to characteristic corresponding to the endpoint
|
|
|
|
if ep_name not in self.name_uuid_lookup.keys():
|
2022-06-22 05:44:19 -04:00
|
|
|
raise RuntimeError(f'Invalid endpoint: {ep_name}')
|
2022-06-07 12:16:23 -04:00
|
|
|
return await self.cli.send_data(self.name_uuid_lookup[ep_name], data)
|