OSDN Git Service

service: add SetMtu and OnMtuChanged
[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 SET_MTU_TRANSACTION: {
88     int client_id = data.readInt32();
89     const char* address = data.readCString();
90     int mtu = data.readInt32();
91
92     bool result = SetMtu(client_id, address, mtu);
93     reply->writeInt32(result);
94
95     return android::NO_ERROR;
96   }
97   case START_SCAN_TRANSACTION: {
98     int client_id = data.readInt32();
99     auto settings = CreateScanSettingsFromParcel(data);
100     CHECK(settings);
101     std::vector<bluetooth::ScanFilter> filters;
102
103     int list_meta_data = data.readInt32();
104     CHECK(list_meta_data == kParcelValList);
105
106     int filter_count = data.readInt32();
107     if (filter_count >= 0) {  // Make sure |filter_count| isn't negative.
108       for (int i = 0; i < filter_count; i++) {
109         auto filter = CreateScanFilterFromParcel(data);
110         CHECK(filter);
111         filters.push_back(*filter);
112       }
113     }
114
115     bool result = StartScan(client_id, *settings, filters);
116     reply->writeInt32(result);
117
118     return android::NO_ERROR;
119   }
120   case STOP_SCAN_TRANSACTION: {
121     int client_id = data.readInt32();
122     bool result = StopScan(client_id);
123     reply->writeInt32(result);
124     return android::NO_ERROR;
125   }
126   case START_MULTI_ADVERTISING_TRANSACTION: {
127     int client_id = data.readInt32();
128     std::unique_ptr<AdvertiseData> adv_data =
129         CreateAdvertiseDataFromParcel(data);
130     std::unique_ptr<AdvertiseData> scan_rsp =
131         CreateAdvertiseDataFromParcel(data);
132     std::unique_ptr<AdvertiseSettings> adv_settings =
133         CreateAdvertiseSettingsFromParcel(data);
134
135     bool result = StartMultiAdvertising(
136         client_id, *adv_data, *scan_rsp, *adv_settings);
137
138     reply->writeInt32(result);
139
140     return android::NO_ERROR;
141   }
142   case STOP_MULTI_ADVERTISING_TRANSACTION: {
143     int client_id = data.readInt32();
144     bool result = StopMultiAdvertising(client_id);
145
146     reply->writeInt32(result);
147
148     return android::NO_ERROR;
149   }
150   default:
151     return BBinder::onTransact(code, data, reply, flags);
152   }
153 }
154
155 // BpBluetoothLowEnergy (client) implementation
156 // ========================================================
157
158 BpBluetoothLowEnergy::BpBluetoothLowEnergy(const sp<IBinder>& impl)
159     : BpInterface<IBluetoothLowEnergy>(impl) {
160 }
161
162 bool BpBluetoothLowEnergy::RegisterClient(
163       const sp<IBluetoothLowEnergyCallback>& callback) {
164   Parcel data, reply;
165
166   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
167   data.writeStrongBinder(IInterface::asBinder(callback.get()));
168
169   remote()->transact(IBluetoothLowEnergy::REGISTER_CLIENT_TRANSACTION,
170                      data, &reply);
171
172   return reply.readInt32();
173 }
174
175 void BpBluetoothLowEnergy::UnregisterClient(int client_id) {
176   Parcel data, reply;
177
178   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
179   data.writeInt32(client_id);
180
181   remote()->transact(IBluetoothLowEnergy::UNREGISTER_CLIENT_TRANSACTION,
182                      data, &reply);
183 }
184
185 void BpBluetoothLowEnergy::UnregisterAll() {
186   Parcel data, reply;
187
188   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
189
190   remote()->transact(IBluetoothLowEnergy::UNREGISTER_ALL_TRANSACTION,
191                      data, &reply);
192 }
193
194 bool BpBluetoothLowEnergy::Connect(int client_id, const char* address,
195                                    bool is_direct) {
196   Parcel data, reply;
197
198   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
199   data.writeInt32(client_id);
200   data.writeCString(address);
201   data.writeBool(is_direct);
202
203   remote()->transact(IBluetoothLowEnergy::CONNECT_TRANSACTION,
204                      data, &reply);
205
206   return reply.readInt32();
207 }
208
209 bool BpBluetoothLowEnergy::Disconnect(int client_id, const char* address) {
210   Parcel data, reply;
211
212   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
213   data.writeInt32(client_id);
214   data.writeCString(address);
215
216   remote()->transact(IBluetoothLowEnergy::DISCONNECT_TRANSACTION,
217                      data, &reply);
218
219   return reply.readInt32();
220 }
221
222 bool BpBluetoothLowEnergy::SetMtu(int client_id, const char* address, int mtu) {
223   Parcel data, reply;
224
225   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
226   data.writeInt32(client_id);
227   data.writeCString(address);
228   data.writeInt32(mtu);
229
230   remote()->transact(IBluetoothLowEnergy::SET_MTU_TRANSACTION, data, &reply);
231   return reply.readInt32();
232 }
233
234 bool BpBluetoothLowEnergy::StartScan(
235     int client_id,
236     const bluetooth::ScanSettings& settings,
237     const std::vector<bluetooth::ScanFilter>& filters) {
238   Parcel data, reply;
239
240   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
241   data.writeInt32(client_id);
242   WriteScanSettingsToParcel(settings, &data);
243
244   // The Java equivalent of |filters| is a List<ScanFilter>. Parcel.java inserts
245   // a metadata value of VAL_LIST (11) for this so I'm doing it here for
246   // compatibility.
247   data.writeInt32(kParcelValList);
248   data.writeInt32(filters.size());
249   for (const auto& filter : filters)
250     WriteScanFilterToParcel(filter, &data);
251
252   remote()->transact(IBluetoothLowEnergy::START_SCAN_TRANSACTION,
253                      data, &reply);
254
255   return reply.readInt32();
256 }
257
258 bool BpBluetoothLowEnergy::StopScan(int client_id) {
259   Parcel data, reply;
260
261   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
262   data.writeInt32(client_id);
263
264   remote()->transact(IBluetoothLowEnergy::STOP_SCAN_TRANSACTION,
265                      data, &reply);
266
267   return reply.readInt32();
268 }
269
270 bool BpBluetoothLowEnergy::StartMultiAdvertising(
271     int client_id,
272     const AdvertiseData& advertise_data,
273     const AdvertiseData& scan_response,
274     const AdvertiseSettings& settings) {
275   Parcel data, reply;
276
277   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
278   data.writeInt32(client_id);
279   WriteAdvertiseDataToParcel(advertise_data, &data);
280   WriteAdvertiseDataToParcel(scan_response, &data);
281   WriteAdvertiseSettingsToParcel(settings, &data);
282
283   remote()->transact(IBluetoothLowEnergy::START_MULTI_ADVERTISING_TRANSACTION,
284                      data, &reply);
285
286   return reply.readInt32();
287 }
288
289 bool BpBluetoothLowEnergy::StopMultiAdvertising(int client_id) {
290   Parcel data, reply;
291
292   data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
293   data.writeInt32(client_id);
294
295   remote()->transact(IBluetoothLowEnergy::STOP_MULTI_ADVERTISING_TRANSACTION,
296                      data, &reply);
297
298   return reply.readInt32();
299 }
300
301 IMPLEMENT_META_INTERFACE(BluetoothLowEnergy, IBluetoothLowEnergy::kServiceName);
302
303 }  // namespace binder
304 }  // namespace ipc