Merge branch 'master' into cloud-interface
[platform/upstream/iotivity.git] / android / examples / simplebase / src / main / java / org / iotivity / base / examples / MessageFragment.java
1 /*
2  * ******************************************************************
3  *
4  * Copyright 2016 Samsung Electronics All Rights Reserved.
5  *
6  * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22
23 package org.iotivity.base.examples;
24
25 import android.app.Activity;
26 import android.app.AlertDialog;
27 import android.app.Fragment;
28 import android.content.Context;
29 import android.content.DialogInterface;
30 import android.content.Intent;
31 import android.nfc.NfcAdapter;
32 import android.os.Bundle;
33 import android.util.Log;
34 import android.view.LayoutInflater;
35 import android.view.View;
36 import android.view.ViewGroup;
37 import android.widget.Button;
38 import android.widget.CompoundButton;
39 import android.widget.EditText;
40 import android.widget.LinearLayout;
41 import android.widget.TextView;
42 import android.widget.Toast;
43 import android.widget.ToggleButton;
44
45 import org.iotivity.base.EntityHandlerResult;
46 import org.iotivity.base.ModeType;
47 import org.iotivity.base.OcConnectivityType;
48 import org.iotivity.base.OcException;
49 import org.iotivity.base.OcHeaderOption;
50 import org.iotivity.base.OcPlatform;
51 import org.iotivity.base.OcRepresentation;
52 import org.iotivity.base.OcResource;
53 import org.iotivity.base.OcResourceHandle;
54 import org.iotivity.base.OcResourceRequest;
55 import org.iotivity.base.OcResourceResponse;
56 import org.iotivity.base.PlatformConfig;
57 import org.iotivity.base.QualityOfService;
58 import org.iotivity.base.ServiceType;
59 import org.iotivity.ca.CaEdrInterface;
60 import org.iotivity.ca.CaIpInterface;
61 import org.iotivity.ca.CaLeClientInterface;
62
63 import java.io.PrintWriter;
64 import java.io.StringWriter;
65 import java.util.ArrayList;
66 import java.util.EnumSet;
67 import java.util.HashMap;
68 import java.util.List;
69 import java.util.Map;
70
71 /**
72  * This class is for messaging between the server and the client.
73  * It can handle message manually.
74  */
75 public class MessageFragment extends Fragment implements OcResource.OnGetListener,
76                                                          OcResource.OnPutListener {
77
78     private static final String TAG          = "OIC_SIMPLE_MESSAGE";
79     private final String        EOL          = System.getProperties().getProperty("line.separator");
80     private final double        MILLI_PER_SEC = 1000.0;
81
82     private Activity            mActivity;
83     private Context             mContext;
84
85     OcPlatform.EntityHandler    mEntityHandler;
86     private OcResourceHandle    mResourceHandle;
87     private OcResource          mFoundResource;
88
89     private QualityOfService    mQos         = QualityOfService.LOW;
90
91     private LinearLayout        mServerLayout;
92     private LinearLayout        mClientLayout;
93     private TextView            mResourceText;
94     private TextView            mActionLog;
95     private TextView            mResultLog;
96     private ToggleButton        mQosToggle;
97     private Button              mRegisterButton;
98     private Button              mGetButton;
99     private Button              mPutButton;
100     private Button              mLargeButton;
101     private Button              mDiscoverIPButton;
102     private Button              mDiscoverBTButton;
103     private Button              mDiscoverLEButton;
104     private Button              mDiscoverTCPButton;
105     private Button              mDiscoverNFCButton;
106
107     private String              mLargeData;
108     private boolean             mState;
109     private long                mStartTime;
110     private long                mEndTime;
111
112     @Override
113     public void onCreate(Bundle savedInstanceState) {
114         super.onCreate(savedInstanceState);
115
116         mActivity = getActivity();
117         mContext = mActivity.getBaseContext();
118     }
119
120     View.OnClickListener getButtonListener() {
121         return new View.OnClickListener() {
122             @Override
123             public void onClick(View view) {
124                 if (mFoundResource != null) {
125                     mStartTime = System.currentTimeMillis();
126                     sendGetToFoundResource(Common.STATE_GET);
127                 } else {
128                     Common.showToast(mContext, "Please discovery first");
129                     Log.e(TAG, "get() : resource is null");
130                 }
131             }
132         };
133     }
134
135     View.OnClickListener putButtonListener() {
136         return new View.OnClickListener() {
137             @Override
138             public void onClick(View view) {
139                 if (mFoundResource != null) {
140                     mStartTime = System.currentTimeMillis();
141                     sendPutToFoundResource();
142                 } else {
143                     Common.showToast(mContext, "Please discovery first");
144                     Log.e(TAG, "put() : resource is null");
145                 }
146             }
147         };
148     }
149
150     View.OnClickListener getLargeListener() {
151         return new View.OnClickListener() {
152             @Override
153             public void onClick(View view) {
154                 if (mFoundResource != null) {
155                     mStartTime = System.currentTimeMillis();
156                     sendGetToFoundResource(Common.LARGE_GET);
157                 } else {
158                     Common.showToast(mContext, "Please discovery first");
159                     Log.e(TAG, "large() : resource is null");
160                 }
161             }
162         };
163     }
164
165     View.OnClickListener discoverButtonListener(
166             final OcConnectivityType connectivityType) {
167         return new View.OnClickListener() {
168             @Override
169             public void onClick(View view) {
170                 initOcPlatform(ModeType.CLIENT);
171                 mFoundResource = null;
172
173                 if (OcConnectivityType.CT_ADAPTER_TCP == connectivityType) {
174                     showTCPInput();
175                 } else {
176                     try {
177                         Log.i(TAG, "discoverButtonListener");
178                         OcPlatform.findResource("",
179                                                 OcPlatform.WELL_KNOWN_QUERY,
180                                                 EnumSet.of(connectivityType),
181                                                 resourceFoundListener, mQos);
182
183                         mActivity.runOnUiThread(new Runnable() {
184                             @Override
185                             public void run() {
186                                 mActionLog.setText("[Action Log]" + EOL);
187                                 mActionLog.append("Find resource()" + EOL);
188                                 mActionLog.append("Connectivity : " + connectivityType + EOL);
189
190                                 mResultLog.setText("[Result Log]" + EOL);
191                                 mResultLog.append("Start Time : ");
192                                 mResultLog.append(Common.getDateCurrentTimeZone() + EOL);
193                                 mStartTime = System.currentTimeMillis();
194                             }
195                         });
196                     } catch (OcException e) {
197                         e.printStackTrace();
198                     }
199                 }
200                 mServerLayout.setVisibility(View.GONE);
201             }
202         };
203     }
204
205     void makeTCPResource(String address) {
206
207         List<String> resourceTypeList = new ArrayList<String>();
208         List<String> resourceInterfaceList = new ArrayList<String>();
209         resourceInterfaceList.add(Common.RESOURCE_INTERFACE);
210         resourceTypeList.add(Common.RESOURCE_TYPE);
211         try {
212             mFoundResource = OcPlatform.constructResourceObject(address,
213                     Common.RESOURCE_URI,
214                     EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP), false,
215                     resourceTypeList, resourceInterfaceList);
216
217             mActionLog.setText("[Action Log]" + EOL);
218             mActionLog.append("Found resource()" + EOL);
219             mActionLog.append("Connectivity : " + OcConnectivityType.CT_ADAPTER_TCP + EOL);
220             mActionLog.append(mFoundResource.getHost() + Common.RESOURCE_URI);
221
222             mResultLog.setText("[Result Log]" + EOL);
223
224         } catch (OcException e) {
225             e.printStackTrace();
226         }
227     }
228
229     void sendGetToFoundResource(String command) {
230         try {
231             Log.i(TAG, "sendGetToFoundResource");
232
233             Map<String, String> queryParameters = new HashMap<String, String>();
234             queryParameters.put(Common.GET_COMMAND, command);
235
236             mFoundResource.get(queryParameters, this, mQos);
237
238             mActionLog.setText("[Action Log]" + EOL + "Send get()"+ EOL + "To : ");
239             mActionLog.append(mFoundResource.getHost() + mFoundResource.getUri() + EOL);
240         } catch (OcException e) {
241             e.printStackTrace();
242         }
243     }
244
245     void sendPutToFoundResource() {
246         try {
247             Log.i(TAG, "sendPutToFoundResource");
248
249             OcRepresentation rep = new OcRepresentation();
250             rep.setValue(Common.STATE_KEY, !mState);
251
252             Map<String, String> queryParams = new HashMap<>();
253
254             mFoundResource.put(rep, queryParams, this);
255             mActionLog.setText("[Action Log]" + EOL);
256             mActionLog.append("Send put()" + EOL + "To : ");
257             mActionLog.append(mFoundResource.getHost() + mFoundResource.getUri() + EOL);
258         } catch (OcException e) {
259             e.printStackTrace();
260         }
261     }
262
263     OcPlatform.OnResourceFoundListener resourceFoundListener =
264                                            new OcPlatform.OnResourceFoundListener() {
265         @Override
266         public void onResourceFound(OcResource ocResource) {
267             synchronized (mActivity) {
268                 final String resourceUri = ocResource.getUri();
269                 Log.i(TAG, "onResourceFound : " + ocResource.getUri());
270
271                 if (resourceUri.contains(Common.RESOURCE_URI)) {
272                     mFoundResource = ocResource;
273                     mActivity.runOnUiThread(new Runnable() {
274                         @Override
275                         public void run() {
276                             mEndTime = System.currentTimeMillis();
277                             double flightTime = (double) (mEndTime - mStartTime) / MILLI_PER_SEC;
278                             mResultLog.append("Discovery Time : ");
279                             mResultLog.append(String.format("%.3f", flightTime) + "sec" + EOL);
280                             mActionLog.append(mFoundResource.getHost() + resourceUri + EOL);
281                         }
282                     });
283                 }
284             }
285         }
286     };
287
288     @Override
289     public void onGetCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
290         String repUri = ocRepresentation.getUri();
291         Log.i(TAG, "onGetCompleted : " + repUri);
292
293         try {
294             final String command = ocRepresentation.getValue(Common.GET_COMMAND);
295
296             if (command == null || command.isEmpty()) {
297                 Log.e(TAG, "Get command is null");
298                 return;
299             } else if (command.equals(Common.STATE_GET)) {
300                 mState = ocRepresentation.getValue(Common.STATE_KEY);
301                 mLargeData = "";
302             } else if (command.equals(Common.LARGE_GET)) {
303                 mLargeData = ocRepresentation.getValue(Common.LARGE_KEY);
304             }
305         } catch (OcException e) {
306             e.printStackTrace();
307         }
308
309         mActivity.runOnUiThread(new Runnable() {
310             @Override
311             public void run() {
312                 mEndTime = System.currentTimeMillis();
313                 double flightTime = (double) (mEndTime - mStartTime) / MILLI_PER_SEC;
314
315                 if (mLargeData == null || mLargeData.isEmpty()) {
316                     mResultLog.append(EOL + "Get Light State : " + mState + EOL);
317                 } else {
318                     mResultLog.append(EOL + "Payload Size : " + mLargeData.length() + EOL);
319                 }
320
321                 mResultLog.append("Get Time : " + String.format("%.3f", flightTime) + "sec" + EOL);
322             }
323         });
324     }
325
326     @Override
327     public void onGetFailed(Throwable throwable) {
328         Log.e(TAG, "Get failed");
329     }
330
331     @Override
332     public void onPutCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
333         String repUri = ocRepresentation.getUri();
334         Log.i(TAG, "onPutCompleted : " + repUri);
335
336         try {
337             mState = ocRepresentation.getValue(Common.STATE_KEY);
338         } catch (OcException e) {
339             e.printStackTrace();
340         }
341
342         mActivity.runOnUiThread(new Runnable() {
343             @Override
344             public void run() {
345                 mEndTime = System.currentTimeMillis();
346                 double flightTime = (double) (mEndTime - mStartTime) / MILLI_PER_SEC;
347                 mResultLog.append(EOL + "Set Light State : " + !mState + EOL + "Put Time : ");
348                 mResultLog.append(String.format("%.3f", flightTime) + "sec" + EOL);
349             }
350         });
351     }
352
353     @Override
354     public void onPutFailed(Throwable throwable) {
355         Log.e(TAG, "Put failed");
356     }
357
358     // ******************************************************************************
359     // End of the OCF Client specific code
360     // ******************************************************************************
361
362     private void createResource() {
363         mEntityHandler = new OcPlatform.EntityHandler() {
364             @Override
365             public EntityHandlerResult handleEntity(
366                     OcResourceRequest ocResourceRequest) {
367                 return mEntityHandler(ocResourceRequest);
368             }
369         };
370
371         try {
372             mResourceHandle = OcPlatform.registerResource(Common.RESOURCE_URI,
373                                  Common.RESOURCE_TYPE, Common.RESOURCE_INTERFACE,
374                                  mEntityHandler, Common.RESOURCE_PROPERTIES);
375
376         } catch (OcException e) {
377             String errString = "Error : " + e.getErrorCode().toString();
378             Log.e(TAG, errString);
379             StringWriter sw = new StringWriter();
380             e.printStackTrace(new PrintWriter(sw));
381             String exceptionAsString = sw.toString();
382             Log.e(TAG, exceptionAsString);
383             mResourceText.setText(errString);
384         }
385
386         StringBuilder sb = new StringBuilder();
387         for (int i = 0; i < Common.DATA_SIZE; i++) {
388             sb.append('j');
389         }
390         mLargeData = sb.toString();
391
392         sb.setLength(0);
393         sb.append("URI :   " + Common.RESOURCE_URI + EOL);
394         sb.append("Type :   " + Common.RESOURCE_TYPE + EOL);
395         sb.append("Interface :   " + Common.RESOURCE_INTERFACE + EOL);
396         sb.append("Properties :   " + Common.RESOURCE_PROPERTIES.toString() + EOL);
397         mResourceText.setText(sb.toString());
398         mActionLog.setText("");
399         mResultLog.setText("Created resource" + EOL);
400     }
401
402     protected EntityHandlerResult mEntityHandler(OcResourceRequest ocResourceRequest) {
403         EntityHandlerResult result = EntityHandlerResult.ERROR;
404         final StringBuilder sb = new StringBuilder();
405         switch (ocResourceRequest.getRequestType()) {
406             case GET:
407                 sb.append("Type :   GET");
408                 if (sendGetResponse(ocResourceRequest)) {
409                     result = EntityHandlerResult.OK;
410                 }
411                 break;
412             case PUT:
413                 sb.append("Type :   PUT");
414                 if (sendPutResponse(ocResourceRequest)) {
415                     result = EntityHandlerResult.OK;
416                 }
417                 break;
418             case DELETE:
419                 sb.append("Type :   DELETE");
420                 break;
421             case POST:
422                 sb.append("Type :   POST");
423                 break;
424             default:
425                 break;
426         }
427         sb.append(EOL + "Light State :   " + mState);
428         sb.append(EOL + "Time :   " + Common.getDateCurrentTimeZone());
429         if (result == EntityHandlerResult.ERROR) {
430             sb.append(EOL + "!! Error occurred during sending the response !!");
431         }
432
433         mActivity.runOnUiThread(new Runnable() {
434             @Override
435             public void run() {
436                 mResultLog.setText(sb.toString());
437             }
438         });
439
440         return result;
441     }
442
443     private boolean sendGetResponse(OcResourceRequest ocResourceRequest) {
444         mActivity.runOnUiThread(new Runnable() {
445             @Override
446             public void run() {
447                 Common.showToast(mContext, "received get command, send response");
448             }
449         });
450
451         Map<String, String> queryParameters = ocResourceRequest.getQueryParameters();
452         final String command = queryParameters.get(Common.GET_COMMAND);
453
454         if (command == null
455                 || (!command.equals(Common.STATE_GET) && !command.equals(Common.LARGE_GET))) {
456             return false;
457         }
458
459         OcRepresentation rep = new OcRepresentation();
460         try {
461             rep.setValue(Common.GET_COMMAND, command);
462             if (command.equals(Common.STATE_GET)) {
463                 rep.setValue(Common.STATE_KEY, mState);
464             } else if (command.equals(Common.LARGE_GET)) {
465                 rep.setValue(Common.LARGE_KEY, mLargeData);
466             }
467         } catch (OcException e) {
468             e.printStackTrace();
469         }
470
471         OcResourceResponse response = new OcResourceResponse();
472
473         response.setRequestHandle(ocResourceRequest.getRequestHandle());
474         response.setResourceHandle(ocResourceRequest.getResourceHandle());
475         response.setResourceRepresentation(rep);
476         try {
477             OcPlatform.sendResponse(response);
478             return true;
479         } catch (OcException e) {
480             e.printStackTrace();
481             return false;
482         }
483     }
484
485     private boolean sendPutResponse(OcResourceRequest ocResourceRequest) {
486         mActivity.runOnUiThread(new Runnable() {
487             @Override
488             public void run() {
489                 Common.showToast(mContext, "received put command, send response");
490             }
491         });
492
493         try {
494             OcRepresentation rep = ocResourceRequest.getResourceRepresentation();
495             if (rep.hasAttribute(Common.STATE_KEY)) {
496                 mState = rep.getValue(Common.STATE_KEY);
497             }
498         } catch (OcException e) {
499             e.printStackTrace();
500         }
501
502         OcResourceResponse response = new OcResourceResponse();
503         OcRepresentation rep = new OcRepresentation();
504
505         response.setRequestHandle(ocResourceRequest.getRequestHandle());
506         response.setResourceHandle(ocResourceRequest.getResourceHandle());
507         response.setResourceRepresentation(rep);
508         try {
509             OcPlatform.sendResponse(response);
510             return true;
511         } catch (OcException e) {
512             e.printStackTrace();
513             return false;
514         }
515     }
516
517     // ******************************************************************************
518     // End of the OCF Server specific code
519     // ******************************************************************************
520
521     private void initOcPlatform(ModeType type) {
522         PlatformConfig cfg = new PlatformConfig(mActivity, mContext,
523                                                 ServiceType.IN_PROC,
524                                                 type,
525                                                 Common.IP_ADDRESS,
526                                                 Common.IP_PORT,
527                                                 mQos);
528         OcPlatform.Configure(cfg);
529     }
530
531     @Override
532     public View onCreateView(LayoutInflater inflater, ViewGroup container,
533             Bundle savedInstanceState) {
534         View rootView = inflater.inflate(R.layout.fragment_message, container, false);
535
536         mServerLayout = (LinearLayout) rootView.findViewById(R.id.server_layout);
537         mClientLayout = (LinearLayout) rootView.findViewById(R.id.client_layout);
538
539         mResourceText = (TextView) rootView.findViewById(R.id.resource_view);
540         mActionLog = (TextView) rootView.findViewById(R.id.action_log_view);
541         mResultLog = (TextView) rootView.findViewById(R.id.result_log_view);
542
543         mDiscoverIPButton = (Button) rootView.findViewById(R.id.ip_button);
544         mDiscoverBTButton = (Button) rootView.findViewById(R.id.bt_button);
545         mDiscoverLEButton = (Button) rootView.findViewById(R.id.le_button);
546         mDiscoverTCPButton = (Button) rootView.findViewById(R.id.tcp_button);
547         mDiscoverNFCButton = (Button) rootView.findViewById(R.id.nfc_button);
548
549         mRegisterButton = (Button) rootView.findViewById(R.id.register_button);
550         mGetButton = (Button) rootView.findViewById(R.id.get_button);
551         mPutButton = (Button) rootView.findViewById(R.id.put_button);
552         mLargeButton = (Button) rootView.findViewById(R.id.large_button);
553
554         mQosToggle = (ToggleButton) rootView.findViewById(R.id.qos_toggle_button);
555
556         mDiscoverIPButton.setOnClickListener(
557                 discoverButtonListener(OcConnectivityType.CT_ADAPTER_IP));
558         mDiscoverBTButton.setOnClickListener(
559                 discoverButtonListener(OcConnectivityType.CT_ADAPTER_RFCOMM_BTEDR));
560         mDiscoverLEButton.setOnClickListener(
561                 discoverButtonListener(OcConnectivityType.CT_ADAPTER_GATT_BTLE));
562         mDiscoverTCPButton.setOnClickListener(
563                 discoverButtonListener(OcConnectivityType.CT_ADAPTER_TCP));
564         mDiscoverNFCButton.setOnClickListener(
565                 discoverButtonListener(OcConnectivityType.CT_ADAPTER_NFC));
566
567         mRegisterButton.setOnClickListener(new View.OnClickListener() {
568             @Override
569             public void onClick(View view) {
570                 if (mResourceHandle == null) {
571                     initOcPlatform(ModeType.SERVER);
572                     createResource();
573                     mClientLayout.setVisibility(View.GONE);
574                 } else {
575                     Common.showToast(mContext, "Already created resource");
576                 }
577             }
578         });
579         mGetButton.setOnClickListener(getButtonListener());
580         mPutButton.setOnClickListener(putButtonListener());
581         mLargeButton.setOnClickListener(getLargeListener());
582
583         mQosToggle
584                 .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
585                     @Override
586                     public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
587                         if (b) {
588                             mQos = QualityOfService.HIGH;
589                         } else {
590                             mQos = QualityOfService.LOW;
591                         }
592                     }
593                 });
594
595         return rootView;
596     }
597
598     private void showTCPInput() {
599
600         LayoutInflater layoutInflater = LayoutInflater.from(mContext);
601         View inputView = layoutInflater.inflate(R.layout.tcp_input, null);
602         AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mActivity);
603         alertDialogBuilder.setView(inputView);
604
605         final EditText editText = (EditText) inputView.getRootView().findViewById(R.id.ipText);
606         editText.setText(Common.TCP_ADDRESS);
607         alertDialogBuilder
608                 .setCancelable(false)
609                 .setPositiveButton("OK", new DialogInterface.OnClickListener() {
610                     public void onClick(DialogInterface dialog, int id) {
611                         if (editText.getText().length() != 0) {
612                             Common.TCP_ADDRESS = editText.getText().toString();
613
614                             StringBuilder sb = new StringBuilder();
615                             sb.append(Common.COAP_TCP);
616                             sb.append(Common.TCP_ADDRESS);
617                             sb.append(Common.TCP_PORT);
618                             makeTCPResource(sb.toString());
619                         }
620                     }
621                 })
622                 .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
623                     public void onClick(DialogInterface dialog, int id) {
624                         dialog.cancel();
625                     }
626                 });
627
628         AlertDialog alert = alertDialogBuilder.create();
629         alert.show();
630     }
631
632     @Override
633     public void onResume() {
634         super.onResume();
635     }
636
637     @Override
638     public void onDestroy() {
639         super.onDestroy();
640     }
641 }