// // Copyright 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_gatt_server_binder_server.h" #include #include "service/adapter.h" using ::android::String8; using ::android::String16; using ::android::binder::Status; using ::android::bluetooth::IBluetoothGattServerCallback; namespace ipc { namespace binder { namespace { const int kInvalidInstanceId = -1; } // namespace BluetoothGattServerBinderServer::BluetoothGattServerBinderServer( bluetooth::Adapter* adapter) : adapter_(adapter) { CHECK(adapter_); } Status BluetoothGattServerBinderServer::RegisterServer( const ::android::sp& callback, bool* _aidl_return) { VLOG(2) << __func__; bluetooth::GattServerFactory* gatt_server_factory = adapter_->GetGattServerFactory(); *_aidl_return = RegisterInstanceBase(callback, gatt_server_factory); return Status::ok(); } Status BluetoothGattServerBinderServer::UnregisterServer(int server_id) { VLOG(2) << __func__; UnregisterInstanceBase(server_id); return Status::ok(); } Status BluetoothGattServerBinderServer::UnregisterAll() { VLOG(2) << __func__; UnregisterAllBase(); return Status::ok(); } Status BluetoothGattServerBinderServer::AddService( int server_id, const android::bluetooth::BluetoothGattService& service, bool* _aidl_return) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_server = GetGattServer(server_id); if (!gatt_server) { LOG(ERROR) << "Unknown server_id: " << server_id; *_aidl_return = false; return Status::ok(); } // Create a weak pointer and pass that to the callback to prevent a potential // use after free. android::wp weak_ptr_to_this(this); auto callback = [=](bluetooth::BLEStatus status, const bluetooth::Service& service) { auto sp_to_this = weak_ptr_to_this.promote(); if (!sp_to_this.get()) { VLOG(2) << "BluetoothLowEnergyBinderServer was deleted"; return; } std::lock_guard lock(*maps_lock()); auto gatt_cb = GetGattServerCallback(server_id); if (!gatt_cb.get()) { VLOG(2) << "The callback was deleted"; return; } gatt_cb->OnServiceAdded(status, service); }; if (!gatt_server->AddService(service, callback)) { LOG(ERROR) << "Failed to add service"; *_aidl_return = false; return Status::ok(); } *_aidl_return = true; return Status::ok(); } Status BluetoothGattServerBinderServer::SendResponse( int server_id, const String16& device_address, int request_id, int status, int offset, const std::vector& value, bool* _aidl_return) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_server = GetGattServer(server_id); if (!gatt_server) { LOG(ERROR) << "Unknown server_id: " << server_id; *_aidl_return = false; return Status::ok(); } *_aidl_return = gatt_server->SendResponse( std::string(String8(device_address).string()), request_id, static_cast(status), offset, value); return Status::ok(); } Status BluetoothGattServerBinderServer::SendNotification( int server_id, const String16& device_address, int handle, bool confirm, const std::vector& value, bool* _aidl_return) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_server = GetGattServer(server_id); if (!gatt_server) { LOG(ERROR) << "Unknown server_id: " << server_id; *_aidl_return = false; return Status::ok(); } // Create a weak pointer and pass that to the callback to prevent a potential // use after free. android::wp weak_ptr_to_this(this); auto callback = [=](bluetooth::GATTError error) { auto sp_to_this = weak_ptr_to_this.promote(); if (!sp_to_this.get()) { VLOG(2) << "BluetoothLowEnergyBinderServer was deleted"; return; } std::lock_guard lock(*maps_lock()); auto gatt_cb = GetGattServerCallback(server_id); if (!gatt_cb.get()) { VLOG(2) << "The callback was deleted"; return; } gatt_cb->OnNotificationSent(device_address, error); }; if (!gatt_server->SendNotification( std::string(String8(device_address).string()), handle, confirm, value, callback)) { LOG(ERROR) << "Failed to send notification"; *_aidl_return = false; return Status::ok(); } *_aidl_return = true; return Status::ok(); } void BluetoothGattServerBinderServer::OnCharacteristicReadRequest( bluetooth::GattServer* gatt_server, const std::string& device_address, int request_id, int offset, bool is_long, uint16_t handle) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_cb = GetGattServerCallback(gatt_server->GetInstanceId()); if (!gatt_cb.get()) { LOG(WARNING) << "Callback for this GattServer was deleted."; return; } gatt_cb->OnCharacteristicReadRequest( String16(device_address.c_str(), device_address.length()), request_id, offset, is_long, handle); } void BluetoothGattServerBinderServer::OnDescriptorReadRequest( bluetooth::GattServer* gatt_server, const std::string& device_address, int request_id, int offset, bool is_long, uint16_t handle) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_cb = GetGattServerCallback(gatt_server->GetInstanceId()); if (!gatt_cb.get()) { LOG(WARNING) << "Callback for this GattServer was deleted."; return; } gatt_cb->OnDescriptorReadRequest( String16(device_address.c_str(), device_address.length()), request_id, offset, is_long, handle); } android::sp BluetoothGattServerBinderServer::GetGattServerCallback(int server_id) { auto cb = GetCallback(server_id); return android::sp( static_cast(cb.get())); } std::shared_ptr BluetoothGattServerBinderServer::GetGattServer(int server_id) { return std::static_pointer_cast( GetInstance(server_id)); } void BluetoothGattServerBinderServer::OnRegisterInstanceImpl( bluetooth::BLEStatus status, android::sp callback, bluetooth::BluetoothInstance* instance) { VLOG(1) << __func__ << " instance ID: " << instance->GetInstanceId() << " status: " << status; bluetooth::GattServer* gatt_server = static_cast(instance); gatt_server->SetDelegate(this); android::sp cb( static_cast(callback.get())); cb->OnServerRegistered(status, (status == bluetooth::BLE_STATUS_SUCCESS) ? instance->GetInstanceId() : kInvalidInstanceId); } void BluetoothGattServerBinderServer::OnCharacteristicWriteRequest( bluetooth::GattServer* gatt_server, const std::string& device_address, int request_id, int offset, bool is_prepare_write, bool need_response, const std::vector& value, uint16_t handle) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_cb = GetGattServerCallback(gatt_server->GetInstanceId()); if (!gatt_cb.get()) { LOG(WARNING) << "Callback for this GattServer was deleted."; return; } gatt_cb->OnCharacteristicWriteRequest( String16(device_address.c_str(), device_address.length()), request_id, offset, is_prepare_write, need_response, value, handle); } void BluetoothGattServerBinderServer::OnDescriptorWriteRequest( bluetooth::GattServer* gatt_server, const std::string& device_address, int request_id, int offset, bool is_prepare_write, bool need_response, const std::vector& value, uint16_t handle) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_cb = GetGattServerCallback(gatt_server->GetInstanceId()); if (!gatt_cb.get()) { LOG(WARNING) << "Callback for this GattServer was deleted."; return; } gatt_cb->OnDescriptorWriteRequest( String16(device_address.c_str(), device_address.length()), request_id, offset, is_prepare_write, need_response, value, handle); } void BluetoothGattServerBinderServer::OnExecuteWriteRequest( bluetooth::GattServer* gatt_server, const std::string& device_address, int request_id, bool is_execute) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_cb = GetGattServerCallback(gatt_server->GetInstanceId()); if (!gatt_cb.get()) { LOG(WARNING) << "Callback for this GattServer was deleted."; return; } gatt_cb->OnExecuteWriteRequest( String16(device_address.c_str(), device_address.length()), request_id, is_execute); } void BluetoothGattServerBinderServer::OnConnectionStateChanged( bluetooth::GattServer* gatt_server, const std::string& device_address, bool connected) { VLOG(2) << __func__; std::lock_guard lock(*maps_lock()); auto gatt_cb = GetGattServerCallback(gatt_server->GetInstanceId()); if (!gatt_cb.get()) { LOG(WARNING) << "Callback for this GattServer was deleted."; return; } gatt_cb->OnConnectionStateChanged( String16(device_address.c_str(), device_address.length()), connected); } } // namespace binder } // namespace ipc