• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <base/bind.h>
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include <hardware/bluetooth.h>
36 #include <hardware/bt_gatt.h>
37 
38 #include "btif_common.h"
39 #include "btif_util.h"
40 
41 #include "bt_common.h"
42 #include "bta_api.h"
43 #include "bta_closure_api.h"
44 #include "bta_gatt_api.h"
45 #include "btif_config.h"
46 #include "btif_dm.h"
47 #include "btif_gatt.h"
48 #include "btif_gatt_util.h"
49 #include "btif_storage.h"
50 #include "osi/include/log.h"
51 
52 using base::Bind;
53 using base::Owned;
54 using std::vector;
55 
56 /*******************************************************************************
57  *  Constants & Macros
58  ******************************************************************************/
59 
60 #define CHECK_BTGATT_INIT()                                      \
61   do {                                                           \
62     if (bt_gatt_callbacks == NULL) {                             \
63       LOG_WARN(LOG_TAG, "%s: BTGATT not initialized", __func__); \
64       return BT_STATUS_NOT_READY;                                \
65     } else {                                                     \
66       LOG_VERBOSE(LOG_TAG, "%s", __func__);                      \
67     }                                                            \
68   } while (0)
69 
70 /*******************************************************************************
71  *  Static variables
72  ******************************************************************************/
73 
74 extern const btgatt_callbacks_t* bt_gatt_callbacks;
75 
76 /*******************************************************************************
77  *  Static functions
78  ******************************************************************************/
79 
btapp_gatts_copy_req_data(uint16_t event,char * p_dest,char * p_src)80 static void btapp_gatts_copy_req_data(uint16_t event, char* p_dest,
81                                       char* p_src) {
82   tBTA_GATTS* p_dest_data = (tBTA_GATTS*)p_dest;
83   tBTA_GATTS* p_src_data = (tBTA_GATTS*)p_src;
84 
85   if (!p_src_data || !p_dest_data) return;
86 
87   // Copy basic structure first
88   maybe_non_aligned_memcpy(p_dest_data, p_src_data, sizeof(*p_src_data));
89 
90   // Allocate buffer for request data if necessary
91   switch (event) {
92     case BTA_GATTS_READ_CHARACTERISTIC_EVT:
93     case BTA_GATTS_READ_DESCRIPTOR_EVT:
94     case BTA_GATTS_WRITE_CHARACTERISTIC_EVT:
95     case BTA_GATTS_WRITE_DESCRIPTOR_EVT:
96     case BTA_GATTS_EXEC_WRITE_EVT:
97     case BTA_GATTS_MTU_EVT:
98       p_dest_data->req_data.p_data =
99           (tBTA_GATTS_REQ_DATA*)osi_malloc(sizeof(tBTA_GATTS_REQ_DATA));
100       memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data,
101              sizeof(tBTA_GATTS_REQ_DATA));
102       break;
103 
104     default:
105       break;
106   }
107 }
108 
btapp_gatts_free_req_data(uint16_t event,tBTA_GATTS * p_data)109 static void btapp_gatts_free_req_data(uint16_t event, tBTA_GATTS* p_data) {
110   switch (event) {
111     case BTA_GATTS_READ_CHARACTERISTIC_EVT:
112     case BTA_GATTS_READ_DESCRIPTOR_EVT:
113     case BTA_GATTS_WRITE_CHARACTERISTIC_EVT:
114     case BTA_GATTS_WRITE_DESCRIPTOR_EVT:
115     case BTA_GATTS_EXEC_WRITE_EVT:
116     case BTA_GATTS_MTU_EVT:
117       if (p_data != NULL) osi_free_and_reset((void**)&p_data->req_data.p_data);
118       break;
119 
120     default:
121       break;
122   }
123 }
124 
btapp_gatts_handle_cback(uint16_t event,char * p_param)125 static void btapp_gatts_handle_cback(uint16_t event, char* p_param) {
126   LOG_VERBOSE(LOG_TAG, "%s: Event %d", __func__, event);
127 
128   tBTA_GATTS* p_data = (tBTA_GATTS*)p_param;
129   switch (event) {
130     case BTA_GATTS_REG_EVT: {
131       bt_uuid_t app_uuid;
132       bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.uuid);
133       HAL_CBACK(bt_gatt_callbacks, server->register_server_cb,
134                 p_data->reg_oper.status, p_data->reg_oper.server_if, &app_uuid);
135       break;
136     }
137 
138     case BTA_GATTS_DEREG_EVT:
139       break;
140 
141     case BTA_GATTS_CONNECT_EVT: {
142       bt_bdaddr_t bda;
143       bdcpy(bda.address, p_data->conn.remote_bda);
144 
145       btif_gatt_check_encrypted_link(p_data->conn.remote_bda,
146                                      p_data->conn.transport);
147 
148       HAL_CBACK(bt_gatt_callbacks, server->connection_cb, p_data->conn.conn_id,
149                 p_data->conn.server_if, true, &bda);
150       break;
151     }
152 
153     case BTA_GATTS_DISCONNECT_EVT: {
154       bt_bdaddr_t bda;
155       bdcpy(bda.address, p_data->conn.remote_bda);
156 
157       HAL_CBACK(bt_gatt_callbacks, server->connection_cb, p_data->conn.conn_id,
158                 p_data->conn.server_if, false, &bda);
159       break;
160     }
161 
162     case BTA_GATTS_STOP_EVT:
163       HAL_CBACK(bt_gatt_callbacks, server->service_stopped_cb,
164                 p_data->srvc_oper.status, p_data->srvc_oper.server_if,
165                 p_data->srvc_oper.service_id);
166       break;
167 
168     case BTA_GATTS_DELELTE_EVT:
169       HAL_CBACK(bt_gatt_callbacks, server->service_deleted_cb,
170                 p_data->srvc_oper.status, p_data->srvc_oper.server_if,
171                 p_data->srvc_oper.service_id);
172       break;
173 
174     case BTA_GATTS_READ_CHARACTERISTIC_EVT: {
175       bt_bdaddr_t bda;
176       bdcpy(bda.address, p_data->req_data.remote_bda);
177 
178       HAL_CBACK(bt_gatt_callbacks, server->request_read_characteristic_cb,
179                 p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
180                 p_data->req_data.p_data->read_req.handle,
181                 p_data->req_data.p_data->read_req.offset,
182                 p_data->req_data.p_data->read_req.is_long);
183       break;
184     }
185 
186     case BTA_GATTS_READ_DESCRIPTOR_EVT: {
187       bt_bdaddr_t bda;
188       bdcpy(bda.address, p_data->req_data.remote_bda);
189 
190       HAL_CBACK(bt_gatt_callbacks, server->request_read_descriptor_cb,
191                 p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
192                 p_data->req_data.p_data->read_req.handle,
193                 p_data->req_data.p_data->read_req.offset,
194                 p_data->req_data.p_data->read_req.is_long);
195       break;
196     }
197 
198     case BTA_GATTS_WRITE_CHARACTERISTIC_EVT: {
199       bt_bdaddr_t bda;
200       bdcpy(bda.address, p_data->req_data.remote_bda);
201       const auto& req = p_data->req_data.p_data->write_req;
202       vector<uint8_t> value(req.value, req.value + req.len);
203       HAL_CBACK(bt_gatt_callbacks, server->request_write_characteristic_cb,
204                 p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
205                 req.handle, req.offset, req.need_rsp, req.is_prep, value);
206       break;
207     }
208 
209     case BTA_GATTS_WRITE_DESCRIPTOR_EVT: {
210       bt_bdaddr_t bda;
211       bdcpy(bda.address, p_data->req_data.remote_bda);
212       const auto& req = p_data->req_data.p_data->write_req;
213       vector<uint8_t> value(req.value, req.value + req.len);
214       HAL_CBACK(bt_gatt_callbacks, server->request_write_descriptor_cb,
215                 p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
216                 req.handle, req.offset, req.need_rsp, req.is_prep, value);
217       break;
218     }
219 
220     case BTA_GATTS_EXEC_WRITE_EVT: {
221       bt_bdaddr_t bda;
222       bdcpy(bda.address, p_data->req_data.remote_bda);
223 
224       HAL_CBACK(bt_gatt_callbacks, server->request_exec_write_cb,
225                 p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
226                 p_data->req_data.p_data->exec_write);
227       break;
228     }
229 
230     case BTA_GATTS_CONF_EVT:
231       HAL_CBACK(bt_gatt_callbacks, server->indication_sent_cb,
232                 p_data->req_data.conn_id, p_data->req_data.status);
233       break;
234 
235     case BTA_GATTS_CONGEST_EVT:
236       HAL_CBACK(bt_gatt_callbacks, server->congestion_cb,
237                 p_data->congest.conn_id, p_data->congest.congested);
238       break;
239 
240     case BTA_GATTS_MTU_EVT:
241       HAL_CBACK(bt_gatt_callbacks, server->mtu_changed_cb,
242                 p_data->req_data.conn_id, p_data->req_data.p_data->mtu);
243       break;
244 
245     case BTA_GATTS_OPEN_EVT:
246     case BTA_GATTS_CANCEL_OPEN_EVT:
247     case BTA_GATTS_CLOSE_EVT:
248       LOG_DEBUG(LOG_TAG, "%s: Empty event (%d)!", __func__, event);
249       break;
250 
251     case BTA_GATTS_PHY_UPDATE_EVT:
252       HAL_CBACK(bt_gatt_callbacks, server->phy_updated_cb,
253                 p_data->phy_update.conn_id, p_data->phy_update.tx_phy,
254                 p_data->phy_update.rx_phy, p_data->phy_update.status);
255       break;
256 
257     case BTA_GATTS_CONN_UPDATE_EVT:
258       HAL_CBACK(bt_gatt_callbacks, server->conn_updated_cb,
259                 p_data->conn_update.conn_id, p_data->conn_update.interval,
260                 p_data->conn_update.latency, p_data->conn_update.timeout,
261                 p_data->conn_update.status);
262       break;
263 
264     default:
265       LOG_ERROR(LOG_TAG, "%s: Unhandled event (%d)!", __func__, event);
266       break;
267   }
268 
269   btapp_gatts_free_req_data(event, p_data);
270 }
271 
btapp_gatts_cback(tBTA_GATTS_EVT event,tBTA_GATTS * p_data)272 static void btapp_gatts_cback(tBTA_GATTS_EVT event, tBTA_GATTS* p_data) {
273   bt_status_t status;
274   status = btif_transfer_context(btapp_gatts_handle_cback, (uint16_t)event,
275                                  (char*)p_data, sizeof(tBTA_GATTS),
276                                  btapp_gatts_copy_req_data);
277   ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
278 }
279 
280 /*******************************************************************************
281  *  Server API Functions
282  ******************************************************************************/
btif_gatts_register_app(bt_uuid_t * bt_uuid)283 static bt_status_t btif_gatts_register_app(bt_uuid_t* bt_uuid) {
284   CHECK_BTGATT_INIT();
285   tBT_UUID* uuid = new tBT_UUID;
286   btif_to_bta_uuid(uuid, bt_uuid);
287 
288   return do_in_jni_thread(
289       Bind(&BTA_GATTS_AppRegister, base::Owned(uuid), &btapp_gatts_cback));
290 }
291 
btif_gatts_unregister_app(int server_if)292 static bt_status_t btif_gatts_unregister_app(int server_if) {
293   CHECK_BTGATT_INIT();
294   return do_in_jni_thread(Bind(&BTA_GATTS_AppDeregister, server_if));
295 }
296 
btif_gatts_open_impl(int server_if,BD_ADDR address,bool is_direct,int transport_param)297 static void btif_gatts_open_impl(int server_if, BD_ADDR address, bool is_direct,
298                                  int transport_param) {
299   // Ensure device is in inquiry database
300   int addr_type = 0;
301   int device_type = 0;
302   tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
303 
304   if (btif_get_address_type(address, &addr_type) &&
305       btif_get_device_type(address, &device_type) &&
306       device_type != BT_DEVICE_TYPE_BREDR) {
307     BTA_DmAddBleDevice(address, addr_type, device_type);
308   }
309 
310   // Mark background connections
311   if (!is_direct) BTA_DmBleStartAutoConn();
312 
313   // Determine transport
314   if (transport_param != GATT_TRANSPORT_AUTO) {
315     transport = transport_param;
316   } else {
317     switch (device_type) {
318       case BT_DEVICE_TYPE_BREDR:
319         transport = BTA_GATT_TRANSPORT_BR_EDR;
320         break;
321 
322       case BT_DEVICE_TYPE_BLE:
323         transport = BTA_GATT_TRANSPORT_LE;
324         break;
325 
326       case BT_DEVICE_TYPE_DUMO:
327         if (transport_param == GATT_TRANSPORT_LE)
328           transport = BTA_GATT_TRANSPORT_LE;
329         else
330           transport = BTA_GATT_TRANSPORT_BR_EDR;
331         break;
332 
333       default:
334         BTIF_TRACE_ERROR("%s: Invalid device type %d", __func__, device_type);
335         return;
336     }
337   }
338 
339   // Connect!
340   BTA_GATTS_Open(server_if, address, is_direct, transport);
341 }
342 
btif_gatts_open(int server_if,const bt_bdaddr_t * bd_addr,bool is_direct,int transport)343 static bt_status_t btif_gatts_open(int server_if, const bt_bdaddr_t* bd_addr,
344                                    bool is_direct, int transport) {
345   CHECK_BTGATT_INIT();
346   uint8_t* address = new BD_ADDR;
347   bdcpy(address, bd_addr->address);
348 
349   return do_in_jni_thread(Bind(&btif_gatts_open_impl, server_if,
350                                base::Owned(address), is_direct, transport));
351 }
352 
btif_gatts_close_impl(int server_if,BD_ADDR address,int conn_id)353 static void btif_gatts_close_impl(int server_if, BD_ADDR address, int conn_id) {
354   // Close active connection
355   if (conn_id != 0)
356     BTA_GATTS_Close(conn_id);
357   else
358     BTA_GATTS_CancelOpen(server_if, address, true);
359 
360   // Cancel pending background connections
361   BTA_GATTS_CancelOpen(server_if, address, false);
362 }
363 
btif_gatts_close(int server_if,const bt_bdaddr_t * bd_addr,int conn_id)364 static bt_status_t btif_gatts_close(int server_if, const bt_bdaddr_t* bd_addr,
365                                     int conn_id) {
366   CHECK_BTGATT_INIT();
367   uint8_t* address = new BD_ADDR;
368   bdcpy(address, bd_addr->address);
369 
370   return do_in_jni_thread(
371       Bind(&btif_gatts_close_impl, server_if, base::Owned(address), conn_id));
372 }
373 
add_service_impl(int server_if,vector<btgatt_db_element_t> service)374 static void add_service_impl(int server_if,
375                              vector<btgatt_db_element_t> service) {
376   bt_uuid_t restricted_uuid1, restricted_uuid2;
377   uuid_128_from_16(&restricted_uuid1, UUID_SERVCLASS_GATT_SERVER);
378   uuid_128_from_16(&restricted_uuid2, UUID_SERVCLASS_GAP_SERVER);
379 
380   // TODO(jpawlowski): btif should be a pass through layer, and no checks should
381   // be made here. This exception is added only until GATT server code is
382   // refactored, and one can distinguish stack-internal aps from external apps
383   if (memcmp(&service[0].uuid, &restricted_uuid1, sizeof(bt_uuid_t)) == 0 ||
384       memcmp(&service[0].uuid, &restricted_uuid2, sizeof(bt_uuid_t)) == 0) {
385     LOG_ERROR(LOG_TAG, "%s: Attept to register restricted service", __func__);
386     HAL_CBACK(bt_gatt_callbacks, server->service_added_cb, BT_STATUS_FAIL,
387               server_if, std::move(service));
388     return;
389   }
390 
391   int status = BTA_GATTS_AddService(server_if, service);
392   HAL_CBACK(bt_gatt_callbacks, server->service_added_cb, status, server_if,
393             std::move(service));
394 }
395 
btif_gatts_add_service(int server_if,vector<btgatt_db_element_t> service)396 static bt_status_t btif_gatts_add_service(int server_if,
397                                           vector<btgatt_db_element_t> service) {
398   CHECK_BTGATT_INIT();
399   return do_in_jni_thread(
400       Bind(&add_service_impl, server_if, std::move(service)));
401 }
402 
btif_gatts_stop_service(int server_if,int service_handle)403 static bt_status_t btif_gatts_stop_service(int server_if, int service_handle) {
404   CHECK_BTGATT_INIT();
405   return do_in_jni_thread(Bind(&BTA_GATTS_StopService, service_handle));
406 }
407 
btif_gatts_delete_service(int server_if,int service_handle)408 static bt_status_t btif_gatts_delete_service(int server_if,
409                                              int service_handle) {
410   CHECK_BTGATT_INIT();
411   return do_in_jni_thread(Bind(&BTA_GATTS_DeleteService, service_handle));
412 }
413 
btif_gatts_send_indication(int server_if,int attribute_handle,int conn_id,int confirm,vector<uint8_t> value)414 static bt_status_t btif_gatts_send_indication(int server_if,
415                                               int attribute_handle, int conn_id,
416                                               int confirm,
417                                               vector<uint8_t> value) {
418   CHECK_BTGATT_INIT();
419 
420   if (value.size() > BTGATT_MAX_ATTR_LEN) value.resize(BTGATT_MAX_ATTR_LEN);
421 
422   return do_in_jni_thread(Bind(&BTA_GATTS_HandleValueIndication, conn_id,
423                                attribute_handle, std::move(value), confirm));
424   // TODO: Might need to send an ACK if handle value indication is
425   //       invoked without need for confirmation.
426 }
427 
btif_gatts_send_response_impl(int conn_id,int trans_id,int status,btgatt_response_t response)428 static void btif_gatts_send_response_impl(int conn_id, int trans_id, int status,
429                                           btgatt_response_t response) {
430   tBTA_GATTS_RSP rsp_struct;
431   btif_to_bta_response(&rsp_struct, &response);
432 
433   BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp_struct);
434 
435   HAL_CBACK(bt_gatt_callbacks, server->response_confirmation_cb, 0,
436             rsp_struct.attr_value.handle);
437 }
438 
btif_gatts_send_response(int conn_id,int trans_id,int status,btgatt_response_t * response)439 static bt_status_t btif_gatts_send_response(int conn_id, int trans_id,
440                                             int status,
441                                             btgatt_response_t* response) {
442   CHECK_BTGATT_INIT();
443   return do_in_jni_thread(Bind(&btif_gatts_send_response_impl, conn_id,
444                                trans_id, status, *response));
445 }
446 
btif_gattc_set_preferred_phy(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint16_t phy_options)447 static bt_status_t btif_gattc_set_preferred_phy(int conn_id, uint8_t tx_phy,
448                                                 uint8_t rx_phy,
449                                                 uint16_t phy_options) {
450   CHECK_BTGATT_INIT();
451   do_in_bta_thread(FROM_HERE, Bind(&GATTC_SetPreferredPHY, conn_id, tx_phy,
452                                    rx_phy, phy_options));
453   return BT_STATUS_SUCCESS;
454 }
455 
btif_gattc_read_phy(int conn_id,base::Callback<void (uint8_t tx_phy,uint8_t rx_phy,uint8_t status)> cb)456 static bt_status_t btif_gattc_read_phy(
457     int conn_id,
458     base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
459   CHECK_BTGATT_INIT();
460   do_in_bta_thread(FROM_HERE, Bind(&GATTC_ReadPHY, conn_id,
461                                    jni_thread_wrapper(FROM_HERE, cb)));
462   return BT_STATUS_SUCCESS;
463 }
464 
465 const btgatt_server_interface_t btgattServerInterface = {
466     btif_gatts_register_app,   btif_gatts_unregister_app,
467     btif_gatts_open,           btif_gatts_close,
468     btif_gatts_add_service,    btif_gatts_stop_service,
469     btif_gatts_delete_service, btif_gatts_send_indication,
470     btif_gatts_send_response,  btif_gattc_set_preferred_phy,
471     btif_gattc_read_phy};
472