Merge branch 'master' into extended-easysetup
authorJihun Ha <jihun.ha@samsung.com>
Sun, 24 Jul 2016 12:30:03 +0000 (21:30 +0900)
committerJihun Ha <jihun.ha@samsung.com>
Sun, 24 Jul 2016 12:30:03 +0000 (21:30 +0900)
Conflicts:
service/easy-setup/mediator/csdk/src/provisioning.cpp
service/easy-setup/mediator/csdk/src/provisioningapi.cpp
service/easy-setup/mediator/csdk/src/wifiprovisioning.cpp

Change-Id: I80e0b7917869577e0716516fa95d9c21c7290cc7
Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
59 files changed:
build_common/SConscript
cloud/interface/pom.xml
cloud/stack/pom.xml
examples/OICMiddle/SConscript
resource/c_common/SConscript
resource/c_common/oic_time/include/oic_time.h
resource/c_common/oic_time/src/oic_time.c
resource/csdk/SConscript
resource/csdk/connectivity/SConscript
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/common/src/camutex_pthreads.c
resource/csdk/connectivity/src/adapter_util/caadapterutils.c
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c
resource/csdk/connectivity/src/tcp_adapter/catcpserver.c
resource/csdk/connectivity/test/ca_api_unittest.cpp
resource/csdk/connectivity/test/cablocktransfertest.cpp
resource/csdk/logger/src/logger.c
resource/csdk/security/include/internal/aclresource.h
resource/csdk/security/include/internal/psinterface.h
resource/csdk/security/include/internal/srmresourcestrings.h
resource/csdk/security/provisioning/ck_manager/sample/Door_sample.cpp
resource/csdk/security/provisioning/include/internal/secureresourceprovider.h
resource/csdk/security/provisioning/sample/provisioningclient.c
resource/csdk/security/provisioning/src/ocprovisioningmanager.c
resource/csdk/security/provisioning/src/secureresourceprovider.c
resource/csdk/security/src/aclresource.c
resource/csdk/security/src/psinterface.c
resource/csdk/security/src/pstatresource.c
resource/csdk/security/src/srmresourcestrings.c
resource/csdk/stack/include/internal/ocresourcehandler.h
resource/csdk/stack/include/ocstackconfig.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp
resource/csdk/stack/samples/tizen/SimpleClientServer/occlient.cpp
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/test/linux/occlient.c
resource/csdk/stack/test/stacktests.cpp
resource/examples/SConscript
resource/include/IClientWrapper.h
resource/include/InProcClientWrapper.h
resource/include/OCApi.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OCResource.h
resource/include/OCSerialization.h
resource/include/OutOfProcClientWrapper.h
resource/src/InProcClientWrapper.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp
resource/src/OCResource.cpp
resource/src/SConscript
resource/unittests/OCPlatformTest.cpp
resource/unittests/SConscript
service/resource-encapsulation/src/common/primitiveResource/src/RCSRepresentation.cpp
service/resource-encapsulation/src/resourceCache/src/DataCache.cpp

index 1c570e0..9756ca0 100644 (file)
@@ -86,8 +86,9 @@ help_vars.Add(EnumVariable('TARGET_OS', 'Target platform', host, host_target_map
 
 help_vars.Add(BoolVariable('WITH_RA', 'Build with Remote Access module', False))
 help_vars.Add(BoolVariable('WITH_TCP', 'Build with TCP adapter', False))
+help_vars.Add(ListVariable('WITH_MQ', 'Build with MQ publisher/broker', 'OFF', ['OFF', 'SUB', 'PUB', 'BROKER']))
 help_vars.Add(EnumVariable('WITH_RD', 'Build including Resource Directory', '0', allowed_values=('0', '1')))
-help_vars.Add(BoolVariable('WITH_CLOUD', 'Build including Cloud client sample', False))
+help_vars.Add(BoolVariable('WITH_CLOUD', 'Build including Cloud Connector and Cloud Client sample', False))
 
 help_vars.Add(BoolVariable('SIMULATOR', 'Build with simulator module', False))
 
index b8528f6..a713f8b 100644 (file)
                        <artifactId>CloudResourceDirectory</artifactId>
                        <version>0.0.1-SNAPSHOT</version>
                </dependency>
-               <dependency>
-                       <groupId>log4j</groupId>
-                       <artifactId>log4j</artifactId>
-                       <version>1.2.17</version>
-               </dependency>
        </dependencies>
 
        <build>
index faeedc7..80273b4 100644 (file)
@@ -3,12 +3,11 @@
   <groupId>org.iotivity.cloud</groupId>
   <artifactId>CloudStack</artifactId>
   <version>0.0.1-SNAPSHOT</version>
-  
+
   <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <maven.test.skip>true</maven.test.skip>
        </properties>
-       
   <dependencies>
                <dependency>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>jackson-dataformat-cbor</artifactId>
                        <version>2.7.4</version>
                </dependency>
+               <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.17</version>
+        </dependency>
        </dependencies>
-       
   <build>
                <plugins>
                        <plugin>
@@ -66,5 +69,4 @@
                        </plugin>
                </plugins>
        </build>
-  
 </project>
\ No newline at end of file
index 340dbe5..98a4d84 100644 (file)
@@ -69,6 +69,9 @@ if target_os == 'android':
 if target_os in ['darwin', 'ios']:
        examples_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE'])
 
+if env.get('WITH_CLOUD'):
+       examples_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
index 2b46f5c..f412655 100644 (file)
@@ -44,14 +44,16 @@ else:
 if target_os in ['tizen', 'linux']:
        env.ParseConfig("pkg-config --cflags --libs uuid")
 
-env.PrependUnique(LIBS = ['c_common'])
-
 common_env = env.Clone()
 common_env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource')])
 
 ######################################################################
 # Build flags
 ######################################################################
+common_conf = Configure(common_env)
+if common_conf.CheckFunc('QueryPerformanceFrequency'):
+       common_env.AppendUnique(CPPDEFINES = ['HAVE_QUERYPERFORMANCEFREQUENCY'])
+common_env = common_conf.Finish()
 
 ######################################################################
 # Source files and Targets
@@ -67,3 +69,5 @@ commonlib = common_env.StaticLibrary('c_common', common_src)
 common_env.InstallTarget(commonlib, 'c_common')
 common_env.UserInstallTargetLib(commonlib, 'c_common')
 common_env.UserInstallTargetHeader('platform_features.h', 'resource', 'platform_features.h')
+
+env.PrependUnique(LIBS = ['c_common'])
index 0deba60..6ca9e3e 100644 (file)
@@ -53,6 +53,8 @@ typedef enum
  * @param     precision   based on this parameter, current time is returned in milliseconds or
  *                        microseconds
  *
+ * @warning   This function may be sensitive to system time changes on some platforms.
+ *
  * @note
  *            On Arduino platform:
  *            if the time precision is in milliseconds then the function will overflow
index 0cf2388..0b094f5 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <stddef.h>        // For NULL
 
-#if defined(_WIN32)
+#if defined(HAVE_WINDOWS_H)
 # include <windows.h>
 #elif !defined(WITH_ARDUINO)
 # if _POSIX_TIMERS > 0
@@ -52,21 +52,21 @@ uint64_t OICGetCurrentTime(OICTimePrecision precision)
 
 #ifdef WITH_ARDUINO
     currentTime = (TIME_IN_MS == precision) ? millis() : micros();
-#elif defined(_WIN32)
-    FILETIME fileTime;
+#elif defined(HAVE_QUERYPERFORMANCEFREQUENCY)
+    static LARGE_INTEGER frequency = {0};
 
-    GetSystemTimePreciseAsFileTime(&fileTime);
-
-    // fileTime should now be a QWORD hundred-nanoseconds time since 1601
+    if (!frequency.QuadPart)
+    {
+        QueryPerformanceFrequency(&frequency);
+    }
 
-    // MSDN recommends using ULARGE_INTEGER as an intermediate representation for math.
-    ULARGE_INTEGER time = { .LowPart  = fileTime.dwLowDateTime,
-                            .HighPart = fileTime.dwHighDateTime };
+    LARGE_INTEGER count = {0};
+    QueryPerformanceCounter(&count);
 
     currentTime =
     (TIME_IN_MS == precision)
-        ? time.QuadPart / (HNS_PER_US * US_PER_MS)
-        : time.QuadPart / (HNS_PER_US);
+        ? count.QuadPart / (frequency.QuadPart / MS_PER_SEC)
+        : count.QuadPart / (frequency.QuadPart / US_PER_SEC);
 #else
 # if _POSIX_TIMERS > 0
 #   if defined(CLOCK_MONOTONIC_COARSE)
index 559eb95..9b31045 100644 (file)
@@ -32,6 +32,7 @@ target_os = env.get('TARGET_OS')
 with_ra = env.get('WITH_RA')
 with_ra_ibb = env.get('WITH_RA_IBB')
 with_tcp = env.get('WITH_TCP')
+with_mq = env.get('WITH_MQ')
 # As in the source code, it includes arduino Time library (C++)
 # It requires compile the .c with g++
 if target_os == 'arduino':
@@ -58,6 +59,13 @@ liboctbstack_env.PrependUnique(CPPPATH = [
                'security/provisioning/include',
                ])
 
+if 'SUB' in with_mq:
+       liboctbstack_env.AppendUnique(CPPDEFINES = ['MQ_SUBSCRIBER', 'WITH_MQ'])
+if 'PUB' in with_mq:
+       liboctbstack_env.AppendUnique(CPPDEFINES = ['MQ_PUBLISHER', 'WITH_MQ'])
+if 'BROKER' in with_mq:
+       liboctbstack_env.AppendUnique(CPPDEFINES = ['MQ_BROKER', 'WITH_MQ'])
+
 if target_os not in ['arduino', 'windows']:
        liboctbstack_env.AppendUnique(CPPDEFINES  = ['WITH_POSIX'])
        liboctbstack_env.AppendUnique(CFLAGS = ['-std=c99'])
index 34b6ac1..42927bf 100644 (file)
@@ -9,10 +9,12 @@ transport = env.get('TARGET_TRANSPORT')
 build_sample = env.get('BUILD_SAMPLE')
 with_ra = env.get('WITH_RA')
 with_tcp = env.get('WITH_TCP')
+with_mq = env.get('WITH_MQ')
 
 print "Given Transport is %s" % transport
 print "Given OS is %s" % target_os
 print "BUILD_SAMPLE is %s" % build_sample
+print "MQ flag is %s" % with_mq
 
 targets_disallow_multitransport = ['arduino']
 
@@ -83,4 +85,16 @@ else:
        else:
                env.AppendUnique(CPPDEFINES = ['NO_NFC_ADAPTER'])
 
+if 'SUB' in with_mq:
+       env.AppendUnique(CPPDEFINES = ['MQ_SUBSCRIBER', 'WITH_MQ'])
+       print "MQ SUB support"
+
+if 'PUB' in with_mq:
+       env.AppendUnique(CPPDEFINES = ['MQ_PUBLISHER', 'WITH_MQ'])
+       print "MQ PUB support"
+
+if 'BROKER' in with_mq:
+       env.AppendUnique(CPPDEFINES = ['MQ_BROKER', 'WITH_MQ'])
+       print "MQ Broker support"
+
 env.SConscript('./src/SConscript')
index 58f8744..d9c2c47 100644 (file)
@@ -155,12 +155,12 @@ typedef int    CASocketFd_t;
 #define MAX_ADDR_STR_SIZE_CA (256)
 #else
 /*
- * Max Address could be "coap+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:yyy.yyy.yyy.yyy]:xxxxx"
- * Which is 64, +1 for null terminator => 65
+ * Max Address could be "coaps+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:yyy.yyy.yyy.yyy]:xxxxx"
+ * Which is 65, +1 for null terminator => 66
  * OCDevAddr (defined in OCTypes.h) must be the same
  * as CAEndpoint_t (defined here)
  */
-#define MAX_ADDR_STR_SIZE_CA (65)
+#define MAX_ADDR_STR_SIZE_CA (66)
 #endif
 
 typedef enum
index ef344fd..db790ec 100644 (file)
@@ -425,8 +425,8 @@ CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseco
             retVal = CA_WAIT_SUCCESS;
         }
 #else
-        int ret;
-        struct timespec abstime;
+        int ret = 0;
+        struct timespec abstime = { .tv_sec = 0 };
 
 #ifdef __ANDROID__
         if (camutex_cond_timedwait_relative)
index 9ddc7e8..888885b 100644 (file)
@@ -176,7 +176,7 @@ void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storag
     VERIFY_NON_NULL_VOID(host, CA_ADAPTER_UTILS_TAG, "host is null");
     VERIFY_NON_NULL_VOID(sockaddr, CA_ADAPTER_UTILS_TAG, "sockaddr is null");
 
-    struct addrinfo *addrs;
+    struct addrinfo *addrs = NULL;
     struct addrinfo hints = { .ai_family = AF_UNSPEC,
                               .ai_socktype = SOCK_DGRAM,
                               .ai_flags = AI_NUMERICHOST };
index 360d449..8108328 100644 (file)
@@ -485,9 +485,11 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags)
 {
     char recvBuffer[COAP_MAX_PDU_SIZE] = {0};
 
-    size_t len;
-    int level, type, namelen;
-    struct sockaddr_storage srcAddr;
+    size_t len = 0;
+    int level = 0;
+    int type = 0;
+    int namelen = 0;
+    struct sockaddr_storage srcAddr = { .ss_family = 0 };
     unsigned char *pktinfo = NULL;
 #if !defined(WSA_CMSG_DATA)
     struct cmsghdr *cmp = NULL;
@@ -667,7 +669,7 @@ static CASocketFd_t CACreateSocket(int family, uint16_t *port, bool isMulticast)
     }
 #endif
     struct sockaddr_storage sa = { .ss_family = family };
