Forráskód Böngészése

first commit onboarding tool only separated with iotivity_lite repository.

Trishia 4 éve
commit
60d27d5c95
64 módosított fájl, 4143 hozzáadás és 0 törlés
  1. 8 0
      OnBoardingTool/.gitignore
  2. 1 0
      OnBoardingTool/app/.gitignore
  3. 46 0
      OnBoardingTool/app/build.gradle
  4. 3 0
      OnBoardingTool/app/libs/.gitignore
  5. 17 0
      OnBoardingTool/app/proguard-rules.pro
  6. 35 0
      OnBoardingTool/app/src/main/AndroidManifest.xml
  7. 13 0
      OnBoardingTool/app/src/main/assets/pki_certs/rootca1.pem
  8. 11 0
      OnBoardingTool/app/src/main/assets/pki_certs/rootca2.pem
  9. 179 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/AcePropertiesHelper.java
  10. 79 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/CredentialListHelper.java
  11. 30 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/DeleteAceHandler.java
  12. 30 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/DeleteCredentialHandler.java
  13. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/DeviceResetHandler.java
  14. 107 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/FactoryPresetsHandler.java
  15. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/GenerateRandomPinHandler.java
  16. 76 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/GetDeviceNameHandler.java
  17. 74 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/JustWorksAndAuthWildcardAceHandler.java
  18. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/JustWorksHandler.java
  19. 52 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ObtInitHandler.java
  20. 49 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OcfDeviceInfo.java
  21. 1630 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OnBoardingActivity.java
  22. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OtmCertificationHandler.java
  23. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OtmRandomPinHandler.java
  24. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OwnedDeviceHandler.java
  25. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionAce2Handler.java
  26. 65 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionAuthWildcardAceAndPairwisingHandler.java
  27. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionAuthWildcardAceHandler.java
  28. 31 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionCredentialsHandler.java
  29. 31 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionIdCertificateHandler.java
  30. 31 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionRoleCertificateHandler.java
  31. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionRoleWildcardAceHandler.java
  32. 55 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ResourceDiscoveryHandler.java
  33. 150 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/RetrieveAcl2Handler.java
  34. 56 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/RetrieveCredentialHandler.java
  35. 133 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/RoleCertificateHelper.java
  36. 91 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/TrustAnchorHelper.java
  37. 35 0
      OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/UnownedDeviceHandler.java
  38. 0 0
      OnBoardingTool/app/src/main/jniLibs/arm64-v8a/.gitignore
  39. BIN
      OnBoardingTool/app/src/main/jniLibs/arm64-v8a/libiotivity-lite-jni.so
  40. 2 0
      OnBoardingTool/app/src/main/jniLibs/armeabi/.gitignore
  41. BIN
      OnBoardingTool/app/src/main/jniLibs/libiotivity-lite-jni.so
  42. BIN
      OnBoardingTool/app/src/main/jniLibs/x86/libiotivity-lite-jni.so
  43. 2 0
      OnBoardingTool/app/src/main/jniLibs/x86_64/.gitignore
  44. 43 0
      OnBoardingTool/app/src/main/res/layout/acl_multi_line.xml
  45. 136 0
      OnBoardingTool/app/src/main/res/layout/activity_main.xml
  46. 79 0
      OnBoardingTool/app/src/main/res/layout/creds_multi_line.xml
  47. 32 0
      OnBoardingTool/app/src/main/res/menu/actionbar_actions.xml
  48. BIN
      OnBoardingTool/app/src/main/res/mipmap-hdpi/ic_launcher.png
  49. BIN
      OnBoardingTool/app/src/main/res/mipmap-mdpi/ic_launcher.png
  50. BIN
      OnBoardingTool/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  51. BIN
      OnBoardingTool/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  52. BIN
      OnBoardingTool/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  53. 6 0
      OnBoardingTool/app/src/main/res/values-w820dp/dimens.xml
  54. 6 0
      OnBoardingTool/app/src/main/res/values/colors.xml
  55. 5 0
      OnBoardingTool/app/src/main/res/values/dimens.xml
  56. 88 0
      OnBoardingTool/app/src/main/res/values/strings.xml
  57. 11 0
      OnBoardingTool/app/src/main/res/values/styles.xml
  58. 26 0
      OnBoardingTool/build.gradle
  59. 17 0
      OnBoardingTool/gradle.properties
  60. BIN
      OnBoardingTool/gradle/wrapper/gradle-wrapper.jar
  61. 6 0
      OnBoardingTool/gradle/wrapper/gradle-wrapper.properties
  62. 160 0
      OnBoardingTool/gradlew
  63. 90 0
      OnBoardingTool/gradlew.bat
  64. 1 0
      OnBoardingTool/settings.gradle

+ 8 - 0
OnBoardingTool/.gitignore

@@ -0,0 +1,8 @@
+*.iml
+.gradle
+/local.properties
+/.idea
+.DS_Store
+/build
+/captures
+.externalNativeBuild

+ 1 - 0
OnBoardingTool/app/.gitignore

@@ -0,0 +1 @@
+/build

+ 46 - 0
OnBoardingTool/app/build.gradle

@@ -0,0 +1,46 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 28
+    buildToolsVersion = '28.0.3'
+    defaultConfig {
+        applicationId "org.iotivity.onboardingtool"
+        minSdkVersion 21
+        targetSdkVersion 26
+        versionCode 1
+        versionName "1.0"
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+    sourceSets {
+        main {
+            jniLibs.srcDirs = ["src/main/jniLibs", "$buildDir/native-libs"]
+        }
+    }
+    splits {
+        abi {
+            enable true
+            reset()
+            include 'x86', 'x86_64', 'armeabi', 'arm64-v8a'
+            universalApk true
+        }
+    }
+
+}
+
+dependencies {
+    implementation 'com.android.support:appcompat-v7:28.0.0'
+
+    //compile fileTree(dir: 'libs', include: ['*.jar'])
+    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+        exclude group: 'com.android.support', module: 'support-annotations'
+    })
+    //compile 'com.android.support:appcompat-v7:24.2.1'
+    //testCompile 'junit:junit:4.12'
+    compile files('libs/iotivity-lite.jar')
+}

+ 3 - 0
OnBoardingTool/app/libs/.gitignore

@@ -0,0 +1,3 @@
+*.jar
+*.so
+

+ 17 - 0
OnBoardingTool/app/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/larrys/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 35 - 0
OnBoardingTool/app/src/main/AndroidManifest.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.iotivity.onboardingtool">
+
+    <uses-feature android:name="android.hardware.nfc" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.NFC" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity
+            android:name=".OnBoardingActivity"
+            android:screenOrientation="portrait">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>

+ 13 - 0
OnBoardingTool/app/src/main/assets/pki_certs/rootca1.pem

@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB3zCCAYWgAwIBAgIJAPObjMBXKhGyMAoGCCqGSM49BAMCMFMxDDAKBgNVBAoM
+A09DRjEiMCAGA1UECwwZS3lyaW8gVGVzdCBJbmZyYXN0cnVjdHVyZTEfMB0GA1UE
+AwwWS3lyaW8gVEVTVCBST09UIENBMDAwMjAeFw0xODExMzAxNzMxMDVaFw0yODEx
+MjcxNzMxMDVaMFMxDDAKBgNVBAoMA09DRjEiMCAGA1UECwwZS3lyaW8gVGVzdCBJ
+bmZyYXN0cnVjdHVyZTEfMB0GA1UEAwwWS3lyaW8gVEVTVCBST09UIENBMDAwMjBZ
+MBMGByqGSM49AgEGCCqGSM49AwEHA0IABGt1sU2QhQcK/kflKSF9TCrvKaDckLWd
+ZoyvP6z0OrqNdtBscZgVYsSHMQZ1R19wWxsflvNr8bMVW1K3HWMkpsijQjBAMA8G
+A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQoSOTlJ1jZ
+CO4JNOSxuz1ZZh/I9TAKBggqhkjOPQQDAgNIADBFAiAlMUwgVeL8d5W4jZdFJ5Zg
+clk7XT66LNMfGkExSjU1ngIhANOvTmd32A0kEtIpHbiKA8+RFDCPJWjN4loxrBC7
+v0JE
+-----END CERTIFICATE-----

+ 11 - 0
OnBoardingTool/app/src/main/assets/pki_certs/rootca2.pem

@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBnTCCAUKgAwIBAgIUfKTxfZOGE/bSAF+l555yrmzbBZYwCgYIKoZIzj0EAwIw
+KzEMMAoGA1UEChMDT0NGMRswGQYDVQQDExJURVNUIE9DRiBSb290IENBIDIwIBcN
+MTgxMTI5MTY0MTIyWhgPMjA2ODExMjkxNjQxMjJaMCsxDDAKBgNVBAoTA09DRjEb
+MBkGA1UEAxMSVEVTVCBPQ0YgUm9vdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0D
+AQcDQgAED4xusXQP8CojjLCIy3Kc/6oDZUM2CxKiq4RfKi4A2hZ9uOKD1TrirCGh
+yVLso63+OQv1Zi6Og9E4SYMDHqvwZKNCMEAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
+DgQWBBSYuivCP5E741G+c2v1466PlBfNizAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
+SM49BAMCA0kAMEYCIQCyF9qhRMdtJhM922E7BrTENwrwrYU9X66zgRtBTuzrVgIh
+ANreyj+BcMMLqXLZUSw1Lbb+4fm+/2ETt92RbrZSwXYt
+-----END CERTIFICATE-----

+ 179 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/AcePropertiesHelper.java

@@ -0,0 +1,179 @@
+package org.iotivity.onboardingtool;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.util.Log;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import org.iotivity.OCAcePermissionsMask;
+import org.iotivity.OCAceWildcard;
+import org.iotivity.OCInterfaceMask;
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.oc.OcAceResource;
+import org.iotivity.oc.OcObt;
+import org.iotivity.oc.OcSecurityAce;
+
+import java.util.HashSet;
+import java.util.Set;
+
+class AcePropertiesHelper {
+
+    private static final String TAG = AcePropertiesHelper.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+    private OcObt obt;
+    private String uuid;
+    private OCObtDeviceStatusHandler provisionAce2Handler;
+    private int resourceNumber;
+
+    AcePropertiesHelper(OnBoardingActivity activity, OcObt obt, String uuid, OCObtDeviceStatusHandler provisionAce2Handler) {
+        this.activity = activity;
+        this.obt = obt;
+        this.uuid = uuid;
+        this.provisionAce2Handler = provisionAce2Handler;
+    }
+
+    void getProperties(final OcSecurityAce ace) {
+        ++resourceNumber;
+
+        final OcAceResource aceResource = new OcAceResource(ace);
+
+        if (aceResource == null) {
+            Toast.makeText(activity, "Error allocating new ace resource", Toast.LENGTH_LONG).show();
+            return;
+        }
+
+        AlertDialog.Builder hrefAlertDialogBuilder = new AlertDialog.Builder(activity);
+
+        LinearLayout layout = new LinearLayout(activity);
+        layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+        layout.setOrientation(LinearLayout.VERTICAL);
+
+        final EditText input = new EditText(activity);
+        layout.addView(input);
+
+        String title = activity.getString(R.string.hrefDialogTitle).replace("?", Integer.toString(resourceNumber));
+        hrefAlertDialogBuilder.setTitle(title);
+        hrefAlertDialogBuilder.setMessage(R.string.hrefDialogMessage);
+        hrefAlertDialogBuilder.setView(layout);
+
+        hrefAlertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                String href = input.getText().toString().trim();
+                if (!href.isEmpty()) {
+                    if (href.length() > 63) {
+                        href = href.substring(0, 63);
+                    }
+
+                    aceResource.setHref(href);
+                    aceResource.setWildcard(OCAceWildcard.OC_ACE_NO_WC);
+
+                    getPermissions(ace);
+
+                } else {
+                    AlertDialog.Builder wildcardAlertDialogBuilder = new AlertDialog.Builder(activity);
+                    String title = activity.getResources().getString(R.string.wildcardDialogTitle).replace("?", Integer.toString(resourceNumber));
+                    wildcardAlertDialogBuilder.setTitle(title);
+                    wildcardAlertDialogBuilder.setItems(R.array.wildcardOptions, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            switch (which) {
+                                case 0:
+                                    aceResource.setWildcard(OCAceWildcard.OC_ACE_NO_WC);
+                                    break;
+                                case 1:
+                                    aceResource.setWildcard(OCAceWildcard.OC_ACE_WC_ALL);
+                                    break;
+                                case 2:
+                                    aceResource.setWildcard(OCAceWildcard.OC_ACE_WC_ALL_SECURED);
+                                    break;
+                                case 3:
+                                    aceResource.setWildcard(OCAceWildcard.OC_ACE_WC_ALL_PUBLIC);
+                                    break;
+                                default:
+                                    break;
+                            }
+
+                            getPermissions(ace);
+                        }
+                    });
+
+                    Dialog wildcardDialog = wildcardAlertDialogBuilder.create();
+                    wildcardDialog.show();
+                }
+            }
+        });
+
+        Dialog hrefDialog = hrefAlertDialogBuilder.create();
+        hrefDialog.show();
+    }
+
+    private void getPermissions(final OcSecurityAce ace) {
+        final Set<Integer> permissions = new HashSet<>();
+        AlertDialog.Builder permissionsAlertDialogBuilder = new AlertDialog.Builder(activity);
+        permissionsAlertDialogBuilder.setTitle(R.string.permissionsDialogTitle);
+        permissionsAlertDialogBuilder.setMultiChoiceItems(R.array.permissions, null, new DialogInterface.OnMultiChoiceClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+                if (isChecked) {
+                    permissions.add(which);
+                } else {
+                    if (permissions.contains(which)) {
+                        permissions.remove(which);
+                    }
+                }
+            }
+        });
+
+        permissionsAlertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                if (!permissions.isEmpty()) {
+                    for (int permission : permissions) {
+                        switch (permission) {
+                            case 0:
+                                ace.addPermission(OCAcePermissionsMask.CREATE);
+                                break;
+                            case 1:
+                                ace.addPermission(OCAcePermissionsMask.RETRIEVE);
+                                break;
+                            case 2:
+                                ace.addPermission(OCAcePermissionsMask.UPDATE);
+                                break;
+                            case 3:
+                                ace.addPermission(OCAcePermissionsMask.DELETE);
+                                break;
+                            case 4:
+                                ace.addPermission(OCAcePermissionsMask.NOTIFY);
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                }
+
+                new Thread(new Runnable() {
+                    public void run() {
+                        if (obt.provisionAce(OCUuidUtil.stringToUuid(uuid), ace, provisionAce2Handler) < 0) {
+                            final String msg = "Failed to provision ace credentials for " + uuid;
+                            Log.d(TAG, msg);
+                            activity.runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }).start();
+            }
+        });
+
+        Dialog permissionsDialog = permissionsAlertDialogBuilder.create();
+        permissionsDialog.show();
+    }
+}

