BLE HID Keyboard (HOGP) with different Report ID

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

I use the example, BLE HID Keyboard from PSoc Creator 3.3.   I need to modify the example code in order to send the key with different Report ID.   Does anyone know the way or an API that I can specify the report ID?

   

Thanks,

   

Paul.

0 Likes
1 Solution
Anonymous
Not applicable

You would have to change multiple values I suspect to dynamically switch between the two report profiles, and possibly the structure of the bluetooth profile/service(s).

   

This document: http://cdn.sparkfun.com/datasheets/Wireless/Bluetooth/RN-HID-User-Guide-v1.0r.pdf

   

contains information on how to implement the consumer keys for Bluetooth; I assume it should be a conversion between the HID keyboard and this. You might need to have the keyboard and consumer keys setup as two different services rather than trying to dynamically reuse the same service for both.

View solution in original post

0 Likes
27 Replies
Anonymous
Not applicable

You should be able to modify the report ID within the BLE profile within the BLE Component in the TopDesign file. (Double-click the BLE component to access its settings).

0 Likes
Anonymous
Not applicable

I have two set of keys, and each set with different report id.  So how do I change the report id dynamically before sending the key?

0 Likes
Anonymous
Not applicable

Since the HID over BLE uses the standard BLE characteristics to store the data for the Report IDs, it should be a simple Cyble_GattsWriteCharacteristicValue() (or something similar iirc). Basically, write the value as if it is a normal bluetooth characteristic before sending it. So, depending on what key you want to use, write that key to the gatt db, then send the reports/data.

0 Likes
Anonymous
Not applicable

the two set keys: BLE HID consumer keys (Report ID: 0x03)  and BLE HID Keyboard (Report ID: 0x02).  The existing keyboard example works for BLE HID keyboard, but not HID consumer keys.  Please advise. Thanks.

0 Likes
Anonymous
Not applicable

I find there is a method from the generated source code:

   

CYBLE_API_RESULT_T CyBle_HidssSetCharacteristicValue(uint8 serviceIndex, CYBLE_HIDS_CHAR_INDEX_T charIndex,  uint8 attrSize, uint8 *attrValue)

   

Is it you mentioned?  Did you have an example to use it to change the report id?

   

Thanks.

0 Likes
Anonymous
Not applicable

You would have to change multiple values I suspect to dynamically switch between the two report profiles, and possibly the structure of the bluetooth profile/service(s).

   

This document: http://cdn.sparkfun.com/datasheets/Wireless/Bluetooth/RN-HID-User-Guide-v1.0r.pdf

   

contains information on how to implement the consumer keys for Bluetooth; I assume it should be a conversion between the HID keyboard and this. You might need to have the keyboard and consumer keys setup as two different services rather than trying to dynamically reuse the same service for both.

0 Likes
Anonymous
Not applicable

I set up 2 HID Services (one for keyboard and one for mouse) by simply loading up .xml files of HID services (mouse and keyboard) from the HID projects of Cypress. Is it necessary to have the Report IDs for both services even though they are totally separate?

0 Likes
Anonymous
Not applicable

I haven't dug too deep into USB, but I believe the Report IDs are needed to separate data and to define which device you are using.

Depending on the receiving HID-over-BLE implementation, it might trigger on the report IDs instead of the services; Realistically, the BLE devices should be written to gracefully handle both, but that isn't always (usually?) the case.

I would suggest trying it with/without both and seeing if there is a difference in behavior, or going with the simpler option to save on space/complexity/data-transmission.

Here is a good tutorial on implementing HID with multiple devices: Tutorial about USB HID Report Descriptors | Eleccelerator

Anonymous
Not applicable

Thanks, e.pratt_1639216​. I'll definitely give your suggestion a try and see what works best.

0 Likes
Anonymous
Not applicable

How to set up with two different services?  Is there an example?

   

Another question, is there an example to implement ONE HID Descriptor (Report Map) containing two usages, and each usage includes one collection with the report ID?

   

