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