bluekitchen / btstack

Dual-mode Bluetooth stack, with small memory footprint.
http://bluekitchen-gmbh.com
Other
1.7k stars 608 forks source link

Bluetooth LE HID host demo ? #118

Closed theElementZero closed 4 years ago

theElementZero commented 6 years ago

Hi all,

i am looking for HID host, i need HID in LE, i was implementing hid_hos_demo but as it turns out it on classic. i am using ESP32 hardware with btstack @mringwal The device i am pairing is having following spec: Bluetooth®4.0 2.4GHz, HID virtual keyboard, nRF8001 μBlue Bluetooth Low Energy Platform.

i can see HID over GATT (HOG) as per comment in topic keyboard and mouse demo are up in example, but i cant see HOST DEMO.

would like yo know what need to be done for HOST application, is there ready to use example/sample code.

Thanks Sushant

mringwal commented 6 years ago

hi. We don't have an HOG Host demo currently.

It would look like this:

we don't have plans for an hog_host demo right now, but we also plan to fully implement Classic HI until summer. We'll see if we add in HOG at that time as well.

theElementZero commented 6 years ago

@mringwal Thanks for reply, appreciated.

how different will be HOG host different from hid host ?

i was doing an experiment , i downloaded hid host example from bt stack in one esp32 module and hid keyboard example in another esp32 module, but they are not getting connected ?

i just changed MAC address in host example, is there any thing else to do ?

log:

BTstack: up and running. Start SDP HID query for remote HID Device. [00:00:01.208] LOG -- l2cap.c.1791: L2CAP_CREATE_CHANNEL addr 24:0A:C4:83:0A:96 psm 0x1 mtu 1691 -> local mtu 1691 [00:00:01.219] EVT <= 6E 00 [00:00:01.221] LOG -- hci.c.3397: Create_connection to 24:0A:C4:83:0A:96 [00:00:01.227] LOG -- hci.c.184: create_connection_for_addr 24:0A:C4:83:0A:96, type ff [00:00:01.235] LOG -- hci.c.3409: conn state 0 [00:00:01.239] CMD => 05 04 0D 96 0A 83 C4 0A 24 18 CC 00 00 00 00 01 [00:00:01.246] EVT <= 0F 04 00 05 05 04 [00:00:01.249] EVT <= 6E 00 [00:00:07.382] EVT <= 03 0B 10 80 00 96 0A 83 C4 0A 24 01 00 [00:00:07.383] LOG -- hci.c.1905: Connection_complete (status=16) 24:0A:C4:83:0A:96 [00:00:07.384] LOG -- l2cap.c.923: L2CAP_EVENT_CHANNEL_OPENED status 0x10 addr 24:0A:C4:83:0A:96 handle 0x0 psm 0x1 local_cid 0x40 remote_cid 0x0 local_mtu 1691, remote_mtu 672, flush_timeout 0 [00:00:07.401] EVT <= 70 16 10 96 0A 83 C4 0A 24 00 00 01 00 40 00 00 00 9B 06 A0 02 00 00 00 [00:00:07.409] LOG -- sdp_client.c.448: SDP Client Connection failed, status 0x10. HID Control PSM missing [00:00:07.418] LOG -- l2cap.c.1051: l2cap_stop_rtx for local cid 0x40

Connection_complete (status=16) does this mean pairing success ? SDP Client Connection failed, status 0x10. may i know what is error and how to solve it ?

MAC address of another ESP32 is // MBP 2016 static const char * remote_addr_string = "24-0a-c4-83-0a-96"; in host file.

however i have used same example to pair with mobile and send data it works, but between 2 ESP32 not working any help would be appreciated

Regards Sushant

mringwal commented 6 years ago

In HID Classic, the HID Descriptor is queried via SDP and then L2CAP is used for the HID messages. In HID over GATT (LE), GATT is used for both. The actual HID data is standardized by USB association.

Status != 0 means error. Error codes are listed e.g. in src/bluetooth.h

define ERROR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED 0x10

This means the remote side did not accept the Bluetooth connection. What's in the log of the remote device?

theElementZero commented 6 years ago

This is log from other esp32, sorry for late reply,

