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