-    socklen_t socklen;
+    socklen_t socklen = 0;
 
     if (family == AF_INET6)
     {
@@ -1207,10 +1209,10 @@ static void sendData(int fd, const CAEndpoint_t *endpoint,
     (void)cast;  // eliminates release warning
     (void)fam;
 
-    struct sockaddr_storage sock;
+    struct sockaddr_storage sock = { .ss_family = 0 };
     CAConvertNameToAddr(endpoint->addr, endpoint->port, &sock);
 
-    socklen_t socklen;
+    socklen_t socklen = 0;
     if (sock.ss_family == AF_INET6)
     {
         /** @todo figure out correct usage for ifindex, and sin6_scope_id */
index cf1a771..40a0552 100644 (file)
@@ -218,11 +218,15 @@ CAInterface_t *CAFindInterfaceChange()
 {
     CAInterface_t *foundNewInterface = NULL;
 #ifdef __linux__
-    char buf[4096];
-    struct nlmsghdr *nh;
-    struct sockaddr_nl sa;
-    struct iovec iov = { buf, sizeof (buf) };
-    struct msghdr msg = { (void *)&sa, sizeof (sa), &iov, 1, NULL, 0, 0 };
+    char buf[4096] = { 0 };
+    struct nlmsghdr *nh = NULL;
+    struct sockaddr_nl sa = { .nl_family = 0 };
+    struct iovec iov = { .iov_base = buf,
+                         .iov_len = sizeof (buf) };
+    struct msghdr msg = { .msg_name = (void *)&sa,
+                          .msg_namelen = sizeof (sa),
+                          .msg_iov = &iov,
+                          .msg_iovlen = 1 };
 
     size_t len = recvmsg(caglobals.ip.netlinkFd, &msg, 0);
 
index 2300a4d..737c41d 100644 (file)
 #define TAG "OIC_CA_TCP_SERVER"
 
 /**
- * Server port number for local test.
- */
-#define SERVER_PORT 8000
-
-/**
  * Maximum CoAP over TCP header length
  * to know the total data length.
  */
@@ -481,7 +476,7 @@ static int CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem)
     }
 
     // #3. set socket length.
-    socklen_t socklen;
+    socklen_t socklen = 0;
     if (sa.ss_family == AF_INET6)
     {
         struct sockaddr_in6 *sock6 = (struct sockaddr_in6 *)&sa;
@@ -519,7 +514,7 @@ static int CACreateAcceptSocket(int family, CASocket_t *sock)
         return sock->fd;
     }
 
-    socklen_t socklen;
+    socklen_t socklen = 0;
     struct sockaddr_storage server = { .ss_family = family };
 
     int fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
index 6a94700..eccca11 100644 (file)
@@ -29,7 +29,8 @@
 
 class CATests : public testing::Test {
     protected:
-    virtual void SetUp() {
+    virtual void SetUp()
+    {
         CAInitialize();
     }
 
index 77cb32f..5efc456 100644 (file)
@@ -213,14 +213,18 @@ TEST_F(CABlockTransferTests, CAGetPayloadFromBlockDataListTest)
     CABlockData_t *currData = CACreateNewBlockData(cadata);
     EXPECT_TRUE(currData != NULL);
 
-    size_t fullPayload = 0;
-    CAPayload_t payload = CAGetPayloadFromBlockDataList(currData->blockDataId,
-                                                        &fullPayload);
+    if (currData)
+    {
+        size_t fullPayload = 0;
+        CAPayload_t payload = CAGetPayloadFromBlockDataList(currData->blockDataId,
+                                                            &fullPayload);
 
-    size_t payloadLen = (payload != NULL) ? strlen((const char*) payload) : 0;
-    EXPECT_TRUE(fullPayload == payloadLen);
+        size_t payloadLen = (payload != NULL) ? strlen((const char*) payload) : 0;
+        EXPECT_TRUE(fullPayload == payloadLen);
+
+        CARemoveBlockDataFromList(currData->blockDataId);
+    }
 
-    CARemoveBlockDataFromList(currData->blockDataId);
     CADestroyDataSet(cadata);
     coap_delete_list(options);
     coap_delete_pdu(pdu);
@@ -306,12 +310,15 @@ TEST_F(CABlockTransferTests, CAAddBlockOption1InRequest)
     CABlockData_t *currData = CACreateNewBlockData(cadata);
     EXPECT_TRUE(currData != NULL);
 
-    EXPECT_EQ(CA_STATUS_OK, CAUpdateBlockOptionType(currData->blockDataId,
-                                                    COAP_OPTION_BLOCK1));
+    if (currData)
+    {
+        EXPECT_EQ(CA_STATUS_OK, CAUpdateBlockOptionType(currData->blockDataId,
+                                                        COAP_OPTION_BLOCK1));
 
-    EXPECT_EQ(CA_STATUS_OK, CAAddBlockOption1(&pdu, &requestData,
-                                              requestData.payloadSize,
-                                              currData->blockDataId, &options));
+        EXPECT_EQ(CA_STATUS_OK, CAAddBlockOption1(&pdu, &requestData,
+                                                  requestData.payloadSize,
+                                                  currData->blockDataId, &options));
+    }
 
     CADestroyDataSet(cadata);
     coap_delete_list(options);
@@ -359,12 +366,15 @@ TEST_F(CABlockTransferTests, CAAddBlockOption1InResponse)
     CABlockData_t *currData = CACreateNewBlockData(cadata);
     EXPECT_TRUE(currData != NULL);
 
-    EXPECT_EQ(CA_STATUS_OK, CAUpdateBlockOptionType(currData->blockDataId,
-                                                    COAP_OPTION_BLOCK1));
+    if (currData)
+    {
+        EXPECT_EQ(CA_STATUS_OK, CAUpdateBlockOptionType(currData->blockDataId,
+                                                        COAP_OPTION_BLOCK1));
 
-    EXPECT_EQ(CA_STATUS_OK, CAAddBlockOption1(&pdu, &responseData,
-                                              responseData.payloadSize,
-                                              currData->blockDataId, &options));
+        EXPECT_EQ(CA_STATUS_OK, CAAddBlockOption1(&pdu, &responseData,
+                                                  responseData.payloadSize,
+                                                  currData->blockDataId, &options));
+    }
 
     CADestroyDataSet(cadata);
     coap_delete_list(options);
@@ -412,12 +422,15 @@ TEST_F(CABlockTransferTests, CAAddBlockOption2InResponse)
     CABlockData_t *currData = CACreateNewBlockData(cadata);
     EXPECT_TRUE(currData != NULL);
 
-    EXPECT_EQ(CA_STATUS_OK, CAUpdateBlockOptionType(currData->blockDataId,
-                                                    COAP_OPTION_BLOCK2));
+    if (currData)
+    {
+        EXPECT_EQ(CA_STATUS_OK, CAUpdateBlockOptionType(currData->blockDataId,
+                                                        COAP_OPTION_BLOCK2));
 
-    EXPECT_EQ(CA_STATUS_OK, CAAddBlockOption2(&pdu, &responseData,
-                                              responseData.payloadSize,
-                                              currData->blockDataId, &options));
+        EXPECT_EQ(CA_STATUS_OK, CAAddBlockOption2(&pdu, &responseData,
+                                                  responseData.payloadSize,
+                                                  currData->blockDataId, &options));
+    }
 
     CADestroyDataSet(cadata);
     coap_delete_list(options);
@@ -464,14 +477,16 @@ TEST_F(CABlockTransferTests, CAAddBlockOption2InRequest)
     CABlockData_t *currData = CACreateNewBlockData(cadata);
     EXPECT_TRUE(currData != NULL);
 
-    EXPECT_EQ(CA_STATUS_OK, CAUpdateBlockOptionType(currData->blockDataId,
-                                                    COAP_OPTION_BLOCK2));
+    if (currData)
+    {
+        EXPECT_EQ(CA_STATUS_OK, CAUpdateBlockOptionType(currData->blockDataId,
+                                                        COAP_OPTION_BLOCK2));
 
-    EXPECT_EQ(CA_STATUS_OK, CAAddBlockOption2(&pdu, &requestData,
-                                              requestData.payloadSize,
-                                              currData->blockDataId, &options));
+        EXPECT_EQ(CA_STATUS_OK, CAAddBlockOption2(&pdu, &requestData,
+                                                  requestData.payloadSize,
+                                                  currData->blockDataId, &options));
+    }
 
-    CARemoveBlockDataFromList(currData->blockDataId);
     CADestroyDataSet(cadata);
     coap_delete_list(options);
     coap_delete_pdu(pdu);
index 7a32b46..cc7f303 100644 (file)
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+
+#ifdef HAVE_ARDUINO_TIME_H
+#include <Time.h>
+#else
 #include <time.h>
+#endif
+
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
index 2b83f81..7daf51f 100644 (file)
@@ -63,6 +63,19 @@ const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t **
 OCStackResult AclToCBORPayload(const OicSecAcl_t * acl, uint8_t **outPayload, size_t *size);
 
 /**
+ * This method removes ACE for the subject and resource from the ACL
+ *
+ * @param subject of the ACE
+ * @param resource of the ACE
+ *
+ * @return
+ *     ::OC_STACK_RESOURCE_DELETED on success
+ *     ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
+ *     ::OC_STACK_INVALID_PARAM on invalid parameter
+ */
+OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource);
+
+/**
  * This function deletes ACL data.
  *
  * @param acl instance of @ref OicSecAcl_t structure to be deleted.
index 34a7822..493690a 100644 (file)
@@ -71,4 +71,21 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat
  */
 OCStackResult UpdateSecureResourceInPS(const char* rsrcName, uint8_t* cborPayload, size_t size);
 
+/**
+ * This method resets the secure resources according to the reset profile.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult ResetSecureResourceInPS(void);
+
+/**
+ * This method creates the reset profile from the persistent storage.
+ * The reset profile is the copy of the initial state of SVR resources
+ * when secure resources are initiated at first.
+ * In remote reset, the SVR will be reset according to the reset profile.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult CreateResetProfile(void);
+
 #endif //IOTVT_SRM_PSI_H
index 7e84a76..d9e8de8 100644 (file)
@@ -89,6 +89,9 @@ extern const char * OIC_RSRC_TYPE_SEC_VER;
 extern const char * OIC_RSRC_VER_URI;
 extern const char * OIC_JSON_VER_NAME;
 
+//reset profile
+extern const char * OIC_JSON_RESET_PF_NAME;
+
 extern const char * OIC_JSON_SUBJECT_NAME;
 extern const char * OIC_JSON_SUBJECTID_NAME;
 extern const char * OIC_JSON_RESOURCES_NAME;
index 316d0da..2807263 100644 (file)
@@ -442,7 +442,7 @@ void SendGetRequest()
 
     initAddress();
 
-    char szQueryUri[64] = { '\0'};
+    char szQueryUri[MAX_QUERY_LENGTH] = { '\0'};
     OCDoHandle handle;
     OCCallbackData cbData;
     cbData.cb = getReqCB;
@@ -462,7 +462,7 @@ void SendGetRequest()
 void *input_function(void * /*data*/)
 {
     char input;
-    char szQueryUri[64] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
     OCDoHandle handle;
     OCCallbackData cbData;
     cbData.cb = discoveryReqCB;
index fe4e546..5fbc284 100644 (file)
@@ -152,6 +152,39 @@ OCStackResult SRPRemoveDevice(void* ctx,
                               const OCProvisionDev_t* pTargetDev,
                               OCProvisionResultCB resultCallback);
 
+/*
+ * Function to sync-up credential and ACL of the target device.
+ * This function will remove credential and ACL of target device from all devices in subnet.
+ *
+ * @param[in] ctx Application context would be returned in result callback
+ * @param[in] waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device discovery.(seconds)
+ * @param[in] pTargetDev Device information to be revoked.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            credential revocation is finished.
+ *            when there is an error, this user callback is called immediately.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ *         If OC_STACK_OK is returned, the caller of this API should wait for callback.
+ *         OC_STACK_CONTINUE means operation is success but no request is need to be initiated.
+ */
+OCStackResult SRPSyncDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDiscovery,
+                         const OCProvisionDev_t* pTargetDev, OCProvisionResultCB resultCallback);
+
+/*
+ * Function for remote reset
+ * This function will send pstat POST(modify) message to the target device
+ * to change current mode to reset state in order to initiate remote reset.
+ *
+ * @param[in] pTargetDev Device information to be revoked.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            credential revocation is finished.
+ *            when there is an error, this user callback is called immediately.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ *         If OC_STACK_OK is returned, the caller of this API should wait for callback.
+ *         OC_STACK_CONTINUE means operation is success but no request is need to be initiated.
+ */
+OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
+        OCProvisionResultCB resultCallback);
+
 #ifdef __cplusplus
 }
 #endif
index a22e393..a2dc06c 100644 (file)
@@ -50,11 +50,12 @@ extern "C"
 #define _30_PROVIS_PAIR_DEVS_   30
 #define _31_PROVIS_CRED_        31
 #define _32_PROVIS_ACL_         32
-#define _33_PROVIS_DP_           33
+#define _33_PROVIS_DP_          33
 #define _34_CHECK_LINK_STATUS_  34
 #define _40_UNLINK_PAIR_DEVS_   40
 #define _50_REMOVE_SELEC_DEV_   50
-#define _60_GET_CRED_  60
+#define _51_RESET_SELEC_DEV_    51
+#define _60_GET_CRED_           60
 #define _61_GET_ACL_            61
 #define _99_EXIT_PRVN_CLT_      99
 
@@ -226,6 +227,20 @@ static void removeDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool
     g_doneCB = true;
 }
 
+static void syncDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
+{
+    if(!hasError)
+    {
+        OIC_LOG_V(INFO, TAG, "Sync Device SUCCEEDED - ctx: %s", (char*) ctx);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "Sync Device FAILED - ctx: %s", (char*) ctx);
+        printResultList((const OCProvisionResult_t*) arr, nOfRes);
+    }
+    g_doneCB = true;
+}
+
 static void inputPinCB(char* pin, size_t len)
 {
     if(!pin || OXM_RANDOM_PIN_SIZE>=len)
@@ -1031,6 +1046,58 @@ static int removeDevice(void)
     return 0;
 }
 
+static int resetDevice(void)
+{
+    // check |own_list| for removing device
+    if (!g_own_list || 1 > g_own_cnt)
+    {
+        printf("   > Owned Device List, to Reset Device, is Empty\n");
+        printf("   > Please Register Unowned Devices first, with [20] Menu\n");
+        return 0;
+    }
+
+    // select device for removing it
+    int dev_num = 0;
+    for ( ; ; )
+    {
+        printf("   > Enter Device Number, for Resetting Device: ");
+        for (int ret = 0; 1 != ret; )
+        {
+            ret = scanf("%d", &dev_num);
+            for ( ; 0x20 <= getchar() ; );  // for removing overflow garbages
+                                            // '0x20 <= code' is character region
+        }
+        if (0 < dev_num && g_own_cnt >= dev_num)
+        {
+            break;
+        }
+        printf("     Entered Wrong Number. Please Enter Again\n");
+    }
+
+    g_doneCB = false;
+    printf("   Resetting Selected Owned Device..\n");
+
+    OCStackResult rst = OCResetDevice((void *) g_ctx, DISCOVERY_TIMEOUT,
+                    getDevInst((const OCProvisionDev_t *) g_own_list, dev_num), syncDeviceCB);
+    if (OC_STACK_OK != rst)
+    {
+        OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst);
+        return -1;
+    }
+
+    if (waitCallbackRet())  // input |g_doneCB| flag implicitly
+    {
+        OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
+        return -1;
+    }
+
+    // display the removed result
+    printf("   > Reset Selected Owned Device SUCCEEDED\n");
+    printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
+
+    return 0;
+}
+
 static OicSecAcl_t* createAcl(const int dev_num)
 {
     if(0>=dev_num || g_own_cnt<dev_num)
@@ -1492,7 +1559,8 @@ static void printMenu(void)
     printf("** 40. Unlink Pairwise Things\n\n");
 
     printf("** [E] REMOVE THE SELECTED DEVICE\n");
-    printf("** 50. Remove the Selected Device\n\n");
+    printf("** 50. Remove the Selected Device\n");
+    printf("** 51. Reset the Selected Device\n\n");
 
     printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
     printf("** 60. Get the Credential resources of the Selected Device\n");
@@ -1616,6 +1684,12 @@ int main()
                 OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error");
             }
             break;
+        case _51_RESET_SELEC_DEV_:
+            if(resetDevice())
+            {
+                OIC_LOG(ERROR, TAG, "_51_RESET_SELEC_DEV_: error");
+            }
+            break;
         case _60_GET_CRED_:
             if(getCred())
             {
index ad8133d..488903d 100644 (file)
@@ -407,6 +407,53 @@ error:
     return res;
 }
 
