[IOT-1207] Endpoint C++ API
authorbg.chun <bg.chun@samsung.com>
Tue, 23 Aug 2016 10:06:01 +0000 (19:06 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Sat, 25 Feb 2017 05:00:06 +0000 (05:00 +0000)
Provide public C++ api for map ocf endpoint flag to resource in server
and change host of resource in client.

Change-Id: I2f4892144c9732fb38162b7174812fa8c51ce02c
Signed-off-by: bg.chun <bg.chun@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/10797
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Dave Thaler <dthaler@microsoft.com>
Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
17 files changed:
resource/csdk/stack/src/ocstack.c
resource/examples/simpleclient.cpp
resource/include/IServerWrapper.h
resource/include/InProcServerWrapper.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OCResource.h
resource/include/OCSerialization.h
resource/include/StringConstants.h
resource/src/InProcServerWrapper.cpp
resource/src/OCException.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp
resource/src/OCResource.cpp
resource/unittests/OCExceptionTest.cpp
resource/unittests/OCPlatformTest.cpp
resource/unittests/OCResourceTest.cpp

index 401aacd..db9da9f 100644 (file)
@@ -429,6 +429,14 @@ static void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, boo
  */
 static void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler,
                                        CAConnectionStateChangedCB connectionHandler);
+/**
+ * Map zoneId to endpoint address which scope is ipv6 link-local.
+ * @param payload Discovery payload which has Endpoint information.
+ * @param ifindex index which indicate network interface.
+ */
+#ifndef WITH_ARDUINO
+static OCStackResult OCMapZoneIdToLinkLocalEndpoint(OCDiscoveryPayload *payload, uint32_t ifindex);
+#endif
 
 //-----------------------------------------------------------------------------
 // Internal functions
@@ -1311,6 +1319,61 @@ OCStackResult HandleBatchResponse(char *requestUri, OCRepPayload **payload)
     return OC_STACK_INVALID_PARAM;
 }
 
+#ifndef WITH_ARDUINO
+OCStackResult OCMapZoneIdToLinkLocalEndpoint(OCDiscoveryPayload *payload, uint32_t ifindex)
+{
+    if (!payload)
+    {
+        OIC_LOG(ERROR, TAG, "Given argument payload is NULL!!");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCResourcePayload *curRes = payload->resources;
+
+    while (curRes != NULL)
+    {
+        OCEndpointPayload* eps = curRes->eps;
+
+        while (eps != NULL)
+        {
+            if (eps->family & OC_IP_USE_V6)
+            {
+                CATransportFlags_t scopeLevel;
+                if (CA_STATUS_OK == CAGetIpv6AddrScope(eps->addr, &scopeLevel))
+                {
+                    if (CA_SCOPE_LINK == scopeLevel)
+                    {
+                        char *zoneId = NULL;
+                        if (OC_STACK_OK == OCGetLinkLocalZoneId(ifindex, &zoneId))
+                        {
+                            assert(zoneId != NULL);
+                            // put zoneId to end of addr
+                            OICStrcat(eps->addr, OC_MAX_ADDR_STR_SIZE, "%");
+                            OICStrcat(eps->addr, OC_MAX_ADDR_STR_SIZE, zoneId);
+                            OICFree(zoneId);
+                        }
+                        else
+                        {
+                            OIC_LOG(ERROR, TAG, "failed at parse zone-id for link-local address");
+                            return OC_STACK_ERROR;
+                        }
+                    }
+                }
+                else
+                {
+                    OIC_LOG(ERROR, TAG, "failed at parse ipv6 scope level");
+                    return OC_STACK_ERROR;
+                }
+            }
+            eps = eps->next;
+        }
+        curRes = curRes->next;
+    }
+
+    return OC_STACK_OK;
+}
+#endif
+
 void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
 {
     OIC_LOG(DEBUG, TAG, "Enter OCHandleResponse");
@@ -1558,6 +1621,22 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
                         OCPayloadDestroy(response->payload);
                         return;
                     }
+
+                    // Check endpoints has link-local ipv6 address.
+                    // if there is, map zone-id which parsed from ifindex
+#ifndef WITH_ARDUINO
+                    if (PAYLOAD_TYPE_DISCOVERY == response->payload->type)
+                    {
+                        OCDiscoveryPayload *disPayload = (OCDiscoveryPayload*)(response->payload);
+                        if (OC_STACK_OK !=
+                            OCMapZoneIdToLinkLocalEndpoint(disPayload, response->devAddr.ifindex))
+                        {
+                            OIC_LOG(ERROR, TAG, "failed at map zone-id for link-local address");
+                            OCPayloadDestroy(response->payload);
+                            return;
+                        }
+                    }
+#endif
                 }
                 else
                 {
index 0c0149e..6c287be 100644 (file)
@@ -392,6 +392,47 @@ void foundResource(std::shared_ptr<OCResource> resource)
                 std::cout << "\t\t" << resourceInterfaces << std::endl;
             }
 
+            // Get Resource current host
+            std::cout << "\tHost of resource: " << std::endl;
+            std::cout << "\t\t" << resource->host() << std::endl;
+
+            // Get Resource Endpoint Infomation
+            std::cout << "\tList of resource endpoints: " << std::endl;
+            for(auto &resourceEndpoints : resource->getAllHosts())
+            {
+                std::cout << "\t\t" << resourceEndpoints << std::endl;
+            }
+
+            // If resource is found from ip based adapter.
+            if (std::string::npos != resource->host().find("coap://") ||
+                std::string::npos != resource->host().find("coaps://") ||
+                std::string::npos != resource->host().find("coap+tcp://") ||
+                std::string::npos != resource->host().find("coaps+tcp://"))
+            {
+                for(auto &resourceEndpoints : resource->getAllHosts())
+                {
+                    if (resourceEndpoints.compare(resource->host()) != 0 &&
+                        std::string::npos == resourceEndpoints.find("coap+rfcomm"))
+                    {
+                        std::string newHost = resourceEndpoints;
+
+                        if (std::string::npos != newHost.find("tcp"))
+                        {
+                            TRANSPORT_TYPE_TO_USE = OCConnectivityType::CT_ADAPTER_TCP;
+                        }
+                        else
+                        {
+                            TRANSPORT_TYPE_TO_USE = OCConnectivityType::CT_ADAPTER_IP;
+                        }
+                        // Change Resource host if another host exists
+                        std::cout << "\tChange host of resource endpoints" << std::endl;
+                        std::cout << "\t\t" << "Current host is "
+                                  << resource->setHost(newHost) << std::endl;
+                        break;
+                    }
+                }
+            }
+
             if(resourceURI == "/a/light")
             {
                 if (resource->connectivityType() & TRANSPORT_TYPE_TO_USE)
index 1025a15..ec3374a 100644 (file)
@@ -51,6 +51,15 @@ namespace OC
                     EntityHandler& entityHandler,
                     uint8_t resourceProperty) = 0;
 
+        virtual OCStackResult registerResourceWithTps(
+                    OCResourceHandle& resourceHandle,
+                    std::string& resourceURI,
+                    const std::string& resourceTypeName,
+                    const std::string& resourceInterface,
+                    EntityHandler& entityHandler,
+                    uint8_t resourceProperty,
+                    OCTpsSchemeFlags resourceTpsTypes) = 0;
+
         // @deprecated: Use setPropertyValue instead.
         virtual OCStackResult registerDeviceInfo(
                     const OCDeviceInfo deviceInfo) = 0;
@@ -86,6 +95,8 @@ namespace OC
         virtual OCStackResult stop() = 0;
 
         virtual OCStackResult start() = 0;
+
+        virtual OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps) = 0;
     };
 }
 
index 9762818..3d213bd 100644 (file)
@@ -44,6 +44,15 @@ namespace OC
                     EntityHandler& entityHandler,
                     uint8_t resourceProperty);
 
+        virtual OCStackResult registerResourceWithTps(
+                    OCResourceHandle& resourceHandle,
+                    std::string& resourceURI,
+                    const std::string& resourceTypeName,
+                    const std::string& resourceInterface,
+                    EntityHandler& entityHandler,
+                    uint8_t resourceProperty,
+                    OCTpsSchemeFlags resourceTpsTypes);
+
         // @deprecated: Use setPropertyValue instead.
         virtual OCStackResult registerDeviceInfo(
                     const OCDeviceInfo deviceInfo);
@@ -80,6 +89,7 @@ namespace OC
 
         virtual OCStackResult start();
 
+        virtual OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps);
     private:
         void processFunc();
         std::thread m_processThread;
index e4c2b0e..1f57b58 100644 (file)
@@ -272,31 +272,37 @@ namespace OC
                     QualityOfService QoS);
 
         /**
+         * This function returns flags of supported endpoint TPS on stack.
+         *
+         * @param[out] supportedTps Bit combinations of supported OCTpsSchemeFlags.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps);
+
+        /**
         * This API registers a resource with the server
         * @note This API applies to server side only.
         *
         * @param resourceHandle Upon successful registration, resourceHandle will be filled
         * @param resourceURI The URI of the resource. Example: "a/light". See NOTE below
-        * @param resourceTypeName The resource type. Example: "light"
+        * @param resourceTypeName The resource type. Example: "core.light"
         * @param resourceInterface The resource interface (whether it is collection etc).
         * @param entityHandler entity handler callback.
-        * @param resourceProperty indicates the property of the resource. Defined in ocstack.h.
+        * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
         * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
         * setting resourceProperty as OC_OBSERVABLE will allow observation
-        * settings resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery and
-        * observation
+        * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
+        * and observation
         *
         * @return Returns ::OC_STACK_OK if success.
-        * @note "a/light" is a relative URI.
-        * Above relative URI will be prepended (by core) with a host IP + namespace "oic"
-        * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI"
-        * Example, a relative URI: 'a/light' will result in a fully qualified URI:
-        *   //192.168.1.1/oic/a/light"
-        * First parameter can take a relative URI and core will take care of preparing the fully
-        * qualified URI OR
-        * first parameter can take fully qualified URI and core will take that as is for further
-        * operations
-        * @note OCStackResult is defined in ocstack.h.
+        * @note "a/light" is a relative reference to URI.
+        * Above relative reference to URI will be prepended (by core) with a host IP
+        * Therefore, fully qualified URI format would be
+        * "CoAP(s)+protocol-URI-Scheme://HostIP-Address/relativeURI"
+        * Example, a relative reference to URI: 'a/light' will result in a fully qualified URI:
+        *   "coap://192.168.1.1:5246/a/light", "coaps://192.168.1.1:5246/a/light"
+        * @note OCStackResult is defined in octypes.h.
         * @note entity handler callback :
         * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT,
         * OC_EH_SLOW and etc in entity handler callback,
@@ -313,6 +319,49 @@ namespace OC
                         uint8_t resourceProperty);
 
         /**
+        * This API registers a resource with the server
+        * @note This API applies to server side only.
+        *
+        * @param resourceHandle Upon successful registration, resourceHandle will be filled
+        * @param resourceURI The URI of the resource. Example: "a/light". See NOTE below
+        * @param resourceTypeName The resource type. Example: "core.light"
+        * @param resourceInterface The resource interface (whether it is collection etc).
+        * @param entityHandler Entity handler callback.
+        * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
+        * @param resourceTpsTypes Transport Protocol Suites(TPS) types of resource for
+                                  open resource to specific transport adapter (e.g., TCP, UDP)
+                                  with messaging protocol(e.g., COAP, COAPS).
+                                  Example: "OC_COAP | OC_COAP_TCP"
+        * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
+        * setting resourceProperty as OC_OBSERVABLE will allow observation
+        * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
+        * and observation
+        *
+        * @return Returns ::OC_STACK_OK if success.
+        * @note "a/light" is a relative reference to URI.
+        * Above relative reference to URI will be prepended (by core) with a host IP
+        * Therefore, fully qualified URI format would be
+        * "CoAP(s)+protocol-URI-Scheme://HostIP-Address/relativeURI"
+        * Example, a relative reference to URI: 'a/light' will result in a fully qualified URI:
+        *   "coap://192.168.1.1:5246/a/light", "coaps://192.168.1.1:5246/a/light"
+        * @note OCStackResult is defined in octypes.h.
+        * @note entity handler callback :
+        * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT,
+        * OC_EH_SLOW and etc in entity handler callback,
+        * ocstack will be not send response automatically to client
+        * except for error return value like OC_EH_ERROR
+        * If you want to send response to client with specific result,
+        * OCDoResponse API should be called with the result value.
+        */
+        OCStackResult registerResource(OCResourceHandle& resourceHandle,
+                        std::string& resourceURI,
+                        const std::string& resourceTypeName,
+                        const std::string& resourceInterface,
+                        EntityHandler entityHandler,
+                        uint8_t resourceProperty,
+                        OCTpsSchemeFlags resourceTpsTypes);
+
+        /**
          * This API registers a resource with the server
          * @note This API applies to server & client side.
          *
@@ -617,17 +666,18 @@ namespace OC
          * to be a Client or Client/Server.  Otherwise, this will return an empty
          * shared ptr.
          *
-         * @param host a string containing a resolvable host address of the server
-         *           holding the resource. Currently this should be in the format of
-         *           coap://address:port for IPv4 and in the format of
-         *           coap://[address%25ZoneID]:port for IPv6. In the future, we expect
-         *           "coap:" section is removed from this format.
+         * @param host a string containing a resolvable "coap(s)", "coap(s)+protocol" uri scheme
+         *        of the server holding the resource.
+         *        Currently this should be in the format coap(s)://address:port or
+         *        coap(s)+protocol://address:port, though in the future, we expect this to
+         *        change to //address:port
          *
          * @param uri the rest of the resource's URI that will permit messages to be
          *           properly routed.  Example: /a/light
          *
          * @param connectivityType ::OCConnectivityType type of connectivity indicating the
-         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         *                           transport method and IP address scope.
+         *                           Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
          *                           if you want to use a specific Flag like IPv4,
          *                           you should apply OR operation for the flag in here.
          *                           Example: static_cast<OCConnectivityType>(CT_ADAPTER_TCP
index 4923de0..6637c16 100644 (file)
@@ -156,31 +156,87 @@ namespace OC
             std::vector<std::string>& value);
 
         /**
+         * This function returns flags of supported endpoint TPS on stack.
+         *
+         * @param[out] supportedTps Bit combinations of supported OCTpsSchemeFlags.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps);
+
+        /**
+        * This API registers a resource with the server
+        * @note This API applies to server side only.
+        *
+        * @param resourceHandle Upon successful registration, resourceHandle will be filled
+        * @param resourceURI The URI of the resource. Example: "a/light". See NOTE below
+        * @param resourceTypeName The resource type. Example: "core.light"
+        * @param resourceInterface The resource interface (whether it is collection etc).
+        * @param entityHandler Entity handler callback.
+        * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
+        * @param resourceTpsTypes Transport Protocol Suites(TPS) types of resource for
+                                  open resource to specific transport adapter (e.g., TCP, UDP)
+                                  with messaging protocol(e.g., COAP, COAPS).
+                                  Example: "OC_COAP | OC_COAP_TCP"
+        * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
+        * setting resourceProperty as OC_OBSERVABLE will allow observation
+        * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
+        * and observation
+        *
+        * @return Returns ::OC_STACK_OK if success.
+        * @note "a/light" is a relative reference to URI.
+        * Above relative reference to URI will be prepended (by core) with a host IP
+        * Therefore, fully qualified URI format would be
+        * "CoAP(s)+protocol-URI-Scheme://HostIP-Address/relativeURI"
+        * Example, a relative reference to URI: 'a/light' will result in a fully qualified URI:
+        *   "coap://192.168.1.1:5246/a/light", "coaps://192.168.1.1:5246/a/light"
+        * @note OCStackResult is defined in octypes.h.
+        * @note entity handler callback :
+        * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT,
+        * OC_EH_SLOW and etc in entity handler callback,
+        * ocstack will be not send response automatically to client
+        * except for error return value like OC_EH_ERROR
+        * If you want to send response to client with specific result,
+        * OCDoResponse API should be called with the result value.
+        */
+        OCStackResult registerResource(OCResourceHandle& resourceHandle,
+                        std::string& resourceURI,
+                        const std::string& resourceTypeName,
+                        const std::string& resourceInterface,
+                        EntityHandler entityHandler,
+                        uint8_t resourceProperty,
+                        OCTpsSchemeFlags resourceTpsTypes);
+
+        /**
         * This API registers a resource with the server
         * @note This API applies to server side only.
         *
         * @param resourceHandle Upon successful registration, resourceHandle will be filled
         * @param resourceURI The URI of the resource. Example: "a/light". See NOTE below
-        * @param resourceTypeName The resource type. Example: "light"
+        * @param resourceTypeName The resource type. Example: "core.light"
         * @param resourceInterface The resource interface (whether it is collection etc).
         * @param entityHandler entity handler callback.
-        * @param resourceProperty indicates the property of the resource. Defined in ocstack.h.
+        * @param resourceProperty indicates the property of the resource. Defined in octypes.h.
         * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource
         * setting resourceProperty as OC_OBSERVABLE will allow observation
-        * settings resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery
+        * setting resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery 
         * and observation
         *
         * @return Returns ::OC_STACK_OK if success.
-        * @note "a/light" is a relative URI.
-        * Above relative URI will be prepended (by core) with a host IP + namespace "oc"
-        * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI"
-        * Example, a relative URI: 'a/light' will result in a fully qualified URI:
-        *   //192.168.1.1/oic/a/light"
-        * First parameter can take a relative URI and core will take care of preparing the fully
-        * qualified URI OR
-        * first parameter can take fully qualified URI and core will take that as is for further
-        * operations
-        * @note OCStackResult is defined in ocstack.h.
+        * @note "a/light" is a relative reference to URI.
+        * Above relative reference to URI will be prepended (by core) with a host IP
+        * Therefore, fully qualified URI format would be
+        * "CoAP(s)+protocol-URI-Scheme://HostIP-Address/relativeURI"
+        * Example, a relative reference to URI: 'a/light' will result in a fully qualified URI:
+        *   "coap://192.168.1.1:5246/a/light", "coaps://192.168.1.1:5246/a/light"
+        * @note OCStackResult is defined in octypes.h.
+        * @note entity handler callback :
+        * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT,
+        * OC_EH_SLOW and etc in entity handler callback,
+        * ocstack will be not send response automatically to client
+        * except for error return value like OC_EH_ERROR
+        * If you want to send response to client with specific result,
+        * OCDoResponse API should be called with the result value.
         */
         OCStackResult registerResource(OCResourceHandle& resourceHandle,
                         std::string& resourceURI,
@@ -260,6 +316,7 @@ namespace OC
                         OCConnectivityType connectivityType, bool isObservable,
                         const std::vector<std::string>& resourceTypes,
                         const std::vector<std::string>& interfaces);
