1 #include "btc_hh.h"
2 #include "osi/allocator.h"
3 #include "string.h"
4 #if HID_HOST_INCLUDED == TRUE
5 
6 /*******************************************************************************
7  *
8  * Function      bta_hh_co_open
9  *
10  * Description   When connection is opened, this call-out function is executed
11  *               by HH to do platform specific initialization.
12  *
13  * Returns       void.
14  ******************************************************************************/
bta_hh_co_open(uint8_t dev_handle,uint8_t sub_class,tBTA_HH_ATTR_MASK attr_mask,uint8_t app_id)15 void bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, tBTA_HH_ATTR_MASK attr_mask, uint8_t app_id)
16 {
17     uint32_t i;
18     btc_hh_device_t *p_dev = NULL;
19 
20     if (dev_handle == BTA_HH_INVALID_HANDLE) {
21         APPL_TRACE_WARNING("%s: Oops, dev_handle (%d) is invalid...", __func__, dev_handle);
22         return;
23     }
24 
25     for (i = 0; i < BTC_HH_MAX_HID; i++) {
26         p_dev = &btc_hh_cb.devices[i];
27         if (p_dev->dev_status != ESP_HIDH_CONN_STATE_UNKNOWN && p_dev->dev_handle == dev_handle) {
28             // We found a device with the same handle. Must be a device reconnected.
29             APPL_TRACE_WARNING("%s: Found an existing device with the same handle dev_status=%d, "
30                                "dev_handle=0x%2x, attr_mask=0x%04x, sub_class=0x%02x, app_id=%d",
31                                __func__, p_dev->dev_status, dev_handle, p_dev->attr_mask, p_dev->sub_class,
32                                p_dev->app_id);
33             break;
34         }
35         p_dev = NULL;
36     }
37 
38     if (p_dev == NULL) {
39         // Did not find a device reconnection case. Find an empty slot now.
40         for (i = 0; i < BTC_HH_MAX_HID; i++) {
41             if (btc_hh_cb.devices[i].dev_status == ESP_HIDH_CONN_STATE_UNKNOWN) {
42                 p_dev = &btc_hh_cb.devices[i];
43                 p_dev->dev_handle = dev_handle;
44                 p_dev->attr_mask = attr_mask;
45                 p_dev->sub_class = sub_class;
46                 p_dev->app_id = app_id;
47                 p_dev->local_vup = false;
48 
49                 btc_hh_cb.device_num++;
50                 break;
51             }
52         }
53     }
54 
55     if (p_dev == NULL) {
56         APPL_TRACE_ERROR("%s: Error: too many HID devices are connected", __func__);
57         return;
58     }
59 
60     p_dev->dev_status = ESP_HIDH_CONN_STATE_CONNECTED;
61     APPL_TRACE_DEBUG("%s: Return device status %d", __func__, p_dev->dev_status);
62 }
63 
64 /*******************************************************************************
65  *
66  * Function      bta_hh_co_close
67  *
68  * Description   When connection is closed, this call-out function is executed
69  *               by HH to do platform specific finalization.
70  *
71  * Parameters    dev_handle  - device handle
72  *                  app_id      - application id
73  *
74  * Returns          void.
75  ******************************************************************************/
bta_hh_co_close(uint8_t dev_handle,uint8_t app_id)76 void bta_hh_co_close(uint8_t dev_handle, uint8_t app_id)
77 {
78     uint32_t i;
79     btc_hh_device_t *p_dev = NULL;
80 
81     APPL_TRACE_WARNING("%s: dev_handle = %d, app_id = %d", __func__, dev_handle, app_id);
82     if (dev_handle == BTA_HH_INVALID_HANDLE) {
83         APPL_TRACE_WARNING("%s: Oops, dev_handle (%d) is invalid...", __func__, dev_handle);
84         return;
85     }
86 
87     for (i = 0; i < BTC_HH_MAX_HID; i++) {
88         p_dev = &btc_hh_cb.devices[i];
89         if (p_dev->dev_status != ESP_HIDH_CONN_STATE_UNKNOWN && p_dev->dev_handle == dev_handle) {
90             APPL_TRACE_WARNING("%s: Found an existing device with the same handle "
91                                "dev_status = %d, dev_handle =%d",
92                                __func__, p_dev->dev_status, p_dev->dev_handle);
93             break;
94         }
95     }
96 }
97 
98 /*******************************************************************************
99  *
100  * Function         bta_hh_co_data
101  *
102  * Description      This function is executed by BTA when HID host receive a
103  *                  data report on interrupt channel.
104  *
105  * Parameters       dev_handle  - device handle
106  *                  *p_rpt      - pointer to the report data
107  *                  len         - length of report data
108  *                  mode        - Hid host Protocol Mode
109  *                  sub_clas    - Device Subclass
110  *                  app_id      - application id
111  *
112  * Returns          void
113  ******************************************************************************/
bta_hh_co_data(UINT8 dev_handle,UINT8 * p_rpt,UINT16 len,tBTA_HH_PROTO_MODE mode,UINT8 sub_class,UINT8 ctry_code,BD_ADDR peer_addr,UINT8 app_id)114 void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len, tBTA_HH_PROTO_MODE mode, UINT8 sub_class, UINT8 ctry_code,
115                BD_ADDR peer_addr, UINT8 app_id)
116 {
117     btc_msg_t msg;
118     tBTA_HH p_data;
119     BT_HDR *p_buf = NULL;
120     bt_status_t status;
121     tBTA_HH_STATUS ret = BTA_HH_OK;
122 
123     msg.sig = BTC_SIG_API_CB;
124     msg.pid = BTC_PID_HH;
125     msg.act = BTA_HH_DATA_IND_EVT;
126 
127     APPL_TRACE_DEBUG("%s: dev_handle = %d, subclass = 0x%02X, mode = %d, "
128                      "ctry_code = %d, app_id = %d",
129                      __func__, dev_handle, sub_class, mode, ctry_code, app_id);
130 
131     do {
132         if ((p_buf = osi_malloc(sizeof(BT_HDR) + len)) == NULL) {
133             APPL_TRACE_ERROR("%s malloc failed!", __func__);
134             ret = BTA_HH_ERR_NO_RES;
135             break;
136         }
137         p_buf->offset = 0;
138         p_buf->len = len;
139         p_buf->event = 0;
140         p_buf->layer_specific = dev_handle;
141         memcpy(p_buf->data, p_rpt, len);
142     } while (0);
143 
144     p_data.int_data.status = ret;
145     p_data.int_data.handle = dev_handle;
146     p_data.int_data.p_data = p_buf;
147     p_data.int_data.proto_mode = mode;
148     status = btc_transfer_context(&msg, &p_data, sizeof(tBTA_HH), NULL, NULL);
149     assert(status == BT_STATUS_SUCCESS);
150 }
151 
152 #endif /* HID_HOST_INCLUDED == TRUE */
153