Update the folder structure for Enrollee implmentation.
[platform/upstream/iotivity.git] / service / easy-setup / sdk / mediator / android / EasySetupCore / src / org / iotivity / service / easysetup / mediator / WiFiSoftAPManager.java
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20 package org.iotivity.service.easysetup.mediator;
21
22 import java.io.BufferedReader;
23 import java.io.FileReader;
24 import java.io.IOException;
25 import java.lang.reflect.Method;
26 import java.net.InetAddress;
27 import java.util.ArrayList;
28
29 import android.content.Context;
30 import android.net.wifi.WifiConfiguration;
31 import android.net.wifi.WifiManager;
32 import android.os.Handler;
33 import android.util.Log;
34
35 public class WiFiSoftAPManager {
36     private final WifiManager                mWifiManager;
37     private Context                          context;
38     static ArrayList<EnrolleeOnBoardingInfo> appNotification = new ArrayList<EnrolleeOnBoardingInfo>();
39     IOnBoardingStatus                        finishListener  = null;
40
41     public enum WIFI_AP_STATE {
42         WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_ENABLING, WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_FAILED
43     }
44
45     public WiFiSoftAPManager(Context context) {
46         this.context = context;
47         mWifiManager = (WifiManager) this.context
48                 .getSystemService(Context.WIFI_SERVICE);
49     }
50
51     /**
52      * Start AccessPoint mode with the specified configuration. If the radio is
53      * already running in AP mode, update the new configuration Note that
54      * starting in access point mode disables station mode operation
55      *
56      * @param wifiConfig
57      *            SSID, security and channel details as part of
58      *            WifiConfiguration
59      * @return {@code true} if the operation succeeds, {@code false} otherwise
60      */
61     public boolean setWifiApEnabled(WifiConfiguration wifiConfig,
62             boolean enabled) {
63         try {
64             if (enabled) { // disable WiFi in any case
65                 mWifiManager.setWifiEnabled(false);
66             }
67
68             Method method = mWifiManager.getClass().getMethod(
69                     "setWifiApEnabled", WifiConfiguration.class, boolean.class);
70             return (Boolean) method.invoke(mWifiManager, wifiConfig, enabled);
71         } catch (Exception e) {
72             Log.e(this.getClass().toString(), "", e);
73             return false;
74         }
75     }
76
77     /**
78      * Gets the Wi-Fi enabled state.
79      *
80      * @return {@link WIFI_AP_STATE}
81      * @see #isWifiApEnabled()
82      */
83     public WIFI_AP_STATE getWifiApState() {
84         try {
85             Method method = mWifiManager.getClass().getMethod("getWifiApState");
86
87             int tmp = ((Integer) method.invoke(mWifiManager));
88
89             // Fix for Android 4
90             if (tmp >= 10) {
91                 tmp = tmp - 10;
92             }
93
94             return WIFI_AP_STATE.class.getEnumConstants()[tmp];
95         } catch (Exception e) {
96             Log.e(this.getClass().toString(), "", e);
97             return WIFI_AP_STATE.WIFI_AP_STATE_FAILED;
98         }
99     }
100
101     /**
102      * Return whether Wi-Fi AP is enabled or disabled.
103      *
104      * @return {@code true} if Wi-Fi AP is enabled
105      * @see #getWifiApState()
106      *
107      * @hide Dont open yet
108      */
109     public boolean isWifiApEnabled() {
110         return getWifiApState() == WIFI_AP_STATE.WIFI_AP_STATE_ENABLED;
111     }
112
113     /**
114      * Gets the Wi-Fi AP Configuration.
115      *
116      * @return AP details in {@link WifiConfiguration}
117      */
118     public WifiConfiguration getWifiApConfiguration() {
119         try {
120             Method method = mWifiManager.getClass().getMethod(
121                     "getWifiApConfiguration");
122             return (WifiConfiguration) method.invoke(mWifiManager);
123         } catch (Exception e) {
124             Log.e(this.getClass().toString(), "", e);
125             return null;
126         }
127     }
128
129     /**
130      * Sets the Wi-Fi AP Configuration.
131      *
132      * @return {@code true} if the operation succeeded, {@code false} otherwise
133      */
134     public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
135         try {
136             Method method = mWifiManager.getClass().getMethod(
137                     "setWifiApConfiguration", WifiConfiguration.class);
138             return (Boolean) method.invoke(mWifiManager, wifiConfig);
139         } catch (Exception e) {
140             Log.e(this.getClass().toString(), "", e);
141             return false;
142         }
143     }
144
145     /**
146      * Gets a list of the clients connected to the Hotspot, reachable timeout is
147      * 300
148      *
149      * @param onlyReachables
150      *            {@code false} if the list should contain unreachable (probably
151      *            disconnected) clients, {@code true} otherwise
152      * @param finishListener
153      *            , Interface called when the scan method finishes
154      */
155     public void getClientList(boolean onlyReachables,
156             IOnBoardingStatus finishListener) {
157         this.finishListener = finishListener;
158         getClientList(onlyReachables, 300);
159     }
160
161     /**
162      * Gets a list of the clients connected to the Hotspot
163      *
164      * @param onlyReachables
165      *            {@code false} if the list should contain unreachable (probably
166      *            disconnected) clients, {@code true} otherwise
167      * @param reachableTimeout
168      *            Reachable Timeout in miliseconds
169      * @param finishListener
170      *            , Interface called when the scan method finishes
171      */
172     public void getClientList(final boolean onlyReachables,
173             final int reachableTimeout) {
174
175         Runnable runnable = new Runnable() {
176             public void run() {
177
178                 BufferedReader br = null;
179                 final EnrolleeInfo result = new EnrolleeInfo();
180
181                 try {
182                     br = new BufferedReader(new FileReader("/proc/net/arp"));
183                     String line;
184                     while ((line = br.readLine()) != null) {
185                         boolean deviceAddedToList = false;
186
187                         String[] splitted = line.split(" +");
188
189                         if ((splitted != null) && (splitted.length >= 4)) {
190                             // Basic sanity check
191                             String mac = splitted[3];
192
193                             if (mac.matches("..:..:..:..:..:..")) {
194                                 boolean isReachable = InetAddress.getByName(
195                                         splitted[0]).isReachable(
196                                         reachableTimeout);
197
198                                 // String execStatement =
199                                 // "ping -c 1 "+splitted[0];
200                                 //
201                                 // Process p1 =
202                                 // java.lang.Runtime.getRuntime().exec(execStatement);
203                                 //
204                                 // int returnVal = p1.waitFor();
205                                 // boolean isReachable = (returnVal==0);
206
207                                 Log.i("exec statement", splitted[0]);
208                                 Log.i("Return Value", " " + isReachable);
209
210                                 if (appNotification.size() > 0) {
211                                     for (EnrolleeOnBoardingInfo ipDeviceOnBoardingNotification : appNotification) {
212                                         boolean macAddressComparison = ipDeviceOnBoardingNotification
213                                                 .getHWAddr().equalsIgnoreCase(
214                                                         mac) ? true : false;
215
216                                         if (macAddressComparison) {
217                                             deviceAddedToList = true;
218
219                                             if (ipDeviceOnBoardingNotification
220                                                     .isAdditionNotified()
221                                                     && isReachable) {
222                                                 continue;
223                                             } else if (ipDeviceOnBoardingNotification
224                                                     .isRemovalNotified()
225                                                     && !isReachable) {
226                                                 continue;
227                                             } else {
228                                                 result.setIpAddr(splitted[0]);
229                                                 result.setHWAddr(splitted[3]);
230                                                 result.setDevice(splitted[5]);
231                                                 result.setReachable(isReachable);
232
233                                                 appNotification
234                                                         .remove(ipDeviceOnBoardingNotification);
235                                                 if (isReachable) {
236                                                     appNotification
237                                                             .add(new EnrolleeOnBoardingInfo(
238                                                                     splitted[0],
239                                                                     splitted[3],
240                                                                     splitted[5],
241                                                                     isReachable,
242                                                                     false, true));
243                                                 } else {
244                                                     appNotification
245                                                             .add(new EnrolleeOnBoardingInfo(
246                                                                     splitted[0],
247                                                                     splitted[3],
248                                                                     splitted[5],
249                                                                     isReachable,
250                                                                     true, false));
251                                                 }
252
253                                                 NotifyApplication(result);
254                                             }
255                                         }
256                                     }
257                                     if (!deviceAddedToList) {
258                                         if (isReachable) {
259                                             appNotification
260                                                     .add(new EnrolleeOnBoardingInfo(
261                                                             splitted[0],
262                                                             splitted[3],
263                                                             splitted[5],
264                                                             isReachable, false,
265                                                             true));
266                                         } else {
267                                             appNotification
268                                                     .add(new EnrolleeOnBoardingInfo(
269                                                             splitted[0],
270                                                             splitted[3],
271                                                             splitted[5],
272                                                             isReachable, true,
273                                                             false));
274                                         }
275
276                                         result.setIpAddr(splitted[0]);
277                                         result.setHWAddr(splitted[3]);
278                                         result.setDevice(splitted[5]);
279                                         result.setReachable(isReachable);
280
281                                         NotifyApplication(result);
282
283                                         break;
284                                     }
285                                 } else {
286                                     if (isReachable) {
287                                         appNotification
288                                                 .add(new EnrolleeOnBoardingInfo(
289                                                         splitted[0],
290                                                         splitted[3],
291                                                         splitted[5],
292                                                         isReachable, false,
293                                                         true));
294                                     } else {
295                                         appNotification
296                                                 .add(new EnrolleeOnBoardingInfo(
297                                                         splitted[0],
298                                                         splitted[3],
299                                                         splitted[5],
300                                                         isReachable, true,
301                                                         false));
302                                     }
303
304                                     result.setIpAddr(splitted[0]);
305                                     result.setHWAddr(splitted[3]);
306                                     result.setDevice(splitted[5]);
307                                     result.setReachable(isReachable);
308
309                                     NotifyApplication(result);
310                                     break;
311                                 }
312                             }
313                         }
314                     }
315                 } catch (Exception e) {
316                     Log.e(this.getClass().toString(), e.toString());
317                 } finally {
318                     try {
319                         br.close();
320                     } catch (IOException e) {
321                         Log.e(this.getClass().toString(), e.getMessage());
322                     }
323                 }
324             }
325         };
326
327         Thread mythread = new Thread(runnable);
328         mythread.start();
329     }
330
331     void NotifyApplication(final EnrolleeInfo result) {
332         // Get a handler that can be used to post to the main thread
333         Handler mainHandler = new Handler(context.getMainLooper());
334         Runnable myRunnable = new Runnable() {
335             @Override
336             public void run() {
337                 finishListener.deviceOnBoardingStatus(result);
338             }
339         };
340         mainHandler.post(myRunnable);
341     }
342 }