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
39static 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*******************************************************************************/
56void 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*******************************************************************************/
83void 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*******************************************************************************/
113void 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*******************************************************************************/
143void 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*******************************************************************************/
173void 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*******************************************************************************/
200void 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*******************************************************************************/
233void 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*******************************************************************************/
261void 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*******************************************************************************/
283void 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*******************************************************************************/
306void 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*******************************************************************************/
331void 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*******************************************************************************/
363void 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*******************************************************************************/
396void 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*******************************************************************************/
425void 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*******************************************************************************/
449void 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*******************************************************************************/
474void 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