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
btapp_gatts_copy_req_data(uint16_t event,char * p_dest,char * p_src)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
btapp_gatts_free_req_data(uint16_t event,tBTA_GATTS * p_data)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
btapp_gatts_handle_cback(uint16_t event,char * p_param)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
btapp_gatts_cback(tBTA_GATTS_EVT event,tBTA_GATTS * p_data)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 ******************************************************************************/
btif_gatts_register_app(bt_uuid_t * bt_uuid)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
btif_gatts_unregister_app(int server_if)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
btif_gatts_open_impl(int server_if,BD_ADDR address,bool is_direct,int transport_param)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
btif_gatts_open(int server_if,const bt_bdaddr_t * bd_addr,bool is_direct,int transport)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
btif_gatts_close_impl(int server_if,BD_ADDR address,int conn_id)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
btif_gatts_close(int server_if,const bt_bdaddr_t * bd_addr,int conn_id)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
add_service_impl(int server_if,vector<btgatt_db_element_t> service)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
btif_gatts_add_service(int server_if,vector<btgatt_db_element_t> service)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
btif_gatts_stop_service(int server_if,int service_handle)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
btif_gatts_delete_service(int server_if,int service_handle)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
btif_gatts_send_indication(int server_if,int attribute_handle,int conn_id,int confirm,vector<uint8_t> value)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
btif_gatts_send_response_impl(int conn_id,int trans_id,int status,btgatt_response_t response)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
btif_gatts_send_response(int conn_id,int trans_id,int status,btgatt_response_t * response)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
btif_gattc_set_preferred_phy(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint16_t phy_options)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
btif_gattc_read_phy(int conn_id,base::Callback<void (uint8_t tx_phy,uint8_t rx_phy,uint8_t status)> cb)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