+/*
+ * Function to reset the target device.
+ * This function will remove credential and ACL of target device from all devices in subnet.
+ *
+ * @param[in] ctx Application context would be returned in result callback
+ * @param[in] waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device discovery.(seconds)
+ * @param[in] pTargetDev Device information to be revoked.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            credential revocation is finished.
+ * @return  OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OCResetDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDiscovery,
+                            const OCProvisionDev_t* pTargetDev,
+                            OCProvisionResultCB resultCallback)
+{
+    OIC_LOG(INFO, TAG, "IN OCResetDevice");
+    OCStackResult res = OC_STACK_ERROR;
+    if (!pTargetDev || 0 == waitTimeForOwnedDeviceDiscovery)
+    {
+        OIC_LOG(INFO, TAG, "OCResetDevice : Invalid parameters");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (!resultCallback)
+    {
+        OIC_LOG(INFO, TAG, "OCResetDevice : NULL Callback");
+        return OC_STACK_INVALID_CALLBACK;
+    }
+
+    // Send DELETE requests to linked devices
+    res = SRPSyncDevice(ctx, waitTimeForOwnedDeviceDiscovery, pTargetDev, resultCallback);
+    if (OC_STACK_CONTINUE == res)
+    {
+        OIC_LOG(DEBUG, TAG, "OCResetDevice : Target device has no linked device except PT.");
+        if(resultCallback)
+        {
+            resultCallback(ctx, 0, NULL, false);
+        }
+        SRPResetDevice(pTargetDev, resultCallback);
+        res = OC_STACK_OK;
+    }
+    else if(OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to invoke SRPSyncDevice");
+    }
+    OIC_LOG(INFO, TAG, "OUT OCResetDevice");
+    return res;
+}
 
 /**
  * Internal Function to update result in link result array.
index 35aebec..a51bd37 100644 (file)
@@ -1177,6 +1177,64 @@ static OCStackResult SendDeleteCredentialRequest(void* ctx,
     return ret;
 }
 
+static OCStackResult SendDeleteACLRequest(void* ctx,
+                                                 OCClientResponseHandler respHandler,
+                                                 const OCProvisionDev_t* revokedDev,
+                                                 const OCProvisionDev_t* destDev)
+{
+    OIC_LOG(DEBUG, TAG, "IN SendDeleteACLRequest");
+
+    if (NULL == ctx || NULL == respHandler || NULL == revokedDev || NULL == destDev)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    char *subID = NULL;
+    OCStackResult ret = ConvertUuidToStr(&revokedDev->doxm->deviceID, &subID);
+    if(OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "SendDeleteACLRequest : Failed to canonical UUID encoding");
+        return OC_STACK_ERROR;
+    }
+
+    char reqBuf[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    int snRet = 0;
+                    //coaps://0.0.0.0:5684/oic/sec/acl?subjectuuid=(Canonical ENCODED UUID)
+    snRet = snprintf(reqBuf, sizeof(reqBuf), SRP_FORM_DELETE_CREDENTIAL, destDev->endpoint.addr,
+                     destDev->securePort, OIC_RSRC_ACL_URI, OIC_JSON_SUBJECTID_NAME, subID);
+    OICFree(subID);
+    if (snRet < 0)
+    {
+        OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Error (snprintf) %d\n", snRet);
+        return OC_STACK_ERROR;
+    }
+    else if ((size_t)snRet >= sizeof(reqBuf))
+    {
+        OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Truncated (snprintf) %d\n", snRet);
+        return OC_STACK_ERROR;
+    }
+
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(cbData));
+    cbData.context = ctx;
+    cbData.cb = respHandler;
+    cbData.cd = NULL;
+    OIC_LOG_V(INFO, TAG, "URI: %s",reqBuf);
+
+    OIC_LOG(DEBUG, TAG, "Sending remove ACL request to resource server");
+
+    ret = OCDoResource(NULL, OC_REST_DELETE, reqBuf,
+                                     &destDev->endpoint, NULL,
+                                     CT_ADAPTER_IP, OC_HIGH_QOS, &cbData, NULL, 0);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "SendDeleteACLRequest : Error in OCDoResource %d", ret);
+    }
+    OIC_LOG(DEBUG, TAG, "OUT SendDeleteACLRequest");
+
+    return ret;
+}
+
 /**
  * Callback handler of unlink second device.
  *
@@ -1450,6 +1508,34 @@ static void registerResultForRemoveDevice(RemoveData_t *removeData, OicUuid_t *p
     }
  }
 
+static void registerResultForResetDevice(RemoveData_t *removeData, OicUuid_t *pLinkedDevId,
+                                          OCStackResult stackresult, bool hasError)
+{
+    OIC_LOG_V(INFO, TAG, "Inside registerResultForResetDevice removeData->numOfResults is %zu\n",
+                         removeData->numOfResults + 1);
+    if (pLinkedDevId)
+    {
+        memcpy(removeData->removeRes[(removeData->numOfResults)].deviceId.id,
+               &pLinkedDevId->id, sizeof(pLinkedDevId->id));
+    }
+    else
+    {
+        memset(removeData->removeRes[(removeData->numOfResults)].deviceId.id,
+               0, sizeof(pLinkedDevId->id) );
+    }
+    removeData->removeRes[(removeData->numOfResults)].res = stackresult;
+    removeData->hasError = hasError;
+    ++(removeData->numOfResults);
+
+    // If we get suffcient result from linked devices, we have to call user callback and do free
+    if (removeData->sizeOfResArray == removeData->numOfResults)
+    {
+        removeData->resultCallback(removeData->ctx, removeData->numOfResults, removeData->removeRes,
+                                   removeData->hasError);
+        DeleteRemoveData_t(removeData);
+    }
+}
+
 /**
  * Callback handler of unlink first device.
  *
@@ -1529,6 +1615,171 @@ static OCStackApplicationResult SRPRemoveDeviceCB(void *delDevCtx, OCDoHandle ha
     return OC_STACK_DELETE_TRANSACTION;
 }
 
+/**
+ * Callback handler of reset device.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] handle          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult SRPSyncDeviceCredCB(void *delDevCtx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
+{
+    //Update the delete credential into delete device context
+    //Save the deleted status in delDevCtx
+    (void)handle;
+    OIC_LOG_V(INFO, TAG, "Inside SRPSyncDeviceCredCB.");
+    VERIFY_NON_NULL(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    OCStackResult res = OC_STACK_ERROR;
+
+    RemoveData_t* removeData = (RemoveData_t*)delDevCtx;
+    OCProvisionDev_t * pTargetDev = PMCloneOCProvisionDev(removeData->revokeTargetDev);
+    OCProvisionResultCB resultCallback = removeData->resultCallback;
+    if (clientResponse)
+    {
+        OicUuid_t revDevUuid = {.id={0}};
+        if(UUID_LENGTH == clientResponse->identity.id_length)
+        {
+            memcpy(revDevUuid.id, clientResponse->identity.id, sizeof(revDevUuid.id));
+            if (OC_STACK_RESOURCE_DELETED == clientResponse->result)
+            {
+                res = PDMUnlinkDevices(&removeData->revokeTargetDev->doxm->deviceID, &revDevUuid);
+                if (OC_STACK_OK != res)
+                {
+                    OIC_LOG(ERROR, TAG, "PDMSetLinkStale() FAIL: PDB is an obsolete one.");
+                           registerResultForResetDevice(removeData, &revDevUuid,
+                           OC_STACK_INCONSISTENT_DB, true);
+
+                    return OC_STACK_DELETE_TRANSACTION;
+                }
+
+                registerResultForResetDevice(removeData, &revDevUuid,
+                                              OC_STACK_RESOURCE_DELETED, false);
+            }
+            else
+            {
+                registerResultForResetDevice(removeData, &revDevUuid,
+                                              clientResponse->result, false);
+                OIC_LOG(ERROR, TAG, "Unexpected result from DELETE credential request!");
+            }
+        }
+        else
+        {
+            OIC_LOG_V(WARNING, TAG, "Incorrect length of device UUID was sent from %s:%d",
+                     clientResponse->devAddr.addr, clientResponse->devAddr.port);
+
+            if (OC_STACK_RESOURCE_DELETED == clientResponse->result)
+            {
+                /**
+                  * Since server's credential was deleted,
+                  * register result as OC_STACK_INCONSISTENT_DB with NULL UUID.
+                  */
+                OIC_LOG_V(ERROR, TAG, "But server's credential was deleted.");
+                registerResultForResetDevice(removeData, NULL, OC_STACK_INCONSISTENT_DB, true);
+            }
+            else
+            {
+                registerResultForResetDevice(removeData, NULL, clientResponse->result, true);
+            }
+        }
+    }
+    else
+    {
+        registerResultForResetDevice(removeData, NULL, OC_STACK_ERROR, true);
+        OIC_LOG(ERROR, TAG, "SRPSyncDevice received Null clientResponse");
+    }
+
+    SRPResetDevice(pTargetDev, resultCallback);
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+/**
+ * Callback handler of reset device sync-up
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] handle          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult SRPSyncDeviceACLCB(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
+{
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+/**
+ * Callback handler of device remote reset.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] handle          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult SRPResetDeviceCB(void *ctx, OCDoHandle handle,
+        OCClientResponse *clientResponse)
+{
+    OIC_LOG(DEBUG, TAG, "IN SRPResetDeviceCB");
+    if(OC_STACK_OK == clientResponse->result)
+    {
+        OIC_LOG(DEBUG, TAG, "Change Target Device Pstat Cm SUCCEEDED");
+    }
+
+    // Delete Cred and ACL related to the target device.
+    const OicSecCred_t *cred = NULL;
+    OCProvisionDev_t * pTargetDev = (OCProvisionDev_t *)ctx;
+    cred = GetCredResourceData(&pTargetDev->doxm->deviceID);
+    if (cred == NULL)
+    {
+        OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to get credential of target device.");
+        goto error;
+    }
+
+    OCStackResult res = RemoveCredential(&cred->subject);
+    if (res != OC_STACK_RESOURCE_DELETED && res != OC_STACK_NO_RESOURCE)
+    {
+        OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to remove credential.");
+        goto error;
+    }
+
+    res = RemoveACE(&cred->subject, NULL);
+    if (res != OC_STACK_RESOURCE_DELETED && res != OC_STACK_NO_RESOURCE)
+    {
+        OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to remove ACL.");
+        goto error;
+    }
+    if (OC_STACK_OK != PDMDeleteDevice(&pTargetDev->doxm->deviceID))
+    {
+        OIC_LOG(ERROR, TAG, "OCResetDevice : Failed to delete device from PDM");
+    }
+
+    //Close the DTLS session of the reset device.
+    CAEndpoint_t* endpoint = (CAEndpoint_t *)&clientResponse->devAddr;
+    CAResult_t caResult = CACloseDtlsSession(endpoint);
+    if(CA_STATUS_OK != caResult)
+    {
+        OIC_LOG_V(WARNING, TAG, "OCResetDevice : Failed to close DTLS session : %d", caResult);
+    }
+
+    /**
+     * If there is no linked device, PM does not send any request.
+     * So we should directly invoke the result callback to inform the result of OCResetDevice.
+     */
+    if(OC_STACK_NO_RESOURCE == res)
+    {
+        res = OC_STACK_OK;
+    }
+
+error:
+    OICFree(pTargetDev);
+    return OC_STACK_DELETE_TRANSACTION;
+
+}
+
 static OCStackResult GetListofDevToReqDeleteCred(const OCProvisionDev_t* pRevokeTargetDev,
                                                  OCProvisionDev_t* pOwnedDevList,
                                                  OCUuidList_t* pLinkedUuidList,
@@ -1728,6 +1979,270 @@ error:
     return res;
 }
 
+/*
+ * Function to sync-up credential and ACL of the target device.
+ * This function will remove credential and ACL of target device from all devices in subnet.
+ *
+ * @param[in] ctx Application context would be returned in result callback
+ * @param[in] waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device discovery.(seconds)
+ * @param[in] pTargetDev Device information to be revoked.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            credential revocation is finished.
+ *            when there is an error, this user callback is called immediately.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ *         If OC_STACK_OK is returned, the caller of this API should wait for callback.
+ *         OC_STACK_CONTINUE means operation is success but no request is need to be initiated.
+ */
+OCStackResult SRPSyncDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDiscovery,
+                         const OCProvisionDev_t* pTargetDev, OCProvisionResultCB resultCallback)
+{
+    OIC_LOG(INFO, TAG, "IN SRPSyncDevice");
+    if (!pTargetDev  || 0 == waitTimeForOwnedDeviceDiscovery)
+    {
+        OIC_LOG(INFO, TAG, "SRPSyncDevice : NULL parameters");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (!resultCallback)
+    {
+        OIC_LOG(INFO, TAG, "SRPSyncDevice : NULL Callback");
+        return OC_STACK_INVALID_CALLBACK;
+    }
+
+    // Declare variables in here to handle error cases with goto statement.
+    OCProvisionDev_t* pOwnedDevList = NULL;
+    OCProvisionDev_t* pLinkedDevList = NULL;
+    RemoveData_t* removeData = NULL;
+
+    //1. Find all devices that has a credential of the revoked device
+    OCUuidList_t* pLinkedUuidList = NULL;
+    size_t numOfDevices = 0;
+    OCStackResult res = OC_STACK_ERROR;
+    res = PDMGetLinkedDevices(&pTargetDev->doxm->deviceID, &pLinkedUuidList, &numOfDevices);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to get linked devices information");
+        return res;
+    }
+    // if there is no related device, we can skip further process.
+    if (0 == numOfDevices)
+    {
+        OIC_LOG(DEBUG, TAG, "SRPSyncDevice : No linked device found.");
+        res = OC_STACK_CONTINUE;
+        goto error;
+    }
+
+    //2. Find owned device from the network
+    res = PMDeviceDiscovery(waitTimeForOwnedDeviceDiscovery, true, &pOwnedDevList);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to PMDeviceDiscovery");
+        goto error;
+    }
+
+    //3. Make a list of devices to send DELETE credential request
+    //   by comparing owned devices from provisioning database with mutlicast discovery result.
+    size_t numOfLinkedDev = 0;
+    res = GetListofDevToReqDeleteCred(pTargetDev, pOwnedDevList, pLinkedUuidList,
+                                      &pLinkedDevList, &numOfLinkedDev);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "SRPSyncDevice : GetListofDevToReqDeleteCred() failed");
+        goto error;
+    }
+    if (0 == numOfLinkedDev) // This case means, there is linked device but it's not alive now.
+    {                       // So we don't have to send request message.
+        OIC_LOG(DEBUG, TAG, "SRPSyncDevice : No alived & linked device found.");
+        res = OC_STACK_CONTINUE;
+        goto error;
+    }
+
+    // 4. Prepare RemoveData Context data.
+    removeData = (RemoveData_t*)OICCalloc(1, sizeof(RemoveData_t));
+    if (!removeData)
+    {
+        OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to memory allocation");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+
+    removeData->revokeTargetDev = PMCloneOCProvisionDev(pTargetDev);
+    if (!removeData->revokeTargetDev)
+    {
+        OIC_LOG(ERROR, TAG, "SRPSyncDevice : PMCloneOCProvisionDev Failed");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+
+    removeData->removeRes =
+        (OCProvisionResult_t*)OICCalloc(numOfLinkedDev, sizeof(OCProvisionResult_t));
+    if (!removeData->removeRes)
+    {
+        OIC_LOG(ERROR, TAG, "SRPSyncDevice : Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+
+    removeData->ctx = ctx;
+    removeData->linkedDevList = pLinkedDevList;
+    removeData->resultCallback = resultCallback;
+    removeData->numOfResults = 0;
+    removeData->sizeOfResArray = numOfLinkedDev;
+    removeData->hasError = false;
+
+    // 5. Send DELETE credential request to linked devices.
+    OCProvisionDev_t *curDev = NULL, *tmpDev = NULL;
+    OCStackResult totalRes = OC_STACK_ERROR;  /* variable for checking request is sent or not */
+    LL_FOREACH_SAFE(pLinkedDevList, curDev, tmpDev)
+    {
+        res = SendDeleteACLRequest((void*)removeData, &SRPSyncDeviceACLCB,
+                                           removeData->revokeTargetDev, curDev);
+        if (OC_STACK_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "SRPSyncDevice : Fail to send the DELETE ACL request to\
+                     %s:%u", curDev->endpoint.addr, curDev->endpoint.port);
+            goto error;
+        }
+        res = SendDeleteCredentialRequest((void*)removeData, &SRPSyncDeviceCredCB,
+                                           removeData->revokeTargetDev, curDev);
+        if (OC_STACK_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "SRPSyncDevice : Fail to send the DELETE credential request to\
+                     %s:%u", curDev->endpoint.addr, curDev->endpoint.port);
+            totalRes = OC_STACK_ERROR;
+        }
+        else
+        {
+            totalRes = OC_STACK_OK; // This means at least one request is successfully sent.
+        }
+    }
+
+    PDMDestoryOicUuidLinkList(pLinkedUuidList); //TODO: Modify API name to have unified convention.
+    PMDeleteDeviceList(pOwnedDevList);
+    OIC_LOG(INFO, TAG, "OUT SRPSyncDevice");
+
+    return totalRes; // Caller of this API should wait callback if totalRes == OC_STACK_OK.
+
+error:
+    PDMDestoryOicUuidLinkList(pLinkedUuidList);
+    PMDeleteDeviceList(pOwnedDevList);
+    PMDeleteDeviceList(pLinkedDevList);
+    if (removeData)
+    {
+        OICFree(removeData->revokeTargetDev);
+        OICFree(removeData->removeRes);
+        OICFree(removeData);
+    }
+    OIC_LOG(INFO, TAG, "OUT ERROR case SRPSyncDevice");
+    return res;
+}
+
+/*
+ * Function for remote reset
+ * This function will send pstat PUT message to the target device to initiate remote reset.
+ *
+ * @param[in] pTargetDev Device information to be revoked.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            credential revocation is finished.
+ *            when there is an error, this user callback is called immediately.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ *         If OC_STACK_OK is returned, the caller of this API should wait for callback.
+ *         OC_STACK_CONTINUE means operation is success but no request is need to be initiated.
+ */
+OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
+        OCProvisionResultCB resultCallback)
+{
+    OIC_LOG(INFO, TAG, "IN SRPResetDevice");
+    if (!pTargetDev)
+    {
+        OIC_LOG(INFO, TAG, "SRPResetDevice : NULL parameters");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (!resultCallback)
+    {
+        OIC_LOG(INFO, TAG, "SRPResetDevice : NULL Callback");
+        return OC_STACK_INVALID_CALLBACK;
+    }
+
+    OCStackResult res = OC_STACK_ERROR;
+    OicSecPstat_t * pstat = (OicSecPstat_t *) OICCalloc(1, sizeof(OicSecPstat_t));
+    if (!pstat)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+
+    pstat->cm = (OicSecDpm_t) 1;
+    pstat->isOp = 0;
+    memcpy(pstat->deviceID.id, pTargetDev->doxm->deviceID.id, sizeof(OicUuid_t));
+    pstat->tm = (OicSecDpm_t) 2;
+    pstat->om = (OicSecDpom_t) 0;
+    pstat->smLen = 1;
+    pstat->sm = (OicSecDpom_t *) OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+    if (NULL == pstat->sm)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+        OICFree(pstat);
+        return OC_STACK_NO_MEMORY;
+    }
+    pstat->sm[0] = (OicSecDpom_t) 3;
+
+    OCSecurityPayload * secPayload = (OCSecurityPayload *) OICCalloc(1, sizeof(OCSecurityPayload));
+    if (!secPayload)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+
+    if (OC_STACK_OK != PstatToCBORPayload(pstat, &(secPayload->securityData),
+                &(secPayload->payloadSize)))
+    {
+        OCPayloadDestroy((OCPayload *) secPayload);
+        OIC_LOG(ERROR, TAG, "Failed to PstatToCBORPayload");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    OIC_LOG(DEBUG, TAG, "Created payload for pstat set");
+    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if (!PMGenerateQuery(true,
+                pTargetDev->endpoint.addr,
+                pTargetDev->securePort,
+                pTargetDev->connType,
+                query, sizeof(query), OIC_RSRC_PSTAT_URI))
+    {
+        OIC_LOG(ERROR, TAG, "SRPResetDevice : Failed to generate query");
+        OCPayloadDestroy((OCPayload *) secPayload);
+        res = OC_STACK_ERROR;
+        goto error;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    OCProvisionDev_t * targetDev = PMCloneOCProvisionDev(pTargetDev);
+    OCCallbackData cbData = { .context = NULL, .cb = NULL, .cd = NULL };
+    cbData.cb = &SRPResetDeviceCB;
+    cbData.context = (void *) targetDev;
+    cbData.cd = NULL;
+    OCMethod method = OC_REST_POST;
+    OCDoHandle handle = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending PSTAT info to resource server");
+    res = OCDoResource(&handle, method, query,
+            &targetDev->endpoint, (OCPayload *)secPayload,
+            targetDev->connType, OC_LOW_QOS, &cbData, NULL, 0);\
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+    }
+
+error:
+    OICFree(pstat->sm);
+    OICFree(pstat);
+    OIC_LOG(INFO, TAG, "OUT SRPResetDevice");
+    return res;
+}
+
 /**
  * Internal Function to store results in result array during GetCredResourceCB.
  */
index 9537efc..e3aef30 100644 (file)
@@ -949,7 +949,7 @@ exit:
  *     ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
  *     ::OC_STACK_INVALID_PARAM on invalid parameter
  */
-static OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
+OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
 {
     OIC_LOG(DEBUG, TAG, "IN RemoveACE");
 
index d263892..7043f81 100644 (file)
@@ -36,6 +36,8 @@
 #include "secureresourcemanager.h"
 #include "srmresourcestrings.h"
 #include "srmutility.h"
+#include "pstatresource.h"
+#include "doxmresource.h"
 
 #define TAG  "SRM-PSI"
 
@@ -180,6 +182,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
     uint8_t *svcCbor = NULL;
     uint8_t *credCbor = NULL;
     uint8_t *pconfCbor = NULL;
+    uint8_t *resetPfCbor = NULL;
 
     int64_t cborEncoderResult = CborNoError;
     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
@@ -192,6 +195,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
         size_t svcCborLen = 0;
         size_t credCborLen = 0;
         size_t pconfCborLen = 0;
+        size_t resetPfCborLen = 0;
 
         // Gets each secure virtual resource from persistent storage
         // this local scoping intended, for destroying large cbor instances after use
@@ -244,13 +248,20 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
             }
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
+            }
         }
 
         // Updates the added |psPayload| with the existing secure virtual resource(s)
         // this local scoping intended, for destroying large cbor instances after use
         {
             size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
-                        + svcCborLen + credCborLen + pconfCborLen + psSize + 255;
+                        + svcCborLen + credCborLen + pconfCborLen + resetPfCborLen
+                        + psSize + 255;
             // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
 
             outPayload = (uint8_t *) OICCalloc(1, size);
@@ -317,6 +328,13 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
             }
