2 * ***************************************************************
\r
4 * Copyright 2015 Samsung Electronics All Rights Reserved.
\r
8 * Licensed under the Apache License, Version 2.0 (the "License");
\r
9 * you may not use this file except in compliance with the License.
\r
10 * You may obtain a copy of the License at
\r
12 * http://www.apache.org/licenses/LICENSE-2.0
\r
14 * Unless required by applicable law or agreed to in writing, software
\r
15 * distributed under the License is distributed on an "AS IS" BASIS,
\r
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
17 * See the License for the specific language governing permissions and
\r
18 * limitations under the License.
\r
20 * ****************************************************************
\r
23 package org.iotivity.service.easysetup;
\r
25 import android.app.Activity;
\r
26 import android.app.AlertDialog;
\r
27 import android.content.DialogInterface;
\r
28 import android.content.Intent;
\r
29 import android.content.SharedPreferences;
\r
30 import android.database.sqlite.SQLiteDatabase;
\r
31 import android.net.ConnectivityManager;
\r
32 import android.net.NetworkInfo;
\r
33 import android.net.wifi.WifiConfiguration;
\r
34 import android.net.wifi.WifiManager;
\r
35 import android.os.Bundle;
\r
36 import android.os.Handler;
\r
37 import android.os.Message;
\r
38 import android.preference.PreferenceManager;
\r
39 import android.util.Log;
\r
40 import android.view.View;
\r
41 import android.view.View.OnClickListener;
\r
42 import android.widget.Button;
\r
43 import android.widget.EditText;
\r
44 import android.widget.LinearLayout;
\r
45 import android.widget.ProgressBar;
\r
46 import android.widget.RadioButton;
\r
47 import android.widget.RelativeLayout;
\r
48 import android.widget.TextView;
\r
49 import android.widget.Toast;
\r
51 import org.iotivity.base.ModeType;
\r
52 import org.iotivity.base.OcException;
\r
53 import org.iotivity.base.OcPlatform;
\r
54 import org.iotivity.base.OcProvisioning;
\r
55 import org.iotivity.base.PlatformConfig;
\r
56 import org.iotivity.base.QualityOfService;
\r
57 import org.iotivity.base.ServiceType;
\r
58 import org.iotivity.service.easysetup.mediator.EasySetupService;
\r
59 import org.iotivity.service.easysetup.mediator.EasySetupStatus;
\r
60 import org.iotivity.service.easysetup.mediator.EnrolleeDevice;
\r
61 import org.iotivity.service.easysetup.mediator.IpOnBoardingConnection;
\r
62 import org.iotivity.service.easysetup.mediator.EnrolleeDeviceFactory;
\r
63 import org.iotivity.service.easysetup.mediator.WiFiOnBoardingConfig;
\r
64 import org.iotivity.service.easysetup.mediator.WiFiProvConfig;
\r
66 import java.io.File;
\r
67 import java.io.FileNotFoundException;
\r
68 import java.io.FileOutputStream;
\r
69 import java.io.IOException;
\r
70 import java.io.InputStream;
\r
71 import java.io.OutputStream;
\r
74 public class MainActivity extends Activity {
\r
75 private static final String TAG = "Easysetup Mediator: ";
\r
77 /* Status to update the UI */
\r
78 public static final int SUCCESS = 0;
\r
79 public static final int FAILED = 1;
\r
80 public static final int STATE_CHANGED = 2;
\r
82 public static final String OIC_CLIENT_JSON_DB_FILE = "oic_svr_db_client.dat";
\r
83 public static final String OIC_SQL_DB_FILE = "PDM.db";
\r
85 private static final int BUFFER_SIZE = 1024;
\r
86 private String filePath = "";
\r
87 private boolean isSecurityEnabled = false;
\r
88 //create platform config
\r
93 String mSoftAPPassword;
\r
94 String mEnrollerSsid;
\r
95 String mEnrollerPassword;
\r
97 EditText mSoftAPSsidText;
\r
98 EditText mSoftAPPassText;
\r
99 EditText mEnrollerSsidText;
\r
100 EditText mEnrollerPasswordPassText;
\r
102 TextView mDeviceIpTextView;
\r
103 TextView mDeviceMacTextView;
\r
104 TextView mResultTextView;
\r
106 ProgressBar mProgressbar;
\r
108 Button mStartButton;
\r
109 Button mStopButton;
\r
111 RadioButton mEnrollee;
\r
112 RadioButton mMediator;
\r
113 RadioButton mEnableSecurity;
\r
115 LinearLayout mSoftAP;
\r
116 RelativeLayout mDeviceInfo;
\r
117 TextView mDeviceText;
\r
119 Handler mHandler = new ThreadHandler();
\r
122 * Objects to be instantiated by the programmer
\r
124 WiFiProvConfig mWiFiProvConfig;
\r
125 WiFiOnBoardingConfig mWiFiOnBoardingConfig;
\r
126 EasySetupService mEasySetupService;
\r
127 EnrolleeDeviceFactory mDeviceFactory;
\r
128 EnrolleeDevice mDevice;
\r
131 protected void onCreate(Bundle savedInstanceState) {
\r
132 super.onCreate(savedInstanceState);
\r
133 setContentView(R.layout.activity_main);
\r
136 * Initialize widgets to get user input for target network's SSID &
\r
139 mSoftAP = (LinearLayout) findViewById(R.id.softAP);
\r
140 mDeviceInfo = (RelativeLayout) findViewById(R.id.deviceInfo);
\r
141 mDeviceText = (TextView) findViewById(R.id.textViewDeviceinfo);
\r
143 mSoftAPSsidText = (EditText) findViewById(R.id.ssid);
\r
144 mSoftAPPassText = (EditText) findViewById(R.id.password);
\r
145 mEnrollerSsidText = (EditText) findViewById(R.id.enrolleeSsid);
\r
146 mEnrollerPasswordPassText = (EditText) findViewById(R.id.enrolleePass);
\r
147 mDeviceIpTextView = (TextView) findViewById(R.id.ipAddr);
\r
148 mDeviceMacTextView = (TextView) findViewById(R.id.hardAddr);
\r
150 mResultTextView = (TextView) findViewById(R.id.status);
\r
151 mProgressbar = (ProgressBar) findViewById(R.id.progressBar);
\r
153 mEnrollee = (RadioButton) findViewById(R.id.enrollee);
\r
154 mMediator = (RadioButton) findViewById(R.id.mediator);
\r
155 mEnableSecurity = (RadioButton) findViewById(R.id.enablesecurity);
\r
157 mStartButton = (Button) findViewById(R.id.startSetup);
\r
159 mEnrollee.setChecked(false);
\r
160 mMediator.setChecked(false);
\r
161 mStartButton.setEnabled(false);
\r
163 /* Create EnrolleeDevice Factory instance */
\r
164 mDeviceFactory = EnrolleeDeviceFactory
\r
165 .newInstance(getApplicationContext());
\r
167 addListenerForStartAP();
\r
168 addListenerForStopAP();
\r
170 // default values for target network
\r
171 mEnrollerSsidText.setText(R.string.target_default_ssid);
\r
172 mEnrollerPasswordPassText.setText(R.string.target_default_pwd);
\r
173 mSoftAPSsidText.setEnabled(false);
\r
174 mSoftAPPassText.setEnabled(false);
\r
176 mEnrollee.setOnClickListener(new OnClickListener() {
\r
178 public void onClick(View v) {
\r
180 mMediator.setChecked(false);
\r
181 AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
\r
182 MainActivity.this);
\r
183 alertDialogBuilder.setTitle("Network selection");
\r
185 .setMessage("Proceed to select the network!")
\r
186 .setCancelable(false)
\r
187 .setPositiveButton("Yes",
\r
188 new DialogInterface.OnClickListener() {
\r
189 public void onClick(DialogInterface dialog,
\r
192 .startActivity(new Intent(
\r
193 WifiManager.ACTION_PICK_WIFI_NETWORK));
\r
195 mStartButton.setEnabled(true);
\r
196 mSoftAP.setVisibility(View.INVISIBLE);
\r
198 .setVisibility(View.INVISIBLE);
\r
200 .setVisibility(View.INVISIBLE);
\r
203 .setNegativeButton("No",
\r
204 new DialogInterface.OnClickListener() {
\r
205 public void onClick(DialogInterface dialog,
\r
207 mEnrollee.setChecked(false);
\r
208 mStartButton.setEnabled(false);
\r
212 alertDialogBuilder.create().show();
\r
216 mMediator.setOnClickListener(new OnClickListener() {
\r
218 public void onClick(View v) {
\r
219 mStartButton.setEnabled(true);
\r
220 mEnrollee.setChecked(false);
\r
221 mSoftAPSsidText.setEnabled(false);
\r
222 mSoftAPPassText.setEnabled(false);
\r
223 mSoftAPSsidText.setText(R.string.softAP_ssid);
\r
224 mSoftAPPassText.setText(R.string.softAP_pwd);
\r
225 mDeviceIpTextView.setText(R.string.not_available);
\r
226 mDeviceMacTextView.setText(R.string.not_available);
\r
227 mResultTextView.setText(R.string.not_started);
\r
228 mSoftAP.setVisibility(View.VISIBLE);
\r
229 mDeviceInfo.setVisibility(View.VISIBLE);
\r
230 mDeviceText.setVisibility(View.VISIBLE);
\r
234 mEnableSecurity.setOnClickListener(new OnClickListener() {
\r
236 public void onClick(View v) {
\r
237 filePath = getFilesDir().getPath() + "/";
\r
238 if (isSecurityEnabled) {
\r
239 isSecurityEnabled = false;
\r
240 mEnableSecurity.setChecked(false);
\r
243 isSecurityEnabled = true;
\r
244 mEnableSecurity.setChecked(true);
\r
246 //copy json when application runs first time
\r
247 SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences
\r
248 (getApplicationContext());
\r
249 boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
\r
251 copyJsonFromAsset();
\r
252 SharedPreferences.Editor editor = wmbPreference.edit();
\r
253 editor.putBoolean("FIRSTRUN", false);
\r
260 /* Create Easy Setup Service instance */
\r
261 mEasySetupService = EasySetupService.getInstance(
\r
262 getApplicationContext(), new EasySetupStatus() {
\r
265 public void onFinished(final EnrolleeDevice enrolledevice) {
\r
266 Log.i("MainActivity", "onFinished() is received "
\r
267 + enrolledevice.isSetupSuccessful());
\r
268 if (enrolledevice.isSetupSuccessful()) {
\r
269 mHandler.sendEmptyMessage(SUCCESS);
\r
271 mHandler.sendEmptyMessage(FAILED);
\r
276 public void onProgress(EnrolleeDevice enrolleeDevice) {
\r
277 Log.i("MainActivity", "onProgress() is received ");
\r
278 mHandler.sendEmptyMessage(STATE_CHANGED);
\r
284 * configure OIC platform and call findResource
\r
286 private void initOICStack() {
\r
287 cfg = new PlatformConfig(
\r
289 ServiceType.IN_PROC,
\r
290 ModeType.CLIENT_SERVER,
\r
291 "0.0.0.0", // bind to all available interfaces
\r
293 QualityOfService.LOW, filePath + OIC_CLIENT_JSON_DB_FILE);
\r
296 * Initialize DataBase
\r
299 OcPlatform.Configure(cfg);
\r
301 String sqlDbPath = getFilesDir().getAbsolutePath().replace("files", "databases") +
\r
303 File file = new File(sqlDbPath);
\r
304 //check files directory exists
\r
305 if (!(file.isDirectory())) {
\r
307 Log.d(TAG, "Sql db directory created at " + sqlDbPath);
\r
309 Log.d(TAG, "Sql db directory exists at " + sqlDbPath);
\r
311 //SQLiteDatabase.openOrCreateDatabase(sqlDbPath+ OIC_SQL_DB_FILE, null);
\r
312 OcProvisioning.provisionInit(sqlDbPath + OIC_SQL_DB_FILE);
\r
313 } catch (OcException e) {
\r
314 logMessage(TAG + "provisionInit error: " + e.getMessage());
\r
315 Log.e(TAG, e.getMessage());
\r
316 } catch (UnsatisfiedLinkError e) {
\r
318 // Note : Easy setup is built with SECURED = 0, but user still selects Security feature
\r
319 // while running the Mediator App it couldn't find "libocprovision.so".
\r
320 // As per the programmer guide, security feature should be invoked only if build is done with SECURED = 1.
\r
321 Log.e(TAG, " Easy setup is built with secured = 0, but executed with security feature");
\r
322 Toast.makeText(this,"Security is not enabled [Easy setup is built with SECURED = 0]",
\r
323 Toast.LENGTH_LONG).show();
\r
324 mEnableSecurity.setChecked(false);
\r
328 * Copy svr db json file from assets folder to app data files dir
\r
330 private void copyJsonFromAsset() {
\r
331 InputStream inputStream = null;
\r
332 OutputStream outputStream = null;
\r
334 byte[] buffer = new byte[BUFFER_SIZE];
\r
336 inputStream = getAssets().open(OIC_CLIENT_JSON_DB_FILE);
\r
337 File file = new File(filePath);
\r
338 //check files directory exists
\r
339 if (!(file.exists() && file.isDirectory())) {
\r
342 outputStream = new FileOutputStream(filePath + OIC_CLIENT_JSON_DB_FILE);
\r
343 while ((length = inputStream.read(buffer)) != -1) {
\r
344 outputStream.write(buffer, 0, length);
\r
346 } catch (NullPointerException e) {
\r
347 logMessage(TAG + "Null pointer exception " + e.getMessage());
\r
348 Log.e(TAG, e.getMessage());
\r
349 } catch (FileNotFoundException e) {
\r
350 logMessage(TAG + "Json svr db file not found " + e.getMessage());
\r
351 Log.e(TAG, e.getMessage());
\r
352 } catch (IOException e) {
\r
353 logMessage(TAG + OIC_CLIENT_JSON_DB_FILE + " file copy failed");
\r
354 Log.e(TAG, e.getMessage());
\r
356 if (inputStream != null) {
\r
358 inputStream.close();
\r
359 } catch (IOException e) {
\r
360 Log.e(TAG, e.getMessage());
\r
363 if (outputStream != null) {
\r
365 outputStream.close();
\r
366 } catch (IOException e) {
\r
367 Log.e(TAG, e.getMessage());
\r
373 public void logMessage(String text) {
\r
378 public void onDestroy() {
\r
380 /* Reset the Easy setup process */
\r
381 if (mEasySetupService != null) {
\r
382 mEasySetupService.finish();
\r
386 public void addListenerForStartAP() {
\r
387 mStartButton = (Button) findViewById(R.id.startSetup);
\r
388 mStartButton.setOnClickListener(new OnClickListener() {
\r
390 public void onClick(View arg0) {
\r
392 if (mEnrollee.isChecked()) {
\r
393 // Check the wifi connectivity
\r
394 if (!isConnectedTowifi()) {
\r
398 mEnrollerSsid = mEnrollerSsidText.getText().toString();
\r
399 mEnrollerPassword = mEnrollerPasswordPassText.getText()
\r
402 mWiFiProvConfig = new WiFiProvConfig(mEnrollerSsid,
\r
403 mEnrollerPassword);
\r
404 mWiFiProvConfig.setSecured(isSecurityEnabled);
\r
405 mDevice = mDeviceFactory
\r
406 .newEnrolleeDevice(mWiFiProvConfig);
\r
407 Thread thread = new Thread() {
\r
409 public void run() {
\r
411 mEasySetupService.startSetup(mDevice);
\r
412 }catch (Exception e) {
\r
413 e.printStackTrace();
\r
419 mSoftAPSsid = mSoftAPSsidText.getText().toString();
\r
420 mSoftAPPassword = mSoftAPPassText.getText().toString();
\r
421 mEnrollerSsid = mEnrollerSsidText.getText().toString();
\r
422 mEnrollerPassword = mEnrollerPasswordPassText.getText()
\r
425 mWiFiProvConfig = new WiFiProvConfig(mEnrollerSsid,
\r
426 mEnrollerPassword);
\r
427 mWiFiProvConfig.setSecured(isSecurityEnabled);
\r
428 mWiFiOnBoardingConfig = new WiFiOnBoardingConfig();
\r
431 * Provide the target credentials to be provisioned to
\r
432 * the Enrollee by Mediator
\r
434 mWiFiOnBoardingConfig.setSSId("EasySetup123");
\r
435 mWiFiOnBoardingConfig.setSharedKey("EasySetup123");
\r
436 mWiFiOnBoardingConfig
\r
437 .setAuthAlgo(WifiConfiguration.AuthAlgorithm.OPEN);
\r
438 mWiFiOnBoardingConfig
\r
439 .setKms(WifiConfiguration.KeyMgmt.WPA_PSK);
\r
440 mDevice = mDeviceFactory.newEnrolleeDevice(
\r
441 mWiFiProvConfig, mWiFiOnBoardingConfig);
\r
442 mEasySetupService.startSetup(mDevice);
\r
444 mProgressbar.setVisibility(View.VISIBLE);
\r
445 mProgressbar.setIndeterminate(true);
\r
446 mStartButton.setEnabled(false);
\r
447 mResultTextView.setText(R.string.running);
\r
449 // Reset Device information
\r
450 mDeviceIpTextView.setText(R.string.not_available);
\r
451 mDeviceMacTextView.setText(R.string.not_available);
\r
452 mStopButton.setEnabled(true);
\r
454 } catch (Exception e) {
\r
455 e.printStackTrace();
\r
461 public void addListenerForStopAP() {
\r
462 mStopButton = (Button) findViewById(R.id.stopSetup);
\r
463 mStopButton.setOnClickListener(new OnClickListener() {
\r
465 public void onClick(View arg0) {
\r
466 mStartButton.setEnabled(true);
\r
467 mStopButton.setEnabled(false);
\r
468 mResultTextView.setText(R.string.stopped);
\r
469 mProgressbar.setIndeterminate(false);
\r
470 mProgressbar.setVisibility(View.INVISIBLE);
\r
472 Thread thread = new Thread() {
\r
474 public void run() {
\r
476 mEasySetupService.stopSetup(mDevice);
\r
477 }catch (Exception e) {
\r
478 e.printStackTrace();
\r
484 }catch(Exception e){
\r
485 Log.i("Stop setup", "Exception");
\r
491 private boolean isConnectedTowifi() {
\r
493 AlertDialog dialog;
\r
494 ConnectivityManager connManager;
\r
497 // Check the wifi connectivity
\r
498 connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
\r
499 wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
\r
500 if (false == wifi.isConnected()) {
\r
502 AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
\r
503 dialogBuilder.setTitle("Error");
\r
505 .setMessage("WiFi is not enabled/connected! Please connect the WiFi..");
\r
506 dialogBuilder.setCancelable(false);
\r
507 dialogBuilder.setPositiveButton("OK",
\r
508 new DialogInterface.OnClickListener() {
\r
510 public void onClick(DialogInterface dialog, int which) {
\r
512 MainActivity.this.startActivity(new Intent(
\r
513 WifiManager.ACTION_PICK_WIFI_NETWORK));
\r
517 dialogBuilder.setNegativeButton("Cancel",
\r
518 new DialogInterface.OnClickListener() {
\r
520 public void onClick(DialogInterface dialog, int which) {
\r
524 dialog = dialogBuilder.create();
\r
531 class ThreadHandler extends Handler {
\r
533 public void handleMessage(Message msg) {
\r
535 switch (msg.what) {
\r
538 mProgressbar.setIndeterminate(false);
\r
539 mStopButton.setEnabled(false);
\r
540 mStartButton.setEnabled(true);
\r
541 mProgressbar.setVisibility(View.INVISIBLE);
\r
542 String resultMsg = "Device configured successfully";
\r
543 mResultTextView.setText(R.string.success);
\r
545 /* Update device information on the Ui */
\r
546 IpOnBoardingConnection connection = (IpOnBoardingConnection) mDevice
\r
548 mDeviceIpTextView.setText(connection.getIp());
\r
549 mDeviceMacTextView.setText(connection.getHardwareAddress());
\r
551 Toast.makeText(getApplicationContext(), resultMsg,
\r
552 Toast.LENGTH_SHORT).show();
\r
557 mProgressbar.setIndeterminate(false);
\r
558 mStopButton.setEnabled(false);
\r
559 mStartButton.setEnabled(true);
\r
560 mProgressbar.setVisibility(View.INVISIBLE);
\r
561 String resultMsg = "Device configuration failed";
\r
562 mResultTextView.setText(R.string.failed);
\r
563 Toast.makeText(getApplicationContext(), resultMsg,
\r
564 Toast.LENGTH_SHORT).show();
\r
568 case STATE_CHANGED: {
\r
569 String resultMsg = "Device state changed";
\r
570 Toast.makeText(getApplicationContext(), resultMsg,
\r
571 Toast.LENGTH_SHORT).show();
\r