+ 79 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/CredentialListHelper.java

@@ -0,0 +1,79 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+
+import org.iotivity.OCCred;
+import org.iotivity.OCCredUtil;
+import org.iotivity.OCCreds;
+import org.iotivity.OCUuidUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class CredentialListHelper {
+
+    private static final String TAG = CredentialListHelper.class.getSimpleName();
+
+    private ArrayList<HashMap<String, String>> credentialsList;
+
+    public CredentialListHelper(ArrayList<HashMap<String, String>> credsList) {
+        this.credentialsList = credsList;
+    }
+
+    public void buildList(OCCreds creds) {
+        OCCred cred = creds.getCredsListHead();
+        while (cred != null) {
+            HashMap<String, String> item = new HashMap<>();
+
+            String line = "Id: " + Integer.toString(cred.getCredId());
+            item.put("line1", line);
+            Log.d(TAG, line);
+
+            line = "Subject UUID: " + OCUuidUtil.uuidToString(cred.getSubjectUuid());
+            item.put("line2", line);
+            Log.d(TAG, line);
+
+            line = "Type: " + OCCredUtil.credTypeString(cred.getCredType());
+            Log.d(TAG, line);
+            item.put("line3", line);
+
+            line = "Usage: " + OCCredUtil.readCredUsage(cred.getCredUsage());
+            item.put("line4", line);
+            Log.d(TAG, line);
+
+            line = "Public Data Encoding: ";
+            if ((cred.getPublicData() != null) && (cred.getPublicData().getData() != null) && (!cred.getPublicData().getData().isEmpty())) {
+                line += OCCredUtil.readEncoding((cred.getPublicData().getEncoding()));
+            } else {
+                line += "<None>";
+            }
+            item.put("line5", line);
+            Log.d(TAG, line);
+
+            line = "Private Data Encoding: " + OCCredUtil.readEncoding((cred.getPrivateData().getEncoding()));
+            item.put("line6", line);
+            Log.d(TAG, line);
+
+            line = "Role: ";
+            if ((cred.getRole() != null) && (!cred.getRole().isEmpty())) {
+                line += cred.getRole();
+            } else {
+                line += "<None>";
+            }
+            item.put("line7", line);
+            Log.d(TAG, line);
+
+            line = "Authority: ";
+            if ((cred.getAuthority() != null) && (!cred.getAuthority().isEmpty())) {
+                line += cred.getAuthority();
+            } else {
+                line += "<None>";
+            }
+            item.put("line8", line);
+            Log.d(TAG, line);
+
+            credentialsList.add(item);
+            cred = cred.getNext();
+        }
+    }
+}

+ 30 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/DeleteAceHandler.java

@@ -0,0 +1,30 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtStatusHandler;
+
+public class DeleteAceHandler implements OCObtStatusHandler {
+
+    private static final String TAG = DeleteAceHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public DeleteAceHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(int status) {
+        if (status < 0) {
+            final String msg = "Error deleting ace, status = " + status;
+            Log.d(TAG, msg);
+            activity.runOnUiThread(new Runnable() {
+                public void run() {
+                    Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                }
+            });
+        }
+    }
+}

+ 30 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/DeleteCredentialHandler.java

