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