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 
     37 /*****************************************************************************
     38 **  Constants
     39 *****************************************************************************/
     40 
     41 static const tBTA_SYS_REG bta_hh_reg =
     42 {
     43     bta_hh_hdl_event,
     44     BTA_HhDisable
     45 };
     46 
     47 /*******************************************************************************
     48 **
     49 ** Function         BTA_HhEnable
     50 **
     51 ** Description      Enable the HID host.  This function must be called before
     52 **                  any other functions in the HID host API are called. When the
     53 **                  enable operation is complete the callback function will be
     54 **                  called with BTA_HH_ENABLE_EVT.
     55 **
     56 **
     57 ** Returns          void
     58 **
     59 *******************************************************************************/
     60 void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
     61 {
     62     tBTA_HH_API_ENABLE *p_buf;
     63 
     64     /* register with BTA system manager */
     65     GKI_sched_lock();
     66     bta_sys_register(BTA_ID_HH, &bta_hh_reg);
     67     GKI_sched_unlock();
     68 
     69     APPL_TRACE_ERROR0("Calling BTA_HhEnable");
     70     p_buf = (tBTA_HH_API_ENABLE *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_ENABLE));
     71 
     72     if (p_buf != NULL)
     73     {
     74         memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));
     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 **
     86 ** Function         BTA_HhDisable
     87 **
     88 ** Description      Disable the HID host. If the server is currently
     89 **                  connected, the connection will be closed.
     90 **
     91 ** Returns          void
     92 **
     93 *******************************************************************************/
     94 void BTA_HhDisable(void)
     95 {
     96     BT_HDR  *p_buf;
     97 
     98     bta_sys_deregister(BTA_ID_HH);
     99     if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR))) != NULL)
    100     {
    101         p_buf->event = BTA_HH_API_DISABLE_EVT;
    102         bta_sys_sendmsg(p_buf);
    103     }
    104 }
    105 
    106 /*******************************************************************************
    107 **
    108 ** Function         BTA_HhClose
    109 **
    110 ** Description      Disconnect a connection.
    111 **
    112 ** Returns          void
    113 **
    114 *******************************************************************************/
    115 void BTA_HhClose(UINT8 dev_handle)
    116 {
    117     BT_HDR    *p_buf;
    118 
    119     if ((p_buf = (BT_HDR *)GKI_getbuf((UINT16)sizeof(BT_HDR))) != NULL)
    120     {
    121         memset(p_buf, 0, sizeof(BT_HDR));
    122         p_buf->event            = BTA_HH_API_CLOSE_EVT;
    123         p_buf->layer_specific   = (UINT16) dev_handle;
    124 
    125         bta_sys_sendmsg(p_buf);
    126     }
    127 }
    128 
    129 /*******************************************************************************
    130 **
    131 ** Function         BTA_HhOpen
    132 **
    133 ** Description      Connect to a device of specified BD address in specified
    134 **                  protocol mode and security level.
    135 **
    136 ** Returns          void
    137 **
    138 *******************************************************************************/
    139 void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, tBTA_SEC sec_mask)
    140 {
    141     tBTA_HH_API_CONN *p_buf;
    142 
    143     p_buf = (tBTA_HH_API_CONN *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_CONN));
    144 
    145     if (p_buf!= NULL)
    146     {
    147         memset((void *)p_buf, 0, sizeof(tBTA_HH_API_CONN));
    148 
    149         p_buf->hdr.event            = BTA_HH_API_OPEN_EVT;
    150         p_buf->hdr.layer_specific   = BTA_HH_INVALID_HANDLE;
    151         p_buf->sec_mask             = sec_mask;
    152         p_buf->mode                 = mode;
    153         bdcpy(p_buf->bd_addr, dev_bda);
    154 
    155         bta_sys_sendmsg((void *)p_buf);
    156     }
    157     else
    158     {
    159         APPL_TRACE_ERROR0("No resource to send HID host Connect request.");
    160     }
    161 }
    162 
    163 /*******************************************************************************
    164 **
    165 ** Function  bta_hh_snd_write_dev
    166 **
    167 *******************************************************************************/
    168 static void bta_hh_snd_write_dev(UINT8 dev_handle, UINT8 t_type, UINT8 param,
    169                                  UINT16 data, UINT8 rpt_id, BT_HDR  *p_data)
    170 {
    171     tBTA_HH_CMD_DATA *p_buf;
    172     UINT16          len = (UINT16) (sizeof(tBTA_HH_CMD_DATA) );
    173 
    174     if ((p_buf = (tBTA_HH_CMD_DATA *)GKI_getbuf(len))!= NULL)
    175     {
    176         memset(p_buf, 0, sizeof(tBTA_HH_CMD_DATA));
    177 
    178         p_buf->hdr.event = BTA_HH_API_WRITE_DEV_EVT;
    179         p_buf->hdr.layer_specific   = (UINT16) dev_handle;
    180         p_buf->t_type   = t_type;
    181         p_buf->data     = data;
    182         p_buf->param    = param;
    183         p_buf->p_data   = p_data;
    184         p_buf->rpt_id   = rpt_id;
    185 
    186         bta_sys_sendmsg(p_buf);
    187     }
    188 }
    189 /*******************************************************************************
    190 **
    191 ** Function         BTA_HhSetReport
    192 **
    193 ** Description      send SET_REPORT to device.
    194 **
    195 ** Parameter        dev_handle: device handle
    196 **                  r_type:     report type, could be BTA_HH_RPTT_OUTPUT or
    197 **                              BTA_HH_RPTT_FEATURE.
    198 ** Returns          void
    199 **
    200 *******************************************************************************/
    201 void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, BT_HDR *p_data)
    202 {
    203     bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_REPORT, r_type, 0, 0, p_data);
    204 }
    205 /*******************************************************************************
    206 **
    207 ** Function         BTA_HhGetReport
    208 **
    209 ** Description      Send a GET_REPORT to HID device.
    210 **
    211 ** Returns          void
    212 **
    213 *******************************************************************************/
    214 void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, UINT8 rpt_id, UINT16 buf_size)
    215 {
    216     UINT8 param = (buf_size) ? (r_type | 0x08) : r_type;
    217 
    218     bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_REPORT, param,
    219                         buf_size, rpt_id, NULL);
    220 }
    221 /*******************************************************************************
    222 **
    223 ** Function         BTA_HhSetProtoMode
    224 **
    225 ** Description      This function set the protocol mode at specified HID handle
    226 **
    227 ** Returns          void
    228 **
    229 *******************************************************************************/
    230 void BTA_HhSetProtoMode(UINT8 dev_handle, tBTA_HH_PROTO_MODE p_type)
    231 {
    232     bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_PROTOCOL, (UINT8)p_type,
    233                         0, 0, NULL);
    234 }
    235 /*******************************************************************************
    236 **
    237 ** Function         BTA_HhGetProtoMode
    238 **
    239 ** Description      This function get protocol mode information.
    240 **
    241 ** Returns          void
    242 **
    243 *******************************************************************************/
    244 void BTA_HhGetProtoMode(UINT8 dev_handle)
    245 {
    246     bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_PROTOCOL, 0, 0, 0, NULL);
    247 }
    248 /*******************************************************************************
    249 **
    250 ** Function         BTA_HhSetIdle
    251 **
    252 ** Description      send SET_IDLE to device.
    253 **
    254 ** Returns          void
    255 **
    256 *******************************************************************************/
    257 void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate)
    258 {
    259     bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_IDLE, 0, idle_rate, 0, NULL);
    260 }
    261 
    262 /*******************************************************************************
    263 **
    264 ** Function         BTA_HhGetIdle
    265 **
    266 ** Description      Send a GET_IDLE from HID device.
    267 **
    268 ** Returns          void
    269 **
    270 *******************************************************************************/
    271 void BTA_HhGetIdle(UINT8 dev_handle)
    272 {
    273     bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_IDLE, 0, 0, 0, NULL);
    274 }
    275 /*******************************************************************************
    276 **
    277 ** Function         BTA_HhSendCtrl
    278 **
    279 ** Description      Send a control command to HID device.
    280 **
    281 ** Returns          void
    282 **
    283 *******************************************************************************/
    284 void BTA_HhSendCtrl(UINT8 dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type)
    285 {
    286     bta_hh_snd_write_dev(dev_handle, HID_TRANS_CONTROL, (UINT8)c_type, 0, 0, NULL);
    287 }
    288 /*******************************************************************************
    289 **
    290 ** Function         BTA_HhSendData
    291 **
    292 ** Description      This function send DATA transaction to HID device.
    293 **
    294 ** Parameter        dev_handle: device handle
    295 **                  dev_bda: remote device address
    296 **                  p_data: data to be sent in the DATA transaction; or
    297 **                          the data to be write into the Output Report of a LE HID
    298 **                          device. The report is identified the report ID which is
    299 **                          the value of the byte (UINT8 *)(p_buf + 1) + p_buf->offset.
    300 **                          p_data->layer_specific needs to be set to the report type,
    301 **                          it can be OUTPUT report, or FEATURE report.
    302 **
    303 ** Returns          void
    304 **
    305 *******************************************************************************/
    306 void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR  *p_data)
    307 {
    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_ERROR0("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_DEBUG1("Unknown boot report: %d", p_report[0]);;
    486             break;
    487         }
    488     }
    489 
    490     return;
    491 }
    492 
    493 #endif /* BTA_HH_INCLUDED */
    494