Modified Android to resolve
[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> periods = new ArrayList<String>();
202             List<String> recurrences = new ArrayList<String>();
203             String rownerID= "61646d69-6e44-6576-6963-655555494430";
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, rownerID);
210             OicSecAcl acl2 = new OicSecAcl(newSecureResource2.getDeviceID(), recurrences, periods,
211                     31, resources, rownerID);
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                     
373                     List<String> periods = new ArrayList<String>();
374                     List<String> recurrences = new ArrayList<String>();
375
376                     String rownerID="61646d69-6e44-6576-6963-655555494430";
377
378                     recurrences.add("Daily");
379                     resources.add("*");
380                     
381                     periods.add("01-01-15");
382                     OicSecAcl aclObject = new OicSecAcl(ocSecureResourceDest.getDeviceID(),
383                             recurrences, periods, 31, resources, rownerID);
384                     ocSecureResource.provisionACL(aclObject, provisionAclListener);
385                 } else {
386                     publishProgress(TAG + "No Owned devices present");
387                 }
388             } catch (Exception e) {
389                 publishProgress(TAG + "ProvisionACL error: " + e.getMessage());
390             }
391             return null;
392         }
393
394         @Override
395         protected void onProgressUpdate(String... values) {
396             logMessage(values[0]);
397         }
398     }
399
400     private class ProvisionCredentialAsyncTask extends AsyncTask<Void, String, Void> {
401
402         @Override
403         protected void onPreExecute() {
404             super.onPreExecute();
405         }
406
407         @Override
408         protected Void doInBackground(Void... params) {
409             try {
410                 if (ownedDeviceList.size() > 1) {
411                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
412                     OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
413                     publishProgress(TAG + "ProvisionCredential for " +
414                             ocSecureResource.getDeviceID() + " with " +
415                             ocSecureResourceDest.getDeviceID());
416                     ocSecureResource.provisionCredentials(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
417                             KeySize.OWNER_PSK_LENGTH_128,
418                             ocSecureResourceDest, provisionCredentialsListener);
419                 } else {
420                     publishProgress(TAG + "Cannot perform credentials between devices");
421                 }
422             } catch (Exception e) {
423                 publishProgress(TAG + "Provision credentials error: " + e.getMessage());
424             }
425             return null;
426         }
427
428         @Override
429         protected void onProgressUpdate(String... values) {
430             logMessage(values[0]);
431         }
432     }
433
434     private class GetLinkedDevicesAsyncTask extends AsyncTask<Void, String, String> {
435
436         @Override
437         protected void onPreExecute() {
438             super.onPreExecute();
439         }
440
441         @Override
442         protected String doInBackground(Void... params) {
443             try {
444                 if (ownedDeviceList.size() > 1) {
445                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
446                     publishProgress(TAG + "Get linked devices of " + ocSecureResource.getDeviceID());
447                     List<String> linkedDevices = ocSecureResource.getLinkedDevices();
448                     if (linkedDevices.size() > 0) {
449                         for (int i = 0; i < linkedDevices.size(); i++) {
450                             publishProgress(TAG + "Linked Devices "+
451                                     (i + 1) + "= " + linkedDevices.get(i));
452                         }
453                     } else {
454                         publishProgress(TAG + "No linked Devices found");
455                     }
456                 } else {
457                     publishProgress(TAG + "Cannot perform linked devices");
458                 }
459             } catch (Exception e) {
460                 publishProgress(TAG + "getLinked device error: " + e.getMessage());
461                 return "failed";
462             }
463             return "success";
464         }
465
466         @Override
467         protected void onProgressUpdate(String... values) {
468             logMessage(values[0]);
469         }
470
471         @Override
472         protected void onPostExecute(String s) {
473             if ("success".equals(s)) {
474                 new ProvisionUnlinkAsyncTask().execute();
475             }
476         }
477     }
478
479     private class ProvisionUnlinkAsyncTask extends AsyncTask<Void, String, Void> {
480
481         @Override
482         protected void onPreExecute() {
483             super.onPreExecute();
484         }
485
486         @Override
487         protected Void doInBackground(Void... params) {
488             try {
489                 if (ownedDeviceList.size() > 1) {
490                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
491                     OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
492                     publishProgress(TAG + "Un linking  " + ocSecureResource.getDeviceID() +
493                             " with " + ocSecureResourceDest.getDeviceID());
494                     ocSecureResource.unlinkDevices(ocSecureResourceDest, unlinkDevicesListener);
495                 } else {
496                     publishProgress(TAG + "Cannot perform unlink devices");
497                 }
498             } catch (Exception e) {
499                 publishProgress(TAG + "Unlink error: " + e.getMessage());
500             }
501             return null;
502         }
503
504         @Override
505         protected void onProgressUpdate(String... values) {
506             logMessage(values[0]);
507         }
508     }
509
510     private class DeviceRevocationAsyncTask extends AsyncTask<Void, String, Void> {
511
512         @Override
513         protected void onPreExecute() {
514             super.onPreExecute();
515         }
516
517         @Override
518         protected Void doInBackground(Void... params) {
519             try {
520                 if (ownedDeviceList.size() > 0) {
521                     OcSecureResource ocSecureResource = ownedDeviceList.get(0);
522                     publishProgress(TAG + "Removing " + ocSecureResource.getDeviceID());
523                     ocSecureResource.removeDevice(StringConstants.DISCOVERY_TIMEOUT_20,
524                             removeDeviceListener);
525                 } else {
526                     publishProgress(TAG + "Cannot remove");
527                 }
528             } catch (Exception e) {
529                 publishProgress(TAG + "Remove Device error: " + e.getMessage());
530             }
531             return null;
532         }
533
534         @Override
535         protected void onProgressUpdate(String... values) {
536             logMessage(values[0]);
537         }
538     }
539
540     private class OwnedDiscoveryAsyncTask extends AsyncTask<Void, String, String> {
541
542         @Override
543         protected void onPreExecute() {
544             super.onPreExecute();
545         }
546
547         @Override
548         protected String doInBackground(Void... params) {
549             try {
550                 publishProgress(TAG + "Initiate Owned device Discovery");
551                 ownedDeviceList = OcProvisioning.discoverOwnedDevices
552                     (StringConstants.DISCOVERY_TIMEOUT_10);
553                 if (ownedDeviceList.size() > 0) {
554                     for (int i = 0; i < ownedDeviceList.size(); i++) {
555                         publishProgress(TAG + "Owned Discovered Device " + (i + 1) + "= " +
556                                         ownedDeviceList.get(i).getDeviceID()
557                                         + "\nIP Address= " + ownedDeviceList.get(i).getIpAddr()
558                                         + "\nOwned Status= " + ownedDeviceList.get(i).getOwnedStatus()
559                                         + "\nDevice Status= " + ((ownedDeviceList.get(i).
560                                         getDeviceStatus() == DeviceStatus.ON) ? "ON" : "OFF")
561                         );
562                     }
563                 } else {
564                     publishProgress(TAG + "No Owned devices present");
565                 }
566             } catch (OcException e) {
567                 publishProgress(TAG + "Owned device Discovery error: " + e.getMessage());
568                 return "Owned device Discovery error: " + e.getMessage();
569             }
570             return "success";
571         }
572
573         @Override
574         protected void onProgressUpdate(String... values) {
575             logMessage(values[0]);
576         }
577
578         @Override
579         protected void onPostExecute(String s) {
580             if (ownedDeviceList.size() > 1 && "success".equals(s)) {
581                 doPairwiseProvisioning();
582             }
583         }
584     }
585
586     /**
587      * to display on Server Message on Client screen
588      */
589     public class MessageReceiver extends BroadcastReceiver {
590         @Override
591         public void onReceive(Context context, Intent intent) {
592             final String message = intent.getStringExtra(StringConstants.MESSAGE);
593             logMessage(message);
594         }
595     }
596 }