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/ipc/binder/bluetooth_low_energy_binder_server.h" 18 19#include <base/logging.h> 20 21#include "service/adapter.h" 22 23using android::String8; 24using android::String16; 25using android::binder::Status; 26 27namespace ipc { 28namespace binder { 29 30namespace { 31const int kInvalidInstanceId = -1; 32} // namespace 33 34BluetoothLowEnergyBinderServer::BluetoothLowEnergyBinderServer( 35 bluetooth::Adapter* adapter) 36 : adapter_(adapter) { 37 CHECK(adapter_); 38} 39 40BluetoothLowEnergyBinderServer::~BluetoothLowEnergyBinderServer() {} 41 42Status 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 53Status BluetoothLowEnergyBinderServer::UnregisterClient(int client_id) { 54 VLOG(2) << __func__; 55 UnregisterInstanceBase(client_id); 56 return Status::ok(); 57} 58 59Status BluetoothLowEnergyBinderServer::UnregisterAll() { 60 VLOG(2) << __func__; 61 UnregisterAllBase(); 62 return Status::ok(); 63} 64 65Status 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 85Status 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 102Status 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 120void 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 136void 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 152android::sp<IBluetoothLowEnergyCallback> 153BluetoothLowEnergyBinderServer::GetLECallback(int client_id) { 154 auto cb = GetCallback(client_id); 155 return android::sp<IBluetoothLowEnergyCallback>( 156 static_cast<IBluetoothLowEnergyCallback*>(cb.get())); 157} 158 159std::shared_ptr<bluetooth::LowEnergyClient> 160BluetoothLowEnergyBinderServer::GetLEClient(int client_id) { 161 return std::static_pointer_cast<bluetooth::LowEnergyClient>( 162 GetInstance(client_id)); 163} 164 165void 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