+            if (strcmp(OIC_JSON_RESET_PF_NAME, rsrcName) && resetPfCborLen)
+            {
+                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
+                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
+            }
 
             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
@@ -348,7 +366,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
 
     if (outPayload && outSize)
     {
-        OIC_LOG_V(DEBUG, TAG, "Writting in the file: %zu", outSize);
+        OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
         OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
         if (ps)
         {
@@ -386,5 +404,290 @@ exit:
     OICFree(svcCbor);
     OICFree(credCbor);
     OICFree(pconfCbor);
+    OICFree(resetPfCbor);
+    return ret;
+}
+
+/**
+ * Resets the Secure Virtual Resource(s).
+ * This function reads the Reset Profile
+ * and resets the secure virtual resources accordingly.
+ *
+ * @return OCStackResult - result of updating Secure Virtual Resource(s)
+ */
+OCStackResult ResetSecureResourceInPS(void)
+{
+    OIC_LOG(DEBUG, TAG, "ResetSecureResourceInPS IN");
+
+    size_t dbSize = 0;
+    size_t outSize = 0;
+    uint8_t *dbData = NULL;
+    uint8_t *outPayload = NULL;
+
+    uint8_t *aclCbor = NULL;
+    uint8_t *pstatCbor = NULL;
+    uint8_t *doxmCbor = NULL;
+    uint8_t *resetPfCbor = NULL;
+
+    int64_t cborEncoderResult = CborNoError;
+    OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
+
+    if(dbData && dbSize)
+    {
+        size_t aclCborLen = 0;
+        size_t pstatCborLen = 0;
+        size_t doxmCborLen = 0;
+        size_t resetPfCborLen = 0;
+
+        // Gets the reset profile from persistent storage
+        {
+            CborParser parser;  // will be initialized in |cbor_parser_init|
+            CborValue cbor;     // will be initialized in |cbor_parser_init|
+            cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
+            CborValue curVal = {0};
+            CborError cborFindResult = CborNoError;
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
+            }
+        }
+
+        // Gets each secure virtual resource from the reset profile
+        {
+            CborParser parser;  // will be initialized in |cbor_parser_init|
+            CborValue cbor;     // will be initialized in |cbor_parser_init|
+            cbor_parser_init(resetPfCbor, resetPfCborLen, 0, &parser, &cbor);
+            CborValue curVal = {0};
+            CborError cborFindResult = CborNoError;
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
+            }
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
+            }
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
+            }
+        }
+
+        {
+            size_t size = aclCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
+            // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
+
+            outPayload = (uint8_t *) OICCalloc(1, size);
+            VERIFY_NON_NULL(TAG, outPayload, ERROR);
+            CborEncoder encoder;
+            cbor_encoder_init(&encoder, outPayload, size, 0);
+            CborEncoder secRsrc;
+            cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
+
+            cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
+            cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
+
+            cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
+            cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
+
+            cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
+            cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
+
+            cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_RESET_PF_NAME, strlen(OIC_JSON_RESET_PF_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Name.");
+            cborEncoderResult |= cbor_encode_byte_string(&secRsrc, resetPfCbor, resetPfCborLen);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Reset Profile Value.");
+
+            cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
+            outSize = encoder.ptr - outPayload;
+        }
+
+        if (outPayload && outSize)
+        {
+            OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
+            OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
+            if (ps)
+            {
+                FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
+                if (fp)
+                {
+                    size_t numberItems = ps->write(outPayload, 1, outSize, fp);
+                    if (outSize == numberItems)
+                    {
+                        OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
+                        ret= OC_STACK_OK;
+                    }
+                    else
+                    {
+                        OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
+                    }
+                    ps->close(fp);
+                }
+                else
+                {
+                    OIC_LOG(ERROR, TAG, "File open failed.");
+                }
+
+            }
+        }
+    }
+
+    SRMDeInitSecureResources();
+    InitSecureResources();
+    OIC_LOG(DEBUG, TAG, "ResetSecureResourceINPS OUT");
+
+exit:
+    OICFree(dbData);
+    OICFree(outPayload);
+    OICFree(aclCbor);
+    OICFree(pstatCbor);
+    OICFree(doxmCbor);
+    OICFree(resetPfCbor);
+}
+
+/**
+ * Creates Reset Profile from the initial secure virtual resources.
+ * This function copies the secure resources
+ * and creates the Reset Profile in the Persistent Storage.
+ * Device ID in doxm and pstat are left empty as it will be renewed after reset.
+ *
+ * @return OCStackResult - result of updating Secure Virtual Resource(s)
+ */
+OCStackResult CreateResetProfile(void)
+{
+    OIC_LOG(DEBUG, TAG, "CreateResetProfile IN");
+
+    size_t dbSize = 0;
+    uint8_t *dbData = NULL;
+
+    uint8_t *aclCbor = NULL;
+    uint8_t *pstatCbor = NULL;
+    uint8_t *doxmCbor = NULL;
+    uint8_t *resetPfCbor = NULL;
+
+    OCStackResult ret = OC_STACK_ERROR;
+    int64_t cborEncoderResult = CborNoError;
+    ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
+    if (dbData && dbSize)
+    {
+        size_t aclCborLen = 0;
+        size_t pstatCborLen = 0;
+        size_t doxmCborLen = 0;
+        size_t resetPfCborLen = 0;
+
+        {
+            CborParser parser;
+            CborValue cbor;
+            cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
+            CborValue curVal = {0};
+            CborError cborFindResult = CborNoError;
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
+            }
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
+            }
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
+            }
+        }
+
+        // Set the Device ID in doxm and pstat to empty
+        if (pstatCbor)
+        {
+            OicSecPstat_t *pstat = NULL;
+            ret = CBORPayloadToPstat(pstatCbor, pstatCborLen, &pstat);
+            OICFree(pstatCbor);
+            pstatCbor = NULL;
+            pstatCborLen = 0;
+
+            OicUuid_t emptyUuid = {.id = {0} };
+            memcpy(&pstat->deviceID, &emptyUuid, sizeof(OicUuid_t));
+            memcpy(&pstat->rownerID, &emptyUuid, sizeof(OicUuid_t));
+
+            ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborLen);
+            OICFree(pstat);
+        }
+        if (doxmCbor)
+        {
+            OicSecDoxm_t *doxm = NULL;
+            ret = CBORPayloadToDoxm(doxmCbor, doxmCborLen, &doxm);
+            OICFree(doxmCbor);
+            doxmCbor = NULL;
+            doxmCborLen = 0;
+
+            OicUuid_t emptyUuid = {.id = {0} };
+            memcpy(&doxm->deviceID, &emptyUuid, sizeof(OicUuid_t));
+            memcpy(&doxm->rownerID, &emptyUuid, sizeof(OicUuid_t));
+
+            ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborLen);
+            OICFree(doxm);
+        }
+
+        {
+            size_t size = aclCborLen + pstatCborLen + doxmCborLen + 255;
+            resetPfCbor = (uint8_t *) OICCalloc(1, size);
+            VERIFY_NON_NULL(TAG, resetPfCbor, ERROR);
+            CborEncoder encoder;  // will be initialized in |cbor_parser_init|
+            cbor_encoder_init(&encoder, resetPfCbor, size, 0);
+            CborEncoder secRsrc;  // will be initialized in |cbor_encoder_create_map|
+            cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
+
+            cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
+            cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
+
+            cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
+            cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
+
+            cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
+            cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
+
+            cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
+            resetPfCborLen = encoder.ptr - resetPfCbor;
+        }
+
+        UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
+
+    }
+    OIC_LOG(DEBUG, TAG, "CreateResetProfile OUT");
+
+exit:
+    OICFree(dbData);
+    OICFree(aclCbor);
+    OICFree(pstatCbor);
+    OICFree(doxmCbor);
+    OICFree(resetPfCbor);
     return ret;
 }
