1 /******************************************************************************
3 * Copyright (C) 2003-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains the GATT Server action functions for the state
24 ******************************************************************************/
27 #include "bt_target.h"
29 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
32 #include "bt_common.h"
34 #include "bta_gatts_int.h"
35 #include "bta_gatts_co.h"
36 #include "btm_ble_api.h"
37 #include "btif/include/btif_debug_conn.h"
40 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
41 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
42 tGATTS_SRV_CHG_RSP *p_rsp);
44 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
45 BOOLEAN connected, tGATT_DISCONN_REASON reason,
46 tGATT_TRANSPORT transport);
47 static void bta_gatts_send_request_cback (UINT16 conn_id,
49 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
50 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);
52 static tGATT_CBACK bta_gatts_cback =
58 bta_gatts_send_request_cback,
63 tGATT_APPL_INFO bta_gatts_nv_cback =
65 bta_gatts_nv_save_cback,
66 bta_gatts_nv_srv_chg_cback
69 /*******************************************************************************
71 ** Function bta_gatts_nv_save_cback
73 ** Description NV save callback function.
75 ** Parameter is_add: true is to add a handle range; otherwise is to delete.
78 *******************************************************************************/
79 static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_range)
81 bta_gatts_co_update_handle_range(is_add, (tBTA_GATTS_HNDL_RANGE *)p_hndl_range);
85 /*******************************************************************************
87 ** Function bta_gatts_nv_srv_chg_cback
89 ** Description NV save callback function.
91 ** Parameter is_add: true is to add a handle range; otherwise is to delete.
94 *******************************************************************************/
95 static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
96 tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
98 return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
99 (tBTA_GATTS_SRV_CHG_REQ *) p_req,
100 (tBTA_GATTS_SRV_CHG_RSP *) p_rsp);
104 /*******************************************************************************
106 ** Function bta_gatts_enable
108 ** Description enable BTA GATTS module.
112 *******************************************************************************/
113 void bta_gatts_enable(tBTA_GATTS_CB *p_cb)
116 tBTA_GATTS_HNDL_RANGE handle_range;
120 APPL_TRACE_DEBUG("GATTS already enabled.");
124 memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
126 p_cb->enabled = TRUE;
128 while ( bta_gatts_co_load_handle_range(index, &handle_range))
130 GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
131 memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
135 APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);
137 if (!GATTS_NVRegister(&bta_gatts_nv_cback))
139 APPL_TRACE_ERROR("BTA GATTS NV register failed.");
144 /*******************************************************************************
146 ** Function bta_gatts_api_disable
148 ** Description disable BTA GATTS module.
152 *******************************************************************************/
153 void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
159 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
161 if (p_cb->rcb[i].in_use)
163 GATT_Deregister(p_cb->rcb[i].gatt_if);
166 memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
170 APPL_TRACE_ERROR("GATTS not enabled");
174 /*******************************************************************************
176 ** Function bta_gatts_register
178 ** Description register an application.
182 *******************************************************************************/
183 void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
186 tBTA_GATT_STATUS status = BTA_GATT_OK;
187 UINT8 i, first_unuse = 0xff;
189 if (p_cb->enabled == FALSE)
191 bta_gatts_enable(p_cb);
194 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
196 if (p_cb->rcb[i].in_use)
198 if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid))
200 APPL_TRACE_ERROR("application already registered.");
201 status = BTA_GATT_DUP_REG;
207 if (status == BTA_GATT_OK)
209 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
211 if (first_unuse == 0xff && !p_cb->rcb[i].in_use)
218 cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
219 memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
220 if (first_unuse != 0xff)
222 APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d", first_unuse);
224 p_cb->rcb[first_unuse].in_use = TRUE;
225 p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
226 memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
227 cb_data.reg_oper.server_if =
228 p_cb->rcb[first_unuse].gatt_if =
229 GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
230 if ( !p_cb->rcb[first_unuse].gatt_if) {
231 status = BTA_GATT_NO_RESOURCES;
233 tBTA_GATTS_INT_START_IF *p_buf =
234 (tBTA_GATTS_INT_START_IF *)osi_malloc(sizeof(tBTA_GATTS_INT_START_IF));
235 p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
236 p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;
238 bta_sys_sendmsg(p_buf);
241 status = BTA_GATT_NO_RESOURCES;
245 cb_data.reg_oper.status = status;
246 if (p_msg->api_reg.p_cback)
247 (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
251 /*******************************************************************************
253 ** Function bta_gatts_start_if
255 ** Description start an application interface.
259 *******************************************************************************/
260 void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
264 if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if))
266 GATT_StartIf(p_msg->int_start_if.server_if);
270 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
271 p_msg->int_start_if.server_if );
274 /*******************************************************************************
276 ** Function bta_gatts_deregister
278 ** Description deregister an application.
282 *******************************************************************************/
283 void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
285 tBTA_GATT_STATUS status = BTA_GATT_ERROR;
286 tBTA_GATTS_CBACK *p_cback = NULL;
290 cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
291 cb_data.reg_oper.status = status;
293 for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
295 if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if)
297 p_cback = p_cb->rcb[i].p_cback;
298 status = BTA_GATT_OK;
300 /* deregister the app */
301 GATT_Deregister(p_cb->rcb[i].gatt_if);
304 memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
305 cb_data.reg_oper.status = status;
312 (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
316 APPL_TRACE_ERROR("application not registered.");
319 /*******************************************************************************
321 ** Function bta_gatts_create_srvc
323 ** Description action function to create a service.
327 *******************************************************************************/
328 void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
333 UINT16 service_id = 0;
335 cb_data.create.status = BTA_GATT_ERROR;
337 rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);
339 APPL_TRACE_ERROR("create service rcb_idx = %d", rcb_idx);
341 if (rcb_idx != BTA_GATTS_INVALID_APP)
343 if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP)
345 /* create the service now */
346 service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if,
347 &p_msg->api_create_svc.service_uuid,
348 p_msg->api_create_svc.inst,
349 p_msg->api_create_svc.num_handle,
350 p_msg->api_create_svc.is_pri);
354 memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
355 &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
356 p_cb->srvc_cb[srvc_idx].service_id = service_id;
357 p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst;
358 p_cb->srvc_cb[srvc_idx].idx = srvc_idx;
360 cb_data.create.status = BTA_GATT_OK;
361 cb_data.create.service_id = service_id;
362 cb_data.create.is_primary = p_msg->api_create_svc.is_pri;
363 cb_data.create.server_if = p_cb->rcb[rcb_idx].gatt_if;
367 cb_data.status = BTA_GATT_ERROR;
368 memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
369 APPL_TRACE_ERROR("service creation failed.");
371 memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
372 cb_data.create.svc_instance= p_msg->api_create_svc.inst;
374 if (p_cb->rcb[rcb_idx].p_cback)
375 (* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);
377 else /* application not registered */
379 APPL_TRACE_ERROR("Application not registered");
382 /*******************************************************************************
384 ** Function bta_gatts_add_include_srvc
386 ** Description action function to add an included service.
390 *******************************************************************************/
391 void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb,tBTA_GATTS_DATA * p_msg)
393 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
397 attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific,
398 p_msg->api_add_incl_srvc.included_service_id);
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;
406 cb_data.add_result.status = BTA_GATT_OK;
410 cb_data.add_result.status = BTA_GATT_ERROR;
414 (*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data);
416 /*******************************************************************************
418 ** Function bta_gatts_add_char
420 ** Description action function to add characteristic.
424 *******************************************************************************/
425 void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
427 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
431 attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
432 &p_msg->api_add_char.char_uuid,
433 p_msg->api_add_char.perm,
434 p_msg->api_add_char.property);
435 cb_data.add_result.server_if = p_rcb->gatt_if;
436 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
437 cb_data.add_result.attr_id = attr_id;
438 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID));
442 cb_data.add_result.status = BTA_GATT_OK;
446 cb_data.add_result.status = BTA_GATT_ERROR;
450 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
452 /*******************************************************************************
454 ** Function bta_gatts_add_char_descr
456 ** Description action function to add characteristic descriptor.
460 *******************************************************************************/
461 void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
463 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
467 attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
468 p_msg->api_add_char_descr.perm,
469 &p_msg->api_add_char_descr.descr_uuid);
471 cb_data.add_result.server_if = p_rcb->gatt_if;
472 cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
473 cb_data.add_result.attr_id = attr_id;
474 memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID));
478 cb_data.add_result.status = BTA_GATT_OK;
482 cb_data.add_result.status = BTA_GATT_ERROR;
486 (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);
489 /*******************************************************************************
491 ** Function bta_gatts_delete_service
493 ** Description action function to delete a service.
497 *******************************************************************************/
498 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
500 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
503 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
504 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
506 if (GATTS_DeleteService(p_rcb->gatt_if,
507 &p_srvc_cb->service_uuid,
508 p_srvc_cb->inst_num))
510 cb_data.srvc_oper.status = BTA_GATT_OK;
511 memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
515 cb_data.srvc_oper.status = BTA_GATT_ERROR;
519 (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
522 /*******************************************************************************
524 ** Function bta_gatts_start_service
526 ** Description action function to start a service.
530 *******************************************************************************/
531 void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
533 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
536 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
537 cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
539 if (GATTS_StartService(p_rcb->gatt_if,
540 p_srvc_cb->service_id,
541 p_msg->api_start.transport) == GATT_SUCCESS)
543 APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
544 cb_data.srvc_oper.status = BTA_GATT_OK;
548 cb_data.srvc_oper.status = BTA_GATT_ERROR;
552 (*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data);
555 /*******************************************************************************
557 ** Function bta_gatts_stop_service
559 ** Description action function to stop a service.
563 *******************************************************************************/
564 void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA * p_msg)
566 tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
570 GATTS_StopService(p_srvc_cb->service_id);
571 cb_data.srvc_oper.server_if = p_rcb->gatt_if;
572 cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
573 cb_data.srvc_oper.status = BTA_GATT_OK;
574 APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
577 (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
580 /*******************************************************************************
582 ** Function bta_gatts_send_rsp
584 ** Description GATTS send response.
588 *******************************************************************************/
589 void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
593 if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific,
594 p_msg->api_rsp.trans_id,
595 p_msg->api_rsp.status,
596 (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS)
598 APPL_TRACE_ERROR("Sending response failed");
602 /*******************************************************************************
604 ** Function bta_gatts_indicate_handle
606 ** Description GATTS send handle value indication or notification.
610 *******************************************************************************/
611 void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
613 tBTA_GATTS_SRVC_CB *p_srvc_cb;
614 tBTA_GATTS_RCB *p_rcb = NULL;
615 tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
618 tBTA_TRANSPORT transport;
621 p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
625 if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
626 &gatt_if, remote_bda, &transport))
628 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
630 if (p_msg->api_indicate.need_confirm)
632 status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
633 p_msg->api_indicate.attr_id,
634 p_msg->api_indicate.len,
635 p_msg->api_indicate.value);
637 status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
638 p_msg->api_indicate.attr_id,
639 p_msg->api_indicate.len,
640 p_msg->api_indicate.value);
642 /* if over BR_EDR, inform PM for mode change */
643 if (transport == BTA_TRANSPORT_BR_EDR)
645 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
646 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
651 APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
652 p_msg->api_indicate.hdr.layer_specific);
655 if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
656 p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
658 cb_data.req_data.status = status;
659 cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
661 (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
666 APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
667 p_msg->api_indicate.attr_id);
672 /*******************************************************************************
674 ** Function bta_gatts_open
680 *******************************************************************************/
681 void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
683 tBTA_GATTS_RCB *p_rcb=NULL;
684 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
688 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
690 /* should always get the connection ID */
691 if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
692 p_msg->api_open.is_direct, p_msg->api_open.transport))
694 status = BTA_GATT_OK;
696 if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
697 &conn_id, p_msg->api_open.transport))
699 status = BTA_GATT_ALREADY_OPEN;
705 APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
708 if (p_rcb && p_rcb->p_cback)
709 (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, (tBTA_GATTS *)&status);
712 /*******************************************************************************
714 ** Function bta_gatts_cancel_open
720 *******************************************************************************/
721 void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
723 tBTA_GATTS_RCB *p_rcb;
724 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
727 if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
729 if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
730 p_msg->api_cancel_open.is_direct))
732 APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
741 APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
744 if (p_rcb && p_rcb->p_cback)
745 (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, (tBTA_GATTS *)&status);
747 /*******************************************************************************
749 ** Function bta_gatts_close
755 *******************************************************************************/
756 void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
758 tBTA_GATTS_RCB *p_rcb;
759 tBTA_GATT_STATUS status= BTA_GATT_ERROR;
762 tBTA_GATT_TRANSPORT transport;
766 if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
768 if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
770 APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
777 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
779 if (p_rcb && p_rcb->p_cback)
781 if (transport == BTA_TRANSPORT_BR_EDR)
782 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);
784 (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status);
789 APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
793 /*******************************************************************************
795 ** Function bta_gatts_listen
797 ** Description Start or stop listening for LE connection on a GATT server
801 *******************************************************************************/
802 void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
804 tBTA_GATTS_RCB *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
808 cb_data.reg_oper.status = BTA_GATT_OK;
809 cb_data.reg_oper.server_if = p_msg->api_listen.server_if;
813 APPL_TRACE_ERROR("Unknown GATTS application");
817 if (!GATT_Listen(p_msg->api_listen.server_if,
818 p_msg->api_listen.start,
819 p_msg->api_listen.remote_bda))
821 cb_data.status = BTA_GATT_ERROR;
822 APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
826 (*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
829 /*******************************************************************************
831 ** Function bta_gatts_request_cback
833 ** Description GATTS attribute request callback.
837 *******************************************************************************/
838 static void bta_gatts_send_request_cback (UINT16 conn_id,
840 tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data)
843 tBTA_GATTS_RCB *p_rcb;
845 tBTA_GATT_TRANSPORT transport;
847 memset(&cb_data, 0 , sizeof(tBTA_GATTS));
849 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
851 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
853 APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
854 conn_id, trans_id, req_type);
856 if (p_rcb && p_rcb->p_cback)
858 /* if over BR_EDR, inform PM for mode change */
859 if (transport == BTA_TRANSPORT_BR_EDR)
861 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
862 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
865 cb_data.req_data.conn_id = conn_id;
866 cb_data.req_data.trans_id = trans_id;
867 cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data;
869 (*p_rcb->p_cback)(req_type, &cb_data);
873 APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
878 APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id);
882 /*******************************************************************************
884 ** Function bta_gatts_conn_cback
886 ** Description connection callback.
890 *******************************************************************************/
891 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
892 BOOLEAN connected, tGATT_DISCONN_REASON reason,
893 tGATT_TRANSPORT transport)
896 UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
897 tBTA_GATTS_RCB *p_reg;
899 APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
900 gatt_if, conn_id, connected, reason);
901 APPL_TRACE_DEBUG("bta_gatts_conn_cback bda :%02x-%02x-%02x-%02x-%02x-%02x ",
902 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
905 bdcpy(bdaddr.address, bda);
907 btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
909 btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
911 p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
913 if (p_reg && p_reg->p_cback)
915 /* there is no RM for GATT */
916 if (transport == BTA_TRANSPORT_BR_EDR)
919 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
921 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda);
924 cb_data.conn.conn_id = conn_id;
925 cb_data.conn.server_if = gatt_if;
926 cb_data.conn.reason = reason;
927 cb_data.conn.transport = transport;
928 memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
929 (*p_reg->p_cback)(evt, &cb_data);
933 APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found",gatt_if);
937 /*******************************************************************************
939 ** Function bta_gatts_cong_cback
941 ** Description congestion callback.
945 *******************************************************************************/
946 static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
948 tBTA_GATTS_RCB *p_rcb;
950 tBTA_GATT_TRANSPORT transport;
953 if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
955 p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
957 if (p_rcb && p_rcb->p_cback)
959 cb_data.congest.conn_id = conn_id;
960 cb_data.congest.congested = congested;
962 (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
966 #endif /* BTA_GATT_INCLUDED */