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