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