[IOT-1207] Endpoint C API with request filtering
authorbg.chun <bg.chun@samsung.com>
Fri, 5 Aug 2016 09:48:18 +0000 (18:48 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Wed, 30 Nov 2016 12:53:25 +0000 (12:53 +0000)
provide public capi "OCCreateResourceWithEp" for mapping endpoint to
resource and filltering request which come from unbinded endpoint.

Change-Id: I7f273acdacff9116d99b60afb76f70fa48709341
Signed-off-by: bg.chun <bg.chun@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/10073
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
18 files changed:
resource/csdk/octbstack_product.def
resource/csdk/stack/include/internal/ocstackinternal.h
resource/csdk/stack/include/ocpayload.h
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/include/payload_logging.h
resource/csdk/stack/samples/linux/SimpleClientServer/SConscript
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.h
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h
resource/csdk/stack/src/ocendpoint.c
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/src/ocpayloadconvert.c
resource/csdk/stack/src/ocpayloadparse.c
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/test/stacktests.cpp

index f9c3156..6251601 100644 (file)
@@ -39,8 +39,10 @@ OCCancel
 OCCreateOCStringLL
 OCCreateResource
 OCDecodeAddressForRFC6874
+OCCreateResourceWithEp
 OCDeleteResource
 OCDiscoverDirectPairingDevices
+OCDiscoveryEndpointDestroy
 OCDiscoveryPayloadCreate
 OCDiscoveryPayloadDestroy
 OCDiscoveryPayloadGetResourceCount
@@ -48,6 +50,8 @@ OCDoDirectPairing
 OCDoResource
 OCDoResponse
 OCEncodeAddressForRFC6874
+OCEndpointPayloadGetEndpoint
+OCEndpointPayloadGetEndpointCount
 OCFreeOCStringLL
 OCGetDeviceId
 OCGetDirectPairedDevices
@@ -66,6 +70,7 @@ OCGetResourceTypeName
 OCGetResourceUri
 OCGetResourceIns
 OCGetServerInstanceIDString
+OCGetSupportedEndpointTpsFlags
 OCInit
 OCInit1
 OCNotifyAllObservers
@@ -104,6 +109,7 @@ OCRepPayloadSetPropString
 OCRepPayloadSetStringArray
 OCRepPayloadSetStringArrayAsOwner
 OCRepPayloadSetUri
+OCResourcePayloadAddNewEndpoint
 OCResourcePayloadAddStringLL
 OCSecurityPayloadCreate
 OCSetDefaultDeviceEntityHandler
index d0e5909..b3838cf 100644 (file)
@@ -227,8 +227,17 @@ OCStackResult BindResourceInterfaceToResource(OCResource* resource,
  * @param resourceTypeName Name of resource type.
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult BindResourceTypeToResource(OCResourceresource,
+OCStackResult BindResourceTypeToResource(OCResource *resource,
                                             const char *resourceTypeName);
+/**
+ * Bind a Transport Protocol Suites type to a resource.
+ *
+ * @param resource Target resource.
+ * @param resourceTpsTypes Name of transport protocol suites type.
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult BindTpsTypeToResource(OCResource *resource,
+                                    OCTpsSchemeFlags resourceTpsTypes);
 
 /**
  * Convert OCStackResult to CAResponseResult_t.
@@ -316,6 +325,40 @@ OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri,
  */
 void OCDeleteResourceAttributes(OCAttribute *rsrcAttributes);
 
+#ifndef TCP_ADAPTER
+/**
+ * Add resource payload with endpoint payload to discovery payload.
+ *
+ * @param payload       Pointer to discovery payload.
+ * @param res           Pointer to OCresource structure.
+ * @param securePort    Secure port number.
+ * @param isVirtual     true: virtual resource (e.g., oic/res), false: resource.
+ * @param networkInfo   List of CAEndpoint_t.
+ * @param infoSize      Size of CAEndpoint_t list.
+ * @param devAddr       Pointer to OCDevAddr structure.
+ */
+void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload *payload, const OCResource *res,
+                                          uint16_t securePort, bool isVirtual,
+                                          void *networkInfo, uint32_t infoSize,
+                                          const OCDevAddr *devAddr);
+#else
+/**
+ * Add resource payload with endpoint payload to discovery payload.
+ *
+ * @param payload       Pointer to discovery payload.
+ * @param res           Pointer to OCresource structure.
+ * @param securePort    Secure port number.
+ * @param isVirtual     true: virtual resource (e.g., oic/res, oic/d), false: resource.
+ * @param networkInfo   List of CAEndpoint_t.
+ * @param infoSize      Size of CAEndpoint_t list.
+ * @param devAddr       Pointer to OCDevAddr structure.
+ * @param tcpPort       TCP port number.
+ */
+void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload *payload, const OCResource *res,
+                                          uint16_t securePort, bool isVirtual,
+                                          void *networkInfo, uint32_t infoSize,
+                                          const OCDevAddr *devAddr, uint16_t tcpPort);
+#endif
 #ifdef __cplusplus
 }
 #endif // __cplusplus
index 0c534e9..6b52fe5 100644 (file)
@@ -240,12 +240,21 @@ void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource
 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
                                    uint16_t securePort, uint16_t tcpPort);
 #endif
-void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res);
+void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload,
+                                      OCResourcePayload* res);
 bool OCResourcePayloadAddStringLL(OCStringLL **payload, const char* type);
 
 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload);
-OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index);
+OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload,
+                                                 size_t index);
 
+size_t OCEndpointPayloadGetEndpointCount(OCEndpointPayload* payload);
+OCEndpointPayload* OCEndpointPayloadGetEndpoint(OCEndpointPayload* payload,
+                                                size_t index);
+
+void OCResourcePayloadAddNewEndpoint(OCResourcePayload* payload,
+                                     OCEndpointPayload* endpoint);
+void OCDiscoveryEndpointDestroy(OCEndpointPayload* payload);
 void OCDiscoveryResourceDestroy(OCResourcePayload* payload);
 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload);
 
