blob: f9f1d3f2fb33048e188031d5c1d65381010e0958 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.providers.settings;
import android.net.IpConfiguration;
import android.net.LinkAddress;
import android.net.ProxyInfo;
import android.net.StaticIpConfiguration;
import android.net.wifi.WifiConfiguration;
import android.util.Log;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.BitSet;
/**
* Backup/Restore Serializer Class for com.android.net.wifi.WifiConfiguration
*/
public class WiFiConfigurationSerializer {
private static final boolean DEBUG = false;
private static final String TAG = "WiFiConfigSerializer";
private static final int NULL = 0;
private static final int NOT_NULL = 1;
/**
* Current Version of the Serializer.
*/
private static int STATE_VERSION = 1;
/**
* Marshals a WifiConfig object into a byte-array.
*
* @param wifiConfig - WifiConfiguration to be Marshalled
* @return byte array
*/
public static byte[] marshalWifiConfig(WifiConfiguration wifiConfig) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if(wifiConfig != null) {
DataOutputStream out = new DataOutputStream(baos);
try {
out.writeInt(STATE_VERSION);
out.writeInt(wifiConfig.networkId);
out.writeInt(wifiConfig.status);
out.writeInt(wifiConfig.disableReason);
writeString(out, wifiConfig.SSID);
writeString(out, wifiConfig.BSSID);
out.writeInt(wifiConfig.apBand);
out.writeInt(wifiConfig.apChannel);
writeString(out, wifiConfig.autoJoinBSSID);
writeString(out, wifiConfig.FQDN);
writeString(out, wifiConfig.providerFriendlyName);
out.writeInt(wifiConfig.roamingConsortiumIds.length);
for (long id : wifiConfig.roamingConsortiumIds) {
out.writeLong(id);
}
writeString(out, wifiConfig.preSharedKey);
for (String wepKey : wifiConfig.wepKeys) {
writeString(out, wepKey);
}
out.writeInt(wifiConfig.wepTxKeyIndex);
out.writeInt(wifiConfig.priority);
out.writeInt(wifiConfig.hiddenSSID ? 1 : 0);
out.writeInt(wifiConfig.requirePMF ? 1 : 0);
writeString(out, wifiConfig.updateIdentifier);
writeBitSet(out, wifiConfig.allowedKeyManagement);
writeBitSet(out, wifiConfig.allowedProtocols);
writeBitSet(out, wifiConfig.allowedAuthAlgorithms);
writeBitSet(out, wifiConfig.allowedPairwiseCiphers);
writeBitSet(out, wifiConfig.allowedGroupCiphers);
//IpConfiguration
writeIpConfiguration(out, wifiConfig.getIpConfiguration());
writeString(out, wifiConfig.dhcpServer);
writeString(out, wifiConfig.defaultGwMacAddress);
out.writeInt(wifiConfig.autoJoinStatus);
out.writeInt(wifiConfig.selfAdded ? 1 : 0);
out.writeInt(wifiConfig.didSelfAdd ? 1 : 0);
out.writeInt(wifiConfig.validatedInternetAccess ? 1 : 0);
out.writeInt(wifiConfig.ephemeral ? 1 : 0);
out.writeInt(wifiConfig.creatorUid);
out.writeInt(wifiConfig.lastConnectUid);
out.writeInt(wifiConfig.lastUpdateUid);
writeString(out, wifiConfig.creatorName);
writeString(out, wifiConfig.lastUpdateName);
out.writeLong(wifiConfig.blackListTimestamp);
out.writeLong(wifiConfig.lastConnectionFailure);
out.writeLong(wifiConfig.lastRoamingFailure);
out.writeInt(wifiConfig.lastRoamingFailureReason);
out.writeLong(wifiConfig.roamingFailureBlackListTimeMilli);
out.writeLong(wifiConfig.numConnectionFailures);
out.writeLong(wifiConfig.numIpConfigFailures);
out.writeInt(wifiConfig.numAuthFailures);
out.writeInt(wifiConfig.numScorerOverride);
out.writeInt(wifiConfig.numScorerOverrideAndSwitchedNetwork);
out.writeInt(wifiConfig.numAssociation);
out.writeInt(wifiConfig.numUserTriggeredWifiDisableLowRSSI);
out.writeInt(wifiConfig.numUserTriggeredWifiDisableBadRSSI);
out.writeInt(wifiConfig.numUserTriggeredWifiDisableNotHighRSSI);
out.writeInt(wifiConfig.numTicksAtLowRSSI);
out.writeInt(wifiConfig.numTicksAtBadRSSI);
out.writeInt(wifiConfig.numTicksAtNotHighRSSI);
out.writeInt(wifiConfig.numUserTriggeredJoinAttempts);
out.writeInt(wifiConfig.autoJoinUseAggressiveJoinAttemptThreshold);
out.writeInt(wifiConfig.autoJoinBailedDueToLowRssi ? 1 : 0);
out.writeInt(wifiConfig.userApproved);
out.writeInt(wifiConfig.numNoInternetAccessReports);
out.writeInt(wifiConfig.noInternetAccessExpected ? 1 : 0);
} catch (IOException ioe) {
Log.e(TAG, "Failed to Convert WifiConfiguration to byte array", ioe);
baos.reset();
}
}
return baos.toByteArray();
}
/**
* Unmarshals a byte array into a WifiConfig Object
*
* @param data - marshalled WifiConfig Object
* @return WifiConfiguration Object
*/
public static WifiConfiguration unmarshalWifiConfig(byte[] data) {
if (data == null || data.length == 0) {
return null;
}
DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
WifiConfiguration config = new WifiConfiguration();
try {
int version = in.readInt();
config.networkId = in.readInt();
config.status = in.readInt();
config.disableReason = in.readInt();
config.SSID = readString(in, version);
config.BSSID = readString(in, version);
config.apBand = in.readInt();
config.apChannel = in.readInt();
config.autoJoinBSSID = readString(in, version);
config.FQDN = readString(in, version);
config.providerFriendlyName = readString(in, version);
int numRoamingConsortiumIds = in.readInt();
config.roamingConsortiumIds = new long[numRoamingConsortiumIds];
for (int i = 0; i < numRoamingConsortiumIds; i++) {
config.roamingConsortiumIds[i] = in.readLong();
}
config.preSharedKey = readString(in, version);
for (int i = 0; i < config.wepKeys.length; i++) {
config.wepKeys[i] = readString(in, version);
}
config.wepTxKeyIndex = in.readInt();
config.priority = in.readInt();
config.hiddenSSID = in.readInt() != 0;
config.requirePMF = in.readInt() != 0;
config.updateIdentifier = readString(in, version);
config.allowedKeyManagement = readBitSet(in, version);
config.allowedProtocols = readBitSet(in, version);
config.allowedAuthAlgorithms = readBitSet(in, version);
config.allowedPairwiseCiphers = readBitSet(in, version);
config.allowedGroupCiphers = readBitSet(in, version);
//Not backed-up because EnterpriseConfig involves
//Certificates which are device specific.
//config.enterpriseConfig = new WifiEnterpriseConfig();
config.setIpConfiguration(readIpConfiguration(in, version));
config.dhcpServer = readString(in, version);
config.defaultGwMacAddress = readString(in, version);
config.autoJoinStatus = in.readInt();
config.selfAdded = in.readInt() != 0;
config.didSelfAdd = in.readInt() != 0;
config.validatedInternetAccess = in.readInt() != 0;
config.ephemeral = in.readInt() != 0;
config.creatorUid = in.readInt();
config.lastConnectUid = in.readInt();
config.lastUpdateUid = in.readInt();
config.creatorName = readString(in, version);
config.lastUpdateName = readString(in, version);
config.blackListTimestamp = in.readLong();
config.lastConnectionFailure = in.readLong();
config.lastRoamingFailure = in.readLong();
config.lastRoamingFailureReason = in.readInt();
config.roamingFailureBlackListTimeMilli = in.readLong();
config.numConnectionFailures = in.readInt();
config.numIpConfigFailures = in.readInt();
config.numAuthFailures = in.readInt();
config.numScorerOverride = in.readInt();
config.numScorerOverrideAndSwitchedNetwork = in.readInt();
config.numAssociation = in.readInt();
config.numUserTriggeredWifiDisableLowRSSI = in.readInt();
config.numUserTriggeredWifiDisableBadRSSI = in.readInt();
config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt();
config.numTicksAtLowRSSI = in.readInt();
config.numTicksAtBadRSSI = in.readInt();
config.numTicksAtNotHighRSSI = in.readInt();
config.numUserTriggeredJoinAttempts = in.readInt();
config.autoJoinUseAggressiveJoinAttemptThreshold = in.readInt();
config.autoJoinBailedDueToLowRssi = in.readInt() != 0;
config.userApproved = in.readInt();
config.numNoInternetAccessReports = in.readInt();
config.noInternetAccessExpected = in.readInt() != 0;
} catch (IOException ioe) {
Log.e(TAG, "Failed to convert byte array to WifiConfiguration object", ioe);
return null;
}
return config;
}
private static ProxyInfo readProxyInfo(DataInputStream in, int version) throws IOException {
int isNull = in.readByte();
if (isNull == NULL) return null;
String host = readString(in, version);
int port = in.readInt();
String exclusionList = readString(in, version);
return new ProxyInfo(host, port, exclusionList);
}
private static void writeProxyInfo(DataOutputStream out, ProxyInfo proxyInfo) throws IOException {
if (proxyInfo != null) {
out.writeByte(NOT_NULL);
writeString(out, proxyInfo.getHost());
out.writeInt(proxyInfo.getPort());
writeString(out, proxyInfo.getExclusionListAsString());
} else {
out.writeByte(NULL);
}
}
private static InetAddress readInetAddress(DataInputStream in, int version) throws IOException {
int isNull = in.readByte();
if (isNull == NULL) return null;
InetAddress address = null;
int addressLength = in.readInt();
if (addressLength < 1) return address;
byte[] addressBytes = new byte[addressLength];
in.read(addressBytes, 0, addressLength);
try {
address = InetAddress.getByAddress(addressBytes);
} catch (UnknownHostException unknownHostException) {
return null;
}
return address;
}
private static void writeInetAddress(DataOutputStream out, InetAddress address) throws IOException {
if (address.getAddress() != null) {
out.writeByte(NOT_NULL);
out.writeInt(address.getAddress().length);
out.write(address.getAddress(), 0, address.getAddress().length);
} else {
out.writeByte(NULL);
}
}
private static LinkAddress readLinkAddress(DataInputStream in, int version) throws IOException {
int isNull = in.readByte();
if (isNull == NULL) return null;
InetAddress address = readInetAddress(in, version);
int prefixLength = in.readInt();
int flags = in.readInt();
int scope = in.readInt();
return new LinkAddress(address, prefixLength, flags, scope);
}
private static void writeLinkAddress(DataOutputStream out, LinkAddress address) throws IOException {
if (address != null) {
out.writeByte(NOT_NULL);
writeInetAddress(out, address.getAddress());
out.writeInt(address.getPrefixLength());
out.writeInt(address.getFlags());
out.writeInt(address.getScope());
} else {
out.writeByte(NULL);
}
}
private static StaticIpConfiguration readStaticIpConfiguration(DataInputStream in, int version) throws IOException {
int isNull = in.readByte();
if (isNull == NULL) return null;
StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
staticIpConfiguration.ipAddress = readLinkAddress(in, version);
staticIpConfiguration.gateway = readInetAddress(in, version);
int dnsServersLength = in.readInt();
for (int i = 0; i < dnsServersLength; i++) {
staticIpConfiguration.dnsServers.add(readInetAddress(in, version));
}
staticIpConfiguration.domains = readString(in, version);
return staticIpConfiguration;
}
private static void writeStaticIpConfiguration(DataOutputStream out, StaticIpConfiguration staticIpConfiguration) throws IOException {
if (staticIpConfiguration != null) {
out.writeByte(NOT_NULL);
writeLinkAddress(out, staticIpConfiguration.ipAddress);
writeInetAddress(out, staticIpConfiguration.gateway);
out.writeInt(staticIpConfiguration.dnsServers.size());
for (InetAddress inetAddress : staticIpConfiguration.dnsServers) {
writeInetAddress(out, inetAddress);
}
writeString(out, staticIpConfiguration.domains);
} else {
out.writeByte(NULL);
}
}
private static IpConfiguration readIpConfiguration(DataInputStream in, int version) throws IOException {
int isNull = in.readByte();
if (isNull == NULL) return null;
IpConfiguration ipConfiguration = new IpConfiguration();
String tmp = readString(in, version);
ipConfiguration.ipAssignment = tmp == null ? null : IpConfiguration.IpAssignment.valueOf(tmp);
tmp = readString(in, version);
ipConfiguration.proxySettings = tmp == null ? null : IpConfiguration.ProxySettings.valueOf(tmp);
ipConfiguration.staticIpConfiguration = readStaticIpConfiguration(in, version);
ipConfiguration.httpProxy = readProxyInfo(in, version);
return ipConfiguration;
}
private static void writeIpConfiguration(DataOutputStream out, IpConfiguration ipConfiguration) throws IOException {
if (ipConfiguration != null) {
out.writeByte(NOT_NULL);
writeString(out, ipConfiguration.ipAssignment != null ? ipConfiguration.ipAssignment.name() : null);
writeString(out, ipConfiguration.proxySettings != null ? ipConfiguration.proxySettings.name() : null);
writeStaticIpConfiguration(out, ipConfiguration.staticIpConfiguration);
writeProxyInfo(out, ipConfiguration.httpProxy);
} else {
out.writeByte(NULL);
}
}
private static String readString(DataInputStream in, int version) throws IOException {
byte isNull = in.readByte();
if (isNull == NOT_NULL) {
return in.readUTF();
}
return null;
}
private static void writeString(DataOutputStream out, String val) throws IOException {
if (val != null) {
out.writeByte(NOT_NULL);
out.writeUTF(val);
} else {
out.writeByte(NULL);
}
}
private static BitSet readBitSet(DataInputStream in, int version) throws IOException {
byte isNull = in.readByte();
if (isNull == NOT_NULL) {
int length = in.readInt();
byte[] bytes = new byte[length];
in.read(bytes, 0, length);
return BitSet.valueOf(bytes);
}
return new BitSet();
}
private static void writeBitSet(DataOutputStream out, BitSet val) throws IOException {
if (val != null) {
out.writeByte(NOT_NULL);
byte[] byteArray = val.toByteArray();
out.writeInt(byteArray.length);
out.write(byteArray);
} else {
out.writeByte(NULL);
}
}
}