Added check to make sure default interface is always first in list.
authorMandeep Shetty <mandeep.shetty@intel.com>
Mon, 11 May 2015 18:17:08 +0000 (11:17 -0700)
committerErich Keane <erich.keane@intel.com>
Tue, 12 May 2015 17:30:01 +0000 (17:30 +0000)
This changeset ensures the default interface, if present, is always
first in the interface list. This addresses spec compliance for section
7.1.4.2.3.
Also added unit tests to test changes made in this changeset and to test
for duplicate interfaces.

Change-Id: Iccfbb297c1745a86ce2cb0010f5b24519d567658
Signed-off-by: Mandeep Shetty <mandeep.shetty@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/954
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Erich Keane <erich.keane@intel.com>
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/test/stacktests.cpp

index 08793a3..fae4aba 100644 (file)
@@ -3589,34 +3589,54 @@ OCResourceType *findResourceType(OCResourceType * resourceTypeList, const char *
     return NULL;
 }
 
-void insertResourceInterface(OCResource *resource,
-        OCResourceInterface *resourceInterface)
+/*
+ * Insert a new interface into interface linked list only if not already present.
+ * If alredy present, 2nd arg is free'd.
+ * Default interface will always be first if present.
+ */
+void insertResourceInterface(OCResource *resource, OCResourceInterface *newInterface)
 {
     OCResourceInterface *pointer = NULL;
     OCResourceInterface *previous = NULL;
 
-    if (!resource->rsrcInterface)
+    newInterface->next = NULL;
+
+    OCResourceInterface **firstInterface = &(resource->rsrcInterface);
+
+    if (!*firstInterface)
     {
-        resource->rsrcInterface = resourceInterface;
+        *firstInterface = newInterface;
+    }
+    else if (strcmp(newInterface->name, OC_RSRVD_INTERFACE_DEFAULT) == 0)
+    {
+        if (strcmp((*firstInterface)->name, OC_RSRVD_INTERFACE_DEFAULT) == 0)
+        {
+            OCFree(newInterface->name);
+            OCFree(newInterface);
+            return;
+        }
+        else
+        {
+            newInterface->next = *firstInterface;
+            *firstInterface = newInterface;
+        }
     }
     else
     {
-        pointer = resource->rsrcInterface;
+        pointer = *firstInterface;
         while (pointer)
         {
-            // resource type already exists. Free 2nd arg and return.
-            if (!strcmp(resourceInterface->name, pointer->name))
+            if (strcmp(newInterface->name, pointer->name) == 0)
             {
-                OCFree(resourceInterface->name);
-                OCFree(resourceInterface);
+                OCFree(newInterface->name);
+                OCFree(newInterface);
                 return;
             }
             previous = pointer;
             pointer = pointer->next;
         }
-        previous->next = resourceInterface;
+        previous->next = newInterface;
     }
-    resourceInterface->next = NULL;
 }
 
 OCResourceInterface *findResourceInterfaceAtIndex(OCResourceHandle handle,
index ba9cad7..e3914ff 100644 (file)
@@ -479,6 +479,97 @@ TEST(StackResource, ResourceTypeInterface)
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
 
+TEST(StackResource, ResourceDefaultInterfaceAlwaysFirst)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    const char * OC_RSRVD_INTERFACE_DEFAULT = "oc.mi.def";
+    OC_LOG(INFO, TAG, "Starting ResourceDefaultInterfaceAlwaysFirst test");
+
+    InitStack(OC_SERVER);
+
+    OCResourceHandle handle;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led",
+                                            0,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE));
+    EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle,
+                                        OC_RSRVD_INTERFACE_DEFAULT));
+    uint8_t numResourceInterfaces;
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
+    EXPECT_EQ(2, numResourceInterfaces);
+
+    const char *interfaceName_1 = OCGetResourceInterfaceName(handle, 0);
+    EXPECT_STREQ(OC_RSRVD_INTERFACE_DEFAULT, interfaceName_1);
+
+    const char*interfaceName_2 = OCGetResourceInterfaceName(handle, 1);
+    EXPECT_STREQ("core.rw", interfaceName_2);
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
+
+TEST(StackResource, ResourceDuplicateDefaultInterfaces)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    const char * OC_RSRVD_INTERFACE_DEFAULT = "oc.mi.def";
+    OC_LOG(INFO, TAG, "Starting ResourceDuplicateDefaultInterfaces test");
+
+    InitStack(OC_SERVER);
+
+    OCResourceHandle handle;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led",
+                                            0,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE));
+
+    EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle,
+                                        OC_RSRVD_INTERFACE_DEFAULT));
+    EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle,
+                                        OC_RSRVD_INTERFACE_DEFAULT));
+
+    uint8_t numResourceInterfaces;
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
+    EXPECT_EQ(2, numResourceInterfaces);
+
+    const char *interfaceName_1 = OCGetResourceInterfaceName(handle, 0);
+    EXPECT_STREQ(OC_RSRVD_INTERFACE_DEFAULT, interfaceName_1);
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
+
+TEST(StackResource, ResourceDuplicateNonDefaultInterfaces)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OC_LOG(INFO, TAG, "Starting ResourceDuplicateInterfaces test");
+
+    InitStack(OC_SERVER);
+
+    OCResourceHandle handle;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led",
+                                            0,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE));
+
+    EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle,
+                                        "core.rw"));
+    EXPECT_EQ(OC_STACK_OK, OCBindResourceInterfaceToResource(handle,
+                                        "core.rw"));
+
+    uint8_t numResourceInterfaces;
+    EXPECT_EQ(OC_STACK_OK, OCGetNumberOfResourceInterfaces(handle, &numResourceInterfaces));
+    EXPECT_EQ(1, numResourceInterfaces);
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
+
 TEST(StackResource, ResourceTypeInterfaceMethods)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);