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.

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:
>>(ACLDATA, 0):40 00 07 00 03 00 04 00 02 12 00
** MTU_REQ **: MTU: 12
<<(ACLDATA, 5183):40 20 07 00 03 00 04 00 03 12 00
** MTU_RESP **: MTU: 12
>>(ACLDATA, 42):40 00 0B 00 07 00 04 00 10 01 00 FF FF 00 28
** READ_BY_GROUP_REQ **: Starting handle:0001 ending handle:ffff Group Type:2800
<<(ACLDATA, 45):40 20 12 00 0E 00 04 00 11 06 01 00 07 00 00 18 08 00 08 00 01 18
** READ_MULTI_RESP **: len per:06
Atr Handle:0001 End Group Handle:0012 Data: 00 18
Atr Handle:0008 End Group Handle:0012 Data: 01 18
>>(ACLDATA, 29):40 00 0B 00 07 00 04 00 10 09 00 FF FF 00 28
** READ_BY_GROUP_REQ **: Starting handle:0009 ending handle:ffff Group Type:2800
<<(ACLDATA, 30):40 20 12 00 0E 00 04 00 11 06 09 00 11 00 0A 18 12 00 15 00 0F 18
** READ_MULTI_RESP **: len per:06
Atr Handle:0009 End Group Handle:0012 Data: 0a 18
Atr Handle:0012 End Group Handle:0012 Data: 0f 18
>>(ACLDATA, 30):40 00 0B 00 07 00 04 00 10 16 00 FF FF 00 28
** READ_BY_GROUP_REQ **: Starting handle:0016 ending handle:ffff Group Type:2800
<<(ACLDATA, 30):40 20 0C 00 08 00 04 00 11 06 16 00 23 00 12 18
** READ_MULTI_RESP **: len per:06
Atr Handle:0016 End Group Handle:000c Data: 12 18
>>(ACLDATA, 14):40 00 0B 00 07 00 04 00 10 24 00 FF FF 00 28
** READ_BY_GROUP_REQ **: Starting handle:0024 ending handle:ffff Group Type:2800
<<(ACLDATA, 45):40 20 09 00 05 00 04 00 01 10 24 00 80
** ATT_ERROR **: OP:10 handle:24 error:80
After discoverServices
But it looks here like it found:
Handle:0001 ID: 1800
0008 ID: 1801
0009 180a
0012 180f
0016 1812
Which map to:
case 0x1800: return "Generic Access service";
case 0x1801: return "Generic Attribute service";
case 0x180A: return "Device Information service";
case 0x1812: return "Human Interface Device service";
It then goes through all 5 of these Services looking for Characteristics:
>>(ACLDATA, 45):40 00 0B 00 07 00 04 00 08 01 00 07 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0001 ending handle:0007 Attribute Type:2803
<<(ACLDATA, 30):40 20 14 00 10 00 04 00 09 07 02 00 02 03 00 00 2A 04 00 02 05 00 01 2A
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:0002 Data: 02 03 00 00 2a
Atr Handle:0004 Data: 02 05 00 01 2a
>>(ACLDATA, 14):40 00 0B 00 07 00 04 00 08 06 00 07 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0006 ending handle:0007 Attribute Type:2803
<<(ACLDATA, 30):40 20 0D 00 09 00 04 00 09 07 06 00 02 07 00 04 2A
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:0006 Data: 02 07 00 04 2a
>>(ACLDATA, 30):40 00 0B 00 07 00 04 00 08 08 00 07 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0008 ending handle:0007 Attribute Type:2803
<<(ACLDATA, 45):40 20 09 00 05 00 04 00 01 08 08 00 01
** ATT_ERROR **: OP:8 handle:8 error:01 - INVALID_HANDLE
>>(ACLDATA, 29):40 00 0B 00 07 00 04 00 08 08 00 08 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0008 ending handle:0008 Attribute Type:2803
<<(ACLDATA, 30):40 20 09 00 05 00 04 00 01 08 08 00 0A
** ATT_ERROR **: OP:8 handle:8 error:0a - ATTR_NOT_FOUND
>>(ACLDATA, 30):40 00 0B 00 07 00 04 00 08 09 00 11 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0009 ending handle:0011 Attribute Type:2803
<<(ACLDATA, 30):40 20 14 00 10 00 04 00 09 07 0A 00 02 0B 00 29 2A 0C 00 02 0D 00 50 2A
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:000a Data: 02 0b 00 29 2a
Atr Handle:000c Data: 02 0d 00 50 2a
>>(ACLDATA, 14):40 00 0B 00 07 00 04 00 08 0E 00 11 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:000e ending handle:0011 Attribute Type:2803
<<(ACLDATA, 30):40 20 14 00 10 00 04 00 09 07 0E 00 02 0F 00 26 2A 10 00 02 11 00 25 2A
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:000e Data: 02 0f 00 26 2a
Atr Handle:0010 Data: 02 11 00 25 2a
>>(ACLDATA, 30):40 00 0B 00 07 00 04 00 08 12 00 11 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0012 ending handle:0011 Attribute Type:2803
<<(ACLDATA, 30):40 20 09 00 05 00 04 00 01 08 12 00 01
** ATT_ERROR **: OP:8 handle:12 error:01 - INVALID_HANDLE
>>(ACLDATA, 14):40 00 0B 00 07 00 04 00 08 12 00 15 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0012 ending handle:0015 Attribute Type:2803
<<(ACLDATA, 30):40 20 0D 00 09 00 04 00 09 07 13 00 12 14 00 19 2A
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:0013 Data: 12 14 00 19 2a
>>(ACLDATA, 30):40 00 0B 00 07 00 04 00 08 15 00 15 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0015 ending handle:0015 Attribute Type:2803
<<(ACLDATA, 30):40 20 09 00 05 00 04 00 01 08 15 00 0A
** ATT_ERROR **: OP:8 handle:15 error:0a - ATTR_NOT_FOUND
>>(ACLDATA, 14):40 00 0B 00 07 00 04 00 08 16 00 23 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0016 ending handle:0023 Attribute Type:2803
<<(ACLDATA, 30):40 20 14 00 10 00 04 00 09 07 17 00 02 18 00 4A 2A 19 00 04 1A 00 4C 2A
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:0017 Data: 02 18 00 4a 2a
Atr Handle:0019 Data: 04 1a 00 4c 2a
>>(ACLDATA, 30):40 00 0B 00 07 00 04 00 08 1B 00 23 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:001b ending handle:0023 Attribute Type:2803
<<(ACLDATA, 30):40 20 14 00 10 00 04 00 09 07 1B 00 02 1C 00 4B 2A 1D 00 12 1E 00 4D 2A
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:001b Data: 02 1c 00 4b 2a
Atr Handle:001d Data: 12 1e 00 4d 2a
>>(ACLDATA, 14):40 00 0B 00 07 00 04 00 08 1F 00 23 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:001f ending handle:0023 Attribute Type:2803
<<(ACLDATA, 30):40 20 0D 00 09 00 04 00 09 07 21 00 0E 22 00 4D 2A
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:0021 Data: 0e 22 00 4d 2a
>>(ACLDATA, 30):40 00 0B 00 07 00 04 00 08 23 00 23 00 03 28
** READ_BY_TYPE_REQ **: Starting handle:0023 ending handle:0023 Attribute Type:2803
<<(ACLDATA, 30):40 20 09 00 05 00 04 00 01 08 23 00 0A
** ATT_ERROR **: OP:8 handle:23 error:0a - ATTR_NOT_FOUND
After discoverCharacteristics
I won't go through all 5 groups here to decode. But looking at the first we see:
** READ_BY_TYPE_REQ **: Starting handle:0001 ending handle:0007 Attribute Type:2803
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:0002 Data: 02 03 00 00 2a
Atr Handle:0004 Data: 02 05 00 01 2a
** READ_BY_TYPE_REQ **: Starting handle:0006 ending handle:0007 Attribute Type:2803
** READ_BY_TYPE_RESP **: len per:07
Atr Handle:0006 Data: 02 07 00 04 2a
** READ_BY_TYPE_REQ **: Starting handle:0008 ending handle:0007 Attribute Type:2803
** ATT_ERROR **: OP:8 handle:8 error:01 - INVALID_HANDLE
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:
`ATTClass::discoverDescriptors(64, 0x20203338)
Service Count:5
0 Service: 1800 #characteristic:3
**(0, 0) characteristic: 2a00 0x20203590, range: 4 5**
ATTClass::findInfoReq(64, 4, 5, 0x20067e80)
>>(ACLDATA, 14):40 00 09 00 05 00 04 00 04 04 00 05 00
** FIND_INFO_REQ **: Starting handle:0004 ending handle:0005
<<(ACLDATA, 30):40 20 0A 00 06 00 04 00 05 01 04 00 03 28
** FIND_INFO_RESP **: Format:1
**Handle:04 UUID:280a**
>>(ACLDATA, 30):40 00 09 00 05 00 04 00 04 05 00 05 00
**** FIND_INFO_REQ **: Starting handle:0005 ending handle:0005**
tx_data callback (bluetooth):40 00 09 00 05 00 04 00 04 05 00 05 00
<<(EVT, 16, H:163 T:163)13 05 01 40 00 02 00
HCI event: 13
Outstanding packets: 0
Data[0]: 0x64
Data[1]: 0x2
0 0 respLength:0
Attribute discovery failed!
Command tx -> 0x1 0x6 0x4 0x3 0x40 0x0 0x13
>>(CMD, 4984):06 04 03 40 00 13
Control callback (bluetooth): 0 : 06 04 03 40 00 13
<<(EVT, 2, H:171 T:171)0F 04 00 01 06 04
HCI event: F
F n cmd: 0x1
F status: 0x0
F opcode: 0x406
<<(EVT, 1899, H:178 T:178)05 04 00 40 00 22
HCI event: 5
Command tx -> 0x1 0xA 0x20 0x1 0x1
>>(CMD, 0):0A 20 01 01
Control callback (bluetooth): 0 : 0a 20 01 01
<<(EVT, 2, H:185 T:185)0E 04 01 0A 20 00
HCI event: E
E ncmd: 0x1
E opcode: 0x200A
E status: 0x0
`
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