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