This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Keyfob support iOS through HID Device (Volume Up control)

Other Parts Discussed in Thread: ASH, CC2541, CC2540

Dear TI, 

This is regarding HID control issue of Keyfob for iOS. I am using consumer control report map using only volume up  feature while key pressing. Its working well with Android but Its not supporting iOS (iPAD, iPhone...). The same code frame I am using to control the function of iOS through KeyFob as HID device. 

 

Issues are:

1. Volume up not supporting iOS (same is supported by Android).


2. Once I connect the HID device (keyfob) to iOS, Its connected well but when I press key to control its volume up, paired connection between Keyfob and iOS gets disconnected. (in fact, there is no code relation with key press and disconnection).


Please help to solve these issues. Urgent help needed.

Thanks a lot.

/Ash

  • Hi Ash,

    What is the iOS version used?

    Is any other Consumer Control HID reports sent properly?

    This should have worked normally.

    Regards,
    Arun
  • Dear Arun,
    I am using iOS version 7.0 (iPad) and 8.2 (iphone). Yes, CC reports are sent properly. Also I tested it on Android, working well.
    Hope to hear soon from you~Thanks & Regards
  • Have you seen any CC report send properly to IPhone from Keyfob apart from Volume Up/down? I have checked out the sending consumer control report to iPhone and it is working. Can you share more details like the reportMap used? Also, the key press handling & report creation should be done on task context and not on interrupt context(Should hand over to task context as soon as key is detected from interrupt context).

    Regards,
    Arun
  • Dear Arun,

    Thanks for your reply~

    well, I checked the same on Android, Its working well. Could you please lemme know, what would be the main cause of not working on iOS ?  I am sharing here the report map I used. Key pressing is treated as ProcessEvent_task.   While pressed, SendReport = TRUE and when released, SendReport = FALSE.

     

    Please help me to solve this issue asap. Thanks a lot.

     

    [0x05, 0x0C,                 // Usage Pg (Consumer Devices)

    0x09, 0x01,                  // Usage (Consumer Control)

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

    0x85, 0x03,                  // Report ID=3

    0x05, 0x0C,                    // Usage Page (Consumer Devices)

    0x15, 0x00,                    // Logical Min (0)

    0x25, 0x01,                   // Logical Max (1)

    0x75, 0x01,                  // Report Size (1)

    0x95, 0x01,                 // Report Count (1)

    0x09, 0xE9,                // Usage (Volume Up)

    0x81, 0x02,               // Input (Data, Var, Abs)

    0xC0                       //   End Collection

  • Hi,

    I see that you dont have any padded data to make your report map & report. 8 bits aligned. This can be problem. Can you pick up the report map from hidkbmservice.c and generate reports as done in HidAdvRemoteControl example and check? This report map is working for me on the iPad that I have tested.

    Regards,
    Arun
  • Also, your Report ID in report map and while generating reports should match.

    Regards,
    Arun
  • Dear Arun,Thanks for your reply~
    well, I am using the same and I disabled others except volume up control. Regarding aligning the map and report, hiow can I do that ? Please suggest.
    Mean while, I will check it again (report map from hidkbmservice.c). Could you please share the report map which you tested on ipad. I will take it as reference for comparison with mine.
    Thanks Regards,/Ash
  • Hi,

    This is the report map i have used

    // HID Report Map characteristic value
    // Keyboard report descriptor (using format for Boot interface descriptor)
    static CONST uint8 hidReportMap[] =
    {
    0x05, 0x01, // Usage Page (Generic Desktop)
    0x09, 0x02, // Usage (Mouse)
    0xA1, 0x01, // Collection (Application)
    0x85, 0x01, // Report Id (1)
    0x09, 0x01, // Usage (Pointer)
    0xA1, 0x00, // Collection (Physical)
    0x05, 0x09, // Usage Page (Buttons)
    0x19, 0x01, // Usage Minimum (01) - Button 1
    0x29, 0x03, // Usage Maximum (03) - Button 3
    0x15, 0x00, // Logical Minimum (0)
    0x25, 0x01, // Logical Maximum (1)
    0x75, 0x01, // Report Size (1)
    0x95, 0x03, // Report Count (3)
    0x81, 0x02, // Input (Data, Variable, Absolute) - Button states
    0x75, 0x05, // Report Size (5)
    0x95, 0x01, // Report Count (1)
    0x81, 0x01, // Input (Constant) - Padding or Reserved bits
    0x05, 0x01, // Usage Page (Generic Desktop)
    0x09, 0x30, // Usage (X)
    0x09, 0x31, // Usage (Y)
    0x09, 0x38, // Usage (Wheel)
    0x15, 0x81, // Logical Minimum (-127)
    0x25, 0x7F, // Logical Maximum (127)
    0x75, 0x08, // Report Size (8)
    0x95, 0x03, // Report Count (3)
    0x81, 0x06, // Input (Data, Variable, Relative) - X & Y coordinate
    0xC0, // End Collection
    0xC0, // End Collection

    0x05, 0x01, // Usage Pg (Generic Desktop)
    0x09, 0x06, // Usage (Keyboard)
    0xA1, 0x01, // Collection: (Application)
    0x85, 0x02, // Report ID (2)
    //
    0x05, 0x07, // Usage Pg (Key Codes)
    0x19, 0xE0, // Usage Min (224)
    0x29, 0xE7, // Usage Max (231)
    0x15, 0x00, // Log Min (0)
    0x25, 0x01, // Log Max (1)
    //
    // Modifier byte
    0x75, 0x01, // Report Size (1)
    0x95, 0x08, // Report Count (8)
    0x81, 0x02, // Input: (Data, Variable, Absolute)
    //
    // Reserved byte
    0x95, 0x01, // Report Count (1)
    0x75, 0x08, // Report Size (8)
    0x81, 0x01, // Input: (Constant)
    //
    // LED report
    0x95, 0x05, // Report Count (5)
    0x75, 0x01, // Report Size (1)
    0x05, 0x08, // Usage Pg (LEDs)
    0x19, 0x01, // Usage Min (1)
    0x29, 0x05, // Usage Max (5)
    0x91, 0x02, // Output: (Data, Variable, Absolute)
    //
    // LED report padding
    0x95, 0x01, // Report Count (1)
    0x75, 0x03, // Report Size (3)
    0x91, 0x01, // Output: (Constant)
    //
    // Key arrays (6 bytes)
    0x95, 0x06, // Report Count (6)
    0x75, 0x08, // Report Size (8)
    0x15, 0x00, // Log Min (0)
    0x25, 0x65, // Log Max (101)
    0x05, 0x07, // Usage Pg (Key Codes)
    0x19, 0x00, // Usage Min (0)
    0x29, 0x65, // Usage Max (101)
    0x81, 0x00, // Input: (Data, Array)
    //
    0xC0, // End Collection
    //
    0x05, 0x0C, // Usage Pg (Consumer Devices)
    0x09, 0x01, // Usage (Consumer Control)
    0xA1, 0x01, // Collection (Application)
    0x85, 0x03, // Report Id (3)
    0x09, 0x02, // Usage (Numeric Key Pad)
    0xA1, 0x02, // Collection (Logical)
    0x05, 0x09, // Usage Pg (Button)
    0x19, 0x01, // Usage Min (Button 1)
    0x29, 0x0A, // Usage Max (Button 10)
    0x15, 0x01, // Logical Min (1)
    0x25, 0x0A, // Logical Max (10)
    0x75, 0x04, // Report Size (4)
    0x95, 0x01, // Report Count (1)
    0x81, 0x00, // Input (Data, Ary, Abs)
    0xC0, // End Collection
    0x05, 0x0C, // Usage Pg (Consumer Devices)
    0x09, 0x86, // Usage (Channel)
    0x15, 0xFF, // Logical Min (-1)
    0x25, 0x01, // Logical Max (1)
    0x75, 0x02, // Report Size (2)
    0x95, 0x01, // Report Count (1)
    0x81, 0x46, // Input (Data, Var, Rel, Null)
    0x09, 0xE9, // Usage (Volume Up)
    0x09, 0xEA, // Usage (Volume Down)
    0x15, 0x00, // Logical Min (0)
    0x75, 0x01, // Report Size (1)
    0x95, 0x02, // Report Count (2)
    0x81, 0x02, // Input (Data, Var, Abs)
    0x09, 0xE2, // Usage (Mute)
    0x09, 0x30, // Usage (Power)
    0x09, 0x32, // Usage (Sleep)
    0x09, 0xB4, // Usage (Rewind)
    0x09, 0xB0, // Usage (Play)
    0x09, 0xB1, // Usage (Pause)
    0x09, 0xB3, // Usage (Fast Forward)
    0x09, 0xB5, // Usage (Scan Next)
    0x09, 0xB6, // Usage (Scan Prev)
    0x09, 0xB7, // Usage (Stop)
    0x15, 0x01, // Logical Min (1)
    0x25, 0x0C, // Logical Max (10)
    0x75, 0x04, // Report Size (4)
    0x95, 0x01, // Report Count (1)
    0x81, 0x00, // Input (Data, Ary, Abs)
    // Sel usages 1
    0x0a, 0x00, 0x02, // USAGE (Generating GUI Application Buttons)
    0xa1, 0x02, // COLLECTION (Logical)
    0x15, 0x01, // LOGICAL_MINIMUM (1)
    0x25, 0x03, // LOGICAL_MAXIMUM (2)
    0x75, 0x02, // REPORT_SIZE (2)
    0x95, 0x01, // REPORT_COUNT (1)
    0x0a, 0x21, 0x02, // USAGE (AC Search) - index 1
    0x0a, 0x23, 0x02, // USAGE (AC Home) - index 2
    0x81, 0x00, // INPUT (Data,Ary,Abs) - index 0 means none of above is selected
    0xc0, // END_COLLECTION
    0xC0 // End Collection
    };


    The reports are generated as follows

    /*********************************************************************
    * @fn HidKeyBoardMediaSendReport
    *
    * @brief Build and send a HID Consumer report.
    *
    * @param keycode - key pressed on Keyboard( Depends upon keyboard layout)
    *
    * @return none
    */
    static void HidKeyBoardMediaSendReport( uint8 keycode )
    {
    uint8_t buf[HID_CC_IN_RPT_LEN] = {0, 0};
    switch(keycode) {

    case HID_KEYBOARD_F1: //mute
    buf[1] = 0x01;
    break;
    case HID_KEYBOARD_F2: //vol down
    buf[0] = 0x80;
    break;
    case HID_KEYBOARD_F3: //vol up
    buf[0] = 0x40;
    break;
    case HID_KEYBOARD_F4: //Scan Prev
    buf[1] = 0x09;
    break;
    case HID_KEYBOARD_F5:
    {
    if(gKeyInfo.play == TRUE)
    {
    buf[1] = 0x06; //Pause
    gKeyInfo.play = FALSE;
    }
    else
    {
    buf[1] = 0x05; //Play
    gKeyInfo.play = TRUE;
    }
    }
    break;
    case HID_KEYBOARD_F6: //Scan Next
    buf[1] = 0x08;
    break;
    case HID_KEYBOARD_F7: //AC Search
    buf[1] = 0x10;
    break;
    case HID_KEYBOARD_F8: //AC Home
    buf[1] = 0x20;
    break;
    case HID_KEYBOARD_F9: //Record
    buf[1] = 0x0A;
    break;
    case HID_KEYBOARD_F10: //Record
    buf[1] = 0x0A;
    break;
    case HID_KEYBOARD_F11: //Sleep
    buf[1] = 0x03;
    break;
    case HID_KEYBOARD_F12: //Power
    buf[1] = 0x02;
    break;
    default:
    buf[0] = 0x00;
    break;
    }

    HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );
    }

    where HID_RPT_ID_CC_IN value is 3 and HID_CC_IN_RPT_LEN value is 2 Bytes.

    Regards,
    Arun
  • Dear Arun,
    Thanks for sharing the report map. I am using the same , with only using the Volume UP consumer control, So comment out others. Is that Ok Or What should I need to change to only use volume UP control ? I am sending the modification..... As I am using keyfFob device to check its functionality, I am using "HIDEmukbd" example and using the CC report map same like mentioned in HIDAdvRemote. I only need to use VolumeUP control.
    Please check it.
    --------------------------------------------------------------------------------------------------------------------------------------------------
    0x05, 0x0C, // Usage Pg (Consumer Devices)
    0x09, 0x01, // Usage (Consumer Control)
    0xA1, 0x01, // Collection (Application) 0x85, 0x03, // Report Id (3)
    0x95, 0x01, // Report Count (2)0x75, 0x01, // Report Size (2)
    0x09, 0xE9, // Usage (Volume Up)0x15, 0x00, // Logical Min (0)
    0x25, 0x01, // Logical Max (1)0x81, 0x02, // Input (Data, Var, Abs)//Padding
    0x95, 0x01, // Report Count (1) 0x75, 0x03, // Report Size (3)
    ..................................................................................................................................................................
    Thanks n Regards,/Ash
  • Hi Ash,

    The report Map should be 1 byte aligned. So even if you are using only Volume Up, it is advised to add padding bits to report map to make it 1 byte aligned. Your current report is only 1 bit in size which can cause wired behaviour sometimes. I would urge you to use my report map & report format as it is to check and then slowly remove the un-wanted elements in it.

    Also, your report should be of the same size as your report Map. So if you are using a 1 bit report map, then the report also should send only 1 bit information. But normally at least 1 byte will be send instead of 1 bit.

    Also, you need to send key release after very valid report is send so that the Host knows the volume Up key has been released by user.

    Regards,
    Arun
  • Dear Arun,
    I followed your report map, but its not working on iOS in my case. May Be I am wrong at some point, so plz correct me. I am using the report map which you shared and here is my "hidEmuKbdSendReport". Please check n correct me....
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    static void hidEMuKbdSendReport( bool bKeyPressed ){
    uint8 buf[HID_CC_IN_RPT_LEN] = {0, 0};if ( bKeyPressed ) {
    HID_CC_RPT_SET_VOLUME_UP( buf ); buf[0] = 0x40; }
    HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );
    }#endif
    --------------------------------------------------------------------------------------------------------------------------------------
    Thanks n Regards
  • Hi Ash,

    Sorry for the delay in replying. Yes. You can use the same report map as you described. Just check whether the report ID set in Report Map and Report(HID_RPT_ID_CC_IN) is same.

    I don't understand why this doesn't work on your side, while its working on my side.

    Regards,
    Arun
  • Dear Arun,Thanks for your reply, I was waiting for it.
    well, I will check the report ID setting and let you know.
    Is the volume Up control in iOS deviceis through HID, properly working in your case? Could you please check it and confirm ?
    Thanks n Regards
  • Hi Ash,

    I did a quick test, and depending on the descriptor you sometimes need to include the report ID as a prefix in the report when communicating with iOS.

    I my test I build my reports consisting of 3 bytes as e.g:

     buf[0] = 0x01;
     buf[1] = HID_CONSUMER_PLAY_PAUSE;
     buf[2] = 0;        

    This worked for me using iOS 8.2.

    Regards,
    Johan

  • Dear Johan,Thanks for your reply~I tried this but Its not workingout on my Ipad.
    I want to control the volume up function of Ipad while pressing the Key. Could you please check this report map.
    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
    0x05, 0x0C, // Usage Pg (Consumer Devices)0x09, 0xE9, // Usage (Volume Up)
    0x15, 0x00, // Logical Min (0)0x25, 0x01, // Logical Max (1)
    0x75, 0x01, // Report Size (1)0x95, 0x01, // Report Count (1)
    0x85, 0x03, // Report ID (3) 0x81, 0x00, // Input (Data, Ary, Abs)
    0xC0 // End Collection
    --------------------------------------------------------------------------------------------------------------------------------
    while defining HID_CC_IN_RPT_LEN 3Please help.
    Thanks n Regards
  • Hi,

    I did a new descriptor that worked for me:

    0x05, 0x0C, // Usage Pg (Consumer Devices)
    0x09, 0xE9, // Usage (Volume Up)
    0xA1, 0x01, // (MAIN) COLLECTION
    0x85, 0x01, // Report ID (1)
    0x19, 0x00, // (LOCAL) USAGE_MINIMUM
    0x2A, 0x9C, 0x02, // (LOCAL) USAGE_MAXIMUM
    0x15, 0x00, // (GLOBAL) LOGICAL_MINIMUM
    0x26, 0x9C, 0x02, // (GLOBAL) LOGICAL_MAXIMUM
    0x75, 0x08, // Report Size (8)
    0x95, 0x01, // Report Count(1)
    0x81, 0x00, // Input (Data, Ary, Abs)
    0xC0 // End Collection

    Maybe you can do something like this.

    Reagrds,
    Johan
  • Dear Johan,Thanks for your reply n sharing the report descriptor~
    I tried this too as follows, still its not working with iOS, (ver 7.0). I have only iPad which has iOS version 7.0. Is this the version issue?
    0x05, 0x0C, // Usage Pg (Consumer Devices)0x09, 0xE9, // Usage (Volume Up)
    0xA1, 0x01, // (MAIN) COLLECTION0x85, 0x01, // Report ID (1)
    0x19, 0x00, // (LOCAL) USAGE_MINIMUM 0x2A, 0x9C, 0x02, // (LOCAL) USAGE_MAXIMUM
    0x15, 0x00, // (GLOBAL) LOGICAL_MINIMUM
    0x26, 0x9C, 0x02, // (GLOBAL) LOGICAL_MAXIMUM 0x75, 0x03, // Report Size (3)
    0x95, 0x01, // Report Count(1) 0x81, 0x00, // Input (Data, Ary, Abs)
    0xC0 // End CollectionWhile using the SendReport like.....
    [uint8 buf[HID_CC_IN_RPT_LEN] = { 0, 0, 0 };if ( KeyPressed ) { buf[0] = 0x01;
    buf[1] = HID_CC_RPT_VOLUME_UP; buf[2] = 0x00; }
    HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );]
    Please check n correct me.Thanks n Regards
  • Hi Ash,

    I doubt its a version issue as but we will try to check consumer control keys on iOS 7.0. What we have verified is on iOS 8.1.2 and iOS8.2 devices. Do you have any working keypad/keyboard with iPad? If so can you sniff the packets when the device connects and sends a consumer report. This way we can try to replicate the exact report descriptor map and report structure in the keyfob to check if there is anything wrong with our report map or report descriptor. 

    Regards,

    Arun

  • Dear Arun,
    Please confirm me after check whether it is version issue or not ?. At present, I dont have working keypad with iPad as I am just checking it through key pressing on KEYFOB. In fact, It should not be so complicated but I don't know why Its not responding.......
    Please help me to resolve this issue.Thanks n Regards
  • Dear Arun /Johan,Please help me to solve this issue.
    I'd be highly thankful to you all....Thanks n Regards
  • Dear Arun/Johan,
    As mentioned by Mr Johan, I followed the report descriptor which he shared and tried with iOS 7.0 device using Keyfob, Its well connected but Its not responding when I press the key from KEYFOB device for Volume UP control. Apart from this, when I tried with iOS 8.1 device, Its connected well, but when I press the key, its disconnected. Seems "KEY" is functioning like connect and disconnect the connection between [iOS 8.1 <---------> Keyfob].
    I couldnt figure out the cause of this behaviour. Please help me to resolve this issue.
    Thanks n Regards,
  • Dear Ash,

    We don't have an iOS7.0 device but I have checked the descriptors with iOS8.1.x devices(although with another TI chip). It baffles me as to why this happens. Can you share the sniffer logs when it connects to iOS8.1.x device?

    I have certain questions and suggestions

    Q1) Do you send a release immediately after the key press?
    Q2) Are you able to see the notification report send over the air(by sniffer)?

    Suggestion

    Try sending a HID report without actually pressing a key. For this you can use a timer with 5 seconds interval and send a volume up notification followed by a release in half a second. If this works, then this might be because CC2541 is taking to much time to process the key or due to shorter connection interval/slave latency/supervision time out.

    Regards,
    Arun
  • 20150326_IPad7.0_Keyfob_sniffer.psd20150326_IPhone8.1_Keyfob_sniffer.psdDear Arun,

    Thank you so much for reply~

    well,I checked the sniff data, while connected between iOS and Keyfob. The process is as follows...

    1. Keyfob ON (Start Advertising)

    2. Sniffering start....

    3. iOS well connected to KeyFOb

    4. Sniffering the packets in connected state

    5. Press the key, Nothing happens in case of iOS 7.0 (iPad), No response. Remain only in connected state.

    6. Same process repeated with iOS 8.1 (iPhone)

    7. well connected and sniff the packets.

    8. While pressing the key, connection gets disconnected. when Again press the key, connected again for 2 seconds and then again disconnected. Seens, Key is acting to conenct and disconnect the connection between two.

    Then why not the same behaviour in both the cases (7.0 and 8.1) ?

    Please make me understand about this and help to resolve the issue.  (Sniffed data attached herewith, please check)

    Thanks n Regards

  • Dear Arun,It seems that you are very busy. I am sorry to ping you again.
    Please let me know If you checked the sniffer results (attached in the last post) as you asked me to do. Please check and suggest me the solution.
    Help required. ThanksBest Regards/Ash
  • Hi,

    Sorry for the delay in replying. 

    I checked the sniffer logs shared by you. Looks like the sniffer has missed out on quite a number of packets as I cant see the report map being read and the report being sent. Looking at the ATT_Read_By_Type_Rsp, the Report Map Characteristic Declaration Handle(from UUID: 2A4B) and Report Map Characteristic Handle is 0x33 and 0x34.

    But I can find the Att Read Request or Response of Handle 0x34. This is required for the iOS device to understand the report map. Also I don't find the reports being sent as notification. 

    Can you check if its just that sniffer failed to capture these packets or its because the iOS device actually dint read the Handle to understand HID report map?

    Regards,

    Arun

  • Dear Arun,
    Thanks for your reply. well, Could you please make me understand in detail, How and where I can check this?
    ThanksRegards,
  • 20150330_Android(4.4.2)_Keyfob_sniffer.psd

    Dear Arun,

     

    I just had sniff shot while the device is connected with Android (4.4.2) and Its working well, key press (HID volume up control).  I am sharing this with you. Please have a look and guide me accordingly to resove the issue with iOS.

     

    Thanks n Regards/

  • Dear Ash,

    While looking at the Android Sniffed packets, I could see the notifications are being sent with byte 0 as 0x01 and byte 1 as 0x40. These notifications are not seen when connected to iOS device. It may be a sniffer issue or may be the notifications are not send at all.

    Can you try sniffing multiple times and check if you see any notifications being send to Master device from Slave. If not successful, can you use a CC debugger and check while in connection to iOS whether the Consumer Report Client Characteristic Configuration characterisitc is set to 01:00 or not?

    Regards,
    Arun
  • Hi Ash,

    Do you have TI keyfob or BLE remote control? I think you can test default project(HIDEmuKbd or HIDAdvRemote) first. please make sure you use default project(hiddev.c/peripheral.c). Maybe you will face same problem with iOS.
  • Dear Kimi,
    I am trying this using Keyfob device and HIDEmuKbd project. The main issue is with iOS. Did you test it with iOS? If you solved this, please share the solution.
    Thanks n Regards
  •  

     

    20150331_IPad7.0_Keyfob_sniffer.psd(KeyPress).psd20150331_IPad8.2_Keyfob_sniffer.psd(KeyPress).psd

    Dear Arun,

    I  did it again n again and found some different behaviour in case of different iOS versions. (dont know why?)

    I sniffed the packets while connected with...

    1. keyfob <-----> iOS7.0

    2. Keyfob <------> iOS 8.2

    It connected with the all devices well.

    1. When connected with iOS7.0 and key press, It shows only LL_Channel_Map_Req with some attributes. No Response (attached)

    2. When connected with iOS8.2 and key press, it disconnect immediately and sniffing stops. (attached)

    I am not getting understand why its showing two different behavior for different iOS versions.

    Please help.

    Thanks n Regards

  • Hi,

    I read in few forums that iOS7.0 doesnt have support for HID over GATT profile(HOGP). So you may be able to get the keyfob working on iOS7.0

    I checked your Log for iOS8.2

    I see that you have report map defined for Handle 0x34 but the report map is read from handle 0x31 which is confusing.

    Anyway, your report map looks like this

    0x05, 0x0C, // Usage Pg (Consumer Devices)

    0x09, 0x01, // Usage (Consumer Control)

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

    0x09, 0xE9, // Usage (Volume Up)

    0x15, 0x00, // Logical Min (0)

    0x25, 0x01, //   Logical Max (1)

    0x75, 0x01, // Report Size (1)

    0x85, 0x03,   // Report Id (3)

    0x95, 0x01, // Report Count (1)

    0x81, 0x02, // Input (Data, Variable, Absolute)

    0xC0,         //   End Collection

    Here why have you defined report ID at the bottom of the Report Map? Again the report map doesn't define the report size. Assuming a value of 1, its still a 1 bit report. You have align the report to 8 bits alt-east. Pad up with extra 7 bits to make it 8 bit aligned. 

    Also, you report that you are actually sending 3 bytes data. 0x01, 0x40, 0x00. This clearly is wrong as the report map is defined for only 1 bit.( 1 byte additional for report ID) .

    It works with android, because irrespective of any report you send the first byte is 0x01 which the Android system thinks Volume Up. So even when you send a reserve byte(release) it would be taken as volume up press. 

    I would suggest you use the report map in this format.

    0x05, 0x0C, // Usage Pg (Consumer Devices)
    0x09, 0x01, // Usage (Consumer Control)
    0xA1, 0x01, // Collection (Application)
    0x85, 0x01, // Report Id (1)
    0x09, 0xE9, // Usage (Volume Up)
    0x09, 0xEA, // Usage (Volume Down)
    0x15, 0x00, // Logical Min (0)
    0x75, 0x01, // Report Size (1)
    0x95, 0x02, // Report Count (2)
    0x81, 0x02, // Input (Data, Var, Abs)


    0x09, 0xE2, // Usage (Mute)
    0x09, 0x30, // Usage (Power)
    0x09, 0x32, // Usage (Sleep)
    0x09, 0xB4, // Usage (Rewind)
    0x09, 0xB0, // Usage (Play)
    0x09, 0xB1, // Usage (Pause)
    0x09, 0xB3, // Usage (Fast Forward)
    0x09, 0xB5, // Usage (Scan Next)
    0x09, 0xB6, // Usage (Scan Prev)
    0x09, 0xB7, // Usage (Stop)
    0x15, 0x01, // Logical Min (1)
    0x25, 0x0C, // Logical Max (10)
    0x75, 0x04, // Report Size (4)
    0x95, 0x01, // Report Count (1)
    0x81, 0x00, // Input (Data, Ary, Abs)

    // Reserved byte
    0x95, 0x01, // Report Count (1)
    0x75, 0x08, // Report Size (2)
    0x81, 0x01, // Input: (Constant)

    0xC0 // End Collection

    And use report format as follows.

    #define HID_CC_IN_RPT_LEN 2

    uint8_t buf[HID_CC_IN_RPT_LEN] = {0,0};

    buf[0] = 0x01; //Report ID

    buf[1] = 0x01; //Voume Up

    HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );

    Edit: can you send me your code so that I can review it here? 

    Regards,

    Arun

  • Dear Arun,

    Thanks a lot  for your reply.  I also went through that post where its mentioned that iOS 7 and lower versions doesnt support HOGP, but somewhere people also mentioned that they tried it on iOS7 as well,,,,,,,seems its confusing, iOS 7 support HID or not?

    Anyway, I used the report map what you shared, Thanks........but still facing the same issue.  I am sharing the report map and report format as follows......please check and suggest.

    ------------------------------------------------------------------Report Map--------------------------------------------------------------------------------------------------

    #define HID_CC_IN_RPT_LEN   2

    // HID Report Map characteristic value
    // Keyboard report descriptor (using format for Boot interface descriptor)
    static CONST uint8 hidReportMap[] =
    {
    0x05, 0x0C, // Usage Pg (Consumer Devices)
    0x09, 0x01, // Usage (Consumer Control)
    0xA1, 0x01, // Collection (Application)
    0x85, 0x01, // Report Id (1)
    0x09, 0xE9, // Usage (Volume Up)
    //0x09, 0xEA, // Usage (Volume Down)
    0x15, 0x00, // Logical Min (0)
    0x25, 0x01, // Logical Max (1)
    0x75, 0x01, // Report Size (1)
    0x95, 0x01, // Report Count (1)
    0x81, 0x02, // Input (Data, Var, Abs)

    0x09, 0xE2, // Usage (Mute)
    0x09, 0x30, // Usage (Power)
    0x09, 0x32, // Usage (Sleep)
    0x09, 0xB4, // Usage (Rewind)
    0x09, 0xB0, // Usage (Play)
    0x09, 0xB1, // Usage (Pause)
    0x09, 0xB3, // Usage (Fast Forward)
    0x09, 0xB5, // Usage (Scan Next)
    0x09, 0xB6, // Usage (Scan Prev)
    0x09, 0xB7, // Usage (Stop)
    0x15, 0x01, // Logical Min (1)
    0x25, 0x0C, // Logical Max (10)
    0x75, 0x04, // Report Size (4)
    0x95, 0x01, // Report Count (1)
    0x81, 0x00, // Input (Data, Ary, Abs)

    // Reserved byte
    0x95, 0x01, // Report Count (1)
    0x75, 0x08, // Report Size (2)
    0x81, 0x01, // Input: (Constant)

    0xC0 // End Collection
    };

    ---------------------------------------------------------------Key Pattern---------------------------------------------------------------------------

    static uint8 buf[HID_CC_IN_RPT_LEN] = { 0, 0 };

     (void)shift;  // Intentionally unreferenced parameter

    if ( (keys & HAL_KEY_SW_1) && (prevKey1 == 0) )
     {
      // pressed

      buf[0] = 0x01;  //vol up 
      buf[1] = 0x01;
     
      HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );

      hidCCSendReport( TRUE ); 
       prevKey1 = 1;
     }

     else if ( !(keys & HAL_KEY_SW_1) && (prevKey1 == 1) )
     {
      // released

      buf[0] = 0x00; 
      buf[1] = 0x00;
       HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );
      

     hidCCSendReport( FALSE ); 
     prevKey1 = 0;
     }

     ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Please check it and suggest me the required corrections if any......

    Thanks n Regards

     

  • Hi,

    Why are you sending hidCCSendReport again after HidDev_sendReport?

    Regards,
    Arun
  • Hi Ash,

    I don't have complete solution for your problem, but I find sonething very ininteresting. Maybe you can check it.

    1. power on your device, turn on bluetooth on your cell phone and connect(pairing) your device.
    2. let cell phone disconnect with deivce(make sure cell phone show "disconnect")
    3. let your device start advertising(in iOS7, device should reconnect to cell phone). In iOS8, you need click device item on your cell phone to reconnect
    4. when you reconnect, test your device function. I think it can work correctly
    5. when you re-pair or pair with new host, you need repeat step1~step3

    For step-3, please modify hiddev.c-->hidDevHighAdvertising()/hidDevLowAdvertising()
    from
    param = GAP_FILTER_POLICY_WHITE;
    to
    param = GAP_FILTER_GAP_FILTER_POLICY_ALL;
  • Dear Kimi,
    Thanks for your reply. But I have already tried this (some one posted about this method) but It didnt work out in my case.
    Thanks anyway, Please suggest.Regards,
  • Dear Arun,
    Before sending the report, I use "HidDev_Report" which defines the report type (format), report length and data. and then send the report using HID_CCSendReport (TRUE) when key is pressed.
    Please correct me if anythng going wrong.........Thanks n Regards
  • Dear Arun,
    Please check my report map and suggest the corrections to resolve this issue.
    Thanks n Regards
  • Hi,

    The report map I shared with you works fine for me when working with iPAd Mini (iOS8.2). Which iOS device are you using? iPhone 6? or iPad? Can you tell me the exact model so that if possible I can test on it.

    Also do send me the updated sniffer logs when you use my report map and report descriptor. 

    Another quick test you can do is send a volume up report without actually pressing the key. You can run a periodical timer which does this operation for you, so that any hardware interrupts don't cause the BLE connection to drop.

    Regards,

    Arun

  • Dear Arun,

    Thanks for your reply~

    1. I am using iPad 4(iOS8.1.3) and iPad mini (iOS7.0) and iPhone 6+ (iOS8.2). I tried on all,but not working.

    2. Updated sniffer logs (using yours Rm and Rd)~ Please check attached files.

    20150403_IPad8.1.3_Keyfob_sniffer.psd(KBPress).psd

    20150403_IPad8.1.3_Keyfob_sniffer.psd(KSPress).psd

     

    3. I used your report map and as I need to use key press while controlling the volume up key code, I send the report using [hidCCSendReport] where HID_CC_IN_RPT_LEn = 2 and  HID_RPT_ID_CC_IN set to 3.

    4. I am using Keyfob as HID device and pressing one of Its button (key) SW1.

    5. As a master device I am using iPad (iOS8.1.3), to connect with Keyfob HID device.

    6. Issue: Once connected with iPad and press the key, the connection disconnect. No response regarding volume up.

    7. Sniffer log is attached here with when connected with iPad 8.1.3 (Keyfob <------> iOS8.1.3)

    8. I didnt modify much the default code of HID (Keyfob), just modify according to KeyPress and Report map.

    ----------------------------------------------------------------------------Report Map Charac's Value-------------------------------------------------------------------------------------------------

    // HID Report Map characteristic value
    // Keyboard report descriptor (using format for Boot interface descriptor)
    static CONST uint8 hidReportMap[] =
    {

    0x05, 0x01, // Usage Page (Generic Desktop)
    0x09, 0x02, // Usage (Mouse)
    0xA1, 0x01, // Collection (Application)
    0x85, 0x01, // Report Id (1)
    0x09, 0x01, // Usage (Pointer)
    0xA1, 0x00, // Collection (Physical)
    0x05, 0x09, // Usage Page (Buttons)
    0x19, 0x01, // Usage Minimum (01) - Button 1
    0x29, 0x03, // Usage Maximum (03) - Button 3
    0x15, 0x00, // Logical Minimum (0)
    0x25, 0x01, // Logical Maximum (1)
    0x75, 0x01, // Report Size (1)
    0x95, 0x03, // Report Count (3)
    0x81, 0x02, // Input (Data, Variable, Absolute) - Button states
    0x75, 0x05, // Report Size (5)
    0x95, 0x01, // Report Count (1)
    0x81, 0x01, // Input (Constant) - Padding or Reserved bits
    0x05, 0x01, // Usage Page (Generic Desktop)
    0x09, 0x30, // Usage (X)
    0x09, 0x31, // Usage (Y)
    0x09, 0x38, // Usage (Wheel)
    0x15, 0x81, // Logical Minimum (-127)
    0x25, 0x7F, // Logical Maximum (127)
    0x75, 0x08, // Report Size (8)
    0x95, 0x03, // Report Count (3)
    0x81, 0x06, // Input (Data, Variable, Relative) - X & Y coordinate
    0xC0, // End Collection
    0xC0, // End Collection

    0x05, 0x01, // Usage Pg (Generic Desktop)
    0x09, 0x06, // Usage (Keyboard)
    0xA1, 0x01, // Collection: (Application)
    0x85, 0x02, // Report ID (2)
    //
    0x05, 0x07, // Usage Pg (Key Codes)
    0x19, 0xE0, // Usage Min (224)
    0x29, 0xE7, // Usage Max (231)
    0x15, 0x00, // Log Min (0)
    0x25, 0x01, // Log Max (1)
    //
    // Modifier byte
    0x75, 0x01, // Report Size (1)
    0x95, 0x08, // Report Count (8)
    0x81, 0x02, // Input: (Data, Variable, Absolute)
    //
    // Reserved byte
    0x95, 0x01, // Report Count (1)
    0x75, 0x08, // Report Size (8)
    0x81, 0x01, // Input: (Constant)
    //
    // LED report
    0x95, 0x05, // Report Count (5)
    0x75, 0x01, // Report Size (1)
    0x05, 0x08, // Usage Pg (LEDs)
    0x19, 0x01, // Usage Min (1)
    0x29, 0x05, // Usage Max (5)
    0x91, 0x02, // Output: (Data, Variable, Absolute)
    //
    // LED report padding
    0x95, 0x01, // Report Count (1)
    0x75, 0x03, // Report Size (3)
    0x91, 0x01, // Output: (Constant)
    //
    // Key arrays (6 bytes)
    0x95, 0x06, // Report Count (6)
    0x75, 0x08, // Report Size (8)
    0x15, 0x00, // Log Min (0)
    0x25, 0x65, // Log Max (101)
    0x05, 0x07, // Usage Pg (Key Codes)
    0x19, 0x00, // Usage Min (0)
    0x29, 0x65, // Usage Max (101)
    0x81, 0x00, // Input: (Data, Array)
    0xC0, // End Collection

    //
    0x05, 0x0C, // Usage Pg (Consumer Devices)
    0x09, 0x01, // Usage (Consumer Control)
    0xA1, 0x01, // Collection (Application)
    0x85, 0x03, // Report Id (3)
    0x09, 0x02, // Usage (Numeric Key Pad)
    0xA1, 0x02, // Collection (Logical)
    0x05, 0x09, // Usage Pg (Button)
    0x19, 0x01, // Usage Min (Button 1)
    0x29, 0x0A, // Usage Max (Button 10)
    0x15, 0x01, // Logical Min (1)
    0x25, 0x0A, // Logical Max (10)
    0x75, 0x04, // Report Size (4)
    0x95, 0x01, // Report Count (1)
    0x81, 0x00, // Input (Data, Ary, Abs)
    0xC0, // End Collection
    //#endif

    0x05, 0x0C, // Usage Pg (Consumer Devices)
    0x09, 0x86, // Usage (Channel)
    0x15, 0xFF, // Logical Min (-1)
    0x25, 0x01, // Logical Max (1)
    0x75, 0x02, // Report Size (2)
    0x95, 0x01, // Report Count (1)
    0x81, 0x46, // Input (Data, Var, Rel, Null)
    //0xC0,     // End Collection    // Ash20150330
    0x09, 0xE9, // Usage (Volume Up)
    0x09, 0xEA, // Usage (Volume Down)
    0x15, 0x00, // Logical Min (0)
    0x75, 0x01, // Report Size (1)
    0x95, 0x02, // Report Count (2)
    0x81, 0x02, // Input (Data, Var, Abs)
    0x09, 0xE2, // Usage (Mute)
    0x09, 0x30, // Usage (Power)
    0x09, 0x32, // Usage (Sleep)
    0x09, 0xB4, // Usage (Rewind)
    0x09, 0xB0, // Usage (Play)
    0x09, 0xB1, // Usage (Pause)
    0x09, 0xB3, // Usage (Fast Forward)
    0x09, 0xB5, // Usage (Scan Next)
    0x09, 0xB6, // Usage (Scan Prev)
    0x09, 0xB7, // Usage (Stop)
    0x15, 0x01, // Logical Min (1)
    0x25, 0x0C, // Logical Max (10)
    0x75, 0x04, // Report Size (4)
    0x95, 0x01, // Report Count (1)
    0x81, 0x00, // Input (Data, Ary, Abs)

    // Sel usages 1
    0x0a, 0x00, 0x02, // USAGE (Generating GUI Application Buttons)
    0xa1, 0x02, // COLLECTION (Logical)
    0x15, 0x01, // LOGICAL_MINIMUM (1)
    0x25, 0x03, // LOGICAL_MAXIMUM (2)
    0x75, 0x02, // REPORT_SIZE (2)
    0x95, 0x01, // REPORT_COUNT (1)
    0x0a, 0x21, 0x02, // USAGE (AC Search) - index 1
    0x0a, 0x23, 0x02, // USAGE (AC Home) - index 2
    0x81, 0x00, // INPUT (Data,Ary,Abs) - index 0 means none of above is selected
    0xc0, // END_COLLECTION
    0xC0 // End Collection
    #endif
    };

    -----------------------------------------------------------------------------------------hidEmuKbd_HandleKeys-------------------------------------------------------------------------------------------

    static uint8 hidBootMouseEnabled = FALSE;

    static void hidEmuKbd_HandleKeys( uint8 shift, uint8 keys )
    {
     static uint8 prevKey1 = 0;
     static uint8 prevKey2 = 0;
     static uint8 buf[HID_CC_IN_RPT_LEN] = { 0, 0 };

     (void)shift;  // Intentionally unreferenced parameter

      if ( (keys & HAL_KEY_SW_1) && (prevKey1 == 0) )
     {
      // pressed

      buf[0] = 0x01; 
      buf[1] = 0x01;
      HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );

      hidCCSendReport( TRUE );
      prevKey1 = 1;
     }

     else if ( !(keys & HAL_KEY_SW_1) && (prevKey1 == 1) )
     {
      // released

      buf[0] = 0x00;
      buf[1] = 0x00;
      HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );
      
      hidCCSendReport( FALSE );
      prevKey1 = 0;
     } 

      if ( (keys & HAL_KEY_SW_2) && (prevKey2 == 0) )
     {

      // pressed
      if ( !hidBootMouseEnabled )
      {
       hidEmuKbdSendReport( KEY_RIGHT_ARROW );
      }
      else
      {
       hidEmuKbdSendMouseReport( MOUSE_BUTTON_1 );
      }
     
      hidEmuKbdSendReport( KEY_RIGHT_ARROW );
      
      prevKey2 = 1;
     }
     
     else if ( !(keys & HAL_KEY_SW_2) && (prevKey2 == 1) )
     
     {

      // released
      if ( !hidBootMouseEnabled )
      {
       hidEmuKbdSendReport( KEY_NONE );
      }
      else
      {
       hidEmuKbdSendMouseReport ( MOUSE_BUTTON_NONE );
      }
      hidEmuKbdSendReport( KEY_NONE );

      prevKey2 = 0;
     }

    }

     -------------------------------------------------------------------------------------hidCCSendReport---------------------------------------------------------------------------------------------------

    static void hidCCSendReport( bool KPressed )
    {
     uint8 buf[HID_CC_IN_RPT_LEN]= { 0, 0 };
    if ( KPressed )
     {
        
      buf[0] = 0x01; 
      buf[1] = 0x01;
     }

     HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );

    }

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    Please check and correct me to solve this issue.

    Thanks a lot.  Please help.

    Regards

    /Ash

  • Hi Ash,

    please test my attachment(replace default HIDEumKbd project), but I think CC2541 can not work with iOS8.x for first connect. You should power on/off your buletooth on the apple device. MY modication is showing below.

    1. remove(disable)hidkbdservice.c/hidkbdservice.h then add hidkbmservice.c/hidkbmservice.h at IAR project-->PROFILES

    2. modify file directory on Options-->C/C++ compiler preprocessor

    from

    $PROJ_DIR$\..\..\Profiles\HidDevKbd

    to

    $PROJ_DIR$\..\..\Profiles\HidDevKbM

    3. modify hidemukbd.c

    4. rebuild all and test

    HIDEmuKbd.zip

  • Dear Kimi,

    Thanks a lot for your reply~

    well, I am trying this with iOS 8.1.3 and Keyfob (CC2540) after modifying the changes you suggested, but unfortunately Its not working. :(

    I can not try it with CC2540, as I have only device with CC2540.

    Something strange is happening, when I press the key on keyfob the connection get disconnected immidiately shows (Not Connected). Even I press any of the key SW1 or SW2, it gets disconnected. I dont understand why Its happening even I checked handle key function many times.

    1. Did you check the profile with CC2540 ?

    2. Is there any fixed configuration of connection parameter setting for iOS?

    Please help.

    Thanks n Regards

  • Hi Ash,

    Please modify hiddev.c,  it can fix disconnect problem.

    from

    GAP_FILTER_POLICY_WHITE

    to

    GAP_FILTER_POLICY_ALL

    1. if you wnat to change to CC2540, you only open CC2540DB then change IAR-->PROFILES and file directory

    2. sorry, I don't knw

  • Dear Kimi,Thanks for your nice reply~
    well, disconnection issue is resolved while set the FILTER POLICY to ALL. But the volume up function is still not working while pressing the key on Keyfob (CC2540). Also I am uanble to see the file properties in IAR-----> PROFILE. How can I chnage this PROFILES and File Directory. During compiling I am getting this error~ E:\Projects\HIDEmuKbd\CC2540DB\..\..\config\buildComponents.cfg [Error while running C/C++ Compiler].
    How can I solve this ?Thanks n Regards
  • Dear Arun,
    Please withdraw some time from your busy schedule to check the Report Map and Descriptor, I shared you in my previous post.
    I am waiting for your response.Thanks n Regards
  • Hi Ash,

    I did a test here now using this descriptor:

    static CONST uint8 hidReportMap[] =
    {
    0x05, 0x0C,             // Usage Pg (Consumer Devices)
    0x09, 0x01,             // Usage (Consumer Control)
      0xA1, 0x01,           // (MAIN) COLLECTION
      0x85, 0x01,           // Report ID   (1) 
      0x19, 0x00,           // (LOCAL)  USAGE_MINIMUM    
      0x2A, 0x9C, 0x02,     // (LOCAL)  USAGE_MAXIMUM    
      0x15, 0x00,           // (GLOBAL) LOGICAL_MINIMUM  
      0x26, 0x9C, 0x02,     // (GLOBAL) LOGICAL_MAXIMUM  
      0x75, 0x08,           // Report Size (8)
      0x95, 0x01,           // Report Count(1) 
      0x81, 0x00, // Input (Data, Ary, Abs) 
    0xC0 // End Collection
    };

    I also modified the advertising to not use white list and used this function to send the reports:

    static void hidEmuKbdSendReport( uint8 keycode )
    {
      uint8 buf[HID_KEYBOARD_IN_RPT_LEN];
    
      buf[0] = 0x1;       
      buf[1] = keycode;  
    // buf[2] = 0; // Keycode 1 // buf[3] = 0; // Keycode 2 // buf[4] = 0; // Keycode 3 // buf[5] = 0; // Keycode 4 // buf[6] = 0; // Keycode 5 // buf[7] = 0; // Keycode 6 HidDev_Report( HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT, 2, buf ); }

    With these modifications I'm able to control the volume up and down on my iOS 8.2 device. I still have to do one disconnect - reconnect before it works though.

    Please test this and see if it works for you.

    Regards,
    Johan

  • Dear Johan,Thanks for your post in reply~
    well, I tried this but Its not working in my case. Could you please tell me, where did you mention the keycode for volume up and Usage for volume up in report map (0xE9). Also please share the modified 'handle keys" function while using the Keyfob device as HID and pressing the Key on keyfob to control the volume up for iOS device. (I modified the Handle key function as posted previouly).
    Thanks n Regards
  • Hi Ash,

    Would it be possible for you share the keyfob code you have written with us? The reason we are asking this is whatever works for us is not working for you. It may be due to some environment change(different boards, iOS device etc.). Also let me know exactly which iOS device are you using(iPhone 6?).

    Regards,

    Arun

  • Dear Arun,

    Thanks.

    well, I am using [iPad3 (iOS 8.1.3) / iPhone6+ (iOS 8.2) / iPad mini (iOS7.0)] while controlling the key on Keyfob.

    As I mentioned that for pressing key in Keyfob, I am using [hidEmuKbd_HandleKeys()] function in [hidemukbd.c], modified as follows.......(also sent you this in my previous replies).

    Please check this and let me know the corrections.

    Thanks n Regards

     

    *******************************************************************HandleKeys******************************************************************************************

    static uint8 hidBootMouseEnabled = FALSE;

    static void hidEmuKbd_HandleKeys( uint8 shift, uint8 keys )
    {
     static uint8 prevKey1 = 0;
     static uint8 prevKey2 = 0;
     static uint8 buf[HID_CC_IN_RPT_LEN] = { 0, 0 };

     (void)shift;  // Intentionally unreferenced parameter

      if ( (keys & HAL_KEY_SW_1) && (prevKey1 == 0) )
     {
      // pressed

      buf[0] = 0x01; 
      buf[1] = 0x01;
      HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );

      hidCCSendReport( TRUE );
      prevKey1 = 1;
     }

     else if ( !(keys & HAL_KEY_SW_1) && (prevKey1 == 1) )
     {
      // released

      buf[0] = 0x00;
      buf[1] = 0x00;
      HidDev_Report( HID_RPT_ID_CC_IN, HID_REPORT_TYPE_INPUT, HID_CC_IN_RPT_LEN, buf );
      
      hidCCSendReport( FALSE );
      prevKey1 = 0;
     } 

      if ( (keys & HAL_KEY_SW_2) && (prevKey2 == 0) )
     {

      // pressed
      if ( !hidBootMouseEnabled )
      {
       hidEmuKbdSendReport( KEY_RIGHT_ARROW );
      }
      else
      {
       hidEmuKbdSendMouseReport( MOUSE_BUTTON_1 );
      }
     
      hidEmuKbdSendReport( KEY_RIGHT_ARROW );
      
      prevKey2 = 1;
     }
     
     else if ( !(keys & HAL_KEY_SW_2) && (prevKey2 == 1) )
     
     {

      // released
      if ( !hidBootMouseEnabled )
      {
       hidEmuKbdSendReport( KEY_NONE );
      }
      else
      {
       hidEmuKbdSendMouseReport ( MOUSE_BUTTON_NONE );
      }
      hidEmuKbdSendReport( KEY_NONE );

      prevKey2 = 0;
     }

    }

    **************************************************************************************************************************************************************************

  • Hi,

    I have done two versions of a report descriptor using two different approaches that I have tested on both iOS and iOS 8.1.2.

    Volume Up 0x01 and Volume Down 0x02:




    static CONST uint8 hidReportMap[] = { 0x05, 0x0C, // Usage Page (Consumer) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x01, // Report ID (1) 0x19, 0xE9, // Usage Minimum (Volume Up) 0x29, 0xEA, // Usage Maximum (Volume Down) 0x15, 0x01, // Logical Minimum (1) 0x25, 0x02, // Logical Maximum (2) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection };


    Play 0x01, Volume Up 0x02 and Volume Down 0x03:


    static CONST uint8 hidReportMap[] =
    {
    0x05, 0x0C, // Usage Page (Consumer)
    0x09, 0x01, // Usage (Consumer Control)
    0xA1, 0x01, // Collection (Application)
    0x85, 0x01, // Report ID (1)
    0x09, 0xB0, // Usage (Play)
    0x09, 0xE9, // Usage (Volume Up)
    0x09, 0xEA, // Usage (Volume Down)
    0x15, 0x01, // Logical Minimum (1)
    0x25, 0x03, // Logical Maximum (3)
    0x75, 0x08, // Report Size (8)
    0x95, 0x01, // Report Count (1)
    0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0, // End Collection
    };




    Regards,
    Johan