Home | History | Annotate | Download | only in binder
      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