Home | History | Annotate | Download | only in src
      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 
     52 using base::Bind;
     53 using base::Owned;
     54 using bluetooth::Uuid;
     55 using 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 
     75 extern const btgatt_callbacks_t* bt_gatt_callbacks;
     76 
     77 /*******************************************************************************
     78  *  Static functions
     79  ******************************************************************************/
     80 
     81 static 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 
    110 static 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 
    126 static 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 
    258 static 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  ******************************************************************************/
    269 static 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 
    276 static 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 
    281 static 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 
    323 static 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 
    330 static 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 
    342 static 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 
    349 static 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 
    355 static 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 
    373 static 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 
    380 static 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 
    385 static 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 
    391 static 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 
    405 static 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 
    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 
    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_bta_thread(FROM_HERE,
    429                    Bind(&BTM_BleSetPhy, bd_addr, tx_phy, rx_phy, phy_options));
    430   return BT_STATUS_SUCCESS;
    431 }
    432 
    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_bta_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