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