Bluetooth Remote Additions (#1330)

* Update the HID Keycodes to pull from the library
* Composite BLE Report Map, add consumer & mouse HID
* Add Mouse & keyboard bt remote, fixed media remote
* BT Keyboard remove long press shift
* Fix usb hid modifier keys
* Fixed misaligned bad usb keys
* Fix keyboard app keys
* Partial fix for bt app and linux
* Update to work across platforms
* Fix for report ids
* BtHidApp: move variable from bss to model, cleanup naming.
* FuriHal: add const to immutable data declaration

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Michael Marcucci
2022-07-08 08:36:34 -04:00
committed by GitHub
parent c72b678510
commit 6b3625f46b
18 changed files with 1341 additions and 633 deletions

View File

@@ -9,10 +9,9 @@
typedef struct {
uint16_t svc_handle;
uint16_t protocol_mode_char_handle;
uint16_t report_char_handle;
uint16_t report_ref_desc_handle;
uint16_t report_char_handle[HID_SVC_REPORT_COUNT];
uint16_t report_ref_desc_handle[HID_SVC_REPORT_COUNT];
uint16_t report_map_char_handle;
uint16_t keyboard_boot_char_handle;
uint16_t info_char_handle;
uint16_t ctrl_point_char_handle;
} HIDSvc;
@@ -47,12 +46,22 @@ void hid_svc_start() {
SVCCTL_RegisterSvcHandler(hid_svc_event_handler);
// Add service
svc_uuid.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID;
status =
aci_gatt_add_service(UUID_TYPE_16, &svc_uuid, PRIMARY_SERVICE, 30, &hid_svc->svc_handle);
/**
* Add Human Interface Device Service
*/
status = aci_gatt_add_service(
UUID_TYPE_16,
&svc_uuid,
PRIMARY_SERVICE,
2 + /* protocol mode */
(4 * HID_SVC_INPUT_REPORT_COUNT) + (3 * HID_SVC_OUTPUT_REPORT_COUNT) +
(3 * HID_SVC_FEATURE_REPORT_COUNT) + 1 + 2 + 2 +
2, /* Service + Report Map + HID Information + HID Control Point */
&hid_svc->svc_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to add HID service: %d", status);
}
// Add Protocol mode characterstics
// Add Protocol mode characteristics
char_uuid.Char_UUID_16 = PROTOCOL_MODE_CHAR_UUID;
status = aci_gatt_add_char(
hid_svc->svc_handle,
@@ -75,42 +84,120 @@ void hid_svc_start() {
if(status) {
FURI_LOG_E(TAG, "Failed to update protocol mode characteristic: %d", status);
}
// Add Report characterstics
char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
status = aci_gatt_add_char(
hid_svc->svc_handle,
UUID_TYPE_16,
&char_uuid,
HID_SVC_REPORT_MAX_LEN,
CHAR_PROP_READ | CHAR_PROP_NOTIFY,
ATTR_PERMISSION_NONE,
GATT_DONT_NOTIFY_EVENTS,
10,
CHAR_VALUE_LEN_VARIABLE,
&hid_svc->report_char_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status);
}
// Add Report descriptor
uint8_t desc_val[] = {0x00, 0x01};
desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
status = aci_gatt_add_char_desc(
hid_svc->svc_handle,
hid_svc->report_char_handle,
UUID_TYPE_16,
&desc_uuid,
HID_SVC_REPORT_REF_LEN,
HID_SVC_REPORT_REF_LEN,
desc_val,
ATTR_PERMISSION_NONE,
ATTR_ACCESS_READ_ONLY,
GATT_DONT_NOTIFY_EVENTS,
MIN_ENCRY_KEY_SIZE,
CHAR_VALUE_LEN_CONSTANT,
&hid_svc->report_ref_desc_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status);
#if(HID_SVC_REPORT_COUNT != 0)
for(uint8_t i = 0; i < HID_SVC_REPORT_COUNT; i++) {
if(i < HID_SVC_INPUT_REPORT_COUNT) {
uint8_t buf[2] = {i + 1, 1}; // 1 input
char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
status = aci_gatt_add_char(
hid_svc->svc_handle,
UUID_TYPE_16,
&char_uuid,
HID_SVC_REPORT_MAX_LEN,
CHAR_PROP_READ | CHAR_PROP_NOTIFY,
ATTR_PERMISSION_NONE,
GATT_DONT_NOTIFY_EVENTS,
10,
CHAR_VALUE_LEN_VARIABLE,
&(hid_svc->report_char_handle[i]));
if(status) {
FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status);
}
desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
status = aci_gatt_add_char_desc(
hid_svc->svc_handle,
hid_svc->report_char_handle[i],
UUID_TYPE_16,
&desc_uuid,
HID_SVC_REPORT_REF_LEN,
HID_SVC_REPORT_REF_LEN,
buf,
ATTR_PERMISSION_NONE,
ATTR_ACCESS_READ_WRITE,
GATT_DONT_NOTIFY_EVENTS,
MIN_ENCRY_KEY_SIZE,
CHAR_VALUE_LEN_CONSTANT,
&(hid_svc->report_ref_desc_handle[i]));
if(status) {
FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status);
}
} else if((i - HID_SVC_INPUT_REPORT_COUNT) < HID_SVC_OUTPUT_REPORT_COUNT) {
uint8_t buf[2] = {i + 1, 2}; // 2 output
char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
status = aci_gatt_add_char(
hid_svc->svc_handle,
UUID_TYPE_16,
&char_uuid,
HID_SVC_REPORT_MAX_LEN,
CHAR_PROP_READ | CHAR_PROP_NOTIFY,
ATTR_PERMISSION_NONE,
GATT_DONT_NOTIFY_EVENTS,
10,
CHAR_VALUE_LEN_VARIABLE,
&(hid_svc->report_char_handle[i]));
if(status) {
FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status);
}
desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
status = aci_gatt_add_char_desc(
hid_svc->svc_handle,
hid_svc->report_char_handle[i],
UUID_TYPE_16,
&desc_uuid,
HID_SVC_REPORT_REF_LEN,
HID_SVC_REPORT_REF_LEN,
buf,
ATTR_PERMISSION_NONE,
ATTR_ACCESS_READ_WRITE,
GATT_DONT_NOTIFY_EVENTS,
MIN_ENCRY_KEY_SIZE,
CHAR_VALUE_LEN_CONSTANT,
&(hid_svc->report_ref_desc_handle[i]));
if(status) {
FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status);
}
} else {
uint8_t buf[2] = {i + 1, 3}; // 3 feature
char_uuid.Char_UUID_16 = REPORT_CHAR_UUID;
status = aci_gatt_add_char(
hid_svc->svc_handle,
UUID_TYPE_16,
&char_uuid,
HID_SVC_REPORT_MAX_LEN,
CHAR_PROP_READ | CHAR_PROP_NOTIFY,
ATTR_PERMISSION_NONE,
GATT_DONT_NOTIFY_EVENTS,
10,
CHAR_VALUE_LEN_VARIABLE,
&(hid_svc->report_char_handle[i]));
if(status) {
FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status);
}
desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID;
status = aci_gatt_add_char_desc(
hid_svc->svc_handle,
hid_svc->report_char_handle[i],
UUID_TYPE_16,
&desc_uuid,
HID_SVC_REPORT_REF_LEN,
HID_SVC_REPORT_REF_LEN,
buf,
ATTR_PERMISSION_NONE,
ATTR_ACCESS_READ_WRITE,
GATT_DONT_NOTIFY_EVENTS,
MIN_ENCRY_KEY_SIZE,
CHAR_VALUE_LEN_CONSTANT,
&(hid_svc->report_ref_desc_handle[i]));
if(status) {
FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status);
}
}
}
#endif
// Add Report Map characteristic
char_uuid.Char_UUID_16 = REPORT_MAP_CHAR_UUID;
status = aci_gatt_add_char(
@@ -127,22 +214,7 @@ void hid_svc_start() {
if(status) {
FURI_LOG_E(TAG, "Failed to add report map characteristic: %d", status);
}
// Add Boot Keyboard characteristic
char_uuid.Char_UUID_16 = BOOT_KEYBOARD_INPUT_REPORT_CHAR_UUID;
status = aci_gatt_add_char(
hid_svc->svc_handle,
UUID_TYPE_16,
&char_uuid,
HID_SVC_BOOT_KEYBOARD_INPUT_REPORT_MAX_LEN,
CHAR_PROP_READ | CHAR_PROP_NOTIFY,
ATTR_PERMISSION_NONE,
GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP,
10,
CHAR_VALUE_LEN_VARIABLE,
&hid_svc->keyboard_boot_char_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to add report map characteristic: %d", status);
}
// Add Information characteristic
char_uuid.Char_UUID_16 = HID_INFORMATION_CHAR_UUID;
status = aci_gatt_add_char(
@@ -177,27 +249,27 @@ void hid_svc_start() {
}
}
bool hid_svc_update_report_map(uint8_t* data, uint16_t len) {
bool hid_svc_update_report_map(const uint8_t* data, uint16_t len) {
furi_assert(data);
furi_assert(hid_svc);
tBleStatus status = aci_gatt_update_char_value(
hid_svc->svc_handle, hid_svc->report_map_char_handle, 0, len, data);
if(status) {
FURI_LOG_E(TAG, "Failed updating report map characteristic");
FURI_LOG_E(TAG, "Failed updating report map characteristic: %d", status);
return false;
}
return true;
}
bool hid_svc_update_input_report(uint8_t* data, uint16_t len) {
bool hid_svc_update_input_report(uint8_t input_report_num, uint8_t* data, uint16_t len) {
furi_assert(data);
furi_assert(hid_svc);
tBleStatus status =
aci_gatt_update_char_value(hid_svc->svc_handle, hid_svc->report_char_handle, 0, len, data);
tBleStatus status = aci_gatt_update_char_value(
hid_svc->svc_handle, hid_svc->report_char_handle[input_report_num], 0, len, data);
if(status) {
FURI_LOG_E(TAG, "Failed updating report characteristic");
FURI_LOG_E(TAG, "Failed updating report characteristic: %d", status);
return false;
}
return true;
@@ -210,7 +282,7 @@ bool hid_svc_update_info(uint8_t* data, uint16_t len) {
tBleStatus status =
aci_gatt_update_char_value(hid_svc->svc_handle, hid_svc->info_char_handle, 0, len, data);
if(status) {
FURI_LOG_E(TAG, "Failed updating info characteristic");
FURI_LOG_E(TAG, "Failed updating info characteristic: %d", status);
return false;
}
return true;
@@ -228,18 +300,18 @@ void hid_svc_stop() {
if(status) {
FURI_LOG_E(TAG, "Failed to delete Report Map characteristic: %d", status);
}
status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_char_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to delete Report characteristic: %d", status);
#if(HID_SVC_INPUT_REPORT_COUNT != 0)
for(uint8_t i = 0; i < HID_SVC_REPORT_COUNT; i++) {
status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_char_handle[i]);
if(status) {
FURI_LOG_E(TAG, "Failed to delete Report characteristic: %d", status);
}
}
#endif
status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->protocol_mode_char_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to delete Protocol Mode characteristic: %d", status);
}
status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->keyboard_boot_char_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to delete Keyboard Boot characteristic: %d", status);
}
status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->info_char_handle);
if(status) {
FURI_LOG_E(TAG, "Failed to delete Information characteristic: %d", status);