2 // Copyright (C) 2015 Google, Inc.
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at:
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #include "service/common/bluetooth/binder/IBluetoothLowEnergy.h"
19 #include <base/logging.h>
20 #include <binder/Parcel.h>
22 #include "service/common/bluetooth/binder/parcel_helpers.h"
24 using android::IBinder;
25 using android::interface_cast;
26 using android::Parcel;
28 using android::status_t;
30 using bluetooth::AdvertiseData;
31 using bluetooth::AdvertiseSettings;
37 const char IBluetoothLowEnergy::kServiceName[] =
38 "bluetooth-low-energy-service";
40 // BnBluetoothLowEnergy (server) implementation
41 // ========================================================
43 status_t BnBluetoothLowEnergy::onTransact(
44 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
45 VLOG(2) << "IBluetoothLowEnergy: " << code;
46 if (!data.checkInterface(this))
47 return android::PERMISSION_DENIED;
50 case REGISTER_CLIENT_TRANSACTION: {
51 sp<IBinder> callback = data.readStrongBinder();
52 bool result = RegisterClient(
53 interface_cast<IBluetoothLowEnergyCallback>(callback));
55 reply->writeInt32(result);
57 return android::NO_ERROR;
59 case UNREGISTER_CLIENT_TRANSACTION: {
60 int client_id = data.readInt32();
61 UnregisterClient(client_id);
62 return android::NO_ERROR;
64 case UNREGISTER_ALL_TRANSACTION: {
66 return android::NO_ERROR;
68 case CONNECT_TRANSACTION: {
69 int client_id = data.readInt32();
70 const char* address = data.readCString();
71 bool is_direct = data.readBool();
73 bool result = Connect(client_id, address, is_direct);
74 reply->writeInt32(result);
76 return android::NO_ERROR;
78 case DISCONNECT_TRANSACTION: {
79 int client_id = data.readInt32();
80 const char* address = data.readCString();
82 bool result = Disconnect(client_id, address);
83 reply->writeInt32(result);
85 return android::NO_ERROR;
87 case START_SCAN_TRANSACTION: {
88 int client_id = data.readInt32();
89 auto settings = CreateScanSettingsFromParcel(data);
91 std::vector<bluetooth::ScanFilter> filters;
93 int list_meta_data = data.readInt32();
94 CHECK(list_meta_data == kParcelValList);
96 int filter_count = data.readInt32();
97 if (filter_count >= 0) { // Make sure |filter_count| isn't negative.
98 for (int i = 0; i < filter_count; i++) {
99 auto filter = CreateScanFilterFromParcel(data);
101 filters.push_back(*filter);
105 bool result = StartScan(client_id, *settings, filters);
106 reply->writeInt32(result);
108 return android::NO_ERROR;
110 case STOP_SCAN_TRANSACTION: {
111 int client_id = data.readInt32();
112 bool result = StopScan(client_id);
113 reply->writeInt32(result);
114 return android::NO_ERROR;
116 case START_MULTI_ADVERTISING_TRANSACTION: {
117 int client_id = data.readInt32();
118 std::unique_ptr<AdvertiseData> adv_data =
119 CreateAdvertiseDataFromParcel(data);
120 std::unique_ptr<AdvertiseData> scan_rsp =
121 CreateAdvertiseDataFromParcel(data);
122 std::unique_ptr<AdvertiseSettings> adv_settings =
123 CreateAdvertiseSettingsFromParcel(data);
125 bool result = StartMultiAdvertising(
126 client_id, *adv_data, *scan_rsp, *adv_settings);
128 reply->writeInt32(result);
130 return android::NO_ERROR;
132 case STOP_MULTI_ADVERTISING_TRANSACTION: {
133 int client_id = data.readInt32();
134 bool result = StopMultiAdvertising(client_id);
136 reply->writeInt32(result);
138 return android::NO_ERROR;
141 return BBinder::onTransact(code, data, reply, flags);
145 // BpBluetoothLowEnergy (client) implementation
146 // ========================================================
148 BpBluetoothLowEnergy::BpBluetoothLowEnergy(const sp<IBinder>& impl)
149 : BpInterface<IBluetoothLowEnergy>(impl) {
152 bool BpBluetoothLowEnergy::RegisterClient(
153 const sp<IBluetoothLowEnergyCallback>& callback) {
156 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
157 data.writeStrongBinder(IInterface::asBinder(callback.get()));
159 remote()->transact(IBluetoothLowEnergy::REGISTER_CLIENT_TRANSACTION,
162 return reply.readInt32();
165 void BpBluetoothLowEnergy::UnregisterClient(int client_id) {
168 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
169 data.writeInt32(client_id);
171 remote()->transact(IBluetoothLowEnergy::UNREGISTER_CLIENT_TRANSACTION,
175 void BpBluetoothLowEnergy::UnregisterAll() {
178 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
180 remote()->transact(IBluetoothLowEnergy::UNREGISTER_ALL_TRANSACTION,
184 bool BpBluetoothLowEnergy::Connect(int client_id, const char* address,
188 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
189 data.writeInt32(client_id);
190 data.writeCString(address);
191 data.writeBool(is_direct);
193 remote()->transact(IBluetoothLowEnergy::CONNECT_TRANSACTION,
196 return reply.readInt32();
199 bool BpBluetoothLowEnergy::Disconnect(int client_id, const char* address) {
202 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
203 data.writeInt32(client_id);
204 data.writeCString(address);
206 remote()->transact(IBluetoothLowEnergy::DISCONNECT_TRANSACTION,
209 return reply.readInt32();
212 bool BpBluetoothLowEnergy::StartScan(
214 const bluetooth::ScanSettings& settings,
215 const std::vector<bluetooth::ScanFilter>& filters) {
218 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
219 data.writeInt32(client_id);
220 WriteScanSettingsToParcel(settings, &data);
222 // The Java equivalent of |filters| is a List<ScanFilter>. Parcel.java inserts
223 // a metadata value of VAL_LIST (11) for this so I'm doing it here for
225 data.writeInt32(kParcelValList);
226 data.writeInt32(filters.size());
227 for (const auto& filter : filters)
228 WriteScanFilterToParcel(filter, &data);
230 remote()->transact(IBluetoothLowEnergy::START_SCAN_TRANSACTION,
233 return reply.readInt32();
236 bool BpBluetoothLowEnergy::StopScan(int client_id) {
239 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
240 data.writeInt32(client_id);
242 remote()->transact(IBluetoothLowEnergy::STOP_SCAN_TRANSACTION,
245 return reply.readInt32();
248 bool BpBluetoothLowEnergy::StartMultiAdvertising(
250 const AdvertiseData& advertise_data,
251 const AdvertiseData& scan_response,
252 const AdvertiseSettings& settings) {
255 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
256 data.writeInt32(client_id);
257 WriteAdvertiseDataToParcel(advertise_data, &data);
258 WriteAdvertiseDataToParcel(scan_response, &data);
259 WriteAdvertiseSettingsToParcel(settings, &data);
261 remote()->transact(IBluetoothLowEnergy::START_MULTI_ADVERTISING_TRANSACTION,
264 return reply.readInt32();
267 bool BpBluetoothLowEnergy::StopMultiAdvertising(int client_id) {
270 data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
271 data.writeInt32(client_id);
273 remote()->transact(IBluetoothLowEnergy::STOP_MULTI_ADVERTISING_TRANSACTION,
276 return reply.readInt32();
279 IMPLEMENT_META_INTERFACE(BluetoothLowEnergy, IBluetoothLowEnergy::kServiceName);
281 } // namespace binder