1 /******************************************************************************
2  *
3  *  Copyright 2010-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 is the implementation of the API for GATT server of BTA.
22  *
23  ******************************************************************************/
24 
25 #include <base/functional/bind.h>
26 #include <base/location.h>
27 #include <bluetooth/log.h>
28 
29 #include <cstdint>
30 #include <memory>
31 #include <vector>
32 
33 #include "bta/gatt/bta_gatts_int.h"
34 #include "internal_include/bt_target.h"
35 #include "osi/include/allocator.h"
36 #include "stack/include/bt_hdr.h"
37 #include "stack/include/main_thread.h"
38 #include "types/bluetooth/uuid.h"
39 #include "types/bt_transport.h"
40 #include "types/raw_address.h"
41 
42 using namespace bluetooth;
43 
44 /*****************************************************************************
45  *  Constants
46  ****************************************************************************/
47 
48 static const tBTA_SYS_REG bta_gatts_reg = {bta_gatts_hdl_event,
49                                            BTA_GATTS_Disable};
50 
51 /*******************************************************************************
52  *
53  * Function         BTA_GATTS_Disable
54  *
55  * Description      This function is called to disable GATTS module
56  *
57  * Parameters       None.
58  *
59  * Returns          None
60  *
61  ******************************************************************************/
BTA_GATTS_Disable(void)62 void BTA_GATTS_Disable(void) {
63   if (!bta_sys_is_register(BTA_ID_GATTS)) {
64     log::warn("GATTS Module not enabled/already disabled");
65     return;
66   }
67 
68   BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
69   p_buf->event = BTA_GATTS_API_DISABLE_EVT;
70   bta_sys_sendmsg(p_buf);
71   bta_sys_deregister(BTA_ID_GATTS);
72 }
73 
74 /*******************************************************************************
75  *
76  * Function         BTA_GATTS_AppRegister
77  *
78  * Description      This function is called to register application callbacks
79  *                    with BTA GATTS module.
80  *
81  * Parameters       p_app_uuid - applicaiton UUID
82  *                  p_cback - pointer to the application callback function.
83  *
84  * Returns          None
85  *
86  ******************************************************************************/
BTA_GATTS_AppRegister(const bluetooth::Uuid & app_uuid,tBTA_GATTS_CBACK * p_cback,bool eatt_support)87 void BTA_GATTS_AppRegister(const bluetooth::Uuid& app_uuid,
88                            tBTA_GATTS_CBACK* p_cback, bool eatt_support) {
89   tBTA_GATTS_API_REG* p_buf =
90       (tBTA_GATTS_API_REG*)osi_malloc(sizeof(tBTA_GATTS_API_REG));
91 
92   /* register with BTA system manager */
93   if (!bta_sys_is_register(BTA_ID_GATTS))
94     bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg);
95 
96   p_buf->hdr.event = BTA_GATTS_API_REG_EVT;
97   p_buf->app_uuid = app_uuid;
98   p_buf->p_cback = p_cback;
99   p_buf->eatt_support = eatt_support;
100 
101   bta_sys_sendmsg(p_buf);
102 }
103 
104 /*******************************************************************************
105  *
106  * Function         BTA_GATTS_AppDeregister
107  *
108  * Description      De-register with GATT Server.
109  *
110  * Parameters       app_id: applicatino ID.
111  *
112  * Returns          void
113  *
114  ******************************************************************************/
BTA_GATTS_AppDeregister(tGATT_IF server_if)115 void BTA_GATTS_AppDeregister(tGATT_IF server_if) {
116   tBTA_GATTS_API_DEREG* p_buf =
117       (tBTA_GATTS_API_DEREG*)osi_malloc(sizeof(tBTA_GATTS_API_DEREG));
118 
119   p_buf->hdr.event = BTA_GATTS_API_DEREG_EVT;
120   p_buf->server_if = server_if;
121 
122   bta_sys_sendmsg(p_buf);
123 }
124 
bta_gatts_add_service_impl(tGATT_IF server_if,std::vector<btgatt_db_element_t> service,BTA_GATTS_AddServiceCb cb)125 void bta_gatts_add_service_impl(tGATT_IF server_if,
126                                 std::vector<btgatt_db_element_t> service,
127                                 BTA_GATTS_AddServiceCb cb) {
128   uint8_t rcb_idx =
129       bta_gatts_find_app_rcb_idx_by_app_if(&bta_gatts_cb, server_if);
130 
131   log::info("rcb_idx={}", rcb_idx);
132 
133   if (rcb_idx == BTA_GATTS_INVALID_APP) {
134     cb.Run(GATT_ERROR, server_if, std::move(service));
135     return;
136   }
137 
138   uint8_t srvc_idx = bta_gatts_alloc_srvc_cb(&bta_gatts_cb, rcb_idx);
139   if (srvc_idx == BTA_GATTS_INVALID_APP) {
140     cb.Run(GATT_ERROR, server_if, std::move(service));
141     return;
142   }
143 
144   tGATT_STATUS status =
145       GATTS_AddService(server_if, service.data(), service.size());
146   if (status != GATT_SERVICE_STARTED) {
147     memset(&bta_gatts_cb.srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
148     log::error("service creation failed.");
149     cb.Run(GATT_ERROR, server_if, std::move(service));
150     return;
151   }
152 
153   bta_gatts_cb.srvc_cb[srvc_idx].service_uuid = service[0].uuid;
154 
155   // service_id is equal to service start handle
156   bta_gatts_cb.srvc_cb[srvc_idx].service_id = service[0].attribute_handle;
157   bta_gatts_cb.srvc_cb[srvc_idx].idx = srvc_idx;
158 
159   cb.Run(GATT_SUCCESS, server_if, std::move(service));
160   return;
161 }
162 
163 /*******************************************************************************
164  *
165  * Function         BTA_GATTS_AddService
166  *
167  * Description      Add the given |service| and all included elements to the
168  *                  GATT database. a |BTA_GATTS_ADD_SRVC_EVT| is triggered to
169  *                  report the status and attribute handles.
170  *
171  * Parameters       server_if: server interface.
172  *                  service: pointer vector describing service.
173  *
174  * Returns          Returns |GATT_SUCCESS| on success or |GATT_ERROR| if the
175  *                  service cannot be added.
176  *
177  ******************************************************************************/
BTA_GATTS_AddService(tGATT_IF server_if,std::vector<btgatt_db_element_t> service,BTA_GATTS_AddServiceCb cb)178 void BTA_GATTS_AddService(tGATT_IF server_if,
179                           std::vector<btgatt_db_element_t> service,
180                           BTA_GATTS_AddServiceCb cb) {
181   do_in_main_thread(FROM_HERE,
182                     base::BindOnce(&bta_gatts_add_service_impl, server_if,
183                                    std::move(service), std::move(cb)));
184 }
185 
186 /*******************************************************************************
187  *
188  * Function         BTA_GATTS_DeleteService
189  *
190  * Description      This function is called to delete a service. When this is
191  *                  done, a callback event BTA_GATTS_DELETE_EVT is report with
192  *                  the status.
193  *
194  * Parameters       service_id: service_id to be deleted.
195  *
196  * Returns          returns none.
197  *
198  ******************************************************************************/
BTA_GATTS_DeleteService(uint16_t service_id)199 void BTA_GATTS_DeleteService(uint16_t service_id) {
200   BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
201 
202   p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT;
203   p_buf->layer_specific = service_id;
204 
205   bta_sys_sendmsg(p_buf);
206 }
207 
208 /*******************************************************************************
209  *
210  * Function         BTA_GATTS_StopService
211  *
212  * Description      This function is called to stop a service.
213  *
214  * Parameters       service_id - service to be topped.
215  *
216  * Returns          None
217  *
218  ******************************************************************************/
BTA_GATTS_StopService(uint16_t service_id)219 void BTA_GATTS_StopService(uint16_t service_id) {
220   BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
221 
222   p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT;
223   p_buf->layer_specific = service_id;
224 
225   bta_sys_sendmsg(p_buf);
226 }
227 
228 /*******************************************************************************
229  *
230  * Function         BTA_GATTS_HandleValueIndication
231  *
232  * Description      This function is called to read a characteristics
233  *                  descriptor.
234  *
235  * Parameters       bda - remote device bd address to indicate.
236  *                  attr_id - attribute ID to indicate.
237  *                  value - data to indicate.
238  *                  need_confirm - if this indication expects a confirmation or
239  *                                 not.
240  *
241  * Returns          None
242  *
243  ******************************************************************************/
BTA_GATTS_HandleValueIndication(uint16_t conn_id,uint16_t attr_id,std::vector<uint8_t> value,bool need_confirm)244 void BTA_GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_id,
245                                      std::vector<uint8_t> value,
246                                      bool need_confirm) {
247 
248   if (value.size() > sizeof(tBTA_GATTS_API_INDICATION::value)) {
249     log::error("data to indicate is too long");
250     return;
251   }
252 
253   tBTA_GATTS_API_INDICATION* p_buf =
254       (tBTA_GATTS_API_INDICATION*)osi_calloc(sizeof(tBTA_GATTS_API_INDICATION));
255 
256   p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT;
257   p_buf->hdr.layer_specific = conn_id;
258   p_buf->attr_id = attr_id;
259   p_buf->need_confirm = need_confirm;
260   if (value.size() > 0) {
261     p_buf->len = value.size();
262     memcpy(p_buf->value, value.data(), value.size());
263   }
264 
265   bta_sys_sendmsg(p_buf);
266 }
267 
268 /*******************************************************************************
269  *
270  * Function         BTA_GATTS_SendRsp
271  *
272  * Description      This function is called to send a response to a request.
273  *
274  * Parameters       conn_id - connection identifier.
275  *                  trans_id - transaction ID.
276  *                  status - response status
277  *                  p_msg - response data.
278  *
279  * Returns          None
280  *
281  ******************************************************************************/
BTA_GATTS_SendRsp(uint16_t conn_id,uint32_t trans_id,tGATT_STATUS status,tGATTS_RSP * p_msg)282 void BTA_GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id, tGATT_STATUS status,
283                        tGATTS_RSP* p_msg) {
284   const size_t len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tGATTS_RSP);
285   tBTA_GATTS_API_RSP* p_buf = (tBTA_GATTS_API_RSP*)osi_calloc(len);
286 
287   p_buf->hdr.event = BTA_GATTS_API_RSP_EVT;
288   p_buf->hdr.layer_specific = conn_id;
289   p_buf->trans_id = trans_id;
290   p_buf->status = status;
291   if (p_msg != NULL) {
292     p_buf->p_rsp = (tGATTS_RSP*)(p_buf + 1);
293     memcpy(p_buf->p_rsp, p_msg, sizeof(tGATTS_RSP));
294   }
295 
296   bta_sys_sendmsg(p_buf);
297 }
298 
299 /*******************************************************************************
300  *
301  * Function         BTA_GATTS_Open
302  *
303  * Description      Open a direct open connection or add a background auto
304  *                  connection bd address
305  *
306  * Parameters       server_if: server interface.
307  *                  remote_bda: remote device BD address.
308  *                  is_direct: direct connection or background auto connection
309  *                  transport : Transport on which GATT connection to be opened
310  *                              (BR/EDR or LE)
311  *
312  * Returns          void
313  *
314  ******************************************************************************/
BTA_GATTS_Open(tGATT_IF server_if,const RawAddress & remote_bda,tBLE_ADDR_TYPE addr_type,bool is_direct,tBT_TRANSPORT transport)315 void BTA_GATTS_Open(tGATT_IF server_if, const RawAddress& remote_bda,
316                     tBLE_ADDR_TYPE addr_type, bool is_direct,
317                     tBT_TRANSPORT transport) {
318   tBTA_GATTS_API_OPEN* p_buf =
319       (tBTA_GATTS_API_OPEN*)osi_malloc(sizeof(tBTA_GATTS_API_OPEN));
320 
321   p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
322   p_buf->server_if = server_if;
323   if (is_direct) {
324     p_buf->connection_type = BTM_BLE_DIRECT_CONNECTION;
325   } else {
326     p_buf->connection_type = BTM_BLE_BKG_CONNECT_ALLOW_LIST;
327   }
328   p_buf->transport = transport;
329   p_buf->remote_bda = remote_bda;
330   p_buf->remote_addr_type = addr_type;
331 
332   bta_sys_sendmsg(p_buf);
333 }
334 
335 /*******************************************************************************
336  *
337  * Function         BTA_GATTS_CancelOpen
338  *
339  * Description      Cancel a direct open connection or remove a background auto
340  *                  connection bd address
341  *
342  * Parameters       server_if: server interface.
343  *                  remote_bda: remote device BD address.
344  *                  is_direct: direct connection or background auto connection
345  *
346  * Returns          void
347  *
348  ******************************************************************************/
BTA_GATTS_CancelOpen(tGATT_IF server_if,const RawAddress & remote_bda,bool is_direct)349 void BTA_GATTS_CancelOpen(tGATT_IF server_if, const RawAddress& remote_bda,
350                           bool is_direct) {
351   tBTA_GATTS_API_CANCEL_OPEN* p_buf = (tBTA_GATTS_API_CANCEL_OPEN*)osi_malloc(
352       sizeof(tBTA_GATTS_API_CANCEL_OPEN));
353 
354   p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT;
355   p_buf->server_if = server_if;
356   p_buf->is_direct = is_direct;
357   p_buf->remote_bda = remote_bda;
358 
359   bta_sys_sendmsg(p_buf);
360 }
361 
362 /*******************************************************************************
363  *
364  * Function         BTA_GATTS_Close
365  *
366  * Description      Close a connection  a remote device.
367  *
368  * Parameters       conn_id: connectino ID to be closed.
369  *
370  * Returns          void
371  *
372  ******************************************************************************/
BTA_GATTS_Close(uint16_t conn_id)373 void BTA_GATTS_Close(uint16_t conn_id) {
374   BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
375 
376   p_buf->event = BTA_GATTS_API_CLOSE_EVT;
377   p_buf->layer_specific = conn_id;
378 
379   bta_sys_sendmsg(p_buf);
380 }
381 
BTA_GATTS_InitBonded(void)382 void BTA_GATTS_InitBonded(void) {
383   log::info("");
384 
385   BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
386   p_buf->event = BTA_GATTS_API_INIT_BONDED_EVT;
387   bta_sys_sendmsg(p_buf);
388 }
389