diff options
Diffstat (limited to 'src/ble/profile/server/hids_kb.c')
-rw-r--r-- | src/ble/profile/server/hids_kb.c | 851 |
1 files changed, 851 insertions, 0 deletions
diff --git a/src/ble/profile/server/hids_kb.c b/src/ble/profile/server/hids_kb.c new file mode 100644 index 0000000..644cc82 --- /dev/null +++ b/src/ble/profile/server/hids_kb.c @@ -0,0 +1,851 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_kb.c + * @brief Source file for using Human Interface Device Service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#include <string.h> +#include "trace.h" +#include "profile_server.h" +#include "hids_kb.h" + + +#define GATT_UUID_HID 0x1812 +#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E +#define GATT_UUID_CHAR_REPORT 0x2A4D +#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B +#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22 +#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32 +#define GATT_UUID_CHAR_HID_INFO 0x2A4A +#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C + +/* Report ID for General Keyboard, change: 0x03 to 0x01 */ +#define HOGP_KB_REPORT_ID 0x03 +#define HOGP_MM_REPORT_ID 0x04 +#define MULTIMEDIA_KEYBOARD +T_HID_INFO hid_info = {0, 0, 0x0100}; +T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE; +uint8_t hid_suspand_mode = 0; +uint16_t external_report_refer = 0; + +const uint8_t hids_report_descriptor[] = +{ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x06, /* USAGE (Keyboard) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_KB_REPORT_ID, /* REPORT_ID (3) */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard Left Control) */ + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x08, /* REPORT_COUNT (8) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x81, 0x01, /* INPUT (Cnst,Var,Abs) */ + 0x95, 0x05, /* REPORT_COUNT (5) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ + 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x03, /* REPORT_SIZE (3) */ + 0x91, 0x01, /* OUTPUT (Cnst,Var,Abs) */ + 0x95, 0x06, /* REPORT_COUNT (6) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xa4, /* LOGICAL_MAXIMUM (164) */ /* Can be 255 */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved-no event indicated) */ + 0x29, 0xa4, /* USAGE_MAXIMUM (Keyboard Application) */ /* Can be 255 */ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + 0xc0, /* END_COLLECTION */ +#ifdef MULTIMEDIA_KEYBOARD + 0x05, 0x0c, /* USAGE_PAGE (Consumer) */ + 0x09, 0x01, /* USAGE (Consumer Control) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_MM_REPORT_ID, /* REPORT_ID (4) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x18, /* REPORT_COUNT (24) */ + 0x09, 0xb5, /* USAGE (Scan Next Track) */ + 0x09, 0xb6, /* USAGE (Scan Previous Track) */ + 0x09, 0xb7, /* USAGE (Stop) */ + 0x09, 0xcd, /* USAGE (Play/Pause) */ + 0x09, 0xe2, /* USAGE (Mute) */ + 0x09, 0xe5, /* USAGE (Bass Boost) */ + 0x09, 0xe7, /* USAGE (Loudness) */ + 0x09, 0xe9, /* USAGE (Volume Increment) */ + 0x09, 0xea, /* USAGE (Volume Decrement) */ + 0x0a, 0x52, 0x01, /* USAGE (Bass Increment) */ + 0x0a, 0x53, 0x01, /* USAGE (Bass Decrement) */ + 0x0a, 0x54, 0x01, /* USAGE (Treble Increment) */ + 0x0a, 0x55, 0x01, /* USAGE (Treble Decrement) */ + 0x0a, 0x83, 0x01, /* USAGE (AL Consumer Control Configuration) */ + 0x0a, 0x8a, 0x01, /* USAGE (AL Email Reader) */ + 0x0a, 0x92, 0x01, /* USAGE (AL Calculator) */ + 0x0a, 0x94, 0x01, /* USAGE (AL Local Machine Browser) */ + 0x0a, 0x21, 0x02, /* USAGE (AC Search) */ + 0x0a, 0x23, 0x02, /* USAGE (AC Home) */ + 0x0a, 0x24, 0x02, /* USAGE (AC Back) */ + 0x0a, 0x25, 0x02, /* USAGE (AC Forward) */ + 0x0a, 0x26, 0x02, /* USAGE (AC Stop) */ + 0x0a, 0x27, 0x02, /* USAGE (AC Refresh) */ + 0x0a, 0x2a, 0x02, /* USAGE (AC Bookmarks) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0xc0 /* END_COLLECTION */ +#endif +}; + +static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL; + +static const T_ATTRIB_APPL hids_attr_tbl[] = +{ + /* <<Primary Service>>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_HID), /* service UUID */ + HI_WORD(GATT_UUID_HID) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <<Characteristic>>, .. 1*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Protocol Mode characteristic value ..2*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE), + HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* <<Characteristic>>, .. 3*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 4*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* client characteristic configuration .. 5*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + }, + + /*report ID map reference descriptor .. 6*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_KB_REPORT_ID, + HID_INPUT_TYPE, + }, + 2, /* bValueLen */ + NULL,//(void*)&cPointerInputReportIdMap, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <<Characteristic>>, .. 7*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 8*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /*report ID map reference descriptor .. 9*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_KB_REPORT_ID, + HID_OUTPUT_TYPE + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <<Characteristic>>, .. 10*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 11*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /*report ID map reference descriptor .. 12*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HOGP_KB_REPORT_ID, + HID_FEATURE_TYPE + }, + 2, /* bValueLen */ + (void *)NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <<Characteristic>>, .. 13*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID report map characteristic value .. 14*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_MAP), + HI_WORD(GATT_UUID_CHAR_REPORT_MAP) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* wPermissions */ + }, + + /* <<EXTERNAL_REPORT_REFERENCE>>, .. 15*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* permissions */ + }, + + /* <<Characteristic>>, .. 16*/ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID boot keyboard input characteristic value .. 17*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ + }, + + /* client characteristic configuration .. 18*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ + }, + + /* <<Characteristic>>, .. 19*/ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID boot keyboard output characteristic value .. 20*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ + }, + + /* <<Characteristic>>, .. 21*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Information characteristic value .. 22*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_INFO), + HI_WORD(GATT_UUID_CHAR_HID_INFO) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* wPermissions */ + }, + + /* <<Characteristic>>, .. 23*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID controlPoint characteristic value .. 24*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + +#ifdef MULTIMEDIA_KEYBOARD + /* <<Characteristic>>, .. 25*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value ,multimedia keyboard Input 26*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 3, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* client characteristic configuration 27*/ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + }, + + /*report ID map reference descriptor 28*/ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HOGP_MM_REPORT_ID, /* client char. config. bit field */ + HID_INPUT_TYPE + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + } +#endif + +}; + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * <b>Example usage</b> + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr) +{ + bool ret = true; + + switch (param_type) + { + case HID_PROTOCOL_MODE: + { + hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr); + } + break; + + case HID_REPORT_INPUT: + break; + + case HID_REPORT_OUTPUT: + break; + + case HID_REPORT_FEATURE: + break; + + case HID_REPORT_MAP: + break; + + case HID_EXTERNAL_REPORT_REFER: + { + external_report_refer = *(uint16_t *)value_ptr; + } + break; + + case HID_BOOT_KB_IN_REPORT: + break; + + case HID_BOOT_KB_OUT_REPORT: + break; + + case HID_INFO: + { + memcpy((void *)&hid_info, value_ptr, length); + } + break; + + case HID_CONTROL_POINT: + hid_suspand_mode = *((uint8_t *)value_ptr); + break; + + default: + ret = false; + break; + } + return ret; +} + + +static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_protocol_mode; + *p_length = sizeof(hid_protocol_mode); + break; + + case GATT_SVC_HID_REPORT_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + *pp_value = (uint8_t *)hids_report_descriptor; + *p_length = sizeof(hids_report_descriptor); + break; + + case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&external_report_refer; + *p_length = sizeof(external_report_refer); + break; + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_info; + *p_length = sizeof(hid_info); + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + return cause; +} + + +static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value; + hids_set_parameter(HID_PROTOCOL_MODE, length, p_value); + break; + + case GATT_SVC_HID_REPORT_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_REPORT_OUTPUT_INDEX; + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.output = *p_value; + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + +void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + bool cause = true; + T_HID_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + + PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + + switch (index) + { + default: + cause = false; + break; + + case GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + } + + if (pfn_hids_cb && (cause == true)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return; +} + + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * <b>Example usage</b> + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len) +{ + PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len); + return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION); +} + + + +uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl); + +const T_FUN_GATT_SERVICE_CBS hids_cbs = +{ + hids_attr_read_cb, // Read callback function pointer + hids_attr_write_cb, // Write callback function pointer + hids_cccd_update_cb, // Authorization callback function pointer +}; + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * <b>Example usage</b> + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs)) + { + PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + + pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + |