1 /*
2  * Copyright (C) 2016, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <array>
18 #include <memory>
19 #include <vector>
20 
21 #include <linux/if_ether.h>
22 
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include <wifi_system_test/mock_interface_tool.h>
26 
27 #include "wificond/logging_utils.h"
28 #include "wificond/tests/mock_ap_interface_event_callback.h"
29 #include "wificond/tests/mock_netlink_manager.h"
30 #include "wificond/tests/mock_netlink_utils.h"
31 
32 #include "wificond/ap_interface_impl.h"
33 
34 using android::wifi_system::MockInterfaceTool;
35 using com::android::server::wifi::wificond::NativeWifiClient;
36 using std::array;
37 using std::placeholders::_1;
38 using std::placeholders::_2;
39 using std::unique_ptr;
40 using std::vector;
41 using testing::NiceMock;
42 using testing::Invoke;
43 using testing::Return;
44 using testing::Sequence;
45 using testing::StrEq;
46 using testing::_;
47 
48 namespace android {
49 namespace wificond {
50 namespace {
51 
52 const char kTestInterfaceName[] = "testwifi0";
53 const uint32_t kTestInterfaceIndex = 42;
54 const array<uint8_t, ETH_ALEN> kFakeMacAddress01 = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
55 const array<uint8_t, ETH_ALEN> kFakeMacAddress02 = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf7};
56 
CaptureStationEventHandler(OnStationEventHandler * out_handler,uint32_t interface_index,OnStationEventHandler handler)57 void CaptureStationEventHandler(
58     OnStationEventHandler* out_handler,
59     uint32_t interface_index,
60     OnStationEventHandler handler) {
61   *out_handler = handler;
62 }
63 
CaptureChannelSwitchEventHandler(OnChannelSwitchEventHandler * out_handler,uint32_t interface_index,OnChannelSwitchEventHandler handler)64 void CaptureChannelSwitchEventHandler(
65     OnChannelSwitchEventHandler* out_handler,
66     uint32_t interface_index,
67     OnChannelSwitchEventHandler handler) {
68   *out_handler = handler;
69 }
70 
71 class ApInterfaceImplTest : public ::testing::Test {
72  protected:
73   unique_ptr<NiceMock<MockInterfaceTool>> if_tool_{
74       new NiceMock<MockInterfaceTool>};
75   unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_{
76       new NiceMock<MockNetlinkManager>()};
77   unique_ptr<NiceMock<MockNetlinkUtils>> netlink_utils_{
78       new NiceMock<MockNetlinkUtils>(netlink_manager_.get())};
79 
80   unique_ptr<ApInterfaceImpl> ap_interface_;
81 
SetUp()82   void SetUp() override {
83     ap_interface_.reset(new ApInterfaceImpl(
84         kTestInterfaceName,
85         kTestInterfaceIndex,
86         netlink_utils_.get(),
87         if_tool_.get()));
88   }
89 };  // class ApInterfaceImplTest
90 
91 }  // namespace
92 
TEST_F(ApInterfaceImplTest,CanGetConnectedClients)93 TEST_F(ApInterfaceImplTest, CanGetConnectedClients) {
94   OnStationEventHandler handler;
95   EXPECT_CALL(*netlink_utils_,
96       SubscribeStationEvent(kTestInterfaceIndex, _)).
97           WillOnce(Invoke(bind(CaptureStationEventHandler, &handler, _1, _2)));
98 
99   ap_interface_.reset(new ApInterfaceImpl(
100         kTestInterfaceName,
101         kTestInterfaceIndex,
102         netlink_utils_.get(),
103         if_tool_.get()));
104 
105   array<uint8_t, ETH_ALEN> fake_mac_address_01 = kFakeMacAddress01;
106   array<uint8_t, ETH_ALEN> fake_mac_address_02 = kFakeMacAddress02;
107   std::vector<NativeWifiClient> associated_stations =
108     ap_interface_->GetConnectedClients();
109   int numberOfStations = static_cast<int>(associated_stations.size());
110   EXPECT_EQ(0, numberOfStations);
111   handler(NEW_STATION, fake_mac_address_01);
112   associated_stations = ap_interface_->GetConnectedClients();
113   numberOfStations = static_cast<int>(associated_stations.size());
114   EXPECT_EQ(1, numberOfStations);
115   handler(NEW_STATION, fake_mac_address_02);
116   associated_stations = ap_interface_->GetConnectedClients();
117   numberOfStations = static_cast<int>(associated_stations.size());
118   EXPECT_EQ(2, numberOfStations);
119   handler(DEL_STATION, fake_mac_address_01);
120   associated_stations = ap_interface_->GetConnectedClients();
121   numberOfStations = static_cast<int>(associated_stations.size());
122   EXPECT_EQ(1, numberOfStations);
123 }
124 
TEST_F(ApInterfaceImplTest,CanGetConnectedClientsSetsValues)125 TEST_F(ApInterfaceImplTest, CanGetConnectedClientsSetsValues) {
126   OnStationEventHandler handler;
127   EXPECT_CALL(*netlink_utils_,
128       SubscribeStationEvent(kTestInterfaceIndex, _)).
129           WillOnce(Invoke(bind(CaptureStationEventHandler, &handler, _1, _2)));
130 
131   ap_interface_.reset(new ApInterfaceImpl(
132         kTestInterfaceName,
133         kTestInterfaceIndex,
134         netlink_utils_.get(),
135         if_tool_.get()));
136 
137   array<uint8_t, ETH_ALEN> fake_mac_address_01 = kFakeMacAddress01;
138   vector<uint8_t> expected_mac_address =
139     vector<uint8_t>(fake_mac_address_01.begin(), fake_mac_address_01.end());
140   handler(NEW_STATION, fake_mac_address_01);
141   std::vector<NativeWifiClient> associated_stations =
142     ap_interface_->GetConnectedClients();
143   NativeWifiClient station = associated_stations[0];
144   EXPECT_EQ(expected_mac_address, station.macAddress);
145 }
146 
TEST_F(ApInterfaceImplTest,CallbackIsCalledOnConnectedClientsChanged)147 TEST_F(ApInterfaceImplTest, CallbackIsCalledOnConnectedClientsChanged) {
148   OnStationEventHandler handler;
149   EXPECT_CALL(*netlink_utils_, SubscribeStationEvent(kTestInterfaceIndex, _))
150       .WillOnce(Invoke(bind(CaptureStationEventHandler, &handler, _1, _2)));
151   ap_interface_.reset(new ApInterfaceImpl(
152       kTestInterfaceName, kTestInterfaceIndex, netlink_utils_.get(),
153       if_tool_.get()));
154 
155   auto binder = ap_interface_->GetBinder();
156   sp<MockApInterfaceEventCallback> callback(new MockApInterfaceEventCallback());
157   bool out_success = false;
158   EXPECT_TRUE(binder->registerCallback(callback, &out_success).isOk());
159   EXPECT_TRUE(out_success);
160 
161   array<uint8_t, ETH_ALEN> fake_mac_address_01 = kFakeMacAddress01;
162   array<uint8_t, ETH_ALEN> fake_mac_address_02 = kFakeMacAddress02;
163   EXPECT_CALL(*callback, onConnectedClientsChanged(_)).Times(3);
164   handler(NEW_STATION, fake_mac_address_01);
165   handler(NEW_STATION, fake_mac_address_02);
166   handler(DEL_STATION, fake_mac_address_01);
167 }
168 
TEST_F(ApInterfaceImplTest,CallbackIsCalledOnConnectedClientsChangedOnlyOnDiff)169 TEST_F(ApInterfaceImplTest, CallbackIsCalledOnConnectedClientsChangedOnlyOnDiff) {
170   OnStationEventHandler handler;
171   EXPECT_CALL(*netlink_utils_, SubscribeStationEvent(kTestInterfaceIndex, _))
172       .WillOnce(Invoke(bind(CaptureStationEventHandler, &handler, _1, _2)));
173   ap_interface_.reset(new ApInterfaceImpl(
174       kTestInterfaceName, kTestInterfaceIndex, netlink_utils_.get(),
175       if_tool_.get()));
176 
177   auto binder = ap_interface_->GetBinder();
178   sp<MockApInterfaceEventCallback> callback(new MockApInterfaceEventCallback());
179   bool out_success = false;
180   EXPECT_TRUE(binder->registerCallback(callback, &out_success).isOk());
181   EXPECT_TRUE(out_success);
182 
183   array<uint8_t, ETH_ALEN> fake_mac_address_01 = kFakeMacAddress01;
184   EXPECT_CALL(*callback, onConnectedClientsChanged(_)).Times(2);
185   handler(NEW_STATION, fake_mac_address_01);
186   handler(NEW_STATION, fake_mac_address_01);
187   handler(DEL_STATION, fake_mac_address_01);
188   handler(DEL_STATION, fake_mac_address_01);
189 }
190 
TEST_F(ApInterfaceImplTest,CallbackIsCalledOnSoftApChannelSwitched)191 TEST_F(ApInterfaceImplTest, CallbackIsCalledOnSoftApChannelSwitched) {
192   OnChannelSwitchEventHandler handler;
193   EXPECT_CALL(*netlink_utils_, SubscribeChannelSwitchEvent(kTestInterfaceIndex, _))
194       .WillOnce(Invoke(bind(CaptureChannelSwitchEventHandler, &handler, _1, _2)));
195   ap_interface_.reset(new ApInterfaceImpl(
196       kTestInterfaceName, kTestInterfaceIndex, netlink_utils_.get(),
197       if_tool_.get()));
198 
199   auto binder = ap_interface_->GetBinder();
200   sp<MockApInterfaceEventCallback> callback(new MockApInterfaceEventCallback());
201   bool out_success = false;
202   EXPECT_TRUE(binder->registerCallback(callback, &out_success).isOk());
203   EXPECT_TRUE(out_success);
204 
205   const uint32_t kTestChannelFrequency = 2437;
206   const ChannelBandwidth kTestChannelBandwidth = ChannelBandwidth::BW_20;
207   EXPECT_CALL(*callback, onSoftApChannelSwitched(kTestChannelFrequency,
208                                                  kTestChannelBandwidth));
209   handler(kTestChannelFrequency, kTestChannelBandwidth);
210 }
211 
212 }  // namespace wificond
213 }  // namespace android
214