index 56f7337..61aecda 100644 (file)
@@ -288,6 +288,47 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
                                uint8_t resourceProperties);
 
 /**
+ * This function creates a resource.
+ *
+ * @param handle                Pointer to handle to newly created resource. Set by ocstack and
+ *                              used to refer to resource.
+ * @param resourceTypeName      Name of resource type.  Example: "core.led".
+ * @param resourceInterfaceName Name of resource interface.  Example: "core.rw".
+ * @param uri                   URI of the resource.  Example:  "/a/led".
+ * @param entityHandler         Entity handler function that is called by ocstack to handle
+ *                              requests, etc.
+ *                              NULL for default entity handler.
+ * @param callbackParam         parameter passed back when entityHandler is called.
+ * @param resourceProperties    Properties supported by resource.
+ *                              Example: ::OC_DISCOVERABLE|::OC_OBSERVABLE.
+ * @param resourceTpsTypes      Transport Protocol Suites(TPS) types of resource for expose
+                                resource to specific transport adapter (e.g., TCP, UDP)
+                                with messaging protocol (e.g., COAP, COAPS).
+                                Example: "OC_COAP | OC_COAP_TCP"
+ *
+ * @note Only supported TPS types on stack will be mapped to resource.
+         It means "OC_COAPS" and "OC_COAPS_TCP" flags will be ignored if secure option
+         not enabled on stack. Also "COAP_TCP" and "COAPS_TCP" flags will be ignored
+         if stack does not support tcp mode.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCCreateResourceWithEp(OCResourceHandle *handle,
+                                     const char *resourceTypeName,
+                                     const char *resourceInterfaceName,
+                                     const char *uri,
+                                     OCEntityHandler entityHandler,
+                                     void *callbackParam,
+                                     uint8_t resourceProperties,
+                                     OCTpsSchemeFlags resourceTpsTypes);
+/*
+ * This function returns flags of supported endpoint TPS on stack.
+ *
+ * @return Bit combinations of supported OCTpsSchemeFlags.
+ */
+OCTpsSchemeFlags OCGetSupportedEndpointTpsFlags();
+
+/**
  * This function adds a resource to a collection resource.
  *
  * @param collectionHandle    Handle to the collection resource.
index bd1d5a7..4c26bf7 100644 (file)
@@ -998,6 +998,9 @@ typedef enum
     OC_STACK_AUTHENTICATION_FAILURE,
     OC_STACK_NOT_ALLOWED_OXM,
 
+    /** Request come from endpoint which is not mapped to the resource. */
+    OC_STACK_BAD_ENDPOINT,
+
     /** Insert all new error codes here!.*/
 #ifdef WITH_PRESENCE
     OC_STACK_PRESENCE_STOPPED = 128,
