Pushing multiple HOG report ids at onse using att_server_multiple_notify()

76 views
Skip to first unread message

MatSOBDev

unread,
Jul 30, 2025, 1:51:40 PMJul 30
to btstack-dev
Hi!

HID again. Inside "hids.device.c" I've added:

uint8_t hids_device_send_input_report_for_id_new(hci_con_handle_t con_handle, uint8_t num_attributes,  uint16_t * attribute_handles, uint16_t * report_id, const uint8_t ** report, uint16_t * report_len){
    hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
    if (!instance){
        log_error("no instance for handle 0x%02x", con_handle);
        return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
    }

    uint8_t pos;
    hids_device_report_t * report_storage;
    for (pos = 0 ; pos < num_attributes ; pos++){
        report_storage = hids_device_get_report_for_id_and_type(instance, report_id[pos], HID_REPORT_TYPE_INPUT);
        if (report_storage == NULL){
            return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
        }
        attribute_handles[pos] = report_storage->value_handle;
    }
   
    return att_server_multiple_notify(con_handle, num_attributes, attribute_handles, report, report_len);
}

with user code of:

uint8_t  keyb_data[8] = {0, 0, 0x17, 0x08, 0x16, 0x17, 0x0C, 0x11};
 uint8_t  cons_data[1] = {0xEA};
 uint8_t  keyb_data_epty[8] = {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 uint8_t  cons_data_epty[1] = {0x00};
 uint16_t lgth_data[2] = {8, 1};
 uint16_t rpid_data[2] = {0x01, 0x04};
 const uint8_t *data_together[2] = {keyb_data, cons_data};
 const uint8_t *data_together_epty[2] = {keyb_data_epty, cons_data_epty};
 uint16_t attribute_handles[2];
     
 while(true) {
  hids_device_send_input_report_for_id(con_handle, 0x04, (uint8_t []){0xEA}, 1);
  sleep_ms(30);
  hids_device_send_input_report_for_id(con_handle, 0x04, (uint8_t []){0x00}, 1);
  sleep_ms(1000);
 
  hids_device_send_input_report_for_id(con_handle, 0x01, (uint8_t []){0, 0, 0x17, 0x08, 0x16, 0x17, 0x0C, 0x0A}, 8);
  sleep_ms(30);
  hids_device_send_input_report_for_id(con_handle, 0x01, (uint8_t []){0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 8);
  sleep_ms(1000);
 
  result = hids_device_send_input_report_for_id_new(con_handle, 2, attribute_handles, rpid_data, data_together, lgth_data);
  printf("Result: %d\r\n", result);
  sleep_ms(30);
  result = hids_device_send_input_report_for_id_new(con_handle, 2, attribute_handles, rpid_data, data_together_epty, lgth_data);
  printf("Result_epty: %d\r\n", result);
  sleep_ms(1000);
 }

to access it. hids_device_send_input_report_for_id() functions works fine as expected, but my hids_device_send_input_report_for_id_new() is not. It returns with "0" data are sen, but it doesn't trigger any key presses. Tested alone as well, without hids_device_send_input_report_for_id(). Here's a log: http://hostuje.net/file.php?id=6059f5d3663d55cb4aa3c06a6cc58923. What I do wrong?

MatSOBDev

unread,
Jul 31, 2025, 1:21:04 PMJul 31
to btstack-dev
My Wireshark version showed ATT_MULTIPLE_HANDLE_VALUE_NTF = 0x23 as "Unknown". Checking with https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/attribute-protocol--att-.html it looks like it is composed the right way: 2 bytes for handle, 2 bytes of length and length bytes of data. Seems like it is just unsupported by my phone: Bluetooth 4.2 (which is version when ATT_MULTIPLE_HANDLE_VALUE_NTF started to be supported, but "computer says no" anyway :D).

MatSOBDev

unread,
Jul 31, 2025, 2:00:39 PMJul 31
to btstack-dev
Actually, it shows up only starting from 5.2 core spec.

Matthias Ringwald

unread,
Aug 1, 2025, 11:32:54 AMAug 1
to btsta...@googlegroups.com
Hi

You're right about ATT_MULTIPLE_HANDLE_VALUE_NTF getting supported only in Bluetooth Core v5.1. More importantly, a GATT Server can only use it if the remote GATT Client has indicated support for it by writing to the GATT Client Supported Features Characteristic.

A minor detail: BTstack is single-threaded, so nothing will happen if you call sleep_ms(...). You can not send multiple messages in a row. Instead, you'll need a small statemachine and use the appropriate "request to send function,
in this case att_server_request_to_send_notification(), to get a callback which then can send one message. (It may work in some configurations, e.g. libusb, but that's more by accident and nothing to build upon)

Cheers
Matthias
> --
> You received this message because you are subscribed to the Google Groups "btstack-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to btstack-dev...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/btstack-dev/b924dbde-3df2-4711-8a59-39aa18652608n%40googlegroups.com.


MatSOBDev

unread,
Aug 1, 2025, 4:06:25 PMAug 1
to btstack-dev
Thanks for clarification. Trying on Ubuntu 20.04, ATT responds with unsupported as it should. Will try on 25.04, that supports 5.2 and partially 5.3 if I'm correct. But one more thing, don't know it it is an issue, or work in progress. Before realizing, it is Bluetooth version to low, I was poking BTstack with ENABLE_GATT_OVER_EATT (and mandatory ENABLE_L2CAP_ENHANCED_CREDIT_BASED_FLOW_CONTROL_MODE) and getting:

/mateush/pico-sdk-2.2.0/lib/btstack/src/l2cap.c.o: in function `l2cap_ecbm_signaling_handler_dispatch':
/home/mateush/pico-sdk-2.2.0/lib/btstack/src/l2cap.c:4100:(.text.l2cap_acl_handler+0x105e): undefined reference to `gap_get_bondable_mode'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.


It was yesterdays develop.

Matthias Ringwald

unread,
Aug 2, 2025, 9:42:51 AMAug 2
to btsta...@googlegroups.com
Hi

Thanks for the reporting the build error. Please share your complete btstack_config.h as it didn't built for you as you have ENABLE_CLASSIC disabled.
I've fixed it on develop.

Chers
Matthias
> To view this discussion visit https://groups.google.com/d/msgid/btstack-dev/cae4954e-ea7e-4b35-8f15-f5b41d694766n%40googlegroups.com.

MatSOBDev

unread,
Aug 2, 2025, 11:57:44 AMAug 2
to btstack-dev
Good afternoon!

It is from the latest pico-examples:

#ifndef _PICO_BTSTACK_BTSTA#ifndef _PICO_BTSTACK_BTSTACK_CONFIG_H
#define _PICO_BTSTACK_BTSTACK_CONFIG_H

// BTstack features that can be enabled
#define ENABLE_LOG_INFO
#define ENABLE_LOG_ERROR
#define ENABLE_PRINTF_HEXDUMP
#define ENABLE_SCO_OVER_HCI
//#define WANT_HCI_DUMP 1

#ifdef ENABLE_BLE
#define ENABLE_GATT_CLIENT_PAIRING
#define ENABLE_L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE
#define ENABLE_LE_CENTRAL
#define ENABLE_LE_DATA_LENGTH_EXTENSION
#define ENABLE_LE_PERIPHERAL
#define ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_GATT_OVER_EATT
#define ENABLE_L2CAP_ENHANCED_CREDIT_BASED_FLOW_CONTROL_MODE
#endif

#ifdef ENABLE_CLASSIC
#define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE
#define ENABLE_GOEP_L2CAP
#endif

#if defined (ENABLE_CLASSIC) && defined(ENABLE_BLE)
#define ENABLE_CROSS_TRANSPORT_KEY_DERIVATION
#endif

// BTstack configuration. buffers, sizes, ...
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4
#define HCI_ACL_PAYLOAD_SIZE (1691 + 4)
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4
#define MAX_NR_AVDTP_CONNECTIONS 1
#define MAX_NR_AVDTP_STREAM_ENDPOINTS 1
#define MAX_NR_AVRCP_CONNECTIONS 2
#define MAX_NR_BNEP_CHANNELS 1
#define MAX_NR_BNEP_SERVICES 1
#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES  2
#define MAX_NR_GATT_CLIENTS 1
#define MAX_NR_HCI_CONNECTIONS 2
#define MAX_NR_HID_HOST_CONNECTIONS 1
#define MAX_NR_HIDS_CLIENTS 1
#define MAX_NR_HFP_CONNECTIONS 1
#define MAX_NR_L2CAP_CHANNELS  4
#define MAX_NR_L2CAP_SERVICES  3
#define MAX_NR_RFCOMM_CHANNELS 1
#define MAX_NR_RFCOMM_MULTIPLEXERS 1
#define MAX_NR_RFCOMM_SERVICES 1
#define MAX_NR_SERVICE_RECORD_ITEMS 4
#define MAX_NR_SM_LOOKUP_ENTRIES 3
#define MAX_NR_WHITELIST_ENTRIES 16
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16

// Limit number of ACL/SCO Buffer to use by stack to avoid cyw43 shared bus overrun
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3
#define MAX_NR_CONTROLLER_SCO_PACKETS 3

// Enable and configure HCI Controller to Host Flow Control to avoid cyw43 shared bus overrun
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL
#define HCI_HOST_ACL_PACKET_LEN 1024
#define HCI_HOST_ACL_PACKET_NUM 3
#define HCI_HOST_SCO_PACKET_LEN 120
#define HCI_HOST_SCO_PACKET_NUM 3

// Link Key DB and LE Device DB using TLV on top of Flash Sector interface
#define NVM_NUM_DEVICE_DB_ENTRIES 16
#define NVM_NUM_LINK_KEYS 16

// We don't give btstack a malloc, so use a fixed-size ATT DB.
#define MAX_ATT_DB_SIZE 512

// BTstack HAL configuration
#define HAVE_EMBEDDED_TIME_MS

// map btstack_assert onto Pico SDK assert()
#define HAVE_ASSERT

// Some USB dongles take longer to respond to HCI reset (e.g. BCM20702A).
#define HCI_RESET_RESEND_TIMEOUT_MS 1000

#define ENABLE_SOFTWARE_AES128
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS

#define HAVE_BTSTACK_STDIN

// To get the audio demos working even with HCI dump at 115200, this truncates long ACL packets
//#define HCI_DUMP_STDOUT_MAX_SIZE_ACL 100

#endif // _PICO_BTSTACK_BTSTACK_CONFIG_HCK_CONFIG_H
#define _PICO_BTSTACK_BTSTACK_CONFIG_H

// BTstack features that can be enabled
#define ENABLE_LOG_INFO
#define ENABLE_LOG_ERROR
#define ENABLE_PRINTF_HEXDUMP
#define ENABLE_SCO_OVER_HCI
//#define WANT_HCI_DUMP 1

#ifdef ENABLE_BLE
#define ENABLE_GATT_CLIENT_PAIRING
#define ENABLE_L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE
#define ENABLE_LE_CENTRAL
#define ENABLE_LE_DATA_LENGTH_EXTENSION
#define ENABLE_LE_PERIPHERAL
#define ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION
#define ENABLE_LE_SECURE_CONNECTIONS
#define ENABLE_GATT_OVER_EATT
#define ENABLE_L2CAP_ENHANCED_CREDIT_BASED_FLOW_CONTROL_MODE
#endif

#ifdef ENABLE_CLASSIC
#define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE
#define ENABLE_GOEP_L2CAP
#endif

#if defined (ENABLE_CLASSIC) && defined(ENABLE_BLE)
#define ENABLE_CROSS_TRANSPORT_KEY_DERIVATION
#endif

// BTstack configuration. buffers, sizes, ...
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4
#define HCI_ACL_PAYLOAD_SIZE (1691 + 4)
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4
#define MAX_NR_AVDTP_CONNECTIONS 1
#define MAX_NR_AVDTP_STREAM_ENDPOINTS 1
#define MAX_NR_AVRCP_CONNECTIONS 2
#define MAX_NR_BNEP_CHANNELS 1
#define MAX_NR_BNEP_SERVICES 1
#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES  2
#define MAX_NR_GATT_CLIENTS 1
#define MAX_NR_HCI_CONNECTIONS 2
#define MAX_NR_HID_HOST_CONNECTIONS 1
#define MAX_NR_HIDS_CLIENTS 1
#define MAX_NR_HFP_CONNECTIONS 1
#define MAX_NR_L2CAP_CHANNELS  4
#define MAX_NR_L2CAP_SERVICES  3
#define MAX_NR_RFCOMM_CHANNELS 1
#define MAX_NR_RFCOMM_MULTIPLEXERS 1
#define MAX_NR_RFCOMM_SERVICES 1
#define MAX_NR_SERVICE_RECORD_ITEMS 4
#define MAX_NR_SM_LOOKUP_ENTRIES 3
#define MAX_NR_WHITELIST_ENTRIES 16
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16

// Limit number of ACL/SCO Buffer to use by stack to avoid cyw43 shared bus overrun
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3
#define MAX_NR_CONTROLLER_SCO_PACKETS 3

// Enable and configure HCI Controller to Host Flow Control to avoid cyw43 shared bus overrun
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL
#define HCI_HOST_ACL_PACKET_LEN 1024
#define HCI_HOST_ACL_PACKET_NUM 3
#define HCI_HOST_SCO_PACKET_LEN 120
#define HCI_HOST_SCO_PACKET_NUM 3

// Link Key DB and LE Device DB using TLV on top of Flash Sector interface
#define NVM_NUM_DEVICE_DB_ENTRIES 16
#define NVM_NUM_LINK_KEYS 16

// We don't give btstack a malloc, so use a fixed-size ATT DB.
#define MAX_ATT_DB_SIZE 512

// BTstack HAL configuration
#define HAVE_EMBEDDED_TIME_MS

// map btstack_assert onto Pico SDK assert()
#define HAVE_ASSERT

// Some USB dongles take longer to respond to HCI reset (e.g. BCM20702A).
#define HCI_RESET_RESEND_TIMEOUT_MS 1000

#define ENABLE_SOFTWARE_AES128
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS

#define HAVE_BTSTACK_STDIN

// To get the audio demos working even with HCI dump at 115200, this truncates long ACL packets
//#define HCI_DUMP_STDOUT_MAX_SIZE_ACL 100

#endif // _PICO_BTSTACK_BTSTACK_CONFIG_H

And yes, I had only pico_btstack_ble, and required pico_btstack_classic (setting ENABLE_CLASSIC) before, but now it only require pico_btstack_ble as advertised in the commit. Tested on Ubuntu 25.04 as well and it works as expected. Maybe it would be a good idea to provide hids_device_send_multiple_input_reports_for_ids?

MatSOBDev

unread,
Aug 2, 2025, 11:59:20 AMAug 2
to btstack-dev
Mostly from pico-examples, apart:

WANT_HCI_DUMP
ENABLE_GATT_OVER_EATT
ENABLE_L2CAP_ENHANCED_CREDIT_BASED_FLOW_CONTROL_MODE
Reply all
Reply to author
Forward
0 new messages