1 package org.iotivity.base.examples.provisioningclient;
3 import android.app.Activity;
4 import android.content.BroadcastReceiver;
5 import android.content.Context;
6 import android.content.Intent;
7 import android.content.SharedPreferences;
8 import android.os.AsyncTask;
9 import android.os.Bundle;
10 import android.os.Message;
11 import android.preference.PreferenceManager;
12 import android.text.method.ScrollingMovementMethod;
13 import android.util.Log;
14 import android.view.Gravity;
15 import android.widget.LinearLayout;
16 import android.widget.TextView;
18 import org.iotivity.base.CredType;
19 import org.iotivity.base.DeviceStatus;
20 import org.iotivity.base.KeySize;
21 import org.iotivity.base.ModeType;
22 import org.iotivity.base.OcException;
23 import org.iotivity.base.OcPlatform;
24 import org.iotivity.base.OcProvisioning;
25 import org.iotivity.base.OcSecureResource;
26 import org.iotivity.base.OicSecAcl;
27 import org.iotivity.base.OicSecPdAcl;
28 import org.iotivity.base.OcPrmType;
29 import org.iotivity.base.OxmType;
30 import org.iotivity.base.PlatformConfig;
31 import org.iotivity.base.ProvisionResult;
32 import org.iotivity.base.QualityOfService;
33 import org.iotivity.base.ServiceType;
36 import java.io.FileNotFoundException;
37 import java.io.FileOutputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.OutputStream;
41 import java.util.ArrayList;
42 import java.util.EnumSet;
43 import java.util.List;
45 public class ProvisioningClient extends Activity implements
46 OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwiseDevicesListener {
48 private static final String TAG = "Provisioning Client: ";
49 private static final int BUFFER_SIZE = 1024;
50 int unownedDevCount = StringConstants.NUMBER_ZERO;
51 OcProvisioning.PinCallbackListener pinCallbackListener =
52 new OcProvisioning.PinCallbackListener() {
54 public String pinCallbackListener() {
55 Log.d(TAG, "Inside Pin Callback ");
59 private String filePath = "";
60 private OcSecureResource newSecureResource;
61 private List<OcSecureResource> deviceList;
62 private List<OcSecureResource> ownedDeviceList;
63 private TextView mEventsTextView;
65 OcSecureResource.ProvisionDirectPairingListener provisionDPListener =
66 new OcSecureResource.ProvisionDirectPairingListener() {
68 public void provisionDirectPairingListener(List<ProvisionResult> provisionResults,
70 Log.d(TAG, "Inside provisionDPListener");
71 ProvisionResult pResult = provisionResults.get(0);
72 if (hasError == StringConstants.ERROR_CODE) {
73 logMessage(TAG + "Provision direct pairing Failed for " + pResult.getDevId());
75 logMessage(TAG + "Provision direct pairing Successful for " + pResult.getDevId());
80 OcSecureResource.ProvisionAclListener provisionAclListener =
81 new OcSecureResource.ProvisionAclListener() {
83 public void provisionAclListener(List<ProvisionResult> provisionResults,
85 Log.d(TAG, "Inside ProvisionAclListener ");
86 if (hasError == StringConstants.ERROR_CODE) {
87 logMessage("Error: ACL Provision failed !!");
89 logMessage("ACL Provision Done !!");
90 new DeviceRevocationAsyncTask().execute();
94 OcSecureResource.ProvisionCredentialsListener provisionCredentialsListener =
95 new OcSecureResource.ProvisionCredentialsListener() {
97 public void provisionCredentialsListener(List<ProvisionResult> provisionResults,
99 Log.d(TAG, "Inside ProvisionCredentialsListener ");
100 if (hasError == StringConstants.ERROR_CODE) {
101 logMessage("Error: Provision Credentials failed !!");
103 logMessage("Provision Credentials Done !!");
104 new ProvisionACLAsyncTask().execute();
108 OcSecureResource.UnlinkDevicesListener unlinkDevicesListener =
109 new OcSecureResource.UnlinkDevicesListener() {
111 public void unlinkDevicesListener(List<ProvisionResult> provisionResults,
113 Log.d(TAG, "Inside unlinkDevicesListener ");
114 if (hasError == StringConstants.ERROR_CODE) {
115 logMessage("Error: UnLinking device !!");
117 logMessage("Unlink Done !!");
118 new ProvisionCredentialAsyncTask().execute();
122 OcSecureResource.RemoveDeviceListener removeDeviceListener =
123 new OcSecureResource.RemoveDeviceListener() {
125 public void removeDeviceListener(List<ProvisionResult> provisionResults,
127 if (hasError == StringConstants.ERROR_CODE) {
128 logMessage("Error: Remove Fail !!");
130 logMessage("Remove Device done !!");
136 protected void onCreate(Bundle savedInstanceState) {
137 super.onCreate(savedInstanceState);
138 setContentView(R.layout.activity_secure_provision_client);
139 mEventsTextView = new TextView(this);
140 mEventsTextView.setGravity(Gravity.BOTTOM);
141 mEventsTextView.setMovementMethod(new ScrollingMovementMethod());
142 LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
143 layout.addView(mEventsTextView, new LinearLayout.LayoutParams(
144 LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)
146 filePath = getFilesDir().getPath() + "/"; // data/data/<package>/files/
147 //copy CBOR file when application runs first time
148 SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
149 boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
152 SharedPreferences.Editor editor = wmbPreference.edit();
153 editor.putBoolean("FIRSTRUN", false);
160 * configure OIC platform and call findResource
162 private void initOICStack() {
163 //create platform config
164 PlatformConfig cfg = new PlatformConfig(
167 ModeType.CLIENT_SERVER,
168 "0.0.0.0", // bind to all available interfaces
170 QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
171 OcPlatform.Configure(cfg);
174 * Initialize DataBase
176 String sqlDbPath = getFilesDir().getAbsolutePath().replace("files", "databases") +
178 File file = new File(sqlDbPath);
179 //check files directory exists
180 if (!(file.isDirectory())) {
182 Log.d(TAG, "Sql db directory created at " + sqlDbPath);
184 Log.d(TAG, "Sql db directory exists at " + sqlDbPath);
185 OcProvisioning.provisionInit(sqlDbPath + StringConstants.OIC_SQL_DB_FILE);
186 } catch (OcException e) {
187 logMessage(TAG + "provisionInit error: " + e.getMessage());
188 Log.e(TAG, e.getMessage());
190 new DiscoveryOTTransferAsyncTask().execute();
194 synchronized public void doOwnershipTransferListener(List<ProvisionResult> ProvisionResultList,
196 ProvisionResult pResult = ProvisionResultList.get(0);
197 if (hasError == StringConstants.ERROR_CODE) {
198 logMessage(TAG + "Ownership Transfer Failed for " + pResult.getDevId());
200 logMessage(TAG + "Ownership Transfer Successful for "
201 + pResult.getDevId());
204 if (unownedDevCount == 0) { //When done with Ownership Transfer
205 new OwnedDiscoveryAsyncTask().execute();
210 private void doDPProvisioning() {
212 logMessage(TAG + "Provision direct pairing for " + ownedDeviceList.get(0).getDeviceID());
213 newSecureResource = ownedDeviceList.get(0);
214 String pin = "00000000";
215 List<OcPrmType>prmTypes = new ArrayList<OcPrmType>();
216 prmTypes.add(OcPrmType.DP_PRE_CONFIGURED);
218 List<String> resources = new ArrayList<String>();
219 List<String> periods = new ArrayList<String>();
220 List<String> recurrences = new ArrayList<String>();
221 resources.add(StringConstants.DEFAULT_RESOURCES);
222 OicSecPdAcl pdAcl = new OicSecPdAcl(recurrences, periods,
223 StringConstants.DEFAULT_PERMISSION, resources);
224 OicSecPdAcl[] oicSecPdAcls = new OicSecPdAcl[1];
225 oicSecPdAcls[0] = pdAcl;
226 newSecureResource.doProvisionDirectPairing(pin, oicSecPdAcls, prmTypes, edp,
227 provisionDPListener);
228 } catch (Exception e) {
229 logMessage(TAG + "Direct Pairing Provisioning error: " + e.getMessage());
230 Log.e(TAG, e.getMessage());
235 private void doPairwiseProvisioning() {
237 logMessage(TAG + "Pairwise Provisioning b/w " + ownedDeviceList.get(0).getDeviceID()
238 + " and " + ownedDeviceList.get(1).getDeviceID());
239 newSecureResource = ownedDeviceList.get(0);
240 OcSecureResource newSecureResource2 = ownedDeviceList.get(1);
241 List<String> resources = new ArrayList<String>();
242 List<String> periods = new ArrayList<String>();
243 List<String> recurrences = new ArrayList<String>();
244 recurrences.add(StringConstants.DEFAULT_RECURRENCES);
245 resources.add(StringConstants.DEFAULT_RESOURCES);
246 periods.add(StringConstants.DEFAULT_PERIOD);
247 OicSecAcl acl1 = new OicSecAcl(newSecureResource.getDeviceID(), recurrences, periods,
248 StringConstants.DEFAULT_PERMISSION, resources, StringConstants.DEFAULT_ROWNER_ID);
249 OicSecAcl acl2 = new OicSecAcl(newSecureResource2.getDeviceID(), recurrences, periods,
250 StringConstants.DEFAULT_PERMISSION, resources, StringConstants.DEFAULT_ROWNER_ID);
251 newSecureResource.provisionPairwiseDevices(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
252 KeySize.OWNER_PSK_LENGTH_128, acl1, newSecureResource2, acl2, this);
253 } catch (Exception e) {
254 logMessage(TAG + "Pairwise Provisioning error: " + e.getMessage());
255 Log.e(TAG, e.getMessage());
260 public void provisionPairwiseDevicesListener(List<ProvisionResult> ProvisionResultList,
262 if (hasError == StringConstants.ERROR_CODE) {
263 logMessage(TAG + "provisionPairwiseDevices Failed");
265 for (int i = 0; i < ProvisionResultList.size(); i++) {
266 ProvisionResult pResult = ProvisionResultList.get(i);
267 logMessage(TAG + "provisionPairwiseDevices Result for "
268 + pResult.getDevId() + "is " + pResult.getResult());
270 new GetLinkedDevicesAsyncTask().execute();
275 * Copy svr db CBOR dat file from assets folder to app data files dir
277 private void copyCborFromAsset() {
278 InputStream inputStream = null;
279 OutputStream outputStream = null;
281 byte[] buffer = new byte[BUFFER_SIZE];
283 inputStream = getAssets().open(StringConstants.OIC_CLIENT_CBOR_DB_FILE);
284 File file = new File(filePath);
285 //check files directory exists
286 if (!(file.exists() && file.isDirectory())) {
289 outputStream = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
290 while ((length = inputStream.read(buffer)) != -1) {
291 outputStream.write(buffer, 0, length);
293 } catch (NullPointerException e) {
294 logMessage(TAG + "Null pointer exception " + e.getMessage());
295 Log.e(TAG, e.getMessage());
296 } catch (FileNotFoundException e) {
297 logMessage(TAG + "CBOR svr db file not found " + e.getMessage());
298 Log.e(TAG, e.getMessage());
299 } catch (IOException e) {
300 logMessage(TAG + StringConstants.OIC_CLIENT_CBOR_DB_FILE + " file copy failed");
301 Log.e(TAG, e.getMessage());
303 if (inputStream != null) {
306 } catch (IOException e) {
307 Log.e(TAG, e.getMessage());
310 if (outputStream != null) {
312 outputStream.close();
313 } catch (IOException e) {
314 Log.e(TAG, e.getMessage());
320 public void logMessage(String text) {
324 public void logMsg(final String text) {
325 runOnUiThread(new Runnable() {
327 Message msg = new Message();
329 mEventsTextView.append(text);
330 mEventsTextView.append("\n\n");
334 Intent intent = new Intent(getPackageName());
335 intent.putExtra(StringConstants.MESSAGE, text);
336 sendBroadcast(intent);
339 private class DiscoveryOTTransferAsyncTask extends AsyncTask<Void, String, String> {
342 protected void onPreExecute() {
343 super.onPreExecute();
347 protected String doInBackground(Void... params) {
350 * Discover Un-owned devices
352 publishProgress(TAG + "Discovering Unowned Devices");
353 deviceList = new ArrayList<OcSecureResource>(OcProvisioning.discoverUnownedDevices
354 (StringConstants.DISCOVERY_TIMEOUT_10));
355 if (deviceList.size() > 0) {
356 unownedDevCount = deviceList.size();
357 for (int i = 0; i < deviceList.size(); i++) {
358 publishProgress(TAG + "Un-owned Discovered Device " + (i + 1) + "= " +
359 deviceList.get(i).getDeviceID());
362 OcProvisioning.SetownershipTransferCBdata(OxmType.OIC_JUST_WORKS,
363 pinCallbackListener);
364 for (int i = 0; i < deviceList.size(); i++) {
365 publishProgress(TAG + "Doing Ownership Transfer for " +
366 deviceList.get(i).getDeviceID());
367 deviceList.get(i).doOwnershipTransfer(ProvisioningClient.this);
369 } catch (OcException e) {
370 publishProgress(TAG + "Ownership Transfer error: " + e.getMessage());
371 return "Ownership Transfer error: " + e.getMessage();
375 publishProgress(TAG + "No un-owned devices present");
376 new OwnedDiscoveryAsyncTask().execute();
378 } catch (OcException e) {
379 publishProgress(TAG + "Un-owned discovery error: " + e.getMessage());
380 return "Un-owned discovery error: " + e.getMessage();
386 protected void onProgressUpdate(String... values) {
387 logMessage(values[0]);
391 protected void onPostExecute(String s) {
392 super.onPostExecute(s);
396 private class ProvisionACLAsyncTask extends AsyncTask<Void, String, Void> {
399 protected void onPreExecute() {
400 super.onPreExecute();
404 protected Void doInBackground(Void... params) {
406 if (ownedDeviceList.size() > 1) {
407 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
408 OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
409 publishProgress(TAG + "ACL Provision for " + ocSecureResource.getDeviceID());
410 List<String> resources = new ArrayList<String>();
411 List<String> periods = new ArrayList<String>();
412 List<String> recurrences = new ArrayList<String>();
413 recurrences.add(StringConstants.DEFAULT_RECURRENCES);
414 resources.add(StringConstants.DEFAULT_RESOURCES);
415 periods.add(StringConstants.DEFAULT_PERIOD);
416 OicSecAcl aclObject = new OicSecAcl(ocSecureResourceDest.getDeviceID(),
417 recurrences, periods, StringConstants.DEFAULT_PERMISSION, resources,
418 StringConstants.DEFAULT_ROWNER_ID);
419 ocSecureResource.provisionACL(aclObject, provisionAclListener);
421 publishProgress(TAG + "No Owned devices present");
423 } catch (Exception e) {
424 publishProgress(TAG + "ProvisionACL error: " + e.getMessage());
430 protected void onProgressUpdate(String... values) {
431 logMessage(values[0]);
435 private class ProvisionCredentialAsyncTask extends AsyncTask<Void, String, Void> {
438 protected void onPreExecute() {
439 super.onPreExecute();
443 protected Void doInBackground(Void... params) {
445 if (ownedDeviceList.size() > 1) {
446 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
447 OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
448 publishProgress(TAG + "ProvisionCredential for " +
449 ocSecureResource.getDeviceID() + " with " +
450 ocSecureResourceDest.getDeviceID());
451 ocSecureResource.provisionCredentials(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
452 KeySize.OWNER_PSK_LENGTH_128,
453 ocSecureResourceDest, provisionCredentialsListener);
455 publishProgress(TAG + "Cannot perform credentials between devices");
457 } catch (Exception e) {
458 publishProgress(TAG + "Provision credentials error: " + e.getMessage());
464 protected void onProgressUpdate(String... values) {
465 logMessage(values[0]);
469 private class GetLinkedDevicesAsyncTask extends AsyncTask<Void, String, String> {
472 protected void onPreExecute() {
473 super.onPreExecute();
477 protected String doInBackground(Void... params) {
479 if (ownedDeviceList.size() > 1) {
480 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
481 publishProgress(TAG + "Get linked devices of " + ocSecureResource.getDeviceID());
482 List<String> linkedDevices = ocSecureResource.getLinkedDevices();
483 if (linkedDevices.size() > 0) {
484 for (int i = 0; i < linkedDevices.size(); i++) {
485 publishProgress(TAG + "Linked Devices " +
486 (i + 1) + "= " + linkedDevices.get(i));
489 publishProgress(TAG + "No linked Devices found");
492 publishProgress(TAG + "Cannot perform linked devices");
494 } catch (Exception e) {
495 publishProgress(TAG + "getLinked device error: " + e.getMessage());
502 protected void onProgressUpdate(String... values) {
503 logMessage(values[0]);
507 protected void onPostExecute(String s) {
508 if ("success".equals(s)) {
509 new ProvisionUnlinkAsyncTask().execute();
514 private class ProvisionUnlinkAsyncTask extends AsyncTask<Void, String, Void> {
517 protected void onPreExecute() {
518 super.onPreExecute();
522 protected Void doInBackground(Void... params) {
524 if (ownedDeviceList.size() > 1) {
525 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
526 OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
527 publishProgress(TAG + "Un linking " + ocSecureResource.getDeviceID() +
528 " with " + ocSecureResourceDest.getDeviceID());
529 ocSecureResource.unlinkDevices(ocSecureResourceDest, unlinkDevicesListener);
531 publishProgress(TAG + "Cannot perform unlink devices");
533 } catch (Exception e) {
534 publishProgress(TAG + "Unlink error: " + e.getMessage());
540 protected void onProgressUpdate(String... values) {
541 logMessage(values[0]);
545 private class DeviceRevocationAsyncTask extends AsyncTask<Void, String, Void> {
548 protected void onPreExecute() {
549 super.onPreExecute();
553 protected Void doInBackground(Void... params) {
555 if (ownedDeviceList.size() > 0) {
556 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
557 publishProgress(TAG + "Removing " + ocSecureResource.getDeviceID());
558 ocSecureResource.removeDevice(StringConstants.DISCOVERY_TIMEOUT_20,
559 removeDeviceListener);
561 publishProgress(TAG + "Cannot remove");
563 } catch (Exception e) {
564 publishProgress(TAG + "Remove Device error: " + e.getMessage());
570 protected void onProgressUpdate(String... values) {
571 logMessage(values[0]);
575 private class OwnedDiscoveryAsyncTask extends AsyncTask<Void, String, String> {
578 protected void onPreExecute() {
579 super.onPreExecute();
583 protected String doInBackground(Void... params) {
585 publishProgress(TAG + "Initiate Owned device Discovery");
586 ownedDeviceList = OcProvisioning.discoverOwnedDevices
587 (StringConstants.DISCOVERY_TIMEOUT_10);
588 if (ownedDeviceList.size() > 0) {
589 for (int i = 0; i < ownedDeviceList.size(); i++) {
590 publishProgress(TAG + "Owned Discovered Device " + (i + 1) + "= " +
591 ownedDeviceList.get(i).getDeviceID()
592 + "\nIP Address= " + ownedDeviceList.get(i).getIpAddr()
593 + "\nOwned Status= " + ownedDeviceList.get(i).getOwnedStatus()
594 + "\nDevice Status= " + ((ownedDeviceList.get(i).
595 getDeviceStatus() == DeviceStatus.ON) ? "ON" : "OFF")
599 publishProgress(TAG + "No Owned devices present");
601 } catch (OcException e) {
602 publishProgress(TAG + "Owned device Discovery error: " + e.getMessage());
603 return "Owned device Discovery error: " + e.getMessage();
609 protected void onProgressUpdate(String... values) {
610 logMessage(values[0]);
614 protected void onPostExecute(String s) {
617 if (ownedDeviceList.size() > 0 && "success".equals(s)) {
621 if (ownedDeviceList.size() > 1 && "success".equals(s)) {
622 doPairwiseProvisioning();
628 * to display on Server Message on Client screen
630 public class MessageReceiver extends BroadcastReceiver {
632 public void onReceive(Context context, Intent intent) {
633 final String message = intent.getStringExtra(StringConstants.MESSAGE);