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