index 1b81907..39914ce 100644 (file)
@@ -174,7 +174,7 @@ INLINE_API void OCPayloadLogRepValues(LogLevel level, OCRepPayloadValue* val)
 INLINE_API void OCPayloadLogRep(LogLevel level, OCRepPayload* payload)
 {
     OIC_LOG(level, (PL_TAG), "Payload Type: Representation");
-    int i = 1;
+    uint32_t i = 1;
     for (OCRepPayload* rep = payload; rep; rep = rep->next, ++i)
     {
         OIC_LOG_V(level, PL_TAG, "\tResource #%d", i);
@@ -237,7 +237,7 @@ INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payloa
 
         OCResourcePayload* res = payload->resources;
 
-        int i = 1;
+        uint32_t i = 1;
         while(res)
         {
             OIC_LOG_V(level, PL_TAG, "\tResource #%d", i);
@@ -260,6 +260,20 @@ INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payloa
             OIC_LOG_V(level, PL_TAG, "\tBitmap: %u", res->bitmap);
             OIC_LOG_V(level, PL_TAG, "\tSecure?: %s", res->secure ? "true" : "false");
             OIC_LOG_V(level, PL_TAG, "\tPort: %u", res->port);
+
+            uint32_t j = 1;
+            OCEndpointPayload* eps = res->eps;
+            while (eps)
+            {
+                OIC_LOG_V(level, PL_TAG, "\tEndpoint #%d", j);
+                OIC_LOG_V(level, PL_TAG, "\t\ttps: %s", eps->tps);
+                OIC_LOG_V(level, PL_TAG, "\t\taddr: %s", eps->addr);
+                OIC_LOG_V(level, PL_TAG, "\t\tport: %d", eps->port);
+                OIC_LOG_V(level, PL_TAG, "\t\tpri: %d", eps->pri);
+                eps = eps->next;
+                ++j;
+            }
+
             OIC_LOG(level, PL_TAG, "");
             res = res->next;
             ++i;
index 020be7c..e2e7cf8 100644 (file)
@@ -59,7 +59,10 @@ if target_os not in ['windows']:
        samples_env.PrependUnique(LIBS = ['m'])
 
 if samples_env.get('SECURED') == '1':
-    samples_env.AppendUnique(LIBS = ['tinydtls'])
+       samples_env.AppendUnique(LIBS = ['tinydtls'])
+
+if target_os in ['windows']:
+       samples_env.AppendUnique(LIBS = ['ws2_32'])
 
 samples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
index 91e445a..f8d58db 100644 (file)
@@ -140,6 +140,12 @@ static void PrintUsage()
             "add  vendor specific header options");
     OIC_LOG(INFO, TAG, "-t 19 :  Discover Platform");
     OIC_LOG(INFO, TAG, "-t 20 :  Discover Devices");
+    OIC_LOG(INFO, TAG, "-t 21 :  Discover Resources and Display endpoints of the server information");
+    OIC_LOG(INFO, TAG, "-t 22 :  Discover Resources and Perform Get Requests by IPv4 + COAP + UDP "\
+            "using server's endpoints information");
+    OIC_LOG(INFO, TAG, "-t 23 :  Discover Resources and Perform Get Requests by IPv4 + COAP + TCP "\
+            "using server's endpoints information");
+
 }
 
 OCStackResult InvokeOCDoResource(std::ostringstream &query,
@@ -473,6 +479,15 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle /*handle*/,
             case TEST_DISCOVER_DEV_REQ:
                 InitDeviceDiscovery(OC_LOW_QOS);
                 break;
+            case TEST_DISCOVER_REQ_SHOW_EPS:
+                showEndpointsInfo(resource);
+                break;
+            case TEST_GET_REQ_UDP:
+                InitGetRequestWithCoap(payload, true);
+                break;
+            case TEST_GET_REQ_TCP:
+                InitGetRequestWithCoap(payload, false);
+                break;
             default:
                 PrintUsage();
                 break;
@@ -812,6 +827,98 @@ int InitDiscovery(OCQualityOfService qos)
     return ret;
 }
 
+int InitGetRequestWithCoap(OCDiscoveryPayload* dis, bool isUdp)
+{
+    if (!dis)
+    {
+        OIC_LOG(INFO, TAG, "Given payload is NULL!!!");
+        return -1;
+    }
+
+    // copy query
+    std::ostringstream query;
+    query << coapServerResource;
+
+    // server addr
+    OCDevAddr dev;
+
+    // find endpoint with ipv4, UDP or TCP
+    OCResourcePayload* res = dis->resources;
+    while (res)
+    {
+        OCEndpointPayload* eps = res->eps;
+        while (eps)
+        {
+            if (strcmp(eps->tps, (isUdp ? COAP_UDP : COAP_TCP)) == 0 &&
+                strlen(eps->addr) < MAX_LENGTH_IPv4_ADDR)
+            {
+                OIC_LOG_V(INFO, TAG, "%s found!!!", (isUdp ? COAP_UDP : COAP_TCP));
+                dev.adapter = (isUdp ? OC_ADAPTER_IP : OC_ADAPTER_TCP);
+                dev.flags = OC_IP_USE_V4;
+                dev.port = eps->port;
+                memcpy(dev.addr, eps->addr, sizeof(dev.addr));
+            }
+            eps = eps->next;
+        }
+        res = res->next;
+    }
+
+    if (dev.adapter == (isUdp ? OC_ADAPTER_IP : OC_ADAPTER_TCP) && dev.flags == OC_IP_USE_V4)
+    {
+        OIC_LOG_V(INFO, TAG, "dev addr is %s", dev.addr);
+        OIC_LOG_V(INFO, TAG, "dev port is %d", dev.port);
+        OIC_LOG_V(INFO, TAG, "dev flags is %d", dev.flags);
+        OIC_LOG_V(INFO, TAG, "dev adapter is %d", dev.adapter);
+
+        // send ocdoresource
+        return (InvokeOCDoResource(query, &dev, OC_REST_GET,
+                OC_LOW_QOS, getReqCB, NULL, 0));
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "Endpoints infomation not found on given payload!!!");
+        return -1;
+    }
+}
+
+void showEndpointsInfo(OCResourcePayload* res)
+{
+    if (!res)
+    {
+        OIC_LOG(INFO, TAG, "No endpoints information in given payload");
+        return;
+    }
+
+    if (!res->eps)
+    {
+        OIC_LOG(INFO, TAG, "No endpoints information in given payload");
+        return;
+    }
+
+    OCEndpointPayload* eps = res->eps;
+
+    while (eps)
+    {
+        if (eps->family == OC_IP_USE_V6)
+        {
+            OIC_LOG_V(INFO, TAG, "Resource [%s] has endpoint [%s://[%s]:%d]",
+                      res->uri, eps->tps, eps->addr, eps->port);
+        }
+        else if (eps->family == OC_IP_USE_V4)
+        {
+            OIC_LOG_V(INFO, TAG, "Resource [%s] has endpoint [%s://%s:%d]",
+                      res->uri, eps->tps, eps->addr, eps->port);
+        }
+        else
+        {
+            OIC_LOG_V(INFO, TAG, "Resource [%s] has endpoint [%s://%s]",
+                      res->uri, eps->tps, eps->addr);
+        }
+
+        eps = eps->next;
+    }
+}
+
 int main(int argc, char* argv[])
 {
     int opt;
index 10d0c85..dfe3acb 100644 (file)
@@ -28,6 +28,8 @@
 // Defines
 //-----------------------------------------------------------------------------
 #define TAG "occlient"
+#define COAP_UDP "coap"
+#define COAP_TCP "coap+tcp"
 #define DEFAULT_CONTEXT_VALUE 0x99
 #ifndef MAX_LENGTH_IPv4_ADDR
 #define MAX_LENGTH_IPv4_ADDR 16
@@ -63,6 +65,9 @@ typedef enum {
     TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS,
     TEST_DISCOVER_PLATFORM_REQ,
     TEST_DISCOVER_DEV_REQ,
+    TEST_DISCOVER_REQ_SHOW_EPS,
+    TEST_GET_REQ_UDP,
+    TEST_GET_REQ_TCP,
     MAX_TESTS
 } CLIENT_TEST;
 
@@ -94,8 +99,11 @@ std::string getIPAddrTBServer(OCClientResponse * clientResponse);
 /* Get the port number the server is listening on */
 std::string getPortTBServer(OCClientResponse * clientResponse);
 
+/* Show endpoints information in given resource payload */
+void showEndpointsInfo(OCResourcePayload* res);
+
 /* Following are initialization functions for GET, Observe, PUT
- * POST, Delete & Discovery operations
+ * POST, Delete & Discovery, Get with coap, get with coap+tcp operations
  */
 int InitGetRequestToUnavailableResource(OCQualityOfService qos);
 int InitObserveRequest(OCQualityOfService qos);
@@ -107,6 +115,7 @@ int InitGetRequest(OCQualityOfService qos);
 int InitDeviceDiscovery(OCQualityOfService qos);
 int InitPlatformDiscovery(OCQualityOfService qos);
 int InitDiscovery(OCQualityOfService qos);
+int InitGetRequestWithCoap(OCDiscoveryPayload* dis, bool isUdp);
 
 /* Call delete operation on already deleted resource */
 void* RequestDeleteDeathResourceTask(void* myqos);
index da6a9ee..53d191a 100644 (file)
 #include "ocpayload.h"
 #include "ocserver.h"
 #include "common.h"
+#include "oic_string.h"
 
 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
 // 9 + 9 + 1 = 19
 const int URI_MAXSIZE = 19;
 
 static int gObserveNotifyType = 3;
+static int gResourceCreateType = ENDPOINT_OPT_NONE;
 
 int gQuitFlag = 0;
 int gLightUnderObservation = 0;
@@ -827,13 +829,41 @@ int createLightResource (char *uri, LightResource *lightResource)
 
     lightResource->state = false;
     lightResource->power= 0;
-    OCStackResult res = OCCreateResource(&(lightResource->handle),
+    OCTpsSchemeFlags endpointFlags = OC_NO_TPS;
+    switch (gResourceCreateType)
+    {
+        case DISPLAY_SUPPORTED_EPS_FLAG:
+        case CREATE_RESOURCE_OC_ALL:
+        // same as OCCreateResource(args...)
+        endpointFlags = OC_ALL;
+        break;
+
+        case CREATE_RESOURCE_OC_COAP:
+        endpointFlags = OC_COAP;
+        break;
+
+#ifdef TCP_ADAPTER
+        case CREATE_RESOURCE_OC_COAP_TCP:
+        endpointFlags = OC_COAP_TCP;
+        break;
+
+        case CREATE_RESOURCE_OC_COAP_WITH_TCP:
+        endpointFlags = (OCTpsSchemeFlags)(OC_COAP | OC_COAP_TCP);
+        break;
+#endif
+        default:
+        endpointFlags = OC_ALL;
+    }
+
+    OCStackResult res = OCCreateResourceWithEp(&(lightResource->handle),
             "core.light",
             "oc.mi.def",
             uri,
             OCEntityHandlerCb,
             NULL,
-            OC_DISCOVERABLE|OC_OBSERVABLE);
+            OC_DISCOVERABLE|OC_OBSERVABLE,
+            endpointFlags);
+
     OIC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
 
     return 0;
@@ -986,6 +1016,13 @@ static void PrintUsage()
     OIC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
     OIC_LOG(INFO, TAG, "-o 0 : Notify all observers");
     OIC_LOG(INFO, TAG, "-o 1 : Notify list of observers");
+    OIC_LOG(INFO, TAG, "-e 0 : Display supported endpoint flags");
+    OIC_LOG(INFO, TAG, "-e 1 : Create resource without endpoint flags");
+    OIC_LOG(INFO, TAG, "-e 2 : Create resource with endpoint flag OC_COAP");
+#ifdef TCP_ADAPTER
+    OIC_LOG(INFO, TAG, "-e 3 : Create resource with endpoint flag OC_COAP_TCP");
+    OIC_LOG(INFO, TAG, "-e 4 : Create resource with endpoint flag OC_COAP | OC_COAP_TCP");
+#endif
 }
 
 #ifdef RA_ADAPTER
