Adding example of a Simple Attribute use on a collection resource using
authorJoseph Morrow <joseph.l.morrow@intel.com>
Sun, 2 Nov 2014 23:18:19 +0000 (18:18 -0500)
committerJoseph Morrow <joseph.l.morrow@intel.com>
Sun, 2 Nov 2014 23:18:19 +0000 (18:18 -0500)
C SDK.

This involved forming proper JSON examples, as well as adding test
cases to the application as the implementation of test cases were not
fullfilled yet.

Change-Id: I0b217a324334367bf3a923d7aadef5150e385821
Signed-off-by: Joseph Morrow <joseph.l.morrow@intel.com>
csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp
csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp

index 8ee05e6..2a93a6f 100644 (file)
@@ -38,10 +38,41 @@ std::string getQueryStrForGetPut(unsigned  const char * responsePayload);
 #define MAX_LENGTH_IPv4_ADDR 16
 #endif
 
-#define MAX_TEST_CASES 5
+typedef enum {
+    TEST_INVALID = 0,
+    TEST_GET_DEFAULT,
+    TEST_GET_BATCH,
+    TEST_GET_LINK_LIST,
+    TEST_PUT_DEFAULT,
+    TEST_PUT_BATCH,
+    TEST_PUT_LINK_LIST,
+    TEST_UNKNOWN_RESOURCE_GET_DEFAULT,
+    TEST_UNKNOWN_RESOURCE_GET_BATCH,
+    TEST_UNKNOWN_RESOURCE_GET_LINK_LIST,
+    MAX_TESTS
+} CLIENT_TEST;
+
+unsigned static int TEST = TEST_INVALID;
+
+typedef struct
+{
+    unsigned char text[30];
+    CLIENT_TEST test;
+} testToTextMap;
+
+testToTextMap queryInterface[] = {
+        {"invalid", TEST_INVALID},
+        {"?if=oc.mi.def", TEST_GET_DEFAULT},
+        {"?if=oc.mi.b", TEST_GET_BATCH},
+        {"?if=oc.mi.ll", TEST_GET_LINK_LIST},
+        {"?if=oc.mi.def", TEST_UNKNOWN_RESOURCE_GET_DEFAULT},
+        {"?if=oc.mi.b", TEST_UNKNOWN_RESOURCE_GET_BATCH},
+        {"?if=oc.mi.ll", TEST_UNKNOWN_RESOURCE_GET_LINK_LIST},
+        {"?if=oc.mi.def", TEST_PUT_DEFAULT},
+        {"?if=oc.mi.b", TEST_PUT_BATCH},
+        {"?if=oc.mi.ll", TEST_PUT_LINK_LIST},
+};
 
-static int UNICAST_DISCOVERY = 0;
-static int TEST_CASE = 0;
 static std::string putPayload = "{\"state\":\"off\",\"power\":\"0\"}";
 
 // The handle for the observe registration
@@ -67,12 +98,25 @@ int InitDiscovery();
 
 void PrintUsage()
 {
-    OC_LOG(INFO, TAG, "Usage : occlient <Unicast Discovery> <Test Case>");
-    OC_LOG(INFO, TAG, "Test Case 1 : Discover Resources");
-    OC_LOG(INFO, TAG, "Test Case 2 : Discover Resources and Initiate Get Request");
-    OC_LOG(INFO, TAG, "Test Case 3 : Discover Resources and Initiate Get/Put Requests");
-    OC_LOG(INFO, TAG, "Test Case 4 : Discover Resources and Initiate Observe Requests");
-    OC_LOG(INFO, TAG, "Test Case 5 : Discover Resources and Initiate Get Request for a resource which is unavailable");
+    OC_LOG(INFO, TAG, "Usage : occlient -t <Test Case>");
+    OC_LOG(INFO, TAG, "Test Case 1 : Discover Resources && Initiate GET Request on an"\
+            "available resource using default interface.");
+    OC_LOG(INFO, TAG, "Test Case 2 : Discover Resources && Initiate GET Request on an"\
+                 "available resource using batch interface.");
+    OC_LOG(INFO, TAG, "Test Case 3 : Discover Resources && Initiate GET Request on an"\
+                 "available resource using link list interface.");
+    OC_LOG(INFO, TAG, "Test Case 4 : Discover Resources && Initiate GET & PUT Request on an"\
+                 "available resource using default interface.");
+    OC_LOG(INFO, TAG, "Test Case 5 : Discover Resources && Initiate GET & PUT Request on an"\
+                 "available resource using batch interface.");
+    OC_LOG(INFO, TAG, "Test Case 6 : Discover Resources && Initiate GET & PUT Request on an"\
+                 "available resource using link list interface.");
+    OC_LOG(INFO, TAG, "Test Case 7 : Discover Resources && Initiate GET Request on an"\
+                 "unavailable resource using default interface.");
+    OC_LOG(INFO, TAG, "Test Case 8 : Discover Resources && Initiate GET Request on an"\
+                 "unavailable resource using batch interface.");
+    OC_LOG(INFO, TAG, "Test Case 9 : Discover Resources && Initiate GET Request on an"\
+                 "unavailable resource using link list interface.");
 }
 
 OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse) {
@@ -106,7 +150,10 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
             }
         }
     }
