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