我正在实施一个基于TI蓝牙LE HID样本的加密狗,需要恢复或禁用键盘功能。将Apple键盘与iOS设备配合使用时,按弹出按钮将启用/禁用设备,隐藏/显示键盘。
大多数参考文献都说弹出按钮没有关键代码,尽管有人将其列为161;从蓝牙LE设备使用时,这不起作用。从键盘发送到设备的关键代码是什么?
我当然假设蓝牙LE设备将发送与蓝牙设备相同的密钥代码,并且Apple的蓝牙LE HID实现包括隐藏和恢复键盘的功能。如果其中一个假设不正确,那也会有所帮助。
答案 0 :(得分:4)
我使用以下报告地图成功地使用了Nordic Semiconductor的nRF51822和S110:
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 Count (2)
0x95, 0x02, // Report Size (8 bit)
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)
0x75, 0x01, // Report Size (1)
0x95, 0x01, // Report Count (1)
0x0A, 0xAE, 0x01, // Usage (AL Keyboard Layout)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0xC0 // End Collection
};
通过此报告地图,我可以使用以下方式发送切换:
static void toggle_send(void)
{
uint32_t err_code;
uint8_t release = 0;
uint8_t keyboard_toggle = 0x01;
// 1 designates the report index, not report ID.
err_code = ble_hids_inp_rep_send(&m_hids, 1, sizeof(keyboard_toggle), &keyboard_toggle);
APP_ERROR_CHECK(err_code);
err_code = ble_hids_inp_rep_send(&m_hids, 1, sizeof(release), &release);
APP_ERROR_CHECK(err_code);
}
我不详细了解TI API,但我希望这可以用来参考。如果您也可以访问该芯片,则上述修改应该很容易添加到常规nRF51 SDK中的ble_app_hids_keyboard。
答案 1 :(得分:0)
这对我有用:
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, 0x00, // 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 Count (2)
0x95, 0x02, // Report Size (8 bit)
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, 0x01, // Report Id (2)
0x15, 0x00, // Logical minimum (0)
0x25, 0x01, // Logical maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x01, // Report Count (1)
0x0A, 0xAE, 0x01, // Usage (AL Keyboard Layout)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0xC0 // End Collection
};
memset((void *)input_report_array, 0, 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[1];
p_input_report->max_len = INPUT_REPORT_KEYS_MAX_LEN;
p_input_report->rep_ref.report_id = 1;
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_input_report = &input_report_array[INPUT_REPORT_KEYS_INDEX];
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);
}