diff --git a/apps/console.py b/apps/console.py index 5d046366..a3523d87 100644 --- a/apps/console.py +++ b/apps/console.py @@ -503,21 +503,9 @@ async def discover_services(self): self.show_error('not connected') return - # Discover all services, characteristics and descriptors - self.append_to_output('discovering services...') - await self.connected_peer.discover_services() - self.append_to_output( - f'found {len(self.connected_peer.services)} services,' - ' discovering characteristics...' - ) - await self.connected_peer.discover_characteristics() - self.append_to_output('found characteristics, discovering descriptors...') - for service in self.connected_peer.services: - for characteristic in service.characteristics: - await self.connected_peer.discover_descriptors(characteristic) - self.append_to_output('discovery completed') - - self.show_remote_services(self.connected_peer.services) + self.append_to_output('Service Discovery starting...') + await self.connected_peer.discover_all() + self.append_to_output('Service Discovery done!') async def discover_attributes(self): if not self.connected_peer: diff --git a/bumble/device.py b/bumble/device.py index 563bbf87..dff89d34 100644 --- a/bumble/device.py +++ b/bumble/device.py @@ -1133,6 +1133,15 @@ async def discover_descriptors( async def discover_attributes(self) -> List[gatt_client.AttributeProxy]: return await self.gatt_client.discover_attributes() + async def discover_all(self): + await self.discover_services() + for service in self.services: + await self.discover_characteristics(service=service) + + for service in self.services: + for characteristic in service.characteristics: + await self.discover_descriptors(characteristic=characteristic) + async def subscribe( self, characteristic: gatt_client.CharacteristicProxy, diff --git a/tests/gatt_test.py b/tests/gatt_test.py index e3c92097..030cd3fa 100644 --- a/tests/gatt_test.py +++ b/tests/gatt_test.py @@ -879,6 +879,57 @@ async def test_unsubscribe(): mock1.assert_called_once_with(ANY, False, False) +# ----------------------------------------------------------------------------- +@pytest.mark.asyncio +async def test_discover_all(): + [client, server] = LinkedDevices().devices[:2] + + characteristic1 = Characteristic( + 'FDB159DB-036C-49E3-B3DB-6325AC750806', + Characteristic.Properties.READ | Characteristic.Properties.NOTIFY, + Characteristic.READABLE, + bytes([1, 2, 3]), + ) + + descriptor1 = Descriptor('2902', 'READABLE,WRITEABLE') + descriptor2 = Descriptor('AAAA', 'READABLE,WRITEABLE') + characteristic2 = Characteristic( + '3234C4F4-3F34-4616-8935-45A50EE05DEB', + Characteristic.Properties.READ | Characteristic.Properties.NOTIFY, + Characteristic.READABLE, + bytes([1, 2, 3]), + descriptors=[descriptor1, descriptor2], + ) + + service1 = Service( + '3A657F47-D34F-46B3-B1EC-698E29B6B829', + [characteristic1, characteristic2], + ) + service2 = Service('1111', []) + server.add_services([service1, service2]) + + await client.power_on() + await server.power_on() + connection = await client.connect(server.random_address) + peer = Peer(connection) + + await peer.discover_all() + assert len(peer.gatt_client.services) == 3 + # service 1800 gets added automatically + assert peer.gatt_client.services[0].uuid == UUID('1800') + assert peer.gatt_client.services[1].uuid == service1.uuid + assert peer.gatt_client.services[2].uuid == service2.uuid + s = peer.get_services_by_uuid(service1.uuid) + assert len(s) == 1 + assert len(s[0].characteristics) == 2 + c = peer.get_characteristics_by_uuid(uuid=characteristic2.uuid, service=s[0]) + assert len(c) == 1 + assert len(c[0].descriptors) == 2 + s = peer.get_services_by_uuid(service2.uuid) + assert len(s) == 1 + assert len(s[0].characteristics) == 0 + + # ----------------------------------------------------------------------------- @pytest.mark.asyncio async def test_mtu_exchange():