+
         OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse);
         std::weak_ptr<std::recursive_mutex> csdkLock();
 
index fd468f6..fbb324a 100644 (file)
@@ -123,6 +123,7 @@ namespace OC
             m_resourceTypes(std::move(o.m_resourceTypes)),
             m_interfaces(std::move(o.m_interfaces)),
             m_children(std::move(m_children)),
+            m_endpoints(std::move(m_endpoints)),
             m_observeHandle(std::move(m_observeHandle)),
             m_headerOptions(std::move(m_headerOptions))
         {
@@ -485,6 +486,12 @@ namespace OC
         std::string host() const;
 
         /**
+        * Function to get the endpoints information of this resource
+        * @return std::vector<std::string> endpoints information
+        */
+        std::vector<std::string> getAllHosts() const;
+
+        /**
         * Function to get the URI for this resource
         * @return std::string resource URI
         */
@@ -503,6 +510,12 @@ namespace OC
         */
         bool isObservable() const;
 
+        /**
+        * Function to change host of this reource
+        * @return std::string New host Address.
+        *         not observable.
+        */
+        std::string setHost(const std::string& host);
 #ifdef WITH_MQ
         /**
         * Function to provide ability to check if this resource is publisher or not
@@ -654,7 +667,6 @@ namespace OC
         bool operator>=(const OCResource &other) const;
 
     private:
-        void setHost(const std::string& host);
         std::weak_ptr<IClientWrapper> m_clientWrapper;
         std::string m_uri;
         OCResourceIdentifier m_resourceId;
@@ -665,6 +677,7 @@ namespace OC
         std::vector<std::string> m_resourceTypes;
         std::vector<std::string> m_interfaces;
         std::vector<std::string> m_children;
+        std::vector<std::string> m_endpoints;
         OCDoHandle m_observeHandle;
         HeaderOptions m_headerOptions;
 
@@ -676,11 +689,26 @@ namespace OC
                     const std::vector<std::string>& interfaces);
 
         OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+                    const OCDevAddr& devAddr, const std::string& uri,
+                    const std::string& serverId, uint8_t property,
+                    const std::vector<std::string>& resourceTypes,
+                    const std::vector<std::string>& interfaces,
+                    const std::vector<std::string>& endpoints);
+
+        OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                     const std::string& host, const std::string& uri,
                     const std::string& serverId,
                     OCConnectivityType connectivityType, uint8_t property,
                     const std::vector<std::string>& resourceTypes,
                     const std::vector<std::string>& interfaces);
+
+        OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+                    const std::string& host, const std::string& uri,
+                    const std::string& serverId,
+                    OCConnectivityType connectivityType, uint8_t property,
+                    const std::vector<std::string>& resourceTypes,
+                    const std::vector<std::string>& interfaces,
+                    const std::vector<std::string>& endpoints);
     };
 
 } // namespace OC
index 96352a7..a3ee22b 100644 (file)
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 #include <StringConstants.h>
+#include <sstream>
+#include <cstring>
 #include "ocpayload.h"
 #include "ocrandom.h"
 #include "oic_string.h"
 
 namespace OC
 {
+    static const char EP_ADDR_SPLIT[]   = "://";
+    static const char EP_PORT_SPLIT[]   = ":";
+    static const char EP_BRAKET_START[] = "[";
+    static const char EP_BRAKET_END[]   = "]";
+
     class ListenOCContainer
     {
         private:
@@ -39,6 +46,40 @@ namespace OC
                 return strs;
             }
 
+            static std::vector<std::string> EpsLLToVector(OCEndpointPayload* head)
+            {
+                std::vector<std::string> strs;
+                while (head)
+                {
+                    std::ostringstream endpoint;
+                    endpoint << head->tps << EP_ADDR_SPLIT;
+
+                    switch (head->family)
+                    {
+                        case OC_DEFAULT_FLAGS:
+                            // mac
+                            endpoint << head->addr;
+                            break;
+
+                        case OC_IP_USE_V4:
+                            endpoint << head->addr << EP_PORT_SPLIT << head->port;
+                            break;
+
+                        case OC_IP_USE_V6:
+                            endpoint << EP_BRAKET_START << head->addr << EP_BRAKET_END
+                                     << EP_PORT_SPLIT << head->port;
+                            break;
+                        default:
+                            head = head->next;
+                            continue;
+                    }
+
+                    strs.push_back(endpoint.str());
+                    head = head->next;
+                }
+                return strs;
+            }
+
         public:
             ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
                     OCDevAddr& devAddr, OCDiscoveryPayload* payload)
@@ -56,6 +97,14 @@ namespace OC
 
                         currentDevAddr.port = (res->port != 0) ? res->port : devAddr.port;
 
+                        OCEndpointPayload* eps = res->eps;
+                        std::vector<std::string> epsVector;
+                        if (eps)
+                        {
+                            //parsing eps from payload
+                            epsVector = EpsLLToVector(eps);
+                        }
+
                         if (payload->baseURI)
                         {
                             OCDevAddr rdPubAddr = currentDevAddr;
@@ -73,7 +122,8 @@ namespace OC
                                             std::string(payload->sid),
                                             res->bitmap,
                                             StringLLToVector(res->types),
-                                            StringLLToVector(res->interfaces)
+                                            StringLLToVector(res->interfaces),
+                                            epsVector
                                             )));
                         }
                         else
@@ -84,7 +134,8 @@ namespace OC
                                         std::string(payload->sid),
                                         res->bitmap,
                                         StringLLToVector(res->types),
-                                        StringLLToVector(res->interfaces)
+                                        StringLLToVector(res->interfaces),
+                                        epsVector
                                         )));
 
 #ifdef TCP_ADAPTER
@@ -99,7 +150,8 @@ namespace OC
                                                 std::string(payload->sid),
                                                 res->bitmap,
                                                 StringLLToVector(res->types),
-                                                StringLLToVector(res->interfaces)
+                                                StringLLToVector(res->interfaces),
+                                                epsVector
                                                 )));
                             }
 #endif
index ae7869c..c12e50e 100644 (file)
@@ -131,6 +131,7 @@ namespace OC
         static const char PUBLISH_RESOURCE_FAILED[]    = "Publish Resource failure";
         static const char FORBIDDEN_REQ[]              = "Forbidden request";
         static const char INTERNAL_SERVER_ERROR[]      = "Internal server error";
+        static const char BAD_ENDPOINT[]               = "Bad Endpoint";
     }
 
     namespace Error
index 774094d..67a44ca 100644 (file)
@@ -435,7 +435,19 @@ namespace OC
                     const std::string& resourceInterface,
                     EntityHandler& eHandler,
                     uint8_t resourceProperties)
+    {
+        return registerResourceWithTps(resourceHandle, resourceURI, resourceTypeName,
+                                       resourceInterface, eHandler, resourceProperties, OC_ALL);
+    }
 
+    OCStackResult InProcServerWrapper::registerResourceWithTps(
+                    OCResourceHandle& resourceHandle,
+                    std::string& resourceURI,
+                    const std::string& resourceTypeName,
+                    const std::string& resourceInterface,
+                    EntityHandler& eHandler,
+                    uint8_t resourceProperties,
+                    OCTpsSchemeFlags resourceTpsTypes)
     {
         OCStackResult result = OC_STACK_ERROR;
 
@@ -447,25 +459,27 @@ namespace OC
 
             if(NULL != eHandler)
             {
-                result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
+                result = OCCreateResourceWithEp(&resourceHandle, // OCResourceHandle *handle
                             resourceTypeName.c_str(), // const char * resourceTypeName
-                            resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
+                            //const char * resourceInterfaceName //TODO fix this
+                            resourceInterface.c_str(),
                             resourceURI.c_str(), // const char * uri
                             EntityHandlerWrapper, // OCEntityHandler entityHandler
                             NULL,
-                            resourceProperties // uint8_t resourceProperties
-                            );
+                            resourceProperties, // uint8_t resourceProperties
+                            resourceTpsTypes);  // OCTpsSchemeFlags resourceTpsTypes
             }
             else
             {
-                result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
+                result = OCCreateResourceWithEp(&resourceHandle, // OCResourceHandle *handle
                             resourceTypeName.c_str(), // const char * resourceTypeName
-                            resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
+                            //const char * resourceInterfaceName //TODO fix this
+                            resourceInterface.c_str(),
                             resourceURI.c_str(), // const char * uri
                             NULL, // OCEntityHandler entityHandler
                             NULL,
-                            resourceProperties // uint8_t resourceProperties
-                            );
+                            resourceProperties, // uint8_t resourceProperties
+                            resourceTpsTypes);  // OCTpsSchemeFlags resourceTpsTypes
             }
 
             if(result != OC_STACK_OK)
@@ -689,6 +703,23 @@ namespace OC
         }
     }
 
+    OCStackResult InProcServerWrapper::getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps)
+    {
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            supportedTps = OCGetSupportedEndpointTpsFlags();
+
+            if (OC_NO_TPS != supportedTps)
+            {
+                result = OC_STACK_OK;
+            }
+        }
+        return result;
+    }
+
     InProcServerWrapper::~InProcServerWrapper()
     {
         try
index d413fd9..34fe08f 100644 (file)
@@ -119,6 +119,8 @@ std::string OC::OCException::reason(const OCStackResult sr)
             return OC::Exception::FORBIDDEN_REQ;
         case OC_STACK_INTERNAL_SERVER_ERROR:
             return OC::Exception::INTERNAL_SERVER_ERROR;
+        case OC_STACK_BAD_ENDPOINT:
+            return OC::Exception::BAD_ENDPOINT;
     }
 
     return OC::Exception::UNKNOWN_ERROR;
index 80db44b..0fa1db3 100644 (file)
@@ -187,12 +187,18 @@ namespace OC
                                  platformInfoHandler, QoS);
         }
 
+        OCStackResult getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps)
+        {
+            return OCPlatform_impl::Instance().getSupportedTransportsInfo(supportedTps);
+        }
+
         OCStackResult registerResource(OCResourceHandle& resourceHandle,
                                  std::string& resourceURI,
                                  const std::string& resourceTypeName,
                                  const std::string& resourceInterface,
                                  EntityHandler entityHandler,
-                                 uint8_t resourceProperty)
+                                 uint8_t resourceProperty
+                                 )
         {
             return OCPlatform_impl::Instance().registerResource(resourceHandle, resourceURI,
                                  resourceTypeName, resourceInterface,
@@ -200,6 +206,20 @@ namespace OC
         }
 
         OCStackResult registerResource(OCResourceHandle& resourceHandle,
+                                 std::string& resourceURI,
+                                 const std::string& resourceTypeName,
+                                 const std::string& resourceInterface,
+                                 EntityHandler entityHandler,
+                                 uint8_t resourceProperty,
+                                 OCTpsSchemeFlags resourceTpsTypes)
+        {
+            return OCPlatform_impl::Instance().registerResource(resourceHandle, resourceURI,
+                                 resourceTypeName, resourceInterface,
+                                 entityHandler, resourceProperty,
+                                 resourceTpsTypes);
+        }
+
+        OCStackResult registerResource(OCResourceHandle& resourceHandle,
                                  const std::shared_ptr< OCResource > resource)
         {
             return OCPlatform_impl::Instance().registerResource(resourceHandle, resource);
index 7f7d412..b04e14e 100644 (file)
@@ -355,6 +355,11 @@ namespace OC
                              host, platformURI, connectivityType, platformInfoHandler, QoS);
     }
 
+    OCStackResult OCPlatform_impl::getSupportedTransportsInfo(OCTpsSchemeFlags& supportedTps)
+    {
+        return checked_guard(m_server, &IServerWrapper::getSupportedTransportsInfo, supportedTps);
+    }
+
     OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
                                             std::string& resourceURI,
                                             const std::string& resourceTypeName,
@@ -367,6 +372,20 @@ namespace OC
                              resourceInterface, entityHandler, resourceProperty);
     }
 
+    OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
+                                            std::string& resourceURI,
+                                            const std::string& resourceTypeName,
+                                            const std::string& resourceInterface,
+                                            EntityHandler entityHandler,
+                                            uint8_t resourceProperty,
+                                            OCTpsSchemeFlags resourceTpsTypes)
+    {
+        return checked_guard(m_server, &IServerWrapper::registerResourceWithTps,
+                             std::ref(resourceHandle), resourceURI, resourceTypeName,
+                             resourceInterface, entityHandler, resourceProperty,
+                             resourceTpsTypes);
+    }
+
     OCStackResult OCPlatform_impl::registerDeviceInfo(const OCDeviceInfo deviceInfo)
     {
         return checked_guard(m_server, &IServerWrapper::registerDeviceInfo, deviceInfo);
index d4ca4b2..f31c1e1 100644 (file)
 #include "iotivity_config.h"
 #include "OCResource.h"
 #include "OCUtilities.h"
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "cacommon.h"
+#include "cautilinterface.h"
+#include "oic_string.h"
 
 #include <boost/lexical_cast.hpp>
 #include <sstream>
@@ -73,15 +78,91 @@ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
 }
 
 OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+                        const OCDevAddr& devAddr, const std::string& uri,
+                        const std::string& serverId, uint8_t property,
+                        const std::vector<std::string>& resourceTypes,
+                        const std::vector<std::string>& interfaces,
+                        const std::vector<std::string>& endpoints)
+ :  m_clientWrapper(clientWrapper), m_uri(uri),
+    m_resourceId(serverId, m_uri), m_devAddr(devAddr),
+    m_isCollection(false), m_property(property),
+    m_resourceTypes(resourceTypes), m_interfaces(interfaces),
+    m_endpoints(endpoints),
+    m_observeHandle(nullptr)
+{
+    m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
+                        != m_interfaces.end();
+
+    if (m_uri.empty() ||
+        resourceTypes.empty() ||
+        interfaces.empty()||
+        m_clientWrapper.expired())
+    {
+        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false);
+    }
+}
+
+OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                         const std::string& host, const std::string& uri,
                         const std::string& serverId,
                         OCConnectivityType connectivityType, uint8_t property,
                         const std::vector<std::string>& resourceTypes,
-                        const std::vector<std::string>& interfaces)
+                        const std::vector<std::string>& interfaces,
+                        const std::vector<std::string>& endpoints)
  :  m_clientWrapper(clientWrapper), m_uri(uri),
     m_resourceId(serverId, m_uri),
     m_isCollection(false), m_property(property),
     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
+    m_endpoints(endpoints),
+    m_observeHandle(nullptr)
+{
+    m_devAddr = OCDevAddr{OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0,
+#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
+                          {0}
+#endif
+                        };
+    m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
+                        != m_interfaces.end();
+
+    if (m_uri.empty() ||
+        resourceTypes.empty() ||
+        interfaces.empty()||
+        m_clientWrapper.expired())
+    {
+        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false);
+    }
+
+    if (uri.length() == 1 && uri[0] == '/')
+    {
+        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false);
+    }
+
+    if (uri[0] != '/')
+    {
+        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false);
+    }
+
+    // construct the devAddr from the pieces we have
+    m_devAddr.adapter = static_cast<OCTransportAdapter>(connectivityType >> CT_ADAPTER_SHIFT);
+    m_devAddr.flags = static_cast<OCTransportFlags>(connectivityType & CT_MASK_FLAGS);
+
+    this->setHost(host);
+}
+
+OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
+                        const std::string& host, const std::string& uri,
+                        const std::string& serverId,
+                        OCConnectivityType connectivityType, uint8_t property,
+                        const std::vector<std::string>& resourceTypes,
+                        const std::vector<std::string>& interfaces)
+:  m_clientWrapper(clientWrapper), m_uri(uri),
+    m_resourceId(serverId, m_uri),
+    m_isCollection(false), m_property(property),
+    m_resourceTypes(resourceTypes), m_interfaces(interfaces),
     m_observeHandle(nullptr)
 {
     m_devAddr = OCDevAddr{OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0,
@@ -124,35 +205,64 @@ OCResource::~OCResource()
 {
 }
 
-void OCResource::setHost(const std::string& host)
+std::string OCResource::setHost(const std::string& host)
 {
     size_t prefix_len;
 
-    if (host.compare(0, sizeof(COAP) - 1, COAP) == 0)
-    {
-        prefix_len = sizeof(COAP) - 1;
-    }
-    else if (host.compare(0, sizeof(COAPS) - 1, COAPS) == 0)
+    OCDevAddr new_devAddr;
+    memset(&new_devAddr, 0, sizeof(new_devAddr));
+    new_devAddr.adapter = OC_DEFAULT_ADAPTER;
+    new_devAddr.flags = OC_DEFAULT_FLAGS;
+
+    // init m_devAddr
+    m_devAddr = new_devAddr;
+    bool usingIpAddr = false;
+
+    if (host.compare(0, sizeof(COAPS) - 1, COAPS) == 0)
     {
+        if (!OC_SECURE)
+        {
+            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+        }
         prefix_len = sizeof(COAPS) - 1;
         m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_SECURE);
+        m_devAddr.adapter = OC_ADAPTER_IP;
+        usingIpAddr = true;
+    }
+    else if (host.compare(0, sizeof(COAP) - 1, COAP) == 0)
+    {
+        prefix_len = sizeof(COAP) - 1;
+        m_devAddr.adapter = OC_ADAPTER_IP;
+        usingIpAddr = true;
     }
     else if (host.compare(0, sizeof(COAP_TCP) - 1, COAP_TCP) == 0)
     {
         prefix_len = sizeof(COAP_TCP) - 1;
+        m_devAddr.adapter = OC_ADAPTER_TCP;
+        usingIpAddr = true;
     }
     else if (host.compare(0, sizeof(COAPS_TCP) - 1, COAPS_TCP) == 0)
     {
+        if (!OC_SECURE)
+        {
+            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+        }
         prefix_len = sizeof(COAPS_TCP) - 1;
         m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_SECURE);
+        m_devAddr.adapter = OC_ADAPTER_TCP;
+        usingIpAddr = true;
     }
     else if (host.compare(0, sizeof(COAP_GATT) - 1, COAP_GATT) == 0)
     {
         prefix_len = sizeof(COAP_GATT) - 1;
+        m_devAddr.adapter = OC_ADAPTER_GATT_BTLE;
     }
     else if (host.compare(0, sizeof(COAP_RFCOMM) - 1, COAP_RFCOMM) == 0)
     {
         prefix_len = sizeof(COAP_RFCOMM) - 1;
+        m_devAddr.adapter = OC_ADAPTER_RFCOMM_BTEDR;
     }
     else
     {
@@ -160,6 +270,21 @@ void OCResource::setHost(const std::string& host)
             m_interfaces.empty(), m_clientWrapper.expired(), false, false);
     }
 
+    // set flag
+    if (usingIpAddr)
+    {
+        if (host.find('[') != std::string::npos)
+        {
+            // ipv6
+            m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_IP_USE_V6);
+        }
+        else
+        {
+            // ipv4
+            m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_IP_USE_V4);
+        }
+    }
+
     // remove 'coap://' or 'coaps://' or 'coap+tcp://' or 'coap+gatt://' or 'coap+rfcomm://'
     std::string host_token = host.substr(prefix_len);
 
@@ -200,13 +325,47 @@ void OCResource::setHost(const std::string& host)
                 m_interfaces.empty(), m_clientWrapper.expired(), false, false);
         }
 
-        OCStackResult result = OCDecodeAddressForRFC6874(m_devAddr.addr,
-            sizeof(m_devAddr.addr), ip6Addr.c_str(), nullptr);
+        if (std::string::npos != ip6Addr.find("%25"))
+        {
+            OCStackResult result = OCDecodeAddressForRFC6874(m_devAddr.addr,
+                                   sizeof(m_devAddr.addr), ip6Addr.c_str(), nullptr);
 
-        if (OC_STACK_OK != result)
+            if (OC_STACK_OK != result)
+            {
+                throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+            }
+        }
+        else
         {
-            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+            // It means zone-id is missing, check ipv6Addr is link local
+            CATransportFlags_t scopeLevel;
+            CAResult_t caResult = CAGetIpv6AddrScope(ip6Addr.c_str(), &scopeLevel);
+
+            if (CA_STATUS_OK != caResult)
+            {
+                throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+            }
+            else
+            {
+                if (CA_SCOPE_LINK == scopeLevel)
+                {
+                    {
+                        // Given ip address is link-local scope without zone-id.
+                        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+                            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+                    }
+                }
+                else
+                {
+                    if (!OICStrcpy(m_devAddr.addr, sizeof(m_devAddr.addr), ip6Addr.c_str()))
+                    {
+                        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
+                            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+                    }
+                }
+            }
         }
 
         m_devAddr.port = static_cast<uint16_t>(port);
@@ -293,6 +452,7 @@ void OCResource::setHost(const std::string& host)
             m_devAddr.port = static_cast<uint16_t>(port);
         }
     }
+    return this->host();
 }
 
 OCStackResult OCResource::get(const QueryParamsMap& queryParametersMap,
@@ -570,6 +730,11 @@ std::string OCResource::host() const
     return ss.str();
 }
 
+std::vector<std::string> OCResource::getAllHosts() const
+{
+    return m_endpoints;
+}
+
 std::string OCResource::uri() const
 {
     return m_uri;
index 742adcc..d2e5118 100644 (file)
@@ -78,7 +78,8 @@ namespace OC
                 OC_STACK_USER_DENIED_REQ,
                 OC_STACK_NOT_ACCEPTABLE,
                 OC_STACK_FORBIDDEN_REQ,
-                OC_STACK_INTERNAL_SERVER_ERROR
+                OC_STACK_INTERNAL_SERVER_ERROR,
+                OC_STACK_BAD_ENDPOINT
             };
 
             std::string resultMessages[]=
@@ -128,7 +129,8 @@ namespace OC
                 OC::Exception::USER_DENIED_REQ,
                 OC::Exception::NOT_ACCEPTABLE,
                 OC::Exception::FORBIDDEN_REQ,
-                OC::Exception::INTERNAL_SERVER_ERROR
+                OC::Exception::INTERNAL_SERVER_ERROR,
+                OC::Exception::BAD_ENDPOINT
             };
             TEST(OCExceptionTest, ReasonCodeMatches)
             {
index 63ffecc..b71b627 100644 (file)
@@ -174,6 +174,19 @@ namespace OCPlatformTest
         return resourceHandle;
     }
 
+    OCResourceHandle RegisterResource(std::string uri, OCTpsSchemeFlags resourceTpsTypes)
+    {
+        PlatformConfig cfg
+        { OC::ServiceType::OutOfProc, OC::ModeType::Server, "0.0.0.0", 0,
+                OC::QualityOfService::LowQos, &gps };
+        OCPlatform::Configure(cfg);
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
+                                        resourceHandle, uri, gResourceTypeName,
+                                        gResourceInterface, entityHandler, gResourceProperty,
+                                        resourceTpsTypes));
+        return resourceHandle;
+    }
+
     //Configure
     // Enable it when the stack throw an exception
     // https://jira.iotivity.org/browse/IOT-428
@@ -403,6 +416,37 @@ namespace OCPlatformTest
                 gResourceInterface, entityHandler, gResourceProperty));
     }
 
+    TEST(RegisterResourceTest, RegisterWithTpsType)
+    {
+        std::string uri = "/a/light7";
+        std::string type = "core.light";
+        uint8_t gResourceProperty = 0;
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
+                resourceHandle, uri, type,
+                gResourceInterface, entityHandler, gResourceProperty , OC_COAP));
+    }
+
+    TEST(RegisterResourceTest, RegisterWithTpsTypeAll)
+    {
+        std::string uri = "/a/light8";
+        std::string type = "core.light";
+        uint8_t gResourceProperty = 0;
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
+                resourceHandle, uri, type,
+                gResourceInterface, entityHandler, gResourceProperty, OC_ALL));
+    }
+#ifdef TCP_ADAPTER
+    TEST(RegisterResourceTest, RegisterWithTpsTypeBitComb)
+    {
+        std::string uri = "/a/light9";
+        std::string type = "core.light";
+        uint8_t gResourceProperty = 0;
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
+                resourceHandle, uri, type,
+                gResourceInterface, entityHandler, gResourceProperty, (OCTpsSchemeFlags)(OC_COAP || OC_COAP_TCP)));
+    }
+#endif
+
     //UnregisterTest
     TEST(UnregisterTest, UnregisterZeroHandleValue)
     {
@@ -803,6 +847,12 @@ namespace OCPlatformTest
                         OC::QualityOfService::NaQos));
     }
 
+    TEST(GetSupportedTransportsInfoTest, getSupportedTransportsInfoWithValidParm)
+    {
+        OCTpsSchemeFlags input = OC_NO_TPS;
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::getSupportedTransportsInfo(input));
+    }
+
     //RegisterDeviceInfo test
     TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithValidParameters)
     {
index fc4b40b..2139930 100644 (file)
@@ -512,6 +512,42 @@ namespace OCResourceTest
         EXPECT_TRUE(resource->host() == "coap://[ffff::ffff%25eth0]:5000");
     }
 
+    // EmptyHosts Test
+    TEST(HostsTest, EmptyHosts)
+    {
+        OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
+        EXPECT_TRUE(resource != NULL);
+        EXPECT_TRUE(resource->getAllHosts().empty());
+    }
+
+    // SetHost Test
+    TEST(SetHostTest, SetHost)
+    {
+        OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
+        EXPECT_TRUE(resource != NULL);
+        EXPECT_TRUE(resource->host() == "coap://192.168.1.2:5000");
+        EXPECT_TRUE(resource->setHost("coap://192.168.1.1:5000") == "coap://192.168.1.1:5000");
+    }
+
+    // SetHost Test2
+    TEST(SetHostTest, SetHost2)
+    {
+        OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
+        EXPECT_TRUE(resource != NULL);
+        EXPECT_TRUE(resource->host() == "coap://192.168.1.2:5000");
+        EXPECT_TRUE(resource->setHost("coap://[3731:54:65fe:2::a7]:32787") ==
+                                      "coap://[3731:54:65fe:2::a7]:32787");
+    }
+
+    // SetHost Test3
+    TEST(SetHostTest, SetHost3)
+    {
+        OCResource::Ptr resource = ConstructResourceObject("coap://[3731:54:65fe:2::a7]:32787", "/resource");
+        EXPECT_TRUE(resource != NULL);
+        EXPECT_TRUE(resource->host() == "coap://[3731:54:65fe:2::a7]:32787");
+        EXPECT_TRUE(resource->setHost("coap://192.168.1.2:5000") == "coap://192.168.1.2:5000");
+    }
+
     //Uri Test
     TEST(UriTest, Uri)
     {
@@ -521,11 +557,19 @@ namespace OCResourceTest
     }
 
     //ConnectivityType Test
-    TEST(ConnectivityTypeTest, ConnectivityType)
+    TEST(ConnectivityTypeTest, ConnectivityTypeIpv4)
     {
         OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000", "/resource");
         EXPECT_TRUE(resource != NULL);
-        EXPECT_TRUE(resource->connectivityType() == CT_DEFAULT);
+        EXPECT_TRUE(resource->connectivityType() == (CT_ADAPTER_IP | CT_IP_USE_V4));
+    }
+
+    //ConnectivityType Test
+    TEST(ConnectivityTypeTest, ConnectivityTypeIpv6)
+    {
+        OCResource::Ptr resource = ConstructResourceObject("coap://[fe80::52b7:c3ff:fead:dc0d%25eth0]:5000", "/resource");
+        EXPECT_TRUE(resource != NULL);
+        EXPECT_TRUE(resource->connectivityType() == (CT_ADAPTER_IP | CT_IP_USE_V6));
     }
 
     //IsObservable Test