blob: 4dd020b592a810f593119ebd7cb4eb89f5313276 [file] [log] [blame]
Roshan Pius3c4e8a32016-10-03 14:53:58 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
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 "wifi_chip.h"
18
19#include <android-base/logging.h>
20
21#include "failure_reason_util.h"
22
Roshan Pius35d958c2016-10-06 16:47:38 -070023namespace {
24using android::sp;
25using android::hardware::hidl_vec;
26using android::hardware::hidl_string;
27
28hidl_vec<hidl_string> createHidlVecOfIfaceNames(const std::string& ifname) {
29 std::vector<hidl_string> ifnames;
30 if (!ifname.empty()) {
31 hidl_string hidl_ifname;
32 hidl_ifname = ifname.c_str();
33 ifnames.emplace_back(hidl_ifname);
34 }
35 hidl_vec<hidl_string> hidl_ifnames;
36 hidl_ifnames.setToExternal(ifnames.data(), ifnames.size());
37 return hidl_ifnames;
38}
39
40template <typename Iface>
41void invalidateAndClear(sp<Iface>& iface) {
42 if (iface.get()) {
43 iface->invalidate();
44 iface.clear();
45 }
46}
47} // namepsace
48
Roshan Pius3c4e8a32016-10-03 14:53:58 -070049namespace android {
50namespace hardware {
51namespace wifi {
Roshan Pius79a99752016-10-04 13:03:58 -070052namespace V1_0 {
53namespace implementation {
Roshan Pius3c4e8a32016-10-03 14:53:58 -070054
Roshan Piuscd566bd2016-10-10 08:03:42 -070055WifiChip::WifiChip(ChipId chip_id,
56 const std::weak_ptr<WifiLegacyHal> legacy_hal)
Roshan Pius35d958c2016-10-06 16:47:38 -070057 : chip_id_(chip_id), legacy_hal_(legacy_hal), is_valid_(true) {}
Roshan Pius3c4e8a32016-10-03 14:53:58 -070058
Roshan Piusaabe5752016-09-29 09:03:59 -070059void WifiChip::invalidate() {
Roshan Pius35d958c2016-10-06 16:47:38 -070060 invalidateAndRemoveAllIfaces();
Roshan Piusaabe5752016-09-29 09:03:59 -070061 legacy_hal_.reset();
Roshan Pius3c4e8a32016-10-03 14:53:58 -070062 callbacks_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -070063 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -070064}
65
Roshan Piuscd566bd2016-10-10 08:03:42 -070066Return<ChipId> WifiChip::getId() {
67 return chip_id_;
68}
69
Roshan Pius3c4e8a32016-10-03 14:53:58 -070070Return<void> WifiChip::registerEventCallback(
Roshan Pius79a99752016-10-04 13:03:58 -070071 const sp<IWifiChipEventCallback>& callback) {
Roshan Pius35d958c2016-10-06 16:47:38 -070072 if (!is_valid_)
Roshan Pius79a99752016-10-04 13:03:58 -070073 return Void();
Roshan Pius3c4e8a32016-10-03 14:53:58 -070074 // TODO(b/31632518): remove the callback when the client is destroyed
Roshan Pius35d958c2016-10-06 16:47:38 -070075 callbacks_.emplace_back(callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -070076 return Void();
77}
78
79Return<void> WifiChip::getAvailableModes(getAvailableModes_cb cb) {
Roshan Pius35d958c2016-10-06 16:47:38 -070080 if (!is_valid_) {
Roshan Pius3c4e8a32016-10-03 14:53:58 -070081 cb(hidl_vec<ChipMode>());
82 return Void();
83 } else {
84 // TODO add implementation
85 return Void();
86 }
87}
88
89Return<void> WifiChip::configureChip(uint32_t /*mode_id*/) {
Roshan Pius35d958c2016-10-06 16:47:38 -070090 if (!is_valid_)
Roshan Pius79a99752016-10-04 13:03:58 -070091 return Void();
Roshan Pius35d958c2016-10-06 16:47:38 -070092
93 invalidateAndRemoveAllIfaces();
Roshan Pius3c4e8a32016-10-03 14:53:58 -070094 // TODO add implementation
95 return Void();
96}
97
98Return<uint32_t> WifiChip::getMode() {
Roshan Pius35d958c2016-10-06 16:47:38 -070099 if (!is_valid_)
Roshan Pius79a99752016-10-04 13:03:58 -0700100 return 0;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700101 // TODO add implementation
102 return 0;
103}
104
105Return<void> WifiChip::requestChipDebugInfo() {
Roshan Pius35d958c2016-10-06 16:47:38 -0700106 if (!is_valid_)
Roshan Pius79a99752016-10-04 13:03:58 -0700107 return Void();
Roshan Pius4b26c832016-10-03 12:49:58 -0700108
109 IWifiChipEventCallback::ChipDebugInfo result;
110
111 std::pair<wifi_error, std::string> ret =
Roshan Piusab5c4712016-10-06 14:37:15 -0700112 legacy_hal_.lock()->getDriverVersion();
Roshan Pius4b26c832016-10-03 12:49:58 -0700113 if (ret.first != WIFI_SUCCESS) {
114 LOG(ERROR) << "Failed to get driver version: "
115 << LegacyErrorToString(ret.first);
Roshan Piusf2436312016-10-07 09:21:42 -0700116 FailureReason reason = CreateFailureReasonLegacyError(
117 ret.first, " failed to get driver version");
118 for (const auto& callback : callbacks_) {
119 callback->onChipDebugInfoFailure(reason);
120 }
Roshan Pius4b26c832016-10-03 12:49:58 -0700121 return Void();
122 }
123 result.driverDescription = ret.second.c_str();
124
Roshan Piusab5c4712016-10-06 14:37:15 -0700125 ret = legacy_hal_.lock()->getFirmwareVersion();
Roshan Pius4b26c832016-10-03 12:49:58 -0700126 if (ret.first != WIFI_SUCCESS) {
127 LOG(ERROR) << "Failed to get firmware version: "
128 << LegacyErrorToString(ret.first);
Roshan Piusf2436312016-10-07 09:21:42 -0700129 FailureReason reason = CreateFailureReasonLegacyError(
130 ret.first, " failed to get firmware version");
131 for (const auto& callback : callbacks_) {
132 callback->onChipDebugInfoFailure(reason);
133 }
Roshan Pius4b26c832016-10-03 12:49:58 -0700134 return Void();
135 }
136 result.firmwareDescription = ret.second.c_str();
137
138 for (const auto& callback : callbacks_) {
139 callback->onChipDebugInfoAvailable(result);
140 }
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700141 return Void();
142}
143
144Return<void> WifiChip::requestDriverDebugDump() {
Roshan Pius35d958c2016-10-06 16:47:38 -0700145 if (!is_valid_)
Roshan Piuscdb77f32016-10-03 14:09:57 -0700146 return Void();
147
148 std::pair<wifi_error, std::vector<char>> ret =
Roshan Piusab5c4712016-10-06 14:37:15 -0700149 legacy_hal_.lock()->requestDriverMemoryDump();
Roshan Piuscdb77f32016-10-03 14:09:57 -0700150 if (ret.first != WIFI_SUCCESS) {
151 LOG(ERROR) << "Failed to get driver debug dump: "
152 << LegacyErrorToString(ret.first);
Roshan Piusf2436312016-10-07 09:21:42 -0700153 FailureReason reason = CreateFailureReasonLegacyError(ret.first, "");
154 for (const auto& callback : callbacks_) {
155 callback->onDriverDebugDumpFailure(reason);
156 }
Roshan Piuscdb77f32016-10-03 14:09:57 -0700157 return Void();
158 }
159
160 auto& driver_dump = ret.second;
161 hidl_vec<uint8_t> hidl_data;
162 hidl_data.setToExternal(reinterpret_cast<uint8_t*>(driver_dump.data()),
163 driver_dump.size());
164 for (const auto& callback : callbacks_) {
165 callback->onDriverDebugDumpAvailable(hidl_data);
166 }
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700167 return Void();
168}
169
170Return<void> WifiChip::requestFirmwareDebugDump() {
Roshan Pius35d958c2016-10-06 16:47:38 -0700171 if (!is_valid_)
Roshan Piuscdb77f32016-10-03 14:09:57 -0700172 return Void();
173
174 std::pair<wifi_error, std::vector<char>> ret =
Roshan Piusab5c4712016-10-06 14:37:15 -0700175 legacy_hal_.lock()->requestFirmwareMemoryDump();
Roshan Piuscdb77f32016-10-03 14:09:57 -0700176 if (ret.first != WIFI_SUCCESS) {
177 LOG(ERROR) << "Failed to get firmware debug dump: "
178 << LegacyErrorToString(ret.first);
Roshan Piusf2436312016-10-07 09:21:42 -0700179 FailureReason reason = CreateFailureReasonLegacyError(ret.first, "");
180 for (const auto& callback : callbacks_) {
181 callback->onFirmwareDebugDumpFailure(reason);
182 }
Roshan Piuscdb77f32016-10-03 14:09:57 -0700183 return Void();
184 }
185
186 auto& firmware_dump = ret.second;
187 hidl_vec<uint8_t> hidl_data;
188 hidl_data.setToExternal(reinterpret_cast<uint8_t*>(firmware_dump.data()),
189 firmware_dump.size());
190 for (const auto& callback : callbacks_) {
191 callback->onFirmwareDebugDumpAvailable(hidl_data);
192 }
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700193 return Void();
194}
195
Roshan Pius35d958c2016-10-06 16:47:38 -0700196Return<void> WifiChip::createApIface(createApIface_cb cb) {
197 if (!is_valid_) {
198 cb(nullptr);
199 return Void();
200 }
201
202 // TODO(b/31997422): Disallow this based on the chip combination.
203 std::string ifname = legacy_hal_.lock()->getApIfaceName();
204 ap_iface_ = new WifiApIface(ifname, legacy_hal_);
205 cb(ap_iface_);
206 return Void();
207}
208
209Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb cb) {
210 if (!is_valid_) {
211 cb(hidl_vec<hidl_string>());
212 return Void();
213 }
214
215 std::string ifname;
216 if (ap_iface_.get()) {
217 ifname = legacy_hal_.lock()->getApIfaceName().c_str();
218 }
219 cb(createHidlVecOfIfaceNames(ifname));
220 return Void();
221}
222
223Return<void> WifiChip::getApIface(const hidl_string& ifname, getApIface_cb cb) {
224 if (!is_valid_) {
225 cb(nullptr);
226 return Void();
227 }
228
229 if (ap_iface_.get() &&
230 (ifname.c_str() == legacy_hal_.lock()->getApIfaceName())) {
231 cb(ap_iface_);
232 } else {
233 cb(nullptr);
234 }
235 return Void();
236}
237
238Return<void> WifiChip::createNanIface(createNanIface_cb cb) {
239 if (!is_valid_) {
240 cb(nullptr);
241 return Void();
242 }
243
244 // TODO(b/31997422): Disallow this based on the chip combination.
245 std::string ifname = legacy_hal_.lock()->getNanIfaceName();
246 nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
247 cb(nan_iface_);
248 return Void();
249}
250
251Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb cb) {
252 if (!is_valid_) {
253 cb(hidl_vec<hidl_string>());
254 return Void();
255 }
256
257 std::string ifname;
258 if (nan_iface_.get()) {
259 ifname = legacy_hal_.lock()->getNanIfaceName().c_str();
260 }
261 cb(createHidlVecOfIfaceNames(ifname));
262 return Void();
263}
264
265Return<void> WifiChip::getNanIface(const hidl_string& ifname,
266 getNanIface_cb cb) {
267 if (!is_valid_) {
268 cb(nullptr);
269 return Void();
270 }
271
272 if (nan_iface_.get() &&
273 (ifname.c_str() == legacy_hal_.lock()->getNanIfaceName())) {
274 cb(nan_iface_);
275 } else {
276 cb(nullptr);
277 }
278 return Void();
279}
280
281Return<void> WifiChip::createP2pIface(createP2pIface_cb cb) {
282 if (!is_valid_) {
283 cb(nullptr);
284 return Void();
285 }
286
287 // TODO(b/31997422): Disallow this based on the chip combination.
288 std::string ifname = legacy_hal_.lock()->getP2pIfaceName();
289 p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
290 cb(p2p_iface_);
291 return Void();
292}
293
294Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb cb) {
295 if (!is_valid_) {
296 cb(hidl_vec<hidl_string>());
297 return Void();
298 }
299
300 std::string ifname;
301 if (p2p_iface_.get()) {
302 ifname = legacy_hal_.lock()->getP2pIfaceName().c_str();
303 }
304 cb(createHidlVecOfIfaceNames(ifname));
305 return Void();
306}
307
308Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
309 getP2pIface_cb cb) {
310 if (!is_valid_) {
311 cb(nullptr);
312 return Void();
313 }
314
315 if (p2p_iface_.get() &&
316 (ifname.c_str() == legacy_hal_.lock()->getP2pIfaceName())) {
317 cb(p2p_iface_);
318 } else {
319 cb(nullptr);
320 }
321 return Void();
322}
323
324Return<void> WifiChip::createStaIface(createStaIface_cb cb) {
325 if (!is_valid_) {
326 cb(nullptr);
327 return Void();
328 }
329
330 // TODO(b/31997422): Disallow this based on the chip combination.
331 std::string ifname = legacy_hal_.lock()->getStaIfaceName();
332 sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
333 cb(sta_iface_);
334 return Void();
335}
336
337Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb cb) {
338 if (!is_valid_) {
339 cb(hidl_vec<hidl_string>());
340 return Void();
341 }
342
343 std::string ifname;
344 if (sta_iface_.get()) {
345 ifname = legacy_hal_.lock()->getStaIfaceName().c_str();
346 }
347 cb(createHidlVecOfIfaceNames(ifname));
348 return Void();
349}
350
351Return<void> WifiChip::getStaIface(const hidl_string& ifname,
352 getStaIface_cb cb) {
353 if (!is_valid_) {
354 cb(nullptr);
355 return Void();
356 }
357
358 if (sta_iface_.get() &&
359 (ifname.c_str() == legacy_hal_.lock()->getStaIfaceName())) {
360 cb(sta_iface_);
361 } else {
362 cb(nullptr);
363 }
364 return Void();
365}
366
Roshan Pius59268282016-10-06 20:23:47 -0700367Return<void> WifiChip::createRttController(const sp<IWifiIface>& bound_iface,
368 createRttController_cb cb) {
369 if (!is_valid_) {
370 cb(nullptr);
371 return Void();
372 }
373
374 sp<WifiRttController> rtt = new WifiRttController(bound_iface, legacy_hal_);
375 rtt_controllers_.emplace_back(rtt);
376 cb(rtt);
377 return Void();
378}
379
Roshan Pius35d958c2016-10-06 16:47:38 -0700380void WifiChip::invalidateAndRemoveAllIfaces() {
381 invalidateAndClear(ap_iface_);
382 invalidateAndClear(nan_iface_);
383 invalidateAndClear(p2p_iface_);
384 invalidateAndClear(sta_iface_);
Roshan Pius59268282016-10-06 20:23:47 -0700385 // Since all the ifaces are invalid now, all RTT controller objects
386 // using those ifaces also need to be invalidated.
387 for (const auto& rtt : rtt_controllers_) {
388 rtt->invalidate();
389 }
390 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700391}
392
Roshan Pius79a99752016-10-04 13:03:58 -0700393} // namespace implementation
394} // namespace V1_0
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700395} // namespace wifi
396} // namespace hardware
397} // namespace android