OSDN Git Service

48d99560a5f3fc6080b36b1bb331d8f2e66cc466
[android-x86/system-bt.git] / service / common / bluetooth / binder / IBluetoothLowEnergy.cpp
1 //
2 //  Copyright (C) 2015 Google, Inc.
3 //
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:
7 //
8 //  http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 #include "service/common/bluetooth/binder/IBluetoothLowEnergy.h"
18
19 #include <base/logging.h>
20 #include <binder/Parcel.h>
21
22 #include "service/common/bluetooth/binder/parcel_helpers.h"
23
24 using android::IBinder;
25 using android::interface_cast;
26 using android::Parcel;
27 using android::sp;
28 using android::status_t;
29
30 using bluetooth::AdvertiseData;
31 using bluetooth::AdvertiseSettings;
32
33 namespace ipc {
34 namespace binder {
35
36 // static
37 const char IBluetoothLowEnergy::kServiceName[] =
38     "bluetooth-low-energy-service";
39
40 // BnBluetoothLowEnergy (server) implementation
41 // ========================================================
42
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;
48
49   switch (code) {
50   case REGISTER_CLIENT_TRANSACTION: {
51     sp<IBinder> callback = data.readStrongBinder();
52     bool result = RegisterClient(
53         interface_cast<IBluetoothLowEnergyCallback>(callback));
54
55     reply->writeInt32(result);
56
57     return android::NO_ERROR;
58   }
59   case UNREGISTER_CLIENT_TRANSACTION: {
60     int client_id = data.readInt32();
61     UnregisterClient(client_id);
62     return android::NO_ERROR;
63   }
64   case UNREGISTER_ALL_TRANSACTION: {
65     UnregisterAll();
66     return android::NO_ERROR;
67   }
68   case CONNECT_TRANSACTION: {
69     int client_id = data.readInt32();
70     const char* address = data.readCString();
71     bool is_direct = data.readBool();
72
73     bool result = Connect(client_id, address, is_direct);
74     reply->writeInt32(result);
75
76     return android::NO_ERROR;
77   }
78   case DISCONNECT_TRANSACTION: {
79     int client_id = data.readInt32();
80     const char* address = data.readCString();
81
82     bool result = Disconnect(client_id, address);
83     reply->writeInt32(result);
84
85     return android::NO_ERROR;
86   }
87   case START_SCAN_TRANSACTION: {
88     int client_id = data.readInt32();
89     auto settings = CreateScanSettingsFromParcel(data);
90     CHECK(settings);
91     std::vector<bluetooth::ScanFilter> filters;
92
93     int list_meta_data = data.readInt32();
94     CHECK(list_meta_data == kParcelValList);
95
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);
100         CHECK(filter);
101         filters.push_back(*filter);
102       }
103     }
104
105     bool result = StartScan(client_id, *settings, filters);
106     reply->writeInt32(result);
107
108     return android::NO_ERROR;
109   }
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;
115   }
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);
124
125     bool result = StartMultiAdvertising(
126         client_id, *adv_data, *scan_rsp, *adv_settings);
127
128     reply->writeInt32(result);
129
130     return android::NO_ERROR;
131   }
132   case STOP_MULTI_ADVERTISING_TRANSACTION: {
133     int client_id = data.readInt32();
134     bool result = StopMultiAdvertising(client_id);
135
136     reply->writeInt32(result);
137
138     return android::NO_ERROR;
139   }
140   default:
141     return BBinder::onTransact(code, data, reply, flags);
142   }
143 }
144
145 // BpBluetoothLowEnergy (client) implementation
146 // ========================================================
147
148 BpBluetoothLowEnergy::BpBluetoothLowEnergy(const sp<IBinder>& impl)
149     : BpInterface<IBluetoothLowEnergy>(impl) {
150 }
151
152 bool BpBluetoothLowEnergy::RegisterClient(
153       const sp<IBluetoothLowEnergyCallback>& callback) {
154   Parcel data, reply;
155
156   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
157   data.writeStrongBinder(IInterface::asBinder(callback.get()));
158
159   remote()->transact(IBluetoothLowEnergy::REGISTER_CLIENT_TRANSACTION,
160                      data, &reply);
161
162   return reply.readInt32();
163 }
164
165 void BpBluetoothLowEnergy::UnregisterClient(int client_id) {
166   Parcel data, reply;
167
168   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
169   data.writeInt32(client_id);
170
171   remote()->transact(IBluetoothLowEnergy::UNREGISTER_CLIENT_TRANSACTION,
172                      data, &reply);
173 }
174
175 void BpBluetoothLowEnergy::UnregisterAll() {
176   Parcel data, reply;
177
178   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
179
180   remote()->transact(IBluetoothLowEnergy::UNREGISTER_ALL_TRANSACTION,
181                      data, &reply);
182 }
183
184 bool BpBluetoothLowEnergy::Connect(int client_id, const char* address,
185                                    bool is_direct) {
186   Parcel data, reply;
187
188   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
189   data.writeInt32(client_id);
190   data.writeCString(address);
191   data.writeBool(is_direct);
192
193   remote()->transact(IBluetoothLowEnergy::CONNECT_TRANSACTION,
194                      data, &reply);
195
196   return reply.readInt32();
197 }
198
199 bool BpBluetoothLowEnergy::Disconnect(int client_id, const char* address) {
200   Parcel data, reply;
201
202   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
203   data.writeInt32(client_id);
204   data.writeCString(address);
205
206   remote()->transact(IBluetoothLowEnergy::DISCONNECT_TRANSACTION,
207                      data, &reply);
208
209   return reply.readInt32();
210 }
211
212 bool BpBluetoothLowEnergy::StartScan(
213     int client_id,
214     const bluetooth::ScanSettings& settings,
215     const std::vector<bluetooth::ScanFilter>& filters) {
216   Parcel data, reply;
217
218   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
219   data.writeInt32(client_id);
220   WriteScanSettingsToParcel(settings, &data);
221
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
224   // compatibility.
225   data.writeInt32(kParcelValList);
226   data.writeInt32(filters.size());
227   for (const auto& filter : filters)
228     WriteScanFilterToParcel(filter, &data);
229
230   remote()->transact(IBluetoothLowEnergy::START_SCAN_TRANSACTION,
231                      data, &reply);
232
233   return reply.readInt32();
234 }
235
236 bool BpBluetoothLowEnergy::StopScan(int client_id) {
237   Parcel data, reply;
238
239   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
240   data.writeInt32(client_id);
241
242   remote()->transact(IBluetoothLowEnergy::STOP_SCAN_TRANSACTION,
243                      data, &reply);
244
245   return reply.readInt32();
246 }
247
248 bool BpBluetoothLowEnergy::StartMultiAdvertising(
249     int client_id,
250     const AdvertiseData& advertise_data,
251     const AdvertiseData& scan_response,
252     const AdvertiseSettings& settings) {
253   Parcel data, reply;
254
255   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
256   data.writeInt32(client_id);
257   WriteAdvertiseDataToParcel(advertise_data, &data);
258   WriteAdvertiseDataToParcel(scan_response, &data);
259   WriteAdvertiseSettingsToParcel(settings, &data);
260
261   remote()->transact(IBluetoothLowEnergy::START_MULTI_ADVERTISING_TRANSACTION,
262                      data, &reply);
263
264   return reply.readInt32();
265 }
266
267 bool BpBluetoothLowEnergy::StopMultiAdvertising(int client_id) {
268   Parcel data, reply;
269
270   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
271   data.writeInt32(client_id);
272
273   remote()->transact(IBluetoothLowEnergy::STOP_MULTI_ADVERTISING_TRANSACTION,
274                      data, &reply);
275
276   return reply.readInt32();
277 }
278
279 IMPLEMENT_META_INTERFACE(BluetoothLowEnergy, IBluetoothLowEnergy::kServiceName);
280
281 }  // namespace binder
282 }  // namespace ipc