-    InitPutRequest(clientResponse);
+    if(TEST == TEST_PUT_DEFAULT || TEST == TEST_PUT_BATCH || TEST == TEST_PUT_LINK_LIST)
+    {
+        InitPutRequest(clientResponse);
+    }
     return OC_STACK_KEEP_TRANSACTION;
 }
 
@@ -136,8 +183,15 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
             remoteIpAddr[2], remoteIpAddr[3], remotePortNu);
 #endif
 
-    InitGetRequest(clientResponse);
-
+    if(TEST == TEST_UNKNOWN_RESOURCE_GET_DEFAULT || TEST == TEST_UNKNOWN_RESOURCE_GET_BATCH ||\
+            TEST == TEST_UNKNOWN_RESOURCE_GET_LINK_LIST)
+    {
+        InitGetRequestToUnavailableResource(clientResponse);
+    }
+    else
+    {
+        InitGetRequest(clientResponse);
+    }
     return OC_STACK_KEEP_TRANSACTION;
 }
 
@@ -173,7 +227,7 @@ int InitObserveRequest(OCClientResponse * clientResponse)
     cbData.cb = getReqCB;
     cbData.context = (void*)CTX_VAL;
     cbData.cd = NULL;
-    OC_LOG_V(INFO, TAG, "PUT payload from client = %s ", putPayload.c_str());
+    OC_LOG_V(INFO, TAG, "OBSERVE payload from client = %s ", putPayload.c_str());
 
     ret = OCDoResource(&handle, OC_REST_OBSERVE, obsReg.str().c_str(), 0, 0, OC_LOW_QOS,
             &cbData, NULL, 0);
@@ -197,7 +251,7 @@ int InitPutRequest(OCClientResponse * clientResponse)
     //* Make a PUT query*/
     std::ostringstream getQuery;
     getQuery << "coap://" << getIPAddrTBServer(clientResponse) << ":" << getPortTBServer(clientResponse) <<
-    "/a/sroom?if=oc.mi.b";
+    "/a/room" << queryInterface[TEST].text;
     cbData.cb = putReqCB;
     cbData.context = (void*)CTX_VAL;
     cbData.cd = NULL;
@@ -229,9 +283,7 @@ int InitGetRequest(OCClientResponse * clientResponse)
     //* Make a GET query*/
     std::ostringstream getQuery;
     getQuery << "coap://" << getIPAddrTBServer(clientResponse) << ":" << getPortTBServer(clientResponse) <<
-    //"/a/sroom?if=oc.mi.def";
-    //"/a/sroom?if=oc.mi.ll";
-    "/a/sroom?if=oc.mi.b";
+    "/a/room" << queryInterface[TEST].text;
 
     std::cout << "Get Query: " << getQuery.str() << std::endl;
 
@@ -247,7 +299,6 @@ int InitGetRequest(OCClientResponse * clientResponse)
     return ret;
 }
 
