1 /****************************************************************************** 2 * 3 * Copyright (C) 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 27 #include "bt_target.h" 28 29 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) 30 31 #include "utl.h" 32 #include "gki.h" 33 #include "bta_sys.h" 34 #include "bta_gatts_int.h" 35 #include "bta_gatts_co.h" 36 #include "btm_ble_api.h" 37 #include "btif/include/btif_debug_conn.h" 38 #include <string.h> 39 40 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range); 41 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, 42 tGATTS_SRV_CHG_RSP *p_rsp); 43 44 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, 45 BOOLEAN connected, tGATT_DISCONN_REASON reason, 46 tGATT_TRANSPORT transport); 47 static void bta_gatts_send_request_cback (UINT16 conn_id, 48 UINT32 trans_id, 49 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data); 50 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested); 51 52 static tGATT_CBACK bta_gatts_cback = 53 { 54 bta_gatts_conn_cback, 55 NULL, 56 NULL, 57 NULL, 58 bta_gatts_send_request_cback, 59 NULL, 60 bta_gatts_cong_cback 61 }; 62 63 tGATT_APPL_INFO bta_gatts_nv_cback = 64 { 65 bta_gatts_nv_save_cback, 66 bta_gatts_nv_srv_chg_cback 67 }; 68 69 /******************************************************************************* 70 ** 71 ** Function bta_gatts_nv_save_cback 72 ** 73 ** Description NV save callback function. 74 ** 75 ** Parameter is_add: true is to add a handle range; otherwise is to delete. 76 ** Returns none. 77 ** 78 *******************************************************************************/ 79 static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_range) 80 { 81 bta_gatts_co_update_handle_range(is_add, (tBTA_GATTS_HNDL_RANGE *)p_hndl_range); 82 } 83 84 85 /******************************************************************************* 86 ** 87 ** Function bta_gatts_nv_srv_chg_cback 88 ** 89 ** Description NV save callback function. 90 ** 91 ** Parameter is_add: true is to add a handle range; otherwise is to delete. 92 ** Returns none. 93 ** 94 *******************************************************************************/ 95 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, 96 tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp) 97 { 98 return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd, 99 (tBTA_GATTS_SRV_CHG_REQ *) p_req, 100 (tBTA_GATTS_SRV_CHG_RSP *) p_rsp); 101 } 102 103 104 /******************************************************************************* 105 ** 106 ** Function bta_gatts_enable 107 ** 108 ** Description enable BTA GATTS module. 109 ** 110 ** Returns none. 111 ** 112 *******************************************************************************/ 113 void bta_gatts_enable(tBTA_GATTS_CB *p_cb) 114 { 115 UINT8 index=0; 116 tBTA_GATTS_HNDL_RANGE handle_range; 117 118 if (p_cb->enabled) 119 { 120 APPL_TRACE_DEBUG("GATTS already enabled."); 121 } 122 else 123 { 124 memset(p_cb, 0, sizeof(tBTA_GATTS_CB)); 125 126 p_cb->enabled = TRUE; 127 128 while ( bta_gatts_co_load_handle_range(index, &handle_range)) 129 { 130 GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range); 131 memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE)); 132 index++; 133 } 134 135 APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index); 136 137 if (!GATTS_NVRegister(&bta_gatts_nv_cback)) 138 { 139 APPL_TRACE_ERROR("BTA GATTS NV register failed."); 140 } 141 } 142 } 143 144 /******************************************************************************* 145 ** 146 ** Function bta_gatts_api_disable 147 ** 148 ** Description disable BTA GATTS module. 149 ** 150 ** Returns none. 151 ** 152 *******************************************************************************/ 153 void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb) 154 { 155 UINT8 i; 156 157 if (p_cb->enabled) 158 { 159 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) 160 { 161 if (p_cb->rcb[i].in_use) 162 { 163 GATT_Deregister(p_cb->rcb[i].gatt_if); 164 } 165 } 166 memset(p_cb, 0, sizeof(tBTA_GATTS_CB)); 167 } 168 else 169 { 170 APPL_TRACE_ERROR("GATTS not enabled"); 171 } 172 } 173 174 /******************************************************************************* 175 ** 176 ** Function bta_gatts_register 177 ** 178 ** Description register an application. 179 ** 180 ** Returns none. 181 ** 182 *******************************************************************************/ 183 void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) 184 { 185 tBTA_GATTS_INT_START_IF *p_buf; 186 tBTA_GATTS cb_data; 187 tBTA_GATT_STATUS status = BTA_GATT_OK; 188 UINT8 i, first_unuse = 0xff; 189 190 if (p_cb->enabled == FALSE) 191 { 192 bta_gatts_enable(p_cb); 193 } 194 195 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) 196 { 197 if (p_cb->rcb[i].in_use) 198 { 199 if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid)) 200 { 201 APPL_TRACE_ERROR("application already registered."); 202 status = BTA_GATT_DUP_REG; 203 break; 204 } 205 } 206 } 207 208 if (status == BTA_GATT_OK) 209 { 210 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) 211 { 212 if (first_unuse == 0xff && !p_cb->rcb[i].in_use) 213 { 214 first_unuse = i; 215 break; 216 } 217 } 218 219 cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF; 220 // btla-specific ++ 221 memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID)); 222 // btla-specific -- 223 if (first_unuse != 0xff) 224 { 225 APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d", first_unuse); 226 227 p_cb->rcb[first_unuse].in_use = TRUE; 228 p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback; 229 memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID)); 230 cb_data.reg_oper.server_if = 231 p_cb->rcb[first_unuse].gatt_if = 232 GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback); 233 if ( !p_cb->rcb[first_unuse].gatt_if) 234 { 235 status = BTA_GATT_NO_RESOURCES; 236 } 237 else 238 { 239 if ((p_buf = 240 (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL) 241 { 242 p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT; 243 p_buf->server_if = p_cb->rcb[first_unuse].gatt_if; 244 245 bta_sys_sendmsg(p_buf); 246 } 247 else 248 { 249 status = BTA_GATT_NO_RESOURCES; 250 memset( &p_cb->rcb[first_unuse], 0 , sizeof(tBTA_GATTS_RCB)); 251 } 252 } 253 } 254 else 255 { 256 status = BTA_GATT_NO_RESOURCES; 257 } 258 259 } 260 cb_data.reg_oper.status = status; 261 if (p_msg->api_reg.p_cback) 262 (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data); 263 } 264 265 266 /******************************************************************************* 267 ** 268 ** Function bta_gatts_start_if 269 ** 270 ** Description start an application interface. 271 ** 272 ** Returns none. 273 ** 274 *******************************************************************************/ 275 void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) 276 { 277 UNUSED(p_cb); 278 279 if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if)) 280 { 281 GATT_StartIf(p_msg->int_start_if.server_if); 282 } 283 else 284 { 285 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d", 286 p_msg->int_start_if.server_if ); 287 } 288 } 289 /******************************************************************************* 290 ** 291 ** Function bta_gatts_deregister 292 ** 293 ** Description deregister an application. 294 ** 295 ** Returns none. 296 ** 297 *******************************************************************************/ 298 void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) 299 { 300 tBTA_GATT_STATUS status = BTA_GATT_ERROR; 301 tBTA_GATTS_CBACK *p_cback = NULL; 302 UINT8 i; 303 tBTA_GATTS cb_data; 304 305 cb_data.reg_oper.server_if = p_msg->api_dereg.server_if; 306 cb_data.reg_oper.status = status; 307 308 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) 309 { 310 if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if) 311 { 312 p_cback = p_cb->rcb[i].p_cback; 313 status = BTA_GATT_OK; 314 315 /* deregister the app */ 316 GATT_Deregister(p_cb->rcb[i].gatt_if); 317 318 /* reset cb */ 319 memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB)); 320 cb_data.reg_oper.status = status; 321 break; 322 } 323 } 324 325 if (p_cback) 326 { 327 (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data); 328 } 329 else 330 { 331 APPL_TRACE_ERROR("application not registered."); 332 } 333 } 334 /******************************************************************************* 335 ** 336 ** Function bta_gatts_create_srvc 337 ** 338 ** Description action function to create a service. 339 ** 340 ** Returns none. 341 ** 342 *******************************************************************************/ 343 void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 344 { 345 UINT8 rcb_idx; 346 tBTA_GATTS cb_data; 347 UINT8 srvc_idx; 348 UINT16 service_id = 0; 349 350 cb_data.create.status = BTA_GATT_ERROR; 351 352 rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if); 353 354 APPL_TRACE_ERROR("create service rcb_idx = %d", rcb_idx); 355 356 if (rcb_idx != BTA_GATTS_INVALID_APP) 357 { 358 if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP) 359 { 360 /* create the service now */ 361 service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if, 362 &p_msg->api_create_svc.service_uuid, 363 p_msg->api_create_svc.inst, 364 p_msg->api_create_svc.num_handle, 365 p_msg->api_create_svc.is_pri); 366 367 if (service_id != 0) 368 { 369 memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid, 370 &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID)); 371 p_cb->srvc_cb[srvc_idx].service_id = service_id; 372 p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst; 373 p_cb->srvc_cb[srvc_idx].idx = srvc_idx; 374 375 cb_data.create.status = BTA_GATT_OK; 376 cb_data.create.service_id = service_id; 377 // btla-specific ++ 378 cb_data.create.is_primary = p_msg->api_create_svc.is_pri; 379 // btla-specific -- 380 cb_data.create.server_if = p_cb->rcb[rcb_idx].gatt_if; 381 } 382 else 383 { 384 cb_data.status = BTA_GATT_ERROR; 385 memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB)); 386 APPL_TRACE_ERROR("service creation failed."); 387 } 388 // btla-specific ++ 389 memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID)); 390 cb_data.create.svc_instance= p_msg->api_create_svc.inst; 391 // btla-specific -- 392 } 393 if (p_cb->rcb[rcb_idx].p_cback) 394 (* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data); 395 } 396 else /* application not registered */ 397 { 398 APPL_TRACE_ERROR("Application not registered"); 399 } 400 } 401 /******************************************************************************* 402 ** 403 ** Function bta_gatts_add_include_srvc 404 ** 405 ** Description action function to add an included service. 406 ** 407 ** Returns none. 408 ** 409 *******************************************************************************/ 410 void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb,tBTA_GATTS_DATA * p_msg) 411 { 412 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 413 UINT16 attr_id = 0; 414 tBTA_GATTS cb_data; 415 416 attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific, 417 p_msg->api_add_incl_srvc.included_service_id); 418 419 cb_data.add_result.server_if = p_rcb->gatt_if; 420 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 421 cb_data.add_result.attr_id = attr_id; 422 423 if (attr_id) 424 { 425 cb_data.add_result.status = BTA_GATT_OK; 426 } 427 else 428 { 429 cb_data.add_result.status = BTA_GATT_ERROR; 430 } 431 432 if (p_rcb->p_cback) 433 (*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data); 434 } 435 /******************************************************************************* 436 ** 437 ** Function bta_gatts_add_char 438 ** 439 ** Description action function to add characteristic. 440 ** 441 ** Returns none. 442 ** 443 *******************************************************************************/ 444 void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 445 { 446 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 447 UINT16 attr_id = 0; 448 tBTA_GATTS cb_data; 449 450 attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific, 451 &p_msg->api_add_char.char_uuid, 452 p_msg->api_add_char.perm, 453 p_msg->api_add_char.property); 454 cb_data.add_result.server_if = p_rcb->gatt_if; 455 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 456 cb_data.add_result.attr_id = attr_id; 457 // btla-specific ++ 458 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID)); 459 // btla-specific -- 460 461 if (attr_id) 462 { 463 cb_data.add_result.status = BTA_GATT_OK; 464 } 465 else 466 { 467 cb_data.add_result.status = BTA_GATT_ERROR; 468 } 469 470 if (p_rcb->p_cback) 471 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data); 472 } 473 /******************************************************************************* 474 ** 475 ** Function bta_gatts_add_char_descr 476 ** 477 ** Description action function to add characteristic descriptor. 478 ** 479 ** Returns none. 480 ** 481 *******************************************************************************/ 482 void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 483 { 484 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 485 UINT16 attr_id = 0; 486 tBTA_GATTS cb_data; 487 488 attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific, 489 p_msg->api_add_char_descr.perm, 490 &p_msg->api_add_char_descr.descr_uuid); 491 492 cb_data.add_result.server_if = p_rcb->gatt_if; 493 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 494 cb_data.add_result.attr_id = attr_id; 495 // btla-specific ++ 496 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID)); 497 // btla-specific -- 498 499 if (attr_id) 500 { 501 cb_data.add_result.status = BTA_GATT_OK; 502 } 503 else 504 { 505 cb_data.add_result.status = BTA_GATT_ERROR; 506 } 507 508 if (p_rcb->p_cback) 509 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data); 510 511 } 512 /******************************************************************************* 513 ** 514 ** Function bta_gatts_delete_service 515 ** 516 ** Description action function to delete a service. 517 ** 518 ** Returns none. 519 ** 520 *******************************************************************************/ 521 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 522 { 523 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 524 tBTA_GATTS cb_data; 525 526 cb_data.srvc_oper.server_if = p_rcb->gatt_if; 527 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 528 529 if (GATTS_DeleteService(p_rcb->gatt_if, 530 &p_srvc_cb->service_uuid, 531 p_srvc_cb->inst_num)) 532 { 533 cb_data.srvc_oper.status = BTA_GATT_OK; 534 memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB)); 535 } 536 else 537 { 538 cb_data.srvc_oper.status = BTA_GATT_ERROR; 539 } 540 541 if (p_rcb->p_cback) 542 (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data); 543 544 } 545 /******************************************************************************* 546 ** 547 ** Function bta_gatts_start_service 548 ** 549 ** Description action function to start a service. 550 ** 551 ** Returns none. 552 ** 553 *******************************************************************************/ 554 void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 555 { 556 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 557 tBTA_GATTS cb_data; 558 559 cb_data.srvc_oper.server_if = p_rcb->gatt_if; 560 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 561 562 if (GATTS_StartService(p_rcb->gatt_if, 563 p_srvc_cb->service_id, 564 p_msg->api_start.transport) == GATT_SUCCESS) 565 { 566 APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id); 567 cb_data.srvc_oper.status = BTA_GATT_OK; 568 } 569 else 570 { 571 cb_data.srvc_oper.status = BTA_GATT_ERROR; 572 } 573 574 if (p_rcb->p_cback) 575 (*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data); 576 577 } 578 /******************************************************************************* 579 ** 580 ** Function bta_gatts_stop_service 581 ** 582 ** Description action function to stop a service. 583 ** 584 ** Returns none. 585 ** 586 *******************************************************************************/ 587 void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 588 { 589 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 590 tBTA_GATTS cb_data; 591 UNUSED(p_msg); 592 593 GATTS_StopService(p_srvc_cb->service_id); 594 cb_data.srvc_oper.server_if = p_rcb->gatt_if; 595 cb_data.srvc_oper.service_id = p_srvc_cb->service_id; 596 cb_data.srvc_oper.status = BTA_GATT_OK; 597 APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id); 598 599 if (p_rcb->p_cback) 600 (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data); 601 602 } 603 /******************************************************************************* 604 ** 605 ** Function bta_gatts_send_rsp 606 ** 607 ** Description GATTS send response. 608 ** 609 ** Returns none. 610 ** 611 *******************************************************************************/ 612 void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 613 { 614 UNUSED(p_cb); 615 616 if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific, 617 p_msg->api_rsp.trans_id, 618 p_msg->api_rsp.status, 619 (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS) 620 { 621 APPL_TRACE_ERROR("Sending response failed"); 622 } 623 624 } 625 /******************************************************************************* 626 ** 627 ** Function bta_gatts_indicate_handle 628 ** 629 ** Description GATTS send handle value indication or notification. 630 ** 631 ** Returns none. 632 ** 633 *******************************************************************************/ 634 void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 635 { 636 tBTA_GATTS_SRVC_CB *p_srvc_cb; 637 tBTA_GATTS_RCB *p_rcb = NULL; 638 tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER; 639 tGATT_IF gatt_if; 640 BD_ADDR remote_bda; 641 tBTA_TRANSPORT transport; 642 tBTA_GATTS cb_data; 643 644 p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id); 645 646 if (p_srvc_cb ) 647 { 648 if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific, 649 &gatt_if, remote_bda, &transport)) 650 { 651 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 652 653 if (p_msg->api_indicate.need_confirm) 654 655 status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific, 656 p_msg->api_indicate.attr_id, 657 p_msg->api_indicate.len, 658 p_msg->api_indicate.value); 659 else 660 status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific, 661 p_msg->api_indicate.attr_id, 662 p_msg->api_indicate.len, 663 p_msg->api_indicate.value); 664 665 /* if over BR_EDR, inform PM for mode change */ 666 if (transport == BTA_TRANSPORT_BR_EDR) 667 { 668 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); 669 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); 670 } 671 } 672 else 673 { 674 APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification", 675 p_msg->api_indicate.hdr.layer_specific); 676 } 677 678 if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) && 679 p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback) 680 { 681 cb_data.req_data.status = status; 682 cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific; 683 684 (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data); 685 } 686 } 687 else 688 { 689 APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x", 690 p_msg->api_indicate.attr_id); 691 } 692 } 693 694 695 /******************************************************************************* 696 ** 697 ** Function bta_gatts_open 698 ** 699 ** Description 700 ** 701 ** Returns none. 702 ** 703 *******************************************************************************/ 704 void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 705 { 706 tBTA_GATTS_RCB *p_rcb=NULL; 707 tBTA_GATT_STATUS status= BTA_GATT_ERROR; 708 UINT16 conn_id; 709 UNUSED(p_cb); 710 711 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL) 712 { 713 /* should always get the connection ID */ 714 if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, 715 p_msg->api_open.is_direct, p_msg->api_open.transport)) 716 { 717 status = BTA_GATT_OK; 718 719 if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda, 720 &conn_id, p_msg->api_open.transport)) 721 { 722 status = BTA_GATT_ALREADY_OPEN; 723 } 724 } 725 } 726 else 727 { 728 APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if); 729 } 730 731 if (p_rcb && p_rcb->p_cback) 732 (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, (tBTA_GATTS *)&status); 733 734 } 735 /******************************************************************************* 736 ** 737 ** Function bta_gatts_cancel_open 738 ** 739 ** Description 740 ** 741 ** Returns none. 742 ** 743 *******************************************************************************/ 744 void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 745 { 746 tBTA_GATTS_RCB *p_rcb; 747 tBTA_GATT_STATUS status= BTA_GATT_ERROR; 748 UNUSED(p_cb); 749 750 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL) 751 { 752 if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, 753 p_msg->api_cancel_open.is_direct)) 754 { 755 APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request"); 756 } 757 else 758 { 759 status= BTA_GATT_OK; 760 } 761 } 762 else 763 { 764 APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if); 765 } 766 767 if (p_rcb && p_rcb->p_cback) 768 (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, (tBTA_GATTS *)&status); 769 } 770 /******************************************************************************* 771 ** 772 ** Function bta_gatts_close 773 ** 774 ** Description 775 ** 776 ** Returns none. 777 ** 778 *******************************************************************************/ 779 void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 780 { 781 tBTA_GATTS_RCB *p_rcb; 782 tBTA_GATT_STATUS status= BTA_GATT_ERROR; 783 tGATT_IF gatt_if; 784 BD_ADDR remote_bda; 785 tBTA_GATT_TRANSPORT transport; 786 787 UNUSED(p_cb); 788 789 if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport)) 790 { 791 if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) 792 { 793 APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific); 794 } 795 else 796 { 797 status= BTA_GATT_OK; 798 } 799 800 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 801 802 if (p_rcb && p_rcb->p_cback) 803 { 804 if (transport == BTA_TRANSPORT_BR_EDR) 805 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda); 806 807 (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status); 808 } 809 } 810 else 811 { 812 APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific); 813 } 814 815 } 816 /******************************************************************************* 817 ** 818 ** Function bta_gatts_listen 819 ** 820 ** Description Start or stop listening for LE connection on a GATT server 821 ** 822 ** Returns none. 823 ** 824 *******************************************************************************/ 825 void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 826 { 827 tBTA_GATTS_RCB *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if); 828 tBTA_GATTS cb_data; 829 UNUSED(p_cb); 830 831 cb_data.reg_oper.status = BTA_GATT_OK; 832 cb_data.reg_oper.server_if = p_msg->api_listen.server_if; 833 834 if (p_rcb == NULL) 835 { 836 APPL_TRACE_ERROR("Unknown GATTS application"); 837 return; 838 } 839 840 if (!GATT_Listen(p_msg->api_listen.server_if, 841 p_msg->api_listen.start, 842 p_msg->api_listen.remote_bda)) 843 { 844 cb_data.status = BTA_GATT_ERROR; 845 APPL_TRACE_ERROR("bta_gatts_listen Listen failed"); 846 } 847 848 if (p_rcb->p_cback) 849 (*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data); 850 } 851 852 /******************************************************************************* 853 ** 854 ** Function bta_gatts_request_cback 855 ** 856 ** Description GATTS attribute request callback. 857 ** 858 ** Returns none. 859 ** 860 *******************************************************************************/ 861 static void bta_gatts_send_request_cback (UINT16 conn_id, 862 UINT32 trans_id, 863 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data) 864 { 865 tBTA_GATTS cb_data; 866 tBTA_GATTS_RCB *p_rcb; 867 tGATT_IF gatt_if; 868 tBTA_GATT_TRANSPORT transport; 869 870 memset(&cb_data, 0 , sizeof(tBTA_GATTS)); 871 872 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport)) 873 { 874 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 875 876 APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d", 877 conn_id, trans_id, req_type); 878 879 if (p_rcb && p_rcb->p_cback) 880 { 881 /* if over BR_EDR, inform PM for mode change */ 882 if (transport == BTA_TRANSPORT_BR_EDR) 883 { 884 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); 885 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); 886 } 887 888 cb_data.req_data.conn_id = conn_id; 889 cb_data.req_data.trans_id = trans_id; 890 cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data; 891 892 (*p_rcb->p_cback)(req_type, &cb_data); 893 } 894 else 895 { 896 APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if); 897 } 898 } 899 else 900 { 901 APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id); 902 } 903 } 904 905 /******************************************************************************* 906 ** 907 ** Function bta_gatts_conn_cback 908 ** 909 ** Description connection callback. 910 ** 911 ** Returns none. 912 ** 913 *******************************************************************************/ 914 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, 915 BOOLEAN connected, tGATT_DISCONN_REASON reason, 916 tGATT_TRANSPORT transport) 917 { 918 tBTA_GATTS cb_data; 919 UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT; 920 tBTA_GATTS_RCB *p_reg; 921 922 APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d", 923 gatt_if, conn_id, connected, reason); 924 APPL_TRACE_DEBUG("bta_gatts_conn_cback bda :%02x-%02x-%02x-%02x-%02x-%02x ", 925 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); 926 927 bt_bdaddr_t bdaddr; 928 bdcpy(bdaddr.address, bda); 929 if (connected) 930 btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN); 931 else 932 btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason); 933 934 p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); 935 936 if (p_reg && p_reg->p_cback) 937 { 938 /* there is no RM for GATT */ 939 if (transport == BTA_TRANSPORT_BR_EDR) 940 { 941 if (connected) 942 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda); 943 else 944 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda); 945 } 946 947 cb_data.conn.conn_id = conn_id; 948 cb_data.conn.server_if = gatt_if; 949 cb_data.conn.reason = reason; 950 cb_data.conn.transport = transport; 951 memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN); 952 (*p_reg->p_cback)(evt, &cb_data); 953 } 954 else 955 { 956 APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found",gatt_if); 957 } 958 } 959 960 /******************************************************************************* 961 ** 962 ** Function bta_gatts_cong_cback 963 ** 964 ** Description congestion callback. 965 ** 966 ** Returns none. 967 ** 968 *******************************************************************************/ 969 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested) 970 { 971 tBTA_GATTS_RCB *p_rcb; 972 tGATT_IF gatt_if; 973 tBTA_GATT_TRANSPORT transport; 974 tBTA_GATTS cb_data; 975 976 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport)) 977 { 978 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 979 980 if (p_rcb && p_rcb->p_cback) 981 { 982 cb_data.congest.conn_id = conn_id; 983 cb_data.congest.congested = congested; 984 985 (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data); 986 } 987 } 988 } 989 #endif /* BTA_GATT_INCLUDED */ 990