1 /****************************************************************************** 2 * 3 * Copyright 2003-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 GATT Server action functions for the state 22 * machine. 23 * 24 ******************************************************************************/ 25 26 #include "bt_target.h" 27 28 #include <base/logging.h> 29 #include <string.h> 30 #include "bt_common.h" 31 #include "bta_gatts_co.h" 32 #include "bta_gatts_int.h" 33 #include "bta_sys.h" 34 #include "btif/include/btif_debug_conn.h" 35 #include "btm_ble_api.h" 36 #include "osi/include/osi.h" 37 #include "utl.h" 38 39 using base::StringPrintf; 40 41 static void bta_gatts_nv_save_cback(bool is_saved, 42 tGATTS_HNDL_RANGE* p_hndl_range); 43 static bool bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, 44 tGATTS_SRV_CHG_REQ* p_req, 45 tGATTS_SRV_CHG_RSP* p_rsp); 46 47 static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bda, 48 uint16_t conn_id, bool connected, 49 tGATT_DISCONN_REASON reason, 50 tGATT_TRANSPORT transport); 51 static void bta_gatts_send_request_cback(uint16_t conn_id, uint32_t trans_id, 52 tGATTS_REQ_TYPE req_type, 53 tGATTS_DATA* p_data); 54 static void bta_gatts_cong_cback(uint16_t conn_id, bool congested); 55 static void bta_gatts_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id, 56 uint8_t tx_phy, uint8_t rx_phy, 57 uint8_t status); 58 static void bta_gatts_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id, 59 uint16_t interval, uint16_t latency, 60 uint16_t timeout, uint8_t status); 61 62 static tGATT_CBACK bta_gatts_cback = {bta_gatts_conn_cback, 63 NULL, 64 NULL, 65 NULL, 66 bta_gatts_send_request_cback, 67 NULL, 68 bta_gatts_cong_cback, 69 bta_gatts_phy_update_cback, 70 bta_gatts_conn_update_cback}; 71 72 tGATT_APPL_INFO bta_gatts_nv_cback = {bta_gatts_nv_save_cback, 73 bta_gatts_nv_srv_chg_cback}; 74 75 /******************************************************************************* 76 * 77 * Function bta_gatts_nv_save_cback 78 * 79 * Description NV save callback function. 80 * 81 * Parameter is_add: true is to add a handle range; otherwise is to 82 * delete. 83 * Returns none. 84 * 85 ******************************************************************************/ 86 static void bta_gatts_nv_save_cback(bool is_add, 87 tGATTS_HNDL_RANGE* p_hndl_range) { 88 bta_gatts_co_update_handle_range(is_add, 89 (tBTA_GATTS_HNDL_RANGE*)p_hndl_range); 90 } 91 92 /******************************************************************************* 93 * 94 * Function bta_gatts_nv_srv_chg_cback 95 * 96 * Description NV save callback function. 97 * 98 * Parameter is_add: true is to add a handle range; otherwise is to 99 * delete. 100 * Returns none. 101 * 102 ******************************************************************************/ 103 static bool bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, 104 tGATTS_SRV_CHG_REQ* p_req, 105 tGATTS_SRV_CHG_RSP* p_rsp) { 106 return bta_gatts_co_srv_chg((tGATTS_SRV_CHG_CMD)cmd, 107 (tGATTS_SRV_CHG_REQ*)p_req, 108 (tGATTS_SRV_CHG_RSP*)p_rsp); 109 } 110 111 /******************************************************************************* 112 * 113 * Function bta_gatts_enable 114 * 115 * Description enable BTA GATTS module. 116 * 117 * Returns none. 118 * 119 ******************************************************************************/ 120 void bta_gatts_enable(tBTA_GATTS_CB* p_cb) { 121 uint8_t index = 0; 122 tBTA_GATTS_HNDL_RANGE handle_range; 123 124 if (p_cb->enabled) { 125 VLOG(1) << "GATTS already enabled."; 126 } else { 127 memset(p_cb, 0, sizeof(tBTA_GATTS_CB)); 128 129 p_cb->enabled = true; 130 131 while (bta_gatts_co_load_handle_range(index, &handle_range)) { 132 GATTS_AddHandleRange((tGATTS_HNDL_RANGE*)&handle_range); 133 memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE)); 134 index++; 135 } 136 137 VLOG(1) << __func__ << ": num of handle range added:" << +index; 138 139 if (!GATTS_NVRegister(&bta_gatts_nv_cback)) { 140 LOG(ERROR) << "BTA GATTS NV register failed."; 141 } 142 } 143 } 144 145 /******************************************************************************* 146 * 147 * Function bta_gatts_api_disable 148 * 149 * Description disable BTA GATTS module. 150 * 151 * Returns none. 152 * 153 ******************************************************************************/ 154 void bta_gatts_api_disable(tBTA_GATTS_CB* p_cb) { 155 uint8_t i; 156 157 if (p_cb->enabled) { 158 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) { 159 if (p_cb->rcb[i].in_use) { 160 GATT_Deregister(p_cb->rcb[i].gatt_if); 161 } 162 } 163 memset(p_cb, 0, sizeof(tBTA_GATTS_CB)); 164 } else { 165 LOG(ERROR) << "GATTS not enabled"; 166 } 167 } 168 169 /******************************************************************************* 170 * 171 * Function bta_gatts_register 172 * 173 * Description register an application. 174 * 175 * Returns none. 176 * 177 ******************************************************************************/ 178 void bta_gatts_register(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { 179 tBTA_GATTS cb_data; 180 tGATT_STATUS status = GATT_SUCCESS; 181 uint8_t i, first_unuse = 0xff; 182 183 if (!p_cb->enabled) { 184 bta_gatts_enable(p_cb); 185 } 186 187 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) { 188 if (p_cb->rcb[i].in_use) { 189 if (p_cb->rcb[i].app_uuid == p_msg->api_reg.app_uuid) { 190 LOG(ERROR) << "application already registered."; 191 status = GATT_DUP_REG; 192 break; 193 } 194 } 195 } 196 197 if (status == GATT_SUCCESS) { 198 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) { 199 if (first_unuse == 0xff && !p_cb->rcb[i].in_use) { 200 first_unuse = i; 201 break; 202 } 203 } 204 205 cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF; 206 cb_data.reg_oper.uuid = p_msg->api_reg.app_uuid; 207 if (first_unuse != 0xff) { 208 LOG(INFO) << "register application first_unuse rcb_idx=" << +first_unuse; 209 210 p_cb->rcb[first_unuse].in_use = true; 211 p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback; 212 p_cb->rcb[first_unuse].app_uuid = p_msg->api_reg.app_uuid; 213 cb_data.reg_oper.server_if = p_cb->rcb[first_unuse].gatt_if = 214 GATT_Register(p_msg->api_reg.app_uuid, &bta_gatts_cback); 215 if (!p_cb->rcb[first_unuse].gatt_if) { 216 status = GATT_NO_RESOURCES; 217 } else { 218 tBTA_GATTS_INT_START_IF* p_buf = (tBTA_GATTS_INT_START_IF*)osi_malloc( 219 sizeof(tBTA_GATTS_INT_START_IF)); 220 p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT; 221 p_buf->server_if = p_cb->rcb[first_unuse].gatt_if; 222 223 bta_sys_sendmsg(p_buf); 224 } 225 } else { 226 status = GATT_NO_RESOURCES; 227 } 228 } 229 cb_data.reg_oper.status = status; 230 if (p_msg->api_reg.p_cback) 231 (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data); 232 } 233 234 /******************************************************************************* 235 * 236 * Function bta_gatts_start_if 237 * 238 * Description start an application interface. 239 * 240 * Returns none. 241 * 242 ******************************************************************************/ 243 void bta_gatts_start_if(UNUSED_ATTR tBTA_GATTS_CB* p_cb, 244 tBTA_GATTS_DATA* p_msg) { 245 if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if)) { 246 GATT_StartIf(p_msg->int_start_if.server_if); 247 } else { 248 LOG(ERROR) << "Unable to start app.: Unknown interface=" 249 << +p_msg->int_start_if.server_if; 250 } 251 } 252 /******************************************************************************* 253 * 254 * Function bta_gatts_deregister 255 * 256 * Description deregister an application. 257 * 258 * Returns none. 259 * 260 ******************************************************************************/ 261 void bta_gatts_deregister(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { 262 tGATT_STATUS status = GATT_ERROR; 263 tBTA_GATTS_CBACK* p_cback = NULL; 264 uint8_t i; 265 tBTA_GATTS cb_data; 266 267 cb_data.reg_oper.server_if = p_msg->api_dereg.server_if; 268 cb_data.reg_oper.status = status; 269 270 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) { 271 if (p_cb->rcb[i].in_use && 272 p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if) { 273 p_cback = p_cb->rcb[i].p_cback; 274 status = GATT_SUCCESS; 275 276 /* deregister the app */ 277 GATT_Deregister(p_cb->rcb[i].gatt_if); 278 279 /* reset cb */ 280 memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB)); 281 cb_data.reg_oper.status = status; 282 break; 283 } 284 } 285 286 if (p_cback) { 287 (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data); 288 } else { 289 LOG(ERROR) << "application not registered."; 290 } 291 } 292 293 /******************************************************************************* 294 * 295 * Function bta_gatts_delete_service 296 * 297 * Description action function to delete a service. 298 * 299 * Returns none. 300 * 301 ******************************************************************************/ 302 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB* p_srvc_cb, 303 tBTA_GATTS_DATA* p_msg) { 304 tBTA_GATTS_RCB* p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 305 tBTA_GATTS cb_data; 306 307 cb_data.srvc_oper.server_if = p_rcb->gatt_if; 308 cb_data.srvc_oper.service_id = p_srvc_cb->service_id; 309 310 if (GATTS_DeleteService(p_rcb->gatt_if, &p_srvc_cb->service_uuid, 311 p_srvc_cb->service_id)) { 312 cb_data.srvc_oper.status = GATT_SUCCESS; 313 memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB)); 314 } else { 315 cb_data.srvc_oper.status = GATT_ERROR; 316 } 317 318 if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data); 319 } 320 321 /******************************************************************************* 322 * 323 * Function bta_gatts_stop_service 324 * 325 * Description action function to stop a service. 326 * 327 * Returns none. 328 * 329 ******************************************************************************/ 330 void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB* p_srvc_cb, 331 UNUSED_ATTR tBTA_GATTS_DATA* p_msg) { 332 tBTA_GATTS_RCB* p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 333 tBTA_GATTS cb_data; 334 335 GATTS_StopService(p_srvc_cb->service_id); 336 cb_data.srvc_oper.server_if = p_rcb->gatt_if; 337 cb_data.srvc_oper.service_id = p_srvc_cb->service_id; 338 cb_data.srvc_oper.status = GATT_SUCCESS; 339 LOG(ERROR) << __func__ << " service_id=" << +p_srvc_cb->service_id; 340 341 if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data); 342 } 343 /******************************************************************************* 344 * 345 * Function bta_gatts_send_rsp 346 * 347 * Description GATTS send response. 348 * 349 * Returns none. 350 * 351 ******************************************************************************/ 352 void bta_gatts_send_rsp(UNUSED_ATTR tBTA_GATTS_CB* p_cb, 353 tBTA_GATTS_DATA* p_msg) { 354 if (GATTS_SendRsp(p_msg->api_rsp.hdr.layer_specific, p_msg->api_rsp.trans_id, 355 p_msg->api_rsp.status, 356 (tGATTS_RSP*)p_msg->api_rsp.p_rsp) != GATT_SUCCESS) { 357 LOG(ERROR) << "Sending response failed"; 358 } 359 } 360 /******************************************************************************* 361 * 362 * Function bta_gatts_indicate_handle 363 * 364 * Description GATTS send handle value indication or notification. 365 * 366 * Returns none. 367 * 368 ******************************************************************************/ 369 void bta_gatts_indicate_handle(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { 370 tBTA_GATTS_SRVC_CB* p_srvc_cb; 371 tBTA_GATTS_RCB* p_rcb = NULL; 372 tGATT_STATUS status = GATT_ILLEGAL_PARAMETER; 373 tGATT_IF gatt_if; 374 RawAddress remote_bda; 375 tBTA_TRANSPORT transport; 376 tBTA_GATTS cb_data; 377 378 p_srvc_cb = 379 bta_gatts_find_srvc_cb_by_attr_id(p_cb, p_msg->api_indicate.attr_id); 380 381 if (p_srvc_cb) { 382 if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific, 383 &gatt_if, remote_bda, &transport)) { 384 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 385 386 if (p_msg->api_indicate.need_confirm) 387 388 status = GATTS_HandleValueIndication( 389 p_msg->api_indicate.hdr.layer_specific, p_msg->api_indicate.attr_id, 390 p_msg->api_indicate.len, p_msg->api_indicate.value); 391 else 392 status = GATTS_HandleValueNotification( 393 p_msg->api_indicate.hdr.layer_specific, p_msg->api_indicate.attr_id, 394 p_msg->api_indicate.len, p_msg->api_indicate.value); 395 396 /* if over BR_EDR, inform PM for mode change */ 397 if (transport == BTA_TRANSPORT_BR_EDR) { 398 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); 399 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); 400 } 401 } else { 402 LOG(ERROR) << "Unknown connection_id=" 403 << loghex(p_msg->api_indicate.hdr.layer_specific) 404 << " fail sending notification"; 405 } 406 407 if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) && 408 p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback) { 409 cb_data.req_data.status = status; 410 cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific; 411 412 (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data); 413 } 414 } else { 415 LOG(ERROR) << "Not an registered servce attribute ID: " 416 << loghex(p_msg->api_indicate.attr_id); 417 } 418 } 419 420 /******************************************************************************* 421 * 422 * Function bta_gatts_open 423 * 424 * Description 425 * 426 * Returns none. 427 * 428 ******************************************************************************/ 429 void bta_gatts_open(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { 430 tBTA_GATTS_RCB* p_rcb = NULL; 431 tGATT_STATUS status = GATT_ERROR; 432 uint16_t conn_id; 433 434 p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if); 435 if (p_rcb != NULL) { 436 /* should always get the connection ID */ 437 if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, 438 p_msg->api_open.is_direct, p_msg->api_open.transport, 439 false)) { 440 status = GATT_SUCCESS; 441 442 if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda, 443 &conn_id, p_msg->api_open.transport)) { 444 status = GATT_ALREADY_OPEN; 445 } 446 } 447 } else { 448 LOG(ERROR) << "Inavlid server_if=" << p_msg->api_open.server_if; 449 } 450 451 if (p_rcb && p_rcb->p_cback) { 452 tBTA_GATTS bta_gatts; 453 bta_gatts.status = status; 454 (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, &bta_gatts); 455 } 456 } 457 /******************************************************************************* 458 * 459 * Function bta_gatts_cancel_open 460 * 461 * Description 462 * 463 * Returns none. 464 * 465 ******************************************************************************/ 466 void bta_gatts_cancel_open(UNUSED_ATTR tBTA_GATTS_CB* p_cb, 467 tBTA_GATTS_DATA* p_msg) { 468 tBTA_GATTS_RCB* p_rcb; 469 tGATT_STATUS status = GATT_ERROR; 470 471 p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if); 472 if (p_rcb != NULL) { 473 if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, 474 p_msg->api_cancel_open.is_direct)) { 475 LOG(ERROR) << __func__ << ": failed for open request"; 476 } else { 477 status = GATT_SUCCESS; 478 } 479 } else { 480 LOG(ERROR) << "Inavlid server_if=" << +p_msg->api_cancel_open.server_if; 481 } 482 483 if (p_rcb && p_rcb->p_cback) { 484 tBTA_GATTS bta_gatts; 485 bta_gatts.status = status; 486 (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, &bta_gatts); 487 } 488 } 489 /******************************************************************************* 490 * 491 * Function bta_gatts_close 492 * 493 * Description 494 * 495 * Returns none. 496 * 497 ******************************************************************************/ 498 void bta_gatts_close(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { 499 tBTA_GATTS_RCB* p_rcb; 500 tGATT_STATUS status = GATT_ERROR; 501 tGATT_IF gatt_if; 502 RawAddress remote_bda; 503 tGATT_TRANSPORT transport; 504 505 if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, 506 &transport)) { 507 if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) { 508 LOG(ERROR) << __func__ 509 << ": fail conn_id=" << loghex(p_msg->hdr.layer_specific); 510 } else { 511 status = GATT_SUCCESS; 512 } 513 514 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 515 516 if (p_rcb && p_rcb->p_cback) { 517 if (transport == BTA_TRANSPORT_BR_EDR) 518 bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); 519 520 tBTA_GATTS bta_gatts; 521 bta_gatts.status = status; 522 (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, &bta_gatts); 523 } 524 } else { 525 LOG(ERROR) << "Unknown connection_id=" << loghex(p_msg->hdr.layer_specific); 526 } 527 } 528 529 /******************************************************************************* 530 * 531 * Function bta_gatts_request_cback 532 * 533 * Description GATTS attribute request callback. 534 * 535 * Returns none. 536 * 537 ******************************************************************************/ 538 static void bta_gatts_send_request_cback(uint16_t conn_id, uint32_t trans_id, 539 tGATTS_REQ_TYPE req_type, 540 tGATTS_DATA* p_data) { 541 tBTA_GATTS cb_data; 542 tBTA_GATTS_RCB* p_rcb; 543 tGATT_IF gatt_if; 544 tGATT_TRANSPORT transport; 545 546 memset(&cb_data, 0, sizeof(tBTA_GATTS)); 547 548 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, 549 &transport)) { 550 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 551 552 VLOG(1) << __func__ << ": conn_id=" << loghex(conn_id) 553 << ", trans_id=" << +trans_id << ", req_type=" << +req_type; 554 555 if (p_rcb && p_rcb->p_cback) { 556 /* if over BR_EDR, inform PM for mode change */ 557 if (transport == BTA_TRANSPORT_BR_EDR) { 558 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); 559 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); 560 } 561 562 cb_data.req_data.conn_id = conn_id; 563 cb_data.req_data.trans_id = trans_id; 564 cb_data.req_data.p_data = (tGATTS_DATA*)p_data; 565 566 (*p_rcb->p_cback)(req_type, &cb_data); 567 } else { 568 LOG(ERROR) << "connection request on gatt_if=" << +gatt_if 569 << " is not interested"; 570 } 571 } else { 572 LOG(ERROR) << "request received on unknown conn_id=" << loghex(conn_id); 573 } 574 } 575 576 /******************************************************************************* 577 * 578 * Function bta_gatts_conn_cback 579 * 580 * Description connection callback. 581 * 582 * Returns none. 583 * 584 ******************************************************************************/ 585 static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bdaddr, 586 uint16_t conn_id, bool connected, 587 tGATT_DISCONN_REASON reason, 588 tGATT_TRANSPORT transport) { 589 tBTA_GATTS cb_data; 590 uint8_t evt = connected ? BTA_GATTS_CONNECT_EVT : BTA_GATTS_DISCONNECT_EVT; 591 tBTA_GATTS_RCB* p_reg; 592 593 VLOG(1) << __func__ << " bda=" << bdaddr << " gatt_if= " << gatt_if 594 << ", conn_id=" << loghex(conn_id) << " connected=" << connected 595 << ", reason=" << loghex(reason); 596 597 if (connected) 598 btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN); 599 else 600 btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason); 601 602 p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); 603 604 if (p_reg && p_reg->p_cback) { 605 /* there is no RM for GATT */ 606 if (transport == BTA_TRANSPORT_BR_EDR) { 607 if (connected) 608 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bdaddr); 609 else 610 bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, bdaddr); 611 } 612 613 cb_data.conn.conn_id = conn_id; 614 cb_data.conn.server_if = gatt_if; 615 cb_data.conn.reason = reason; 616 cb_data.conn.transport = transport; 617 cb_data.conn.remote_bda = bdaddr; 618 (*p_reg->p_cback)(evt, &cb_data); 619 } else { 620 LOG(ERROR) << __func__ << " server_if=" << +gatt_if << " not found"; 621 } 622 } 623 624 static void bta_gatts_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id, 625 uint8_t tx_phy, uint8_t rx_phy, 626 uint8_t status) { 627 tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); 628 if (!p_reg || !p_reg->p_cback) { 629 LOG(ERROR) << __func__ << ": server_if=" << +gatt_if << " not found"; 630 return; 631 } 632 633 tBTA_GATTS cb_data; 634 cb_data.phy_update.conn_id = conn_id; 635 cb_data.phy_update.server_if = gatt_if; 636 cb_data.phy_update.tx_phy = tx_phy; 637 cb_data.phy_update.rx_phy = rx_phy; 638 cb_data.phy_update.status = status; 639 (*p_reg->p_cback)(BTA_GATTS_PHY_UPDATE_EVT, &cb_data); 640 } 641 642 static void bta_gatts_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id, 643 uint16_t interval, uint16_t latency, 644 uint16_t timeout, uint8_t status) { 645 tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); 646 if (!p_reg || !p_reg->p_cback) { 647 LOG(ERROR) << __func__ << ": server_if=" << +gatt_if << " not found"; 648 return; 649 } 650 651 tBTA_GATTS cb_data; 652 cb_data.conn_update.conn_id = conn_id; 653 cb_data.conn_update.server_if = gatt_if; 654 cb_data.conn_update.interval = interval; 655 cb_data.conn_update.latency = latency; 656 cb_data.conn_update.timeout = timeout; 657 cb_data.conn_update.status = status; 658 (*p_reg->p_cback)(BTA_GATTS_CONN_UPDATE_EVT, &cb_data); 659 } 660 661 /******************************************************************************* 662 * 663 * Function bta_gatts_cong_cback 664 * 665 * Description congestion callback. 666 * 667 * Returns none. 668 * 669 ******************************************************************************/ 670 static void bta_gatts_cong_cback(uint16_t conn_id, bool congested) { 671 tBTA_GATTS_RCB* p_rcb; 672 tGATT_IF gatt_if; 673 tGATT_TRANSPORT transport; 674 tBTA_GATTS cb_data; 675 676 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, 677 &transport)) { 678 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 679 680 if (p_rcb && p_rcb->p_cback) { 681 cb_data.congest.conn_id = conn_id; 682 cb_data.congest.congested = congested; 683 684 (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data); 685 } 686 } 687 } 688