LOCAL_CPPFLAGS := $(wificond_cpp_flags)
LOCAL_C_INCLUDES := $(wificond_includes)
LOCAL_SRC_FILES := \
- tests/main.cpp \
+ tests/ap_interface_impl_unittest.cpp \
tests/looper_backed_event_loop_unittest.cpp \
+ tests/main.cpp \
tests/nl80211_attribute_unittest.cpp \
tests/nl80211_packet_unittest.cpp \
tests/server_unittest.cpp
// WiFi access point.
interface IApInterface {
+ const int ENCRYPTION_TYPE_NONE = 0;
+ const int ENCRYPTION_TYPE_WPA = 1;
+ const int ENCRYPTION_TYPE_WPA2 = 2;
+
+ // Start up an instance of hostapd associated with this interface.
+ // @return true on success.
+ boolean startHostapd();
+
+ // Stop a previously started instance of hostapd.
+ // @return true on success.
+ boolean stopHostapd();
+
+ // Write out a configuration file for hostapd. This will be used on the next
+ // successful call to StartHostapd(). Returns true on success.
+ //
+ // @param ssid string of <=32 bytes to use as the SSID for this AP.
+ // @param isHidden True iff the AP should not broadcast its SSID.
+ // @param channel WiFi channel to expose the AP on.
+ // @param encryptionType one of ENCRYPTION_TYPE* above.
+ // @param passphrase string of bytes to use as the passphrase for this AP.
+ // Ignored if encryptionType is None.
+ // @return true on success.
+ boolean writeHostapdConfig(in byte[] ssid, boolean isHidden, int channel,
+ int encryptionType, in byte[] passphrase);
+
}
#include "wificond/ap_interface_binder.h"
+#include <android-base/logging.h>
+#include <wifi_system/hostapd_manager.h>
+
+#include "wificond/ap_interface_impl.h"
+
+using android::wifi_system::HostapdManager;
+
namespace android {
namespace wificond {
ApInterfaceBinder::~ApInterfaceBinder() {
}
+binder::Status ApInterfaceBinder::startHostapd(bool* out_success) {
+ *out_success = false;
+ if (!impl_) {
+ LOG(WARNING) << "Cannot start hostapd on dead ApInterface.";
+ return binder::Status::ok();
+ }
+ *out_success = impl_->StartHostapd();
+ 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();
+ return binder::Status::ok();
+}
+
+binder::Status ApInterfaceBinder::writeHostapdConfig(
+ const std::vector<uint8_t>& ssid,
+ bool is_hidden,
+ int32_t channel,
+ int32_t binder_encryption_type,
+ const std::vector<uint8_t>& passphrase,
+ bool* out_success) {
+ *out_success = false;
+ if (!impl_) {
+ LOG(WARNING) << "Cannot set config on dead ApInterface.";
+ return binder::Status::ok();
+ }
+
+ HostapdManager::EncryptionType encryption_type;
+ switch (binder_encryption_type) {
+ case IApInterface::ENCRYPTION_TYPE_NONE:
+ encryption_type = HostapdManager::EncryptionType::kOpen;
+ break;
+ case IApInterface::ENCRYPTION_TYPE_WPA:
+ encryption_type = HostapdManager::EncryptionType::kWpa;
+ break;
+ case IApInterface::ENCRYPTION_TYPE_WPA2:
+ encryption_type = HostapdManager::EncryptionType::kWpa2;
+ break;
+ default:
+ LOG(ERROR) << "Unknown encryption type: " << binder_encryption_type;
+ return binder::Status::ok();
+ }
+
+ *out_success = impl_->WriteHostapdConfig(
+ ssid, is_hidden, channel, encryption_type, passphrase);
+
+ return binder::Status::ok();
+}
+
} // namespace wificond
} // namespace android
// by remote processes are possible.
void NotifyImplDead() { impl_ = nullptr; }
+ binder::Status startHostapd(bool* out_success) override;
+ binder::Status stopHostapd(bool* out_success) override;
+ binder::Status writeHostapdConfig(const std::vector<uint8_t>& ssid,
+ bool is_hidden,
+ int32_t channel,
+ int32_t encryption_type,
+ const std::vector<uint8_t>& passphrase,
+ bool* out_success) override;
+
private:
ApInterfaceImpl* impl_;
#include "wificond/ap_interface_binder.h"
using android::net::wifi::IApInterface;
+using android::wifi_system::HostapdManager;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+using EncryptionType = android::wifi_system::HostapdManager::EncryptionType;
namespace android {
namespace wificond {
-ApInterfaceImpl::ApInterfaceImpl() {
+ApInterfaceImpl::ApInterfaceImpl(const string& interface_name,
+ unique_ptr<HostapdManager> hostapd_manager)
+ : interface_name_(interface_name),
+ hostapd_manager_(std::move(hostapd_manager)) {
binder_ = new ApInterfaceBinder(this);
}
return binder_;
}
+bool ApInterfaceImpl::StartHostapd() {
+ return hostapd_manager_->StartHostapd();
+}
+
+bool ApInterfaceImpl::StopHostapd() {
+ return hostapd_manager_->StopHostapd();
+}
+
+bool ApInterfaceImpl::WriteHostapdConfig(const vector<uint8_t>& ssid,
+ bool is_hidden,
+ int32_t channel,
+ EncryptionType encryption_type,
+ const vector<uint8_t>& passphrase) {
+ string config = hostapd_manager_->CreateHostapdConfig(
+ interface_name_, ssid, is_hidden, channel, encryption_type, passphrase);
+
+ if (config.empty()) {
+ return false;
+ }
+
+ return hostapd_manager_->WriteHostapdConfig(config);
+}
+
} // namespace wificond
} // namespace android
#ifndef WIFICOND_AP_INTERFACE_IMPL_H_
#define WIFICOND_AP_INTERFACE_IMPL_H_
+#include <memory>
+#include <string>
+#include <vector>
+
#include <android-base/macros.h>
+#include <wifi_system/hostapd_manager.h>
#include "android/net/wifi/IApInterface.h"
// keep this object separate from the binder representation of itself.
class ApInterfaceImpl {
public:
- ApInterfaceImpl();
+ ApInterfaceImpl(const std::string& interface_name,
+ std::unique_ptr<wifi_system::HostapdManager> hostapd_manager);
~ApInterfaceImpl();
// Get a pointer to the binder representing this ApInterfaceImpl.
android::sp<android::net::wifi::IApInterface> GetBinder() const;
+ bool StartHostapd();
+ bool StopHostapd();
+ bool WriteHostapdConfig(
+ const std::vector<uint8_t>& ssid,
+ bool is_hidden,
+ int32_t channel,
+ wifi_system::HostapdManager::EncryptionType encryption_type,
+ const std::vector<uint8_t>& passphrase);
+
private:
+ const std::string interface_name_;
+ const std::unique_ptr<wifi_system::HostapdManager> hostapd_manager_;
android::sp<ApInterfaceBinder> binder_;
DISALLOW_COPY_AND_ASSIGN(ApInterfaceImpl);
using android::binder::Status;
using android::sp;
using android::IBinder;
+using std::string;
using std::vector;
using std::unique_ptr;
using android::net::wifi::IApInterface;
using android::wifi_hal::DriverTool;
using android::wifi_system::HalTool;
+using android::wifi_system::HostapdManager;
using android::wifi_system::InterfaceTool;
namespace android {
namespace wificond {
+namespace {
+
+const char kNetworkInterfaceName[] = "wlan0";
+
+} // namespace
Server::Server(unique_ptr<HalTool> hal_tool,
unique_ptr<InterfaceTool> if_tool,
return Status::ok();
}
- if (!SetupInterfaceForMode(DriverTool::kFirmwareModeAp)) {
+ string interface_name;
+ if (!SetupInterfaceForMode(DriverTool::kFirmwareModeAp, &interface_name)) {
return Status::ok(); // Logging was done internally
}
- unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl);
+ unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
+ interface_name,
+ unique_ptr<HostapdManager>(new HostapdManager)));
*created_interface = ap_interface->GetBinder();
ap_interfaces_.push_back(std::move(ap_interface));
return Status::ok();
return Status::ok();
}
-bool Server::SetupInterfaceForMode(int mode) {
+bool Server::SetupInterfaceForMode(int mode, string* interface_name) {
+ string result;
if (!driver_tool_->LoadDriver()) {
LOG(ERROR) << "Failed to load WiFi driver!";
return false;
// TODO: Confirm the ap interface is ready for use by checking its
// nl80211 published capabilities.
+ *interface_name = kNetworkInterfaceName;
return true;
}
#define WIFICOND_SERVER_H_
#include <memory>
+#include <string>
#include <vector>
#include <android-base/macros.h>
private:
// Does the actual work of setting up an interface for a particular mode.
+ //
// |mode| is one of WIFI_GET_FW_PATH_* defined in hardware_legacy/wifi.h.
+ // |interface_name| is a pointer to a string to store the name of Linux
+ // network interface that has been setup.
+ //
// Returns true on success, false otherwise.
- bool SetupInterfaceForMode(int mode);
+ bool SetupInterfaceForMode(int mode, std::string* interface_name);
const std::unique_ptr<wifi_system::HalTool> hal_tool_;
const std::unique_ptr<wifi_system::InterfaceTool> if_tool_;
--- /dev/null
+/*
+ * 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 <memory>
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <wifi_system_test/mock_hostapd_manager.h>
+
+#include "wificond/ap_interface_impl.h"
+
+using android::wifi_system::HostapdManager;
+using android::wifi_system::MockHostapdManager;
+using std::unique_ptr;
+using std::vector;
+using testing::NiceMock;
+using testing::Return;
+using testing::Sequence;
+using testing::_;
+
+namespace android {
+namespace wificond {
+namespace {
+
+const char kTestInterfaceName[] = "testwifi0";
+
+class ApInterfaceImplTest : public ::testing::Test {
+ protected:
+ NiceMock<MockHostapdManager>* hostapd_manager_ =
+ new NiceMock<MockHostapdManager>;
+ ApInterfaceImpl ap_interface_{kTestInterfaceName,
+ unique_ptr<HostapdManager>(hostapd_manager_)};
+}; // 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_TRUE(ap_interface_.StopHostapd());
+}
+
+TEST_F(ApInterfaceImplTest, ShouldRejectInvalidConfig) {
+ EXPECT_CALL(*hostapd_manager_, CreateHostapdConfig(_, _, _, _, _, _))
+ .WillOnce(Return(""));
+ EXPECT_CALL(*hostapd_manager_, WriteHostapdConfig(_)).Times(0);
+ EXPECT_FALSE(ap_interface_.WriteHostapdConfig(
+ vector<uint8_t>(),
+ false,
+ 0,
+ HostapdManager::EncryptionType::kWpa2,
+ vector<uint8_t>()));
+}
+
+} // namespace wificond
+} // namespace android
service wificond /system/bin/wificond
class main
+ user root
+ group wifi