@@ -0,0 +1,30 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtStatusHandler;
+
+public class DeleteCredentialHandler implements OCObtStatusHandler {
+
+    private static final String TAG = DeleteCredentialHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public DeleteCredentialHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(int status) {
+        if (status < 0) {
+            final String msg = "Error deleting credential, status = " + status;
+            Log.d(TAG, msg);
+            activity.runOnUiThread(new Runnable() {
+                public void run() {
+                    Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                }
+            });
+        }
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/DeviceResetHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class DeviceResetHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = DeviceResetHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public DeviceResetHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully performed hard reset on device " + deviceId :
+                "Error performing hard reset on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 107 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/FactoryPresetsHandler.java

@@ -0,0 +1,107 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+
+import org.iotivity.OCFactoryPresetsHandler;
+import org.iotivity.OCPki;
+import org.iotivity.oc.OcObt;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class FactoryPresetsHandler implements OCFactoryPresetsHandler {
+
+    private static final String TAG = FactoryPresetsHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public FactoryPresetsHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(long deviceIndex) {
+        Log.d(TAG, "inside the FactoryPresetsHandler, deviceIndex  = " + deviceIndex);
+
+        // Shutdown and re-init instance
+        if (activity.getObt() != null) {
+            activity.getObt().shutdown();
+        }
+        activity.ownedDeviceList.clear();
+        activity.unownedDeviceList.clear();
+        activity.setObt(new OcObt());
+
+        setPKISecurityMfgCert(deviceIndex);
+    }
+
+    private void setPKISecurityMfgCert(long deviceIndex) {
+
+        byte[] rootCa1 = getFileBytes("pki_certs/rootca1.pem");
+        if (rootCa1 == null) {
+            Log.e(TAG, "Failed to read root ca1 certificate");
+            return;
+        }
+
+        int rootCaCredId = OCPki.addMfgTrustAnchor(deviceIndex, rootCa1);
+        Log.d(TAG, "addMfgTrustAnchor() result = " + rootCaCredId);
+        if (rootCaCredId < 0) {
+            Log.e(TAG, "Error installing root ca1 certificate");
+            return;
+        }
+
+        byte[] rootCa2 = getFileBytes("pki_certs/rootca2.pem");
+        if (rootCa2 == null) {
+            Log.e(TAG, "Failed to read root ca2 certificate");
+            return;
+        }
+
+        rootCaCredId = OCPki.addMfgTrustAnchor(deviceIndex, rootCa2);
+        Log.d(TAG, "addMfgTrustAnchor() result = " + rootCaCredId);
+        if (rootCaCredId < 0) {
+            Log.e(TAG, "Error installing root ca2 certificate");
+            return;
+        }
+    }
+
+    public byte[] getFileBytes(String filepath) {
+
+        ByteArrayOutputStream baos = null;
+        try {
+            InputStream is = activity.getAssets().open(filepath);
+            Log.d(TAG, "reading file " + filepath);
+
+            try {
+                byte[] buffer = new byte[8192];
+                baos = new ByteArrayOutputStream();
+                int length = 0;
+                while ((length = is.read(buffer)) != -1) {
+                    Log.d(TAG, "bytes read = " + length);
+                    baos.write(buffer, 0, length);
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error reading file " + filepath);
+            } finally {
+                try {
+                    if (baos != null) {
+                        baos.close();
+                    }
+                } catch (IOException e) {
+                    // ignore
+                }
+                try {
+                    if (is != null) {
+                        is.close();
+                    }
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to read " + filepath);
+        }
+
+        return ((baos != null) ? baos.toByteArray() : null);
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/GenerateRandomPinHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class GenerateRandomPinHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = GenerateRandomPinHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public GenerateRandomPinHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully generated Random PIN on device " + deviceId :
+                "Error generating Random PIN on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 76 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/GetDeviceNameHandler.java

@@ -0,0 +1,76 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.oc.OcCborException;
+import org.iotivity.oc.OcRepresentation;
+
+public class GetDeviceNameHandler implements OCResponseHandler {
+
+    private static final String TAG = GetDeviceNameHandler.class.getSimpleName();
+
+    private static final String N_KEY = "n";
+    private static final String DI_KEY = "di";
+    private static final String PIID_KEY = "piid";
+    private static final String ICV_KEY = "icv";
+    private static final String DMV_KEY = "dmv";
+
+    private OnBoardingActivity activity;
+    private boolean ownedList;
+
+
+    public GetDeviceNameHandler(OnBoardingActivity activity, boolean ownedList) {
+        this.activity = activity;
+        this.ownedList = ownedList;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+        Log.d(TAG, "Get Device Name Handler:");
+        OcRepresentation rep = new OcRepresentation(response.getPayload());
+        String n = null;
+        String di = null;
+        String piid=null, icv=null, dmv = null ;
+        while (rep != null) {
+            try {
+                //Log.d(TAG, "Types = " + rep.getType());
+                //Log.d(TAG, rep.getKey() + " = " + rep.getValue().getString());
+                if (N_KEY.equals(rep.getKey())) {
+                    n = rep.getString(N_KEY);
+                }
+                if (DI_KEY.equals(rep.getKey())) {
+                    di = rep.getString(DI_KEY);
+                }
+                if(PIID_KEY.equals(rep.getKey())) {
+                    piid = rep.getString(PIID_KEY);
+                }
+                if(ICV_KEY.equals(rep.getKey())) {
+                    icv = rep.getString(ICV_KEY);
+                }
+                if(DMV_KEY.equals(rep.getKey())) {
+                    dmv = rep.getString(DMV_KEY);
+                }
+            } catch (OcCborException e) {
+                Log.e(TAG, e.getMessage());
+            }
+            rep = rep.getNext();
+        }
+
+        if ((di != null) && (n != null)) {
+
+            OcfDeviceInfo device = new OcfDeviceInfo(OCUuidUtil.stringToUuid(di), n);
+            device.setPiid(OCUuidUtil.stringToUuid(piid));
+            device.setSpec(icv);
+            device.setDataModel(dmv);
+
+            if (ownedList) {
+                activity.addOwnedDevice(device);
+            } else {
+                activity.addUnownedDevice(device);
+            }
+        }
+    }
+}

+ 74 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/JustWorksAndAuthWildcardAceHandler.java

@@ -0,0 +1,74 @@
+package org.iotivity.onboardingtool;
+
+import android.os.Handler;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class JustWorksAndAuthWildcardAceHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = JustWorksAndAuthWildcardAceHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public JustWorksAndAuthWildcardAceHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(final OCUuid uuid, int status) {
+        final String deviceId = OCUuidUtil.uuidToString(uuid);
+        final String msg = (status >= 0) ?
+                "Successfully performed OTM on device " + deviceId :
+                "Error performing ownership transfer on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+
+        if(status >= 0) {
+
+            // provision Auth-crypt WildCard ACE to the owned device
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+
+                    if (activity.getObt().provisionAuthWildcardAce(uuid, new ProvisionAuthWildcardAceHandler(activity)) < 0) {
+                        final String fail_msg = "Failed to provision auth-crypt * ACE for uuid " + deviceId;
+                        Log.d(TAG, fail_msg);
+                        activity.runOnUiThread(new Runnable() {
+                            public void run() {
+                                Toast.makeText(activity, fail_msg, Toast.LENGTH_LONG).show();
+                            }
+                        });
+                    }
+                }
+            }).start();
+
+            // discovery Owned devices
+            /*new Thread(new Runnable() {
+                public void run() {
+
+                    activity.getOwnedDeviceList().clear();
+
+                    if (activity.getObt().discoverOwnedDevices(new OwnedDeviceHandler(activity)) < 0) {
+                        final String msg = "Failed to discover owned devices";
+                        Log.d(TAG, msg);
+                        activity.runOnUiThread(new Runnable() {
+                            public void run() {
+                                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                            }
+                        });
+                    }
+                }
+            }).start();*/
+        }
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/JustWorksHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class JustWorksHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = JustWorksHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public JustWorksHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully performed OTM on device " + deviceId :
+                "Error performing ownership transfer on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 52 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ObtInitHandler.java

@@ -0,0 +1,52 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+
+import org.iotivity.OCAddDeviceHandler;
+import org.iotivity.OCMainInitHandler;
+import org.iotivity.oc.OcDevice;
+import org.iotivity.oc.OcPlatform;
+
+public class ObtInitHandler implements OCMainInitHandler {
+
+    private static final String TAG = ObtInitHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+    private OcPlatform obtPlatform;
+
+    public ObtInitHandler(OnBoardingActivity activity, OcPlatform obtPlatform) {
+        this.activity = activity;
+        this.obtPlatform = obtPlatform;
+    }
+
+    @Override
+    public int initialize() {
+        Log.d(TAG, "inside ObtInitHandler.initialize()");
+        int ret = obtPlatform.platformInit("OCF"); // Manufaturer Name
+        if (ret >= 0) {
+            OcDevice device = new OcDevice("/oic/d", "oic.d.dots", "OBT", "ocf.2.0.5", "ocf.res.1.0.0,ocf.sh.1.0.0");
+            /*,
+                    new OCAddDeviceHandler() {
+                        public void handler() {
+                            Log.d(TAG, "inside Obt.OCAddDeviceHandler.handler()");
+                        }
+                    });*/
+            ret |= obtPlatform.addDevice(device);
+            // Note: device must be added to platform before additional resource types can be added
+            device.bindResourceType("oic.d.ams");
+            device.bindResourceType("oic.d.cms");
+        }
+
+        return ret;
+    }
+
+    @Override
+    public void registerResources() {
+        Log.d(TAG, "inside ObtInitHandler.registerResources()");
+    }
+
+    @Override
+    public void requestEntry() {
+        Log.d(TAG, "inside ObtInitHandler.requestEntry()");
+    }
+}

+ 49 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OcfDeviceInfo.java

@@ -0,0 +1,49 @@
+package org.iotivity.onboardingtool;
+
+import org.iotivity.OCUuid;
+
+public class OcfDeviceInfo {
+
+    private OCUuid uuid;
+    private String name;
+    private OCUuid piid;
+    private String spec;
+    private String dataModel ;
+
+    OcfDeviceInfo(OCUuid uuid, String name) {
+        this.uuid = uuid;
+        this.name = name;
+    }
+
+    public OCUuid getUuid() {
+        return uuid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setPiid(OCUuid piid) {
+        this.piid = piid ;
+    }
+
+    public void setSpec(String spec) {
+        this.spec = spec;
+    }
+
+    public void setDataModel(String data_model) {
+        this.dataModel = data_model ;
+    }
+
+    public int hashCode() {
+        int result = 17;
+        result = 37 * result + uuid.hashCode();
+        result = 37 * result + name.hashCode();
+        return result;
+    }
+
+    public boolean equals(Object obj) {
+        OcfDeviceInfo other = (OcfDeviceInfo) obj;
+        return (uuid.equals(other.uuid) && name.equals(other.name));
+    }
+}

+ 1630 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OnBoardingActivity.java

@@ -0,0 +1,1630 @@
+package org.iotivity.onboardingtool;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.iotivity.OCCred;
+import org.iotivity.OCCredUtil;
+import org.iotivity.OCCreds;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.oc.OcAnonSecurityAce;
+import org.iotivity.oc.OcAuthSecurityAce;
+import org.iotivity.oc.OcObt;
+import org.iotivity.oc.OcPlatform;
+import org.iotivity.oc.OcRemoteDevice;
+import org.iotivity.oc.OcRoleSecurityAce;
+import org.iotivity.oc.OcSecurityAce;
+import org.iotivity.oc.OcSubjectSecurityAce;
+import org.iotivity.oc.OcUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class OnBoardingActivity extends AppCompatActivity {
+
+    private static final String TAG = OnBoardingActivity.class.getSimpleName();
+
+    private boolean isRadioChecking;
+    private RadioGroup allRadioGroup;
+    private RadioGroup realmRadioGroup;
+    private RadioGroup siteRadioGroup;
+    private RadioButton ownedRadioButton;
+    private RadioButton unownedRadioButton;
+    private RadioButton ownedRealmRadioButton;
+    private RadioButton unownedRealmRadioButton;
+    private RadioButton ownedSiteRadioButton;
+    private RadioButton unownedSiteRadioButton;
+    private Button refreshButton;
+    private Button onboardingButton;
+    private Button pairwisingButton;
+    private Button offboardingButton;
+    private ListView listView;
+
+    private AdapterView.OnItemClickListener ownedItemClickListener;
+    private AdapterView.OnItemClickListener unownedItemClickListener;
+
+    private ArrayAdapter<OcfDeviceInfo> ownedArrayAdapter;
+    private ArrayAdapter<OcfDeviceInfo> unownedArrayAdapter;
+
+    ArrayList<OcfDeviceInfo> ownedDeviceList = new ArrayList<>();
+    ArrayList<OcfDeviceInfo> unownedDeviceList = new ArrayList<>();
+
+    private final Object arrayAdapterSync = new Object();
+
+    private OcObt obt;
+    private OcPlatform obtPlatform;
+
+    private Handler mHandler = new Handler();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        createContent();
+
+        if (savedInstanceState == null) {
+            // start first time only
+
+            // Note: If using a factory presets handler,
+            // the factory presets handler must be set prior to calling
+            // systemInit().
+            // The systemInit() function will cause the factory presets handler to
+            // be called if it is set.
+            OcUtils.setFactoryPresetsHandler(new FactoryPresetsHandler(this));
+
+            obtPlatform = OcPlatform.getInstance();
+            ObtInitHandler handler = new ObtInitHandler(this, obtPlatform);
+            obtPlatform.systemInit(handler);
+            obt = new OcObt();
+
+            //this.scheduledTaskInit();
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.d(TAG, "Calling Shutdown.");
+        obtPlatform.systemShutdown();
+        obt.shutdown();
+
+        super.onDestroy();
+
+        System.runFinalizersOnExit(true);
+        System.exit(0);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.actionbar_actions, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.action_obt_retrieve_credentials: {
+                AlertDialog.Builder retrieveOwnCredsDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                retrieveOwnCredsDialogBuilder.setTitle("/oic/sec/cred");
+
+                ListView ownCredsListView = new ListView(OnBoardingActivity.this);
+
+                final ArrayList<HashMap<String, String>> ownCredsList = new ArrayList<>();
+                final SimpleAdapter ownCredsAdapter = new SimpleAdapter(OnBoardingActivity.this, ownCredsList, R.layout.creds_multi_line,
+                        new String[]{"line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8"},
+                        new int[]{R.id.line_1, R.id.line_2, R.id.line_3, R.id.line_4, R.id.line_5, R.id.line_6, R.id.line_7, R.id.line_8});
+
+                ownCredsListView.setAdapter(ownCredsAdapter);
+
+                ownCredsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+                    @Override
+                    public void onItemClick(AdapterView<?> parent, View view, int position, final long id) {
+                        Object item = ownCredsAdapter.getItem((int) id);
+                        if ((item instanceof HashMap) && (item != null)) {
+                            HashMap<String, String> lines = (HashMap) item;
+                            String line = lines.get("line1");
+                            if (line != null) {
+                                final String credId = line.substring(4);
+                                Log.d(TAG, "Credential Id = " + credId);
+                                try {
+                                    final int credentialId = Integer.parseInt(credId);
+
+                                    AlertDialog.Builder deleteOwnCredDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    deleteOwnCredDialogBuilder.setTitle(credId);
+                                    deleteOwnCredDialogBuilder.setMessage(getString(R.string.deleteCredential));
+
+                                    deleteOwnCredDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            int status = obt.deleteOwnCredByCredId(credentialId);
+                                            String msg = (status >= 0) ?
+                                                    "Successfully deleted credential " + credId :
+                                                    "Error deleting credential " + credId + ", status = " + status;
+                                            Log.d(TAG, msg);
+                                            Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                            if (status >= 0) {
+                                                ownCredsList.remove((int) id);
+                                                ownCredsAdapter.notifyDataSetChanged();
+                                            }
+                                        }
+                                    });
+
+                                    deleteOwnCredDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                        }
+                                    });
+
+                                    Dialog deleteOwnCredDialog = deleteOwnCredDialogBuilder.create();
+                                    deleteOwnCredDialog.show();
+
+                                } catch (NumberFormatException e) {
+                                    String msg = "Error parsing credential id " + credId;
+                                    Log.d(TAG, msg);
+                                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            }
+                        }
+                    }
+                });
+
+                retrieveOwnCredsDialogBuilder.setView(ownCredsListView);
+
+                OCCreds ocCreds = obt.retrieveOwnCreds();
+                if (ocCreds != null) {
+                    CredentialListHelper clh = new CredentialListHelper(ownCredsList);
+                    clh.buildList(ocCreds);
+                }
+
+                Dialog retrieveOwnCredsDialog = retrieveOwnCredsDialogBuilder.create();
+                retrieveOwnCredsDialog.show();
+                return true;
+            }
+            /*
+            case R.id.action_obt_install_mfg_trustca: {
+                TrustAnchorHelper trustAnchorHelper = new TrustAnchorHelper(OnBoardingActivity.this);
+                trustAnchorHelper.installTrustAnchor(); // calls addMfgTrustAnchor()
+                return true;
+            }*/
+            case R.id.action_obt_reset: {
+                AlertDialog.Builder resetObtDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                resetObtDialogBuilder.setTitle(getString(R.string.resetObt));
+                resetObtDialogBuilder.setMessage(getString(R.string.resetMessage));
+
+                resetObtDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        obtPlatform.reset();
+                        obt.shutdown();
+                        ownedDeviceList.clear();
+                        ownedArrayAdapter.notifyDataSetChanged();
+                        unownedDeviceList.clear();
+                        unownedArrayAdapter.notifyDataSetChanged();
+                        obt = new OcObt();
+                    }
+                });
+
+                resetObtDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                    }
+                });
+
+                Dialog resetObtDialog = resetObtDialogBuilder.create();
+                resetObtDialog.show();
+                return true;
+            }
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+
+    private void createContent() {
+
+        ownedItemClickListener = new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                final OcfDeviceInfo deviceInfo = ownedArrayAdapter.getItem((int) id);
+                if (deviceInfo != null) {
+                    final String uuid = OCUuidUtil.uuidToString(deviceInfo.getUuid());
+                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                    alertDialogBuilder.setTitle(uuid);
+                    alertDialogBuilder.setItems(R.array.ownedDeviceActions, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            switch (which) {
+                                case 0: // Discover resources
+                                    AlertDialog.Builder discoverResourcesDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    discoverResourcesDialogBuilder.setTitle(R.string.discoveredResources);
+
+                                    ListView resourceListView = new ListView(OnBoardingActivity.this);
+                                    ArrayList<String> resourceList = new ArrayList<>();
+                                    final ArrayAdapter<String> resourceAdapter = new ArrayAdapter<>(OnBoardingActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, resourceList);
+                                    resourceListView.setAdapter(resourceAdapter);
+                                    discoverResourcesDialogBuilder.setView(resourceListView);
+
+                                    Dialog discoverResourcesDialog = discoverResourcesDialogBuilder.create();
+                                    discoverResourcesDialog.show();
+
+                                    new Thread(new Runnable() {
+                                        public void run() {
+                                            if (obt.discoverAllResources(OCUuidUtil.stringToUuid(uuid), new ResourceDiscoveryHandler(OnBoardingActivity.this, resourceAdapter)) < 0) {
+                                                final String msg = "Error issuing resource discovery request for uuid " + uuid;
+                                                Log.d(TAG, msg);
+                                                runOnUiThread(new Runnable() {
+                                                    public void run() {
+                                                        Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                    }
+                                                });
+                                            }
+                                        }
+                                    }).start();
+                                    break;
+
+                                case 1: // Provision pair-wise credentials
+                                    AlertDialog.Builder selectDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    selectDialogBuilder.setTitle(R.string.selectDevice);
+                                    final String[] secondDeviceList = new String[ownedDeviceList.size()];
+                                    for (int i = 0; i < secondDeviceList.length; ++i) {
+                                        secondDeviceList[i] = OCUuidUtil.uuidToString(ownedDeviceList.get(i).getUuid());
+                                    }
+                                    selectDialogBuilder.setItems(secondDeviceList, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            final String uuidPair = secondDeviceList[which];
+                                            Log.d(TAG, "Pairing " + uuid + " and " + uuidPair);
+                                            new Thread(new Runnable() {
+                                                public void run() {
+                                                    if (obt.provisionPairwiseCredentials(OCUuidUtil.stringToUuid(uuid), OCUuidUtil.stringToUuid(uuidPair), new ProvisionCredentialsHandler(OnBoardingActivity.this)) < 0) {
+                                                        final String msg = "Failed to provision credentials for " + uuid + " and " + uuidPair;
+                                                        Log.d(TAG, msg);
+                                                        runOnUiThread(new Runnable() {
+                                                            public void run() {
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                            }
+                                                        });
+                                                    }
+                                                }
+                                            }).start();
+                                        }
+                                    });
+
+                                    Dialog provisionPairDialog = selectDialogBuilder.create();
+                                    provisionPairDialog.show();
+                                    break;
+
+                                case 2: // Provision ACE2
+                                    AlertDialog.Builder aceDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    aceDialogBuilder.setTitle(R.string.selectAceSubject);
+                                    final String[] aceSubjectList = new String[ownedDeviceList.size() + 3];
+                                    aceSubjectList[0] = getString(R.string.aceAnonClear);
+                                    aceSubjectList[1] = getString(R.string.aceAuthCrypt);
+                                    aceSubjectList[2] = getString(R.string.aceRole);
+                                    for (int i = 0; i < ownedDeviceList.size(); ++i) {
+                                        aceSubjectList[i + 3] = OCUuidUtil.uuidToString(ownedArrayAdapter.getItem(i).getUuid());
+                                    }
+                                    aceDialogBuilder.setItems(aceSubjectList, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            final String subject = aceSubjectList[which];
+                                            Log.d(TAG, "Ace subject = " + subject);
+                                            final OcSecurityAce ace;
+                                            if (which == 0) {
+                                                ace = new OcAnonSecurityAce();
+                                            } else if (which == 1) {
+                                                ace = new OcAuthSecurityAce();
+                                            } else if (which == 2) {
+                                                ace = null;
+                                                // ace is left null for now and handled below
+                                            } else {
+                                                ace = new OcSubjectSecurityAce(OCUuidUtil.stringToUuid(aceSubjectList[which]));
+                                            }
+
+                                            if (ace != null) {
+                                                AcePropertiesHelper acePropertiesHelper = new AcePropertiesHelper(OnBoardingActivity.this, obt, uuid, new ProvisionAce2Handler(OnBoardingActivity.this));
+                                                acePropertiesHelper.getProperties(ace); // calls provisionAce()
+
+                                            } else if (which == 2) {
+                                                // Need to get role and authority first in order to create the ace
+                                                AlertDialog.Builder roleDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+
+                                                LinearLayout layout = new LinearLayout(OnBoardingActivity.this);
+                                                layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+                                                layout.setOrientation(LinearLayout.VERTICAL);
+
+                                                final EditText input = new EditText(OnBoardingActivity.this);
+                                                layout.addView(input);
+
+                                                String title = getString(R.string.roleDialogTitle);
+                                                roleDialogBuilder.setTitle(title);
+                                                roleDialogBuilder.setMessage(R.string.roleDialogMessage);
+                                                roleDialogBuilder.setView(layout);
+
+                                                roleDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                                    @Override
+                                                    public void onClick(DialogInterface dialog, int which) {
+                                                        String role = input.getText().toString().trim();
+                                                        if (!role.isEmpty()) {
+                                                            if (role.length() > 63) {
+                                                                role = role.substring(0, 63);
+                                                            }
+
+                                                            final String aceRole = role;
+
+                                                            AlertDialog.Builder authorityAlertBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+
+                                                            LinearLayout layout = new LinearLayout(OnBoardingActivity.this);
+                                                            layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+                                                            layout.setOrientation(LinearLayout.VERTICAL);
+
+                                                            final EditText input = new EditText(OnBoardingActivity.this);
+                                                            layout.addView(input);
+
+                                                            String title = getString(R.string.authorityDialogTitle);
+                                                            authorityAlertBuilder.setTitle(title);
+                                                            authorityAlertBuilder.setMessage(R.string.authorityDialogMessage);
+                                                            authorityAlertBuilder.setView(layout);
+
+                                                            authorityAlertBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                                                @Override
+                                                                public void onClick(DialogInterface dialog, int which) {
+                                                                    String authority = input.getText().toString().trim();
+                                                                    if (!authority.isEmpty()) {
+                                                                        if (authority.length() > 63) {
+                                                                            authority = authority.substring(0, 63);
+                                                                        }
+                                                                    } else {
+                                                                        authority = null;
+                                                                    }
+                                                                    final OcSecurityAce ace = new OcRoleSecurityAce(aceRole, authority);
+                                                                    AcePropertiesHelper acePropertiesHelper = new AcePropertiesHelper(OnBoardingActivity.this, obt, uuid, new ProvisionAce2Handler(OnBoardingActivity.this));
+                                                                    acePropertiesHelper.getProperties(ace); // calls provisionAce()
+                                                                }
+                                                            });
+
+                                                            Dialog authorityDialog = authorityAlertBuilder.create();
+                                                            authorityDialog.show();
+                                                        }
+                                                    }
+                                                });
+
+                                                Dialog roleDialog = roleDialogBuilder.create();
+                                                roleDialog.show();
+
+                                            } else {
+                                                final String msg = "Failed to create ace object for device " + uuid;
+                                                Log.d(TAG, msg);
+                                                runOnUiThread(new Runnable() {
+                                                    public void run() {
+                                                        Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                    }
+                                                });
+                                            }
+                                        }
+                                    });
+
+                                    Dialog provisionAceDialog = aceDialogBuilder.create();
+                                    provisionAceDialog.show();
+                                    break;
+
+                                case 3: // Provision auth-crypt RW access to NCRs
+                                    AlertDialog.Builder authCryptRwDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    authCryptRwDialogBuilder.setTitle(uuid);
+                                    authCryptRwDialogBuilder.setMessage(getResources().getStringArray(R.array.ownedDeviceActions)[which]);
+
+                                    authCryptRwDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            new Thread(new Runnable() {
+                                                public void run() {
+                                                    if (obt.provisionAuthWildcardAce(OCUuidUtil.stringToUuid(uuid), new ProvisionAuthWildcardAceHandler(OnBoardingActivity.this)) < 0) {
+                                                        final String msg = "Failed to provision auth-crypt * ACE for uuid " + uuid;
+                                                        Log.d(TAG, msg);
+                                                        runOnUiThread(new Runnable() {
+                                                            public void run() {
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                            }
+                                                        });
+                                                    }
+                                                }
+                                            }).start();
+                                        }
+                                    });
+
+                                    authCryptRwDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                        }
+                                    });
+
+                                    Dialog authCryptRwDialog = authCryptRwDialogBuilder.create();
+                                    authCryptRwDialog.show();
+                                    break;
+
+                                case 4: // Retrieve /oic/sec/cred
+                                    AlertDialog.Builder retrieveCredsDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    retrieveCredsDialogBuilder.setTitle("/oic/sec/cred");
+
+                                    ListView credsListView = new ListView(OnBoardingActivity.this);
+
+                                    final ArrayList<HashMap<String, String>> credsList = new ArrayList<>();
+                                    final SimpleAdapter credsAdapter = new SimpleAdapter(OnBoardingActivity.this, credsList, R.layout.creds_multi_line,
+                                            new String[]{"line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8"},
+                                            new int[]{R.id.line_1, R.id.line_2, R.id.line_3, R.id.line_4, R.id.line_5, R.id.line_6, R.id.line_7, R.id.line_8});
+
+                                    credsListView.setAdapter(credsAdapter);
+
+                                    credsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+                                        @Override
+                                        public void onItemClick(AdapterView<?> parent, View view, int position, final long id) {
+                                            Object item = credsAdapter.getItem((int) id);
+                                            if ((item instanceof HashMap) && (item != null)) {
+                                                HashMap<String, String> lines = (HashMap) item;
+                                                String line = lines.get("line1");
+                                                if (line != null) {
+                                                    final String credId = line.substring(4);
+                                                    Log.d(TAG, "Credential Id = " + credId);
+                                                    try {
+                                                        final int credentialId = Integer.parseInt(credId);
+
+                                                        AlertDialog.Builder deleteCredDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                                        deleteCredDialogBuilder.setTitle(credId);
+                                                        deleteCredDialogBuilder.setMessage(getString(R.string.deleteCredential));
+
+                                                        deleteCredDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                                            @Override
+                                                            public void onClick(DialogInterface dialog, int which) {
+                                                                int status = obt.deleteCredByCredId(OCUuidUtil.stringToUuid(uuid), credentialId, new DeleteCredentialHandler(OnBoardingActivity.this));
+                                                                String msg = (status >= 0) ?
+                                                                        "Successfully deleted credential " + credId :
+                                                                        "Error deleting credential " + credId + ", status = " + status;
+                                                                Log.d(TAG, msg);
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                                if (status >= 0) {
+                                                                    credsList.remove((int) id);
+                                                                    credsAdapter.notifyDataSetChanged();
+                                                                }
+                                                            }
+                                                        });
+
+                                                        deleteCredDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                                            @Override
+                                                            public void onClick(DialogInterface dialog, int which) {
+                                                            }
+                                                        });
+
+                                                        Dialog deleteCredDialog = deleteCredDialogBuilder.create();
+                                                        deleteCredDialog.show();
+
+                                                    } catch (NumberFormatException e) {
+                                                        String msg = "Error parsing credential id " + credId;
+                                                        Log.d(TAG, msg);
+                                                        Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    });
+
+                                    retrieveCredsDialogBuilder.setView(credsListView);
+
+                                    Dialog retrieveCredsDialog = retrieveCredsDialogBuilder.create();
+                                    retrieveCredsDialog.show();
+
+                                    new Thread(new Runnable() {
+                                        public void run() {
+                                            if (obt.retrieveCreds(OCUuidUtil.stringToUuid(uuid), new RetrieveCredentialHandler(OnBoardingActivity.this, credsAdapter, credsList)) < 0) {
+                                                final String msg = "Error issuing request to retrieve /oic/sec/cred for uuid " + uuid;
+                                                Log.d(TAG, msg);
+                                                runOnUiThread(new Runnable() {
+                                                    public void run() {
+                                                        Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                    }
+                                                });
+                                            }
+                                        }
+                                    }).start();
+                                    break;
+
+                                case 5: // Retrieve /oic/sec/acl2
+                                    AlertDialog.Builder retrieveAclDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    retrieveAclDialogBuilder.setTitle("/oic/sec/acl2");
+
+                                    ListView aclListView = new ListView(OnBoardingActivity.this);
+
+                                    final ArrayList<HashMap<String, String>> aclList = new ArrayList<>();
+                                    final SimpleAdapter aclAdapter = new SimpleAdapter(OnBoardingActivity.this, aclList, R.layout.acl_multi_line,
+                                            new String[]{"line1", "line2", "line3", "line4"},
+                                            new int[]{R.id.line_1, R.id.line_2, R.id.line_3, R.id.line_4});
+
+                                    aclListView.setAdapter(aclAdapter);
+
+                                    aclListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+                                        @Override
+                                        public void onItemClick(AdapterView<?> parent, View view, int position, final long id) {
+                                            Object item = aclAdapter.getItem((int) id);
+                                            if ((item instanceof HashMap) && (item != null)) {
+                                                HashMap<String, String> lines = (HashMap) item;
+                                                String line = lines.get("line1");
+                                                if (line != null) {
+                                                    final String aceIdString = line.substring(4);
+                                                    Log.d(TAG, "Ace Id = " + aceIdString);
+                                                    try {
+                                                        final int aceId = Integer.parseInt(aceIdString);
+
+                                                        AlertDialog.Builder deleteAceDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                                        deleteAceDialogBuilder.setTitle(aceIdString);
+                                                        deleteAceDialogBuilder.setMessage(getString(R.string.deleteAce));
+
+                                                        deleteAceDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                                            @Override
+                                                            public void onClick(DialogInterface dialog, int which) {
+                                                                int status = obt.deleteAceByAceId(OCUuidUtil.stringToUuid(uuid), aceId, new DeleteAceHandler(OnBoardingActivity.this));
+                                                                String msg = (status >= 0) ?
+                                                                        "Successfully deleted ace " + aceId :
+                                                                        "Error deleting ace " + aceId + ", status = " + status;
+                                                                Log.d(TAG, msg);
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                                if (status >= 0) {
+                                                                    aclList.remove((int) id);
+                                                                    aclAdapter.notifyDataSetChanged();
+                                                                }
+                                                            }
+                                                        });
+
+                                                        deleteAceDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                                            @Override
+                                                            public void onClick(DialogInterface dialog, int which) {
+                                                            }
+                                                        });
+
+                                                        Dialog deleteAceDialog = deleteAceDialogBuilder.create();
+                                                        deleteAceDialog.show();
+
+                                                    } catch (NumberFormatException e) {
+                                                        String msg = "Error parsing ace id " + aceIdString;
+                                                        Log.d(TAG, msg);
+                                                        Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    });
+
+                                    retrieveAclDialogBuilder.setView(aclListView);
+
+                                    Dialog retrieveAclDialog = retrieveAclDialogBuilder.create();
+                                    retrieveAclDialog.show();
+
+                                    new Thread(new Runnable() {
+                                        public void run() {
+                                            if (obt.retrieveAcl(OCUuidUtil.stringToUuid(uuid), new RetrieveAcl2Handler(OnBoardingActivity.this, aclAdapter, aclList)) < 0) {
+                                                final String msg = "Error issuing request to retrieve /oic/sec/acl2 for uuid " + uuid;
+                                                Log.d(TAG, msg);
+                                                runOnUiThread(new Runnable() {
+                                                    public void run() {
+                                                        Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                    }
+                                                });
+                                            }
+                                        }
+                                    }).start();
+                                    break;
+
+                                case 6: // Provision role RW access to NCRs
+                                    AlertDialog.Builder roleDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+
+                                    LinearLayout layout = new LinearLayout(OnBoardingActivity.this);
+                                    layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+                                    layout.setOrientation(LinearLayout.VERTICAL);
+
+                                    final EditText input = new EditText(OnBoardingActivity.this);
+                                    layout.addView(input);
+
+                                    String title = getString(R.string.roleDialogTitle);
+                                    roleDialogBuilder.setTitle(title);
+                                    roleDialogBuilder.setMessage(R.string.roleDialogMessage);
+                                    roleDialogBuilder.setView(layout);
+
+                                    roleDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            String role = input.getText().toString().trim();
+                                            if (!role.isEmpty()) {
+                                                if (role.length() > 63) {
+                                                    role = role.substring(0, 63);
+                                                }
+
+                                                final String aceRole = role;
+
+                                                AlertDialog.Builder authorityAlertBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+
+                                                LinearLayout layout = new LinearLayout(OnBoardingActivity.this);
+                                                layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+                                                layout.setOrientation(LinearLayout.VERTICAL);
+
+                                                final EditText input = new EditText(OnBoardingActivity.this);
+                                                layout.addView(input);
+
+                                                String title = getString(R.string.authorityDialogTitle);
+                                                authorityAlertBuilder.setTitle(title);
+                                                authorityAlertBuilder.setMessage(R.string.authorityDialogMessage);
+                                                authorityAlertBuilder.setView(layout);
+
+                                                authorityAlertBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                                    @Override
+                                                    public void onClick(DialogInterface dialog, int which) {
+                                                        String authority = input.getText().toString().trim();
+                                                        if (!authority.isEmpty()) {
+                                                            if (authority.length() > 63) {
+                                                                authority = authority.substring(0, 63);
+                                                            }
+                                                        } else {
+                                                            authority = null;
+                                                        }
+
+                                                        final String aceAuthority = authority;
+
+                                                        new Thread(new Runnable() {
+                                                            public void run() {
+                                                                if (obt.provisionRoleWildcardAce(OCUuidUtil.stringToUuid(uuid), aceRole, aceAuthority, new ProvisionRoleWildcardAceHandler(OnBoardingActivity.this)) < 0) {
+                                                                    final String msg = "Failed to provision role * ACE for uuid " + uuid;
+                                                                    Log.d(TAG, msg);
+                                                                    runOnUiThread(new Runnable() {
+                                                                        public void run() {
+                                                                            Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                                        }
+                                                                    });
+                                                                }
+                                                            }
+                                                        }).start();
+                                                    }
+                                                });
+
+                                                Dialog authorityDialog = authorityAlertBuilder.create();
+                                                authorityDialog.show();
+                                            }
+                                        }
+                                    });
+
+                                    Dialog roleDialog = roleDialogBuilder.create();
+                                    roleDialog.show();
+                                    break;
+
+                                case 7: // Provision identity certificate
+                                    AlertDialog.Builder idCertDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    idCertDialogBuilder.setTitle(uuid);
+                                    idCertDialogBuilder.setMessage(getResources().getStringArray(R.array.ownedDeviceActions)[which]);
+
+                                    idCertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            new Thread(new Runnable() {
+                                                public void run() {
+                                                    if (obt.provisionIdentityCertificate(OCUuidUtil.stringToUuid(uuid), new ProvisionIdCertificateHandler(OnBoardingActivity.this)) < 0) {
+                                                        final String msg = "Failed to provision identity certificate for uuid " + uuid;
+                                                        Log.d(TAG, msg);
+                                                        runOnUiThread(new Runnable() {
+                                                            public void run() {
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                            }
+                                                        });
+                                                    }
+                                                }
+                                            }).start();
+                                        }
+                                    });
+
+                                    idCertDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                        }
+                                    });
+
+                                    Dialog idCertDialog = idCertDialogBuilder.create();
+                                    idCertDialog.show();
+                                    break;
+
+                                case 8: // Provision role certificate
+                                    RoleCertificateHelper roleCertificateHelper = new RoleCertificateHelper(OnBoardingActivity.this, obt, uuid, new ProvisionRoleCertificateHandler(OnBoardingActivity.this));
+                                    roleCertificateHelper.getRoles(null); // calls provisionRoleCertificate()
+                                    break;
+
+                                case 9: // Reset Device
+                                    AlertDialog.Builder resetDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    resetDialogBuilder.setTitle(uuid);
+                                    resetDialogBuilder.setMessage(getResources().getStringArray(R.array.ownedDeviceActions)[which]);
+
+                                    resetDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            new Thread(new Runnable() {
+                                                public void run() {
+                                                    if (obt.deviceHardReset(OCUuidUtil.stringToUuid(uuid), new DeviceResetHandler(OnBoardingActivity.this)) < 0) {
+                                                        final String msg = "Failed to perform device reset for uuid " + uuid;
+                                                        Log.d(TAG, msg);
+                                                        runOnUiThread(new Runnable() {
+                                                            public void run() {
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                            }
+                                                        });
+                                                    } else {
+                                                        removeOwnedDevice(deviceInfo);
+                                                    }
+                                                }
+                                            }).start();
+                                        }
+                                    });
+
+                                    resetDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                        }
+                                    });
+
+                                    Dialog resetDeviceDialog = resetDialogBuilder.create();
+                                    resetDeviceDialog.show();
+                                    break;
+
+                                default:
+                                    break;
+                            }
+                        }
+                    });
+
+                    Dialog ownedDeviceDialog = alertDialogBuilder.create();
+                    ownedDeviceDialog.show();
+
+                } else {
+                    Log.w(TAG, "Uuid not found in list");
+                }
+            }
+        };
+
+        unownedItemClickListener = new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                final OcfDeviceInfo deviceInfo = unownedArrayAdapter.getItem((int) id);
+                if (deviceInfo != null) {
+                    final String uuid = OCUuidUtil.uuidToString(deviceInfo.getUuid());
+                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                    alertDialogBuilder.setTitle(uuid);
+                    alertDialogBuilder.setItems(R.array.unownedDeviceActions, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            switch (which) {
+                                case 0: // Discover resources
+                                    AlertDialog.Builder discoverResourcesDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    discoverResourcesDialogBuilder.setTitle(R.string.discoveredResources);
+
+                                    ListView resourceListView = new ListView(OnBoardingActivity.this);
+                                    ArrayList<String> resourceList = new ArrayList<>();
+                                    final ArrayAdapter<String> resourceAdapter = new ArrayAdapter<>(OnBoardingActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, resourceList);
+                                    resourceListView.setAdapter(resourceAdapter);
+                                    discoverResourcesDialogBuilder.setView(resourceListView);
+
+                                    Dialog discoverResourcesDialog = discoverResourcesDialogBuilder.create();
+                                    discoverResourcesDialog.show();
+
+                                    new Thread(new Runnable() {
+                                        public void run() {
+                                            if (obt.discoverAllResources(OCUuidUtil.stringToUuid(uuid), new ResourceDiscoveryHandler(OnBoardingActivity.this, resourceAdapter)) < 0) {
+                                                final String msg = "Error issuing resource discovery request for uuid " + uuid;
+                                                Log.d(TAG, msg);
+                                                runOnUiThread(new Runnable() {
+                                                    public void run() {
+                                                        Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                    }
+                                                });
+                                            }
+                                        }
+                                    }).start();
+                                    break;
+
+                                case 1: // Just Works OTM
+                                    AlertDialog.Builder justWorksOtmDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    justWorksOtmDialogBuilder.setTitle(uuid);
+                                    justWorksOtmDialogBuilder.setMessage(getResources().getStringArray(R.array.unownedDeviceActions)[which]);
+
+                                    justWorksOtmDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            new Thread(new Runnable() {
+                                                public void run() {
+                                                    if (obt.performJustWorksOtm(OCUuidUtil.stringToUuid(uuid), new JustWorksHandler(OnBoardingActivity.this)) < 0) {
+                                                        final String msg = "Failed to perform ownership transfer for uuid " + uuid;
+                                                        Log.d(TAG, msg);
+                                                        runOnUiThread(new Runnable() {
+                                                            public void run() {
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                            }
+                                                        });
+                                                    } else {
+                                                        removeUnownedDevice(deviceInfo);
+                                                    }
+                                                }
+                                            }).start();
+                                        }
+                                    });
+
+                                    justWorksOtmDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                        }
+                                    });
+
+                                    Dialog justWorksOtmDialog = justWorksOtmDialogBuilder.create();
+                                    justWorksOtmDialog.show();
+                                    break;
+
+                                case 2: // Generate Random Pin
+                                    AlertDialog.Builder generateRandomPinDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    generateRandomPinDialogBuilder.setTitle(uuid);
+                                    generateRandomPinDialogBuilder.setMessage(getResources().getStringArray(R.array.unownedDeviceActions)[which]);
+
+                                    generateRandomPinDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            new Thread(new Runnable() {
+                                                public void run() {
+                                                    if (obt.requestRandomPin(OCUuidUtil.stringToUuid(uuid), new GenerateRandomPinHandler(OnBoardingActivity.this)) < 0) {
+                                                        final String msg = "Failed to generate random pin for uuid " + uuid;
+                                                        Log.d(TAG, msg);
+                                                        runOnUiThread(new Runnable() {
+                                                            public void run() {
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                            }
+                                                        });
+                                                    }
+                                                }
+                                            }).start();
+                                        }
+                                    });
+
+                                    generateRandomPinDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                        }
+                                    });
+
+                                    Dialog generateRandomPinDialog = generateRandomPinDialogBuilder.create();
+                                    generateRandomPinDialog.show();
+                                    break;
+
+                                case 3: // Random Pin OTM
+                                    LinearLayout layout = new LinearLayout(OnBoardingActivity.this);
+                                    layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+                                    layout.setOrientation(LinearLayout.VERTICAL);
+
+                                    final EditText input = new EditText(OnBoardingActivity.this);
+                                    layout.addView(input);
+
+                                    AlertDialog.Builder randomPinOtmDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    randomPinOtmDialogBuilder.setTitle(uuid);
+                                    randomPinOtmDialogBuilder.setMessage(R.string.enterPin);
+                                    randomPinOtmDialogBuilder.setView(layout);
+
+                                    randomPinOtmDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            new Thread(new Runnable() {
+                                                public void run() {
+                                                    String pin = input.getText().toString().trim();
+                                                    if (pin.length() > 24) {
+                                                        pin = pin.substring(0, 24);
+                                                    }
+                                                    Log.d(TAG, "PIN = " + pin);
+                                                    if (obt.performRandomPinOtm(OCUuidUtil.stringToUuid(uuid), pin, new OtmRandomPinHandler(OnBoardingActivity.this)) < 0) {
+                                                        final String msg = "Failed to perform ownership transfer for uuid " + uuid;
+                                                        Log.d(TAG, msg);
+                                                        runOnUiThread(new Runnable() {
+                                                            public void run() {
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                            }
+                                                        });
+                                                    } else {
+                                                        removeUnownedDevice(deviceInfo);
+                                                    }
+                                                }
+                                            }).start();
+                                        }
+                                    });
+
+                                    randomPinOtmDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                        }
+                                    });
+
+                                    Dialog randomPinOtmDialog = randomPinOtmDialogBuilder.create();
+                                    randomPinOtmDialog.show();
+                                    break;
+
+                                case 4: // Manufacturer Certificate OTM
+                                    AlertDialog.Builder mfgCertOtmDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+                                    mfgCertOtmDialogBuilder.setTitle(uuid);
+                                    mfgCertOtmDialogBuilder.setMessage(getResources().getStringArray(R.array.unownedDeviceActions)[which]);
+
+                                    mfgCertOtmDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                            new Thread(new Runnable() {
+                                                public void run() {
+                                                    if (obt.performCertOtm(OCUuidUtil.stringToUuid(uuid), new OtmCertificationHandler(OnBoardingActivity.this)) < 0) {
+                                                        final String msg = "Failed to perform ownership transfer for uuid " + uuid;
+                                                        Log.d(TAG, msg);
+                                                        runOnUiThread(new Runnable() {
+                                                            public void run() {
+                                                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                                            }
+                                                        });
+                                                    } else {
+                                                        removeUnownedDevice(deviceInfo);
+                                                    }
+                                                }
+                                            }).start();
+                                        }
+                                    });
+
+                                    mfgCertOtmDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                                        @Override
+                                        public void onClick(DialogInterface dialog, int which) {
+                                        }
+                                    });
+
+                                    Dialog mfgCertOtmDialog = mfgCertOtmDialogBuilder.create();
+                                    mfgCertOtmDialog.show();
+                                    break;
+
+                                default:
+                                    break;
+                            }
+                        }
+                    });
+
+                    Dialog unownedDeviceDialog = alertDialogBuilder.create();
+                    unownedDeviceDialog.show();
+
+                } else {
+                    Log.w(TAG, "Uuid not found in list");
+                }
+            }
+        };
+
+        allRadioGroup = (RadioGroup) findViewById(R.id.radio_group);
+        realmRadioGroup = (RadioGroup) findViewById(R.id.realm_radio_group);
+        siteRadioGroup = (RadioGroup) findViewById(R.id.site_radio_group);
+
+        allRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(RadioGroup group, int checkedId) {
+                if ((checkedId != -1) && isRadioChecking) {
+                    isRadioChecking = false;
+                    realmRadioGroup.clearCheck();
+                    siteRadioGroup.clearCheck();
+                }
+                isRadioChecking = true;
+            }
+        });
+
+        realmRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(RadioGroup group, int checkedId) {
+                if ((checkedId != -1) && isRadioChecking) {
+                    isRadioChecking = false;
+                    allRadioGroup.clearCheck();
+                    siteRadioGroup.clearCheck();
+                }
+                isRadioChecking = true;
+            }
+        });
+
+        siteRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(RadioGroup group, int checkedId) {
+                if ((checkedId != -1) && isRadioChecking) {
+                    isRadioChecking = false;
+                    allRadioGroup.clearCheck();
+                    realmRadioGroup.clearCheck();
+                }
+                isRadioChecking = true;
+            }
+        });
+
+        ownedRadioButton = (RadioButton) findViewById(R.id.owned_radio_button);
+        ownedRadioButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ownedArrayAdapter.setNotifyOnChange(false);
+                ownedArrayAdapter.clear();
+                ownedArrayAdapter.setNotifyOnChange(true);
+                listView.setAdapter(ownedArrayAdapter);
+                listView.setOnItemClickListener(ownedItemClickListener);
+
+                new Thread(new Runnable() {
+                    public void run() {
+                        if (obt.discoverOwnedDevices(new OwnedDeviceHandler(OnBoardingActivity.this)) < 0) {
+                            final String msg = "Failed to discover owned devices";
+                            Log.d(TAG, msg);
+                            runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }).start();
+
+                refreshButton.setEnabled(true);
+            }
+        });
+
+        ownedRealmRadioButton = (RadioButton) findViewById(R.id.owned_realm_radio_button);
+        ownedRealmRadioButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ownedArrayAdapter.setNotifyOnChange(false);
+                ownedArrayAdapter.clear();
+                ownedArrayAdapter.setNotifyOnChange(true);
+                listView.setAdapter(ownedArrayAdapter);
+                listView.setOnItemClickListener(ownedItemClickListener);
+
+                new Thread(new Runnable() {
+                    public void run() {
+                        if (obt.discoverOwnedDevicesRealmLocalIPv6(new OwnedDeviceHandler(OnBoardingActivity.this)) < 0) {
+                            final String msg = "Failed to discover owned realm local devices";
+                            Log.d(TAG, msg);
+                            runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }).start();
+
+                refreshButton.setEnabled(true);
+            }
+        });
+
+        ownedSiteRadioButton = (RadioButton) findViewById(R.id.owned_site_radio_button);
+        ownedSiteRadioButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                ownedArrayAdapter.setNotifyOnChange(false);
+                ownedArrayAdapter.clear();
+                ownedArrayAdapter.setNotifyOnChange(true);
+                listView.setAdapter(ownedArrayAdapter);
+                listView.setOnItemClickListener(ownedItemClickListener);
+
+                new Thread(new Runnable() {
+                    public void run() {
+                        if (obt.discoverOwnedDevicesSiteLocalIPv6(new OwnedDeviceHandler(OnBoardingActivity.this)) < 0) {
+                            final String msg = "Failed to discover owned site local devices";
+                            Log.d(TAG, msg);
+                            runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }).start();
+
+                refreshButton.setEnabled(true);
+            }
+        });
+
+        unownedRadioButton = (RadioButton) findViewById(R.id.unowned_radio_button);
+        unownedRadioButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                unownedArrayAdapter.setNotifyOnChange(false);
+                unownedArrayAdapter.clear();
+                unownedArrayAdapter.setNotifyOnChange(true);
+                listView.setAdapter(unownedArrayAdapter);
+                listView.setOnItemClickListener(unownedItemClickListener);
+
+                new Thread(new Runnable() {
+                    public void run() {
+                        if (obt.discoverUnownedDevices(new UnownedDeviceHandler(OnBoardingActivity.this)) < 0) {
+                            final String msg = "Failed to discover unowned devices";
+                            Log.d(TAG, msg);
+                            runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }).start();
+
+                refreshButton.setEnabled(true);
+            }
+        });
+
+        unownedRealmRadioButton = (RadioButton) findViewById(R.id.unowned_realm_radio_button);
+        unownedRealmRadioButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                unownedArrayAdapter.setNotifyOnChange(false);
+                unownedArrayAdapter.clear();
+                unownedArrayAdapter.setNotifyOnChange(true);
+                listView.setAdapter(unownedArrayAdapter);
+                listView.setOnItemClickListener(unownedItemClickListener);
+
+                new Thread(new Runnable() {
+                    public void run() {
+                        if (obt.discoverUnownedDevicesRealmLocalIPv6(new UnownedDeviceHandler(OnBoardingActivity.this)) < 0) {
+                            final String msg = "Failed to discover unowned realm local devices";
+                            Log.d(TAG, msg);
+                            runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }).start();
+
+                refreshButton.setEnabled(true);
+            }
+        });
+
+        unownedSiteRadioButton = (RadioButton) findViewById(R.id.unowned_site_radio_button);
+        unownedSiteRadioButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                unownedArrayAdapter.setNotifyOnChange(false);
+                unownedArrayAdapter.clear();
+                unownedArrayAdapter.setNotifyOnChange(true);
+                listView.setAdapter(unownedArrayAdapter);
+                listView.setOnItemClickListener(unownedItemClickListener);
+
+                new Thread(new Runnable() {
+                    public void run() {
+                        if (obt.discoverUnownedDevicesSiteLocalIPv6(new UnownedDeviceHandler(OnBoardingActivity.this)) < 0) {
+                            final String msg = "Failed to discover unowned site local devices";
+                            Log.d(TAG, msg);
+                            runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }).start();
+
+                refreshButton.setEnabled(true);
+            }
+        });
+
+        refreshButton = (Button) findViewById(R.id.refresh_button);
+        refreshButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (ownedRadioButton.isChecked()) {
+                    ownedArrayAdapter.setNotifyOnChange(false);
+                    ownedArrayAdapter.clear();
+                    ownedArrayAdapter.setNotifyOnChange(true);
+
+                    ownedRadioButton.callOnClick();
+
+                } else if (ownedRealmRadioButton.isChecked()) {
+                    ownedArrayAdapter.setNotifyOnChange(false);
+                    ownedArrayAdapter.clear();
+                    ownedArrayAdapter.setNotifyOnChange(true);
+
+                    ownedRealmRadioButton.callOnClick();
+
+                } else if (ownedSiteRadioButton.isChecked()) {
+                    ownedArrayAdapter.setNotifyOnChange(false);
+                    ownedArrayAdapter.clear();
+                    ownedArrayAdapter.setNotifyOnChange(true);
+
+                    ownedSiteRadioButton.callOnClick();
+
+                } else if (unownedRadioButton.isChecked()) {
+                    unownedArrayAdapter.setNotifyOnChange(false);
+                    unownedArrayAdapter.clear();
+                    unownedArrayAdapter.setNotifyOnChange(true);
+
+                    unownedRadioButton.callOnClick();
+
+                } else if (unownedRealmRadioButton.isChecked()) {
+                    unownedArrayAdapter.setNotifyOnChange(false);
+                    unownedArrayAdapter.clear();
+                    unownedArrayAdapter.setNotifyOnChange(true);
+
+                    unownedRealmRadioButton.callOnClick();
+
+                } else if (unownedSiteRadioButton.isChecked()) {
+                    unownedArrayAdapter.setNotifyOnChange(false);
+                    unownedArrayAdapter.clear();
+                    unownedArrayAdapter.setNotifyOnChange(true);
+
+                    unownedSiteRadioButton.callOnClick();
+                }
+            }
+        });
+
+        listView = (ListView) findViewById(R.id.list_view);
+
+        ownedArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_2, android.R.id.text1, ownedDeviceList) {
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                View view = super.getView(position, convertView, parent);
+                TextView text1 = (TextView) view.findViewById(android.R.id.text1);
+                TextView text2 = (TextView) view.findViewById(android.R.id.text2);
+
+                OcfDeviceInfo deviceInfo = ownedArrayAdapter.getItem(position);
+                if (deviceInfo != null) {
+                    text1.setText(OCUuidUtil.uuidToString(ownedDeviceList.get(position).getUuid()));
+                    text2.setText("\t" + ownedDeviceList.get(position).getName());
+                }
+                return view;
+            }
+        };
+        unownedArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_2, android.R.id.text1, unownedDeviceList) {
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                View view = super.getView(position, convertView, parent);
+                TextView text1 = (TextView) view.findViewById(android.R.id.text1);
+                TextView text2 = (TextView) view.findViewById(android.R.id.text2);
+
+                OcfDeviceInfo deviceInfo = unownedArrayAdapter.getItem(position);
+                if (deviceInfo != null) {
+                    text1.setText(OCUuidUtil.uuidToString(unownedDeviceList.get(position).getUuid()));
+                    text2.setText("\t" + unownedDeviceList.get(position).getName());
+                }
+                return view;
+            }
+        };
+
+        //TODO : batch function buttons
+        onboardingButton = (Button) findViewById(R.id.onboarding_all);
+        onboardingButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                // onboarding and provision ACL
+                onboardingAllUnownedDevices();
+            }
+        });
+
+        pairwisingButton = (Button) findViewById(R.id.pairwising_all);
+        pairwisingButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                // pairwising bridge and servers for virtual client
+                // pairwisingWithAllOwnedDevices();
+                pairwisingSelectDeviceWithOtherOwnedDevices();
+
+            }
+        });
+
+        offboardingButton = (Button) findViewById(R.id.offboarding_all);
+        offboardingButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                // pairwising bridge and servers for virtual client
+                offboardingAllOwnedDevices();
+
+            }
+        });
+    }
+
+    public void addOwnedDevice(final OcfDeviceInfo deviceInfo) {
+
+        runOnUiThread(new Runnable() {
+            public void run() {
+
+                synchronized (arrayAdapterSync) {
+                    ownedArrayAdapter.setNotifyOnChange(false);
+                    ownedArrayAdapter.add(deviceInfo);
+                    ownedArrayAdapter.setNotifyOnChange(true);
+                }
+                ownedArrayAdapter.notifyDataSetChanged();
+            }
+        });
+    }
+
+    public void addUnownedDevice(final OcfDeviceInfo deviceInfo) {
+
+
+        runOnUiThread(new Runnable() {
+            public void run() {
+                synchronized (arrayAdapterSync) {
+                    unownedArrayAdapter.setNotifyOnChange(false);
+                    unownedArrayAdapter.add(deviceInfo);
+                    unownedArrayAdapter.setNotifyOnChange(true);
+                }
+                unownedArrayAdapter.notifyDataSetChanged();
+            }
+        });
+    }
+
+    public void removeOwnedDevice(final OcfDeviceInfo deviceInfo) {
+
+        runOnUiThread(new Runnable() {
+            public void run() {
+
+                synchronized (arrayAdapterSync) {
+                    ownedArrayAdapter.setNotifyOnChange(false);
+                    ownedArrayAdapter.remove(deviceInfo);
+                    ownedArrayAdapter.setNotifyOnChange(true);
+                }
+                ownedArrayAdapter.notifyDataSetChanged();
+            }
+        });
+    }
+
+    public void removeUnownedDevice(final OcfDeviceInfo deviceInfo) {
+
+        runOnUiThread(new Runnable() {
+            public void run() {
+                synchronized (arrayAdapterSync) {
+                    unownedArrayAdapter.setNotifyOnChange(false);
+                    unownedArrayAdapter.remove(deviceInfo);
+                    unownedArrayAdapter.setNotifyOnChange(true);
+                }
+                unownedArrayAdapter.notifyDataSetChanged();
+            }
+        });
+    }
+
+    public OcObt getObt() {
+        return obt;
+    }
+
+    public void setObt(OcObt obt) {
+        this.obt = obt;
+    }
+
+    public OcPlatform getObtPlatform() {
+        return obtPlatform;
+    }
+
+    public ArrayList<OcfDeviceInfo> getOwnedDeviceList() {
+        return ownedDeviceList ;
+    }
+
+    public ArrayList<OcfDeviceInfo> getUnownedDeviceList() {
+        return unownedDeviceList ;
+    }
+
+    /* Automatically onboarding all unowned device with Justworks OTM
+     * and then provision Auth-crypt wildcard acl for NCRs after onboarding.
+     * */
+    public void onboardingAllUnownedDevices() {
+
+        if(unownedDeviceList.size() == 0) {
+            final String msg = "No unowned devices to perform ownership transfer. ";
+            Log.d(TAG, msg);
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                }
+            });
+            return ;
+        }
+
+        final ArrayList<OcfDeviceInfo> devicelist = (ArrayList<OcfDeviceInfo>) unownedDeviceList.clone();
+        for (int index = 0; index < devicelist.size(); index++) {
+            final OcfDeviceInfo deviceInfo = devicelist.get(index);
+            final OCUuid uuid = deviceInfo.getUuid();
+
+            mHandler.postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    if (obt.performJustWorksOtm(uuid, new JustWorksAndAuthWildcardAceHandler(OnBoardingActivity.this)) < 0) {
+                        final String msg = "Failed to perform ownership transfer for uuid " + OCUuidUtil.uuidToString(uuid);
+                        Log.d(TAG, msg);
+                        runOnUiThread(new Runnable() {
+                            public void run() {
+                                Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                            }
+                        });
+                    } else {
+                        removeUnownedDevice(deviceInfo);
+                    }
+                }
+            }, 3000 * index);
+        }
+
+    }
+
+    /*  All device pairwising for all metrics
+     *  It means all clients and servers are accessable to each other
+     */
+    public void pairwisingWithAllOwnedDevices() {
+
+        ArrayList<OcfDeviceInfo> owned_devices = (ArrayList<OcfDeviceInfo>) ownedDeviceList.clone();
+        for(int iLoop = 0; iLoop < owned_devices.size(); iLoop++) {
+            final OCUuid sel_uuid = owned_devices.get(iLoop).getUuid();
+            for(int jLoop = iLoop + 1; jLoop < owned_devices.size(); jLoop++) {
+                final OCUuid target_uuid = owned_devices.get(jLoop).getUuid();
+                mHandler.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (obt.provisionPairwiseCredentials(sel_uuid, target_uuid, new ProvisionCredentialsHandler(OnBoardingActivity.this)) < 0) {
+                            final String msg = "Failed to provision pair-wise credentials for " + OCUuidUtil.uuidToString(sel_uuid) + " and " + OCUuidUtil.uuidToString(target_uuid);
+                            Log.d(TAG, msg);
+                            runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }, 3000 * iLoop * jLoop);
+            }
+        }
+    }
+
+    /*  All device pairwising with selected one devics
+     *  It means one client and the other servers are accessable
+     */
+    public void pairwisingSelectDeviceWithOtherOwnedDevices() {
+
+        AlertDialog.Builder selectDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+        selectDialogBuilder.setTitle(R.string.selectPairingClient);
+
+        final ArrayList<OcfDeviceInfo> owned_devices = (ArrayList<OcfDeviceInfo>)ownedDeviceList.clone();
+        final String[] secondDeviceList = new String[owned_devices.size()];
+        for (int i = 0; i < secondDeviceList.length; ++i) {
+            OcfDeviceInfo info = owned_devices.get(i);
+            secondDeviceList[i] = OCUuidUtil.uuidToString(info.getUuid()) + "\n" + info.getName();
+        }
+        selectDialogBuilder.setItems(secondDeviceList, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                String str_uuid = secondDeviceList[which].split("\n")[0];
+                final OCUuid sel_uuid = OCUuidUtil.stringToUuid(str_uuid);
+                Log.d(TAG, "pair-wise " + OCUuidUtil.uuidToString(sel_uuid) + " and the others will start" );
+
+                new Thread(new Runnable() {
+                    public void run() {
+
+                        for(OcfDeviceInfo deviceInfo : owned_devices) {
+                            if(!OCUuidUtil.isEqual(sel_uuid, deviceInfo.getUuid())) {
+                                final OCUuid uuidPair = deviceInfo.getUuid();
+                                Log.d(TAG, "Pairing " + OCUuidUtil.uuidToString(sel_uuid) + " and " + OCUuidUtil.uuidToString(uuidPair));
+
+                                if (obt.provisionPairwiseCredentials(sel_uuid, uuidPair, new ProvisionCredentialsHandler(OnBoardingActivity.this)) < 0) {
+                                    final String msg = "Failed to provision pair-wise credentials for " + OCUuidUtil.uuidToString(sel_uuid) + " and " + OCUuidUtil.uuidToString(uuidPair);
+                                    Log.d(TAG, msg);
+                                    runOnUiThread(new Runnable() {
+                                        public void run() {
+                                            Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                        }
+                                    });
+                                }
+
+                                try {
+                                    Thread.sleep(1500);
+                                } catch (InterruptedException e) {
+                                    e.printStackTrace();
+                                }
+                            }
+                        }
+                    }
+                }).start();
+            }
+        });
+        selectDialogBuilder.setNegativeButton(getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                dialog.dismiss();
+            }
+        });
+
+        Dialog provisionPairDialog = selectDialogBuilder.create();
+        provisionPairDialog.show();
+
+    }
+
+    /*  All owned device are off-boarding (hardreset)
+     *  It means all owned device will be initialized.
+     */
+    public void offboardingAllOwnedDevices() {
+
+        AlertDialog.Builder resetDialogBuilder = new AlertDialog.Builder(OnBoardingActivity.this);
+        resetDialogBuilder.setTitle(R.string.offboarding_ownership_transfer);
+        resetDialogBuilder.setMessage(R.string.offboardingMessage);
+
+        resetDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+
+                for(int iLoop = 0; iLoop < ownedDeviceList.size(); iLoop++) {
+
+                    final OcfDeviceInfo deviceInfo = ownedDeviceList.get(iLoop);
+                    final OCUuid uuid = deviceInfo.getUuid();
+
+                    mHandler.postDelayed(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (obt.deviceHardReset(uuid, new DeviceResetHandler(OnBoardingActivity.this)) < 0) {
+                                final String msg = "Failed to perform device reset for uuid " + uuid;
+                                Log.d(TAG, msg);
+                                runOnUiThread(new Runnable() {
+                                    public void run() {
+                                        Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                                    }
+                                });
+                            } else {
+                                removeOwnedDevice(deviceInfo);
+                            }
+                        }
+                    }, 1000 * iLoop);
+
+                }
+            }
+        });
+        resetDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                dialog.dismiss();
+            }
+        });
+
+        Dialog resetDialog = resetDialogBuilder.create();
+        resetDialog.show();
+    }
+
+    public void scheduledTaskInit () {
+
+        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
+        // executorService.schedule(Classname::someTask, delayInSeconds, TimeUnit.SECONDS);                 // once after a delay
+        // executorService.scheduleAtFixedRate(Classname::someTask, 0, delayInSeconds, TimeUnit.SECONDS);   // at fixed time interval
+        executorService.scheduleAtFixedRate(new Runnable() {
+            @Override
+            public void run() {
+
+                if (obt.discoverUnownedDevices(new UnownedDeviceHandler(OnBoardingActivity.this)) < 0) {
+                    final String msg = "Failed to discover unowned devices";
+                    Log.d(TAG, msg);
+                    runOnUiThread(new Runnable() {
+                        public void run() {
+                            Toast.makeText(OnBoardingActivity.this, msg, Toast.LENGTH_LONG).show();
+                        }
+                    });
+                }
+           }
+        }, 10, 30, TimeUnit.SECONDS); // 30sec interval after 10sec delay
+
+        executorService.scheduleAtFixedRate(new Runnable() {
+            @Override
+            public void run() {
+                onboardingAllUnownedDevices();
+            }
+        }, 30, 30, TimeUnit.SECONDS); // 30sec interval after 30sec delay
+    }
+
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OtmCertificationHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class OtmCertificationHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = OtmCertificationHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public OtmCertificationHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully performed OTM on device " + deviceId :
+                "Error performing ownership transfer on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OtmRandomPinHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class OtmRandomPinHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = OtmRandomPinHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public OtmRandomPinHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully performed OTM on device " + deviceId :
+                "Error performing ownership transfer on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/OwnedDeviceHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+
+import org.iotivity.OCEndpoint;
+import org.iotivity.OCObtDiscoveryHandler;
+import org.iotivity.OCQos;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.oc.OcUtils;
+
+public class OwnedDeviceHandler implements OCObtDiscoveryHandler {
+
+    private static final String TAG = OwnedDeviceHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public OwnedDeviceHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, OCEndpoint endpoints) {
+        OCEndpoint ep = endpoints;
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+        Log.d(TAG, "discovered owned device: " + deviceId + " at:");
+        while (endpoints != null) {
+            String endpointStr = OcUtils.endpointToString(endpoints);
+            Log.d(TAG, endpointStr);
+            endpoints = endpoints.getNext();
+        }
+
+        OcUtils.doGet("/oic/d", ep, null, new GetDeviceNameHandler(activity, true), OCQos.HIGH_QOS);
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionAce2Handler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class ProvisionAce2Handler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = ProvisionAce2Handler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public ProvisionAce2Handler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully provisioned ACE on device " + deviceId :
+                "Error provisioning ACE on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 65 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionAuthWildcardAceAndPairwisingHandler.java

@@ -0,0 +1,65 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+import java.util.ArrayList;
+
+public class ProvisionAuthWildcardAceAndPairwisingHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = ProvisionAuthWildcardAceAndPairwisingHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public ProvisionAuthWildcardAceAndPairwisingHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(final OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully provisioned auth-crypt * ACE on device " + deviceId :
+                "Error provisioning auth-crypt * ACE on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+
+        // pairwising owned device with the other owned devices
+        new Thread(new Runnable() {
+            public void run() {
+                final ArrayList<OcfDeviceInfo> owned_devices = (ArrayList<OcfDeviceInfo>)activity.getOwnedDeviceList().clone();
+                for(OcfDeviceInfo deviceInfo : owned_devices) {
+                    if(!OCUuidUtil.isEqual(uuid, deviceInfo.getUuid())) {
+                        final OCUuid uuidPair = deviceInfo.getUuid();
+                        Log.d(TAG, "Pairing " + OCUuidUtil.uuidToString(uuid) + " and " + OCUuidUtil.uuidToString(uuidPair));
+
+                        if (activity.getObt().provisionPairwiseCredentials(uuid, uuidPair, new ProvisionCredentialsHandler(activity)) < 0) {
+                            final String msg = "Failed to provision pair-wise credentials for " + OCUuidUtil.uuidToString(uuid) + " and " + OCUuidUtil.uuidToString(uuidPair);
+                            Log.d(TAG, msg);
+                            activity.runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                        try {
+                            Thread.sleep(2500);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            }
+        }).start();
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionAuthWildcardAceHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class ProvisionAuthWildcardAceHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = ProvisionAuthWildcardAceHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public ProvisionAuthWildcardAceHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully provisioned auth-crypt * ACE on device " + deviceId :
+                "Error provisioning auth-crypt * ACE on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 31 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionCredentialsHandler.java

@@ -0,0 +1,31 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtStatusHandler;
+
+public class ProvisionCredentialsHandler implements OCObtStatusHandler {
+
+    private static final String TAG = ProvisionCredentialsHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public ProvisionCredentialsHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(int status) {
+        final String msg = (status >= 0) ?
+                "Successfully provisioned pair-wise credentials" :
+                "Error provisioning pair-wise credentials, status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 31 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionIdCertificateHandler.java

@@ -0,0 +1,31 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtStatusHandler;
+
+public class ProvisionIdCertificateHandler implements OCObtStatusHandler {
+
+    private static final String TAG = ProvisionIdCertificateHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public ProvisionIdCertificateHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(int status) {
+        final String msg = (status >= 0) ?
+                "Successfully provisioned identity certificate" :
+                "Error provisioning identity certificate, status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 31 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionRoleCertificateHandler.java

@@ -0,0 +1,31 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtStatusHandler;
+
+public class ProvisionRoleCertificateHandler implements OCObtStatusHandler {
+
+    private static final String TAG = ProvisionRoleCertificateHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public ProvisionRoleCertificateHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(int status) {
+        final String msg = (status >= 0) ?
+                "Successfully provisioned role certificate" :
+                "Error provisioning role certificate, status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ProvisionRoleWildcardAceHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.OCObtDeviceStatusHandler;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+
+public class ProvisionRoleWildcardAceHandler implements OCObtDeviceStatusHandler {
+
+    private static final String TAG = ProvisionRoleWildcardAceHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public ProvisionRoleWildcardAceHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, int status) {
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+
+        final String msg = (status >= 0) ?
+                "Successfully provisioned role * ACE on device " + deviceId :
+                "Error provisioning role * ACE on device " + deviceId + ", status = " + status;
+
+        Log.d(TAG, msg);
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+}

+ 55 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/ResourceDiscoveryHandler.java

@@ -0,0 +1,55 @@
+package org.iotivity.onboardingtool;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import org.iotivity.OCDiscoveryFlags;
+import org.iotivity.OCDiscoveryAllHandler;
+import org.iotivity.OCEndpoint;
+import org.iotivity.OCMain;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.oc.OcUtils;
+
+import java.util.ArrayList;
+
+public class ResourceDiscoveryHandler implements OCDiscoveryAllHandler {
+
+    private static final String TAG = ResourceDiscoveryHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+    private ArrayAdapter<String> resourceAdapter;
+
+    public ResourceDiscoveryHandler(OnBoardingActivity activity, ArrayAdapter<String> resourceAdapter) {
+        this.activity = activity;
+        this.resourceAdapter = resourceAdapter;
+    }
+
+    @Override
+    public OCDiscoveryFlags handler(String anchor, String uri, String[] types, int interfaceMask, OCEndpoint endpoints,
+            int resourcePropertiesMask, boolean more) {
+        synchronized (resourceAdapter) {
+            resourceAdapter.setNotifyOnChange(false);
+            resourceAdapter.add(anchor + uri);
+            resourceAdapter.setNotifyOnChange(true);
+        }
+
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                resourceAdapter.notifyDataSetChanged();
+            }
+        });
+
+        Log.d(TAG, "anchor: " + anchor + ", uri: " + uri);
+        if(!more) {
+            Log.d(TAG, "----End of discovery response---");
+            return OCDiscoveryFlags.OC_STOP_DISCOVERY;
+        }
+        return OCDiscoveryFlags.OC_CONTINUE_DISCOVERY;
+    }
+}

+ 150 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/RetrieveAcl2Handler.java

@@ -0,0 +1,150 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.SimpleAdapter;
+import android.widget.Toast;
+
+import org.iotivity.OCAceConnectionType;
+import org.iotivity.OCAcePermissionsMask;
+import org.iotivity.OCAceResource;
+import org.iotivity.OCAceSubjectType;
+import org.iotivity.OCObt;
+import org.iotivity.OCObtAclHandler;
+import org.iotivity.OCSecurityAce;
+import org.iotivity.OCSecurityAcl;
+import org.iotivity.OCUuidUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class RetrieveAcl2Handler implements OCObtAclHandler {
+
+    private static final String TAG = RetrieveAcl2Handler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+    private SimpleAdapter aclAdapter;
+    private ArrayList<HashMap<String, String>> aclList;
+
+    public RetrieveAcl2Handler(OnBoardingActivity activity, SimpleAdapter aclAdapter, ArrayList<HashMap<String, String>> aclList) {
+        this.activity = activity;
+        this.aclAdapter = aclAdapter;
+        this.aclList = aclList;
+    }
+
+    @Override
+    public void handler(OCSecurityAcl acl) {
+        if (acl != null) {
+            OCSecurityAce ace = acl.getSubjectsListHead();
+            if (ace == null) {
+                final String msg = "No security ACEs found";
+                Log.d(TAG, msg);
+                activity.runOnUiThread(new Runnable() {
+                    public void run() {
+                        Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                    }
+                });
+            }
+
+            while (ace != null) {
+                HashMap<String, String> item = new HashMap<>();
+
+                String line = "Id: " + Integer.toString(ace.getAceid());
+                item.put("line1", line);
+                Log.d(TAG, line);
+
+                if (ace.getSubjectType() == OCAceSubjectType.OC_SUBJECT_UUID) {
+                    line = "Subject: " + OCUuidUtil.uuidToString(ace.getSubject().getUuid());
+
+                } else if (ace.getSubjectType() == OCAceSubjectType.OC_SUBJECT_ROLE) {
+                    line = "Role / Authority: " + ace.getSubject().getRole() + " / ";
+
+                    if ((ace.getSubject().getAuthority() != null) && (!ace.getSubject().getAuthority().isEmpty())) {
+                        line += ace.getSubject().getAuthority();
+                    } else {
+                        line += "<None>";
+                    }
+
+                } else if (ace.getSubjectType() == OCAceSubjectType.OC_SUBJECT_CONN) {
+                    line = "Connection Type: ";
+                    if (ace.getSubject().getConn() == OCAceConnectionType.OC_CONN_AUTH_CRYPT) {
+                        line += "auth-crypt";
+                    } else {
+                        line += "anon-clear";
+                    }
+                }
+
+                item.put("line2", line);
+                Log.d(TAG, line);
+
+                StringBuilder permissions = new StringBuilder();
+                permissions.append("Permissions:");
+                if ((ace.getPermission() & OCAcePermissionsMask.CREATE) == OCAcePermissionsMask.CREATE) {
+                    permissions.append(" C");
+                }
+                if ((ace.getPermission() & OCAcePermissionsMask.RETRIEVE) == OCAcePermissionsMask.RETRIEVE) {
+                    permissions.append(" R");
+                }
+                if ((ace.getPermission() & OCAcePermissionsMask.UPDATE) == OCAcePermissionsMask.UPDATE) {
+                    permissions.append(" U");
+                }
+                if ((ace.getPermission() & OCAcePermissionsMask.DELETE) == OCAcePermissionsMask.DELETE) {
+                    permissions.append(" D");
+                }
+                if ((ace.getPermission() & OCAcePermissionsMask.NOTIFY) == OCAcePermissionsMask.NOTIFY) {
+                    permissions.append(" N");
+                }
+                line = permissions.toString();
+                item.put("line3", line);
+                Log.d(TAG, line);
+
+                StringBuilder aceResources = new StringBuilder();
+                aceResources.append("Resources: ");
+                OCAceResource res = ace.getResourcesListHead();
+                while (res != null) {
+                    if ((res.getHref() != null) && (!res.getHref().isEmpty())) {
+                        aceResources.append(" " + res.getHref() + " ");
+                    } else if (res.getWildcard() != null) {
+                        switch (res.getWildcard()) {
+                            case OC_ACE_WC_ALL:
+                                aceResources.append(" *");
+                                break;
+                            case OC_ACE_WC_ALL_SECURED:
+                                aceResources.append(" +");
+                                break;
+                            case OC_ACE_WC_ALL_PUBLIC:
+                                aceResources.append(" -");
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                    res = res.getNext();
+                }
+                line = aceResources.toString();
+                item.put("line4", line);
+                Log.d(TAG, line);
+
+                aclList.add(item);
+                ace = ace.getNext();
+            }
+
+            activity.runOnUiThread(new Runnable() {
+                public void run() {
+                    aclAdapter.notifyDataSetChanged();
+                }
+            });
+
+            /* Free the ACL structure */
+            OCObt.freeAcl(acl);
+
+        } else {
+            final String msg = "No ACLs found when retrieving /oic/sec/acl2";
+            Log.d(TAG, msg);
+            activity.runOnUiThread(new Runnable() {
+                public void run() {
+                    Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                }
+            });
+        }
+    }
+}

+ 56 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/RetrieveCredentialHandler.java

@@ -0,0 +1,56 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+import android.widget.SimpleAdapter;
+import android.widget.Toast;
+
+import org.iotivity.OCCred;
+import org.iotivity.OCCredUtil;
+import org.iotivity.OCCreds;
+import org.iotivity.OCObt;
+import org.iotivity.OCObtCredsHandler;
+import org.iotivity.OCUuidUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class RetrieveCredentialHandler implements OCObtCredsHandler {
+
+    private static final String TAG = RetrieveCredentialHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+    private SimpleAdapter credsAdapter;
+    private ArrayList<HashMap<String, String>> credsList;
+
+    public RetrieveCredentialHandler(OnBoardingActivity activity, SimpleAdapter credsAdapter, ArrayList<HashMap<String, String>> credsList) {
+        this.activity = activity;
+        this.credsAdapter = credsAdapter;
+        this.credsList = credsList;
+    }
+
+    @Override
+    public void handler(OCCreds creds) {
+        if (creds != null) {
+            CredentialListHelper clh = new CredentialListHelper(credsList);
+            clh.buildList(creds);
+
+            activity.runOnUiThread(new Runnable() {
+                public void run() {
+                    credsAdapter.notifyDataSetChanged();
+                }
+            });
+
+            /* Free the credential structure */
+            OCObt.freeCreds(creds);
+
+        } else {
+            final String msg = "No credentials found when retrieving /oic/sec/cred";
+            Log.d(TAG, msg);
+            activity.runOnUiThread(new Runnable() {
+                public void run() {
+                    Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                }
+            });
+        }
+    }
+}

+ 133 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/RoleCertificateHelper.java

@@ -0,0 +1,133 @@
+package org.iotivity.onboardingtool;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.util.Log;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import org.iotivity.OCObtStatusHandler;
+import org.iotivity.OCRole;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.oc.OcObt;
+
+class RoleCertificateHelper {
+
+    private static final String TAG = RoleCertificateHelper.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+    private OcObt obt;
+    private String uuid;
+    private OCObtStatusHandler provisionRoleCertificateHandler;
+    private OCRole roles;
+
+    RoleCertificateHelper(OnBoardingActivity activity, OcObt obt, String uuid, OCObtStatusHandler provisionRoleCertificateHandler) {
+        this.activity = activity;
+        this.obt = obt;
+        this.uuid = uuid;
+        this.provisionRoleCertificateHandler = provisionRoleCertificateHandler;
+    }
+
+    void getRoles(final OCRole roles) {
+
+        AlertDialog.Builder roleDialogBuilder = new AlertDialog.Builder(activity);
+
+        LinearLayout layout = new LinearLayout(activity);
+        layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+        layout.setOrientation(LinearLayout.VERTICAL);
+
+        final EditText input = new EditText(activity);
+        layout.addView(input);
+
+        String title = activity.getString(R.string.roleDialogTitle);
+        roleDialogBuilder.setTitle(title);
+        roleDialogBuilder.setMessage(R.string.roleDialogMessage);
+        roleDialogBuilder.setView(layout);
+
+        roleDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                String role = input.getText().toString().trim();
+                if (!role.isEmpty()) {
+                    if (role.length() > 63) {
+                        role = role.substring(0, 63);
+                    }
+
+                    final String certRole = role;
+
+                    AlertDialog.Builder authorityAlertBuilder = new AlertDialog.Builder(activity);
+
+                    LinearLayout layout = new LinearLayout(activity);
+                    layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+                    layout.setOrientation(LinearLayout.VERTICAL);
+
+                    final EditText input = new EditText(activity);
+                    layout.addView(input);
+
+                    String title = activity.getString(R.string.authorityDialogTitle);
+                    authorityAlertBuilder.setTitle(title);
+                    authorityAlertBuilder.setMessage(R.string.authorityDialogMessage);
+                    authorityAlertBuilder.setView(layout);
+
+                    authorityAlertBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            String authority = input.getText().toString().trim();
+                            if (!authority.isEmpty()) {
+                                if (authority.length() > 63) {
+                                    authority = authority.substring(0, 63);
+                                }
+                            } else {
+                                authority = null;
+                            }
+
+                            final String certAuthority = authority;
+
+                            RoleCertificateHelper.this.roles = obt.addRoleId(roles, certRole, certAuthority);
+
+                            AlertDialog.Builder moreRolesAlertDialogBuilder = new AlertDialog.Builder(activity);
+                            moreRolesAlertDialogBuilder.setTitle(R.string.addMoreRolesDialogMessage);
+
+                            moreRolesAlertDialogBuilder.setPositiveButton("Yes"/*android.R.string.yes*/, new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+                                    getRoles(RoleCertificateHelper.this.roles);
+                                }
+                            });
+
+                            moreRolesAlertDialogBuilder.setNegativeButton("No"/*android.R.string.no*/, new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+                                    new Thread(new Runnable() {
+                                        public void run() {
+                                            if (obt.provisionRoleCertificate(RoleCertificateHelper.this.roles, OCUuidUtil.stringToUuid(uuid), provisionRoleCertificateHandler) < 0) {
+                                                final String msg = "Failed to provision role certificate for uuid " + uuid;
+                                                Log.d(TAG, msg);
+                                                activity.runOnUiThread(new Runnable() {
+                                                    public void run() {
+                                                        Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                                                    }
+                                                });
+                                            }
+                                        }
+                                    }).start();
+                                }
+                            });
+
+                            Dialog moreRolesDialog = moreRolesAlertDialogBuilder.create();
+                            moreRolesDialog.show();
+                        }
+                    });
+
+                    Dialog authorityDialog = authorityAlertBuilder.create();
+                    authorityDialog.show();
+                }
+            }
+        });
+
+        Dialog roleDialog = roleDialogBuilder.create();
+        roleDialog.show();
+    }
+}

+ 91 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/TrustAnchorHelper.java

@@ -0,0 +1,91 @@
+package org.iotivity.onboardingtool;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.graphics.Typeface;
+import android.util.Log;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import org.iotivity.OCPki;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+class TrustAnchorHelper {
+
+    private static final String TAG = TrustAnchorHelper.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    TrustAnchorHelper(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    void installTrustAnchor() {
+
+        AlertDialog.Builder installTrustAnchorDialogBuilder = new AlertDialog.Builder(activity);
+
+        LinearLayout layout = new LinearLayout(activity);
+        layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+        layout.setOrientation(LinearLayout.VERTICAL);
+
+        final EditText input = new EditText(activity);
+        Typeface tf = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL);
+        input.setTypeface(tf);
+        input.setTextSize(Math.min(input.getTextSize(), 12));
+        layout.addView(input);
+
+        String title = activity.getString(R.string.installTrustAnchor);
+        installTrustAnchorDialogBuilder.setTitle(title);
+        installTrustAnchorDialogBuilder.setMessage(R.string.trustAnchorMessage);
+        installTrustAnchorDialogBuilder.setView(layout);
+
+        installTrustAnchorDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                String certificate = input.getText().toString().trim();
+                if (!certificate.isEmpty()) {
+                    Log.d(TAG, certificate);
+
+                    ByteArrayOutputStream certBuffer = new ByteArrayOutputStream();
+
+                    try {
+                        certBuffer.write(certificate.getBytes());
+                        int rootCaCredentialId = OCPki.addMfgTrustAnchor(0, certBuffer.toByteArray());
+
+                        final String msg = (rootCaCredentialId >= 0) ?
+                                "Successfully installed root certificate" :
+                                "Error installing root certificate";
+                        Log.d(TAG, msg);
+                        activity.runOnUiThread(new Runnable() {
+                            public void run() {
+                                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                            }
+                        });
+
+                    } catch (IOException e) {
+                        final String msg = "Error reading input, certificate not installed";
+                        Log.d(TAG, msg);
+                        activity.runOnUiThread(new Runnable() {
+                            public void run() {
+                                Toast.makeText(activity, msg, Toast.LENGTH_LONG).show();
+                            }
+                        });
+                    }
+                }
+            }
+        });
+
+        installTrustAnchorDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+            }
+        });
+
+        Dialog installTrustAnchorDialog = installTrustAnchorDialogBuilder.create();
+        installTrustAnchorDialog.show();
+    }
+}

