blob: 15b6bfc74f2d343e9b63575e0fbf9e12c7244fe4 [file] [log] [blame]
Roshan Piusaabe5752016-09-29 09:03:59 -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 <array>
18
Roshan Piusaabe5752016-09-29 09:03:59 -070019#include <android-base/logging.h>
20#include <cutils/properties.h>
Roshan Pius908a69a2016-10-03 13:33:23 -070021#include <wifi_system/interface_tool.h>
Roshan Piusaabe5752016-09-29 09:03:59 -070022
Roshan Pius955542e2016-10-28 09:42:44 -070023#include "wifi_legacy_hal.h"
24
25namespace android {
26namespace hardware {
27namespace wifi {
28namespace V1_0 {
29namespace implementation {
30namespace legacy_hal {
Roshan Pius76ff3022016-10-28 10:33:34 -070031// Constants ported over from the legacy HAL calling code
32// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
33// away when this shim layer is replaced by the real vendor
34// implementation.
Roshan Pius511cc492016-10-28 09:54:26 -070035static constexpr uint32_t kMaxVersionStringLength = 256;
Roshan Pius76ff3022016-10-28 10:33:34 -070036static constexpr uint32_t kMaxCachedGscanResults = 64;
37static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
Roshan Pius7cece412016-10-28 10:38:21 -070038static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
Roshan Pius511cc492016-10-28 09:54:26 -070039
Roshan Piusaabe5752016-09-29 09:03:59 -070040// Legacy HAL functions accept "C" style function pointers, so use global
41// functions to pass to the legacy HAL function and store the corresponding
42// std::function methods to be invoked.
43// Callback to be invoked once |stop| is complete.
44std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
45void onStopComplete(wifi_handle handle) {
46 if (on_stop_complete_internal_callback) {
47 on_stop_complete_internal_callback(handle);
48 }
49}
Roshan Piuscdb77f32016-10-03 14:09:57 -070050
51// Callback to be invoked for driver dump.
52std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
53void onDriverMemoryDump(char* buffer, int buffer_size) {
54 if (on_driver_memory_dump_internal_callback) {
55 on_driver_memory_dump_internal_callback(buffer, buffer_size);
56 }
57}
58
59// Callback to be invoked for firmware dump.
60std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
61void onFirmwareMemoryDump(char* buffer, int buffer_size) {
62 if (on_firmware_memory_dump_internal_callback) {
63 on_firmware_memory_dump_internal_callback(buffer, buffer_size);
64 }
65}
Roshan Pius76ff3022016-10-28 10:33:34 -070066
67// Callback to be invoked for Gscan events.
68std::function<void(wifi_request_id, wifi_scan_event)>
69 on_gscan_event_internal_callback;
70void onGscanEvent(wifi_request_id id, wifi_scan_event event) {
71 if (on_gscan_event_internal_callback) {
72 on_gscan_event_internal_callback(id, event);
73 }
74}
75
76// Callback to be invoked for Gscan full results.
77std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
78 on_gscan_full_result_internal_callback;
79void onGscanFullResult(wifi_request_id id,
80 wifi_scan_result* result,
81 uint32_t buckets_scanned) {
82 if (on_gscan_full_result_internal_callback) {
83 on_gscan_full_result_internal_callback(id, result, buckets_scanned);
84 }
85}
86
Roshan Pius7cece412016-10-28 10:38:21 -070087// Callback to be invoked for link layer stats results.
88std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
89 on_link_layer_stats_result_internal_callback;
90void onLinkLayerStatsDataResult(wifi_request_id id,
91 wifi_iface_stat* iface_stat,
92 int num_radios,
93 wifi_radio_stat* radio_stat) {
94 if (on_link_layer_stats_result_internal_callback) {
95 on_link_layer_stats_result_internal_callback(
96 id, iface_stat, num_radios, radio_stat);
97 }
98}
99
Roshan Pius955542e2016-10-28 09:42:44 -0700100// End of the free-standing "C" style callbacks.
Roshan Piusaabe5752016-09-29 09:03:59 -0700101
Roshan Piusaabe5752016-09-29 09:03:59 -0700102WifiLegacyHal::WifiLegacyHal()
103 : global_handle_(nullptr),
104 wlan_interface_handle_(nullptr),
Roshan Pius908a69a2016-10-03 13:33:23 -0700105 awaiting_event_loop_termination_(false) {}
Roshan Piusaabe5752016-09-29 09:03:59 -0700106
107wifi_error WifiLegacyHal::start() {
108 // Ensure that we're starting in a good state.
109 CHECK(!global_handle_ && !wlan_interface_handle_ &&
110 !awaiting_event_loop_termination_);
111
Roshan Pius908a69a2016-10-03 13:33:23 -0700112 android::wifi_system::InterfaceTool if_tool;
Roshan Pius955542e2016-10-28 09:42:44 -0700113 // TODO: Add back the HAL Tool if we need to. All we need from the HAL tool
114 // for now is this function call which we can directly call.
115 wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_);
116 if (status != WIFI_SUCCESS) {
Roshan Pius908a69a2016-10-03 13:33:23 -0700117 LOG(ERROR) << "Failed to initialize legacy hal function table";
118 return WIFI_ERROR_UNKNOWN;
119 }
120 if (!if_tool.SetWifiUpState(true)) {
121 LOG(ERROR) << "Failed to set WiFi interface up";
122 return WIFI_ERROR_UNKNOWN;
123 }
124
Roshan Piusaabe5752016-09-29 09:03:59 -0700125 LOG(INFO) << "Starting legacy HAL";
Roshan Pius955542e2016-10-28 09:42:44 -0700126 status = global_func_table_.wifi_initialize(&global_handle_);
Roshan Piusaabe5752016-09-29 09:03:59 -0700127 if (status != WIFI_SUCCESS || !global_handle_) {
128 LOG(ERROR) << "Failed to retrieve global handle";
129 return status;
130 }
131 event_loop_thread_ = std::thread(&WifiLegacyHal::runEventLoop, this);
132 status = retrieveWlanInterfaceHandle();
133 if (status != WIFI_SUCCESS || !wlan_interface_handle_) {
134 LOG(ERROR) << "Failed to retrieve wlan interface handle";
135 return status;
136 }
137 LOG(VERBOSE) << "Legacy HAL start complete";
138 return WIFI_SUCCESS;
139}
140
141wifi_error WifiLegacyHal::stop(
142 const std::function<void()>& on_stop_complete_user_callback) {
143 LOG(INFO) << "Stopping legacy HAL";
144 on_stop_complete_internal_callback = [&](wifi_handle handle) {
145 CHECK_EQ(global_handle_, handle) << "Handle mismatch";
146 on_stop_complete_user_callback();
Roshan Pius511cc492016-10-28 09:54:26 -0700147 // Invalidate all the internal pointers now that the HAL is
148 // stopped.
149 invalidate();
Roshan Piusaabe5752016-09-29 09:03:59 -0700150 };
151 awaiting_event_loop_termination_ = true;
152 global_func_table_.wifi_cleanup(global_handle_, onStopComplete);
153 LOG(VERBOSE) << "Legacy HAL stop initiated";
154 return WIFI_SUCCESS;
155}
156
Roshan Piusab5c4712016-10-06 14:37:15 -0700157std::string WifiLegacyHal::getApIfaceName() {
158 // Fake name. This interface does not exist in legacy HAL
159 // API's.
160 return "ap0";
161}
162
163std::string WifiLegacyHal::getNanIfaceName() {
164 // Fake name. This interface does not exist in legacy HAL
165 // API's.
166 return "nan0";
167}
168
169std::string WifiLegacyHal::getP2pIfaceName() {
170 std::array<char, PROPERTY_VALUE_MAX> buffer;
171 property_get("wifi.direct.interface", buffer.data(), "p2p0");
172 return buffer.data();
173}
174
175std::string WifiLegacyHal::getStaIfaceName() {
176 std::array<char, PROPERTY_VALUE_MAX> buffer;
177 property_get("wifi.interface", buffer.data(), "wlan0");
178 return buffer.data();
179}
180
181std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion() {
Roshan Pius4b26c832016-10-03 12:49:58 -0700182 std::array<char, kMaxVersionStringLength> buffer;
183 buffer.fill(0);
184 wifi_error status = global_func_table_.wifi_get_driver_version(
185 wlan_interface_handle_, buffer.data(), buffer.size());
Roshan Pius0a47c182016-10-28 10:23:00 -0700186 return {status, buffer.data()};
Roshan Pius4b26c832016-10-03 12:49:58 -0700187}
188
Roshan Piusab5c4712016-10-06 14:37:15 -0700189std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion() {
Roshan Pius4b26c832016-10-03 12:49:58 -0700190 std::array<char, kMaxVersionStringLength> buffer;
191 buffer.fill(0);
192 wifi_error status = global_func_table_.wifi_get_firmware_version(
193 wlan_interface_handle_, buffer.data(), buffer.size());
Roshan Pius0a47c182016-10-28 10:23:00 -0700194 return {status, buffer.data()};
Roshan Pius4b26c832016-10-03 12:49:58 -0700195}
196
Roshan Pius3c868522016-10-27 12:43:49 -0700197std::pair<wifi_error, std::vector<uint8_t>>
Roshan Piusab5c4712016-10-06 14:37:15 -0700198WifiLegacyHal::requestDriverMemoryDump() {
Roshan Pius3c868522016-10-27 12:43:49 -0700199 std::vector<uint8_t> driver_dump;
Roshan Piuscdb77f32016-10-03 14:09:57 -0700200 on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer,
201 int buffer_size) {
Roshan Pius3c868522016-10-27 12:43:49 -0700202 driver_dump.insert(driver_dump.end(),
203 reinterpret_cast<uint8_t*>(buffer),
204 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
Roshan Piuscdb77f32016-10-03 14:09:57 -0700205 };
206 wifi_error status = global_func_table_.wifi_get_driver_memory_dump(
207 wlan_interface_handle_, {onDriverMemoryDump});
208 on_driver_memory_dump_internal_callback = nullptr;
Roshan Pius0a47c182016-10-28 10:23:00 -0700209 return {status, std::move(driver_dump)};
Roshan Piuscdb77f32016-10-03 14:09:57 -0700210}
211
Roshan Pius3c868522016-10-27 12:43:49 -0700212std::pair<wifi_error, std::vector<uint8_t>>
Roshan Piusab5c4712016-10-06 14:37:15 -0700213WifiLegacyHal::requestFirmwareMemoryDump() {
Roshan Pius3c868522016-10-27 12:43:49 -0700214 std::vector<uint8_t> firmware_dump;
Roshan Piuscdb77f32016-10-03 14:09:57 -0700215 on_firmware_memory_dump_internal_callback = [&firmware_dump](
216 char* buffer, int buffer_size) {
Roshan Pius3c868522016-10-27 12:43:49 -0700217 firmware_dump.insert(firmware_dump.end(),
218 reinterpret_cast<uint8_t*>(buffer),
219 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
Roshan Piuscdb77f32016-10-03 14:09:57 -0700220 };
221 wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
222 wlan_interface_handle_, {onFirmwareMemoryDump});
223 on_firmware_memory_dump_internal_callback = nullptr;
Roshan Pius0a47c182016-10-28 10:23:00 -0700224 return {status, std::move(firmware_dump)};
225}
226
227std::pair<wifi_error, uint32_t> WifiLegacyHal::getSupportedFeatureSet() {
228 feature_set set;
229 static_assert(sizeof(set) == sizeof(uint32_t),
230 "Some features can not be represented in output");
231 wifi_error status = global_func_table_.wifi_get_supported_feature_set(
232 wlan_interface_handle_, &set);
233 return {status, static_cast<uint32_t>(set)};
234}
235
236std::pair<wifi_error, PacketFilterCapabilities>
237WifiLegacyHal::getPacketFilterCapabilities() {
238 PacketFilterCapabilities caps;
239 wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
240 wlan_interface_handle_, &caps.version, &caps.max_len);
241 return {status, caps};
242}
243
244wifi_error WifiLegacyHal::setPacketFilter(const std::vector<uint8_t>& program) {
245 return global_func_table_.wifi_set_packet_filter(
246 wlan_interface_handle_, program.data(), program.size());
Roshan Piuscdb77f32016-10-03 14:09:57 -0700247}
248
Roshan Pius76ff3022016-10-28 10:33:34 -0700249std::pair<wifi_error, wifi_gscan_capabilities>
250WifiLegacyHal::getGscanCapabilities() {
251 wifi_gscan_capabilities caps;
252 wifi_error status = global_func_table_.wifi_get_gscan_capabilities(
253 wlan_interface_handle_, &caps);
254 return {status, caps};
255}
256
257wifi_error WifiLegacyHal::startGscan(
258 wifi_request_id id,
259 const wifi_scan_cmd_params& params,
260 const std::function<void(wifi_request_id)>& on_failure_user_callback,
261 const on_gscan_results_callback& on_results_user_callback,
262 const on_gscan_full_result_callback& on_full_result_user_callback) {
263 // If there is already an ongoing background scan, reject new scan requests.
264 if (on_gscan_event_internal_callback ||
265 on_gscan_full_result_internal_callback) {
266 return WIFI_ERROR_NOT_AVAILABLE;
267 }
268
269 // This callback will be used to either trigger |on_results_user_callback| or
270 // |on_failure_user_callback|.
271 on_gscan_event_internal_callback =
272 [on_failure_user_callback, on_results_user_callback, this](
273 wifi_request_id id, wifi_scan_event event) {
274 switch (event) {
275 case WIFI_SCAN_RESULTS_AVAILABLE:
276 case WIFI_SCAN_THRESHOLD_NUM_SCANS:
277 case WIFI_SCAN_THRESHOLD_PERCENT: {
278 wifi_error status;
279 std::vector<wifi_cached_scan_results> cached_scan_results;
280 std::tie(status, cached_scan_results) = getGscanCachedResults();
281 if (status == WIFI_SUCCESS) {
282 on_results_user_callback(id, cached_scan_results);
283 return;
284 }
285 }
286 // Fall through if failed. Failure to retrieve cached scan results
287 // should trigger a background scan failure.
288 case WIFI_SCAN_FAILED:
289 on_failure_user_callback(id);
290 on_gscan_event_internal_callback = nullptr;
291 on_gscan_full_result_internal_callback = nullptr;
292 return;
293 }
294 LOG(FATAL) << "Unexpected gscan event received: " << event;
295 };
296
297 on_gscan_full_result_internal_callback = [on_full_result_user_callback](
298 wifi_request_id id, wifi_scan_result* result, uint32_t buckets_scanned) {
299 if (result) {
300 on_full_result_user_callback(id, result, buckets_scanned);
301 }
302 };
303
304 wifi_scan_result_handler handler = {onGscanFullResult, onGscanEvent};
305 wifi_error status = global_func_table_.wifi_start_gscan(
306 id, wlan_interface_handle_, params, handler);
307 if (status != WIFI_SUCCESS) {
308 on_gscan_event_internal_callback = nullptr;
309 on_gscan_full_result_internal_callback = nullptr;
310 }
311 return status;
312}
313
314wifi_error WifiLegacyHal::stopGscan(wifi_request_id id) {
315 // If there is no an ongoing background scan, reject stop requests.
316 // TODO(b/32337212): This needs to be handled by the HIDL object because we
317 // need to return the NOT_STARTED error code.
318 if (!on_gscan_event_internal_callback &&
319 !on_gscan_full_result_internal_callback) {
320 return WIFI_ERROR_NOT_AVAILABLE;
321 }
322 wifi_error status =
323 global_func_table_.wifi_stop_gscan(id, wlan_interface_handle_);
324 // If the request Id is wrong, don't stop the ongoing background scan. Any
325 // other error should be treated as the end of background scan.
326 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
327 on_gscan_event_internal_callback = nullptr;
328 on_gscan_full_result_internal_callback = nullptr;
329 }
330 return status;
331}
332
333std::pair<wifi_error, std::vector<uint32_t>>
334WifiLegacyHal::getValidFrequenciesForGscan(wifi_band band) {
335 static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
336 "Wifi Channel cannot be represented in output");
337 std::vector<uint32_t> freqs;
338 freqs.resize(kMaxGscanFrequenciesForBand);
339 int32_t num_freqs = 0;
340 wifi_error status = global_func_table_.wifi_get_valid_channels(
341 wlan_interface_handle_,
342 band,
343 freqs.size(),
344 reinterpret_cast<wifi_channel*>(freqs.data()),
345 &num_freqs);
346 CHECK(num_freqs >= 0 &&
347 static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
348 freqs.resize(num_freqs);
349 return {status, std::move(freqs)};
350}
351
Roshan Pius7cece412016-10-28 10:38:21 -0700352wifi_error WifiLegacyHal::enableLinkLayerStats(bool debug) {
353 wifi_link_layer_params params;
354 params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
355 params.aggressive_statistics_gathering = debug;
356 return global_func_table_.wifi_set_link_stats(wlan_interface_handle_, params);
357}
358
359wifi_error WifiLegacyHal::disableLinkLayerStats() {
360 // TODO: Do we care about these responses?
361 uint32_t clear_mask_rsp;
362 uint8_t stop_rsp;
363 return global_func_table_.wifi_clear_link_stats(
364 wlan_interface_handle_, 0xFFFFFFFF, &clear_mask_rsp, 1, &stop_rsp);
365}
366
367std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats() {
368 LinkLayerStats link_stats{};
369 LinkLayerStats* link_stats_ptr = &link_stats;
370
371 on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
372 wifi_request_id /* id */,
373 wifi_iface_stat* iface_stats_ptr,
374 int num_radios,
375 wifi_radio_stat* radio_stats_ptr) {
376 if (iface_stats_ptr != nullptr) {
377 link_stats_ptr->iface = *iface_stats_ptr;
378 link_stats_ptr->iface.num_peers = 0;
379 } else {
380 LOG(ERROR) << "Invalid iface stats in link layer stats";
381 }
382 if (num_radios == 1 && radio_stats_ptr != nullptr) {
383 link_stats_ptr->radio = *radio_stats_ptr;
384 // Copy over the tx level array to the separate vector.
385 if (radio_stats_ptr->num_tx_levels > 0 &&
386 radio_stats_ptr->tx_time_per_levels != nullptr) {
387 link_stats_ptr->radio_tx_time_per_levels.assign(
388 radio_stats_ptr->tx_time_per_levels,
389 radio_stats_ptr->tx_time_per_levels +
390 radio_stats_ptr->num_tx_levels);
391 }
392 link_stats_ptr->radio.num_tx_levels = 0;
393 link_stats_ptr->radio.tx_time_per_levels = nullptr;
394 } else {
395 LOG(ERROR) << "Invalid radio stats in link layer stats";
396 }
397 };
398
399 wifi_error status = global_func_table_.wifi_get_link_stats(
400 0, wlan_interface_handle_, {onLinkLayerStatsDataResult});
401 on_link_layer_stats_result_internal_callback = nullptr;
402 return {status, link_stats};
403}
404
Roshan Piusaabe5752016-09-29 09:03:59 -0700405wifi_error WifiLegacyHal::retrieveWlanInterfaceHandle() {
Roshan Piusab5c4712016-10-06 14:37:15 -0700406 const std::string& ifname_to_find = getStaIfaceName();
Roshan Piusaabe5752016-09-29 09:03:59 -0700407 wifi_interface_handle* iface_handles = nullptr;
408 int num_iface_handles = 0;
409 wifi_error status = global_func_table_.wifi_get_ifaces(
410 global_handle_, &num_iface_handles, &iface_handles);
411 if (status != WIFI_SUCCESS) {
Roshan Pius511cc492016-10-28 09:54:26 -0700412 LOG(ERROR) << "Failed to enumerate interface handles";
Roshan Piusaabe5752016-09-29 09:03:59 -0700413 return status;
414 }
415 for (int i = 0; i < num_iface_handles; ++i) {
416 std::array<char, IFNAMSIZ> current_ifname;
417 current_ifname.fill(0);
418 status = global_func_table_.wifi_get_iface_name(
419 iface_handles[i], current_ifname.data(), current_ifname.size());
420 if (status != WIFI_SUCCESS) {
Roshan Pius511cc492016-10-28 09:54:26 -0700421 LOG(WARNING) << "Failed to get interface handle name";
Roshan Piusaabe5752016-09-29 09:03:59 -0700422 continue;
423 }
424 if (ifname_to_find == current_ifname.data()) {
425 wlan_interface_handle_ = iface_handles[i];
426 return WIFI_SUCCESS;
427 }
428 }
429 return WIFI_ERROR_UNKNOWN;
430}
431
432void WifiLegacyHal::runEventLoop() {
433 LOG(VERBOSE) << "Starting legacy HAL event loop";
434 global_func_table_.wifi_event_loop(global_handle_);
435 if (!awaiting_event_loop_termination_) {
436 LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
437 }
438 LOG(VERBOSE) << "Legacy HAL event loop terminated";
439 awaiting_event_loop_termination_ = false;
Roshan Pius908a69a2016-10-03 13:33:23 -0700440 android::wifi_system::InterfaceTool if_tool;
441 if_tool.SetWifiUpState(false);
Roshan Piusaabe5752016-09-29 09:03:59 -0700442}
443
Roshan Pius76ff3022016-10-28 10:33:34 -0700444std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
445WifiLegacyHal::getGscanCachedResults() {
446 std::vector<wifi_cached_scan_results> cached_scan_results;
447 cached_scan_results.resize(kMaxCachedGscanResults);
448 int32_t num_results = 0;
449 wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
450 wlan_interface_handle_,
451 true /* always flush */,
452 cached_scan_results.size(),
453 cached_scan_results.data(),
454 &num_results);
455 CHECK(num_results >= 0 &&
456 static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
457 cached_scan_results.resize(num_results);
458 // Check for invalid IE lengths in these cached scan results and correct it.
459 for (auto& cached_scan_result : cached_scan_results) {
460 int num_scan_results = cached_scan_result.num_results;
461 for (int i = 0; i < num_scan_results; i++) {
462 auto& scan_result = cached_scan_result.results[i];
463 if (scan_result.ie_length > 0) {
464 LOG(ERROR) << "Cached scan result has non-zero IE length "
465 << scan_result.ie_length;
466 scan_result.ie_length = 0;
467 }
468 }
469 }
470 return {status, std::move(cached_scan_results)};
471}
472
Roshan Pius511cc492016-10-28 09:54:26 -0700473void WifiLegacyHal::invalidate() {
474 global_handle_ = nullptr;
475 wlan_interface_handle_ = nullptr;
476 on_stop_complete_internal_callback = nullptr;
477 on_driver_memory_dump_internal_callback = nullptr;
478 on_firmware_memory_dump_internal_callback = nullptr;
Roshan Pius76ff3022016-10-28 10:33:34 -0700479 on_gscan_event_internal_callback = nullptr;
480 on_gscan_full_result_internal_callback = nullptr;
Roshan Pius7cece412016-10-28 10:38:21 -0700481 on_link_layer_stats_result_internal_callback = nullptr;
Roshan Pius511cc492016-10-28 09:54:26 -0700482}
Roshan Pius955542e2016-10-28 09:42:44 -0700483
484} // namespace legacy_hal
Roshan Piusaabe5752016-09-29 09:03:59 -0700485} // namespace implementation
486} // namespace V1_0
487} // namespace wifi
488} // namespace hardware
489} // namespace android