• 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 <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