+ 35 - 0
OnBoardingTool/app/src/main/java/org/iotivity/onboardingtool/UnownedDeviceHandler.java

@@ -0,0 +1,35 @@
+package org.iotivity.onboardingtool;
+
+import android.util.Log;
+
+import org.iotivity.OCEndpoint;
+import org.iotivity.OCObtDiscoveryHandler;
+import org.iotivity.OCQos;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.oc.OcUtils;
+
+public class UnownedDeviceHandler implements OCObtDiscoveryHandler {
+
+    private static final String TAG = UnownedDeviceHandler.class.getSimpleName();
+
+    private OnBoardingActivity activity;
+
+    public UnownedDeviceHandler(OnBoardingActivity activity) {
+        this.activity = activity;
+    }
+
+    @Override
+    public void handler(OCUuid uuid, OCEndpoint endpoints) {
+        OCEndpoint ep = endpoints;
+        String deviceId = OCUuidUtil.uuidToString(uuid);
+        Log.d(TAG, "discovered unowned device: " + deviceId + " at:");
+        while (endpoints != null) {
+            String endpointStr = OcUtils.endpointToString(endpoints);
+            Log.d(TAG, endpointStr);
+            endpoints = endpoints.getNext();
+        }
+
+        OcUtils.doGet("/oic/d", ep, null, new GetDeviceNameHandler(activity, false), OCQos.HIGH_QOS);
+    }
+}

