DO NOT MERGE - Merge Android 10 into master
Bug: 139893257
Change-Id: Ic9046fa1839a2aed313702f73f1c809d7879490b
diff --git a/Android.bp b/Android.bp
index 33c8816..d4a928e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -41,7 +41,6 @@
"libhidltransport",
"libminijail",
"libutils",
- "libwifi-system",
"libwifi-system-iface",
],
static_libs: ["libwificond"],
@@ -83,7 +82,6 @@
"libutils",
"libhidlbase",
"libhidltransport",
- "libwifi-system",
"libwifi-system-iface",
],
whole_static_libs: [
@@ -158,6 +156,7 @@
"aidl/android/net/wifi/IInterfaceEventCallback.aidl",
"aidl/android/net/wifi/IPnoScanEvent.aidl",
"aidl/android/net/wifi/IScanEvent.aidl",
+ "aidl/android/net/wifi/ISendMgmtFrameEvent.aidl",
"aidl/android/net/wifi/IWificond.aidl",
"aidl/android/net/wifi/IWifiScannerImpl.aidl",
],
@@ -224,7 +223,6 @@
static_libs: [
"libgmock",
"libgtest",
- "libwifi-system-test",
"libwifi-system-iface-test",
"libwificond",
"libwificond_nl",
@@ -238,7 +236,6 @@
"libhidlbase",
"liblog",
"libutils",
- "libwifi-system",
"libwifi-system-iface",
],
}
@@ -254,7 +251,6 @@
"tests/integration/client_interface_test.cpp",
"tests/integration/life_cycle_test.cpp",
"tests/integration/scanner_test.cpp",
- "tests/integration/service_test.cpp",
"tests/main.cpp",
"tests/shell_unittest.cpp",
],
@@ -263,7 +259,6 @@
"libbinder",
"libcutils",
"libutils",
- "libwifi-system",
"libwifi-system-iface",
],
static_libs: [
diff --git a/aidl/android/net/wifi/IApInterface.aidl b/aidl/android/net/wifi/IApInterface.aidl
index 2d7d6da..b37c068 100644
--- a/aidl/android/net/wifi/IApInterface.aidl
+++ b/aidl/android/net/wifi/IApInterface.aidl
@@ -26,15 +26,11 @@
const int ENCRYPTION_TYPE_WPA = 1;
const int ENCRYPTION_TYPE_WPA2 = 2;
- // Start up an instance of hostapd associated with this interface.
+ // Register a callback object for this interface.
//
// @param callback Object to add a set of event callbacks.
// @return true on success.
- boolean startHostapd(IApInterfaceEventCallback callback);
-
- // Stop a previously started instance of hostapd.
- // @return true on success.
- boolean stopHostapd();
+ boolean registerCallback(IApInterfaceEventCallback callback);
// Retrieve the name of the network interface corresponding to this
// IApInterface instance (e.g. "wlan0")
diff --git a/aidl/android/net/wifi/IClientInterface.aidl b/aidl/android/net/wifi/IClientInterface.aidl
index ed34886..1b8b404 100644
--- a/aidl/android/net/wifi/IClientInterface.aidl
+++ b/aidl/android/net/wifi/IClientInterface.aidl
@@ -16,6 +16,7 @@
package android.net.wifi;
+import android.net.wifi.ISendMgmtFrameEvent;
import android.net.wifi.IWifiScannerImpl;
// IClientInterface represents a network interface that can be used to connect
@@ -32,6 +33,7 @@
// First element in array is the RSSI value in dBM.
// Second element in array is the transmission bit rate in Mbps.
// Third element in array is the association frequency in MHz.
+ // Fourth element in array is the last received packet bit rate in Mbps.
// This call is valid only when interface is associated with an AP, otherwise
// it returns an empty array.
int[] signalPoll();
@@ -51,4 +53,17 @@
// Set the MAC address of this interface
// Returns true if the set was successful
boolean setMacAddress(in byte[] mac);
+
+ // Sends an arbitrary 802.11 management frame on the current channel.
+ // @param frame Bytes of the 802.11 management frame to be sent, including the
+ // header, but not including the frame check sequence (FCS).
+ // @param Callback triggered when the transmitted frame is ACKed or the
+ // transmission fails.
+ // @param mcs MCS rate which the management frame will be sent at. If mcs < 0,
+ // the driver will select the rate automatically. If the device does not
+ // support sending the frame at a specified MCS rate, the transmission
+ // will be aborted and ISendMgmtFrameEvent.OnFailure() will be called with
+ // reason ISendMgmtFrameEvent.SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED.
+ oneway void SendMgmtFrame(
+ in byte[] frame, in ISendMgmtFrameEvent callback, int mcs);
}
diff --git a/aidl/android/net/wifi/ISendMgmtFrameEvent.aidl b/aidl/android/net/wifi/ISendMgmtFrameEvent.aidl
new file mode 100644
index 0000000..3af84aa
--- /dev/null
+++ b/aidl/android/net/wifi/ISendMgmtFrameEvent.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package android.net.wifi;
+
+// A callback to notify the results of sending a management frame.
+interface ISendMgmtFrameEvent {
+ // Error codes for OnFailure():
+
+ // Unknown error.
+ const int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1;
+
+ // Specifying the MCS rate is not supported by this device.
+ const int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2;
+
+ // Driver reported that no ACK was received for the transmitted frame.
+ const int SEND_MGMT_FRAME_ERROR_NO_ACK = 3;
+
+ // Timed out while waiting for a response from the driver about the status
+ // of the transmitted frame.
+ const int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4;
+
+ // An existing transmission is in progress. Another frame cannot be sent until
+ // the first transmission completes.
+ const int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5;
+
+ // Called when the management frame was successfully sent and ACKed by the
+ // recipient.
+ // @param elapsedTimeMs The elapsed time between when the management frame was
+ // sent and when the ACK was processed, in milliseconds, as measured by
+ // wificond. This includes the time that the send frame spent queuing
+ // before it was sent, any firmware retries, and the time the received
+ // ACK spent queuing before it was processed.
+ oneway void OnAck(int elapsedTimeMs);
+
+ // Called when the send failed.
+ // @param reason The error code for the failure.
+ oneway void OnFailure(int reason);
+}
diff --git a/aidl/android/net/wifi/IWificond.aidl b/aidl/android/net/wifi/IWificond.aidl
index 6a6920b..d3a3089 100644
--- a/aidl/android/net/wifi/IWificond.aidl
+++ b/aidl/android/net/wifi/IWificond.aidl
@@ -59,16 +59,6 @@
// Returrns null on failure.
@nullable int[] getAvailableDFSChannels();
- // Enable wpa_supplicant.
- // Returns true if supplicant was successfully enabled,
- // or is already enabled.
- boolean enableSupplicant();
-
- // Disable wpa_supplicant.
- // Returns true if supplicant was successfully disabled,
- // or is already disabled.
- boolean disableSupplicant();
-
// Register a callback to receive interface status updates.
//
// Multiple callbacks can be registered simultaneously.
diff --git a/ap_interface_binder.cpp b/ap_interface_binder.cpp
index 4d6a321..56e779f 100644
--- a/ap_interface_binder.cpp
+++ b/ap_interface_binder.cpp
@@ -17,7 +17,6 @@
#include "wificond/ap_interface_binder.h"
#include <android-base/logging.h>
-#include <wifi_system/hostapd_manager.h>
#include "wificond/ap_interface_impl.h"
@@ -73,48 +72,20 @@
ap_interface_event_callback_->onSoftApChannelSwitched(frequency, bandwidth);
}
-binder::Status ApInterfaceBinder::startHostapd(
+binder::Status ApInterfaceBinder::registerCallback(
const sp<IApInterfaceEventCallback>& callback, bool* out_success) {
- *out_success = false;
- if (!impl_) {
- LOG(WARNING) << "Cannot start hostapd on dead ApInterface.";
- return binder::Status::ok();
- }
- *out_success = impl_->StartHostapd();
- if (*out_success) {
- ap_interface_event_callback_ = callback;
- }
- return binder::Status::ok();
-}
-
-binder::Status ApInterfaceBinder::stopHostapd(bool* out_success) {
- *out_success = false;
- if (!impl_) {
- LOG(WARNING) << "Cannot stop hostapd on dead ApInterface.";
- return binder::Status::ok();
- }
- *out_success = impl_->StopHostapd();
- ap_interface_event_callback_.clear();
+ *out_success = true;
+ ap_interface_event_callback_ = callback;
return binder::Status::ok();
}
binder::Status ApInterfaceBinder::getInterfaceName(std::string* out_name) {
- if (!impl_) {
- LOG(WARNING) << "Cannot get interface name from dead ApInterface";
- return binder::Status::ok();
- }
*out_name = impl_->GetInterfaceName();
return binder::Status::ok();
}
binder::Status ApInterfaceBinder::getNumberOfAssociatedStations(
int* out_num_of_stations) {
- if (!impl_) {
- LOG(WARNING) << "Cannot get number of associated stations "
- << "from dead ApInterface";
- *out_num_of_stations = -1;
- return binder::Status::ok();
- }
*out_num_of_stations = impl_->GetNumberOfAssociatedStations();
return binder::Status::ok();
}
diff --git a/ap_interface_binder.h b/ap_interface_binder.h
index ea1c9d5..7e332f5 100644
--- a/ap_interface_binder.h
+++ b/ap_interface_binder.h
@@ -46,10 +46,9 @@
void NotifySoftApChannelSwitched(int frequency,
ChannelBandwidth channel_bandwidth);
- binder::Status startHostapd(
+ binder::Status registerCallback(
const sp<net::wifi::IApInterfaceEventCallback>& callback,
bool* out_success) override;
- binder::Status stopHostapd(bool* out_success) override;
binder::Status getInterfaceName(std::string* out_name) override;
binder::Status getNumberOfAssociatedStations(
int* out_num_of_stations) override;
diff --git a/ap_interface_impl.cpp b/ap_interface_impl.cpp
index 28cd4f9..f39e9c1 100644
--- a/ap_interface_impl.cpp
+++ b/ap_interface_impl.cpp
@@ -24,12 +24,11 @@
#include "wificond/logging_utils.h"
using android::net::wifi::IApInterface;
-using android::wifi_system::HostapdManager;
using android::wifi_system::InterfaceTool;
+using std::array;
using std::endl;
using std::string;
using std::unique_ptr;
-using std::vector;
using namespace std::placeholders;
@@ -39,13 +38,11 @@
ApInterfaceImpl::ApInterfaceImpl(const string& interface_name,
uint32_t interface_index,
NetlinkUtils* netlink_utils,
- InterfaceTool* if_tool,
- HostapdManager* hostapd_manager)
+ InterfaceTool* if_tool)
: interface_name_(interface_name),
interface_index_(interface_index),
netlink_utils_(netlink_utils),
if_tool_(if_tool),
- hostapd_manager_(hostapd_manager),
binder_(new ApInterfaceBinder(this)),
number_of_associated_stations_(0) {
// This log keeps compiler happy.
@@ -83,38 +80,9 @@
*ss << "------- Dump End -------" << endl;
}
-bool ApInterfaceImpl::StartHostapd() {
- return hostapd_manager_->StartHostapd();
-}
-
-bool ApInterfaceImpl::StopHostapd() {
- // Drop SIGKILL on hostapd.
- if (!hostapd_manager_->StopHostapd()) {
- // Logging was done internally.
- return false;
- }
-
- // Take down the interface.
- if (!if_tool_->SetUpState(interface_name_.c_str(), false)) {
- // Logging was done internally.
- return false;
- }
-
- // Since wificond SIGKILLs hostapd, hostapd has no chance to handle
- // the cleanup.
- // Besides taking down the interface, we also need to set the interface mode
- // back to station mode for the cleanup.
- if (!netlink_utils_->SetInterfaceMode(interface_index_,
- NetlinkUtils::STATION_MODE)) {
- LOG(ERROR) << "Failed to set interface back to station mode";
- return false;
- }
-
- return true;
-}
-
-void ApInterfaceImpl::OnStationEvent(StationEvent event,
- const vector<uint8_t>& mac_address) {
+void ApInterfaceImpl::OnStationEvent(
+ StationEvent event,
+ const array<uint8_t, ETH_ALEN>& mac_address) {
if (event == NEW_STATION) {
LOG(INFO) << "New station "
<< LoggingUtils::GetMacString(mac_address)
diff --git a/ap_interface_impl.h b/ap_interface_impl.h
index 3bbbcef..ab3bac3 100644
--- a/ap_interface_impl.h
+++ b/ap_interface_impl.h
@@ -17,11 +17,12 @@
#ifndef WIFICOND_AP_INTERFACE_IMPL_H_
#define WIFICOND_AP_INTERFACE_IMPL_H_
+#include <array>
#include <string>
-#include <vector>
+
+#include <linux/if_ether.h>
#include <android-base/macros.h>
-#include <wifi_system/hostapd_manager.h>
#include <wifi_system/interface_tool.h>
#include "wificond/net/netlink_manager.h"
@@ -43,15 +44,12 @@
ApInterfaceImpl(const std::string& interface_name,
uint32_t interface_index,
NetlinkUtils* netlink_utils,
- wifi_system::InterfaceTool* if_tool,
- wifi_system::HostapdManager* hostapd_manager);
+ wifi_system::InterfaceTool* if_tool);
~ApInterfaceImpl();
// Get a pointer to the binder representing this ApInterfaceImpl.
android::sp<android::net::wifi::IApInterface> GetBinder() const;
- bool StartHostapd();
- bool StopHostapd();
std::string GetInterfaceName() { return interface_name_; }
int GetNumberOfAssociatedStations() const;
void Dump(std::stringstream* ss) const;
@@ -61,14 +59,13 @@
const uint32_t interface_index_;
NetlinkUtils* const netlink_utils_;
wifi_system::InterfaceTool* const if_tool_;
- wifi_system::HostapdManager* const hostapd_manager_;
const android::sp<ApInterfaceBinder> binder_;
// Number of associated stations.
int number_of_associated_stations_;
void OnStationEvent(StationEvent event,
- const std::vector<uint8_t>& mac_address);
+ const std::array<uint8_t, ETH_ALEN>& mac_address);
void OnChannelSwitchEvent(uint32_t frequency, ChannelBandwidth bandwidth);
diff --git a/client_interface_binder.cpp b/client_interface_binder.cpp
index 5b60844..960be8b 100644
--- a/client_interface_binder.cpp
+++ b/client_interface_binder.cpp
@@ -16,13 +16,19 @@
#include "wificond/client_interface_binder.h"
+#include <algorithm>
#include <vector>
+#include <linux/if_ether.h>
+
+#include <android-base/logging.h>
+
#include <binder/Status.h>
#include "wificond/client_interface_impl.h"
using android::binder::Status;
+using android::net::wifi::ISendMgmtFrameEvent;
using android::net::wifi::IWifiScannerImpl;
using std::vector;
@@ -58,7 +64,8 @@
if (impl_ == nullptr) {
return Status::ok();
}
- *out_mac_address = impl_->GetMacAddress();
+ const std::array<uint8_t, ETH_ALEN>& mac = impl_->GetMacAddress();
+ *out_mac_address = vector<uint8_t>(mac.begin(), mac.end());
return Status::ok();
}
@@ -82,7 +89,29 @@
Status ClientInterfaceBinder::setMacAddress(const vector<uint8_t>& mac, bool* success) {
- *success = impl_ && impl_->SetMacAddress(mac);
+ if (impl_ == nullptr) {
+ *success = false;
+ return Status::ok();
+ }
+ if (mac.size() != ETH_ALEN) {
+ LOG(ERROR) << "Invalid MAC length " << mac.size();
+ *success = false;
+ return Status::ok();
+ }
+ std::array<uint8_t, ETH_ALEN> mac_array;
+ std::copy_n(mac.begin(), ETH_ALEN, mac_array.begin());
+ *success = impl_->SetMacAddress(mac_array);
+ return Status::ok();
+}
+
+Status ClientInterfaceBinder::SendMgmtFrame(const vector<uint8_t>& frame,
+ const sp<ISendMgmtFrameEvent>& callback, int32_t mcs) {
+ if (impl_ == nullptr) {
+ callback->OnFailure(ISendMgmtFrameEvent::SEND_MGMT_FRAME_ERROR_UNKNOWN);
+ return Status::ok();
+ }
+ // TODO (b/112029045) validate mcs
+ impl_->SendMgmtFrame(frame, callback, mcs);
return Status::ok();
}
diff --git a/client_interface_binder.h b/client_interface_binder.h
index ecd5700..b1fceea 100644
--- a/client_interface_binder.h
+++ b/client_interface_binder.h
@@ -21,6 +21,7 @@
#include <binder/Status.h>
#include "android/net/wifi/BnClientInterface.h"
+#include "android/net/wifi/ISendMgmtFrameEvent.h"
namespace android {
namespace wificond {
@@ -48,6 +49,10 @@
::android::sp<::android::net::wifi::IWifiScannerImpl>* out_wifi_scanner_impl) override;
::android::binder::Status setMacAddress(
const ::std::vector<uint8_t>& mac, bool* success) override;
+ ::android::binder::Status SendMgmtFrame(
+ const ::std::vector<uint8_t>& frame,
+ const sp<::android::net::wifi::ISendMgmtFrameEvent>& callback,
+ int32_t mcs) override;
private:
ClientInterfaceImpl* impl_;
diff --git a/client_interface_impl.cpp b/client_interface_impl.cpp
index 2ea6871..60bae8e 100644
--- a/client_interface_impl.cpp
+++ b/client_interface_impl.cpp
@@ -18,9 +18,8 @@
#include <vector>
-#include <linux/if_ether.h>
-
#include <android-base/logging.h>
+#include <utils/Timers.h>
#include "wificond/client_interface_binder.h"
#include "wificond/logging_utils.h"
@@ -32,6 +31,7 @@
#include "wificond/scanning/scanner_impl.h"
using android::net::wifi::IClientInterface;
+using android::net::wifi::ISendMgmtFrameEvent;
using com::android::server::wifi::wificond::NativeScanResult;
using android::sp;
using android::wifi_system::InterfaceTool;
@@ -61,7 +61,7 @@
LOG(INFO) << "Connect timeout";
}
client_interface_->is_associated_ = false;
- client_interface_->bssid_.clear();
+ client_interface_->bssid_.fill(0);
}
}
@@ -81,18 +81,18 @@
LOG(INFO) << "Associate timeout";
}
client_interface_->is_associated_ = false;
- client_interface_->bssid_.clear();
+ client_interface_->bssid_.fill(0);
}
}
void MlmeEventHandlerImpl::OnDisconnect(unique_ptr<MlmeDisconnectEvent> event) {
client_interface_->is_associated_ = false;
- client_interface_->bssid_.clear();
+ client_interface_->bssid_.fill(0);
}
void MlmeEventHandlerImpl::OnDisassociate(unique_ptr<MlmeDisassociateEvent> event) {
client_interface_->is_associated_ = false;
- client_interface_->bssid_.clear();
+ client_interface_->bssid_.fill(0);
}
@@ -100,7 +100,7 @@
uint32_t wiphy_index,
const std::string& interface_name,
uint32_t interface_index,
- const std::vector<uint8_t>& interface_mac_addr,
+ const std::array<uint8_t, ETH_ALEN>& interface_mac_addr,
InterfaceTool* if_tool,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils)
@@ -114,10 +114,25 @@
offload_service_utils_(new OffloadServiceUtils()),
mlme_event_handler_(new MlmeEventHandlerImpl(this)),
binder_(new ClientInterfaceBinder(this)),
- is_associated_(false) {
+ is_associated_(false),
+ frame_tx_in_progress_(false),
+ frame_tx_status_cookie_(0),
+ on_frame_tx_status_event_handler_([](bool was_acked) {}) {
netlink_utils_->SubscribeMlmeEvent(
interface_index_,
mlme_event_handler_.get());
+
+ netlink_utils_->SubscribeFrameTxStatusEvent(
+ interface_index,
+ [this](uint64_t cookie, bool was_acked) {
+ if (frame_tx_in_progress_ && frame_tx_status_cookie_ == cookie) {
+ on_frame_tx_status_event_handler_(was_acked);
+ frame_tx_in_progress_ = false;
+ frame_tx_status_cookie_ = 0;
+ on_frame_tx_status_event_handler_ = [](bool was_acked) {};
+ }
+ });
+
if (!netlink_utils_->GetWiphyInfo(wiphy_index_,
&band_info_,
&scan_capabilities_,
@@ -132,11 +147,15 @@
this,
scan_utils_,
offload_service_utils_);
+ // Need to set the interface up (especially in scan mode since wpa_supplicant
+ // is not started)
+ if_tool_->SetUpState(interface_name_.c_str(), true);
}
ClientInterfaceImpl::~ClientInterfaceImpl() {
binder_->NotifyImplDead();
scanner_->Invalidate();
+ netlink_utils_->UnsubscribeFrameTxStatusEvent(interface_index_);
netlink_utils_->UnsubscribeMlmeEvent(interface_index_);
if_tool_->SetUpState(interface_name_.c_str(), false);
}
@@ -171,6 +190,8 @@
<< wiphy_features_.supports_high_accuracy_oneshot_scan << endl;
*ss << "Device supports random MAC for scheduled scan: "
<< wiphy_features_.supports_random_mac_sched_scan << endl;
+ *ss << "Device supports sending management frames at specified MCS rate: "
+ << wiphy_features_.supports_tx_mgmt_frame_mcs << endl;
*ss << "------- Dump End -------" << endl;
}
@@ -207,25 +228,23 @@
// Association frequency.
out_signal_poll_results->push_back(
static_cast<int32_t>(associate_freq_));
+ // Convert from 100kbit/s to Mbps.
+ out_signal_poll_results->push_back(
+ static_cast<int32_t>(station_info.station_rx_bitrate/10));
return true;
}
-const vector<uint8_t>& ClientInterfaceImpl::GetMacAddress() {
+const std::array<uint8_t, ETH_ALEN>& ClientInterfaceImpl::GetMacAddress() {
return interface_mac_addr_;
}
-bool ClientInterfaceImpl::SetMacAddress(const ::std::vector<uint8_t>& mac) {
- if (mac.size() != ETH_ALEN) {
- LOG(ERROR) << "Invalid MAC length " << mac.size();
- return false;
- }
+bool ClientInterfaceImpl::SetMacAddress(const std::array<uint8_t, ETH_ALEN>& mac) {
if (!if_tool_->SetWifiUpState(false)) {
LOG(ERROR) << "SetWifiUpState(false) failed.";
return false;
}
- if (!if_tool_->SetMacAddress(interface_name_.c_str(),
- {{mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]}})) {
+ if (!if_tool_->SetMacAddress(interface_name_.c_str(), mac)) {
LOG(ERROR) << "SetMacAddress(" << interface_name_ << ", "
<< LoggingUtils::GetMacString(mac) << ") failed.";
return false;
@@ -257,5 +276,36 @@
return is_associated_;
}
+void ClientInterfaceImpl::SendMgmtFrame(const vector<uint8_t>& frame,
+ const sp<ISendMgmtFrameEvent>& callback, int32_t mcs) {
+ if (mcs >= 0 && !wiphy_features_.supports_tx_mgmt_frame_mcs) {
+ callback->OnFailure(
+ ISendMgmtFrameEvent::SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED);
+ return;
+ }
+
+ uint64_t cookie;
+ if (!netlink_utils_->SendMgmtFrame(interface_index_, frame, mcs, &cookie)) {
+ callback->OnFailure(ISendMgmtFrameEvent::SEND_MGMT_FRAME_ERROR_UNKNOWN);
+ return;
+ }
+
+ frame_tx_in_progress_ = true;
+ frame_tx_status_cookie_ = cookie;
+ nsecs_t start_time_ns = systemTime(SYSTEM_TIME_MONOTONIC);
+ on_frame_tx_status_event_handler_ =
+ [callback, start_time_ns](bool was_acked) {
+ if (was_acked) {
+ nsecs_t end_time_ns = systemTime(SYSTEM_TIME_MONOTONIC);
+ int32_t elapsed_time_ms = static_cast<int32_t>(
+ nanoseconds_to_milliseconds(end_time_ns - start_time_ns));
+ callback->OnAck(elapsed_time_ms);
+ } else {
+ callback->OnFailure(
+ ISendMgmtFrameEvent::SEND_MGMT_FRAME_ERROR_NO_ACK);
+ }
+ };
+}
+
} // namespace wificond
} // namespace android
diff --git a/client_interface_impl.h b/client_interface_impl.h
index 63077ec..e07b18b 100644
--- a/client_interface_impl.h
+++ b/client_interface_impl.h
@@ -17,13 +17,17 @@
#ifndef WIFICOND_CLIENT_INTERFACE_IMPL_H_
#define WIFICOND_CLIENT_INTERFACE_IMPL_H_
+#include <array>
#include <string>
+#include <linux/if_ether.h>
+
#include <android-base/macros.h>
#include <utils/StrongPointer.h>
#include <wifi_system/interface_tool.h>
#include "android/net/wifi/IClientInterface.h"
+#include "android/net/wifi/ISendMgmtFrameEvent.h"
#include "wificond/net/mlme_event_handler.h"
#include "wificond/net/netlink_utils.h"
#include "wificond/scanning/offload/offload_service_utils.h"
@@ -62,7 +66,7 @@
uint32_t wiphy_index,
const std::string& interface_name,
uint32_t interface_index,
- const std::vector<uint8_t>& interface_mac_addr,
+ const std::array<uint8_t, ETH_ALEN>& interface_mac_addr,
android::wifi_system::InterfaceTool* if_tool,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils);
@@ -73,12 +77,16 @@
bool GetPacketCounters(std::vector<int32_t>* out_packet_counters);
bool SignalPoll(std::vector<int32_t>* out_signal_poll_results);
- const std::vector<uint8_t>& GetMacAddress();
+ const std::array<uint8_t, ETH_ALEN>& GetMacAddress();
const std::string& GetInterfaceName() const { return interface_name_; }
const android::sp<ScannerImpl> GetScanner() { return scanner_; };
- bool SetMacAddress(const ::std::vector<uint8_t>& mac);
+ bool SetMacAddress(const std::array<uint8_t, ETH_ALEN>& mac);
virtual bool IsAssociated() const;
void Dump(std::stringstream* ss) const;
+ void SendMgmtFrame(
+ const std::vector<uint8_t>& frame,
+ const sp<::android::net::wifi::ISendMgmtFrameEvent>& callback,
+ int32_t mcs);
private:
bool RefreshAssociateFreq();
@@ -86,7 +94,7 @@
const uint32_t wiphy_index_;
const std::string interface_name_;
const uint32_t interface_index_;
- const std::vector<uint8_t> interface_mac_addr_;
+ const std::array<uint8_t, ETH_ALEN> interface_mac_addr_;
android::wifi_system::InterfaceTool* const if_tool_;
NetlinkUtils* const netlink_utils_;
ScanUtils* const scan_utils_;
@@ -97,7 +105,7 @@
// Cached information for this connection.
bool is_associated_;
- std::vector<uint8_t> bssid_;
+ std::array<uint8_t, ETH_ALEN> bssid_;
uint32_t associate_freq_;
// Capability information for this wiphy/interface.
@@ -105,6 +113,11 @@
ScanCapabilities scan_capabilities_;
WiphyFeatures wiphy_features_;
+ // handler for frame tx status messages
+ bool frame_tx_in_progress_;
+ uint64_t frame_tx_status_cookie_;
+ std::function<void(bool was_acked)> on_frame_tx_status_event_handler_;
+
DISALLOW_COPY_AND_ASSIGN(ClientInterfaceImpl);
friend class MlmeEventHandlerImpl;
};
diff --git a/logging_utils.cpp b/logging_utils.cpp
index f717a50..189f0dd 100644
--- a/logging_utils.cpp
+++ b/logging_utils.cpp
@@ -16,19 +16,19 @@
#include "wificond/logging_utils.h"
+#include <array>
#include <iomanip>
-#include <vector>
#include <android-base/macros.h>
+using std::array;
using std::string;
using std::stringstream;
-using std::vector;
namespace android {
namespace wificond {
-string LoggingUtils::GetMacString(const vector<uint8_t>& mac_address) {
+string LoggingUtils::GetMacString(const array<uint8_t, ETH_ALEN>& mac_address) {
stringstream ss;
for (const uint8_t& b : mac_address) {
ss << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(b);
diff --git a/logging_utils.h b/logging_utils.h
index 1176d8a..86592b3 100644
--- a/logging_utils.h
+++ b/logging_utils.h
@@ -17,9 +17,11 @@
#ifndef WIFICOND_LOGGING_UTILS_H_
#define WIFICOND_LOGGING_UTILS_H_
-#include <vector>
+#include <array>
#include <sstream>
+#include <linux/if_ether.h>
+
#include <android-base/macros.h>
#include "wificond/net/netlink_manager.h"
@@ -30,7 +32,7 @@
class LoggingUtils {
public:
LoggingUtils() = default;
- static std::string GetMacString(const std::vector<uint8_t>& mac_address);
+ static std::string GetMacString(const std::array<uint8_t, ETH_ALEN>& mac_address);
static std::string GetBandwidthString(ChannelBandwidth bandwidth);
private:
diff --git a/main.cpp b/main.cpp
index 9928f63..4e8586f 100644
--- a/main.cpp
+++ b/main.cpp
@@ -39,9 +39,7 @@
#include "wificond/server.h"
using android::net::wifi::IWificond;
-using android::wifi_system::HostapdManager;
using android::wifi_system::InterfaceTool;
-using android::wifi_system::SupplicantManager;
using android::wificond::ipc_constants::kServiceName;
using std::unique_ptr;
@@ -144,8 +142,6 @@
unique_ptr<android::wificond::Server> server(new android::wificond::Server(
unique_ptr<InterfaceTool>(new InterfaceTool),
- unique_ptr<SupplicantManager>(new SupplicantManager()),
- unique_ptr<HostapdManager>(new HostapdManager()),
&netlink_utils,
&scan_utils));
RegisterServiceOrCrash(server.get());
diff --git a/net/mlme_event.cpp b/net/mlme_event.cpp
index 2a87a1d..1e58d38 100644
--- a/net/mlme_event.cpp
+++ b/net/mlme_event.cpp
@@ -23,6 +23,7 @@
#include "wificond/net/kernel-header-latest/nl80211.h"
#include "wificond/net/nl80211_packet.h"
+using std::array;
using std::unique_ptr;
using std::vector;
@@ -33,7 +34,7 @@
bool GetCommonFields(const NL80211Packet* packet,
uint32_t* if_index,
- vector<uint8_t>* bssid) {
+ array<uint8_t, ETH_ALEN>* bssid) {
if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, if_index)) {
LOG(ERROR) << "Failed to get NL80211_ATTR_IFINDEX";
return false;
diff --git a/net/mlme_event.h b/net/mlme_event.h
index cc332fc..79d25e3 100644
--- a/net/mlme_event.h
+++ b/net/mlme_event.h
@@ -17,8 +17,10 @@
#ifndef WIFICOND_NET_MLME_EVENT_H_
#define WIFICOND_NET_MLME_EVENT_H_
+#include <array>
#include <memory>
-#include <vector>
+
+#include <linux/if_ether.h>
#include <android-base/macros.h>
@@ -32,7 +34,7 @@
static std::unique_ptr<MlmeConnectEvent> InitFromPacket(
const NL80211Packet* packet);
// Returns the BSSID of the associated AP.
- const std::vector<uint8_t>& GetBSSID() const { return bssid_; }
+ const std::array<uint8_t, ETH_ALEN>& GetBSSID() const { return bssid_; }
// Get the status code of this connect event.
// 0 = success, non-zero = failure.
// Status codes definition: IEEE 802.11-2012, 8.4.1.9, Table 8-37
@@ -44,7 +46,7 @@
MlmeConnectEvent() = default;
uint32_t interface_index_;
- std::vector<uint8_t> bssid_;
+ std::array<uint8_t, ETH_ALEN> bssid_;
uint16_t status_code_;
bool is_timeout_;
@@ -56,7 +58,7 @@
static std::unique_ptr<MlmeAssociateEvent> InitFromPacket(
const NL80211Packet* packet);
// Returns the BSSID of the associated AP.
- const std::vector<uint8_t>& GetBSSID() const { return bssid_; }
+ const std::array<uint8_t, ETH_ALEN>& GetBSSID() const { return bssid_; }
// Get the status code of this associate event.
// 0 = success, non-zero = failure.
// Status codes definition: IEEE 802.11-2012, 8.4.1.9, Table 8-37
@@ -68,7 +70,7 @@
MlmeAssociateEvent() = default;
uint32_t interface_index_;
- std::vector<uint8_t> bssid_;
+ std::array<uint8_t, ETH_ALEN> bssid_;
uint16_t status_code_;
bool is_timeout_;
@@ -80,14 +82,14 @@
static std::unique_ptr<MlmeRoamEvent> InitFromPacket(
const NL80211Packet* packet);
// Returns the BSSID of the associated AP.
- const std::vector<uint8_t>& GetBSSID() const { return bssid_; }
+ const std::array<uint8_t, ETH_ALEN>& GetBSSID() const { return bssid_; }
uint32_t GetInterfaceIndex() const { return interface_index_; }
private:
MlmeRoamEvent() = default;
uint32_t interface_index_;
- std::vector<uint8_t> bssid_;
+ std::array<uint8_t, ETH_ALEN> bssid_;
DISALLOW_COPY_AND_ASSIGN(MlmeRoamEvent);
};
@@ -102,7 +104,7 @@
MlmeDisconnectEvent() = default;
uint32_t interface_index_;
- std::vector<uint8_t> bssid_;
+ std::array<uint8_t, ETH_ALEN> bssid_;
DISALLOW_COPY_AND_ASSIGN(MlmeDisconnectEvent);
};
@@ -116,7 +118,7 @@
MlmeDisassociateEvent() = default;
uint32_t interface_index_;
- std::vector<uint8_t> bssid_;
+ std::array<uint8_t, ETH_ALEN> bssid_;
DISALLOW_COPY_AND_ASSIGN(MlmeDisassociateEvent);
};
diff --git a/net/netlink_manager.cpp b/net/netlink_manager.cpp
index f9c8997..0238f0b 100644
--- a/net/netlink_manager.cpp
+++ b/net/netlink_manager.cpp
@@ -33,6 +33,7 @@
#include "net/nl80211_packet.h"
using android::base::unique_fd;
+using std::array;
using std::placeholders::_1;
using std::string;
using std::unique_ptr;
@@ -534,7 +535,7 @@
}
const auto handler = on_station_event_handler_.find(if_index);
if (handler != on_station_event_handler_.end()) {
- vector<uint8_t> mac_address;
+ array<uint8_t, ETH_ALEN> mac_address;
if (!packet->GetAttributeValue(NL80211_ATTR_MAC, &mac_address)) {
LOG(WARNING) << "Failed to get mac address from station event";
return;
@@ -551,6 +552,10 @@
OnChannelSwitchEvent(std::move(packet));
return;
}
+ if (command == NL80211_CMD_FRAME_TX_STATUS) {
+ OnFrameTxStatusEvent(std::move(packet));
+ return;
+ }
}
void NetlinkManager::OnRegChangeEvent(unique_ptr<const NL80211Packet> packet) {
@@ -727,6 +732,31 @@
}
}
+void NetlinkManager::OnFrameTxStatusEvent(
+ unique_ptr<const NL80211Packet> packet) {
+
+ uint32_t if_index;
+ if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
+ LOG(WARNING) << "Failed to get NL80211_ATTR_IFINDEX"
+ << "from NL80211_CMD_FRAME_TX_STATUS event";
+ return;
+ }
+
+ uint64_t cookie;
+ if (!packet->GetAttributeValue(NL80211_ATTR_COOKIE, &cookie)) {
+ LOG(WARNING) << "Failed to get NL80211_ATTR_COOKIE"
+ << "from NL80211_CMD_FRAME_TX_STATUS event";
+ return;
+ }
+
+ bool was_acked = packet->HasAttribute(NL80211_ATTR_ACK);
+
+ const auto handler = on_frame_tx_status_event_handler_.find(if_index);
+ if (handler != on_frame_tx_status_event_handler_.end()) {
+ handler->second(cookie, was_acked);
+ }
+}
+
void NetlinkManager::SubscribeStationEvent(
uint32_t interface_index,
OnStationEventHandler handler) {
@@ -789,5 +819,14 @@
on_sched_scan_result_ready_handler_.erase(interface_index);
}
+void NetlinkManager::SubscribeFrameTxStatusEvent(
+ uint32_t interface_index, OnFrameTxStatusEventHandler handler) {
+ on_frame_tx_status_event_handler_[interface_index] = handler;
+}
+
+void NetlinkManager::UnsubscribeFrameTxStatusEvent(uint32_t interface_index) {
+ on_frame_tx_status_event_handler_.erase(interface_index);
+}
+
} // namespace wificond
} // namespace android
diff --git a/net/netlink_manager.h b/net/netlink_manager.h
index f8817f4..98db5ae 100644
--- a/net/netlink_manager.h
+++ b/net/netlink_manager.h
@@ -17,10 +17,13 @@
#ifndef WIFICOND_NET_NETLINK_MANAGER_H_
#define WIFICOND_NET_NETLINK_MANAGER_H_
+#include <array>
#include <functional>
#include <map>
#include <memory>
+#include <linux/if_ether.h>
+
#include <android-base/macros.h>
#include <android-base/unique_fd.h>
@@ -113,7 +116,14 @@
// |mac_address| is the station mac address associated with this event.
typedef std::function<void(
StationEvent event,
- const std::vector<uint8_t>& mac_address)> OnStationEventHandler;
+ const std::array<uint8_t, ETH_ALEN>& mac_address)> OnStationEventHandler;
+
+// This describes a type of function handling frame tx status events.
+// |cookie| specifies the cookie of the transmitted frame that this status
+// event corresponds to.
+// |was_acked| reports whether the transmitted frame was ACKed.
+typedef std::function<void(
+ uint64_t cookie, bool was_acked)> OnFrameTxStatusEventHandler;
class NetlinkManager {
public:
@@ -255,6 +265,13 @@
// Cancel the sign-up of receiving channel events.
virtual void UnsubscribeChannelSwitchEvent(uint32_t interface_index);
+ // Sign up to be notified of frame tx status events.
+ virtual void SubscribeFrameTxStatusEvent(
+ uint32_t interface_index, OnFrameTxStatusEventHandler handler);
+
+ // Cancel the sign-up of receiving frame tx status events.
+ virtual void UnsubscribeFrameTxStatusEvent(uint32_t interface_index);
+
private:
bool SetupSocket(android::base::unique_fd* netlink_fd);
bool WatchSocket(android::base::unique_fd* netlink_fd);
@@ -267,6 +284,7 @@
void OnScanResultsReady(std::unique_ptr<const NL80211Packet> packet);
void OnSchedScanResultsReady(std::unique_ptr<const NL80211Packet> packet);
void OnChannelSwitchEvent(std::unique_ptr<const NL80211Packet> packet);
+ void OnFrameTxStatusEvent(std::unique_ptr<const NL80211Packet> packet);
// This handler revceives mapping from NL80211 family name to family id,
// as well as mapping from group name to group id.
@@ -303,6 +321,10 @@
std::map<uint32_t, OnStationEventHandler> on_station_event_handler_;
std::map<uint32_t, OnChannelSwitchEventHandler> on_channel_switch_event_handler_;
+ // mapping from interface_index to frame tx status event handler
+ std::map<uint32_t, OnFrameTxStatusEventHandler>
+ on_frame_tx_status_event_handler_;
+
// Mapping from family name to family id, and group name to group id.
std::map<std::string, MessageType> message_types_;
diff --git a/net/netlink_utils.cpp b/net/netlink_utils.cpp
index b47d542..f395d92 100644
--- a/net/netlink_utils.cpp
+++ b/net/netlink_utils.cpp
@@ -16,6 +16,8 @@
#include "wificond/net/netlink_utils.h"
+#include <array>
+#include <algorithm>
#include <bitset>
#include <map>
#include <string>
@@ -30,6 +32,7 @@
#include "wificond/net/mlme_event_handler.h"
#include "wificond/net/nl80211_packet.h"
+using std::array;
using std::make_pair;
using std::make_unique;
using std::map;
@@ -85,6 +88,11 @@
supports_high_accuracy_oneshot_scan =
IsExtFeatureFlagSet(ext_feature_flags_bytes,
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN);
+ // TODO (b/112029045) check if sending frame at specified MCS is supported
+ supports_tx_mgmt_frame_mcs = false;
+ supports_ext_sched_scan_relative_rssi =
+ IsExtFeatureFlagSet(ext_feature_flags_bytes,
+ NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI);
}
NetlinkUtils::NetlinkUtils(NetlinkManager* netlink_manager)
@@ -208,7 +216,7 @@
continue;
}
- vector<uint8_t> if_mac_addr;
+ array<uint8_t, ETH_ALEN> if_mac_addr;
if (!packet->GetAttributeValue(NL80211_ATTR_MAC, &if_mac_addr)) {
LOG(WARNING) << "Failed to get interface mac address";
continue;
@@ -467,7 +475,7 @@
}
bool NetlinkUtils::GetStationInfo(uint32_t interface_index,
- const vector<uint8_t>& mac_address,
+ const array<uint8_t, ETH_ALEN>& mac_address,
StationInfo* out_station_info) {
NL80211Packet get_station(
netlink_manager_->GetFamilyId(),
@@ -476,8 +484,8 @@
getpid());
get_station.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX,
interface_index));
- get_station.AddAttribute(NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC,
- mac_address));
+ get_station.AddAttribute(NL80211Attr<array<uint8_t, ETH_ALEN>>(
+ NL80211_ATTR_MAC, mac_address));
unique_ptr<const NL80211Packet> response;
if (!netlink_manager_->SendMessageAndGetSingleResponse(get_station,
@@ -510,19 +518,26 @@
return false;
}
NL80211NestedAttr tx_bitrate_attr(0);
- if (!sta_info.GetAttribute(NL80211_STA_INFO_TX_BITRATE,
+ uint32_t tx_bitrate = 0;
+ if (sta_info.GetAttribute(NL80211_STA_INFO_TX_BITRATE,
&tx_bitrate_attr)) {
- LOG(ERROR) << "Failed to get NL80211_STA_INFO_TX_BITRATE";
- return false;
- }
- uint32_t tx_bitrate;
- if (!tx_bitrate_attr.GetAttributeValue(NL80211_RATE_INFO_BITRATE32,
+ if (!tx_bitrate_attr.GetAttributeValue(NL80211_RATE_INFO_BITRATE32,
&tx_bitrate)) {
- LOG(ERROR) << "Failed to get NL80211_RATE_INFO_BITRATE32";
- return false;
+ // Return invalid tx rate to avoid breaking the get station cmd
+ tx_bitrate = 0;
+ }
}
-
- *out_station_info = StationInfo(tx_good, tx_bad, tx_bitrate, current_rssi);
+ NL80211NestedAttr rx_bitrate_attr(0);
+ uint32_t rx_bitrate = 0;
+ if (sta_info.GetAttribute(NL80211_STA_INFO_RX_BITRATE,
+ &rx_bitrate_attr)) {
+ if (!rx_bitrate_attr.GetAttributeValue(NL80211_RATE_INFO_BITRATE32,
+ &rx_bitrate)) {
+ // Return invalid rx rate to avoid breaking the get station cmd
+ rx_bitrate = 0;
+ }
+ }
+ *out_station_info = StationInfo(tx_good, tx_bad, tx_bitrate, current_rssi, rx_bitrate);
return true;
}
@@ -600,6 +615,40 @@
return true;
}
+bool NetlinkUtils::SendMgmtFrame(uint32_t interface_index,
+ const vector<uint8_t>& frame, int32_t mcs, uint64_t* out_cookie) {
+
+ NL80211Packet send_mgmt_frame(
+ netlink_manager_->GetFamilyId(),
+ NL80211_CMD_FRAME,
+ netlink_manager_->GetSequenceNumber(),
+ getpid());
+
+ send_mgmt_frame.AddAttribute(
+ NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, interface_index));
+
+ send_mgmt_frame.AddAttribute(
+ NL80211Attr<vector<uint8_t>>(NL80211_ATTR_FRAME, frame));
+
+ if (mcs >= 0) {
+ // TODO (b/112029045) if mcs >= 0, add MCS attribute
+ }
+
+ unique_ptr<const NL80211Packet> response;
+ if (!netlink_manager_->SendMessageAndGetSingleResponse(
+ send_mgmt_frame, &response)) {
+ LOG(ERROR) << "NL80211_CMD_FRAME failed";
+ return false;
+ }
+
+ if (!response->GetAttributeValue(NL80211_ATTR_COOKIE, out_cookie)) {
+ LOG(ERROR) << "Get NL80211_ATTR_COOKIE failed";
+ return false;
+ }
+
+ return true;
+}
+
void NetlinkUtils::SubscribeMlmeEvent(uint32_t interface_index,
MlmeEventHandler* handler) {
netlink_manager_->SubscribeMlmeEvent(interface_index, handler);
@@ -637,6 +686,14 @@
netlink_manager_->UnsubscribeChannelSwitchEvent(interface_index);
}
+void NetlinkUtils::SubscribeFrameTxStatusEvent(
+ uint32_t interface_index, OnFrameTxStatusEventHandler handler) {
+ netlink_manager_->SubscribeFrameTxStatusEvent(interface_index, handler);
+}
+
+void NetlinkUtils::UnsubscribeFrameTxStatusEvent(uint32_t interface_index) {
+ netlink_manager_->UnsubscribeFrameTxStatusEvent(interface_index);
+}
} // namespace wificond
} // namespace android
diff --git a/net/netlink_utils.h b/net/netlink_utils.h
index 5e840b6..b3c34d3 100644
--- a/net/netlink_utils.h
+++ b/net/netlink_utils.h
@@ -17,9 +17,13 @@
#ifndef WIFICOND_NET_NETLINK_UTILS_H_
#define WIFICOND_NET_NETLINK_UTILS_H_
+#include <array>
+#include <functional>
#include <string>
#include <vector>
+#include <linux/if_ether.h>
+
#include <android-base/macros.h>
#include "wificond/net/kernel-header-latest/nl80211.h"
@@ -30,18 +34,18 @@
struct InterfaceInfo {
InterfaceInfo() = default;
- InterfaceInfo(uint32_t index_,
- const std::string name_,
- const std::vector<uint8_t> mac_address_)
- : index(index_),
- name(name_),
- mac_address(mac_address_) {}
+ InterfaceInfo(uint32_t index,
+ const std::string& name,
+ const std::array<uint8_t, ETH_ALEN>& mac_address)
+ : index(index),
+ name(name),
+ mac_address(mac_address) {}
// Index of this interface.
uint32_t index;
// Name of this interface.
std::string name;
// MAC address of this interface.
- std::vector<uint8_t> mac_address;
+ std::array<uint8_t, ETH_ALEN> mac_address;
};
struct BandInfo {
@@ -96,7 +100,8 @@
supports_random_mac_sched_scan(false),
supports_low_span_oneshot_scan(false),
supports_low_power_oneshot_scan(false),
- supports_high_accuracy_oneshot_scan(false) {}
+ supports_high_accuracy_oneshot_scan(false),
+ supports_tx_mgmt_frame_mcs(false) {}
WiphyFeatures(uint32_t feature_flags,
const std::vector<uint8_t>& ext_feature_flags_bytes);
// This device/driver supports using a random MAC address during scan
@@ -111,6 +116,11 @@
bool supports_low_power_oneshot_scan;
// This device/driver supports performing high-accuracy one-shot scans.
bool supports_high_accuracy_oneshot_scan;
+ // This device/driver supports sending a management frame at a specified MCS.
+ bool supports_tx_mgmt_frame_mcs;
+ // This device/driver supports sched_scan for reporting BSSs
+ // with better RSSI than the current connected BSS
+ bool supports_ext_sched_scan_relative_rssi;
// There are other flags included in NL80211_ATTR_FEATURE_FLAGS.
// We will add them once we find them useful.
};
@@ -120,11 +130,13 @@
StationInfo(uint32_t station_tx_packets_,
uint32_t station_tx_failed_,
uint32_t station_tx_bitrate_,
- int8_t current_rssi_)
+ int8_t current_rssi_,
+ uint32_t station_rx_bitrate_)
: station_tx_packets(station_tx_packets_),
station_tx_failed(station_tx_failed_),
station_tx_bitrate(station_tx_bitrate_),
- current_rssi(current_rssi_) {}
+ current_rssi(current_rssi_),
+ station_rx_bitrate(station_rx_bitrate_) {}
// Number of successfully transmitted packets.
int32_t station_tx_packets;
// Number of tramsmission failures.
@@ -133,6 +145,8 @@
uint32_t station_tx_bitrate;
// Current signal strength.
int8_t current_rssi;
+ // Last Received unicast packet bit rate in 100kbit/s.
+ uint32_t station_rx_bitrate;
// There are many other counters/parameters included in station info.
// We will add them once we find them useful.
};
@@ -186,7 +200,7 @@
// |*out_station_info]| is the struct of available station information.
// Returns true on success.
virtual bool GetStationInfo(uint32_t interface_index,
- const std::vector<uint8_t>& mac_address,
+ const std::array<uint8_t, ETH_ALEN>& mac_address,
StationInfo* out_station_info);
// Get a bitmap for nl80211 protocol features,
@@ -244,6 +258,16 @@
// Cancel the sign-up of receiving channel switch events.
virtual void UnsubscribeChannelSwitchEvent(uint32_t interface_index);
+ // Sign up to be notified of frame tx status events.
+ virtual void SubscribeFrameTxStatusEvent(
+ uint32_t interface_index, OnFrameTxStatusEventHandler handler);
+
+ // Cancel the sign-up of receiving frame tx status events.
+ virtual void UnsubscribeFrameTxStatusEvent(uint32_t interface_index);
+
+ virtual bool SendMgmtFrame(uint32_t interface_index,
+ const std::vector<uint8_t>& frame, int32_t mcs, uint64_t* out_cookie);
+
// Visible for testing.
bool supports_split_wiphy_dump_;
diff --git a/net/nl80211_attribute.h b/net/nl80211_attribute.h
index 04fc890..1493c56 100644
--- a/net/nl80211_attribute.h
+++ b/net/nl80211_attribute.h
@@ -113,6 +113,23 @@
std::vector<uint8_t> GetValue() const;
}; // class NL80211Attr for raw data
+template <size_t N>
+class NL80211Attr<std::array<uint8_t, N>> : public BaseNL80211Attr {
+ public:
+ NL80211Attr(int id, const std::array<uint8_t, N>& raw_buffer)
+ : BaseNL80211Attr(
+ id, std::vector<uint8_t>(raw_buffer.begin(), raw_buffer.end())) {}
+ explicit NL80211Attr(const std::vector<uint8_t>& data) {
+ data_ = data;
+ }
+ ~NL80211Attr() override = default;
+ std::array<uint8_t, N> GetValue() const {
+ std::array<uint8_t, N> arr;
+ std::copy_n(data_.data() + NLA_HDRLEN, N, arr.begin());
+ return arr;
+ }
+}; // class NL80211Attr for fixed size array
+
template <>
class NL80211Attr<std::string> : public BaseNL80211Attr {
public:
diff --git a/scanning/offload/offload_scan_utils.cpp b/scanning/offload/offload_scan_utils.cpp
index 1446f76..d476507 100644
--- a/scanning/offload/offload_scan_utils.cpp
+++ b/scanning/offload/offload_scan_utils.cpp
@@ -43,7 +43,7 @@
single_scan_result.ssid.assign(scan_result[i].networkInfo.ssid.begin(),
scan_result[i].networkInfo.ssid.end());
for (size_t j = 0; j < scan_result[i].bssid.elementCount(); j++) {
- single_scan_result.bssid.push_back(scan_result[i].bssid[j]);
+ single_scan_result.bssid.at(j) = scan_result[i].bssid[j];
}
single_scan_result.frequency = scan_result[i].frequency;
single_scan_result.signal_mbm = scan_result[i].rssi;
diff --git a/scanning/pno_network.cpp b/scanning/pno_network.cpp
index d63f6b3..02f8e5f 100644
--- a/scanning/pno_network.cpp
+++ b/scanning/pno_network.cpp
@@ -31,6 +31,7 @@
status_t PnoNetwork::writeToParcel(::android::Parcel* parcel) const {
RETURN_IF_FAILED(parcel->writeInt32(is_hidden_ ? 1 : 0));
RETURN_IF_FAILED(parcel->writeByteVector(ssid_));
+ RETURN_IF_FAILED(parcel->writeInt32Vector(frequencies_));
return ::android::OK;
}
@@ -39,6 +40,7 @@
RETURN_IF_FAILED(parcel->readInt32(&is_hidden));
is_hidden_ = (is_hidden != 0);
RETURN_IF_FAILED(parcel->readByteVector(&ssid_));
+ RETURN_IF_FAILED(parcel->readInt32Vector(&frequencies_));
return ::android::OK;
}
diff --git a/scanning/pno_network.h b/scanning/pno_network.h
index 6156c6c..bd5d6cb 100644
--- a/scanning/pno_network.h
+++ b/scanning/pno_network.h
@@ -40,6 +40,7 @@
bool is_hidden_;
std::vector<uint8_t> ssid_;
+ std::vector<int32_t> frequencies_;
};
} // namespace wificond
diff --git a/scanning/scan_result.cpp b/scanning/scan_result.cpp
index 7df4daa..fa85981 100644
--- a/scanning/scan_result.cpp
+++ b/scanning/scan_result.cpp
@@ -16,6 +16,8 @@
#include "wificond/scanning/scan_result.h"
+#include <algorithm>
+
#include <android-base/logging.h>
#include "wificond/logging_utils.h"
@@ -32,7 +34,7 @@
namespace wificond {
NativeScanResult::NativeScanResult(std::vector<uint8_t>& ssid_,
- std::vector<uint8_t>& bssid_,
+ std::array<uint8_t, ETH_ALEN>& bssid_,
std::vector<uint8_t>& info_element_,
uint32_t frequency_,
int32_t signal_mbm_,
@@ -53,7 +55,8 @@
status_t NativeScanResult::writeToParcel(::android::Parcel* parcel) const {
RETURN_IF_FAILED(parcel->writeByteVector(ssid));
- RETURN_IF_FAILED(parcel->writeByteVector(bssid));
+ RETURN_IF_FAILED(parcel->writeByteVector(
+ std::vector<uint8_t>(bssid.begin(), bssid.end())));
RETURN_IF_FAILED(parcel->writeByteVector(info_element));
RETURN_IF_FAILED(parcel->writeUint32(frequency));
RETURN_IF_FAILED(parcel->writeInt32(signal_mbm));
@@ -74,7 +77,16 @@
status_t NativeScanResult::readFromParcel(const ::android::Parcel* parcel) {
RETURN_IF_FAILED(parcel->readByteVector(&ssid));
- RETURN_IF_FAILED(parcel->readByteVector(&bssid));
+ {
+ std::vector<uint8_t> bssid_vec;
+ RETURN_IF_FAILED(parcel->readByteVector(&bssid_vec));
+ if (bssid_vec.size() != ETH_ALEN) {
+ LOG(ERROR) << "bssid length expected " << ETH_ALEN << " bytes, but got "
+ << bssid_vec.size() << " bytes";
+ return ::android::BAD_VALUE;
+ }
+ std::copy_n(bssid_vec.begin(), ETH_ALEN, bssid.begin());
+ }
RETURN_IF_FAILED(parcel->readByteVector(&info_element));
RETURN_IF_FAILED(parcel->readUint32(&frequency));
RETURN_IF_FAILED(parcel->readInt32(&signal_mbm));
diff --git a/scanning/scan_result.h b/scanning/scan_result.h
index 4e7df47..bd9dc98 100644
--- a/scanning/scan_result.h
+++ b/scanning/scan_result.h
@@ -17,8 +17,11 @@
#ifndef WIFICOND_SCANNING_SCAN_RESULT_H_
#define WIFICOND_SCANNING_SCAN_RESULT_H_
+#include <array>
#include <vector>
+#include <linux/if_ether.h>
+
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
@@ -35,7 +38,7 @@
public:
NativeScanResult() = default;
NativeScanResult(std::vector<uint8_t>& ssid,
- std::vector<uint8_t>& bssid,
+ std::array<uint8_t, ETH_ALEN>& bssid,
std::vector<uint8_t>& info_element,
uint32_t frequency,
int32_t signal_mbm,
@@ -51,7 +54,7 @@
// SSID of the BSS.
std::vector<uint8_t> ssid;
// BSSID of the BSS.
- std::vector<uint8_t> bssid;
+ std::array<uint8_t, ETH_ALEN> bssid;
// Binary array containing the raw information elements from the probe
// response/beacon.
std::vector<uint8_t> info_element;
diff --git a/scanning/scan_utils.cpp b/scanning/scan_utils.cpp
index 708e0b4..65f8f8c 100644
--- a/scanning/scan_utils.cpp
+++ b/scanning/scan_utils.cpp
@@ -17,9 +17,11 @@
#include "android/net/wifi/IWifiScannerImpl.h"
#include "wificond/scanning/scan_utils.h"
+#include <array>
#include <vector>
#include <linux/netlink.h>
+#include <linux/if_ether.h>
#include <android-base/logging.h>
@@ -31,6 +33,7 @@
using android::net::wifi::IWifiScannerImpl;
using com::android::server::wifi::wificond::NativeScanResult;
using com::android::server::wifi::wificond::RadioChainInfo;
+using std::array;
using std::unique_ptr;
using std::vector;
@@ -134,7 +137,7 @@
}
NL80211NestedAttr bss(0);
if (packet->GetAttribute(NL80211_ATTR_BSS, &bss)) {
- vector<uint8_t> bssid;
+ array<uint8_t, ETH_ALEN> bssid;
if (!bss.GetAttributeValue(NL80211_BSS_BSSID, &bssid)) {
LOG(ERROR) << "Failed to get BSSID from scan result packet";
return false;
@@ -402,8 +405,7 @@
const SchedScanIntervalSetting& interval_setting,
int32_t rssi_threshold_2g,
int32_t rssi_threshold_5g,
- bool request_random_mac,
- bool request_low_power,
+ const SchedScanReqFlags& req_flags,
const std::vector<std::vector<uint8_t>>& scan_ssids,
const std::vector<std::vector<uint8_t>>& match_ssids,
const std::vector<uint32_t>& freqs,
@@ -441,15 +443,18 @@
start_sched_scan.AddAttribute(scan_match_attr);
// We set 5g threshold for default and ajust threshold for 2g band.
- struct nl80211_bss_select_rssi_adjust rssi_adjust;
- rssi_adjust.band = NL80211_BAND_2GHZ;
- rssi_adjust.delta = static_cast<int8_t>(rssi_threshold_2g - rssi_threshold_5g);
- NL80211Attr<vector<uint8_t>> rssi_adjust_attr(
- NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
- vector<uint8_t>(
- reinterpret_cast<uint8_t*>(&rssi_adjust),
- reinterpret_cast<uint8_t*>(&rssi_adjust) + sizeof(rssi_adjust)));
- start_sched_scan.AddAttribute(rssi_adjust_attr);
+ // check sched_scan supported before set NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST attribute.
+ if (req_flags.request_sched_scan_relative_rssi) {
+ struct nl80211_bss_select_rssi_adjust rssi_adjust;
+ rssi_adjust.band = NL80211_BAND_2GHZ;
+ rssi_adjust.delta = static_cast<int8_t>(rssi_threshold_2g - rssi_threshold_5g);
+ NL80211Attr<vector<uint8_t>> rssi_adjust_attr(
+ NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
+ vector<uint8_t>(
+ reinterpret_cast<uint8_t*>(&rssi_adjust),
+ reinterpret_cast<uint8_t*>(&rssi_adjust) + sizeof(rssi_adjust)));
+ start_sched_scan.AddAttribute(rssi_adjust_attr);
+ }
// Append all attributes to the NL80211_CMD_START_SCHED_SCAN packet.
start_sched_scan.AddAttribute(
@@ -485,10 +490,10 @@
interval_setting.final_interval_ms));
}
uint32_t scan_flags = 0;
- if (request_random_mac) {
+ if (req_flags.request_random_mac) {
scan_flags |= NL80211_SCAN_FLAG_RANDOM_ADDR;
}
- if (request_low_power) {
+ if (req_flags.request_low_power) {
scan_flags |= NL80211_SCAN_FLAG_LOW_POWER;
}
if (scan_flags) {
diff --git a/scanning/scan_utils.h b/scanning/scan_utils.h
index a33023b..d160123 100644
--- a/scanning/scan_utils.h
+++ b/scanning/scan_utils.h
@@ -56,6 +56,12 @@
uint32_t final_interval_ms{0};
};
+struct SchedScanReqFlags {
+ bool request_random_mac;
+ bool request_low_power;
+ bool request_sched_scan_relative_rssi;
+};
+
// Provides scanning helper functions.
class ScanUtils {
public:
@@ -111,6 +117,9 @@
// - |request_low_power|: If true, prioritize power consumption over
// other scan performance attributes.
// Requires |supports_low_power_oneshot_scan|.
+ // - |request_sched_scan_relative_rssi| is sched_scan flag for better BSS's from connected BSS.
+ // If |request_sched_scan_relative_rssi| is true, it will fill scan rssi adjust to
+ // get BSS's with better RSSI from connected BSS.
// - |scan_ssids| is the list of ssids to actively scan for.
// If |scan_ssids| is an empty vector, it will do a passive scan.
// If |scan_ssids| contains an empty string, it will a scan for all ssids.
@@ -126,8 +135,7 @@
const SchedScanIntervalSetting& interval_setting,
int32_t rssi_threshold_2g,
int32_t rssi_threshold_5g,
- bool request_random_mac,
- bool request_low_power,
+ const SchedScanReqFlags& req_flags,
const std::vector<std::vector<uint8_t>>& scan_ssids,
const std::vector<std::vector<uint8_t>>& match_ssids,
const std::vector<uint32_t>& freqs,
diff --git a/scanning/scanner_impl.cpp b/scanning/scanner_impl.cpp
index eb15178..f2953d8 100644
--- a/scanning/scanner_impl.cpp
+++ b/scanning/scanner_impl.cpp
@@ -16,6 +16,7 @@
#include "wificond/scanning/scanner_impl.h"
+#include <set>
#include <string>
#include <vector>
@@ -57,6 +58,10 @@
}
return {};
}
+
+constexpr const int kPercentNetworksWithFreq = 30;
+constexpr const int kPnoScanDefaultFreqs[] = {2412, 2417, 2422, 2427, 2432, 2437, 2447, 2452,
+ 2457, 2462, 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805};
} // namespace
namespace android {
@@ -243,6 +248,8 @@
const uint8_t kNetworkFlagsDefault = 0;
vector<vector<uint8_t>> skipped_scan_ssids;
vector<vector<uint8_t>> skipped_match_ssids;
+ std::set<int32_t> unique_frequencies;
+ int num_networks_no_freqs = 0;
for (auto& network : pno_settings.pno_networks_) {
// Add hidden network ssid.
if (network.is_hidden_) {
@@ -261,8 +268,25 @@
}
match_ssids->push_back(network.ssid_);
match_security->push_back(kNetworkFlagsDefault);
+
+ // build the set of unique frequencies to scan for.
+ for (const auto& frequency : network.frequencies_) {
+ unique_frequencies.insert(frequency);
+ }
+ if (network.frequencies_.empty()) {
+ num_networks_no_freqs++;
+ }
}
+ // Also scan the default frequencies if there is frequency data passed down but more than 30% of
+ // networks don't have frequency data.
+ if (unique_frequencies.size() > 0 && num_networks_no_freqs * 100 / match_ssids->size()
+ > kPercentNetworksWithFreq) {
+ unique_frequencies.insert(std::begin(kPnoScanDefaultFreqs), std::end(kPnoScanDefaultFreqs));
+ }
+ for (const auto& frequency : unique_frequencies) {
+ freqs->push_back(frequency);
+ }
LogSsidList(skipped_scan_ssids, "Skip scan ssid for pno scan");
LogSsidList(skipped_match_ssids, "Skip match ssid for pno scan");
}
@@ -288,13 +312,18 @@
// Always request a low power scan for PNO, if device supports it.
bool request_low_power = wiphy_features_.supports_low_power_oneshot_scan;
+ bool request_sched_scan_relative_rssi = wiphy_features_.supports_ext_sched_scan_relative_rssi;
+
int error_code = 0;
+ struct SchedScanReqFlags req_flags = {};
+ req_flags.request_random_mac = request_random_mac;
+ req_flags.request_low_power = request_low_power;
+ req_flags.request_sched_scan_relative_rssi = request_sched_scan_relative_rssi;
if (!scan_utils_->StartScheduledScan(interface_index_,
GenerateIntervalSetting(pno_settings),
pno_settings.min_2g_rssi_,
pno_settings.min_5g_rssi_,
- request_random_mac,
- request_low_power,
+ req_flags,
scan_ssids,
match_ssids,
freqs,
@@ -303,7 +332,16 @@
CHECK(error_code != ENODEV) << "Driver is in a bad state, restarting wificond";
return false;
}
- LOG(INFO) << "Pno scan started";
+ string freq_string;
+ if (freqs.empty()) {
+ freq_string = "for all supported frequencies";
+ } else {
+ freq_string = "for frequencies: ";
+ for (uint32_t f : freqs) {
+ freq_string += std::to_string(f) + ", ";
+ }
+ }
+ LOG(INFO) << "Pno scan started " << freq_string;
pno_scan_started_ = true;
return true;
}
diff --git a/server.cpp b/server.cpp
index 7db0f75..b592dfe 100644
--- a/server.cpp
+++ b/server.cpp
@@ -35,9 +35,7 @@
using android::net::wifi::IApInterface;
using android::net::wifi::IClientInterface;
using android::net::wifi::IInterfaceEventCallback;
-using android::wifi_system::HostapdManager;
using android::wifi_system::InterfaceTool;
-using android::wifi_system::SupplicantManager;
using std::endl;
using std::placeholders::_1;
@@ -56,13 +54,9 @@
} // namespace
Server::Server(unique_ptr<InterfaceTool> if_tool,
- unique_ptr<SupplicantManager> supplicant_manager,
- unique_ptr<HostapdManager> hostapd_manager,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils)
: if_tool_(std::move(if_tool)),
- supplicant_manager_(std::move(supplicant_manager)),
- hostapd_manager_(std::move(hostapd_manager)),
netlink_utils_(netlink_utils),
scan_utils_(scan_utils) {
}
@@ -105,8 +99,7 @@
interface.name,
interface.index,
netlink_utils_,
- if_tool_.get(),
- hostapd_manager_.get()));
+ if_tool_.get()));
*created_interface = ap_interface->GetBinder();
BroadcastApInterfaceReady(ap_interface->GetBinder());
ap_interfaces_[iface_name] = std::move(ap_interface);
@@ -178,16 +171,6 @@
return Status::ok();
}
-Status Server::enableSupplicant(bool* success) {
- *success = supplicant_manager_->StartSupplicant();
- return Status::ok();
-}
-
-Status Server::disableSupplicant(bool* success) {
- *success = supplicant_manager_->StopSupplicant();
- return Status::ok();
-}
-
Status Server::GetClientInterfaces(vector<sp<IBinder>>* out_client_interfaces) {
vector<sp<android::IBinder>> client_interfaces_binder;
for (auto& it : client_interfaces_) {
diff --git a/server.h b/server.h
index ded3518..cdce6b2 100644
--- a/server.h
+++ b/server.h
@@ -23,7 +23,6 @@
#include <android-base/macros.h>
#include <wifi_system/interface_tool.h>
-#include <wifi_system/supplicant_manager.h>
#include "android/net/wifi/BnWificond.h"
#include "android/net/wifi/IApInterface.h"
@@ -45,8 +44,6 @@
class Server : public android::net::wifi::BnWificond {
public:
Server(std::unique_ptr<wifi_system::InterfaceTool> if_tool,
- std::unique_ptr<wifi_system::SupplicantManager> supplicant_man,
- std::unique_ptr<wifi_system::HostapdManager> hostapd_man,
NetlinkUtils* netlink_utils,
ScanUtils* scan_utils);
~Server() override = default;
@@ -86,8 +83,6 @@
bool* out_success) override;
android::binder::Status tearDownInterfaces() override;
- android::binder::Status enableSupplicant(bool* success) override;
- android::binder::Status disableSupplicant(bool* success) override;
android::binder::Status GetClientInterfaces(
std::vector<android::sp<android::IBinder>>* out_client_ifs) override;
@@ -116,8 +111,6 @@
void MarkDownAllInterfaces();
const std::unique_ptr<wifi_system::InterfaceTool> if_tool_;
- const std::unique_ptr<wifi_system::SupplicantManager> supplicant_manager_;
- const std::unique_ptr<wifi_system::HostapdManager> hostapd_manager_;
NetlinkUtils* const netlink_utils_;
ScanUtils* const scan_utils_;
diff --git a/tests/ap_interface_impl_unittest.cpp b/tests/ap_interface_impl_unittest.cpp
index bcd885d..0f1bf28 100644
--- a/tests/ap_interface_impl_unittest.cpp
+++ b/tests/ap_interface_impl_unittest.cpp
@@ -14,12 +14,14 @@
* limitations under the License.
*/
+#include <array>
#include <memory>
#include <vector>
+#include <linux/if_ether.h>
+
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include <wifi_system_test/mock_hostapd_manager.h>
#include <wifi_system_test/mock_interface_tool.h>
#include "wificond/tests/mock_ap_interface_event_callback.h"
@@ -28,9 +30,8 @@
#include "wificond/ap_interface_impl.h"
-using android::wifi_system::HostapdManager;
-using android::wifi_system::MockHostapdManager;
using android::wifi_system::MockInterfaceTool;
+using std::array;
using std::placeholders::_1;
using std::placeholders::_2;
using std::unique_ptr;
@@ -48,7 +49,7 @@
const char kTestInterfaceName[] = "testwifi0";
const uint32_t kTestInterfaceIndex = 42;
-const uint8_t kFakeMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const array<uint8_t, ETH_ALEN> kFakeMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
void CaptureStationEventHandler(
OnStationEventHandler* out_handler,
@@ -68,8 +69,6 @@
protected:
unique_ptr<NiceMock<MockInterfaceTool>> if_tool_{
new NiceMock<MockInterfaceTool>};
- unique_ptr<NiceMock<MockHostapdManager>> hostapd_manager_{
- new NiceMock<MockHostapdManager>};
unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
new NiceMock<MockNetlinkManager>()};
unique_ptr<NiceMock<MockNetlinkUtils>> netlink_utils_{
@@ -82,43 +81,12 @@
kTestInterfaceName,
kTestInterfaceIndex,
netlink_utils_.get(),
- if_tool_.get(),
- hostapd_manager_.get()));
+ if_tool_.get()));
}
}; // class ApInterfaceImplTest
} // namespace
-TEST_F(ApInterfaceImplTest, ShouldReportStartFailure) {
- EXPECT_CALL(*hostapd_manager_, StartHostapd())
- .WillOnce(Return(false));
- EXPECT_FALSE(ap_interface_->StartHostapd());
-}
-
-TEST_F(ApInterfaceImplTest, ShouldReportStartSuccess) {
- EXPECT_CALL(*hostapd_manager_, StartHostapd())
- .WillOnce(Return(true));
- EXPECT_TRUE(ap_interface_->StartHostapd());
-}
-
-TEST_F(ApInterfaceImplTest, ShouldReportStopFailure) {
- EXPECT_CALL(*hostapd_manager_, StopHostapd())
- .WillOnce(Return(false));
- EXPECT_FALSE(ap_interface_->StopHostapd());
-}
-
-TEST_F(ApInterfaceImplTest, ShouldReportStopSuccess) {
- EXPECT_CALL(*hostapd_manager_, StopHostapd())
- .WillOnce(Return(true));
- EXPECT_CALL(*if_tool_, SetUpState(StrEq(kTestInterfaceName), false))
- .WillOnce(Return(true));
- EXPECT_CALL(*netlink_utils_, SetInterfaceMode(
- kTestInterfaceIndex,
- NetlinkUtils::STATION_MODE)).WillOnce(Return(true));
- EXPECT_TRUE(ap_interface_->StopHostapd());
- testing::Mock::VerifyAndClearExpectations(if_tool_.get());
-}
-
TEST_F(ApInterfaceImplTest, CanGetNumberOfAssociatedStations) {
OnStationEventHandler handler;
EXPECT_CALL(*netlink_utils_,
@@ -129,11 +97,9 @@
kTestInterfaceName,
kTestInterfaceIndex,
netlink_utils_.get(),
- if_tool_.get(),
- hostapd_manager_.get()));
+ if_tool_.get()));
- vector<uint8_t> fake_mac_address(kFakeMacAddress,
- kFakeMacAddress + sizeof(kFakeMacAddress));
+ array<uint8_t, ETH_ALEN> fake_mac_address = kFakeMacAddress;
EXPECT_EQ(0, ap_interface_->GetNumberOfAssociatedStations());
handler(NEW_STATION, fake_mac_address);
EXPECT_EQ(1, ap_interface_->GetNumberOfAssociatedStations());
@@ -149,17 +115,15 @@
.WillOnce(Invoke(bind(CaptureStationEventHandler, &handler, _1, _2)));
ap_interface_.reset(new ApInterfaceImpl(
kTestInterfaceName, kTestInterfaceIndex, netlink_utils_.get(),
- if_tool_.get(), hostapd_manager_.get()));
+ if_tool_.get()));
- EXPECT_CALL(*hostapd_manager_, StartHostapd()).WillOnce(Return(true));
auto binder = ap_interface_->GetBinder();
sp<MockApInterfaceEventCallback> callback(new MockApInterfaceEventCallback());
bool out_success = false;
- EXPECT_TRUE(binder->startHostapd(callback, &out_success).isOk());
+ EXPECT_TRUE(binder->registerCallback(callback, &out_success).isOk());
EXPECT_TRUE(out_success);
- vector<uint8_t> fake_mac_address(kFakeMacAddress,
- kFakeMacAddress + sizeof(kFakeMacAddress));
+ array<uint8_t, ETH_ALEN> fake_mac_address = kFakeMacAddress;
EXPECT_CALL(*callback, onNumAssociatedStationsChanged(1));
handler(NEW_STATION, fake_mac_address);
EXPECT_CALL(*callback, onNumAssociatedStationsChanged(2));
@@ -174,13 +138,12 @@
.WillOnce(Invoke(bind(CaptureChannelSwitchEventHandler, &handler, _1, _2)));
ap_interface_.reset(new ApInterfaceImpl(
kTestInterfaceName, kTestInterfaceIndex, netlink_utils_.get(),
- if_tool_.get(), hostapd_manager_.get()));
+ if_tool_.get()));
- EXPECT_CALL(*hostapd_manager_, StartHostapd()).WillOnce(Return(true));
auto binder = ap_interface_->GetBinder();
sp<MockApInterfaceEventCallback> callback(new MockApInterfaceEventCallback());
bool out_success = false;
- EXPECT_TRUE(binder->startHostapd(callback, &out_success).isOk());
+ EXPECT_TRUE(binder->registerCallback(callback, &out_success).isOk());
EXPECT_TRUE(out_success);
const uint32_t kTestChannelFrequency = 2437;
diff --git a/tests/client_interface_impl_unittest.cpp b/tests/client_interface_impl_unittest.cpp
index da61ce6..5929139 100644
--- a/tests/client_interface_impl_unittest.cpp
+++ b/tests/client_interface_impl_unittest.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <array>
#include <memory>
#include <vector>
@@ -22,6 +23,7 @@
#include <wifi_system_test/mock_interface_tool.h>
#include "wificond/client_interface_impl.h"
+#include "wificond/tests/mock_i_send_mgmt_frame_event.h"
#include "wificond/tests/mock_netlink_manager.h"
#include "wificond/tests/mock_netlink_utils.h"
#include "wificond/tests/mock_scan_utils.h"
@@ -29,8 +31,10 @@
using android::wifi_system::MockInterfaceTool;
using std::unique_ptr;
using std::vector;
+using testing::Mock;
using testing::NiceMock;
using testing::Return;
+using testing::StrictMock;
using testing::_;
namespace android {
@@ -40,21 +44,44 @@
const uint32_t kTestWiphyIndex = 2;
const char kTestInterfaceName[] = "testwifi0";
const uint32_t kTestInterfaceIndex = 42;
-const size_t kMacAddrLenBytes = ETH_ALEN;
+const uint64_t kCookie = 42;
+const int32_t kAutoMcs = -1;
+const int32_t kMcs = 5;
+const uint8_t kTestFrame[] = {0x00, 0x01, 0x02, 0x03};
class ClientInterfaceImplTest : public ::testing::Test {
protected:
void SetUp() override {
+ SetUp(WiphyFeatures());
+ }
+
+ /**
+ * call SetUp(WiphyFeatures wiphy_features) in your test function if
+ * you would like to change WiphyFeatures.
+ */
+ void SetUp(WiphyFeatures wiphy_features) {
EXPECT_CALL(*netlink_utils_,
SubscribeMlmeEvent(kTestInterfaceIndex, _));
EXPECT_CALL(*netlink_utils_,
- GetWiphyInfo(kTestWiphyIndex, _, _, _));
+ GetWiphyInfo(kTestWiphyIndex, _, _, _))
+ .WillOnce([wiphy_features](uint32_t wiphy_index, BandInfo* out_band_info,
+ ScanCapabilities* out_scan_capabilities,
+ WiphyFeatures* out_wiphy_features) {
+ *out_wiphy_features = wiphy_features;
+ return true;
+ });
+ EXPECT_CALL(*netlink_utils_,
+ SubscribeFrameTxStatusEvent(kTestInterfaceIndex, _))
+ .WillOnce([this](uint32_t interface_index,
+ OnFrameTxStatusEventHandler handler) {
+ frame_tx_status_event_handler_ = handler;
+ });
client_interface_.reset(new ClientInterfaceImpl{
kTestWiphyIndex,
kTestInterfaceName,
kTestInterfaceIndex,
- vector<uint8_t>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ std::array<uint8_t, ETH_ALEN>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
if_tool_.get(),
netlink_utils_.get(),
scan_utils_.get()});
@@ -63,6 +90,8 @@
void TearDown() override {
EXPECT_CALL(*netlink_utils_,
UnsubscribeMlmeEvent(kTestInterfaceIndex));
+ EXPECT_CALL(*netlink_utils_,
+ UnsubscribeFrameTxStatusEvent(kTestInterfaceIndex));
}
unique_ptr<NiceMock<MockInterfaceTool>> if_tool_{
@@ -74,28 +103,24 @@
unique_ptr<NiceMock<MockScanUtils>> scan_utils_{
new NiceMock<MockScanUtils>(netlink_manager_.get())};
unique_ptr<ClientInterfaceImpl> client_interface_;
+ OnFrameTxStatusEventHandler frame_tx_status_event_handler_;
+ sp<StrictMock<MockISendMgmtFrameEvent>> send_mgmt_frame_event_{
+ new StrictMock<MockISendMgmtFrameEvent>()};
}; // class ClientInterfaceImplTest
} // namespace
-TEST_F(ClientInterfaceImplTest, SetMacAddressFailsOnInvalidInput) {
- EXPECT_FALSE(client_interface_->SetMacAddress(
- std::vector<uint8_t>(kMacAddrLenBytes - 1)));
- EXPECT_FALSE(client_interface_->SetMacAddress(
- std::vector<uint8_t>(kMacAddrLenBytes + 1)));
-}
-
TEST_F(ClientInterfaceImplTest, SetMacAddressFailsOnInterfaceDownFailure) {
EXPECT_CALL(*if_tool_, SetWifiUpState(false)).WillOnce(Return(false));
EXPECT_FALSE(
- client_interface_->SetMacAddress(std::vector<uint8_t>(kMacAddrLenBytes)));
+ client_interface_->SetMacAddress(std::array<uint8_t, ETH_ALEN>()));
}
TEST_F(ClientInterfaceImplTest, SetMacAddressFailsOnAddressChangeFailure) {
EXPECT_CALL(*if_tool_, SetWifiUpState(false)).WillOnce(Return(true));
EXPECT_CALL(*if_tool_, SetMacAddress(_, _)).WillOnce(Return(false));
EXPECT_FALSE(
- client_interface_->SetMacAddress(std::vector<uint8_t>(kMacAddrLenBytes)));
+ client_interface_->SetMacAddress(std::array<uint8_t, ETH_ALEN>()));
}
TEST_F(ClientInterfaceImplTest, SetMacAddressFailsOnInterfaceUpFailure) {
@@ -103,7 +128,7 @@
EXPECT_CALL(*if_tool_, SetMacAddress(_, _)).WillOnce(Return(true));
EXPECT_CALL(*if_tool_, SetWifiUpState(true)).WillOnce(Return(false));
EXPECT_FALSE(
- client_interface_->SetMacAddress(std::vector<uint8_t>(kMacAddrLenBytes)));
+ client_interface_->SetMacAddress(std::array<uint8_t, ETH_ALEN>()));
}
TEST_F(ClientInterfaceImplTest, SetMacAddressReturnsTrueOnSuccess) {
@@ -111,17 +136,274 @@
EXPECT_CALL(*if_tool_, SetMacAddress(_, _)).WillOnce(Return(true));
EXPECT_CALL(*if_tool_, SetWifiUpState(true)).WillOnce(Return(true));
EXPECT_TRUE(
- client_interface_->SetMacAddress(std::vector<uint8_t>(kMacAddrLenBytes)));
+ client_interface_->SetMacAddress(std::array<uint8_t, ETH_ALEN>()));
}
TEST_F(ClientInterfaceImplTest, SetMacAddressPassesCorrectAddressToIfTool) {
EXPECT_CALL(*if_tool_, SetWifiUpState(false)).WillOnce(Return(true));
EXPECT_CALL(*if_tool_, SetMacAddress(_,
- std::array<uint8_t, kMacAddrLenBytes>{{1, 2, 3, 4, 5, 6}}))
+ std::array<uint8_t, ETH_ALEN>{{1, 2, 3, 4, 5, 6}}))
.WillOnce(Return(true));
EXPECT_CALL(*if_tool_, SetWifiUpState(true)).WillOnce(Return(true));
EXPECT_TRUE(client_interface_->SetMacAddress(
- std::vector<uint8_t>{1, 2, 3, 4, 5, 6}));
+ std::array<uint8_t, ETH_ALEN>{{1, 2, 3, 4, 5, 6}}));
+}
+
+/**
+ * If the device does not support sending mgmt frame at specified MCS rate,
+ * and the caller specifies a MCS < 0, the call should still succeed (and the
+ * driver will determine the MCS rate automatically).
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameMcsUnsupportedAutoSelectMcs) {
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ kAutoMcs, _))
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = kCookie;
+ return true;
+ });
+
+ EXPECT_CALL(*send_mgmt_frame_event_, OnAck(_));
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kAutoMcs);
+ frame_tx_status_event_handler_(kCookie, true);
+}
+
+/**
+ * If the device does not support sending mgmt frame at specified MCS rate,
+ * and the caller specifies a MCS >= 0, the call should fail.
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameMcsUnsupportedCallerSpecifiedMcs) {
+ EXPECT_CALL(*send_mgmt_frame_event_,
+ OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED));
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kMcs);
+}
+
+/**
+ * If the device does support sending mgmt frame at specified MCS rate and the
+ * user specifies a valid MCS rate, the call should succeed.
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameMcsSupported) {
+ WiphyFeatures wiphy_features;
+ wiphy_features.supports_tx_mgmt_frame_mcs = true;
+ SetUp(wiphy_features);
+
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ kMcs, _))
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = kCookie;
+ return true;
+ });
+
+ EXPECT_CALL(*send_mgmt_frame_event_, OnAck(_));
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kMcs);
+ frame_tx_status_event_handler_(kCookie, true);
+}
+
+/**
+ * Transmitted frame was not ACKed.
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameNotAcked) {
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ kAutoMcs, _))
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = kCookie;
+ return true;
+ });
+
+ EXPECT_CALL(*send_mgmt_frame_event_,
+ OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_NO_ACK));
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kAutoMcs);
+ frame_tx_status_event_handler_(kCookie, false);
+}
+
+/**
+ * Transmission failed due to unknown NL80211 error.
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameUnknownError) {
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)), kAutoMcs, _))
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ return false;
+ });
+
+ EXPECT_CALL(*send_mgmt_frame_event_,
+ OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_UNKNOWN));
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kAutoMcs);
+}
+
+/**
+ * Received cookie was different than expected; No callback should be triggered.
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameWrongCookie) {
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ kAutoMcs, _))
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = kCookie;
+ return true;
+ });
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kAutoMcs);
+ frame_tx_status_event_handler_(
+ kCookie + 1, // wrong cookie
+ false);
+
+ // StrictMock<MockISendMgmtFrameEvent> will fail if any unexpected method is
+ // called, guaranteeing no interaction with the callback.
+}
+
+/**
+ * frame_tx_status_event_handler_ triggered even though no transmission is in
+ * progress. No callback should be triggered.
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameNoTxCallbackTriggered) {
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ kAutoMcs, _))
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = kCookie;
+ return true;
+ });
+
+ EXPECT_CALL(*send_mgmt_frame_event_,
+ OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_NO_ACK));
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kAutoMcs);
+ frame_tx_status_event_handler_(kCookie, false);
+
+ // transmission has finished here.
+
+ // Now send another Tx status event.
+ frame_tx_status_event_handler_(kCookie + 1, false);
+ // StrictMock<MockISendMgmtFrameEvent> will fail if any unexpected method is
+ // called, guaranteeing no more interaction with the callback.
+}
+
+/**
+ * Second transmission was started even though no Tx Status event was received
+ * for the first transmission. Should discard first transmission, and second
+ * transmission should work normally.
+ *
+ * Since timeout of this SendMgmtFrame() is managed by framework, and framework
+ * does not notify wificond when the call times out, wificond should still work
+ * when a second call is made, even though it seems as though the first call is
+ * still incomplete.
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameSecondTxWhileFirstTxIncomplete) {
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ kAutoMcs, _))
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = kCookie;
+ return true;
+ })
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = kCookie + 1;
+ return true;
+ });
+
+ // first transmission; no tx status
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kAutoMcs);
+
+ sp<StrictMock<MockISendMgmtFrameEvent>> send_mgmt_frame_event2{
+ new StrictMock<MockISendMgmtFrameEvent>()};
+
+ EXPECT_CALL(*send_mgmt_frame_event2,
+ OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_NO_ACK));
+
+ // second transmission; yes tx status
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event2, kAutoMcs);
+ frame_tx_status_event_handler_(kCookie + 1, false);
+
+ // now trigger tx status for first call; nothing should happen (implicitly
+ // verified by StrictMock).
+ frame_tx_status_event_handler_(kCookie, false);
+}
+
+/**
+ * Tests that internal state is reset correctly between calls by performing
+ * two transmissions in sequence.
+ */
+TEST_F(ClientInterfaceImplTest, SendMgmtFrameInternalStateResetBetweenCalls) {
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ kAutoMcs, _))
+ .WillOnce([](uint32_t interface_index, const vector<uint8_t>& frame,
+ int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = kCookie;
+ return true;
+ });
+
+ EXPECT_CALL(*send_mgmt_frame_event_, OnAck(_));
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kAutoMcs);
+ frame_tx_status_event_handler_(kCookie, true);
+
+ Mock::VerifyAndClearExpectations(netlink_utils_.get());
+ Mock::VerifyAndClearExpectations(send_mgmt_frame_event_.get());
+
+ uint64_t new_cookie = kCookie + 1;
+
+ EXPECT_CALL(*netlink_utils_,
+ SendMgmtFrame(kTestInterfaceIndex,
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ kAutoMcs, _))
+ .WillOnce([new_cookie](uint32_t interface_index,
+ const vector<uint8_t>& frame, int32_t mcs, uint64_t* out_cookie) {
+ *out_cookie = new_cookie;
+ return true;
+ });
+
+ EXPECT_CALL(*send_mgmt_frame_event_,
+ OnFailure(send_mgmt_frame_event_->SEND_MGMT_FRAME_ERROR_NO_ACK));
+
+ client_interface_->SendMgmtFrame(
+ vector<uint8_t>(std::begin(kTestFrame), std::end(kTestFrame)),
+ send_mgmt_frame_event_, kAutoMcs);
+ frame_tx_status_event_handler_(new_cookie, false);
}
} // namespace wificond
diff --git a/tests/integration/ap_interface_test.cpp b/tests/integration/ap_interface_test.cpp
index d562b61..3af92f7 100644
--- a/tests/integration/ap_interface_test.cpp
+++ b/tests/integration/ap_interface_test.cpp
@@ -29,8 +29,6 @@
using android::net::wifi::IWificond;
using android::wifi_system::InterfaceTool;
using android::wificond::MockApInterfaceEventCallback;
-using android::wificond::tests::integration::HostapdIsDead;
-using android::wificond::tests::integration::HostapdIsRunning;
using android::wificond::tests::integration::ScopedDevModeWificond;
using android::wificond::tests::integration::WaitForTrue;
using std::string;
@@ -40,8 +38,6 @@
namespace wificond {
namespace {
const char kInterfaceName[] = "wlan0";
-constexpr int kHostapdStartupTimeoutSeconds = 3;
-constexpr int kHostapdDeathTimeoutSeconds = 3;
} // namespace
TEST(ApInterfaceTest, CanCreateApInterfaces) {
@@ -79,59 +75,5 @@
// Teardown everything at the end of the test.
EXPECT_TRUE(service->tearDownInterfaces().isOk());
}
-
-// TODO: b/30311493 this test fails because hostapd fails to set the driver
-// channel every other time.
-TEST(ApInterfaceTest, CanStartStopHostapd) {
- ScopedDevModeWificond dev_mode;
- sp<IWificond> service = dev_mode.EnterDevModeOrDie();
- sp<IApInterface> ap_interface;
- EXPECT_TRUE(service->createApInterface(kInterfaceName, &ap_interface).isOk());
- ASSERT_NE(nullptr, ap_interface.get());
-
- // Interface should start out down.
- string if_name;
- EXPECT_TRUE(ap_interface->getInterfaceName(&if_name).isOk());
- EXPECT_TRUE(!if_name.empty());
- InterfaceTool if_tool;
- EXPECT_FALSE(if_tool.GetUpState(if_name.c_str()));
-
- sp<MockApInterfaceEventCallback> ap_interface_event_callback(
- new MockApInterfaceEventCallback());
-
- for (int iteration = 0; iteration < 4; iteration++) {
- bool hostapd_started = false;
- EXPECT_TRUE(
- ap_interface
- ->startHostapd(ap_interface_event_callback, &hostapd_started)
- .isOk());
- EXPECT_TRUE(hostapd_started);
-
- EXPECT_TRUE(WaitForTrue(HostapdIsRunning, kHostapdStartupTimeoutSeconds))
- << "Failed on iteration " << iteration;
-
- // There are two reasons to do this:
- // 1) We look for hostapd so quickly that we miss when it dies on startup
- // 2) If we don't give hostapd enough time to get fully up, killing it
- // can leave the driver in a poor state.
- // The latter points to an obvious race, where we cannot fully clean up the
- // driver on quick transitions.
- auto InterfaceIsUp = [&if_tool, &if_name] () {
- return if_tool.GetUpState(if_name.c_str());
- };
- EXPECT_TRUE(WaitForTrue(InterfaceIsUp, kHostapdStartupTimeoutSeconds))
- << "Failed on iteration " << iteration;
- EXPECT_TRUE(HostapdIsRunning()) << "Failed on iteration " << iteration;
-
- bool hostapd_stopped = false;
- EXPECT_TRUE(ap_interface->stopHostapd(&hostapd_stopped).isOk());
- EXPECT_TRUE(hostapd_stopped);
- EXPECT_FALSE(if_tool.GetUpState(if_name.c_str()));
-
-
- EXPECT_TRUE(WaitForTrue(HostapdIsDead, kHostapdDeathTimeoutSeconds))
- << "Failed on iteration " << iteration;
- }
-}
} // namespace wificond
} // namespace android
diff --git a/tests/integration/client_interface_test.cpp b/tests/integration/client_interface_test.cpp
index e25222b..37b9dba 100644
--- a/tests/integration/client_interface_test.cpp
+++ b/tests/integration/client_interface_test.cpp
@@ -29,9 +29,6 @@
using android::net::wifi::IWificond;
using android::wifi_system::InterfaceTool;
using android::wificond::tests::integration::ScopedDevModeWificond;
-using android::wificond::tests::integration::SupplicantIsDead;
-using android::wificond::tests::integration::SupplicantIsRunning;
-using android::wificond::tests::integration::WaitForTrue;
using std::string;
using std::vector;
diff --git a/tests/integration/service_test.cpp b/tests/integration/service_test.cpp
deleted file mode 100644
index 1711339..0000000
--- a/tests/integration/service_test.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2016, The Android Open Source Project
- *
- * 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 <gtest/gtest.h>
-#include <utils/StrongPointer.h>
-
-#include "android/net/wifi/IClientInterface.h"
-#include "android/net/wifi/IWificond.h"
-#include "wificond/tests/integration/process_utils.h"
-#include "wificond/tests/shell_utils.h"
-
-using android::net::wifi::IClientInterface;
-using android::net::wifi::IWificond;
-using android::sp;
-using android::wificond::tests::integration::RunShellCommand;
-using android::wificond::tests::integration::ScopedDevModeWificond;
-using android::wificond::tests::integration::SupplicantIsDead;
-using android::wificond::tests::integration::SupplicantIsRunning;
-using android::wificond::tests::integration::WaitForTrue;
-using android::wificond::tests::integration::WificondIsDead;
-
-namespace android {
-namespace wificond {
-namespace {
-
-constexpr int kTimeoutSeconds = 3;
-} // namespace
-
-TEST(ServiceTest, ShouldTearDownSystemOnStartup) {
- // Simulate doing normal connectivity things by startup supplicant.
- ScopedDevModeWificond dev_mode;
- sp<IWificond> service = dev_mode.EnterDevModeOrDie();
-
- bool supplicant_started = false;
- EXPECT_TRUE(service->enableSupplicant(&supplicant_started).isOk());
- EXPECT_TRUE(supplicant_started);
-
- EXPECT_TRUE(WaitForTrue(SupplicantIsRunning, kTimeoutSeconds));
-
- // Kill wificond abruptly. It should not clean up on the way out.
- RunShellCommand("stop wificond");
- EXPECT_TRUE(WaitForTrue(WificondIsDead, kTimeoutSeconds));
-
- // Supplicant should still be up.
- EXPECT_TRUE(SupplicantIsRunning());
-
- // Restart wificond, which should kill supplicant on startup.
- service = dev_mode.EnterDevModeOrDie();
- EXPECT_TRUE(WaitForTrue(SupplicantIsDead, kTimeoutSeconds));
-}
-
-TEST(ServiceTest, CanStartStopSupplicant) {
- ScopedDevModeWificond dev_mode;
- sp<IWificond> service = dev_mode.EnterDevModeOrDie();
-
- for (int iteration = 0; iteration < 4; iteration++) {
- bool supplicant_started = false;
- EXPECT_TRUE(service->enableSupplicant(&supplicant_started).isOk());
- EXPECT_TRUE(supplicant_started);
-
- EXPECT_TRUE(WaitForTrue(SupplicantIsRunning,
- kTimeoutSeconds))
- << "Failed on iteration " << iteration;
-
- // We look for supplicant so quickly that we miss when it dies on startup
- sleep(1);
- EXPECT_TRUE(SupplicantIsRunning()) << "Failed on iteration " << iteration;
-
- bool supplicant_stopped = false;
- EXPECT_TRUE(
- service->disableSupplicant(&supplicant_stopped).isOk());
- EXPECT_TRUE(supplicant_stopped);
-
- EXPECT_TRUE(WaitForTrue(SupplicantIsDead, kTimeoutSeconds))
- << "Failed on iteration " << iteration;
- }
-}
-
-} // namespace wificond
-} // namespace android
diff --git a/tests/mock_client_interface_impl.cpp b/tests/mock_client_interface_impl.cpp
index ba88f1c..8476cff 100644
--- a/tests/mock_client_interface_impl.cpp
+++ b/tests/mock_client_interface_impl.cpp
@@ -18,8 +18,9 @@
#include <vector>
+#include <linux/if_ether.h>
+
#include <wifi_system/interface_tool.h>
-#include <wifi_system/supplicant_manager.h>
#include "wificond/net/netlink_utils.h"
#include "wificond/scanning/scan_utils.h"
@@ -28,7 +29,7 @@
namespace wificond {
const char kTestInterfaceName[] = "testwifi0";
-const uint8_t kTestInterfaceMacAddress[] = {0x10, 0x20, 0xfe, 0xae, 0x2d, 0xc2};
+const std::array<uint8_t, ETH_ALEN> kTestInterfaceMacAddress = {0x10, 0x20, 0xfe, 0xae, 0x2d, 0xc2};
const uint32_t kTestInterfaceIndex = 42;
const uint32_t kTestWiphyIndex = 2;
@@ -40,9 +41,7 @@
kTestWiphyIndex,
kTestInterfaceName,
kTestInterfaceIndex,
- std::vector<uint8_t>(
- kTestInterfaceMacAddress,
- kTestInterfaceMacAddress + arraysize(kTestInterfaceMacAddress)),
+ std::array<uint8_t, ETH_ALEN>(kTestInterfaceMacAddress),
interface_tool,
netlink_utils,
scan_utils) {}
diff --git a/tests/mock_i_send_mgmt_frame_event.h b/tests/mock_i_send_mgmt_frame_event.h
new file mode 100644
index 0000000..30b7da7
--- /dev/null
+++ b/tests/mock_i_send_mgmt_frame_event.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef WIFICOND_TESTS_MOCK_I_SEND_MGMT_FRAME_EVENT_H_
+#define WIFICOND_TESTS_MOCK_I_SEND_MGMT_FRAME_EVENT_H_
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "android/net/wifi/ISendMgmtFrameEvent.h"
+
+namespace android {
+namespace wificond {
+
+class MockISendMgmtFrameEvent
+ : public ::android::net::wifi::ISendMgmtFrameEvent {
+ public:
+ virtual ~MockISendMgmtFrameEvent() override = default;
+
+ MOCK_METHOD0(onAsBinder, ::android::IBinder*());
+ MOCK_METHOD1(OnAck, ::android::binder::Status(int elapsed_time_ms));
+ MOCK_METHOD1(OnFailure, ::android::binder::Status(int reason));
+};
+
+}
+}
+
+#endif // WIFICOND_TESTS_MOCK_I_SEND_MGMT_FRAME_EVENT_H_
diff --git a/tests/mock_netlink_utils.h b/tests/mock_netlink_utils.h
index fd0868f..708a385 100644
--- a/tests/mock_netlink_utils.h
+++ b/tests/mock_netlink_utils.h
@@ -30,10 +30,13 @@
~MockNetlinkUtils() override = default;
MOCK_METHOD1(GetWiphyIndex, bool(uint32_t* out_wiphy_index));
+ MOCK_METHOD2(GetWiphyIndex,
+ bool(uint32_t* out_wiphy_index, const std::string& iface_name));
MOCK_METHOD1(UnsubscribeMlmeEvent, void(uint32_t interface_index));
MOCK_METHOD1(UnsubscribeRegDomainChange, void(uint32_t wiphy_index));
MOCK_METHOD1(UnsubscribeStationEvent, void(uint32_t interface_index));
MOCK_METHOD1(UnsubscribeChannelSwitchEvent, void(uint32_t interface_index));
+ MOCK_METHOD1(UnsubscribeFrameTxStatusEvent, void(uint32_t interface_index));
MOCK_METHOD1(GetProtocolFeatures, bool(uint32_t* features));
MOCK_METHOD2(SetInterfaceMode,
@@ -50,6 +53,9 @@
MOCK_METHOD2(SubscribeChannelSwitchEvent,
void(uint32_t interface_index,
OnChannelSwitchEventHandler handler));
+ MOCK_METHOD2(SubscribeFrameTxStatusEvent,
+ void(uint32_t interface_index,
+ OnFrameTxStatusEventHandler handler));
MOCK_METHOD2(GetInterfaces,
bool(uint32_t wiphy_index,
@@ -59,6 +65,11 @@
BandInfo* band_info,
ScanCapabilities* scan_capabilities,
WiphyFeatures* wiphy_features));
+ MOCK_METHOD4(SendMgmtFrame,
+ bool(uint32_t interface_index,
+ const std::vector<uint8_t>& frame,
+ int32_t mcs,
+ uint64_t* out_cookie));
}; // class MockNetlinkUtils
diff --git a/tests/mock_scan_utils.h b/tests/mock_scan_utils.h
index 9a8fd93..eb7e9c7 100644
--- a/tests/mock_scan_utils.h
+++ b/tests/mock_scan_utils.h
@@ -49,13 +49,12 @@
const std::vector<uint32_t>& freqs,
int* error_code));
- MOCK_METHOD10(StartScheduledScan, bool(
+ MOCK_METHOD9(StartScheduledScan, bool(
uint32_t interface_index,
const SchedScanIntervalSetting& interval_setting,
int32_t rssi_threshold_2g,
int32_t rssi_threshold_5g,
- bool request_random_mac,
- bool request_low_power,
+ const SchedScanReqFlags& req_flags,
const std::vector<std::vector<uint8_t>>& scan_ssids,
const std::vector<std::vector<uint8_t>>& match_ssids,
const std::vector<uint32_t>& freqs,
diff --git a/tests/netlink_utils_unittest.cpp b/tests/netlink_utils_unittest.cpp
index 4e7fd56..34f5c21 100644
--- a/tests/netlink_utils_unittest.cpp
+++ b/tests/netlink_utils_unittest.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <array>
#include <memory>
#include <string>
#include <vector>
@@ -58,19 +59,23 @@
constexpr uint32_t kFakeProtocolFeatures = 0x02;
constexpr uint16_t kFakeWiphyIndex = 8;
constexpr uint16_t kFakeWiphyIndex1 = 10;
+constexpr uint64_t kFakeCookie = 42;
constexpr int kFakeErrorCode = EIO;
+constexpr int32_t kFakeMcs = 5;
constexpr bool kFakeSupportsRandomMacOneshotScan = true;
constexpr bool kFakeSupportsRandomMacSchedScan = false;
const char kFakeInterfaceName[] = "testif0";
const char kFakeCountryCode[] = "US";
const uint32_t kFakeInterfaceIndex = 34;
const uint32_t kFakeInterfaceIndex1 = 36;
-const uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
-const uint8_t kFakeInterfaceMacAddress1[] = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress1 = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
const uint8_t kFakeExtFeaturesForLowSpanScan[] = {0x0, 0x0, 0x40};
const uint8_t kFakeExtFeaturesForLowPowerScan[] = {0x0, 0x0, 0x80};
const uint8_t kFakeExtFeaturesForHighAccuracy[] = {0x0, 0x0, 0x0, 0x1};
const uint8_t kFakeExtFeaturesForAllScanType[] = {0x0, 0x0, 0xC0, 0x1};
+const uint8_t kFakeFrame[] = {0x00, 0x01, 0x02, 0x03};
+
// Currently, control messages are only created by the kernel and sent to us.
// Therefore NL80211Packet doesn't have corresponding constructor.
@@ -367,11 +372,8 @@
NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
new_interface.AddAttribute(if_index_attr);
// Insert mac address attribute.
- std::vector<uint8_t> if_mac_addr;
- if_mac_addr.assign(
- kFakeInterfaceMacAddress,
- kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
- NL80211Attr<vector<uint8_t>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
+ std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
+ NL80211Attr<std::array<uint8_t, ETH_ALEN>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
new_interface.AddAttribute(if_mac_attr);
// Mock a valid response from kernel.
@@ -409,12 +411,9 @@
NL80211_ATTR_IFNAME, string(kFakeInterfaceName)));
expected_interface.AddAttribute(NL80211Attr<uint32_t>(
NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
- std::vector<uint8_t> if_mac_addr;
- if_mac_addr.assign(
- kFakeInterfaceMacAddress,
- kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
+ std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
expected_interface.AddAttribute(
- NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
+ NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr));
// Kernel can send us the pseduo interface packet first
vector<NL80211Packet> response = {psuedo_interface, expected_interface};
@@ -443,11 +442,9 @@
new_interface.AddAttribute(
NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
// Insert mac address attribute.
- std::vector<uint8_t> if_mac_addr(
- kFakeInterfaceMacAddress,
- kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
+ std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
new_interface.AddAttribute(
- NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
+ NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr));
// Create a new interface packet for p2p0.
NL80211Packet new_interface_p2p0(
@@ -463,11 +460,9 @@
new_interface_p2p0.AddAttribute(
NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex1));
// Insert mac address attribute.
- std::vector<uint8_t> if_mac_addr_p2p(
- kFakeInterfaceMacAddress1,
- kFakeInterfaceMacAddress1 + sizeof(kFakeInterfaceMacAddress1));
+ std::array<uint8_t, ETH_ALEN> if_mac_addr_p2p = kFakeInterfaceMacAddress1;
new_interface_p2p0.AddAttribute(
- NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr_p2p));
+ NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr_p2p));
// Mock response from kernel, including 2 interfaces.
vector<NL80211Packet> response = {new_interface_p2p0, new_interface};
@@ -835,7 +830,7 @@
// Still use NL80211_CMD_GET_REG here.
NL80211Packet get_country_code_response(
netlink_manager_->GetFamilyId(),
- NL80211_CMD_GET_PROTOCOL_FEATURES,
+ NL80211_CMD_GET_REG,
netlink_manager_->GetSequenceNumber(),
getpid());
get_country_code_response.AddAttribute(
@@ -862,5 +857,40 @@
EXPECT_FALSE(netlink_utils_->GetCountryCode(&country_code_ignored));
}
+TEST_F(NetlinkUtilsTest, CanSendMgmtFrame) {
+ // There is no specification for the response packet id for
+ // NL80211_CMD_FRAME.
+ // Still use NL80211_CMD_FRAME here.
+ NL80211Packet send_mgmt_frame_response(
+ netlink_manager_->GetFamilyId(),
+ NL80211_CMD_FRAME,
+ netlink_manager_->GetSequenceNumber(),
+ getpid());
+ send_mgmt_frame_response.AddAttribute(
+ NL80211Attr<uint64_t>(NL80211_ATTR_COOKIE, kFakeCookie));
+ vector<NL80211Packet> response = {send_mgmt_frame_response};
+
+ EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _))
+ .WillOnce(DoAll(MakeupResponse(response), Return(true)));
+
+ uint64_t cookie;
+ EXPECT_TRUE(netlink_utils_->SendMgmtFrame(kFakeInterfaceIndex,
+ vector<uint8_t>(std::begin(kFakeFrame), std::end(kFakeFrame)),
+ kFakeMcs, &cookie));
+ EXPECT_EQ(kFakeCookie, cookie);
+}
+
+TEST_F(NetlinkUtilsTest, CanHandleSendMgmtFrameError) {
+ // Mock an error response from kernel.
+ vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
+ EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
+ WillOnce(DoAll(MakeupResponse(response), Return(true)));
+
+ uint64_t cookie_ignored;
+ EXPECT_FALSE(netlink_utils_->SendMgmtFrame(kFakeInterfaceIndex,
+ vector<uint8_t>(std::begin(kFakeFrame), std::end(kFakeFrame)),
+ kFakeMcs, &cookie_ignored));
+}
+
} // namespace wificond
} // namespace android
diff --git a/tests/scan_result_unittest.cpp b/tests/scan_result_unittest.cpp
index 01dcfd7..facda6f 100644
--- a/tests/scan_result_unittest.cpp
+++ b/tests/scan_result_unittest.cpp
@@ -14,14 +14,18 @@
* limitations under the License.
*/
+#include <array>
#include <vector>
+#include <linux/if_ether.h>
+
#include <gtest/gtest.h>
#include "wificond/scanning/scan_result.h"
using ::com::android::server::wifi::wificond::NativeScanResult;
using ::com::android::server::wifi::wificond::RadioChainInfo;
+using std::array;
using std::vector;
namespace android {
@@ -32,7 +36,7 @@
const uint8_t kFakeSsid[] =
{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
-const uint8_t kFakeBssid[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const array<uint8_t, ETH_ALEN> kFakeBssid = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
const uint8_t kFakeIE[] = {0x05, 0x11, 0x32, 0x11};
constexpr uint32_t kFakeFrequency = 5240;
constexpr int32_t kFakeSignalMbm= -32;
@@ -49,7 +53,7 @@
TEST_F(ScanResultTest, ParcelableTest) {
std::vector<uint8_t> ssid(kFakeSsid, kFakeSsid + sizeof(kFakeSsid));
- std::vector<uint8_t> bssid(kFakeBssid, kFakeBssid + sizeof(kFakeBssid));
+ array<uint8_t, ETH_ALEN> bssid = kFakeBssid;
std::vector<uint8_t> ie(kFakeIE, kFakeIE + sizeof(kFakeIE));
std::vector<RadioChainInfo> radio_chain_infos;
radio_chain_infos.emplace_back(
diff --git a/tests/scan_utils_unittest.cpp b/tests/scan_utils_unittest.cpp
index 17f000b..f8ec523 100644
--- a/tests/scan_utils_unittest.cpp
+++ b/tests/scan_utils_unittest.cpp
@@ -56,6 +56,7 @@
constexpr int32_t kFake5gRssiThreshold = -77;
constexpr bool kFakeUseRandomMAC = true;
constexpr bool kFakeRequestLowPower = true;
+constexpr bool kFakeRequestSchedScanRelativeRssi = true;
constexpr int kFakeScanType = IWifiScannerImpl::SCAN_TYPE_LOW_SPAN;
// Currently, control messages are only created by the kernel and sent to us.
@@ -151,7 +152,6 @@
DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
-
int errno_ignored;
EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC,
kFakeScanType, {}, {}, &errno_ignored));
@@ -273,12 +273,16 @@
DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
+
+ const SchedScanReqFlags req_flags = {
+ kFakeUseRandomMAC, kFakeRequestLowPower, kFakeRequestSchedScanRelativeRssi
+ };
int errno_ignored;
EXPECT_TRUE(scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
SchedScanIntervalSetting(),
- kFake2gRssiThreshold, kFake5gRssiThreshold,
- kFakeUseRandomMAC, kFakeRequestLowPower, {}, {}, {}, &errno_ignored));
+ kFake2gRssiThreshold, kFake5gRssiThreshold, req_flags, {}, {}, {},
+ &errno_ignored));
// TODO(b/34231420): Add validation of requested scan ssids, threshold,
// and frequencies.
}
@@ -291,12 +295,15 @@
DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)).
WillOnce(Invoke(bind(
AppendMessageAndReturn, response, true, _1, _2)));
+ const SchedScanReqFlags req_flags = {
+ kFakeUseRandomMAC, kFakeRequestLowPower, kFakeRequestSchedScanRelativeRssi
+ };
int error_code;
EXPECT_FALSE(scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
SchedScanIntervalSetting(),
kFake2gRssiThreshold, kFake5gRssiThreshold,
- kFakeUseRandomMAC, kFakeRequestLowPower, {}, {}, {}, &error_code));
+ req_flags, {}, {}, {}, &error_code));
EXPECT_EQ(kFakeErrorCode, error_code);
}
@@ -311,11 +318,14 @@
NL80211_ATTR_SCAN_FLAGS, NL80211_SCAN_FLAG_LOW_POWER)),
_));
int errno_ignored;
+ const SchedScanReqFlags req_flags = {
+ false, true, false
+ };
scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
SchedScanIntervalSetting(),
kFake2gRssiThreshold, kFake5gRssiThreshold,
- false, true, {}, {}, {}, &errno_ignored);
+ req_flags, {}, {}, {}, &errno_ignored);
}
TEST_F(ScanUtilsTest, CanSpecifyScanPlansForSchedScanRequest) {
@@ -332,12 +342,14 @@
SchedScanIntervalSetting interval_setting{
{{kFakeScheduledScanIntervalMs, 10 /* repeated times */}},
kFakeScheduledScanIntervalMs * 3 /* interval for infinite scans */};
-
+ const SchedScanReqFlags req_flags = {
+ kFakeUseRandomMAC, kFakeRequestLowPower, kFakeRequestSchedScanRelativeRssi
+ };
scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
interval_setting,
kFake2gRssiThreshold, kFake5gRssiThreshold,
- kFakeUseRandomMAC, kFakeRequestLowPower, {}, {}, {}, &errno_ignored);
+ req_flags, {}, {}, {}, &errno_ignored);
}
TEST_F(ScanUtilsTest, CanSpecifySingleIntervalForSchedScanRequest) {
@@ -352,12 +364,14 @@
_));
int errno_ignored;
SchedScanIntervalSetting interval_setting{{}, kFakeScheduledScanIntervalMs};
-
+ const SchedScanReqFlags req_flags = {
+ kFakeUseRandomMAC, kFakeRequestLowPower, kFakeRequestSchedScanRelativeRssi
+ };
scan_utils_.StartScheduledScan(
kFakeInterfaceIndex,
interval_setting,
kFake2gRssiThreshold, kFake5gRssiThreshold,
- kFakeUseRandomMAC, kFakeRequestLowPower, {}, {}, {}, &errno_ignored);
+ req_flags, {}, {}, {}, &errno_ignored);
}
TEST_F(ScanUtilsTest, CanPrioritizeLastSeenSinceBootNetlinkAttribute) {
diff --git a/tests/scanner_unittest.cpp b/tests/scanner_unittest.cpp
index 463ab83..39a591e 100644
--- a/tests/scanner_unittest.cpp
+++ b/tests/scanner_unittest.cpp
@@ -19,8 +19,6 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <wifi_system_test/mock_interface_tool.h>
-#include <wifi_system_test/mock_supplicant_manager.h>
-
#include "android/net/wifi/IWifiScannerImpl.h"
#include "wificond/scanning/offload/offload_scan_utils.h"
#include "wificond/scanning/scanner_impl.h"
@@ -37,9 +35,11 @@
using ::android::net::wifi::IWifiScannerImpl;
using ::android::wifi_system::MockInterfaceTool;
using ::com::android::server::wifi::wificond::SingleScanSettings;
+using ::com::android::server::wifi::wificond::PnoNetwork;
using ::com::android::server::wifi::wificond::PnoSettings;
using ::com::android::server::wifi::wificond::NativeScanResult;
using android::hardware::wifi::offload::V1_0::ScanResult;
+using ::testing::Eq;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
@@ -81,8 +81,7 @@
const SchedScanIntervalSetting& interval_setting,
int32_t /* rssi_threshold_2g */,
int32_t /* rssi_threshold_5g */,
- bool /* request_random_mac */,
- bool /* request_low_power_scan */,
+ const SchedScanReqFlags& /* req_flags */,
const std::vector<std::vector<uint8_t>>& /* scan_ssids */,
const std::vector<std::vector<uint8_t>>& /* match_ssids */,
const std::vector<uint32_t>& /* freqs */,
@@ -92,6 +91,21 @@
return true;
}
+bool CaptureSchedScanReqFlags(
+ uint32_t /* interface_index */,
+ const SchedScanIntervalSetting& /* interval_setting */,
+ int32_t /* rssi_threshold_2g */,
+ int32_t /* rssi_threshold_5g */,
+ const SchedScanReqFlags& req_flags,
+ const std::vector<std::vector<uint8_t>>& /* scan_ssids */,
+ const std::vector<std::vector<uint8_t>>& /* match_ssids */,
+ const std::vector<uint32_t>& /* freqs */,
+ int* /* error_code */,
+ SchedScanReqFlags* out_req_flags) {
+ *out_req_flags = req_flags;
+ return true;
+}
+
bool ReturnOffloadScanResults(
std::vector<NativeScanResult>* native_scan_results_,
const std::vector<ScanResult>& offload_scan_results) {
@@ -321,7 +335,7 @@
&scan_utils_, offload_service_utils_);
EXPECT_CALL(
scan_utils_,
- StartScheduledScan(_, _, _, _, _, false, _, _, _, _)).
+ StartScheduledScan(_, _, _, _, _, _, _, _, _)).
WillOnce(Return(true));
EXPECT_TRUE(scanner_impl.startPnoScan(PnoSettings(), &success).isOk());
EXPECT_TRUE(success);
@@ -336,12 +350,16 @@
ScannerImpl scanner_impl(kFakeInterfaceIndex, scan_capabilities_,
wiphy_features_, &client_interface_impl_,
&scan_utils_, offload_service_utils_);
+ SchedScanReqFlags req_flags = {};
EXPECT_CALL(
scan_utils_,
- StartScheduledScan(_, _, _, _, _, true, _, _, _, _)).
- WillOnce(Return(true));
+ StartScheduledScan(_, _, _, _, _, _, _, _, _)).
+ WillOnce(Invoke(bind(
+ CaptureSchedScanReqFlags,
+ _1, _2, _3, _4, _5, _6, _7, _8, _9, &req_flags)));
EXPECT_TRUE(scanner_impl.startPnoScan(PnoSettings(), &success).isOk());
EXPECT_TRUE(success);
+ EXPECT_TRUE(req_flags.request_low_power);
}
TEST_F(ScannerTest, TestStopPnoScanViaNetlink) {
@@ -392,7 +410,7 @@
EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
.WillOnce(Return(false));
EXPECT_CALL(*offload_scan_manager_, stopScan(_)).Times(0);
- EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _, _))
+ EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _))
.WillOnce(Return(true));
EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
EXPECT_TRUE(scanner_impl_->startPnoScan(PnoSettings(), &success).isOk());
@@ -416,7 +434,7 @@
scan_capabilities_, wiphy_features_,
&client_interface_impl_,
&scan_utils_, offload_service_utils_));
- EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _, _))
+ EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _))
.WillOnce(Return(true));
EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
scanner_impl_->startPnoScan(PnoSettings(), &success);
@@ -476,7 +494,7 @@
scan_capabilities_, wiphy_features_,
&client_interface_impl_,
&scan_utils_, offload_service_utils_));
- EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _, _))
+ EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _))
.WillOnce(Return(true));
EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
EXPECT_TRUE(scanner_impl_->startPnoScan(PnoSettings(), &success).isOk());
@@ -511,10 +529,10 @@
SchedScanIntervalSetting interval_setting;
EXPECT_CALL(
scan_utils_,
- StartScheduledScan(_, _, _, _, _, _, _, _, _, _)).
+ StartScheduledScan(_, _, _, _, _, _, _, _, _)).
WillOnce(Invoke(bind(
CaptureSchedScanIntervalSetting,
- _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, &interval_setting)));
+ _1, _2, _3, _4, _5, _6, _7, _8, _9, &interval_setting)));
bool success_ignored = 0;
EXPECT_TRUE(scanner.startPnoScan(pno_settings, &success_ignored).isOk());
@@ -544,10 +562,10 @@
SchedScanIntervalSetting interval_setting;
EXPECT_CALL(
scan_utils_,
- StartScheduledScan(_, _, _, _, _, _, _, _, _, _)).
+ StartScheduledScan(_, _, _, _, _, _, _, _, _)).
WillOnce(Invoke(bind(
CaptureSchedScanIntervalSetting,
- _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, &interval_setting)));
+ _1, _2, _3, _4, _5, _6, _7, _8, _9, &interval_setting)));
bool success_ignored = 0;
EXPECT_TRUE(scanner.startPnoScan(pno_settings, &success_ignored).isOk());
@@ -556,5 +574,165 @@
EXPECT_EQ(kFakeScanIntervalMs, interval_setting.final_interval_ms);
}
+TEST_F(ScannerTest, TestGetScanResultsOnInvalidatedScannerImpl) {
+ vector<NativeScanResult> scan_results;
+ scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
+ scan_capabilities_, wiphy_features_,
+ &client_interface_impl_,
+ &scan_utils_, offload_service_utils_));
+ scanner_impl_->Invalidate();
+ EXPECT_CALL(scan_utils_, GetScanResult(_, _))
+ .Times(0)
+ .WillOnce(Return(true));
+ EXPECT_TRUE(scanner_impl_->getScanResults(&scan_results).isOk());
+}
+
+// Verify that pno scanning starts with no errors given a non-empty frequency list.
+TEST_F(ScannerTest, TestStartPnoScanWithNonEmptyFrequencyList) {
+ bool success = false;
+ ScanCapabilities scan_capabilities_test_frequencies(
+ 1 /* max_num_scan_ssids */,
+ 1 /* max_num_sched_scan_ssids */,
+ 1 /* max_match_sets */,
+ 0,
+ kFakeScanIntervalMs * PnoSettings::kSlowScanIntervalMultiplier / 1000,
+ PnoSettings::kFastScanIterations);
+ EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
+ .Times(1)
+ .WillRepeatedly(Return(false));
+ ScannerImpl scanner_impl(kFakeInterfaceIndex, scan_capabilities_test_frequencies,
+ wiphy_features_, &client_interface_impl_,
+ &scan_utils_, offload_service_utils_);
+
+ PnoSettings pno_settings;
+ PnoNetwork network;
+ network.is_hidden_ = false;
+ network.frequencies_.push_back(2412);
+ pno_settings.pno_networks_.push_back(network);
+
+ std::vector<uint32_t> expected_freqs;
+ expected_freqs.push_back(2412);
+ EXPECT_CALL(
+ scan_utils_,
+ StartScheduledScan(_, _, _, _, _, _, _, Eq(expected_freqs), _)).
+ WillOnce(Return(true));
+ EXPECT_TRUE(scanner_impl.startPnoScan(pno_settings, &success).isOk());
+ EXPECT_TRUE(success);
+}
+
+// Verify that a unique set of frequencies is passed in for scanning when the input
+// contains duplicate frequencies.
+TEST_F(ScannerTest, TestStartPnoScanWithFrequencyListNoDuplicates) {
+ bool success = false;
+ ScanCapabilities scan_capabilities_test_frequencies(
+ 1 /* max_num_scan_ssids */,
+ 1 /* max_num_sched_scan_ssids */,
+ 2 /* max_match_sets */,
+ 0,
+ kFakeScanIntervalMs * PnoSettings::kSlowScanIntervalMultiplier / 1000,
+ PnoSettings::kFastScanIterations);
+ EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
+ .Times(1)
+ .WillRepeatedly(Return(false));
+ ScannerImpl scanner_impl(kFakeInterfaceIndex, scan_capabilities_test_frequencies,
+ wiphy_features_, &client_interface_impl_,
+ &scan_utils_, offload_service_utils_);
+
+ PnoSettings pno_settings;
+ PnoNetwork network;
+ PnoNetwork network2;
+ network.is_hidden_ = false;
+ network.frequencies_.push_back(2412);
+ network.frequencies_.push_back(2437);
+ network2.is_hidden_ = false;
+ network2.frequencies_.push_back(2437);
+ network2.frequencies_.push_back(2462);
+ pno_settings.pno_networks_.push_back(network);
+ pno_settings.pno_networks_.push_back(network2);
+
+ std::vector<uint32_t> expected_freqs;
+ expected_freqs.push_back(2412);
+ expected_freqs.push_back(2437);
+ expected_freqs.push_back(2462);
+ EXPECT_CALL(
+ scan_utils_,
+ StartScheduledScan(_, _, _, _, _, _, _, Eq(expected_freqs), _)).
+ WillOnce(Return(true));
+ EXPECT_TRUE(scanner_impl.startPnoScan(pno_settings, &success).isOk());
+ EXPECT_TRUE(success);
+}
+
+// Verify that if more than 30% of networks don't have frequency data then a list of default
+// frequencies will be added to the scan.
+TEST_F(ScannerTest, TestStartPnoScanWithFrequencyListFallbackMechanism) {
+ bool success = false;
+ ScanCapabilities scan_capabilities_test_frequencies(
+ 1 /* max_num_scan_ssids */,
+ 1 /* max_num_sched_scan_ssids */,
+ 2 /* max_match_sets */,
+ 0,
+ kFakeScanIntervalMs * PnoSettings::kSlowScanIntervalMultiplier / 1000,
+ PnoSettings::kFastScanIterations);
+ EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
+ .Times(1)
+ .WillRepeatedly(Return(false));
+ ScannerImpl scanner_impl(kFakeInterfaceIndex, scan_capabilities_test_frequencies,
+ wiphy_features_, &client_interface_impl_,
+ &scan_utils_, offload_service_utils_);
+
+ PnoSettings pno_settings;
+ PnoNetwork network;
+ PnoNetwork network2;
+ network.is_hidden_ = false;
+ network.frequencies_.push_back(5640);
+ network2.is_hidden_ = false;
+ pno_settings.pno_networks_.push_back(network);
+ pno_settings.pno_networks_.push_back(network2);
+
+ std::set<int32_t> default_frequencies = {2412, 2417, 2422, 2427, 2432, 2437, 2447, 2452, 2457,
+ 2462, 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805};
+ default_frequencies.insert(5640); // add frequency from saved network
+ vector<uint32_t> expected_frequencies(default_frequencies.begin(), default_frequencies.end());
+ EXPECT_CALL(
+ scan_utils_,
+ StartScheduledScan(_, _, _, _, _, _, _, Eq(expected_frequencies), _)).
+ WillOnce(Return(true));
+ EXPECT_TRUE(scanner_impl.startPnoScan(pno_settings, &success).isOk());
+ EXPECT_TRUE(success);
+}
+
+// Verify that when there is no frequency data all pno networks, an empty list is passed into
+// StartScheduledScan in order to scan all frequencies.
+TEST_F(ScannerTest, TestStartPnoScanEmptyList) {
+ bool success = false;
+ ScanCapabilities scan_capabilities_test_frequencies(
+ 1 /* max_num_scan_ssids */,
+ 1 /* max_num_sched_scan_ssids */,
+ 2 /* max_match_sets */,
+ 0,
+ kFakeScanIntervalMs * PnoSettings::kSlowScanIntervalMultiplier / 1000,
+ PnoSettings::kFastScanIterations);
+ EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
+ .Times(1)
+ .WillRepeatedly(Return(false));
+ ScannerImpl scanner_impl(kFakeInterfaceIndex, scan_capabilities_test_frequencies,
+ wiphy_features_, &client_interface_impl_,
+ &scan_utils_, offload_service_utils_);
+
+ PnoSettings pno_settings;
+ PnoNetwork network;
+ PnoNetwork network2;
+ network.is_hidden_ = false;
+ network2.is_hidden_ = false;
+ pno_settings.pno_networks_.push_back(network);
+ pno_settings.pno_networks_.push_back(network2);
+ EXPECT_CALL(
+ scan_utils_,
+ StartScheduledScan(_, _, _, _, _, _, _, Eq(vector<uint32_t>{}), _)).
+ WillOnce(Return(true));
+ EXPECT_TRUE(scanner_impl.startPnoScan(pno_settings, &success).isOk());
+ EXPECT_TRUE(success);
+}
+
} // namespace wificond
} // namespace android
diff --git a/tests/server_unittest.cpp b/tests/server_unittest.cpp
index 58a275c..2175cf9 100644
--- a/tests/server_unittest.cpp
+++ b/tests/server_unittest.cpp
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include <array>
#include <memory>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include <wifi_system_test/mock_hostapd_manager.h>
#include <wifi_system_test/mock_interface_tool.h>
-#include <wifi_system_test/mock_supplicant_manager.h>
#include "android/net/wifi/IApInterface.h"
#include "wificond/tests/mock_netlink_manager.h"
@@ -30,12 +29,8 @@
using android::net::wifi::IApInterface;
using android::net::wifi::IClientInterface;
-using android::wifi_system::HostapdManager;
using android::wifi_system::InterfaceTool;
-using android::wifi_system::MockHostapdManager;
using android::wifi_system::MockInterfaceTool;
-using android::wifi_system::MockSupplicantManager;
-using android::wifi_system::SupplicantManager;
using std::unique_ptr;
using std::vector;
using testing::Eq;
@@ -59,9 +54,9 @@
const uint32_t kFakeInterfaceIndex = 34;
const uint32_t kFakeInterfaceIndex1 = 36;
const uint32_t kFakeInterfaceIndexP2p = 36;
-const uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
-const uint8_t kFakeInterfaceMacAddress1[] = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
-const uint8_t kFakeInterfaceMacAddressP2p[] = {0x15, 0x24, 0xef, 0x27, 0x12, 0xff};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress1 = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddressP2p = {0x15, 0x24, 0xef, 0x27, 0x12, 0xff};
// This is a helper function to mock the behavior of
// NetlinkUtils::GetInterfaces().
@@ -85,16 +80,13 @@
void SetUp() override {
ON_CALL(*if_tool_, SetUpState(_, _)).WillByDefault(Return(true));
ON_CALL(*netlink_utils_, GetWiphyIndex(_)).WillByDefault(Return(true));
+ ON_CALL(*netlink_utils_, GetWiphyIndex(_, _)).WillByDefault(Return(true));
ON_CALL(*netlink_utils_, GetInterfaces(_, _))
.WillByDefault(Invoke(bind(
MockGetInterfacesResponse, mock_interfaces, true, _1, _2)));
}
NiceMock<MockInterfaceTool>* if_tool_ = new NiceMock<MockInterfaceTool>;
- NiceMock<MockSupplicantManager>* supplicant_manager_ =
- new NiceMock<MockSupplicantManager>;
- NiceMock<MockHostapdManager>* hostapd_manager_ =
- new NiceMock<MockHostapdManager>;
unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
new NiceMock<MockNetlinkManager>()};
@@ -108,28 +100,20 @@
InterfaceInfo(
kFakeInterfaceIndex,
std::string(kFakeInterfaceName),
- vector<uint8_t>(
- kFakeInterfaceMacAddress,
- kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress))),
+ std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddress)),
// AP Interface
InterfaceInfo(
kFakeInterfaceIndex1,
std::string(kFakeInterfaceName1),
- vector<uint8_t>(
- kFakeInterfaceMacAddress1,
- kFakeInterfaceMacAddress1 + sizeof(kFakeInterfaceMacAddress1))),
+ std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddress1)),
// p2p interface
InterfaceInfo(
kFakeInterfaceIndexP2p,
std::string(kFakeInterfaceNameP2p),
- vector<uint8_t>(
- kFakeInterfaceMacAddressP2p,
- kFakeInterfaceMacAddressP2p + sizeof(kFakeInterfaceMacAddressP2p)))
+ std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddressP2p))
};
Server server_{unique_ptr<InterfaceTool>(if_tool_),
- unique_ptr<SupplicantManager>(supplicant_manager_),
- unique_ptr<HostapdManager>(hostapd_manager_),
netlink_utils_.get(),
scan_utils_.get()};
}; // class ServerTest
@@ -172,9 +156,6 @@
TEST_F(ServerTest, CanTeardownApInterface) {
sp<IApInterface> ap_if;
- // When we tear down the interface, we expect the iface to be unloaded.
- EXPECT_CALL(*if_tool_, SetUpState(StrEq(kFakeInterfaceName), Eq(false)));
-
EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName, &ap_if).isOk());
EXPECT_NE(nullptr, ap_if.get());
@@ -191,9 +172,6 @@
TEST_F(ServerTest, CanTeardownClientInterface) {
sp<IClientInterface> client_if;
- // When we tear down the interface, we expect the iface to be unloaded.
- EXPECT_CALL(*if_tool_, SetUpState(StrEq(kFakeInterfaceName), Eq(false)));
-
EXPECT_TRUE(server_.createClientInterface(
kFakeInterfaceName, &client_if).isOk());
EXPECT_NE(nullptr, client_if.get());
@@ -209,38 +187,6 @@
EXPECT_TRUE(success);
}
-TEST_F(ServerTest, ShouldReportEnableFailure) {
- EXPECT_CALL(*supplicant_manager_, StartSupplicant())
- .WillOnce(Return(false));
- bool success = true;
- EXPECT_TRUE(server_.enableSupplicant(&success).isOk());
- EXPECT_FALSE(success);
-}
-
-TEST_F(ServerTest, ShouldReportenableSuccess) {
- EXPECT_CALL(*supplicant_manager_, StartSupplicant())
- .WillOnce(Return(true));
- bool success = false;
- EXPECT_TRUE(server_.enableSupplicant(&success).isOk());
- EXPECT_TRUE(success);
-}
-
-TEST_F(ServerTest, ShouldReportDisableFailure) {
- EXPECT_CALL(*supplicant_manager_, StopSupplicant())
- .WillOnce(Return(false));
- bool success = true;
- EXPECT_TRUE(server_.disableSupplicant(&success).isOk());
- EXPECT_FALSE(success);
-}
-
-TEST_F(ServerTest, ShouldReportDisableSuccess) {
- EXPECT_CALL(*supplicant_manager_, StopSupplicant())
- .WillOnce(Return(true));
- bool success = false;
- EXPECT_TRUE(server_.disableSupplicant(&success).isOk());
- EXPECT_TRUE(success);
-}
-
TEST_F(ServerTest, CanCreateTeardownApAndClientInterface) {
sp<IClientInterface> client_if;
sp<IApInterface> ap_if;
@@ -251,10 +197,6 @@
EXPECT_TRUE(server_.createApInterface(kFakeInterfaceName1, &ap_if).isOk());
EXPECT_NE(nullptr, ap_if.get());
- // When we tear down the interfaces, we expect the iface to be unloaded.
- EXPECT_CALL(*if_tool_, SetUpState(StrEq(kFakeInterfaceName), Eq(false)));
- EXPECT_CALL(*if_tool_, SetUpState(StrEq(kFakeInterfaceName1), Eq(false)));
-
bool success = true;
// Try to remove an invalid iface name, this should fail.
EXPECT_TRUE(server_.tearDownClientInterface(