OSDN Git Service

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