Combines SimpleServer and SimpleClient into a single app.
If there are errors, return code is non-zero.
To build:
$ scons TARGET_TRANSPORT=IP SECURED=0 RELEASE=1 BUILD_JAVA=ON
To run:
$ export LD_LIBRARY_PATH="<iotivity>/out/linux/x86_64/release/"
$ java -cp java/examples-java/simpleclientserver/build/libs/simpleclientserver.jar:\
java/iotivity-linux/build/libs/iotivity-linux.jar org.iotivity.base.examples.SimpleClientServer ;\
echo result code = $?
Change-Id: I8f4bcd04ecd41518694b1e9901b7dcc84da4c6fd
Signed-off-by: Larry Sachs <larry.j.sachs@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/16239
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: George Nash <george.nash@intel.com>
Reviewed-by: Rick Bell <richard.s.bell@intel.com>
-include ':simpleserver', ':simpleclient'//, ':fridgeserver', ':fridgeclient', ':guiclient', ':provisioningclient', ':presenceserver', ':presenceclient', ':devicediscoveryclient', ':devicediscoveryserver', ':groupclient', ':groupserver', ':fridgegroupclient', ':fridgegroupserver'
+include ':simpleserver', ':simpleclient', ':simpleclientserver'//, ':fridgeserver', ':fridgeclient', ':guiclient', ':provisioningclient', ':presenceserver', ':presenceclient', ':devicediscoveryclient', ':devicediscoveryserver', ':groupclient', ':groupserver', ':fridgegroupclient', ':fridgegroupserver'
--- /dev/null
+{
+ "acl": [
+ {
+ "sub": "Kg==",
+ "rsrc": [
+ "/oic/res",
+ "/oic/d",
+ "/oic/p",
+ "/oic/res/types/d",
+ "/oic/ad",
+ "/oic/sec/acl"
+ ],
+ "perms": 2,
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ },
+ {
+ "sub": "Kg==",
+ "rsrc": [
+ "/oic/sec/doxm",
+ "/oic/sec/pstat"
+ ],
+ "perms": 2,
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }
+ ],
+ "pstat": {
+ "isop": true,
+ "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
+ "ch": 0,
+ "cm": 0,
+ "tm": 0,
+ "om": 3,
+ "sm": [3]
+ },
+ "doxm": {
+ "oxm": [0],
+ "oxmsel": 0,
+ "sct": 1,
+ "owned": true,
+ "deviceid": "MjIyMjIyMjIyMjIyMjIyMg==",
+ "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+ },
+ "cred": [{
+ "credid": 1,
+ "sub": "MTExMTExMTExMTExMTExMQ==",
+ "credtyp": 1,
+ "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }]
+}
--- /dev/null
+/*
+ *******************************************************************
+ *
+ * Copyright 2017 Intel Corporation.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples;
+
+import org.iotivity.base.EntityHandlerResult;
+import org.iotivity.base.ErrorCode;
+import org.iotivity.base.ObservationInfo;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcRepresentation;
+import org.iotivity.base.OcResource;
+import org.iotivity.base.OcResourceHandle;
+import org.iotivity.base.OcResourceRequest;
+import org.iotivity.base.OcResourceResponse;
+import org.iotivity.base.RequestHandlerFlag;
+import org.iotivity.base.RequestType;
+import org.iotivity.base.ResourceProperty;
+
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * ServerLight
+ * <p/>
+ * This class represents a server light resource.
+ */
+public class ServerLight extends SimpleLight implements OcPlatform.EntityHandler {
+
+ private static final String TAG = ServerLight.class.getSimpleName();
+
+ public static final String DEFAULT_RESOURCE_URI = "/a/light";
+ public static final String DEFAULT_RESOURCE_NAME = "John's light";
+
+ private SimpleServer mServer; // server
+ private String mResourceUri; // resource URI
+ private String mResourceTypeName; // resource type name
+ private String mResourceInterface; // resource interface
+ private OcResourceHandle mResourceHandle; // resource handle
+
+ private Thread mObserverNotifier;
+
+ public ServerLight(SimpleServer server, String resourceUri, String name, boolean state, int power) {
+ mServer = server;
+ mResourceUri = resourceUri;
+ mResourceTypeName = SimpleLight.RESOURCE_TYPE;
+ mResourceInterface = OcPlatform.DEFAULT_INTERFACE;
+ mResourceHandle = null; // this is set when resource is registered
+
+ setName(name);
+ setState(state);
+ setPower(power);
+ }
+
+ public synchronized void registerResource() throws OcException {
+ if (null == mResourceHandle) {
+ mResourceHandle = OcPlatform.registerResource(mResourceUri, mResourceTypeName, mResourceInterface, this,
+ EnumSet.of(ResourceProperty.DISCOVERABLE, ResourceProperty.OBSERVABLE));
+ }
+ }
+
+ /**
+ * NOTE: This is just a sample implementation of entity handler. Entity
+ * handler can be implemented in several ways by the manufacturer.
+ */
+ @Override
+ public synchronized EntityHandlerResult handleEntity(final OcResourceRequest request) {
+ EntityHandlerResult ehResult = EntityHandlerResult.ERROR;
+ if (null == request) {
+ msg("Server request is invalid");
+ return ehResult;
+ }
+ // Get the request flags
+ EnumSet<RequestHandlerFlag> requestFlags = request.getRequestHandlerFlagSet();
+ if (requestFlags.contains(RequestHandlerFlag.INIT)) {
+ msg("\t\tRequest Flag: Init");
+ ehResult = EntityHandlerResult.OK;
+ }
+ if (requestFlags.contains(RequestHandlerFlag.REQUEST)) {
+ msg("\t\tRequest Flag: Request");
+ ehResult = handleRequest(request);
+ }
+ if (requestFlags.contains(RequestHandlerFlag.OBSERVER)) {
+ msg("\t\tRequest Flag: Observer");
+ ehResult = handleObserver(request);
+ }
+ return ehResult;
+ }
+
+ private EntityHandlerResult handleRequest(OcResourceRequest request) {
+ EntityHandlerResult ehResult = EntityHandlerResult.ERROR;
+ // Check for query params (if any)
+ Map<String, String> queries = request.getQueryParameters();
+ if (!queries.isEmpty()) {
+ msg("Query processing is up to entityHandler");
+ } else {
+ msg("No query parameters in this request");
+ }
+
+ for (Map.Entry<String, String> entry : queries.entrySet()) {
+ msg("Query key: " + entry.getKey() + " value: " + entry.getValue());
+ }
+
+ // Get the request type
+ RequestType requestType = request.getRequestType();
+ switch (requestType) {
+ case GET:
+ msg("\t\t\tRequest Type is GET");
+ ehResult = handleGetRequest(request);
+ break;
+ case PUT:
+ msg("\t\t\tRequest Type is PUT");
+ ehResult = handlePutRequest(request);
+ break;
+ case POST:
+ msg("\t\t\tRequest Type is POST");
+ ehResult = handlePostRequest(request);
+ break;
+ case DELETE:
+ msg("\t\t\tRequest Type is DELETE");
+ ehResult = handleDeleteRequest();
+ break;
+ }
+ return ehResult;
+ }
+
+ private EntityHandlerResult handleGetRequest(final OcResourceRequest request) {
+ EntityHandlerResult ehResult;
+ OcResourceResponse response = new OcResourceResponse();
+ response.setRequestHandle(request.getRequestHandle());
+ response.setResourceHandle(request.getResourceHandle());
+
+ response.setResponseResult(EntityHandlerResult.OK);
+ response.setResourceRepresentation(getOcRepresentation());
+ ehResult = sendResponse(response);
+ return ehResult;
+ }
+
+ private EntityHandlerResult handlePutRequest(OcResourceRequest request) {
+ OcResourceResponse response = new OcResourceResponse();
+ response.setRequestHandle(request.getRequestHandle());
+ response.setResourceHandle(request.getResourceHandle());
+
+ setOcRepresentation(request.getResourceRepresentation());
+ response.setResourceRepresentation(getOcRepresentation());
+ response.setResponseResult(EntityHandlerResult.OK);
+ return sendResponse(response);
+ }
+
+ private int sUriCounter = 1;
+
+ private EntityHandlerResult handlePostRequest(OcResourceRequest request) {
+ OcResourceResponse response = new OcResourceResponse();
+ response.setRequestHandle(request.getRequestHandle());
+ response.setResourceHandle(request.getResourceHandle());
+ String newUri = DEFAULT_RESOURCE_URI + "/" + (++sUriCounter);
+ mServer.createNewLightResource(newUri, DEFAULT_RESOURCE_NAME + " " + sUriCounter);
+ OcRepresentation rep_post = getOcRepresentation();
+ try {
+ rep_post.setValue(OcResource.CREATED_URI_KEY, newUri);
+ } catch (OcException e) {
+ msgError(TAG, e.toString());
+ }
+ response.setResourceRepresentation(rep_post);
+ response.setNewResourceUri(newUri);
+ response.setResponseResult(EntityHandlerResult.RESOURCE_CREATED);
+ return sendResponse(response);
+ }
+
+ private EntityHandlerResult handleDeleteRequest() {
+ try {
+ unregisterResource();
+ return EntityHandlerResult.RESOURCE_DELETED;
+ } catch (OcException e) {
+ msgError(TAG, e.toString());
+ msg("Failed to unregister a light resource");
+ return EntityHandlerResult.ERROR;
+ }
+ }
+
+ private List<Byte> mObservationIds = new LinkedList<>();
+
+ private EntityHandlerResult handleObserver(final OcResourceRequest request) {
+ ObservationInfo observationInfo = request.getObservationInfo();
+ switch (observationInfo.getObserveAction()) {
+ case REGISTER:
+ mObservationIds.add(observationInfo.getOcObservationId());
+ break;
+ case UNREGISTER:
+ mObservationIds.remove((Byte) observationInfo.getOcObservationId());
+ break;
+ }
+ // Observation happens on a different thread in notifyObservers method.
+ // If we have not created the thread already, we will create one here.
+ if (null == mObserverNotifier) {
+ mObserverNotifier = new Thread(new Runnable() {
+ public void run() {
+ notifyObservers(request);
+ }
+ });
+ mObserverNotifier.start();
+ }
+ return EntityHandlerResult.OK;
+ }
+
+ private void notifyObservers(OcResourceRequest request) {
+ while (true) {
+ // increment current power value by 10 every 2 seconds
+ setPower(getPower() + 10);
+ sleep(2);
+
+ msg("Notifying observers...");
+ msg(toString());
+ try {
+ OcPlatform.notifyAllObservers(mResourceHandle);
+ } catch (OcException e) {
+ ErrorCode errorCode = e.getErrorCode();
+ if (ErrorCode.NO_OBSERVERS == errorCode) {
+ msg("No more observers, stopping notifications");
+ }
+ return;
+ }
+ }
+ }
+
+ private EntityHandlerResult sendResponse(OcResourceResponse response) {
+ try {
+ OcPlatform.sendResponse(response);
+ return EntityHandlerResult.OK;
+ } catch (OcException e) {
+ msgError(TAG, e.toString());
+ msg("Failed to send response");
+ return EntityHandlerResult.ERROR;
+ }
+ }
+
+ public synchronized void unregisterResource() throws OcException {
+ if (null != mResourceHandle) {
+ OcPlatform.unregisterResource(mResourceHandle);
+ }
+ }
+
+ public void setOcRepresentation(OcRepresentation rep) {
+ try {
+ if (rep.hasAttribute(NAME_KEY))
+ setName((String) rep.getValue(NAME_KEY));
+ if (rep.hasAttribute(STATE_KEY))
+ setState((boolean) rep.getValue(STATE_KEY));
+ if (rep.hasAttribute(POWER_KEY))
+ setPower((int) rep.getValue(POWER_KEY));
+ } catch (OcException e) {
+ msgError(TAG, e.toString());
+ msg("Failed to get representation values");
+ }
+ }
+
+ public OcRepresentation getOcRepresentation() {
+ OcRepresentation rep = new OcRepresentation();
+ try {
+ rep.setValue(NAME_KEY, getName());
+ rep.setValue(STATE_KEY, getState());
+ rep.setValue(POWER_KEY, getPower());
+ } catch (OcException e) {
+ msgError(TAG, e.toString());
+ msg("Failed to set representation values");
+ }
+ return rep;
+ }
+
+ // ******************************************************************************
+ // End of the OIC specific code
+ // ******************************************************************************
+
+ @Override
+ public String toString() {
+ return "\t" + "URI" + ": " + mResourceUri + "\n\t" + NAME_KEY + ": " + getName() + "\n\t" + STATE_KEY + ": "
+ + getState() + "\n\t" + POWER_KEY + ": " + getPower();
+ }
+
+ private void sleep(int seconds) {
+ try {
+ Thread.sleep(seconds * 1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ msgError(TAG, e.toString());
+ }
+ }
+
+ private void msg(String text) {
+ mServer.msg(text);
+ }
+
+ private void msgError(String tag, String text) {
+ mServer.msgError(tag, text);
+ }
+}
--- /dev/null
+/*
+ *******************************************************************
+ *
+ * Copyright 2017 Intel Corporation.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples;
+
+import org.iotivity.base.ErrorCode;
+import org.iotivity.base.ObserveType;
+import org.iotivity.base.OcConnectivityType;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcHeaderOption;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcRepresentation;
+import org.iotivity.base.OcResource;
+import org.iotivity.base.OcResourceIdentifier;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * SimpleClient
+ * <p/>
+ * SimpleClient is a sample client app which should be started after the
+ * SimpleServer is started. It finds resources advertised by the server and
+ * calls different operations on it (GET, PUT, POST, DELETE and OBSERVE).
+ */
+public class SimpleClient implements OcPlatform.OnResourceFoundListener, OcResource.OnGetListener,
+ OcResource.OnPutListener, OcResource.OnPostListener, OcResource.OnObserveListener {
+
+ private Map<OcResourceIdentifier, OcResource> mFoundResources = new HashMap<>();
+ private OcResource mFoundLightResource;
+ private boolean isDone;
+ private Object mWaitLock;
+ // local representation of a client's light resource
+ private SimpleLight mLight = new SimpleLight();
+
+ public SimpleClient(Object waitLock) {
+ mWaitLock = waitLock;
+
+ try {
+ msg("Finding all resources of type \""+SimpleLight.RESOURCE_TYPE+"\".");
+ String requestUri = OcPlatform.WELL_KNOWN_QUERY + "?rt="+SimpleLight.RESOURCE_TYPE;
+ OcPlatform.findResource("", requestUri, EnumSet.of(OcConnectivityType.CT_DEFAULT), this);
+
+ /*
+ * Find resource is done twice so that we discover the original
+ * resources a second time. These resources will have the same
+ * unique identifier (yet be different objects), so that we can
+ * verify/show the duplicate-checking code in foundResource(above);
+ */
+ msg("Finding all resources of type \""+SimpleLight.RESOURCE_TYPE+"\" for the second time");
+ OcPlatform.findResource("", requestUri, EnumSet.of(OcConnectivityType.CT_DEFAULT), this);
+
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Failed to invoke find resource API");
+ }
+
+ printLine();
+ }
+
+ public boolean isRunning() {
+ return !isDone;
+ }
+
+ /**
+ * An event handler to be executed whenever a "findResource" request
+ * completes successfully
+ *
+ * @param ocResource
+ * found resource
+ */
+ @Override
+ public synchronized void onResourceFound(OcResource ocResource) {
+ if (null == ocResource) {
+ msg("Found resource is invalid");
+ return;
+ }
+
+ if (mFoundResources.containsKey(ocResource.getUniqueIdentifier())) {
+ msg("Found a previously seen resource again!");
+ } else {
+ msg("Found resource for the first time on server with ID: " + ocResource.getServerId());
+ mFoundResources.put(ocResource.getUniqueIdentifier(), ocResource);
+ }
+
+ if (null != mFoundLightResource) {
+ msg("Found another resource, ignoring");
+ return;
+ }
+
+ // Get the resource URI
+ String resourceUri = ocResource.getUri();
+ // Get the resource host address
+ String hostAddress = ocResource.getHost();
+ msg("\tURI of the resource: " + resourceUri);
+ msg("\tHost address of the resource: " + hostAddress);
+ // Get the resource types
+ msg("\tList of resource types: ");
+ for (String resourceType : ocResource.getResourceTypes()) {
+ msg("\t\t" + resourceType);
+ }
+ msg("\tList of resource interfaces:");
+ for (String resourceInterface : ocResource.getResourceInterfaces()) {
+ msg("\t\t" + resourceInterface);
+ }
+ msg("\tList of resource connectivity types:");
+ for (OcConnectivityType connectivityType : ocResource.getConnectivityTypeSet()) {
+ msg("\t\t" + connectivityType);
+ }
+ printLine();
+
+ // In this example we are only interested in the light resources
+ if (resourceUri.equals(ServerLight.DEFAULT_RESOURCE_URI)) {
+ mFoundLightResource = ocResource;
+
+ // Call a local method which will internally invoke "get" API on the
+ // foundLightResource
+ getLightResourceRepresentation();
+ }
+ }
+
+ @Override
+ public synchronized void onFindResourceFailed(Throwable throwable, String uri) {
+ msg("findResource request has failed");
+ msgError(throwable.toString());
+ }
+
+ /**
+ * Local method to get representation of a found light resource
+ */
+ private void getLightResourceRepresentation() {
+ msg("Getting Light Representation...");
+
+ Map<String, String> queryParams = new HashMap<>();
+ try {
+ // Invoke resource's "get" API with a OcResource.OnGetListener event
+ // listener implementation
+ mFoundLightResource.get(queryParams, this);
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Error occurred while invoking \"get\" API");
+ }
+ }
+
+ /**
+ * An event handler to be executed whenever a "get" request completes
+ * successfully
+ *
+ * @param list
+ * list of the header options
+ * @param ocRepresentation
+ * representation of a resource
+ */
+ @Override
+ public synchronized void onGetCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
+ msg("GET request was successful");
+ msg("Resource URI: " + ocRepresentation.getUri());
+
+ try {
+ // Read attribute values into local representation of a light
+ mLight.setOcRepresentation(ocRepresentation);
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Failed to read the attributes of a light resource");
+ }
+ msg("Light attributes: ");
+ msg(mLight.toString());
+ printLine();
+
+ // Call a local method which will internally invoke put API on the
+ // foundLightResource
+ putLightRepresentation();
+ }
+
+ /**
+ * An event handler to be executed whenever a "get" request fails
+ *
+ * @param throwable
+ * exception
+ */
+ @Override
+ public synchronized void onGetFailed(Throwable throwable) {
+ if (throwable instanceof OcException) {
+ OcException ocEx = (OcException) throwable;
+ msgError(ocEx.toString());
+ ErrorCode errCode = ocEx.getErrorCode();
+ // do something based on errorCode
+ msg("Error code: " + errCode);
+ }
+ msg("Failed to get representation of a found light resource");
+ }
+
+ /**
+ * Local method to put a different state for this light resource
+ */
+ private void putLightRepresentation() {
+ // set new values
+ mLight.setState(true);
+ mLight.setPower(15);
+
+ msg("Putting light representation...");
+ OcRepresentation representation = null;
+ try {
+ representation = mLight.getOcRepresentation();
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Failed to get OcRepresentation from a light");
+ }
+
+ Map<String, String> queryParams = new HashMap<>();
+
+ try {
+ // Invoke resource's "put" API with a new representation, query
+ // parameters and OcResource.OnPutListener event listener
+ // implementation
+ mFoundLightResource.put(representation, queryParams, this);
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Error occurred while invoking \"put\" API");
+ }
+ }
+
+ /**
+ * An event handler to be executed whenever a "put" request completes
+ * successfully
+ *
+ * @param list
+ * list of the header options
+ * @param ocRepresentation
+ * representation of a resource
+ */
+ @Override
+ public synchronized void onPutCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
+ msg("PUT request was successful");
+ try {
+ mLight.setOcRepresentation(ocRepresentation);
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Failed to create Light representation");
+ }
+ msg("Light attributes: ");
+ msg(mLight.toString());
+ printLine();
+
+ // Call a local method which will internally invoke post API on the
+ // foundLightResource
+ postLightRepresentation();
+ }
+
+ /**
+ * An event handler to be executed whenever a "put" request fails
+ *
+ * @param throwable
+ * exception
+ */
+ @Override
+ public synchronized void onPutFailed(Throwable throwable) {
+ if (throwable instanceof OcException) {
+ OcException ocEx = (OcException) throwable;
+ msgError(ocEx.toString());
+ ErrorCode errCode = ocEx.getErrorCode();
+ // do something based on errorCode
+ msg("Error code: " + errCode);
+ }
+ msg("Failed to \"put\" a new representation");
+ }
+
+ /**
+ * Local method to post a different state for this light resource
+ */
+ private void postLightRepresentation() {
+ // set new values
+ mLight.setState(false);
+ mLight.setPower(105);
+
+ msg("Posting light representation...");
+ OcRepresentation representation = null;
+ try {
+ representation = mLight.getOcRepresentation();
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Failed to get OcRepresentation from a light");
+ }
+
+ Map<String, String> queryParams = new HashMap<>();
+ try {
+ // Invoke resource's "post" API with a new representation, query
+ // parameters and OcResource.OnPostListener event listener
+ // implementation
+ mFoundLightResource.post(representation, queryParams, this);
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Error occurred while invoking \"post\" API");
+ }
+ }
+
+ /**
+ * An event handler to be executed whenever a "post" request completes
+ * successfully
+ *
+ * @param list
+ * list of the header options
+ * @param ocRepresentation
+ * representation of a resource
+ */
+ @Override
+ public synchronized void onPostCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
+ msg("POST request was successful");
+ try {
+ if (ocRepresentation.hasAttribute(OcResource.CREATED_URI_KEY)) {
+ msg("\tUri of the created resource: " + ocRepresentation.getValue(OcResource.CREATED_URI_KEY));
+ } else {
+ mLight.setOcRepresentation(ocRepresentation);
+ msg(mLight.toString());
+ }
+ } catch (OcException e) {
+ msgError(e.toString());
+ }
+
+ // setting new values
+ mLight.setState(true);
+ mLight.setPower(55);
+ msg("Posting again light representation...");
+ OcRepresentation representation2 = null;
+ try {
+ representation2 = mLight.getOcRepresentation();
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Failed to get OcRepresentation from a light");
+ }
+
+ Map<String, String> queryParams = new HashMap<>();
+ try {
+ // Invoke resource's "post" API with a new representation, query
+ // parameters and OcResource.OnPostListener event listener
+ // implementation
+ mFoundLightResource.post(representation2, queryParams, onPostListener2);
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Error occurred while invoking \"post\" API");
+ }
+ }
+
+ /**
+ * An event handler to be executed whenever a "post" request fails
+ *
+ * @param throwable
+ * exception
+ */
+ @Override
+ public synchronized void onPostFailed(Throwable throwable) {
+ if (throwable instanceof OcException) {
+ OcException ocEx = (OcException) throwable;
+ msgError(ocEx.toString());
+ ErrorCode errCode = ocEx.getErrorCode();
+ // do something based on errorCode
+ msg("Error code: " + errCode);
+ }
+ msg("Failed to \"post\" a new representation");
+ }
+
+ /**
+ * Declare and implement a second OcResource.OnPostListener
+ */
+ OcResource.OnPostListener onPostListener2 = new OcResource.OnPostListener() {
+ /**
+ * An event handler to be executed whenever a "post" request completes
+ * successfully
+ *
+ * @param list
+ * list of the header options
+ * @param ocRepresentation
+ * representation of a resource
+ */
+ @Override
+ public synchronized void onPostCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
+ msg("Second POST request was successful");
+ try {
+ if (ocRepresentation.hasAttribute(OcResource.CREATED_URI_KEY)) {
+ msg("\tUri of the created resource: " + ocRepresentation.getValue(OcResource.CREATED_URI_KEY));
+ } else {
+ mLight.setOcRepresentation(ocRepresentation);
+ msg(mLight.toString());
+ }
+ } catch (OcException e) {
+ msgError(e.toString());
+ }
+
+ // Call a local method which will internally invoke observe API on
+ // the foundLightResource
+ observeFoundLightResource();
+ }
+
+ /**
+ * An event handler to be executed whenever a "post" request fails
+ *
+ * @param throwable
+ * exception
+ */
+ @Override
+ public synchronized void onPostFailed(Throwable throwable) {
+ if (throwable instanceof OcException) {
+ OcException ocEx = (OcException) throwable;
+ msgError(ocEx.toString());
+ ErrorCode errCode = ocEx.getErrorCode();
+ // do something based on errorCode
+ msg("Error code: " + errCode);
+ }
+ msg("Failed to \"post\" a new representation");
+ }
+ };
+
+ /**
+ * Local method to start observing this light resource
+ */
+ private void observeFoundLightResource() {
+ try {
+ // Invoke resource's "observe" API with a observe type, query
+ // parameters and
+ // OcResource.OnObserveListener event listener implementation
+ mFoundLightResource.observe(ObserveType.OBSERVE, new HashMap<String, String>(), this);
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Error occurred while invoking \"observe\" API");
+ }
+ }
+
+ // holds current number of observations
+ private int mObserveCount = 0;
+
+ /**
+ * An event handler to be executed whenever a "post" request completes
+ * successfully
+ *
+ * @param list
+ * list of the header options
+ * @param ocRepresentation
+ * representation of a resource
+ * @param sequenceNumber
+ * sequence number
+ */
+ @Override
+ public synchronized void onObserveCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation,
+ int sequenceNumber) {
+ if (OcResource.OnObserveListener.REGISTER == sequenceNumber) {
+ msg("Observe registration action is successful:");
+ } else if (OcResource.OnObserveListener.DEREGISTER == sequenceNumber) {
+ msg("Observe De-registration action is successful");
+ } else if (OcResource.OnObserveListener.NO_OPTION == sequenceNumber) {
+ msg("Observe registration or de-registration action is failed");
+ }
+
+ msg("OBSERVE Result:");
+ msg("\tSequenceNumber: " + sequenceNumber);
+ try {
+ mLight.setOcRepresentation(ocRepresentation);
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Failed to get the attribute values");
+ }
+ msg(mLight.toString());
+
+ if ((++mObserveCount) > 11) {
+ msg("Cancelling Observe...");
+ try {
+ mFoundLightResource.cancelObserve();
+ } catch (OcException e) {
+ msgError(e.toString());
+ msg("Error occurred while invoking \"cancelObserve\" API");
+ }
+ msg("DONE");
+ isDone = true;
+
+ synchronized (mWaitLock) {
+ mWaitLock.notify();
+ }
+ }
+ }
+
+ /**
+ * An event handler to be executed whenever a "observe" request fails
+ *
+ * @param throwable
+ * exception
+ */
+ @Override
+ public synchronized void onObserveFailed(Throwable throwable) {
+ if (throwable instanceof OcException) {
+ OcException ocEx = (OcException) throwable;
+ msgError(ocEx.toString());
+ ErrorCode errCode = ocEx.getErrorCode();
+ // do something based on errorCode
+ msg("Error code: " + errCode);
+ }
+ msg("Observation of the found light resource has failed");
+ }
+
+ // ******************************************************************************
+ // End of the OIC specific code
+ // ******************************************************************************
+
+ private static final String TAG = SimpleClient.class.getSimpleName();
+
+ private void msg(final String text) {
+ SimpleClientServer.msg(TAG, text);
+ }
+
+ private void msgError(final String text) {
+ SimpleClientServer.msgError(TAG, text);
+ }
+
+ private void printLine() {
+ SimpleClientServer.printLine(TAG);
+ }
+}
--- /dev/null
+/*
+ *******************************************************************
+ *
+ * Copyright 2017 Intel Corporation.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples;
+
+import org.iotivity.base.ModeType;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * SimpleClientServer
+ * <p/>
+ * SimpleClientServer is a sample OIC client/server application. Return code is
+ * 0 if no errors detected.
+ */
+public class SimpleClientServer {
+
+ private static final String TAG = SimpleClientServer.class.getSimpleName();
+
+ public static void main(String[] args) {
+
+ PlatformConfig platformConfig = new PlatformConfig(ServiceType.IN_PROC, ModeType.CLIENT_SERVER, "0.0.0.0", 0,
+ QualityOfService.LOW);
+ msg(TAG, "Configuring platform.");
+ OcPlatform.Configure(platformConfig);
+
+ SimpleServer server = new SimpleServer();
+ Object waitLock = new Object();
+ SimpleClient client = new SimpleClient(waitLock);
+
+ int returnCode = -1;
+ synchronized (waitLock) {
+ try {
+ waitLock.wait(60 * 1000);
+ if (client.isRunning()) {
+ msgError(TAG, "Failed to complete on time!");
+ } else {
+ returnCode = 0;
+ }
+ } catch (InterruptedException e) {
+ msgError(TAG, e.toString());
+ }
+ }
+
+ server.stopSimpleServer();
+ System.exit(returnCode);
+ }
+
+ private static String getMessage(String tag, String text, boolean isError) {
+ return "[" + (isError ? "E" : "O") + "]" + tag + " | " + text;
+ }
+
+ protected static void msg(final String tag, final String text) {
+ System.out.println(getMessage(tag, text, false));
+ }
+
+ protected static void msgError(final String tag, final String text) {
+ System.out.println(getMessage(tag, text, true));
+ }
+
+ protected static void printLine(final String tag) {
+ msg(tag, "------------------------------------------------------------------------");
+ }
+}
--- /dev/null
+/*
+ *******************************************************************
+ *
+ * Copyright 2017 Intel Corporation.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples;
+
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcRepresentation;
+
+/**
+ * SimpleLight
+ * <p/>
+ * This class is used by SimpleClient to create an object representation of a
+ * remote light resource and update the values depending on the server response.
+ */
+public class SimpleLight {
+
+ public static final String RESOURCE_TYPE = "core.light";
+
+ public static final String NAME_KEY = "name";
+ public static final String STATE_KEY = "state";
+ public static final String POWER_KEY = "power";
+
+ private String mName;
+ private boolean mState;
+ private int mPower;
+
+ public SimpleLight() {
+ mName = "";
+ mState = false;
+ mPower = 0;
+ }
+
+ public void setOcRepresentation(OcRepresentation rep) throws OcException {
+ mName = rep.getValue(NAME_KEY);
+ mState = rep.getValue(STATE_KEY);
+ mPower = rep.getValue(POWER_KEY);
+ }
+
+ public OcRepresentation getOcRepresentation() throws OcException {
+ OcRepresentation rep = new OcRepresentation();
+ rep.setValue(NAME_KEY, mName);
+ rep.setValue(STATE_KEY, mState);
+ rep.setValue(POWER_KEY, mPower);
+ return rep;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ }
+
+ public boolean getState() {
+ return mState;
+ }
+
+ public void setState(boolean state) {
+ mState = state;
+ }
+
+ public int getPower() {
+ return mPower;
+ }
+
+ public void setPower(int power) {
+ mPower = power;
+ }
+
+ @Override
+ public String toString() {
+ return "\t" + NAME_KEY + ": " + getName() + "\n\t" + STATE_KEY + ": " + getState() + "\n\t" + POWER_KEY + ": "
+ + getPower();
+ }
+}
--- /dev/null
+/*
+ *******************************************************************
+ *
+ * Copyright 2017 Intel Corporation.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples;
+
+import org.iotivity.base.OcException;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * SimpleServer
+ * <p/>
+ * SimpleServer is a sample OIC server application. It creates a Light and waits
+ * for the incoming client calls to handle various request scenarios.
+ */
+public class SimpleServer {
+
+ private List<ServerLight> lights = new LinkedList<>();
+
+ public SimpleServer() {
+ createNewLightResource(ServerLight.DEFAULT_RESOURCE_URI, ServerLight.DEFAULT_RESOURCE_NAME);
+
+ msg("Waiting for the requests...");
+ printLine();
+ }
+
+ protected void createNewLightResource(String resourceUri, String resourceName) {
+ msg("Creating a light");
+ ServerLight light = new ServerLight(this, resourceUri, resourceName, false, 0);
+ msg(light.toString());
+
+ msg("Registering light as a resource");
+ try {
+ light.registerResource();
+ } catch (OcException e) {
+ msgError(TAG, e.toString());
+ msg("Failed to register a light resource");
+ }
+ lights.add(light);
+ }
+
+ public void stopSimpleServer() {
+ for (ServerLight light : lights) {
+ try {
+ light.unregisterResource();
+ } catch (OcException e) {
+ msgError(TAG, e.toString());
+ msg("Failed to unregister a light resource");
+ }
+ }
+ lights.clear();
+
+ msg("All created resources have been unregistered");
+ printLine();
+ }
+
+ // ******************************************************************************
+ // End of the OIC specific code
+ // ******************************************************************************
+
+ private static final String TAG = SimpleServer.class.getSimpleName();
+
+ protected void msg(final String text) {
+ SimpleClientServer.msg(TAG, text);
+ }
+
+ protected void msgError(final String tag, final String text) {
+ SimpleClientServer.msgError(tag, text);
+ }
+
+ private void printLine() {
+ SimpleClientServer.printLine(TAG);
+ }
+}