HID Descriptor

   

    0x05, 0x01,                         // USAGE_PAGE (Generic Desktop)

   

    0x09, 0x06,                         // USAGE (Keyboard)

   

    0xA1, 0x01,                         // COLLECTION (Application)

   

    0x85, 0x05,                         //    REPORT_ID

   

    0x75, 0x01,                         //    REPORT_SIZE (1)

   

    0x95, 0x08,                         //    REPORT_COUNT (8)

   

    0x05, 0x07,                         //    USAGE_PAGE (Keyboard

   

   ....

   

    0x05, 0x07,                         //    USAGE_PAGE (Keyboard)

   

    0x19, 0x00,                         //    USAGE_MINIMUM (Reserved (no event indicated))

   

    0x29, 0xFF,                         //    USAGE_MAXIMUM (Reserved (no event indicated))

   

    0x81, 0x00,                         //    INPUT

   

    0xC0,                               // END_COLLECTION

   

 

   

    // User-defined 0 report, USER_DEF0_REPORT_ID

   

    0x05, 0x0C,                         // USAGE_PAGE(CONSUMER_DEVICES)

   

    0x09, 0x01,                         // USAGE(REMOTE_CONTROL)

   

    0xA1, 0x01,                         // COLLECTION(Application)

   

    0x85, 0x06                           //      REPORT_ID

   

    0x95, 0x04,                         //      REPORT_COUNT(4)

   

    0x75, 0x10,                         //      REPORT_SIZE(16)

   

    0x15, 0x00,                         //      LOGICAL_MINIMUM(0)

   

   ...

   

    0x2A, 0xFF, 0x01,                //      USAGE_MAXIMUM(0x1FF)

   

    0x81, 0x00,                           //      INPUT

   

    0xC0,                               // END_COLLECTION

   

 

   

Thanks.

0 Likes
Anonymous
Not applicable

I have not seen an example HID setup for two separate services, but it should be as simple as mimicking the functionality of the current HID service in another service (e.g. HID2), but then change it to behave as the second HID function that you want to implement.

   

Sorry I don't have an example ready for multiple HID services on the same device, but I think you can definitely achieve your goal 🙂

   

This website should explain everything you need to know about HID data transmission to the PC: http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/

   

The only difference between an HID device plugged into a PC and a HID BLE device is the way the data reaches the PC, as the BLE part just transmits it between two BLE devices. The link I listed in the above paragraph should hold all the information you need to answer the question with some time and effort.

0 Likes
Anonymous
Not applicable

I only setup with one HID service.  In the report map, HID descriptor, (see below screen shot) as mentioned, it contains two sections with different report id defined. 

   

I use this call to send the key data; 

   

apiResult = CyBle_HidssSendNotification(cyBle_connHandle, CYBLE_HUMAN_INTERFACE_DEVICE_SERVICE_INDEX,
                        CYBLE_HUMAN_INTERFACE_DEVICE_REPORT_IN, KEYBOARD_DATA_SIZE, keyboard_data);

   

but I am not sure where I can set the report id along with this data sending.  Did you know how to set the report id for this?

   

Thanks.

   

   

0 Likes
Anonymous
Not applicable

   

I don't know how the CyBle_HidssSendNotification() function works, but all you need to do to add a Report ID is to click the plus symbol (circled with red) to add a collection, and then add the Report ID within the collection (plus an other data you want with it, like usage, etc.)

   

Using the plus icon you can add all of the various metadata for the HID device that you want to specify.

   

Then, using the notifications, you should be able to manipulate that data 🙂

   

I circled an example collection that I added at the bottom in blue.

   

0 Likes
Anonymous
Not applicable

Thanks e.pratt_1639216.  Could you guide me a bit of detail about "using the notifications, you should be able to manipulate that data"? 

0 Likes
Anonymous
Not applicable

Once you setup the BLE profile configuration for HID, then it will be stored on the GATT DB just like other bluetooth services/characteristics. Then, to send data to the remote device when connected, you just use GATTSNotification() to send data to the remote device (that is connected). You will also need to call CyBle_GattsReadAttributeValue() if you want the data to be saved on the local device (the one running the code).

   

The usage and operation should be the same as the original HID profile example that you started with. The only difference is that you are adding more BLE profile attributes to send to the computer.

0 Likes
Anonymous
Not applicable

Is the report ID (0x03)  in the part of the data?  I need to add explicitly.

   

such as HID data:   '0x03' '00' '00' '23' ....

0 Likes
Anonymous
Not applicable

I would think so, yes 🙂

   

But it might remain constant once you add it into the BLE component profile.

0 Likes
Anonymous
Not applicable

what is the purpose of Client Characteristic Configuration?

   

0 Likes
Anonymous
Not applicable

It allows you to enable/disable receiving asynchronous data from the BLE device (It's basically a flag setting to tell the device you don't want to receive asynchronous reports/data)

