Open KurtE opened 1 year ago
To follow up on the first post, I am still trying to figure out what the
bool ATTClass::discoverDescriptors(uint16_t connectionHandle, BLERemoteDevice* device)
code is doing when it is tries to enumerate the services/Characteristics to discover the attributes:
I added some debug code at the start of this, that enumerates some of the stuff we know when we get here: Serial.printf("\tService Count:%u\n", serviceCount);
#if 1
// Lets print out the information we know:
Serial.println("****************** Service characteristic list ******************");
for (int i = 0; i < serviceCount; i++) {
BLERemoteService* service = device->service(i);
Serial.printf("Service(%u): UUID: %s Handle Range: %u %u\n", i, service->uuid(),
service->startHandle(), service->endHandle());
int characteristicCount = service->characteristicCount();
for (int j = 0; j < characteristicCount; j++) {
BLERemoteCharacteristic* characteristic = service->characteristic(j);
Serial.printf("\tcharacteristic(%u): UUID: %s Handle Range: %u %u\n", j, characteristic->uuid(),
characteristic->startHandle(), characteristic->valueHandle());
}
}
Serial.println("****************** end ******************");
And for example if I run the PeripheralExplorer with the Microsoft "Surface Arc Mouse"; running in pairing mode, I see:
Service Count:5
****************** Service characteristic list ******************
Service(0): UUID: 1800 Handle Range: 1 7
characteristic(0): UUID: 2a00 Handle Range: 2 3
characteristic(1): UUID: 2a01 Handle Range: 4 5
characteristic(2): UUID: 2a04 Handle Range: 6 7
Service(1): UUID: 1801 Handle Range: 8 8
Service(2): UUID: 180a Handle Range: 9 13
characteristic(0): UUID: 2a29 Handle Range: 10 11
characteristic(1): UUID: 2a50 Handle Range: 12 13
Service(3): UUID: 180f Handle Range: 14 17
characteristic(0): UUID: 2a19 Handle Range: 15 16
Service(4): UUID: 1812 Handle Range: 18 65535
characteristic(0): UUID: 2a4e Handle Range: 19 20
characteristic(1): UUID: 2a4d Handle Range: 21 22
characteristic(2): UUID: 2a4d Handle Range: 25 26
characteristic(3): UUID: 2a4d Handle Range: 29 30
characteristic(4): UUID: 2a4d Handle Range: 33 34
characteristic(5): UUID: 2a4d Handle Range: 37 38
characteristic(6): UUID: 2a4d Handle Range: 41 42
characteristic(7): UUID: 2a4d Handle Range: 45 46
characteristic(8): UUID: 2a4d Handle Range: 49 50
characteristic(9): UUID: 2a4d Handle Range: 53 54
characteristic(10): UUID: 2a4d Handle Range: 57 58
characteristic(11): UUID: 2a4d Handle Range: 61 62
characteristic(12): UUID: 2a4d Handle Range: 64 65
characteristic(13): UUID: 2a4d Handle Range: 67 68
characteristic(14): UUID: 2a4d Handle Range: 70 71
characteristic(15): UUID: 2a4d Handle Range: 73 74
characteristic(16): UUID: 2a4d Handle Range: 76 77
characteristic(17): UUID: 2a4b Handle Range: 79 80
characteristic(18): UUID: 2a33 Handle Range: 81 82
characteristic(19): UUID: 2a4a Handle Range: 84 85
characteristic(20): UUID: 2a4c Handle Range: 86 87
****************** end ******************
Then when the current main code is trying to enumerate let's say the first Service with 3 characteristics: I have some additional debug output, condensed here:
0 Service: 1800 #characteristic:3
(0, 0) characteristic: 2a00 0x20203590, range: 4 5
Handle:04 UUID:280e
Handle:05 UUID:2a0e
(0, 1) characteristic: 2a01 0x202035f0, range: 6 7
Handle:06 UUID:280e
Handle:07 UUID:2a0e
(0, 2) characteristic: 2a04 0x0, range: 8 7
1 Service: 1801 #characteristic:0
2 Service: 180a #characteristic:2
So the first characteristic it looks like it is passing in the range for the 2nd one. Second one, the third, and the third one invalid range so it returns nothing for it.
I know I am probably missing something obvious here, My Gut (read that as my Naive and very little understanding of BLE) wonders if this code Could simply call the while (1) loop with the range maybe incremented by 1? like: Service(0): UUID: 1800 Handle Range: 1 7 And guessing if the handle returned matches one of the start handle, value handle of a characteristic add the object to that one?
EDIT: Or maybe if >= start handle of one and less then then next one then add it...
But again, I more or less am throwing darts here.
Thoughts?
I know I am probably simply talking to myself (not too unusual) ;)
I now have my extended version of the Peripheral Explorer getting information from an XBox One Controller with the updated firmware that uses BLE on a Teensy 4.1... Example Output:
HCIClass::readLeBufferSize called
Bluetooth® Low Energy Central - Peripheral Explorer
Found c8:3f:26:b3:ac:16 'Xbox Wireless Controller'
Connecting ...
Connected
Discovering attributes ...
Attributes discovered
Device name: Xbox Wireless Controll
Appearance: 0x0
Service 1800 //Generic Access service
Characteristic 2a00, properties 0x2, value 0x58626F7820576972656C65737320436F6E74726F6C6C //Device Name
Descriptor 2803, value 0x020300002A //Characteristic
Descriptor 00002a00-0000-0000-0000-000000000000, value 0x58626F7820576972656C65737320436F6E74726F6C6C
Characteristic 2a01, properties 0x2, value 0xC403 //Appearance
Descriptor 2803, value 0x020500012A //Characteristic
Descriptor 00002a01-0000-0000-0000-000000000000, value 0xC403
Characteristic 2a04, properties 0x2, value 0x0600060000002C01 //Peripheral Preferred Connection Parameters
Descriptor 2803, value 0x020700042A //Characteristic
Descriptor 00002a04-0000-0000-0000-000000000000, value 0x0600060000002C01
Service 1801 //Generic Attribute service
Service 180a //Device Information service
Characteristic 2a29, properties 0x2, value 0x4D6963726F736F6674 //Manufacturer Name String
Descriptor 2803, value 0x020B00292A //Characteristic
Descriptor 00002a29-0000-0000-0000-000000000000, value 0x4D6963726F736F6674
Characteristic 2a50, properties 0x2, value 0x025E04200B1505 //PnP ID
Descriptor 2803, value 0x020D00502A //Characteristic
Descriptor 00002a50-0000-0000-0000-000000000000, value 0x025E04200B1505
Characteristic 2a26, properties 0x2, value 0x352E31352E333136382E30 //Firmware Revision String
Descriptor 2803, value 0x020F00262A //Characteristic
Descriptor 00002a26-0000-0000-0000-000000000000, value 0x352E31352E333136382E30
Characteristic 2a25, properties 0x2, value 0x3033363030303332393035363234 //Serial Number String
Descriptor 2803, value 0x021100252A //Characteristic
Descriptor 00002a25-0000-0000-0000-000000000000, value 0x3033363030303332393035363234
Service 180f //Battery service
Characteristic 2a19, properties 0x12, value 0x32 //Battery Level
Descriptor 2803, value 0x121400192A //Characteristic
Descriptor 00002a19-0000-0000-0000-000000000000, value 0x32
Descriptor 2902, value 0x0000 //Client Characteristic Configuration
Service 1812 //Human Interface Device service
Characteristic 2a4a, properties 0x2 //HID Information
Descriptor 2803, value 0x0218004A2A //Characteristic
Descriptor 00002a4a-0000-0000-0000-000000000000, value 0x
Characteristic 2a4c, properties 0x4 //HID Control Point
Descriptor 2803, value 0x041A004C2A //Characteristic
Descriptor 00002a4c-0000-0000-0000-000000000000, value 0x
Characteristic 2a4b, properties 0x2 //Report Map
Descriptor 2803, value 0x021C004B2A //Characteristic
Descriptor 00002a4b-0000-0000-0000-000000000000, value 0x
Characteristic 2a4d, properties 0x12 //Report
Descriptor 2803, value 0x121E004D2A //Characteristic
Descriptor 00002a4d-0000-0000-0000-000000000000, value 0x
Descriptor 2902, value 0x0000 //Client Characteristic Configuration
Descriptor 2908, value 0x0101 //Report Reference
Characteristic 2a4d, properties 0xE //Report
Descriptor 2803, value 0x0E22004D2A //Characteristic
Descriptor 00002a4d-0000-0000-0000-000000000000, value 0x
Descriptor 2908, value 0x0302 //Report Reference
Service 00000001-5f60-4c4f-9c83-a7953298d40d
Characteristic 00000002-5f60-4c4f-9c83-a7953298d40d, properties 0x2
Descriptor 2803, value 0x0226000DD4983295A7839C4F4C605F02000000 //Characteristic
Descriptor 00000002-5f60-4c4f-9c83-a7953298d40d, value 0x
Characteristic 00000003-5f60-4c4f-9c83-a7953298d40d, properties 0x2
Descriptor 2803, value 0x0228000DD4983295A7839C4F4C605F03000000 //Characteristic
Descriptor 00000003-5f60-4c4f-9c83-a7953298d40d, value 0x
Characteristic 00000004-5f60-4c4f-9c83-a7953298d40d, properties 0x8
Descriptor 2803, value 0x082A000DD4983295A7839C4F4C605F04000000 //Characteristic
Descriptor 00000004-5f60-4c4f-9c83-a7953298d40d, value 0x
Disconnecting ...
Disconnected
My Fork/Branch is updated with the code. Still has some debug stuff turned on.
Note: The main Issue that was causing this to not work, was in the function:
int HCIClass::readLeBufferSize(uint16_t& pktLen, uint8_t& maxPkt)
{
int result = sendCommand(OGF_LE_CTL << 10 | OCF_LE_READ_BUFFER_SIZE);
//Serial.println("HCIClass::readLeBufferSize called");
if (result == 0) {
struct __attribute__ ((packed)) HCILeBufferSize {
uint16_t pktLen;
uint8_t maxPkt;
} *leBufferSize = (HCILeBufferSize*)_cmdResponse;
pktLen = leBufferSize->pktLen;
_maxPkt = maxPkt = leBufferSize->maxPkt;
#ifdef _BLE_TRACE_
Serial.print("\tpktlen: ");
Serial.print(pktLen, DEC);
Serial.print(" maxPkt: ");
Serial.println(maxPkt, DEC);
#endif
#if (defined(TEENSYDUINO) && (__IMXRT1062__) || (ARDUINO_TEENSY36)) || !defined(__AVR__)
ATT.setMaxMtu(pktLen/* - 9*/); // max pkt len - ACL header size
#endif
}
return result;
}
The Bluetooth 4.0 dongle returned 27 and the code was subtracting 9 from it for the ACL data size...
From the Bluetooth 5.3 manual it says:
Total_Num_ISO_Data_Packets return parameter contains the total number of isochronous data packets that can be stored in the data buffers of the Controller. The Host determines how to divide the buffers between different connection handle(s). Note: The LE_ACL_Data_Packet_Length and ISO_Data_Packet_Length return parameters do not include the length of the HCI ACL Data packet header or the HCI ISO Data packet header respectively.
Removing that -9 caused everything to appear to work now.
Hello, I've run into same issue when attempting discoverAttributes on XBox controller (BLE). I've been testing your changes and what made this work are your changes for descriptor UUID (16/128 bit format). -9 on setMaxMtu has no effect in my case. My HW: Arduino Nano RB2040 Connect
^
Hi! Just run into the same issue with Arduino Uno R4 - stuck in infinite loop in discoverAttributes. Can confirm what @bediver said, your changes in discoverDescriptors from https://github.com/KurtE/ArduinoBLE/tree/uno_r4_wifi_teensy branch fix it.
Thank you kindly for putting it up here, I would've never figured it out myself! Hope ArduinoBLE devs will pick it up eventually?
If you update an XBox One controller to the latest firmware, the update will convert the controller to running using BLE. Microsoft shows a few different ways to do the update, including I believe simply plug it into USB to XBox One that is running the latest stuff. I updated one of mine using the Windows XBox Accessories App.
Side note: trying to add BLE support to our Teensy USBHost_t36 code base. We already have some bluetooth support, and for example we can connect and use an XBox one controller, with the original firmware, but not after they are updated.
So I thought I would experiment using the ArduinoBLE library, and first tried on Arduino Nano 33 IOT as well as BLE and this call fails. Note: I now also have a fork/branch of this library that runs on Teensy boards (T3.6 and 4.x) and right now doing most of my stuff I am using a bluetooth dongle plugged into an USBHost connector on either a 4.1 or a Micromod.
In order for BLE to see this you need to put the controller into pairing mode. Hopefully after I figure out this part will then figure out how to do an actual BLE pairing (Again sort of outside of this issue).
When in pairing mode I found a windows App, that can talk to the device.![image](https://user-images.githubusercontent.com/1558080/202805704-e8110cc6-4751-44cc-aa14-e1d836fe31df.png)
Note: I posted Some of these details up on both a PJRC forum thread as well as an Arduino one: https://forum.arduino.cc/t/arduinoble-trying-to-connect-to-xbox-one-controller-and-other-ble-devices/1054844/3 https://forum.pjrc.com/threads/71503-USBHost-Bluetooth-gt-BLE-gt-ArduinoBLE
As the title mentioned, the discoverAttributes call fails. I have added a lot of debug outputs and the like to code including into my TeensyTransport code. This includes doing some decoding of the data that is sent back and forth with the ATT messages.
It looks like the code is properly enumerating the Services and the Characteristics and then fails after that:
From my debug output: first enumerating the Services: Pardon some of my cryptic outputs:
But it looks here like it found: Handle:0001 ID: 1800 0008 ID: 1801 0009 180a 0012 180f 0016 1812
Which map to:
It then goes through all 5 of these Services looking for Characteristics:
I won't go through all 5 groups here to decode. But looking at the first we see:
So as I read this, the first group should have 3 handles 2, 4 and 6 I have not fully decoded the 5 bytes, but it looks like 2 goes to UUID 0x2A00 and likewise and 04->0x2A01 Which maps to: case 0x2A00: return "Device Name"; case 0x2A01: return "Appearance"; Which again matches the data I see with the Windows app.
Again the call discoverCharacteristics works, but then the call to: bool ATTClass::discoverDescriptors(uint16_t connectionHandle, BLERemoteDevice* device) Fails on the first items. That is i=0 and j=0;
If fails in the while(1) { loop. Some debug from that part:
Something that does not feel right here is: As I mentioned earlier is it looks like the first one has handle 2 but it is searching for it with the range 4,5? It finds the 2nd one with ID 4, It then tries a search on 5-5 which then bails with an error and I don't see any response on the ACLDATA for it.
Still investigating