• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_gatt_api.h"
44 #include "btif_config.h"
45 #include "btif_dm.h"
46 #include "btif_gatt.h"
47 #include "btif_gatt_util.h"
48 #include "btif_storage.h"
49 #include "osi/include/log.h"
50 #include "stack/include/btu.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 
btapp_gatts_copy_req_data(uint16_t event,char * p_dest,char * p_src)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 
btapp_gatts_free_req_data(uint16_t event,tBTA_GATTS * p_data)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 
btapp_gatts_handle_cback(uint16_t event,char * p_param)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 
btapp_gatts_cback(tBTA_GATTS_EVT event,tBTA_GATTS * p_data)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  ******************************************************************************/
btif_gatts_register_app(const Uuid & bt_uuid)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 
btif_gatts_unregister_app(int server_if)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 
btif_gatts_open_impl(int server_if,const RawAddress & address,bool is_direct,int transport_param)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   // Determine transport
295   if (transport_param != GATT_TRANSPORT_AUTO) {
296     transport = transport_param;
297   } else {
298     switch (device_type) {
299       case BT_DEVICE_TYPE_BREDR:
300         transport = GATT_TRANSPORT_BR_EDR;
301         break;
302 
303       case BT_DEVICE_TYPE_BLE:
304         transport = GATT_TRANSPORT_LE;
305         break;
306 
307       case BT_DEVICE_TYPE_DUMO:
308         if (transport_param == GATT_TRANSPORT_LE)
309           transport = GATT_TRANSPORT_LE;
310         else
311           transport = GATT_TRANSPORT_BR_EDR;
312         break;
313     }
314   }
315 
316   // Connect!
317   BTA_GATTS_Open(server_if, address, is_direct, transport);
318 }
319 
btif_gatts_open(int server_if,const RawAddress & bd_addr,bool is_direct,int transport)320 static bt_status_t btif_gatts_open(int server_if, const RawAddress& bd_addr,
321                                    bool is_direct, int transport) {
322   CHECK_BTGATT_INIT();
323   return do_in_jni_thread(
324       Bind(&btif_gatts_open_impl, server_if, bd_addr, is_direct, transport));
325 }
326 
btif_gatts_close_impl(int server_if,const RawAddress & address,int conn_id)327 static void btif_gatts_close_impl(int server_if, const RawAddress& address,
328                                   int conn_id) {
329   // Close active connection
330   if (conn_id != 0)
331     BTA_GATTS_Close(conn_id);
332   else
333     BTA_GATTS_CancelOpen(server_if, address, true);
334 
335   // Cancel pending background connections
336   BTA_GATTS_CancelOpen(server_if, address, false);
337 }
338 
btif_gatts_close(int server_if,const RawAddress & bd_addr,int conn_id)339 static bt_status_t btif_gatts_close(int server_if, const RawAddress& bd_addr,
340                                     int conn_id) {
341   CHECK_BTGATT_INIT();
342   return do_in_jni_thread(
343       Bind(&btif_gatts_close_impl, server_if, bd_addr, conn_id));
344 }
345 
on_service_added_cb(uint8_t status,int server_if,vector<btgatt_db_element_t> service)346 static void on_service_added_cb(uint8_t status, int server_if,
347                                 vector<btgatt_db_element_t> service) {
348   HAL_CBACK(bt_gatt_callbacks, server->service_added_cb, status, server_if,
349             std::move(service));
350 }
351 
add_service_impl(int server_if,vector<btgatt_db_element_t> service)352 static void add_service_impl(int server_if,
353                              vector<btgatt_db_element_t> service) {
354   // TODO(jpawlowski): btif should be a pass through layer, and no checks should
355   // be made here. This exception is added only until GATT server code is
356   // refactored, and one can distinguish stack-internal aps from external apps
357   if (service[0].uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER) ||
358       service[0].uuid == Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER)) {
359     LOG_ERROR(LOG_TAG, "%s: Attept to register restricted service", __func__);
360     HAL_CBACK(bt_gatt_callbacks, server->service_added_cb, BT_STATUS_FAIL,
361               server_if, std::move(service));
362     return;
363   }
364 
365   BTA_GATTS_AddService(
366       server_if, service,
367       jni_thread_wrapper(FROM_HERE, base::Bind(&on_service_added_cb)));
368 }
369 
btif_gatts_add_service(int server_if,vector<btgatt_db_element_t> service)370 static bt_status_t btif_gatts_add_service(int server_if,
371                                           vector<btgatt_db_element_t> service) {
372   CHECK_BTGATT_INIT();
373   return do_in_jni_thread(
374       FROM_HERE, Bind(&add_service_impl, server_if, std::move(service)));
375 }
376 
btif_gatts_stop_service(int server_if,int service_handle)377 static bt_status_t btif_gatts_stop_service(int server_if, int service_handle) {
378   CHECK_BTGATT_INIT();
379   return do_in_jni_thread(Bind(&BTA_GATTS_StopService, service_handle));
380 }
381 
btif_gatts_delete_service(int server_if,int service_handle)382 static bt_status_t btif_gatts_delete_service(int server_if,
383                                              int service_handle) {
384   CHECK_BTGATT_INIT();
385   return do_in_jni_thread(Bind(&BTA_GATTS_DeleteService, service_handle));
386 }
387 
btif_gatts_send_indication(int server_if,int attribute_handle,int conn_id,int confirm,vector<uint8_t> value)388 static bt_status_t btif_gatts_send_indication(int server_if,
389                                               int attribute_handle, int conn_id,
390                                               int confirm,
391                                               vector<uint8_t> value) {
392   CHECK_BTGATT_INIT();
393 
394   if (value.size() > BTGATT_MAX_ATTR_LEN) value.resize(BTGATT_MAX_ATTR_LEN);
395 
396   return do_in_jni_thread(Bind(&BTA_GATTS_HandleValueIndication, conn_id,
397                                attribute_handle, std::move(value), confirm));
398   // TODO: Might need to send an ACK if handle value indication is
399   //       invoked without need for confirmation.
400 }
401 
btif_gatts_send_response_impl(int conn_id,int trans_id,int status,btgatt_response_t response)402 static void btif_gatts_send_response_impl(int conn_id, int trans_id, int status,
403                                           btgatt_response_t response) {
404   tGATTS_RSP rsp_struct;
405   btif_to_bta_response(&rsp_struct, &response);
406 
407   BTA_GATTS_SendRsp(conn_id, trans_id, status, &rsp_struct);
408 
409   HAL_CBACK(bt_gatt_callbacks, server->response_confirmation_cb, 0,
410             rsp_struct.attr_value.handle);
411 }
412 
btif_gatts_send_response(int conn_id,int trans_id,int status,const btgatt_response_t & response)413 static bt_status_t btif_gatts_send_response(int conn_id, int trans_id,
414                                             int status,
415                                             const btgatt_response_t& response) {
416   CHECK_BTGATT_INIT();
417   return do_in_jni_thread(Bind(&btif_gatts_send_response_impl, conn_id,
418                                trans_id, status, response));
419 }
420 
btif_gatts_set_preferred_phy(const RawAddress & bd_addr,uint8_t tx_phy,uint8_t rx_phy,uint16_t phy_options)421 static bt_status_t btif_gatts_set_preferred_phy(const RawAddress& bd_addr,
422                                                 uint8_t tx_phy, uint8_t rx_phy,
423                                                 uint16_t phy_options) {
424   CHECK_BTGATT_INIT();
425   do_in_main_thread(FROM_HERE,
426                     Bind(&BTM_BleSetPhy, bd_addr, tx_phy, rx_phy, phy_options));
427   return BT_STATUS_SUCCESS;
428 }
429 
btif_gatts_read_phy(const RawAddress & bd_addr,base::Callback<void (uint8_t tx_phy,uint8_t rx_phy,uint8_t status)> cb)430 static bt_status_t btif_gatts_read_phy(
431     const RawAddress& bd_addr,
432     base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
433   CHECK_BTGATT_INIT();
434   do_in_main_thread(FROM_HERE, Bind(&BTM_BleReadPhy, bd_addr,
435                                     jni_thread_wrapper(FROM_HERE, cb)));
436   return BT_STATUS_SUCCESS;
437 }
438 
439 const btgatt_server_interface_t btgattServerInterface = {
440     btif_gatts_register_app,   btif_gatts_unregister_app,
441     btif_gatts_open,           btif_gatts_close,
442     btif_gatts_add_service,    btif_gatts_stop_service,
443     btif_gatts_delete_service, btif_gatts_send_indication,
444     btif_gatts_send_response,  btif_gatts_set_preferred_phy,
445     btif_gatts_read_phy};
446