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.OxmType;
28 import org.iotivity.base.PlatformConfig;
29 import org.iotivity.base.ProvisionResult;
30 import org.iotivity.base.QualityOfService;
31 import org.iotivity.base.ServiceType;
34 import java.io.FileNotFoundException;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.io.OutputStream;
39 import java.util.ArrayList;
40 import java.util.EnumSet;
41 import java.util.List;
43 public class ProvisioningClient extends Activity implements
44 OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwiseDevicesListener {
46 private static final String TAG = "Provisioning Client: ";
47 private static final int BUFFER_SIZE = 1024;
48 int unownedDevCount = StringConstants.NUMBER_ZERO;
49 OcProvisioning.PinCallbackListener pinCallbackListener =
50 new OcProvisioning.PinCallbackListener() {
52 public String pinCallbackListener() {
53 Log.d(TAG, "Inside Pin Callback ");
57 private String filePath = "";
58 private OcSecureResource newSecureResource;
59 private List<OcSecureResource> deviceList;
60 private List<OcSecureResource> ownedDeviceList;
61 private TextView mEventsTextView;
62 OcSecureResource.ProvisionAclListener provisionAclListener =
63 new OcSecureResource.ProvisionAclListener() {
65 public void provisionAclListener(List<ProvisionResult> provisionResults,
67 Log.d(TAG, "Inside ProvisionAclListener ");
68 if (hasError == StringConstants.ERROR_CODE) {
69 logMessage("Error: ACL Provision failed !!");
71 logMessage("ACL Provision Done !!");
72 new DeviceRevocationAsyncTask().execute();
76 OcSecureResource.ProvisionCredentialsListener provisionCredentialsListener =
77 new OcSecureResource.ProvisionCredentialsListener() {
79 public void provisionCredentialsListener(List<ProvisionResult> provisionResults,
81 Log.d(TAG, "Inside ProvisionCredentialsListener ");
82 if (hasError == StringConstants.ERROR_CODE) {
83 logMessage("Error: Provision Credentials failed !!");
85 logMessage("Provision Credentials Done !!");
86 new ProvisionACLAsyncTask().execute();
90 OcSecureResource.UnlinkDevicesListener unlinkDevicesListener =
91 new OcSecureResource.UnlinkDevicesListener() {
93 public void unlinkDevicesListener(List<ProvisionResult> provisionResults,
95 Log.d(TAG, "Inside unlinkDevicesListener ");
96 if (hasError == StringConstants.ERROR_CODE) {
97 logMessage("Error: UnLinking device !!");
99 logMessage("Unlink Done !!");
100 new ProvisionCredentialAsyncTask().execute();
104 OcSecureResource.RemoveDeviceListener removeDeviceListener =
105 new OcSecureResource.RemoveDeviceListener() {
107 public void removeDeviceListener(List<ProvisionResult> provisionResults,
109 if (hasError == StringConstants.ERROR_CODE) {
110 logMessage("Error: Remove Fail !!");
112 logMessage("Remove Device done !!");
118 protected void onCreate(Bundle savedInstanceState) {
119 super.onCreate(savedInstanceState);
120 setContentView(R.layout.activity_secure_provision_client);
121 mEventsTextView = new TextView(this);
122 mEventsTextView.setGravity(Gravity.BOTTOM);
123 mEventsTextView.setMovementMethod(new ScrollingMovementMethod());
124 LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
125 layout.addView(mEventsTextView, new LinearLayout.LayoutParams(
126 LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)
128 filePath = getFilesDir().getPath() + "/"; // data/data/<package>/files/
129 //copy CBOR file when application runs first time
130 SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
131 boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
134 SharedPreferences.Editor editor = wmbPreference.edit();
135 editor.putBoolean("FIRSTRUN", false);
142 * configure OIC platform and call findResource
144 private void initOICStack() {
145 //create platform config
146 PlatformConfig cfg = new PlatformConfig(
149 ModeType.CLIENT_SERVER,
150 "0.0.0.0", // bind to all available interfaces
152 QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
153 OcPlatform.Configure(cfg);
156 * Initialize DataBase
158 String sqlDbPath = getFilesDir().getAbsolutePath().replace("files", "databases") +
160 File file = new File(sqlDbPath);
161 //check files directory exists
162 if (!(file.isDirectory())) {
164 Log.d(TAG, "Sql db directory created at " + sqlDbPath);
166 Log.d(TAG, "Sql db directory exists at " + sqlDbPath);
167 OcProvisioning.provisionInit(sqlDbPath + StringConstants.OIC_SQL_DB_FILE);
168 } catch (OcException e) {
169 logMessage(TAG + "provisionInit error: " + e.getMessage());
170 Log.e(TAG, e.getMessage());
172 new DiscoveryOTTransferAsyncTask().execute();
176 synchronized public void doOwnershipTransferListener(List<ProvisionResult> ProvisionResultList,
178 ProvisionResult pResult = ProvisionResultList.get(0);
179 if (hasError == StringConstants.ERROR_CODE) {
180 logMessage(TAG + "Ownership Transfer Failed for " + pResult.getDevId());
182 logMessage(TAG + "Ownership Transfer Successful for "
183 + pResult.getDevId());
186 if (unownedDevCount == 0) { //When done with Ownership Transfer
187 new OwnedDiscoveryAsyncTask().execute();
191 private void doPairwiseProvisioning() {
193 logMessage(TAG + "Pairwise Provisioning b/w " + ownedDeviceList.get(0).getDeviceID()
194 + " and " + ownedDeviceList.get(1).getDeviceID());
195 newSecureResource = ownedDeviceList.get(0);
196 OcSecureResource newSecureResource2 = ownedDeviceList.get(1);
197 List<String> resources = new ArrayList<String>();
198 List<String> periods = new ArrayList<String>();
199 List<String> recurrences = new ArrayList<String>();
200 recurrences.add(StringConstants.DEFAULT_RECURRENCES);
201 resources.add(StringConstants.DEFAULT_RESOURCES);
202 periods.add(StringConstants.DEFAULT_PERIOD);
203 OicSecAcl acl1 = new OicSecAcl(newSecureResource.getDeviceID(), recurrences, periods,
204 StringConstants.DEFAULT_PERMISSION, resources, StringConstants.DEFAULT_ROWNER_ID);
205 OicSecAcl acl2 = new OicSecAcl(newSecureResource2.getDeviceID(), recurrences, periods,
206 StringConstants.DEFAULT_PERMISSION, resources, StringConstants.DEFAULT_ROWNER_ID);
207 newSecureResource.provisionPairwiseDevices(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
208 KeySize.OWNER_PSK_LENGTH_128, acl1, newSecureResource2, acl2, this);
209 } catch (Exception e) {
210 logMessage(TAG + "Pairwise Provisioning error: " + e.getMessage());
211 Log.e(TAG, e.getMessage());
216 public void provisionPairwiseDevicesListener(List<ProvisionResult> ProvisionResultList,
218 if (hasError == StringConstants.ERROR_CODE) {
219 logMessage(TAG + "provisionPairwiseDevices Failed");
221 for (int i = 0; i < ProvisionResultList.size(); i++) {
222 ProvisionResult pResult = ProvisionResultList.get(i);
223 logMessage(TAG + "provisionPairwiseDevices Result for "
224 + pResult.getDevId() + "is " + pResult.getResult());
226 new GetLinkedDevicesAsyncTask().execute();
231 * Copy svr db CBOR dat file from assets folder to app data files dir
233 private void copyCborFromAsset() {
234 InputStream inputStream = null;
235 OutputStream outputStream = null;
237 byte[] buffer = new byte[BUFFER_SIZE];
239 inputStream = getAssets().open(StringConstants.OIC_CLIENT_CBOR_DB_FILE);
240 File file = new File(filePath);
241 //check files directory exists
242 if (!(file.exists() && file.isDirectory())) {
245 outputStream = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
246 while ((length = inputStream.read(buffer)) != -1) {
247 outputStream.write(buffer, 0, length);
249 } catch (NullPointerException e) {
250 logMessage(TAG + "Null pointer exception " + e.getMessage());
251 Log.e(TAG, e.getMessage());
252 } catch (FileNotFoundException e) {
253 logMessage(TAG + "CBOR svr db file not found " + e.getMessage());
254 Log.e(TAG, e.getMessage());
255 } catch (IOException e) {
256 logMessage(TAG + StringConstants.OIC_CLIENT_CBOR_DB_FILE + " file copy failed");
257 Log.e(TAG, e.getMessage());
259 if (inputStream != null) {
262 } catch (IOException e) {
263 Log.e(TAG, e.getMessage());
266 if (outputStream != null) {
268 outputStream.close();
269 } catch (IOException e) {
270 Log.e(TAG, e.getMessage());
276 public void logMessage(String text) {
280 public void logMsg(final String text) {
281 runOnUiThread(new Runnable() {
283 Message msg = new Message();
285 mEventsTextView.append(text);
286 mEventsTextView.append("\n\n");
290 Intent intent = new Intent(getPackageName());
291 intent.putExtra(StringConstants.MESSAGE, text);
292 sendBroadcast(intent);
295 private class DiscoveryOTTransferAsyncTask extends AsyncTask<Void, String, String> {
298 protected void onPreExecute() {
299 super.onPreExecute();
303 protected String doInBackground(Void... params) {
306 * Discover Un-owned devices
308 publishProgress(TAG + "Discovering Unowned Devices");
309 deviceList = new ArrayList<OcSecureResource>(OcProvisioning.discoverUnownedDevices
310 (StringConstants.DISCOVERY_TIMEOUT_10));
311 if (deviceList.size() > 0) {
312 unownedDevCount = deviceList.size();
313 for (int i = 0; i < deviceList.size(); i++) {
314 publishProgress(TAG + "Un-owned Discovered Device " + (i + 1) + "= " +
315 deviceList.get(i).getDeviceID());
318 OcProvisioning.SetownershipTransferCBdata(OxmType.OIC_JUST_WORKS,
319 pinCallbackListener);
320 for (int i = 0; i < deviceList.size(); i++) {
321 publishProgress(TAG + "Doing Ownership Transfer for " +
322 deviceList.get(i).getDeviceID());
323 deviceList.get(i).doOwnershipTransfer(ProvisioningClient.this);
325 } catch (OcException e) {
326 publishProgress(TAG + "Ownership Transfer error: " + e.getMessage());
327 return "Ownership Transfer error: " + e.getMessage();
331 publishProgress(TAG + "No un-owned devices present");
332 new OwnedDiscoveryAsyncTask().execute();
334 } catch (OcException e) {
335 publishProgress(TAG + "Un-owned discovery error: " + e.getMessage());
336 return "Un-owned discovery error: " + e.getMessage();
342 protected void onProgressUpdate(String... values) {
343 logMessage(values[0]);
347 protected void onPostExecute(String s) {
348 super.onPostExecute(s);
352 private class ProvisionACLAsyncTask extends AsyncTask<Void, String, Void> {
355 protected void onPreExecute() {
356 super.onPreExecute();
360 protected Void doInBackground(Void... params) {
362 if (ownedDeviceList.size() > 1) {
363 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
364 OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
365 publishProgress(TAG + "ACL Provision for " + ocSecureResource.getDeviceID());
366 List<String> resources = new ArrayList<String>();
367 List<String> periods = new ArrayList<String>();
368 List<String> recurrences = new ArrayList<String>();
369 recurrences.add(StringConstants.DEFAULT_RECURRENCES);
370 resources.add(StringConstants.DEFAULT_RESOURCES);
371 periods.add(StringConstants.DEFAULT_PERIOD);
372 OicSecAcl aclObject = new OicSecAcl(ocSecureResourceDest.getDeviceID(),
373 recurrences, periods, StringConstants.DEFAULT_PERMISSION, resources,
374 StringConstants.DEFAULT_ROWNER_ID);
375 ocSecureResource.provisionACL(aclObject, provisionAclListener);
377 publishProgress(TAG + "No Owned devices present");
379 } catch (Exception e) {
380 publishProgress(TAG + "ProvisionACL error: " + e.getMessage());
386 protected void onProgressUpdate(String... values) {
387 logMessage(values[0]);
391 private class ProvisionCredentialAsyncTask extends AsyncTask<Void, String, Void> {
394 protected void onPreExecute() {
395 super.onPreExecute();
399 protected Void doInBackground(Void... params) {
401 if (ownedDeviceList.size() > 1) {
402 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
403 OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
404 publishProgress(TAG + "ProvisionCredential for " +
405 ocSecureResource.getDeviceID() + " with " +
406 ocSecureResourceDest.getDeviceID());
407 ocSecureResource.provisionCredentials(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
408 KeySize.OWNER_PSK_LENGTH_128,
409 ocSecureResourceDest, provisionCredentialsListener);
411 publishProgress(TAG + "Cannot perform credentials between devices");
413 } catch (Exception e) {
414 publishProgress(TAG + "Provision credentials error: " + e.getMessage());
420 protected void onProgressUpdate(String... values) {
421 logMessage(values[0]);
425 private class GetLinkedDevicesAsyncTask extends AsyncTask<Void, String, String> {
428 protected void onPreExecute() {
429 super.onPreExecute();
433 protected String doInBackground(Void... params) {
435 if (ownedDeviceList.size() > 1) {
436 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
437 publishProgress(TAG + "Get linked devices of " + ocSecureResource.getDeviceID());
438 List<String> linkedDevices = ocSecureResource.getLinkedDevices();
439 if (linkedDevices.size() > 0) {
440 for (int i = 0; i < linkedDevices.size(); i++) {
441 publishProgress(TAG + "Linked Devices " +
442 (i + 1) + "= " + linkedDevices.get(i));
445 publishProgress(TAG + "No linked Devices found");
448 publishProgress(TAG + "Cannot perform linked devices");
450 } catch (Exception e) {
451 publishProgress(TAG + "getLinked device error: " + e.getMessage());
458 protected void onProgressUpdate(String... values) {
459 logMessage(values[0]);
463 protected void onPostExecute(String s) {
464 if ("success".equals(s)) {
465 new ProvisionUnlinkAsyncTask().execute();
470 private class ProvisionUnlinkAsyncTask extends AsyncTask<Void, String, Void> {
473 protected void onPreExecute() {
474 super.onPreExecute();
478 protected Void doInBackground(Void... params) {
480 if (ownedDeviceList.size() > 1) {
481 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
482 OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
483 publishProgress(TAG + "Un linking " + ocSecureResource.getDeviceID() +
484 " with " + ocSecureResourceDest.getDeviceID());
485 ocSecureResource.unlinkDevices(ocSecureResourceDest, unlinkDevicesListener);
487 publishProgress(TAG + "Cannot perform unlink devices");
489 } catch (Exception e) {
490 publishProgress(TAG + "Unlink error: " + e.getMessage());
496 protected void onProgressUpdate(String... values) {
497 logMessage(values[0]);
501 private class DeviceRevocationAsyncTask extends AsyncTask<Void, String, Void> {
504 protected void onPreExecute() {
505 super.onPreExecute();
509 protected Void doInBackground(Void... params) {
511 if (ownedDeviceList.size() > 0) {
512 OcSecureResource ocSecureResource = ownedDeviceList.get(0);
513 publishProgress(TAG + "Removing " + ocSecureResource.getDeviceID());
514 ocSecureResource.removeDevice(StringConstants.DISCOVERY_TIMEOUT_20,
515 removeDeviceListener);
517 publishProgress(TAG + "Cannot remove");
519 } catch (Exception e) {
520 publishProgress(TAG + "Remove Device error: " + e.getMessage());
526 protected void onProgressUpdate(String... values) {
527 logMessage(values[0]);
531 private class OwnedDiscoveryAsyncTask extends AsyncTask<Void, String, String> {
534 protected void onPreExecute() {
535 super.onPreExecute();
539 protected String doInBackground(Void... params) {
541 publishProgress(TAG + "Initiate Owned device Discovery");
542 ownedDeviceList = OcProvisioning.discoverOwnedDevices
543 (StringConstants.DISCOVERY_TIMEOUT_10);
544 if (ownedDeviceList.size() > 0) {
545 for (int i = 0; i < ownedDeviceList.size(); i++) {
546 publishProgress(TAG + "Owned Discovered Device " + (i + 1) + "= " +
547 ownedDeviceList.get(i).getDeviceID()
548 + "\nIP Address= " + ownedDeviceList.get(i).getIpAddr()
549 + "\nOwned Status= " + ownedDeviceList.get(i).getOwnedStatus()
550 + "\nDevice Status= " + ((ownedDeviceList.get(i).
551 getDeviceStatus() == DeviceStatus.ON) ? "ON" : "OFF")
555 publishProgress(TAG + "No Owned devices present");
557 } catch (OcException e) {
558 publishProgress(TAG + "Owned device Discovery error: " + e.getMessage());
559 return "Owned device Discovery error: " + e.getMessage();
565 protected void onProgressUpdate(String... values) {
566 logMessage(values[0]);
570 protected void onPostExecute(String s) {
571 if (ownedDeviceList.size() > 1 && "success".equals(s)) {
572 doPairwiseProvisioning();
578 * to display on Server Message on Client screen
580 public class MessageReceiver extends BroadcastReceiver {
582 public void onReceive(Context context, Intent intent) {
583 final String message = intent.getStringExtra(StringConstants.MESSAGE);