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