1/****************************************************************************** 2 * 3 * Copyright (C) 2009-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 is the implementation file for the HeaLth device profile (HL) 22 * subsystem call-out functions. 23 * 24 ******************************************************************************/ 25 26#include <ctype.h> 27#include <errno.h> 28#include <fcntl.h> 29#include <stdio.h> 30#include <stdlib.h> 31#include <string.h> 32#include <sys/socket.h> 33#include <sys/types.h> 34#include <sys/un.h> 35#include <time.h> 36 37#include "bta_api.h" 38#include "bta_hl_api.h" 39#include "bta_hl_ci.h" 40#include "bta_hl_co.h" 41#include "bta_sys.h" 42#include "btif_hl.h" 43#include "btif_util.h" 44#include "btm_api.h" 45#include "osi/include/osi.h" 46 47/***************************************************************************** 48 * Constants and Data Types 49 ****************************************************************************/ 50/************************** 51 * Common Definitions 52 **************************/ 53 54/******************************************************************************* 55 * 56 * Function bta_hl_co_get_num_of_mdep 57 * 58 * Description This function is called to get the number of MDEPs for this 59 * application ID 60 * 61 * Parameters app_id - application ID 62 * p_num_of_mdep (output) - number of MDEP configurations 63 * supported by the application 64 * 65 * Returns true on success 66 * 67 ******************************************************************************/ 68bool bta_hl_co_get_num_of_mdep(uint8_t app_id, uint8_t* p_num_of_mdep) { 69 uint8_t app_idx; 70 bool success = false; 71 72 if (btif_hl_find_app_idx(app_id, &app_idx)) { 73 *p_num_of_mdep = p_btif_hl_cb->acb[app_idx].sup_feature.num_of_mdeps; 74 success = true; 75 } 76 77 BTIF_TRACE_DEBUG("%s success=%d num_mdeps=%d", __func__, success, 78 *p_num_of_mdep); 79 return success; 80} 81 82/******************************************************************************* 83 * 84 * Function bta_hl_co_advrtise_source_sdp 85 * 86 * Description This function is called to find out whether the SOURCE MDEP 87 * configuration information should be advertise in the SDP or 88 * not. 89 * 90 * Parameters app_id - application ID 91 * 92 * Returns true when advertise the SOURCE MDEP configuration 93 * information 94 * 95 ******************************************************************************/ 96bool bta_hl_co_advrtise_source_sdp(uint8_t app_id) { 97 bool advertize_source_sdp = false; 98 uint8_t app_idx; 99 100 if (btif_hl_find_app_idx(app_id, &app_idx)) { 101 advertize_source_sdp = 102 p_btif_hl_cb->acb[app_idx].sup_feature.advertize_source_sdp; 103 } 104 105 BTIF_TRACE_DEBUG("%s advertize_flag=%d", __func__, advertize_source_sdp); 106 107 return advertize_source_sdp; 108} 109/******************************************************************************* 110 * 111 * Function bta_hl_co_get_mdep_config 112 * 113 * Description This function is called to get the supported feature 114 * configuration for the specified mdep index and it also 115 * assigns the MDEP ID for the specified mdep index 116 * 117 * Parameters app_id - HDP application ID 118 * mdep_idx - the mdep index 119 * mdep_counter - number of mdeps 120 * mdep_id - the assigned MDEP ID for the specified medp_idx 121 * p_mdl_cfg (output) - pointer to the MDEP configuration 122 * 123 * 124 * Returns Bloolean - true success 125 ******************************************************************************/ 126bool bta_hl_co_get_mdep_config(uint8_t app_id, uint8_t mdep_idx, 127 uint8_t mdep_counter, tBTA_HL_MDEP_ID mdep_id, 128 tBTA_HL_MDEP_CFG* p_mdep_cfg) { 129 uint8_t idx; 130 uint8_t app_idx; 131 bool success = false; 132 133 BTIF_TRACE_DEBUG("%s app_id=%d mdep_idx=%d mdep_id=%d mdep_counter=%d", 134 __func__, app_id, mdep_idx, mdep_id, mdep_counter); 135 136 if (btif_hl_find_app_idx(app_id, &app_idx)) { 137 idx = mdep_idx - mdep_counter - 1; 138 p_btif_hl_cb->acb[app_idx].sup_feature.mdep[idx].mdep_id = mdep_id; 139 memcpy(p_mdep_cfg, 140 &p_btif_hl_cb->acb[app_idx].sup_feature.mdep[idx].mdep_cfg, 141 sizeof(tBTA_HL_MDEP_CFG)); 142 143 success = true; 144 } 145 146 BTIF_TRACE_DEBUG("%s success=%d mdep_idx=%d mdep_id=%d", __func__, success, 147 mdep_idx, mdep_id); 148 149 return success; 150} 151 152/******************************************************************************* 153 * 154 * Function bta_hl_co_get_echo_config 155 * 156 * Description This function is called to get the echo test 157 * maximum APDU size configurations 158 * 159 * Parameters app_id - HDP application ID 160 * p_echo_cfg (output) - pointer to the Echo test maximum APDU 161 * size configuration 162 * 163 * Returns Bloolean - true success 164 ******************************************************************************/ 165bool bta_hl_co_get_echo_config(uint8_t app_id, tBTA_HL_ECHO_CFG* p_echo_cfg) { 166 uint8_t app_idx; 167 bool success = false; 168 btif_hl_app_cb_t* p_acb; 169 tBTA_HL_SUP_FEATURE* p_sup; 170 171 BTIF_TRACE_DEBUG("%s app_id=%d", __func__, app_id); 172 173 if (btif_hl_find_app_idx(app_id, &app_idx)) { 174 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 175 p_sup = &p_acb->sup_feature; 176 p_echo_cfg->max_rx_apdu_size = p_sup->echo_cfg.max_rx_apdu_size; 177 p_echo_cfg->max_tx_apdu_size = p_sup->echo_cfg.max_tx_apdu_size; 178 success = true; 179 } 180 181 BTIF_TRACE_DEBUG("%s success=%d max tx_size=%d rx_size=%d", __func__, success, 182 p_echo_cfg->max_tx_apdu_size, p_echo_cfg->max_rx_apdu_size); 183 184 return success; 185} 186 187/******************************************************************************* 188 * 189 * Function bta_hl_co_save_mdl 190 * 191 * Description This function is called to save a MDL configuration item in 192 * persistent storage 193 * 194 * Parameters app_id - HDP application ID 195 * item_idx - the MDL configuration storage index 196 * p_mdl_cfg - pointer to the MDL configuration data 197 * 198 * Returns void 199 * 200 ******************************************************************************/ 201void bta_hl_co_save_mdl(uint8_t mdep_id, uint8_t item_idx, 202 tBTA_HL_MDL_CFG* p_mdl_cfg) { 203 BTIF_TRACE_DEBUG("%s mdep_id =%d, item_idx=%d active=%d mdl_id=%d time=%d", 204 __func__, mdep_id, item_idx, p_mdl_cfg->active, 205 p_mdl_cfg->mdl_id, p_mdl_cfg->time); 206 207 btif_hl_save_mdl_cfg(mdep_id, item_idx, p_mdl_cfg); 208} 209 210/******************************************************************************* 211 * 212 * Function bta_hl_co_delete_mdl 213 * 214 * Description This function is called to delete a MDL configuration item in 215 * persistent storage 216 * 217 * Parameters app_id - HDP application ID 218 * item_idx - the MDL configuration storage index 219 * 220 * Returns void 221 * 222 ******************************************************************************/ 223void bta_hl_co_delete_mdl(uint8_t mdep_id, uint8_t item_idx) { 224 BTIF_TRACE_DEBUG("%s mdep_id=%d, item_idx=%d", __func__, mdep_id, item_idx); 225 226 btif_hl_delete_mdl_cfg(mdep_id, item_idx); 227} 228 229/******************************************************************************* 230 * 231 * Function bta_hl_co_get_mdl_config 232 * 233 * Description This function is called to get the MDL configuration 234 * from the persistent memory. This function shall only be 235 * called once after the device is powered up 236 * 237 * Parameters app_id - HDP application ID 238 * buffer_size - the unit of the buffer size is 239 * sizeof(tBTA_HL_MDL_CFG) 240 * p_mdl_buf - Point to the starting location of the buffer 241 * 242 * Returns bool 243 * 244 * 245 ******************************************************************************/ 246bool bta_hl_co_load_mdl_config(uint8_t app_id, uint8_t buffer_size, 247 tBTA_HL_MDL_CFG* p_mdl_buf) { 248 bool result = true; 249 uint8_t i; 250 tBTA_HL_MDL_CFG* p; 251 252 BTIF_TRACE_DEBUG("%s app_id=%d, num_items=%d", __func__, app_id, buffer_size); 253 254 if (buffer_size > BTA_HL_NUM_MDL_CFGS) { 255 result = false; 256 return result; 257 } 258 result = btif_hl_load_mdl_config(app_id, buffer_size, p_mdl_buf); 259 260 if (result) { 261 for (i = 0, p = p_mdl_buf; i < buffer_size; i++, p++) { 262 if (p->active) { 263 BTIF_TRACE_DEBUG( 264 "i=%d mdl_id=0x%x dch_mode=%d local mdep_role=%d mdep_id=%d mtu=%d", 265 i, p->mdl_id, p->dch_mode, p->local_mdep_role, p->local_mdep_role, 266 p->mtu); 267 } 268 } 269 } 270 271 BTIF_TRACE_DEBUG("%s success=%d num_items=%d", __func__, result, buffer_size); 272 273 return result; 274} 275 276/******************************************************************************* 277 * 278 * Function bta_hl_co_get_tx_data 279 * 280 * Description Get the data to be sent 281 * 282 * Parameters app_id - HDP application ID 283 * mdl_handle - MDL handle 284 * buf_size - the size of the buffer 285 * p_buf - the buffer pointer 286 * evt - the evt to be passed back to the HL in the 287 * bta_hl_ci_get_tx_data call-in function 288 * 289 * Returns Void 290 * 291 ******************************************************************************/ 292void bta_hl_co_get_tx_data(uint8_t app_id, tBTA_HL_MDL_HANDLE mdl_handle, 293 uint16_t buf_size, uint8_t* p_buf, uint16_t evt) { 294 uint8_t app_idx, mcl_idx, mdl_idx; 295 btif_hl_mdl_cb_t* p_dcb; 296 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL; 297 298 BTIF_TRACE_DEBUG("%s app_id=%d mdl_handle=0x%x buf_size=%d", __func__, app_id, 299 mdl_handle, buf_size); 300 301 if (btif_hl_find_mdl_idx_using_handle(mdl_handle, &app_idx, &mcl_idx, 302 &mdl_idx)) { 303 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 304 305 if ((p_dcb->tx_size <= buf_size) && p_dcb->p_tx_pkt) { 306 memcpy(p_buf, p_dcb->p_tx_pkt, p_dcb->tx_size); 307 osi_free_and_reset((void**)&p_dcb->p_tx_pkt); 308 p_dcb->tx_size = 0; 309 status = BTA_HL_STATUS_OK; 310 } 311 } 312 313 bta_hl_ci_get_tx_data(mdl_handle, status, evt); 314} 315 316/******************************************************************************* 317 * 318 * Function bta_hl_co_put_rx_data 319 * 320 * Description Put the received data 321 * 322 * Parameters app_id - HDP application ID 323 * mdl_handle - MDL handle 324 * data_size - the size of the data 325 * p_data - the data pointer 326 * evt - the evt to be passed back to the HL in the 327 * bta_hl_ci_put_rx_data call-in function 328 * 329 * Returns Void 330 * 331 ******************************************************************************/ 332void bta_hl_co_put_rx_data(uint8_t app_id, tBTA_HL_MDL_HANDLE mdl_handle, 333 uint16_t data_size, uint8_t* p_data, uint16_t evt) { 334 uint8_t app_idx, mcl_idx, mdl_idx; 335 btif_hl_mdl_cb_t* p_dcb; 336 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL; 337 BTIF_TRACE_DEBUG("%s app_id=%d mdl_handle=0x%x data_size=%d", __func__, 338 app_id, mdl_handle, data_size); 339 340 if (btif_hl_find_mdl_idx_using_handle(mdl_handle, &app_idx, &mcl_idx, 341 &mdl_idx)) { 342 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 343 344 p_dcb->p_rx_pkt = (uint8_t*)osi_malloc(data_size); 345 memcpy(p_dcb->p_rx_pkt, p_data, data_size); 346 if (p_dcb->p_scb) { 347 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=0x%x mdl_idx=0x%x data_size=%d", 348 app_idx, mcl_idx, mdl_idx, data_size); 349 ssize_t r; 350 OSI_NO_INTR( 351 r = send(p_dcb->p_scb->socket_id[1], p_dcb->p_rx_pkt, data_size, 0)); 352 if (r == data_size) { 353 BTIF_TRACE_DEBUG("socket send success data_size=%d", data_size); 354 status = BTA_HL_STATUS_OK; 355 } else { 356 BTIF_TRACE_ERROR("socket send failed r=%d data_size=%d", r, data_size); 357 } 358 } 359 osi_free_and_reset((void**)&p_dcb->p_rx_pkt); 360 } 361 362 bta_hl_ci_put_rx_data(mdl_handle, status, evt); 363} 364 365/******************************************************************************* 366 * 367 * Function bta_hl_co_get_tx_data 368 * 369 * Description Get the Echo data to be sent 370 * 371 * Parameters app_id - HDP application ID 372 * mcl_handle - MCL handle 373 * buf_size - the size of the buffer 374 * p_buf - the buffer pointer 375 * evt - the evt to be passed back to the HL in the 376 * bta_hl_ci_get_tx_data call-in function 377 * 378 * Returns Void 379 * 380 ******************************************************************************/ 381void bta_hl_co_get_echo_data(UNUSED_ATTR uint8_t app_id, 382 tBTA_HL_MCL_HANDLE mcl_handle, 383 UNUSED_ATTR uint16_t buf_size, 384 UNUSED_ATTR uint8_t* p_buf, uint16_t evt) { 385 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL; 386 387 BTIF_TRACE_ERROR("%s not supported", __func__); 388 bta_hl_ci_get_echo_data(mcl_handle, status, evt); 389} 390 391/******************************************************************************* 392 * 393 * Function bta_hl_co_put_echo_data 394 * 395 * Description Put the received loopback echo data 396 * 397 * Parameters app_id - HDP application ID 398 * mcl_handle - MCL handle 399 * data_size - the size of the data 400 * p_data - the data pointer 401 * evt - the evt to be passed back to the HL in the 402 * bta_hl_ci_put_echo_data call-in function 403 * 404 * Returns Void 405 * 406 ******************************************************************************/ 407void bta_hl_co_put_echo_data(UNUSED_ATTR uint8_t app_id, 408 tBTA_HL_MCL_HANDLE mcl_handle, 409 UNUSED_ATTR uint16_t data_size, 410 UNUSED_ATTR uint8_t* p_data, uint16_t evt) { 411 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL; 412 413 BTIF_TRACE_ERROR("%s not supported", __func__); 414 bta_hl_ci_put_echo_data(mcl_handle, status, evt); 415} 416