BTstack: up and running. [00:00:01.102] EVT <= 6E 00 [00:00:11.885] EVT <= 04 0A 3E 89 12 C4 0A 24 0C 02 7A 01 [00:00:11.885] LOG -- hci.c.1881: Connection_incoming: 24:0A:C4:12:89:3E, type 1 [00:00:11.886] LOG -- hci.c.184: create_connection_for_addr 24:0A:C4:12:89:3E, type ff [00:00:11.894] LOG -- hci.c.3136: sending hci_accept_connection_request, remote eSCO 0 [00:00:11.902] CMD => 09 04 07 3E 89 12 C4 0A 24 01 [00:00:11.907] EVT <= 0F 04 00 05 09 04 [00:00:11.910] EVT <= 6E 00 [00:00:11.919] EVT <= 03 0B 00 80 00 3E 89 12 C4 0A 24 01 00 [00:00:11.919] LOG -- hci.c.1905: Connection_complete (status=0) 24:0A:C4:12:89:3E [00:00:11.925] LOG -- hci.c.1918: New connection: handle 128, 24:0A:C4:12:89:3E [00:00:11.932] LOG -- hci.c.3756: BTSTACK_EVENT_NR_CONNECTIONS_CHANGED 1 [00:00:11.939] EVT <= 61 01 01 [00:00:11.942] CMD => 1B 04 02 80 00 [00:00:11.945] EVT <= 1B 03 80 00 05 [00:00:11.948] EVT <= 0F 04 00 05 1B 04 [00:00:11.952] EVT <= 0B 0B 00 80 00 BF EE CD FE DB FF 7B 87 [00:00:11.958] LOG -- hci.c.1984: HCI_EVENT_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE, bonding flags 6, eSCO 1 [00:00:11.967] EVT <= 6E 00 [00:00:11.990] ACL <= 80 20 0C 00 08 00 01 00 02 01 04 00 01 00 40 00 [00:00:11.990] LOG -- hci.c.3889: gap_request_security_level 0, current level 0 [00:00:11.992] LOG -- hci.c.3787: hci_emit_security_level 0 for handle 80 [00:00:11.999] EVT <= E0 03 80 00 00 [00:00:12.002] LOG -- l2cap.c.2127: l2cap - security level update [00:00:12.008] LOG -- l2cap.c.2136: channel state 5: actual 0 >= required 0? [00:00:12.015] LOG -- l2cap.c.951: L2CAP_EVENT_INCOMING_CONNECTION addr 24:0A:C4:12:89:3E handle 0x80 psm 0x1 local_cid 0x40 remote_cid 0x40 [00:00:12.027] EVT <= 72 0E 3E 89 12 C4 0A 24 80 00 01 00 40 00 40 00 [00:00:12.033] LOG -- l2cap.c.2247: L2CAP_ACCEPT_CONNECTION local_cid 0x40 [00:00:12.040] ACL => 80 00 10 00 0C 00 01 00 03 01 08 00 40 00 40 00 00 00 00 00 [00:00:12.047] EVT <= 6E 00 [00:00:12.050] ACL => 80 00 10 00 0C 00 01 00 04 01 08 00 40 00 00 00 01 02 9B 06 [00:00:12.057] LOG -- l2cap.c.1051: l2cap_stop_rtx for local cid 0x40 [00:00:12.063] LOG -- l2cap.c.1057: l2cap_start_rtx for local cid 0x40 [00:00:12.070] EVT <= 6E 00 [00:00:12.072] CMD => 35 0C 05 01 80 00 01 00 [00:00:12.076] EVT <= 13 05 01 80 00 01 00 [00:00:12.080] EVT <= 13 05 01 80 00 01 00 [00:00:12.084] EVT <= 6E 00 [00:00:12.089] ACL <= 80 20 10 00 0C 00 01 00 04 02 08 00 40 00 00 00 01 02 9B 06 [00:00:12.094] LOG -- l2cap.c.2451: L2CAP signaling handler code 4, state 11 [00:00:12.101] LOG -- l2cap.c.2303: Remote MTU 1691 [00:00:12.105] ACL => 80 00 12 00 0E 00 01 00 05 02 0A 00 40 00 00 00 00 00 01 02 9B 06 [00:00:12.113] EVT <= 6E 00 [00:00:12.116] CMD => 35 0C 05 01 80 00 01 00 [00:00:12.120] EVT <= 13 05 01 80 00 01 00 [00:00:12.124] EVT <= 6E 00 [00:00:12.161] ACL <= 80 20 12 00 0E 00 01 00 05 01 0A 00 40 00 00 00 00 00 01 02 9B 06 [00:00:12.161] LOG -- l2cap.c.2451: L2CAP signaling handler code 5, state 11 [00:00:12.165] LOG -- l2cap.c.1051: l2cap_stop_rtx for local cid 0x40 [00:00:12.171] LOG -- l2cap.c.2383: l2cap_signaling_handle_configure_response [00:00:12.178] LOG -- l2cap.c.923: L2CAP_EVENT_CHANNEL_OPENED status 0x0 addr 24:0A:C4:12:89:3E handle 0x80 psm 0x1 local_cid 0x40 remote_cid 0x40 local_mtu 1691, remote_mtu 1691, flush_timeout 0 [00:00:12.195] EVT <= 70 16 00 3E 89 12 C4 0A 24 80 00 01 00 40 00 40 00 9B 06 9B 06 00 00 01 [00:00:12.203] CMD => 35 0C 05 01 80 00 01 00 [00:00:12.208] ACL <= 80 20 18 00 14 00 40 00 06 00 01 00 0F 35 03 19 11 24 06 9B 35 05 0A 00 01 FF FF 00 [00:00:12.217] EVT <= 6E 00 [00:00:12.220] EVT <= 78 02 40 00 [00:00:12.223] ACL => 80 00 F3 00 EF 00 40 00 07 00 01 00 EA 00 E7 36 00 E4 36 00 E1 09 00 01 36 00 03 19 11 24 09 00 04 36 00 0F 36 00 06 19 01 00 09 00 11 36 00 03 19 00 11 09 00 06 36 00 09 09 65 6E 09 00 6A 09 01 00 09 00 0D 36 00 0C 36 00 03 19 00 11 19 01 00 09 00 13 09 01 00 25 14 42 54 73 74 61 63 6B 20 48 49 44 20 4B 65 79 62 6F 61 72 64 09 00 09 36 00 09 36 00 06 19 11 24 09 01 01 09 02 01 09 01 11 09 02 02 08 40 09 02 03 08 21 09 02 04 28 00 09 02 05 28 00 09 02 06 36 00 46 36 00 43 08 22 25 3F 05 01 09 06 A1 01 75 01 95 08 05 07 19 E0 29 E7 15 00 25 01 81 02 75 01 95 08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 03 95 06 75 08 15 00 25 FF 05 07 19 00 29 FF 81 00 C0 09 02 07 36 00 09 36 00 06 09 04 09 09 01 00 09 02 0E 28 00 00 [00:00:12.289] EVT <= 6E 00 [00:00:12.292] CMD => 35 0C 05 01 80 00 01 00 [00:00:12.296] EVT <= 6E 00 [00:00:12.314] EVT <= 13 05 01 80 00 01 00 [00:00:12.402] ACL <= 80 20 0C 00 08 00 01 00 06 03 04 00 40 00 40 00 [00:00:12.403] LOG -- l2cap.c.2451: L2CAP signaling handler code 6, state 12 [00:00:12.404] ACL => 80 00 0C 00 08 00 01 00 07 03 04 00 40 00 40 00 [00:00:12.411] LOG -- l2cap.c.945: L2CAP_EVENT_CHANNEL_CLOSED local_cid 0x40 [00:00:12.417] EVT <= 71 02 40 00 [00:00:12.421] LOG -- l2cap.c.1051: l2cap_stop_rtx for local cid 0x40 [00:00:12.427] EVT <= 6E 00 [00:00:12.429] CMD => 35 0C 05 01 80 00 01 00 [00:00:12.434] EVT <= 6E 00 [00:00:12.436] EVT <= 13 05 01 80 00 01 00

