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