diff options
author | 2024-10-04 22:07:58 +0000 | |
---|---|---|
committer | 2024-10-08 22:28:40 +0000 | |
commit | 94e3b26ef65d374b2342d365c571773b86220ab5 (patch) | |
tree | 3c852418ee035ee7e154019c2aa475dc18775e6e /pandora | |
parent | 9d0a929c40309b0658983fb04ab65c6d39c23de9 (diff) |
Pandora: Enable Bumble config modification at runtime
Bug: 370701018
Bug: 370608988
Test: atest avatar - manual testing with avatar
Change-Id: I9c190c70ca4e6c57bf97350cd5afb3bd32ac390c
Diffstat (limited to 'pandora')
-rw-r--r-- | pandora/interfaces/pandora_experimental/bumble_config.proto | 60 | ||||
-rw-r--r-- | pandora/interfaces/python/Android.bp | 5 | ||||
-rw-r--r-- | pandora/server/bumble_experimental/bumble_config.py | 73 |
3 files changed, 138 insertions, 0 deletions
diff --git a/pandora/interfaces/pandora_experimental/bumble_config.proto b/pandora/interfaces/pandora_experimental/bumble_config.proto new file mode 100644 index 0000000000..438f2ba16b --- /dev/null +++ b/pandora/interfaces/pandora_experimental/bumble_config.proto @@ -0,0 +1,60 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +option java_outer_classname = "BumbleConfigProto"; + +package pandora; + +import "google/protobuf/empty.proto"; +import "pandora/host.proto"; + +// This service provides runtime configuration for the Bumble Bluetooth stack. +// It allows overriding the initial configuration provided by the JSON file and +// the Security Service. This service should only be used by BumbleBluetoothTests. +service BumbleConfig { + // Override the initial Bumble configuration. This will erase any + // previous configuration set via JSON file or Security Service. + rpc Override(OverrideRequest) returns (google.protobuf.Empty); +} + +message PairingConfig { + bool sc = 1; + bool mitm = 2; + bool bonding = 3; + OwnAddressType identity_address_type = 4; +} + +enum IoCapability { + DISPLAY_ONLY = 0x00; + DISPLAY_YES_NO = 0x01; + KEYBOARD_ONLY = 0x02; + NO_OUTPUT_NO_INPUT = 0x03; + KEYBOARD_DISPLAY = 0x04; +} + +enum KeyDistribution { + ENCRYPTION_KEY = 0x00; + IDENTITY_KEY = 0x01; + SIGNING_KEY = 0x02; + LINK_KEY = 0x03; +} + +message OverrideRequest { + IoCapability io_capability = 1; + PairingConfig pairing_config = 2; + KeyDistribution initiator_key_distribution = 3; + KeyDistribution responder_key_distribution = 4; +} diff --git a/pandora/interfaces/python/Android.bp b/pandora/interfaces/python/Android.bp index 2abac309db..d295f2cfd3 100644 --- a/pandora/interfaces/python/Android.bp +++ b/pandora/interfaces/python/Android.bp @@ -34,6 +34,10 @@ genrule { "pandora_experimental/avrcp_grpc_aio.py", "pandora_experimental/avrcp_pb2.py", "pandora_experimental/avrcp_pb2.pyi", + "pandora_experimental/bumble_config_grpc.py", + "pandora_experimental/bumble_config_grpc_aio.py", + "pandora_experimental/bumble_config_pb2.py", + "pandora_experimental/bumble_config_pb2.pyi", "pandora_experimental/dck_grpc.py", "pandora_experimental/dck_grpc_aio.py", "pandora_experimental/dck_pb2.py", @@ -109,6 +113,7 @@ filegroup { srcs: [ ":pandora_experimental-python-gen-src{pandora_experimental/asha_pb2.pyi}", ":pandora_experimental-python-gen-src{pandora_experimental/avrcp_pb2.pyi}", + ":pandora_experimental-python-gen-src{pandora_experimental/bumble_config_pb2.pyi}", ":pandora_experimental-python-gen-src{pandora_experimental/dck_pb2.pyi}", ":pandora_experimental-python-gen-src{pandora_experimental/gatt_pb2.pyi}", ":pandora_experimental-python-gen-src{pandora_experimental/hap_pb2.pyi}", diff --git a/pandora/server/bumble_experimental/bumble_config.py b/pandora/server/bumble_experimental/bumble_config.py new file mode 100644 index 0000000000..4435476198 --- /dev/null +++ b/pandora/server/bumble_experimental/bumble_config.py @@ -0,0 +1,73 @@ +# Copyright 2024 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. + +import logging + +import grpc +from bumble.device import Connection as BumbleConnection +from bumble.device import Device +from bumble.pairing import PairingConfig +from bumble.pairing import PairingDelegate as BasePairingDelegate +from bumble.pandora import Config, utils +from bumble.pandora.security import PairingDelegate +from google.protobuf.empty_pb2 import Empty +from pandora.host_pb2 import PUBLIC +from pandora_experimental.bumble_config_grpc_aio import BumbleConfigServicer +from pandora_experimental.bumble_config_pb2 import (KeyDistribution, + OverrideRequest) + + +class BumbleConfigService(BumbleConfigServicer): + device: Device + + def __init__(self, device: Device, server_config: Config) -> None: + self.log = utils.BumbleServerLoggerAdapter(logging.getLogger(), {"service_name": "BumbleConfig", "device": device}) + self.device = device + self.server_config = server_config + + @utils.rpc + async def Override(self, request: OverrideRequest, context: grpc.ServicerContext) -> Empty: + + def parseProtoKeyDistribution(key: KeyDistribution,) -> BasePairingDelegate.KeyDistribution: + return [ + BasePairingDelegate.KeyDistribution.DISTRIBUTE_ENCRYPTION_KEY, + BasePairingDelegate.KeyDistribution.DISTRIBUTE_IDENTITY_KEY, + BasePairingDelegate.KeyDistribution.DISTRIBUTE_SIGNING_KEY, + BasePairingDelegate.KeyDistribution.DISTRIBUTE_LINK_KEY, + ][key] # type: ignore + + def pairing_config_factory(connection: BumbleConnection) -> PairingConfig: + pairing_delegate = PairingDelegate( + connection=connection, + io_capability=BasePairingDelegate.IoCapability(request.io_capability), + local_initiator_key_distribution=parseProtoKeyDistribution(request.initiator_key_distribution), + local_responder_key_distribution=parseProtoKeyDistribution(request.responder_key_distribution), + ) + + pc_req = request.pairing_config + pairing_config = PairingConfig( + sc=pc_req.sc, + mitm=pc_req.mitm, + bonding=pc_req.bonding, + identity_address_type=PairingConfig.AddressType.PUBLIC + if request.identity_address_type == PUBLIC else PairingConfig.AddressType.RANDOM, + delegate=pairing_delegate, + ) + self.log.debug(f"Override: {pairing_config}") + + return pairing_config + + self.device.pairing_config_factory = pairing_config_factory + + return Empty() |