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 #if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
28 
29 #include <string.h>
30 #include "bt_common.h"
31 #include "bta_sys.h"
32 #include "bta_gatt_api.h"
33 #include "bta_gatts_int.h"
34 
35 /*****************************************************************************
36 **  Constants
37 *****************************************************************************/
38 
39 static const tBTA_SYS_REG bta_gatts_reg =
40 {
41     bta_gatts_hdl_event,
42     BTA_GATTS_Disable
43 };
44 
45 /*******************************************************************************
46 **
47 ** Function         BTA_GATTS_Disable
48 **
49 ** Description      This function is called to disable GATTS module
50 **
51 ** Parameters       None.
52 **
53 ** Returns          None
54 **
55 *******************************************************************************/
BTA_GATTS_Disable(void)56 void BTA_GATTS_Disable(void)
57 {
58     if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
59     {
60         APPL_TRACE_WARNING("GATTS Module not enabled/already disabled");
61         return;
62     }
63 
64     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR));
65     p_buf->event = BTA_GATTS_API_DISABLE_EVT;
66     bta_sys_sendmsg(p_buf);
67     bta_sys_deregister(BTA_ID_GATTS);
68 }
69 
70 /*******************************************************************************
71 **
72 ** Function         BTA_GATTS_AppRegister
73 **
74 ** Description      This function is called to register application callbacks
75 **                    with BTA GATTS module.
76 **
77 ** Parameters       p_app_uuid - applicaiton UUID
78 **                  p_cback - pointer to the application callback function.
79 **
80 ** Returns          None
81 **
82 *******************************************************************************/
BTA_GATTS_AppRegister(tBT_UUID * p_app_uuid,tBTA_GATTS_CBACK * p_cback)83 void BTA_GATTS_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTS_CBACK *p_cback)
84 {
85     tBTA_GATTS_API_REG *p_buf =
86         (tBTA_GATTS_API_REG *)osi_malloc(sizeof(tBTA_GATTS_API_REG));
87 
88     /* register with BTA system manager */
89     if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
90         bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg);
91 
92     p_buf->hdr.event = BTA_GATTS_API_REG_EVT;
93     if (p_app_uuid != NULL)
94         memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_UUID));
95     p_buf->p_cback = p_cback;
96 
97     bta_sys_sendmsg(p_buf);
98 }
99 
100 
101 
102 /*******************************************************************************
103 **
104 ** Function         BTA_GATTS_AppDeregister
105 **
106 ** Description      De-register with GATT Server.
107 **
108 ** Parameters       app_id: applicatino ID.
109 **
110 ** Returns          void
111 **
112 *******************************************************************************/
BTA_GATTS_AppDeregister(tBTA_GATTS_IF server_if)113 void BTA_GATTS_AppDeregister(tBTA_GATTS_IF server_if)
114 {
115     tBTA_GATTS_API_DEREG *p_buf =
116         (tBTA_GATTS_API_DEREG *)osi_malloc(sizeof(tBTA_GATTS_API_DEREG));
117 
118     p_buf->hdr.event = BTA_GATTS_API_DEREG_EVT;
119     p_buf->server_if = server_if;
120 
121     bta_sys_sendmsg(p_buf);
122 }
123 
124 /*******************************************************************************
125 **
126 ** Function         BTA_GATTS_CreateService
127 **
128 ** Description      Create a service. When service creation is done, a callback
129 **                  event BTA_GATTS_CREATE_SRVC_EVT is called to report status
130 **                  and service ID to the profile. The service ID obtained in
131 **                  the callback function needs to be used when adding included
132 **                  service and characteristics/descriptors into the service.
133 **
134 ** Parameters       app_id: Profile ID this service is belonged to.
135 **                  p_service_uuid: service UUID.
136 **                  inst: instance ID number of this service.
137 **                  num_handle: numble of handle requessted for this service.
138 **                  is_primary: is this service a primary one or not.
139 **
140 ** Returns          void
141 **
142 *******************************************************************************/
BTA_GATTS_CreateService(tBTA_GATTS_IF server_if,tBT_UUID * p_service_uuid,UINT8 inst,UINT16 num_handle,BOOLEAN is_primary)143 void BTA_GATTS_CreateService(tBTA_GATTS_IF server_if, tBT_UUID *p_service_uuid, UINT8 inst,
144                              UINT16 num_handle, BOOLEAN is_primary)
145 {
146     tBTA_GATTS_API_CREATE_SRVC *p_buf =
147         (tBTA_GATTS_API_CREATE_SRVC *)osi_malloc(sizeof(tBTA_GATTS_API_CREATE_SRVC));
148 
149     p_buf->hdr.event = BTA_GATTS_API_CREATE_SRVC_EVT;
150     p_buf->server_if = server_if;
151     p_buf->inst = inst;
152     memcpy(&p_buf->service_uuid, p_service_uuid, sizeof(tBT_UUID));
153     p_buf->num_handle = num_handle;
154     p_buf->is_pri = is_primary;
155 
156     bta_sys_sendmsg(p_buf);
157 }
158 /*******************************************************************************
159 **
160 ** Function         BTA_GATTS_AddIncludeService
161 **
162 ** Description      This function is called to add an included service. After included
163 **                  service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
164 **                  is reported the included service ID.
165 **
166 ** Parameters       service_id: service ID to which this included service is to
167 **                              be added.
168 **                  included_service_id: the service ID to be included.
169 **
170 ** Returns          void
171 **
172 *******************************************************************************/
BTA_GATTS_AddIncludeService(UINT16 service_id,UINT16 included_service_id)173 void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_service_id)
174 {
175     tBTA_GATTS_API_ADD_INCL_SRVC *p_buf =
176         (tBTA_GATTS_API_ADD_INCL_SRVC *)osi_malloc(sizeof(tBTA_GATTS_API_ADD_INCL_SRVC));
177 
178     p_buf->hdr.event = BTA_GATTS_API_ADD_INCL_SRVC_EVT;
179     p_buf->hdr.layer_specific = service_id;
180     p_buf->included_service_id = included_service_id;
181 
182     bta_sys_sendmsg(p_buf);
183 }
184 
185 /*******************************************************************************
186 **
187 ** Function         BTA_GATTS_AddCharacteristic
188 **
189 ** Description      This function is called to add a characteristic into a service.
190 **
191 ** Parameters       service_id: service ID to which this included service is to
192 **                              be added.
193 **                  p_char_uuid : Characteristic UUID.
194 **                  perm      : Characteristic value declaration attribute permission.
195 **                  property  : Characteristic Properties
196 **
197 ** Returns          None
198 **
199 *******************************************************************************/
BTA_GATTS_AddCharacteristic(UINT16 service_id,tBT_UUID * p_char_uuid,tBTA_GATT_PERM perm,tBTA_GATT_CHAR_PROP property)200 void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID  *p_char_uuid,
201                                   tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property)
202 {
203     tBTA_GATTS_API_ADD_CHAR *p_buf =
204         (tBTA_GATTS_API_ADD_CHAR *)osi_calloc(sizeof(tBTA_GATTS_API_ADD_CHAR));
205 
206     p_buf->hdr.event = BTA_GATTS_API_ADD_CHAR_EVT;
207     p_buf->hdr.layer_specific = service_id;
208     p_buf->perm = perm;
209     p_buf->property = property;
210 
211     if (p_char_uuid)
212         memcpy(&p_buf->char_uuid, p_char_uuid, sizeof(tBT_UUID));
213 
214     bta_sys_sendmsg(p_buf);
215 }
216 
217 /*******************************************************************************
218 **
219 ** Function         BTA_GATTS_AddCharDescriptor
220 **
221 ** Description      This function is called to add characteristic descriptor. When
222 **                  it's done, a callback event BTA_GATTS_ADD_DESCR_EVT is called
223 **                  to report the status and an ID number for this descriptor.
224 **
225 ** Parameters       service_id: service ID to which this charatceristic descriptor is to
226 **                              be added.
227 **                  perm: descriptor access permission.
228 **                  p_descr_uuid: descriptor UUID.
229 **
230 ** Returns          returns status.
231 **
232 *******************************************************************************/
BTA_GATTS_AddCharDescriptor(UINT16 service_id,tBTA_GATT_PERM perm,tBT_UUID * p_descr_uuid)233 void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
234                                   tBTA_GATT_PERM perm,
235                                   tBT_UUID  * p_descr_uuid)
236 {
237     tBTA_GATTS_API_ADD_DESCR *p_buf =
238         (tBTA_GATTS_API_ADD_DESCR *)osi_calloc(sizeof(tBTA_GATTS_API_ADD_DESCR));
239 
240     p_buf->hdr.event = BTA_GATTS_API_ADD_DESCR_EVT;
241     p_buf->hdr.layer_specific = service_id;
242     p_buf->perm = perm;
243     if (p_descr_uuid)
244         memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID));
245 
246     bta_sys_sendmsg(p_buf);
247 }
248 
249 /*******************************************************************************
250 **
251 ** Function         BTA_GATTS_DeleteService
252 **
253 ** Description      This function is called to delete a service. When this is done,
254 **                  a callback event BTA_GATTS_DELETE_EVT is report with the status.
255 **
256 ** Parameters       service_id: service_id to be deleted.
257 **
258 ** Returns          returns none.
259 **
260 *******************************************************************************/
BTA_GATTS_DeleteService(UINT16 service_id)261 void BTA_GATTS_DeleteService(UINT16 service_id)
262 {
263     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR));
264 
265     p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT;
266     p_buf->layer_specific = service_id;
267 
268     bta_sys_sendmsg(p_buf);
269 }
270 
271 /*******************************************************************************
272 **
273 ** Function         BTA_GATTS_StartService
274 **
275 ** Description      This function is called to start a service.
276 **
277 ** Parameters       service_id: the service ID to be started.
278 **                  sup_transport: supported trasnport.
279 **
280 ** Returns          None.
281 **
282 *******************************************************************************/
BTA_GATTS_StartService(UINT16 service_id,tBTA_GATT_TRANSPORT sup_transport)283 void BTA_GATTS_StartService(UINT16 service_id, tBTA_GATT_TRANSPORT sup_transport)
284 {
285     tBTA_GATTS_API_START *p_buf =
286         (tBTA_GATTS_API_START *)osi_malloc(sizeof(tBTA_GATTS_API_START));
287 
288     p_buf->hdr.event = BTA_GATTS_API_START_SRVC_EVT;
289     p_buf->hdr.layer_specific = service_id;
290     p_buf->transport = sup_transport;
291 
292     bta_sys_sendmsg(p_buf);
293 }
294 
295 /*******************************************************************************
296 **
297 ** Function         BTA_GATTS_StopService
298 **
299 ** Description      This function is called to stop a service.
300 **
301 ** Parameters       service_id - service to be topped.
302 **
303 ** Returns          None
304 **
305 *******************************************************************************/
BTA_GATTS_StopService(UINT16 service_id)306 void BTA_GATTS_StopService(UINT16 service_id)
307 {
308     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR));
309 
310     p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT;
311     p_buf->layer_specific = service_id;
312 
313     bta_sys_sendmsg(p_buf);
314 }
315 
316 /*******************************************************************************
317 **
318 ** Function         BTA_GATTS_HandleValueIndication
319 **
320 ** Description      This function is called to read a characteristics descriptor.
321 **
322 ** Parameters       bda - remote device bd address to indicate.
323 **					attr_id - attribute ID to indicate.
324 **                  data_len - indicate data length.
325 **                  p_data: data to indicate.
326 **                  need_confirm - if this indication expects a confirmation or not.
327 **
328 ** Returns          None
329 **
330 *******************************************************************************/
BTA_GATTS_HandleValueIndication(UINT16 conn_id,UINT16 attr_id,UINT16 data_len,UINT8 * p_data,BOOLEAN need_confirm)331 void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 data_len,
332                                       UINT8 *p_data, BOOLEAN need_confirm)
333 {
334     tBTA_GATTS_API_INDICATION *p_buf =
335         (tBTA_GATTS_API_INDICATION *)osi_calloc(sizeof(tBTA_GATTS_API_INDICATION));
336 
337     p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT;
338     p_buf->hdr.layer_specific = conn_id;
339     p_buf->attr_id = attr_id;
340     p_buf->need_confirm = need_confirm;
341     if (data_len > 0 && p_data != NULL) {
342         p_buf->len = data_len;
343         memcpy(p_buf->value, p_data, data_len);
344     }
345 
346     bta_sys_sendmsg(p_buf);
347 }
348 
349 /*******************************************************************************
350 **
351 ** Function         BTA_GATTS_SendRsp
352 **
353 ** Description      This function is called to send a response to a request.
354 **
355 ** Parameters       conn_id - connection identifier.
356 **                  trans_id - transaction ID.
357 **                  status - response status
358 **                  p_msg - response data.
359 **
360 ** Returns          None
361 **
362 *******************************************************************************/
BTA_GATTS_SendRsp(UINT16 conn_id,UINT32 trans_id,tBTA_GATT_STATUS status,tBTA_GATTS_RSP * p_msg)363 void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
364                         tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg)
365 {
366     const size_t len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tBTA_GATTS_RSP);
367     tBTA_GATTS_API_RSP *p_buf = (tBTA_GATTS_API_RSP *)osi_calloc(len);
368 
369     p_buf->hdr.event = BTA_GATTS_API_RSP_EVT;
370     p_buf->hdr.layer_specific = conn_id;
371     p_buf->trans_id = trans_id;
372     p_buf->status = status;
373     if (p_msg != NULL) {
374         p_buf->p_rsp = (tBTA_GATTS_RSP *)(p_buf + 1);
375         memcpy(p_buf->p_rsp, p_msg, sizeof(tBTA_GATTS_RSP));
376     }
377 
378     bta_sys_sendmsg(p_buf);
379 }
380 
381 /*******************************************************************************
382 **
383 ** Function         BTA_GATTS_Open
384 **
385 ** Description      Open a direct open connection or add a background auto connection
386 **                  bd address
387 **
388 ** Parameters       server_if: server interface.
389 **                  remote_bda: remote device BD address.
390 **                  is_direct: direct connection or background auto connection
391 **                  transport : Transport on which GATT connection to be opened (BR/EDR or LE)
392 **
393 ** Returns          void
394 **
395 *******************************************************************************/
BTA_GATTS_Open(tBTA_GATTS_IF server_if,BD_ADDR remote_bda,BOOLEAN is_direct,tBTA_GATT_TRANSPORT transport)396 void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct,
397                     tBTA_GATT_TRANSPORT transport)
398 {
399     tBTA_GATTS_API_OPEN *p_buf =
400         (tBTA_GATTS_API_OPEN *)osi_malloc(sizeof(tBTA_GATTS_API_OPEN));
401 
402     p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
403     p_buf->server_if = server_if;
404     p_buf->is_direct = is_direct;
405     p_buf->transport = transport;
406     memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
407 
408     bta_sys_sendmsg(p_buf);
409 }
410 
411 /*******************************************************************************
412 **
413 ** Function         BTA_GATTS_CancelOpen
414 **
415 ** Description      Cancel a direct open connection or remove a background auto connection
416 **                  bd address
417 **
418 ** Parameters       server_if: server interface.
419 **                  remote_bda: remote device BD address.
420 **                  is_direct: direct connection or background auto connection
421 **
422 ** Returns          void
423 **
424 *******************************************************************************/
BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if,BD_ADDR remote_bda,BOOLEAN is_direct)425 void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct)
426 {
427     tBTA_GATTS_API_CANCEL_OPEN *p_buf =
428         (tBTA_GATTS_API_CANCEL_OPEN *)osi_malloc(sizeof(tBTA_GATTS_API_CANCEL_OPEN));
429 
430     p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT;
431     p_buf->server_if = server_if;
432     p_buf->is_direct = is_direct;
433     memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
434 
435     bta_sys_sendmsg(p_buf);
436 }
437 
438 /*******************************************************************************
439 **
440 ** Function         BTA_GATTS_Close
441 **
442 ** Description      Close a connection  a remote device.
443 **
444 ** Parameters       conn_id: connectino ID to be closed.
445 **
446 ** Returns          void
447 **
448 *******************************************************************************/
BTA_GATTS_Close(UINT16 conn_id)449 void BTA_GATTS_Close(UINT16 conn_id)
450 {
451     BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR));
452 
453     p_buf->event = BTA_GATTS_API_CLOSE_EVT;
454     p_buf->layer_specific = conn_id;
455 
456     bta_sys_sendmsg(p_buf);
457 }
458 
459 /*******************************************************************************
460 **
461 ** Function         BTA_GATTS_Listen
462 **
463 ** Description      Start advertisement to listen for connection request for a
464 **                  GATT server
465 **
466 ** Parameters       server_if: server interface.
467 **                  start: to start or stop listening for connection
468 **                  remote_bda: remote device BD address, if listen to all device
469 **                              use NULL.
470 **
471 ** Returns          void
472 **
473 *******************************************************************************/
BTA_GATTS_Listen(tBTA_GATTS_IF server_if,BOOLEAN start,BD_ADDR_PTR target_bda)474 void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, BD_ADDR_PTR target_bda)
475 {
476     tBTA_GATTS_API_LISTEN *p_buf =
477         (tBTA_GATTS_API_LISTEN *)osi_malloc(sizeof(tBTA_GATTS_API_LISTEN) + BD_ADDR_LEN);
478 
479     p_buf->hdr.event = BTA_GATTS_API_LISTEN_EVT;
480     p_buf->server_if = server_if;
481     p_buf->start = start;
482     if (target_bda) {
483         p_buf->remote_bda = (UINT8 *)(p_buf + 1);
484         memcpy(p_buf->remote_bda, target_bda, BD_ADDR_LEN);
485     } else {
486        p_buf->remote_bda = NULL;
487     }
488 
489     bta_sys_sendmsg(p_buf);
490 }
491 
492 #endif /* BTA_GATT_INCLUDED */
493