1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2013 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 * Filename: btif_gatt_server.c
22 *
23 * Description: GATT server implementation
24 *
25 ***********************************************************************************/
26
27 #define LOG_TAG "bt_btif_gatt"
28
29 #include <errno.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include <hardware/bluetooth.h>
35 #include <hardware/bt_gatt.h>
36
37 #include "btif_common.h"
38 #include "btif_util.h"
39
40 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
41
42 #include "bta_api.h"
43 #include "bta_gatt_api.h"
44 #include "btif_config.h"
45 #include "btif_dm.h"
46 #include "btif_gatt.h"
47 #include "btif_gatt_util.h"
48 #include "btif_storage.h"
49 #include "bt_common.h"
50 #include "osi/include/log.h"
51
52 /************************************************************************************
53 ** Constants & Macros
54 ************************************************************************************/
55
56 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
57 {\
58 LOG_WARN(LOG_TAG, "%s: BTGATT not initialized", __FUNCTION__);\
59 return BT_STATUS_NOT_READY;\
60 } else {\
61 LOG_VERBOSE(LOG_TAG, "%s", __FUNCTION__);\
62 }
63
64 typedef enum {
65 BTIF_GATTS_REGISTER_APP = 2000,
66 BTIF_GATTS_UNREGISTER_APP,
67 BTIF_GATTS_OPEN,
68 BTIF_GATTS_CLOSE,
69 BTIF_GATTS_CREATE_SERVICE,
70 BTIF_GATTS_ADD_INCLUDED_SERVICE,
71 BTIF_GATTS_ADD_CHARACTERISTIC,
72 BTIF_GATTS_ADD_DESCRIPTOR,
73 BTIF_GATTS_START_SERVICE,
74 BTIF_GATTS_STOP_SERVICE,
75 BTIF_GATTS_DELETE_SERVICE,
76 BTIF_GATTS_SEND_INDICATION,
77 BTIF_GATTS_SEND_RESPONSE
78 } btif_gatts_event_t;
79
80 /************************************************************************************
81 ** Local type definitions
82 ************************************************************************************/
83
84 typedef struct
85 {
86 uint8_t value[BTGATT_MAX_ATTR_LEN];
87 btgatt_response_t response;
88 btgatt_srvc_id_t srvc_id;
89 bt_bdaddr_t bd_addr;
90 bt_uuid_t uuid;
91 uint32_t trans_id;
92 uint16_t conn_id;
93 uint16_t srvc_handle;
94 uint16_t incl_handle;
95 uint16_t attr_handle;
96 uint16_t permissions;
97 uint16_t len;
98 uint8_t server_if;
99 uint8_t is_direct;
100 uint8_t num_handles;
101 uint8_t properties;
102 uint8_t confirm;
103 uint8_t status;
104 btgatt_transport_t transport;
105
106 } __attribute__((packed)) btif_gatts_cb_t;
107
108 /************************************************************************************
109 ** Static variables
110 ************************************************************************************/
111
112 extern const btgatt_callbacks_t *bt_gatt_callbacks;
113
114 /************************************************************************************
115 ** Static functions
116 ************************************************************************************/
117
btapp_gatts_copy_req_data(UINT16 event,char * p_dest,char * p_src)118 static void btapp_gatts_copy_req_data(UINT16 event, char *p_dest, char *p_src)
119 {
120 tBTA_GATTS *p_dest_data = (tBTA_GATTS*) p_dest;
121 tBTA_GATTS *p_src_data = (tBTA_GATTS*) p_src;
122
123 if (!p_src_data || !p_dest_data)
124 return;
125
126 // Copy basic structure first
127 maybe_non_aligned_memcpy(p_dest_data, p_src_data, sizeof(*p_src_data));
128
129 // Allocate buffer for request data if necessary
130 switch (event)
131 {
132 case BTA_GATTS_READ_EVT:
133 case BTA_GATTS_WRITE_EVT:
134 case BTA_GATTS_EXEC_WRITE_EVT:
135 case BTA_GATTS_MTU_EVT:
136 p_dest_data->req_data.p_data = osi_malloc(sizeof(tBTA_GATTS_REQ_DATA));
137 memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data,
138 sizeof(tBTA_GATTS_REQ_DATA));
139 break;
140
141 default:
142 break;
143 }
144 }
145
btapp_gatts_free_req_data(UINT16 event,tBTA_GATTS * p_data)146 static void btapp_gatts_free_req_data(UINT16 event, tBTA_GATTS *p_data)
147 {
148 switch (event)
149 {
150 case BTA_GATTS_READ_EVT:
151 case BTA_GATTS_WRITE_EVT:
152 case BTA_GATTS_EXEC_WRITE_EVT:
153 case BTA_GATTS_MTU_EVT:
154 if (p_data != NULL)
155 osi_free_and_reset((void **)&p_data->req_data.p_data);
156 break;
157
158 default:
159 break;
160 }
161 }
162
btapp_gatts_handle_cback(uint16_t event,char * p_param)163 static void btapp_gatts_handle_cback(uint16_t event, char* p_param)
164 {
165 LOG_VERBOSE(LOG_TAG, "%s: Event %d", __FUNCTION__, event);
166
167 tBTA_GATTS *p_data = (tBTA_GATTS*)p_param;
168 switch (event)
169 {
170 case BTA_GATTS_REG_EVT:
171 {
172 bt_uuid_t app_uuid;
173 bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.uuid);
174 HAL_CBACK(bt_gatt_callbacks, server->register_server_cb
175 , p_data->reg_oper.status
176 , p_data->reg_oper.server_if
177 , &app_uuid
178 );
179 break;
180 }
181
182 case BTA_GATTS_DEREG_EVT:
183 break;
184
185 case BTA_GATTS_CONNECT_EVT:
186 {
187 bt_bdaddr_t bda;
188 bdcpy(bda.address, p_data->conn.remote_bda);
189
190 btif_gatt_check_encrypted_link(p_data->conn.remote_bda, p_data->conn.transport);
191
192 HAL_CBACK(bt_gatt_callbacks, server->connection_cb,
193 p_data->conn.conn_id, p_data->conn.server_if, TRUE, &bda);
194 break;
195 }
196
197 case BTA_GATTS_DISCONNECT_EVT:
198 {
199 bt_bdaddr_t bda;
200 bdcpy(bda.address, p_data->conn.remote_bda);
201
202 HAL_CBACK(bt_gatt_callbacks, server->connection_cb,
203 p_data->conn.conn_id, p_data->conn.server_if, FALSE, &bda);
204 break;
205 }
206
207 case BTA_GATTS_CREATE_EVT:
208 {
209 btgatt_srvc_id_t srvc_id;
210 srvc_id.is_primary = p_data->create.is_primary;
211 srvc_id.id.inst_id = p_data->create.svc_instance;
212 bta_to_btif_uuid(&srvc_id.id.uuid, &p_data->create.uuid);
213
214 HAL_CBACK(bt_gatt_callbacks, server->service_added_cb,
215 p_data->create.status, p_data->create.server_if, &srvc_id,
216 p_data->create.service_id
217 );
218 }
219 break;
220
221 case BTA_GATTS_ADD_INCL_SRVC_EVT:
222 HAL_CBACK(bt_gatt_callbacks, server->included_service_added_cb,
223 p_data->add_result.status,
224 p_data->add_result.server_if,
225 p_data->add_result.service_id,
226 p_data->add_result.attr_id);
227 break;
228
229 case BTA_GATTS_ADD_CHAR_EVT:
230 {
231 bt_uuid_t uuid;
232 bta_to_btif_uuid(&uuid, &p_data->add_result.char_uuid);
233
234 HAL_CBACK(bt_gatt_callbacks, server->characteristic_added_cb,
235 p_data->add_result.status,
236 p_data->add_result.server_if,
237 &uuid,
238 p_data->add_result.service_id,
239 p_data->add_result.attr_id);
240 break;
241 }
242
243 case BTA_GATTS_ADD_CHAR_DESCR_EVT:
244 {
245 bt_uuid_t uuid;
246 bta_to_btif_uuid(&uuid, &p_data->add_result.char_uuid);
247
248 HAL_CBACK(bt_gatt_callbacks, server->descriptor_added_cb,
249 p_data->add_result.status,
250 p_data->add_result.server_if,
251 &uuid,
252 p_data->add_result.service_id,
253 p_data->add_result.attr_id);
254 break;
255 }
256
257 case BTA_GATTS_START_EVT:
258 HAL_CBACK(bt_gatt_callbacks, server->service_started_cb,
259 p_data->srvc_oper.status,
260 p_data->srvc_oper.server_if,
261 p_data->srvc_oper.service_id);
262 break;
263
264 case BTA_GATTS_STOP_EVT:
265 HAL_CBACK(bt_gatt_callbacks, server->service_stopped_cb,
266 p_data->srvc_oper.status,
267 p_data->srvc_oper.server_if,
268 p_data->srvc_oper.service_id);
269 break;
270
271 case BTA_GATTS_DELELTE_EVT:
272 HAL_CBACK(bt_gatt_callbacks, server->service_deleted_cb,
273 p_data->srvc_oper.status,
274 p_data->srvc_oper.server_if,
275 p_data->srvc_oper.service_id);
276 break;
277
278 case BTA_GATTS_READ_EVT:
279 {
280 bt_bdaddr_t bda;
281 bdcpy(bda.address, p_data->req_data.remote_bda);
282
283 HAL_CBACK(bt_gatt_callbacks, server->request_read_cb,
284 p_data->req_data.conn_id,p_data->req_data.trans_id, &bda,
285 p_data->req_data.p_data->read_req.handle,
286 p_data->req_data.p_data->read_req.offset,
287 p_data->req_data.p_data->read_req.is_long);
288 break;
289 }
290
291 case BTA_GATTS_WRITE_EVT:
292 {
293 bt_bdaddr_t bda;
294 bdcpy(bda.address, p_data->req_data.remote_bda);
295
296 HAL_CBACK(bt_gatt_callbacks, server->request_write_cb,
297 p_data->req_data.conn_id,p_data->req_data.trans_id, &bda,
298 p_data->req_data.p_data->write_req.handle,
299 p_data->req_data.p_data->write_req.offset,
300 p_data->req_data.p_data->write_req.len,
301 p_data->req_data.p_data->write_req.need_rsp,
302 p_data->req_data.p_data->write_req.is_prep,
303 p_data->req_data.p_data->write_req.value);
304 break;
305 }
306
307 case BTA_GATTS_EXEC_WRITE_EVT:
308 {
309 bt_bdaddr_t bda;
310 bdcpy(bda.address, p_data->req_data.remote_bda);
311
312 HAL_CBACK(bt_gatt_callbacks, server->request_exec_write_cb,
313 p_data->req_data.conn_id,p_data->req_data.trans_id, &bda,
314 p_data->req_data.p_data->exec_write);
315 break;
316 }
317
318 case BTA_GATTS_CONF_EVT:
319 HAL_CBACK(bt_gatt_callbacks, server->indication_sent_cb,
320 p_data->req_data.conn_id, p_data->req_data.status);
321 break;
322
323 case BTA_GATTS_CONGEST_EVT:
324 HAL_CBACK(bt_gatt_callbacks, server->congestion_cb
325 , p_data->congest.conn_id
326 , p_data->congest.congested
327 );
328 break;
329
330 case BTA_GATTS_MTU_EVT:
331 HAL_CBACK(bt_gatt_callbacks, server->mtu_changed_cb
332 , p_data->req_data.conn_id
333 , p_data->req_data.p_data->mtu
334 );
335 break;
336
337 case BTA_GATTS_OPEN_EVT:
338 case BTA_GATTS_CANCEL_OPEN_EVT:
339 case BTA_GATTS_CLOSE_EVT:
340 LOG_DEBUG(LOG_TAG, "%s: Empty event (%d)!", __FUNCTION__, event);
341 break;
342
343 default:
344 LOG_ERROR(LOG_TAG, "%s: Unhandled event (%d)!", __FUNCTION__, event);
345 break;
346 }
347
348 btapp_gatts_free_req_data(event, p_data);
349 }
350
btapp_gatts_cback(tBTA_GATTS_EVT event,tBTA_GATTS * p_data)351 static void btapp_gatts_cback(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
352 {
353 bt_status_t status;
354 status = btif_transfer_context(btapp_gatts_handle_cback, (uint16_t) event,
355 (void*)p_data, sizeof(tBTA_GATTS), btapp_gatts_copy_req_data);
356 ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
357 }
358
btgatts_handle_event(uint16_t event,char * p_param)359 static void btgatts_handle_event(uint16_t event, char* p_param)
360 {
361 btif_gatts_cb_t* p_cb = (btif_gatts_cb_t*)p_param;
362 if (!p_cb) return;
363
364 LOG_VERBOSE(LOG_TAG, "%s: Event %d", __FUNCTION__, event);
365
366 switch (event)
367 {
368 case BTIF_GATTS_REGISTER_APP:
369 {
370 tBT_UUID uuid;
371 btif_to_bta_uuid(&uuid, &p_cb->uuid);
372 BTA_GATTS_AppRegister(&uuid, btapp_gatts_cback);
373 break;
374 }
375
376 case BTIF_GATTS_UNREGISTER_APP:
377 BTA_GATTS_AppDeregister(p_cb->server_if);
378 break;
379
380 case BTIF_GATTS_OPEN:
381 {
382 // Ensure device is in inquiry database
383 int addr_type = 0;
384 int device_type = 0;
385 tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
386
387 if (btif_get_address_type(p_cb->bd_addr.address, &addr_type) &&
388 btif_get_device_type(p_cb->bd_addr.address, &device_type) &&
389 device_type != BT_DEVICE_TYPE_BREDR)
390 {
391 BTA_DmAddBleDevice(p_cb->bd_addr.address, addr_type, device_type);
392 }
393
394 // Mark background connections
395 if (!p_cb->is_direct)
396 BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
397
398 // Determine transport
399 if (p_cb->transport != GATT_TRANSPORT_AUTO)
400 {
401 transport = p_cb->transport;
402 } else {
403 switch(device_type)
404 {
405 case BT_DEVICE_TYPE_BREDR:
406 transport = BTA_GATT_TRANSPORT_BR_EDR;
407 break;
408
409 case BT_DEVICE_TYPE_BLE:
410 transport = BTA_GATT_TRANSPORT_LE;
411 break;
412
413 case BT_DEVICE_TYPE_DUMO:
414 if (p_cb->transport == GATT_TRANSPORT_LE)
415 transport = BTA_GATT_TRANSPORT_LE;
416 else
417 transport = BTA_GATT_TRANSPORT_BR_EDR;
418 break;
419
420 default:
421 BTIF_TRACE_ERROR ("%s: Invalid device type %d", __func__, device_type);
422 return;
423 }
424 }
425
426 // Connect!
427 BTA_GATTS_Open(p_cb->server_if, p_cb->bd_addr.address,
428 p_cb->is_direct, transport);
429 break;
430 }
431
432 case BTIF_GATTS_CLOSE:
433 // Cancel pending foreground/background connections
434 BTA_GATTS_CancelOpen(p_cb->server_if, p_cb->bd_addr.address, TRUE);
435 BTA_GATTS_CancelOpen(p_cb->server_if, p_cb->bd_addr.address, FALSE);
436
437 // Close active connection
438 if (p_cb->conn_id != 0)
439 BTA_GATTS_Close(p_cb->conn_id);
440 break;
441
442 case BTIF_GATTS_CREATE_SERVICE:
443 {
444 tBT_UUID uuid;
445 btif_to_bta_uuid(&uuid, &p_cb->srvc_id.id.uuid);
446
447 BTA_GATTS_CreateService(p_cb->server_if, &uuid,
448 p_cb->srvc_id.id.inst_id, p_cb->num_handles,
449 p_cb->srvc_id.is_primary);
450
451 break;
452 }
453
454 case BTIF_GATTS_ADD_INCLUDED_SERVICE:
455 BTA_GATTS_AddIncludeService(p_cb->srvc_handle, p_cb->incl_handle);
456 break;
457
458 case BTIF_GATTS_ADD_CHARACTERISTIC:
459 {
460 tBT_UUID uuid;
461 btif_to_bta_uuid(&uuid, &p_cb->uuid);
462
463 BTA_GATTS_AddCharacteristic(p_cb->srvc_handle, &uuid,
464 p_cb->permissions, p_cb->properties);
465 break;
466 }
467
468 case BTIF_GATTS_ADD_DESCRIPTOR:
469 {
470 tBT_UUID uuid;
471 btif_to_bta_uuid(&uuid, &p_cb->uuid);
472
473 BTA_GATTS_AddCharDescriptor(p_cb->srvc_handle, p_cb->permissions,
474 &uuid);
475 break;
476 }
477
478 case BTIF_GATTS_START_SERVICE:
479 BTA_GATTS_StartService(p_cb->srvc_handle, p_cb->transport);
480 break;
481
482 case BTIF_GATTS_STOP_SERVICE:
483 BTA_GATTS_StopService(p_cb->srvc_handle);
484 break;
485
486 case BTIF_GATTS_DELETE_SERVICE:
487 BTA_GATTS_DeleteService(p_cb->srvc_handle);
488 break;
489
490 case BTIF_GATTS_SEND_INDICATION:
491 BTA_GATTS_HandleValueIndication(p_cb->conn_id, p_cb->attr_handle,
492 p_cb->len, p_cb->value, p_cb->confirm);
493 // TODO: Might need to send an ACK if handle value indication is
494 // invoked without need for confirmation.
495 break;
496
497 case BTIF_GATTS_SEND_RESPONSE:
498 {
499 tBTA_GATTS_RSP rsp_struct;
500 btgatt_response_t *p_rsp = &p_cb->response;
501 btif_to_bta_response(&rsp_struct, p_rsp);
502
503 BTA_GATTS_SendRsp(p_cb->conn_id, p_cb->trans_id,
504 p_cb->status, &rsp_struct);
505
506 HAL_CBACK(bt_gatt_callbacks, server->response_confirmation_cb,
507 0, rsp_struct.attr_value.handle);
508 break;
509 }
510
511 default:
512 LOG_ERROR(LOG_TAG, "%s: Unknown event (%d)!", __FUNCTION__, event);
513 break;
514 }
515 }
516
517 /************************************************************************************
518 ** Server API Functions
519 ************************************************************************************/
520
btif_gatts_register_app(bt_uuid_t * uuid)521 static bt_status_t btif_gatts_register_app(bt_uuid_t *uuid)
522 {
523 CHECK_BTGATT_INIT();
524 btif_gatts_cb_t btif_cb;
525 memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
526 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_REGISTER_APP,
527 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
528 }
529
btif_gatts_unregister_app(int server_if)530 static bt_status_t btif_gatts_unregister_app( int server_if )
531 {
532 CHECK_BTGATT_INIT();
533 btif_gatts_cb_t btif_cb;
534 btif_cb.server_if = (uint8_t) server_if;
535 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_UNREGISTER_APP,
536 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
537 }
538
btif_gatts_open(int server_if,const bt_bdaddr_t * bd_addr,bool is_direct,int transport)539 static bt_status_t btif_gatts_open( int server_if, const bt_bdaddr_t *bd_addr,
540 bool is_direct, int transport )
541 {
542 CHECK_BTGATT_INIT();
543 btif_gatts_cb_t btif_cb;
544 btif_cb.server_if = (uint8_t) server_if;
545 btif_cb.is_direct = is_direct ? 1 : 0;
546 btif_cb.transport = (btgatt_transport_t)transport;
547 bdcpy(btif_cb.bd_addr.address, bd_addr->address);
548 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_OPEN,
549 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
550 }
551
btif_gatts_close(int server_if,const bt_bdaddr_t * bd_addr,int conn_id)552 static bt_status_t btif_gatts_close(int server_if, const bt_bdaddr_t *bd_addr, int conn_id)
553 {
554 CHECK_BTGATT_INIT();
555 btif_gatts_cb_t btif_cb;
556 btif_cb.server_if = (uint8_t) server_if;
557 btif_cb.conn_id = (uint16_t) conn_id;
558 bdcpy(btif_cb.bd_addr.address, bd_addr->address);
559 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_CLOSE,
560 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
561 }
562
btif_gatts_add_service(int server_if,btgatt_srvc_id_t * srvc_id,int num_handles)563 static bt_status_t btif_gatts_add_service(int server_if, btgatt_srvc_id_t *srvc_id,
564 int num_handles)
565 {
566 CHECK_BTGATT_INIT();
567 btif_gatts_cb_t btif_cb;
568 btif_cb.server_if = (uint8_t) server_if;
569 btif_cb.num_handles = (uint8_t) num_handles;
570 memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
571 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_CREATE_SERVICE,
572 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
573 }
574
btif_gatts_add_included_service(int server_if,int service_handle,int included_handle)575 static bt_status_t btif_gatts_add_included_service(int server_if, int service_handle,
576 int included_handle)
577 {
578 CHECK_BTGATT_INIT();
579 btif_gatts_cb_t btif_cb;
580 btif_cb.server_if = (uint8_t) server_if;
581 btif_cb.srvc_handle = (uint16_t) service_handle;
582 btif_cb.incl_handle = (uint16_t) included_handle;
583 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_ADD_INCLUDED_SERVICE,
584 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
585 }
586
btif_gatts_add_characteristic(int server_if,int service_handle,bt_uuid_t * uuid,int properties,int permissions)587 static bt_status_t btif_gatts_add_characteristic(int server_if, int service_handle,
588 bt_uuid_t *uuid, int properties,
589 int permissions)
590 {
591 CHECK_BTGATT_INIT();
592 btif_gatts_cb_t btif_cb;
593 btif_cb.server_if = (uint8_t) server_if;
594 btif_cb.srvc_handle = (uint16_t) service_handle;
595 btif_cb.properties = (uint8_t) properties;
596 btif_cb.permissions = (uint16_t) permissions;
597 memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
598 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_ADD_CHARACTERISTIC,
599 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
600 }
601
btif_gatts_add_descriptor(int server_if,int service_handle,bt_uuid_t * uuid,int permissions)602 static bt_status_t btif_gatts_add_descriptor(int server_if, int service_handle, bt_uuid_t *uuid,
603 int permissions)
604 {
605 CHECK_BTGATT_INIT();
606 btif_gatts_cb_t btif_cb;
607 btif_cb.server_if = (uint8_t) server_if;
608 btif_cb.srvc_handle = (uint16_t) service_handle;
609 btif_cb.permissions = (uint16_t) permissions;
610 memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
611 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_ADD_DESCRIPTOR,
612 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
613 }
614
btif_gatts_start_service(int server_if,int service_handle,int transport)615 static bt_status_t btif_gatts_start_service(int server_if, int service_handle, int transport)
616 {
617 CHECK_BTGATT_INIT();
618 btif_gatts_cb_t btif_cb;
619 btif_cb.server_if = (uint8_t) server_if;
620 btif_cb.srvc_handle = (uint16_t) service_handle;
621 btif_cb.transport = (uint8_t) transport;
622 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_START_SERVICE,
623 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
624 }
625
btif_gatts_stop_service(int server_if,int service_handle)626 static bt_status_t btif_gatts_stop_service(int server_if, int service_handle)
627 {
628 CHECK_BTGATT_INIT();
629 btif_gatts_cb_t btif_cb;
630 btif_cb.server_if = (uint8_t) server_if;
631 btif_cb.srvc_handle = (uint16_t) service_handle;
632 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_STOP_SERVICE,
633 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
634 }
635
btif_gatts_delete_service(int server_if,int service_handle)636 static bt_status_t btif_gatts_delete_service(int server_if, int service_handle)
637 {
638 CHECK_BTGATT_INIT();
639 btif_gatts_cb_t btif_cb;
640 btif_cb.server_if = (uint8_t) server_if;
641 btif_cb.srvc_handle = (uint16_t) service_handle;
642 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_DELETE_SERVICE,
643 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
644 }
645
btif_gatts_send_indication(int server_if,int attribute_handle,int conn_id,int len,int confirm,char * p_value)646 static bt_status_t btif_gatts_send_indication(int server_if, int attribute_handle, int conn_id,
647 int len, int confirm, char* p_value)
648 {
649 CHECK_BTGATT_INIT();
650 btif_gatts_cb_t btif_cb;
651 btif_cb.server_if = (uint8_t) server_if;
652 btif_cb.conn_id = (uint16_t) conn_id;
653 btif_cb.attr_handle = attribute_handle;
654 btif_cb.confirm = confirm;
655 btif_cb.len = len;
656 memcpy(btif_cb.value, p_value, len > BTGATT_MAX_ATTR_LEN ? BTGATT_MAX_ATTR_LEN : len);
657 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_SEND_INDICATION,
658 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
659 }
660
btif_gatts_send_response(int conn_id,int trans_id,int status,btgatt_response_t * response)661 static bt_status_t btif_gatts_send_response(int conn_id, int trans_id,
662 int status, btgatt_response_t *response)
663 {
664 CHECK_BTGATT_INIT();
665 btif_gatts_cb_t btif_cb;
666 btif_cb.conn_id = (uint16_t) conn_id;
667 btif_cb.trans_id = (uint32_t) trans_id;
668 btif_cb.status = (uint8_t) status;
669 memcpy(&btif_cb.response, response, sizeof(btgatt_response_t));
670 return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_SEND_RESPONSE,
671 (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
672 }
673
674 const btgatt_server_interface_t btgattServerInterface = {
675 btif_gatts_register_app,
676 btif_gatts_unregister_app,
677 btif_gatts_open,
678 btif_gatts_close,
679 btif_gatts_add_service,
680 btif_gatts_add_included_service,
681 btif_gatts_add_characteristic,
682 btif_gatts_add_descriptor,
683 btif_gatts_start_service,
684 btif_gatts_stop_service,
685 btif_gatts_delete_service,
686 btif_gatts_send_indication,
687 btif_gatts_send_response
688 };
689
690 #endif
691