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 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 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 *******************************************************************************/ 135 void 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 *******************************************************************************/ 224 void 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 *******************************************************************************/ 244 void 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 *******************************************************************************/ 289 void 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 //tBTA_GATTS_HNDL_RANGE handle_range; 296 297 cb_data.create.status = BTA_GATT_ERROR; 298 299 rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if); 300 301 APPL_TRACE_ERROR1("create service rcb_idx = %d", rcb_idx); 302 303 if (rcb_idx != BTA_GATTS_INVALID_APP) 304 { 305 if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP) 306 { 307 /* create the service now */ 308 service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if, 309 &p_msg->api_create_svc.service_uuid, 310 p_msg->api_create_svc.inst, 311 p_msg->api_create_svc.num_handle, 312 p_msg->api_create_svc.is_pri); 313 314 if (service_id != 0) 315 { 316 memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID)); 317 p_cb->srvc_cb[srvc_idx].service_id = service_id; 318 p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst; 319 p_cb->srvc_cb[srvc_idx].idx = srvc_idx; 320 321 cb_data.create.status = BTA_GATT_OK; 322 cb_data.create.service_id = service_id; 323 // btla-specific ++ 324 cb_data.create.is_primary = p_msg->api_create_svc.is_pri; 325 // btla-specific -- 326 cb_data.create.server_if = p_cb->rcb[rcb_idx].gatt_if; 327 } 328 else 329 { 330 cb_data.status = BTA_GATT_ERROR; 331 memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB)); 332 APPL_TRACE_ERROR0("service creation failed."); 333 } 334 // btla-specific ++ 335 memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID)); 336 cb_data.create.svc_instance= p_msg->api_create_svc.inst; 337 // btla-specific -- 338 } 339 if (p_cb->rcb[rcb_idx].p_cback) 340 (* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data); 341 } 342 else /* application not registered */ 343 { 344 APPL_TRACE_ERROR0("Application not registered"); 345 } 346 } 347 /******************************************************************************* 348 ** 349 ** Function bta_gatts_add_include_srvc 350 ** 351 ** Description action function to add an included service. 352 ** 353 ** Returns none. 354 ** 355 *******************************************************************************/ 356 void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb,tBTA_GATTS_DATA * p_msg) 357 { 358 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 359 UINT16 attr_id = 0; 360 tBTA_GATTS cb_data; 361 362 attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific, 363 p_msg->api_add_incl_srvc.included_service_id); 364 365 cb_data.add_result.server_if = p_rcb->gatt_if; 366 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 367 cb_data.add_result.attr_id = attr_id; 368 369 if (attr_id) 370 { 371 cb_data.add_result.status = BTA_GATT_OK; 372 } 373 else 374 { 375 cb_data.add_result.status = BTA_GATT_ERROR; 376 } 377 378 if (p_rcb->p_cback) 379 (*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data); 380 } 381 /******************************************************************************* 382 ** 383 ** Function bta_gatts_add_char 384 ** 385 ** Description action function to add characteristic. 386 ** 387 ** Returns none. 388 ** 389 *******************************************************************************/ 390 void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 391 { 392 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 393 UINT16 attr_id = 0; 394 tBTA_GATTS cb_data; 395 396 attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific, 397 &p_msg->api_add_char.char_uuid, 398 p_msg->api_add_char.perm, 399 p_msg->api_add_char.property); 400 cb_data.add_result.server_if = p_rcb->gatt_if; 401 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 402 cb_data.add_result.attr_id = attr_id; 403 // btla-specific ++ 404 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID)); 405 // btla-specific -- 406 407 if (attr_id) 408 { 409 cb_data.add_result.status = BTA_GATT_OK; 410 } 411 else 412 { 413 cb_data.add_result.status = BTA_GATT_ERROR; 414 } 415 416 if (p_rcb->p_cback) 417 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data); 418 } 419 /******************************************************************************* 420 ** 421 ** Function bta_gatts_add_char_descr 422 ** 423 ** Description action function to add characteristic descriptor. 424 ** 425 ** Returns none. 426 ** 427 *******************************************************************************/ 428 void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 429 { 430 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 431 UINT16 attr_id = 0; 432 tBTA_GATTS cb_data; 433 434 attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific, 435 p_msg->api_add_char_descr.perm, 436 &p_msg->api_add_char_descr.descr_uuid); 437 438 cb_data.add_result.server_if = p_rcb->gatt_if; 439 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 440 cb_data.add_result.attr_id = attr_id; 441 // btla-specific ++ 442 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID)); 443 // btla-specific -- 444 445 if (attr_id) 446 { 447 cb_data.add_result.status = BTA_GATT_OK; 448 } 449 else 450 { 451 cb_data.add_result.status = BTA_GATT_ERROR; 452 } 453 454 if (p_rcb->p_cback) 455 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data); 456 457 } 458 /******************************************************************************* 459 ** 460 ** Function bta_gatts_delete_service 461 ** 462 ** Description action function to delete a service. 463 ** 464 ** Returns none. 465 ** 466 *******************************************************************************/ 467 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 468 { 469 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 470 tBTA_GATTS cb_data; 471 472 cb_data.srvc_oper.server_if = p_rcb->gatt_if; 473 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 474 475 if (GATTS_DeleteService(p_rcb->gatt_if, 476 &p_srvc_cb->service_uuid, 477 p_srvc_cb->inst_num)) 478 { 479 cb_data.srvc_oper.status = BTA_GATT_OK; 480 memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB)); 481 } 482 else 483 { 484 cb_data.srvc_oper.status = BTA_GATT_ERROR; 485 } 486 487 if (p_rcb->p_cback) 488 (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data); 489 490 } 491 /******************************************************************************* 492 ** 493 ** Function bta_gatts_start_service 494 ** 495 ** Description action function to start a service. 496 ** 497 ** Returns none. 498 ** 499 *******************************************************************************/ 500 void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 501 { 502 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 503 tBTA_GATTS cb_data; 504 505 cb_data.srvc_oper.server_if = p_rcb->gatt_if; 506 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific; 507 508 if (GATTS_StartService(p_rcb->gatt_if, 509 p_srvc_cb->service_id, 510 p_msg->api_start.transport) == GATT_SUCCESS) 511 { 512 APPL_TRACE_DEBUG1("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id); 513 cb_data.srvc_oper.status = BTA_GATT_OK; 514 } 515 else 516 { 517 cb_data.srvc_oper.status = BTA_GATT_ERROR; 518 } 519 520 if (p_rcb->p_cback) 521 (*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data); 522 523 } 524 /******************************************************************************* 525 ** 526 ** Function bta_gatts_stop_service 527 ** 528 ** Description action function to stop a service. 529 ** 530 ** Returns none. 531 ** 532 *******************************************************************************/ 533 void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg) 534 { 535 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx]; 536 tBTA_GATTS cb_data; 537 538 GATTS_StopService(p_srvc_cb->service_id); 539 cb_data.srvc_oper.server_if = p_rcb->gatt_if; 540 cb_data.srvc_oper.service_id = p_srvc_cb->service_id; 541 cb_data.srvc_oper.status = BTA_GATT_OK; 542 APPL_TRACE_ERROR1("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id); 543 544 if (p_rcb->p_cback) 545 (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data); 546 547 } 548 /******************************************************************************* 549 ** 550 ** Function bta_gatts_send_rsp 551 ** 552 ** Description GATTS send response. 553 ** 554 ** Returns none. 555 ** 556 *******************************************************************************/ 557 void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 558 { 559 560 if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific, 561 p_msg->api_rsp.trans_id, 562 p_msg->api_rsp.status, 563 (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS) 564 { 565 APPL_TRACE_ERROR0("Sending response failed"); 566 } 567 568 } 569 /******************************************************************************* 570 ** 571 ** Function bta_gatts_send_rsp 572 ** 573 ** Description GATTS send response. 574 ** 575 ** Returns none. 576 ** 577 *******************************************************************************/ 578 void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 579 { 580 tBTA_GATTS_SRVC_CB *p_srvc_cb; 581 tBTA_GATT_STATUS status; 582 583 584 p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id); 585 586 if (p_srvc_cb ) 587 { 588 if (p_msg->api_indicate.need_confirm) 589 590 status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific, 591 p_msg->api_indicate.attr_id, 592 p_msg->api_indicate.len, 593 p_msg->api_indicate.value); 594 else 595 status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific, 596 p_msg->api_indicate.attr_id, 597 p_msg->api_indicate.len, 598 p_msg->api_indicate.value); 599 600 if (status != GATT_SUCCESS && 601 p_msg->api_indicate.need_confirm && 602 p_cb->rcb[p_srvc_cb->rcb_idx].p_cback) 603 { 604 (*p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)(BTA_GATTS_CONF_EVT, (tBTA_GATTS *)&status); 605 } 606 } 607 else 608 { 609 APPL_TRACE_ERROR1("Not an registered servce attribute ID: 0x%04x", p_msg->api_indicate.attr_id); 610 } 611 } 612 613 614 /******************************************************************************* 615 ** 616 ** Function bta_gatts_open 617 ** 618 ** Description 619 ** 620 ** Returns none. 621 ** 622 *******************************************************************************/ 623 void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 624 { 625 tBTA_GATTS_RCB *p_rcb=NULL; 626 tBTA_GATT_STATUS status= BTA_GATT_ERROR; 627 628 629 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL) 630 { 631 if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, p_msg->api_open.is_direct)) 632 { 633 status = BTA_GATT_OK; 634 } 635 } 636 else 637 { 638 APPL_TRACE_ERROR1("Inavlide server_if=%d", p_msg->api_open.server_if); 639 } 640 641 if (p_rcb && p_rcb->p_cback) 642 (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, (tBTA_GATTS *)&status); 643 644 } 645 /******************************************************************************* 646 ** 647 ** Function bta_gatts_cancel_open 648 ** 649 ** Description 650 ** 651 ** Returns none. 652 ** 653 *******************************************************************************/ 654 void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 655 { 656 tBTA_GATTS_RCB *p_rcb; 657 tBTA_GATT_STATUS status= BTA_GATT_ERROR; 658 659 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL) 660 { 661 if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, p_msg->api_cancel_open.is_direct)) 662 { 663 APPL_TRACE_ERROR0("bta_gatts_cancel_open failed for open request"); 664 } 665 else 666 { 667 status= BTA_GATT_OK; 668 } 669 } 670 else 671 { 672 APPL_TRACE_ERROR1("Inavlide server_if=%d", p_msg->api_cancel_open.server_if); 673 } 674 675 if (p_rcb && p_rcb->p_cback) 676 (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, (tBTA_GATTS *)&status); 677 } 678 /******************************************************************************* 679 ** 680 ** Function bta_gatts_close 681 ** 682 ** Description 683 ** 684 ** Returns none. 685 ** 686 *******************************************************************************/ 687 void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg) 688 { 689 tBTA_GATTS_RCB *p_rcb; 690 tBTA_GATT_STATUS status= BTA_GATT_ERROR; 691 tGATT_IF gatt_if; 692 BD_ADDR remote_bda; 693 694 if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda)) 695 { 696 if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) 697 { 698 APPL_TRACE_ERROR1("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific); 699 } 700 else 701 { 702 status= BTA_GATT_OK; 703 } 704 705 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 706 707 if (p_rcb && p_rcb->p_cback) 708 (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status); 709 } 710 else 711 { 712 APPL_TRACE_ERROR1("Unknown connection ID: %d", p_msg->hdr.layer_specific); 713 } 714 715 } 716 717 718 /******************************************************************************* 719 ** 720 ** Function bta_gatts_request_cback 721 ** 722 ** Description GATTS attribute request callback. 723 ** 724 ** Returns none. 725 ** 726 *******************************************************************************/ 727 static void bta_gatts_send_request_cback (UINT16 conn_id, 728 UINT32 trans_id, 729 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data) 730 { 731 tBTA_GATTS cb_data; 732 tBTA_GATTS_RCB *p_rcb; 733 tGATT_IF gatt_if; 734 735 memset(&cb_data, 0 , sizeof(tBTA_GATTS)); 736 737 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda)) 738 { 739 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); 740 741 APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d", conn_id, trans_id, req_type); 742 743 if (p_rcb && p_rcb->p_cback) 744 { 745 cb_data.req_data.conn_id = conn_id; 746 cb_data.req_data.trans_id = trans_id; 747 cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data; 748 749 (*p_rcb->p_cback)(req_type, &cb_data); 750 } 751 else 752 { 753 APPL_TRACE_ERROR1("connection request on gatt_if[%d] is not interested", gatt_if); 754 } 755 } 756 else 757 { 758 APPL_TRACE_ERROR1("request received on unknown connectino ID: %d", conn_id); 759 } 760 } 761 762 /******************************************************************************* 763 ** 764 ** Function bta_gatts_conn_cback 765 ** 766 ** Description connection callback. 767 ** 768 ** Returns none. 769 ** 770 *******************************************************************************/ 771 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, 772 BOOLEAN connected, tGATT_DISCONN_REASON reason) 773 { 774 tBTA_GATTS cb_data; 775 UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT; 776 tBTA_GATTS_RCB *p_reg; 777 778 APPL_TRACE_DEBUG4 ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d", 779 gatt_if, conn_id, connected, reason); 780 APPL_TRACE_DEBUG6("bta_gatts_conn_cback bda :%02x-%02x-%02x-%02x-%02x-%02x ", 781 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); 782 783 p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); 784 785 if (p_reg && p_reg->p_cback) 786 { 787 cb_data.conn.conn_id = conn_id; 788 cb_data.conn.server_if = gatt_if; 789 cb_data.conn.reason = reason; 790 memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN); 791 (*p_reg->p_cback)(evt, &cb_data); 792 } 793 else 794 { 795 APPL_TRACE_ERROR1("bta_gatts_conn_cback server_if=%d not found",gatt_if); 796 } 797 } 798 #endif /* BTA_GATT_INCLUDED */ 799