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