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