+
index 050c497..3d49a4b 100644 (file)
@@ -448,7 +448,12 @@ static OCEntityHandlerResult HandlePstatPostRequest(const OCEntityHandlerRequest
         VERIFY_NON_NULL(TAG, pstat, ERROR);
         if (OC_STACK_OK == ret)
         {
-            if (false == (pstat->cm & TAKE_OWNER) && false == pstat->isOp)
+            if (true == (pstat->cm & RESET) && false == pstat->isOp)
+            {
+                gPstat->cm = pstat->cm;
+                OIC_LOG(INFO, TAG, "State changed to Ready for Reset");
+            }
+            else if (false == (pstat->cm & TAKE_OWNER) && false == pstat->isOp)
             {
                 gPstat->cm = pstat->cm;
                 OIC_LOG (INFO, TAG, "State changed to Ready for Provisioning");
@@ -482,6 +487,23 @@ static OCEntityHandlerResult HandlePstatPostRequest(const OCEntityHandlerRequest
             {
                 ehRet = OC_EH_OK;
             }
+            if (true == (pstat->cm & RESET))
+            {
+                if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+                {
+                    ehRet = OC_EH_ERROR;
+                    OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest");
+                    DeletePstatBinData(pstat);
+                    return ehRet;
+                }
+                ret = ResetSecureResourceInPS();
+                if (OC_STACK_OK == ret)
+                {
+                    ehRet = OC_EH_OK;
+                }
+                DeletePstatBinData(pstat);
+                return ehRet;
+            }
         }
     }
  exit:
index 5414ef6..20f54bf 100644 (file)
@@ -83,6 +83,9 @@ const char * OIC_RSRC_TYPE_SEC_VER = "oic.r.ver";
 const char * OIC_RSRC_VER_URI =  "/oic/sec/ver";
 const char * OIC_JSON_VER_NAME = "ver";
 
+//reset profile
+const char * OIC_JSON_RESET_PF_NAME = "resetpf";
+
 const char * OIC_JSON_SUBJECT_NAME = "subject";
 const char * OIC_JSON_RESOURCES_NAME = "resources";
 const char * OIC_JSON_AMSS_NAME = "amss";
index 8b77e34..ba25f5d 100644 (file)
@@ -72,8 +72,14 @@ typedef enum
     OC_PRESENCE,
     #endif
 
+#ifdef MQ_BROKER
+    /** "/oic/ps" .*/
+    OC_MQ_BROKER_URI,
+#endif
+
     /** Max items in the list */
     OC_MAX_VIRTUAL_RESOURCES    //<s Max items in the list
+
 } OCVirtualResources;
 
 /**
index 8680c7f..96afa7a 100644 (file)
@@ -39,7 +39,7 @@
  * Maximum length of the query supported by client/server while processing
  * REST requests/responses.
  */
-#define MAX_QUERY_LENGTH (64)
+#define MAX_QUERY_LENGTH (256)
 
 /**
  * Maximum length of the Manufacturer name supported by the server
@@ -63,7 +63,7 @@
  *  Maximum number of vendor specific header options an application can set or receive
  *  in PDU
  */
-#define MAX_HEADER_OPTIONS (2)
+#define MAX_HEADER_OPTIONS (100)
 
 /**
  *  Maximum Length of the vendor specific header option
index 7ea3819..b132d6e 100644 (file)
@@ -68,11 +68,20 @@ extern "C" {
 /** Gateway URI.*/
 #define OC_RSRVD_GATEWAY_URI                  "/oic/gateway"
 #endif
+
+#ifdef WITH_MQ
+/** MQ Broker URI.*/
+#define OC_RSRVD_WELL_KNOWN_MQ_URI            "/.well-known/ocf/ps"
+#endif
+
 #ifdef WITH_PRESENCE
 
 /** Presence URI through which the OIC devices advertise their presence.*/
 #define OC_RSRVD_PRESENCE_URI                 "/oic/ad"
 
+/** Presence URI through which the OCF devices advertise their device presence.*/
+#define OCF_RSRVD_DEVICE_PRESENCE_URI         "/.well-known/ocf/prs"
+
 /** Sets the default time to live (TTL) for presence.*/
 #define OC_DEFAULT_PRESENCE_TTL_SECONDS (60)
 
@@ -146,6 +155,14 @@ extern "C" {
 /** To represent resource type with RES.*/
 #define OC_RSRVD_RESOURCE_TYPE_RES    "oic.wk.res"
 
+#ifdef WITH_MQ
+/** To represent content type with MQ Broker.*/
+#define OC_RSRVD_RESOURCE_TYPE_MQ_BROKER     "ocf.wk.ps"
+
+/** To represent content type with MQ Topic.*/
+#define OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC      "ocf.wk.ps.topic"
+#endif
+
 /** To represent interface.*/
 #define OC_RSRVD_INTERFACE              "if"
 
@@ -282,10 +299,10 @@ extern "C" {
 #define MAX_ADDR_STR_SIZE (256)
 #else
 /** Max Address could be
- * "coap+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:yyy.yyy.yyy.yyy]:xxxxx"
+ * "coaps+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:yyy.yyy.yyy.yyy]:xxxxx"
  * +1 for null terminator.
  */
-#define MAX_ADDR_STR_SIZE (65)
+#define MAX_ADDR_STR_SIZE (66)
 #endif
 
 /** Length of MAC address */
@@ -338,6 +355,38 @@ extern "C" {
 /** To represent resource type with Publish RD.*/
 #define OC_RSRVD_RESOURCE_TYPE_RDPUBLISH "oic.wk.rdpub"
 
+/** Cloud Account */
+
+/** Account URI.*/
+#define OC_RSRVD_ACCOUNT_URI               "/.well-known/ocf/account"
+
+/** Account session URI.*/
+#define OC_RSRVD_ACCOUNT_SESSION_URI       "/.well-known/ocf/account/session"
+
+/** Account token refresh URI.*/
+#define OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI "/.well-known/ocf/account/tokenrefresh"
+
+/** Defines auth provider. */
+#define OC_RSRVD_AUTHPROVIDER              "authprovider"
+
+/** Defines auth code. */
+#define OC_RSRVD_AUTHCODE                  "authcode"
+
+/** Defines session. */
+#define OC_RSRVD_ACCESS_TOKEN              "accesstoken"
+
+/** Defines status. */
+#define OC_RSRVD_STATUS                    "status"
+
+/** Defines grant type. */
+#define OC_RSRVD_GRANT_TYPE                "granttype"
+
+/** Defines refresh token. */
+#define OC_RSRVD_REFRESH_TOKEN             "refreshtoken"
+
+/** To represent grant type with refresh token. */
+#define OC_RSRVD_GRANT_TYPE_REFRESH_TOKEN  "refresh_token"
+
 /**
  * Mark a parameter as unused. Used to prevent unused variable compiler warnings.
  * Used in three cases:
@@ -684,6 +733,16 @@ typedef enum
      *  if discovery request contains an explicit querystring.
      *  Ex: GET /oic/res?rt=oic.sec.acl */
     OC_EXPLICIT_DISCOVERABLE   = (1 << 5)
+
+#ifdef WITH_MQ
+    /** When this bit is set, the resource is allowed to be published */
+    ,OC_MQ_PUBLISHER     = (1 << 6)
+#endif
+
+#ifdef MQ_BROKER
+    /** When this bit is set, the resource is allowed to be notified as MQ broker.*/
+    ,OC_MQ_BROKER        = (1 << 7)
+#endif
 } OCResourceProperty;
 
 /**
@@ -810,7 +869,14 @@ typedef enum
     OC_OBSERVE_DEREGISTER = 1,
 
     /** Others. */
-    OC_OBSERVE_NO_OPTION = 2
+    OC_OBSERVE_NO_OPTION = 2,
+
+//#ifdef WITH_MQ
+    OC_MQ_SUBSCRIBER = 3,
+
+    OC_MQ_UNSUBSCRIBER = 4,
+//#endif
+
 } OCObserveAction;
 
 
index 123f969..fe7c8ae 100644 (file)
@@ -739,7 +739,7 @@ int InitPlatformDiscovery(OCQualityOfService qos)
 
     OCStackResult ret;
     OCCallbackData cbData;
-    char szQueryUri[64] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
 
     snprintf(szQueryUri, sizeof (szQueryUri) - 1, PLATFORM_DISCOVERY_QUERY, discoveryAddr);
 
@@ -764,7 +764,7 @@ int InitDeviceDiscovery(OCQualityOfService qos)
 
     OCStackResult ret;
     OCCallbackData cbData;
-    char szQueryUri[100] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
 
     snprintf(szQueryUri, sizeof (szQueryUri) - 1, DEVICE_DISCOVERY_QUERY, discoveryAddr);
 
@@ -787,7 +787,7 @@ int InitDiscovery(OCQualityOfService qos)
 {
     OCStackResult ret;
     OCCallbackData cbData;
-    char szQueryUri[100] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
 
     snprintf(szQueryUri, sizeof (szQueryUri) - 1, RESOURCE_DISCOVERY_QUERY, discoveryAddr);
 
index f13c6bc..375b169 100644 (file)
@@ -356,7 +356,7 @@ int InitDiscovery()
     OCStackResult ret;
     OCCallbackData cbData;
     /* Start a discovery query*/
-    char szQueryUri[64] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
 
     strcpy(szQueryUri, RESOURCE_DISCOVERY_QUERY);
 
index a66a5fa..8b3d86e 100644 (file)
@@ -719,7 +719,7 @@ int InitPlatformDiscovery(OCQualityOfService qos)
 
     OCStackResult ret;
     OCCallbackData cbData;
-    char szQueryUri[64] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
 
     snprintf(szQueryUri, sizeof (szQueryUri) - 1, PLATFORM_DISCOVERY_QUERY, g_discoveryAddr);
 
@@ -744,7 +744,7 @@ int InitDeviceDiscovery(OCQualityOfService qos)
 
     OCStackResult ret;
     OCCallbackData cbData;
-    char szQueryUri[100] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
 
     snprintf(szQueryUri, sizeof (szQueryUri) - 1, DEVICE_DISCOVERY_QUERY, g_discoveryAddr);
 
@@ -767,7 +767,7 @@ int InitDiscovery(OCQualityOfService qos)
 {
     OCStackResult ret;
     OCCallbackData cbData;
-    char szQueryUri[100] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
 
     snprintf(szQueryUri, sizeof (szQueryUri) - 1, RESOURCE_DISCOVERY_QUERY, g_discoveryAddr);
 
index 362224b..da1b517 100644 (file)
@@ -1584,7 +1584,11 @@ static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t secureP
         }
     }
 
-    pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
+    pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
+#ifdef MQ_PUBLISHER
+                                            | OC_MQ_PUBLISHER
+#endif
+                                            );
     pl->secure = (res->resourceProperties & OC_SECURE) != 0;
     pl->port = securePort;
 #ifdef TCP_ADAPTER
index 86db477..44a2135 100755 (executable)
@@ -157,6 +157,12 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char
 
     OIC_LOG_V(INFO, TAG, "Extracting params from %s", query);
 
+    if (strnlen(query, MAX_QUERY_LENGTH) >= MAX_QUERY_LENGTH)
+    {
+        OIC_LOG(ERROR, TAG, "Query exceeds maximum length.");
+        return OC_STACK_INVALID_QUERY;
+    }
+
     char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
 
     while(keyValuePair)
@@ -225,6 +231,13 @@ static OCVirtualResources GetTypeOfVirtualURI(const char *uriInRequest)
         return OC_PRESENCE;
     }
 #endif //WITH_PRESENCE
+
+#ifdef MQ_BROKER
+    else if (0 == strcmp(uriInRequest, OC_RSRVD_WELL_KNOWN_MQ_URI))
+    {
+        return OC_MQ_BROKER_URI;
+    }
+#endif //MQ_BROKER
     return OC_UNKNOWN_URI;
 }
 
@@ -715,7 +728,11 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
     OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
 
     // Step 1: Generate the response to discovery request
-    if (virtualUriInRequest == OC_WELL_KNOWN_URI)
+    if (virtualUriInRequest == OC_WELL_KNOWN_URI
+#ifdef MQ_BROKER
+            || virtualUriInRequest == OC_MQ_BROKER_URI
+#endif
+            )
     {
         if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
         {
@@ -753,10 +770,19 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
 
                 if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
                 {
+                    OCResourceProperty prop = OC_DISCOVERABLE;
+#ifdef MQ_BROKER
+                    if (OC_MQ_BROKER_URI == virtualUriInRequest)
+                    {
+                        prop = OC_MQ_BROKER;
+                    }
+#endif
+
                     for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
                     {
                         bool result = false;
-                        if (resource->resourceProperties & OC_DISCOVERABLE)
+
+                        if (resource->resourceProperties & prop)
                         {
                             result = true;
                         }
index 963c6aa..d3e8922 100644 (file)
@@ -51,6 +51,7 @@
 #include "logger.h"
 #include "ocserverrequest.h"
 #include "secureresourcemanager.h"
+#include "psinterface.h"
 #include "doxmresource.h"
 #include "cacommon.h"
 #include "cainterface.h"
@@ -118,6 +119,10 @@ OCResource *headResource = NULL;
 static OCResource *tailResource = NULL;
 static OCResourceHandle platformResource = {0};
 static OCResourceHandle deviceResource = {0};
+#ifdef MQ_BROKER
+static OCResourceHandle brokerResource = {0};
+#endif
+
 #ifdef WITH_PRESENCE
 static OCPresenceState presenceState = OC_PRESENCE_UNINITIALIZED;
 static PresenceResource presenceResource = {0};
@@ -634,7 +639,6 @@ static OCStackResult CAResultToOCStackResult(CAResult_t caResult)
 OCStackResult CAResponseToOCStackResult(CAResponseResult_t caCode)
 {
     OCStackResult ret = OC_STACK_ERROR;
-
     switch(caCode)
     {
         case CA_CREATED:
@@ -698,7 +702,8 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method)
                    // This should not happen but,
                    // give it a value just in case but output an error
                    ret = CA_CONTENT;
-                   OIC_LOG_V(ERROR, TAG, "Unexpected OC_STACK_OK return code for method [%d].", method);
+                   OIC_LOG_V(ERROR, TAG, "Unexpected OC_STACK_OK return code for method [%d].",
+                            method);
             }
             break;
         case OC_STACK_RESOURCE_CREATED:
@@ -707,6 +712,9 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method)
         case OC_STACK_RESOURCE_DELETED:
             ret = CA_DELETED;
             break;
+        case OC_STACK_RESOURCE_CHANGED:
+            ret = CA_CHANGED;
+            break;
         case OC_STACK_INVALID_QUERY:
             ret = CA_BAD_REQ;
             break;
@@ -866,7 +874,8 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
 
     if (inputLength >= ENCODE_MAX_INPUT_LENGTH)
     {
-        OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: Invalid input string: too long/unterminated!");
+        OIC_LOG(ERROR, TAG,
+                "encodeAddressForRFC6874 failed: Invalid input string: too long/unterminated!");
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -1283,6 +1292,12 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
                     {
                         type = PAYLOAD_TYPE_DISCOVERY;
                     }
+#ifdef WITH_MQ
+                    else if (strcmp(cbNode->requestUri, OC_RSRVD_WELL_KNOWN_MQ_URI) == 0)
+                    {
+                        type = PAYLOAD_TYPE_DISCOVERY;
+                    }
+#endif
                     else if (strcmp(cbNode->requestUri, OC_RSRVD_DEVICE_URI) == 0)
                     {
                         type = PAYLOAD_TYPE_DEVICE;
@@ -1379,7 +1394,6 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
                             (observationOption << 8) | optionData[i];
                     }
                     response.sequenceNumber = observationOption;
-
                     response.numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions - 1;
                     start = 1;
                 }
@@ -3221,15 +3235,25 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
         return OC_STACK_INVALID_PARAM;
     }
 
-    if(!resourceInterfaceName || strlen(resourceInterfaceName) == 0)
+    if (!resourceInterfaceName || strlen(resourceInterfaceName) == 0)
     {
         resourceInterfaceName = OC_RSRVD_INTERFACE_DEFAULT;
     }
 
+#ifdef MQ_PUBLISHER
+    resourceProperties = resourceProperties | OC_MQ_PUBLISHER;
+#endif
     // Make sure resourceProperties bitmask has allowed properties specified
     if (resourceProperties
             > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW | OC_SECURE |
-               OC_EXPLICIT_DISCOVERABLE))
+               OC_EXPLICIT_DISCOVERABLE
+#ifdef MQ_PUBLISHER
+               | OC_MQ_PUBLISHER
+#endif
+#ifdef MQ_BROKER
+               | OC_MQ_BROKER
+#endif
+               ))
     {
         OIC_LOG(ERROR, TAG, "Invalid property");
         return OC_STACK_INVALID_PARAM;
@@ -4150,6 +4174,7 @@ OCStackResult initResources()
 
     if(result == OC_STACK_OK)
     {
+        CreateResetProfile();
         result = OCCreateResource(&deviceResource,
                                   OC_RSRVD_RESOURCE_TYPE_DEVICE,
                                   OC_RSRVD_INTERFACE_DEFAULT,
@@ -4233,6 +4258,9 @@ void deleteAllResources()
     }
     memset(&platformResource, 0, sizeof(platformResource));
     memset(&deviceResource, 0, sizeof(deviceResource));
+#ifdef MQ_BROKER
+    memset(&brokerResource, 0, sizeof(brokerResource));
+#endif
 
     SRMDeInitSecureResources();
 
@@ -4463,7 +4491,8 @@ void insertResourceInterface(OCResource *resource, OCResourceInterface *newInter
         }
         else
         {
-            OCStackResult result = BindResourceInterfaceToResource(resource, OC_RSRVD_INTERFACE_DEFAULT);
+            OCStackResult result = BindResourceInterfaceToResource(resource,
+                                                                    OC_RSRVD_INTERFACE_DEFAULT);
             if (result != OC_STACK_OK)
             {
                 OICFree(newInterface->name);
index 40132fd..d646439 100644 (file)
@@ -60,7 +60,7 @@ int main() {
     }
 
     /* Start a discovery query*/
-    char szQueryUri[64] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
     strcpy(szQueryUri, OC_EXPLICIT_DEVICE_DISCOVERY_URI);
     if (OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_LOW_QOS,
             0, 0, 0) != OC_STACK_OK) {
index 01ca65e..9bafe8e 100644 (file)
@@ -373,7 +373,7 @@ TEST(StackDiscovery, DISABLED_DoResourceDeviceDiscovery)
     InitStack(OC_CLIENT);
 
     /* Start a discovery query*/
-    char szQueryUri[64] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
     strcpy(szQueryUri, OC_RSRVD_WELL_KNOWN_URI);
     cbData.cb = asyncDoResourcesCallback;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
@@ -415,7 +415,7 @@ TEST(StackResource, DISABLED_UpdateResourceNullURI)
     InitStack(OC_CLIENT);
 
     /* Start a discovery query*/
-    char szQueryUri[64] = { 0 };
+    char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
     strcpy(szQueryUri, OC_RSRVD_WELL_KNOWN_URI);
     cbData.cb = asyncDoResourcesCallback;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
@@ -464,7 +464,7 @@ TEST(StackResource, CreateResourceBadParams)
                                             "/a/led",
                                             0,
                                             NULL,
-                                            128));// invalid bitmask for OCResourceProperty
+                                            255));// invalid bitmask for OCResourceProperty
 
     EXPECT_EQ(OC_STACK_OK, OCStop());
 }
@@ -1758,7 +1758,7 @@ TEST(StackResource, MultipleResourcesDiscovery)
                                             NULL,
                                             OC_DISCOVERABLE|OC_OBSERVABLE));
     /* Start a discovery query*/
-    char szQueryUri[256] = "/oic/res?if=oic.if.ll";
+    char szQueryUri[MAX_QUERY_LENGTH] = "/oic/res?if=oic.if.ll";
     OCCallbackData cbData;
     cbData.cb = discoveryCallback;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
index 895a2e5..c85806d 100644 (file)
@@ -73,12 +73,12 @@ if target_os in ['darwin', 'ios']:
 if examples_env.get('LOGGING'):
        examples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
+if examples_env.get('WITH_CLOUD'):
+       examples_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+
 if target_os in ['msys_nt', 'windows']:
        examples_env.AppendUnique(LIBS = ['Comctl32', 'Gdi32', 'User32'])
 
-if examples_env.get('LOGGING'):
-       examples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
-
 def make_single_file_cpp_program(program_name):
        return examples_env.Program(program_name, program_name + ".cpp")
 
index 0cbfa53..43e52c1 100644 (file)
@@ -77,6 +77,7 @@ namespace OC
                         const std::string& uri,
                         const OCRepresentation& rep, const QueryParamsMap& queryParams,
                         const HeaderOptions& headerOptions,
+                        OCConnectivityType connectivityType,
                         PostCallback& callback, QualityOfService QoS) = 0;
 
         virtual OCStackResult DeleteResource(
@@ -108,6 +109,12 @@ namespace OC
 
         virtual OCStackResult UnsubscribePresence(OCDoHandle handle) =0;
 
+        virtual OCStackResult SubscribeDevicePresence(OCDoHandle* handle,
+                                                      const std::string& host,
+                                                      const QueryParamsList& queryParams,
+                                                      OCConnectivityType connectivityType,
+                                                      ObserveCallback& callback) = 0;
+
         virtual OCStackResult GetDefaultQos(QualityOfService& qos) = 0;
 
         virtual OCStackResult FindDirectPairingDevices(unsigned short waittime,
@@ -115,9 +122,24 @@ namespace OC
 
         virtual OCStackResult GetDirectPairedDevices(GetDirectPairedCallback& callback) = 0;
 
-        virtual OCStackResult DoDirectPairing(std::shared_ptr<OCDirectPairing> peer, const OCPrm_t& pmSel,
-                const std::string& pinNumber, DirectPairingCallback& resultCallback) = 0;
-
+        virtual OCStackResult DoDirectPairing(std::shared_ptr< OCDirectPairing > peer,
+                                              const OCPrm_t& pmSel, const std::string& pinNumber,
+                                              DirectPairingCallback& resultCallback) = 0;
+
+#ifdef WITH_MQ
+        virtual OCStackResult ListenForMQTopic(
+            const OCDevAddr& devAddr,
+            const std::string& resourceUri,
+            const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+            FindCallback& callback, QualityOfService QoS) = 0;
+
+        virtual OCStackResult PutMQTopicRepresentation(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
+            const OCRepresentation& rep,
+            const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+            MQCreateTopicCallback& callback, QualityOfService QoS) = 0;
+#endif
         virtual ~IClientWrapper(){}
     };
 }
