1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/*
2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright (C) 2010 The Android Open Source Project
3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License");
5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License.
6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at
7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *      http://www.apache.org/licenses/LICENSE-2.0
9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software
11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS,
12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and
14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License.
15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepackage com.android.server.wifi;
18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
19155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Context;
20155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WifiConfiguration;
21155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WifiConfiguration.KeyMgmt;
22155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Environment;
23155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Handler;
24155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Message;
25155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Messenger;
26155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.Log;
27155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
28155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.AsyncChannel;
29155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.R;
30155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.State;
31155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.StateMachine;
32155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
33155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.BufferedInputStream;
34155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.BufferedOutputStream;
35155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.DataInputStream;
36155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.DataOutputStream;
37155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.FileInputStream;
38155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.FileOutputStream;
39155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.IOException;
4052b6d4cbf2815d18f35c64af955bf3859907b5c1xinheimport java.util.ArrayList;
41155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.UUID;
42155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
43155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
44155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Provides API to the WifiStateMachine for doing read/write access
45155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * to soft access point configuration
46155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
47155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeclass WifiApConfigStore extends StateMachine {
48155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
49155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private Context mContext;
50155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String TAG = "WifiApConfigStore";
51155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
52155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String AP_CONFIG_FILE = Environment.getDataDirectory() +
53155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        "/misc/wifi/softap.conf";
54155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
550e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe    private static final int AP_CONFIG_FILE_VERSION = 2;
56155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
57155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mDefaultState = new DefaultState();
58155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mInactiveState = new InactiveState();
59155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private State mActiveState = new ActiveState();
60155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
61155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiConfiguration mWifiApConfig = null;
62155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AsyncChannel mReplyChannel = new AsyncChannel();
6352b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe    public ArrayList <Integer> allowed2GChannel = null;
64155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
65155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    WifiApConfigStore(Context context, Handler target) {
66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        super(TAG, target.getLooper());
67155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext = context;
69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        addState(mDefaultState);
70155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mInactiveState, mDefaultState);
71155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mActiveState, mDefaultState);
72155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
73155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        setInitialState(mInactiveState);
7452b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe        String ap2GChannelListStr = (mContext.getResources().getString(
7552b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe                R.string.config_wifi_framework_sap_2G_channel_list));
7652b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe        Log.d(TAG, "2G band allowed channels are:" + ap2GChannelListStr);
7752b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe
7852b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe        if (ap2GChannelListStr != null) {
7952b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe            allowed2GChannel = new ArrayList<Integer>();
8052b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe            String channelList[] = ap2GChannelListStr.split(",");
8152b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe            for (String tmp : channelList) {
8252b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe                allowed2GChannel.add(Integer.parseInt(tmp));
8352b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe            }
8452b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe        }
85155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
86155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
87155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static WifiApConfigStore makeWifiApConfigStore(Context context, Handler target) {
88155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiApConfigStore s = new WifiApConfigStore(context, target);
89155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        s.start();
90155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return s;
91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DefaultState extends State {
94155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
95155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_SET_AP_CONFIG:
97155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED:
98155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Log.e(TAG, "Unexpected message: " + message);
99155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_REQUEST_AP_CONFIG:
101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mReplyChannel.replyToMessage(message,
102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiStateMachine.CMD_RESPONSE_AP_CONFIG, mWifiApConfig);
103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Log.e(TAG, "Failed to handle " + message);
106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class InactiveState extends State {
113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_SET_AP_CONFIG:
1160e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe                     WifiConfiguration config = (WifiConfiguration)message.obj;
11756d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    if (config.SSID != null) {
1180e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe                        mWifiApConfig = config;
11956d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                        transitionTo(mActiveState);
12056d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    } else {
12156d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                        Log.e(TAG, "Try to setup AP config without SSID: " + message);
12256d0178183460eed9afbd85e5c0d215e27d5f5bcvandwalle                    }
123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class ActiveState extends State {
132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            new Thread(new Runnable() {
134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                public void run() {
135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    writeApConfiguration(mWifiApConfig);
136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED);
137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }).start();
139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                //TODO: have feedback to the user when we do this
144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                //to indicate the write is currently in progress
145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_SET_AP_CONFIG:
146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED:
149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    void loadApConfiguration() {
159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        DataInputStream in = null;
160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiConfiguration config = new WifiConfiguration();
162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            in = new DataInputStream(new BufferedInputStream(new FileInputStream(
163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            AP_CONFIG_FILE)));
164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int version = in.readInt();
1660e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe            if ((version != 1) && (version != 2)) {
167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Log.e(TAG, "Bad version on hotspot configuration file, set defaults");
168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                setDefaultApConfiguration();
169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return;
170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            config.SSID = in.readUTF();
1720e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe
1730e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe            if (version >= 2) {
1740e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe                config.apBand = in.readInt();
1750e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe                config.apChannel = in.readInt();
1760e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe            }
1770e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe
178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int authType = in.readInt();
179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            config.allowedKeyManagement.set(authType);
180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (authType != KeyMgmt.NONE) {
181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                config.preSharedKey = in.readUTF();
182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
18352b6d4cbf2815d18f35c64af955bf3859907b5c1xinhe
184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiApConfig = config;
185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (IOException ignore) {
186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setDefaultApConfiguration();
187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } finally {
188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (in != null) {
189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    in.close();
191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch (IOException e) {}
192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    Messenger getMessenger() {
197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return new Messenger(getHandler());
198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void writeApConfiguration(final WifiConfiguration config) {
201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        DataOutputStream out = null;
202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            out = new DataOutputStream(new BufferedOutputStream(
204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        new FileOutputStream(AP_CONFIG_FILE)));
205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            out.writeInt(AP_CONFIG_FILE_VERSION);
207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            out.writeUTF(config.SSID);
2080e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe            out.writeInt(config.apBand);
2090e8f0d87d62589d9dda54d5a4941d0309e3ecf2axinhe            out.writeInt(config.apChannel);
210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int authType = config.getAuthType();
211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            out.writeInt(authType);
212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if(authType != KeyMgmt.NONE) {
213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                out.writeUTF(config.preSharedKey);
214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (IOException e) {
216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            Log.e(TAG, "Error writing hotspot configuration" + e);
217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } finally {
218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (out != null) {
219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    out.close();
221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch (IOException e) {}
222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Generate a default WPA2 based configuration with a random password.
227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande       We are changing the Wifi Ap configuration storage from secure settings to a
228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande       flat file accessible only by the system. A WPA2 based default configuration
229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande       will keep the device secure after the update */
230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setDefaultApConfiguration() {
231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiConfiguration config = new WifiConfiguration();
232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        config.SSID = mContext.getString(R.string.wifi_tether_configure_ssid_default);
233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String randomUUID = UUID.randomUUID().toString();
235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13);
237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG, config);
238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
240