1 //
2 // Copyright (C) 2014 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 "shill/cellular/cellular_bearer.h"
18 
19 #include <ModemManager/ModemManager.h>
20 
21 #include "shill/mock_control.h"
22 #include "shill/mock_dbus_properties_proxy.h"
23 #include "shill/testing.h"
24 
25 using std::string;
26 using std::vector;
27 using testing::Return;
28 using testing::ReturnNull;
29 using testing::_;
30 
31 namespace shill {
32 
33 namespace {
34 
35 const char kBearerDBusPath[] = "/org/freedesktop/ModemManager/Bearer/0";
36 const char kBearerDBusService[] = "org.freedesktop.ModemManager";
37 const char kDataInterface[] = "/dev/ppp0";
38 const char kIPv4Address[] = "10.0.0.1";
39 const char kIPv4Gateway[] = "10.0.0.254";
40 const int kIPv4SubnetPrefix = 8;
41 const char* const kIPv4DNS[] = { "10.0.0.2", "8.8.4.4", "8.8.8.8" };
42 const char kIPv6Address[] = "0:0:0:0:0:ffff:a00:1";
43 const char kIPv6Gateway[] = "0:0:0:0:0:ffff:a00:fe";
44 const int kIPv6SubnetPrefix = 16;
45 const char* const kIPv6DNS[] = {
46   "0:0:0:0:0:ffff:a00:fe", "0:0:0:0:0:ffff:808:404", "0:0:0:0:0:ffff:808:808"
47 };
48 
49 }  // namespace
50 
51 class CellularBearerTest : public testing::Test {
52  public:
CellularBearerTest()53   CellularBearerTest()
54       : control_(new MockControl()),
55         bearer_(control_.get(), kBearerDBusPath, kBearerDBusService) {}
56 
57  protected:
VerifyDefaultProperties()58   void VerifyDefaultProperties() {
59     EXPECT_EQ(kBearerDBusPath, bearer_.dbus_path());
60     EXPECT_EQ(kBearerDBusService, bearer_.dbus_service());
61     EXPECT_FALSE(bearer_.connected());
62     EXPECT_EQ("", bearer_.data_interface());
63     EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv4_config_method());
64     EXPECT_EQ(nullptr, bearer_.ipv4_config_properties());;
65     EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv6_config_method());
66     EXPECT_EQ(nullptr, bearer_.ipv6_config_properties());;
67   }
68 
ConstructIPv4ConfigProperties(MMBearerIpMethod ipconfig_method)69   static KeyValueStore ConstructIPv4ConfigProperties(
70       MMBearerIpMethod ipconfig_method) {
71     KeyValueStore ipconfig_properties;
72     ipconfig_properties.SetUint("method", ipconfig_method);
73     if (ipconfig_method == MM_BEARER_IP_METHOD_STATIC) {
74       ipconfig_properties.SetString("address", kIPv4Address);
75       ipconfig_properties.SetString("gateway", kIPv4Gateway);
76       ipconfig_properties.SetUint("prefix", kIPv4SubnetPrefix);
77       ipconfig_properties.SetString("dns1", kIPv4DNS[0]);
78       ipconfig_properties.SetString("dns2", kIPv4DNS[1]);
79       ipconfig_properties.SetString("dns3", kIPv4DNS[2]);
80     }
81     return ipconfig_properties;
82   }
83 
ConstructIPv6ConfigProperties(MMBearerIpMethod ipconfig_method)84   static KeyValueStore ConstructIPv6ConfigProperties(
85       MMBearerIpMethod ipconfig_method) {
86     KeyValueStore ipconfig_properties;
87     ipconfig_properties.SetUint("method", ipconfig_method);
88     if (ipconfig_method == MM_BEARER_IP_METHOD_STATIC) {
89       ipconfig_properties.SetString("address", kIPv6Address);
90       ipconfig_properties.SetString("gateway", kIPv6Gateway);
91       ipconfig_properties.SetUint("prefix", kIPv6SubnetPrefix);
92       ipconfig_properties.SetString("dns1", kIPv6DNS[0]);
93       ipconfig_properties.SetString("dns2", kIPv6DNS[1]);
94       ipconfig_properties.SetString("dns3", kIPv6DNS[2]);
95     }
96     return ipconfig_properties;
97   }
98 
ConstructBearerProperties(bool connected,const string & data_interface,MMBearerIpMethod ipv4_config_method,MMBearerIpMethod ipv6_config_method)99   static KeyValueStore ConstructBearerProperties(
100       bool connected, const string& data_interface,
101       MMBearerIpMethod ipv4_config_method,
102       MMBearerIpMethod ipv6_config_method) {
103     KeyValueStore properties;
104     properties.SetBool(MM_BEARER_PROPERTY_CONNECTED, connected);
105     properties.SetString(MM_BEARER_PROPERTY_INTERFACE, data_interface);
106 
107     properties.SetKeyValueStore(
108         MM_BEARER_PROPERTY_IP4CONFIG,
109         ConstructIPv4ConfigProperties(ipv4_config_method));
110     properties.SetKeyValueStore(
111         MM_BEARER_PROPERTY_IP6CONFIG,
112         ConstructIPv6ConfigProperties(ipv6_config_method));
113     return properties;
114   }
115 
VerifyStaticIPv4ConfigMethodAndProperties()116   void VerifyStaticIPv4ConfigMethodAndProperties() {
117     EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv4_config_method());
118     const IPConfig::Properties* ipv4_config_properties =
119         bearer_.ipv4_config_properties();
120     ASSERT_NE(nullptr, ipv4_config_properties);;
121     EXPECT_EQ(IPAddress::kFamilyIPv4, ipv4_config_properties->address_family);
122     EXPECT_EQ(kIPv4Address, ipv4_config_properties->address);
123     EXPECT_EQ(kIPv4Gateway, ipv4_config_properties->gateway);
124     EXPECT_EQ(kIPv4SubnetPrefix, ipv4_config_properties->subnet_prefix);
125     ASSERT_EQ(3, ipv4_config_properties->dns_servers.size());
126     EXPECT_EQ(kIPv4DNS[0], ipv4_config_properties->dns_servers[0]);
127     EXPECT_EQ(kIPv4DNS[1], ipv4_config_properties->dns_servers[1]);
128     EXPECT_EQ(kIPv4DNS[2], ipv4_config_properties->dns_servers[2]);
129   }
130 
VerifyStaticIPv6ConfigMethodAndProperties()131   void VerifyStaticIPv6ConfigMethodAndProperties() {
132     EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv6_config_method());
133     const IPConfig::Properties* ipv6_config_properties =
134         bearer_.ipv6_config_properties();
135     ASSERT_NE(nullptr, ipv6_config_properties);;
136     EXPECT_EQ(IPAddress::kFamilyIPv6, ipv6_config_properties->address_family);
137     EXPECT_EQ(kIPv6Address, ipv6_config_properties->address);
138     EXPECT_EQ(kIPv6Gateway, ipv6_config_properties->gateway);
139     EXPECT_EQ(kIPv6SubnetPrefix, ipv6_config_properties->subnet_prefix);
140     ASSERT_EQ(3, ipv6_config_properties->dns_servers.size());
141     EXPECT_EQ(kIPv6DNS[0], ipv6_config_properties->dns_servers[0]);
142     EXPECT_EQ(kIPv6DNS[1], ipv6_config_properties->dns_servers[1]);
143     EXPECT_EQ(kIPv6DNS[2], ipv6_config_properties->dns_servers[2]);
144   }
145 
146   std::unique_ptr<MockControl> control_;
147   CellularBearer bearer_;
148 };
149 
TEST_F(CellularBearerTest,Constructor)150 TEST_F(CellularBearerTest, Constructor) {
151   VerifyDefaultProperties();
152 }
153 
TEST_F(CellularBearerTest,Init)154 TEST_F(CellularBearerTest, Init) {
155   // Ownership of |properties_proxy| is transferred to |bearer_| via
156   // |control_|.
157   std::unique_ptr<MockDBusPropertiesProxy> properties_proxy(
158       new MockDBusPropertiesProxy);
159   EXPECT_CALL(*control_.get(),
160               CreateDBusPropertiesProxy(kBearerDBusPath, kBearerDBusService))
161       .WillOnce(ReturnAndReleasePointee(&properties_proxy));
162   EXPECT_CALL(*properties_proxy.get(), set_properties_changed_callback(_))
163       .Times(1);
164   EXPECT_CALL(*properties_proxy.get(), GetAll(MM_DBUS_INTERFACE_BEARER))
165       .WillOnce(Return(ConstructBearerProperties(true, kDataInterface,
166                                                  MM_BEARER_IP_METHOD_STATIC,
167                                                  MM_BEARER_IP_METHOD_STATIC)));
168   bearer_.Init();
169   EXPECT_TRUE(bearer_.connected());
170   EXPECT_EQ(kDataInterface, bearer_.data_interface());
171   VerifyStaticIPv4ConfigMethodAndProperties();
172   VerifyStaticIPv6ConfigMethodAndProperties();
173 }
174 
TEST_F(CellularBearerTest,InitAndCreateDBusPropertiesProxyFails)175 TEST_F(CellularBearerTest, InitAndCreateDBusPropertiesProxyFails) {
176   EXPECT_CALL(*control_.get(),
177               CreateDBusPropertiesProxy(kBearerDBusPath, kBearerDBusService))
178       .WillOnce(ReturnNull());
179   bearer_.Init();
180   VerifyDefaultProperties();
181 }
182 
TEST_F(CellularBearerTest,OnPropertiesChanged)183 TEST_F(CellularBearerTest, OnPropertiesChanged) {
184   KeyValueStore properties;
185 
186   // If interface is not MM_DBUS_INTERFACE_BEARER, no updates should be done.
187   bearer_.OnPropertiesChanged("", properties, vector<string>());
188   VerifyDefaultProperties();
189 
190   properties.SetBool(MM_BEARER_PROPERTY_CONNECTED, true);
191   bearer_.OnPropertiesChanged("", properties, vector<string>());
192   VerifyDefaultProperties();
193 
194   // Update 'interface' property.
195   properties.Clear();
196   properties.SetString(MM_BEARER_PROPERTY_INTERFACE, kDataInterface);
197   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
198                               vector<string>());
199   EXPECT_EQ(kDataInterface, bearer_.data_interface());
200 
201   // Update 'connected' property.
202   properties.Clear();
203   properties.SetBool(MM_BEARER_PROPERTY_CONNECTED, true);
204   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
205                               vector<string>());
206   EXPECT_TRUE(bearer_.connected());
207   // 'interface' property remains unchanged.
208   EXPECT_EQ(kDataInterface, bearer_.data_interface());
209 
210   // Update 'ip4config' property.
211   properties.Clear();
212   properties.SetKeyValueStore(
213       MM_BEARER_PROPERTY_IP4CONFIG,
214       ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_UNKNOWN));
215   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
216                               vector<string>());
217   EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv4_config_method());
218 
219   properties.Clear();
220   properties.SetKeyValueStore(
221       MM_BEARER_PROPERTY_IP4CONFIG,
222       ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_PPP));
223   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
224                               vector<string>());
225   EXPECT_EQ(IPConfig::kMethodPPP, bearer_.ipv4_config_method());
226 
227   properties.Clear();
228   properties.SetKeyValueStore(
229       MM_BEARER_PROPERTY_IP4CONFIG,
230       ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_STATIC));
231   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
232                               vector<string>());
233   EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv4_config_method());
234   VerifyStaticIPv4ConfigMethodAndProperties();
235 
236   properties.Clear();
237   properties.SetKeyValueStore(
238       MM_BEARER_PROPERTY_IP4CONFIG,
239       ConstructIPv4ConfigProperties(MM_BEARER_IP_METHOD_DHCP));
240   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
241                               vector<string>());
242   EXPECT_EQ(IPConfig::kMethodDHCP, bearer_.ipv4_config_method());
243 
244   // Update 'ip6config' property.
245   properties.Clear();
246   properties.SetKeyValueStore(
247       MM_BEARER_PROPERTY_IP6CONFIG,
248       ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_UNKNOWN));
249   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
250                               vector<string>());
251   EXPECT_EQ(IPConfig::kMethodUnknown, bearer_.ipv6_config_method());
252 
253   properties.Clear();
254   properties.SetKeyValueStore(
255       MM_BEARER_PROPERTY_IP6CONFIG,
256       ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_PPP));
257   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
258                               vector<string>());
259   EXPECT_EQ(IPConfig::kMethodPPP, bearer_.ipv6_config_method());
260 
261   properties.Clear();
262   properties.SetKeyValueStore(
263       MM_BEARER_PROPERTY_IP6CONFIG,
264       ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_STATIC));
265   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
266                               vector<string>());
267   EXPECT_EQ(IPConfig::kMethodStatic, bearer_.ipv6_config_method());
268   VerifyStaticIPv6ConfigMethodAndProperties();
269 
270   properties.Clear();
271   properties.SetKeyValueStore(
272       MM_BEARER_PROPERTY_IP6CONFIG,
273       ConstructIPv6ConfigProperties(MM_BEARER_IP_METHOD_DHCP));
274   bearer_.OnPropertiesChanged(MM_DBUS_INTERFACE_BEARER, properties,
275                               vector<string>());
276   EXPECT_EQ(IPConfig::kMethodDHCP, bearer_.ipv6_config_method());
277 }
278 
279 }  // namespace shill
280