1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/system/gonk/NetworkUtils.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1735 @@ 1.4 +/* Copyright 2012 Mozilla Foundation and Mozilla contributors 1.5 + * 1.6 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.7 + * you may not use this file except in compliance with the License. 1.8 + * You may obtain a copy of the License at 1.9 + * 1.10 + * http://www.apache.org/licenses/LICENSE-2.0 1.11 + * 1.12 + * Unless required by applicable law or agreed to in writing, software 1.13 + * distributed under the License is distributed on an "AS IS" BASIS, 1.14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.15 + * See the License for the specific language governing permissions and 1.16 + * limitations under the License. 1.17 + */ 1.18 + 1.19 +#include "NetworkUtils.h" 1.20 + 1.21 +#include <android/log.h> 1.22 +#include <cutils/properties.h> 1.23 +#include <limits> 1.24 +#include "mozilla/dom/network/NetUtils.h" 1.25 + 1.26 +#include <sys/types.h> // struct addrinfo 1.27 +#include <sys/socket.h> // getaddrinfo(), freeaddrinfo() 1.28 +#include <netdb.h> 1.29 +#include <arpa/inet.h> // inet_ntop() 1.30 + 1.31 +#define _DEBUG 0 1.32 + 1.33 +#define WARN(args...) __android_log_print(ANDROID_LOG_WARN, "NetworkUtils", ## args) 1.34 +#define ERROR(args...) __android_log_print(ANDROID_LOG_ERROR, "NetworkUtils", ## args) 1.35 + 1.36 +#if _DEBUG 1.37 +#define DEBUG(args...) __android_log_print(ANDROID_LOG_DEBUG, "NetworkUtils" , ## args) 1.38 +#else 1.39 +#define DEBUG(args...) 1.40 +#endif 1.41 + 1.42 +using namespace mozilla::dom; 1.43 +using namespace mozilla::ipc; 1.44 + 1.45 +static const char* PERSIST_SYS_USB_CONFIG_PROPERTY = "persist.sys.usb.config"; 1.46 +static const char* SYS_USB_CONFIG_PROPERTY = "sys.usb.config"; 1.47 +static const char* SYS_USB_STATE_PROPERTY = "sys.usb.state"; 1.48 + 1.49 +static const char* USB_FUNCTION_RNDIS = "rndis"; 1.50 +static const char* USB_FUNCTION_ADB = "adb"; 1.51 + 1.52 +// Use this command to continue the function chain. 1.53 +static const char* DUMMY_COMMAND = "tether status"; 1.54 + 1.55 +// Retry 20 times (2 seconds) for usb state transition. 1.56 +static const uint32_t USB_FUNCTION_RETRY_TIMES = 20; 1.57 +// Check "sys.usb.state" every 100ms. 1.58 +static const uint32_t USB_FUNCTION_RETRY_INTERVAL = 100; 1.59 + 1.60 +// 1xx - Requested action is proceeding 1.61 +static const uint32_t NETD_COMMAND_PROCEEDING = 100; 1.62 +// 2xx - Requested action has been successfully completed 1.63 +static const uint32_t NETD_COMMAND_OKAY = 200; 1.64 +// 4xx - The command is accepted but the requested action didn't 1.65 +// take place. 1.66 +static const uint32_t NETD_COMMAND_FAIL = 400; 1.67 +// 5xx - The command syntax or parameters error 1.68 +static const uint32_t NETD_COMMAND_ERROR = 500; 1.69 +// 6xx - Unsolicited broadcasts 1.70 +static const uint32_t NETD_COMMAND_UNSOLICITED = 600; 1.71 + 1.72 +// Broadcast messages 1.73 +static const uint32_t NETD_COMMAND_INTERFACE_CHANGE = 600; 1.74 +static const uint32_t NETD_COMMAND_BANDWIDTH_CONTROLLER = 601; 1.75 + 1.76 +static const char* INTERFACE_DELIMIT = ","; 1.77 +static const char* USB_CONFIG_DELIMIT = ","; 1.78 +static const char* NETD_MESSAGE_DELIMIT = " "; 1.79 + 1.80 +static const uint32_t BUF_SIZE = 1024; 1.81 + 1.82 +static uint32_t SDK_VERSION; 1.83 + 1.84 +struct IFProperties { 1.85 + char gateway[PROPERTY_VALUE_MAX]; 1.86 + char dns1[PROPERTY_VALUE_MAX]; 1.87 + char dns2[PROPERTY_VALUE_MAX]; 1.88 +}; 1.89 + 1.90 +struct CurrentCommand { 1.91 + CommandChain* chain; 1.92 + CommandCallback callback; 1.93 + char command[MAX_COMMAND_SIZE]; 1.94 +}; 1.95 + 1.96 +typedef Tuple3<NetdCommand*, CommandChain*, CommandCallback> QueueData; 1.97 + 1.98 +#define GET_CURRENT_NETD_COMMAND (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].a) 1.99 +#define GET_CURRENT_CHAIN (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].b) 1.100 +#define GET_CURRENT_CALLBACK (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].c) 1.101 +#define GET_CURRENT_COMMAND (gCommandQueue.IsEmpty() ? nullptr : gCommandQueue[0].a->mData) 1.102 + 1.103 +static NetworkUtils* gNetworkUtils; 1.104 +static nsTArray<QueueData> gCommandQueue; 1.105 +static CurrentCommand gCurrentCommand; 1.106 +static bool gPending = false; 1.107 +static nsTArray<nsCString> gReason; 1.108 + 1.109 +CommandFunc NetworkUtils::sWifiEnableChain[] = { 1.110 + NetworkUtils::wifiFirmwareReload, 1.111 + NetworkUtils::startAccessPointDriver, 1.112 + NetworkUtils::setAccessPoint, 1.113 + NetworkUtils::startSoftAP, 1.114 + NetworkUtils::setInterfaceUp, 1.115 + NetworkUtils::tetherInterface, 1.116 + NetworkUtils::setIpForwardingEnabled, 1.117 + NetworkUtils::tetheringStatus, 1.118 + NetworkUtils::startTethering, 1.119 + NetworkUtils::setDnsForwarders, 1.120 + NetworkUtils::enableNat, 1.121 + NetworkUtils::wifiTetheringSuccess 1.122 +}; 1.123 + 1.124 +CommandFunc NetworkUtils::sWifiDisableChain[] = { 1.125 + NetworkUtils::stopSoftAP, 1.126 + NetworkUtils::stopAccessPointDriver, 1.127 + NetworkUtils::wifiFirmwareReload, 1.128 + NetworkUtils::untetherInterface, 1.129 + NetworkUtils::preTetherInterfaceList, 1.130 + NetworkUtils::postTetherInterfaceList, 1.131 + NetworkUtils::disableNat, 1.132 + NetworkUtils::setIpForwardingEnabled, 1.133 + NetworkUtils::stopTethering, 1.134 + NetworkUtils::wifiTetheringSuccess 1.135 +}; 1.136 + 1.137 +CommandFunc NetworkUtils::sWifiFailChain[] = { 1.138 + NetworkUtils::stopSoftAP, 1.139 + NetworkUtils::setIpForwardingEnabled, 1.140 + NetworkUtils::stopTethering 1.141 +}; 1.142 + 1.143 +CommandFunc NetworkUtils::sWifiOperationModeChain[] = { 1.144 + NetworkUtils::wifiFirmwareReload, 1.145 + NetworkUtils::wifiOperationModeSuccess 1.146 +}; 1.147 + 1.148 +CommandFunc NetworkUtils::sUSBEnableChain[] = { 1.149 + NetworkUtils::setInterfaceUp, 1.150 + NetworkUtils::enableNat, 1.151 + NetworkUtils::setIpForwardingEnabled, 1.152 + NetworkUtils::tetherInterface, 1.153 + NetworkUtils::tetheringStatus, 1.154 + NetworkUtils::startTethering, 1.155 + NetworkUtils::setDnsForwarders, 1.156 + NetworkUtils::usbTetheringSuccess 1.157 +}; 1.158 + 1.159 +CommandFunc NetworkUtils::sUSBDisableChain[] = { 1.160 + NetworkUtils::untetherInterface, 1.161 + NetworkUtils::preTetherInterfaceList, 1.162 + NetworkUtils::postTetherInterfaceList, 1.163 + NetworkUtils::disableNat, 1.164 + NetworkUtils::setIpForwardingEnabled, 1.165 + NetworkUtils::stopTethering, 1.166 + NetworkUtils::usbTetheringSuccess 1.167 +}; 1.168 + 1.169 +CommandFunc NetworkUtils::sUSBFailChain[] = { 1.170 + NetworkUtils::stopSoftAP, 1.171 + NetworkUtils::setIpForwardingEnabled, 1.172 + NetworkUtils::stopTethering 1.173 +}; 1.174 + 1.175 +CommandFunc NetworkUtils::sUpdateUpStreamChain[] = { 1.176 + NetworkUtils::cleanUpStream, 1.177 + NetworkUtils::createUpStream, 1.178 + NetworkUtils::updateUpStreamSuccess 1.179 +}; 1.180 + 1.181 +CommandFunc NetworkUtils::sStartDhcpServerChain[] = { 1.182 + NetworkUtils::setInterfaceUp, 1.183 + NetworkUtils::startTethering, 1.184 + NetworkUtils::setDhcpServerSuccess 1.185 +}; 1.186 + 1.187 +CommandFunc NetworkUtils::sStopDhcpServerChain[] = { 1.188 + NetworkUtils::stopTethering, 1.189 + NetworkUtils::setDhcpServerSuccess 1.190 +}; 1.191 + 1.192 +CommandFunc NetworkUtils::sNetworkInterfaceStatsChain[] = { 1.193 + NetworkUtils::getRxBytes, 1.194 + NetworkUtils::getTxBytes, 1.195 + NetworkUtils::networkInterfaceStatsSuccess 1.196 +}; 1.197 + 1.198 +CommandFunc NetworkUtils::sNetworkInterfaceEnableAlarmChain[] = { 1.199 + NetworkUtils::enableAlarm, 1.200 + NetworkUtils::setQuota, 1.201 + NetworkUtils::setAlarm, 1.202 + NetworkUtils::networkInterfaceAlarmSuccess 1.203 +}; 1.204 + 1.205 +CommandFunc NetworkUtils::sNetworkInterfaceDisableAlarmChain[] = { 1.206 + NetworkUtils::removeQuota, 1.207 + NetworkUtils::disableAlarm, 1.208 + NetworkUtils::networkInterfaceAlarmSuccess 1.209 +}; 1.210 + 1.211 +CommandFunc NetworkUtils::sNetworkInterfaceSetAlarmChain[] = { 1.212 + NetworkUtils::setAlarm, 1.213 + NetworkUtils::networkInterfaceAlarmSuccess 1.214 +}; 1.215 + 1.216 +CommandFunc NetworkUtils::sSetDnsChain[] = { 1.217 + NetworkUtils::setDefaultInterface, 1.218 + NetworkUtils::setInterfaceDns 1.219 +}; 1.220 + 1.221 +/** 1.222 + * Helper function to get the mask from given prefix length. 1.223 + */ 1.224 +static uint32_t makeMask(const uint32_t prefixLength) 1.225 +{ 1.226 + uint32_t mask = 0; 1.227 + for (uint32_t i = 0; i < prefixLength; ++i) { 1.228 + mask |= (0x80000000 >> i); 1.229 + } 1.230 + return ntohl(mask); 1.231 +} 1.232 + 1.233 +/** 1.234 + * Helper function to get the network part of an ip from prefix. 1.235 + * param ip must be in network byte order. 1.236 + */ 1.237 +static char* getNetworkAddr(const uint32_t ip, const uint32_t prefix) 1.238 +{ 1.239 + uint32_t mask = 0, subnet = 0; 1.240 + 1.241 + mask = ~mask << (32 - prefix); 1.242 + mask = htonl(mask); 1.243 + subnet = ip & mask; 1.244 + 1.245 + struct in_addr addr; 1.246 + addr.s_addr = subnet; 1.247 + 1.248 + return inet_ntoa(addr); 1.249 +} 1.250 + 1.251 +/** 1.252 + * Helper function to split string by seperator, store split result as an nsTArray. 1.253 + */ 1.254 +static void split(char* str, const char* sep, nsTArray<nsCString>& result) 1.255 +{ 1.256 + char *s = strtok(str, sep); 1.257 + while (s != nullptr) { 1.258 + result.AppendElement(s); 1.259 + s = strtok(nullptr, sep); 1.260 + } 1.261 +} 1.262 + 1.263 +static void split(char* str, const char* sep, nsTArray<nsString>& result) 1.264 +{ 1.265 + char *s = strtok(str, sep); 1.266 + while (s != nullptr) { 1.267 + result.AppendElement(NS_ConvertUTF8toUTF16(s)); 1.268 + s = strtok(nullptr, sep); 1.269 + } 1.270 +} 1.271 + 1.272 +/** 1.273 + * Helper function that implement join function. 1.274 + */ 1.275 +static void join(nsTArray<nsCString>& array, 1.276 + const char* sep, 1.277 + const uint32_t maxlen, 1.278 + char* result) 1.279 +{ 1.280 +#define CHECK_LENGTH(len, add, max) len += add; \ 1.281 + if (len > max - 1) \ 1.282 + return; \ 1.283 + 1.284 + uint32_t len = 0; 1.285 + uint32_t seplen = strlen(sep); 1.286 + 1.287 + if (array.Length() > 0) { 1.288 + CHECK_LENGTH(len, strlen(array[0].get()), maxlen) 1.289 + strcpy(result, array[0].get()); 1.290 + 1.291 + for (uint32_t i = 1; i < array.Length(); i++) { 1.292 + CHECK_LENGTH(len, seplen, maxlen) 1.293 + strcat(result, sep); 1.294 + 1.295 + CHECK_LENGTH(len, strlen(array[i].get()), maxlen) 1.296 + strcat(result, array[i].get()); 1.297 + } 1.298 + } 1.299 + 1.300 +#undef CHECK_LEN 1.301 +} 1.302 + 1.303 +/** 1.304 + * Helper function to get network interface properties from the system property table. 1.305 + */ 1.306 +static void getIFProperties(const char* ifname, IFProperties& prop) 1.307 +{ 1.308 + char key[PROPERTY_KEY_MAX]; 1.309 + snprintf(key, PROPERTY_KEY_MAX - 1, "net.%s.gw", ifname); 1.310 + property_get(key, prop.gateway, ""); 1.311 + snprintf(key, PROPERTY_KEY_MAX - 1, "net.%s.dns1", ifname); 1.312 + property_get(key, prop.dns1, ""); 1.313 + snprintf(key, PROPERTY_KEY_MAX - 1, "net.%s.dns2", ifname); 1.314 + property_get(key, prop.dns2, ""); 1.315 +} 1.316 + 1.317 +static int getIpType(const char *aIp) { 1.318 + struct addrinfo hint, *ip_info = NULL; 1.319 + 1.320 + memset(&hint, 0, sizeof(hint)); 1.321 + hint.ai_family = AF_UNSPEC; 1.322 + hint.ai_flags = AI_NUMERICHOST; 1.323 + 1.324 + if (getaddrinfo(aIp, NULL, &hint, &ip_info)) { 1.325 + return AF_UNSPEC; 1.326 + } 1.327 + 1.328 + int type = ip_info->ai_family; 1.329 + freeaddrinfo(ip_info); 1.330 + 1.331 + return type; 1.332 +} 1.333 + 1.334 +/** 1.335 + * Helper function to find the best match gateway. For now, return 1.336 + * the gateway that matches the address family passed. 1.337 + */ 1.338 +static uint32_t selectGateway(nsTArray<nsString>& gateways, int addrFamily) 1.339 +{ 1.340 + uint32_t length = gateways.Length(); 1.341 + 1.342 + for (uint32_t i = 0; i < length; i++) { 1.343 + NS_ConvertUTF16toUTF8 autoGateway(gateways[i]); 1.344 + if ((getIpType(autoGateway.get()) == AF_INET && addrFamily == AF_INET) || 1.345 + (getIpType(autoGateway.get()) == AF_INET6 && addrFamily == AF_INET6)) { 1.346 + return i; 1.347 + } 1.348 + } 1.349 + return length; // invalid index. 1.350 +} 1.351 + 1.352 +static void postMessage(NetworkResultOptions& aResult) 1.353 +{ 1.354 + MOZ_ASSERT(gNetworkUtils); 1.355 + MOZ_ASSERT(gNetworkUtils->getMessageCallback()); 1.356 + 1.357 + if (*(gNetworkUtils->getMessageCallback())) 1.358 + (*(gNetworkUtils->getMessageCallback()))(aResult); 1.359 +} 1.360 + 1.361 +static void postMessage(NetworkParams& aOptions, NetworkResultOptions& aResult) 1.362 +{ 1.363 + MOZ_ASSERT(gNetworkUtils); 1.364 + MOZ_ASSERT(gNetworkUtils->getMessageCallback()); 1.365 + 1.366 + aResult.mId = aOptions.mId; 1.367 + 1.368 + if (*(gNetworkUtils->getMessageCallback())) 1.369 + (*(gNetworkUtils->getMessageCallback()))(aResult); 1.370 +} 1.371 + 1.372 +void NetworkUtils::next(CommandChain* aChain, bool aError, NetworkResultOptions& aResult) 1.373 +{ 1.374 + if (aError) { 1.375 + ErrorCallback onError = aChain->getErrorCallback(); 1.376 + if(onError) { 1.377 + aResult.mError = true; 1.378 + (*onError)(aChain->getParams(), aResult); 1.379 + } 1.380 + delete aChain; 1.381 + return; 1.382 + } 1.383 + CommandFunc f = aChain->getNextCommand(); 1.384 + if (!f) { 1.385 + delete aChain; 1.386 + return; 1.387 + } 1.388 + 1.389 + (*f)(aChain, next, aResult); 1.390 +} 1.391 + 1.392 +/** 1.393 + * Send command to netd. 1.394 + */ 1.395 +void NetworkUtils::nextNetdCommand() 1.396 +{ 1.397 + if (gCommandQueue.IsEmpty() || gPending) { 1.398 + return; 1.399 + } 1.400 + 1.401 + gCurrentCommand.chain = GET_CURRENT_CHAIN; 1.402 + gCurrentCommand.callback = GET_CURRENT_CALLBACK; 1.403 + snprintf(gCurrentCommand.command, MAX_COMMAND_SIZE - 1, "%s", GET_CURRENT_COMMAND); 1.404 + 1.405 + DEBUG("Sending \'%s\' command to netd.", gCurrentCommand.command); 1.406 + SendNetdCommand(GET_CURRENT_NETD_COMMAND); 1.407 + 1.408 + gCommandQueue.RemoveElementAt(0); 1.409 + gPending = true; 1.410 +} 1.411 + 1.412 +/** 1.413 + * Composite NetdCommand sent to netd 1.414 + * 1.415 + * @param aCommand Command sent to netd to execute. 1.416 + * @param aChain Store command chain data, ex. command parameter. 1.417 + * @param aCallback Callback function to be executed when the result of 1.418 + * this command is returned from netd. 1.419 + */ 1.420 +void NetworkUtils::doCommand(const char* aCommand, CommandChain* aChain, CommandCallback aCallback) 1.421 +{ 1.422 + DEBUG("Preparing to send \'%s\' command...", aCommand); 1.423 + 1.424 + NetdCommand* netdCommand = new NetdCommand(); 1.425 + 1.426 + // Android JB version adds sequence number to netd command. 1.427 + if (SDK_VERSION >= 16) { 1.428 + snprintf((char*)netdCommand->mData, MAX_COMMAND_SIZE - 1, "0 %s", aCommand); 1.429 + } else { 1.430 + snprintf((char*)netdCommand->mData, MAX_COMMAND_SIZE - 1, "%s", aCommand); 1.431 + } 1.432 + netdCommand->mSize = strlen((char*)netdCommand->mData) + 1; 1.433 + 1.434 + gCommandQueue.AppendElement(QueueData(netdCommand, aChain, aCallback)); 1.435 + 1.436 + nextNetdCommand(); 1.437 +} 1.438 + 1.439 +/* 1.440 + * Netd command function 1.441 + */ 1.442 +#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aChain->getParams().prop).get() 1.443 +#define GET_FIELD(prop) aChain->getParams().prop 1.444 + 1.445 +void NetworkUtils::wifiFirmwareReload(CommandChain* aChain, 1.446 + CommandCallback aCallback, 1.447 + NetworkResultOptions& aResult) 1.448 +{ 1.449 + char command[MAX_COMMAND_SIZE]; 1.450 + snprintf(command, MAX_COMMAND_SIZE - 1, "softap fwreload %s %s", GET_CHAR(mIfname), GET_CHAR(mMode)); 1.451 + 1.452 + doCommand(command, aChain, aCallback); 1.453 +} 1.454 + 1.455 +void NetworkUtils::startAccessPointDriver(CommandChain* aChain, 1.456 + CommandCallback aCallback, 1.457 + NetworkResultOptions& aResult) 1.458 +{ 1.459 + // Skip the command for sdk version >= 16. 1.460 + if (SDK_VERSION >= 16) { 1.461 + aResult.mResultCode = 0; 1.462 + aResult.mResultReason = NS_ConvertUTF8toUTF16(""); 1.463 + aCallback(aChain, false, aResult); 1.464 + return; 1.465 + } 1.466 + 1.467 + char command[MAX_COMMAND_SIZE]; 1.468 + snprintf(command, MAX_COMMAND_SIZE - 1, "softap start %s", GET_CHAR(mIfname)); 1.469 + 1.470 + doCommand(command, aChain, aCallback); 1.471 +} 1.472 + 1.473 +void NetworkUtils::stopAccessPointDriver(CommandChain* aChain, 1.474 + CommandCallback aCallback, 1.475 + NetworkResultOptions& aResult) 1.476 +{ 1.477 + // Skip the command for sdk version >= 16. 1.478 + if (SDK_VERSION >= 16) { 1.479 + aResult.mResultCode = 0; 1.480 + aResult.mResultReason = NS_ConvertUTF8toUTF16(""); 1.481 + aCallback(aChain, false, aResult); 1.482 + return; 1.483 + } 1.484 + 1.485 + char command[MAX_COMMAND_SIZE]; 1.486 + snprintf(command, MAX_COMMAND_SIZE - 1, "softap stop %s", GET_CHAR(mIfname)); 1.487 + 1.488 + doCommand(command, aChain, aCallback); 1.489 +} 1.490 + 1.491 +/** 1.492 + * Command format for sdk version < 16 1.493 + * Arguments: 1.494 + * argv[2] - wlan interface 1.495 + * argv[3] - SSID 1.496 + * argv[4] - Security 1.497 + * argv[5] - Key 1.498 + * argv[6] - Channel 1.499 + * argv[7] - Preamble 1.500 + * argv[8] - Max SCB 1.501 + * 1.502 + * Command format for sdk version >= 16 1.503 + * Arguments: 1.504 + * argv[2] - wlan interface 1.505 + * argv[3] - SSID 1.506 + * argv[4] - Security 1.507 + * argv[5] - Key 1.508 + * 1.509 + * Command format for sdk version >= 18 1.510 + * Arguments: 1.511 + * argv[2] - wlan interface 1.512 + * argv[3] - SSID 1.513 + * argv[4] - Broadcast/Hidden 1.514 + * argv[5] - Channel 1.515 + * argv[6] - Security 1.516 + * argv[7] - Key 1.517 + */ 1.518 +void NetworkUtils::setAccessPoint(CommandChain* aChain, 1.519 + CommandCallback aCallback, 1.520 + NetworkResultOptions& aResult) 1.521 +{ 1.522 + char command[MAX_COMMAND_SIZE]; 1.523 + nsCString ssid(GET_CHAR(mSsid)); 1.524 + nsCString key(GET_CHAR(mKey)); 1.525 + 1.526 + escapeQuote(ssid); 1.527 + escapeQuote(key); 1.528 + 1.529 + if (SDK_VERSION >= 19) { 1.530 + snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s \"%s\" broadcast 6 %s \"%s\"", 1.531 + GET_CHAR(mIfname), 1.532 + ssid.get(), 1.533 + GET_CHAR(mSecurity), 1.534 + key.get()); 1.535 + } else if (SDK_VERSION >= 16) { 1.536 + snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s \"%s\" %s \"%s\"", 1.537 + GET_CHAR(mIfname), 1.538 + ssid.get(), 1.539 + GET_CHAR(mSecurity), 1.540 + key.get()); 1.541 + } else { 1.542 + snprintf(command, MAX_COMMAND_SIZE - 1, "softap set %s %s \"%s\" %s \"%s\" 6 0 8", 1.543 + GET_CHAR(mIfname), 1.544 + GET_CHAR(mWifictrlinterfacename), 1.545 + ssid.get(), 1.546 + GET_CHAR(mSecurity), 1.547 + key.get()); 1.548 + } 1.549 + 1.550 + doCommand(command, aChain, aCallback); 1.551 +} 1.552 + 1.553 +void NetworkUtils::cleanUpStream(CommandChain* aChain, 1.554 + CommandCallback aCallback, 1.555 + NetworkResultOptions& aResult) 1.556 +{ 1.557 + char command[MAX_COMMAND_SIZE]; 1.558 + snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 0", GET_CHAR(mPreInternalIfname), GET_CHAR(mPreExternalIfname)); 1.559 + 1.560 + doCommand(command, aChain, aCallback); 1.561 +} 1.562 + 1.563 +void NetworkUtils::createUpStream(CommandChain* aChain, 1.564 + CommandCallback aCallback, 1.565 + NetworkResultOptions& aResult) 1.566 +{ 1.567 + char command[MAX_COMMAND_SIZE]; 1.568 + snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 0", GET_CHAR(mCurInternalIfname), GET_CHAR(mCurExternalIfname)); 1.569 + 1.570 + doCommand(command, aChain, aCallback); 1.571 +} 1.572 + 1.573 +void NetworkUtils::startSoftAP(CommandChain* aChain, 1.574 + CommandCallback aCallback, 1.575 + NetworkResultOptions& aResult) 1.576 +{ 1.577 + const char* command= "softap startap"; 1.578 + doCommand(command, aChain, aCallback); 1.579 +} 1.580 + 1.581 +void NetworkUtils::stopSoftAP(CommandChain* aChain, 1.582 + CommandCallback aCallback, 1.583 + NetworkResultOptions& aResult) 1.584 +{ 1.585 + const char* command= "softap stopap"; 1.586 + doCommand(command, aChain, aCallback); 1.587 +} 1.588 + 1.589 +void NetworkUtils::getRxBytes(CommandChain* aChain, 1.590 + CommandCallback aCallback, 1.591 + NetworkResultOptions& aResult) 1.592 +{ 1.593 + char command[MAX_COMMAND_SIZE]; 1.594 + snprintf(command, MAX_COMMAND_SIZE - 1, "interface readrxcounter %s", GET_CHAR(mIfname)); 1.595 + 1.596 + doCommand(command, aChain, aCallback); 1.597 +} 1.598 + 1.599 +void NetworkUtils::getTxBytes(CommandChain* aChain, 1.600 + CommandCallback aCallback, 1.601 + NetworkResultOptions& aResult) 1.602 +{ 1.603 + NetworkParams& options = aChain->getParams(); 1.604 + options.mRxBytes = atof(NS_ConvertUTF16toUTF8(aResult.mResultReason).get()); 1.605 + 1.606 + char command[MAX_COMMAND_SIZE]; 1.607 + snprintf(command, MAX_COMMAND_SIZE - 1, "interface readtxcounter %s", GET_CHAR(mIfname)); 1.608 + 1.609 + doCommand(command, aChain, aCallback); 1.610 +} 1.611 + 1.612 +void NetworkUtils::enableAlarm(CommandChain* aChain, 1.613 + CommandCallback aCallback, 1.614 + NetworkResultOptions& aResult) 1.615 +{ 1.616 + const char* command= "bandwidth enable"; 1.617 + doCommand(command, aChain, aCallback); 1.618 +} 1.619 + 1.620 +void NetworkUtils::disableAlarm(CommandChain* aChain, 1.621 + CommandCallback aCallback, 1.622 + NetworkResultOptions& aResult) 1.623 +{ 1.624 + const char* command= "bandwidth disable"; 1.625 + doCommand(command, aChain, aCallback); 1.626 +} 1.627 + 1.628 +void NetworkUtils::setQuota(CommandChain* aChain, 1.629 + CommandCallback aCallback, 1.630 + NetworkResultOptions& aResult) 1.631 +{ 1.632 + char command[MAX_COMMAND_SIZE]; 1.633 + snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setiquota %s %lld", GET_CHAR(mIfname), LLONG_MAX); 1.634 + 1.635 + doCommand(command, aChain, aCallback); 1.636 +} 1.637 + 1.638 +void NetworkUtils::removeQuota(CommandChain* aChain, 1.639 + CommandCallback aCallback, 1.640 + NetworkResultOptions& aResult) 1.641 +{ 1.642 + char command[MAX_COMMAND_SIZE]; 1.643 + snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth removeiquota %s", GET_CHAR(mIfname)); 1.644 + 1.645 + doCommand(command, aChain, aCallback); 1.646 +} 1.647 + 1.648 +void NetworkUtils::setAlarm(CommandChain* aChain, 1.649 + CommandCallback aCallback, 1.650 + NetworkResultOptions& aResult) 1.651 +{ 1.652 + char command[MAX_COMMAND_SIZE]; 1.653 + snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setinterfacealert %s %ld", GET_CHAR(mIfname), GET_FIELD(mThreshold)); 1.654 + 1.655 + doCommand(command, aChain, aCallback); 1.656 +} 1.657 + 1.658 +void NetworkUtils::setInterfaceUp(CommandChain* aChain, 1.659 + CommandCallback aCallback, 1.660 + NetworkResultOptions& aResult) 1.661 +{ 1.662 + char command[MAX_COMMAND_SIZE]; 1.663 + if (SDK_VERSION >= 16) { 1.664 + snprintf(command, MAX_COMMAND_SIZE - 1, "interface setcfg %s %s %s %s", 1.665 + GET_CHAR(mIfname), 1.666 + GET_CHAR(mIp), 1.667 + GET_CHAR(mPrefix), 1.668 + GET_CHAR(mLink)); 1.669 + } else { 1.670 + snprintf(command, MAX_COMMAND_SIZE - 1, "interface setcfg %s %s %s [%s]", 1.671 + GET_CHAR(mIfname), 1.672 + GET_CHAR(mIp), 1.673 + GET_CHAR(mPrefix), 1.674 + GET_CHAR(mLink)); 1.675 + } 1.676 + doCommand(command, aChain, aCallback); 1.677 +} 1.678 + 1.679 +void NetworkUtils::tetherInterface(CommandChain* aChain, 1.680 + CommandCallback aCallback, 1.681 + NetworkResultOptions& aResult) 1.682 +{ 1.683 + char command[MAX_COMMAND_SIZE]; 1.684 + snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface add %s", GET_CHAR(mIfname)); 1.685 + 1.686 + doCommand(command, aChain, aCallback); 1.687 +} 1.688 + 1.689 +void NetworkUtils::preTetherInterfaceList(CommandChain* aChain, 1.690 + CommandCallback aCallback, 1.691 + NetworkResultOptions& aResult) 1.692 +{ 1.693 + char command[MAX_COMMAND_SIZE]; 1.694 + if (SDK_VERSION >= 16) { 1.695 + snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface list"); 1.696 + } else { 1.697 + snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface list 0"); 1.698 + } 1.699 + 1.700 + doCommand(command, aChain, aCallback); 1.701 +} 1.702 + 1.703 +void NetworkUtils::postTetherInterfaceList(CommandChain* aChain, 1.704 + CommandCallback aCallback, 1.705 + NetworkResultOptions& aResult) 1.706 +{ 1.707 + // Send the dummy command to continue the function chain. 1.708 + char command[MAX_COMMAND_SIZE]; 1.709 + snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND); 1.710 + 1.711 + char buf[BUF_SIZE]; 1.712 + const char* reason = NS_ConvertUTF16toUTF8(aResult.mResultReason).get(); 1.713 + memcpy(buf, reason, strlen(reason)); 1.714 + split(buf, INTERFACE_DELIMIT, GET_FIELD(mInterfaceList)); 1.715 + 1.716 + doCommand(command, aChain, aCallback); 1.717 +} 1.718 + 1.719 +void NetworkUtils::setIpForwardingEnabled(CommandChain* aChain, 1.720 + CommandCallback aCallback, 1.721 + NetworkResultOptions& aResult) 1.722 +{ 1.723 + char command[MAX_COMMAND_SIZE]; 1.724 + 1.725 + if (GET_FIELD(mEnable)) { 1.726 + snprintf(command, MAX_COMMAND_SIZE - 1, "ipfwd enable"); 1.727 + } else { 1.728 + // Don't disable ip forwarding because others interface still need it. 1.729 + // Send the dummy command to continue the function chain. 1.730 + if (GET_FIELD(mInterfaceList).Length() > 1) { 1.731 + snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND); 1.732 + } else { 1.733 + snprintf(command, MAX_COMMAND_SIZE - 1, "ipfwd disable"); 1.734 + } 1.735 + } 1.736 + 1.737 + doCommand(command, aChain, aCallback); 1.738 +} 1.739 + 1.740 +void NetworkUtils::tetheringStatus(CommandChain* aChain, 1.741 + CommandCallback aCallback, 1.742 + NetworkResultOptions& aResult) 1.743 +{ 1.744 + const char* command= "tether status"; 1.745 + doCommand(command, aChain, aCallback); 1.746 +} 1.747 + 1.748 +void NetworkUtils::stopTethering(CommandChain* aChain, 1.749 + CommandCallback aCallback, 1.750 + NetworkResultOptions& aResult) 1.751 +{ 1.752 + char command[MAX_COMMAND_SIZE]; 1.753 + 1.754 + // Don't stop tethering because others interface still need it. 1.755 + // Send the dummy to continue the function chain. 1.756 + if (GET_FIELD(mInterfaceList).Length() > 1) { 1.757 + snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND); 1.758 + } else { 1.759 + snprintf(command, MAX_COMMAND_SIZE - 1, "tether stop"); 1.760 + } 1.761 + 1.762 + doCommand(command, aChain, aCallback); 1.763 +} 1.764 + 1.765 +void NetworkUtils::startTethering(CommandChain* aChain, 1.766 + CommandCallback aCallback, 1.767 + NetworkResultOptions& aResult) 1.768 +{ 1.769 + char command[MAX_COMMAND_SIZE]; 1.770 + 1.771 + // We don't need to start tethering again. 1.772 + // Send the dummy command to continue the function chain. 1.773 + if (aResult.mResultReason.Find("started") != kNotFound) { 1.774 + snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND); 1.775 + } else { 1.776 + snprintf(command, MAX_COMMAND_SIZE - 1, "tether start %s %s", GET_CHAR(mWifiStartIp), GET_CHAR(mWifiEndIp)); 1.777 + 1.778 + // If usbStartIp/usbEndIp is not valid, don't append them since 1.779 + // the trailing white spaces will be parsed to extra empty args 1.780 + // See: http://androidxref.com/4.3_r2.1/xref/system/core/libsysutils/src/FrameworkListener.cpp#78 1.781 + if (!GET_FIELD(mUsbStartIp).IsEmpty() && !GET_FIELD(mUsbEndIp).IsEmpty()) { 1.782 + snprintf(command, MAX_COMMAND_SIZE - 1, "%s %s %s", command, GET_CHAR(mUsbStartIp), GET_CHAR(mUsbEndIp)); 1.783 + } 1.784 + } 1.785 + 1.786 + doCommand(command, aChain, aCallback); 1.787 +} 1.788 + 1.789 +void NetworkUtils::untetherInterface(CommandChain* aChain, 1.790 + CommandCallback aCallback, 1.791 + NetworkResultOptions& aResult) 1.792 +{ 1.793 + char command[MAX_COMMAND_SIZE]; 1.794 + snprintf(command, MAX_COMMAND_SIZE - 1, "tether interface remove %s", GET_CHAR(mIfname)); 1.795 + 1.796 + doCommand(command, aChain, aCallback); 1.797 +} 1.798 + 1.799 +void NetworkUtils::setDnsForwarders(CommandChain* aChain, 1.800 + CommandCallback aCallback, 1.801 + NetworkResultOptions& aResult) 1.802 +{ 1.803 + char command[MAX_COMMAND_SIZE]; 1.804 + snprintf(command, MAX_COMMAND_SIZE - 1, "tether dns set %s %s", GET_CHAR(mDns1), GET_CHAR(mDns2)); 1.805 + 1.806 + doCommand(command, aChain, aCallback); 1.807 +} 1.808 + 1.809 +void NetworkUtils::enableNat(CommandChain* aChain, 1.810 + CommandCallback aCallback, 1.811 + NetworkResultOptions& aResult) 1.812 +{ 1.813 + char command[MAX_COMMAND_SIZE]; 1.814 + 1.815 + if (!GET_FIELD(mIp).IsEmpty() && !GET_FIELD(mPrefix).IsEmpty()) { 1.816 + uint32_t prefix = atoi(GET_CHAR(mPrefix)); 1.817 + uint32_t ip = inet_addr(GET_CHAR(mIp)); 1.818 + char* networkAddr = getNetworkAddr(ip, prefix); 1.819 + 1.820 + // address/prefix will only take effect when secondary routing table exists. 1.821 + snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 1 %s/%s", 1.822 + GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname), networkAddr, 1.823 + GET_CHAR(mPrefix)); 1.824 + } else { 1.825 + snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 0", 1.826 + GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); 1.827 + } 1.828 + 1.829 + doCommand(command, aChain, aCallback); 1.830 +} 1.831 + 1.832 +void NetworkUtils::disableNat(CommandChain* aChain, 1.833 + CommandCallback aCallback, 1.834 + NetworkResultOptions& aResult) 1.835 +{ 1.836 + char command[MAX_COMMAND_SIZE]; 1.837 + 1.838 + if (!GET_FIELD(mIp).IsEmpty() && !GET_FIELD(mPrefix).IsEmpty()) { 1.839 + uint32_t prefix = atoi(GET_CHAR(mPrefix)); 1.840 + uint32_t ip = inet_addr(GET_CHAR(mIp)); 1.841 + char* networkAddr = getNetworkAddr(ip, prefix); 1.842 + 1.843 + snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 1 %s/%s", 1.844 + GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname), networkAddr, 1.845 + GET_CHAR(mPrefix)); 1.846 + } else { 1.847 + snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 0", 1.848 + GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); 1.849 + } 1.850 + 1.851 + doCommand(command, aChain, aCallback); 1.852 +} 1.853 + 1.854 +void NetworkUtils::setDefaultInterface(CommandChain* aChain, 1.855 + CommandCallback aCallback, 1.856 + NetworkResultOptions& aResult) 1.857 +{ 1.858 + char command[MAX_COMMAND_SIZE]; 1.859 + snprintf(command, MAX_COMMAND_SIZE - 1, "resolver setdefaultif %s", GET_CHAR(mIfname)); 1.860 + 1.861 + doCommand(command, aChain, aCallback); 1.862 +} 1.863 + 1.864 +void NetworkUtils::setInterfaceDns(CommandChain* aChain, 1.865 + CommandCallback aCallback, 1.866 + NetworkResultOptions& aResult) 1.867 +{ 1.868 + char command[MAX_COMMAND_SIZE]; 1.869 + int written = snprintf(command, sizeof command, "resolver setifdns %s %s", 1.870 + GET_CHAR(mIfname), GET_CHAR(mDomain)); 1.871 + 1.872 + nsTArray<nsString>& dnses = GET_FIELD(mDnses); 1.873 + uint32_t length = dnses.Length(); 1.874 + 1.875 + for (uint32_t i = 0; i < length; i++) { 1.876 + NS_ConvertUTF16toUTF8 autoDns(dnses[i]); 1.877 + 1.878 + int ret = snprintf(command + written, sizeof(command) - written, " %s", autoDns.get()); 1.879 + if (ret <= 1) { 1.880 + command[written] = '\0'; 1.881 + continue; 1.882 + } 1.883 + 1.884 + if ((ret + written) >= sizeof(command)) { 1.885 + command[written] = '\0'; 1.886 + break; 1.887 + } 1.888 + 1.889 + written += ret; 1.890 + } 1.891 + 1.892 + doCommand(command, aChain, aCallback); 1.893 +} 1.894 + 1.895 +#undef GET_CHAR 1.896 +#undef GET_FIELD 1.897 + 1.898 +/* 1.899 + * Netd command success/fail function 1.900 + */ 1.901 +#define ASSIGN_FIELD(prop) aResult.prop = aChain->getParams().prop; 1.902 +#define ASSIGN_FIELD_VALUE(prop, value) aResult.prop = value; 1.903 + 1.904 +#define RUN_CHAIN(param, cmds, err) \ 1.905 + uint32_t size = sizeof(cmds) / sizeof(CommandFunc); \ 1.906 + CommandChain* chain = new CommandChain(param, cmds, size, err); \ 1.907 + NetworkResultOptions result; \ 1.908 + next(chain, false, result); 1.909 + 1.910 +void NetworkUtils::wifiTetheringFail(NetworkParams& aOptions, NetworkResultOptions& aResult) 1.911 +{ 1.912 + // Notify the main thread. 1.913 + postMessage(aOptions, aResult); 1.914 + 1.915 + // If one of the stages fails, we try roll back to ensure 1.916 + // we don't leave the network systems in limbo. 1.917 + ASSIGN_FIELD_VALUE(mEnable, false) 1.918 + RUN_CHAIN(aOptions, sWifiFailChain, nullptr) 1.919 +} 1.920 + 1.921 +void NetworkUtils::wifiTetheringSuccess(CommandChain* aChain, 1.922 + CommandCallback aCallback, 1.923 + NetworkResultOptions& aResult) 1.924 +{ 1.925 + ASSIGN_FIELD(mEnable) 1.926 + postMessage(aChain->getParams(), aResult); 1.927 +} 1.928 + 1.929 +void NetworkUtils::usbTetheringFail(NetworkParams& aOptions, 1.930 + NetworkResultOptions& aResult) 1.931 +{ 1.932 + // Notify the main thread. 1.933 + postMessage(aOptions, aResult); 1.934 + // Try to roll back to ensure 1.935 + // we don't leave the network systems in limbo. 1.936 + // This parameter is used to disable ipforwarding. 1.937 + { 1.938 + aOptions.mEnable = false; 1.939 + RUN_CHAIN(aOptions, sUSBFailChain, nullptr) 1.940 + } 1.941 + 1.942 + // Disable usb rndis function. 1.943 + { 1.944 + NetworkParams options; 1.945 + options.mEnable = false; 1.946 + options.mReport = false; 1.947 + gNetworkUtils->enableUsbRndis(options); 1.948 + } 1.949 +} 1.950 + 1.951 +void NetworkUtils::usbTetheringSuccess(CommandChain* aChain, 1.952 + CommandCallback aCallback, 1.953 + NetworkResultOptions& aResult) 1.954 +{ 1.955 + ASSIGN_FIELD(mEnable) 1.956 + postMessage(aChain->getParams(), aResult); 1.957 +} 1.958 + 1.959 +void NetworkUtils::networkInterfaceStatsFail(NetworkParams& aOptions, NetworkResultOptions& aResult) 1.960 +{ 1.961 + postMessage(aOptions, aResult); 1.962 +} 1.963 + 1.964 +void NetworkUtils::networkInterfaceStatsSuccess(CommandChain* aChain, 1.965 + CommandCallback aCallback, 1.966 + NetworkResultOptions& aResult) 1.967 +{ 1.968 + ASSIGN_FIELD(mRxBytes) 1.969 + ASSIGN_FIELD_VALUE(mTxBytes, atof(NS_ConvertUTF16toUTF8(aResult.mResultReason).get())) 1.970 + postMessage(aChain->getParams(), aResult); 1.971 +} 1.972 + 1.973 +void NetworkUtils::networkInterfaceAlarmFail(NetworkParams& aOptions, NetworkResultOptions& aResult) 1.974 +{ 1.975 + postMessage(aOptions, aResult); 1.976 +} 1.977 + 1.978 +void NetworkUtils::networkInterfaceAlarmSuccess(CommandChain* aChain, 1.979 + CommandCallback aCallback, 1.980 + NetworkResultOptions& aResult) 1.981 +{ 1.982 + // TODO : error is not used , and it is conflict with boolean type error. 1.983 + // params.error = parseFloat(params.resultReason); 1.984 + postMessage(aChain->getParams(), aResult); 1.985 +} 1.986 + 1.987 +void NetworkUtils::updateUpStreamFail(NetworkParams& aOptions, NetworkResultOptions& aResult) 1.988 +{ 1.989 + postMessage(aOptions, aResult); 1.990 +} 1.991 + 1.992 +void NetworkUtils::updateUpStreamSuccess(CommandChain* aChain, 1.993 + CommandCallback aCallback, 1.994 + NetworkResultOptions& aResult) 1.995 +{ 1.996 + ASSIGN_FIELD(mCurExternalIfname) 1.997 + ASSIGN_FIELD(mCurInternalIfname) 1.998 + postMessage(aChain->getParams(), aResult); 1.999 +} 1.1000 + 1.1001 +void NetworkUtils::setDhcpServerFail(NetworkParams& aOptions, NetworkResultOptions& aResult) 1.1002 +{ 1.1003 + aResult.mSuccess = false; 1.1004 + postMessage(aOptions, aResult); 1.1005 +} 1.1006 + 1.1007 +void NetworkUtils::setDhcpServerSuccess(CommandChain* aChain, CommandCallback aCallback, NetworkResultOptions& aResult) 1.1008 +{ 1.1009 + aResult.mSuccess = true; 1.1010 + postMessage(aChain->getParams(), aResult); 1.1011 +} 1.1012 + 1.1013 +void NetworkUtils::wifiOperationModeFail(NetworkParams& aOptions, NetworkResultOptions& aResult) 1.1014 +{ 1.1015 + postMessage(aOptions, aResult); 1.1016 +} 1.1017 + 1.1018 +void NetworkUtils::wifiOperationModeSuccess(CommandChain* aChain, 1.1019 + CommandCallback aCallback, 1.1020 + NetworkResultOptions& aResult) 1.1021 +{ 1.1022 + postMessage(aChain->getParams(), aResult); 1.1023 +} 1.1024 + 1.1025 +void NetworkUtils::setDnsFail(NetworkParams& aOptions, NetworkResultOptions& aResult) 1.1026 +{ 1.1027 + postMessage(aOptions, aResult); 1.1028 +} 1.1029 + 1.1030 +#undef ASSIGN_FIELD 1.1031 +#undef ASSIGN_FIELD_VALUE 1.1032 + 1.1033 +NetworkUtils::NetworkUtils(MessageCallback aCallback) 1.1034 + : mMessageCallback(aCallback) 1.1035 +{ 1.1036 + mNetUtils = new NetUtils(); 1.1037 + 1.1038 + char value[PROPERTY_VALUE_MAX]; 1.1039 + property_get("ro.build.version.sdk", value, nullptr); 1.1040 + SDK_VERSION = atoi(value); 1.1041 + 1.1042 + gNetworkUtils = this; 1.1043 +} 1.1044 + 1.1045 +NetworkUtils::~NetworkUtils() 1.1046 +{ 1.1047 +} 1.1048 + 1.1049 +#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aOptions.prop).get() 1.1050 +#define GET_FIELD(prop) aOptions.prop 1.1051 + 1.1052 +void NetworkUtils::ExecuteCommand(NetworkParams aOptions) 1.1053 +{ 1.1054 + bool ret = true; 1.1055 + 1.1056 + if (aOptions.mCmd.EqualsLiteral("removeNetworkRoute")) { 1.1057 + removeNetworkRoute(aOptions); 1.1058 + } else if (aOptions.mCmd.EqualsLiteral("setDNS")) { 1.1059 + setDNS(aOptions); 1.1060 + } else if (aOptions.mCmd.EqualsLiteral("setDefaultRouteAndDNS")) { 1.1061 + setDefaultRouteAndDNS(aOptions); 1.1062 + } else if (aOptions.mCmd.EqualsLiteral("removeDefaultRoute")) { 1.1063 + removeDefaultRoute(aOptions); 1.1064 + } else if (aOptions.mCmd.EqualsLiteral("addHostRoute")) { 1.1065 + addHostRoute(aOptions); 1.1066 + } else if (aOptions.mCmd.EqualsLiteral("removeHostRoute")) { 1.1067 + removeHostRoute(aOptions); 1.1068 + } else if (aOptions.mCmd.EqualsLiteral("removeHostRoutes")) { 1.1069 + removeHostRoutes(aOptions); 1.1070 + } else if (aOptions.mCmd.EqualsLiteral("addSecondaryRoute")) { 1.1071 + addSecondaryRoute(aOptions); 1.1072 + } else if (aOptions.mCmd.EqualsLiteral("removeSecondaryRoute")) { 1.1073 + removeSecondaryRoute(aOptions); 1.1074 + } else if (aOptions.mCmd.EqualsLiteral("getNetworkInterfaceStats")) { 1.1075 + getNetworkInterfaceStats(aOptions); 1.1076 + } else if (aOptions.mCmd.EqualsLiteral("setNetworkInterfaceAlarm")) { 1.1077 + setNetworkInterfaceAlarm(aOptions); 1.1078 + } else if (aOptions.mCmd.EqualsLiteral("enableNetworkInterfaceAlarm")) { 1.1079 + enableNetworkInterfaceAlarm(aOptions); 1.1080 + } else if (aOptions.mCmd.EqualsLiteral("disableNetworkInterfaceAlarm")) { 1.1081 + disableNetworkInterfaceAlarm(aOptions); 1.1082 + } else if (aOptions.mCmd.EqualsLiteral("setWifiOperationMode")) { 1.1083 + setWifiOperationMode(aOptions); 1.1084 + } else if (aOptions.mCmd.EqualsLiteral("setDhcpServer")) { 1.1085 + setDhcpServer(aOptions); 1.1086 + } else if (aOptions.mCmd.EqualsLiteral("setWifiTethering")) { 1.1087 + setWifiTethering(aOptions); 1.1088 + } else if (aOptions.mCmd.EqualsLiteral("setUSBTethering")) { 1.1089 + setUSBTethering(aOptions); 1.1090 + } else if (aOptions.mCmd.EqualsLiteral("enableUsbRndis")) { 1.1091 + enableUsbRndis(aOptions); 1.1092 + } else if (aOptions.mCmd.EqualsLiteral("updateUpStream")) { 1.1093 + updateUpStream(aOptions); 1.1094 + } else { 1.1095 + WARN("unknon message"); 1.1096 + return; 1.1097 + } 1.1098 + 1.1099 + if (!aOptions.mIsAsync) { 1.1100 + NetworkResultOptions result; 1.1101 + result.mRet = ret; 1.1102 + postMessage(aOptions, result); 1.1103 + } 1.1104 +} 1.1105 + 1.1106 +/** 1.1107 + * Handle received data from netd. 1.1108 + */ 1.1109 +void NetworkUtils::onNetdMessage(NetdCommand* aCommand) 1.1110 +{ 1.1111 + char* data = (char*)aCommand->mData; 1.1112 + 1.1113 + // get code & reason. 1.1114 + char* result = strtok(data, NETD_MESSAGE_DELIMIT); 1.1115 + 1.1116 + if (!result) { 1.1117 + nextNetdCommand(); 1.1118 + return; 1.1119 + } 1.1120 + uint32_t code = atoi(result); 1.1121 + 1.1122 + if (!isBroadcastMessage(code) && SDK_VERSION >= 16) { 1.1123 + strtok(nullptr, NETD_MESSAGE_DELIMIT); 1.1124 + } 1.1125 + 1.1126 + char* reason = strtok(nullptr, "\0"); 1.1127 + 1.1128 + if (isBroadcastMessage(code)) { 1.1129 + DEBUG("Receiving broadcast message from netd."); 1.1130 + DEBUG(" ==> Code: %d Reason: %s", code, reason); 1.1131 + sendBroadcastMessage(code, reason); 1.1132 + nextNetdCommand(); 1.1133 + return; 1.1134 + } 1.1135 + 1.1136 + // Set pending to false before we handle next command. 1.1137 + DEBUG("Receiving \"%s\" command response from netd.", gCurrentCommand.command); 1.1138 + DEBUG(" ==> Code: %d Reason: %s", code, reason); 1.1139 + 1.1140 + gReason.AppendElement(nsCString(reason)); 1.1141 + 1.1142 + // 1xx response code regards as command is proceeding, we need to wait for 1.1143 + // final response code such as 2xx, 4xx and 5xx before sending next command. 1.1144 + if (isProceeding(code)) { 1.1145 + return; 1.1146 + } 1.1147 + 1.1148 + if (isComplete(code)) { 1.1149 + gPending = false; 1.1150 + } 1.1151 + 1.1152 + if (gCurrentCommand.callback) { 1.1153 + char buf[BUF_SIZE]; 1.1154 + join(gReason, INTERFACE_DELIMIT, BUF_SIZE, buf); 1.1155 + 1.1156 + NetworkResultOptions result; 1.1157 + result.mResultCode = code; 1.1158 + result.mResultReason = NS_ConvertUTF8toUTF16(buf); 1.1159 + (*gCurrentCommand.callback)(gCurrentCommand.chain, isError(code), result); 1.1160 + gReason.Clear(); 1.1161 + } 1.1162 + 1.1163 + // Handling pending commands if any. 1.1164 + if (isComplete(code)) { 1.1165 + nextNetdCommand(); 1.1166 + } 1.1167 +} 1.1168 + 1.1169 +/** 1.1170 + * Start/Stop DHCP server. 1.1171 + */ 1.1172 +bool NetworkUtils::setDhcpServer(NetworkParams& aOptions) 1.1173 +{ 1.1174 + if (aOptions.mEnabled) { 1.1175 + aOptions.mWifiStartIp = aOptions.mStartIp; 1.1176 + aOptions.mWifiEndIp = aOptions.mEndIp; 1.1177 + aOptions.mIp = aOptions.mServerIp; 1.1178 + aOptions.mPrefix = aOptions.mMaskLength; 1.1179 + aOptions.mLink = NS_ConvertUTF8toUTF16("up"); 1.1180 + 1.1181 + RUN_CHAIN(aOptions, sStartDhcpServerChain, setDhcpServerFail) 1.1182 + } else { 1.1183 + RUN_CHAIN(aOptions, sStopDhcpServerChain, setDhcpServerFail) 1.1184 + } 1.1185 + return true; 1.1186 +} 1.1187 + 1.1188 +/** 1.1189 + * Set DNS servers for given network interface. 1.1190 + */ 1.1191 +bool NetworkUtils::setDNS(NetworkParams& aOptions) 1.1192 +{ 1.1193 + uint32_t length = aOptions.mDnses.Length(); 1.1194 + 1.1195 + if (length > 0) { 1.1196 + for (uint32_t i = 0; i < length; i++) { 1.1197 + NS_ConvertUTF16toUTF8 autoDns(aOptions.mDnses[i]); 1.1198 + 1.1199 + char dns_prop_key[PROPERTY_VALUE_MAX]; 1.1200 + snprintf(dns_prop_key, sizeof dns_prop_key, "net.dns%d", i+1); 1.1201 + property_set(dns_prop_key, autoDns.get()); 1.1202 + } 1.1203 + } else { 1.1204 + // Set dnses from system properties. 1.1205 + IFProperties interfaceProperties; 1.1206 + getIFProperties(GET_CHAR(mIfname), interfaceProperties); 1.1207 + 1.1208 + property_set("net.dns1", interfaceProperties.dns1); 1.1209 + property_set("net.dns2", interfaceProperties.dns2); 1.1210 + } 1.1211 + 1.1212 + // Bump the DNS change property. 1.1213 + char dnschange[PROPERTY_VALUE_MAX]; 1.1214 + property_get("net.dnschange", dnschange, "0"); 1.1215 + 1.1216 + char num[PROPERTY_VALUE_MAX]; 1.1217 + snprintf(num, PROPERTY_VALUE_MAX - 1, "%d", atoi(dnschange) + 1); 1.1218 + property_set("net.dnschange", num); 1.1219 + 1.1220 + // DNS needs to be set through netd since JellyBean (4.3). 1.1221 + if (SDK_VERSION >= 18) { 1.1222 + RUN_CHAIN(aOptions, sSetDnsChain, setDnsFail) 1.1223 + } 1.1224 + 1.1225 + return true; 1.1226 +} 1.1227 + 1.1228 +/** 1.1229 + * Set default route and DNS servers for given network interface. 1.1230 + */ 1.1231 +bool NetworkUtils::setDefaultRouteAndDNS(NetworkParams& aOptions) 1.1232 +{ 1.1233 + NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); 1.1234 + 1.1235 + if (!aOptions.mOldIfname.IsEmpty()) { 1.1236 + // Remove IPv4's default route. 1.1237 + mNetUtils->do_ifc_remove_default_route(GET_CHAR(mOldIfname)); 1.1238 + // Remove IPv6's default route. 1.1239 + mNetUtils->do_ifc_remove_route(GET_CHAR(mOldIfname), "::", 0, NULL); 1.1240 + } 1.1241 + 1.1242 + uint32_t length = aOptions.mGateways.Length(); 1.1243 + if (length > 0) { 1.1244 + for (uint32_t i = 0; i < length; i++) { 1.1245 + NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateways[i]); 1.1246 + 1.1247 + int type = getIpType(autoGateway.get()); 1.1248 + if (type != AF_INET && type != AF_INET6) { 1.1249 + continue; 1.1250 + } 1.1251 + 1.1252 + if (type == AF_INET6) { 1.1253 + mNetUtils->do_ifc_add_route(autoIfname.get(), "::", 0, autoGateway.get()); 1.1254 + } else { /* type == AF_INET */ 1.1255 + mNetUtils->do_ifc_set_default_route(autoIfname.get(), inet_addr(autoGateway.get())); 1.1256 + } 1.1257 + } 1.1258 + } else { 1.1259 + // Set default froute from system properties. 1.1260 + char key[PROPERTY_KEY_MAX]; 1.1261 + char gateway[PROPERTY_KEY_MAX]; 1.1262 + 1.1263 + snprintf(key, sizeof key - 1, "net.%s.gw", autoIfname.get()); 1.1264 + property_get(key, gateway, ""); 1.1265 + 1.1266 + int type = getIpType(gateway); 1.1267 + if (type != AF_INET && type != AF_INET6) { 1.1268 + return false; 1.1269 + } 1.1270 + 1.1271 + if (type == AF_INET6) { 1.1272 + mNetUtils->do_ifc_add_route(autoIfname.get(), "::", 0, gateway); 1.1273 + } else { /* type == AF_INET */ 1.1274 + mNetUtils->do_ifc_set_default_route(autoIfname.get(), inet_addr(gateway)); 1.1275 + } 1.1276 + } 1.1277 + 1.1278 + setDNS(aOptions); 1.1279 + return true; 1.1280 +} 1.1281 + 1.1282 +/** 1.1283 + * Remove default route for given network interface. 1.1284 + */ 1.1285 +bool NetworkUtils::removeDefaultRoute(NetworkParams& aOptions) 1.1286 +{ 1.1287 + uint32_t length = aOptions.mGateways.Length(); 1.1288 + for (uint32_t i = 0; i < length; i++) { 1.1289 + NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateways[i]); 1.1290 + 1.1291 + int type = getIpType(autoGateway.get()); 1.1292 + if (type != AF_INET && type != AF_INET6) { 1.1293 + return false; 1.1294 + } 1.1295 + 1.1296 + mNetUtils->do_ifc_remove_route(GET_CHAR(mIfname), 1.1297 + type == AF_INET ? "0.0.0.0" : "::", 1.1298 + 0, autoGateway.get()); 1.1299 + } 1.1300 + 1.1301 + return true; 1.1302 +} 1.1303 + 1.1304 +/** 1.1305 + * Add host route for given network interface. 1.1306 + */ 1.1307 +bool NetworkUtils::addHostRoute(NetworkParams& aOptions) 1.1308 +{ 1.1309 + NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); 1.1310 + int type, prefix; 1.1311 + 1.1312 + uint32_t length = aOptions.mHostnames.Length(); 1.1313 + for (uint32_t i = 0; i < length; i++) { 1.1314 + NS_ConvertUTF16toUTF8 autoHostname(aOptions.mHostnames[i]); 1.1315 + 1.1316 + type = getIpType(autoHostname.get()); 1.1317 + if (type != AF_INET && type != AF_INET6) { 1.1318 + continue; 1.1319 + } 1.1320 + 1.1321 + uint32_t index = selectGateway(aOptions.mGateways, type); 1.1322 + if (index >= aOptions.mGateways.Length()) { 1.1323 + continue; 1.1324 + } 1.1325 + 1.1326 + NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateways[index]); 1.1327 + prefix = type == AF_INET ? 32 : 128; 1.1328 + mNetUtils->do_ifc_add_route(autoIfname.get(), autoHostname.get(), prefix, 1.1329 + autoGateway.get()); 1.1330 + } 1.1331 + return true; 1.1332 +} 1.1333 + 1.1334 +/** 1.1335 + * Remove host route for given network interface. 1.1336 + */ 1.1337 +bool NetworkUtils::removeHostRoute(NetworkParams& aOptions) 1.1338 +{ 1.1339 + NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); 1.1340 + int type, prefix; 1.1341 + 1.1342 + uint32_t length = aOptions.mHostnames.Length(); 1.1343 + for (uint32_t i = 0; i < length; i++) { 1.1344 + NS_ConvertUTF16toUTF8 autoHostname(aOptions.mHostnames[i]); 1.1345 + 1.1346 + type = getIpType(autoHostname.get()); 1.1347 + if (type != AF_INET && type != AF_INET6) { 1.1348 + continue; 1.1349 + } 1.1350 + 1.1351 + uint32_t index = selectGateway(aOptions.mGateways, type); 1.1352 + if (index >= aOptions.mGateways.Length()) { 1.1353 + continue; 1.1354 + } 1.1355 + 1.1356 + NS_ConvertUTF16toUTF8 autoGateway(aOptions.mGateways[index]); 1.1357 + prefix = type == AF_INET ? 32 : 128; 1.1358 + mNetUtils->do_ifc_remove_route(autoIfname.get(), autoHostname.get(), prefix, 1.1359 + autoGateway.get()); 1.1360 + } 1.1361 + return true; 1.1362 +} 1.1363 + 1.1364 +/** 1.1365 + * Remove the routes associated with the named interface. 1.1366 + */ 1.1367 +bool NetworkUtils::removeHostRoutes(NetworkParams& aOptions) 1.1368 +{ 1.1369 + mNetUtils->do_ifc_remove_host_routes(GET_CHAR(mIfname)); 1.1370 + return true; 1.1371 +} 1.1372 + 1.1373 +bool NetworkUtils::removeNetworkRoute(NetworkParams& aOptions) 1.1374 +{ 1.1375 + NS_ConvertUTF16toUTF8 autoIfname(aOptions.mIfname); 1.1376 + NS_ConvertUTF16toUTF8 autoIp(aOptions.mIp); 1.1377 + 1.1378 + int type = getIpType(autoIp.get()); 1.1379 + if (type != AF_INET && type != AF_INET6) { 1.1380 + return false; 1.1381 + } 1.1382 + 1.1383 + uint32_t prefixLength = GET_FIELD(mPrefixLength); 1.1384 + 1.1385 + if (type == AF_INET6) { 1.1386 + // Calculate subnet. 1.1387 + struct in6_addr in6; 1.1388 + if (inet_pton(AF_INET6, autoIp.get(), &in6) != 1) { 1.1389 + return false; 1.1390 + } 1.1391 + 1.1392 + uint32_t p, i, p1, mask; 1.1393 + p = prefixLength; 1.1394 + i = 0; 1.1395 + while (i < 4) { 1.1396 + p1 = p > 32 ? 32 : p; 1.1397 + p -= p1; 1.1398 + mask = p1 ? ~0x0 << (32 - p1) : 0; 1.1399 + in6.s6_addr32[i++] &= htonl(mask); 1.1400 + } 1.1401 + 1.1402 + char subnetStr[INET6_ADDRSTRLEN]; 1.1403 + if (!inet_ntop(AF_INET6, &in6, subnetStr, sizeof subnetStr)) { 1.1404 + return false; 1.1405 + } 1.1406 + 1.1407 + // Remove default route. 1.1408 + mNetUtils->do_ifc_remove_route(autoIfname.get(), "::", 0, NULL); 1.1409 + 1.1410 + // Remove subnet route. 1.1411 + mNetUtils->do_ifc_remove_route(autoIfname.get(), subnetStr, prefixLength, NULL); 1.1412 + return true; 1.1413 + } 1.1414 + 1.1415 + /* type == AF_INET */ 1.1416 + uint32_t ip = inet_addr(autoIp.get()); 1.1417 + uint32_t netmask = makeMask(prefixLength); 1.1418 + uint32_t subnet = ip & netmask; 1.1419 + const char* gateway = "0.0.0.0"; 1.1420 + struct in_addr addr; 1.1421 + addr.s_addr = subnet; 1.1422 + const char* dst = inet_ntoa(addr); 1.1423 + 1.1424 + mNetUtils->do_ifc_remove_default_route(autoIfname.get()); 1.1425 + mNetUtils->do_ifc_remove_route(autoIfname.get(), dst, prefixLength, gateway); 1.1426 + return true; 1.1427 +} 1.1428 + 1.1429 +bool NetworkUtils::addSecondaryRoute(NetworkParams& aOptions) 1.1430 +{ 1.1431 + char command[MAX_COMMAND_SIZE]; 1.1432 + snprintf(command, MAX_COMMAND_SIZE - 1, 1.1433 + "interface route add %s secondary %s %s %s", 1.1434 + GET_CHAR(mIfname), 1.1435 + GET_CHAR(mIp), 1.1436 + GET_CHAR(mPrefix), 1.1437 + GET_CHAR(mGateway)); 1.1438 + 1.1439 + doCommand(command, nullptr, nullptr); 1.1440 + return true; 1.1441 +} 1.1442 + 1.1443 +bool NetworkUtils::removeSecondaryRoute(NetworkParams& aOptions) 1.1444 +{ 1.1445 + char command[MAX_COMMAND_SIZE]; 1.1446 + snprintf(command, MAX_COMMAND_SIZE - 1, 1.1447 + "interface route remove %s secondary %s %s %s", 1.1448 + GET_CHAR(mIfname), 1.1449 + GET_CHAR(mIp), 1.1450 + GET_CHAR(mPrefix), 1.1451 + GET_CHAR(mGateway)); 1.1452 + 1.1453 + doCommand(command, nullptr, nullptr); 1.1454 + return true; 1.1455 +} 1.1456 + 1.1457 +bool NetworkUtils::getNetworkInterfaceStats(NetworkParams& aOptions) 1.1458 +{ 1.1459 + DEBUG("getNetworkInterfaceStats: %s", GET_CHAR(mIfname)); 1.1460 + aOptions.mRxBytes = -1; 1.1461 + aOptions.mTxBytes = -1; 1.1462 + 1.1463 + RUN_CHAIN(aOptions, sNetworkInterfaceStatsChain, networkInterfaceStatsFail); 1.1464 + return true; 1.1465 +} 1.1466 + 1.1467 +bool NetworkUtils::setNetworkInterfaceAlarm(NetworkParams& aOptions) 1.1468 +{ 1.1469 + DEBUG("setNetworkInterfaceAlarms: %s", GET_CHAR(mIfname)); 1.1470 + RUN_CHAIN(aOptions, sNetworkInterfaceSetAlarmChain, networkInterfaceAlarmFail); 1.1471 + return true; 1.1472 +} 1.1473 + 1.1474 +bool NetworkUtils::enableNetworkInterfaceAlarm(NetworkParams& aOptions) 1.1475 +{ 1.1476 + DEBUG("enableNetworkInterfaceAlarm: %s", GET_CHAR(mIfname)); 1.1477 + RUN_CHAIN(aOptions, sNetworkInterfaceEnableAlarmChain, networkInterfaceAlarmFail); 1.1478 + return true; 1.1479 +} 1.1480 + 1.1481 +bool NetworkUtils::disableNetworkInterfaceAlarm(NetworkParams& aOptions) 1.1482 +{ 1.1483 + DEBUG("disableNetworkInterfaceAlarms: %s", GET_CHAR(mIfname)); 1.1484 + RUN_CHAIN(aOptions, sNetworkInterfaceDisableAlarmChain, networkInterfaceAlarmFail); 1.1485 + return true; 1.1486 +} 1.1487 + 1.1488 +/** 1.1489 + * handling main thread's reload Wifi firmware request 1.1490 + */ 1.1491 +bool NetworkUtils::setWifiOperationMode(NetworkParams& aOptions) 1.1492 +{ 1.1493 + DEBUG("setWifiOperationMode: %s %s", GET_CHAR(mIfname), GET_CHAR(mMode)); 1.1494 + RUN_CHAIN(aOptions, sWifiOperationModeChain, wifiOperationModeFail); 1.1495 + return true; 1.1496 +} 1.1497 + 1.1498 +/** 1.1499 + * handling main thread's enable/disable WiFi Tethering request 1.1500 + */ 1.1501 +bool NetworkUtils::setWifiTethering(NetworkParams& aOptions) 1.1502 +{ 1.1503 + bool enable = aOptions.mEnable; 1.1504 + IFProperties interfaceProperties; 1.1505 + getIFProperties(GET_CHAR(mExternalIfname), interfaceProperties); 1.1506 + 1.1507 + if (strcmp(interfaceProperties.dns1, "")) { 1.1508 + aOptions.mDns1 = NS_ConvertUTF8toUTF16(interfaceProperties.dns1); 1.1509 + } 1.1510 + if (strcmp(interfaceProperties.dns2, "")) { 1.1511 + aOptions.mDns2 = NS_ConvertUTF8toUTF16(interfaceProperties.dns2); 1.1512 + } 1.1513 + dumpParams(aOptions, "WIFI"); 1.1514 + 1.1515 + if (enable) { 1.1516 + DEBUG("Starting Wifi Tethering on %s <-> %s", 1.1517 + GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); 1.1518 + RUN_CHAIN(aOptions, sWifiEnableChain, wifiTetheringFail) 1.1519 + } else { 1.1520 + DEBUG("Stopping Wifi Tethering on %s <-> %s", 1.1521 + GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); 1.1522 + RUN_CHAIN(aOptions, sWifiDisableChain, wifiTetheringFail) 1.1523 + } 1.1524 + return true; 1.1525 +} 1.1526 + 1.1527 +bool NetworkUtils::setUSBTethering(NetworkParams& aOptions) 1.1528 +{ 1.1529 + bool enable = aOptions.mEnable; 1.1530 + IFProperties interfaceProperties; 1.1531 + getIFProperties(GET_CHAR(mExternalIfname), interfaceProperties); 1.1532 + 1.1533 + if (strcmp(interfaceProperties.dns1, "")) { 1.1534 + aOptions.mDns1 = NS_ConvertUTF8toUTF16(interfaceProperties.dns1); 1.1535 + } 1.1536 + if (strcmp(interfaceProperties.dns2, "")) { 1.1537 + aOptions.mDns2 = NS_ConvertUTF8toUTF16(interfaceProperties.dns2); 1.1538 + } 1.1539 + dumpParams(aOptions, "USB"); 1.1540 + 1.1541 + if (enable) { 1.1542 + DEBUG("Starting USB Tethering on %s <-> %s", 1.1543 + GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); 1.1544 + RUN_CHAIN(aOptions, sUSBEnableChain, usbTetheringFail) 1.1545 + } else { 1.1546 + DEBUG("Stopping USB Tethering on %s <-> %s", 1.1547 + GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname)); 1.1548 + RUN_CHAIN(aOptions, sUSBDisableChain, usbTetheringFail) 1.1549 + } 1.1550 + return true; 1.1551 +} 1.1552 + 1.1553 +void NetworkUtils::escapeQuote(nsCString& aString) 1.1554 +{ 1.1555 + aString.ReplaceSubstring("\\", "\\\\"); 1.1556 + aString.ReplaceSubstring("\"", "\\\""); 1.1557 +} 1.1558 + 1.1559 +void NetworkUtils::checkUsbRndisState(NetworkParams& aOptions) 1.1560 +{ 1.1561 + static uint32_t retry = 0; 1.1562 + 1.1563 + char currentState[PROPERTY_VALUE_MAX]; 1.1564 + property_get(SYS_USB_STATE_PROPERTY, currentState, nullptr); 1.1565 + 1.1566 + nsTArray<nsCString> stateFuncs; 1.1567 + split(currentState, USB_CONFIG_DELIMIT, stateFuncs); 1.1568 + bool rndisPresent = stateFuncs.Contains(nsCString(USB_FUNCTION_RNDIS)); 1.1569 + 1.1570 + if (aOptions.mEnable == rndisPresent) { 1.1571 + NetworkResultOptions result; 1.1572 + result.mEnable = aOptions.mEnable; 1.1573 + result.mResult = true; 1.1574 + postMessage(aOptions, result); 1.1575 + retry = 0; 1.1576 + return; 1.1577 + } 1.1578 + if (retry < USB_FUNCTION_RETRY_TIMES) { 1.1579 + retry++; 1.1580 + usleep(USB_FUNCTION_RETRY_INTERVAL * 1000); 1.1581 + checkUsbRndisState(aOptions); 1.1582 + return; 1.1583 + } 1.1584 + 1.1585 + NetworkResultOptions result; 1.1586 + result.mResult = false; 1.1587 + postMessage(aOptions, result); 1.1588 + retry = 0; 1.1589 +} 1.1590 + 1.1591 +/** 1.1592 + * Modify usb function's property to turn on USB RNDIS function 1.1593 + */ 1.1594 +bool NetworkUtils::enableUsbRndis(NetworkParams& aOptions) 1.1595 +{ 1.1596 + bool report = aOptions.mReport; 1.1597 + 1.1598 + // For some reason, rndis doesn't play well with diag,modem,nmea. 1.1599 + // So when turning rndis on, we set sys.usb.config to either "rndis" 1.1600 + // or "rndis,adb". When turning rndis off, we go back to 1.1601 + // persist.sys.usb.config. 1.1602 + // 1.1603 + // On the otoro/unagi, persist.sys.usb.config should be one of: 1.1604 + // 1.1605 + // diag,modem,nmea,mass_storage 1.1606 + // diag,modem,nmea,mass_storage,adb 1.1607 + // 1.1608 + // When rndis is enabled, sys.usb.config should be one of: 1.1609 + // 1.1610 + // rdnis 1.1611 + // rndis,adb 1.1612 + // 1.1613 + // and when rndis is disabled, it should revert to persist.sys.usb.config 1.1614 + 1.1615 + char currentConfig[PROPERTY_VALUE_MAX]; 1.1616 + property_get(SYS_USB_CONFIG_PROPERTY, currentConfig, nullptr); 1.1617 + 1.1618 + nsTArray<nsCString> configFuncs; 1.1619 + split(currentConfig, USB_CONFIG_DELIMIT, configFuncs); 1.1620 + 1.1621 + char persistConfig[PROPERTY_VALUE_MAX]; 1.1622 + property_get(PERSIST_SYS_USB_CONFIG_PROPERTY, persistConfig, nullptr); 1.1623 + 1.1624 + nsTArray<nsCString> persistFuncs; 1.1625 + split(persistConfig, USB_CONFIG_DELIMIT, persistFuncs); 1.1626 + 1.1627 + if (aOptions.mEnable) { 1.1628 + configFuncs.Clear(); 1.1629 + configFuncs.AppendElement(nsCString(USB_FUNCTION_RNDIS)); 1.1630 + if (persistFuncs.Contains(nsCString(USB_FUNCTION_ADB))) { 1.1631 + configFuncs.AppendElement(nsCString(USB_FUNCTION_ADB)); 1.1632 + } 1.1633 + } else { 1.1634 + // We're turning rndis off, revert back to the persist setting. 1.1635 + // adb will already be correct there, so we don't need to do any 1.1636 + // further adjustments. 1.1637 + configFuncs = persistFuncs; 1.1638 + } 1.1639 + 1.1640 + char newConfig[PROPERTY_VALUE_MAX] = ""; 1.1641 + property_get(SYS_USB_CONFIG_PROPERTY, currentConfig, nullptr); 1.1642 + join(configFuncs, USB_CONFIG_DELIMIT, PROPERTY_VALUE_MAX, newConfig); 1.1643 + if (strcmp(currentConfig, newConfig)) { 1.1644 + property_set(SYS_USB_CONFIG_PROPERTY, newConfig); 1.1645 + } 1.1646 + 1.1647 + // Trigger the timer to check usb state and report the result to NetworkManager. 1.1648 + if (report) { 1.1649 + usleep(USB_FUNCTION_RETRY_INTERVAL * 1000); 1.1650 + checkUsbRndisState(aOptions); 1.1651 + } 1.1652 + return true; 1.1653 +} 1.1654 + 1.1655 +/** 1.1656 + * handling upstream interface change event. 1.1657 + */ 1.1658 +bool NetworkUtils::updateUpStream(NetworkParams& aOptions) 1.1659 +{ 1.1660 + RUN_CHAIN(aOptions, sUpdateUpStreamChain, updateUpStreamFail) 1.1661 + return true; 1.1662 +} 1.1663 + 1.1664 +void NetworkUtils::sendBroadcastMessage(uint32_t code, char* reason) 1.1665 +{ 1.1666 + NetworkResultOptions result; 1.1667 + switch(code) { 1.1668 + case NETD_COMMAND_INTERFACE_CHANGE: 1.1669 + result.mTopic = NS_ConvertUTF8toUTF16("netd-interface-change"); 1.1670 + break; 1.1671 + case NETD_COMMAND_BANDWIDTH_CONTROLLER: 1.1672 + result.mTopic = NS_ConvertUTF8toUTF16("netd-bandwidth-control"); 1.1673 + break; 1.1674 + default: 1.1675 + return; 1.1676 + } 1.1677 + 1.1678 + result.mBroadcast = true; 1.1679 + result.mReason = NS_ConvertUTF8toUTF16(reason); 1.1680 + postMessage(result); 1.1681 +} 1.1682 + 1.1683 +inline uint32_t NetworkUtils::netdResponseType(uint32_t code) 1.1684 +{ 1.1685 + return (code / 100) * 100; 1.1686 +} 1.1687 + 1.1688 +inline bool NetworkUtils::isBroadcastMessage(uint32_t code) 1.1689 +{ 1.1690 + uint32_t type = netdResponseType(code); 1.1691 + return type == NETD_COMMAND_UNSOLICITED; 1.1692 +} 1.1693 + 1.1694 +inline bool NetworkUtils::isError(uint32_t code) 1.1695 +{ 1.1696 + uint32_t type = netdResponseType(code); 1.1697 + return type != NETD_COMMAND_PROCEEDING && type != NETD_COMMAND_OKAY; 1.1698 +} 1.1699 + 1.1700 +inline bool NetworkUtils::isComplete(uint32_t code) 1.1701 +{ 1.1702 + uint32_t type = netdResponseType(code); 1.1703 + return type != NETD_COMMAND_PROCEEDING; 1.1704 +} 1.1705 + 1.1706 +inline bool NetworkUtils::isProceeding(uint32_t code) 1.1707 +{ 1.1708 + uint32_t type = netdResponseType(code); 1.1709 + return type == NETD_COMMAND_PROCEEDING; 1.1710 +} 1.1711 + 1.1712 +void NetworkUtils::dumpParams(NetworkParams& aOptions, const char* aType) 1.1713 +{ 1.1714 +#ifdef _DEBUG 1.1715 + DEBUG("Dump params:"); 1.1716 + DEBUG(" ifname: %s", GET_CHAR(mIfname)); 1.1717 + DEBUG(" ip: %s", GET_CHAR(mIp)); 1.1718 + DEBUG(" link: %s", GET_CHAR(mLink)); 1.1719 + DEBUG(" prefix: %s", GET_CHAR(mPrefix)); 1.1720 + DEBUG(" wifiStartIp: %s", GET_CHAR(mWifiStartIp)); 1.1721 + DEBUG(" wifiEndIp: %s", GET_CHAR(mWifiEndIp)); 1.1722 + DEBUG(" usbStartIp: %s", GET_CHAR(mUsbStartIp)); 1.1723 + DEBUG(" usbEndIp: %s", GET_CHAR(mUsbEndIp)); 1.1724 + DEBUG(" dnsserver1: %s", GET_CHAR(mDns1)); 1.1725 + DEBUG(" dnsserver2: %s", GET_CHAR(mDns2)); 1.1726 + DEBUG(" internalIfname: %s", GET_CHAR(mInternalIfname)); 1.1727 + DEBUG(" externalIfname: %s", GET_CHAR(mExternalIfname)); 1.1728 + if (!strcmp(aType, "WIFI")) { 1.1729 + DEBUG(" wifictrlinterfacename: %s", GET_CHAR(mWifictrlinterfacename)); 1.1730 + DEBUG(" ssid: %s", GET_CHAR(mSsid)); 1.1731 + DEBUG(" security: %s", GET_CHAR(mSecurity)); 1.1732 + DEBUG(" key: %s", GET_CHAR(mKey)); 1.1733 + } 1.1734 +#endif 1.1735 +} 1.1736 + 1.1737 +#undef GET_CHAR 1.1738 +#undef GET_FIELD