micropython / micropython-lib

Core Python libraries ported to MicroPython
Other
2.43k stars 1k forks source link

Issue in AIOBLE #442

Closed steveli777 closed 2 months ago

steveli777 commented 3 years ago

I found one issue if I am running the temp_sensor.py file that is an example file from the AIOBLE. But I added a descriptor, when running the example, it returns an error: IndexError: tuple index out of range on aioble/server.py, line 238. And I attached the modified temp_sensor.py file I tried to print out the handles, it only returns 1 handle, I guess it belongs to the characteristic, but not the descriptor.

temp-sensor.zip

jimmo commented 3 years ago

I suspect the problem here is that MicroPython (and NimBLE) take care of managing the CCCD for you.

We should probably raise an error in aioble (or modbluetooth) if you try and register a CCCD yourself.

What do you need the CCCD for?

chrisovergaauw commented 2 years ago

Hi Jimmo,

I'm running into the exact same issue. I downloaded steveli's zip and exchanged the CCCD UUID for 0x2901 (bluetooth sig user description) or a 128-bit UUID and the exact same error still occurs.

Any clue what else it could be?

EDIT: Sorry, I should have put more thought into posting something, rather than just asking. I'm about to leave my desk, but I'd like to already leave one finding:

print(tuple(s._tuple() for s in services)) in server.py (line 274) already shows the issue I think. ((UUID(0x181a), ((UUID(0x2a6e), 18),)),)

The Tuples returned are missing descriptors altogether. I think class Characteristic should return descriptors as well in _tuple function but it plainly uses the one defined in class BaseCharacteristic.

chrisovergaauw commented 2 years ago

The example starts working with this patch.

diff --git a/micropython/bluetooth/aioble/aioble/server.py b/micropython/bluetooth/aioble/aioble/server.py
index b537638..baae307 100644
--- a/micropython/bluetooth/aioble/aioble/server.py
+++ b/micropython/bluetooth/aioble/aioble/server.py
@@ -199,6 +199,9 @@ class Characteristic(BaseCharacteristic):
         self._value_handle = None
         self._initial = initial

+    def _tuple(self):
+        return (self.uuid, self.flags, tuple(d._tuple() for d in self.descriptors))
+
     def notify(self, connection, data=None):
         if not (self.flags & _FLAG_NOTIFY):
             raise ValueError("Not supported")
jonnor commented 2 months ago

I believe this should be fixed in the above merge request by @jimmo . Proposing to close this issue.