bta_gatts_act.c revision 6975b4d711142b885af479721cada448952c6b41
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 39static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range); 40static 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 42static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason); 43static void bta_gatts_send_request_cback (UINT16 conn_id, 44 UINT32 trans_id, 45 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data); 46static 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 55tGATT_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*******************************************************************************/ 71static 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*******************************************************************************/ 87static 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*******************************************************************************/ 104void 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*******************************************************************************/ 146void 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*******************************************************************************/ 177void 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*******************************************************************************/ 267void 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*******************************************************************************/ 287void 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*******************************************************************************/ 332void 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*******************************************************************************/ 398void 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*******************************************************************************/ 432void 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*******************************************************************************/ 470void 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*******************************************************************************/ 509void 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*******************************************************************************/ 542void 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*******************************************************************************/ 575void 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*******************************************************************************/ 599void 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*******************************************************************************/ 624void 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*******************************************************************************/ 686void 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*******************************************************************************/ 717void 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*******************************************************************************/ 750void 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** 787** Function bta_gatts_request_cback 788** 789** Description GATTS attribute request callback. 790** 791** Returns none. 792** 793*******************************************************************************/ 794static void bta_gatts_send_request_cback (UINT16 conn_id, 795 UINT32 trans_id, 796 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data) 797{ 798 tBTA_GATTS cb_data; 799 tBTA_GATTS_RCB *p_rcb; 800 tGATT_IF gatt_if; 801 802 memset(&cb_data, 0 , sizeof(tBTA_GATTS)); 803 804 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda)) 805 { 806 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 807 808 APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d", conn_id, trans_id, req_type); 809 810 if (p_rcb && p_rcb->p_cback) 811 { 812 /* if over BR_EDR, inform PM for mode change */ 813 if (!BTM_IsBleLink(cb_data.req_data.remote_bda)) 814 { 815 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); 816 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda); 817 } 818 819 cb_data.req_data.conn_id = conn_id; 820 cb_data.req_data.trans_id = trans_id; 821 cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data; 822 823 (*p_rcb->p_cback)(req_type, &cb_data); 824 } 825 else 826 { 827 APPL_TRACE_ERROR1("connection request on gatt_if[%d] is not interested", gatt_if); 828 } 829 } 830 else 831 { 832 APPL_TRACE_ERROR1("request received on unknown connectino ID: %d", conn_id); 833 } 834} 835 836/******************************************************************************* 837** 838** Function bta_gatts_conn_cback 839** 840** Description connection callback. 841** 842** Returns none. 843** 844*******************************************************************************/ 845static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, 846 BOOLEAN connected, tGATT_DISCONN_REASON reason) 847{ 848 tBTA_GATTS cb_data; 849 UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT; 850 tBTA_GATTS_RCB *p_reg; 851 852 APPL_TRACE_DEBUG4 ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d", 853 gatt_if, conn_id, connected, reason); 854 APPL_TRACE_DEBUG6("bta_gatts_conn_cback bda :%02x-%02x-%02x-%02x-%02x-%02x ", 855 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); 856 857 p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); 858 859 if (p_reg && p_reg->p_cback) 860 { 861 /* there is no RM for GATT */ 862 if (!BTM_IsBleLink(bda)) 863 { 864 if (connected) 865 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda); 866 else 867 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda); 868 } 869 870 cb_data.conn.conn_id = conn_id; 871 cb_data.conn.server_if = gatt_if; 872 cb_data.conn.reason = reason; 873 memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN); 874 (*p_reg->p_cback)(evt, &cb_data); 875 } 876 else 877 { 878 APPL_TRACE_ERROR1("bta_gatts_conn_cback server_if=%d not found",gatt_if); 879 } 880} 881#endif /* BTA_GATT_INCLUDED */ 882