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 
BluetoothLowEnergyBinderServer(bluetooth::Adapter * adapter)34 BluetoothLowEnergyBinderServer::BluetoothLowEnergyBinderServer(
35     bluetooth::Adapter* adapter)
36     : adapter_(adapter) {
37   CHECK(adapter_);
38 }
39 
~BluetoothLowEnergyBinderServer()40 BluetoothLowEnergyBinderServer::~BluetoothLowEnergyBinderServer() {}
41 
RegisterClient(const android::sp<IBluetoothLowEnergyCallback> & callback,bool * _aidl_return)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 
UnregisterClient(int client_id)53 Status BluetoothLowEnergyBinderServer::UnregisterClient(int client_id) {
54   VLOG(2) << __func__;
55   UnregisterInstanceBase(client_id);
56   return Status::ok();
57 }
58 
UnregisterAll()59 Status BluetoothLowEnergyBinderServer::UnregisterAll() {
60   VLOG(2) << __func__;
61   UnregisterAllBase();
62   return Status::ok();
63 }
64 
Connect(int client_id,const String16 & address,bool is_direct,bool * _aidl_return)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 
Disconnect(int client_id,const String16 & address,bool * _aidl_return)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 
SetMtu(int client_id,const String16 & address,int mtu,bool * _aidl_return)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 
OnConnectionState(bluetooth::LowEnergyClient * client,int status,const char * address,bool connected)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 
OnMtuChanged(bluetooth::LowEnergyClient * client,int status,const char * address,int mtu)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>
GetLECallback(int client_id)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>
GetLEClient(int client_id)160 BluetoothLowEnergyBinderServer::GetLEClient(int client_id) {
161   return std::static_pointer_cast<bluetooth::LowEnergyClient>(
162       GetInstance(client_id));
163 }
164 
OnRegisterInstanceImpl(bluetooth::BLEStatus status,android::sp<IInterface> callback,bluetooth::BluetoothInstance * instance)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