0 Likes
Anonymous
Not applicable

What is the report reference for?

   

   

0 Likes
Anonymous
Not applicable

I have no idea 🙂

0 Likes
Anonymous
Not applicable

Hello,

   

About Report ID, I have two input Report IDs (such as 0x01 and 0x03) defined in Report Map. 

   

How do I define both input Report IDs in Report In->Report Reference?

   

How do I change the report id in report reference before sending the next hid report from report host (cypress kit) to hid host (set-top)?

   

Thanks.

0 Likes
Anonymous
Not applicable

I would guess that the Report In->Report Reference is a single-report reference pointer, and thus should only point to one of them.

   

You can change it using a GattsWriteCharacteristic() (or similary named function, I don't recall the exact name...)

   

That will save it to the local database on the BLE device; If you are looking to send it over the wireless BLE, then you will probably want to call GATTSNotification() (or a similarly named function, I forget the exact name) 

   

Hope this helps,

   

E.Pratt

0 Likes
Anonymous
Not applicable

Hi E.Pratt,

   

I could not find the way to modify the report id in report reference field in run-time. 

   

It seems Cypress PSoC Creator 3.3 SDK only supports one static report id for HOGP Profile.

   

Did you know if there is a way to request cypress to make the change?

   

Thanks.

0 Likes
Anonymous
Not applicable

I am able to read the report id in report reference:

   

apiResult = CyBle_HidssGetCharacteristicDescriptor(CYBLE_HUMAN_INTERFACE_DEVICE_SERVICE_INDEX,
                   CYBLE_HIDS_REPORT, CYBLE_HIDS_REPORT_RRD, 2, (uint8 *)&rrdValue);
    if (apiResult == CYBLE_ERROR_OK)
    {
        uint8* v = (uint8 *)&rrdValue;
        printf("DEBUG> rrdValue=%d \r\n", v[0]);  //Report ID in Report Reference
    }

   

--

   

Even I can change the report id in the report reference in  cyBle_gatts[] (see below SetReportId), but still unable to send the notification carrying out the report reference changed. 

   

Here is what I change so far.  Again, it seems Cypress does not support to change report id in report reference in run-time.  Please advise.
 

   

static void SetReportId(uint8 id)
{
    CYBLE_API_RESULT_T apiResult;
    CYBLE_GATTS_ATT_GEN_VAL_LEN_T val1 = cyBle_attValuesLen[8]; //report reference
    char *v1 = val1.attGenericVal;
    v1[0] = id;
   
    apiResult = CyBle_GattsDbRegister(cyBle_gattDB, CYBLE_GATT_DB_INDEX_COUNT, CYBLE_GATT_DB_MAX_VALUE_LEN);
    if (apiResult != CYBLE_ERROR_OK)
    {
        printf("DEBUG> CyBle_GattsDbRegister Failed \r\n");
    }
}

0 Likes
Anonymous
Not applicable

I would try opening a case with cypress support to get help on switching between the two reports. They have more experience with HOGP than I do 🙂

   

Also, I'm not familiar with the CyBle_GattsDbRegister(cyBle_gattDB, CYBLE_GATT_DB_INDEX_COUNT, CYBLE_GATT_DB_MAX_VALUE_LEN); function.

   

For writing the report ID, I would assume that you would use: apiResult = CyBle_GattcWriteCharacteristicValue(connHandle, &writeReqParam); 

0 Likes
Renate
Level 3
Level 3
25 replies posted 25 sign-ins 10 replies posted

I know this is age old, but it doesn't answer anything.

To send HID reports with different report IDs:

In the profile make your Report Map with multiple reports, just like with USB HID report descriptors.

In the profile have multiple Report Ins, maybe called "Keyboard Report In" and "Consumer Report In".

In the profile make the Report References agree with the report IDs.

Do not add report IDs to your reports, unlike USB HID.

In your code, do something like this:

/* I'm sending report ID=1 */
res=CyBle_HidssSendNotification(cyBle_connHandle, CYBLE_HID_SERVICE_SERVICE_INDEX,                                         CYBLE_HID_SERVICE_KEYBOARD_REPORT_IN, size, report);

/* I'm sending report ID=2 */
res=CyBle_HidssSendNotification(cyBle_connHandle, CYBLE_HID_SERVICE_SERVICE_INDEX,                                         CYBLE_HID_SERVICE_CONSUMER_REPORT_IN, size, report);

(Your constants will probably have different names.)

 

0 Likes