This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Getting NRF_INVALID_PARAM when hid device is not keyboard nor mouse

SDK version: 5.1.0 S110 version: 6.0.0 chip: nRF51822

I am experimenting a generic Data transfer hid device, the report map is as follows:


 0x05, 0x0C, // Usage Page (Consumer devices),
 0x09, 0x00, // Usage (unassigned),
 0xa1, 0x02, // Collection (datalink),
 0x09, 0x00, //   Usage (unassigned),
 0x95, 0x40, //   report count 64
 0x75, 0x08, //   report size 8
 0x81, 0x00, //   input
 0x09, 0x00, //   Usage (unassigned)
 0x95, 0x40, //   report count 64
 0x75, 0x08, //   report size 8
 0x91, 0x00, //   output
 0xC0        // End Collection

And the hid service initialisation is very similar to keyboard example. When the following booleans are as follows:


    hids_init_obj.is_kb                          = false;
    hids_init_obj.is_mouse                       = false;

on connection a error will happen on


Thread [1] (Suspended: Signal 'SIGTRAP' received. Description: Trace/breakpoint trap.)	
	12 app_error_handler() main.c:111 0x0001474c	
	11 service_error_handler() hog_interf.c:42 0x000198d6	
	10 on_connect() ble_hids.c:88 0x0001ea6e	
	9 ble_hids_on_ble_evt() ble_hids.c:347 0x0001f01a	
	8 hog_interf_on_ble_evt() hog_interf.c:424 0x0001a490	
	7 ble_evt_dispatch() main.c:625 0x000151e8	
	6 intern_softdevice_events_execute() softdevice_handler.c:133 0x00023e1c	
	5 SWI2_IRQHandler() softdevice_handler.c:310 0x00023f92	
	4 <signal handler called>()  0xfffffff9	
	3 s110dev()  0x0000fe3e	
	2 s110dev()  0x0000016a	
	1 s110dev()  0x0000016a	

The error is returned from command sd_ble_gatts_value_set, where


p_hids->protocol_mode_handles.value_handle == 0

From the hids code it seems to me that if the device is not mouse nor keyboard the protocol mode value handle will not be initiated on hids_init because of protocol_mode_char_add will not be called.

What should I do to bypass the issue in a clean way?

  • Hi Peeter,

    The ble_hids library has a bug, where it will assert if is_kb && is_mouse == false. In file ble_hids.c, function on_connect, it will try to set protocol mode (for mice and keyboard), however the characteristic is not added (as you've already found out).

    This bug is reported internally and we are working on a fix. Proposed workaround: add is_kb and is_mouse to a static global inside the ble_hids library, and then do a check in function "on_connect":

    if (is_kb || is_mouse)
      err_code = sd_ble_gatts_value_set(...);
    

    Another note: I see that your usb descriptor is setup with a size of 64 byte. You will have issues with this descriptor. The maximum in BLE is 20 bytes from peripheral to central, and 22 bytes from central to peripheral.

    Best regards Håkon

  • Yes, I am struggling with the interface and maybe there is connection with 64 bytes... I need to port a USB device to use BLE... I will think something out.

    I have also faked this device to be mouse and in that case there is no assert. And I also tried to ignore the assert. With MasterControlPanel I can send and receive reports with few bytes independent of the mouse issue. Although with Linux bluez library I have issue sending output report. Input report arrives well. At the moment I have no clear understanding what can be wrong. Reducing the size to 20 bytes does not improve things.... I'll dig further.

  • At the moment it seems to me that on Linux, sending oversized output report (more than 22 bytes) will cause the bluetoothd not to send any more output reports (including reports with correct size) until the device is disconnected and reconnected.

  • Hi,

    I have same issue.  If I ignore the sd_ble_gatts_value_set(...) as you mention.  It will crash at ble_bondmngr_sys_attr_store(); 
    When can we expect this bug resolved ?
    

    Thanks

  • I found out to get HID generic working is to comment out this line :

    //if (p_hids_init->is_kb || p_hids_init->is_mouse)
    

    in the function ble_hids_init(...) of ble_hids.c line 1060. That was the missing parameter setting.

Related