1 /******************************************************************************
2 *
3 * Copyright (C) 2005-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains the HID HOST API in the subsystem of BTA.
22 *
23 ******************************************************************************/
24
25 #include "common/bt_target.h"
26
27 #if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdio.h>
32
33 #include "bta/bta_hh_api.h"
34 #include "bta_hh_int.h"
35 #include "stack/l2c_api.h"
36 #include "bta/utl.h"
37
38 #include "osi/allocator.h"
39
40 /*****************************************************************************
41 ** Constants
42 *****************************************************************************/
43
44 static const tBTA_SYS_REG bta_hh_reg = {
45 bta_hh_hdl_event,
46 BTA_HhDisable
47 };
48
49 /*******************************************************************************
50 **
51 ** Function BTA_HhEnable
52 **
53 ** Description Enable the HID host. This function must be called before
54 ** any other functions in the HID host API are called. When the
55 ** enable operation is complete the callback function will be
56 ** called with BTA_HH_ENABLE_EVT.
57 **
58 **
59 ** Returns void
60 **
61 *******************************************************************************/
BTA_HhEnable(tBTA_SEC sec_mask,tBTA_HH_CBACK * p_cback)62 void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
63 {
64 tBTA_HH_API_ENABLE *p_buf;
65
66 /* register with BTA system manager */
67 bta_sys_register(BTA_ID_HH, &bta_hh_reg);
68
69 APPL_TRACE_API("%s sec_mask:0x%x p_cback:%p", __func__, sec_mask, p_cback);
70 p_buf = (tBTA_HH_API_ENABLE *)osi_malloc((UINT16)sizeof(tBTA_HH_API_ENABLE));
71
72 if (p_buf != NULL) {
73 memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));
74
75 p_buf->hdr.event = BTA_HH_API_ENABLE_EVT;
76 p_buf->p_cback = p_cback;
77 p_buf->sec_mask = sec_mask;
78
79 bta_sys_sendmsg(p_buf);
80 }
81 }
82
83 /*******************************************************************************
84 **
85 ** Function BTA_HhDisable
86 **
87 ** Description Disable the HID host. If the server is currently
88 ** connected, the connection will be closed.
89 **
90 ** Returns void
91 **
92 *******************************************************************************/
BTA_HhDisable(void)93 void BTA_HhDisable(void)
94 {
95 BT_HDR *p_buf;
96
97 bta_sys_deregister(BTA_ID_HH);
98 if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
99 p_buf->event = BTA_HH_API_DISABLE_EVT;
100 bta_sys_sendmsg(p_buf);
101 }
102 }
103
104 /*******************************************************************************
105 **
106 ** Function BTA_HhClose
107 **
108 ** Description Disconnect a connection.
109 **
110 ** Returns void
111 **
112 *******************************************************************************/
BTA_HhClose(UINT8 dev_handle)113 void BTA_HhClose(UINT8 dev_handle)
114 {
115 BT_HDR *p_buf;
116
117 if ((p_buf = (BT_HDR *)osi_malloc((UINT16)sizeof(BT_HDR))) != NULL) {
118 memset(p_buf, 0, sizeof(BT_HDR));
119 p_buf->event = BTA_HH_API_CLOSE_EVT;
120 p_buf->layer_specific = (UINT16) dev_handle;
121
122 bta_sys_sendmsg(p_buf);
123 }
124 }
125
126 /*******************************************************************************
127 **
128 ** Function BTA_HhOpen
129 **
130 ** Description Connect to a device of specified BD address in specified
131 ** protocol mode and security level.
132 **
133 ** Returns void
134 **
135 *******************************************************************************/
BTA_HhOpen(BD_ADDR dev_bda,tBTA_HH_PROTO_MODE mode,tBTA_SEC sec_mask)136 void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, tBTA_SEC sec_mask)
137 {
138 tBTA_HH_API_CONN *p_buf;
139
140 p_buf = (tBTA_HH_API_CONN *)osi_malloc((UINT16)sizeof(tBTA_HH_API_CONN));
141
142 if (p_buf != NULL) {
143 memset((void *)p_buf, 0, sizeof(tBTA_HH_API_CONN));
144
145 p_buf->hdr.event = BTA_HH_API_OPEN_EVT;
146 p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
147 p_buf->sec_mask = sec_mask;
148 p_buf->mode = mode;
149 bdcpy(p_buf->bd_addr, dev_bda);
150
151 bta_sys_sendmsg((void *)p_buf);
152 } else {
153 APPL_TRACE_ERROR("No resource to send HID host Connect request.");
154 }
155 }
156
157 /*******************************************************************************
158 **
159 ** Function bta_hh_snd_write_dev
160 **
161 *******************************************************************************/
bta_hh_snd_write_dev(UINT8 dev_handle,UINT8 t_type,UINT8 param,UINT16 data,UINT8 rpt_id,BT_HDR * p_data)162 static void bta_hh_snd_write_dev(UINT8 dev_handle, UINT8 t_type, UINT8 param,
163 UINT16 data, UINT8 rpt_id, BT_HDR *p_data)
164 {
165 tBTA_HH_CMD_DATA *p_buf;
166 UINT16 len = (UINT16) (sizeof(tBTA_HH_CMD_DATA) );
167
168 if ((p_buf = (tBTA_HH_CMD_DATA *)osi_malloc(len)) != NULL) {
169 memset(p_buf, 0, sizeof(tBTA_HH_CMD_DATA));
170
171 p_buf->hdr.event = BTA_HH_API_WRITE_DEV_EVT;
172 p_buf->hdr.layer_specific = (UINT16) dev_handle;
173 p_buf->t_type = t_type;
174 p_buf->data = data;
175 p_buf->param = param;
176 p_buf->p_data = p_data;
177 p_buf->rpt_id = rpt_id;
178
179 bta_sys_sendmsg(p_buf);
180 }
181 }
182 /*******************************************************************************
183 **
184 ** Function BTA_HhSetReport
185 **
186 ** Description send SET_REPORT to device.
187 **
188 ** Parameter dev_handle: device handle
189 ** r_type: report type, could be BTA_HH_RPTT_OUTPUT or
190 ** BTA_HH_RPTT_FEATURE.
191 ** Returns void
192 **
193 *******************************************************************************/
BTA_HhSetReport(UINT8 dev_handle,tBTA_HH_RPT_TYPE r_type,BT_HDR * p_data)194 void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, BT_HDR *p_data)
195 {
196 bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_REPORT, r_type, 0, 0, p_data);
197 }
198 /*******************************************************************************
199 **
200 ** Function BTA_HhGetReport
201 **
202 ** Description Send a GET_REPORT to HID device.
203 **
204 ** Returns void
205 **
206 *******************************************************************************/
BTA_HhGetReport(UINT8 dev_handle,tBTA_HH_RPT_TYPE r_type,UINT8 rpt_id,UINT16 buf_size)207 void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, UINT8 rpt_id, UINT16 buf_size)
208 {
209 UINT8 param = (buf_size) ? (r_type | 0x08) : r_type;
210
211 bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_REPORT, param,
212 buf_size, rpt_id, NULL);
213 }
214 /*******************************************************************************
215 **
216 ** Function BTA_HhSetProtoMode
217 **
218 ** Description This function set the protocol mode at specified HID handle
219 **
220 ** Returns void
221 **
222 *******************************************************************************/
BTA_HhSetProtoMode(UINT8 dev_handle,tBTA_HH_PROTO_MODE p_type)223 void BTA_HhSetProtoMode(UINT8 dev_handle, tBTA_HH_PROTO_MODE p_type)
224 {
225 bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_PROTOCOL, (UINT8)p_type,
226 0, 0, NULL);
227 }
228 /*******************************************************************************
229 **
230 ** Function BTA_HhGetProtoMode
231 **
232 ** Description This function get protocol mode information.
233 **
234 ** Returns void
235 **
236 *******************************************************************************/
BTA_HhGetProtoMode(UINT8 dev_handle)237 void BTA_HhGetProtoMode(UINT8 dev_handle)
238 {
239 bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_PROTOCOL, 0, 0, 0, NULL);
240 }
241 /*******************************************************************************
242 **
243 ** Function BTA_HhSetIdle
244 **
245 ** Description send SET_IDLE to device.
246 **
247 ** Returns void
248 **
249 *******************************************************************************/
BTA_HhSetIdle(UINT8 dev_handle,UINT16 idle_rate)250 void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate)
251 {
252 bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_IDLE, 0, idle_rate, 0, NULL);
253 }
254
255 /*******************************************************************************
256 **
257 ** Function BTA_HhGetIdle
258 **
259 ** Description Send a GET_IDLE from HID device.
260 **
261 ** Returns void
262 **
263 *******************************************************************************/
BTA_HhGetIdle(UINT8 dev_handle)264 void BTA_HhGetIdle(UINT8 dev_handle)
265 {
266 bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_IDLE, 0, 0, 0, NULL);
267 }
268 /*******************************************************************************
269 **
270 ** Function BTA_HhSendCtrl
271 **
272 ** Description Send a control command to HID device.
273 **
274 ** Returns void
275 **
276 *******************************************************************************/
BTA_HhSendCtrl(UINT8 dev_handle,tBTA_HH_TRANS_CTRL_TYPE c_type)277 void BTA_HhSendCtrl(UINT8 dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type)
278 {
279 bta_hh_snd_write_dev(dev_handle, HID_TRANS_CONTROL, (UINT8)c_type, 0, 0, NULL);
280 }
281 /*******************************************************************************
282 **
283 ** Function BTA_HhSendData
284 **
285 ** Description This function send DATA transaction to HID device.
286 **
287 ** Parameter dev_handle: device handle
288 ** dev_bda: remote device address
289 ** p_data: data to be sent in the DATA transaction; or
290 ** the data to be write into the Output Report of a LE HID
291 ** device. The report is identified the report ID which is
292 ** the value of the byte (UINT8 *)(p_buf + 1) + p_buf->offset.
293 ** p_data->layer_specific needs to be set to the report type,
294 ** it can be OUTPUT report, or FEATURE report.
295 **
296 ** Returns void
297 **
298 *******************************************************************************/
BTA_HhSendData(UINT8 dev_handle,BD_ADDR dev_bda,BT_HDR * p_data)299 void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_data)
300 {
301 UNUSED(dev_bda);
302 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
303 if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT) {
304 APPL_TRACE_ERROR("ERROR! Wrong report type! Write Command only valid for output report!");
305 return;
306 }
307 #endif
308 bta_hh_snd_write_dev(dev_handle, HID_TRANS_DATA, (UINT8)p_data->layer_specific, 0, 0, p_data);
309 }
310
311 /*******************************************************************************
312 **
313 ** Function BTA_HhGetDscpInfo
314 **
315 ** Description Get HID device report descriptor
316 **
317 ** Returns void
318 **
319 *******************************************************************************/
BTA_HhGetDscpInfo(UINT8 dev_handle)320 void BTA_HhGetDscpInfo(UINT8 dev_handle)
321 {
322 BT_HDR *p_buf;
323
324 if ((p_buf = (BT_HDR *)osi_malloc((UINT16)sizeof(BT_HDR))) != NULL) {
325 memset(p_buf, 0, sizeof(BT_HDR));
326 p_buf->event = BTA_HH_API_GET_DSCP_EVT;
327 p_buf->layer_specific = (UINT16) dev_handle;
328
329 bta_sys_sendmsg(p_buf);
330 }
331 }
332
333 /*******************************************************************************
334 **
335 ** Function BTA_HhAddDev
336 **
337 ** Description Add a virtually cabled device into HID-Host device list
338 ** to manage and assign a device handle for future API call,
339 ** host applciation call this API at start-up to initialize its
340 ** virtually cabled devices.
341 **
342 ** Returns void
343 **
344 *******************************************************************************/
BTA_HhAddDev(BD_ADDR bda,tBTA_HH_ATTR_MASK attr_mask,UINT8 sub_class,UINT8 app_id,tBTA_HH_DEV_DSCP_INFO dscp_info)345 void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, UINT8 sub_class,
346 UINT8 app_id, tBTA_HH_DEV_DSCP_INFO dscp_info)
347 {
348 tBTA_HH_MAINT_DEV *p_buf;
349 UINT16 len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len;
350
351 p_buf = (tBTA_HH_MAINT_DEV *)osi_malloc(len);
352
353 if (p_buf != NULL) {
354 memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
355
356 p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
357 p_buf->sub_event = BTA_HH_ADD_DEV_EVT;
358 p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
359
360 p_buf->attr_mask = (UINT16) attr_mask;
361 p_buf->sub_class = sub_class;
362 p_buf->app_id = app_id;
363 bdcpy(p_buf->bda, bda);
364
365 memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO));
366 if ( dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list) {
367 p_buf->dscp_info.descriptor.dl_len = dscp_info.descriptor.dl_len;
368 p_buf->dscp_info.descriptor.dsc_list = (UINT8 *)(p_buf + 1);
369 memcpy(p_buf->dscp_info.descriptor.dsc_list, dscp_info.descriptor.dsc_list, dscp_info.descriptor.dl_len);
370 } else {
371 p_buf->dscp_info.descriptor.dsc_list = NULL;
372 p_buf->dscp_info.descriptor.dl_len = 0;
373 }
374
375 bta_sys_sendmsg(p_buf);
376 }
377 }
378 /*******************************************************************************
379 **
380 ** Function BTA_HhRemoveDev
381 **
382 ** Description Remove a device from the HID host devices list.
383 **
384 ** Returns void
385 **
386 *******************************************************************************/
BTA_HhRemoveDev(UINT8 dev_handle)387 void BTA_HhRemoveDev(UINT8 dev_handle )
388 {
389 tBTA_HH_MAINT_DEV *p_buf;
390
391 p_buf = (tBTA_HH_MAINT_DEV *)osi_malloc((UINT16)sizeof(tBTA_HH_MAINT_DEV));
392
393 if (p_buf != NULL) {
394 memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
395
396 p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
397 p_buf->sub_event = BTA_HH_RMV_DEV_EVT;
398 p_buf->hdr.layer_specific = (UINT16) dev_handle;
399
400 bta_sys_sendmsg(p_buf);
401 }
402 }
403 #if BTA_HH_LE_INCLUDED == TRUE
404
405 /*******************************************************************************
406 **
407 ** Function BTA_HhUpdateLeScanParam
408 **
409 ** Description Update the scan paramteters if connected to a LE hid device as
410 ** report host.
411 **
412 ** Returns void
413 **
414 *******************************************************************************/
BTA_HhUpdateLeScanParam(UINT8 dev_handle,UINT16 scan_int,UINT16 scan_win)415 void BTA_HhUpdateLeScanParam(UINT8 dev_handle, UINT16 scan_int, UINT16 scan_win)
416 {
417 tBTA_HH_SCPP_UPDATE *p_buf;
418
419 p_buf = (tBTA_HH_SCPP_UPDATE *)osi_malloc((UINT16)sizeof(tBTA_HH_SCPP_UPDATE));
420
421 if (p_buf != NULL) {
422 memset(p_buf, 0, sizeof(tBTA_HH_SCPP_UPDATE));
423
424 p_buf->hdr.event = BTA_HH_API_SCPP_UPDATE_EVT;
425 p_buf->hdr.layer_specific = (UINT16) dev_handle;
426 p_buf->scan_int = scan_int;
427 p_buf->scan_win = scan_win;
428
429 bta_sys_sendmsg(p_buf);
430 }
431 }
432 #endif
433 /*******************************************************************************/
434 /* Utility Function */
435 /*******************************************************************************/
436
437 /*******************************************************************************
438 **
439 ** Function BTA_HhParseBootRpt
440 **
441 ** Description This utility function parse a boot mode report.
442 ** For keyboard report, report data will carry the keycode max
443 ** up to 6 key press in one report. Application need to convert
444 ** the keycode into keypress character according to keyboard
445 ** language.
446 **
447 ** Returns void
448 **
449 *******************************************************************************/
BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT * p_data,UINT8 * p_report,UINT16 report_len)450 void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report,
451 UINT16 report_len)
452 {
453 p_data->dev_type = BTA_HH_DEVT_UNKNOWN;
454
455 if (p_report) {
456 /* first byte is report ID */
457 switch (p_report[0]) {
458 case BTA_HH_KEYBD_RPT_ID: /* key board report ID */
459 p_data->dev_type = p_report[0];
460 bta_hh_parse_keybd_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
461 break;
462
463 case BTA_HH_MOUSE_RPT_ID: /* mouse report ID */
464 p_data->dev_type = p_report[0];
465 bta_hh_parse_mice_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
466 break;
467
468 default:
469 APPL_TRACE_DEBUG("Unknown boot report: %d", p_report[0]);;
470 break;
471 }
472 }
473
474 return;
475 }
476
477 #endif /* BTA_HH_INCLUDED */
478