index c13edb1..e97c990 100644 (file)
@@ -99,6 +99,16 @@ namespace OC
             DirectPairingContext(DirectPairingCallback cb) : callback(cb){}
 
         };
+
+#ifdef WITH_MQ
+        struct CreateMQTopicContext
+        {
+            MQCreateTopicCallback callback;
+            std::weak_ptr<IClientWrapper> clientWrapper;
+            CreateMQTopicContext(MQCreateTopicCallback cb, std::weak_ptr<IClientWrapper> cw)
+                : callback(cb), clientWrapper(cw){}
+        };
+#endif
     }
 
     class InProcClientWrapper : public IClientWrapper
@@ -138,7 +148,8 @@ namespace OC
             const OCDevAddr& devAddr,
             const std::string& uri,
             const OCRepresentation& attributes, const QueryParamsMap& queryParams,
-            const HeaderOptions& headerOptions, PostCallback& callback, QualityOfService QoS);
+            const HeaderOptions& headerOptions, OCConnectivityType connectivityType,
+            PostCallback& callback, QualityOfService QoS);
 
         virtual OCStackResult DeleteResource(
             const OCDevAddr& devAddr,
@@ -167,8 +178,14 @@ namespace OC
             SubscribeCallback& presenceHandler);
 
         virtual OCStackResult UnsubscribePresence(OCDoHandle handle);
-        OCStackResult GetDefaultQos(QualityOfService& QoS);
 
+        virtual OCStackResult SubscribeDevicePresence(OCDoHandle* handle,
+                                                      const std::string& host,
+                                                      const QueryParamsList& queryParams,
+                                                      OCConnectivityType connectivityType,
+                                                      ObserveCallback& callback);
+
+        OCStackResult GetDefaultQos(QualityOfService& QoS);
 
         virtual OCStackResult FindDirectPairingDevices(unsigned short waittime,
                        GetDirectPairedCallback& callback);
@@ -178,9 +195,25 @@ namespace OC
         virtual OCStackResult DoDirectPairing(std::shared_ptr<OCDirectPairing> peer, const OCPrm_t& pmSel,
                 const std::string& pinNumber, DirectPairingCallback& resultCallback);
 
+#ifdef WITH_MQ
+        virtual OCStackResult ListenForMQTopic(
+            const OCDevAddr& devAddr,
+            const std::string& resourceUri,
+            const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+            FindCallback& callback, QualityOfService QoS);
+
+        virtual OCStackResult PutMQTopicRepresentation(
+            const OCDevAddr& devAddr,
+            const std::string& uri,
+            const OCRepresentation& rep,
+            const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+            MQCreateTopicCallback& callback, QualityOfService QoS);
+#endif
+
     private:
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
+        std::string assembleSetResourceUri(std::string uri, const QueryParamsList& queryParams);
         OCPayload* assembleSetResourcePayload(const OCRepresentation& attributes);
         OCHeaderOption* assembleHeaderOptions(OCHeaderOption options[],
            const HeaderOptions& headerOptions);
index d2ac74a..1188db1 100644 (file)
@@ -221,6 +221,9 @@ namespace OC
     // Typedef for query parameter map
     typedef std::map<std::string, std::string> QueryParamsMap;
 
+    // Typedef for query parameter map with Vector
+    typedef std::map< std::string, std::vector<std::string> > QueryParamsList;
+
     // Typedef for list of observation IDs
     typedef std::vector<OCObservationId> ObservationIds;
 
@@ -291,6 +294,10 @@ namespace OC
 
     typedef std::function<void(const PairedDevices&)> GetDirectPairedCallback;
 
+    typedef std::function<void(const HeaderOptions&,
+                               const OCRepresentation&, const int,
+                               std::shared_ptr<OCResource>)> MQCreateTopicCallback;
+
 } // namespace OC
 
 #endif
index a5c50e2..c3d540f 100644 (file)
@@ -535,6 +535,28 @@ namespace OC
         OCStackResult unsubscribePresence(OCPresenceHandle presenceHandle);
 
         /**
+         * Subscribes to a server's device presence change events.
+         *
+         * @param presenceHandle a handle object that can be used to identify this subscription
+         *               request.  It can be used to unsubscribe from these events in the future.
+         *               It will be set upon successful return of this method.
+         * @param host The IP address/addressable name of the server to subscribe to.
+         *               This should be in the format coap://address:port
+         * @param queryParams map which can have the query parameter name and list of value.
+         * @param observeHandler handles callback
+         *        The callback function will be invoked with a map of attribute name and values.
+         *        The callback function will also have the result from this observe operation
+         *        This will have error codes
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult subscribeDevicePresence(OCPresenceHandle& presenceHandle,
+                                              const std::string& host,
+                                              const QueryParamsList& queryParams,
+                                              OCConnectivityType connectivityType,
+                                              ObserveCallback callback);
+
+        /**
          * Creates a resource proxy object so that get/put/observe functionality
          * can be used without discovering the object in advance.  Note that the
          * consumer of this method needs to provide all of the details required to
@@ -615,6 +637,82 @@ namespace OC
         OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel,
                                      const std::string& pinNumber,
                                      DirectPairingCallback resultCallback);
+#ifdef WITH_CLOUD
+        /**
+         * API for Account Registration to Account Server
+         * @note Not supported on client mode for now since device id is not generated yet on
+         *       client mode. So it should be server or both mode for API to work.
+         *
+         * @param host Host IP Address of a account server.
+         * @param authProvider Provider name used for authentication.
+         * @param authCode The authorization code obtained by using an authorization server
+         *                 as an intermediary between the client and resource owner.
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         * @param cloudConnectHandler Callback function that will get the result of the operation.
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult signUp(const std::string& host,
+                             const std::string& authProvider,
+                             const std::string& authCode,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler);
+
+        /**
+         * API for Sign-In to Account Server
+         * @note Not supported on client mode for now since device id is not generated yet on
+         *       client mode. So it should be server or both mode for API to work.
+         *
+         * @param host Host IP Address of a account server.
+         * @param accessToken Identifier of the resource obtained by account registration.
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         * @param cloudConnectHandler Callback function that will get the result of the operation.
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult signIn(const std::string& host,
+                             const std::string& accessToken,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler);
+
+        /**
+         * API for Sign-Out to Account Server
+         * @note Not supported on client mode for now since device id is not generated yet on
+         *       client mode. So it should be server or both mode for API to work.
+         *
+         * @param host Host IP Address of a account server.
+         * @param accessToken Identifier of the resource obtained by account registration.
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         * @param cloudConnectHandler Callback function that will get the result of the operation.
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult signOut(const std::string& host,
+                              const std::string& accessToken,
+                              OCConnectivityType connectivityType,
+                              PostCallback cloudConnectHandler);
+
+        /**
+         * API for Refresh Access token to Account Server
+         * @note Not supported on client mode for now since device id is not generated yet on
+         *       client mode. So it should be server or both mode for API to work.
+         *
+         * @param host Host IP Address of a account server.
+         * @param refreshToken Refresh token used for access token refresh.
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         * @param cloudConnectHandler Callback function that will get the result of the operation.
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult refreshAccessToken(const std::string& host,
+                                         const std::string& refreshToken,
+                                         OCConnectivityType connectivityType,
+                                         PostCallback cloudConnectHandler);
+#endif // WITH_CLOUD
     }
 }
 
index 51217f0..2beb4a3 100644 (file)
@@ -225,6 +225,12 @@ namespace OC
                         SubscribeCallback presenceHandler);
         OCStackResult unsubscribePresence(OCPresenceHandle presenceHandle);
 
+        OCStackResult subscribeDevicePresence(OCPresenceHandle& presenceHandle,
+                                              const std::string& host,
+                                              const QueryParamsList& queryParams,
+                                              OCConnectivityType connectivityType,
+                                              ObserveCallback callback);
+
         OCResource::Ptr constructResourceObject(const std::string& host, const std::string& uri,
                         OCConnectivityType connectivityType, bool isObservable,
                         const std::vector<std::string>& resourceTypes,
@@ -241,7 +247,34 @@ namespace OC
         OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel,
                                          const std::string& pinNumber,
                                          DirectPairingCallback resultCallback);
-
+#ifdef WITH_CLOUD
+        OCStackResult signUp(const std::string& host,
+                             const std::string& authProvider,
+                             const std::string& authCode,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler);
+
+        OCStackResult signIn(const std::string& host,
+                             const std::string& accessToken,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler);
+
+        OCStackResult signOut(const std::string& host,
+                              const std::string& accessToken,
+                              OCConnectivityType connectivityType,
+                              PostCallback cloudConnectHandler);
+
+        OCStackResult signInOut(const std::string& host,
+                                const std::string& accessToken,
+                                bool isSignIn,
+                                OCConnectivityType connectivityType,
+                                PostCallback cloudConnectHandler);
+
+        OCStackResult refreshAccessToken(const std::string& host,
+                                         const std::string& refreshToken,
+                                         OCConnectivityType connectivityType,
+                                         PostCallback cloudConnectHandler);
+#endif // WITH_CLOUD
     private:
         PlatformConfig m_cfg;
 
index bc0bcdb..1e413a6 100644 (file)
@@ -118,7 +118,7 @@ namespace OC
             m_resourceId(std::move(o.m_resourceId)),
             m_devAddr(std::move(o.m_devAddr)),
             m_useHostString(o.m_useHostString),
-            m_isObservable(o.m_isObservable),
+            m_property(o.m_property),
             m_isCollection(o.m_isCollection),
             m_resourceTypes(std::move(o.m_resourceTypes)),
             m_interfaces(std::move(o.m_interfaces)),
@@ -503,6 +503,15 @@ namespace OC
         */
         bool isObservable() const;
 
+#ifdef WITH_MQ
+        /**
+        * Function to provide ability to check if this resource is publisher or not
+        * @return bool true indicates resource is publisher; false indicates resource is
+        *         not publisher.
+        */
+        bool isPublish() const;
+#endif
+
         /**
         * Function to get the list of resource types
         * @return vector of resource types
@@ -534,6 +543,92 @@ namespace OC
         */
         std::string sid() const;
 
+#ifdef WITH_MQ
+        /**
+        * Function to discovery Topics from MQ Broker.
+        *
+        * @param queryParametersMap map which can have the query parameter name and value
+        * @param attributeHandler handles callback
+
+        * @return Returns  ::OC_STACK_OK on success, some other value upon failure.
+        * @note OCStackResult is defined in ocstack.h.
+        *
+        */
+        OCStackResult discoveryMQTopics(const QueryParamsMap& queryParametersMap,
+                                        FindCallback attributeHandler);
+        /**
+        * Function to create Topic into MQ Broker.
+        * SubTopic is also created through this method.
+        *
+        * @param rep representation of the topic
+        * @param topicUri new uri of the topic which want to create
+        * @param queryParametersMap map which can have the query parameter name and value
+        * @param attributeHandler handles callback
+
+        * @return Returns  ::OC_STACK_OK on success, some other value upon failure.
+        * @note OCStackResult is defined in ocstack.h.
+        *
+        */
+        OCStackResult createMQTopic(const OCRepresentation& rep,
+                                    const std::string& topicUri,
+                                    const QueryParamsMap& queryParametersMap,
+                                    MQCreateTopicCallback attributeHandler);
+#endif
+#ifdef MQ_SUBSCRIBER
+        /**
+        * Function to subscribe Topic to MQ Broker.
+        *
+        * @param observeType allows the client to specify how it wants to observe.
+        * @param queryParametersMap map which can have the query parameter name and value
+        * @param observeHandler handles callback
+
+        * @return Returns  ::OC_STACK_OK on success, some other value upon failure.
+        * @note OCStackResult is defined in ocstack.h.
+        *
+        */
+        OCStackResult subscribeMQTopic(ObserveType observeType,
+                                       const QueryParamsMap& queryParametersMap,
+                                       ObserveCallback observeHandler);
+
+        /**
+        * Function to unsubscribe Topic to MQ Broker.
+        *
+        * @return Returns  ::OC_STACK_OK on success, some other value upon failure.
+        * @note OCStackResult is defined in ocstack.h.
+        *
+        */
+        OCStackResult unsubscribeMQTopic();
+
+        /**
+        * Function to request publish to MQ publisher.
+        * Publisher can confirm the request message as key:"req_pub" and value:"true".
+        *
+        * @param queryParametersMap map which can have the query parameter name and value
+        * @param attributeHandler handles callback
+
+        * @return Returns  ::OC_STACK_OK on success, some other value upon failure.
+        * @note OCStackResult is defined in ocstack.h.
+        *
+        */
+        OCStackResult requestMQPublish(const QueryParamsMap& queryParametersMap,
+                                       PostCallback attributeHandler);
+#endif
+#ifdef MQ_PUBLISHER
+        /**
+        * Function to publish Topic information into MQ Broker.
+        *
+        * @param rep representation of the topic
+        * @param queryParametersMap map which can have the query parameter name and value
+        * @param attributeHandler handles callback
+
+        * @return Returns  ::OC_STACK_OK on success, some other value upon failure.
+        * @note OCStackResult is defined in ocstack.h.
+        *
+        */
+        OCStackResult publishMQTopic(const OCRepresentation& rep,
+                                     const QueryParamsMap& queryParametersMap,
+                                     PostCallback attributeHandler);
+#endif
         // overloaded operators allow for putting into a 'set'
         // the uniqueidentifier allows for putting into a hash
         bool operator==(const OCResource &other) const;
@@ -555,8 +650,8 @@ namespace OC
         OCResourceIdentifier m_resourceId;
         OCDevAddr m_devAddr;
         bool m_useHostString;
-        bool m_isObservable;
         bool m_isCollection;
+        uint8_t m_property;
         std::vector<std::string> m_resourceTypes;
         std::vector<std::string> m_interfaces;
         std::vector<std::string> m_children;
@@ -566,14 +661,14 @@ namespace OC
     private:
         OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                     const OCDevAddr& devAddr, const std::string& uri,
-                    const std::string& serverId, bool observable,
+                    const std::string& serverId, 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, bool observable,
+                    OCConnectivityType connectivityType, uint8_t property,
                     const std::vector<std::string>& resourceTypes,
                     const std::vector<std::string>& interfaces);
     };
index f037213..693f546 100644 (file)
@@ -57,8 +57,9 @@ namespace OC
 
                         if (res->port != 0)
                         {
-                             m_devAddr.port = res->port;
+                            m_devAddr.port = res->port;
                         }
+
                         if (payload->baseURI)
                         {
                             OCDevAddr rdPubAddr = m_devAddr;
@@ -68,7 +69,7 @@ namespace OC
                                         new OC::OCResource(m_clientWrapper, rdPubAddr,
                                             std::string(res->uri),
                                             std::string(payload->sid),
-                                            (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                            res->bitmap,
                                             StringLLToVector(res->types),
                                             StringLLToVector(res->interfaces)
                                             )));
@@ -79,7 +80,7 @@ namespace OC
                                     new OC::OCResource(m_clientWrapper, m_devAddr,
                                         std::string(res->uri),
                                         std::string(payload->sid),
-                                        (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                        res->bitmap,
                                         StringLLToVector(res->types),
                                         StringLLToVector(res->interfaces)
                                         )));
@@ -94,7 +95,7 @@ namespace OC
                                             new OC::OCResource(m_clientWrapper, tcpDevAddr,
                                                 std::string(res->uri),
                                                 std::string(payload->sid),
-                                                (res->bitmap & OC_OBSERVABLE) == OC_OBSERVABLE,
+                                                res->bitmap,
                                                 StringLLToVector(res->types),
                                                 StringLLToVector(res->interfaces)
                                                 )));
@@ -107,6 +108,44 @@ namespace OC
                 }
             }
 
