Home | History | Annotate | Download | only in src
      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 
     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 
    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 
    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 
    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  ******************************************************************************/
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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