aboutsummaryrefslogtreecommitdiff
path: root/src/ble/profile/server/hids_ms.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ble/profile/server/hids_ms.c')
-rw-r--r--src/ble/profile/server/hids_ms.c861
1 files changed, 861 insertions, 0 deletions
diff --git a/src/ble/profile/server/hids_ms.c b/src/ble/profile/server/hids_ms.c
new file mode 100644
index 0000000..8e5a9fc
--- /dev/null
+++ b/src/ble/profile/server/hids_ms.c
@@ -0,0 +1,861 @@
+/**
+*****************************************************************************************
+* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
+*****************************************************************************************
+ * @file hids_ms.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_ms.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_MS_IN_REPORT 0x2A33
+#define GATT_UUID_CHAR_HID_INFO 0x2A4A
+#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C
+
+#define HOGP_MOUSE_REPORT_ID 1
+#define HOGP_VENDOR_REPORT_ID 0x10
+
+static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL;
+
+T_HID_INFO hid_info = {0, 0, 0};
+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) main item*/
+ 0x09, 0x02, /* USAGE (Mouse) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_MOUSE_REPORT_ID, /* REPORT_ID (1) */
+ 0x09, 0x01, /* USAGE (Pointer) */
+ 0xa1, 0x00, /* COLLECTION (Physical) */
+ 0x05, 0x09, /* USAGE_PAGE (Button) */
+ 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
+ 0x29, 0x05, /* USAGE_MAXIMUM (Button 5) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
+ 0x95, 0x05, /* REPORT_COUNT (5) */
+ 0x75, 0x01, /* REPORT_SIZE (1) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x75, 0x03, /* REPORT_SIZE (3) */
+ 0x81, 0x01, /* INPUT (Cnst,Var,Abs) */
+
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) main item*/
+ 0x09, 0x30, /* USAGE (X) */
+ 0x09, 0x31, /* USAGE (Y) */
+ 0x16, 0x01, 0x80, /* LOGICAL_MINIMUM (-32767) */
+ 0x26, 0xff, 0x7f, /* LOGICAL_MAXIMUM (32767) */
+ 0x75, 0x10, /* REPORT_SIZE (16) */
+ 0x95, 0x02, /* REPORT_COUNT (2) */
+ 0x81, 0x06, /* INPUT (Data,Var,Rel) */
+ 0x09, 0x38, /* USAGE (Wheel) */
+ 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
+ 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x95, 0x01, /* REPORT_COUNT (1) */
+ 0x81, 0x06, /* INPUT (Data,Var,Rel) */
+ 0xc0, /* END_COLLECTION */
+ 0xc0, /* END_COLLECTION */
+
+ 0x06, 0x01, 0xff, /* USAGE_PAGE (vendor) */
+ 0x09, 0x01, /* USAGE (vendor) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ 0x85, HOGP_VENDOR_REPORT_ID, /* REPORT_ID (0x10) */
+ 0x19, 0x00, /* USAGE_MINIMUM (0) */
+ 0x29, 0xff, /* USAGE_MAXIMUM (0xff) */
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
+ 0x25, 0xff, /* LOGICAL_MAXIMUM (0xff) */
+ 0x75, 0x08, /* REPORT_SIZE (8) */
+ 0x95, 0x04, /* REPORT_COUNT (4) */
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */
+ 0xc0, /* END_COLLECTION */
+};
+
+
+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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /* <<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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /* 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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+#endif
+ },
+
+ /*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_MOUSE_REPORT_ID,
+ HID_INPUT_TYPE,
+ },
+ 2, /* bValueLen */
+ NULL,//(void*)&cPointerInputReportIdMap,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+ /* <<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_NOTIFY, /* 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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /* client characteristic configuration .. 9*/
+ {
+ (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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */
+#endif
+ },
+
+ /*report ID map reference descriptor .. 10*/
+ {
+ (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_VENDOR_REPORT_ID,
+ HID_INPUT_TYPE,
+ },
+ 2, /* bValueLen */
+ NULL,//(void*)&cPointerInputReportIdMap,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 11*/
+ {
+ 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 .. 12*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /*report ID map reference descriptor .. 13*/
+ {
+ (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_MOUSE_REPORT_ID,
+ HID_OUTPUT_TYPE
+ },
+ 2, /* bValueLen */
+ NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 14*/
+ {
+ 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 .. 15*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_REPORT),
+ HI_WORD(GATT_UUID_CHAR_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+ /*report ID map reference descriptor .. 16*/
+ {
+ (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_MOUSE_REPORT_ID,
+ HID_FEATURE_TYPE
+ },
+ 2, /* bValueLen */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 17*/
+ {
+ 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 .. 18*/
+ {
+ 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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ /* wPermissions */
+#endif
+ },
+
+ /* <<EXTERNAL_REPORT_REFERENCE>>, .. 19*/
+ {
+ 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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ (GATT_PERM_READ) /* wPermissions */
+#endif /* permissions */
+ },
+
+ /* <<Characteristic>>, .. 20*/
+ {
+ 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 boot mouse input characteristic value .. 21*/
+ {
+ ATTRIB_FLAG_VALUE_APPL, /* wFlags */
+ { /* bTypeValue */
+ LO_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT),
+ HI_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT)
+ },
+ 0, /* variable size */
+ (void *)NULL,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */
+#endif
+ },
+
+
+ /* client characteristic configuration .. 22*/
+ {
+ (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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* permissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 23*/
+ {
+ 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 .. 24*/
+ {
+ 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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ /* wPermissions */
+#endif
+ },
+
+ /* <<Characteristic>>, .. 25*/
+ {
+ 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 .. 26*/
+ {
+ 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,
+#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ
+ (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */
+#else
+ GATT_PERM_READ | GATT_PERM_WRITE /* 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_MS_IN_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_MOUSE_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_MS_IN_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.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_MOUSE_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:
+ break;
+
+ case GATT_SVC_HID_BOOT_MS_IN_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_MOUSE_INPUT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_MOUSE_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_REPORT_VNEDOR_INPUT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_VNEDOR_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_MS_IN_REPORT_CCCD_INDEX:
+ {
+ callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_MS_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_MOUSE_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;
+}