blob: bb5427d018790be30e6657f59020296f2d7d9ec3 [file] [log] [blame]
/*
* Copyright (C) 2010 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 android.net.wifi;
import android.content.Context;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Environment;
import android.os.Message;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.UUID;
import com.android.internal.R;
/**
* Provides API to the WifiStateMachine for doing read/write access
* to soft access point configuration
*/
class WifiApConfigStore {
private static Context sContext;
private static final String TAG = "WifiApConfigStore";
private static final String AP_CONFIG_FILE = Environment.getDataDirectory() +
"/misc/wifi/softap.conf";
private static final int AP_CONFIG_FILE_VERSION = 1;
private static WifiConfiguration sApConfig = new WifiConfiguration();
private static final Object sApConfigLock = new Object();
private static FileReadWriteHandler sFileReadWriteHandler;
private static final int READ_AP_CONFIG = 1;
private static final int WRITE_AP_CONFIG = 2;
static void initialize(Context context) {
sContext = context;
/* File operations happen on a seperate thread */
HandlerThread configThread = new HandlerThread("WifiApConfigStore");
configThread.start();
sFileReadWriteHandler = new FileReadWriteHandler(configThread.getLooper());
Message.obtain(sFileReadWriteHandler, READ_AP_CONFIG).sendToTarget();
}
static void setApConfiguration(WifiConfiguration config) {
synchronized (sApConfigLock) {
sApConfig = config;
}
Message.obtain(sFileReadWriteHandler, WRITE_AP_CONFIG, new WifiConfiguration(config))
.sendToTarget();
}
static WifiConfiguration getApConfiguration() {
synchronized (sApConfigLock) {
return new WifiConfiguration(sApConfig);
}
}
/**
* File read/write handler
*/
private static class FileReadWriteHandler extends Handler {
public FileReadWriteHandler(android.os.Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case WRITE_AP_CONFIG:
writeApConfiguration((WifiConfiguration) msg.obj);
break;
case READ_AP_CONFIG:
readApConfiguration();
break;
default:
Log.e(TAG, "Unknown command in FileReadWriteHandler: " + msg);
break;
}
}
private static void writeApConfiguration(final WifiConfiguration config) {
DataOutputStream out = null;
try {
out = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(AP_CONFIG_FILE)));
out.writeInt(AP_CONFIG_FILE_VERSION);
out.writeUTF(config.SSID);
int authType = config.getAuthType();
out.writeInt(authType);
if(authType != KeyMgmt.NONE) {
out.writeUTF(config.preSharedKey);
}
} catch (IOException e) {
Log.e(TAG, "Error writing hotspot configuration" + e);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {}
}
}
}
private static void readApConfiguration() {
DataInputStream in = null;
try {
WifiConfiguration config = new WifiConfiguration();
in = new DataInputStream(new BufferedInputStream(new FileInputStream(
AP_CONFIG_FILE)));
int version = in.readInt();
if (version != 1) {
Log.e(TAG, "Bad version on hotspot configuration file, set defaults");
setDefaultApConfiguration();
return;
}
config.SSID = in.readUTF();
int authType = in.readInt();
config.allowedKeyManagement.set(authType);
if (authType != KeyMgmt.NONE) {
config.preSharedKey = in.readUTF();
}
synchronized (sApConfigLock) {
sApConfig = config;
}
} catch (IOException ignore) {
setDefaultApConfiguration();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {}
}
}
}
/* Generate a default WPA2 based configuration with a random password.
We are changing the Wifi Ap configuration storage from secure settings to a
flat file accessible only by the system. A WPA2 based default configuration
will keep the device secure after the update */
private static void setDefaultApConfiguration() {
WifiConfiguration config = new WifiConfiguration();
config.SSID = sContext.getString(R.string.wifi_tether_configure_ssid_default);
config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
String randomUUID = UUID.randomUUID().toString();
//first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13);
setApConfiguration(config);
}
}
}