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 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 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 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 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 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 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 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 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 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 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 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 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 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 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