2 * ***************************************************************
4 * Copyright 2016 Samsung Electronics All Rights Reserved.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
20 * ****************************************************************
23 package org.iotivity.service.easysetup;
25 import android.app.Activity;
26 import android.content.Context;
27 import android.content.SharedPreferences;
28 import android.os.Bundle;
29 import android.preference.PreferenceManager;
30 import android.util.Log;
31 import android.view.View;
32 import android.widget.ArrayAdapter;
33 import android.widget.Button;
34 import android.widget.EditText;
35 import android.widget.LinearLayout;
36 import android.widget.RadioButton;
37 import android.widget.RadioGroup;
38 import android.widget.Spinner;
39 import android.widget.TextView;
40 import android.widget.Toast;
41 import android.widget.ToggleButton;
43 import org.iotivity.base.ModeType;
44 import org.iotivity.base.OcConnectivityType;
45 import org.iotivity.base.OcException;
46 import org.iotivity.base.OcPlatform;
47 import org.iotivity.base.OcProvisioning;
48 import org.iotivity.base.OcResource;
49 import org.iotivity.base.PlatformConfig;
50 import org.iotivity.base.QualityOfService;
51 import org.iotivity.base.ServiceType;
52 import org.iotivity.service.easysetup.mediator.CloudProp;
53 import org.iotivity.service.easysetup.mediator.CloudPropProvisioningCallback;
54 import org.iotivity.service.easysetup.mediator.CloudPropProvisioningStatus;
55 import org.iotivity.service.easysetup.mediator.DeviceConfig;
56 import org.iotivity.service.easysetup.mediator.DeviceProp;
57 import org.iotivity.service.easysetup.mediator.DevicePropProvisioningCallback;
58 import org.iotivity.service.easysetup.mediator.DevicePropProvisioningStatus;
59 import org.iotivity.service.easysetup.mediator.ESException;
60 import org.iotivity.service.easysetup.mediator.EasySetup;
61 import org.iotivity.service.easysetup.mediator.EnrolleeConf;
62 import org.iotivity.service.easysetup.mediator.GetConfigurationCallback;
63 import org.iotivity.service.easysetup.mediator.GetConfigurationStatus;
64 import org.iotivity.service.easysetup.mediator.RemoteEnrollee;
65 import org.iotivity.service.easysetup.mediator.SecurityProvisioningCallback;
66 import org.iotivity.service.easysetup.mediator.SecurityProvisioningStatus;
67 import org.iotivity.service.easysetup.mediator.WiFiConfig;
68 import org.iotivity.service.easysetup.mediator.enums.ESCloudProvState;
69 import org.iotivity.service.easysetup.mediator.enums.ESResult;
70 import org.iotivity.service.easysetup.mediator.enums.WIFI_AUTHTYPE;
71 import org.iotivity.service.easysetup.mediator.enums.WIFI_ENCTYPE;
72 import org.iotivity.service.easysetup.mediator.enums.WIFI_FREQ;
73 import org.iotivity.service.easysetup.mediator.enums.WIFI_MODE;
76 import java.io.FileNotFoundException;
77 import java.io.FileOutputStream;
78 import java.io.IOException;
79 import java.io.InputStream;
80 import java.io.OutputStream;
81 import java.util.ArrayList;
82 import java.util.EnumSet;
85 public class EasysetupActivity extends Activity {
86 private static final String TAG = "Easysetup Mediator: ";
89 private static final int BUFFER_SIZE = 1024;
91 private String filePath = "";
92 public static final String OIC_CLIENT_JSON_DB_FILE = "oic_svr_db_client.dat";
93 public static final String OIC_SQL_DB_FILE = "PDM.db";
95 private boolean isSecurityEnabled = false;
96 private boolean isFirstTime = true;
98 ToggleButton mSecurityMode;
100 RadioGroup mEasysetupProcess;
101 RadioButton mConfigureSecProcess;
102 RadioButton mGetConfigurationProcess;
103 RadioButton mProvisionDevConfProcess;
104 RadioButton mProvisionCloudConfProcess;
106 Button mDiscoverResource;
107 Button mStartGetConfiguration;
108 Button mStartConfigureSec;
109 Button mStartProvisionDevConf;
110 Button mStartProvisionCloudConf;
112 TextView mGetconfigurationStateText;
113 TextView mDevNameText;
114 TextView mLanguageText;
115 TextView mCountryText;
116 TextView mWifiModeText;
117 TextView mWifiFreqText;
118 TextView mCloudAccessableText;
119 TextView mSecStateText;
120 TextView mSecDevIDText;
121 TextView mProvisionDevConfState;
122 TextView mProvisionCloudConfState;
124 EditText mEnrollerSsidText;
125 EditText mEnrollerPWText;
126 EditText mInputLanguageText;
127 EditText mInputCountryText;
128 EditText mAuthCodeText;
129 EditText mAuthProviderText;
130 EditText mCIServerText;
132 LinearLayout mGetConfigurationInfo;
133 LinearLayout mConfigureSecInfo;
134 LinearLayout mProvisionDevConfInfo;
135 LinearLayout mProvisionCloudConfInfo;
140 EasySetup mEasySetup;
141 RemoteEnrollee mRemoteEnrollee;
147 protected void onCreate(Bundle savedInstanceState) {
148 super.onCreate(savedInstanceState);
149 setContentView(R.layout.easysetup_main);
151 mActivity = EasysetupActivity.this;
152 mContext = mActivity.getBaseContext();
154 mSecurityMode = (ToggleButton) findViewById(R.id.btn_Security);
156 mEasysetupProcess = (RadioGroup) findViewById(R.id.rg_EasysetupProcess);
158 mConfigureSecProcess = (RadioButton) findViewById(R.id.btn_configurSec);
159 mGetConfigurationProcess = (RadioButton) findViewById(R.id.btn_getConfiguration);
160 mProvisionDevConfProcess = (RadioButton) findViewById(R.id.btn_provisionDevConf);
161 mProvisionCloudConfProcess =
162 (RadioButton) findViewById(R.id.btn_provisionCloudConf);
164 mDiscoverResource = (Button) findViewById(R.id.btn_discoverResource);
165 mStartGetConfiguration =
166 (Button) findViewById(R.id.btn_startGetConfiguration);
167 mStartConfigureSec = (Button) findViewById(R.id.btn_startConfigureSec);
168 mStartProvisionDevConf = (Button) findViewById(R.id.btn_startProvisionDevConf);
169 mStartProvisionCloudConf = (Button) findViewById(R.id.btn_startProvisionCloudConf);
171 mGetconfigurationStateText =
172 (TextView) findViewById(R.id.txt_getConfigurationState);
173 mDevNameText = (TextView) findViewById(R.id.txt_devName);
174 mLanguageText = (TextView) findViewById(R.id.txt_language);
175 mCountryText = (TextView) findViewById(R.id.txt_country);
176 mWifiModeText = (TextView) findViewById(R.id.txt_wifiMode);
177 mWifiFreqText = (TextView) findViewById(R.id.txt_wifiFreq);
178 mCloudAccessableText = (TextView) findViewById(R.id.txt_cloudAccessable);
179 mSecStateText = (TextView) findViewById(R.id.txt_secState);
180 mSecDevIDText = (TextView) findViewById(R.id.txt_secDevID);
181 mProvisionDevConfState = (TextView) findViewById(R.id.txt_provisionDevConfState);
182 mProvisionCloudConfState =
183 (TextView) findViewById(R.id.txt_provisionCloudConfState);
185 mEnrollerSsidText = (EditText) findViewById(R.id.editText_EnrollerSSID);
186 mEnrollerPWText = (EditText) findViewById(R.id.editText_EnrollerPW);
187 mInputLanguageText = (EditText) findViewById(R.id.editText_Language);
188 mInputCountryText = (EditText) findViewById(R.id.editText_Country);
189 mAuthCodeText = (EditText) findViewById(R.id.editText_authcode);
190 mAuthProviderText = (EditText) findViewById(R.id.editText_authprovider);
191 mCIServerText = (EditText) findViewById(R.id.editText_ciserver);
193 mGetConfigurationInfo =
194 (LinearLayout) findViewById(R.id.layout_GetConfiguration);
195 mConfigureSecInfo = (LinearLayout) findViewById(R.id.layout_ConfigurSec);
196 mProvisionDevConfInfo = (LinearLayout) findViewById(R.id.layout_ProvisionDevConf);
197 mProvisionCloudConfInfo = (LinearLayout) findViewById(R.id.layout_ProvisionCloudConf);
199 mAuthType = (Spinner) findViewById(R.id.spinner_authType);
200 mEncType = (Spinner) findViewById(R.id.spinner_encType);
202 mEasysetupProcess.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
204 public void onCheckedChanged(RadioGroup group, int checkedId) {
205 mGetConfigurationInfo.setVisibility(View.GONE);
206 mConfigureSecInfo.setVisibility(View.GONE);
207 mProvisionDevConfInfo.setVisibility(View.GONE);
208 mProvisionCloudConfInfo.setVisibility(View.GONE);
211 case R.id.btn_configurSec:
212 mConfigureSecInfo.setVisibility(View.VISIBLE);
215 case R.id.btn_getConfiguration:
216 mGetConfigurationInfo.setVisibility(View.VISIBLE);
219 case R.id.btn_provisionDevConf:
220 mProvisionDevConfInfo.setVisibility(View.VISIBLE);
223 case R.id.btn_provisionCloudConf:
224 mProvisionCloudConfInfo.setVisibility(View.VISIBLE);
230 ArrayAdapter<CharSequence> adAuthType, adEnctype;
232 adAuthType = ArrayAdapter.createFromResource(this, R.array.auth_type,
233 android.R.layout.simple_spinner_item);
234 adAuthType.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
236 adEnctype = ArrayAdapter.createFromResource(this, R.array.enc_type,
237 android.R.layout.simple_spinner_item);
238 adEnctype.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
240 mAuthType.setAdapter(adAuthType);
241 mAuthType.setSelection(0);
243 mEncType.setAdapter(adEnctype);
244 mEncType.setSelection(0);
246 addListenerForDiscoverEnrollee();
247 addListenerForStartConfigureSec();
248 addListenerForStartGetConfiguration();
249 addListenerForStartProvisionDevProp();
250 addListenerForStartProvisionCloudProp();
252 mSecurityMode.setClickable(false);
253 mConfigureSecProcess.setEnabled(false);
254 mGetConfigurationProcess.setEnabled(false);
255 mProvisionDevConfProcess.setEnabled(false);
256 mProvisionCloudConfProcess.setEnabled(false);
258 mEasySetup = EasySetup.getInstance(getApplicationContext());
263 private void initOICStack() {
264 filePath = getFilesDir().getPath() + "/";
266 SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences
267 (getApplicationContext());
268 boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
270 if(!copyJsonFromAsset())
272 Log.e(TAG, "initOICStack error: " + "copyJsonFromAsset()");
273 Toast.makeText(this,"Can't Copy DB file from asset, please retry start SampleApp.",
274 Toast.LENGTH_LONG).show();
277 SharedPreferences.Editor editor = wmbPreference.edit();
278 editor.putBoolean("FIRSTRUN", false);
282 cfg = new PlatformConfig(
285 ModeType.CLIENT_SERVER,
286 "0.0.0.0", // bind to all available interfaces
288 QualityOfService.LOW, filePath + OIC_CLIENT_JSON_DB_FILE);
291 * Initialize DataBase
294 OcPlatform.Configure(cfg);
296 String sqlDbPath = getFilesDir().getAbsolutePath().replace("files", "databases") +
298 File file = new File(sqlDbPath);
299 //check files directory exists
300 if (!(file.isDirectory())) {
302 Log.d(TAG, "Sql db directory created at " + sqlDbPath);
304 Log.d(TAG, "Sql db directory exists at " + sqlDbPath);
306 //SQLiteDatabase.openOrCreateDatabase(sqlDbPath+ OIC_SQL_DB_FILE, null);
307 OcProvisioning.provisionInit(sqlDbPath + OIC_SQL_DB_FILE);
308 mSecurityMode.setChecked(true);
309 } catch (OcException e) {
310 logMessage(TAG + "provisionInit error: " + e.getMessage());
311 Log.e(TAG, e.getMessage());
312 Toast.makeText(this,"provisionInit error: " + e.getMessage(),
313 Toast.LENGTH_LONG).show();
314 mSecurityMode.setChecked(false);
316 } catch (UnsatisfiedLinkError e) {
318 // Note : Easy setup is built with SECURED = 0, but user still selects Security feature
319 // while running the Mediator App it couldn't find "libocprovision.so".
320 // As per the programmer guide, security feature should be invoked only if build is done with SECURED = 1.
321 mSecurityMode.setChecked(false);
322 Log.e(TAG, " Easy setup is built with secured = 0, but executed with security feature");
323 Toast.makeText(this,"Security is not enabled [Easy setup is built with SECURED = 0]",
324 Toast.LENGTH_LONG).show();
329 OcPlatform.OnResourceFoundListener listener =
330 new OcPlatform.OnResourceFoundListener() {
332 public void onFindResourceFailed(Throwable throwable, String s) {
333 Log.e(TAG, "Failed found resource, ecode: " + s);
336 public void onResourceFound(OcResource ocResource) {
337 synchronized (mActivity) {
339 if (null == ocResource) {
340 Log.e(TAG, "Found resource is invalid");
344 if(ocResource.getHost().contains("coap+tcp")) {
345 Log.d(TAG, "Recv Found resource event from tcp port, ignoring URI : " + ocResource.getUri());
346 runOnUiThread(new Runnable() {
349 mDiscoverResource.setEnabled(true);
355 // Get the resource URI
356 String resourceUri = ocResource.getUri();
357 // Get the resource host address
358 String hostAddress = ocResource.getHost();
359 Log.d(TAG,"URI of the resource: " + resourceUri);
360 Log.d(TAG,"Host address of the resource: " + hostAddress);
362 runOnUiThread(new Runnable() {
365 mDiscoverResource.setText("Founded");
366 mConfigureSecProcess.setEnabled(true);
367 mGetConfigurationProcess.setEnabled(true);
368 mProvisionDevConfProcess.setEnabled(true);
369 mProvisionCloudConfProcess.setEnabled(true);
373 mRemoteEnrollee = mEasySetup.createRemoteEnrollee(ocResource);
379 private void addListenerForDiscoverEnrollee() {
380 mDiscoverResource.setOnClickListener(new View.OnClickListener() {
382 public void onClick(View v) {
383 Thread thread = new Thread() {
384 boolean result = true;
387 runOnUiThread(new Runnable() {
390 mDiscoverResource.setEnabled(false);
395 String requestUri = OcPlatform.WELL_KNOWN_QUERY + "?rt=ocf.wk.prov";
396 OcPlatform.findResource("",
398 EnumSet.of(OcConnectivityType.CT_DEFAULT),
402 catch (OcException e) {
405 runOnUiThread(new Runnable() {
408 mDiscoverResource.setEnabled(true);
420 private void addListenerForStartConfigureSec() {
421 mStartConfigureSec.setOnClickListener(new View.OnClickListener() {
423 public void onClick(View v) {
424 Thread thread = new Thread() {
427 runOnUiThread(new Runnable() {
430 mStartConfigureSec.setEnabled(false);
435 mRemoteEnrollee.provisionSecurity(new SecurityProvisioningCallback() {
437 public void onProgress(final SecurityProvisioningStatus securityProvisioningStatus) {
438 if(securityProvisioningStatus.getESResult() == ESResult.ES_OK) {
439 runOnUiThread(new Runnable() {
442 mSecStateText.setText("Success");
443 mSecDevIDText.setText(securityProvisioningStatus.getDevUUID());
448 runOnUiThread(new Runnable() {
451 mSecStateText.setText("Failed");
452 mStartConfigureSec.setEnabled(true);
458 } catch (ESException e) {
460 runOnUiThread(new Runnable() {
463 mStartConfigureSec.setEnabled(true);
475 private void addListenerForStartGetConfiguration(){
476 mStartGetConfiguration.setOnClickListener(new View.OnClickListener() {
478 public void onClick(View v) {
479 Thread thread = new Thread() {
482 runOnUiThread(new Runnable() {
485 mGetconfigurationStateText.setText("Process");
486 mStartGetConfiguration.setEnabled(false);
491 mRemoteEnrollee.getConfiguration(new GetConfigurationCallback() {
493 public void onProgress(GetConfigurationStatus getConfigurationStatus) {
494 if(getConfigurationStatus.getESResult() == ESResult.ES_OK) {
496 final EnrolleeConf enrolleeConf = getConfigurationStatus.getEnrolleeConf();
497 runOnUiThread(new Runnable() {
500 mGetconfigurationStateText.setText("Success");
501 mDevNameText.setText(enrolleeConf.getDeviceName());
502 setWifiModes(enrolleeConf.getWiFiModes());
503 setWifiFreq(enrolleeConf.getWiFiFreq());
505 if(enrolleeConf.isCloudAccessible()) {
506 mCloudAccessableText.setText("TRUE");
509 mCloudAccessableText.setText("FALSE");
516 runOnUiThread(new Runnable() {
519 mGetconfigurationStateText.setText("Failed");
520 mStartGetConfiguration.setEnabled(true);
526 } catch (ESException e) {
528 runOnUiThread(new Runnable() {
531 mGetconfigurationStateText.setText("Failed");
532 mStartGetConfiguration.setEnabled(true);
544 private void addListenerForStartProvisionDevProp() {
545 mStartProvisionDevConf.setOnClickListener(new View.OnClickListener() {
547 public void onClick(View v) {
548 Thread thread = new Thread() {
552 runOnUiThread(new Runnable() {
555 mProvisionDevConfState.setText("Progress");
556 mStartProvisionDevConf.setEnabled(false);
560 String enrollerSSID = mEnrollerSsidText.getText().toString();
561 String enrollerPW = mEnrollerPWText.getText().toString();
562 WIFI_AUTHTYPE authType =
563 WIFI_AUTHTYPE.fromInt(mAuthType.getSelectedItemPosition());
564 WIFI_ENCTYPE encType =
565 WIFI_ENCTYPE.fromInt(mEncType.getSelectedItemPosition());
566 String inputLanguage = mInputLanguageText.getText().toString();
567 String inputCountry = mInputCountryText.getText().toString();
569 DeviceProp deviceProp = new DeviceProp();
570 deviceProp.setWiFiProp(enrollerSSID, enrollerPW, authType, encType);
571 deviceProp.setDevConfProp(inputLanguage, inputCountry);
573 mRemoteEnrollee.provisionDeviceProperties(deviceProp, new DevicePropProvisioningCallback() {
575 public void onProgress(DevicePropProvisioningStatus devPropProvisioningStatus) {
576 final ESResult result = devPropProvisioningStatus.getESResult();
577 runOnUiThread(new Runnable() {
580 if(result.equals(ESResult.ES_OK)) {
581 mProvisionDevConfState.setText("Success");
583 else if(result.equals(ESResult.ES_ERROR)) {
584 mProvisionDevConfState.setText("Failed");
586 else if(result.equals(ESResult.ES_UNAUTHORIZED)) {
587 mProvisionDevConfState.setText("Failed. Need SecProv");
589 mStartProvisionDevConf.setEnabled(true);
594 } catch (ESException e) {
596 runOnUiThread(new Runnable() {
599 mProvisionDevConfState.setText("Failed");
600 mStartProvisionDevConf.setEnabled(true);
612 private void addListenerForStartProvisionCloudProp() {
613 mStartProvisionCloudConf.setOnClickListener(new View.OnClickListener() {
615 public void onClick(View v) {
616 Thread thread = new Thread() {
619 runOnUiThread(new Runnable() {
622 mProvisionCloudConfState.setText("Progress");
623 mStartProvisionCloudConf.setEnabled(false);
628 String authCode = mAuthCodeText.getText().toString();
629 String authProvider = mAuthProviderText.getText().toString();
630 String ciserver = mCIServerText.getText().toString();
632 CloudProp cloudProp = new CloudProp();
633 cloudProp.setCloudProp(authCode, authProvider, ciserver);
635 mRemoteEnrollee.provisionCloudProperties(cloudProp, new CloudPropProvisioningCallback() {
637 public void onProgress(CloudPropProvisioningStatus cloudProvisioningStatus) {
638 final ESResult result = cloudProvisioningStatus.getESResult();
639 final ESCloudProvState state = cloudProvisioningStatus.getESCloudState();
640 runOnUiThread(new Runnable() {
643 if(result.equals(ESResult.ES_OK)) {
644 if(state.equals(ESCloudProvState.ES_CLOUD_ENROLLEE_FOUND)) {
645 mProvisionCloudConfState.setText("Found Resource");
647 else if(state.equals(ESCloudProvState.ES_CLOUD_PROVISIONING_SUCCESS)) {
648 mProvisionCloudConfState.setText("Success");
652 if(state.equals(ESCloudProvState.ES_CLOUD_ENROLLEE_NOT_FOUND)) {
653 mProvisionCloudConfState.setText("Not Found Resource");
655 else if(state.equals(ESCloudProvState.ES_CLOUD_PROVISIONING_ERROR)) {
656 mProvisionCloudConfState.setText("Failed");
658 mStartProvisionCloudConf.setEnabled(true);
664 } catch (ESException e) {
666 runOnUiThread(new Runnable() {
669 mProvisionCloudConfState.setText("Failed");
670 mStartProvisionCloudConf.setEnabled(true);
682 private boolean copyJsonFromAsset() {
683 InputStream inputStream = null;
684 OutputStream outputStream = null;
686 byte[] buffer = new byte[BUFFER_SIZE];
688 inputStream = getAssets().open(OIC_CLIENT_JSON_DB_FILE);
689 File file = new File(filePath);
690 //check files directory exists
691 if (!(file.exists() && file.isDirectory())) {
694 outputStream = new FileOutputStream(filePath + OIC_CLIENT_JSON_DB_FILE);
695 while ((length = inputStream.read(buffer)) != -1) {
696 outputStream.write(buffer, 0, length);
698 } catch (NullPointerException e) {
699 logMessage(TAG + "Null pointer exception " + e.getMessage());
700 Log.e(TAG, e.getMessage());
702 } catch (FileNotFoundException e) {
703 logMessage(TAG + "Json svr db file not found " + e.getMessage());
704 Log.e(TAG, e.getMessage());
706 } catch (IOException e) {
707 logMessage(TAG + OIC_CLIENT_JSON_DB_FILE + " file copy failed");
708 Log.e(TAG, e.getMessage());
711 if (inputStream != null) {
714 } catch (IOException e) {
715 Log.e(TAG, e.getMessage());
719 if (outputStream != null) {
721 outputStream.close();
722 } catch (IOException e) {
723 Log.e(TAG, e.getMessage());
731 public void logMessage(String text) {
735 public void setWifiModes(ArrayList<WIFI_MODE> types) {
736 String temp = "WIFI - ";
738 for(WIFI_MODE type : types) {
739 if(type.equals(WIFI_MODE.WIFI_11A)) {
740 temp = temp + "11A ";
742 else if(type.equals(WIFI_MODE.WIFI_11B)) {
743 temp = temp + "11B ";
745 else if(type.equals(WIFI_MODE.WIFI_11G)) {
746 temp = temp + "11G ";
748 else if(type.equals(WIFI_MODE.WIFI_11N)) {
749 temp = temp + "11N ";
751 else if(type.equals(WIFI_MODE.WIFI_11AC)) {
752 temp = temp + "11AC ";
755 final String modeTypes = temp;
756 runOnUiThread(new Runnable() {
759 mWifiModeText.setText(modeTypes);
764 public void setWifiFreq(final WIFI_FREQ freq) {
765 runOnUiThread(new Runnable() {
768 if(freq.equals(WIFI_FREQ.WIFI_24G)) {
769 mWifiFreqText.setText("2.4G");
771 else if(freq.equals(WIFI_FREQ.WIFI_5G)) {
772 mWifiFreqText.setText("5G");
774 else if(freq.equals(WIFI_FREQ.WIFI_BOTH)) {
775 mWifiFreqText.setText("2.4G & 5G");
782 protected void onDestroy() {