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:
@@ -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);
|
||||
|
Reference in New Issue
Block a user