+ 0 - 0
OnBoardingTool/app/src/main/jniLibs/arm64-v8a/.gitignore


BIN
OnBoardingTool/app/src/main/jniLibs/arm64-v8a/libiotivity-lite-jni.so


+ 2 - 0
OnBoardingTool/app/src/main/jniLibs/armeabi/.gitignore

@@ -0,0 +1,2 @@
+*.so
+

BIN
OnBoardingTool/app/src/main/jniLibs/libiotivity-lite-jni.so


BIN
OnBoardingTool/app/src/main/jniLibs/x86/libiotivity-lite-jni.so


+ 2 - 0
OnBoardingTool/app/src/main/jniLibs/x86_64/.gitignore

@@ -0,0 +1,2 @@
+*.so
+

+ 43 - 0
OnBoardingTool/app/src/main/res/layout/acl_multi_line.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/line_1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?attr/textAppearanceListItem"
+        android:textColor="#000000" />
+
+    <TextView
+        android:id="@+id/line_2"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_3"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_4"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+</LinearLayout>

+ 136 - 0
OnBoardingTool/app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/activity_on_boarding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context="org.iotivity.onboardingtool.OnBoardingActivity">
+
+    <RadioGroup
+        android:id="@+id/radio_group"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="false"
+        android:layout_alignParentTop="false"
+        android:orientation="horizontal">
+
+        <RadioButton
+            android:id="@+id/owned_radio_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/owned" />
+
+        <RadioButton
+            android:id="@+id/unowned_radio_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/unowned" />
+
+    </RadioGroup>
+
+    <RadioGroup
+        android:id="@+id/realm_radio_group"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="false"
+        android:layout_alignParentTop="false"
+        android:layout_below="@+id/radio_group"
+        android:visibility="gone"
+        android:orientation="horizontal">
+
+        <RadioButton
+            android:id="@+id/owned_realm_radio_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/ownedRealm" />
+
+        <RadioButton
+            android:id="@+id/unowned_realm_radio_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/unownedRealm" />
+
+    </RadioGroup>
+
+    <RadioGroup
+        android:id="@+id/site_radio_group"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentStart="false"
+        android:layout_alignParentTop="false"
+        android:layout_below="@+id/realm_radio_group"
+        android:visibility="gone"
+        android:orientation="horizontal">
+
+        <RadioButton
+            android:id="@+id/owned_site_radio_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/ownedSite" />
+
+        <RadioButton
+            android:id="@+id/unowned_site_radio_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/unownedSite" />
+
+    </RadioGroup>
+
+    <Button
+        android:id="@+id/refresh_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/site_radio_group"
+        android:enabled="false"
+        android:text="@string/refresh" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_below="@+id/refresh_button"
+        android:orientation="vertical">
+
+        <ListView
+            android:id="@+id/list_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/refresh_button"
+            android:layout_weight="1" />
+
+        <Button
+            android:id="@+id/onboarding_all"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/list_view"
+            android:enabled="true"
+            android:visibility="visible"
+            android:text="@string/onboarding_ownership_transfer" />
+
+        <Button
+            android:id="@+id/pairwising_all"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:enabled="true"
+            android:visibility="visible"
+            android:text="@string/provision_pairwise_credentials" />
+
+        <Button
+            android:id="@+id/offboarding_all"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:enabled="true"
+            android:visibility="visible"
+            android:text="@string/offboarding_ownership_transfer" />
+    </LinearLayout>
+
+</RelativeLayout>

