Merge test folder of test branch
[iotivity.git] / test / src / iBtestapp / modules / pm / android / src / org / iotivity / test / pm / app / PMLight.java
1 /******************************************************************
2  *
3  * Copyright 2017 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      LICENSE-2.0" target="_blank">http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *
20  ******************************************************************/
21 package org.iotivity.test.pm.app;
22
23 import android.content.Context;
24 import android.content.Intent;
25 import android.util.Log;
26
27 import org.iotivity.base.EntityHandlerResult;
28 import org.iotivity.base.ErrorCode;
29 import org.iotivity.base.ObservationInfo;
30 import org.iotivity.base.OcException;
31 import org.iotivity.base.OcPlatform;
32 import org.iotivity.base.OcRepresentation;
33 import org.iotivity.base.OcResource;
34 import org.iotivity.base.OcResourceHandle;
35 import org.iotivity.base.OcResourceRequest;
36 import org.iotivity.base.OcResourceResponse;
37 import org.iotivity.base.RequestHandlerFlag;
38 import org.iotivity.base.RequestType;
39 import org.iotivity.base.ResourceProperty;
40
41 import java.util.EnumSet;
42 import java.util.LinkedList;
43 import java.util.List;
44 import java.util.Map;
45
46 public class PMLight implements OcPlatform.EntityHandler {
47   private static final String NAME_KEY  = "name";
48   private static final String STATE_KEY = "state";
49   private static final String POWER_KEY = "power";
50
51   private String              mResourceUri;       // resource URI
52   private String              mResourceTypeName;  // resource type name.
53   private String              mResourceInterface; // resource interface.
54   private OcResourceHandle    mResourceHandle;    // resource handle
55
56   private String              mName;              // light name
57   private boolean             mState;             // light state
58   private int                 mPower;             // light power
59
60   public PMLight(String resourceUri, String name, boolean state, int power) {
61     mResourceUri = resourceUri;
62     mResourceTypeName = "core.light";
63     mResourceInterface = OcPlatform.DEFAULT_INTERFACE;
64     mResourceHandle = null; // this is set when resource is registered
65
66     mName = name;
67     mState = state;
68     mPower = power;
69   }
70
71   public synchronized void registerResource() throws OcException {
72     if (null == mResourceHandle) {
73       mResourceHandle = OcPlatform.registerResource(mResourceUri,
74           mResourceTypeName, mResourceInterface, this, EnumSet.of(
75               ResourceProperty.DISCOVERABLE, ResourceProperty.OBSERVABLE));
76     }
77   }
78
79   /**
80    * NOTE: This is just a sample implementation of entity handler. Entity
81    * handler can be implemented in several ways by the manufacturer.
82    *
83    * @param request
84    * @return
85    */
86   @Override
87   public synchronized EntityHandlerResult handleEntity(
88       final OcResourceRequest request) {
89     EntityHandlerResult ehResult = EntityHandlerResult.ERROR;
90     if (null == request) {
91       msg("Server request is invalid");
92       return ehResult;
93     }
94     // Get the request flags
95     EnumSet<RequestHandlerFlag> requestFlags = request
96         .getRequestHandlerFlagSet();
97     if (requestFlags.contains(RequestHandlerFlag.INIT)) {
98       msg("\t\tRequest Flag: Init");
99       ehResult = EntityHandlerResult.OK;
100     }
101     if (requestFlags.contains(RequestHandlerFlag.REQUEST)) {
102       msg("\t\tRequest Flag: Request");
103       ehResult = handleRequest(request);
104     }
105     if (requestFlags.contains(RequestHandlerFlag.OBSERVER)) {
106       msg("\t\tRequest Flag: Observer");
107       ehResult = handleObserver(request);
108     }
109     return ehResult;
110   }
111
112   private EntityHandlerResult handleRequest(OcResourceRequest request) {
113     EntityHandlerResult ehResult = EntityHandlerResult.ERROR;
114     // Check for query params (if any)
115     Map<String, String> queries = request.getQueryParameters();
116     if (!queries.isEmpty()) {
117       msg("Query processing is up to entityHandler");
118     } else {
119       msg("No query parameters in this request");
120     }
121
122     for (Map.Entry<String, String> entry : queries.entrySet()) {
123       msg("Query key: " + entry.getKey() + " value: " + entry.getValue());
124     }
125
126     // Get the request type
127     RequestType requestType = request.getRequestType();
128     switch (requestType) {
129       case GET:
130         msg("\t\t\tRequest Type is GET");
131         ehResult = handleGetRequest(request);
132         break;
133       case PUT:
134         msg("\t\t\tRequest Type is PUT");
135         ehResult = handlePutRequest(request);
136         break;
137       case POST:
138         msg("\t\t\tRequest Type is POST");
139         ehResult = handlePostRequest(request);
140         break;
141       case DELETE:
142         msg("\t\t\tRequest Type is DELETE");
143         ehResult = handleDeleteRequest();
144         break;
145     }
146     return ehResult;
147   }
148
149   private EntityHandlerResult handleGetRequest(final OcResourceRequest request) {
150     EntityHandlerResult ehResult;
151     OcResourceResponse response = new OcResourceResponse();
152     response.setRequestHandle(request.getRequestHandle());
153     response.setResourceHandle(request.getResourceHandle());
154
155     if (mIsSlowResponse) { // Slow response case
156       new Thread(new Runnable() {
157         public void run() {
158           handleSlowResponse(request);
159         }
160       }).start();
161       ehResult = EntityHandlerResult.SLOW;
162     } else { // normal response case.
163       response.setResponseResult(EntityHandlerResult.OK);
164       response.setResourceRepresentation(getOcRepresentation());
165       ehResult = sendResponse(response);
166     }
167     return ehResult;
168   }
169
170   private EntityHandlerResult handlePutRequest(OcResourceRequest request) {
171     OcResourceResponse response = new OcResourceResponse();
172     response.setRequestHandle(request.getRequestHandle());
173     response.setResourceHandle(request.getResourceHandle());
174
175     setOcRepresentation(request.getResourceRepresentation());
176     response.setResourceRepresentation(getOcRepresentation());
177     response.setResponseResult(EntityHandlerResult.OK);
178     return sendResponse(response);
179   }
180
181   private static int sUriCounter = 1;
182
183   private EntityHandlerResult handlePostRequest(OcResourceRequest request) {
184     OcResourceResponse response = new OcResourceResponse();
185     response.setRequestHandle(request.getRequestHandle());
186     response.setResourceHandle(request.getResourceHandle());
187     String newUri = "/a/light" + (++sUriCounter);
188     OcRepresentation rep_post = getOcRepresentation();
189     try {
190       rep_post.setValue(OcResource.CREATED_URI_KEY, newUri);
191     } catch (OcException e) {
192       Log.e(TAG, e.toString());
193     }
194     response.setResourceRepresentation(rep_post);
195     response.setNewResourceUri(newUri);
196     response.setResponseResult(EntityHandlerResult.RESOURCE_CREATED);
197     return sendResponse(response);
198   }
199
200   private EntityHandlerResult handleDeleteRequest() {
201     try {
202       this.unregisterResource();
203       return EntityHandlerResult.RESOURCE_DELETED;
204     } catch (OcException e) {
205       Log.e(TAG, e.toString());
206       msg("Failed to unregister a light resource");
207       return EntityHandlerResult.ERROR;
208     }
209   }
210
211   private void handleSlowResponse(OcResourceRequest request) {
212     sleep(10);
213     msg("Sending slow response...");
214     OcResourceResponse response = new OcResourceResponse();
215     response.setRequestHandle(request.getRequestHandle());
216     response.setResourceHandle(request.getResourceHandle());
217
218     response.setResponseResult(EntityHandlerResult.OK);
219     response.setResourceRepresentation(getOcRepresentation());
220     sendResponse(response);
221   }
222
223   private List<Byte> mObservationIds; // IDs of observes
224
225   private EntityHandlerResult handleObserver(final OcResourceRequest request) {
226     ObservationInfo observationInfo = request.getObservationInfo();
227     switch (observationInfo.getObserveAction()) {
228       case REGISTER:
229         if (null == mObservationIds) {
230           mObservationIds = new LinkedList<>();
231         }
232         mObservationIds.add(observationInfo.getOcObservationId());
233         break;
234       case UNREGISTER:
235         mObservationIds.remove((Byte) observationInfo.getOcObservationId());
236         break;
237     }
238     // Observation happens on a different thread in notifyObservers method.
239     // If we have not created the thread already, we will create one here.
240     if (null == mObserverNotifier) {
241       mObserverNotifier = new Thread(new Runnable() {
242         public void run() {
243           notifyObservers(request);
244         }
245       });
246       mObserverNotifier.start();
247     }
248     return EntityHandlerResult.OK;
249   }
250
251   private void notifyObservers(OcResourceRequest request) {
252     while (true) {
253       // increment current power value by 10 every 2 seconds
254       mPower += 10;
255       sleep(2);
256
257       msg("Notifying observers...");
258       msg(this.toString());
259       try {
260         if (mIsListOfObservers) {
261           OcResourceResponse response = new OcResourceResponse();
262           response.setResourceRepresentation(getOcRepresentation());
263           OcPlatform.notifyListOfObservers(mResourceHandle, mObservationIds,
264               response);
265         } else {
266           OcPlatform.notifyAllObservers(mResourceHandle);
267         }
268       } catch (OcException e) {
269         ErrorCode errorCode = e.getErrorCode();
270         if (ErrorCode.NO_OBSERVERS == errorCode) {
271           msg("No more observers, stopping notifications");
272         }
273         return;
274       }
275     }
276   }
277
278   private EntityHandlerResult sendResponse(OcResourceResponse response) {
279     try {
280       OcPlatform.sendResponse(response);
281       return EntityHandlerResult.OK;
282     } catch (OcException e) {
283       Log.e(TAG, e.toString());
284       msg("Failed to send response");
285       return EntityHandlerResult.ERROR;
286     }
287   }
288
289   public synchronized void unregisterResource() throws OcException {
290     if (null != mResourceHandle) {
291       OcPlatform.unregisterResource(mResourceHandle);
292     }
293   }
294
295   public void setOcRepresentation(OcRepresentation rep) {
296     try {
297       if (rep.hasAttribute(NAME_KEY))
298         mName = rep.getValue(NAME_KEY);
299       if (rep.hasAttribute(STATE_KEY))
300         mState = rep.getValue(STATE_KEY);
301       if (rep.hasAttribute(POWER_KEY))
302         mPower = rep.getValue(POWER_KEY);
303     } catch (OcException e) {
304       Log.e(TAG, e.toString());
305       msg("Failed to get representation values");
306     }
307   }
308
309   public OcRepresentation getOcRepresentation() {
310     OcRepresentation rep = new OcRepresentation();
311     try {
312       rep.setValue(NAME_KEY, mName);
313       rep.setValue(STATE_KEY, mState);
314       rep.setValue(POWER_KEY, mPower);
315     } catch (OcException e) {
316       Log.e(TAG, e.toString());
317       msg("Failed to set representation values");
318     }
319     return rep;
320   }
321
322   // ******************************************************************************
323   // End of the OIC specific code
324   // ******************************************************************************
325
326   public void setSlowResponse(boolean isSlowResponse) {
327     mIsSlowResponse = isSlowResponse;
328   }
329
330   public void useListOfObservers(boolean isListOfObservers) {
331     mIsListOfObservers = isListOfObservers;
332   }
333
334   public void setContext(Context context) {
335     mContext = context;
336   }
337
338   @Override
339   public String toString() {
340     return "\t" + "URI" + ": " + mResourceUri + "\n\t" + NAME_KEY + ": "
341         + mName + "\n\t" + STATE_KEY + ": " + mState + "\n\t" + POWER_KEY
342         + ": " + mPower;
343   }
344
345   private void sleep(int seconds) {
346     try {
347       Thread.sleep(seconds * 1000);
348     } catch (InterruptedException e) {
349       e.printStackTrace();
350       Log.e(TAG, e.toString());
351     }
352   }
353
354   private void msg(String text) {
355     if (null != mContext) {
356       Intent intent = new Intent("org.iotivity.base.examples.simpleserver");
357       intent.putExtra("message", text);
358       mContext.sendBroadcast(intent);
359     }
360   }
361
362   private final static String TAG                = PMLight.class.getSimpleName();
363   private final static int    SUCCESS            = 200;
364   private boolean             mIsSlowResponse    = false;
365   private boolean             mIsListOfObservers = false;
366   private Thread              mObserverNotifier;
367   private Context             mContext;
368 }