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