+ 79 - 0
OnBoardingTool/app/src/main/res/layout/creds_multi_line.xml

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/line_1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?attr/textAppearanceListItem"
+        android:textColor="#000000" />
+
+    <TextView
+        android:id="@+id/line_2"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_3"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_4"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_5"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_6"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_7"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_8"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+</LinearLayout>

+ 32 - 0
OnBoardingTool/app/src/main/res/menu/actionbar_actions.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+
+    <item
+        android:id="@+id/action_obt_retrieve_credentials"
+        android:title="Retrieve OBT Own Creds"
+        app:showAsAction="never"/>
+
+    <!--<item
+        android:id="@+id/action_obt_install_mfg_trustca"
+        android:title="Install OBT MFG Trust CA"
+        app:showAsAction="never"/>-->
+
+    <item
+        android:id="@+id/action_obt_reset"
+        android:title="Reset OBT"
+        app:showAsAction="never"/>
+
+    <!--
+    <item
+        android:id="@+id/action_settings"
+        android:title="Settings"
+        app:showAsAction="never"/>
+
+    <item
+        android:id="@+id/action_search"
+        android:icon="@drawable/ic_search_white_48dp"
+        android:title="Search"
+        app:showAsAction="ifRoom"/>-->
+</menu>

BIN
OnBoardingTool/app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
OnBoardingTool/app/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
OnBoardingTool/app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
OnBoardingTool/app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
OnBoardingTool/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


