| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- #include "include.h"
- #include "utils_hid_usage.h"
- #include "ble_hid_service.h"
- #define TRACE_EN 1
- #if TRACE_EN
- #define TRACE(...) my_printf("[BLE] ");my_printf(__VA_ARGS__)
- #define TRACE_R(...) my_print_r(__VA_ARGS__)
- #else // !TRACE_EN
- #define TRACE(...)
- #define TRACE_R(...)
- #endif // TRACE_EN
- #define BLE_HID_HANDLE_MAP ATT_CHARACTERISTIC_2a4b_01_VALUE_HANDLE
- #define BLE_HID_HANDLE_CTRL_POINT ATT_CHARACTERISTIC_2a4c_01_VALUE_HANDLE
- #define BLE_HID_HANDLE_REP_CONSUMER ATT_CHARACTERISTIC_2a4d_01_VALUE_HANDLE
- #define BLE_HID_HANDLE_REP_CONSUMER_CCC ATT_CHARACTERISTIC_2a4d_01_CLIENT_CONFIGURATION_HANDLE
- #define BLE_HID_HANDLE_REP_KEYBOARD ATT_CHARACTERISTIC_2a4d_02_VALUE_HANDLE
- #define BLE_HID_HANDLE_REP_KEYBOARD_CCC ATT_CHARACTERISTIC_2a4d_02_CLIENT_CONFIGURATION_HANDLE
- #define BLE_HID_HANDLE_REP_LED ATT_CHARACTERISTIC_2a4d_03_VALUE_HANDLE
- //#define BLE_HID_HANDLE_REP_MOUSE ATT_CHARACTERISTIC_2a4d_04_VALUE_HANDLE
- //#define BLE_HID_HANDLE_REP_MOUSE_CCC ATT_CHARACTERISTIC_2a4d_04_CLIENT_CONFIGURATION_HANDLE
- static att_service_handler_t hid_service;
- static uint16_t hid_report_client_config_consumer;
- static uint16_t hid_report_client_config_keyboard;
- static uint16_t hid_report_client_config_mouse;
- static uint16_t hid_connect_handle;
- static struct {
- bool ready;
- hid_rep_info_t data;
- } ble_hid_state AT(.ble_buf.hid.comm);
- #if 0
- static u8 report_map[] = {
- HID_REP_MAP_CONSUMER(1),
- HID_REP_MAP_KEYBOARD(2),
- HID_REP_MAP_MOUSE(3),
- #if 0
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x02, // USAGE (Mouse)
- 0xA1, 0x01, // COLLECTION (Application)
- 0x85, 0x01, // 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)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x95, 0x05, // REPORT_COUNT (5)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x75, 0x03, // REPORT_SIZE (3)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x81, 0x03, // INPUT (Cnst,Var,Abs)
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x38, // USAGE (Wheel)
- 0x09, 0x30, // USAGE (X)
- 0x09, 0x31, // USAGE (Y)
- 0x15, 0x81, // LOGICAL_MINIMUM (-127)
- 0x25, 0x7F, // LOGICAL_MAXIMUM (127)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x03, // REPORT_COUNT (3)
- 0x81, 0x06, // INPUT (Data,Var,Rel)
- 0xC0, // END_COLLECTION
- 0xC0, // END_COLLECTION
- #endif
- };
- #endif // 0
- static void hid_service_event_packet_handle(uint8_t event_type, uint8_t *param, uint16_t size)
- {
- switch(event_type){
- case BLE_EVT_CONNECT:{
- memcpy(&hid_connect_handle, ¶m[7], 2);
- TRACE("Connected - con_handle: 0x%04x\n", hid_connect_handle);
- ble_hid_state.ready = true;
- } break;
- case BLE_EVT_DISCONNECT:{
- uint16_t con_handle;
- memcpy(&con_handle, ¶m[0], 2);
- TRACE("Disconnected - con_handle: 0x%04x\n", con_handle);
- if (con_handle == hid_connect_handle) {
- hid_connect_handle = 0;
- // TODO: The CCCD value shall be persistent across connections for bonded devices.
- hid_report_client_config_consumer = CCCD_DFT;
- hid_report_client_config_keyboard = CCCD_DFT;
- hid_report_client_config_mouse = CCCD_DFT;
- }
- ble_hid_state.ready = false;
- } break;
- default:
- break;
- }
- }
- static uint16_t hid_service_read_callback(uint16_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size)
- {
- u8 data_len = 0;
- //u8 hid_report_map_len = sizeof(report_map);
- switch (attribute_handle) {
- #if 0
- case BLE_HID_HANDLE_MAP:
- if (buffer) {
- data_len = (buffer_size < (hid_report_map_len - offset))? buffer_size: (hid_report_map_len - offset);
- memcpy(buffer, report_map + offset, data_len);
- TRACE("Read Request - handle: 0x%04x len: %d data:\n", attribute_handle, buffer_size);
- TRACE_R(buffer, buffer_size);
- } else {
- data_len = hid_report_map_len;
- }
- break;
- case BLE_HID_HANDLE_REP_CONSUMER_CCC:
- if (buffer) {
- TRACE("Read CCC Consumer - val: 0x%04x\n", hid_report_client_config_consumer);
- data_len = 2;
- memcpy(buffer, (u8 *)&hid_report_client_config_consumer, 2);
- } else {
- data_len = 2;
- }
- break;
- case BLE_HID_HANDLE_REP_KEYBOARD_CCC:
- if (buffer) {
- TRACE("Read CCC Keyboard - val: 0x%04x\n", hid_report_client_config_keyboard);
- data_len = 2;
- memcpy(buffer, (u8 *)&hid_report_client_config_keyboard, 2);
- } else {
- data_len = 2;
- }
- break;
- case BLE_HID_HANDLE_REP_MOUSE_CCC:
- if (buffer) {
- TRACE("Read CCC Mouse - val: 0x%04x\n", hid_report_client_config_mouse);
- data_len = 2;
- memcpy(buffer, (u8 *)&hid_report_client_config_mouse, 2);
- } else {
- data_len = 2;
- }
- break;
- case BLE_HID_HANDLE_REP_CONSUMER:
- case BLE_HID_HANDLE_REP_KEYBOARD:
- case BLE_HID_HANDLE_REP_MOUSE:
- if (buffer) {
- /* Response default value that all zere */
- hid_rep_info_t hid_rep_info;
- memset(&hid_rep_info, 0x00, sizeof(hid_rep_info));
- data_len = sizeof(hid_rep_info.pdu);
- TRACE("Read Val - handle: 0x%04x val[%d]: ", attribute_handle, data_len);
- TRACE_R(&hid_rep_info.pdu, data_len);
- } else {
- hid_rep_info_t hid_rep_info;
- data_len = sizeof(hid_rep_info.pdu);
- }
- break;
- #endif // 0
- default:
- TRACE("No process read - handle: 0x%04x\n", attribute_handle);
- break;
- }
- return data_len;
- }
- static int hid_service_write_callback(uint16_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size)
- {
- switch (attribute_handle) {
- case BLE_HID_HANDLE_CTRL_POINT:
- /* 0: suspend 1: exit suspend, maybe not used because some central will disc when sleep */
- TRACE("Write Suspend status - val: 0x%02x\n", buffer[0]);
- break;
- case BLE_HID_HANDLE_REP_CONSUMER_CCC:
- hid_report_client_config_consumer = GET_LE16(buffer);
- TRACE("Write CCC Consumer - val: 0x%04x\n", hid_report_client_config_consumer);
- break;
- case BLE_HID_HANDLE_REP_KEYBOARD_CCC:
- hid_report_client_config_keyboard = GET_LE16(buffer);
- TRACE("Write CCC Keyboard - val: 0x%04x\n", hid_report_client_config_keyboard);
- break;
- //case BLE_HID_HANDLE_REP_MOUSE_CCC:
- // hid_report_client_config_mouse = GET_LE16(buffer);
- // TRACE("Write CCC Mouse - val: 0x%04x\n", hid_report_client_config_mouse);
- // break;
- case BLE_HID_HANDLE_REP_LED:
- break;
- default:
- TRACE("No process write - handle: 0x%04x\n", attribute_handle);
- break;
- }
- return ATT_ERR_NO_ERR;
- }
- int ble_hid_mouse_report(hid_rep_info_t *param)
- {
- //uint16_t handle;
- int ret = -1;
- //if (param->report_id == HID_REP_ID_CONSUMER) {
- // handle = BLE_HID_HANDLE_REP_CONSUMER;
- //} else if (param->report_id == HID_REP_ID_KEYBOARD) {
- // handle = BLE_HID_HANDLE_REP_KEYBOARD;
- //} else if (param->report_id == HID_REP_ID_MOUSE) {
- // handle = BLE_HID_HANDLE_REP_MOUSE;
- //} else {
- // return ret;
- //}
- // TRACE("Report - handle: 0x%04x data[%d]: ", handle, sizeof(param->pdu));
- // TRACE_R(¶m->pdu, sizeof(param->pdu));
- /* Some Central-Device do not subscribe again after being connected back. Do not determine the client config here */
- // TODO: The CCCD value shall be persistent across connections for bonded devices.
- lowpwr_pwroff_delay_reset();
- lowpwr_sleep_delay_reset();
- /*Prevent acl buffer is full before connection really success when report mouse data*/
- //if (!hid_report_client_config_mouse && (handle == BLE_HID_HANDLE_REP_MOUSE)) {
- // return ret;
- //}
- /*Prevent acl buffer is full before connection really success*/
- //if (!txpkt_is_full(&ble_tx)) {
- // ret = ble_notify_for_handle(hid_connect_handle, handle, (u8 *)¶m->pdu, sizeof(param->pdu));
- //}
- return ret;
- }
- void ble_hid_service_init(void)
- {
- printf("%s\n", __func__);
- hid_service.start_handle = ATT_SERVICE_1812_START_HANDLE;
- hid_service.end_handle = ATT_SERVICE_1812_END_HANDLE;
- hid_service.read_callback = &hid_service_read_callback;
- hid_service.write_callback = &hid_service_write_callback;
- hid_service.event_handler = &hid_service_event_packet_handle;
- att_server_register_service_handler(&hid_service);
- hid_report_client_config_consumer = CCCD_DFT;
- hid_report_client_config_keyboard = CCCD_DFT;
- hid_report_client_config_mouse = CCCD_DFT;
- memset(&ble_hid_state, 0x00, sizeof(ble_hid_state));
- }
- void ble_hid_service_proc(void)
- {
- if (hid_connect_handle) {
- if (ble_hid_state.ready) {
- } else {
- /* Retry */
- ble_hid_state.ready = (0 == ble_hid_mouse_report(&ble_hid_state.data));
- }
- }
- }
- void ble_hid_set_mouse_cccd()
- {
- hid_report_client_config_mouse = 1;
- }
|