From 4ab9303be3d016454f127ea1e62d05d6ced71c12 Mon Sep 17 00:00:00 2001 From: Jee Hyeok Kim Date: Fri, 11 Mar 2016 16:41:30 +0900 Subject: [PATCH] Update cloud project 1. Add Testcases for each projects. 2. Fix coap encoder to correctly reference accept flag 3. Modify native sample application to use csdk Change-Id: I0697341fe6e927c679d8d4b4f0e07275f28e86fb Signed-off-by: Jee Hyeok Kim Reviewed-on: https://gerrit.iotivity.org/gerrit/5713 Reviewed-by: Ziran Sun Tested-by: jenkins-iotivity --- cloud/account/README | 2 +- .../cloud/accountserver/AccountServer.java | 2 +- .../cloud/accountserver/AccountServerManager.java | 48 +- .../cloud/accountserver/db/AccountDBManager.java | 57 +- .../iotivity/cloud/accountserver/db/MongoDB.java | 179 ++--- .../accountserver/resources/AccountResource.java | 65 +- .../accountserver/resources/AuthResource.java | 57 +- .../accountserver/util/CoapMessageBuilder.java | 32 +- .../cloud/accountserver/util/JSONUtil.java | 18 +- .../cloud/testaccountserver/TestAccountServer.java | 4 +- cloud/interface/README | 2 +- .../cloud/ciserver/CloudInterfaceServer.java | 2 +- .../cloud/ciserver/protocols/CoapAuthHandler.java | 21 + .../cloud/ciserver/protocols/CoapRelayHandler.java | 91 ++- .../cloud/ciserver/testci/TestCloudInterface.java | 255 ++++++++ cloud/resourcedirectory/README | 2 +- .../resources/ResourceDirectoryResource.java | 14 +- .../iotivity/cloud/testrdserver/RDServerTest.java | 2 +- cloud/samples/client/SConscript | 2 +- cloud/samples/client/cloud_connector.c | 75 +-- cloud/samples/client/sample_device.cpp | 726 +++++++++++---------- cloud/stack/README | 2 +- .../java/org/iotivity/cloud/base/HttpClient.java | 401 ++++++------ .../java/org/iotivity/cloud/base/HttpServer.java | 278 ++++---- .../org/iotivity/cloud/base/ResourceManager.java | 31 +- .../org/iotivity/cloud/base/SessionManager.java | 9 +- .../cloud/base/protocols/coap/CoapMessage.java | 2 +- .../cloud/base/protocols/coap/CoapRequest.java | 20 +- .../base/protocols/proxy/CoapHttpProxyHandler.java | 407 ++++++------ .../org/iotivity/cloud/util/CoapLogHandler.java | 4 +- .../org/iotivity/cloud/base/CoapClientTest.java | 29 +- .../org/iotivity/cloud/base/CoapServerTest.java | 16 +- .../iotivity/cloud/base/ResourceManagerTest.java | 66 ++ .../java/org/iotivity/cloud/base/ResourceTest.java | 54 ++ .../iotivity/cloud/base/SessionManagerTest.java | 99 +++ .../cloud/base/protocols/coap/CoapRequestTest.java | 77 +++ .../base/protocols/coap/CoapResponseTest.java | 21 + 37 files changed, 1873 insertions(+), 1299 deletions(-) create mode 100644 cloud/interface/src/test/java/org/iotivity/cloud/ciserver/testci/TestCloudInterface.java create mode 100644 cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceManagerTest.java create mode 100644 cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceTest.java create mode 100644 cloud/stack/src/test/java/org/iotivity/cloud/base/SessionManagerTest.java create mode 100644 cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapRequestTest.java create mode 100644 cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapResponseTest.java diff --git a/cloud/account/README b/cloud/account/README index 4e7a0b9..4a2615b 100644 --- a/cloud/account/README +++ b/cloud/account/README @@ -14,7 +14,7 @@ Build and Run 3) Build a .jar file - $ mvn install + $ mvn install -Dmaven.test.skip=true - The CloudAccount-0.0.1-SNAPSHOT.jar file will be placed in the "target" folder diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java index 12b233e..96c36bf 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java @@ -32,7 +32,7 @@ import org.iotivity.cloud.util.Net; /** * - * This class is in charge of running account server. + * This class is in charge of running of account server. * */ public class AccountServer { diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServerManager.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServerManager.java index 4be8fb7..8a62ba7 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServerManager.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServerManager.java @@ -30,12 +30,21 @@ import org.iotivity.cloud.util.Logger; /** * - * This class provides a set of API to handle requests for registering account - * information of authorized user, and publishing and finding resources. + * This class provides a set of APIs to handle requests about account + * information of authorized user. * */ public class AccountServerManager { + /** + * API for requesting user account + * + * @param userId + * user identifier + * @param deviceId + * device identifier + * @return Boolean - true if registered, otherwise false + */ public Boolean registerUserAccount(String userId, String deviceId) { Boolean ret = false; @@ -47,6 +56,14 @@ public class AccountServerManager { return ret; } + /** + * API for requesting user account and getting session code for registered + * user. + * + * @param userId + * user identifier + * @return String - session code for registered user + */ public String registerUserAccount(String userId) { String sessionCode = null; @@ -60,10 +77,11 @@ public class AccountServerManager { } /** - * API for requesting user identifier to interested authorization server + * API for requesting user identifier corresponding with authorization + * information. * - * @param accessToeken - * access token + * @param authCode + * authorization code * @param authServer * authorization server * @return String - user identifier @@ -78,6 +96,13 @@ public class AccountServerManager { return userId; } + /** + * API for requesting user identifier corresponding with session code. + * + * @param sessionCode + * session code + * @return String - user identifier + */ public String requestUserId(String sessionCode) { String userId = null; @@ -89,10 +114,10 @@ public class AccountServerManager { } /** - * API for getting devices according to authorized user from database + * API for getting devices corresponding with user identifier. * * @param userId - * identifier of authorized user + * user identifier * @return ArrayList - list of devices */ public ArrayList requestAccountDevices(String userId) { @@ -105,15 +130,6 @@ public class AccountServerManager { return deviceList; } - /** - * API for requesting access token to interested authorization server - * - * @param authServer - * server name for authorization - * @param authCode - * authorization code - * @return ArrayList - array list of name of authorization servers - */ private String getAccessToken(String authCode, String authServer) { String accessToken = null; diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AccountDBManager.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AccountDBManager.java index faba8fe..1142c75 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AccountDBManager.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AccountDBManager.java @@ -58,28 +58,14 @@ public class AccountDBManager { return accoutDBManager; } - private void registerAdminAccount() { - - String adminId = "admin"; - String adminSessionCode = "00000000"; - - UserSession userSession = new UserSession(); - - userSession.setUserId(adminId); - userSession.setSessionCode(adminSessionCode); - - mongoDB.createResource(userSession); - mongoDB.printResources(); - } - /** - * API for storing session information of authorized user to mongoDB + * API for storing session information of authorized user * * @param userId - * identifier of authorized user + * user identifier * @param sessionCode * session code - * @return Boolean - true if stored, false if not + * @return Boolean - true if stored, otherwise false */ public Boolean registerUserSessionCode(String userId, String sessionCode) { @@ -94,6 +80,15 @@ public class AccountDBManager { return true; } + /** + * API for storing device information of authorized user + * + * @param userId + * user identifier + * @param deviceId + * device identifier + * @return Boolean - true if stored, otherwise false + */ public Boolean registerUserDevice(String userId, String deviceId) { UserDevice userDevice = new UserDevice(); @@ -107,6 +102,16 @@ public class AccountDBManager { return true; } + /** + * API for getting user identifier information corresponding with session + * code + * + * @param userId + * identifier of authorized user + * @param sessionCode + * session code + * @return Boolean - true if stored, otherwise false + */ public String getUserId(String sessionCode) { String userId = null; @@ -117,10 +122,10 @@ public class AccountDBManager { } /** - * API for getting devices according to authorized user + * API for getting devices corresponding with user identifier * * @param userId - * identifier of authorized user + * user identifier * @return ArrayList - list of devices */ public ArrayList getDevices(String userId) { @@ -131,4 +136,18 @@ public class AccountDBManager { return deviceList; } + + private void registerAdminAccount() { + + String adminId = "admin"; + String adminSessionCode = "00000000"; + + UserSession userSession = new UserSession(); + + userSession.setUserId(adminId); + userSession.setSessionCode(adminSessionCode); + + mongoDB.createResource(userSession); + mongoDB.printResources(); + } } diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java index 4f6ad4a..16b5d2b 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java @@ -51,6 +51,7 @@ public class MongoDB { * @throws Exception */ public MongoDB(String dbname) throws Exception { + mongoClient = new MongoClient(); mongoClient.dropDatabase(dbname); db = mongoClient.getDatabase(dbname); @@ -63,6 +64,7 @@ public class MongoDB { * collection name */ public void createTable(String tableName) { + db.createCollection(tableName); } @@ -73,20 +75,24 @@ public class MongoDB { * collection name */ public void deleteTable(String tableName) { + db.getCollection(tableName).drop(); } + /** + * API getting database object + * + */ public MongoDatabase getMongoDatabase() { + return db; } /** - * API for storing information of authorized users + * API for storing session information of user * - * @param accountInfo - * information of authorized users - * @param tablename - * table name of mongoDB + * @param UserSession + * session information of user */ public void createResource(UserSession userSession) { @@ -105,16 +111,21 @@ public class MongoDB { return; } + /** + * API for inserting device information of user + * + * @param UserDevice + * device information of user + */ public void createResource(UserDevice userDevice) { Document doc = createDocument(userDevice); MongoCollection collection = db .getCollection(Const.DEVICE_TABLE); - if (collection.findOneAndReplace( - Filters.and(Filters.eq(Const.USER_ID, doc.get(Const.USER_ID)), - Filters.eq(Const.DEVICE_ID, doc.get(Const.DEVICE_ID))), - doc) == null) { + if (collection.findOneAndReplace(Filters.and( + Filters.eq(Const.USER_ID, doc.get(Const.USER_ID)), + Filters.eq(Const.DEVICE_ID, doc.get(Const.DEVICE_ID))), doc) == null) { collection.insertOne(doc); } @@ -122,42 +133,14 @@ public class MongoDB { return; } - private Document createDocument(UserSession userSession) { - - Document doc = new Document(Const.USER_ID, userSession.getUserId()) - .append(Const.SESSION_CODE, userSession.getSessionCode()); - - return doc; - } - - private Document createDocument(UserDevice userDevice) { - - Document doc = new Document(Const.USER_ID, userDevice.getUserId()) - .append(Const.DEVICE_ID, userDevice.getDeviceId()); - - return doc; - } - - private UserSession convertSessionDocToResource(Document doc) { - - UserSession userSession = new UserSession(); - - userSession.setUserId(doc.getString(Const.USER_ID)); - userSession.setSessionCode(doc.getString(Const.SESSION_CODE)); - - return userSession; - } - - private UserDevice convertDeviceDocToResource(Document doc) { - - UserDevice userDevice = new UserDevice(); - - userDevice.setUserId(doc.getString(Const.USER_ID)); - userDevice.setDeviceId(doc.getString(Const.DEVICE_ID)); - - return userDevice; - } - + /** + * API for getting user identifier corresponding with session code from + * database + * + * @param sessionCode + * session code + * @return String - user identifier + */ public String getUserId(String sessionCode) { String userId = null; @@ -165,8 +148,8 @@ public class MongoDB { MongoCollection collection = db .getCollection(Const.SESSION_TABLE); - MongoCursor cursor = collection - .find(Filters.eq(Const.SESSION_CODE, sessionCode)).iterator(); + MongoCursor cursor = collection.find( + Filters.eq(Const.SESSION_CODE, sessionCode)).iterator(); try { @@ -188,12 +171,10 @@ public class MongoDB { } /** - * API for getting devices according to user from mongoDB + * API for getting devices corresponding with user identifier from database * * @param userId * user identifier - * @param tablename - * table name of mongoDB */ public ArrayList getDevices(String userId) { @@ -202,8 +183,8 @@ public class MongoDB { MongoCollection collection = db .getCollection(Const.DEVICE_TABLE); - MongoCursor cursor = collection - .find(Filters.eq(Const.USER_ID, userId)).iterator(); + MongoCursor cursor = collection.find( + Filters.eq(Const.USER_ID, userId)).iterator(); try { @@ -223,6 +204,71 @@ public class MongoDB { return deviceList; } + public void printResources() { + + ArrayList dlist = readDeviceResources(); + int size = dlist.size(); + + Logger.i("*Table: " + Const.DEVICE_TABLE); + for (int i = 0; i < size; i++) { + + UserDevice item = dlist.get(i); + + Logger.i("[" + i + "]" + item.getUserId() + ", " + + item.getDeviceId()); + } + + ArrayList slist = readSessionResources(); + size = slist.size(); + + Logger.i("*Table: " + Const.SESSION_TABLE); + + for (int i = 0; i < size; i++) { + + UserSession item = slist.get(i); + + Logger.i("[" + i + "]" + item.getUserId() + ", " + + item.getSessionCode()); + + } + } + + private Document createDocument(UserSession userSession) { + + Document doc = new Document(Const.USER_ID, userSession.getUserId()) + .append(Const.SESSION_CODE, userSession.getSessionCode()); + + return doc; + } + + private Document createDocument(UserDevice userDevice) { + + Document doc = new Document(Const.USER_ID, userDevice.getUserId()) + .append(Const.DEVICE_ID, userDevice.getDeviceId()); + + return doc; + } + + private UserSession convertSessionDocToResource(Document doc) { + + UserSession userSession = new UserSession(); + + userSession.setUserId(doc.getString(Const.USER_ID)); + userSession.setSessionCode(doc.getString(Const.SESSION_CODE)); + + return userSession; + } + + private UserDevice convertDeviceDocToResource(Document doc) { + + UserDevice userDevice = new UserDevice(); + + userDevice.setUserId(doc.getString(Const.USER_ID)); + userDevice.setDeviceId(doc.getString(Const.DEVICE_ID)); + + return userDevice; + } + private ArrayList readSessionResources() { ArrayList userSessionList = new ArrayList(); @@ -261,33 +307,4 @@ public class MongoDB { return userDeviceList; } - public void printResources() { - - ArrayList dlist = readDeviceResources(); - int size = dlist.size(); - - Logger.i("*Table: " + Const.DEVICE_TABLE); - for (int i = 0; i < size; i++) { - - UserDevice item = dlist.get(i); - - Logger.i("[" + i + "]" + item.getUserId() + ", " - + item.getDeviceId()); - } - - ArrayList slist = readSessionResources(); - size = slist.size(); - - Logger.i("*Table: " + Const.SESSION_TABLE); - - for (int i = 0; i < size; i++) { - - UserSession item = slist.get(i); - - Logger.i("[" + i + "]" + item.getUserId() + ", " - + item.getSessionCode()); - - } - } - } diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java index 5936d24..c0be4b8 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java @@ -40,8 +40,8 @@ import io.netty.channel.ChannelHandlerContext; /** * - * This class provides a set of APIs to handle requests for publishing and - * finding resources. + * This class provides a set of APIs to manage resources corresponding with user + * account * */ public class AccountResource extends Resource { @@ -51,8 +51,7 @@ public class AccountResource extends Resource { } @Override - public void onRequestReceived(ChannelHandlerContext ctx, - CoapRequest request) { + public void onRequestReceived(ChannelHandlerContext ctx, CoapRequest request) { Logger.d("AccountResource IN"); @@ -87,23 +86,13 @@ public class AccountResource extends Resource { } } - /** - * API for handling GET message - * - * @param ctx - * ChannelHandlerContext of request message - * @param request - * CoAP request message - * @throws Exception - */ - private void handleGetRequest(ChannelHandlerContext ctx, - CoapRequest request) throws Exception { + private void handleGetRequest(ChannelHandlerContext ctx, CoapRequest request) + throws Exception { String reqType = extractQuery(request, Const.REQ_TYPE); if (reqType == null) - throw new IllegalArgumentException( - "request type is null in query!"); + throw new IllegalArgumentException("request type is null in query!"); CoapResponse response = null; @@ -116,27 +105,17 @@ public class AccountResource extends Resource { Logger.w("reqType[" + reqType + "] is not supported"); } - ctx.write(response); + ctx.writeAndFlush(response); } - /** - * API for handling POST message - * - * @param ctx - * ChannelHandlerContext of request message - * @param request - * CoAP request message - * @throws Exception - */ private void handlePostRequest(ChannelHandlerContext ctx, CoapRequest request) throws Exception { String reqType = extractQuery(request, Const.REQ_TYPE); if (reqType == null) - throw new IllegalArgumentException( - "request type is null in query!"); + throw new IllegalArgumentException("request type is null in query!"); CoapResponse response = null; @@ -149,9 +128,18 @@ public class AccountResource extends Resource { "request type is not supported"); } - ctx.write(response); + ctx.writeAndFlush(response); } + /** + * API for handling request for publishing resource corresponding with user + * account + * + * @param requeset + * CoAP request message + * @return CoapResponse - CoAP response message with response result + * information + */ private CoapResponse handlePublishRequest(CoapRequest request) { String payload = request.getPayloadString(); @@ -172,16 +160,25 @@ public class AccountResource extends Resource { CoapResponse coapResponse = null; if (status) { - coapResponse = responseMessage.buildCoapResponse(request.getToken(), - CoapStatus.CREATED); + coapResponse = responseMessage.buildCoapResponse( + request.getToken(), CoapStatus.CREATED); } else { - coapResponse = responseMessage.buildCoapResponse(request.getToken(), - CoapStatus.INTERNAL_SERVER_ERROR); + coapResponse = responseMessage.buildCoapResponse( + request.getToken(), CoapStatus.INTERNAL_SERVER_ERROR); } return coapResponse; } + /** + * API for handling request for finding resource corresponding with user + * account + * + * @param requeset + * CoAP request message + * @return CoapResponse - CoAP response message with response result + * information + */ private CoapResponse handleFindRequest(CoapRequest request) { String payload = request.getPayloadString(); diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java index 234eaf3..7a85141 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java @@ -39,8 +39,8 @@ import io.netty.channel.ChannelHandlerContext; /** * - * This class provides a set of APIs to register account information of - * authorized user. + * This class provides a set of APIs to manage user account with authorization + * process. * */ public class AuthResource extends Resource { @@ -50,7 +50,8 @@ public class AuthResource extends Resource { } @Override - public void onRequestReceived(ChannelHandlerContext ctx, CoapRequest request) { + public void onRequestReceived(ChannelHandlerContext ctx, + CoapRequest request) { Logger.d("AuthResource IN"); @@ -77,22 +78,14 @@ public class AuthResource extends Resource { } } - /** - * API for handling POST message - * - * @param ctx - * ChannelHandlerContext of request message - * @param request - * CoAP request message - * @throws Exception - */ private void handlePostRequest(ChannelHandlerContext ctx, CoapRequest request) throws Exception { String reqType = extractQuery(request, Const.REQ_TYPE); if (reqType == null) - throw new IllegalArgumentException("request type is null in query!"); + throw new IllegalArgumentException( + "request type is null in query!"); CoapResponse response = null; @@ -108,16 +101,24 @@ public class AuthResource extends Resource { "request type is not supported"); } - ctx.write(response); + ctx.writeAndFlush(response); } + /** + * API for handling request for login by user account + * + * @param request + * CoAP request message + * @return CoapResponse - CoAP response message with response result + * information + */ private CoapResponse handleLoginRequest(CoapRequest request) { String payload = request.getPayloadString(); JSONUtil util = new JSONUtil(); - String sessionCode = util - .parseJSON(payload, Const.REQUEST_SESSION_CODE); + String sessionCode = util.parseJSON(payload, + Const.REQUEST_SESSION_CODE); Logger.d("sessionCode: " + sessionCode); @@ -136,19 +137,27 @@ public class AuthResource extends Resource { String responseJson = convertLoginResponseToJson(response); Logger.d("responseJson: " + responseJson); - coapResponse = responseMessage.buildCoapResponse( - request.getToken(), responseJson, CoapStatus.CREATED); + coapResponse = responseMessage.buildCoapResponse(request.getToken(), + responseJson, CoapStatus.CREATED); } else { - coapResponse = responseMessage.buildCoapResponse( - request.getToken(), CoapStatus.INTERNAL_SERVER_ERROR); + coapResponse = responseMessage.buildCoapResponse(request.getToken(), + CoapStatus.INTERNAL_SERVER_ERROR); } return coapResponse; } + /** + * API for handling request for registering user account + * + * @param request + * CoAP request message + * @return CoapResponse - CoAP response message with response result + * information + */ private CoapResponse handleRegisterRequest(CoapRequest request) { String payload = request.getPayloadString(); @@ -178,13 +187,13 @@ public class AuthResource extends Resource { String responseJson = convertRegisterResponseToJson(response); Logger.d("responseJson: " + responseJson); - coapResponse = responseMessage.buildCoapResponse( - request.getToken(), responseJson, CoapStatus.CREATED); + coapResponse = responseMessage.buildCoapResponse(request.getToken(), + responseJson, CoapStatus.CREATED); } else { - coapResponse = responseMessage.buildCoapResponse( - request.getToken(), CoapStatus.UNAUTHORIZED); + coapResponse = responseMessage.buildCoapResponse(request.getToken(), + CoapStatus.UNAUTHORIZED); } diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java index 47e9269..47cbe58 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java @@ -32,18 +32,39 @@ import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus; /** * - * This class provides utility for making CoAP request and response. + * This class provides a set of APIs to build build data of CoAP request and + * response type. * */ public class CoapMessageBuilder { public static final int APPLICATION_JSON = 50; + /** + * API for building data of CoAP response type without payload. + * + * @param token + * token + * @param status + * response status + * @return CoapResponse - data of CoAP response type + */ public CoapResponse buildCoapResponse(byte[] token, CoapStatus status) { return buildCoapResponse(token, null, status); } + /** + * API for building data of CoAP response type with payload. + * + * @param token + * token + * @param jsonString + * payload data + * @param status + * response status + * @return CoapResponse - data of CoAP response type + */ public CoapResponse buildCoapResponse(byte[] token, String jsonString, CoapStatus status) { @@ -62,6 +83,15 @@ public class CoapMessageBuilder { return coapResponse; } + /** + * API for building data of CoAP requeset type with payload. + * + * @param token + * token + * @param jsonString + * payload data + * @return CoapRequest - data of CoAP request type + */ public CoapRequest buildCoapRequest(byte[] token, String jsonString) { CoapRequest coapRequest = new CoapRequest(CoapMethod.GET); diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/JSONUtil.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/JSONUtil.java index 70fca30..8fb0816 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/JSONUtil.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/JSONUtil.java @@ -30,14 +30,21 @@ import com.fasterxml.jackson.databind.ObjectMapper; /** * - * This class provides utility for parsing JSON object and converting data to - * JSON string. + * This class provides a set of APIs to parse JSON object and convert data + * object to JSON string. * */ public class JSONUtil { private static ObjectMapper mapper = new ObjectMapper(); + /** + * API for parsing json string and getting value corresponding with key. + * + * @param jsonString + * json string + * @return String - value corresponding with key + */ public String parseJSON(String jsonString, String key) { if (jsonString == null || jsonString.equals("")) @@ -57,6 +64,13 @@ public class JSONUtil { return value; } + /** + * API for converting data of HashMap-type to json string. + * + * @param data + * data of HashMap-type + * @return String - converted json string + */ public String writeJSON(HashMap data) { if (data == null) return null; diff --git a/cloud/account/src/test/java/org/iotivity/cloud/testaccountserver/TestAccountServer.java b/cloud/account/src/test/java/org/iotivity/cloud/testaccountserver/TestAccountServer.java index 9080ceb..0d39ee1 100644 --- a/cloud/account/src/test/java/org/iotivity/cloud/testaccountserver/TestAccountServer.java +++ b/cloud/account/src/test/java/org/iotivity/cloud/testaccountserver/TestAccountServer.java @@ -84,7 +84,7 @@ public class TestAccountServer { System.out .println("https://github.com/login?return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dea9c18f540323b0213d0%26redirect_uri%3Dhttp%253A%252F%252Fwww.example.com%252Foauth_callback%252F"); - String authCode = "a05c2d8f6531ec15230e"; // write your authCode here. + String authCode = "7243699de9726d05e74c"; // write your authCode here. String authServer = "github"; String json = "{\"authcode\":\"" + authCode + "\",\"authprovider\":\"" @@ -153,7 +153,7 @@ public class TestAccountServer { String userId = "eyedglen"; String json = "{\"userid\":\"" + userId + "\"}"; - CoapRequest request = new CoapRequest(CoapMethod.POST); + CoapRequest request = new CoapRequest(CoapMethod.GET); request.setUriPath(Const.ACCOUNT_URI); request.setUriQuery("reqtype=find"); request.setToken("1234".getBytes(StandardCharsets.UTF_8)); diff --git a/cloud/interface/README b/cloud/interface/README index c0867c7..698c03f 100644 --- a/cloud/interface/README +++ b/cloud/interface/README @@ -13,7 +13,7 @@ Build and Run 3) Build a .jar file - $ mvn install + $ mvn install -Dmaven.test.skip=true - The CloudInterface-0.0.1-SNAPSHOT.jar file will be placed in the "target" folder diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/CloudInterfaceServer.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/CloudInterfaceServer.java index 83301fa..88e0577 100644 --- a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/CloudInterfaceServer.java +++ b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/CloudInterfaceServer.java @@ -59,7 +59,7 @@ public class CloudInterfaceServer { sessionManager = new SessionManager(); - resourceManager = new ResourceManager(sessionManager); + resourceManager = new ResourceManager(); coapServer.addHandler( new CoapAuthHandler(args[3], Integer.parseInt(args[4]))); diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapAuthHandler.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapAuthHandler.java index d0daaaa..9cfa4d5 100644 --- a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapAuthHandler.java +++ b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapAuthHandler.java @@ -1,3 +1,24 @@ +/* + * //****************************************************************** + * // + * // Copyright 2016 Samsung Electronics All Rights Reserved. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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.cloud.ciserver.protocols; import java.net.InetSocketAddress; diff --git a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java index 395b326..3629097 100644 --- a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java +++ b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java @@ -34,8 +34,8 @@ import org.iotivity.cloud.base.protocols.coap.CoapResponse; import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus; import org.iotivity.cloud.ciserver.Constants; +import org.iotivity.cloud.util.Cbor; import org.iotivity.cloud.util.Logger; -import org.iotivity.cloud.util.Net; import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandler.Sharable; @@ -148,10 +148,14 @@ public class CoapRelayHandler extends ChannelDuplexHandler { .set(new ArrayList()); } + public CoapRelayHandler(SessionManager sessionManager) { + this.sessionManager = sessionManager; + } + private static final AttributeKey keyDevice = AttributeKey .newInstance("deviceCtx"); - private HashMap ciRelayClients = new HashMap(); + private Cbor> cbor = new Cbor>(); @Override public void channelRead(ChannelHandlerContext ctx, Object msg) @@ -192,7 +196,8 @@ public class CoapRelayHandler extends ChannelDuplexHandler { accountRequest.setUriPath(Constants.ACCOUNT_URI); accountRequest.setUriQuery("reqtype=publish"); accountRequest.setToken(request.getToken()); - accountRequest.setPayload(authPayload.getBytes(StandardCharsets.UTF_8)); + accountRequest.setPayload(authPayload + .getBytes(StandardCharsets.UTF_8)); // TODO: deviceId must be registered after session // granted @@ -247,62 +252,45 @@ public class CoapRelayHandler extends ChannelDuplexHandler { default: List uriPathList = request.getUriPathSegments(); - String originUriPathList = request.getUriPath(); Logger.i("uriPahtList: " + uriPathList.toString()); - String ciAddress = uriPathList.get(0); - String did = uriPathList.get(1); - Logger.i("CI address: " + ciAddress); + String did = uriPathList.get(0); + Logger.i("did: " + did); - // TODO: getMyIP ? - String hostAddress = Net.getMyIpAddress().replace("/", ""); - Logger.i("hostAddress : " + hostAddress); - // if published CI is mine - if (hostAddress.equals(ciAddress) == true) { - // find ctx about did, and send msg - Logger.d("published CI is mine"); - String resource = new String(); - List pathSegments = uriPathList.subList(2, - uriPathList.size()); - for (String path : pathSegments) { - resource += "/"; - resource += path; - } - Logger.i("resource: " + resource); - request.setUriPath(resource); - - ChannelHandlerContext deviceCtx = sessionManager - .querySession(did); - if (deviceCtx != null) { - deviceCtx.attr(keyDevice).set(ctx); - deviceCtx.writeAndFlush(request); - } else { - Logger.e("deviceCtx is null"); - response = new CoapResponse(CoapStatus.FORBIDDEN); - response.setToken(request.getToken()); - ctx.writeAndFlush(response); - } + // TODO: Clustering algorithm required + // find ctx about did, and send msg + String resource = new String(); + List pathSegments = uriPathList.subList(1, + uriPathList.size()); + for (String path : pathSegments) { + resource += "/"; + resource += path; + } + Logger.i("resource: " + resource); + request.setUriPath(resource); + + ChannelHandlerContext deviceCtx = sessionManager + .querySession(did); + if (deviceCtx != null) { + deviceCtx.attr(keyDevice).set(ctx); + deviceCtx.writeAndFlush(request); } else { - // if CI is not connected, connect and send msg - CoapClient otherCI = null; - synchronized (ciRelayClients) { - otherCI = ciRelayClients.get(ciAddress); - if (otherCI == null) { - otherCI = new CoapClient(); - otherCI.startClient( - new InetSocketAddress(ciAddress, 5683)); - ciRelayClients.put(ciAddress, otherCI); - } - } - request.setUriPath(originUriPathList); - otherCI.sendRequest(request); + Logger.e("deviceCtx is null"); + response = new CoapResponse(CoapStatus.FORBIDDEN); + response.setToken(request.getToken()); + ctx.writeAndFlush(response); } return; } } else if (msg instanceof CoapResponse) { if (ctx.attr(keyDevice).get() != null) { + Logger.i("Forwards message to client"); + + if (((CoapResponse) msg).getPayload() == null) + Logger.i("No payload in reponse"); + Logger.i("ctx.channel : " + ctx.attr(keyDevice).get().channel().toString()); ctx.attr(keyDevice).get().writeAndFlush(msg); @@ -314,6 +302,13 @@ public class CoapRelayHandler extends ChannelDuplexHandler { } @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + Logger.d("Channel Inactive"); + sessionManager.removeSessionByChannel(ctx); + super.channelInactive(ctx); + } + + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); diff --git a/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/testci/TestCloudInterface.java b/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/testci/TestCloudInterface.java new file mode 100644 index 0000000..4856855 --- /dev/null +++ b/cloud/interface/src/test/java/org/iotivity/cloud/ciserver/testci/TestCloudInterface.java @@ -0,0 +1,255 @@ +package org.iotivity.cloud.ciserver.testci; + +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; + +import org.iotivity.cloud.base.CoapClient; +import org.iotivity.cloud.base.CoapServer; +import org.iotivity.cloud.base.ResourceManager; +import org.iotivity.cloud.base.SessionManager; +import org.iotivity.cloud.base.protocols.coap.CoapRequest; +import org.iotivity.cloud.base.protocols.coap.CoapResponse; +import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; +import org.iotivity.cloud.ciserver.Constants; +import org.iotivity.cloud.ciserver.protocols.CoapRelayHandler; +import org.iotivity.cloud.ciserver.resources.KeepAliveResource; +import org.iotivity.cloud.util.Cbor; +import org.iotivity.cloud.util.CoapLogHandler; +import org.junit.Test; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +public class TestCloudInterface { + + private SessionManager sessionManager = new SessionManager(); + private ResourceManager resourceManager = new ResourceManager(); + + private CoapServer coapServer = null; + private CoapClient coapClient = null; + private CoapRelayHandler coapRelayHandler = new CoapRelayHandler( + sessionManager); + private KeepAliveResource keepAliveResource = new KeepAliveResource( + sessionManager, new int[] { 1, 2, 4, 8 }); + + static class CoapClientHandler + extends SimpleChannelInboundHandler { + + ChannelHandlerContext connectCtx = null; + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + connectCtx = ctx; + } + + @Override + protected void channelRead0(ChannelHandlerContext arg0, + CoapResponse arg1) throws Exception { + // TODO : receive response + System.out.println("Get Response"); + } + } + + public void startServer() throws Exception { + + coapServer = new CoapServer(); + + coapServer.addHandler(new CoapLogHandler()); + coapServer.addHandler(coapRelayHandler); + + coapServer.addHandler(resourceManager); + resourceManager.registerResource(keepAliveResource); + + coapServer.startServer(new InetSocketAddress(5683)); + } + + public ChannelHandlerContext startClient() throws Exception { + + coapClient = new CoapClient(); + + CoapClientHandler coapHandler = new CoapClientHandler(); + coapClient.addHandler(coapHandler); + + coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); + + return coapHandler.connectCtx; + } + + public CoapRequest makePayload(CoapRequest request) throws Exception { + ArrayList payload = new ArrayList(); + + HashMap tags = new HashMap(); + tags.put("di", "98f7483c-5a31-4161-ba7e-9c13e0d"); + tags.put("bm", (int) 1); + tags.put("ttl", (int) 86400); + + ArrayList> publishLinks = new ArrayList>(); + LinkedHashMap link = new LinkedHashMap(); + link.put("href", "/a/light"); + ArrayList rt = new ArrayList(); + ArrayList itf = new ArrayList(); + ArrayList mt = new ArrayList(); + rt.add("core.light"); + link.put("rt", rt); + + itf.add("oic.if.baseline"); + link.put("if", itf); + + mt.add("application/json"); + link.put("mt", mt); + + link.put("ins", 1); + + publishLinks.add(link); + + payload.add(tags); + payload.add(publishLinks); + + Cbor> cbor = new Cbor>(); + + request.setPayload(cbor.encodingPayloadToCbor(payload)); + + return request; + } + + public CoapRequest makeinterval(CoapRequest request) throws Exception { + + HashMap payload = new HashMap(); + payload.put("in", 1); + + Cbor> cbor = new Cbor>(); + + request.setPayload(cbor.encodingPayloadToCbor(payload)); + + return request; + } + + @Test + public void TestKeepAlivePutInterval() throws Exception { + + CoapRequest request = new CoapRequest(CoapMethod.PUT); + request.setUriPath(Constants.KEEP_ALIVE_URI); + request.setToken("1234".getBytes(StandardCharsets.UTF_8)); + makeinterval(request); + + startServer(); + ChannelHandlerContext ctx = startClient(); + + coapClient.sendRequest(request); + + System.out.println("Waiting for KeepAliveTask.."); + Thread.sleep(30000); + + coapClient.stopClient(); + coapServer.stopServer(); + } + + @Test + public void TestKeepAliveGetFirst() throws Exception { + + CoapRequest request = new CoapRequest(CoapMethod.GET); + request.setUriPath(Constants.KEEP_ALIVE_URI); + request.setToken("1234".getBytes(StandardCharsets.UTF_8)); + + startServer(); + ChannelHandlerContext ctx = startClient(); + + coapClient.sendRequest(request); + + coapClient.stopClient(); + coapServer.stopServer(); + } + + @Test + public void TestDiscoveryDevice() throws Exception { + + CoapRequest request = new CoapRequest(CoapMethod.GET); + request.setUriPath(Constants.WELL_KNOWN_URI); + request.setUriQuery("rt=oic.wk.rdpub"); + request.setToken("1234".getBytes(StandardCharsets.UTF_8)); + + startServer(); + ChannelHandlerContext ctx = startClient(); + + coapClient.sendRequest(request); + + coapClient.stopClient(); + coapServer.stopServer(); + } + + @Test + public void TestPublishDevice() throws Exception { + + CoapRequest request = new CoapRequest(CoapMethod.POST); + request.setUriPath(Constants.RD_URI); + request.setUriQuery("rt=oic.wk.rdpub"); + request.setToken("1234".getBytes(StandardCharsets.UTF_8)); + makePayload(request); + + startServer(); + ChannelHandlerContext ctx = startClient(); + + coapClient.sendRequest(request); + + coapClient.stopClient(); + coapServer.stopServer(); + } + + @Test + public void TestRequestGetMessageToDeviceCIOwner() throws Exception { + + CoapRequest request = new CoapRequest(CoapMethod.GET); + request.setUriPath( + "/10.113.64.98/98f7483c-5a31-4161-ba7e-9c13e0d/a/light"); + request.setToken("1234".getBytes(StandardCharsets.UTF_8)); + makePayload(request); + + startServer(); + ChannelHandlerContext ctx = startClient(); + + coapClient.sendRequest(request); + + coapServer.stopServer(); + coapClient.stopClient(); + } + + @Test + public void TestRequestGetMessageToDeviceNotCIOwner() throws Exception { + + CoapRequest request = new CoapRequest(CoapMethod.GET); + request.setUriPath( + "/10.113.64.102/98f7483c-5a31-4161-ba7e-9c13e0d/a/light"); + request.setToken("1234".getBytes(StandardCharsets.UTF_8)); + makePayload(request); + + startServer(); + ChannelHandlerContext ctx = startClient(); + + coapClient.sendRequest(request); + + coapServer.stopServer(); + coapClient.stopClient(); + } + + @Test + public void TestRequestPutMessageToDevice() throws Exception { + + CoapRequest request = new CoapRequest(CoapMethod.PUT); + request.setUriPath( + "/10.113.64.98/98f7483c-5a31-4161-ba7e-9c13e0d/a/light"); + request.setToken("1234".getBytes(StandardCharsets.UTF_8)); + makePayload(request); + + startServer(); + ChannelHandlerContext ctx = startClient(); + + coapClient.sendRequest(request); + + coapServer.stopServer(); + coapClient.stopClient(); + } + +} diff --git a/cloud/resourcedirectory/README b/cloud/resourcedirectory/README index 9b8623f..36eadcb 100644 --- a/cloud/resourcedirectory/README +++ b/cloud/resourcedirectory/README @@ -13,7 +13,7 @@ Build and Run 3) Build a CloudStack. If you are building first time, then build the stack. go to "stack" folder in root directory - $ mvn install + $ mvn install -Dmaven.test.skip=true 4) Build a .jar file diff --git a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java index e2d1502..2276568 100644 --- a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java +++ b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java @@ -21,7 +21,6 @@ */ package org.iotivity.cloud.rdserver.resources; -import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -40,7 +39,6 @@ import org.iotivity.cloud.rdserver.JSONUtil; import org.iotivity.cloud.rdserver.MongoDB; import org.iotivity.cloud.util.Cbor; import org.iotivity.cloud.util.Logger; -import org.iotivity.cloud.util.Net; import io.netty.channel.ChannelHandlerContext; @@ -173,7 +171,8 @@ public class ResourceDirectoryResource extends Resource { for (HashMap segmentPayload : discoverPayload) { String stringDi = segmentPayload.get(Constants.RS_DEVICE_ID) .toString(); - segmentPayload.put(Constants.RS_DEVICE_ID, stringDi.getBytes(StandardCharsets.UTF_8)); + segmentPayload.put(Constants.RS_DEVICE_ID, + stringDi.getBytes(StandardCharsets.UTF_8)); } Logger.i("discoverPayload :" + discoverPayload.toString()); @@ -325,13 +324,6 @@ public class ResourceDirectoryResource extends Resource { PublishPayloadFormat pubPayload = new PublishPayloadFormat(); - String ciAddress = ((InetSocketAddress) ctx.channel() - .remoteAddress()).getAddress().getHostAddress(); - - if (ciAddress.equalsIgnoreCase("127.0.0.1")) { - ciAddress = Net.getMyIpAddress().replace("/", ""); - } - ArrayList payloadData = cbor.parsePayloadFromCbor( request.getPayload(), ArrayList.class); @@ -405,7 +397,7 @@ public class ResourceDirectoryResource extends Resource { LinksPayloadFormat storeLinks = new LinksPayloadFormat(); if (o.get(Constants.RS_HREF) != null) { - String prefix = "/" + ciAddress + "/" + pubPayload.getDi(); + String prefix = "/" + pubPayload.getDi(); storeLinks.setHref( prefix + o.get(Constants.RS_HREF).toString()); Logger.i("href : " + storeLinks.getHref()); diff --git a/cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java b/cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java index 7d5ff40..72929d0 100644 --- a/cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java +++ b/cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java @@ -85,7 +85,7 @@ public class RDServerTest { CoapRequest request = new CoapRequest(CoapMethod.POST); request.setUriPath(Constants.RD_URI); - request.setUriQuery("rt=oic.wk.rdPub"); + request.setUriQuery("rt=oic.wk.rdpub"); request.setToken("1234".getBytes(StandardCharsets.UTF_8)); ArrayList payload = new ArrayList(); diff --git a/cloud/samples/client/SConscript b/cloud/samples/client/SConscript index 4bc2807..5f51c88 100644 --- a/cloud/samples/client/SConscript +++ b/cloud/samples/client/SConscript @@ -42,7 +42,7 @@ cc_sample_app_env.AppendUnique(CPPPATH = [ cc_sample_app_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x', '-pthread']) cc_sample_app_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) cc_sample_app_env.AppendUnique(RPATH = [env.get('BUILD_DIR')]) -cc_sample_app_env.PrependUnique(LIBS = ['oc', 'octbstack']) +cc_sample_app_env.PrependUnique(LIBS = ['octbstack']) ###################################################################### # Source files and Targets diff --git a/cloud/samples/client/cloud_connector.c b/cloud/samples/client/cloud_connector.c index 4083a5c..9c3924a 100644 --- a/cloud/samples/client/cloud_connector.c +++ b/cloud/samples/client/cloud_connector.c @@ -83,55 +83,12 @@ static OCStackResult createStringLL(uint8_t numElements, OCResourceHandle handle return OC_STACK_OK; } -OCStackResult parseHost(const char *host, int *port, char *addr) -{ - //Parse addr, port from host - if (strstr(host, DEFAULT_COAP_TCP_HOST) != NULL) - { - *port = DEFAULT_COAP_TCP_PORT; - strncpy(addr, host + strlen(DEFAULT_COAP_TCP_HOST), - strlen(host) - strlen(DEFAULT_COAP_TCP_HOST)); - } - else if (strstr(host, DEFAULT_COAP_TCP_SECURE_HOST) != NULL) - { - *port = DEFAULT_COAP_TCP_SECURE_PORT; - strncpy(addr, host + strlen(DEFAULT_COAP_TCP_SECURE_HOST), - strlen(host) - strlen(DEFAULT_COAP_TCP_SECURE_HOST)); - } - else - { - return OC_STACK_INVALID_URI; - } - - if (strchr(addr, ':') != NULL) - { - char *strPort = strchr(addr, ':'); - *port = atoi(strPort + 1); - addr[strlen(addr) - strlen(strPort)] = '\0'; - } - - return OC_STACK_OK; -} - OCStackResult OCCloudRegisterLogin(const char *host, const char *auth_provider, const char *auth_code, OCClientResponseHandler response) { char targetUri[MAX_URI_LENGTH * 2] = { 0, }; snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, DEFAULT_AUTH_REGISTER_LOGIN); - int port = 0; - char addr[MAX_ADDR_STR_SIZE] = { 0, }; - - if (parseHost(host, &port, (char *)&addr) != OC_STACK_OK) - { - return OC_STACK_INVALID_URI; - } - - OCDevAddr authAddr; - memset(&authAddr, 0, sizeof(OCDevAddr)); - OICStrcpy(authAddr.addr, MAX_ADDR_STR_SIZE, addr); - authAddr.port = port; - OCCallbackData cbData; memset(&cbData, 0, sizeof(OCCallbackData)); cbData.cb = response; @@ -147,7 +104,7 @@ OCStackResult OCCloudRegisterLogin(const char *host, const char *auth_provider, OCRepPayloadSetPropString(registerPayload, "authprovider", auth_provider); OCRepPayloadSetPropString(registerPayload, "authcode", auth_code); - return OCDoResource(NULL, OC_REST_POST, targetUri, &authAddr, (OCPayload *)registerPayload, + return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)registerPayload, CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0); no_memory: @@ -161,19 +118,6 @@ OCStackResult OCCloudLoginout(const char *host, const char *query, const char *a char targetUri[MAX_URI_LENGTH * 2] = { 0, }; snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query); - int port = 0; - char addr[MAX_ADDR_STR_SIZE] = { 0, }; - - if (parseHost(host, &port, (char *)&addr) != OC_STACK_OK) - { - return OC_STACK_INVALID_URI; - } - - OCDevAddr authAddr; - memset(&authAddr, 0, sizeof(OCDevAddr)); - OICStrcpy(authAddr.addr, MAX_ADDR_STR_SIZE, addr); - authAddr.port = port; - OCCallbackData cbData; memset(&cbData, 0, sizeof(OCCallbackData)); cbData.cb = response; @@ -188,7 +132,7 @@ OCStackResult OCCloudLoginout(const char *host, const char *query, const char *a OCRepPayloadSetPropString(loginoutPayload, "session", auth_session); - return OCDoResource(NULL, OC_REST_POST, targetUri, &authAddr, (OCPayload *)loginoutPayload, + return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)loginoutPayload, CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0); no_memory: @@ -215,19 +159,6 @@ OCStackResult OCCloudPublish(const char *host, const char *query, char targetUri[MAX_URI_LENGTH * 2] = { 0, }; snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query); - int port = 0; - char addr[MAX_ADDR_STR_SIZE] = { 0, }; - - if (parseHost(host, &port, (char *)&addr) != OC_STACK_OK) - { - return OC_STACK_INVALID_URI; - } - - OCDevAddr rdAddr; - memset(&rdAddr, 0, sizeof(OCDevAddr)); - OICStrcpy(rdAddr.addr, MAX_ADDR_STR_SIZE, addr); - rdAddr.port = port; - // Gather all resources locally and do publish OCCallbackData cbData; memset(&cbData, 0, sizeof(OCCallbackData)); @@ -331,7 +262,7 @@ OCStackResult OCCloudPublish(const char *host, const char *query, goto no_memory; } - return OCDoResource(NULL, OC_REST_POST, targetUri, &rdAddr, (OCPayload *)rdPayload, + return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload, CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0); no_memory: diff --git a/cloud/samples/client/sample_device.cpp b/cloud/samples/client/sample_device.cpp index 4ecc23b..342c46d 100644 --- a/cloud/samples/client/sample_device.cpp +++ b/cloud/samples/client/sample_device.cpp @@ -29,321 +29,427 @@ #include #include #include -#include "OCPlatform.h" -#include "OCApi.h" +#include + +#include "ocstack.h" +#include "ocpayload.h" #include "cloud_connector.h" #define DEFAULT_CONTEXT_VALUE 0x99 #define DEFAULT_PUBLISH_QUERY "/oic/rd?rt=oic.wk.rdpub" -#define DEFAULT_DISCOVER_QUERY "/oic/res?rt=core.foo" - -using namespace OC; +#define DEFAULT_DISCOVER_QUERY "/oic/res?rt=core.light" -typedef std::map> DiscoveredResourceMap; +////////////////////////////////////////Device Sample +#define SAMPLE_MAX_NUM_POST_INSTANCE 2 +typedef struct LIGHTRESOURCE +{ + OCResourceHandle handle; + bool state; + int power; +} LightResource; +static LightResource Light; +static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE]; -DiscoveredResourceMap discoveredResources; -class ResourceClient +OCRepPayload *getPayload(const char *uri, int64_t power, bool state) { - private: - void putResourceInfo(const HeaderOptions & /*headerOptions*/, - const OCRepresentation rep, const OCRepresentation /*rep2*/, const int eCode) - { - std::cout << "In PutResourceInfo" << std::endl; + OCRepPayload *payload = OCRepPayloadCreate(); + if (!payload) + { + std::cout << "Failed to allocate Payload" << std::endl; + return nullptr; + } - std::cout << "Clientside Put response to get was: " << std::endl; - std::cout << "ErrorCode: " << eCode << std::endl; + OCRepPayloadSetUri(payload, uri); + OCRepPayloadSetPropBool(payload, "state", state); + OCRepPayloadSetPropInt(payload, "power", power); - if (eCode == 0) - { - std::cout << "Successful Put. Attributes sent were: " << std::endl; + return payload; +} - rep.getValue("isFoo", m_isFoo); - rep.getValue("barCount", m_barCount); - std::cout << "\tisFoo: " << m_isFoo << std::endl; - std::cout << "\tbarCount: " << m_barCount << std::endl; +OCRepPayload *constructResponse(OCEntityHandlerRequest *ehRequest) +{ + char *resourceUri = NULL; - std::cout << "Actual New values are: " << std::endl; + if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION) + { + std::cout << "Incoming payload not a representation" << std::endl; + return nullptr; + } - rep.getValue("isFoo", m_isFoo); - rep.getValue("barCount", m_barCount); + LightResource *currLightResource = &Light; - std::cout << "\tisFoo: " << m_isFoo << std::endl; - std::cout << "\tbarCount: " << m_barCount << std::endl; + if (ehRequest->resource == gLightInstance[0].handle) + { + currLightResource = &gLightInstance[0]; + resourceUri = (char *) "/a/light/0"; + } + else if (ehRequest->resource == gLightInstance[1].handle) + { + currLightResource = &gLightInstance[1]; + resourceUri = (char *) "/a/light/1"; + } - m_cv.notify_all(); - } - } + std::cout << "Resource URI " << resourceUri << std::endl; - void getResourceInfo(const HeaderOptions & /*headerOptions*/, const OCRepresentation rep, - const int eCode) - { - std::cout << "In getResourceInfo" << std::endl; + return getPayload(resourceUri, currLightResource->power, currLightResource->state); +} - std::cout << "Clientside response to get was: " << std::endl; - std::cout << "Error Code: " << eCode << std::endl; +OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, + OCRepPayload **payload) +{ + OCRepPayload *getResp = constructResponse(ehRequest); + if (!getResp) + { + std::cout << "constructResponse failed" << std::endl; + return OC_EH_ERROR; + } - if (eCode == 0) - { - std::cout << "Successful Get. Attributes are: " << std::endl; + *payload = getResp; - rep.getValue("isFoo", m_isFoo); - rep.getValue("barCount", m_barCount); + return OC_EH_OK; +} - std::cout << "\tisFoo: " << m_isFoo << std::endl; - std::cout << "\tbarCount: " << m_barCount << std::endl; +OCEntityHandlerResult +OCEntityHandlerCb(OCEntityHandlerFlag flag, + OCEntityHandlerRequest *entityHandlerRequest, void * /*callback*/) +{ + OCEntityHandlerResult ehResult = OC_EH_OK; + OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, {}, { 0 }, false }; - std::cout << "Doing a put on q/foo" << std::endl; - OCRepresentation rep2(rep); - m_isFoo = false; - m_barCount = 211; + // Validate pointer + if (!entityHandlerRequest) + { + std::cout << "Invalid request pointer" << std::endl; + return OC_EH_ERROR; + } - rep2.setValue("isFoo", m_isFoo); - rep2.setValue("barCount", m_barCount); + // Initialize certain response fields + response.numSendVendorSpecificHeaderOptions = 0; + memset(response.sendVendorSpecificHeaderOptions, + 0, sizeof response.sendVendorSpecificHeaderOptions); + memset(response.resourceUri, 0, sizeof response.resourceUri); + OCRepPayload *payload = nullptr; - m_resource->put(rep2, QueryParamsMap(), - PutCallback(std::bind(&ResourceClient::putResourceInfo, this, std::placeholders::_1, - rep2, std::placeholders::_2, std::placeholders::_3))); - } - } + if (flag & OC_REQUEST_FLAG) + { + std::cout << "Flag includes OC_REQUEST_FLAG" << std::endl; - void foundResource(std::shared_ptr resource) + if (OC_REST_GET == entityHandlerRequest->method) { - std::cout << "In foundResource" << std::endl; - std::lock_guard lock(m_resourceLock); - - if (discoveredResources.find(resource->uniqueIdentifier()) == discoveredResources.end()) - { - std::cout << "Found resource " << resource->uniqueIdentifier() << - " for the first time on server with ID: " << resource->sid() << std::endl; - discoveredResources[resource->uniqueIdentifier()] = resource; - } - else + std::cout << "Received OC_REST_GET from client" << std::endl; + ehResult = ProcessGetRequest(entityHandlerRequest, &payload); + } + else + { + std::cout << "Received unsupported method %d from client " << entityHandlerRequest->method << + std::endl; + ehResult = OC_EH_ERROR; + } + // If the result isn't an error or forbidden, send response + if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN))) + { + // Format the response. Note this requires some info about the request + response.requestHandle = entityHandlerRequest->requestHandle; + response.resourceHandle = entityHandlerRequest->resource; + response.ehResult = ehResult; + response.payload = reinterpret_cast(payload); + // Indicate that response is NOT in a persistent buffer + response.persistentBufferFlag = 0; + + // Send the response + if (OCDoResponse(&response) != OC_STACK_OK) { - std::cout << "Found resource " << resource->uniqueIdentifier() << " again!" << std::endl; + std::cout << "Error sending response" << std::endl; + ehResult = OC_EH_ERROR; } + } + } - if (resource) - { - std::cout << "Found Resource: " << std::endl; - std::cout << "\tHost: " << resource->host() << std::endl; - std::cout << "\tURI: " << resource->uri() << std::endl; - - // Get the resource types - std::cout << "\tList of resource types: " << std::endl; - for (auto &resourceTypes : resource->getResourceTypes()) - { - std::cout << "\t\t" << resourceTypes << std::endl; - } + OCPayloadDestroy(response.payload); + return ehResult; +} - // Get the resource interfaces - std::cout << "\tList of resource interfaces: " << std::endl; - for (auto &resourceInterfaces : resource->getResourceInterfaces()) - { - std::cout << "\t\t" << resourceInterfaces << std::endl; - } +int createLightResource(char *uri, LightResource *lightResource) +{ + if (!uri) + { + std::cout << "Resource URI cannot be NULL" << std::endl; + return -1; + } - std::cout << "found resource OUT" << std::endl; + lightResource->state = false; + lightResource->power = 0; + OCStackResult res = OCCreateResource(&(lightResource->handle), + "core.light", + "oc.mi.def", + uri, + OCEntityHandlerCb, + NULL, + OC_DISCOVERABLE | OC_OBSERVABLE); + std::cout << "Created Light resource with result:" << res << std::endl; + + return res; +} - m_resource = resource; +OCStackApplicationResult handlePublishCB(void *ctx, + OCDoHandle /*handle*/, + OCClientResponse *clientResponse) +{ + if (ctx != (void *)DEFAULT_CONTEXT_VALUE) + { + std::cout << "Invalid Publish callback received" << std::endl; + } - std::cout << "Doing a get on q/foo." << std::endl; + std::cout << "Publish resource response received, code: " << clientResponse->result << std::endl; - m_resource->get(QueryParamsMap(), - GetCallback(std::bind(&ResourceClient::getResourceInfo, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3))); - } - } + return OC_STACK_KEEP_TRANSACTION; +} - public: - ResourceClient() - {} +void PublishResources(std::string host, std::string additionalQuery) +{ + std::cout << "Running as Server mode" << std::endl; - OCStackResult start(std::string hostUri, std::string requestUri) - { - FindCallback f(std::bind(&ResourceClient::foundResource, this, std::placeholders::_1)); + std::string requestQuery = DEFAULT_PUBLISH_QUERY; + requestQuery += additionalQuery; - return OCPlatform::findResource(hostUri, requestUri, CT_ADAPTER_TCP, f); - } - private: - std::mutex m_mutex; - std::mutex m_resourceLock; - std::condition_variable m_cv; - std::shared_ptr m_resource; - bool m_isFoo; - int m_barCount; -}; - -struct FooResource -{ - bool m_isFoo; - int m_barCount; - OCResourceHandle m_resourceHandle; - OCResourceHandle m_resourceHandle2; - OCRepresentation m_rep; + std::cout << "Publishing resources..." << std::endl; + std::cout << host.c_str() << requestQuery.c_str() << std::endl; - FooResource() : m_isFoo(true), m_barCount(0) + if (createLightResource((char *)"/a/light/0", &gLightInstance[0]) != 0) { - m_rep.setValue("isFoo", m_isFoo); - m_rep.setValue("barCount", m_barCount); + std::cout << "Unable to create sample resource" << std::endl; } - bool createResource(std::string resourceURI) + if (createLightResource((char *)"/a/light/1", &gLightInstance[1]) != 0) { - std::string resourceTypeName = "core.foo"; - std::string resourceInterface = DEFAULT_INTERFACE; - - m_rep.setUri(resourceURI); - - uint8_t resourceProperty = OC_DISCOVERABLE; - - EntityHandler eh(std::bind(&FooResource::entityHandler, - this, std::placeholders::_1)); - OCStackResult result = OCPlatform::registerResource(m_resourceHandle, - resourceURI, resourceTypeName, - resourceInterface, - eh, resourceProperty); - if (OC_STACK_OK != result) - { - std::cout << "Resource creation unsuccessful" << std::endl; - return false; - } - - return true; + std::cout << "Unable to create sample resource" << std::endl; } - OCResourceHandle getHandle() + if (OCCloudPublish(host.c_str(), requestQuery.c_str(), &handlePublishCB, 2, + gLightInstance[0].handle, gLightInstance[1].handle) != OC_STACK_OK) { - return m_resourceHandle; + std::cout << "Unable to publish resources to cloud" << std::endl; } +} - OCResourceHandle getHandle2() +////////////////////////////////////////Client Sample +std::string g_host = "coap+tcp://"; + +OCStackApplicationResult handleGetCB(void *ctx, + OCDoHandle /*handle*/, + OCClientResponse *clientResponse) +{ + std::cout << "Get response received from " << clientResponse->resourceUri << std::endl; + + if (ctx != (void *)DEFAULT_CONTEXT_VALUE) { - return m_resourceHandle2; + std::cout << "Invalid Publish callback received" << std::endl; } + if (clientResponse->payload == NULL) + std::cout << "No payload received" << std::endl; - OCRepresentation get() + if (clientResponse->payload != NULL && + clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION) { - m_rep.setValue("isFoo", m_isFoo); - m_rep.setValue("barCount", m_barCount); + std::cout << "PAYLOAD_TYPE_REPRESENTATION received" << std::endl; - return m_rep; - } + OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values; - void put(OCRepresentation &rep) - { - rep.getValue("isFoo", m_isFoo); - rep.getValue("barCount", m_barCount); + while (val) + { + std::cout << "Key: " << val->name << " Value: "; + switch (val->type) + { + case OCREP_PROP_NULL: + std::cout << "NULL" << std::endl; + break; + + case OCREP_PROP_INT: + std::cout << val->i << std::endl; + break; + + case OCREP_PROP_DOUBLE: + std::cout << val->d << std::endl; + break; + + case OCREP_PROP_BOOL: + std::cout << val->b << std::endl; + break; + + case OCREP_PROP_STRING: + std::cout << val->str << std::endl; + break; + + case OCREP_PROP_BYTE_STRING: + std::cout << "[ByteString]" << std::endl; + break; + + case OCREP_PROP_OBJECT: + std::cout << "[Object]" << std::endl; + break; + + case OCREP_PROP_ARRAY: + std::cout << "[Array]" << std::endl; + break; + } + + val = val->next; + } } - OCStackResult sendResponse(std::shared_ptr pRequest) + return OC_STACK_KEEP_TRANSACTION; +} + +// This is a function called back when a device is discovered +OCStackApplicationResult discoveryReqCB(void *ctx, OCDoHandle /*handle*/, + OCClientResponse *clientResponse) +{ + if (ctx == (void *)DEFAULT_CONTEXT_VALUE) { - auto pResponse = std::make_shared(); - pResponse->setRequestHandle(pRequest->getRequestHandle()); - pResponse->setResourceHandle(pRequest->getResourceHandle()); - pResponse->setResourceRepresentation(get(), ""); - pResponse->setErrorCode(200); - pResponse->setResponseResult(OC_EH_OK); - - return OCPlatform::sendResponse(pResponse); + std::cout << "Callback Context for DISCOVER query recvd successfully" << std::endl; } - OCEntityHandlerResult entityHandler(std::shared_ptr request) + if (clientResponse) { - std::cout << "\tConsumer Entity Handler:" << std::endl; - OCEntityHandlerResult ehResult = OC_EH_ERROR; + std::cout << "StackResult: " << clientResponse->result << std::endl; - if (request) + OCDiscoveryPayload *payload = (OCDiscoveryPayload *)clientResponse->payload; + if (!payload) { - // Note: Most of the handlers are not here, since this is for - // demoing client/server co-process existence. - // See simpleserver for a more complete example. - if (request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag) - { - std::cout << "\t\trequestFlag : Request" << std::endl; - - if (request->getRequestType() == "GET") - { - std::cout << "\t\t\trequestType : GET" << std::endl; - if (OC_STACK_OK == sendResponse(request)) - { - ehResult = OC_EH_OK; - } - } - else if (request->getRequestType() == "PUT") - { - std::cout << "\t\t\trequestType : PUT" << std::endl; - - OCRepresentation rep = request->getResourceRepresentation(); - put(rep); - if (OC_STACK_OK == sendResponse(request)) - { - ehResult = OC_EH_OK; - } - } - else - { - std::cout << "\t\t\trequestType : UNSUPPORTED: " << - request->getRequestType() << std::endl; - } - } - else - { - std::cout << "\t\trequestFlag : UNSUPPORTED: "; + std::cout << "Empty payload" << std::endl; + return OC_STACK_DELETE_TRANSACTION; + } - if (request->getRequestHandlerFlag() == RequestHandlerFlag::ObserverFlag) - { - std::cout << "ObserverFlag" << std::endl; - } - } + OCResourcePayload *resource = (OCResourcePayload *)payload->resources; + if (!resource) + { + std::cout << "No resources in payload" << std::endl; + return OC_STACK_DELETE_TRANSACTION; } - else + + OCCallbackData cbData; + cbData.cb = handleGetCB; + cbData.context = (void *)DEFAULT_CONTEXT_VALUE; + cbData.cd = NULL; + + while (resource) { - std::cout << "Request Invalid!" << std::endl; + std::cout << "Found Resource " << resource->uri << std::endl; + std::string requestUri = g_host; + requestUri += resource->uri; + + std::cout << "Request GET to resource " << requestUri.c_str() << std::endl; + + OCStackResult res = OCDoResource(NULL, OC_REST_GET, requestUri.c_str(), NULL, NULL, + CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0); + + std::cout << "Requesting GET res=" << res << std::endl; + + resource = resource->next; } + } + else + { + std::cout << "discoveryReqCB received Null clientResponse" << std::endl; + } + return OC_STACK_KEEP_TRANSACTION; +} + +void DiscoverResources(std::string host, std::string additionalQuery) +{ + std::cout << "Running as Client mode" << std::endl; + + std::string requestQuery = host; + requestQuery += DEFAULT_DISCOVER_QUERY; + requestQuery += additionalQuery; + + std::cout << "Finding resources..." << std::endl; + std::cout << requestQuery.c_str() << std::endl; + + OCCallbackData cbData; - return ehResult; + cbData.cb = discoveryReqCB; + cbData.context = (void *)DEFAULT_CONTEXT_VALUE; + cbData.cd = NULL; + + if (OCDoResource(NULL, OC_REST_DISCOVER, requestQuery.c_str(), NULL, 0, CT_ADAPTER_TCP, + OC_LOW_QOS, &cbData, NULL, 0) != OC_STACK_OK) + { + std::cout << "Unable to find resources from cloud" << std::endl; } -}; +} -OCStackApplicationResult handlePublishCB(void *ctx, + + +/////////////////////////////////////////////Common sample + +int g_runningMode = 0; + +OCStackApplicationResult handleLoginoutCB(void *ctx, OCDoHandle /*handle*/, OCClientResponse *clientResponse) { if (ctx != (void *)DEFAULT_CONTEXT_VALUE) { - std::cout << "Invalid Publish callback received" << std::endl; + std::cout << "Invalid Login callback received" << std::endl; } - std::cout << "Publish resource response received, code: " << clientResponse->result << std::endl; + std::cout << "Login/out response received code: " << clientResponse->result << std::endl; + + if (clientResponse->payload != NULL && + clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION) + { + std::cout << "PAYLOAD_TYPE_REPRESENTATION received" << std::endl; + + OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values; + + while (val) + { + std::cout << "Key: " << val->name << " Value: " << val->str << std::endl; + val = val->next; + } + + if (g_runningMode == 1) + { + PublishResources(g_host, ""); + } + else if (g_runningMode == 2) + { + DiscoverResources(g_host, ""); + } + + } return OC_STACK_KEEP_TRANSACTION; } -OCStackApplicationResult handleLoginoutCB(void *ctx, +OCStackApplicationResult handleRegisterCB(void *ctx, OCDoHandle /*handle*/, OCClientResponse *clientResponse) { if (ctx != (void *)DEFAULT_CONTEXT_VALUE) { - std::cout << "Invalid Login callback received" << std::endl; + std::cout << "Invalid Register callback received" << std::endl; } - std::cout << "Login/out response received code: " << clientResponse->result << std::endl; + std::cout << "Register response received code: " << clientResponse->result << std::endl; if (clientResponse->payload != NULL && clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION) { std::cout << "PAYLOAD_TYPE_REPRESENTATION received" << std::endl; + std::cout << "You can login using received session variable after disconnected or reboot" << + std::endl; OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values; while (val) { - std::cout << "Name: " << val->name << " Value: " << val->str << std::endl; + std::cout << "Key: " << val->name << " Value: " << val->str << std::endl; val = val->next; } } @@ -354,170 +460,98 @@ OCStackApplicationResult handleLoginoutCB(void *ctx, void PrintUsage() { std::cout << std::endl; - std::cout << "Usage : cloud_device \n"; + std::cout << "Usage : cloud_device \n"; std::cout << ": Cloud Address, \"127.0.0.1:5683\"\n"; std::cout << ": String value, Provided by response of onboarding scenario\n\tor kind of registration portal\n\n"; std::cout << - "If you want to go API test mode include device registration,\n\tleave blank to fields\n"; + ": String value, 's' for publish resource, 'c' for start discovery\n\n"; std::cout << - "sample: \"cloud_device 127.0.0.1:5683\"\n\t-Enter API testmode\n\n"; + "If you want to get session key using OAuth 2 auth code,\n\tleave blank to , fields\n"; std::cout << - "sample: \"cloud_device 127.0.0.1:5683 1234567890123456\"\n\t-Enter API testmode using registered session\n\n"; + "sample: \"cloud_device 127.0.0.1:5683\"\n\t-OAuth 2 registration mode\n\n"; + std::cout << + "sample: \"cloud_device 127.0.0.1:5683 1234567890123456 s\"\n\t-Publish resource under registered session\n\n"; + std::cout << + "sample: \"cloud_device 127.0.0.1:5683 1234567890123456 c\"\n\t-Discover resource under registered session\n\n"; } -void PublishResources(std::string host, std::string additionalQuery) +int main(int argc, char *argv[]) { - std::cout << "Running as Server mode" << std::endl; - - FooResource fooRes1, fooRes2; + std::string session; - if (!fooRes1.createResource("/q/resource_foo1")) - { - std::cout << "Unable to create resource" << std::endl; - return; - } + std::string authProvider; + std::string authCode; - if (!fooRes2.createResource("/q/resource_foo2")) + switch (argc) { - std::cout << "Unable to create resource" << std::endl; - return; - } - - std::string requestQuery = DEFAULT_PUBLISH_QUERY; - requestQuery += additionalQuery; + case 2: + std::cout << "Put auth provider name(ex: github)" << std::endl; + std::cin >> authProvider; + std::cout << "Put auth code(provided by auth provider)" << std::endl; + std::cin >> authCode; + break; - std::cout << "Publishing resources..." << std::endl; - std::cout << host.c_str() << requestQuery.c_str() << std::endl; + case 4: + session = argv[2]; + if (argv[3][0] == 's') + g_runningMode = 1; + else if (argv[3][0] == 'c') + g_runningMode = 2; + break; - if (OCCloudPublish(host.c_str(), requestQuery.c_str(), &handlePublishCB, 2, - fooRes1.getHandle(), fooRes2.getHandle()) != OC_STACK_OK) - { - std::cout << "Unable to publish resources to cloud" << std::endl; + default: + PrintUsage(); + return 0; } -} -void DiscoverResources(std::string host, std::string additionalQuery) -{ - std::cout << "Running as Client mode" << std::endl; + g_host += argv[1]; - ResourceClient client; - std::string requestQuery = DEFAULT_DISCOVER_QUERY; - requestQuery += additionalQuery; + std::cout << "Host " << g_host.c_str() << std::endl; - std::cout << "Finding resources..." << std::endl; - std::cout << host.c_str() << requestQuery.c_str() << std::endl; - - if (client.start(host.c_str(), requestQuery.c_str()) != OC_STACK_OK) - { - std::cout << "Unable to find resources from cloud" << std::endl; - } -} - -int main(int argc, char *argv[]) -{ - std::string host = "coap+tcp://"; - - std::string cmdQuery; - std::string session; + OCStackResult res = OC_STACK_ERROR; - PlatformConfig cfg + if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK) { - OC::ServiceType::InProc, - OC::ModeType::Both, - "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces - 0, // Uses randomly available port - OC::QualityOfService::LowQos - }; - - OCPlatform::Configure(cfg); - FooResource defaultResource; - if (!defaultResource.createResource("/q/default")) - { - std::cout << "Unable to create default resource" << std::endl; - return -1; + std::cout << "OCStack init error" << std::endl; + return 0; } switch (argc) { - case 1: - PrintUsage(); - return 0; - break; - case 2: - std::cout << - "1. Login to cloud using OAuth2 auth code and auth provider name(AuthCode'OAuth2' required)" << - std::endl; - std::cout << "2. Login to cloud using session(Session required)" << std::endl; - std::cout << "3. Logout from cloud using session(Session required)" << std::endl; - std::cout << "s. Running as Resource Server mode" << std::endl; - std::cout << "c. Running as Resource Client mode" << std::endl; - std::cout << "exit: q" << std::endl; - std::cin >> cmdQuery; + std::cout << "Register account to cloud using " << authProvider << " " << authCode << std::endl; + res = OCCloudRegisterLogin(g_host.c_str(), authProvider.c_str(), authCode.c_str(), + handleRegisterCB); + std::cout << "OCCloudRegisterLogin return " << res << std::endl; break; - case 3: - cmdQuery = "2"; - session = argv[2]; + case 4: + res = OCCloudLogin(g_host.c_str(), session.c_str(), handleLoginoutCB); + std::cout << "OCCloudLogin return " << res << std::endl; break; - } - - host += argv[1]; - - std::cout << "Host " << host.c_str() << std::endl; - std::string authProvider; - std::string authCode; + default: + PrintUsage(); + return 0; + } - OCStackResult res = OC_STACK_ERROR; + std::cout << "Waiting response.." << std::endl; - while (cmdQuery[0] != 'q') + while (true) { - switch (cmdQuery[0]) + if (OCProcess() != OC_STACK_OK) { - case '1': - std::cout << "Put auth provider name(ex: github)" << std::endl; - std::cin >> authProvider; - std::cout << "Put auth code(provided by auth provider)" << std::endl; - std::cin >> authCode; - std::cout << "Login to cloud using " << authProvider << " " << authCode << std::endl; - res = OCCloudRegisterLogin(host.c_str(), authProvider.c_str(), authCode.c_str(), - handleLoginoutCB); - std::cout << "OCCloudRegisterLogin return " << res << std::endl; - break; - - case '2': - std::cout << "Put session to login" << std::endl; - if (session.size() == 0) - std::cin >> session; - else - std::cout << session.c_str() << std::endl; - res = OCCloudLogin(host.c_str(), session.c_str(), handleLoginoutCB); - std::cout << "OCCloudLogin return " << res << std::endl; - break; - - case '3': - std::cout << "Put session to logout" << std::endl; - if (session.size() == 0) - std::cin >> session; - else - std::cout << session.c_str() << std::endl; - res = OCCloudLogout(host.c_str(), session.c_str(), handleLoginoutCB); - std::cout << "OCCloudLogout return" << res << std::endl; - break; - - case 's': - PublishResources(host, ""); - break; - - case 'c': - DiscoverResources(host, ""); - break; + std::cout << "OCProcess process error" << std::endl; } - std::cin >> cmdQuery; + sleep(1); + } + + if (OCStop() != OC_STACK_OK) + { + std::cout << "OCStop process error" << std::endl; } return 0; -} +} \ No newline at end of file diff --git a/cloud/stack/README b/cloud/stack/README index 3811258..b8b2710 100644 --- a/cloud/stack/README +++ b/cloud/stack/README @@ -8,6 +8,6 @@ Build 2) Build a .jar file - $ mvn install + $ mvn install -Dmaven.test.skip=true - The CloudStack-0.0.1-SNAPSHOT.jar file will be placed in the "target" folder. diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpClient.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpClient.java index e1a2466..add75a4 100644 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpClient.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpClient.java @@ -1,207 +1,200 @@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // 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. - * // + * //****************************************************************** // // + * Copyright 2016 Samsung Electronics All Rights Reserved. // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // + * 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.cloud.base; - -import java.net.URI; -import java.net.URISyntaxException; - -import javax.net.ssl.SSLException; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.codec.http.ClientCookieEncoder; -import io.netty.handler.codec.http.DefaultCookie; -import io.netty.handler.codec.http.DefaultFullHttpRequest; -import io.netty.handler.codec.http.HttpClientCodec; -import io.netty.handler.codec.http.HttpContent; -import io.netty.handler.codec.http.HttpContentDecompressor; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpObject; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import io.netty.util.CharsetUtil; - -public class HttpClient { - - private static class HttpClientInitializer - extends ChannelInitializer { - - public static class HttpSnoopClientHandler - extends SimpleChannelInboundHandler { - - @Override - public void channelRead0(ChannelHandlerContext ctx, - HttpObject msg) { - if (msg instanceof HttpResponse) { - HttpResponse response = (HttpResponse) msg; - - System.err.println("STATUS: " + response.getStatus()); - System.err.println( - "VERSION: " + response.getProtocolVersion()); - System.err.println(); - - if (!response.headers().isEmpty()) { - for (String name : response.headers().names()) { - for (String value : response.headers() - .getAll(name)) { - System.err.println( - "HEADER: " + name + " = " + value); - } - } - System.err.println(); - } - - if (HttpHeaders.isTransferEncodingChunked(response)) { - System.err.println("CHUNKED CONTENT {"); - } else { - System.err.println("CONTENT {"); - } - } - if (msg instanceof HttpContent) { - HttpContent content = (HttpContent) msg; - - System.err.print( - content.content().toString(CharsetUtil.UTF_8)); - System.err.flush(); - - if (content instanceof LastHttpContent) { - System.err.println("} END OF CONTENT"); - ctx.close(); - } - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, - Throwable cause) { - cause.printStackTrace(); - ctx.close(); - } - } - - private final SslContext sslCtx; - - public HttpClientInitializer(SslContext sslCtx) { - this.sslCtx = sslCtx; - } - - @Override - public void initChannel(SocketChannel ch) { - ChannelPipeline p = ch.pipeline(); - - // Enable HTTPS if necessary. - if (sslCtx != null) { - p.addLast(sslCtx.newHandler(ch.alloc())); - } - - p.addLast(new HttpClientCodec()); - - // Remove the following line if you don't want automatic content - // decompression. - p.addLast(new HttpContentDecompressor()); - - // Uncomment the following line if you don't want to handle - // HttpContents. - // p.addLast(new HttpObjectAggregator(1048576)); - - p.addLast(new HttpSnoopClientHandler()); - } - } - - public void connect(String strUrl) - throws URISyntaxException, InterruptedException, SSLException { - URI uri = new URI(strUrl); - - String scheme = uri.getScheme() == null ? "http" : uri.getScheme(); - String host = uri.getHost() == null ? "127.0.0.1" : uri.getHost(); - - int port = uri.getPort(); - - if (port == -1) { - if ("http".equalsIgnoreCase(scheme)) { - port = 80; - } else if ("https".equalsIgnoreCase(scheme)) { - port = 443; - } - } - - if (!"http".equalsIgnoreCase(scheme) - && !"https".equalsIgnoreCase(scheme)) { - return; - } - - final boolean ssl = "https".equalsIgnoreCase(scheme); - final SslContext sslCtx; - - if (ssl) { - sslCtx = SslContextBuilder.forClient() - .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); - } else { - sslCtx = null; - } - - EventLoopGroup group = new NioEventLoopGroup(); - - try { - Bootstrap b = new Bootstrap(); - b.group(group); - b.channel(NioSocketChannel.class); - b.handler(new HttpClientInitializer(sslCtx)); - - Channel ch = b.connect(host, port).sync().channel(); - - HttpRequest request = new DefaultFullHttpRequest( - HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath()); - request.headers().set(HttpHeaders.Names.HOST, host); - request.headers().set(HttpHeaders.Names.CONNECTION, - HttpHeaders.Values.CLOSE); - request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, - HttpHeaders.Values.GZIP); - - request.headers().set(HttpHeaders.Names.COOKIE, - ClientCookieEncoder.encode( - new DefaultCookie("my-cookie", "foo"), - new DefaultCookie("another-cookie", "bar"))); - - ch.writeAndFlush(request); - - ch.closeFuture().sync(); - } finally { - group.shutdownGracefully(); - } - } - -} +// package org.iotivity.cloud.base; +// +// import java.net.URI; +// import java.net.URISyntaxException; +// +// import javax.net.ssl.SSLException; +// +// import io.netty.bootstrap.Bootstrap; +// import io.netty.channel.Channel; +// import io.netty.channel.ChannelHandlerContext; +// import io.netty.channel.ChannelInitializer; +// import io.netty.channel.ChannelPipeline; +// import io.netty.channel.EventLoopGroup; +// import io.netty.channel.SimpleChannelInboundHandler; +// import io.netty.channel.nio.NioEventLoopGroup; +// import io.netty.channel.socket.SocketChannel; +// import io.netty.channel.socket.nio.NioSocketChannel; +// import io.netty.handler.codec.http.ClientCookieEncoder; +// import io.netty.handler.codec.http.DefaultCookie; +// import io.netty.handler.codec.http.DefaultFullHttpRequest; +// import io.netty.handler.codec.http.HttpClientCodec; +// import io.netty.handler.codec.http.HttpContent; +// import io.netty.handler.codec.http.HttpContentDecompressor; +// import io.netty.handler.codec.http.HttpHeaders; +// import io.netty.handler.codec.http.HttpMethod; +// import io.netty.handler.codec.http.HttpObject; +// import io.netty.handler.codec.http.HttpRequest; +// import io.netty.handler.codec.http.HttpResponse; +// import io.netty.handler.codec.http.HttpVersion; +// import io.netty.handler.codec.http.LastHttpContent; +// import io.netty.handler.ssl.SslContext; +// import io.netty.handler.ssl.SslContextBuilder; +// import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +// import io.netty.util.CharsetUtil; +// +// public class HttpClient { +// +// private static class HttpClientInitializer +// extends ChannelInitializer { +// +// public static class HttpSnoopClientHandler +// extends SimpleChannelInboundHandler { +// +// @Override +// public void channelRead0(ChannelHandlerContext ctx, +// HttpObject msg) { +// if (msg instanceof HttpResponse) { +// HttpResponse response = (HttpResponse) msg; +// +// System.err.println("STATUS: " + response.getStatus()); +// System.err.println( +// "VERSION: " + response.getProtocolVersion()); +// System.err.println(); +// +// if (!response.headers().isEmpty()) { +// for (String name : response.headers().names()) { +// for (String value : response.headers() +// .getAll(name)) { +// System.err.println( +// "HEADER: " + name + " = " + value); +// } +// } +// System.err.println(); +// } +// +// if (HttpHeaders.isTransferEncodingChunked(response)) { +// System.err.println("CHUNKED CONTENT {"); +// } else { +// System.err.println("CONTENT {"); +// } +// } +// if (msg instanceof HttpContent) { +// HttpContent content = (HttpContent) msg; +// +// System.err.print( +// content.content().toString(CharsetUtil.UTF_8)); +// System.err.flush(); +// +// if (content instanceof LastHttpContent) { +// System.err.println("} END OF CONTENT"); +// ctx.close(); +// } +// } +// } +// +// @Override +// public void exceptionCaught(ChannelHandlerContext ctx, +// Throwable cause) { +// cause.printStackTrace(); +// ctx.close(); +// } +// } +// +// private final SslContext sslCtx; +// +// public HttpClientInitializer(SslContext sslCtx) { +// this.sslCtx = sslCtx; +// } +// +// @Override +// public void initChannel(SocketChannel ch) { +// ChannelPipeline p = ch.pipeline(); +// +// // Enable HTTPS if necessary. +// if (sslCtx != null) { +// p.addLast(sslCtx.newHandler(ch.alloc())); +// } +// +// p.addLast(new HttpClientCodec()); +// +// // Remove the following line if you don't want automatic content +// // decompression. +// p.addLast(new HttpContentDecompressor()); +// +// // Uncomment the following line if you don't want to handle +// // HttpContents. +// // p.addLast(new HttpObjectAggregator(1048576)); +// +// p.addLast(new HttpSnoopClientHandler()); +// } +// } +// +// public void connect(String strUrl) +// throws URISyntaxException, InterruptedException, SSLException { +// URI uri = new URI(strUrl); +// +// String scheme = uri.getScheme() == null ? "http" : uri.getScheme(); +// String host = uri.getHost() == null ? "127.0.0.1" : uri.getHost(); +// +// int port = uri.getPort(); +// +// if (port == -1) { +// if ("http".equalsIgnoreCase(scheme)) { +// port = 80; +// } else if ("https".equalsIgnoreCase(scheme)) { +// port = 443; +// } +// } +// +// if (!"http".equalsIgnoreCase(scheme) +// && !"https".equalsIgnoreCase(scheme)) { +// return; +// } +// +// final boolean ssl = "https".equalsIgnoreCase(scheme); +// final SslContext sslCtx; +// +// if (ssl) { +// sslCtx = SslContextBuilder.forClient() +// .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); +// } else { +// sslCtx = null; +// } +// +// EventLoopGroup group = new NioEventLoopGroup(); +// +// try { +// Bootstrap b = new Bootstrap(); +// b.group(group); +// b.channel(NioSocketChannel.class); +// b.handler(new HttpClientInitializer(sslCtx)); +// +// Channel ch = b.connect(host, port).sync().channel(); +// +// HttpRequest request = new DefaultFullHttpRequest( +// HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath()); +// request.headers().set(HttpHeaders.Names.HOST, host); +// request.headers().set(HttpHeaders.Names.CONNECTION, +// HttpHeaders.Values.CLOSE); +// request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, +// HttpHeaders.Values.GZIP); +// +// request.headers().set(HttpHeaders.Names.COOKIE, +// ClientCookieEncoder.encode( +// new DefaultCookie("my-cookie", "foo"), +// new DefaultCookie("another-cookie", "bar"))); +// +// ch.writeAndFlush(request); +// +// ch.closeFuture().sync(); +// } finally { +// group.shutdownGracefully(); +// } +// } +// +// } diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java index 7183f6e..3f4498f 100644 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java @@ -1,145 +1,139 @@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // 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. - * // + * //****************************************************************** // // + * Copyright 2016 Samsung Electronics All Rights Reserved. // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // + * 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.cloud.base; - -import java.net.InetSocketAddress; -import java.security.cert.CertificateException; -import java.util.ArrayList; -import java.util.List; - -import javax.net.ssl.SSLException; - -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseEncoder; -import io.netty.handler.logging.LogLevel; -import io.netty.handler.logging.LoggingHandler; -import io.netty.util.concurrent.GenericFutureListener; - -public class HttpServer { - - private static class HttpServerInitializer - extends ChannelInitializer { - - private List additionalHandlers = new ArrayList(); - - public HttpServerInitializer() { - } - - public void addHandler(ChannelHandler handler) { - additionalHandlers.add(handler); - } - - @Override - public void initChannel(SocketChannel ch) { - ChannelPipeline p = ch.pipeline(); - /* - * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); } - */ - p.addLast(new HttpRequestDecoder()); - // Uncomment the following line if you don't want to handle - // HttpChunks. - // p.addLast(new HttpObjectAggregator(1048576)); - p.addLast(new HttpResponseEncoder()); - // Remove the following line if you don't want automatic content - // compression. - // p.addLast(new HttpContentCompressor()); - for (ChannelHandler handler : additionalHandlers) { - p.addLast(handler); - } - } - - } - - EventLoopGroup bossGroup = new NioEventLoopGroup(1); - - EventLoopGroup workerGroup = new NioEventLoopGroup(); - - HttpServerInitializer initializer = new HttpServerInitializer(); - - public void addHandler(ChannelHandler handler) { - initializer.addHandler(handler); - } - - public void startServer(InetSocketAddress inetSocketAddress) - throws CertificateException, SSLException, InterruptedException { - - try { - ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup); - b.channel(NioServerSocketChannel.class); - b.handler(new LoggingHandler(LogLevel.INFO)); - - b.childHandler(initializer); - - ChannelFuture ch = b.bind(inetSocketAddress).sync(); - ch.addListener(new GenericFutureListener() { - - @Override - public void operationComplete(ChannelFuture future) - throws Exception { - // TODO Auto-generated method stub - System.out - .println("Connection status of TCP Http SERVER : " - + future.isSuccess()); - } - - }); - } finally { - } - - } - - public void stopServer() { - // shut down all event loops - if (bossGroup != null) { - bossGroup.shutdownGracefully(); - - try { - bossGroup.terminationFuture().sync(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - if (workerGroup != null) { - workerGroup.shutdownGracefully(); - - try { - workerGroup.terminationFuture().sync(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - -} +// package org.iotivity.cloud.base; +// +// import java.net.InetSocketAddress; +// import java.security.cert.CertificateException; +// import java.util.ArrayList; +// import java.util.List; +// +// import javax.net.ssl.SSLException; +// +// import io.netty.bootstrap.ServerBootstrap; +// import io.netty.channel.ChannelFuture; +// import io.netty.channel.ChannelHandler; +// import io.netty.channel.ChannelInitializer; +// import io.netty.channel.ChannelPipeline; +// import io.netty.channel.EventLoopGroup; +// import io.netty.channel.nio.NioEventLoopGroup; +// import io.netty.channel.socket.SocketChannel; +// import io.netty.channel.socket.nio.NioServerSocketChannel; +// import io.netty.handler.codec.http.HttpRequestDecoder; +// import io.netty.handler.codec.http.HttpResponseEncoder; +// import io.netty.handler.logging.LogLevel; +// import io.netty.handler.logging.LoggingHandler; +// import io.netty.util.concurrent.GenericFutureListener; +// +// public class HttpServer { +// +// private static class HttpServerInitializer +// extends ChannelInitializer { +// +// private List additionalHandlers = new +// ArrayList(); +// +// public HttpServerInitializer() { +// } +// +// public void addHandler(ChannelHandler handler) { +// additionalHandlers.add(handler); +// } +// +// @Override +// public void initChannel(SocketChannel ch) { +// ChannelPipeline p = ch.pipeline(); +// /* +// * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); } +// */ +// p.addLast(new HttpRequestDecoder()); +// // Uncomment the following line if you don't want to handle +// // HttpChunks. +// // p.addLast(new HttpObjectAggregator(1048576)); +// p.addLast(new HttpResponseEncoder()); +// // Remove the following line if you don't want automatic content +// // compression. +// // p.addLast(new HttpContentCompressor()); +// for (ChannelHandler handler : additionalHandlers) { +// p.addLast(handler); +// } +// } +// +// } +// +// EventLoopGroup bossGroup = new NioEventLoopGroup(1); +// +// EventLoopGroup workerGroup = new NioEventLoopGroup(); +// +// HttpServerInitializer initializer = new HttpServerInitializer(); +// +// public void addHandler(ChannelHandler handler) { +// initializer.addHandler(handler); +// } +// +// public void startServer(InetSocketAddress inetSocketAddress) +// throws CertificateException, SSLException, InterruptedException { +// +// try { +// ServerBootstrap b = new ServerBootstrap(); +// b.group(bossGroup, workerGroup); +// b.channel(NioServerSocketChannel.class); +// b.handler(new LoggingHandler(LogLevel.INFO)); +// +// b.childHandler(initializer); +// +// ChannelFuture ch = b.bind(inetSocketAddress).sync(); +// ch.addListener(new GenericFutureListener() { +// +// @Override +// public void operationComplete(ChannelFuture future) +// throws Exception { +// // TODO Auto-generated method stub +// System.out +// .println("Connection status of TCP Http SERVER : " +// + future.isSuccess()); +// } +// +// }); +// } finally { +// } +// +// } +// +// public void stopServer() { +// // shut down all event loops +// if (bossGroup != null) { +// bossGroup.shutdownGracefully(); +// +// try { +// bossGroup.terminationFuture().sync(); +// } catch (InterruptedException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// } +// +// if (workerGroup != null) { +// workerGroup.shutdownGracefully(); +// +// try { +// workerGroup.terminationFuture().sync(); +// } catch (InterruptedException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// } +// } +// +// } diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java index b33ba24..0ca806f 100644 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java @@ -24,7 +24,6 @@ package org.iotivity.cloud.base; import java.util.ArrayList; import org.iotivity.cloud.base.protocols.coap.CoapRequest; -import org.iotivity.cloud.util.Logger; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; @@ -33,35 +32,7 @@ import io.netty.channel.SimpleChannelInboundHandler; @Sharable public class ResourceManager extends SimpleChannelInboundHandler { - private ArrayList resources = new ArrayList(); - SessionManager sessionManager = null; - - public ResourceManager() { - - } - - public ResourceManager(SessionManager sessionManager) { - this.sessionManager = sessionManager; - } - - @Override - public void channelReadComplete(ChannelHandlerContext ctx) { - ctx.flush(); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - Logger.d("Channel Inactive"); - sessionManager.removeSessionByChannel(ctx); - super.channelInactive(ctx); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - - cause.printStackTrace(); - ctx.close(); - } + private ArrayList resources = new ArrayList(); @Override public void channelRead0(ChannelHandlerContext ctx, CoapRequest request) diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java index 6b0ef5d..fd933aa 100644 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java @@ -77,14 +77,7 @@ public class SessionManager { return ctx; } - public boolean isThereCtx(ChannelHandlerContext ctx) { - - synchronized (sessions) { - return sessions.containsValue(ctx); - } - } - - public boolean isThereCtxChannel(ChannelHandlerContext ctx) { + private boolean isThereCtxChannel(ChannelHandlerContext ctx) { synchronized (sessions) { Iterator iterator = sessions.keySet().iterator(); diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapMessage.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapMessage.java index 57382e2..e7c42e4 100644 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapMessage.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapMessage.java @@ -236,7 +236,7 @@ public class CoapMessage { // ACCEPT case 17: - return accept != null ? Arrays.asList(content_format) : null; + return accept != null ? Arrays.asList(accept) : null; // LOCATION_QUERY case 20: diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapRequest.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapRequest.java index 35657a6..3a1f013 100644 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapRequest.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapRequest.java @@ -66,11 +66,12 @@ public class CoapRequest extends CoapMessage { } public List getUriPathSegments() { + if (uri_path == null) { + return null; + } List segments = new ArrayList(); - if (uri_path != null) { - for (byte[] pathSegment : uri_path) { - segments.add(new String(pathSegment, StandardCharsets.UTF_8)); - } + for (byte[] pathSegment : uri_path) { + segments.add(new String(pathSegment, StandardCharsets.UTF_8)); } return segments; } @@ -101,6 +102,9 @@ public class CoapRequest extends CoapMessage { } public List getUriQuerySegments() { + if (uri_query == null) { + return null; + } List segments = new ArrayList(); for (byte[] querySegment : uri_query) { segments.add(new String(querySegment, StandardCharsets.UTF_8)); @@ -109,10 +113,8 @@ public class CoapRequest extends CoapMessage { } public void clearUriPath() { - uri_path.clear(); - } - - public void setAccept(byte[] accepts) { - accept = accepts; + if (uri_path != null) { + uri_path.clear(); + } } } \ No newline at end of file diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java index fda99c1..2ac4109 100644 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java @@ -1,209 +1,204 @@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // 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. - * // + * //****************************************************************** // // + * Copyright 2016 Samsung Electronics All Rights Reserved. // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // + * 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.cloud.base.protocols.proxy; - -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; - -import org.iotivity.cloud.base.SessionManager; -import org.iotivity.cloud.base.protocols.coap.CoapRequest; -import org.iotivity.cloud.base.protocols.coap.CoapResponse; -import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; -import org.iotivity.cloud.util.Cbor; -import org.iotivity.cloud.util.Logger; - -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.DefaultFullHttpResponse; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.QueryStringDecoder; -import io.netty.util.AttributeKey; -import io.netty.util.CharsetUtil; - -@Sharable -public class CoapHttpProxyHandler extends ChannelDuplexHandler { - - // Proxy converts http request to coaprequest and coapresponse to - // httpresponse - private SessionManager sessionManager = null; - - private static final AttributeKey keyHttpCtx = AttributeKey - .newInstance("httpCtx"); - - public CoapHttpProxyHandler(SessionManager sessionManager) { - this.sessionManager = sessionManager; - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) - throws Exception { - - // in case of Receive Request from http - if (msg instanceof HttpRequest) { - // Check uri query param that contains coap device uuid - // then search those and create coapRequest and send - HttpRequest httpRequest = (HttpRequest) msg; - QueryStringDecoder queryStringDecoder = new QueryStringDecoder( - httpRequest.getUri()); - - List didList = queryStringDecoder.parameters().get("di"); - - if (didList != null) { - ChannelHandlerContext coapClient = sessionManager - .querySession(didList.get(0)); - - if (coapClient != null) { - List uriList = queryStringDecoder.parameters() - .get("href"); - if (uriList != null) { - coapClient.channel().attr(keyHttpCtx).set(ctx); - coapClient.writeAndFlush(httpRequestToCoAPRequest( - uriList.get(0), (HttpRequest) msg)); - - return; - } - } else { - Logger.d("Unable to find session: " + didList.get(0)); - } - } - - // Prints available sessions to html - - ctx.writeAndFlush(printsAvailableSessions()) - .addListener(ChannelFutureListener.CLOSE); - return; - } - - if (msg instanceof CoapResponse) { - ctx.channel().attr(keyHttpCtx).get() - .writeAndFlush( - coapResponseToHttpResponse((CoapResponse) msg)) - .addListener(ChannelFutureListener.CLOSE); - return; - } - - // Pass to upper-layer - super.channelRead(ctx, msg); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - cause.printStackTrace(); - ctx.close(); - } - - HttpResponse printsAvailableSessions() { - - StringBuilder strBuilder = new StringBuilder(); - List sessions = sessionManager.getSessions(); - - strBuilder.append(""); - strBuilder.append("Available sessions
"); - - for (String session : sessions) { - strBuilder.append(session); - strBuilder.append("
"); - } - - strBuilder.append(""); - - HttpResponse response = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.OK, - Unpooled.copiedBuffer(strBuilder.toString(), - CharsetUtil.UTF_8)); - response.headers().set(HttpHeaders.Names.CONTENT_TYPE, - "text/html; charset=UTF-8"); - - return response; - } - - HttpResponse httpRequestToSendError() { - HttpResponse response = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, - Unpooled.copiedBuffer( - "Failure: " + HttpResponseStatus.NOT_FOUND + "\r\n", - CharsetUtil.UTF_8)); - response.headers().set(HttpHeaders.Names.CONTENT_TYPE, - "text/html; charset=UTF-8"); - - return response; - } - - CoapRequest httpRequestToCoAPRequest(String uri, HttpRequest httpRequest) { - CoapRequest coapRequest; - - // TODO: coapRequest converter required - // coapRequest.getOptions().setUriQuery(); - if (httpRequest.getMethod() == HttpMethod.GET) { - coapRequest = new CoapRequest(CoapMethod.GET); - } else if (httpRequest.getMethod() == HttpMethod.PUT) { - coapRequest = new CoapRequest(CoapMethod.PUT); - } else if (httpRequest.getMethod() == HttpMethod.POST) { - coapRequest = new CoapRequest(CoapMethod.POST); - } else if (httpRequest.getMethod() == HttpMethod.DELETE) { - coapRequest = new CoapRequest(CoapMethod.DELETE); - } else { - throw new IllegalArgumentException(); - } - - coapRequest.setUriPath(uri); - - return coapRequest; - } - - HttpResponse coapResponseToHttpResponse(CoapResponse coapResponse) { - - Cbor> cbor = new Cbor>(); - - HashMap rep = cbor - .parsePayloadFromCbor(coapResponse.getPayload(), HashMap.class); - - StringBuilder strBuilder = new StringBuilder(); - - for (Entry entry : rep.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue().toString(); - strBuilder.append("Key: " + key + " Value: " + value + "
"); - } - - HttpResponse httpResponse = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.OK, - Unpooled.wrappedBuffer(strBuilder.toString().getBytes(StandardCharsets.UTF_8))); - - httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, - "text/html; charset=UTF-8"); - - // TODO: httpResponse converter required - - return httpResponse; - } -} +// package org.iotivity.cloud.base.protocols.proxy; +// +// import java.nio.charset.StandardCharsets; +// import java.util.HashMap; +// import java.util.List; +// import java.util.Map.Entry; +// +// import org.iotivity.cloud.base.SessionManager; +// import org.iotivity.cloud.base.protocols.coap.CoapRequest; +// import org.iotivity.cloud.base.protocols.coap.CoapResponse; +// import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; +// import org.iotivity.cloud.util.Cbor; +// import org.iotivity.cloud.util.Logger; +// +// import io.netty.buffer.Unpooled; +// import io.netty.channel.ChannelDuplexHandler; +// import io.netty.channel.ChannelFutureListener; +// import io.netty.channel.ChannelHandler.Sharable; +// import io.netty.channel.ChannelHandlerContext; +// import io.netty.handler.codec.http.DefaultFullHttpResponse; +// import io.netty.handler.codec.http.HttpHeaders; +// import io.netty.handler.codec.http.HttpMethod; +// import io.netty.handler.codec.http.HttpRequest; +// import io.netty.handler.codec.http.HttpResponse; +// import io.netty.handler.codec.http.HttpResponseStatus; +// import io.netty.handler.codec.http.HttpVersion; +// import io.netty.handler.codec.http.QueryStringDecoder; +// import io.netty.util.AttributeKey; +// import io.netty.util.CharsetUtil; +// +// @Sharable +// public class CoapHttpProxyHandler extends ChannelDuplexHandler { +// +// // Proxy converts http request to coaprequest and coapresponse to +// // httpresponse +// private SessionManager sessionManager = null; +// +// private static final AttributeKey keyHttpCtx = +// AttributeKey +// .newInstance("httpCtx"); +// +// public CoapHttpProxyHandler(SessionManager sessionManager) { +// this.sessionManager = sessionManager; +// } +// +// @Override +// public void channelRead(ChannelHandlerContext ctx, Object msg) +// throws Exception { +// +// // in case of Receive Request from http +// if (msg instanceof HttpRequest) { +// // Check uri query param that contains coap device uuid +// // then search those and create coapRequest and send +// HttpRequest httpRequest = (HttpRequest) msg; +// QueryStringDecoder queryStringDecoder = new QueryStringDecoder( +// httpRequest.getUri()); +// +// List didList = queryStringDecoder.parameters().get("di"); +// +// if (didList != null) { +// ChannelHandlerContext coapClient = sessionManager +// .querySession(didList.get(0)); +// +// if (coapClient != null) { +// List uriList = queryStringDecoder.parameters() +// .get("href"); +// if (uriList != null) { +// coapClient.channel().attr(keyHttpCtx).set(ctx); +// coapClient.writeAndFlush(httpRequestToCoAPRequest( +// uriList.get(0), (HttpRequest) msg)); +// +// return; +// } +// } else { +// Logger.d("Unable to find session: " + didList.get(0)); +// } +// } +// +// // Prints available sessions to html +// +// ctx.writeAndFlush(printsAvailableSessions()) +// .addListener(ChannelFutureListener.CLOSE); +// return; +// } +// +// if (msg instanceof CoapResponse) { +// ctx.channel().attr(keyHttpCtx).get() +// .writeAndFlush( +// coapResponseToHttpResponse((CoapResponse) msg)) +// .addListener(ChannelFutureListener.CLOSE); +// return; +// } +// +// // Pass to upper-layer +// super.channelRead(ctx, msg); +// } +// +// @Override +// public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { +// cause.printStackTrace(); +// ctx.close(); +// } +// +// HttpResponse printsAvailableSessions() { +// +// StringBuilder strBuilder = new StringBuilder(); +// List sessions = sessionManager.getSessions(); +// +// strBuilder.append(""); +// strBuilder.append("Available sessions
"); +// +// for (String session : sessions) { +// strBuilder.append(session); +// strBuilder.append("
"); +// } +// +// strBuilder.append(""); +// +// HttpResponse response = new DefaultFullHttpResponse( +// HttpVersion.HTTP_1_1, HttpResponseStatus.OK, +// Unpooled.copiedBuffer(strBuilder.toString(), +// CharsetUtil.UTF_8)); +// response.headers().set(HttpHeaders.Names.CONTENT_TYPE, +// "text/html; charset=UTF-8"); +// +// return response; +// } +// +// HttpResponse httpRequestToSendError() { +// HttpResponse response = new DefaultFullHttpResponse( +// HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, +// Unpooled.copiedBuffer( +// "Failure: " + HttpResponseStatus.NOT_FOUND + "\r\n", +// CharsetUtil.UTF_8)); +// response.headers().set(HttpHeaders.Names.CONTENT_TYPE, +// "text/html; charset=UTF-8"); +// +// return response; +// } +// +// CoapRequest httpRequestToCoAPRequest(String uri, HttpRequest httpRequest) { +// CoapRequest coapRequest; +// +// // TODO: coapRequest converter required +// // coapRequest.getOptions().setUriQuery(); +// if (httpRequest.getMethod() == HttpMethod.GET) { +// coapRequest = new CoapRequest(CoapMethod.GET); +// } else if (httpRequest.getMethod() == HttpMethod.PUT) { +// coapRequest = new CoapRequest(CoapMethod.PUT); +// } else if (httpRequest.getMethod() == HttpMethod.POST) { +// coapRequest = new CoapRequest(CoapMethod.POST); +// } else if (httpRequest.getMethod() == HttpMethod.DELETE) { +// coapRequest = new CoapRequest(CoapMethod.DELETE); +// } else { +// throw new IllegalArgumentException(); +// } +// +// coapRequest.setUriPath(uri); +// +// return coapRequest; +// } +// +// HttpResponse coapResponseToHttpResponse(CoapResponse coapResponse) { +// +// Cbor> cbor = new Cbor>(); +// +// HashMap rep = cbor +// .parsePayloadFromCbor(coapResponse.getPayload(), HashMap.class); +// +// StringBuilder strBuilder = new StringBuilder(); +// +// for (Entry entry : rep.entrySet()) { +// String key = entry.getKey(); +// String value = entry.getValue().toString(); +// strBuilder.append("Key: " + key + " Value: " + value + "
"); +// } +// +// HttpResponse httpResponse = new DefaultFullHttpResponse( +// HttpVersion.HTTP_1_1, HttpResponseStatus.OK, +// Unpooled.wrappedBuffer(strBuilder.toString() +// .getBytes(StandardCharsets.UTF_8))); +// +// httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, +// "text/html; charset=UTF-8"); +// +// // TODO: httpResponse converter required +// +// return httpResponse; +// } +// } diff --git a/cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java b/cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java index b1d2601..f12a807 100644 --- a/cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java @@ -21,6 +21,8 @@ */ package org.iotivity.cloud.util; +import java.nio.charset.StandardCharsets; + import org.iotivity.cloud.base.protocols.coap.CoapMessage; import org.iotivity.cloud.base.protocols.coap.CoapRequest; @@ -70,7 +72,7 @@ public class CoapLogHandler extends ChannelDuplexHandler { Logger.d(strBuilder.toString()); ByteBuf outByteBuf = ctx.alloc().buffer(); - outByteBuf.writeBytes(message.getBytes()); + outByteBuf.writeBytes(message.getBytes(StandardCharsets.UTF_8)); } ctx.write(msg); diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java index 7eadf51..4003cfe 100644 --- a/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java @@ -22,32 +22,21 @@ package org.iotivity.cloud.base; import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; import org.iotivity.cloud.base.protocols.coap.CoapRequest; import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; +import org.iotivity.cloud.util.CoapLogHandler; import org.junit.Test; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - public class CoapClientTest { - - private static class CoapHandler - extends SimpleChannelInboundHandler { - @Override - protected void channelRead0(ChannelHandlerContext ctx, CoapRequest msg) - throws Exception { - // TODO Auto-generated method stub - } - } - @Test public void testAddHandler() throws Exception { CoapServer coapServer = new CoapServer(); coapServer.startServer(new InetSocketAddress(5683)); CoapClient coapClient = new CoapClient(); coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); - coapClient.addHandler(new CoapHandler()); + coapClient.addHandler(new CoapLogHandler()); coapClient.stopClient(); coapServer.stopServer(); } @@ -59,26 +48,26 @@ public class CoapClientTest { CoapClient coapClient = new CoapClient(); coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); - coapClient.addHandler(new CoapHandler()); + coapClient.addHandler(new CoapLogHandler()); CoapRequest request = new CoapRequest(CoapMethod.GET); coapClient.sendRequest(request); CoapRequest request2 = new CoapRequest(CoapMethod.GET); - request2.setToken("1234".getBytes()); + request2.setToken("1234".getBytes(StandardCharsets.UTF_8)); coapClient.sendRequest(request2); CoapRequest request3 = new CoapRequest(CoapMethod.GET); - request3.setPayload("sample1".getBytes()); + request3.setPayload("sample1".getBytes(StandardCharsets.UTF_8)); coapClient.sendRequest(request3); CoapRequest request4 = new CoapRequest(CoapMethod.GET); - request4.setToken("5576".getBytes()); - request4.setPayload("sample2".getBytes()); + request4.setToken("5576".getBytes(StandardCharsets.UTF_8)); + request4.setPayload("sample2".getBytes(StandardCharsets.UTF_8)); coapClient.sendRequest(request4); CoapRequest request5 = new CoapRequest(CoapMethod.GET); - request5.setToken("565761".getBytes()); + request5.setToken("565761".getBytes(StandardCharsets.UTF_8)); coapClient.sendRequest(request5); CoapRequest request6 = new CoapRequest(CoapMethod.GET); diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java index 5ae72f6..f2162ec 100644 --- a/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java @@ -23,27 +23,15 @@ package org.iotivity.cloud.base; import java.net.InetSocketAddress; -import org.iotivity.cloud.base.protocols.coap.CoapRequest; +import org.iotivity.cloud.util.CoapLogHandler; import org.junit.Test; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - public class CoapServerTest { - private static class CoapHandler - extends SimpleChannelInboundHandler { - @Override - protected void channelRead0(ChannelHandlerContext ctx, CoapRequest msg) - throws Exception { - // TODO Auto-generated method stub - } - } - @Test public void testAddHandler() throws Exception { CoapServer server = new CoapServer(); server.startServer(new InetSocketAddress(5683)); - server.addHandler(new CoapHandler()); + server.addHandler(new CoapLogHandler()); server.stopServer(); } diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceManagerTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceManagerTest.java new file mode 100644 index 0000000..c5c6a8c --- /dev/null +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceManagerTest.java @@ -0,0 +1,66 @@ +package org.iotivity.cloud.base; + +import java.net.InetSocketAddress; + +import org.iotivity.cloud.base.SessionManagerTest.CoapClientHandler; +import org.iotivity.cloud.base.protocols.coap.CoapRequest; +import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; +import org.junit.Test; + +import io.netty.channel.ChannelHandlerContext; + +public class ResourceManagerTest { + + private static class SampleResource extends Resource { + + public SampleResource() { + setUri("sampleUri"); + } + + @Override + public void onRequestReceived(ChannelHandlerContext ctx, + CoapRequest request) { + // TODO Auto-generated method stub + } + } + + @Test + public void testChannelRead0ChannelHandlerContextCoapRequest() + throws Exception { + + ResourceManager resourceManager = new ResourceManager(); + + resourceManager.registerResource(new SampleResource()); + + CoapServer coapServer = new CoapServer(); + CoapClient coapClient = new CoapClient(); + CoapClientHandler coapClientHandler = new CoapClientHandler(); + coapServer.startServer(new InetSocketAddress(5683)); + coapClient.addHandler(coapClientHandler); + coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); + + CoapRequest request = new CoapRequest(CoapMethod.GET); + request.setUriPath("sampleUri"); + + resourceManager.channelRead0(coapClientHandler.connectCtx, request); + + coapClient.stopClient(); + coapServer.stopServer(); + } + + @Test + public void testRegisterResource() { + ResourceManager resourceManager = new ResourceManager(); + + resourceManager.registerResource(new SampleResource()); + } + + @Test + public void testUnregisterResource() { + SampleResource sampleResource = new SampleResource(); + ResourceManager resourceManager = new ResourceManager(); + + resourceManager.registerResource(sampleResource); + resourceManager.unregisterResource(sampleResource); + } +} \ No newline at end of file diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceTest.java new file mode 100644 index 0000000..6e38855 --- /dev/null +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/ResourceTest.java @@ -0,0 +1,54 @@ +package org.iotivity.cloud.base; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.iotivity.cloud.base.protocols.coap.CoapRequest; +import org.junit.Test; + +import io.netty.channel.ChannelHandlerContext; + +public class ResourceTest { + + private static class SampleResource extends Resource { + + public SampleResource() { + setUri("sampleUri"); + } + + @Override + public void onRequestReceived(ChannelHandlerContext ctx, + CoapRequest request) { + // TODO Auto-generated method stub + } + } + + @Test + public void testGetSetUri() { + SampleResource sampleResource = new SampleResource(); + assertEquals(sampleResource.getUri(), "sampleUri"); + sampleResource.setUri("sampleUri2"); + assertEquals(sampleResource.getUri(), "sampleUri2"); + } + + @Test + public void testGetSetType() { + SampleResource sampleResource = new SampleResource(); + assertNull(sampleResource.getType()); + sampleResource.setType("sampleType"); + assertEquals(sampleResource.getType(), "sampleType"); + } + + @Test + public void testGetSetRif() { + SampleResource sampleResource = new SampleResource(); + assertNull(sampleResource.getRif()); + sampleResource.setRif("sampleRif"); + assertEquals(sampleResource.getRif(), "sampleRif"); + } + + @Test + public void testOnRequestReceived() { + + } +} diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/SessionManagerTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/SessionManagerTest.java new file mode 100644 index 0000000..30df055 --- /dev/null +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/SessionManagerTest.java @@ -0,0 +1,99 @@ +package org.iotivity.cloud.base; + +import static org.junit.Assert.assertNotNull; + +import java.net.InetSocketAddress; + +import org.iotivity.cloud.base.protocols.coap.CoapResponse; +import org.junit.Test; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +public class SessionManagerTest { + + static class CoapClientHandler + extends SimpleChannelInboundHandler { + + ChannelHandlerContext connectCtx = null; + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + connectCtx = ctx; + } + + @Override + protected void channelRead0(ChannelHandlerContext arg0, + CoapResponse arg1) throws Exception { + // TODO Auto-generated method stub + + } + } + + @Test + public void testAddSession() throws Exception { + SessionManager sessionManager = new SessionManager(); + CoapServer coapServer = new CoapServer(); + CoapClient coapClient = new CoapClient(); + CoapClientHandler coapClientHandler = new CoapClientHandler(); + coapServer.startServer(new InetSocketAddress(5683)); + coapClient.addHandler(coapClientHandler); + coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); + + sessionManager.addSession("sampleDid", coapClientHandler.connectCtx); + + coapClient.stopClient(); + coapServer.stopServer(); + } + + @Test + public void testRemoveSession() throws Exception { + SessionManager sessionManager = new SessionManager(); + CoapServer coapServer = new CoapServer(); + CoapClient coapClient = new CoapClient(); + CoapClientHandler coapClientHandler = new CoapClientHandler(); + coapServer.startServer(new InetSocketAddress(5683)); + coapClient.addHandler(coapClientHandler); + coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); + + sessionManager.addSession("sampleDid", coapClientHandler.connectCtx); + sessionManager.removeSession("sampleDid"); + + coapClient.stopClient(); + coapServer.stopServer(); + } + + @Test + public void testRemoveSessionByChannel() throws Exception { + SessionManager sessionManager = new SessionManager(); + CoapServer coapServer = new CoapServer(); + CoapClient coapClient = new CoapClient(); + CoapClientHandler coapClientHandler = new CoapClientHandler(); + coapServer.startServer(new InetSocketAddress(5683)); + coapClient.addHandler(coapClientHandler); + coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); + + sessionManager.addSession("sampleDid", coapClientHandler.connectCtx); + sessionManager.removeSessionByChannel(coapClientHandler.connectCtx); + + coapClient.stopClient(); + coapServer.stopServer(); + } + + @Test + public void testQuerySession() throws Exception { + SessionManager sessionManager = new SessionManager(); + CoapServer coapServer = new CoapServer(); + CoapClient coapClient = new CoapClient(); + CoapClientHandler coapClientHandler = new CoapClientHandler(); + coapServer.startServer(new InetSocketAddress(5683)); + coapClient.addHandler(coapClientHandler); + coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); + + sessionManager.addSession("sampleDid", coapClientHandler.connectCtx); + assertNotNull(sessionManager.querySession("sampleDid")); + + coapClient.stopClient(); + coapServer.stopServer(); + } +} diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapRequestTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapRequestTest.java new file mode 100644 index 0000000..7cea05c --- /dev/null +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapRequestTest.java @@ -0,0 +1,77 @@ +package org.iotivity.cloud.base.protocols.coap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; +import org.junit.Test; + +public class CoapRequestTest { + + @Test + public void testCoapRequest() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + assertNotNull(request); + } + + @Test + public void testGetRequestMethod() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + assertEquals(request.getRequestMethod(), CoapMethod.GET); + } + + @Test + public void testSetUriPath() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + request.setUriPath("sample"); + } + + @Test + public void testGetUriPath() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + assertNull(request.getUriPath()); + request.setUriPath("sample"); + assertEquals(request.getUriPath(), "sample"); + } + + @Test + public void testGetUriPathSegments() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + assertNull(request.getUriPathSegments()); + request.setUriPath("parent/child"); + assertEquals(request.getUriPathSegments().size(), 2); + } + + @Test + public void testSetUriQuery() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + request.setUriQuery("sample=sample"); + } + + @Test + public void testGetUriQuery() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + assertNull(request.getUriQuery()); + request.setUriQuery("sample=sample"); + assertEquals(request.getUriQuery(), "sample=sample"); + } + + @Test + public void testGetUriQuerySegments() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + assertNull(request.getUriQuerySegments()); + request.setUriQuery("sample=samplle&sample2=sample2"); + assertEquals(request.getUriQuerySegments().size(), 2); + } + + @Test + public void testClearUriPath() { + CoapRequest request = new CoapRequest(CoapMethod.GET); + assertNull(request.getUriPathSegments()); + request.setUriPath("sample"); + assertEquals(request.getUriPathSegments().size(), 1); + request.clearUriPath(); + assertEquals(request.getUriPathSegments().size(), 0); + } +} diff --git a/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapResponseTest.java b/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapResponseTest.java new file mode 100644 index 0000000..5aaf4d5 --- /dev/null +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/protocols/coap/CoapResponseTest.java @@ -0,0 +1,21 @@ +package org.iotivity.cloud.base.protocols.coap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus; +import org.junit.Test; + +public class CoapResponseTest { + @Test + public void testCoapResponse() throws Exception { + CoapResponse response = new CoapResponse(CoapStatus.VALID); + assertNotNull(response); + } + + @Test + public void testGetResponseCode() throws Exception { + CoapResponse response = new CoapResponse(CoapStatus.VALID); + assertEquals(response.getResponseCode(), CoapStatus.VALID); + } +} -- 2.7.4