-#define TEST_APP_UNICAST_DISCOVERY_QUERY                  PCF("coap://0.0.0.0:5683/oc/core")
 int InitDiscovery()
 {
     OCStackResult ret;
@@ -256,8 +307,7 @@ int InitDiscovery()
     /* Start a discovery query*/
     char szQueryUri[64] = { 0 };
 
-    //strcpy(szQueryUri, "coap://224.0.1.187:5683/oc/core");//?rt=core.sroom");
-    strcpy(szQueryUri, "coap://0.0.0.0:5683/oc/core");
+    strcpy(szQueryUri, OC_WELL_KNOWN_QUERY);
 
     cbData.cb = discoveryReqCB;
     cbData.context = (void*)CTX_VAL;
@@ -272,6 +322,20 @@ int InitDiscovery()
 }
 
 int main(int argc, char* argv[]) {
+    if(argc >= 2 && strcmp(argv[1], "-t") == 0)
+    {
+        TEST = atoi(argv[2]);
+        if(TEST >= MAX_TESTS || TEST < 1)
+        {
+            PrintUsage();
+            return 0;
+        }
+    }
+    else
+    {
+        PrintUsage();
+        return 0;
+    }
     uint8_t addr[20] = {0};
     uint8_t* paddr = NULL;
     uint16_t port = USE_RANDOM_PORT;
@@ -342,5 +406,5 @@ std::string getQueryStrForGetPut(unsigned  const char * responsePayload){
 
     std::string jsonPayload(reinterpret_cast<char*>(const_cast<unsigned char*>(responsePayload)));
 
-    return "/a/sroom";
+    return "/a/room";
 }
index 537e9c9..7a6d239 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <string>
 #include <stdlib.h>
 #include <unistd.h>
 #include <signal.h>
@@ -33,27 +34,39 @@ const char *getResult(OCStackResult result);
 #define TAG PCF("ocservercontainer")
 
 int gQuitFlag = 0;
-int gLEDUnderObservation = 0;
+int gLightUnderObservation = 0;
 void createResources();
-typedef struct LEDRESOURCE{
+typedef struct LIGHTRESOURCE{
     OCResourceHandle handle;
     bool state;
     int power;
-} LEDResource;
+} LightResource;
 
-static LEDResource LED;
+static LightResource light;
+
+// TODO : hard coded for now, change after Sprint10
+const char rspGetRoomDefault[] = "{\"href\":\"/a/room\",\"rep\":{\"name\":\"John's Room\"}}";
+const char rspGetRoomCollection[] = "{\"href\":\"/a/room\"}";
+// TODO : Needs to be changed to retrieve current status of room and return that in response
+const char rspPutRoomDefault[] = "{\"href\":\"/a/room\",\"rep\":{\"name\":\"John's Room\"}}";
+const char rspPutRoomCollection[] = "{\"href\":\"/a/room\"}";
+const char rspFailureRoom[] = "{\"href\":\"/a/room\",\"rep\":{\"error\":\"ROOM_OP_FAIL\"}}";
 
 // TODO : hard coded for now, change after Sprint4
-const char rspGetLed[] = "{\"href\":\"/a/led\",\"rep\":{\"state\":\"on\",\"color\":\"yellow\"}}";
-// TODO : Needs to be changed to retrieve current status of led and return that in response
-const char rspPutLed[] = "{\"href\":\"/a/led\",\"rep\":{\"state\":\"off\",\"color\":\"off\"}}";
-const char rspFailureLed[] = "{\"href\":\"/a/led\",\"rep\":{\"error\":\"LED_OP_FAIL\"}}";
+const char rspGetLightDefault[] = "{\"href\":\"/a/light\",\"rep\":{\"state\":\"false\",\"color\":\"0\"}}";
+const char rspGetLightCollection[] = "{\"href\":\"/a/light\"}";
+// TODO : Needs to be changed to retrieve current status of light and return that in response
+const char rspPutLightDefault[] = "{\"href\":\"/a/light\",\"rep\":{\"state\":\"true\",\"color\":\"0\"}}";
+const char rspPutLightCollection[] = "{\"href\":\"/a/light\"}";
+const char rspFailureLight[] = "{\"href\":\"/a/light\",\"rep\":{\"error\":\"LIGHT_OP_FAIL\"}}";
 
 
 // TODO : hard coded for now, change after Sprint4
-const char rspGetFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"on\",\"speed\":10}}";
+const char rspGetFanDefault[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"true\",\"speed\":10}}";
+const char rspGetFanCollection[] = "{\"href\":\"/a/fan\"}";
 // TODO : Needs to be changed to retrieve current status of fan and return that in response
-const char rspPutFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"off\",\"speed\":0}}";
+const char rspPutFanDefault[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"false\",\"speed\":0}}";
+const char rspPutFanCollection[] = "{\"href\":\"/a/fan\"}";
 const char rspFailureFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"error\":\"FAN_OP_FAIL\"}}";
 
 static OCEntityHandlerResult
@@ -63,11 +76,11 @@ HandleCallback(OCEntityHandlerRequest * ehRequest, const char* opStr, const char
 
     if (strlen(opStr) < ehRequest->resJSONPayloadLen)
     {
-        strncpy((char*)ehRequest->resJSONPayload, opStr, ehRequest->resJSONPayloadLen);
+        strncat((char*)ehRequest->resJSONPayload, opStr, ehRequest->resJSONPayloadLen);
     }
     else if (strlen(errStr) < ehRequest->resJSONPayloadLen)
     {
-        strncpy((char*)ehRequest->resJSONPayload, errStr, ehRequest->resJSONPayloadLen);
+        strncat((char*)ehRequest->resJSONPayload, errStr, ehRequest->resJSONPayloadLen);
         ret = OC_EH_ERROR;
     }
     else
@@ -102,26 +115,135 @@ PrintReceivedMsgInfo(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehReques
              (ehRequest->method == OC_REST_GET) ? "OC_REST_GET" : "OC_REST_PUT" );
 }
 
-OCEntityHandlerResult OCEntityHandlerLedCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest ) {
+OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,\
+        OCEntityHandlerRequest * ehRequest )
+{
+    OCEntityHandlerResult ret = OC_EH_OK;
+
+    OC_LOG_V(INFO, TAG, "Callback for Room");
+    PrintReceivedMsgInfo(flag, ehRequest );
+
+    if(ehRequest && flag == OC_REQUEST_FLAG )
+    {
+        std::string query = (const char*)ehRequest->query;
+
+        if(OC_REST_GET == ehRequest->method)
+        {
+            if(query.find("oc.mi.def") != std::string::npos)
+            {
+                ret = HandleCallback(ehRequest, rspGetRoomDefault, rspFailureRoom);
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspGetLightCollection, rspFailureLight);
+                }
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspGetFanCollection, rspFailureFan);
+                }
+            }
+            else if(query.find("oc.mi.ll") != std::string::npos)
+            {
+                ret = HandleCallback(ehRequest, rspGetRoomCollection, rspFailureRoom);
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspGetLightCollection, rspFailureLight);
+                }
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspGetFanCollection, rspFailureFan);
+                }
+            }
+            else if(query.find("oc.mi.b") != std::string::npos)
+            {
+                ret = HandleCallback(ehRequest, rspGetRoomCollection, rspFailureRoom);
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspGetLightDefault, rspFailureLight);
+                }
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspGetFanDefault, rspFailureFan);
+                }
+            }
+        }
+        if(OC_REST_PUT == ehRequest->method)
+        {
+            if(query.find("oc.mi.def") != std::string::npos)
+            {
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, rspPutRoomDefault, rspFailureRoom);
+                }
+            }
+            if(query.find("oc.mi.ll") != std::string::npos)
+            {
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, rspPutRoomCollection, rspFailureRoom);
+                }
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspPutLightCollection, rspFailureLight);
+                }
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspPutFanCollection, rspFailureFan);
+                }
+            }
+            if(query.find("oc.mi.b") != std::string::npos)
+            {
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, rspPutRoomCollection, rspFailureRoom);
+                }
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspPutLightDefault, rspFailureLight);
+                }
+                if(ret != OC_EH_ERROR)
+                {
+                    ret = HandleCallback(ehRequest, ",", ",");
+                    ret = HandleCallback(ehRequest, rspPutFanDefault, rspFailureFan);
+                }
+            }
+        }
+    }
+    else if (ehRequest && flag == OC_OBSERVE_FLAG)
+    {
+        gLightUnderObservation = 1;
+    }
+    return ret;
+}
+
+OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest ) {
     OCEntityHandlerResult ret = OC_EH_OK;
 
-    OC_LOG_V(INFO, TAG, "Callback for Led");
+    OC_LOG_V(INFO, TAG, "Callback for Light");
     PrintReceivedMsgInfo(flag, ehRequest );
 
     if(ehRequest && flag == OC_REQUEST_FLAG)
     {
         if(OC_REST_GET == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest, rspGetLed, rspFailureLed);
+            ret = HandleCallback(ehRequest, rspGetLightDefault, rspFailureLight);
         }
         if(OC_REST_PUT == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest, rspPutLed, rspFailureLed);
+            ret = HandleCallback(ehRequest, rspPutLightDefault, rspFailureLight);
         }
     }
     else if (ehRequest && flag == OC_OBSERVE_FLAG)
     {
-        gLEDUnderObservation = 1;
+        gLightUnderObservation = 1;
     }
 
     return ret;
