• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "gatt_shim.h"
16 
17 #include <base/functional/bind.h>
18 #include <base/functional/callback.h>
19 #include <base/location.h>
20 #include <bluetooth/log.h>
21 
22 #include <cstdint>
23 #include <optional>
24 
25 #include "include/hardware/bluetooth.h"
26 #include "include/hardware/bt_common_types.h"
27 #include "include/hardware/bt_gatt_client.h"
28 #include "include/hardware/bt_gatt_server.h"
29 #include "rust/cxx.h"
30 #include "stack/include/gatt_api.h"
31 #include "types/bluetooth/uuid.h"
32 #include "types/raw_address.h"
33 
34 bt_status_t do_in_jni_thread(base::OnceClosure task);
35 
36 namespace {
AddressOfConnection(uint16_t conn_id)37 std::optional<RawAddress> AddressOfConnection(uint16_t conn_id) {
38   tGATT_IF gatt_if;
39   RawAddress remote_bda;
40   tBT_TRANSPORT transport;
41   auto valid =
42           GATT_GetConnectionInfor(static_cast<tCONN_ID>(conn_id), &gatt_if, remote_bda, &transport);
43   if (!valid) {
44     return std::nullopt;
45   }
46   return remote_bda;
47 }
48 }  // namespace
49 
50 namespace bluetooth {
51 namespace gatt {
52 
OnServerRead(uint16_t conn_id,uint32_t trans_id,uint16_t attr_handle,AttributeBackingType attr_type,uint32_t offset,bool is_long) const53 void GattServerCallbacks::OnServerRead(uint16_t conn_id, uint32_t trans_id, uint16_t attr_handle,
54                                        AttributeBackingType attr_type, uint32_t offset,
55                                        bool is_long) const {
56   auto addr = AddressOfConnection(conn_id);
57   if (!addr.has_value()) {
58     log::warn("Dropping server read characteristic since connection {} not found", conn_id);
59     return;
60   }
61 
62   switch (attr_type) {
63     case AttributeBackingType::CHARACTERISTIC:
64       do_in_jni_thread(base::BindOnce(callbacks.request_read_characteristic_cb, conn_id, trans_id,
65                                       addr.value(), attr_handle, offset, is_long));
66       break;
67     case AttributeBackingType::DESCRIPTOR:
68       do_in_jni_thread(base::BindOnce(callbacks.request_read_descriptor_cb, conn_id, trans_id,
69                                       addr.value(), attr_handle, offset, is_long));
70       break;
71     default:
72       log::fatal("Unexpected backing type {}", attr_type);
73   }
74 }
75 
request_write_with_vec(request_write_callback cb,int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool need_rsp,bool is_prep,const std::vector<uint8_t> & value)76 static void request_write_with_vec(request_write_callback cb, int conn_id, int trans_id,
77                                    const RawAddress& bda, int attr_handle, int offset,
78                                    bool need_rsp, bool is_prep, const std::vector<uint8_t>& value) {
79   cb(conn_id, trans_id, bda, attr_handle, offset, need_rsp, is_prep, value.data(), value.size());
80 }
81 
OnServerWrite(uint16_t conn_id,uint32_t trans_id,uint16_t attr_handle,AttributeBackingType attr_type,uint32_t offset,bool need_response,bool is_prepare,::rust::Slice<const uint8_t> value) const82 void GattServerCallbacks::OnServerWrite(uint16_t conn_id, uint32_t trans_id, uint16_t attr_handle,
83                                         AttributeBackingType attr_type, uint32_t offset,
84                                         bool need_response, bool is_prepare,
85                                         ::rust::Slice<const uint8_t> value) const {
86   auto addr = AddressOfConnection(conn_id);
87   if (!addr.has_value()) {
88     log::warn("Dropping server write characteristic since connection {} not found", conn_id);
89     return;
90   }
91 
92   auto buf = std::vector<uint8_t>(value.begin(), value.end());
93 
94   switch (attr_type) {
95     case AttributeBackingType::CHARACTERISTIC:
96       do_in_jni_thread(base::BindOnce(
97               request_write_with_vec, callbacks.request_write_characteristic_cb, conn_id, trans_id,
98               addr.value(), attr_handle, offset, need_response, is_prepare, std::move(buf)));
99       break;
100     case AttributeBackingType::DESCRIPTOR:
101       do_in_jni_thread(base::BindOnce(request_write_with_vec, callbacks.request_write_descriptor_cb,
102                                       conn_id, trans_id, addr.value(), attr_handle, offset,
103                                       need_response, is_prepare, std::move(buf)));
104       break;
105     default:
106       log::fatal("Unexpected backing type {}", attr_type);
107   }
108 }
109 
OnIndicationSentConfirmation(uint16_t conn_id,int status) const110 void GattServerCallbacks::OnIndicationSentConfirmation(uint16_t conn_id, int status) const {
111   do_in_jni_thread(base::BindOnce(callbacks.indication_sent_cb, conn_id, status));
112 }
113 
OnExecute(uint16_t conn_id,uint32_t trans_id,bool execute) const114 void GattServerCallbacks::OnExecute(uint16_t conn_id, uint32_t trans_id, bool execute) const {
115   auto addr = AddressOfConnection(conn_id);
116   if (!addr.has_value()) {
117     log::warn("Dropping server execute write since connection {} not found", conn_id);
118     return;
119   }
120 
121   do_in_jni_thread(base::BindOnce(callbacks.request_exec_write_cb, conn_id, trans_id, addr.value(),
122                                   execute));
123 }
124 
125 }  // namespace gatt
126 }  // namespace bluetooth
127