df92e2f48993e95da867a163f1753bafa9e4ccdc
[platform/upstream/iotivity.git] / android / examples / provisioningclient / src / main / java / org / iotivity / base / examples / provisioningclient / ProvisioningClient.java
1 package org.iotivity.base.examples.provisioningclient;
2
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;
17 import org.iotivity.base.ModeType;
18 import org.iotivity.base.OcException;
19 import org.iotivity.base.OcPlatform;
20 import org.iotivity.base.PlatformConfig;
21 import org.iotivity.base.QualityOfService;
22 import org.iotivity.base.ServiceType;
23 import org.iotivity.base.OcProvisioning;
24 import org.iotivity.base.OcSecureResource;
25 import org.iotivity.base.ProvisionResult;
26 import org.iotivity.base.OxmType;
27 import org.iotivity.base.OicSecAcl;
28 import org.iotivity.base.CredType;
29 import org.iotivity.base.KeySize;
30 import org.iotivity.base.DeviceStatus;
31 import java.io.File;
32 import java.io.FileNotFoundException;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.OutputStream;
37 import java.util.ArrayList;
38 import java.util.EnumSet;
39 import java.util.List;
40
41 public class ProvisioningClient extends Activity implements
42     OcSecureResource.DoOwnershipTransferListener,OcSecureResource.ProvisionPairwiseDevicesListener {
43
44     private static final String TAG = "Provisioning Client: ";
45     private static final int BUFFER_SIZE = 1024;
46     int unownedDevCount = StringConstants.NUMBER_ZERO;
47     private String filePath = "";
48     private OcSecureResource newSecureResource;
49     private List<OcSecureResource> deviceList;
50     private List<OcSecureResource> ownedDeviceList;
51     private TextView mEventsTextView;
52
53     @Override
54     protected void onCreate(Bundle savedInstanceState) {
55         super.onCreate(savedInstanceState);
56         setContentView(R.layout.activity_secure_provision_client);
57         mEventsTextView = new TextView(this);
58         mEventsTextView.setGravity(Gravity.BOTTOM);
59         mEventsTextView.setMovementMethod(new ScrollingMovementMethod());
60         LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
61         layout.addView(mEventsTextView, new LinearLayout.LayoutParams(
62                         LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)
63         );
64         filePath = getFilesDir().getPath() + "/"; //  data/data/<package>/files/
65         //copy json when application runs first time
66         SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
67         boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
68         if (isFirstRun) {
69             copyJsonFromAsset();
70             SharedPreferences.Editor editor = wmbPreference.edit();
71             editor.putBoolean("FIRSTRUN", false);
72             editor.commit();
73         }
74         initOICStack();
75     }
76
77     OcProvisioning.PinCallbackListener pinCallbackListener =
78             new OcProvisioning.PinCallbackListener() {
79                 @Override
80                 public String pinCallbackListener() {
81                     Log.d(TAG, "Inside Pin Callback ");
82                     return "";
83                 }
84             };
85
86     OcSecureResource.ProvisionAclListener provisionAclListener =
87             new OcSecureResource.ProvisionAclListener() {
88                 @Override
89                 public void provisionAclListener(List<ProvisionResult> provisionResults,
90                                                  int hasError) {
91                     Log.d(TAG, "Inside ProvisionAclListener ");
92                     if (hasError == StringConstants.ERROR_CODE) {
93                         logMessage("Error: ACL Provision failed !!");
94                     } else {
95                         logMessage("ACL Provision Done !!");
96                         new DeviceRevocationAsyncTask().execute();
97                     }
98                 }
99             };
100
101     OcSecureResource.ProvisionCredentialsListener provisionCredentialsListener =
102             new OcSecureResource.ProvisionCredentialsListener() {
103                 @Override
104                 public void provisionCredentialsListener(List<ProvisionResult> provisionResults,
105                                                          int hasError) {
106                     Log.d(TAG, "Inside ProvisionCredentialsListener ");
107                     if (hasError == StringConstants.ERROR_CODE) {
108                         logMessage("Error: Provision Credentials failed !!");
109                     } else {
110                         logMessage("Provision Credentials Done !!");
111                         new ProvisionACLAsyncTask().execute();
112                     }
113                 }
114             };
115
116     OcSecureResource.UnlinkDevicesListener unlinkDevicesListener =
117             new OcSecureResource.UnlinkDevicesListener() {
118                 @Override
119                 public void unlinkDevicesListener(List<ProvisionResult> provisionResults,
120                                                   int hasError) {
121                     Log.d(TAG, "Inside unlinkDevicesListener ");
122                     if (hasError == StringConstants.ERROR_CODE) {
123                         logMessage("Error: UnLinking device !!");
124                     } else {
125                         logMessage("Unlink Done !!");
126                         new ProvisionCredentialAsyncTask().execute();
127                     }
128                 }
129             };
130
131     OcSecureResource.RemoveDeviceListener removeDeviceListener =
132             new OcSecureResource.RemoveDeviceListener() {
133                 @Override
134                 public void removeDeviceListener(List<ProvisionResult> provisionResults,
135                                                  int hasError) {
136                     if (hasError == StringConstants.ERROR_CODE) {
137                         logMessage("Error: Remove Fail !!");
138                     } else {
139                         logMessage("Remove Device done !!");
140                     }
141                 }
142             };
143
144     /**
145      * configure OIC platform and call findResource
146      */
147     private void initOICStack() {
148         //create platform config
149         PlatformConfig cfg = new PlatformConfig(
150                 this,
151                 ServiceType.IN_PROC,
152                 ModeType.CLIENT_SERVER,
153                 "0.0.0.0", // bind to all available interfaces
154                 0,
155                 QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);
156         OcPlatform.Configure(cfg);
157         try {
158             /*
159              * Initialize DataBase
160              */
161             String sqlDbPath = getFilesDir().getAbsolutePath().replace("files", "databases") +
162                     File.separator;
163             File file = new File(sqlDbPath);
164             //check files directory exists
165             if (!(file.isDirectory())) {
166                 file.mkdirs();
167                 Log.d(TAG, "Sql db directory created at " + sqlDbPath);
168             }
169             Log.d(TAG, "Sql db directory exists at " + sqlDbPath);
170             OcProvisioning.provisionInit(sqlDbPath + StringConstants.OIC_SQL_DB_FILE);
171         } catch (OcException e) {
172             logMessage(TAG + "provisionInit error: " + e.getMessage());
173             Log.e(TAG, e.getMessage());
174         }
175         new DiscoveryOTTransferAsyncTask().execute();
176     }
177
178     @Override
179     synchronized public void doOwnershipTransferListener(List<ProvisionResult> ProvisionResultList,
180                                                          int hasError) {
181         ProvisionResult pResult = ProvisionResultList.get(0);
182         if (hasError == StringConstants.ERROR_CODE) {
183             logMessage(TAG + "Ownership Transfer Failed for " + pResult.getDevId());
184         } else {
185             logMessage(TAG + "Ownership Transfer Successful for "
186                     + pResult.getDevId());
187             unownedDevCount--;
188         }
189         if (unownedDevCount == 0) { //When done with Ownership Transfer
190             new OwnedDiscoveryAsyncTask().execute();
191         }
192     }
193
194     private void doPairwiseProvisioning() {
195         try {
196             logMessage(TAG + "Pairwise Provisioning b/w " + ownedDeviceList.get(0).getDeviceID()
197                     + " and " + ownedDeviceList.get(1).getDeviceID());
198             newSecureResource = ownedDeviceList.get(0);
199             OcSecureResource newSecureResource2 = ownedDeviceList.get(1);
200             List<String> resources = new ArrayList<String>();
201             List<String> owners = new ArrayList<String>();
202             List<String> periods = new ArrayList<String>();
203             List<String> recurrences = new ArrayList<String>();
204             recurrences.add("Daily");
205             resources.add("*");
206             owners.add("adminDeviceUUID0");
207             periods.add("01-01-15");
208             OicSecAcl acl1 = new OicSecAcl(newSecureResource.getDeviceID(), recurrences, periods,
209                     31, resources, owners);
210             OicSecAcl acl2 = new OicSecAcl(newSecureResource2.getDeviceID(), recurrences, periods,
211                     31, resources, owners);
212             newSecureResource.provisionPairwiseDevices(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
213                     KeySize.OWNER_PSK_LENGTH_128, acl1, newSecureResource2, acl2, this);
214         } catch (Exception e) {
215             logMessage(TAG + "Pairwise Provisioning  error: " + e.getMessage());
216             Log.e(TAG, e.getMessage());
217         }
218     }
219
220     @Override
221     public void provisionPairwiseDevicesListener(List<ProvisionResult> ProvisionResultList,
222                                                  int hasError) {
223         if (hasError == StringConstants.ERROR_CODE) {
224             logMessage(TAG + "provisionPairwiseDevices Failed");
225         } else {
226             for (int i = 0; i < ProvisionResultList.size(); i++) {
227                 ProvisionResult pResult = ProvisionResultList.get(i);
228                 logMessage(TAG + "provisionPairwiseDevices Result for "
229                         + pResult.getDevId() + "is " + pResult.getResult());
230             }
231             new GetLinkedDevicesAsyncTask().execute();
232         }
233     }
234
235     /**
236      * Copy svr db json file from assets folder to app data files dir
237      */
238     private void copyJsonFromAsset() {
239         InputStream inputStream = null;
240         OutputStream outputStream = null;
241         int length;
242         byte[] buffer = new byte[BUFFER_SIZE];
243         try {
244             inputStream = getAssets().open(StringConstants.OIC_CLIENT_JSON_DB_FILE);
245             File file = new File(filePath);
246             //check files directory exists
247             if (!(file.exists() && file.isDirectory())) {
248                 file.mkdirs();
249             }
250             outputStream = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);
251             while ((length = inputStream.read(buffer)) != -1) {
252                 outputStream.write(buffer, 0, length);
253             }
254         } catch (NullPointerException e) {
255             logMessage(TAG + "Null pointer exception " + e.getMessage());
256             Log.e(TAG, e.getMessage());
257         } catch (FileNotFoundException e) {
258             logMessage(TAG + "Json svr db file not found " + e.getMessage());
259             Log.e(TAG, e.getMessage());
260         } catch (IOException e) {
261             logMessage(TAG + StringConstants.OIC_CLIENT_JSON_DB_FILE + " file copy failed");
262             Log.e(TAG, e.getMessage());
263         } finally {
264             if (inputStream != null) {
265                 try {
266                     inputStream.close();
267                 } catch (IOException e) {
268                     Log.e(TAG, e.getMessage());
269                 }
270             }
271             if (outputStream != null) {
272                 try {
273                     outputStream.close();
274                 } catch (IOException e) {
275                     Log.e(TAG, e.getMessage());
276                 }
277             }
278         }
279     }
280
281     public void logMessage(String text) {
282         logMsg(text);
283     }
284
285     public void logMsg(final String text) {
286         runOnUiThread(new Runnable() {
287             public void run() {
288                 Message msg = new Message();
289                 msg.obj = text;
290                 mEventsTextView.append(text);
291                 mEventsTextView.append("\n\n");
292             }
293         });
294         Log.i(TAG, text);
295         Intent intent = new Intent(getPackageName());
296         intent.putExtra(StringConstants.MESSAGE, text);
297         sendBroadcast(intent);
298     }
299
300     private class DiscoveryOTTransferAsyncTask extends AsyncTask<Void, String, String> {
301
302         @Override
303         protected void onPreExecute() {
304             super.onPreExecute();
305         }
306
307         @Override
308         protected String doInBackground(Void... params) {
309             try {
310                 /**
311                  * Discover Un-owned devices
312                  */
313                 publishProgress(TAG + "Discovering Unowned Devices");
314                 deviceList = new ArrayList<OcSecureResource>(OcProvisioning.discoverUnownedDevices
315                         (StringConstants.DISCOVERY_TIMEOUT_10));
316                 if (deviceList.size() > 0) {
317                     unownedDevCount = deviceList.size();
318                     for (int i = 0; i < deviceList.size(); i++) {
319                         publishProgress(TAG + "Un-owned Discovered Device " + (i + 1) + "= " +
320                                 deviceList.get(i).getDeviceID());
321                     }
322                     try {
323                         OcProvisioning.SetownershipTransferCBdata(OxmType.OIC_JUST_WORKS,
324                                 pinCallbackListener);
325                         for (int i = 0; i < deviceList.size(); i++) {
326                             publishProgress(TAG + "Doing Ownership Transfer for " +
327                                     deviceList.get(i).getDeviceID());
328                             deviceList.get(i).doOwnershipTransfer(ProvisioningClient.this);
329                         }
330                     } catch (OcException e) {
331                         publishProgress(TAG + "Ownership Transfer error: " + e.getMessage());
332                         return "Ownership Transfer error: " + e.getMessage();
333
334                     }
335                 } else {
336                     publishProgress(TAG + "No un-owned devices present");
337                     new OwnedDiscoveryAsyncTask().execute();
338                 }
339             } catch (OcException e) {
340                 publishProgress(TAG + "Un-owned discovery error: " + e.getMessage());
341                 return "Un-owned discovery error:  " + e.getMessage();
342             }
343             return "success";
344         }
345
346         @Override
347         protected void onProgressUpdate(String... values) {
348             logMessage(values[0]);
349         }
350
351         @Override
352         protected void onPostExecute(String s) {
353             super.onPostExecute(s);
354         }
355     }
356
357     private class ProvisionACLAsyncTask extends AsyncTask<Void, String, Void> {
358
359         @Override
360         protected void onPreExecute() {
361             super.onPreExecute();
362         }
363
364         @Override
365         protected Void doInBackground(Void... params) {
366             try {
367                 if (ownedDeviceList.size() > 1) {
368                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
369                     OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
370                     publishProgress(TAG + "ACL Provision for " + ocSecureResource.getDeviceID());
371                     List<String> resources = new ArrayList<String>();
372                     List<String> owners = new ArrayList<String>();
373                     List<String> periods = new ArrayList<String>();
374                     List<String> recurrences = new ArrayList<String>();
375                     recurrences.add("Daily");
376                     resources.add("*");
377                     owners.add("adminDeviceUUID0");
378                     periods.add("01-01-15");
379                     OicSecAcl aclObject = new OicSecAcl(ocSecureResourceDest.getDeviceID(),
380                             recurrences, periods, 31, resources, owners);
381                     ocSecureResource.provisionACL(aclObject, provisionAclListener);
382                 } else {
383                     publishProgress(TAG + "No Owned devices present");
384                 }
385             } catch (Exception e) {
386                 publishProgress(TAG + "ProvisionACL error: " + e.getMessage());
387             }
388             return null;
389         }
390
391         @Override
392         protected void onProgressUpdate(String... values) {
393             logMessage(values[0]);
394         }
395     }
396
397     private class ProvisionCredentialAsyncTask extends AsyncTask<Void, String, Void> {
398
399         @Override
400         protected void onPreExecute() {
401             super.onPreExecute();
402         }
403
404         @Override
405         protected Void doInBackground(Void... params) {
406             try {
407                 if (ownedDeviceList.size() > 1) {
408                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
409                     OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
410                     publishProgress(TAG + "ProvisionCredential for " +
411                             ocSecureResource.getDeviceID() + " with " +
412                             ocSecureResourceDest.getDeviceID());
413                     ocSecureResource.provisionCredentials(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
414                             KeySize.OWNER_PSK_LENGTH_128,
415                             ocSecureResourceDest, provisionCredentialsListener);
416                 } else {
417                     publishProgress(TAG + "Cannot perform credentials between devices");
418                 }
419             } catch (Exception e) {
420                 publishProgress(TAG + "Provision credentials error: " + e.getMessage());
421             }
422             return null;
423         }
424
425         @Override
426         protected void onProgressUpdate(String... values) {
427             logMessage(values[0]);
428         }
429     }
430
431     private class GetLinkedDevicesAsyncTask extends AsyncTask<Void, String, String> {
432
433         @Override
434         protected void onPreExecute() {
435             super.onPreExecute();
436         }
437
438         @Override
439         protected String doInBackground(Void... params) {
440             try {
441                 if (ownedDeviceList.size() > 1) {
442                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
443                     publishProgress(TAG + "Get linked devices of " + ocSecureResource.getDeviceID());
444                     List<String> linkedDevices = ocSecureResource.getLinkedDevices();
445                     if (linkedDevices.size() > 0) {
446                         for (int i = 0; i < linkedDevices.size(); i++) {
447                             publishProgress(TAG + "Linked Devices "+
448                                     (i + 1) + "= " + linkedDevices.get(i));
449                         }
450                     } else {
451                         publishProgress(TAG + "No linked Devices found");
452                     }
453                 } else {
454                     publishProgress(TAG + "Cannot perform linked devices");
455                 }
456             } catch (Exception e) {
457                 publishProgress(TAG + "getLinked device error: " + e.getMessage());
458                 return "failed";
459             }
460             return "success";
461         }
462
463         @Override
464         protected void onProgressUpdate(String... values) {
465             logMessage(values[0]);
466         }
467
468         @Override
469         protected void onPostExecute(String s) {
470             if ("success".equals(s)) {
471                 new ProvisionUnlinkAsyncTask().execute();
472             }
473         }
474     }
475
476     private class ProvisionUnlinkAsyncTask extends AsyncTask<Void, String, Void> {
477
478         @Override
479         protected void onPreExecute() {
480             super.onPreExecute();
481         }
482
483         @Override
484         protected Void doInBackground(Void... params) {
485             try {
486                 if (ownedDeviceList.size() > 1) {
487                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
488                     OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
489                     publishProgress(TAG + "Un linking  " + ocSecureResource.getDeviceID() +
490                             " with " + ocSecureResourceDest.getDeviceID());
491                     ocSecureResource.unlinkDevices(ocSecureResourceDest, unlinkDevicesListener);
492                 } else {
493                     publishProgress(TAG + "Cannot perform unlink devices");
494                 }
495             } catch (Exception e) {
496                 publishProgress(TAG + "Unlink error: " + e.getMessage());
497             }
498             return null;
499         }
500
501         @Override
502         protected void onProgressUpdate(String... values) {
503             logMessage(values[0]);
504         }
505     }
506
507     private class DeviceRevocationAsyncTask extends AsyncTask<Void, String, Void> {
508
509         @Override
510         protected void onPreExecute() {
511             super.onPreExecute();
512         }
513
514         @Override
515         protected Void doInBackground(Void... params) {
516             try {
517                 if (ownedDeviceList.size() > 0) {
518                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
519                     publishProgress(TAG + "Removing " + ocSecureResource.getDeviceID());
520                     ocSecureResource.removeDevice(StringConstants.DISCOVERY_TIMEOUT_20,
521                             removeDeviceListener);
522                 } else {
523                     publishProgress(TAG + "Cannot remove");
524                 }
525             } catch (Exception e) {
526                 publishProgress(TAG + "Remove Device error: " + e.getMessage());
527             }
528             return null;
529         }
530
531         @Override
532         protected void onProgressUpdate(String... values) {
533             logMessage(values[0]);
534         }
535     }
536
537     private class OwnedDiscoveryAsyncTask extends AsyncTask<Void, String, String> {
538
539         @Override
540         protected void onPreExecute() {
541             super.onPreExecute();
542         }
543
544         @Override
545         protected String doInBackground(Void... params) {
546             try {
547                 publishProgress(TAG + "Initiate Owned device Discovery");
548                 ownedDeviceList = OcProvisioning.discoverOwnedDevices
549                     (StringConstants.DISCOVERY_TIMEOUT_10);
550                 if (ownedDeviceList.size() > 0) {
551                     for (int i = 0; i < ownedDeviceList.size(); i++) {
552                         publishProgress(TAG + "Owned Discovered Device " + (i + 1) + "= " +
553                                         ownedDeviceList.get(i).getDeviceID()
554                                         + "\nIP Address= " + ownedDeviceList.get(i).getIpAddr()
555                                         + "\nOwned Status= " + ownedDeviceList.get(i).getOwnedStatus()
556                                         + "\nDevice Status= " + ((ownedDeviceList.get(i).
557                                         getDeviceStatus() == DeviceStatus.ON) ? "ON" : "OFF")
558                         );
559                     }
560                 } else {
561                     publishProgress(TAG + "No Owned devices present");
562                 }
563             } catch (OcException e) {
564                 publishProgress(TAG + "Owned device Discovery error: " + e.getMessage());
565                 return "Owned device Discovery error: " + e.getMessage();
566             }
567             return "success";
568         }
569
570         @Override
571         protected void onProgressUpdate(String... values) {
572             logMessage(values[0]);
573         }
574
575         @Override
576         protected void onPostExecute(String s) {
577             if (ownedDeviceList.size() > 1 && "success".equals(s)) {
578                 doPairwiseProvisioning();
579             }
580         }
581     }
582
583     /**
584      * to display on Server Message on Client screen
585      */
586     public class MessageReceiver extends BroadcastReceiver {
587         @Override
588         public void onReceive(Context context, Intent intent) {
589             final String message = intent.getStringExtra(StringConstants.MESSAGE);
590             logMessage(message);
591         }
592     }
593 }