+#ifdef WITH_MQ
+            ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
+                                OCDevAddr& devAddr, OCRepPayload* payload)
+                                : m_clientWrapper(cw), m_devAddr(devAddr)
+            {
+                if (payload)
+                {
+                    char**topicList = nullptr;
+                    size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0};
+                    OCRepPayloadGetStringArray(payload, "topiclist", &topicList, dimensions);
+
+                    for(size_t idx = 0; idx < dimensions[0]; idx++)
+                    {
+                        m_resources.push_back(std::shared_ptr<OC::OCResource>(
+                                new OC::OCResource(m_clientWrapper, m_devAddr,
+                                                   std::string(topicList[idx]),
+                                                   "",
+                                                   OC_OBSERVABLE,
+                                                   {OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC},
+                                                   {DEFAULT_INTERFACE})));
+                    }
+                }
+            }
+
+            ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
+                              OCDevAddr& devAddr, const std::string& topicUri)
+                              : m_clientWrapper(cw), m_devAddr(devAddr)
+            {
+                    m_resources.push_back(std::shared_ptr<OC::OCResource>(
+                            new OC::OCResource(m_clientWrapper, m_devAddr,
+                                               topicUri,
+                                               "",
+                                               OC_OBSERVABLE,
+                                               {OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC},
+                                               {DEFAULT_INTERFACE})));
+            }
+#endif
+
             const std::vector<std::shared_ptr<OCResource>>& Resources() const
             {
                 return m_resources;
index 3719a63..513156d 100644 (file)
@@ -84,6 +84,7 @@ namespace OC
             const OCRepresentation& /*attributes*/,
             const QueryParamsMap& /*queryParams*/,
             const HeaderOptions& /*headerOptions*/,
+            OCConnectivityType /*connectivityType*/,
             PostCallback& /*callback*/, QualityOfService /*QoS*/)
             {return OC_STACK_NOTIMPL;}
 
@@ -121,6 +122,14 @@ namespace OC
         virtual OCStackResult UnsubscribePresence(OCDoHandle /*handle*/)
             {return OC_STACK_NOTIMPL;}
 
+        virtual OCStackResult SubscribeDevicePresence(
+            OCDoHandle* /*handle*/,
+            const std::string& /*host*/,
+            const QueryParamsList& /*queryParams*/,
+            OCConnectivityType /*connectivityType*/,
+            ObserveCallback& /*callback*/)
+            {return OC_STACK_NOTIMPL;}
+
         virtual OCStackResult GetDefaultQos(QualityOfService& /*QoS*/)
             {return OC_STACK_NOTIMPL;}
 
@@ -135,6 +144,25 @@ namespace OC
                 const OCPrm_t& /*pmSel*/,
                 const std::string& /*pinNumber*/, DirectPairingCallback& /*resultCallback*/)
             {return OC_STACK_NOTIMPL;}
+
+#ifdef WITH_MQ
+        virtual OCStackResult ListenForMQTopic(const OCDevAddr& /*devAddr*/,
+                                               const std::string& /*resourceUri*/,
+                                               const QueryParamsMap& /*queryParams*/,
+                                               const HeaderOptions& /*headerOptions*/,
+                                               FindCallback& /*callback*/,
+                                               QualityOfService /*QoS*/)
+            {return OC_STACK_NOTIMPL;}
+
+        virtual OCStackResult PutMQTopicRepresentation(const OCDevAddr& /*devAddr*/,
+                                                       const std::string& /*uri*/,
+                                                       const OCRepresentation& /*rep*/,
+                                                       const QueryParamsMap& /*queryParams*/,
+                                                       const HeaderOptions& /*headerOptions*/,
+                                                       MQCreateTopicCallback& /*callback*/,
+                                                       QualityOfService /*QoS*/)
+            {return OC_STACK_NOTIMPL;}
+#endif
     };
 }
 
index 1d68a2f..8a892c6 100644 (file)
@@ -169,6 +169,7 @@ namespace OC
             ListenOCContainer container(clientWrapper, clientResponse->devAddr,
                                     reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
             // loop to ensure valid construction of all resources
+
             for(auto resource : container.Resources())
             {
                 std::thread exec(context->callback, resource);
@@ -324,6 +325,101 @@ namespace OC
         }
         return result;
     }
+#ifdef WITH_MQ
+    OCStackApplicationResult listenMQCallback(void* ctx, OCDoHandle /*handle*/,
+            OCClientResponse* clientResponse)
+    {
+        ClientCallbackContext::ListenContext* context =
+            static_cast<ClientCallbackContext::ListenContext*>(ctx);
+
+        if (!clientResponse)
+        {
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        if (clientResponse->result != OC_STACK_OK)
+        {
+            oclog() << "listenMQCallback(): failed to create resource. clientResponse: "
+                    << clientResponse->result
+                    << std::flush;
+
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        auto clientWrapper = context->clientWrapper.lock();
+        if (!clientWrapper)
+        {
+            oclog() << "listenMQCallback(): failed to get a shared_ptr to the client wrapper"
+                    << std::flush;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        try{
+            ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+                                        (OCRepPayload *) clientResponse->payload);
+
+            // loop to ensure valid construction of all resources
+            for (auto resource : container.Resources())
+            {
+                std::thread exec(context->callback, resource);
+                exec.detach();
+            }
+        }
+        catch (std::exception &e){
+            oclog() << "Exception in listCallback, ignoring response: "
+                    << e.what() << std::flush;
+        }
+
+
+        return OC_STACK_KEEP_TRANSACTION;
+    }
+
+    OCStackResult InProcClientWrapper::ListenForMQTopic(
+            const OCDevAddr& devAddr,
+            const std::string& resourceUri,
+            const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+            FindCallback& callback, QualityOfService QoS)
+    {
+        oclog() << "ListenForMQTopic()" << std::flush;
+
+        if (!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        ClientCallbackContext::ListenContext* context =
+            new ClientCallbackContext::ListenContext(callback, shared_from_this());
+        OCCallbackData cbdata;
+        cbdata.context = static_cast<void*>(context),
+        cbdata.cb      = listenMQCallback;
+        cbdata.cd      = [](void* c){delete (ClientCallbackContext::ListenContext*)c;};
+
+        std::string uri = assembleSetResourceUri(resourceUri, queryParams);
+
+        OCStackResult result = OC_STACK_ERROR;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCHeaderOption options[MAX_HEADER_OPTIONS];
+            result = OCDoResource(
+                                  nullptr, OC_REST_GET,
+                                  uri.c_str(),
+                                  &devAddr, nullptr,
+                                  CT_DEFAULT,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  assembleHeaderOptions(options, headerOptions),
+                                  headerOptions.size());
+        }
+        else
+        {
+            delete context;
+        }
+
+        return result;
+    }
+#endif
 
     OCStackApplicationResult listenDeviceCallback(void* ctx,
                                                   OCDoHandle /*handle*/,
@@ -415,6 +511,135 @@ namespace OC
         }
     }
 
+#ifdef WITH_MQ
+    OCStackApplicationResult createMQTopicCallback(void* ctx, OCDoHandle /*handle*/,
+                    OCClientResponse* clientResponse)
+    {
+        ClientCallbackContext::CreateMQTopicContext* context =
+            static_cast<ClientCallbackContext::CreateMQTopicContext*>(ctx);
+        OCRepresentation rep;
+        HeaderOptions serverHeaderOptions;
+
+        if (!clientResponse)
+        {
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+
+        std::string createdUri;
+        OCStackResult result = clientResponse->result;
+        if (OC_STACK_OK               == result ||
+            OC_STACK_RESOURCE_CREATED == result)
+        {
+            parseServerHeaderOptions(clientResponse, serverHeaderOptions);
+            try
+            {
+                rep = parseGetSetCallback(clientResponse);
+            }
+            catch(OC::OCException& e)
+            {
+                result = e.code();
+            }
+
+            bool isLocationOption = false;
+            for (auto headerOption : serverHeaderOptions)
+            {
+                if (HeaderOption::LOCATION_PATH_OPTION_ID == headerOption.getOptionID())
+                {
+                    createdUri += "/";
+                    createdUri += headerOption.getOptionData();
+                    if (!isLocationOption)
+                    {
+                        isLocationOption = true;
+                    }
+                }
+            }
+
+            if (!isLocationOption)
+            {
+                createdUri = clientResponse->resourceUri;
+            }
+        }
+
+        auto clientWrapper = context->clientWrapper.lock();
+
+        if (!clientWrapper)
+        {
+            oclog() << "createMQTopicCallback(): failed to get a shared_ptr to the client wrapper"
+                    << std::flush;
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+
+        try{
+            if (OC_STACK_OK               == result ||
+                OC_STACK_RESOURCE_CREATED == result)
+            {
+                ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+                                            createdUri);
+                for (auto resource : container.Resources())
+                {
+                    std::thread exec(context->callback, serverHeaderOptions, rep, result, resource);
+                    exec.detach();
+                }
+            }
+            else
+            {
+                std::thread exec(context->callback, serverHeaderOptions, rep, result, nullptr);
+                exec.detach();
+            }
+        }
+        catch (std::exception &e){
+            oclog() << "Exception in createMQTopicCallback, ignoring response: "
+                    << e.what() << std::flush;
+        }
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OCStackResult InProcClientWrapper::PutMQTopicRepresentation(
+                const OCDevAddr& devAddr,
+                const std::string& uri,
+                const OCRepresentation& rep,
+                const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+                MQCreateTopicCallback& callback, QualityOfService QoS)
+    {
+        if (!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
+        OCStackResult result;
+        ClientCallbackContext::CreateMQTopicContext* ctx =
+                new ClientCallbackContext::CreateMQTopicContext(callback, shared_from_this());
+        OCCallbackData cbdata;
+        cbdata.context = static_cast<void*>(ctx),
+        cbdata.cb      = createMQTopicCallback;
+        cbdata.cd      = [](void* c){delete (ClientCallbackContext::CreateMQTopicContext*)c;};
+
+        std::string url = assembleSetResourceUri(uri, queryParams);
+
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+            result = OCDoResource(nullptr, OC_REST_PUT,
+                                  url.c_str(), &devAddr,
+                                  assembleSetResourcePayload(rep),
+                                  CT_DEFAULT,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  assembleHeaderOptions(options, headerOptions),
+                                  headerOptions.size());
+        }
+        else
+        {
+            delete ctx;
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+#endif
     OCStackApplicationResult getResourceCallback(void* ctx,
                                                  OCDoHandle /*handle*/,
         OCClientResponse* clientResponse)
@@ -559,6 +784,52 @@ namespace OC
         return ret;
     }
 
+    std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
+        const QueryParamsList& queryParams)
+    {
+        if (!uri.empty())
+        {
+            if (uri.back() == '/')
+            {
+                uri.resize(uri.size() - 1);
+            }
+        }
+
+        ostringstream paramsList;
+        if (queryParams.size() > 0)
+        {
+            paramsList << '?';
+        }
+
+        for (auto& param : queryParams)
+        {
+            for (auto& paramList : param.second)
+            {
+                paramsList << param.first << '=' << paramList;
+                if (paramList != param.second.back())
+                {
+                    paramsList << '&';
+                }
+            }
+            paramsList << ';';
+        }
+
+        std::string queryString = paramsList.str();
+
+        if (queryString.empty())
+        {
+            return uri;
+        }
+
+        if (queryString.back() == ';')
+        {
+            queryString.resize(queryString.size() - 1);
+        }
+
+        std::string ret = uri + queryString;
+        return ret;
+    }
+
     OCPayload* InProcClientWrapper::assembleSetResourcePayload(const OCRepresentation& rep)
     {
         MessageContainer ocInfo;
@@ -576,6 +847,7 @@ namespace OC
         const std::string& uri,
         const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+        OCConnectivityType connectivityType,
         PostCallback& callback, QualityOfService QoS)
     {
         if (!callback)
@@ -602,7 +874,7 @@ namespace OC
             result = OCDoResource(nullptr, OC_REST_POST,
                                   url.c_str(), &devAddr,
                                   assembleSetResourcePayload(rep),
-                                  CT_DEFAULT,
+                                  connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
@@ -925,6 +1197,50 @@ namespace OC
         return result;
     }
 
+    OCStackResult InProcClientWrapper::SubscribeDevicePresence(OCDoHandle* handle,
+                                                               const std::string& host,
+                                                               const QueryParamsList& queryParams,
+                                                               OCConnectivityType connectivityType,
+                                                               ObserveCallback& callback)
+    {
+        if (!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
+        OCStackResult result;
+
+        ClientCallbackContext::ObserveContext* ctx =
+            new ClientCallbackContext::ObserveContext(callback);
+        OCCallbackData cbdata;
+        cbdata.context = static_cast<void*>(ctx),
+        cbdata.cb      = observeResourceCallback;
+        cbdata.cd      = [](void* c){delete (ClientCallbackContext::ObserveContext*)c;};
+
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+
+            std::ostringstream os;
+            os << host << OCF_RSRVD_DEVICE_PRESENCE_URI;
+            std::string url = assembleSetResourceUri(os.str(), queryParams);
+
+            result = OCDoResource(handle, OC_REST_OBSERVE,
+                                  url.c_str(), nullptr,
+                                  nullptr, connectivityType,
+                                  OC_LOW_QOS, &cbdata,
+                                  nullptr, 0);
+        }
+        else
+        {
+            delete ctx;
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
     OCStackResult InProcClientWrapper::GetDefaultQos(QualityOfService& qos)
     {
         qos = m_cfg.QoS;
index b722750..dd161e4 100644 (file)
@@ -266,6 +266,19 @@ namespace OC
             return OCPlatform_impl::Instance().unsubscribePresence(presenceHandle);
         }
 
+        OCStackResult subscribeDevicePresence(OCPresenceHandle& presenceHandle,
+                                              const std::string& host,
+                                              const QueryParamsList& queryParams,
+                                              OCConnectivityType connectivityType,
+                                              ObserveCallback callback)
+        {
+            return OCPlatform_impl::Instance().subscribeDevicePresence(presenceHandle,
+                                                                       host,
+                                                                       queryParams,
+                                                                       connectivityType,
+                                                                       callback);
+        }
+
         OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse)
         {
             return OCPlatform_impl::Instance().sendResponse(pResponse);
@@ -290,7 +303,44 @@ namespace OC
             return OCPlatform_impl::Instance().doDirectPairing(peer, pmSel,
                                              pinNumber, resultCallback);
         }
+#ifdef WITH_CLOUD
+        OCStackResult signUp(const std::string& host,
+                             const std::string& authProvider,
+                             const std::string& authCode,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler)
+        {
+            return OCPlatform_impl::Instance().signUp(host, authProvider, authCode,
+                                                      connectivityType, cloudConnectHandler);
+        }
 
+        OCStackResult signIn(const std::string& host,
+                             const std::string& accessToken,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler)
+        {
+            return OCPlatform_impl::Instance().signIn(host, accessToken,
+                                                      connectivityType, cloudConnectHandler);
+        }
+
+        OCStackResult signOut(const std::string& host,
+                              const std::string& accessToken,
+                              OCConnectivityType connectivityType,
+                              PostCallback cloudConnectHandler)
+        {
+            return OCPlatform_impl::Instance().signOut(host, accessToken,
+                                                       connectivityType, cloudConnectHandler);
+        }
+
+        OCStackResult refreshAccessToken(const std::string& host,
+                                         const std::string& refreshToken,
+                                         OCConnectivityType connectivityType,
+                                         PostCallback cloudConnectHandler)
+        {
+            return OCPlatform_impl::Instance().refreshAccessToken(host, refreshToken,
+                                                       connectivityType, cloudConnectHandler);
+        }
+#endif // WITH_CLOUD
     } // namespace OCPlatform
 } //namespace OC
 
index 03fa1d9..f40c14c 100644 (file)
@@ -156,10 +156,15 @@ namespace OC
             return std::shared_ptr<OCResource>();
         }
 
+        uint8_t resourceProperty = 0;
+        if (isObservable)
+        {
+            resourceProperty = (resourceProperty | OC_OBSERVABLE);
+        }
         return std::shared_ptr<OCResource>(new OCResource(m_client,
                                             host,
                                             uri, "", connectivityType,
-                                            isObservable,
+                                            resourceProperty,
                                             resourceTypes,
                                             interfaces));
     }
@@ -377,6 +382,16 @@ namespace OC
                              std::ref(presenceHandle));
     }
 
