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