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