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