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