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#include "bt_target.h"
27
28#include <base/logging.h>
29#include <string.h>
30#include "bt_common.h"
31#include "bta_gatts_co.h"
32#include "bta_gatts_int.h"
33#include "bta_sys.h"
34#include "btif/include/btif_debug_conn.h"
35#include "btm_ble_api.h"
36#include "osi/include/osi.h"
37#include "utl.h"
38
39static void bta_gatts_nv_save_cback(bool is_saved,
40                                    tGATTS_HNDL_RANGE* p_hndl_range);
41static bool bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
42                                       tGATTS_SRV_CHG_REQ* p_req,
43                                       tGATTS_SRV_CHG_RSP* p_rsp);
44
45static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bda,
46                                 uint16_t conn_id, bool connected,
47                                 tGATT_DISCONN_REASON reason,
48                                 tGATT_TRANSPORT transport);
49static void bta_gatts_send_request_cback(uint16_t conn_id, uint32_t trans_id,
50                                         tGATTS_REQ_TYPE req_type,
51                                         tGATTS_DATA* p_data);
52static void bta_gatts_cong_cback(uint16_t conn_id, bool congested);
53static void bta_gatts_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
54                                       uint8_t tx_phy, uint8_t rx_phy,
55                                       uint8_t status);
56static void bta_gatts_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
57                                        uint16_t interval, uint16_t latency,
58                                        uint16_t timeout, uint8_t status);
59
60static tGATT_CBACK bta_gatts_cback = {bta_gatts_conn_cback,
61                                      NULL,
62                                      NULL,
63                                      NULL,
64                                      bta_gatts_send_request_cback,
65                                      NULL,
66                                      bta_gatts_cong_cback,
67                                      bta_gatts_phy_update_cback,
68                                      bta_gatts_conn_update_cback};
69
70tGATT_APPL_INFO bta_gatts_nv_cback = {bta_gatts_nv_save_cback,
71                                      bta_gatts_nv_srv_chg_cback};
72
73/*******************************************************************************
74 *
75 * Function         bta_gatts_nv_save_cback
76 *
77 * Description      NV save callback function.
78 *
79 * Parameter        is_add: true is to add a handle range; otherwise is to
80 *                          delete.
81 * Returns          none.
82 *
83 ******************************************************************************/
84static void bta_gatts_nv_save_cback(bool is_add,
85                                    tGATTS_HNDL_RANGE* p_hndl_range) {
86  bta_gatts_co_update_handle_range(is_add,
87                                   (tBTA_GATTS_HNDL_RANGE*)p_hndl_range);
88}
89
90/*******************************************************************************
91 *
92 * Function         bta_gatts_nv_srv_chg_cback
93 *
94 * Description      NV save callback function.
95 *
96 * Parameter        is_add: true is to add a handle range; otherwise is to
97 *                          delete.
98 * Returns          none.
99 *
100 ******************************************************************************/
101static bool bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
102                                       tGATTS_SRV_CHG_REQ* p_req,
103                                       tGATTS_SRV_CHG_RSP* p_rsp) {
104  return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD)cmd,
105                              (tBTA_GATTS_SRV_CHG_REQ*)p_req,
106                              (tBTA_GATTS_SRV_CHG_RSP*)p_rsp);
107}
108
109/*******************************************************************************
110 *
111 * Function         bta_gatts_enable
112 *
113 * Description      enable BTA GATTS module.
114 *
115 * Returns          none.
116 *
117 ******************************************************************************/
118void bta_gatts_enable(tBTA_GATTS_CB* p_cb) {
119  uint8_t index = 0;
120  tBTA_GATTS_HNDL_RANGE handle_range;
121
122  if (p_cb->enabled) {
123    APPL_TRACE_DEBUG("GATTS already enabled.");
124  } else {
125    memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
126
127    p_cb->enabled = true;
128
129    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));
132      index++;
133    }
134
135    APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);
136
137    if (!GATTS_NVRegister(&bta_gatts_nv_cback)) {
138      APPL_TRACE_ERROR("BTA GATTS NV register failed.");
139    }
140  }
141}
142
143/*******************************************************************************
144 *
145 * Function         bta_gatts_api_disable
146 *
147 * Description      disable BTA GATTS module.
148 *
149 * Returns          none.
150 *
151 ******************************************************************************/
152void bta_gatts_api_disable(tBTA_GATTS_CB* p_cb) {
153  uint8_t i;
154
155  if (p_cb->enabled) {
156    for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
157      if (p_cb->rcb[i].in_use) {
158        GATT_Deregister(p_cb->rcb[i].gatt_if);
159      }
160    }
161    memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
162  } else {
163    APPL_TRACE_ERROR("GATTS not enabled");
164  }
165}
166
167/*******************************************************************************
168 *
169 * Function         bta_gatts_register
170 *
171 * Description      register an application.
172 *
173 * Returns          none.
174 *
175 ******************************************************************************/
176void bta_gatts_register(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
177  tBTA_GATTS cb_data;
178  tBTA_GATT_STATUS status = BTA_GATT_OK;
179  uint8_t i, first_unuse = 0xff;
180
181  if (p_cb->enabled == false) {
182    bta_gatts_enable(p_cb);
183  }
184
185  for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
186    if (p_cb->rcb[i].in_use) {
187      if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid,
188                                 p_msg->api_reg.app_uuid)) {
189        APPL_TRACE_ERROR("application already registered.");
190        status = BTA_GATT_DUP_REG;
191        break;
192      }
193    }
194  }
195
196  if (status == BTA_GATT_OK) {
197    for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
198      if (first_unuse == 0xff && !p_cb->rcb[i].in_use) {
199        first_unuse = i;
200        break;
201      }
202    }
203
204    cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
205    memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
206    if (first_unuse != 0xff) {
207      APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d",
208                       first_unuse);
209
210      p_cb->rcb[first_unuse].in_use = true;
211      p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
212      memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid,
213             sizeof(tBT_UUID));
214      cb_data.reg_oper.server_if = p_cb->rcb[first_unuse].gatt_if =
215          GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
216      if (!p_cb->rcb[first_unuse].gatt_if) {
217        status = BTA_GATT_NO_RESOURCES;
218      } else {
219        tBTA_GATTS_INT_START_IF* p_buf = (tBTA_GATTS_INT_START_IF*)osi_malloc(
220            sizeof(tBTA_GATTS_INT_START_IF));
221        p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
222        p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;
223
224        bta_sys_sendmsg(p_buf);
225      }
226    } else {
227      status = BTA_GATT_NO_RESOURCES;
228    }
229  }
230  cb_data.reg_oper.status = status;
231  if (p_msg->api_reg.p_cback)
232    (*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
233}
234
235/*******************************************************************************
236 *
237 * Function         bta_gatts_start_if
238 *
239 * Description      start an application interface.
240 *
241 * Returns          none.
242 *
243 ******************************************************************************/
244void bta_gatts_start_if(UNUSED_ATTR tBTA_GATTS_CB* p_cb,
245                        tBTA_GATTS_DATA* p_msg) {
246  if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if)) {
247    GATT_StartIf(p_msg->int_start_if.server_if);
248  } else {
249    APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
250                     p_msg->int_start_if.server_if);
251  }
252}
253/*******************************************************************************
254 *
255 * Function         bta_gatts_deregister
256 *
257 * Description      deregister an application.
258 *
259 * Returns          none.
260 *
261 ******************************************************************************/
262void bta_gatts_deregister(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
263  tBTA_GATT_STATUS status = BTA_GATT_ERROR;
264  tBTA_GATTS_CBACK* p_cback = NULL;
265  uint8_t i;
266  tBTA_GATTS cb_data;
267
268  cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
269  cb_data.reg_oper.status = status;
270
271  for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) {
272    if (p_cb->rcb[i].in_use &&
273        p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if) {
274      p_cback = p_cb->rcb[i].p_cback;
275      status = BTA_GATT_OK;
276
277      /* deregister the app */
278      GATT_Deregister(p_cb->rcb[i].gatt_if);
279
280      /* reset cb */
281      memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
282      cb_data.reg_oper.status = status;
283      break;
284    }
285  }
286
287  if (p_cback) {
288    (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
289  } else {
290    APPL_TRACE_ERROR("application not registered.");
291  }
292}
293
294/*******************************************************************************
295 *
296 * Function         bta_gatts_delete_service
297 *
298 * Description      action function to delete a service.
299 *
300 * Returns          none.
301 *
302 ******************************************************************************/
303void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB* p_srvc_cb,
304                              tBTA_GATTS_DATA* p_msg) {
305  tBTA_GATTS_RCB* p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
306  tBTA_GATTS cb_data;
307
308  cb_data.srvc_oper.server_if = p_rcb->gatt_if;
309  cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
310
311  if (GATTS_DeleteService(p_rcb->gatt_if, &p_srvc_cb->service_uuid,
312                          p_srvc_cb->service_id)) {
313    cb_data.srvc_oper.status = BTA_GATT_OK;
314    memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
315  } else {
316    cb_data.srvc_oper.status = BTA_GATT_ERROR;
317  }
318
319  if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
320}
321
322/*******************************************************************************
323 *
324 * Function         bta_gatts_stop_service
325 *
326 * Description      action function to stop a service.
327 *
328 * Returns          none.
329 *
330 ******************************************************************************/
331void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB* p_srvc_cb,
332                            UNUSED_ATTR tBTA_GATTS_DATA* p_msg) {
333  tBTA_GATTS_RCB* p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
334  tBTA_GATTS cb_data;
335
336  GATTS_StopService(p_srvc_cb->service_id);
337  cb_data.srvc_oper.server_if = p_rcb->gatt_if;
338  cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
339  cb_data.srvc_oper.status = BTA_GATT_OK;
340  APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d",
341                   p_srvc_cb->service_id);
342
343  if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
344}
345/*******************************************************************************
346 *
347 * Function         bta_gatts_send_rsp
348 *
349 * Description      GATTS send response.
350 *
351 * Returns          none.
352 *
353 ******************************************************************************/
354void bta_gatts_send_rsp(UNUSED_ATTR tBTA_GATTS_CB* p_cb,
355                        tBTA_GATTS_DATA* p_msg) {
356  if (GATTS_SendRsp(p_msg->api_rsp.hdr.layer_specific, p_msg->api_rsp.trans_id,
357                    p_msg->api_rsp.status,
358                    (tGATTS_RSP*)p_msg->api_rsp.p_rsp) != GATT_SUCCESS) {
359    APPL_TRACE_ERROR("Sending response failed");
360  }
361}
362/*******************************************************************************
363 *
364 * Function         bta_gatts_indicate_handle
365 *
366 * Description      GATTS send handle value indication or notification.
367 *
368 * Returns          none.
369 *
370 ******************************************************************************/
371void bta_gatts_indicate_handle(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
372  tBTA_GATTS_SRVC_CB* p_srvc_cb;
373  tBTA_GATTS_RCB* p_rcb = NULL;
374  tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
375  tGATT_IF gatt_if;
376  RawAddress remote_bda;
377  tBTA_TRANSPORT transport;
378  tBTA_GATTS cb_data;
379
380  p_srvc_cb =
381      bta_gatts_find_srvc_cb_by_attr_id(p_cb, p_msg->api_indicate.attr_id);
382
383  if (p_srvc_cb) {
384    if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
385                                &gatt_if, remote_bda, &transport)) {
386      p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
387
388      if (p_msg->api_indicate.need_confirm)
389
390        status = GATTS_HandleValueIndication(
391            p_msg->api_indicate.hdr.layer_specific, p_msg->api_indicate.attr_id,
392            p_msg->api_indicate.len, p_msg->api_indicate.value);
393      else
394        status = GATTS_HandleValueNotification(
395            p_msg->api_indicate.hdr.layer_specific, p_msg->api_indicate.attr_id,
396            p_msg->api_indicate.len, p_msg->api_indicate.value);
397
398      /* if over BR_EDR, inform PM for mode change */
399      if (transport == BTA_TRANSPORT_BR_EDR) {
400        bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
401        bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
402      }
403    } else {
404      APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
405                       p_msg->api_indicate.hdr.layer_specific);
406    }
407
408    if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
409        p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback) {
410      cb_data.req_data.status = status;
411      cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
412
413      (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
414    }
415  } else {
416    APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
417                     p_msg->api_indicate.attr_id);
418  }
419}
420
421/*******************************************************************************
422 *
423 * Function         bta_gatts_open
424 *
425 * Description
426 *
427 * Returns          none.
428 *
429 ******************************************************************************/
430void bta_gatts_open(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
431  tBTA_GATTS_RCB* p_rcb = NULL;
432  tBTA_GATT_STATUS status = BTA_GATT_ERROR;
433  uint16_t conn_id;
434
435  p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if);
436  if (p_rcb != NULL) {
437    /* should always get the connection ID */
438    if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
439                     p_msg->api_open.is_direct, p_msg->api_open.transport,
440                     false)) {
441      status = BTA_GATT_OK;
442
443      if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
444                                    &conn_id, p_msg->api_open.transport)) {
445        status = BTA_GATT_ALREADY_OPEN;
446      }
447    }
448  } else {
449    APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
450  }
451
452  if (p_rcb && p_rcb->p_cback)
453    (*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, (tBTA_GATTS*)&status);
454}
455/*******************************************************************************
456 *
457 * Function         bta_gatts_cancel_open
458 *
459 * Description
460 *
461 * Returns          none.
462 *
463 ******************************************************************************/
464void bta_gatts_cancel_open(UNUSED_ATTR tBTA_GATTS_CB* p_cb,
465                           tBTA_GATTS_DATA* p_msg) {
466  tBTA_GATTS_RCB* p_rcb;
467  tBTA_GATT_STATUS status = BTA_GATT_ERROR;
468
469  p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if);
470  if (p_rcb != NULL) {
471    if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
472                            p_msg->api_cancel_open.is_direct)) {
473      APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
474    } else {
475      status = BTA_GATT_OK;
476    }
477  } else {
478    APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
479  }
480
481  if (p_rcb && p_rcb->p_cback)
482    (*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, (tBTA_GATTS*)&status);
483}
484/*******************************************************************************
485 *
486 * Function         bta_gatts_close
487 *
488 * Description
489 *
490 * Returns          none.
491 *
492 ******************************************************************************/
493void bta_gatts_close(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) {
494  tBTA_GATTS_RCB* p_rcb;
495  tBTA_GATT_STATUS status = BTA_GATT_ERROR;
496  tGATT_IF gatt_if;
497  RawAddress remote_bda;
498  tBTA_GATT_TRANSPORT transport;
499
500  if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda,
501                              &transport)) {
502    if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) {
503      APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d",
504                       p_msg->hdr.layer_specific);
505    } else {
506      status = BTA_GATT_OK;
507    }
508
509    p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
510
511    if (p_rcb && p_rcb->p_cback) {
512      if (transport == BTA_TRANSPORT_BR_EDR)
513        bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
514
515      (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS*)&status);
516    }
517  } else {
518    APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
519  }
520}
521
522/*******************************************************************************
523 *
524 * Function         bta_gatts_request_cback
525 *
526 * Description      GATTS attribute request callback.
527 *
528 * Returns          none.
529 *
530 ******************************************************************************/
531static void bta_gatts_send_request_cback(uint16_t conn_id, uint32_t trans_id,
532                                         tGATTS_REQ_TYPE req_type,
533                                         tGATTS_DATA* p_data) {
534  tBTA_GATTS cb_data;
535  tBTA_GATTS_RCB* p_rcb;
536  tGATT_IF gatt_if;
537  tBTA_GATT_TRANSPORT transport;
538
539  memset(&cb_data, 0, sizeof(tBTA_GATTS));
540
541  if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda,
542                              &transport)) {
543    p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
544
545    APPL_TRACE_DEBUG("%s: conn_id=%d trans_id=%d req_type=%d", __func__,
546                     conn_id, trans_id, req_type);
547
548    if (p_rcb && p_rcb->p_cback) {
549      /* if over BR_EDR, inform PM for mode change */
550      if (transport == BTA_TRANSPORT_BR_EDR) {
551        bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
552        bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
553      }
554
555      cb_data.req_data.conn_id = conn_id;
556      cb_data.req_data.trans_id = trans_id;
557      cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA*)p_data;
558
559      (*p_rcb->p_cback)(req_type, &cb_data);
560    } else {
561      APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested",
562                       gatt_if);
563    }
564  } else {
565    APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id);
566  }
567}
568
569/*******************************************************************************
570 *
571 * Function         bta_gatts_conn_cback
572 *
573 * Description      connection callback.
574 *
575 * Returns          none.
576 *
577 ******************************************************************************/
578static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bdaddr,
579                                 uint16_t conn_id, bool connected,
580                                 tGATT_DISCONN_REASON reason,
581                                 tGATT_TRANSPORT transport) {
582  tBTA_GATTS cb_data;
583  uint8_t evt = connected ? BTA_GATTS_CONNECT_EVT : BTA_GATTS_DISCONNECT_EVT;
584  tBTA_GATTS_RCB* p_reg;
585
586  APPL_TRACE_DEBUG(
587      "bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
588      gatt_if, conn_id, connected, reason);
589  VLOG(1) << __func__ << "  bda :" << bdaddr;
590
591  if (connected)
592    btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
593  else
594    btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
595
596  p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
597
598  if (p_reg && p_reg->p_cback) {
599    /* there is no RM for GATT */
600    if (transport == BTA_TRANSPORT_BR_EDR) {
601      if (connected)
602        bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bdaddr);
603      else
604        bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, bdaddr);
605    }
606
607    cb_data.conn.conn_id = conn_id;
608    cb_data.conn.server_if = gatt_if;
609    cb_data.conn.reason = reason;
610    cb_data.conn.transport = transport;
611    cb_data.conn.remote_bda = bdaddr;
612    (*p_reg->p_cback)(evt, &cb_data);
613  } else {
614    APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found", gatt_if);
615  }
616}
617
618static void bta_gatts_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
619                                       uint8_t tx_phy, uint8_t rx_phy,
620                                       uint8_t status) {
621  tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
622  if (!p_reg || !p_reg->p_cback) {
623    APPL_TRACE_ERROR("%s: server_if=%d not found", __func__, gatt_if);
624    return;
625  }
626
627  tBTA_GATTS cb_data;
628  cb_data.phy_update.conn_id = conn_id;
629  cb_data.phy_update.server_if = gatt_if;
630  cb_data.phy_update.tx_phy = tx_phy;
631  cb_data.phy_update.rx_phy = rx_phy;
632  cb_data.phy_update.status = status;
633  (*p_reg->p_cback)(BTA_GATTS_PHY_UPDATE_EVT, &cb_data);
634}
635
636static void bta_gatts_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
637                                        uint16_t interval, uint16_t latency,
638                                        uint16_t timeout, uint8_t status) {
639  tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
640  if (!p_reg || !p_reg->p_cback) {
641    APPL_TRACE_ERROR("%s: server_if=%d not found", __func__, gatt_if);
642    return;
643  }
644
645  tBTA_GATTS cb_data;
646  cb_data.conn_update.conn_id = conn_id;
647  cb_data.conn_update.server_if = gatt_if;
648  cb_data.conn_update.interval = interval;
649  cb_data.conn_update.latency = latency;
650  cb_data.conn_update.timeout = timeout;
651  cb_data.conn_update.status = status;
652  (*p_reg->p_cback)(BTA_GATTS_CONN_UPDATE_EVT, &cb_data);
653}
654
655/*******************************************************************************
656 *
657 * Function         bta_gatts_cong_cback
658 *
659 * Description      congestion callback.
660 *
661 * Returns          none.
662 *
663 ******************************************************************************/
664static void bta_gatts_cong_cback(uint16_t conn_id, bool congested) {
665  tBTA_GATTS_RCB* p_rcb;
666  tGATT_IF gatt_if;
667  tBTA_GATT_TRANSPORT transport;
668  tBTA_GATTS cb_data;
669
670  if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda,
671                              &transport)) {
672    p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
673
674    if (p_rcb && p_rcb->p_cback) {
675      cb_data.congest.conn_id = conn_id;
676      cb_data.congest.congested = congested;
677
678      (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
679    }
680  }
681}
682