Home | History | Annotate | Download | only in hh
      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         (tBTA_HH_API_ENABLE *)osi_calloc(sizeof(tBTA_HH_API_ENABLE));
     69 
     70     LOG_INFO(LOG_TAG, "%s sec_mask:0x%x p_cback:%p", __func__, sec_mask,
     71              p_cback);
     72 
     73     /* register with BTA system manager */
     74     bta_sys_register(BTA_ID_HH, &bta_hh_reg);
     75 
     76     p_buf->hdr.event = BTA_HH_API_ENABLE_EVT;
     77     p_buf->p_cback = p_cback;
     78     p_buf->sec_mask = sec_mask;
     79 
     80     bta_sys_sendmsg(p_buf);
     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 *******************************************************************************/
     93 void BTA_HhDisable(void)
     94 {
     95     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR));
     96 
     97     bta_sys_deregister(BTA_ID_HH);
     98     p_buf->event = BTA_HH_API_DISABLE_EVT;
     99 
    100     bta_sys_sendmsg(p_buf);
    101 }
    102 
    103 /*******************************************************************************
    104 **
    105 ** Function         BTA_HhClose
    106 **
    107 ** Description      Disconnect a connection.
    108 **
    109 ** Returns          void
    110 **
    111 *******************************************************************************/
    112 void BTA_HhClose(UINT8 dev_handle)
    113 {
    114     BT_HDR *p_buf = (BT_HDR *)osi_calloc(sizeof(BT_HDR));
    115 
    116     p_buf->event = BTA_HH_API_CLOSE_EVT;
    117     p_buf->layer_specific = (UINT16)dev_handle;
    118 
    119     bta_sys_sendmsg(p_buf);
    120 }
    121 
    122 /*******************************************************************************
    123 **
    124 ** Function         BTA_HhOpen
    125 **
    126 ** Description      Connect to a device of specified BD address in specified
    127 **                  protocol mode and security level.
    128 **
    129 ** Returns          void
    130 **
    131 *******************************************************************************/
    132 void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, tBTA_SEC sec_mask)
    133 {
    134     tBTA_HH_API_CONN *p_buf =
    135         (tBTA_HH_API_CONN *)osi_calloc(sizeof(tBTA_HH_API_CONN));
    136 
    137     p_buf->hdr.event = BTA_HH_API_OPEN_EVT;
    138     p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
    139     p_buf->sec_mask = sec_mask;
    140     p_buf->mode = mode;
    141     bdcpy(p_buf->bd_addr, dev_bda);
    142 
    143     bta_sys_sendmsg((void *)p_buf);
    144 }
    145 
    146 /*******************************************************************************
    147 **
    148 ** Function  bta_hh_snd_write_dev
    149 **
    150 *******************************************************************************/
    151 static void bta_hh_snd_write_dev(UINT8 dev_handle, UINT8 t_type, UINT8 param,
    152                                  UINT16 data, UINT8 rpt_id, BT_HDR  *p_data)
    153 {
    154     tBTA_HH_CMD_DATA *p_buf =
    155         (tBTA_HH_CMD_DATA *)osi_calloc(sizeof(tBTA_HH_CMD_DATA));
    156 
    157     p_buf->hdr.event = BTA_HH_API_WRITE_DEV_EVT;
    158     p_buf->hdr.layer_specific = (UINT16)dev_handle;
    159     p_buf->t_type = t_type;
    160     p_buf->data = data;
    161     p_buf->param = param;
    162     p_buf->p_data = p_data;
    163     p_buf->rpt_id = rpt_id;
    164 
    165     bta_sys_sendmsg(p_buf);
    166 }
    167 
    168 /*******************************************************************************
    169 **
    170 ** Function         BTA_HhSetReport
    171 **
    172 ** Description      send SET_REPORT to device.
    173 **
    174 ** Parameter        dev_handle: device handle
    175 **                  r_type:     report type, could be BTA_HH_RPTT_OUTPUT or
    176 **                              BTA_HH_RPTT_FEATURE.
    177 ** Returns          void
    178 **
    179 *******************************************************************************/
    180 void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, BT_HDR *p_data)
    181 {
    182     bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_REPORT, r_type, 0, 0, p_data);
    183 }
    184 /*******************************************************************************
    185 **
    186 ** Function         BTA_HhGetReport
    187 **
    188 ** Description      Send a GET_REPORT to HID device.
    189 **
    190 ** Returns          void
    191 **
    192 *******************************************************************************/
    193 void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, UINT8 rpt_id, UINT16 buf_size)
    194 {
    195     UINT8 param = (buf_size) ? (r_type | 0x08) : r_type;
    196 
    197     bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_REPORT, param,
    198                         buf_size, rpt_id, NULL);
    199 }
    200 /*******************************************************************************
    201 **
    202 ** Function         BTA_HhSetProtoMode
    203 **
    204 ** Description      This function set the protocol mode at specified HID handle
    205 **
    206 ** Returns          void
    207 **
    208 *******************************************************************************/
    209 void BTA_HhSetProtoMode(UINT8 dev_handle, tBTA_HH_PROTO_MODE p_type)
    210 {
    211     bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_PROTOCOL, (UINT8)p_type,
    212                         0, 0, NULL);
    213 }
    214 /*******************************************************************************
    215 **
    216 ** Function         BTA_HhGetProtoMode
    217 **
    218 ** Description      This function get protocol mode information.
    219 **
    220 ** Returns          void
    221 **
    222 *******************************************************************************/
    223 void BTA_HhGetProtoMode(UINT8 dev_handle)
    224 {
    225     bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_PROTOCOL, 0, 0, 0, NULL);
    226 }
    227 /*******************************************************************************
    228 **
    229 ** Function         BTA_HhSetIdle
    230 **
    231 ** Description      send SET_IDLE to device.
    232 **
    233 ** Returns          void
    234 **
    235 *******************************************************************************/
    236 void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate)
    237 {
    238     bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_IDLE, 0, idle_rate, 0, NULL);
    239 }
    240 
    241 /*******************************************************************************
    242 **
    243 ** Function         BTA_HhGetIdle
    244 **
    245 ** Description      Send a GET_IDLE from HID device.
    246 **
    247 ** Returns          void
    248 **
    249 *******************************************************************************/
    250 void BTA_HhGetIdle(UINT8 dev_handle)
    251 {
    252     bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_IDLE, 0, 0, 0, NULL);
    253 }
    254 /*******************************************************************************
    255 **
    256 ** Function         BTA_HhSendCtrl
    257 **
    258 ** Description      Send a control command to HID device.
    259 **
    260 ** Returns          void
    261 **
    262 *******************************************************************************/
    263 void BTA_HhSendCtrl(UINT8 dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type)
    264 {
    265     bta_hh_snd_write_dev(dev_handle, HID_TRANS_CONTROL, (UINT8)c_type, 0, 0, NULL);
    266 }
    267 /*******************************************************************************
    268 **
    269 ** Function         BTA_HhSendData
    270 **
    271 ** Description      This function send DATA transaction to HID device.
    272 **
    273 ** Parameter        dev_handle: device handle
    274 **                  dev_bda: remote device address
    275 **                  p_data: data to be sent in the DATA transaction; or
    276 **                          the data to be write into the Output Report of a LE HID
    277 **                          device. The report is identified the report ID which is
    278 **                          the value of the byte (UINT8 *)(p_buf + 1) + p_buf->offset.
    279 **                          p_data->layer_specific needs to be set to the report type,
    280 **                          it can be OUTPUT report, or FEATURE report.
    281 **
    282 ** Returns          void
    283 **
    284 *******************************************************************************/
    285 void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR  *p_data)
    286 {
    287     UNUSED(dev_bda);
    288 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    289     if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT)
    290     {
    291         APPL_TRACE_ERROR("ERROR! Wrong report type! Write Command only valid for output report!");
    292         return;
    293     }
    294 #endif
    295     bta_hh_snd_write_dev(dev_handle, HID_TRANS_DATA, (UINT8)p_data->layer_specific, 0, 0, p_data);
    296 }
    297 
    298 /*******************************************************************************
    299 **
    300 ** Function         BTA_HhGetDscpInfo
    301 **
    302 ** Description      Get HID device report descriptor
    303 **
    304 ** Returns          void
    305 **
    306 *******************************************************************************/
    307 void BTA_HhGetDscpInfo(UINT8 dev_handle)
    308 {
    309     BT_HDR *p_buf = (BT_HDR *)osi_calloc(sizeof(BT_HDR));
    310 
    311     p_buf->event = BTA_HH_API_GET_DSCP_EVT;
    312     p_buf->layer_specific = (UINT16)dev_handle;
    313 
    314     bta_sys_sendmsg(p_buf);
    315 }
    316 
    317 /*******************************************************************************
    318 **
    319 ** Function         BTA_HhAddDev
    320 **
    321 ** Description      Add a virtually cabled device into HID-Host device list
    322 **                  to manage and assign a device handle for future API call,
    323 **                  host applciation call this API at start-up to initialize its
    324 **                  virtually cabled devices.
    325 **
    326 ** Returns          void
    327 **
    328 *******************************************************************************/
    329 void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, UINT8 sub_class,
    330                   UINT8 app_id, tBTA_HH_DEV_DSCP_INFO dscp_info)
    331 {
    332     size_t len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len;
    333     tBTA_HH_MAINT_DEV *p_buf = (tBTA_HH_MAINT_DEV *)osi_calloc(len);
    334 
    335     p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
    336     p_buf->sub_event = BTA_HH_ADD_DEV_EVT;
    337     p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
    338 
    339     p_buf->attr_mask = (UINT16) attr_mask;
    340     p_buf->sub_class = sub_class;
    341     p_buf->app_id = app_id;
    342     bdcpy(p_buf->bda, bda);
    343 
    344     memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO));
    345     if ( dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list) {
    346         p_buf->dscp_info.descriptor.dl_len =  dscp_info.descriptor.dl_len;
    347         p_buf->dscp_info.descriptor.dsc_list = (UINT8 *)(p_buf + 1);
    348         memcpy(p_buf->dscp_info.descriptor.dsc_list,
    349                dscp_info.descriptor.dsc_list,
    350                dscp_info.descriptor.dl_len);
    351     } else {
    352       p_buf->dscp_info.descriptor.dsc_list = NULL;
    353       p_buf->dscp_info.descriptor.dl_len = 0;
    354     }
    355 
    356     bta_sys_sendmsg(p_buf);
    357 }
    358 
    359 /*******************************************************************************
    360 **
    361 ** Function         BTA_HhRemoveDev
    362 **
    363 ** Description      Remove a device from the HID host devices list.
    364 **
    365 ** Returns          void
    366 **
    367 *******************************************************************************/
    368 void BTA_HhRemoveDev(UINT8 dev_handle )
    369 {
    370     tBTA_HH_MAINT_DEV *p_buf =
    371         (tBTA_HH_MAINT_DEV *)osi_calloc(sizeof(tBTA_HH_MAINT_DEV));
    372 
    373     p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
    374     p_buf->sub_event = BTA_HH_RMV_DEV_EVT;
    375     p_buf->hdr.layer_specific = (UINT16)dev_handle;
    376 
    377     bta_sys_sendmsg(p_buf);
    378 }
    379 
    380 #if BTA_HH_LE_INCLUDED == TRUE
    381 
    382 /*******************************************************************************
    383 **
    384 ** Function         BTA_HhUpdateLeScanParam
    385 **
    386 ** Description      Update the scan paramteters if connected to a LE hid device as
    387 **                  report host.
    388 **
    389 ** Returns          void
    390 **
    391 *******************************************************************************/
    392 void BTA_HhUpdateLeScanParam(UINT8 dev_handle, UINT16 scan_int, UINT16 scan_win)
    393 {
    394     tBTA_HH_SCPP_UPDATE *p_buf =
    395         (tBTA_HH_SCPP_UPDATE *)osi_calloc(sizeof(tBTA_HH_SCPP_UPDATE));
    396 
    397     p_buf->hdr.event = BTA_HH_API_SCPP_UPDATE_EVT;
    398     p_buf->hdr.layer_specific = (UINT16)dev_handle;
    399     p_buf->scan_int = scan_int;
    400     p_buf->scan_win = scan_win;
    401 
    402     bta_sys_sendmsg(p_buf);
    403 }
    404 #endif
    405 
    406 /*******************************************************************************/
    407 /*                          Utility Function                                   */
    408 /*******************************************************************************/
    409 
    410 /*******************************************************************************
    411 **
    412 ** Function         BTA_HhParseBootRpt
    413 **
    414 ** Description      This utility function parse a boot mode report.
    415 **                  For keyboard report, report data will carry the keycode max
    416 **                  up to 6 key press in one report. Application need to convert
    417 **                  the keycode into keypress character according to keyboard
    418 **                  language.
    419 **
    420 ** Returns          void
    421 **
    422 *******************************************************************************/
    423 void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report,
    424                         UINT16 report_len)
    425 {
    426     p_data->dev_type = BTA_HH_DEVT_UNKNOWN;
    427 
    428     if (p_report)
    429     {
    430         /* first byte is report ID */
    431         switch (p_report[0])
    432         {
    433         case BTA_HH_KEYBD_RPT_ID: /* key board report ID */
    434             p_data->dev_type = p_report[0];
    435             bta_hh_parse_keybd_rpt(p_data, p_report + 1, (UINT16)(report_len -1));
    436             break;
    437 
    438         case BTA_HH_MOUSE_RPT_ID: /* mouse report ID */
    439             p_data->dev_type = p_report[0];
    440             bta_hh_parse_mice_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
    441             break;
    442 
    443         default:
    444             APPL_TRACE_DEBUG("Unknown boot report: %d", p_report[0]);;
    445             break;
    446         }
    447     }
    448 
    449     return;
    450 }
    451 
    452 #endif /* BTA_HH_INCLUDED */
    453