Imported Upstream version 1.1.0
[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
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;
32
33 import java.io.File;
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;
42
43 public class ProvisioningClient extends Activity implements
44         OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwiseDevicesListener {
45
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() {
51                 @Override
52                 public String pinCallbackListener() {
53                     Log.d(TAG, "Inside Pin Callback ");
54                     return "";
55                 }
56             };
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() {
64                 @Override
65                 public void provisionAclListener(List<ProvisionResult> provisionResults,
66                                                  int hasError) {
67                     Log.d(TAG, "Inside ProvisionAclListener ");
68                     if (hasError == StringConstants.ERROR_CODE) {
69                         logMessage("Error: ACL Provision failed !!");
70                     } else {
71                         logMessage("ACL Provision Done !!");
72                         new DeviceRevocationAsyncTask().execute();
73                     }
74                 }
75             };
76     OcSecureResource.ProvisionCredentialsListener provisionCredentialsListener =
77             new OcSecureResource.ProvisionCredentialsListener() {
78                 @Override
79                 public void provisionCredentialsListener(List<ProvisionResult> provisionResults,
80                                                          int hasError) {
81                     Log.d(TAG, "Inside ProvisionCredentialsListener ");
82                     if (hasError == StringConstants.ERROR_CODE) {
83                         logMessage("Error: Provision Credentials failed !!");
84                     } else {
85                         logMessage("Provision Credentials Done !!");
86                         new ProvisionACLAsyncTask().execute();
87                     }
88                 }
89             };
90     OcSecureResource.UnlinkDevicesListener unlinkDevicesListener =
91             new OcSecureResource.UnlinkDevicesListener() {
92                 @Override
93                 public void unlinkDevicesListener(List<ProvisionResult> provisionResults,
94                                                   int hasError) {
95                     Log.d(TAG, "Inside unlinkDevicesListener ");
96                     if (hasError == StringConstants.ERROR_CODE) {
97                         logMessage("Error: UnLinking device !!");
98                     } else {
99                         logMessage("Unlink Done !!");
100                         new ProvisionCredentialAsyncTask().execute();
101                     }
102                 }
103             };
104     OcSecureResource.RemoveDeviceListener removeDeviceListener =
105             new OcSecureResource.RemoveDeviceListener() {
106                 @Override
107                 public void removeDeviceListener(List<ProvisionResult> provisionResults,
108                                                  int hasError) {
109                     if (hasError == StringConstants.ERROR_CODE) {
110                         logMessage("Error: Remove Fail !!");
111                     } else {
112                         logMessage("Remove Device done !!");
113                     }
114                 }
115             };
116
117     @Override
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)
127         );
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);
132         if (isFirstRun) {
133             copyCborFromAsset();
134             SharedPreferences.Editor editor = wmbPreference.edit();
135             editor.putBoolean("FIRSTRUN", false);
136             editor.commit();
137         }
138         initOICStack();
139     }
140
141     /**
142      * configure OIC platform and call findResource
143      */
144     private void initOICStack() {
145         //create platform config
146         PlatformConfig cfg = new PlatformConfig(
147                 this,
148                 ServiceType.IN_PROC,
149                 ModeType.CLIENT_SERVER,
150                 "0.0.0.0", // bind to all available interfaces
151                 0,
152                 QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
153         OcPlatform.Configure(cfg);
154         try {
155             /*
156              * Initialize DataBase
157              */
158             String sqlDbPath = getFilesDir().getAbsolutePath().replace("files", "databases") +
159                     File.separator;
160             File file = new File(sqlDbPath);
161             //check files directory exists
162             if (!(file.isDirectory())) {
163                 file.mkdirs();
164                 Log.d(TAG, "Sql db directory created at " + sqlDbPath);
165             }
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());
171         }
172         new DiscoveryOTTransferAsyncTask().execute();
173     }
174
175     @Override
176     synchronized public void doOwnershipTransferListener(List<ProvisionResult> ProvisionResultList,
177                                                          int hasError) {
178         ProvisionResult pResult = ProvisionResultList.get(0);
179         if (hasError == StringConstants.ERROR_CODE) {
180             logMessage(TAG + "Ownership Transfer Failed for " + pResult.getDevId());
181         } else {
182             logMessage(TAG + "Ownership Transfer Successful for "
183                     + pResult.getDevId());
184             unownedDevCount--;
185         }
186         if (unownedDevCount == 0) { //When done with Ownership Transfer
187             new OwnedDiscoveryAsyncTask().execute();
188         }
189     }
190
191     private void doPairwiseProvisioning() {
192         try {
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());
212         }
213     }
214
215     @Override
216     public void provisionPairwiseDevicesListener(List<ProvisionResult> ProvisionResultList,
217                                                  int hasError) {
218         if (hasError == StringConstants.ERROR_CODE) {
219             logMessage(TAG + "provisionPairwiseDevices Failed");
220         } else {
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());
225             }
226             new GetLinkedDevicesAsyncTask().execute();
227         }
228     }
229
230     /**
231      * Copy svr db CBOR dat file from assets folder to app data files dir
232      */
233     private void copyCborFromAsset() {
234         InputStream inputStream = null;
235         OutputStream outputStream = null;
236         int length;
237         byte[] buffer = new byte[BUFFER_SIZE];
238         try {
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())) {
243                 file.mkdirs();
244             }
245             outputStream = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
246             while ((length = inputStream.read(buffer)) != -1) {
247                 outputStream.write(buffer, 0, length);
248             }
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());
258         } finally {
259             if (inputStream != null) {
260                 try {
261                     inputStream.close();
262                 } catch (IOException e) {
263                     Log.e(TAG, e.getMessage());
264                 }
265             }
266             if (outputStream != null) {
267                 try {
268                     outputStream.close();
269                 } catch (IOException e) {
270                     Log.e(TAG, e.getMessage());
271                 }
272             }
273         }
274     }
275
276     public void logMessage(String text) {
277         logMsg(text);
278     }
279
280     public void logMsg(final String text) {
281         runOnUiThread(new Runnable() {
282             public void run() {
283                 Message msg = new Message();
284                 msg.obj = text;
285                 mEventsTextView.append(text);
286                 mEventsTextView.append("\n\n");
287             }
288         });
289         Log.i(TAG, text);
290         Intent intent = new Intent(getPackageName());
291         intent.putExtra(StringConstants.MESSAGE, text);
292         sendBroadcast(intent);
293     }
294
295     private class DiscoveryOTTransferAsyncTask extends AsyncTask<Void, String, String> {
296
297         @Override
298         protected void onPreExecute() {
299             super.onPreExecute();
300         }
301
302         @Override
303         protected String doInBackground(Void... params) {
304             try {
305                 /**
306                  * Discover Un-owned devices
307                  */
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());
316                     }
317                     try {
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);
324                         }
325                     } catch (OcException e) {
326                         publishProgress(TAG + "Ownership Transfer error: " + e.getMessage());
327                         return "Ownership Transfer error: " + e.getMessage();
328
329                     }
330                 } else {
331                     publishProgress(TAG + "No un-owned devices present");
332                     new OwnedDiscoveryAsyncTask().execute();
333                 }
334             } catch (OcException e) {
335                 publishProgress(TAG + "Un-owned discovery error: " + e.getMessage());
336                 return "Un-owned discovery error:  " + e.getMessage();
337             }
338             return "success";
339         }
340
341         @Override
342         protected void onProgressUpdate(String... values) {
343             logMessage(values[0]);
344         }
345
346         @Override
347         protected void onPostExecute(String s) {
348             super.onPostExecute(s);
349         }
350     }
351
352     private class ProvisionACLAsyncTask extends AsyncTask<Void, String, Void> {
353
354         @Override
355         protected void onPreExecute() {
356             super.onPreExecute();
357         }
358
359         @Override
360         protected Void doInBackground(Void... params) {
361             try {
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);
376                 } else {
377                     publishProgress(TAG + "No Owned devices present");
378                 }
379             } catch (Exception e) {
380                 publishProgress(TAG + "ProvisionACL error: " + e.getMessage());
381             }
382             return null;
383         }
384
385         @Override
386         protected void onProgressUpdate(String... values) {
387             logMessage(values[0]);
388         }
389     }
390
391     private class ProvisionCredentialAsyncTask extends AsyncTask<Void, String, Void> {
392
393         @Override
394         protected void onPreExecute() {
395             super.onPreExecute();
396         }
397
398         @Override
399         protected Void doInBackground(Void... params) {
400             try {
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);
410                 } else {
411                     publishProgress(TAG + "Cannot perform credentials between devices");
412                 }
413             } catch (Exception e) {
414                 publishProgress(TAG + "Provision credentials error: " + e.getMessage());
415             }
416             return null;
417         }
418
419         @Override
420         protected void onProgressUpdate(String... values) {
421             logMessage(values[0]);
422         }
423     }
424
425     private class GetLinkedDevicesAsyncTask extends AsyncTask<Void, String, String> {
426
427         @Override
428         protected void onPreExecute() {
429             super.onPreExecute();
430         }
431
432         @Override
433         protected String doInBackground(Void... params) {
434             try {
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));
443                         }
444                     } else {
445                         publishProgress(TAG + "No linked Devices found");
446                     }
447                 } else {
448                     publishProgress(TAG + "Cannot perform linked devices");
449                 }
450             } catch (Exception e) {
451                 publishProgress(TAG + "getLinked device error: " + e.getMessage());
452                 return "failed";
453             }
454             return "success";
455         }
456
457         @Override
458         protected void onProgressUpdate(String... values) {
459             logMessage(values[0]);
460         }
461
462         @Override
463         protected void onPostExecute(String s) {
464             if ("success".equals(s)) {
465                 new ProvisionUnlinkAsyncTask().execute();
466             }
467         }
468     }
469
470     private class ProvisionUnlinkAsyncTask extends AsyncTask<Void, String, Void> {
471
472         @Override
473         protected void onPreExecute() {
474             super.onPreExecute();
475         }
476
477         @Override
478         protected Void doInBackground(Void... params) {
479             try {
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);
486                 } else {
487                     publishProgress(TAG + "Cannot perform unlink devices");
488                 }
489             } catch (Exception e) {
490                 publishProgress(TAG + "Unlink error: " + e.getMessage());
491             }
492             return null;
493         }
494
495         @Override
496         protected void onProgressUpdate(String... values) {
497             logMessage(values[0]);
498         }
499     }
500
501     private class DeviceRevocationAsyncTask extends AsyncTask<Void, String, Void> {
502
503         @Override
504         protected void onPreExecute() {
505             super.onPreExecute();
506         }
507
508         @Override
509         protected Void doInBackground(Void... params) {
510             try {
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);
516                 } else {
517                     publishProgress(TAG + "Cannot remove");
518                 }
519             } catch (Exception e) {
520                 publishProgress(TAG + "Remove Device error: " + e.getMessage());
521             }
522             return null;
523         }
524
525         @Override
526         protected void onProgressUpdate(String... values) {
527             logMessage(values[0]);
528         }
529     }
530
531     private class OwnedDiscoveryAsyncTask extends AsyncTask<Void, String, String> {
532
533         @Override
534         protected void onPreExecute() {
535             super.onPreExecute();
536         }
537
538         @Override
539         protected String doInBackground(Void... params) {
540             try {
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")
552                         );
553                     }
554                 } else {
555                     publishProgress(TAG + "No Owned devices present");
556                 }
557             } catch (OcException e) {
558                 publishProgress(TAG + "Owned device Discovery error: " + e.getMessage());
559                 return "Owned device Discovery error: " + e.getMessage();
560             }
561             return "success";
562         }
563
564         @Override
565         protected void onProgressUpdate(String... values) {
566             logMessage(values[0]);
567         }
568
569         @Override
570         protected void onPostExecute(String s) {
571             if (ownedDeviceList.size() > 1 && "success".equals(s)) {
572                 doPairwiseProvisioning();
573             }
574         }
575     }
576
577     /**
578      * to display on Server Message on Client screen
579      */
580     public class MessageReceiver extends BroadcastReceiver {
581         @Override
582         public void onReceive(Context context, Intent intent) {
583             final String message = intent.getStringExtra(StringConstants.MESSAGE);
584             logMessage(message);
585         }
586     }
587 }