@@ -137,16 +259,16 @@ OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag, OCEntityHan
     {
         if(OC_REST_GET == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest, rspGetFan, rspFailureFan);
+            ret = HandleCallback(ehRequest, rspGetFanDefault, rspFailureFan);
         }
         if(OC_REST_PUT == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest, rspPutFan, rspFailureFan);
+            ret = HandleCallback(ehRequest, rspPutFanDefault, rspFailureFan);
         }
     }
     else if (ehRequest && flag == OC_OBSERVE_FLAG)
     {
-        gLEDUnderObservation = 1;
+        gLightUnderObservation = 1;
     }
 
     return ret;
@@ -159,7 +281,7 @@ void handleSigInt(int signum) {
     }
 }
 
-void *ChangeLEDRepresentation (void *param)
+void *ChangeLightRepresentation (void *param)
 {
     (void)param;
     OCStackResult result = OC_STACK_ERROR;
@@ -167,14 +289,14 @@ void *ChangeLEDRepresentation (void *param)
     while (1)
     {
         sleep(10);
-        LED.power += 5;
-        if (gLEDUnderObservation)
+        light.power += 5;
+        if (gLightUnderObservation)
         {
-     OC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", LED.power);
-            result = OCNotifyAllObservers (LED.handle, OC_NA_QOS);
+     OC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", light.power);
+            result = OCNotifyAllObservers (light.handle, OC_NA_QOS);
             if (OC_STACK_NO_OBSERVERS == result)
             {
-                gLEDUnderObservation = 0;
+                gLightUnderObservation = 0;
             }
         }
     }
@@ -186,7 +308,7 @@ int main() {
     OC_LOG(DEBUG, TAG, "OCServer is starting...");
     uint8_t addr[20] = {0};
     uint8_t* paddr = NULL;
-    uint16_t port = 5683;
+    uint16_t port = 0;
     uint8_t ifname[] = "eth0";
     pthread_t threadId;
 
@@ -205,14 +327,14 @@ int main() {
     }
 
     /*
-     * Declare and create the example resource: LED
+     * Declare and create the example resource: light
      */
     createResources();
 
     /*
-     * Create a thread for changing the representation of the LED
+     * Create a thread for changing the representation of the light
      */
-    pthread_create (&threadId, NULL, ChangeLEDRepresentation, (void *)NULL);
+    pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
 
     // Break from loop with Ctrl-C
     OC_LOG(INFO, TAG, "Entering ocserver main loop...");
@@ -226,7 +348,7 @@ int main() {
     }
 
     /*
-     * Cancel the LED thread and wait for it to terminate
+     * Cancel the light thread and wait for it to terminate
      */
     pthread_cancel(threadId);
     pthread_join(threadId, NULL);
@@ -240,27 +362,10 @@ int main() {
     return 0;
 }
 void createResources() {
-    LED.state = false;
-    OCResourceHandle room;
-    OCStackResult res = OCCreateResource(&room,
-            "core.sroom",
-            "oc.mi.ll",
-            "/a/sroom",
-            NULL,
-            OC_DISCOVERABLE);
-    OC_LOG_V(INFO, TAG, "Created room resource with result: %s", getResult(res));
-
-    OCResourceHandle light;
-    res = OCCreateResource(&light,
-            "core.light",
-            "oc.mi.def",
-            "/a/led",
-            OCEntityHandlerLedCb,
-            OC_DISCOVERABLE|OC_OBSERVABLE);
-    OC_LOG_V(INFO, TAG, "Created light resource with result: %s", getResult(res));
+    light.state = false;
 
     OCResourceHandle fan;
-    res = OCCreateResource(&fan,
+    OCStackResult res = OCCreateResource(&fan,
             "core.fan",
             "oc.mi.def",
             "/a/fan",
@@ -268,6 +373,26 @@ void createResources() {
             OC_DISCOVERABLE|OC_OBSERVABLE);
     OC_LOG_V(INFO, TAG, "Created fan resource with result: %s", getResult(res));
 
+    OCResourceHandle light;
+    res = OCCreateResource(&light,
+            "core.light",
+            "oc.mi.def",
+            "/a/light",
+            OCEntityHandlerLightCb,
+            OC_DISCOVERABLE|OC_OBSERVABLE);
+    OC_LOG_V(INFO, TAG, "Created light resource with result: %s", getResult(res));
+
+    OCResourceHandle room;
+    res = OCCreateResource(&room,
+            "core.room",
+            "oc.mi.b",
+            "/a/room",
+            OCEntityHandlerRoomCb,
+            OC_DISCOVERABLE);
+    OC_LOG_V(INFO, TAG, "Created room resource with result: %s", getResult(res));
+    OCBindResourceInterfaceToResource(room, "oc.mi.ll");
+    OCBindResourceInterfaceToResource(room, "oc.mi.def");
+
     res = OCBindResource(room, light);
     OC_LOG_V(INFO, TAG, "OC Bind Contained Resource to resource: %s", getResult(res));