LOCAL_CPPFLAGS := $(wificond_cpp_flags)
LOCAL_C_INCLUDES := $(wificond_includes)
LOCAL_SRC_FILES := \
- net/nl80211_attribute.cpp \
net/netlink_manager.cpp \
+ net/netlink_utils.cpp \
+ net/nl80211_attribute.cpp \
net/nl80211_packet.cpp
LOCAL_SHARED_LIBRARIES := \
libbase
tests/looper_backed_event_loop_unittest.cpp \
tests/main.cpp \
tests/mock_netlink_manager.cpp \
+ tests/mock_netlink_utils.cpp \
tests/netlink_manager_unittest.cpp \
tests/nl80211_attribute_unittest.cpp \
tests/nl80211_packet_unittest.cpp \
#include "wificond/ipc_constants.h"
#include "wificond/looper_backed_event_loop.h"
#include "wificond/net/netlink_manager.h"
+#include "wificond/net/netlink_utils.h"
#include "wificond/server.h"
using android::net::wifi::IWificond;
android::wificond::NetlinkManager netlink_manager(event_dispatcher.get());
CHECK(netlink_manager.Start()) << "Failed to start netlink manager";
+ android::wificond::NetlinkUtils netlink_utils(&netlink_manager);
unique_ptr<android::wificond::Server> server(new android::wificond::Server(
unique_ptr<HalTool>(new HalTool),
unique_ptr<InterfaceTool>(new InterfaceTool),
unique_ptr<DriverTool>(new DriverTool),
- &netlink_manager));
+ &netlink_utils));
RegisterServiceOrCrash(server.get());
event_dispatcher->Poll();
return true;
}
-bool NetlinkManager::GetWiphyIndex(uint32_t* out_wiphy_index) {
- NL80211Packet get_wiphy(
- GetFamilyId(),
- NL80211_CMD_GET_WIPHY,
- GetSequenceNumber(),
- getpid());
- get_wiphy.AddFlag(NLM_F_DUMP);
- vector<NL80211Packet> response;
- if (!SendMessageAndGetResponses(get_wiphy, &response)) {
- LOG(ERROR) << "Failed to get wiphy index";
- return false;
- }
- for (NL80211Packet& packet : response) {
- if (packet.GetMessageType() == NLMSG_ERROR) {
- LOG(ERROR) << "Receive ERROR message: "
- << strerror(packet.GetErrorCode());
- return false;
- }
- if (packet.GetCommand() != NL80211_CMD_NEW_WIPHY) {
- LOG(ERROR) << "Wrong command for new wiphy message";
- return false;
- }
- if (!packet.GetAttributeValue(NL80211_ATTR_WIPHY, out_wiphy_index)) {
- LOG(ERROR) << "Failed to get wiphy index from reply message";
- return false;
- }
- }
- return true;
-}
-
-bool NetlinkManager::GetInterfaceName(uint32_t wiphy_index,
- string* interface_name) {
- NL80211Packet get_interface(
- GetFamilyId(),
- NL80211_CMD_GET_INTERFACE,
- GetSequenceNumber(),
- getpid());
-
- get_interface.AddFlag(NLM_F_DUMP);
- NL80211Attr<uint32_t> wiphy(NL80211_ATTR_WIPHY, wiphy_index);
- get_interface.AddAttribute(wiphy);
- vector<NL80211Packet> response;
- if (!SendMessageAndGetResponses(get_interface, &response)) {
- LOG(ERROR) << "Failed to send GetWiphy message";
- }
- for (NL80211Packet& packet : response) {
- if (packet.GetMessageType() == NLMSG_ERROR) {
- LOG(ERROR) << "Receive ERROR message: "
- << strerror(packet.GetErrorCode());
- return false;
- }
- if (packet.GetMessageType() != GetFamilyId()) {
- LOG(ERROR) << "Wrong message type for new interface message: "
- << packet.GetMessageType();
- return false;
- }
- if (packet.GetCommand() != NL80211_CMD_NEW_INTERFACE) {
- LOG(ERROR) << "Wrong command for new interface message: "
- << packet.GetCommand();
- return false;
- }
-
- // Today we don't check NL80211_ATTR_IFTYPE because at this point of time
- // driver always reports that interface is in STATION mode. Even when we
- // are asking interfaces infomation on behalf of tethering, it is still so
- // because hostapd is supposed to set interface to AP mode later.
-
- string if_name;
- if (!packet.GetAttributeValue(NL80211_ATTR_IFNAME, &if_name)) {
- LOG(ERROR) << "Failed to get interface name";
- return false;
- }
- if (if_name == "p2p0") {
- LOG(DEBUG) << "Driver may tell a lie that p2p0 is in STATION mode,"
- <<" we need to blacklist it.";
- continue;
- }
- *interface_name = if_name;
- return true;
- }
-
- LOG(ERROR) << "Failed to get expected interface info from kernel";
- return false;
-}
-
} // namespace wificond
} // namespace android
bool SendMessageAndGetResponses(const NL80211Packet& packet,
std::vector<NL80211Packet>* response);
- // Get the wiphy index from kernel.
- // |*out_wiphy_index| returns the wiphy index from kernel.
- // Returns true on success.
- virtual bool GetWiphyIndex(uint32_t* out_wiphy_index);
-
- // Get wifi interface name from kernel.
- // |wiphy_index| is the wiphy index we get using GetWiphyIndex().
- // Returns true on success.
- virtual bool GetInterfaceName(uint32_t wiphy_index,
- std::string* interface_name);
-
private:
bool SetupSocket(android::base::unique_fd* netlink_fd);
bool WatchSocket(android::base::unique_fd* netlink_fd);
--- /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 "wificond/net/netlink_utils.h"
+
+#include <string>
+#include <vector>
+
+#include <linux/netlink.h>
+#include <linux/nl80211.h>
+
+#include <android-base/logging.h>
+
+#include "wificond/net/netlink_manager.h"
+#include "wificond/net/nl80211_packet.h"
+
+using std::string;
+using std::vector;
+
+namespace android {
+namespace wificond {
+
+NetlinkUtils::NetlinkUtils(NetlinkManager* netlink_manager)
+ : netlink_manager_(netlink_manager) {
+ if (!netlink_manager_->IsStarted()) {
+ netlink_manager_->Start();
+ }
+}
+
+NetlinkUtils::~NetlinkUtils() {}
+
+bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index) {
+ NL80211Packet get_wiphy(
+ netlink_manager_->GetFamilyId(),
+ NL80211_CMD_GET_WIPHY,
+ netlink_manager_->GetSequenceNumber(),
+ getpid());
+ get_wiphy.AddFlag(NLM_F_DUMP);
+ vector<NL80211Packet> response;
+ if (!netlink_manager_->SendMessageAndGetResponses(get_wiphy, &response)) {
+ LOG(ERROR) << "Failed to get wiphy index";
+ return false;
+ }
+ for (NL80211Packet& packet : response) {
+ if (packet.GetMessageType() == NLMSG_ERROR) {
+ LOG(ERROR) << "Receive ERROR message: "
+ << strerror(packet.GetErrorCode());
+ return false;
+ }
+ if (packet.GetMessageType() != netlink_manager_->GetFamilyId()) {
+ LOG(ERROR) << "Wrong message type for new interface message: "
+ << packet.GetMessageType();
+ return false;
+ }
+ if (packet.GetCommand() != NL80211_CMD_NEW_WIPHY) {
+ LOG(ERROR) << "Wrong command for new wiphy message";
+ return false;
+ }
+ if (!packet.GetAttributeValue(NL80211_ATTR_WIPHY, out_wiphy_index)) {
+ LOG(ERROR) << "Failed to get wiphy index from reply message";
+ return false;
+ }
+ }
+ return true;
+}
+
+bool NetlinkUtils::GetInterfaceName(uint32_t wiphy_index,
+ string* interface_name) {
+ NL80211Packet get_interface(
+ netlink_manager_->GetFamilyId(),
+ NL80211_CMD_GET_INTERFACE,
+ netlink_manager_->GetSequenceNumber(),
+ getpid());
+
+ get_interface.AddFlag(NLM_F_DUMP);
+ NL80211Attr<uint32_t> wiphy(NL80211_ATTR_WIPHY, wiphy_index);
+ get_interface.AddAttribute(wiphy);
+ vector<NL80211Packet> response;
+ if (!netlink_manager_->SendMessageAndGetResponses(get_interface, &response)) {
+ LOG(ERROR) << "Failed to send GetWiphy message";
+ }
+ for (NL80211Packet& packet : response) {
+ if (packet.GetMessageType() == NLMSG_ERROR) {
+ LOG(ERROR) << "Receive ERROR message: "
+ << strerror(packet.GetErrorCode());
+ return false;
+ }
+ if (packet.GetMessageType() != netlink_manager_->GetFamilyId()) {
+ LOG(ERROR) << "Wrong message type for new interface message: "
+ << packet.GetMessageType();
+ return false;
+ }
+ if (packet.GetCommand() != NL80211_CMD_NEW_INTERFACE) {
+ LOG(ERROR) << "Wrong command for new interface message: "
+ << packet.GetCommand();
+ return false;
+ }
+
+ // Today we don't check NL80211_ATTR_IFTYPE because at this point of time
+ // driver always reports that interface is in STATION mode. Even when we
+ // are asking interfaces infomation on behalf of tethering, it is still so
+ // because hostapd is supposed to set interface to AP mode later.
+
+ string if_name;
+ if (!packet.GetAttributeValue(NL80211_ATTR_IFNAME, &if_name)) {
+ LOG(ERROR) << "Failed to get interface name";
+ return false;
+ }
+ if (if_name == "p2p0") {
+ LOG(DEBUG) << "Driver may tell a lie that p2p0 is in STATION mode,"
+ <<" we need to blacklist it.";
+ continue;
+ }
+ *interface_name = if_name;
+ return true;
+ }
+
+ LOG(ERROR) << "Failed to get expected interface info from kernel";
+ return false;
+}
+
+} // namespace wificond
+} // namespace android
--- /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.
+ */
+
+#ifndef WIFICOND_NET_NETLINK_UTILS_H_
+#define WIFICOND_NET_NETLINK_UTILS_H_
+
+#include <string>
+
+#include <android-base/macros.h>
+
+namespace android {
+namespace wificond {
+
+class NL80211Packet;
+class NetlinkManager;
+
+// Provides NL80211 helper functions.
+class NetlinkUtils {
+ public:
+ explicit NetlinkUtils(NetlinkManager* netlink_manager);
+ virtual ~NetlinkUtils();
+
+ // Get the wiphy index from kernel.
+ // |*out_wiphy_index| returns the wiphy index from kernel.
+ // Returns true on success.
+ virtual bool GetWiphyIndex(uint32_t* out_wiphy_index);
+
+ // Get wifi interface name from kernel.
+ // |wiphy_index| is the wiphy index we get using GetWiphyIndex().
+ // Returns true on success.
+ virtual bool GetInterfaceName(uint32_t wiphy_index,
+ std::string* interface_name);
+
+ private:
+ NetlinkManager* netlink_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetlinkUtils);
+};
+
+} // namespace wificond
+} // namespace android
+
+#endif // WIFICOND_NET_NETLINK_UTILS_H_
#include <android-base/logging.h>
-#include "wificond/net/netlink_manager.h"
+#include "wificond/net/netlink_utils.h"
using android::binder::Status;
using android::sp;
Server::Server(unique_ptr<HalTool> hal_tool,
unique_ptr<InterfaceTool> if_tool,
unique_ptr<DriverTool> driver_tool,
- NetlinkManager* netlink_manager)
+ NetlinkUtils* netlink_utils)
: hal_tool_(std::move(hal_tool)),
if_tool_(std::move(if_tool)),
driver_tool_(std::move(driver_tool)),
- netlink_manager_(netlink_manager) {
+ netlink_utils_(netlink_utils) {
}
Status Server::createApInterface(sp<IApInterface>* created_interface) {
return false;
}
- if (!netlink_manager_->GetInterfaceName(wiphy_index_, interface_name)) {
+ if (!netlink_utils_->GetInterfaceName(wiphy_index_, interface_name)) {
return false;
}
}
bool Server::RefreshWiphyIndex() {
- if (!netlink_manager_->GetWiphyIndex(&wiphy_index_)) {
+ if (!netlink_utils_->GetWiphyIndex(&wiphy_index_)) {
LOG(ERROR) << "Failed to get wiphy index";
return false;
}
namespace wificond {
class NL80211Packet;
-class NetlinkManager;
+class NetlinkUtils;
class Server : public android::net::wifi::BnWificond {
public:
Server(std::unique_ptr<wifi_system::HalTool> hal_tool,
std::unique_ptr<wifi_system::InterfaceTool> if_tool,
std::unique_ptr<wifi_hal::DriverTool> driver_tool,
- NetlinkManager* netlink_manager);
+ NetlinkUtils* netlink_utils);
~Server() override = default;
android::binder::Status createApInterface(
const std::unique_ptr<wifi_system::HalTool> hal_tool_;
const std::unique_ptr<wifi_system::InterfaceTool> if_tool_;
const std::unique_ptr<wifi_hal::DriverTool> driver_tool_;
- NetlinkManager* netlink_manager_;
+ NetlinkUtils* netlink_utils_;
uint32_t wiphy_index_;
std::vector<std::unique_ptr<ApInterfaceImpl>> ap_interfaces_;
MockNetlinkManager(EventLoop* event_loop);
~MockNetlinkManager() override = default;
- MOCK_METHOD1(GetWiphyIndex, bool(uint32_t* out_wiphy_index));
- MOCK_METHOD2(GetInterfaceName, bool(uint32_t wiphy_index,
- std::string* interface_name));
-
}; // class MockNetlinkManager
} // namespace wificond
--- /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 "wificond/tests/mock_netlink_utils.h"
+
+namespace android {
+namespace wificond {
+
+MockNetlinkUtils::MockNetlinkUtils(NetlinkManager* netlink_manager)
+ : NetlinkUtils(netlink_manager) {
+}
+
+} // namespace wificond
+} // namespace android
--- /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.
+ */
+
+#ifndef WIFICOND_TEST_MOCK_NETLINK_UTILS_H_
+#define WIFICOND_TEST_MOCK_NETLINK_UTILS_H_
+
+#include <gmock/gmock.h>
+
+#include "wificond/net/netlink_utils.h"
+
+namespace android {
+namespace wificond {
+
+class MockNetlinkUtils : public NetlinkUtils {
+ public:
+ MockNetlinkUtils(NetlinkManager* netlink_manager);
+ ~MockNetlinkUtils() override = default;
+
+ MOCK_METHOD1(GetWiphyIndex, bool(uint32_t* out_wiphy_index));
+ MOCK_METHOD2(GetInterfaceName, bool(uint32_t wiphy_index,
+ std::string* interface_name));
+
+}; // class MockNetlinkUtils
+
+} // namespace wificond
+} // namespace android
+
+#endif // WIFICOND_TEST_MOCK_NETLINK_UTILS_H
#include "android/net/wifi/IApInterface.h"
#include "wificond/looper_backed_event_loop.h"
#include "wificond/tests/mock_netlink_manager.h"
+#include "wificond/tests/mock_netlink_utils.h"
#include "wificond/server.h"
using android::net::wifi::IApInterface;
ON_CALL(*driver_tool_, UnloadDriver()).WillByDefault(Return(true));
ON_CALL(*driver_tool_, ChangeFirmwareMode(_)).WillByDefault(Return(true));
ON_CALL(*if_tool_, SetWifiUpState(_)).WillByDefault(Return(true));
- ON_CALL(*netlink_manager_, GetWiphyIndex(_)).WillByDefault(Return(true));
- ON_CALL(*netlink_manager_, GetInterfaceName(_, _)).WillByDefault(Return(true));
+ ON_CALL(*netlink_utils_, GetWiphyIndex(_)).WillByDefault(Return(true));
+ ON_CALL(*netlink_utils_, GetInterfaceName(_, _)).WillByDefault(Return(true));
}
NiceMock<LooperBackedEventLoop>* event_loop_ =
unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
new NiceMock<MockNetlinkManager>(event_loop_)};
+ unique_ptr<NiceMock<MockNetlinkUtils>> netlink_utils_{
+ new NiceMock<MockNetlinkUtils>(netlink_manager_.get())};
+
+
Server server_{unique_ptr<HalTool>(hal_tool_),
unique_ptr<InterfaceTool>(if_tool_),
unique_ptr<DriverTool>(driver_tool_),
- netlink_manager_.get()};
+ netlink_utils_.get()};
}; // class ServerTest
} // namespace
EXPECT_CALL(*driver_tool_, ChangeFirmwareMode(DriverTool::kFirmwareModeAp))
.InSequence(sequence)
.WillOnce(Return(true));
- EXPECT_CALL(*netlink_manager_, GetWiphyIndex(_))
+ EXPECT_CALL(*netlink_utils_, GetWiphyIndex(_))
.InSequence(sequence)
.WillOnce(Return(true));
- EXPECT_CALL(*netlink_manager_, GetInterfaceName(_, _))
+ EXPECT_CALL(*netlink_utils_, GetInterfaceName(_, _))
.InSequence(sequence)
.WillOnce(Return(true));
TEST_F(ServerTest, DoesNotSupportMultipleInterfaces) {
sp<IApInterface> ap_if;
- EXPECT_CALL(*netlink_manager_, GetWiphyIndex(_)).Times(1);
- EXPECT_CALL(*netlink_manager_, GetInterfaceName(_, _)).Times(1);
+ EXPECT_CALL(*netlink_utils_, GetWiphyIndex(_)).Times(1);
+ EXPECT_CALL(*netlink_utils_, GetInterfaceName(_, _)).Times(1);
EXPECT_TRUE(server_.createApInterface(&ap_if).isOk());
EXPECT_NE(nullptr, ap_if.get());
TEST_F(ServerTest, CanDestroyInterfaces) {
sp<IApInterface> ap_if;
- EXPECT_CALL(*netlink_manager_, GetWiphyIndex(_)).Times(2);
- EXPECT_CALL(*netlink_manager_, GetInterfaceName(_, _)).Times(2);
+ EXPECT_CALL(*netlink_utils_, GetWiphyIndex(_)).Times(2);
+ EXPECT_CALL(*netlink_utils_, GetInterfaceName(_, _)).Times(2);
EXPECT_CALL(*driver_tool_, UnloadDriver()).Times(0);
EXPECT_TRUE(server_.createApInterface(&ap_if).isOk());