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