@@ -1016,13 +1053,16 @@ int main(int argc, char* argv[])
 #endif
 
     int opt = 0;
-    while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1)
+    while ((opt = getopt(argc, argv, "o:e:s:p:d:u:w:r:j:")) != -1)
     {
         switch(opt)
         {
             case 'o':
                 gObserveNotifyType = atoi(optarg);
                 break;
+            case 'e':
+                gResourceCreateType = atoi(optarg);
+                break;
 #ifdef RA_ADAPTER
             case 's':
                 rainfo.hostname = optarg;
@@ -1052,7 +1092,15 @@ int main(int argc, char* argv[])
         }
     }
 
-    if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
+    if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1) &&
+         gResourceCreateType == ENDPOINT_OPT_NONE)
+    {
+        PrintUsage();
+        return -1;
+    }
+
+    if (gResourceCreateType < DISPLAY_SUPPORTED_EPS_FLAG ||
+        gResourceCreateType > ENDPOINT_OPT_NONE)
     {
         PrintUsage();
         return -1;
@@ -1077,6 +1125,39 @@ int main(int argc, char* argv[])
     }
 #endif
 
+    if (DISPLAY_SUPPORTED_EPS_FLAG == gResourceCreateType)
+    {
+        char strBuff[SAMPLE_MAX_STR_BUFF_SIZE] = {0};
+        OCTpsSchemeFlags deviceFlags = OCGetSupportedEndpointTpsFlags();
+
+        if (deviceFlags & OC_COAP)
+        {
+            OICStrcat(strBuff, sizeof(strBuff), "OC_COAP");
+        }
+        if (deviceFlags & OC_COAPS)
+        {
+            OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS");
+        }
+#ifdef TCP_ADAPTER
+        if (deviceFlags & OC_COAP_TCP)
+        {
+            OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_TCP");
+        }
+        if (deviceFlags & OC_COAPS_TCP)
+        {
+            OICStrcat(strBuff, sizeof(strBuff), ", OC_COAPS_TCP");
+        }
+#endif
+#ifdef EDR_ADAPTER
+        if (deviceFlags & OC_COAP_RFCOMM)
+        {
+            OICStrcat(strBuff, sizeof(strBuff), ", OC_COAP_RFCOMM");
+        }
+#endif
+        OIC_LOG_V(INFO, TAG, "Endpoint flag %s is supported", strBuff);
+        return 0;
+    }
+
     OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
 
     OCStackResult registrationResult =
index 8c87326..f07ee8f 100644 (file)
@@ -29,6 +29,7 @@
 #define TAG "ocserver"
 #define SAMPLE_MAX_NUM_OBSERVATIONS     8
 #define SAMPLE_MAX_NUM_POST_INSTANCE  2
+#define SAMPLE_MAX_STR_BUFF_SIZE  100
 
 //-----------------------------------------------------------------------------
 // Typedefs
@@ -50,6 +51,15 @@ typedef struct
     OCResourceHandle resourceHandle;
 } Observers;
 
+typedef enum
+{
+    DISPLAY_SUPPORTED_EPS_FLAG        = 0,
+    CREATE_RESOURCE_OC_ALL,
+    CREATE_RESOURCE_OC_COAP,
+    CREATE_RESOURCE_OC_COAP_TCP,
+    CREATE_RESOURCE_OC_COAP_WITH_TCP,
+    ENDPOINT_OPT_NONE
+} EndpointOption;
 //-----------------------------------------------------------------------------
 // Function prototype
 //-----------------------------------------------------------------------------
index 6a5e7b0..10b53b0 100644 (file)
@@ -384,7 +384,7 @@ exit:
 
 OCTpsSchemeFlags OCGetSupportedTpsFlags()
 {
-    OCTpsSchemeFlags ret = (OCTpsSchemeFlags)0;
+    OCTpsSchemeFlags ret = OC_NO_TPS;
     CATransportAdapter_t SelectedNetwork = CAGetSelectedNetwork();
 
     if (SelectedNetwork & CA_ADAPTER_IP)
@@ -397,7 +397,7 @@ OCTpsSchemeFlags OCGetSupportedTpsFlags()
         }
     }
 #ifdef TCP_ADAPTER
-    else if (SelectedNetwork & CA_ADAPTER_TCP)
+    if (SelectedNetwork & CA_ADAPTER_TCP)
     {
         ret = (OCTpsSchemeFlags)(ret | OC_COAP_TCP);
 
@@ -408,7 +408,7 @@ OCTpsSchemeFlags OCGetSupportedTpsFlags()
     }
 #endif
 #ifdef EDR_ADAPTER
-    else if (SelectedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
+    if (SelectedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
     {
         ret = (OCTpsSchemeFlags)(ret | OC_COAP_RFCOMM);
     }
index 6958938..a0554b7 100644 (file)
@@ -31,6 +31,8 @@
 #include "ocstackinternal.h"
 #include "ocresource.h"
 #include "logger.h"
+#include "ocendpoint.h"
+#include "cacommon.h"
 
 #define TAG "OIC_RI_PAYLOAD"
 #define CSV_SEPARATOR ','
@@ -1672,11 +1674,63 @@ OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, si
     return NULL;
 }
 
+size_t OCEndpointPayloadGetEndpointCount(OCEndpointPayload* payload)
+{
+    size_t i = 0;
+    OCEndpointPayload* ep = payload;
+    while (ep)
+    {
+        ++i;
+        ep = ep->next;
+    }
+    return i;
+}
+
+OCEndpointPayload* OCEndpointPayloadGetEndpoint(OCEndpointPayload* payload, size_t index)
+{
+    size_t i = 0;
+    OCEndpointPayload* ep = payload;
+    while (ep)
+    {
+        if (i == index)
+        {
+            return ep;
+        }
+        ++i;
+        ep = ep->next;
+    }
+    return NULL;
+}
+
+void OCResourcePayloadAddNewEndpoint(OCResourcePayload* payload, OCEndpointPayload* endpoint)
+{
+    if (!payload)
+    {
+        return;
+    }
+
+    if (!payload->eps)
+    {
+        payload->eps = endpoint;
+    }
+    else
+    {
+        OCEndpointPayload* ep = payload->eps;
+        while (ep->next)
+        {
+            ep = ep->next;
+        }
+        ep->next = endpoint;
+    }
+}
+
+static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
+                                         bool isVirtual, CAEndpoint_t *networkInfo,
+                                         uint32_t infoSize, const OCDevAddr *devAddr
 #ifndef TCP_ADAPTER
-static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
+                                                                                    )
 #else
