1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chromeos/network/network_type_pattern.h"
6
7#include "chromeos/network/network_event_log.h"
8#include "third_party/cros_system_api/dbus/service_constants.h"
9
10namespace chromeos {
11
12namespace {
13
14const char kPatternDefault[] = "PatternDefault";
15const char kPatternEthernet[] = "PatternEthernet";
16const char kPatternWireless[] = "PatternWireless";
17const char kPatternMobile[] = "PatternMobile";
18const char kPatternNonVirtual[] = "PatternNonVirtual";
19
20enum NetworkTypeBitFlag {
21  kNetworkTypeNone = 0,
22  kNetworkTypeEthernet = 1 << 0,
23  kNetworkTypeWifi = 1 << 1,
24  kNetworkTypeWimax = 1 << 2,
25  kNetworkTypeCellular = 1 << 3,
26  kNetworkTypeVPN = 1 << 4,
27  kNetworkTypeEthernetEap = 1 << 5,
28  kNetworkTypeBluetooth = 1 << 6
29};
30
31struct ShillToBitFlagEntry {
32  const char* shill_network_type;
33  NetworkTypeBitFlag bit_flag;
34} shill_type_to_flag[] = {
35  { shill::kTypeEthernet, kNetworkTypeEthernet },
36  { shill::kTypeEthernetEap, kNetworkTypeEthernetEap },
37  { shill::kTypeWifi, kNetworkTypeWifi },
38  { shill::kTypeWimax, kNetworkTypeWimax },
39  { shill::kTypeCellular, kNetworkTypeCellular },
40  { shill::kTypeVPN, kNetworkTypeVPN },
41  { shill::kTypeBluetooth, kNetworkTypeBluetooth }
42};
43
44NetworkTypeBitFlag ShillNetworkTypeToFlag(const std::string& shill_type) {
45  for (size_t i = 0; i < arraysize(shill_type_to_flag); ++i) {
46    if (shill_type_to_flag[i].shill_network_type == shill_type)
47      return shill_type_to_flag[i].bit_flag;
48  }
49  NET_LOG_ERROR("ShillNetworkTypeToFlag", "Unknown type: " + shill_type);
50  return kNetworkTypeNone;
51}
52
53}  // namespace
54
55// static
56NetworkTypePattern NetworkTypePattern::Default() {
57  return NetworkTypePattern(~0);
58}
59
60// static
61NetworkTypePattern NetworkTypePattern::Wireless() {
62  return NetworkTypePattern(kNetworkTypeWifi | kNetworkTypeWimax |
63                            kNetworkTypeCellular);
64}
65
66// static
67NetworkTypePattern NetworkTypePattern::Mobile() {
68  return NetworkTypePattern(kNetworkTypeCellular | kNetworkTypeWimax);
69}
70
71// static
72NetworkTypePattern NetworkTypePattern::NonVirtual() {
73  return NetworkTypePattern(~kNetworkTypeVPN);
74}
75
76// static
77NetworkTypePattern NetworkTypePattern::Ethernet() {
78  return NetworkTypePattern(kNetworkTypeEthernet);
79}
80
81// static
82NetworkTypePattern NetworkTypePattern::WiFi() {
83  return NetworkTypePattern(kNetworkTypeWifi);
84}
85
86// static
87NetworkTypePattern NetworkTypePattern::Cellular() {
88  return NetworkTypePattern(kNetworkTypeCellular);
89}
90
91// static
92NetworkTypePattern NetworkTypePattern::VPN() {
93  return NetworkTypePattern(kNetworkTypeVPN);
94}
95
96// static
97NetworkTypePattern NetworkTypePattern::Wimax() {
98  return NetworkTypePattern(kNetworkTypeWimax);
99}
100
101// static
102NetworkTypePattern NetworkTypePattern::Primitive(
103    const std::string& shill_network_type) {
104  return NetworkTypePattern(ShillNetworkTypeToFlag(shill_network_type));
105}
106
107bool NetworkTypePattern::Equals(const NetworkTypePattern& other) const {
108  return pattern_ == other.pattern_;
109}
110
111bool NetworkTypePattern::MatchesType(
112    const std::string& shill_network_type) const {
113  return MatchesPattern(Primitive(shill_network_type));
114}
115
116bool NetworkTypePattern::MatchesPattern(
117    const NetworkTypePattern& other_pattern) const {
118  if (Equals(other_pattern))
119    return true;
120
121  return pattern_ & other_pattern.pattern_;
122}
123
124std::string NetworkTypePattern::ToDebugString() const {
125  if (Equals(Default()))
126    return kPatternDefault;
127  if (Equals(Ethernet()))
128    return kPatternEthernet;
129  if (Equals(Wireless()))
130    return kPatternWireless;
131  if (Equals(Mobile()))
132    return kPatternMobile;
133  if (Equals(NonVirtual()))
134    return kPatternNonVirtual;
135
136  std::string str;
137  for (size_t i = 0; i < arraysize(shill_type_to_flag); ++i) {
138    if (!(pattern_ & shill_type_to_flag[i].bit_flag))
139      continue;
140    if (!str.empty())
141      str += "|";
142    str += shill_type_to_flag[i].shill_network_type;
143  }
144  return str;
145}
146
147NetworkTypePattern::NetworkTypePattern(int pattern) : pattern_(pattern) {}
148
149}  // namespace chromeos
150