Using HID keyboard and the iOS soft-keyboard combined

Viewed 16

I've been using nRF52840, SDK 17.0.2, with the example code for HID over BLE keyboard. When connecting to an iOS phone, the HID keyboard promotes the iOS soft-keyboard, so not input is enabled from the phone's user. I would like to enable the iOS soft-keyboard while BLE connected with the nRF.

I am using the hid_init configuration and the eject-keyboard key sending, described in here: Bluetooth LE HID Eject Key Code?

Another source for the above code: https://github.com/Rallare/nrf51_ble_app_hids_kbd_consumercontrol/blob/master/main.c

However, sending the key will not enable the keyboard unless the phone is currently in a text field. If not in a text field, the key is ignored.

I've also tried sending the following sequence to enable the keyboard: report key modifier release *{0, 0x0B, 0x08, true} // Home

{0, 0x2C, 0x08, true} //spotlight

{0, 0x52, 0, true} // Up Arrow

{0, 0x04, 0x08, true} // Select All

{0, 0x2A, 0, true} // Backspace

{1, 0x01, 0, true} // eject

{0, 0x2C, 0x08, true} //spotlight*

But, this solution is not stable and mostly does not work.

I also use shortcuts and keyboard commands to lunch apps, in the project, but could not find something that might help with my issue.