+ 6 - 0
OnBoardingTool/app/src/main/res/values-w820dp/dimens.xml

@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>

+ 6 - 0
OnBoardingTool/app/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>

+ 5 - 0
OnBoardingTool/app/src/main/res/values/dimens.xml

@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>

+ 88 - 0
OnBoardingTool/app/src/main/res/values/strings.xml

@@ -0,0 +1,88 @@
+<resources>
+    <string name="app_name">On Boarding Tool</string>
+    <string name="owned">Owned</string>
+    <string name="ownedRealm">Owned Realm-local IPv6</string>
+    <string name="ownedSite">Owned Site-local IPv6</string>
+    <string name="unowned">Unowned</string>
+    <string name="unownedRealm">Unowned Realm-local IPv6</string>
+    <string name="unownedSite">Unowned Site-local IPv6</string>
+    <string name="refresh">Refresh</string>
+    <string name="retrieveOwnCredentials">Retrieve Own Credentials</string>
+    <string name="deleteCredential">Delete Credential</string>
+    <string name="deleteAce">Delete Ace</string>
+    <string name="installTrustAnchor">Install new manufacturer trust anchor</string>
+    <string name="trustAnchorMessage">Paste certificate here</string>
+    <string name="resetObt">Reset On Boarding Tool</string>
+    <string name="resetMessage">Note: All owned devices will no longer be doable</string>
+    <string name="discoveredResources">Discovered Resources</string>
+    <string name="enterPin">Enter PIN</string>
+    <string name="selectDevice">Select device for pairing</string>
+    <string name="selectAceSubject">Select subject or device</string>
+    <string name="aceAnonClear">anon-clear</string>
+    <string name="aceAuthCrypt">auth-crypt</string>
+    <string name="aceRole">role</string>
+    <string name="roleDialogTitle">Role</string>
+    <string name="roleDialogMessage">Enter role (cannot be empty)</string>
+    <string name="authorityDialogTitle">Authority</string>
+    <string name="authorityDialogMessage">Enter authority or leave blank if no authority</string>
+    <string name="addMoreRolesDialogMessage">Add more roles?</string>
+    <string name="hrefDialogTitle">Resource ? Href Property</string>
+    <string name="hrefDialogMessage">Enter href property (eg. /a/light) or leave blank if no href</string>
+    <string name="wildcardDialogTitle">Resource ? Wildcard Property</string>
+    <string name="resourceTypesDialogTitle">Resource ? Resource Types Property</string>
+    <string name="resourceTypesDialogMessage">Enter comma separated list of resource types, or leave blank if no resource types</string>
+    <string name="interfacesDialogTitle">Select Resource ? Interfaces (if any)</string>
+    <string name="addMoreResourcesDialogMessage">Add more resources to this ACE?</string>
+    <string name="permissionsDialogTitle">Select ACE Permissions (if any)</string>
+
+    <!-- batch functions -->
+    <string name="onboarding_ownership_transfer">On-boarding All Unowned Devices</string>
+    <string name="provision_pairwise_credentials">Pair-Wising All Owned Devices</string>
+    <string name="offboarding_ownership_transfer">Off-boarding All Owned Devices </string>
+    <string name="offboardingMessage">Note: All owned devices will be off-boarded (hard reset) </string>
+    <string name="selectPairingClient">Select Pair-Wising Client</string>
+
+    <string-array name="unownedDeviceActions">
+        <item>Discover Resources</item>
+        <item>Just-Works Ownership Transfer Method</item>
+        <item>Request Random PIN from device for OTM</item>
+        <item>Random PIN Ownership Transfer Method</item>
+        <item>Manufacturer Certificate based Ownership Transfer Method</item>
+    </string-array>
+    <string-array name="ownedDeviceActions">
+        <item>Discover Resources</item>
+        <item>Provision pair-wise credentials</item>
+        <item>Provision ACE2</item>
+        <item>Provision auth-crypt RW access to NCRs</item>
+        <item>Retrieve /oic/sec/cred</item>
+        <item>Retrieve /oic/sec/acl2</item>
+        <item>Provision role RW access to NCRs</item>
+        <item>Provision identity certificate</item>
+        <item>Provision role certificate</item>
+        <item>Reset device (Hard Reset)</item>
+    </string-array>
+    <string-array name="wildcardOptions">
+        <item>No wildcard resources</item>
+        <item>All NCRs \'*\'</item>
+        <item>All NCRs with >=1 secured endpoint \'+\'</item>
+        <item>All NCRs with >=1 unsecured endpoint \'-\'</item>
+    </string-array>
+    <string-array name="interfaces">
+        <item>oic.if.baseline</item>
+        <item>oic.if.ll</item>
+        <item>oic.if.b</item>
+        <item>oic.if.r</item>
+        <item>oic.if.rw</item>
+        <item>oic.if.a</item>
+        <item>oic.if.s</item>
+    </string-array>
+    <string-array name="permissions">
+        <item>CREATE</item>
+        <item>RETRIEVE</item>
+        <item>UPDATE</item>
+        <item>DELETE</item>
+        <item>NOTIFY</item>
+    </string-array>
+
+
+</resources>

+ 11 - 0
OnBoardingTool/app/src/main/res/values/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>

+ 26 - 0
OnBoardingTool/build.gradle

@@ -0,0 +1,26 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        google()
+        jcenter()
+        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.6.1'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 17 - 0
OnBoardingTool/gradle.properties

@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true

BIN
OnBoardingTool/gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
OnBoardingTool/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Thu Mar 12 03:12:00 KST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

+ 160 - 0
OnBoardingTool/gradlew

@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90 - 0
OnBoardingTool/gradlew.bat

@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 1 - 0
OnBoardingTool/settings.gradle

@@ -0,0 +1 @@
+include ':app'