-static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
-                                         uint16_t tcpPort)
+                                         , uint16_t tcpPort)
 #endif
 {
     OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
@@ -1780,6 +1834,84 @@ static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t secureP
 #ifdef TCP_ADAPTER
     pl->tcpPort = tcpPort;
 #endif
+
+    if (isVirtual || !networkInfo || infoSize == 0 || !devAddr)
+    {
+        pl->eps = NULL;
+    }
+    else
+    {
+        OCEndpointPayload *lastNode = pl->eps;
+        if ((OC_ADAPTER_IP | OC_ADAPTER_TCP) & (devAddr->adapter))
+        {
+            for (uint32_t i = 0; i < infoSize; i++)
+            {
+                CAEndpoint_t *info = networkInfo + i;
+
+                if (info)
+                {
+                    if (((CA_ADAPTER_IP | CA_ADAPTER_TCP) & info->adapter &&
+                        info->ifindex == devAddr->ifindex) ||
+                        info->adapter == CA_ADAPTER_RFCOMM_BTEDR)
+                    {
+                        OCTpsSchemeFlags matchedTps = OC_NO_TPS;
+                        if (OC_STACK_OK != OCGetMatchedTpsFlags(info->adapter,
+                                                                info->flags,
+                                                                &matchedTps))
+                        {
+                            return NULL;
+                        }
+
+                        if ((res->endpointType) & matchedTps)
+                        {
+                            // create payload
+                            OCEndpointPayload* tmpNode = (OCEndpointPayload*)
+                                                          OICCalloc(1, sizeof(OCEndpointPayload));
+                            if (!tmpNode)
+                            {
+                                return NULL;
+                            }
+
+                            OCStackResult ret = OCConvertTpsToString(matchedTps, &(tmpNode->tps));
+                            if (ret != OC_STACK_OK)
+                            {
+                                OCDiscoveryEndpointDestroy(tmpNode);
+                                OCDiscoveryResourceDestroy(pl);
+                                return NULL;
+                            }
+
+                            tmpNode->addr = (char*)OICCalloc(MAX_ADDR_STR_SIZE, sizeof(char));
+                            if (!tmpNode->addr)
+                            {
+                                OCDiscoveryEndpointDestroy(tmpNode);
+                                OCDiscoveryResourceDestroy(pl);
+                                return NULL;
+                            }
+
+                            memcpy(tmpNode->addr, info->addr, sizeof(info->addr));
+                            tmpNode->family = (OCTransportFlags)(info->flags);
+                            tmpNode->port = info->port;
+                            tmpNode->pri  = 1;
+                            tmpNode->next = NULL;
+
+                            // store in list
+                            if (!pl->eps)
+                            {
+                                pl->eps = tmpNode;
+                                lastNode = tmpNode;
+                            }
+                            else
+                            {
+                                lastNode->next = tmpNode;
+                                lastNode = tmpNode;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     return pl;
 }
 
@@ -1787,13 +1919,37 @@ static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t secureP
 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
                                    uint16_t securePort)
 {
-    OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
+    OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, false, NULL, 0, NULL));
 }
 #else
 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
                                    uint16_t securePort, uint16_t tcpPort)
 {
-    OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
+    OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, false, NULL, 0, NULL, tcpPort));
+}
+#endif
+
+#ifndef TCP_ADAPTER
+void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload* payload, const OCResource* res,
+                                          uint16_t securePort, bool isVirtual,
+                                          void *networkInfo, uint32_t infoSize,
+                                          const OCDevAddr *devAddr)
+{
+    OCDiscoveryPayloadAddNewResource(payload,
+                                     OCCopyResource(res, securePort, isVirtual,
+                                                    (CAEndpoint_t *)networkInfo,
+                                                    infoSize, devAddr));
+}
+#else
+void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload* payload, const OCResource* res,
+                                          uint16_t securePort, bool isVirtual,
+                                          void *networkInfo, uint32_t infoSize,
+                                          const OCDevAddr *devAddr, uint16_t tcpPort)
+{
+    OCDiscoveryPayloadAddNewResource(payload,
+                                     OCCopyResource(res, securePort, isVirtual,
+                                                    (CAEndpoint_t *)networkInfo,
+                                                    infoSize, devAddr, tcpPort));
 }
 #endif
 
@@ -1850,6 +2006,19 @@ void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePay
     }
 }
 
