// // Copyright (C) 2015 Google, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "service/ipc/binder/bluetooth_low_energy_binder_server.h" #include <base/logging.h> #include "service/adapter.h" using android::String8; using android::String16; using android::binder::Status; namespace ipc { namespace binder { namespace { const int kInvalidInstanceId = -1; } // namespace BluetoothLowEnergyBinderServer::BluetoothLowEnergyBinderServer( bluetooth::Adapter* adapter) : adapter_(adapter) { CHECK(adapter_); } BluetoothLowEnergyBinderServer::~BluetoothLowEnergyBinderServer() {} Status BluetoothLowEnergyBinderServer::RegisterClient( const android::sp<IBluetoothLowEnergyCallback>& callback, bool* _aidl_return) { VLOG(2) << __func__; bluetooth::LowEnergyClientFactory* ble_factory = adapter_->GetLowEnergyClientFactory(); *_aidl_return = RegisterInstanceBase(callback, ble_factory); return Status::ok(); } Status BluetoothLowEnergyBinderServer::UnregisterClient(int client_id) { VLOG(2) << __func__; UnregisterInstanceBase(client_id); return Status::ok(); } Status BluetoothLowEnergyBinderServer::UnregisterAll() { VLOG(2) << __func__; UnregisterAllBase(); return Status::ok(); } Status BluetoothLowEnergyBinderServer::Connect(int client_id, const String16& address, bool is_direct, bool* _aidl_return) { VLOG(2) << __func__ << " client_id: " << client_id << " address: " << address << " is_direct: " << is_direct; std::lock_guard<std::mutex> lock(*maps_lock()); auto client = GetLEClient(client_id); if (!client) { LOG(ERROR) << "Unknown client_id: " << client_id; *_aidl_return = false; return Status::ok(); } *_aidl_return = client->Connect(std::string(String8(address).string()), is_direct); return Status::ok(); } Status BluetoothLowEnergyBinderServer::Disconnect(int client_id, const String16& address, bool* _aidl_return) { VLOG(2) << __func__ << " client_id: " << client_id << " address: " << address; std::lock_guard<std::mutex> lock(*maps_lock()); auto client = GetLEClient(client_id); if (!client) { LOG(ERROR) << "Unknown client_id: " << client_id; *_aidl_return = false; return Status::ok(); } *_aidl_return = client->Disconnect(std::string(String8(address).string())); return Status::ok(); } Status BluetoothLowEnergyBinderServer::SetMtu(int client_id, const String16& address, int mtu, bool* _aidl_return) { VLOG(2) << __func__ << " client_id: " << client_id << " address: " << address << " mtu: " << mtu; std::lock_guard<std::mutex> lock(*maps_lock()); auto client = GetLEClient(client_id); if (!client) { LOG(ERROR) << "Unknown client_id: " << client_id; *_aidl_return = false; return Status::ok(); } *_aidl_return = client->SetMtu(std::string(String8(address).string()), mtu); return Status::ok(); } void BluetoothLowEnergyBinderServer::OnConnectionState( bluetooth::LowEnergyClient* client, int status, const char* address, bool connected) { VLOG(2) << __func__ << " address: " << address << " connected: " << connected; int client_id = client->GetInstanceId(); auto cb = GetLECallback(client->GetInstanceId()); if (!cb.get()) { VLOG(2) << "Client was unregistered - client_id: " << client_id; return; } cb->OnConnectionState(status, client_id, String16(address, std::strlen(address)), connected); } void BluetoothLowEnergyBinderServer::OnMtuChanged( bluetooth::LowEnergyClient* client, int status, const char* address, int mtu) { VLOG(2) << __func__ << " address: " << address << " status: " << status << " mtu: " << mtu; int client_id = client->GetInstanceId(); auto cb = GetLECallback(client_id); if (!cb.get()) { VLOG(2) << "Client was unregistered - client_id: " << client_id; return; } cb->OnMtuChanged(status, String16(address, std::strlen(address)), mtu); } android::sp<IBluetoothLowEnergyCallback> BluetoothLowEnergyBinderServer::GetLECallback(int client_id) { auto cb = GetCallback(client_id); return android::sp<IBluetoothLowEnergyCallback>( static_cast<IBluetoothLowEnergyCallback*>(cb.get())); } std::shared_ptr<bluetooth::LowEnergyClient> BluetoothLowEnergyBinderServer::GetLEClient(int client_id) { return std::static_pointer_cast<bluetooth::LowEnergyClient>( GetInstance(client_id)); } void BluetoothLowEnergyBinderServer::OnRegisterInstanceImpl( bluetooth::BLEStatus status, android::sp<IInterface> callback, bluetooth::BluetoothInstance* instance) { VLOG(1) << __func__ << " status: " << status; bluetooth::LowEnergyClient* le_client = static_cast<bluetooth::LowEnergyClient*>(instance); le_client->SetDelegate(this); android::sp<IBluetoothLowEnergyCallback> cb( static_cast<IBluetoothLowEnergyCallback*>(callback.get())); cb->OnClientRegistered(status, (status == bluetooth::BLE_STATUS_SUCCESS) ? instance->GetInstanceId() : kInvalidInstanceId); } } // namespace binder } // namespace ipc