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/parcel_helpers.h"
18 
19 #include "service/common/bluetooth/util/address_helper.h"
20 
21 using android::Parcel;
22 
23 using bluetooth::AdvertiseData;
24 using bluetooth::AdvertiseSettings;
25 using bluetooth::GattIdentifier;
26 using bluetooth::ScanFilter;
27 using bluetooth::ScanResult;
28 using bluetooth::ScanSettings;
29 using bluetooth::UUID;
30 
31 namespace ipc {
32 namespace binder {
33 
34 // TODO(armansito): The helpers below currently don't match the Java
35 // definitions. We need to change the AIDL and framework code to comply with the
36 // new definition and Parcel format provided here.
37 
WriteAdvertiseDataToParcel(const AdvertiseData & data,Parcel * parcel)38 void WriteAdvertiseDataToParcel(const AdvertiseData& data, Parcel* parcel) {
39   CHECK(parcel);
40   parcel->writeByteVector(data.data());
41   parcel->writeInt32(data.include_device_name());
42   parcel->writeInt32(data.include_tx_power_level());
43 }
44 
CreateAdvertiseDataFromParcel(const Parcel & parcel)45 std::unique_ptr<AdvertiseData> CreateAdvertiseDataFromParcel(
46     const Parcel& parcel) {
47   std::unique_ptr<std::vector<uint8_t>> data;
48   parcel.readByteVector(&data);
49   CHECK(data.get());
50 
51   bool include_device_name = parcel.readInt32();
52   bool include_tx_power = parcel.readInt32();
53 
54   std::unique_ptr<AdvertiseData> adv(new AdvertiseData(*data));
55   adv->set_include_device_name(include_device_name);
56   adv->set_include_tx_power_level(include_tx_power);
57 
58   return adv;
59 }
60 
WriteAdvertiseSettingsToParcel(const AdvertiseSettings & settings,Parcel * parcel)61 void WriteAdvertiseSettingsToParcel(const AdvertiseSettings& settings,
62                                     Parcel* parcel) {
63   CHECK(parcel);
64   parcel->writeInt32(settings.mode());
65   parcel->writeInt32(settings.tx_power_level());
66   parcel->writeInt32(settings.connectable());
67   parcel->writeInt64(settings.timeout().InMilliseconds());
68 }
69 
CreateAdvertiseSettingsFromParcel(const Parcel & parcel)70 std::unique_ptr<AdvertiseSettings> CreateAdvertiseSettingsFromParcel(
71     const Parcel& parcel) {
72   AdvertiseSettings::Mode mode =
73       static_cast<AdvertiseSettings::Mode>(parcel.readInt32());
74   AdvertiseSettings::TxPowerLevel tx_power =
75       static_cast<AdvertiseSettings::TxPowerLevel>(parcel.readInt32());
76   bool connectable = parcel.readInt32();
77   base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
78       parcel.readInt64());
79 
80   return std::unique_ptr<AdvertiseSettings>(
81       new AdvertiseSettings(mode, timeout, tx_power, connectable));
82 }
83 
WriteUUIDToParcel(const UUID & uuid,android::Parcel * parcel)84 void WriteUUIDToParcel(const UUID& uuid, android::Parcel* parcel) {
85   // The scheme used by android.os.ParcelUuid is to wrote the most significant
86   // bits first as one 64-bit integer, followed by the least significant bits in
87   // a second 64-bit integer. This is the same as writing the raw-bytes in
88   // sequence, but we don't want to assume any host-endianness here. So follow
89   // the same scheme and use the same Parcel APIs.
90   UUID::UUID128Bit bytes = uuid.GetFullBigEndian();
91 
92   uint64_t most_sig_bits =
93       ((((uint64_t) bytes[0]) << 56) |
94        (((uint64_t) bytes[1]) << 48) |
95        (((uint64_t) bytes[2]) << 40) |
96        (((uint64_t) bytes[3]) << 32) |
97        (((uint64_t) bytes[4]) << 24) |
98        (((uint64_t) bytes[5]) << 16) |
99        (((uint64_t) bytes[6]) << 8) |
100        bytes[7]);
101 
102   uint64_t least_sig_bits =
103       ((((uint64_t) bytes[8]) << 56) |
104        (((uint64_t) bytes[9]) << 48) |
105        (((uint64_t) bytes[10]) << 40) |
106        (((uint64_t) bytes[11]) << 32) |
107        (((uint64_t) bytes[12]) << 24) |
108        (((uint64_t) bytes[13]) << 16) |
109        (((uint64_t) bytes[14]) << 8) |
110        bytes[15]);
111 
112   parcel->writeUint64(most_sig_bits);
113   parcel->writeUint64(least_sig_bits);
114 }
115 
CreateUUIDFromParcel(const android::Parcel & parcel)116 std::unique_ptr<UUID> CreateUUIDFromParcel(
117     const android::Parcel& parcel) {
118   UUID::UUID128Bit bytes;
119 
120   uint64_t most_sig_bits = parcel.readUint64();
121   uint64_t least_sig_bits = parcel.readUint64();
122 
123   bytes[0] = (most_sig_bits >> 56) & 0xFF;
124   bytes[1] = (most_sig_bits >> 48) & 0xFF;
125   bytes[2] = (most_sig_bits >> 40) & 0xFF;
126   bytes[3] = (most_sig_bits >> 32) & 0xFF;
127   bytes[4] = (most_sig_bits >> 24) & 0xFF;
128   bytes[5] = (most_sig_bits >> 16) & 0xFF;
129   bytes[6] = (most_sig_bits >> 8) & 0xFF;
130   bytes[7] = most_sig_bits & 0xFF;
131 
132   bytes[8] = (least_sig_bits >> 56) & 0xFF;
133   bytes[9] = (least_sig_bits >> 48) & 0xFF;
134   bytes[10] = (least_sig_bits >> 40) & 0xFF;
135   bytes[11] = (least_sig_bits >> 32) & 0xFF;
136   bytes[12] = (least_sig_bits >> 24) & 0xFF;
137   bytes[13] = (least_sig_bits >> 16) & 0xFF;
138   bytes[14] = (least_sig_bits >> 8) & 0xFF;
139   bytes[15] = least_sig_bits & 0xFF;
140 
141   return std::unique_ptr<UUID>(new UUID(bytes));
142 }
143 
WriteGattIdentifierToParcel(const GattIdentifier & gatt_id,android::Parcel * parcel)144 void WriteGattIdentifierToParcel(
145     const GattIdentifier& gatt_id,
146     android::Parcel* parcel) {
147   parcel->writeCString(gatt_id.device_address().c_str());
148   parcel->writeInt32(gatt_id.is_primary());
149 
150   WriteUUIDToParcel(gatt_id.service_uuid(), parcel);
151   WriteUUIDToParcel(gatt_id.characteristic_uuid(), parcel);
152   WriteUUIDToParcel(gatt_id.descriptor_uuid(), parcel);
153 
154   parcel->writeInt32(gatt_id.service_instance_id());
155   parcel->writeInt32(gatt_id.characteristic_instance_id());
156   parcel->writeInt32(gatt_id.descriptor_instance_id());
157 }
158 
CreateGattIdentifierFromParcel(const android::Parcel & parcel)159 std::unique_ptr<GattIdentifier> CreateGattIdentifierFromParcel(
160     const android::Parcel& parcel) {
161   std::string device_address = parcel.readCString();
162   bool is_primary = parcel.readInt32();
163 
164   auto service_uuid = CreateUUIDFromParcel(parcel);
165   auto char_uuid = CreateUUIDFromParcel(parcel);
166   auto desc_uuid = CreateUUIDFromParcel(parcel);
167 
168   int service_id = parcel.readInt32();
169   int char_id = parcel.readInt32();
170   int desc_id = parcel.readInt32();
171 
172   return std::unique_ptr<GattIdentifier>(
173       new GattIdentifier(
174           device_address, is_primary,
175           *service_uuid, *char_uuid, *desc_uuid,
176           service_id, char_id, desc_id));
177 }
178 
WriteScanFilterToParcel(const ScanFilter & filter,android::Parcel * parcel)179 void WriteScanFilterToParcel(
180     const ScanFilter& filter,
181     android::Parcel* parcel) {
182   bool has_name = !filter.device_name().empty();
183   parcel->writeInt32(has_name ? 1 : 0);
184   if (has_name)
185     parcel->writeCString(filter.device_name().c_str());
186 
187   bool has_address = !filter.device_address().empty();
188   parcel->writeInt32(has_address ? 1 : 0);
189   if (has_address)
190     parcel->writeCString(filter.device_address().c_str());
191 
192   parcel->writeInt32(filter.service_uuid() ? 1 : 0);
193   if (filter.service_uuid()) {
194     WriteUUIDToParcel(*filter.service_uuid(), parcel);
195     parcel->writeInt32(filter.service_uuid_mask() ? 1 : 0);
196     if (filter.service_uuid_mask())
197       WriteUUIDToParcel(*filter.service_uuid_mask(), parcel);
198   }
199 
200   // TODO(armansito): Support service and manufacturer data.
201 }
202 
CreateScanFilterFromParcel(const android::Parcel & parcel)203 std::unique_ptr<ScanFilter> CreateScanFilterFromParcel(
204     const android::Parcel& parcel) {
205   std::string device_name;
206   if (parcel.readInt32() == 1)
207     device_name = parcel.readCString();
208 
209   std::string device_address;
210   if (parcel.readInt32() == 1)
211     device_address = parcel.readCString();
212 
213   std::unique_ptr<UUID> service_uuid, service_uuid_mask;
214   if (parcel.readInt32() == 1) {
215     service_uuid = CreateUUIDFromParcel(parcel);
216     if (parcel.readInt32() == 1)
217       service_uuid_mask = CreateUUIDFromParcel(parcel);
218   }
219 
220   // TODO(armansito): Support service and manufacturer data.
221 
222   std::unique_ptr<ScanFilter> filter(new ScanFilter());
223 
224   filter->set_device_name(device_name);
225 
226   if (!filter->SetDeviceAddress(device_address))
227     return nullptr;
228 
229   if (!service_uuid)
230     return filter;
231 
232   if (service_uuid_mask)
233     filter->SetServiceUuidWithMask(*service_uuid, *service_uuid_mask);
234   else
235     filter->SetServiceUuid(*service_uuid);
236 
237   return filter;
238 }
239 
WriteScanSettingsToParcel(const ScanSettings & settings,android::Parcel * parcel)240 void WriteScanSettingsToParcel(
241     const ScanSettings& settings,
242     android::Parcel* parcel) {
243   parcel->writeInt32(settings.mode());
244   parcel->writeInt32(settings.callback_type());
245   parcel->writeInt32(settings.result_type());
246   parcel->writeInt64(settings.report_delay().InMilliseconds());
247   parcel->writeInt32(settings.match_mode());
248   parcel->writeInt32(settings.match_count_per_filter());
249 }
250 
CreateScanSettingsFromParcel(const android::Parcel & parcel)251 std::unique_ptr<ScanSettings> CreateScanSettingsFromParcel(
252     const android::Parcel& parcel) {
253   ScanSettings::Mode mode =
254       static_cast<ScanSettings::Mode>(parcel.readInt32());
255   ScanSettings::CallbackType callback_type =
256       static_cast<ScanSettings::CallbackType>(parcel.readInt32());
257   ScanSettings::ResultType result_type =
258       static_cast<ScanSettings::ResultType>(parcel.readInt32());
259   base::TimeDelta report_delay = base::TimeDelta::FromMilliseconds(
260       parcel.readInt64());
261   ScanSettings::MatchMode match_mode =
262       static_cast<ScanSettings::MatchMode>(parcel.readInt32());
263   ScanSettings::MatchCount match_count_per_filter =
264       static_cast<ScanSettings::MatchCount>(parcel.readInt32());
265 
266   return std::unique_ptr<ScanSettings>(new ScanSettings(
267       mode, callback_type, result_type, report_delay,
268       match_mode, match_count_per_filter));
269 }
270 
WriteScanResultToParcel(const bluetooth::ScanResult & scan_result,android::Parcel * parcel)271 void WriteScanResultToParcel(
272     const bluetooth::ScanResult& scan_result,
273     android::Parcel* parcel) {
274   // The Java framework code conditionally inserts 1 or 0 to indicate if the
275   // device adress and the scan record fields are present, based on whether the
276   // Java object is null. We do something similar here for consistency, although
277   // the native definition of ScanResult requires a valid BD_ADDR.
278   if (util::IsAddressValid(scan_result.device_address())) {
279     parcel->writeInt32(1);
280     parcel->writeCString(scan_result.device_address().c_str());
281   } else {
282     parcel->writeInt32(0);
283   }
284 
285   parcel->writeByteVector(scan_result.scan_record());
286   parcel->writeInt32(scan_result.rssi());
287 }
288 
CreateScanResultFromParcel(const android::Parcel & parcel)289 std::unique_ptr<bluetooth::ScanResult> CreateScanResultFromParcel(
290     const android::Parcel& parcel) {
291   std::string device_address;
292   if (parcel.readInt32())
293     device_address = parcel.readCString();
294 
295   std::unique_ptr<std::vector<uint8_t>> scan_record;
296   parcel.readByteVector(&scan_record);
297   CHECK(scan_record.get());
298 
299   int rssi = parcel.readInt32();
300 
301   return std::unique_ptr<ScanResult>(new ScanResult(
302       device_address, *scan_record, rssi));
303 }
304 }  // namespace binder
305 }  // namespace ipc
306