+void OCDiscoveryEndpointDestroy(OCEndpointPayload* payload)
+{
+    if (!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->tps);
+    OICFree(payload->addr);
+    OCDiscoveryEndpointDestroy(payload->next);
+    OICFree(payload);
+}
+
 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
 {
     if (!payload)
@@ -1860,9 +2029,9 @@ void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
     OICFree(payload->uri);
     OCFreeOCStringLL(payload->types);
     OCFreeOCStringLL(payload->interfaces);
+    OCDiscoveryEndpointDestroy(payload->eps);
     OCDiscoveryResourceDestroy(payload->next);
     OICFree(payload);
-
 }
 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
 {
index 69a928e..af183b7 100644 (file)
 #include "ocrandom.h"
 #include "ocresourcehandler.h"
 #include "cbor.h"
+#include "ocendpoint.h"
 
 #define TAG "OIC_RI_PAYLOADCONVERT"
 
 // Arbitrarily chosen size that seems to contain the majority of packages
 #define INIT_SIZE (255)
 
-// Discovery Links Map Length.
-#define LINKS_MAP_LEN 4
+// Discovery Links Map with endpoints Length.
+#define LINKS_MAP_LEN_WITH_EPS (5)
+
+// Discovery Links Map without endpoints Length.
+#define LINKS_MAP_LEN_WITHOUT_EPS (4)
+
+// Endpoint Map length, it contains "ep", "pri".
+#define EP_MAP_LEN (2)
 
 // Functions all return either a CborError, or a negative version of the OC_STACK return values
 static int64_t OCConvertPayloadHelper(OCPayload *payload, uint8_t *outPayload, size_t *size);
@@ -226,10 +233,10 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o
             "di": "0685B960-736F-46F7-BEC0-9E6CBD61ADC1",
             links :[                                   // linksArray contains maps of resources
                         {
-                            href, rt, if, policy       // Resource 1
+                            href, rt, if, policy, eps  // Resource 1
                         },
                         {
-                            href, rt, if, policy       // Resource 2
+                            href, rt, if, policy, eps  // Resource 2
                         },
                         .
                         .
@@ -296,8 +303,16 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o
             VERIFY_PARAM_NON_NULL(TAG, resource, "Failed retrieving resource");
 
             // resource map inside the links array.
-            err |= cbor_encoder_create_map(&linkArray, &linkMap, LINKS_MAP_LEN);
-            VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map");
+            if (resource->eps)
+            {
+                err |= cbor_encoder_create_map(&linkArray, &linkMap, LINKS_MAP_LEN_WITH_EPS);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map");
+            }
+            else
+            {
+                err |= cbor_encoder_create_map(&linkArray, &linkMap, LINKS_MAP_LEN_WITHOUT_EPS);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map");
+            }
 
             // Below are insertions of the resource properties into the map.
             // Uri
@@ -358,10 +373,52 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o
             err |= cbor_encode_uint(&policyMap, resource->tcpPort);
             VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port value");
 #endif
-
             err |= cbor_encoder_close_container(&linkMap, &policyMap);
             VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing policy map");
 
+            // Endpoints
+            size_t epsCount = OCEndpointPayloadGetEndpointCount(resource->eps);
+
+            // Embed Endpoints in discovery response when any endpoint exist on the resource.
+            if (epsCount > 0)
+            {
+                CborEncoder epsArray;
+                err |= cbor_encode_text_string(&linkMap, OC_RSRVD_ENDPOINTS,
+                                                         sizeof(OC_RSRVD_ENDPOINTS) - 1);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting endpoints array tag");
+
+                err |= cbor_encoder_create_array(&linkMap, &epsArray, epsCount);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting endpoints array");
+
+                for (size_t i = 0; i < epsCount; ++i)
+                {
+                    CborEncoder endpointMap;
+                    OCEndpointPayload* endpoint = OCEndpointPayloadGetEndpoint(resource->eps, i);
+                    VERIFY_PARAM_NON_NULL(TAG, endpoint, "Failed retrieving endpoint");
+
+                    char* endpointStr = OCCreateEndpointString(endpoint);
+                    VERIFY_PARAM_NON_NULL(TAG, endpointStr, "Failed creating endpoint string");
+
+                    err |= cbor_encoder_create_map(&epsArray, &endpointMap, EP_MAP_LEN);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating endpoint map");
+
+                    err |= AddTextStringToMap(&endpointMap, OC_RSRVD_ENDPOINT,
+                                              sizeof(OC_RSRVD_ENDPOINT) - 1, endpointStr);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding endpoint to endpoint map");
+
+                    err |= cbor_encode_text_string(&endpointMap, OC_RSRVD_PRIORITY,
+                                                   sizeof(OC_RSRVD_PRIORITY) - 1);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding priority tag to endpoint map");
+                    err |= cbor_encode_uint(&endpointMap, endpoint->pri);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding priority value to endpoint map");
+
+                    err |= cbor_encoder_close_container(&epsArray, &endpointMap);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing endpoint map");
+                }
+
+                err |= cbor_encoder_close_container(&linkMap, &epsArray);
+                VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing endpoints map");
+            }
             // Finsihed encoding a resource, close the map.
             err |= cbor_encoder_close_container(&linkArray, &linkMap);
             VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link map");
index 3366fc2..44d5588 100644 (file)
@@ -36,6 +36,7 @@
 #include "ocstackinternal.h"
 #include "payload_logging.h"
 #include "platform_features.h"
+#include "ocendpoint.h"
 
 #define TAG "OIC_RI_PAYLOADPARSE"
 
@@ -175,6 +176,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
     OCDiscoveryPayload *temp = NULL;
     OCDiscoveryPayload *rootPayload = NULL;
     OCDiscoveryPayload *curPayload = NULL;
+    OCEndpointPayload *endpoint = NULL;
     size_t len = 0;
     CborError err = CborNoError;
     *outPayload = NULL;
@@ -345,6 +347,64 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
                     resource->tcpPort = (uint16_t)tcpPort;
                 }
 #endif
+                // Endpoints
+                CborValue epsMap;
+                err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_ENDPOINTS, &epsMap);
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find eps tag");
+
+                if (cbor_value_is_valid(&epsMap))
+                {
+                    CborValue epMap;
+                    err = cbor_value_enter_container(&epsMap, &epMap);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "to enter endpoint map");
+
+                    while (cbor_value_is_map(&epMap))
+                    {
+                        endpoint = NULL;
+                        int pri = 0;
+                        char *endpointStr = NULL;
+                        OCStackResult ret = OC_STACK_ERROR;
+                        endpoint = (OCEndpointPayload *)OICCalloc(1, sizeof(OCEndpointPayload));
+                        VERIFY_PARAM_NON_NULL(TAG, endpoint, "Failed allocating endpoint payload");
+
+                        // ep
+                        err = cbor_value_map_find_value(&epMap, OC_RSRVD_ENDPOINT, &curVal);
+                        VERIFY_CBOR_SUCCESS(TAG, err, "to find endpoint tag");
+                        err = cbor_value_dup_text_string(&curVal, &endpointStr, &len, NULL);
+                        VERIFY_CBOR_SUCCESS(TAG, err, "to find endpoint value");
+
+                        ret = OCParseEndpointString(endpointStr, endpoint);
+                        OICFree(endpointStr);
+
+                        if (OC_STACK_OK == ret)
+                        {
+                            // pri
+                            err = cbor_value_map_find_value(&epMap, OC_RSRVD_PRIORITY, &curVal);
+                            VERIFY_CBOR_SUCCESS(TAG, err, "to find priority tag");
+                            err = cbor_value_get_int(&curVal, &pri);
+                            VERIFY_CBOR_SUCCESS(TAG, err, "to find priority value");
+                            endpoint->pri = (uint16_t)pri;
+                            OCResourcePayloadAddNewEndpoint(resource, endpoint);
+                            endpoint = NULL;
+                        }
+                        else
+                        {
+                            if (OC_STACK_ADAPTER_NOT_ENABLED == ret)
+                            {
+                                OIC_LOG(ERROR, TAG, "Ignore unrecognized endpoint info");
+                            }
+                            // destroy endpoint
+                            OCDiscoveryEndpointDestroy(endpoint);
+                            endpoint = NULL;
+                        }
+
+                        err = cbor_value_advance(&epMap);
+                        VERIFY_CBOR_SUCCESS(TAG, err, "to advance endpoint map");
+                    }
+
+                    err = cbor_value_leave_container(&epsMap, &epMap);
+                    VERIFY_CBOR_SUCCESS(TAG, err, "to leave eps map");
+                }
 
                 err = cbor_value_advance(&resourceMap);
                 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
@@ -386,6 +446,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
     return OC_STACK_OK;
 
 exit:
+    OCDiscoveryEndpointDestroy(endpoint);
     OCDiscoveryResourceDestroy(resource);
     OCDiscoveryPayloadDestroy(rootPayload);
     return ret;
index a987b29..7a002e3 100755 (executable)
@@ -52,6 +52,9 @@
 #include "ocpayload.h"
 #include "platform_features.h"
 #include "payload_logging.h"
+#include "ocendpoint.h"
+#include "ocstackinternal.h"
+
 #ifdef ROUTING_GATEWAY
 #include "routingmanager.h"
 #endif
@@ -68,8 +71,10 @@ extern OCResource *headResource;
  * Prepares a Payload for response.
  */
 static OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
