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