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     bta_hh_snd_write_dev(dev_handle, HID_TRANS_DATA, (UINT8)p_data->layer_specific, 0, 0, p_data);
    309 }
    310 
    311 /*******************************************************************************
    312 **
    313 ** Function         BTA_HhGetDscpInfo
    314 **
    315 ** Description      Get HID device report descriptor
    316 **
    317 ** Returns          void
    318 **
    319 *******************************************************************************/
    320 void BTA_HhGetDscpInfo(UINT8 dev_handle)
    321 {
    322     BT_HDR    *p_buf;
    323 
    324     if ((p_buf = (BT_HDR *)GKI_getbuf((UINT16)sizeof(BT_HDR))) != NULL)
    325     {
    326         memset(p_buf, 0, sizeof(BT_HDR));
    327         p_buf->event            = BTA_HH_API_GET_DSCP_EVT;
    328         p_buf->layer_specific   = (UINT16) dev_handle;
    329 
    330         bta_sys_sendmsg(p_buf);
    331     }
    332 }
    333 
    334 /*******************************************************************************
    335 **
    336 ** Function         BTA_HhAddDev
    337 **
    338 ** Description      Add a virtually cabled device into HID-Host device list
    339 **                  to manage and assign a device handle for future API call,
    340 **                  host applciation call this API at start-up to initialize its
    341 **                  virtually cabled devices.
    342 **
    343 ** Returns          void
    344 **
    345 *******************************************************************************/
    346 void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, UINT8 sub_class,
    347                   UINT8 app_id, tBTA_HH_DEV_DSCP_INFO dscp_info)
    348 {
    349     tBTA_HH_MAINT_DEV    *p_buf;
    350     UINT16  len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len;
    351 
    352     p_buf = (tBTA_HH_MAINT_DEV *)GKI_getbuf(len);
    353 
    354     if (p_buf != NULL)
    355     {
    356         memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
    357 
    358         p_buf->hdr.event            = BTA_HH_API_MAINT_DEV_EVT;
    359         p_buf->sub_event            = BTA_HH_ADD_DEV_EVT;
    360         p_buf->hdr.layer_specific   = BTA_HH_INVALID_HANDLE;
    361 
    362         p_buf->attr_mask            = (UINT16) attr_mask;
    363         p_buf->sub_class            = sub_class;
    364         p_buf->app_id               = app_id;
    365         bdcpy(p_buf->bda, bda);
    366 
    367         memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO));
    368         if ( dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list)
    369         {
    370             p_buf->dscp_info.descriptor.dl_len =  dscp_info.descriptor.dl_len;
    371             p_buf->dscp_info.descriptor.dsc_list = (UINT8 *)(p_buf + 1);
    372             memcpy(p_buf->dscp_info.descriptor.dsc_list, dscp_info.descriptor.dsc_list, dscp_info.descriptor.dl_len);
    373         }
    374         else
    375         {
    376             p_buf->dscp_info.descriptor.dsc_list = NULL;
    377             p_buf->dscp_info.descriptor.dl_len = 0;
    378         }
    379 
    380         bta_sys_sendmsg(p_buf);
    381     }
    382 }
    383 /*******************************************************************************
    384 **
    385 ** Function         BTA_HhRemoveDev
    386 **
    387 ** Description      Remove a device from the HID host devices list.
    388 **
    389 ** Returns          void
    390 **
    391 *******************************************************************************/
    392 void BTA_HhRemoveDev(UINT8 dev_handle )
    393 {
    394     tBTA_HH_MAINT_DEV    *p_buf;
    395 
    396     p_buf = (tBTA_HH_MAINT_DEV *)GKI_getbuf((UINT16)sizeof(tBTA_HH_MAINT_DEV));
    397 
    398     if (p_buf != NULL)
    399     {
    400         memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
    401 
    402         p_buf->hdr.event            = BTA_HH_API_MAINT_DEV_EVT;
    403         p_buf->sub_event            = BTA_HH_RMV_DEV_EVT;
    404         p_buf->hdr.layer_specific   = (UINT16) dev_handle;
    405 
    406         bta_sys_sendmsg(p_buf);
    407     }
    408 }
    409 
    410 /*******************************************************************************/
    411 /*                          Utility Function                                   */
    412 /*******************************************************************************/
    413 
    414 /*******************************************************************************
    415 **
    416 ** Function         BTA_HhParseBootRpt
    417 **
    418 ** Description      This utility function parse a boot mode report.
    419 **                  For keyboard report, report data will carry the keycode max
    420 **                  up to 6 key press in one report. Application need to convert
    421 **                  the keycode into keypress character according to keyboard
    422 **                  language.
    423 **
    424 ** Returns          void
    425 **
    426 *******************************************************************************/
    427 void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report,
    428                         UINT16 report_len)
    429 {
    430     p_data->dev_type = BTA_HH_DEVT_UNKNOWN;
    431 
    432     if (p_report)
    433     {
    434         /* first byte is report ID */
    435         switch (p_report[0])
    436         {
    437         case BTA_HH_KEYBD_RPT_ID: /* key board report ID */
    438             p_data->dev_type = p_report[0];
    439             bta_hh_parse_keybd_rpt(p_data, p_report + 1, (UINT16)(report_len -1));
    440             break;
    441 
    442         case BTA_HH_MOUSE_RPT_ID: /* mouse report ID */
    443             p_data->dev_type = p_report[0];
    444             bta_hh_parse_mice_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
    445             break;
    446 
    447         default:
    448             APPL_TRACE_DEBUG1("Unknown boot report: %d", p_report[0]);;
    449             break;
    450         }
    451     }
    452 
    453     return;
    454 }
    455 
    456 #endif /* BTA_HH_INCLUDED */
    457