+    OCStackResult OCPlatform_impl::subscribeDevicePresence(OCPresenceHandle& presenceHandle,
+                                                           const std::string& host,
+                                                           const QueryParamsList& queryParams,
+                                                           OCConnectivityType connectivityType,
+                                                           ObserveCallback callback)
+    {
+        return checked_guard(m_client, &IClientWrapper::SubscribeDevicePresence,
+                             &presenceHandle, host, queryParams, connectivityType, callback);
+    }
+
     OCStackResult OCPlatform_impl::sendResponse(const std::shared_ptr<OCResourceResponse> pResponse)
     {
         return checked_guard(m_server, &IServerWrapper::sendResponse,
@@ -412,6 +427,120 @@ namespace OC
         return checked_guard(m_client, &IClientWrapper::DoDirectPairing,
                              peer, pmSel, pinNumber, resultCallback);
     }
+#ifdef WITH_CLOUD
+    OCStackResult OCPlatform_impl::signUp(const std::string& host,
+                                          const std::string& authProvider,
+                                          const std::string& authCode,
+                                          OCConnectivityType connectivityType,
+                                          PostCallback cloudConnectHandler)
+    {
+        const char* di = OCGetServerInstanceIDString();
+        if (!di)
+        {
+            oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
+            return result_guard(OC_STACK_ERROR);
+        }
+        std::string deviceId(di);
+
+        OCRepresentation rep;
+        rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
+        rep.setValue(OC_RSRVD_AUTHPROVIDER, authProvider);
+        rep.setValue(OC_RSRVD_AUTHCODE, authCode);
+
+        std::string uri = host + OC_RSRVD_ACCOUNT_URI;
+
+        OCDevAddr devAddr;
+        QueryParamsMap queryParams;
+        HeaderOptions headerOptions;
+
+        QualityOfService defaultQos = OC::QualityOfService::NaQos;
+        checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
+
+        return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
+                             devAddr, uri, rep, queryParams, headerOptions,
+                             connectivityType, cloudConnectHandler, defaultQos);
+    }
+
+    OCStackResult OCPlatform_impl::signIn(const std::string& host,
+                                          const std::string& accessToken,
+                                          OCConnectivityType connectivityType,
+                                          PostCallback cloudConnectHandler)
+    {
+        return signInOut(host, accessToken, true, connectivityType, cloudConnectHandler);
+    }
+
+    OCStackResult OCPlatform_impl::signOut(const std::string& host,
+                                           const std::string& accessToken,
+                                           OCConnectivityType connectivityType,
+                                           PostCallback cloudConnectHandler)
+    {
+        return signInOut(host, accessToken, false, connectivityType, cloudConnectHandler);
+    }
 
+    OCStackResult OCPlatform_impl::signInOut(const std::string& host,
+                                             const std::string& accessToken,
+                                             bool isSignIn,
+                                             OCConnectivityType connectivityType,
+                                             PostCallback cloudConnectHandler)
+    {
+        const char* di = OCGetServerInstanceIDString();
+        if (!di)
+        {
+            oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
+            return result_guard(OC_STACK_ERROR);
+        }
+        std::string deviceId(di);
+
+        OCRepresentation rep;
+        rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
+        rep.setValue(OC_RSRVD_ACCESS_TOKEN, accessToken);
+        rep.setValue(OC_RSRVD_STATUS, isSignIn);
+
+        std::string uri = host + OC_RSRVD_ACCOUNT_SESSION_URI;
+
+        OCDevAddr devAddr;
+        QueryParamsMap queryParams;
+        HeaderOptions headerOptions;
+
+        QualityOfService defaultQos = OC::QualityOfService::NaQos;
+        checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
+
+        return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
+                             devAddr, uri, rep, queryParams, headerOptions,
+                             connectivityType, cloudConnectHandler, defaultQos);
+    }
+
+    OCStackResult OCPlatform_impl::refreshAccessToken(const std::string& host,
+                                                      const std::string& refreshToken,
+                                                      OCConnectivityType connectivityType,
+                                                      PostCallback cloudConnectHandler)
+    {
+        const char* di = OCGetServerInstanceIDString();
+        if (!di)
+        {
+            oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
+            return result_guard(OC_STACK_ERROR);
+        }
+        std::string deviceId(di);
+
+        OCRepresentation rep;
+        rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
+        rep.setValue(OC_RSRVD_REFRESH_TOKEN, refreshToken);
+        rep.setValue(OC_RSRVD_GRANT_TYPE, OC_RSRVD_GRANT_TYPE_REFRESH_TOKEN);
+
+        std::string uri = host + OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI;
+
+        OCDevAddr devAddr;
+        QueryParamsMap queryParams;
+        HeaderOptions headerOptions;
+
+        QualityOfService defaultQos = OC::QualityOfService::NaQos;
+        checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
+
+        return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
+                             devAddr, uri, rep, queryParams, headerOptions,
+                             connectivityType, cloudConnectHandler, defaultQos);
+    }
+#endif // WITH_CLOUD
 } //namespace OC
 
index c0601eb..2fef5c1 100644 (file)
@@ -47,12 +47,12 @@ using OC::checked_guard;
 
 OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                         const OCDevAddr& devAddr, const std::string& uri,
-                        const std::string& serverId, bool observable,
+                        const std::string& serverId, 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_devAddr(devAddr),
-    m_isObservable(observable), m_isCollection(false),
+    m_property(property), m_isCollection(false),
     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
     m_observeHandle(nullptr)
 {
@@ -72,12 +72,12 @@ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
 OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                         const std::string& host, const std::string& uri,
                         const std::string& serverId,
-                        OCConnectivityType connectivityType, bool observable,
+                        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_isObservable(observable), m_isCollection(false),
+    m_property(property), m_isCollection(false),
     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
     m_observeHandle(nullptr)
 {
@@ -376,7 +376,7 @@ OCStackResult OCResource::post(const OCRepresentation& rep,
 {
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
                          m_devAddr, m_uri, rep, queryParametersMap,
-                         m_headerOptions, attributeHandler, QoS);
+                         m_headerOptions, CT_DEFAULT, attributeHandler, QoS);
 }
 
 OCStackResult OCResource::post(const OCRepresentation& rep,
@@ -550,8 +550,15 @@ OCConnectivityType OCResource::connectivityType() const
 
 bool OCResource::isObservable() const
 {
-    return m_isObservable;
+    return (m_property & OC_OBSERVABLE) == OC_OBSERVABLE;
+}
+
+#ifdef WITH_MQ
+bool OCResource::isPublish() const
+{
+    return (m_property & OC_MQ_PUBLISHER) == OC_MQ_PUBLISHER;
 }
+#endif
 
 std::vector<std::string> OCResource::getResourceTypes() const
 {
@@ -573,6 +580,69 @@ std::string OCResource::sid() const
     return this->uniqueIdentifier().m_representation;
 }
 
+#ifdef WITH_MQ
+OCStackResult OCResource::discoveryMQTopics(const QueryParamsMap& queryParametersMap,
+                                            FindCallback attributeHandler)
+{
+    QualityOfService defaultQos = OC::QualityOfService::NaQos;
+    checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
+    return checked_guard(m_clientWrapper.lock(),
+                            &IClientWrapper::ListenForMQTopic,
+                            m_devAddr, m_uri,
+                            queryParametersMap, m_headerOptions,
+                            attributeHandler, defaultQos);
+}
+
+OCStackResult OCResource::createMQTopic(const OCRepresentation& rep,
+                                        const std::string& topicUri,
+                                        const QueryParamsMap& queryParametersMap,
+                                        MQCreateTopicCallback attributeHandler)
+{
+    QualityOfService defaultQos = OC::QualityOfService::NaQos;
+    checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
+    return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PutMQTopicRepresentation,
+                         m_devAddr, topicUri, rep, queryParametersMap,
+                         m_headerOptions, attributeHandler, defaultQos);
+}
+#endif
+#ifdef MQ_SUBSCRIBER
+OCStackResult OCResource::subscribeMQTopic(ObserveType observeType,
+        const QueryParamsMap& queryParametersMap, ObserveCallback observeHandler)
+{
+    QualityOfService defaultQoS = OC::QualityOfService::NaQos;
+    checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
+
+    return result_guard(observe(observeType, queryParametersMap, observeHandler, defaultQoS));
+}
+
+OCStackResult OCResource::unsubscribeMQTopic()
+{
+    QualityOfService defaultQoS = OC::QualityOfService::NaQos;
+    checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQoS);
+    return result_guard(cancelObserve(defaultQoS));
+}
+
+OCStackResult OCResource::requestMQPublish(const QueryParamsMap& queryParametersMap,
+                                           PostCallback attributeHandler)
+{
+    OCRepresentation rep;
+    rep.setValue(std::string("req_pub"), std::string("true"));
+    QualityOfService defaultQos = OC::QualityOfService::NaQos;
+    checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
+    return result_guard(post(rep, queryParametersMap, attributeHandler, defaultQos));
+}
+#endif
+#ifdef MQ_PUBLISHER
+OCStackResult OCResource::publishMQTopic(const OCRepresentation& rep,
+                                         const QueryParamsMap& queryParametersMap,
+                                         PostCallback attributeHandler)
+{
+    QualityOfService defaultQos = OC::QualityOfService::NaQos;
+    checked_guard(m_clientWrapper.lock(), &IClientWrapper::GetDefaultQos, defaultQos);
+    return result_guard(post(rep, queryParametersMap, attributeHandler, defaultQos));
+}
+#endif
+
 bool OCResource::operator==(const OCResource &other) const
 {
     return m_resourceId == other.m_resourceId;
index 0f31035..32ff64b 100644 (file)
@@ -77,6 +77,9 @@ if target_os in ['msys_nt', 'windows']:
        if secured == '1':
                oclib_env.AppendUnique(LIBS=['tinydtls'])
 
+if oclib_env.get('WITH_CLOUD'):
+       oclib_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
index d5aad2e..2a18ad7 100644 (file)
@@ -62,6 +62,10 @@ namespace OCPlatformTest
     {
     }
 
+    void onObserve(const HeaderOptions, const OCRepresentation&, const int&, const int&)
+    {
+    }
+
     void directPairHandler(std::shared_ptr<OCDirectPairing> /*dev*/, OCStackResult /*res*/)
     {
     }
@@ -69,7 +73,12 @@ namespace OCPlatformTest
     void pairedHandler(const PairedDevices& /*list*/)
     {
     }
-
+#ifdef WITH_CLOUD
+    void accountHandler(const HeaderOptions& /*headerOptions*/, const OCRepresentation& /*rep*/,
+            const int /*eCode*/)
+    {
+    }
+#endif
     //Helper methods
     void DeleteStringLL(OCStringLL* ll)
     {
@@ -828,6 +837,47 @@ namespace OCPlatformTest
         EXPECT_EQ(OC_STACK_OK, OCPlatform::unsubscribePresence(presenceHandle));
     }
 
+    //SubscribeDevicePresence Test
+    TEST(SubscribeDevicePresenceTest, DISABLED_SubscribeDevicePresenceWithValidParameters)
+    {
+        std::string hostAddress = "192.168.1.2:5000";
+        OCPlatform::OCPresenceHandle presenceHandle = nullptr;
+        QueryParamsList queryParams = {};
+
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribeDevicePresence(presenceHandle,
+                hostAddress, queryParams, CT_DEFAULT, &onObserve));
+    }
+
+    TEST(SubscribeDevicePresenceTest, SubscribeDevicePresenceWithNullHost)
+    {
+        OCPlatform::OCPresenceHandle presenceHandle = nullptr;
+        QueryParamsList queryParams = {};
+
+        EXPECT_ANY_THROW(OCPlatform::subscribeDevicePresence(presenceHandle,
+                        nullptr, queryParams, CT_DEFAULT, &onObserve));
+    }
+
+    TEST(SubscribeDevicePresenceTest, SubscribeDevicePresenceWithNullOnObserve)
+    {
+        std::string hostAddress = "192.168.1.2:5000";
+        OCPlatform::OCPresenceHandle presenceHandle = nullptr;
+        QueryParamsList queryParams = {};
+
+        EXPECT_ANY_THROW(OCPlatform::subscribeDevicePresence(presenceHandle,
+                        hostAddress, queryParams, CT_DEFAULT, NULL));
+    }
+
+    TEST(SubscribeDevicePresenceTest, DISABLED_UnsubscribePresenceWithValidHandle)
+    {
+        std::string hostAddress = "192.168.1.2:5000";
+        OCPlatform::OCPresenceHandle presenceHandle = nullptr;
+        QueryParamsList queryParams = {};
+
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribeDevicePresence(presenceHandle,
+                hostAddress, queryParams, CT_DEFAULT, &onObserve));
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::unsubscribePresence(presenceHandle));
+    }
+
     TEST(FindDirectPairingTest, FindDirectPairingNullCallback)
     {
         EXPECT_ANY_THROW(OCPlatform::findDirectPairingDevices(1, nullptr));
@@ -869,4 +919,70 @@ namespace OCPlatformTest
         std::shared_ptr<OCDirectPairing> s_dp(new OCDirectPairing(&peer));
         EXPECT_ANY_THROW(OCPlatform::doDirectPairing(nullptr, pmSel, pin, nullptr));
     }
+#ifdef WITH_CLOUD
+    //SignUp Test
+    TEST(SignUpTest, DISABLED_SignUpWithValidParameters)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string authProvider("AnyAuthProvider");
+        std::string authCode("AnyAuthCode");
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::signUp(host, authProvider, authCode,
+                                                  CT_DEFAULT, &accountHandler));
+    }
+
+    TEST(SignUpTest, SignUpWithNullCallback)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string authProvider("AnyAuthProvider");
+        std::string authCode("AnyAuthCode");
+        EXPECT_ANY_THROW(OCPlatform::signUp(host, authProvider, authCode, CT_DEFAULT, nullptr));
+    }
+
+    //SignIn Test
+    TEST(SignInTest, DISABLED_SignInWithValidParameters)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string accessToken("AnyAccessToken");
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::signIn(host, accessToken, CT_DEFAULT, &accountHandler));
+    }
+
+    TEST(SignInTest, SignInWithNullCallback)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string accessToken("AnyAccessToken");
+        EXPECT_ANY_THROW(OCPlatform::signIn(host, accessToken, CT_DEFAULT, nullptr));
+    }
+
+    //SignOut Test
+    TEST(SignOutTest, DISABLED_SignOutWithValidParameters)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string accessToken("AnyAccessToken");
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::signOut(host, accessToken,
+                                                   CT_DEFAULT, &accountHandler));
+    }
+
+    TEST(SignOutTest, SignOutWithNullCallback)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string accessToken("AnyAccessToken");
+        EXPECT_ANY_THROW(OCPlatform::signOut(host, accessToken, CT_DEFAULT, nullptr));
+    }
+
+    //RefreshAccessToken Test
+    TEST(RefreshAccessTokenTest, DISABLED_RefreshAccessTokenWithValidParameters)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string refreshToken("AnyRefreshToken");
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::refreshAccessToken(host, refreshToken,
+                                                              CT_DEFAULT, &accountHandler));
+    }
+
+    TEST(RefreshAccessTokenTest, RefreshAccessTokenWithNullCallback)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string refreshToken("AnyRefreshToken");
+        EXPECT_ANY_THROW(OCPlatform::refreshAccessToken(host, refreshToken, CT_DEFAULT, nullptr));
+    }
+#endif // WITH_CLOUD
 }
index 8d1249d..a3a78cd 100644 (file)
@@ -60,6 +60,9 @@ if unittests_env.get('SECURED') == '1':
 if unittests_env.get('LOGGING'):
        unittests_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
+if unittests_env.get('WITH_CLOUD'):
+       unittests_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
index 79db0bd..d0a1a9d 100644 (file)
@@ -147,9 +147,17 @@ namespace OIC
 
         RCSRepresentation RCSRepresentation::fromOCRepresentation(const OC::OCRepresentation& ocRep)
         {
-            return RCSRepresentation(ocRep.getUri(), ocRep.getResourceInterfaces(),
+            RCSRepresentation rcsRep(ocRep.getUri(), ocRep.getResourceInterfaces(),
                     ocRep.getResourceTypes(),
                     ResourceAttributesConverter::fromOCRepresentation(ocRep));
+
+            // Convert child representations
+            for (auto &childOCRep : ocRep.getChildren())
+            {
+                rcsRep.addChild(fromOCRepresentation(childOCRep));
+            }
+
+            return rcsRep;
         }
 
         OC::OCRepresentation RCSRepresentation::toOCRepresentation(const RCSRepresentation& rcsRep)
index 51b3536..e774d68 100644 (file)
@@ -31,6 +31,8 @@
 #include "RCSResourceAttributes.h"
 #include "ExpiryTimer.h"
 
+#include "ocrandom.h"
+
 namespace OIC
 {
     namespace Service
@@ -314,17 +316,15 @@ namespace OIC
         CacheID DataCache::generateCacheID()
         {
             CacheID retID = 0;
-            srand(time(NULL));
-
             while (1)
             {
                 if (findSubscriber(retID).first == 0 && retID != 0)
                 {
                     break;
                 }
-                retID = rand();
-            }
 
+                retID = OCGetRandom();
+            }
             return retID;
         }