1 // Copyright (c) 2012 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_util.h" 6 7 #include "base/strings/string_tokenizer.h" 8 #include "base/strings/string_util.h" 9 #include "base/strings/stringprintf.h" 10 #include "chromeos/network/network_state.h" 11 #include "chromeos/network/network_state_handler.h" 12 #include "chromeos/network/onc/onc_signature.h" 13 #include "chromeos/network/onc/onc_translator.h" 14 #include "third_party/cros_system_api/dbus/service_constants.h" 15 16 namespace chromeos { 17 18 WifiAccessPoint::WifiAccessPoint() 19 : signal_strength(0), 20 signal_to_noise(0), 21 channel(0) { 22 } 23 24 WifiAccessPoint::~WifiAccessPoint() { 25 } 26 27 CellularScanResult::CellularScanResult() { 28 } 29 30 CellularScanResult::~CellularScanResult() { 31 } 32 33 namespace network_util { 34 35 std::string PrefixLengthToNetmask(int32 prefix_length) { 36 std::string netmask; 37 // Return the empty string for invalid inputs. 38 if (prefix_length < 0 || prefix_length > 32) 39 return netmask; 40 for (int i = 0; i < 4; i++) { 41 int remainder = 8; 42 if (prefix_length >= 8) { 43 prefix_length -= 8; 44 } else { 45 remainder = prefix_length; 46 prefix_length = 0; 47 } 48 if (i > 0) 49 netmask += "."; 50 int value = remainder == 0 ? 0 : 51 ((2L << (remainder - 1)) - 1) << (8 - remainder); 52 netmask += base::StringPrintf("%d", value); 53 } 54 return netmask; 55 } 56 57 int32 NetmaskToPrefixLength(const std::string& netmask) { 58 int count = 0; 59 int prefix_length = 0; 60 base::StringTokenizer t(netmask, "."); 61 while (t.GetNext()) { 62 // If there are more than 4 numbers, then it's invalid. 63 if (count == 4) 64 return -1; 65 66 std::string token = t.token(); 67 // If we already found the last mask and the current one is not 68 // "0" then the netmask is invalid. For example, 255.224.255.0 69 if (prefix_length / 8 != count) { 70 if (token != "0") 71 return -1; 72 } else if (token == "255") { 73 prefix_length += 8; 74 } else if (token == "254") { 75 prefix_length += 7; 76 } else if (token == "252") { 77 prefix_length += 6; 78 } else if (token == "248") { 79 prefix_length += 5; 80 } else if (token == "240") { 81 prefix_length += 4; 82 } else if (token == "224") { 83 prefix_length += 3; 84 } else if (token == "192") { 85 prefix_length += 2; 86 } else if (token == "128") { 87 prefix_length += 1; 88 } else if (token == "0") { 89 prefix_length += 0; 90 } else { 91 // mask is not a valid number. 92 return -1; 93 } 94 count++; 95 } 96 if (count < 4) 97 return -1; 98 return prefix_length; 99 } 100 101 std::string FormattedMacAddress(const std::string& shill_mac_address) { 102 if (shill_mac_address.size() % 2 != 0) 103 return shill_mac_address; 104 std::string result; 105 for (size_t i = 0; i < shill_mac_address.size(); ++i) { 106 if ((i != 0) && (i % 2 == 0)) 107 result.push_back(':'); 108 result.push_back(base::ToUpperASCII(shill_mac_address[i])); 109 } 110 return result; 111 } 112 113 bool ParseCellularScanResults(const base::ListValue& list, 114 std::vector<CellularScanResult>* scan_results) { 115 scan_results->clear(); 116 scan_results->reserve(list.GetSize()); 117 for (base::ListValue::const_iterator it = list.begin(); 118 it != list.end(); ++it) { 119 if (!(*it)->IsType(base::Value::TYPE_DICTIONARY)) 120 return false; 121 CellularScanResult scan_result; 122 const base::DictionaryValue* dict = 123 static_cast<const base::DictionaryValue*>(*it); 124 // If the network id property is not present then this network cannot be 125 // connected to so don't include it in the results. 126 if (!dict->GetStringWithoutPathExpansion(shill::kNetworkIdProperty, 127 &scan_result.network_id)) 128 continue; 129 dict->GetStringWithoutPathExpansion(shill::kStatusProperty, 130 &scan_result.status); 131 dict->GetStringWithoutPathExpansion(shill::kLongNameProperty, 132 &scan_result.long_name); 133 dict->GetStringWithoutPathExpansion(shill::kShortNameProperty, 134 &scan_result.short_name); 135 dict->GetStringWithoutPathExpansion(shill::kTechnologyProperty, 136 &scan_result.technology); 137 scan_results->push_back(scan_result); 138 } 139 return true; 140 } 141 142 scoped_ptr<base::DictionaryValue> TranslateNetworkStateToONC( 143 const NetworkState* network) { 144 // Get the properties from the NetworkState. 145 base::DictionaryValue shill_dictionary; 146 network->GetStateProperties(&shill_dictionary); 147 148 scoped_ptr<base::DictionaryValue> onc_dictionary = 149 TranslateShillServiceToONCPart( 150 shill_dictionary, &onc::kNetworkWithStateSignature); 151 return onc_dictionary.Pass(); 152 } 153 154 scoped_ptr<base::ListValue> TranslateNetworkListToONC( 155 NetworkTypePattern pattern, 156 bool configured_only, 157 bool visible_only, 158 int limit, 159 bool debugging_properties) { 160 NetworkStateHandler::NetworkStateList network_states; 161 NetworkHandler::Get()->network_state_handler()->GetNetworkListByType( 162 pattern, configured_only, visible_only, limit, &network_states); 163 164 scoped_ptr<base::ListValue> network_properties_list(new base::ListValue); 165 for (NetworkStateHandler::NetworkStateList::iterator it = 166 network_states.begin(); 167 it != network_states.end(); 168 ++it) { 169 scoped_ptr<base::DictionaryValue> onc_dictionary = 170 TranslateNetworkStateToONC(*it); 171 172 if (debugging_properties) { 173 onc_dictionary->SetBoolean("connectable", (*it)->connectable()); 174 onc_dictionary->SetBoolean("visible", (*it)->visible()); 175 onc_dictionary->SetString("profile_path", (*it)->profile_path()); 176 std::string onc_source = (*it)->ui_data().GetONCSourceAsString(); 177 if (!onc_source.empty()) 178 onc_dictionary->SetString("onc_source", onc_source); 179 } 180 181 network_properties_list->Append(onc_dictionary.release()); 182 } 183 return network_properties_list.Pass(); 184 } 185 186 } // namespace network_util 187 } // namespace chromeos 188