Home | History | Annotate | Download | only in binder
      1 //
      2 //  Copyright 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/ipc/binder/bluetooth_low_energy_binder_server.h"
     18 
     19 #include <base/logging.h>
     20 
     21 #include "service/adapter.h"
     22 
     23 using android::String8;
     24 using android::String16;
     25 using android::binder::Status;
     26 
     27 namespace ipc {
     28 namespace binder {
     29 
     30 namespace {
     31 const int kInvalidInstanceId = -1;
     32 }  // namespace
     33 
     34 BluetoothLowEnergyBinderServer::BluetoothLowEnergyBinderServer(
     35     bluetooth::Adapter* adapter)
     36     : adapter_(adapter) {
     37   CHECK(adapter_);
     38 }
     39 
     40 BluetoothLowEnergyBinderServer::~BluetoothLowEnergyBinderServer() {}
     41 
     42 Status BluetoothLowEnergyBinderServer::RegisterClient(
     43     const android::sp<IBluetoothLowEnergyCallback>& callback,
     44     bool* _aidl_return) {
     45   VLOG(2) << __func__;
     46   bluetooth::LowEnergyClientFactory* ble_factory =
     47       adapter_->GetLowEnergyClientFactory();
     48 
     49   *_aidl_return = RegisterInstanceBase(callback, ble_factory);
     50   return Status::ok();
     51 }
     52 
     53 Status BluetoothLowEnergyBinderServer::UnregisterClient(int client_id) {
     54   VLOG(2) << __func__;
     55   UnregisterInstanceBase(client_id);
     56   return Status::ok();
     57 }
     58 
     59 Status BluetoothLowEnergyBinderServer::UnregisterAll() {
     60   VLOG(2) << __func__;
     61   UnregisterAllBase();
     62   return Status::ok();
     63 }
     64 
     65 Status BluetoothLowEnergyBinderServer::Connect(int client_id,
     66                                                const String16& address,
     67                                                bool is_direct,
     68                                                bool* _aidl_return) {
     69   VLOG(2) << __func__ << " client_id: " << client_id << " address: " << address
     70           << " is_direct: " << is_direct;
     71   std::lock_guard<std::mutex> lock(*maps_lock());
     72 
     73   auto client = GetLEClient(client_id);
     74   if (!client) {
     75     LOG(ERROR) << "Unknown client_id: " << client_id;
     76     *_aidl_return = false;
     77     return Status::ok();
     78   }
     79 
     80   *_aidl_return =
     81       client->Connect(std::string(String8(address).string()), is_direct);
     82   return Status::ok();
     83 }
     84 
     85 Status BluetoothLowEnergyBinderServer::Disconnect(int client_id,
     86                                                   const String16& address,
     87                                                   bool* _aidl_return) {
     88   VLOG(2) << __func__ << " client_id: " << client_id << " address: " << address;
     89   std::lock_guard<std::mutex> lock(*maps_lock());
     90 
     91   auto client = GetLEClient(client_id);
     92   if (!client) {
     93     LOG(ERROR) << "Unknown client_id: " << client_id;
     94     *_aidl_return = false;
     95     return Status::ok();
     96   }
     97 
     98   *_aidl_return = client->Disconnect(std::string(String8(address).string()));
     99   return Status::ok();
    100 }
    101 
    102 Status BluetoothLowEnergyBinderServer::SetMtu(int client_id,
    103                                               const String16& address, int mtu,
    104                                               bool* _aidl_return) {
    105   VLOG(2) << __func__ << " client_id: " << client_id << " address: " << address
    106           << " mtu: " << mtu;
    107   std::lock_guard<std::mutex> lock(*maps_lock());
    108 
    109   auto client = GetLEClient(client_id);
    110   if (!client) {
    111     LOG(ERROR) << "Unknown client_id: " << client_id;
    112     *_aidl_return = false;
    113     return Status::ok();
    114   }
    115 
    116   *_aidl_return = client->SetMtu(std::string(String8(address).string()), mtu);
    117   return Status::ok();
    118 }
    119 
    120 void BluetoothLowEnergyBinderServer::OnConnectionState(
    121     bluetooth::LowEnergyClient* client, int status, const char* address,
    122     bool connected) {
    123   VLOG(2) << __func__ << " address: " << address << " connected: " << connected;
    124 
    125   int client_id = client->GetInstanceId();
    126   auto cb = GetLECallback(client->GetInstanceId());
    127   if (!cb.get()) {
    128     VLOG(2) << "Client was unregistered - client_id: " << client_id;
    129     return;
    130   }
    131 
    132   cb->OnConnectionState(status, client_id,
    133                         String16(address, std::strlen(address)), connected);
    134 }
    135 
    136 void BluetoothLowEnergyBinderServer::OnMtuChanged(
    137     bluetooth::LowEnergyClient* client, int status, const char* address,
    138     int mtu) {
    139   VLOG(2) << __func__ << " address: " << address << " status: " << status
    140           << " mtu: " << mtu;
    141 
    142   int client_id = client->GetInstanceId();
    143   auto cb = GetLECallback(client_id);
    144   if (!cb.get()) {
    145     VLOG(2) << "Client was unregistered - client_id: " << client_id;
    146     return;
    147   }
    148 
    149   cb->OnMtuChanged(status, String16(address, std::strlen(address)), mtu);
    150 }
    151 
    152 android::sp<IBluetoothLowEnergyCallback>
    153 BluetoothLowEnergyBinderServer::GetLECallback(int client_id) {
    154   auto cb = GetCallback(client_id);
    155   return android::sp<IBluetoothLowEnergyCallback>(
    156       static_cast<IBluetoothLowEnergyCallback*>(cb.get()));
    157 }
    158 
    159 std::shared_ptr<bluetooth::LowEnergyClient>
    160 BluetoothLowEnergyBinderServer::GetLEClient(int client_id) {
    161   return std::static_pointer_cast<bluetooth::LowEnergyClient>(
    162       GetInstance(client_id));
    163 }
    164 
    165 void BluetoothLowEnergyBinderServer::OnRegisterInstanceImpl(
    166     bluetooth::BLEStatus status, android::sp<IInterface> callback,
    167     bluetooth::BluetoothInstance* instance) {
    168   VLOG(1) << __func__ << " status: " << status;
    169   bluetooth::LowEnergyClient* le_client =
    170       static_cast<bluetooth::LowEnergyClient*>(instance);
    171   le_client->SetDelegate(this);
    172 
    173   android::sp<IBluetoothLowEnergyCallback> cb(
    174       static_cast<IBluetoothLowEnergyCallback*>(callback.get()));
    175   cb->OnClientRegistered(status, (status == bluetooth::BLE_STATUS_SUCCESS)
    176                                      ? instance->GetInstanceId()
    177                                      : kInvalidInstanceId);
    178 }
    179 
    180 }  // namespace binder
    181 }  // namespace ipc
    182