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