TorstenRobitzki / bluetoe

C++ Framework to build Bluetooth LE Server (GATT)
MIT License
142 stars 29 forks source link

Characteristics discovery not working with server::l2cap_input #24

Closed kaofishy closed 6 years ago

kaofishy commented 6 years ago

Hi there,

I'm trying to use your library through an HCI host, basically I'm instantiating a bluetoe::server class and pass the advertising and L2CAP data back and forth with my own link layer through l2cap_input. I've got advertising working, and I can connect and discover all the services, however I have not been able to get characteristics discovery working. When an client sends Read By Type Request with 0x2803 for characteristics declarations, the server instance invariably returns an error response with code 0x0a (Attribute Not Found).

I have tried all the server examples and none of them seems to work.

Tony

kaofishy commented 6 years ago

Upon further inspection, handle_read_by_type_request (used by characteristics discovery) seems to use a different attribute iteration algorithm than handle_read_by_group_type_request (used by service discovery). Could this be the reason?

TorstenRobitzki commented 6 years ago

Hi Tony, this sounds great. I'm definitely interested in sorting this out with you. This week I'm very busy, but next week I will have enough time to help you.

In very early versions of Bluetoe, I used the L2CAP layer of my laptop for testing. Can you give me a definition of your server and sniffed logs?

kind regards, Torsten

kaofishy commented 6 years ago

Hi Torsten,

Thanks for the quick response! This is the server definition I took from your server_example.cpp (I've tried other examples with the same result):

bluetoe::service<
        bluetoe::service_uuid< 0x8C8B4094, 0x0DE2, 0x499F, 0xA28A, 0x4EED5BC73CA9 >,
        bluetoe::characteristic<
            bluetoe::bind_characteristic_value< decltype( temperature ), &temperature >,
            bluetoe::no_read_access
        >
    >
>

and these are the ATT packets as seen from the server side (using a Windows 10 client):

client request
020d02
server response
030901

client request
100100ffff0028
server response
111401000300a93cc75bed4e8aa29f49e20d94408b8c

client request
100400ffff0028
server response
1106040008000018

client request
100900ffff0028
server response
011009000a

client request
08040008000328
server response
010804000a

client request
08010003000328
server response
010801000a

client request
08040008000328
server response
010804000a

Connecting with an iOS client

client request
02b900
server response
030901

client request
100100ffff0028
server response
111401000300a93cc75bed4e8aa29f49e20d94408b8c

client request
100400ffff0028
server response
1106040008000018

client request
100900ffff0028
server response
011009000a

client request
08010003000328
server response
010801000a

client request
0804000800002a
server response
09100600426c7565746f652d536572766572
kaofishy commented 6 years ago

Also, strangely, when I call attribute_at() on the server it returns 0 as UUID except for two GAP service attributes...

TorstenRobitzki commented 6 years ago

Am 21.06.2018 um 08:57 schrieb Tony Kao notifications@github.com:

bluetoe::service< bluetoe::service_uuid< 0x8C8B4094, 0x0DE2, 0x499F, 0xA28A, 0x4EED5BC73CA9

, bluetoe::characteristic< bluetoe::bind_characteristic_value< decltype( temperature ), &temperature >, bluetoe::no_read_access

So the service definition should have the handle 0x0001, the characteristic definition handle 0x0002 and the characteristic value should be 0x0003.

and these are the ATT packets as seen from the server side:

client request 020d02

Exchange MTU Request: 0x20d

server response 030901

Exchange MTU Response: 0x109

client request 100100ffff0028

Read by Group Type Request: 0x0001 - 0xffff, 0x2800 (Primary Service)

server response 111401000300a93cc75bed4e8aa29f49e20d94408b8c

Read By Type Response; length: 20 Attribute Handle: 0x0001 End Group Handle: 0x0003 UUID: a93cc75bed4e8aa29f49e20d94408b8c

client request 100400ffff0028

Read by Group Type Request: 0x0004 - 0xffff, 0x2800 (Primary Service)

server response 1106040008000018

Read By Type Response; length: 6 Attribute Handle: 0x0004 End Group Handle: 0x0008 UUID: 0x1800

client request 100900ffff0028

Read by Group Type Request: 0x0009 - 0xffff, 0x2800 (Primary Service)

server response 011009000a

Not found. (that’s ok)

client request 08040008000328

Read By Type Request 0x0004-0x0008, Type: 0x2803 (Characteristic Declaration)

server response 010804000a

yes, this response looks wrong to me. There should be characteristics in that range.

client request 08010003000328

Read By Type Request 0x0001-0x0003, Type: 0x2803 (Characteristic Declaration)

server response 010801000a

here, the user defined characteristic of the service above should have been found.

I will try to make this a unit test. The only thing I currently can think of, is the relatively high MTU size.

TorstenRobitzki commented 6 years ago

attribute_at() should be able to report the attributes, otherwise Read by Group Type Request shouldn't have worked. The parameter to attribute_at() is the handle -1.

kaofishy commented 6 years ago

Yeah I'm not sure what's going on with attribute_at(), I tried to trace the code to figure out what's wrong but I've come to the conclusion that my template metaprogramming-fu is nowhere near yours lol

With respect to the MTU, I've tried different sizes from small to large and they've made no difference.

kaofishy commented 6 years ago

These are the UUIDs returned when I iterate over attribute_at():

0
0
0
0
0
2A00
0
2A01
kaofishy commented 6 years ago

Okay I have found the problem: it turns out the bits(gatt_uuid) conversion function wasn't getting called to initialize the attributes because it is not constexpr. Now all the UUIDs are showing up when I iterate through attribute_at().

TorstenRobitzki commented 6 years ago

Does it mean that your problem is solved?

kaofishy commented 6 years ago

Yes, it seems there was some static initialization order fiasco involved. I'm preparing a git pull request for the fix.