mringwal commented 6 years ago

thanks for the second log. to me, it doesn't look like the logs are from the same connection. In the second, the HCI connection is successful as well as the SDP query. I think I never tried hid_keyboard with hid_host together, I'll give it a try.

theElementZero commented 6 years ago

@mringwal i will try to provide proper log file again, But now i am trying, HOG_MOUSE_DEMO in one esp32 and GATT_BATTERY_QUERY in another ESP32, these example give me little idea about my project, as i would have to do same over HID profile,

but problem is i am getting disconnection at regular interval, can you just go through log file and help me ?

HOG_MOUSE_DEMO_LOG GATT_BATTERY_QUERY

i think this should have worked as you have initialized battery service in HOG_MOUSE_DEMO.c

// setup ATT server
att_server_init(profile_data, NULL, NULL);

// setup battery service
battery_service_server_init(battery);

And also i tried hog_keyboard_demo.c, i was able to pair with mobile (Android 5.1) but it didnt work with another mobile (android 7.1), also it just got paired, it never got connected to send data. i will try to provide you log file.

theElementZero commented 6 years ago

@mringwal Here is new log file from HID_HOST and HID KEYBOARD HID_HOST HID_KEYBOARD

after Reset, Host reset first, Keyboard host

Sorry for late posting

mringwal commented 6 years ago

