michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef NetworkUtils_h michael@0: #define NetworkUtils_h michael@0: michael@0: #include "nsString.h" michael@0: #include "mozilla/dom/NetworkOptionsBinding.h" michael@0: #include "mozilla/dom/network/NetUtils.h" michael@0: #include "mozilla/ipc/Netd.h" michael@0: #include "nsTArray.h" michael@0: michael@0: class NetworkParams; michael@0: class CommandChain; michael@0: michael@0: using namespace mozilla::dom; michael@0: michael@0: typedef void (*CommandCallback)(CommandChain*, bool, NetworkResultOptions& aResult); michael@0: typedef void (*CommandFunc)(CommandChain*, CommandCallback, NetworkResultOptions& aResult); michael@0: typedef void (*MessageCallback)(NetworkResultOptions& aResult); michael@0: typedef void (*ErrorCallback)(NetworkParams& aOptions, NetworkResultOptions& aResult); michael@0: michael@0: class NetworkParams michael@0: { michael@0: public: michael@0: NetworkParams() { michael@0: } michael@0: michael@0: NetworkParams(const NetworkParams& aOther) { michael@0: mIp = aOther.mIp; michael@0: mCmd = aOther.mCmd; michael@0: mDomain = aOther.mDomain; michael@0: mGateway = aOther.mGateway; michael@0: mGateways = aOther.mGateways; michael@0: mHostnames = aOther.mHostnames; michael@0: mId = aOther.mId; michael@0: mIfname = aOther.mIfname; michael@0: mPrefixLength = aOther.mPrefixLength; michael@0: mOldIfname = aOther.mOldIfname; michael@0: mMode = aOther.mMode; michael@0: mReport = aOther.mReport; michael@0: mIsAsync = aOther.mIsAsync; michael@0: mEnabled = aOther.mEnabled; michael@0: mWifictrlinterfacename = aOther.mWifictrlinterfacename; michael@0: mInternalIfname = aOther.mInternalIfname; michael@0: mExternalIfname = aOther.mExternalIfname; michael@0: mEnable = aOther.mEnable; michael@0: mSsid = aOther.mSsid; michael@0: mSecurity = aOther.mSecurity; michael@0: mKey = aOther.mKey; michael@0: mPrefix = aOther.mPrefix; michael@0: mLink = aOther.mLink; michael@0: mInterfaceList = aOther.mInterfaceList; michael@0: mWifiStartIp = aOther.mWifiStartIp; michael@0: mWifiEndIp = aOther.mWifiEndIp; michael@0: mUsbStartIp = aOther.mUsbStartIp; michael@0: mUsbEndIp = aOther.mUsbEndIp; michael@0: mDns1 = aOther.mDns1; michael@0: mDns2 = aOther.mDns2; michael@0: mDnses = aOther.mDnses; michael@0: mRxBytes = aOther.mRxBytes; michael@0: mTxBytes = aOther.mTxBytes; michael@0: mDate = aOther.mDate; michael@0: mStartIp = aOther.mStartIp; michael@0: mEndIp = aOther.mEndIp; michael@0: mServerIp = aOther.mServerIp; michael@0: mMaskLength = aOther.mMaskLength; michael@0: mPreInternalIfname = aOther.mPreInternalIfname; michael@0: mPreExternalIfname = aOther.mPreExternalIfname; michael@0: mCurInternalIfname = aOther.mCurInternalIfname; michael@0: mCurExternalIfname = aOther.mCurExternalIfname; michael@0: mThreshold = aOther.mThreshold; michael@0: } michael@0: michael@0: NetworkParams(const NetworkCommandOptions& aOther) { michael@0: michael@0: #define COPY_SEQUENCE_FIELD(prop, type) \ michael@0: if (aOther.prop.WasPassed()) { \ michael@0: mozilla::dom::Sequence const & currentValue = aOther.prop.InternalValue(); \ michael@0: uint32_t length = currentValue.Length(); \ michael@0: for (uint32_t idx = 0; idx < length; idx++) { \ michael@0: prop.AppendElement(currentValue[idx]); \ michael@0: } \ michael@0: } michael@0: michael@0: #define COPY_OPT_STRING_FIELD(prop, defaultValue) \ michael@0: if (aOther.prop.WasPassed()) { \ michael@0: if (aOther.prop.Value().EqualsLiteral("null")) { \ michael@0: prop = defaultValue; \ michael@0: } else { \ michael@0: prop = aOther.prop.Value(); \ michael@0: } \ michael@0: } else { \ michael@0: prop = defaultValue; \ michael@0: } michael@0: michael@0: #define COPY_OPT_FIELD(prop, defaultValue) \ michael@0: if (aOther.prop.WasPassed()) { \ michael@0: prop = aOther.prop.Value(); \ michael@0: } else { \ michael@0: prop = defaultValue; \ michael@0: } michael@0: michael@0: #define COPY_FIELD(prop) prop = aOther.prop; michael@0: michael@0: COPY_FIELD(mId) michael@0: COPY_FIELD(mCmd) michael@0: COPY_OPT_STRING_FIELD(mDomain, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mGateway, EmptyString()) michael@0: COPY_SEQUENCE_FIELD(mGateways, nsString) michael@0: COPY_SEQUENCE_FIELD(mHostnames, nsString) michael@0: COPY_OPT_STRING_FIELD(mIfname, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mIp, EmptyString()) michael@0: COPY_OPT_FIELD(mPrefixLength, 0) michael@0: COPY_OPT_STRING_FIELD(mOldIfname, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mMode, EmptyString()) michael@0: COPY_OPT_FIELD(mReport, false) michael@0: COPY_OPT_FIELD(mIsAsync, true) michael@0: COPY_OPT_FIELD(mEnabled, false) michael@0: COPY_OPT_STRING_FIELD(mWifictrlinterfacename, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mInternalIfname, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mExternalIfname, EmptyString()) michael@0: COPY_OPT_FIELD(mEnable, false) michael@0: COPY_OPT_STRING_FIELD(mSsid, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mSecurity, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mKey, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mPrefix, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mLink, EmptyString()) michael@0: COPY_SEQUENCE_FIELD(mInterfaceList, nsString) michael@0: COPY_OPT_STRING_FIELD(mWifiStartIp, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mWifiEndIp, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mUsbStartIp, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mUsbEndIp, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mDns1, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mDns2, EmptyString()) michael@0: COPY_SEQUENCE_FIELD(mDnses, nsString) michael@0: COPY_OPT_FIELD(mRxBytes, -1) michael@0: COPY_OPT_FIELD(mTxBytes, -1) michael@0: COPY_OPT_STRING_FIELD(mDate, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mStartIp, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mEndIp, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mServerIp, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mMaskLength, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mPreInternalIfname, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mPreExternalIfname, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mCurInternalIfname, EmptyString()) michael@0: COPY_OPT_STRING_FIELD(mCurExternalIfname, EmptyString()) michael@0: COPY_OPT_FIELD(mThreshold, -1) michael@0: michael@0: #undef COPY_SEQUENCE_FIELD michael@0: #undef COPY_OPT_STRING_FIELD michael@0: #undef COPY_OPT_FIELD michael@0: #undef COPY_FIELD michael@0: } michael@0: michael@0: int32_t mId; michael@0: nsString mCmd; michael@0: nsString mDomain; michael@0: nsString mGateway; michael@0: nsTArray mGateways; michael@0: nsTArray mHostnames; michael@0: nsString mIfname; michael@0: nsString mIp; michael@0: uint32_t mPrefixLength; michael@0: nsString mOldIfname; michael@0: nsString mMode; michael@0: bool mReport; michael@0: bool mIsAsync; michael@0: bool mEnabled; michael@0: nsString mWifictrlinterfacename; michael@0: nsString mInternalIfname; michael@0: nsString mExternalIfname; michael@0: bool mEnable; michael@0: nsString mSsid; michael@0: nsString mSecurity; michael@0: nsString mKey; michael@0: nsString mPrefix; michael@0: nsString mLink; michael@0: nsTArray mInterfaceList; michael@0: nsString mWifiStartIp; michael@0: nsString mWifiEndIp; michael@0: nsString mUsbStartIp; michael@0: nsString mUsbEndIp; michael@0: nsString mDns1; michael@0: nsString mDns2; michael@0: nsTArray mDnses; michael@0: float mRxBytes; michael@0: float mTxBytes; michael@0: nsString mDate; michael@0: nsString mStartIp; michael@0: nsString mEndIp; michael@0: nsString mServerIp; michael@0: nsString mMaskLength; michael@0: nsString mPreInternalIfname; michael@0: nsString mPreExternalIfname; michael@0: nsString mCurInternalIfname; michael@0: nsString mCurExternalIfname; michael@0: long mThreshold; michael@0: }; michael@0: michael@0: // CommandChain store the necessary information to execute command one by one. michael@0: // Including : michael@0: // 1. Command parameters. michael@0: // 2. Command list. michael@0: // 3. Error callback function. michael@0: // 4. Index of current execution command. michael@0: class CommandChain MOZ_FINAL michael@0: { michael@0: public: michael@0: CommandChain(const NetworkParams& aParams, michael@0: CommandFunc aCmds[], michael@0: uint32_t aLength, michael@0: ErrorCallback aError) michael@0: : mIndex(-1) michael@0: , mParams(aParams) michael@0: , mCommands(aCmds) michael@0: , mLength(aLength) michael@0: , mError(aError) { michael@0: } michael@0: michael@0: NetworkParams& michael@0: getParams() michael@0: { michael@0: return mParams; michael@0: }; michael@0: michael@0: CommandFunc michael@0: getNextCommand() michael@0: { michael@0: mIndex++; michael@0: return mIndex < mLength ? mCommands[mIndex] : nullptr; michael@0: }; michael@0: michael@0: ErrorCallback michael@0: getErrorCallback() const michael@0: { michael@0: return mError; michael@0: }; michael@0: michael@0: private: michael@0: uint32_t mIndex; michael@0: NetworkParams mParams; michael@0: CommandFunc* mCommands; michael@0: uint32_t mLength; michael@0: ErrorCallback mError; michael@0: }; michael@0: michael@0: class NetworkUtils MOZ_FINAL michael@0: { michael@0: public: michael@0: NetworkUtils(MessageCallback aCallback); michael@0: ~NetworkUtils(); michael@0: michael@0: void ExecuteCommand(NetworkParams aOptions); michael@0: void onNetdMessage(mozilla::ipc::NetdCommand* aCommand); michael@0: michael@0: MessageCallback getMessageCallback() { return mMessageCallback; } michael@0: michael@0: private: michael@0: /** michael@0: * Commands supported by NetworkUtils. michael@0: */ michael@0: bool setDNS(NetworkParams& aOptions); michael@0: bool setDefaultRouteAndDNS(NetworkParams& aOptions); michael@0: bool addHostRoute(NetworkParams& aOptions); michael@0: bool removeDefaultRoute(NetworkParams& aOptions); michael@0: bool removeHostRoute(NetworkParams& aOptions); michael@0: bool removeHostRoutes(NetworkParams& aOptions); michael@0: bool removeNetworkRoute(NetworkParams& aOptions); michael@0: bool addSecondaryRoute(NetworkParams& aOptions); michael@0: bool removeSecondaryRoute(NetworkParams& aOptions); michael@0: bool getNetworkInterfaceStats(NetworkParams& aOptions); michael@0: bool setNetworkInterfaceAlarm(NetworkParams& aOptions); michael@0: bool enableNetworkInterfaceAlarm(NetworkParams& aOptions); michael@0: bool disableNetworkInterfaceAlarm(NetworkParams& aOptions); michael@0: bool setWifiOperationMode(NetworkParams& aOptions); michael@0: bool setDhcpServer(NetworkParams& aOptions); michael@0: bool setWifiTethering(NetworkParams& aOptions); michael@0: bool setUSBTethering(NetworkParams& aOptions); michael@0: bool enableUsbRndis(NetworkParams& aOptions); michael@0: bool updateUpStream(NetworkParams& aOptions); michael@0: michael@0: /** michael@0: * function pointer array holds all netd commands should be executed michael@0: * in sequence to accomplish a given command by other module. michael@0: */ michael@0: static CommandFunc sWifiEnableChain[]; michael@0: static CommandFunc sWifiDisableChain[]; michael@0: static CommandFunc sWifiFailChain[]; michael@0: static CommandFunc sWifiOperationModeChain[]; michael@0: static CommandFunc sUSBEnableChain[]; michael@0: static CommandFunc sUSBDisableChain[]; michael@0: static CommandFunc sUSBFailChain[]; michael@0: static CommandFunc sUpdateUpStreamChain[]; michael@0: static CommandFunc sStartDhcpServerChain[]; michael@0: static CommandFunc sStopDhcpServerChain[]; michael@0: static CommandFunc sNetworkInterfaceStatsChain[]; michael@0: static CommandFunc sNetworkInterfaceEnableAlarmChain[]; michael@0: static CommandFunc sNetworkInterfaceDisableAlarmChain[]; michael@0: static CommandFunc sNetworkInterfaceSetAlarmChain[]; michael@0: static CommandFunc sSetDnsChain[]; michael@0: michael@0: /** michael@0: * Individual netd command stored in command chain. michael@0: */ michael@0: #define PARAMS CommandChain* aChain, CommandCallback aCallback, NetworkResultOptions& aResult michael@0: static void wifiFirmwareReload(PARAMS); michael@0: static void startAccessPointDriver(PARAMS); michael@0: static void stopAccessPointDriver(PARAMS); michael@0: static void setAccessPoint(PARAMS); michael@0: static void cleanUpStream(PARAMS); michael@0: static void createUpStream(PARAMS); michael@0: static void startSoftAP(PARAMS); michael@0: static void stopSoftAP(PARAMS); michael@0: static void getRxBytes(PARAMS); michael@0: static void getTxBytes(PARAMS); michael@0: static void enableAlarm(PARAMS); michael@0: static void disableAlarm(PARAMS); michael@0: static void setQuota(PARAMS); michael@0: static void removeQuota(PARAMS); michael@0: static void setAlarm(PARAMS); michael@0: static void setInterfaceUp(PARAMS); michael@0: static void tetherInterface(PARAMS); michael@0: static void preTetherInterfaceList(PARAMS); michael@0: static void postTetherInterfaceList(PARAMS); michael@0: static void setIpForwardingEnabled(PARAMS); michael@0: static void tetheringStatus(PARAMS); michael@0: static void stopTethering(PARAMS); michael@0: static void startTethering(PARAMS); michael@0: static void untetherInterface(PARAMS); michael@0: static void setDnsForwarders(PARAMS); michael@0: static void enableNat(PARAMS); michael@0: static void disableNat(PARAMS); michael@0: static void setDefaultInterface(PARAMS); michael@0: static void setInterfaceDns(PARAMS); michael@0: static void wifiTetheringSuccess(PARAMS); michael@0: static void usbTetheringSuccess(PARAMS); michael@0: static void networkInterfaceStatsSuccess(PARAMS); michael@0: static void networkInterfaceAlarmSuccess(PARAMS); michael@0: static void updateUpStreamSuccess(PARAMS); michael@0: static void setDhcpServerSuccess(PARAMS); michael@0: static void wifiOperationModeSuccess(PARAMS); michael@0: #undef PARAMS michael@0: michael@0: /** michael@0: * Error callback function executed when a command is fail. michael@0: */ michael@0: #define PARAMS NetworkParams& aOptions, NetworkResultOptions& aResult michael@0: static void wifiTetheringFail(PARAMS); michael@0: static void wifiOperationModeFail(PARAMS); michael@0: static void usbTetheringFail(PARAMS); michael@0: static void updateUpStreamFail(PARAMS); michael@0: static void setDhcpServerFail(PARAMS); michael@0: static void networkInterfaceStatsFail(PARAMS); michael@0: static void networkInterfaceAlarmFail(PARAMS); michael@0: static void setDnsFail(PARAMS); michael@0: #undef PARAMS michael@0: michael@0: /** michael@0: * Command chain processing functions. michael@0: */ michael@0: static void next(CommandChain* aChain, bool aError, NetworkResultOptions& aResult); michael@0: static void nextNetdCommand(); michael@0: static void doCommand(const char* aCommand, CommandChain* aChain, CommandCallback aCallback); michael@0: michael@0: /** michael@0: * Notify broadcast message to main thread. michael@0: */ michael@0: void sendBroadcastMessage(uint32_t code, char* reason); michael@0: michael@0: /** michael@0: * Utility functions. michael@0: */ michael@0: void checkUsbRndisState(NetworkParams& aOptions); michael@0: void dumpParams(NetworkParams& aOptions, const char* aType); michael@0: michael@0: static void escapeQuote(nsCString& aString); michael@0: inline uint32_t netdResponseType(uint32_t code); michael@0: inline bool isBroadcastMessage(uint32_t code); michael@0: inline bool isError(uint32_t code); michael@0: inline bool isComplete(uint32_t code); michael@0: inline bool isProceeding(uint32_t code); michael@0: void Shutdown(); michael@0: /** michael@0: * Callback function to send netd result to main thread. michael@0: */ michael@0: MessageCallback mMessageCallback; michael@0: michael@0: /* michael@0: * Utility class to access libnetutils. michael@0: */ michael@0: nsAutoPtr mNetUtils; michael@0: }; michael@0: michael@0: #endif