-                                                  OCDiscoveryPayload* payload,
-                                                  OCDevAddr *endpoint);
+                                                  OCDiscoveryPayload *payload,
+                                                  OCDevAddr *endpoint,
+                                                  CAEndpoint_t *networkInfo,
+                                                  uint32_t infoSize);
 
 //-----------------------------------------------------------------------------
 // Default resource entity handler function
@@ -420,9 +425,12 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
 }
 
 OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
-                        OCDiscoveryPayload *payload, OCDevAddr *devAddr)
+                                           OCDiscoveryPayload *payload,
+                                           OCDevAddr *devAddr,
+                                           CAEndpoint_t *networkInfo,
+                                           uint32_t infoSize)
 {
-    if (!resourcePtr || !payload)
+    if (!resourcePtr || !payload || !networkInfo)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -435,15 +443,22 @@ OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
        }
     }
 
+    bool isVirtual = false;
+    if (GetTypeOfVirtualURI(resourcePtr->uri) != OC_UNKNOWN_URI)
+    {
+        isVirtual = true;
+    }
 #ifdef TCP_ADAPTER
     uint16_t tcpPort = 0;
     if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK)
     {
         tcpPort = 0;
     }
-    OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort);
+    OCDiscoveryPayloadAddResourceWithEps(payload, resourcePtr, securePort,
+                                         isVirtual, networkInfo, infoSize, devAddr, tcpPort);
 #else
-    OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort);
+    OCDiscoveryPayloadAddResourceWithEps(payload, resourcePtr, securePort,
+                                         isVirtual, networkInfo, infoSize, devAddr);
 #endif
 
     return OC_STACK_OK;
@@ -484,6 +499,37 @@ OCResource *FindResourceByUri(const char* resourceUri)
     return NULL;
 }
 