This is the hid configuration I use: *static void hids_init(void) { ret_code_t err_code;

ble_hids_init_t               hids_init_obj;

ble_hids_inp_rep_init_t     * p_input_report;

ble_hids_outp_rep_init_t    * p_output_report;

ble_hids_feature_rep_init_t * p_feature_report;

uint8_t                       hid_info_flags;

static ble_hids_inp_rep_init_t     input_report_array[2];

static ble_hids_outp_rep_init_t    output_report_array[1];

static ble_hids_feature_rep_init_t feature_report_array[1];

static uint8_t                     report_map_data[] =

{

    0x05, 0x01,       // Usage Page (Generic Desktop)

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

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

    0x85, 0x01,       // Report Id (1)

    0x05, 0x07,       // Usage Page (Key Codes)

    0x19, 0xe0,       // Usage Minimum (224)

    0x29, 0xe7,       // Usage Maximum (231)

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

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

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

    0x95, 0x08,       // Report Count (8)

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

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

    0x75, 0x08,       // Report Size (8)

    0x81, 0x01,       // Input (Constant) reserved byte(1)

    0x95, 0x05,       // Report Count (5)

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

    0x05, 0x08,       // Usage Page (Page# for LEDs)

    0x19, 0x01,       // Usage Minimum (1)

    0x29, 0x05,       // Usage Maximum (5)

    0x91, 0x02,       // Output (Data, Variable, Absolute), Led report

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

    0x75, 0x03,       // Report Size (3)

    0x91, 0x01,       // Output (Data, Variable, Absolute), Led report 

                         padding

    0x95, 0x06,       // Report Count (6)

    0x75, 0x08,       // Report Size (8)

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

    0x25, 0x65,       // Logical Maximum (101)

    0x05, 0x07,       // Usage Page (Key codes)

    0x19, 0x00,       // Usage Minimum (0)

    0x29, 0x65,       // Usage Maximum (101)

    0x81, 0x00,       // Input (Data, Array) Key array(6 bytes)

    0x09, 0x05,       // Usage (Vendor Defined)

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

    0x26, 0xFF, 0x00, // Logical Maximum (255)

    0x75, 0x08,       // Report Size (8 bit)

    0x95, 0x02,       // Report Count (2)

    0xB1, 0x02,       // Feature (Data, Variable, Absolute)

    0xC0,             // End Collection (Application)

    // Report ID 2: Advanced buttons

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

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

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

    0x85, 0x02, // Report Id (2)

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

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

    0x0A, 0xAE, 0x01, // Usage (AL Keyboard Layout)

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

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

    0x81, 0x06, // Input (Data,Value,Relative,Bit Field)

    0xC0 // End Collection

};

memset((void *)input_report_array, 0, 

       2*sizeof(ble_hids_inp_rep_init_t));

memset((void *)output_report_array, 0, 

       sizeof(ble_hids_outp_rep_init_t));

memset((void *)feature_report_array, 0, 

       sizeof(ble_hids_feature_rep_init_t));

// Initialize HID Service

p_input_report = &input_report_array[INPUT_REPORT_KEYS_INDEX];

p_input_report->max_len             = INPUT_REPORT_KEYS_MAX_LEN;

p_input_report->rep_ref.report_id   = INPUT_REP_REF_ID;

p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

p_input_report->sec.cccd_wr = SEC_JUST_WORKS;

p_input_report->sec.wr      = SEC_JUST_WORKS;

p_input_report->sec.rd      = SEC_JUST_WORKS;

// Initialize HID Service

p_input_report = &input_report_array[INPUT_REPORT_TOGGLE_INDEX];

p_input_report->max_len = INPUT_REPORT_KEYS_MAX_LEN;

p_input_report->rep_ref.report_id = INPUT_REP_TOGGLE_ID;

p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

p_input_report->sec.cccd_wr = SEC_JUST_WORKS;

p_input_report->sec.wr = SEC_JUST_WORKS;

p_input_report->sec.rd = SEC_JUST_WORKS;

p_output_report = &output_report_array[OUTPUT_REPORT_INDEX];

p_output_report->max_len             = OUTPUT_REPORT_MAX_LEN;

p_output_report->rep_ref.report_id   = OUTPUT_REP_REF_ID;

p_output_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_OUTPUT;

p_output_report->sec.wr = SEC_JUST_WORKS;

p_output_report->sec.rd = SEC_JUST_WORKS;

p_feature_report = &feature_report_array[FEATURE_REPORT_INDEX];

p_feature_report->max_len             = FEATURE_REPORT_MAX_LEN;

p_feature_report->rep_ref.report_id   = FEATURE_REP_REF_ID;

p_feature_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_FEATURE;

p_feature_report->sec.rd              = SEC_JUST_WORKS;

p_feature_report->sec.wr              = SEC_JUST_WORKS;

hid_info_flags = HID_INFO_FLAG_REMOTE_WAKE_MSK | 

                 HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK;

memset(&hids_init_obj, 0, sizeof(hids_init_obj));

hids_init_obj.evt_handler                    = on_hids_evt;

hids_init_obj.error_handler                  = service_error_handler;

hids_init_obj.is_kb                          = true;

hids_init_obj.is_mouse                       = false;

hids_init_obj.inp_rep_count                  = 2;

hids_init_obj.p_inp_rep_array                = input_report_array;

hids_init_obj.outp_rep_count                 = 1;

hids_init_obj.p_outp_rep_array               = output_report_array;

hids_init_obj.feature_rep_count              = 1;

hids_init_obj.p_feature_rep_array            = feature_report_array;

hids_init_obj.rep_map.data_len               = sizeof(report_map_data);

hids_init_obj.rep_map.p_data                 = report_map_data;

hids_init_obj.hid_information.bcd_hid        =BASE_USB_HID_SPEC_VERSION;

hids_init_obj.hid_information.b_country_code = 0;

hids_init_obj.hid_information.flags          = hid_info_flags;

hids_init_obj.included_services_count        = 0;

hids_init_obj.p_included_services_array      = NULL;

hids_init_obj.rep_map.rd_sec         = SEC_JUST_WORKS;

hids_init_obj.hid_information.rd_sec = SEC_JUST_WORKS;

hids_init_obj.boot_kb_inp_rep_sec.cccd_wr = SEC_JUST_WORKS;

hids_init_obj.boot_kb_inp_rep_sec.rd      = SEC_JUST_WORKS;

hids_init_obj.boot_kb_outp_rep_sec.rd = SEC_JUST_WORKS;

hids_init_obj.boot_kb_outp_rep_sec.wr = SEC_JUST_WORKS;

hids_init_obj.protocol_mode_rd_sec = SEC_JUST_WORKS;

hids_init_obj.protocol_mode_wr_sec = SEC_JUST_WORKS;

hids_init_obj.ctrl_point_wr_sec    = SEC_JUST_WORKS;

err_code = ble_hids_init(&m_hids, &hids_init_obj);

APP_ERROR_CHECK(err_code);

}*

Tnx for any help given.

0 Answers
Related