hog-mouse-demo vs. gatt-battery-query: logs are good, but gatt-battery-query disconnects after it subscribes for changes to the battery. That's incorrect. If you comment the call to gap_disconnect in line 221, it should stay connected.

mringwal commented 6 years ago

hid_host vs. hid_keyboard: looks like the logs are not from the same test. hid_host tries to connect once and the connection fails. hid_keyboard has one connect with a successful SDP query and then it looks like it gets a 'connection request' although there is no disconnect.

If your goal is to talk to the LE keyboard, you could try gatt_battery_query against it and check if you can read the battery value. Then, you'd need to find the HID Service and its services. After subscribing to the ORG_BLUETOOTH_CHARACTERISTIC_REPORT characteristic, you should get HID reports. You can then either use BTstack's minimal HID parser or just try to match the reports somehow.

theElementZero commented 6 years ago

If you comment the call to gap_disconnect in line 221, it should stay connected.

i did this test you can find a log below host with HOG_Mouse Host with HOG Keyboard

i didnt find any difference, however i tried to directly read value as you can see in code below

//printf("\nConfigure battery level characteristic for notify.\n");
//status = gatt_client_write_client_characteristic_configuration(handle_gatt_client_event, //connection_handle, &config_characteristic, //GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION);
// if (status != 0){
     printf("\nNotification not supported. Query value of characteristic.\n");
      gatt_client_read_value_of_characteristic(handle_gatt_client_event, connection_handle, &config_characteristic);
     // }

below is output log from this experiment, i got the battery value Host with HOG MOuse

You can see Battery Value 91 is read

i read in HOGP document it is mandatory to support battery service, but i dont understand the problem to read/subcribe NOTIFY. Do i need to change HOG_KEYBOARD/MOUSE_DEMO file ?

theElementZero commented 6 years ago

hid_host vs. hid_keyboard: looks like the logs are not from the same test. hid_host tries to connect once and the connection fails. hid_keyboard has one connect with a successful SDP query and then it looks like it gets a 'connection request' although there is no disconnect.

i am sure log is from same as i have got same log over and over again, if you have time you may check at your end.

theElementZero commented 6 years ago

If your goal is to talk to the LE keyboard, you could try gatt_battery_query against it and check if you can read the battery value. Then, you'd need to find the HID Service and its services. After subscribing to the ORG_BLUETOOTH_CHARACTERISTIC_REPORT characteristic, you should get HID reports. You can then either use BTstack's minimal HID parser or just try to match the reports somehow.

Yes thats what i am trying to achieve but somehow stuck in battery service NOTIFY. i think this is not done by before i have found very less support or data on HID HOST in micro controller.

tharunjoy commented 5 years ago

Hi, Any update in the HID host demo??

mringwal commented 4 years ago

Hi. Checkt out example/hog_boot_host_demo on the develop branch.