+OCStackResult CheckRequestsEndpoint(const OCDevAddr *reqDevAddr,
+                                    OCTpsSchemeFlags resTpsFlags)
+{
+    if (!reqDevAddr)
+    {
+        OIC_LOG(ERROR, TAG, "OCDevAddr* is NULL!!!");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCTpsSchemeFlags reqTpsFlags = OC_NO_TPS;
+    OCStackResult result = OCGetMatchedTpsFlags((CATransportAdapter_t)reqDevAddr->adapter,
+                                  (CATransportFlags_t)reqDevAddr->flags, &reqTpsFlags);
+
+    if (result != OC_STACK_OK)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed at get TPS flags. errcode is %d", result);
+        return result;
+    }
+
+    // bit compare between request tps flags and resource tps flags
+    if (reqTpsFlags & resTpsFlags)
+    {
+        OIC_LOG(INFO, TAG, "Request come from registered TPS");
+        return OC_STACK_OK;
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "Request come from unregistered TPS!!!");
+        return OC_STACK_BAD_ENDPOINT;
+    }
+}
 
 OCStackResult DetermineResourceHandling (const OCServerRequest *request,
                                          ResourceHandling *handling,
@@ -514,6 +560,27 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request,
     {
         OCResource *resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
         *resource = resourcePtr;
+
+        // Checking resource TPS flags if resource exist in stack.
+        if (resourcePtr)
+        {
+            OCStackResult result = CheckRequestsEndpoint(&(request->devAddr), resourcePtr->endpointType);
+
+            if (result != OC_STACK_OK)
+            {
+                if (result == OC_STACK_BAD_ENDPOINT)
+                {
+                    OIC_LOG(ERROR, TAG, "Request come from bad endpoint. ignore request!!!");
+                    return OC_STACK_BAD_ENDPOINT;
+                }
+                else
+                {
+                    OIC_LOG_V(ERROR, TAG, "Failed at get tps flag errcode: %d", result);
+                    return result;
+                }
+            }
+        }
+
         if (!resourcePtr)
         {
             if(defaultDeviceHandler)
@@ -840,6 +907,28 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
 #endif
             )
     {
+        if (request->method == OC_REST_PUT || request->method == OC_REST_POST ||
+            request->method == OC_REST_DELETE)
+        {
+            OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d",
+                request->resourceUrl, request->method);
+            discoveryResult = OC_STACK_UNAUTHORIZED_REQ;
+            goto exit;
+        }
+
+        char *interfaceQuery = NULL;
+        char *resourceTypeQuery = NULL;
+
+        CAEndpoint_t *networkInfo = NULL;
+        uint32_t infoSize = 0;
+
+        CAResult_t caResult = CAGetNetworkInformation(&networkInfo, &infoSize);
+        if (CA_STATUS_OK != caResult || !networkInfo || infoSize == 0)
+        {
+            OIC_LOG(ERROR, TAG, "CAGetNetworkInformation has error on parsing network infomation");
+            return OC_STACK_ERROR;
+        }
+
         discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
                 &interfaceQuery, &resourceTypeQuery);
         VERIFY_SUCCESS(discoveryResult);
@@ -881,11 +970,19 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
                 // This case will handle when no resource type and it is oic.if.ll.
                 if (!resourceTypeQuery && !baselineQuery && (resource->resourceProperties & prop))
                 {
-                    discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
+                    discoveryResult = BuildVirtualResourceResponse(resource,
+                                                                   discPayload,
+                                                                   &request->devAddr,
+                                                                   networkInfo,
+                                                                   infoSize);
                 }
                 else if (includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
                 {
-                    discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
+                    discoveryResult = BuildVirtualResourceResponse(resource,
+                                                                   discPayload,
+                                                                   &request->devAddr,
+                                                                   networkInfo,
+                                                                   infoSize);
                 }
                 else
                 {
@@ -897,6 +994,11 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
         {
             discoveryResult = OC_STACK_NO_RESOURCE;
         }
+
+        if (networkInfo)
+        {
+            OICFree(networkInfo);
+        }
     }
     else if (virtualUriInRequest == OC_DEVICE_URI)
     {
index 4b5b810..c89716f 100644 (file)
@@ -60,6 +60,7 @@
 #include "ocpayloadcbor.h"
 #include "cautilinterface.h"
 #include "oicgroup.h"
+#include "ocendpoint.h"
 
 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
 #include "routingutility.h"
@@ -752,6 +753,8 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method)
         case OC_STACK_INTERNAL_SERVER_ERROR:
             ret = CA_INTERNAL_SERVER_ERROR;
             break;
+        case OC_STACK_BAD_ENDPOINT:
+            ret = CA_BAD_REQ;
         default:
             break;
     }
@@ -1983,9 +1986,8 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque
 
     requestResult = HandleStackRequests (&serverRequest);
 
-    // Send ACK to client as precursor to slow response
     if (requestResult == OC_STACK_SLOW_RESOURCE)
-    {
+    {   // Send ACK to client as precursor to slow response
         if (requestInfo->info.type == CA_MSG_CONFIRM)
         {
             SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_EMPTY,
@@ -3217,13 +3219,35 @@ OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandle
     return OC_STACK_OK;
 }
 
+OCTpsSchemeFlags OCGetSupportedEndpointTpsFlags()
+{
+    return OCGetSupportedTpsFlags();
+}
+
 OCStackResult OCCreateResource(OCResourceHandle *handle,
         const char *resourceTypeName,
         const char *resourceInterfaceName,
         const char *uri, OCEntityHandler entityHandler,
-        voidcallbackParam,
+        void *callbackParam,
         uint8_t resourceProperties)
 {
+    return OCCreateResourceWithEp(handle,
+                                  resourceTypeName,
+                                  resourceInterfaceName,
+                                  uri, entityHandler,
+                                  callbackParam,
+                                  resourceProperties,
+                                  OC_ALL);
+}
+
+OCStackResult OCCreateResourceWithEp(OCResourceHandle *handle,
+        const char *resourceTypeName,
+        const char *resourceInterfaceName,
+        const char *uri, OCEntityHandler entityHandler,
+        void *callbackParam,
+        uint8_t resourceProperties,
+        OCTpsSchemeFlags resourceTpsTypes)
+{
 
     OCResource *pointer = NULL;
     OCStackResult result = OC_STACK_ERROR;
@@ -3271,6 +3295,26 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
         return OC_STACK_INVALID_PARAM;
     }
 
+    // Checking resourceTpsTypes param
+    OCTpsSchemeFlags validTps = OC_NO_TPS;
+    validTps = (OCTpsSchemeFlags)(validTps | OC_COAP | OC_COAPS);
+#ifdef TCP_ADAPTER
+    validTps = (OCTpsSchemeFlags)(validTps | OC_COAP_TCP | OC_COAPS_TCP);
+#endif
+#ifdef HTTP_ADAPTER
+    validTps = (OCTpsSchemeFlags)(validTps | OC_HTTP | OC_HTTP);
+#endif
+#ifdef EDR_ADAPTER
+    validTps = (OCTpsSchemeFlags)(validTps | OC_COAP_RFCOMM);
+#endif
+
+    if ((resourceTpsTypes < OC_COAP) || ((resourceTpsTypes != OC_ALL) &&
+                                         (resourceTpsTypes > validTps)))
+    {
+        OIC_LOG(ERROR, TAG, "Invalid TPS Types OC_ALL");
+        return OC_STACK_INVALID_PARAM;
+    }
+
     // If the headResource is NULL, then no resources have been created...
     pointer = headResource;
     if (pointer)
@@ -3326,6 +3370,13 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
         goto exit;
     }
 
+    result = BindTpsTypeToResource(pointer, resourceTpsTypes);
+    if (result != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "Error adding resource TPS types");
+        goto exit;
+    }
+
     // If an entity handler has been passed, attach it to the newly created
     // resource.  Otherwise, set the default entity handler.
     if (entityHandler)
@@ -3654,6 +3705,37 @@ OCStackResult BindResourceInterfaceToResource(OCResource* resource,
     return result;
 }
 
+OCStackResult BindTpsTypeToResource(OCResource* resource,
+                                    OCTpsSchemeFlags resourceTpsTypes)
+{
+    if (!resource)
+    {
+        OIC_LOG(ERROR, TAG, "Resource pointer is NULL!!!");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCTpsSchemeFlags supportedTps = OC_NO_TPS;
+    OCStackResult result = OCGetSupportedEndpointFlags(resourceTpsTypes,
+                                                       &supportedTps);
+
+    if (result != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "Failed at get supported endpoint flags");
+        return result;
+    }
+
+    // If there isn`t any enabled flag, return error for notify to user.
+    if (OC_NO_TPS == supportedTps)
+    {
+        OIC_LOG_V(ERROR, TAG, "There isn`t any enabled flag on resource %s", resource->uri);
+        return OC_STACK_BAD_ENDPOINT;
+    }
+
+    OIC_LOG_V(INFO, TAG, "Binding %d TPS flags to %s", supportedTps, resource->uri);
+    resource->endpointType = supportedTps;
+    return result;
+}
+
 OCStackResult OCBindResourceTypeToResource(OCResourceHandle handle,
         const char *resourceTypeName)
 {
index d48e5b3..8fd4cd6 100644 (file)
@@ -55,6 +55,8 @@ using namespace std;
 namespace itst = iotivity::test;
 
 #define DEFAULT_CONTEXT_VALUE 0x99
+#define INVALID_TPS_FLAGS (250)
+#define INVALID_TPS_FLAGS_ZERO (0)
 
 //-----------------------------------------------------------------------------
 // Private variables
@@ -873,6 +875,78 @@ TEST(StackResource, CreateResourceGoodResourceType)
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
 
+TEST(StackResource, CreateResourceWithBadEndpointsFlags)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OIC_LOG(INFO, TAG, "CreateResourceWithEndpointsFlags test");
+
+    InitStack(OC_SERVER);
+
+    OCResourceHandle handle;
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, OCCreateResourceWithEp(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led",
+                                            0,
+                                            NULL,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE,
+                                            (OCTpsSchemeFlags)INVALID_TPS_FLAGS));
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
+
+TEST(StackResource, CreateResourceWithGoodEndpointsFlags)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OIC_LOG(INFO, TAG, "CreateResourceWithEndpointsFlags test");
+
+    InitStack(OC_SERVER);
+
+    OCResourceHandle handle;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResourceWithEp(&handle,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led",
+                                            0,
+                                            NULL,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE,
+                                            OC_ALL));
+    OCResourceHandle handle2;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResourceWithEp(&handle2,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led2",
+                                            0,
+                                            NULL,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE,
+                                            OC_COAP));
+#ifdef TCP_ADAPTER
+    OCResourceHandle handle3;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResourceWithEp(&handle3,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led3",
+                                            0,
+                                            NULL,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE,
+                                            OC_COAP_TCP));
+
+    OCResourceHandle handle4;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResourceWithEp(&handle4,
+                                            "core.led",
+                                            "core.rw",
+                                            "/a/led4",
+                                            0,
+                                            NULL,
+                                            OC_DISCOVERABLE|OC_OBSERVABLE,
+                                            (OCTpsSchemeFlags)(OC_COAP | OC_COAP_TCP)));
+#endif
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}
+
 TEST(StackResource, ResourceTypeName)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
@@ -2141,3 +2215,16 @@ TEST(StackHeaderOption, getHeaderOption)
     EXPECT_EQ(optionData[0], 1);
     EXPECT_EQ(actualDataSize, 8);
 }
+
+TEST(StackEndpoints, OCGetSupportedEndpointTpsFlags)
+{
+    itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+    OIC_LOG(INFO, TAG, "OCGetSupportedEndpointTpsFlags test");
+
+    InitStack(OC_SERVER);
+
+    EXPECT_LE(INVALID_TPS_FLAGS_ZERO, OCGetSupportedEndpointTpsFlags());
+
+    EXPECT_EQ(OC_STACK_OK, OCStop());
+}