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