Merge branch 'master' into resource-container
authorMarkus Jung <markus.jung85@gmail.com>
Wed, 18 Nov 2015 20:02:00 +0000 (05:02 +0900)
committerMarkus Jung <markus.jung85@gmail.com>
Wed, 18 Nov 2015 20:03:41 +0000 (05:03 +0900)
Change-Id: I897c55a73b18288a0686a6d6770cf8fd8dcf1f2c
Signed-off-by: Markus Jung <markus.jung85@gmail.com>
81 files changed:
android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java
extlibs/tinydtls/README_Iotivity [new file with mode: 0644]
extlibs/tinydtls/SConscript
extlibs/tinydtls/crypto.c
extlibs/tinydtls/crypto.h
extlibs/tinydtls/dtls.c
extlibs/tinydtls/tests/dtls-client.c
plugins/src/SConscript
resource/c_common/SConscript
resource/c_common/oic_time/include/oic_time.h [new file with mode: 0644]
resource/c_common/oic_time/src/oic_time.c [new file with mode: 0644]
resource/c_common/oic_time/test/SConscript [new file with mode: 0644]
resource/c_common/oic_time/test/linux/oic_time_tests.cpp [new file with mode: 0644]
resource/csdk/SConscript
resource/csdk/connectivity/samples/android/casample/cAInterface/src/main/java/org/iotivity/ca/CaIpInterface.java
resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c
resource/csdk/connectivity/src/cablockwisetransfer.c
resource/csdk/connectivity/src/camessagehandler.c
resource/csdk/connectivity/src/caprotocolmessage.c
resource/csdk/connectivity/src/caretransmission.c
resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/tcp_adapter/catcpserver.c
resource/csdk/routing/src/routingmanager.c
resource/csdk/security/include/internal/amsmgr.h
resource/csdk/security/provisioning/src/pmutility.c [changed mode: 0644->0755]
resource/csdk/security/provisioning/src/secureresourceprovider.c
resource/csdk/security/src/amsmgr.c
resource/csdk/security/src/doxmresource.c
resource/csdk/security/src/iotvticalendar.c
resource/csdk/security/src/policyengine.c
resource/csdk/security/src/psinterface.c
resource/csdk/security/src/secureresourcemanager.c
resource/csdk/security/unittest/credentialresource.cpp
resource/csdk/stack/include/ocpayload.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/include/payload_logging.h
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/src/ocpayloadconvert.c
resource/csdk/stack/src/ocpayloadparse.c
resource/csdk/stack/src/ocserverrequest.c [changed mode: 0644->0755]
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/src/oicgroup.c
resource/csdk/stack/test/SConscript
resource/csdk/stack/test/cbortests.cpp [new file with mode: 0644]
resource/docs/Doxyfile
resource/include/OCRepresentation.h
resource/include/OCUtilities.h
resource/oc_logger/samples/linux/README [deleted file]
resource/oc_logger/samples/linux/test_logging.c [deleted file]
resource/src/OCResource.cpp
resource/unit_tests.scons
resource/unittests/OCResourceTest.cpp
service/easy-setup/sdk/mediator/src/provisioning.cpp
service/resource-container/examples/tizen/ContainerClientApp/.cproject
service/resource-container/examples/tizen/ContainerClientApp/src/clientmain.cpp
service/resource-container/examples/tizen/ContainerClientApp/src/containerclient.cpp
service/resource-container/examples/tizen/ContainerServerApp/inc/container.h
service/resource-container/examples/tizen/ContainerServerApp/inc/rcmain.h
service/resource-container/examples/tizen/ContainerServerApp/src/container.cpp
service/resource-container/examples/tizen/ContainerServerApp/src/rcmain.cpp
service/resource-encapsulation/android/service/src/main/java/org/iotivity/service/server/RcsResourceObject.java
service/resource-encapsulation/android/service/src/main/jni/JniRcsLockedAttributes.cpp
service/resource-encapsulation/android/service/src/main/jni/JniRcsResourceObject.cpp
service/resource-encapsulation/examples/android/RESampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ResourceClientActivity.java
service/resource-encapsulation/examples/linux/NestedAttributesClient.cpp [moved from service/resource-encapsulation/examples/linux/NestedAttributeClient.cpp with 100% similarity]
service/resource-encapsulation/examples/linux/NestedAttributesServer.cpp [moved from service/resource-encapsulation/examples/linux/NestedAttributeServer.cpp with 97% similarity]
service/resource-encapsulation/examples/linux/SConscript
service/resource-encapsulation/examples/linux/SampleResourceClient.cpp
service/resource-encapsulation/examples/linux/SampleResourceServer.cpp
service/resource-encapsulation/include/RCSResourceAttributes.h
service/resource-encapsulation/include/RCSResourceObject.h
service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp
service/resource-encapsulation/src/resourceCache/include/DataCache.h
service/resource-encapsulation/src/resourceCache/src/DataCache.cpp
service/resource-encapsulation/src/resourceCache/unittests/DataCacheTest.cpp
service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp
service/resource-encapsulation/src/serverBuilder/unittests/RCSResourceObjectTest.cpp
service/things-manager/sampleapp/tizen/TMSampleApp/src/configuration.cpp

index a011dfe..81ab7d5 100644 (file)
@@ -66,6 +66,10 @@ public class CaIpInterface {
         mContext.registerReceiver(mReceiver, intentFilter);\r
     }\r
 \r
+    public static void destroyIpInterface() {\r
+        mContext.unregisterReceiver(mReceiver);\r
+    }\r
+\r
     private static BroadcastReceiver mReceiver = new BroadcastReceiver() {\r
         @Override\r
         public void onReceive(Context context, Intent intent) {\r
diff --git a/extlibs/tinydtls/README_Iotivity b/extlibs/tinydtls/README_Iotivity
new file mode 100644 (file)
index 0000000..3d18404
--- /dev/null
@@ -0,0 +1,26 @@
+SUPPORTED CIPHER-SUITES
+  TLS_PSK_WITH_AES_128_CCM_8(0xC0A8)
+  TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8(0xC0AE)
+  TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256(0xC037)
+  TLS_ECDH_anon_WITH_AES_128_CBC_SHA256(0xC018)
+
+TEST APPLICATIONS
+These applications can be build from Iotivity's root directory using below commands:
+scons extlibs/tinydtls/dtls-client SECURED=1 RELEASE=0
+scons extlibs/tinydtls/dtls-server SECURED=1 RELEASE=0
+
+
+INTER-OPERABILITY TESTING
+tinyDTLS's cipher-suite implementations can be verified for compatibility against other
+SSL libraries.
+Use below commands to perform compatibility testing against mBed SSL library.
+./ssl_server2 debug_level=5 dtls=1 psk=73656372657450534b psk_identity=Client_identity \
+    force_version=dtls1_2 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256
+./dtls-client -v 6 -c 4 localhost 4433
+
+./ssl_client2 debug_level=5 dtls=1 psk=73656372657450534b psk_identity=Client_identity \
+    force_version=dtls1_2 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256
+./dtls-server -v 6 localhost -p 4433
+
+Above commands can also be tested with TLS-PSK-WITH-AES-128-CCM-8 cipher suite.
+
index 1f3c2a7..64d5d08 100644 (file)
@@ -68,7 +68,7 @@ if not env.get('RELEASE'):
 else:
        env.AppendUnique(CPPDEFINES = ['NDEBUG'])
 
-env.AppendUnique(CPPDEFINES = ['DTLSV12',  'WITH_SHA256', 'DTLS_CHECK_CONTENTTYPE'])
+env.AppendUnique(CPPDEFINES = ['DTLSV12',  'WITH_SHA256', 'DTLS_CHECK_CONTENTTYPE', 'SHA2_USE_INTTYPES_H'])
 
 
 libtinydtls = env.StaticLibrary('libtinydtls', env.get('TINYDTLS_SRC'), OBJPREFIX='libtinydtls_')
index 77a8e04..92c73c0 100644 (file)
@@ -330,7 +330,7 @@ dtls_ccm_decrypt(aes128_t *ccm_ctx, const unsigned char *src,
 
 static size_t
 dtls_cbc_encrypt(aes128_t *aes_ctx,
-                 unsigned char *key, size_t keylen,
+                 unsigned char *mac_key, size_t mac_keylen,
                  const unsigned char *iv,
                  const unsigned char *src, size_t srclen,
                  unsigned char *buf) {
@@ -349,7 +349,7 @@ dtls_cbc_encrypt(aes128_t *aes_ctx,
     dtls_hdr = src - DTLS_CBC_IV_LENGTH - sizeof(dtls_record_header_t);
 
     //Calculate MAC : Append the MAC code to end of content
-    hmac_ctx = dtls_hmac_new(key, keylen);
+    hmac_ctx = dtls_hmac_new(mac_key, mac_keylen);
     dtls_mac(hmac_ctx,
              dtls_hdr,
              src, srclen,
@@ -389,7 +389,7 @@ dtls_cbc_encrypt(aes128_t *aes_ctx,
 
 static size_t
 dtls_cbc_decrypt(aes128_t *aes_ctx,
-                 unsigned char *key, size_t keylen,
+                 unsigned char *mac_key, size_t mac_keylen,
                  const unsigned char *iv,
                  const unsigned char *src, size_t srclen,
                  unsigned char *buf) {
@@ -430,7 +430,7 @@ dtls_cbc_decrypt(aes128_t *aes_ctx,
     depaddinglen = buf[srclen -1];
 
     //Calculate MAC
-    hmac_ctx = dtls_hmac_new(key, keylen);
+    hmac_ctx = dtls_hmac_new(mac_key, mac_keylen);
     if(!hmac_ctx) {
         return -1;
     }
@@ -702,7 +702,8 @@ int
 dtls_encrypt(const unsigned char *src, size_t length,
             unsigned char *buf,
             unsigned char *nounce,
-            unsigned char *key, size_t keylen,
+            unsigned char *write_key, size_t write_keylen,
+            unsigned char *mac_key, size_t mac_keylen,
             const unsigned char *aad, size_t la,
             const dtls_cipher_t cipher)
 {
@@ -711,7 +712,7 @@ dtls_encrypt(const unsigned char *src, size_t length,
 
   if(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
      cipher == TLS_PSK_WITH_AES_128_CCM_8) {
-      ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
+      ret = rijndael_set_key_enc_only(&ctx->data.ctx, write_key, 8 * write_keylen);
       if (ret < 0) {
         /* cleanup everything in case the key has the wrong size */
         dtls_warn("cannot set rijndael key\n");
@@ -724,7 +725,7 @@ dtls_encrypt(const unsigned char *src, size_t length,
   }
   if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
      cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
-      ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
+      ret = rijndael_set_key(&ctx->data.ctx, write_key, 8 * write_keylen);
       if (ret < 0) {
         /* cleanup everything in case the key has the wrong size */
         dtls_warn("cannot set rijndael key\n");
@@ -733,7 +734,7 @@ dtls_encrypt(const unsigned char *src, size_t length,
 
       if (src != buf)
         memmove(buf, src, length);
-      ret = dtls_cbc_encrypt(&ctx->data, key, keylen, nounce, src, length, buf);
+      ret = dtls_cbc_encrypt(&ctx->data, mac_key, mac_keylen, nounce, src, length, buf);
   }
 
 error:
@@ -745,7 +746,8 @@ int
 dtls_decrypt(const unsigned char *src, size_t length,
             unsigned char *buf,
             unsigned char *nounce,
-            unsigned char *key, size_t keylen,
+            unsigned char *read_key, size_t read_keylen,
+            unsigned char *mac_key, size_t mac_keylen,
             const unsigned char *aad, size_t la,
             const dtls_cipher_t cipher)
 {
@@ -754,7 +756,7 @@ dtls_decrypt(const unsigned char *src, size_t length,
 
   if(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
      cipher == TLS_PSK_WITH_AES_128_CCM_8) {
-      ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen);
+      ret = rijndael_set_key_enc_only(&ctx->data.ctx, read_key, 8 * read_keylen);
       if (ret < 0) {
         /* cleanup everything in case the key has the wrong size */
         dtls_warn("cannot set rijndael key\n");
@@ -768,7 +770,7 @@ dtls_decrypt(const unsigned char *src, size_t length,
 
   if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
      cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
-      ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
+      ret = rijndael_set_key(&ctx->data.ctx, read_key, 8 * read_keylen);
       if (ret < 0) {
         /* cleanup everything in case the key has the wrong size */
         dtls_warn("cannot set rijndael key\n");
@@ -777,7 +779,7 @@ dtls_decrypt(const unsigned char *src, size_t length,
 
       if (src != buf)
         memmove(buf, src, length);
-      ret = dtls_cbc_decrypt(&ctx->data, key, keylen, nounce, src, length, buf);
+      ret = dtls_cbc_decrypt(&ctx->data, mac_key, mac_keylen, nounce, src, length, buf);
     }
 
 error:
index e101a11..8ea83f2 100644 (file)
 #include "ecc/ecc.h"
 
 /* TLS_PSK_WITH_AES_128_CCM_8 */
-#define DTLS_MAC_KEY_LENGTH    0
+#define DTLS_CCM_MAC_KEY_LENGTH        0       /* MAC Key length for AES-CCM cipher suites */
+#define DTLS_CBC_MAC_KEY_LENGTH       32       /* MAC Key length for AES-CBC Cipher suites */
 #define DTLS_KEY_LENGTH        16 /* AES-128 */
 #define DTLS_BLK_LENGTH        16 /* AES-128 */
 #define DTLS_MAC_LENGTH        DTLS_HMAC_DIGEST_SIZE
-#define DTLS_IV_LENGTH         4  /* length of nonce_explicit */
+#define DTLS_CCM_IV_LENGTH     4  /* length of nonce_explicit */
 #define DTLS_CBC_IV_LENGTH     16
 
 /** 
  * be large enough to hold the pre_master_secret, i.e. twice the length of the 
  * pre-shared key + 1.
  */
+#define CCM_KB_LENGTH  \
+    (2 * DTLS_KEY_LENGTH + 2 * DTLS_CCM_IV_LENGTH)
+
+#define CBC_KB_LENGTH  \
+    (2 * DTLS_CBC_MAC_KEY_LENGTH + 2 * DTLS_KEY_LENGTH )
+
 #define MAX_KEYBLOCK_LENGTH  \
-  (2 * DTLS_MAC_KEY_LENGTH + 2 * DTLS_KEY_LENGTH + 2 * DTLS_IV_LENGTH)
+    ((CCM_KB_LENGTH) > (CBC_KB_LENGTH) ? (CCM_KB_LENGTH) : (CBC_KB_LENGTH) )
 
 /** Length of DTLS master_secret */
 #define DTLS_MASTER_SECRET_LENGTH 48
@@ -151,9 +158,59 @@ typedef struct {
 /* The following macros provide access to the components of the
  * key_block in the security parameters. */
 
+static inline int dtls_kb_mac_secret_size(dtls_cipher_t cipher)
+{
+    switch(cipher)
+    {
+        case TLS_NULL_WITH_NULL_NULL:
+
+            return 0;
+            break;
+
+        case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
+        case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256:
+
+            return DTLS_CBC_MAC_KEY_LENGTH;
+            break;
+
+        case TLS_PSK_WITH_AES_128_CCM_8:
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+
+            return DTLS_CCM_MAC_KEY_LENGTH;
+            break;
+    }
+
+    return -1;
+}
+
+
+static inline int dtls_kb_iv_size(dtls_cipher_t cipher)
+{
+    switch(cipher)
+    {
+        case TLS_NULL_WITH_NULL_NULL:
+        case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
+        case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256:
+
+            return 0;
+            break;
+
+        case TLS_PSK_WITH_AES_128_CCM_8:
+        case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+
+            return DTLS_CCM_IV_LENGTH;
+            break;
+    }
+
+    return -1;
+}
+
+
+
+
 #define dtls_kb_client_mac_secret(Param, Role) ((Param)->key_block)
 #define dtls_kb_server_mac_secret(Param, Role)                         \
-  (dtls_kb_client_mac_secret(Param, Role) + DTLS_MAC_KEY_LENGTH)
+  (dtls_kb_client_mac_secret(Param, Role) + dtls_kb_mac_secret_size((Param)->cipher))
 #define dtls_kb_remote_mac_secret(Param, Role)                         \
   ((Role) == DTLS_SERVER                                               \
    ? dtls_kb_client_mac_secret(Param, Role)                            \
@@ -162,9 +219,8 @@ typedef struct {
   ((Role) == DTLS_CLIENT                                               \
    ? dtls_kb_client_mac_secret(Param, Role)                            \
    : dtls_kb_server_mac_secret(Param, Role))
-#define dtls_kb_mac_secret_size(Param, Role) DTLS_MAC_KEY_LENGTH
 #define dtls_kb_client_write_key(Param, Role)                          \
-  (dtls_kb_server_mac_secret(Param, Role) + DTLS_MAC_KEY_LENGTH)
+  (dtls_kb_server_mac_secret(Param, Role) + dtls_kb_mac_secret_size((Param)->cipher))
 #define dtls_kb_server_write_key(Param, Role)                          \
   (dtls_kb_client_write_key(Param, Role) + DTLS_KEY_LENGTH)
 #define dtls_kb_remote_write_key(Param, Role)                          \
@@ -179,7 +235,7 @@ typedef struct {
 #define dtls_kb_client_iv(Param, Role)                                 \
   (dtls_kb_server_write_key(Param, Role) + DTLS_KEY_LENGTH)
 #define dtls_kb_server_iv(Param, Role)                                 \
-  (dtls_kb_client_iv(Param, Role) + DTLS_IV_LENGTH)
+  (dtls_kb_client_iv(Param, Role) + dtls_kb_iv_size((Param)->cipher))
 #define dtls_kb_remote_iv(Param, Role)                                 \
   ((Role) == DTLS_SERVER                                               \
    ? dtls_kb_client_iv(Param, Role)                                    \
@@ -188,11 +244,10 @@ typedef struct {
   ((Role) == DTLS_CLIENT                                               \
    ? dtls_kb_client_iv(Param, Role)                                    \
    : dtls_kb_server_iv(Param, Role))
-#define dtls_kb_iv_size(Param, Role) DTLS_IV_LENGTH
 
 #define dtls_kb_size(Param, Role)                                      \
-  (2 * (dtls_kb_mac_secret_size(Param, Role) +                         \
-       dtls_kb_key_size(Param, Role) + dtls_kb_iv_size(Param, Role)))
+  (2 * (dtls_kb_mac_secret_size((Param)->cipher) +                     \
+       dtls_kb_key_size(Param, Role) + dtls_kb_iv_size((Param)->cipher)))
 
 /* just for consistency */
 #define dtls_kb_digest_size(Param, Role) DTLS_MAC_LENGTH
@@ -275,7 +330,8 @@ void dtls_mac(dtls_hmac_context_t *hmac_ctx,
 int dtls_encrypt(const unsigned char *src, size_t length,
                 unsigned char *buf,
                 unsigned char *nounce,
-                unsigned char *key, size_t keylen,
+                unsigned char *write_key, size_t write_keylen,
+                unsigned char *mac_key, size_t mac_keylen,
                 const unsigned char *aad, size_t aad_length,
                 const dtls_cipher_t cipher);
 
@@ -300,7 +356,8 @@ int dtls_encrypt(const unsigned char *src, size_t length,
 int dtls_decrypt(const unsigned char *src, size_t length,
                 unsigned char *buf,
                 unsigned char *nounce,
-                unsigned char *key, size_t keylen,
+                unsigned char *read_key, size_t read_keylen,
+                unsigned char *mac_key, size_t mac_keylen,
                 const unsigned char *a_data, size_t a_data_length,
                 const dtls_cipher_t cipher);
 
index 7815c66..2869aca 100644 (file)
@@ -660,11 +660,11 @@ static void dtls_debug_keyblock(dtls_security_parameters_t *config)
   dtls_debug("key_block (%d bytes):\n", dtls_kb_size(config, peer->role));
   dtls_debug_dump("  client_MAC_secret",
                  dtls_kb_client_mac_secret(config, peer->role),
-                 dtls_kb_mac_secret_size(config, peer->role));
+                 dtls_kb_mac_secret_size(config->cipher));
 
   dtls_debug_dump("  server_MAC_secret",
                  dtls_kb_server_mac_secret(config, peer->role),
-                 dtls_kb_mac_secret_size(config, peer->role));
+                 dtls_kb_mac_secret_size(config->cipher));
 
   dtls_debug_dump("  client_write_key",
                  dtls_kb_client_write_key(config, peer->role),
@@ -676,11 +676,11 @@ static void dtls_debug_keyblock(dtls_security_parameters_t *config)
 
   dtls_debug_dump("  client_IV",
                  dtls_kb_client_iv(config, peer->role),
-                 dtls_kb_iv_size(config, peer->role));
+                 dtls_kb_iv_size(config->cipher));
 
   dtls_debug_dump("  server_IV",
                  dtls_kb_server_iv(config, peer->role),
-                 dtls_kb_iv_size(config, peer->role));
+                 dtls_kb_iv_size(config->cipher));
 }
 
 /** returns the name of the goven handshake type number.
@@ -835,6 +835,9 @@ calculate_key_block(dtls_context_t *ctx,
   /* create key_block from master_secret
    * key_block = PRF(master_secret,
                     "key expansion" + tmp.random.server + tmp.random.client) */
+  security->cipher = handshake->cipher;
+  security->compression = handshake->compression;
+  security->rseq = 0;
 
   dtls_prf(master_secret,
           DTLS_MASTER_SECRET_LENGTH,
@@ -847,9 +850,6 @@ calculate_key_block(dtls_context_t *ctx,
   memcpy(handshake->tmp.master_secret, master_secret, DTLS_MASTER_SECRET_LENGTH);
   dtls_debug_keyblock(security);
 
-  security->cipher = handshake->cipher;
-  security->compression = handshake->compression;
-  security->rseq = 0;
 
   return 0;
 }
@@ -1471,6 +1471,8 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
                start + DTLS_CBC_IV_LENGTH, nonce,
                dtls_kb_local_write_key(security, peer->role),
                dtls_kb_key_size(security, peer->role),
+               dtls_kb_local_mac_secret(security, peer->role),
+               dtls_kb_mac_secret_size(security->cipher),
                NULL, 0,
                security->cipher);
      if (res < 0)
@@ -1553,8 +1555,8 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
 
     memset(nonce, 0, DTLS_CCM_BLOCKSIZE);
     memcpy(nonce, dtls_kb_local_iv(security, peer->role),
-        dtls_kb_iv_size(security, peer->role));
-    memcpy(nonce + dtls_kb_iv_size(security, peer->role), start, 8); /* epoch + seq_num */
+        dtls_kb_iv_size(security->cipher));
+    memcpy(nonce + dtls_kb_iv_size(security->cipher), start, 8); /* epoch + seq_num */
 
     dtls_debug_dump("nonce:", nonce, DTLS_CCM_BLOCKSIZE);
     dtls_debug_dump("key:", dtls_kb_local_write_key(security, peer->role),
@@ -1572,6 +1574,8 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
     res = dtls_encrypt(start + 8, res - 8, start + 8, nonce,
                dtls_kb_local_write_key(security, peer->role),
                dtls_kb_key_size(security, peer->role),
+               dtls_kb_local_mac_secret(security, peer->role),
+               dtls_kb_mac_secret_size(security->cipher),
                A_DATA, A_DATA_LEN,
                security->cipher);
 
@@ -2815,8 +2819,8 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
                        uint8 cookie[], size_t cookie_length) {
   uint8 buf[DTLS_CH_LENGTH_MAX];
   uint8 *p = buf;
-  uint8_t cipher_size;
-  uint8_t extension_size;
+  uint8_t cipher_size = 0;
+  uint8_t extension_size = 0;
   int psk = 0;
   int ecdsa = 0;
   int ecdh_anon = 0;
@@ -2850,7 +2854,13 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
    }
 
   cipher_size = 2 + ((ecdsa || x509) ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0) + (ecdhe_psk ? 2 : 0);
-  extension_size = (ecdsa || x509) ? (2 + 6 + 6 + 8 + 6) : 0;
+
+  /* Is extension needed? */
+  extension_size = (ecdsa || x509 || ecdhe_psk || ecdh_anon) ? 2 : 0;
+  /* Supported EC and Supported Point Formats */
+  extension_size += (ecdsa || x509 || ecdhe_psk | ecdh_anon) ? ( 8 + 6) : 0;
+  /* Supported Client and Server Cert Types */
+  extension_size += (ecdsa || x509) ? ( 6 + 6) : 0;
 
   if (cipher_size == 0) {
     dtls_crit("no cipher callbacks implemented\n");
@@ -2944,7 +2954,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
 
     p += sizeof(uint8);
 
-    /* client certificate type extension */
+    /* server certificate type extension */
     dtls_int_to_uint16(p, TLS_EXT_SERVER_CERTIFICATE_TYPE);
     p += sizeof(uint16);
 
@@ -2964,7 +2974,9 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
       dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
 
     p += sizeof(uint8);
+  }
 
+  if (ecdsa || x509 || ecdhe_psk || ecdh_anon ) {
     /* elliptic_curves */
     dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES);
     p += sizeof(uint16);
@@ -3646,6 +3658,8 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
     clen = dtls_decrypt(*cleartext, clen, *cleartext, nonce,
                       dtls_kb_remote_write_key(security, peer->role),
                       dtls_kb_key_size(security, peer->role),
+                       dtls_kb_remote_mac_secret(security, peer->role),
+                       dtls_kb_mac_secret_size(security->cipher),
                       NULL, 0,
                       security->cipher);
 
@@ -3663,10 +3677,10 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
 
     memset(nonce, 0, DTLS_CCM_BLOCKSIZE);
     memcpy(nonce, dtls_kb_remote_iv(security, peer->role),
-        dtls_kb_iv_size(security, peer->role));
+        dtls_kb_iv_size(security->cipher));
 
     /* read epoch and seq_num from message */
-    memcpy(nonce + dtls_kb_iv_size(security, peer->role), *cleartext, 8);
+    memcpy(nonce + dtls_kb_iv_size(security->cipher), *cleartext, 8);
     *cleartext += 8;
     clen -= 8;
 
@@ -3687,6 +3701,8 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
     clen = dtls_decrypt(*cleartext, clen, *cleartext, nonce,
                       dtls_kb_remote_write_key(security, peer->role),
                       dtls_kb_key_size(security, peer->role),
+                       dtls_kb_remote_mac_secret(security, peer->role),
+                       dtls_kb_mac_secret_size(security->cipher),
                       A_DATA, A_DATA_LEN,
                       security->cipher);
   }
index 2c4eff9..279d91a 100644 (file)
@@ -252,9 +252,9 @@ get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM,
     return psk_client_id_length;
   case DTLS_PSK_KEY:
     if (id_len != psk_server_id_length || memcmp(psk_server_id, id, id_len) != 0) {
-      dtls_warn("PSK for unknown id requested, exiting\n");
-      return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER);
-    } else if (result_length < psk_key_length) {
+      dtls_debug("PSK for unknown id requested\n");
+    }
+    if (result_length < psk_key_length) {
       dtls_warn("cannot set psk -- buffer too small\n");
       return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
     }
index 55f0b7d..939084d 100644 (file)
@@ -37,6 +37,7 @@ print"Reading PI script"
 
 env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'resource', 'c_common', 'oic_malloc', 'include'),
                               os.path.join(src_dir, 'resource', 'c_common', 'oic_string', 'include'),
+                              os.path.join(src_dir, 'resource', 'c_common', 'oic_time', 'include'),
                               os.path.join(src_dir, 'resource', 'oc_logger', 'include'),
                               os.path.join(src_dir, 'resource', 'csdk', 'logger', 'include'),
                               os.path.join(src_dir, 'resource', 'csdk', 'stack', 'include'),
index d018d88..bdbf06b 100644 (file)
 Import('env')
 import os
 
+target_os = env.get('TARGET_OS')
+
 env.AppendUnique(CPPPATH = [
             os.path.join(Dir('.').abspath),
             os.path.join(Dir('.').abspath, 'oic_malloc/include'),
-            os.path.join(Dir('.').abspath, 'oic_string/include')
+            os.path.join(Dir('.').abspath, 'oic_string/include'),
+            os.path.join(Dir('.').abspath, 'oic_time/include')
         ])
 
-if env.get('TARGET_OS') == 'tizen':
+if target_os == 'tizen':
        env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
 else:
        env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource/c_common')])
@@ -46,7 +49,8 @@ common_env = env.Clone()
 ######################################################################
 common_src = [
     'oic_string/src/oic_string.c',
-    'oic_malloc/src/oic_malloc.c'
+    'oic_malloc/src/oic_malloc.c',
+    'oic_time/src/oic_time.c'
     ]
 
 commonlib = common_env.StaticLibrary('c_common', common_src)
diff --git a/resource/c_common/oic_time/include/oic_time.h b/resource/c_common/oic_time/include/oic_time.h
new file mode 100644 (file)
index 0000000..3ecdd8a
--- /dev/null
@@ -0,0 +1,70 @@
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OIC_TIME_H_
+#define OIC_TIME_H_
+
+#include <stdint.h>
+
+#define MS_PER_SEC  (1000)
+#define US_PER_SEC  (1000000)
+#define US_PER_MS   (1000)
+#define NS_PER_US   (1000)
+#define NS_PER_MS   (1000000)
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+typedef enum
+{
+    TIME_IN_MS = 0,
+    TIME_IN_US,
+}OICTimePrecision;
+
+/*
+ * If monotonic coarse/monotonic clock supported then gets current time as monotonic time
+ * in milliseconds or microseconds as the elapsed time since some unspecified starting point
+ * else gets current time in milliseconds or microseconds as the elapsed time since the epoch.
+ *
+ * For Arduino gets current time in milliseconds or microseconds since Arduino board begin
+ * running this program.
+ *
+ * @param     precision   based on this parameter, current time is returned in milliseconds or
+ *                        microseconds
+ *
+ * @note
+ *            On Arduino platform:
+ *            if the time precision is in milliseconds then the function will overflow
+ *            (go back to 0) after approximately 50 days.
+ *            if the time precision is in microseconds then the function will overflow
+ *            (go back to 0) after approximately 70minutes.
+ *
+ * @return
+ *         returns current time in milliseconds or microseconds.
+ */
+uint64_t OICGetCurrentTime(OICTimePrecision precision);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // OIC_TIME_H_
diff --git a/resource/c_common/oic_time/src/oic_time.c b/resource/c_common/oic_time/src/oic_time.c
new file mode 100644 (file)
index 0000000..ba7e464
--- /dev/null
@@ -0,0 +1,94 @@
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Defining _POSIX_C_SOURCE macro with 199309L (or greater) as value
+// causes header files to expose definitions
+// corresponding to the POSIX.1b, Real-time extensions
+// (IEEE Std 1003.1b-1993) specification
+//
+// For this specific file, see use of clock_gettime,
+// Refer to http://pubs.opengroup.org/stage7tc1/functions/clock_gettime.html
+// and to http://man7.org/linux/man-pages/man2/clock_gettime.2.html
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include "oic_time.h"
+#include <stdio.h>
+
+#ifndef WITH_ARDUINO
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+#define TAG "OIC_TIME"
+
+uint64_t OICGetCurrentTime(OICTimePrecision precision)
+{
+    uint64_t currentTime = 0;
+    int err = 0;
+
+#ifdef WITH_ARDUINO
+    currentTime = (TIME_IN_MS == precision) ? (uint64_t)millis() : (uint64_t)micros();
+#else
+    #if _POSIX_TIMERS > 0
+        int32_t clockId = CLOCK_REALTIME;
+        static int32_t cachedRet = 0;
+
+        #if defined(CLOCK_MONOTONIC_COARSE)
+            clockId = CLOCK_MONOTONIC_COARSE;
+        #elif _POSIX_MONOTONIC_CLOCK >= 0
+            //Option _POSIX_MONOTONIC_CLOCK == 0 indicates that the option is
+            //available at compile time but may not be supported at run time.
+            //Checking if option _POSIX_MONOTONIC_CLOCK  is supported at run time.
+            #if _POSIX_MONOTONIC_CLOCK == 0
+                cachedRet = (0 == cachedRet) ? sysconf(_SC_MONOTONIC_CLOCK) : cachedRet;
+                if(cachedRet > 0)
+                {
+                    clockId = CLOCK_MONOTONIC;
+                }
+            #else
+                clockId = CLOCK_MONOTONIC;
+            #endif
+        #else
+            clockId = CLOCK_REALTIME;
+        #endif
+
+        struct timespec current = {.tv_sec=0, .tv_nsec=0};
+        if((err = clock_gettime(clockId, &current)) != -1)
+        {
+            currentTime = (TIME_IN_MS == precision) ?
+                          (((uint64_t)current.tv_sec * MS_PER_SEC) + (current.tv_nsec / NS_PER_MS)):
+                          (((uint64_t)current.tv_sec * US_PER_SEC) + (current.tv_nsec / NS_PER_US));
+        }
+    #else
+        struct timeval current = {.tv_sec=0, .tv_usec=0};
+        if((err = gettimeofday(&current, NULL)) != -1)
+        {
+            currentTime = (TIME_IN_MS == precision) ?
+                          (((uint64_t)current.tv_sec * MS_PER_SEC) + (current.tv_usec / US_PER_MS)):
+                          (((uint64_t)current.tv_sec * US_PER_SEC) + (current.tv_usec));
+        }
+    #endif
+#endif
+    return (!err) ? currentTime : 0;
+}
+
diff --git a/resource/c_common/oic_time/test/SConscript b/resource/c_common/oic_time/test/SConscript
new file mode 100644 (file)
index 0000000..222b9e8
--- /dev/null
@@ -0,0 +1,58 @@
+#******************************************************************
+#
+# Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+Import('env')
+import os
+
+
+timetest_env = env.Clone()
+src_dir = timetest_env.get('SRC_DIR')
+
+######################################################################
+# Build flags
+######################################################################
+timetest_env.PrependUnique(CPPPATH = [
+        '../include',
+        '#extlibs/gtest/gtest-1.7.0/include' ])
+
+timetest_env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource/c_common')])
+timetest_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
+timetest_env.PrependUnique(LIBS = ['c_common', 'gtest', 'gtest_main', 'pthread'])
+timetest_env.Append(LIBS = ['rt']);
+
+if env.get('LOGGING'):
+    timetest_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+#
+######################################################################
+# Source files and Targets
+######################################################################
+timetests = timetest_env.Program('timetests', ['linux/oic_time_tests.cpp'])
+
+Alias("test", [timetests])
+
+env.AppendTarget('test')
+if env.get('TEST') == '1':
+    target_os = env.get('TARGET_OS')
+    if target_os == 'linux':
+                from tools.scons.RunTest import *
+                run_test(timetest_env,
+                         'resource_ccommon_time_test.memcheck',
+                         'resource/c_common/oic_time/test/timetests')
diff --git a/resource/c_common/oic_time/test/linux/oic_time_tests.cpp b/resource/c_common/oic_time/test/linux/oic_time_tests.cpp
new file mode 100644 (file)
index 0000000..4e98ef2
--- /dev/null
@@ -0,0 +1,37 @@
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "oic_time.h"
+#include "gtest/gtest.h"
+#include <stdint.h>
+
+// Tests to get current time in milli seconds
+TEST(TimeTests, GetCurrentTimeInMilliSec)
+{
+    uint64_t  currentMilliSecTime = OICGetCurrentTime(TIME_IN_MS);
+    EXPECT_TRUE(0 != currentMilliSecTime);
+}
+
+//Test to get current time in micro seconds
+TEST(TimeTests, GetCurrentTimeInMicroSec)
+{
+    uint64_t currentMicroSecTime = OICGetCurrentTime(TIME_IN_US);
+    EXPECT_TRUE(0 != currentMicroSecTime);
+}
index 6b54384..52c075d 100644 (file)
@@ -109,6 +109,11 @@ if env.get('LOGGING'):
 if env.get('DTLS_WITH_X509') == '1':
        liboctbstack_env.AppendUnique(CPPDEFINES = ['__WITH_X509__'])
 
+if env.get('WITH_RD') == '1':
+       liboctbstack_env.PrependUnique(CPPPATH = ['../../service/resource-directory/include'])
+       liboctbstack_env.AppendUnique(CPPDEFINES = ['-DWITH_RD'])
+       liboctbstack_env.AppendUnique(LIBS = ['resource_directory'])
+
 liboctbstack_env.Append(LIBS = ['c_common'])
 
 if liboctbstack_env.get('ROUTING') in ['GW', 'EP']:
@@ -152,4 +157,3 @@ else:
        liboctbstack_env.UserInstallTargetHeader('stack/include/ocstackconfig.h', 'resource', 'ocstackconfig.h')
        liboctbstack_env.UserInstallTargetHeader('stack/include/octypes.h', 'resource', 'octypes.h')
        liboctbstack_env.UserInstallTargetHeader('stack/include/ocstack.h', 'resource', 'ocstack.h')
-
index cbe0ec0..1b85af5 100755 (executable)
@@ -44,6 +44,10 @@ public class CaIpInterface {
         mContext.registerReceiver(mReceiver, intentFilter);
     }
 
+    public static void destroyIpInterface() {
+        mContext.unregisterReceiver(mReceiver);
+    }
+
     private static BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
index 599423c..a0b5784 100644 (file)
@@ -407,7 +407,7 @@ static int32_t CAReadDecryptedPayload(dtls_context_t *context,
     OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
 
     VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
-    OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
+    OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%zu]", bufLen);
 
     stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *)session;
 
index dd3e1b5..5df026e 100644 (file)
@@ -62,7 +62,7 @@ static bool CACheckPayloadLength(const CAData_t *sendData)
 
     // check if message has to be transfered to a block
     size_t maxBlockSize = BLOCK_SIZE(CA_DEFAULT_BLOCK_SIZE);
-    OIC_LOG_V(DEBUG, TAG, "payloadLen=%d, maxBlockSize=%d", payloadLen, maxBlockSize);
+    OIC_LOG_V(DEBUG, TAG, "payloadLen=%zu, maxBlockSize=%zu", payloadLen, maxBlockSize);
 
     if (payloadLen <= maxBlockSize)
     {
@@ -309,9 +309,18 @@ CAResult_t CAReceiveBlockWiseData(coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
                 endpoint->port);
         if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
         {
-            OIC_LOG(ERROR, TAG, "blockId is null");
-            CADestroyBlockID(blockDataID);
-            return CA_STATUS_FAILED;
+            // if retransmission is timeout, callback msg will be send without token.
+            if (NULL == blockDataID && !receivedData->responseInfo->info.token)
+            {
+                OIC_LOG(INFO, TAG, "retransmission was stopped");
+                return CA_REQUEST_TIMEOUT;
+            }
+            else
+            {
+                OIC_LOG(ERROR, TAG, "blockId is null");
+                CADestroyBlockID(blockDataID);
+                return CA_STATUS_FAILED;
+            }
         }
 
         CARemoveBlockDataFromList(blockDataID);
@@ -1408,7 +1417,7 @@ CAResult_t CAAddBlockOption(coap_pdu_t **pdu, const CAInfo_t *info,
     if (info->payload)
     {
         dataLength = info->payloadSize;
-        OIC_LOG_V(DEBUG, TAG, "dataLength - %d", dataLength);
+        OIC_LOG_V(DEBUG, TAG, "dataLength - %zu", dataLength);
     }
 
     OIC_LOG_V(DEBUG, TAG, "previous payload - %s", (*pdu)->data);
@@ -1843,7 +1852,7 @@ bool CAIsPayloadLengthInPduWithBlockSizeOption(coap_pdu_t *pdu,
         *totalPayloadLen = coap_decode_var_bytes(COAP_OPT_VALUE(option),
                                                  COAP_OPT_LENGTH(option));
 
-        OIC_LOG_V(DEBUG, TAG, "the total payload length to be received is [%d]bytes",
+        OIC_LOG_V(DEBUG, TAG, "the total payload length to be received is [%zu]bytes",
                   *totalPayloadLen);
 
         return true;
@@ -2031,7 +2040,7 @@ CAResult_t CAUpdatePayloadData(CABlockData_t *currData, const CAData_t *received
         // update received payload length
         currData->receivedPayloadLen += blockPayloadLen;
 
-        OIC_LOG_V(DEBUG, TAG, "updated payload: %s, len: %d", currData->payload,
+        OIC_LOG_V(DEBUG, TAG, "updated payload: %s, len: %zu", currData->payload,
                   currData->receivedPayloadLen);
     }
 
index fd0be7e..ebd43c5 100644 (file)
@@ -615,7 +615,7 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
         CALogPDUInfo(pdu, data->remoteEndpoint);
 
         OIC_LOG(DEBUG, TAG, "pdu to send :");
-        OIC_LOG_BUFFER(DEBUG, TAG,  pdu->hdr, pdu->length);
+        OIC_LOG_BUFFER(DEBUG, TAG,  (uint8_t*)pdu->hdr, pdu->length);
 
         res = CASendMulticastData(data->remoteEndpoint, pdu->hdr, pdu->length);
         if (CA_STATUS_OK != res)
@@ -794,7 +794,7 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
             )
     {
         CAResult_t res = CAReceiveBlockWiseData(pdu, &(sep->endpoint), cadata, dataLen);
-        if (CA_NOT_SUPPORTED == res)
+        if (CA_NOT_SUPPORTED == res || CA_REQUEST_TIMEOUT == res)
         {
             OIC_LOG(ERROR, TAG, "this message does not have block option");
             CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
@@ -1254,6 +1254,8 @@ void CALogPDUInfo(coap_pdu_t *pdu, const CAEndpoint_t *endpoint)
         OIC_LOG_BUFFER(DEBUG, TAG,  pdu->hdr, pdu->length);
     }
     else
+#else
+    (void) endpoint;
 #endif
     {
         OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->coap_hdr_udp_t.type);
@@ -1283,7 +1285,7 @@ static void CALogPayloadInfo(CAInfo_t *info)
 
         if (info->payload)
         {
-            OIC_LOG_V(DEBUG, TAG, "payload: %p(%u)", info->payload,
+            OIC_LOG_V(DEBUG, TAG, "payload: %p(%zu)", info->payload,
                       info->payloadSize);
         }
 
index 227543d..d5f9a3e 100644 (file)
@@ -200,6 +200,8 @@ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode,
         transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)data)[0] >> 4);
     }
     else
+#else
+    (void) endpoint;
 #endif
     {
         transport = coap_udp;
@@ -289,8 +291,8 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, const CAInfo_t *info,
                 }
                 msgLength += optLength;
                 prevOptNumber = curOptNumber;
-                OIC_LOG_V(DEBUG, TAG, "curOptNumber[%d], prevOptNumber[%d], optValueLen[%d], "
-                        "optLength[%d], msgLength[%d]",
+                OIC_LOG_V(DEBUG, TAG, "curOptNumber[%d], prevOptNumber[%d], optValueLen[%zu], "
+                        "optLength[%zu], msgLength[%d]",
                           curOptNumber, prevOptNumber, optValueLen, optLength, msgLength);
             }
         }
@@ -317,7 +319,7 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, const CAInfo_t *info,
         return NULL;
     }
 
-    OIC_LOG_V(DEBUG, TAG, "transport type: %d, payload size: %d",
+    OIC_LOG_V(DEBUG, TAG, "transport type: %d, payload size: %zu",
               *transport, info->payloadSize);
 
 #ifdef TCP_ADAPTER
@@ -726,6 +728,8 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
         transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)pdu->hdr)[0] >> 4);
     }
     else
+#else
+    (void) endpoint;
 #endif
     {
         transport = coap_udp;
@@ -953,7 +957,7 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
 
     if (optionResult[0] != '\0')
     {
-        OIC_LOG_V(DEBUG, TAG, "URL length:%d", strlen(optionResult));
+        OIC_LOG_V(DEBUG, TAG, "URL length:%zu", strlen(optionResult));
         outInfo->resourceUri = OICStrdup(optionResult);
         if (!outInfo->resourceUri)
         {
@@ -994,6 +998,8 @@ CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo,
         transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)pdu_hdr)[0] >> 4);
     }
     else
+#else
+    (void) endpoint;
 #endif
     {
         transport = coap_udp;
index 4f212c2..125ae10 100644 (file)
@@ -140,7 +140,7 @@ static bool CACheckTimeout(uint64_t currentTime, CARetransmissionData_t *retData
 
     if (currentTime >= retData->timeStamp + timeout)
     {
-        OIC_LOG_V(DEBUG, TAG, "%d microseconds time out!!, tried count(%ld)",
+        OIC_LOG_V(DEBUG, TAG, "%zu microseconds time out!!, tried count(%d)",
                   timeout, retData->triedCount);
         return true;
     }
index 544f561..7df7585 100755 (executable)
@@ -46,6 +46,12 @@ static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
 
 CAResult_t CAIPJniInit();
 
+/**
+ * destroy JNI interface.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+static CAResult_t CAIPDestroyJniInterface();
+
 #define MAX_INTERFACE_INFO_LENGTH 1024 // allows 32 interfaces from SIOCGIFCONF
 
 CAResult_t CAIPStartNetworkMonitor()
@@ -55,7 +61,7 @@ CAResult_t CAIPStartNetworkMonitor()
 
 CAResult_t CAIPStopNetworkMonitor()
 {
-    return CA_STATUS_OK;
+    return CAIPDestroyJniInterface();
 }
 
 int CAGetPollingInterval(int interval)
@@ -361,6 +367,78 @@ CAResult_t CAIPJniInit()
     return CA_STATUS_OK;
 }
 
+static CAResult_t CAIPDestroyJniInterface()
+{
+    OIC_LOG(DEBUG, TAG, "CAIPDestroyJniInterface");
+
+    JavaVM *jvm = CANativeJNIGetJavaVM();
+    if (!jvm)
+    {
+        OIC_LOG(ERROR, TAG, "Could not get JavaVM pointer");
+        return CA_STATUS_FAILED;
+    }
+
+    bool isAttached = false;
+    JNIEnv* env;
+    jint res = (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
+        res = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
+
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
+        }
+        isAttached = true;
+    }
+
+    jclass jni_IpInterface = (*env)->FindClass(env, "org/iotivity/ca/CaIpInterface");
+    if (!jni_IpInterface)
+    {
+        OIC_LOG(ERROR, TAG, "Could not get CaIpInterface class");
+        goto error_exit;
+    }
+
+    jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_IpInterface,
+                                                                     "destroyIpInterface",
+                                                                     "()V");
+    if (!jni_InterfaceDestroyMethod)
+    {
+        OIC_LOG(ERROR, TAG, "Could not get CaIpInterface destroy method");
+        goto error_exit;
+    }
+
+    (*env)->CallStaticVoidMethod(env, jni_IpInterface, jni_InterfaceDestroyMethod);
+
+    if ((*env)->ExceptionCheck(env))
+    {
+        OIC_LOG(ERROR, TAG, "destroyIpInterface has failed");
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        goto error_exit;
+    }
+
+    OIC_LOG(DEBUG, TAG, "Destroy instance for CaIpInterface");
+
+    if (isAttached)
+    {
+        (*jvm)->DetachCurrentThread(jvm);
+    }
+
+    return CA_STATUS_OK;
+
+error_exit:
+
+    if (isAttached)
+    {
+        (*jvm)->DetachCurrentThread(jvm);
+    }
+
+    return CA_STATUS_FAILED;
+}
+
 JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaIpInterface_caIpStateEnabled(JNIEnv *env, jclass class)
 {
index 5dd5b87..e5db106 100644 (file)
@@ -120,7 +120,6 @@ static void CAReceiveHandler(void *data)
 {
     (void)data;
     OIC_LOG(DEBUG, TAG, "IN");
-
     while (!caglobals.ip.terminate)
     {
         CAFindReadyMessage();
@@ -196,8 +195,10 @@ static void CASelectReturned(fd_set *readFds, int ret)
             CAHandleNetlink();
             break;
         }
-        else
+        else if (FD_ISSET(caglobals.ip.shutdownFds[0], readFds))
         {
+            char buf[10] = {0};
+            (void)read(caglobals.ip.shutdownFds[0], buf, sizeof (buf));
             CAInterface_t *ifchanged = CAFindInterfaceChange();
             if (ifchanged)
             {
@@ -206,6 +207,10 @@ static void CASelectReturned(fd_set *readFds, int ret)
             }
             break;
         }
+        else
+        {
+            break;
+        }
 
         (void)CAReceiveMessage(fd, flags);
         FD_CLR(fd, readFds);
@@ -667,6 +672,7 @@ static void applyMulticastToInterface6(uint32_t interface)
     //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressSit, interface);
     //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressOrg, interface);
     //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressGlb, interface);
+
     //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressInt, interface);
     applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressLnk, interface);
     //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressRlm, interface);
index 74c800e..e51e11c 100644 (file)
@@ -211,9 +211,9 @@ static size_t CAGetTotalLengthFromHeader(const unsigned char *recvBuffer)
                                                         transport);
     size_t headerLen = coap_get_tcp_header_length((unsigned char *)recvBuffer);
 
-    OIC_LOG_V(DEBUG, TAG, "option/paylaod length [%d]", optPaylaodLen);
-    OIC_LOG_V(DEBUG, TAG, "header length [%d]", headerLen);
-    OIC_LOG_V(DEBUG, TAG, "total data length [%d]", headerLen + optPaylaodLen);
+    OIC_LOG_V(DEBUG, TAG, "option/paylaod length [%zu]", optPaylaodLen);
+    OIC_LOG_V(DEBUG, TAG, "header length [%zu]", headerLen);
+    OIC_LOG_V(DEBUG, TAG, "total data length [%zu]", headerLen + optPaylaodLen);
 
     OIC_LOG(DEBUG, TAG, "OUT - CAGetTotalLengthFromHeader");
     return headerLen + optPaylaodLen;
@@ -296,7 +296,7 @@ static CAResult_t CAReceiveMessage()
                 {
                     g_packetReceivedCallback(&ep, recvBuffer, totalLen);
                 }
-                OIC_LOG_V(DEBUG, TAG, "received data len:%d", totalLen);
+                OIC_LOG_V(DEBUG, TAG, "received data len:%zu", totalLen);
                 break;
             }
         } while (!totalLen || totalLen > totalReceivedLen);
@@ -710,7 +710,7 @@ static void sendData(const CAEndpoint_t *endpoint,
         remainLen -= len;
     } while (remainLen > 0);
 
-    OIC_LOG_V(INFO, TAG, "unicast ipv4tcp sendTo is successful: %d bytes", dlen);
+    OIC_LOG_V(INFO, TAG, "unicast ipv4tcp sendTo is successful: %zu bytes", dlen);
 }
 
 void CATCPSendData(CAEndpoint_t *endpoint, const void *data, uint32_t datalen,
index 41024e4..b13c3da 100644 (file)
@@ -775,7 +775,7 @@ void RMProcess()
 
     if (!g_isValidated && ROUTINGTABLE_REFRESH_TIMEOUT <= (currentTime - g_refreshTableTime))
     {
-        OC_LOG_V(DEBUG, TAG, "Refreshing the routing table: %u", currentTime);
+        OC_LOG_V(DEBUG, TAG, "Refreshing the routing table: %llu", currentTime);
         u_linklist_t* invalidInterfaces = NULL;
         RTMUpdateDestAddrValidity(&invalidInterfaces, &g_routingGatewayTable);
         if (0 < u_linklist_length(invalidInterfaces))
index c83530f..d9d74b5 100644 (file)
@@ -125,11 +125,19 @@ bool FoundAmaclForRequest(PEContext_t *context);
 
 /*
  * This method is used by Policy engine to process AMS request
- * *
+ *
  * @param context   Policy engine context.
  *
- * @return          None
  */
 void ProcessAMSRequest(PEContext_t *context);
 
+
+/*
+ * This method is used by Policy engine to free AMS context requestInfo
+ *
+ * @param requestInfo   pointer to CARequestInfo_t.
+ *
+ */
+void FreeCARequestInfo(CARequestInfo_t *requestInfo);
+
 #endif //IOTVT_SRM_AMSMGR_H
old mode 100644 (file)
new mode 100755 (executable)
index f6e2ff3..51414a6
@@ -534,13 +534,20 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                     DeleteDoxmBinData(ptrDoxm);
                     return OC_STACK_KEEP_TRANSACTION;
                 }
-
+                char rsrc_uri[MAX_URI_LENGTH+1] = {0};
+                int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",
+                          OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM);
+                if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))
+                {
+                    OC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");
+                    return OC_STACK_ERROR;
+                }
                 //Try to the unicast discovery to getting secure port
-                char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = { 0, };
+                char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};
                 if(!PMGenerateQuery(false,
                                     clientResponse->devAddr.addr, clientResponse->devAddr.port,
                                     clientResponse->connType,
-                                    query, sizeof(query), OC_RSRVD_WELL_KNOWN_URI))
+                                    query, sizeof(query), rsrc_uri))
                 {
                     OC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
                     return OC_STACK_KEEP_TRANSACTION;
index b9761ee..460609b 100755 (executable)
@@ -1219,7 +1219,7 @@ static void DeleteRemoveData_t(RemoveData_t* pRemoveData)
 static void registerResultForRemoveDevice(RemoveData_t *removeData, OicUuid_t *pLinkedDevId,
                                           OCStackResult stackresult, bool hasError)
 {
-    OC_LOG_V(INFO, TAG, "Inside registerResultForRemoveDevice removeData->numOfResults is %d\n",
+    OC_LOG_V(INFO, TAG, "Inside registerResultForRemoveDevice removeData->numOfResults is %zu\n",
                          removeData->numOfResults + 1);
     if (pLinkedDevId)
     {
index c0f7377..8779b0b 100644 (file)
@@ -181,13 +181,14 @@ static OCStackApplicationResult SecurePortDiscoveryCallback(void *ctx, OCDoHandl
         !clientResponse->payload||
         (PAYLOAD_TYPE_DISCOVERY != clientResponse->payload->type)||
         (OC_STACK_OK != clientResponse->result))
-        {
-            OC_LOG_V(ERROR, TAG, "%s Invalid Response ", __func__);
-            SRMSendResponse(ACCESS_DENIED_AMS_SERVICE_ERROR);
-            return OC_STACK_DELETE_TRANSACTION;
-        }
+    {
+        OC_LOG_V(ERROR, TAG, "%s Invalid Response ", __func__);
+        SRMSendResponse(ACCESS_DENIED_AMS_SERVICE_ERROR);
+        return OC_STACK_DELETE_TRANSACTION;
+    }
 
     PEContext_t *context = (PEContext_t *) ctx;
+
     (void)handle;
     if (context->state != AWAITING_AMS_RESPONSE)
     {
@@ -196,6 +197,7 @@ static OCStackApplicationResult SecurePortDiscoveryCallback(void *ctx, OCDoHandl
         SRMSendResponse(context->retVal);
         return OC_STACK_DELETE_TRANSACTION;
     }
+
     OCResourcePayload* resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
 
     //Verifying if the ID of the sender is an AMS service that this device trusts.
@@ -203,6 +205,7 @@ static OCStackApplicationResult SecurePortDiscoveryCallback(void *ctx, OCDoHandl
        memcmp(context->amsMgrContext->amsDeviceId.id, resPayload->sid,
                     sizeof(context->amsMgrContext->amsDeviceId.id)) != 0)
     {
+        OC_LOG_V(ERROR, TAG, "%s Invalid AMS device", __func__);
         context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
         SRMSendResponse(context->retVal);
         return OC_STACK_DELETE_TRANSACTION;
@@ -217,6 +220,7 @@ static OCStackApplicationResult SecurePortDiscoveryCallback(void *ctx, OCDoHandl
         }
     }
     OC_LOG(INFO, TAG, "Can not find secure port information");
+
     context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
     SRMSendResponse(context->retVal);
     return OC_STACK_DELETE_TRANSACTION;
@@ -279,8 +283,9 @@ static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handl
         (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type) ||
         (clientResponse->result != OC_STACK_OK))
     {
+        OC_LOG_V(ERROR, TAG, "%s Invalid Response ", __func__);
         SRMSendResponse(ACCESS_DENIED_AMS_SERVICE_ERROR);
-        goto exit;
+        return OC_STACK_DELETE_TRANSACTION;
     }
 
     if (context->state != AWAITING_AMS_RESPONSE)
@@ -315,8 +320,6 @@ static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handl
 exit:
     context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
     SRMSendResponse(context->retVal);
-    FreeCARequestInfo(context->amsMgrContext->requestInfo);
-    OICFree(context->amsMgrContext->endpoint);
     return OC_STACK_DELETE_TRANSACTION;
 }
 
@@ -351,6 +354,11 @@ exit:
 
 void FreeCARequestInfo(CARequestInfo_t *requestInfo)
 {
+    if(NULL == requestInfo)
+    {
+        OC_LOG_V(ERROR, TAG, "%s: Can't free memory. Received NULL requestInfo", __func__);
+        return;
+    }
     OICFree(requestInfo->info.token);
     OICFree(requestInfo->info.options);
     OICFree(requestInfo->info.payload);
@@ -404,6 +412,7 @@ void ProcessAMSRequest(PEContext_t *context)
                 if(OC_STACK_OK == DiscoverAmsService(context))
                 {
                     context->retVal = ACCESS_WAITING_FOR_AMS;
+                    context->state = AWAITING_AMS_RESPONSE;
                 }
                 else
                 {
index cb2bd37..6acb7e3 100644 (file)
@@ -596,9 +596,11 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
         }
         else if(OIC_RANDOM_DEVICE_PIN == newDoxm->oxmSel)
         {
+#ifdef __WITH_DTLS__
             //this temp Credential ID is used to track temporal Cred Id
             static OicUuid_t tmpCredId = {.id={0}};
             static bool tmpCredGenFlag = false;
+#endif //__WITH_DTLS__
 
             if ((false == gDoxm->owned) && (false == newDoxm->owned))
             {
index 8276365..d65578a 100644 (file)
@@ -320,6 +320,59 @@ static int DiffSecs(IotvtICalDateTime_t *time1, IotvtICalDateTime_t *time2)
            (3600 * time1->tm_hour + 60 * time1->tm_min + time1->tm_sec);
 }
 
+/**
+ * Validates if the @param currentTime is with in allowable period
+ *
+ * @param   period         -- allowable period
+ * @param   currentTime    -- the time that need to be validated against allowable time
+ *
+ * @return  IOTVTICAL_VALID_ACCESS      -- if the request is within valid time period
+ *          IOTVTICAL_INVALID_ACCESS    -- if the request is not within valid time period
+ *          IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
+ */
+static IotvtICalResult_t ValidatePeriod(IotvtICalPeriod_t *period, IotvtICalDateTime_t *currentTime)
+{
+    if(NULL == period || NULL == currentTime)
+    {
+        return IOTVTICAL_INVALID_PARAMETER;
+    }
+
+    bool validStartTime = true;
+    bool validEndTime = true;
+    bool validDay = false;
+    bool todayIsStartDay = (0 == DiffDays(&period->startDateTime, currentTime)) ? true : false;
+    bool todayIsEndDay = (0 == DiffDays(currentTime, &period->endDateTime)) ? true : false;
+
+    //If today is the start day of the allowable period then check
+    //currentTime > allowable period startTime
+    if(todayIsStartDay)
+    {
+        validStartTime = (0 <= DiffSecs(&period->startDateTime, currentTime)) ? true : false;
+    }
+
+    //If today is the end day of allowable period then check
+    //currentTime < allowable period endTime
+    if(todayIsEndDay)
+    {
+        validEndTime = (0 <= DiffSecs(currentTime, &period->endDateTime)) ? true :false;
+    }
+
+    //Check if today is valid day between startDate and EndDate inclusive
+    if((0 <= DiffDays(&period->startDateTime, currentTime)) &&
+       (0 <= DiffDays(currentTime, &period->endDateTime)))
+    {
+        validDay = true;
+    }
+
+    if(validDay && validStartTime && validEndTime)
+    {
+        return IOTVTICAL_VALID_ACCESS;
+    }
+    else
+    {
+        return IOTVTICAL_INVALID_ACCESS;
+    }
+}
 
 /**
  * This API is used by policy engine to checks if the
@@ -358,14 +411,10 @@ IotvtICalResult_t IsRequestWithinValidTime(char *periodStr, char *recurStr)
         return ret;
     }
 
-    //If recur is NULL then the access time is between period's startDate and endDate
+    //If recur is NULL then the access time is between period's startDateTime and endDateTime
     if(NULL == recurStr)
     {
-        if((0 <= DiffDays(&period.startDateTime, currentTime)) &&
-           (0 <= DiffDays(currentTime, &period.endDateTime)))
-        {
-            ret = IOTVTICAL_VALID_ACCESS;
-        }
+        ret = ValidatePeriod(&period, currentTime);
     }
 
     //If recur is not NULL then the access time is between period's startTime and
index ef7b005..36b03fa 100644 (file)
@@ -96,6 +96,9 @@ void SetPolicyEngineState(PEContext_t *context, const PEState_t state)
     context->matchingAclFound = false;
     context->amsProcessing = false;
     context->retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR;
+
+    FreeCARequestInfo(context->amsMgrContext->requestInfo);
+    OICFree(context->amsMgrContext->endpoint);
     memset(context->amsMgrContext, 0, sizeof(AmsMgrContext_t));
 
     // Set state.
@@ -442,14 +445,7 @@ SRMAccessResponse_t CheckPermission(
     // Capture retVal before resetting state for next request.
     retVal = context->retVal;
 
-    //Change the state of PE to "AWAITING_AMS_RESPONSE", if waiting
-    //for response from AMS service else to "AWAITING_REQUEST"
-    if(ACCESS_WAITING_FOR_AMS == retVal)
-    {
-        OC_LOG(INFO, TAG, "Setting PE State to AWAITING_AMS_RESPONSE");
-        context->state = AWAITING_AMS_RESPONSE;
-    }
-    else if(!context->amsProcessing)
+   if(!context->amsProcessing)
     {
         OC_LOG(INFO, TAG, "Resetting PE context and PE State to AWAITING_REQUEST");
         SetPolicyEngineState(context, AWAITING_REQUEST);
@@ -466,14 +462,18 @@ exit:
  */
 OCStackResult InitPolicyEngine(PEContext_t *context)
 {
-    if(NULL== context)
+    if(NULL == context)
     {
         return OC_STACK_ERROR;
     }
 
-    context->amsMgrContext = (AmsMgrContext_t *)OICMalloc(sizeof(AmsMgrContext_t));
-    SetPolicyEngineState(context, AWAITING_REQUEST);
+    context->amsMgrContext = (AmsMgrContext_t *)OICCalloc(1, sizeof(AmsMgrContext_t));
+    if(NULL == context->amsMgrContext)
+    {
+        return OC_STACK_ERROR;
+    }
 
+    SetPolicyEngineState(context, AWAITING_REQUEST);
     return OC_STACK_OK;
 }
 
index 992fe70..391c62f 100644 (file)
@@ -96,7 +96,7 @@ char * GetSVRDatabase()
             size_t bytesRead = ps->read(jsonStr, 1, size, fp);
             jsonStr[bytesRead] = '\0';
 
-            OC_LOG_V(DEBUG, TAG, "Read %d bytes from SVR database file", bytesRead);
+            OC_LOG_V(DEBUG, TAG, "Read %zu bytes from SVR database file", bytesRead);
             ps->close(fp);
             fp = NULL;
         }
@@ -190,7 +190,7 @@ OCStackResult UpdateSVRDatabase(const char* rsrcName, cJSON* jsonObj)
             {
                 ret = OC_STACK_OK;
             }
-            OC_LOG_V(DEBUG, TAG, "Written %d bytes into SVR database file", bytesWritten);
+            OC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", bytesWritten);
             ps->close(fp);
             fp = NULL;
         }
index 6d55727..a91bc53 100644 (file)
@@ -69,17 +69,26 @@ void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler)
 static void SRMSendUnAuthorizedAccessresponse(PEContext_t *context)
 {
     CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
+
+    if(NULL == context ||
+       NULL == context->amsMgrContext->requestInfo)
+    {
+        OC_LOG_V(ERROR, TAG, "%s : NULL Parameter(s)",__func__);
+        return;
+    }
+
     memcpy(&responseInfo.info, &(context->amsMgrContext->requestInfo->info),
             sizeof(responseInfo.info));
     responseInfo.info.payload = NULL;
     responseInfo.result = CA_UNAUTHORIZED_REQ;
-    if (CA_STATUS_OK != CASendResponse(context->amsMgrContext->endpoint, &responseInfo))
+
+    if (CA_STATUS_OK == CASendResponse(context->amsMgrContext->endpoint, &responseInfo))
     {
-        OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
+        OC_LOG(DEBUG, TAG, "Succeed in sending response to a unauthorized request!");
     }
     else
     {
-        OC_LOG(INFO, TAG, "Succeed in sending response to a unauthorized request!");
+        OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
     }
 }
 
@@ -92,7 +101,7 @@ void SRMSendResponse(SRMAccessResponse_t responseVal)
     {
         OC_LOG_V(INFO, TAG, "%s : Access granted. Passing Request to RI layer", __func__);
         if (!g_policyEngineContext.amsMgrContext->endpoint ||
-                !g_policyEngineContext.amsMgrContext->requestInfo)
+            !g_policyEngineContext.amsMgrContext->requestInfo)
         {
             OC_LOG_V(ERROR, TAG, "%s : Invalid arguments", __func__);
             SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext);
@@ -108,7 +117,7 @@ void SRMSendResponse(SRMAccessResponse_t responseVal)
     }
 
 exit:
-    //Resting PE state to AWAITING_REQUEST
+    //Resetting PE state to AWAITING_REQUEST
     SetPolicyEngineState(&g_policyEngineContext, AWAITING_REQUEST);
 }
 
index 5421efe..4c5b6b4 100644 (file)
@@ -131,10 +131,10 @@ static void printCred(const OicSecCred_t * cred)
         {
            OC_LOG_V(INFO, TAG, "cred->publicData.data = %s", credTmp1->publicData.data);
         }
-        OC_LOG_V(INFO, TAG, "cred->ownersLen = %zd", credTmp1->ownersLen);
+        OC_LOG_V(INFO, TAG, "cred->ownersLen = %zu", credTmp1->ownersLen);
         for(size_t i = 0; i < cred->ownersLen; i++)
         {
-            OC_LOG_V(INFO, TAG, "cred->owners[%zd].id = %s", i, credTmp1->owners[i].id);
+            OC_LOG_V(INFO, TAG, "cred->owners[%zu].id = %s", i, credTmp1->owners[i].id);
         }
     }
 }
index d453621..66c086e 100755 (executable)
@@ -21,6 +21,8 @@
 #ifndef OCPAYLOAD_H_
 #define OCPAYLOAD_H_
 
+#define __STDC_FORMAT_MACROS
+#define __STDC_LIMIT_MACROS
 #include <stdbool.h>
 #include <inttypes.h>
 #include "octypes.h"
@@ -60,6 +62,43 @@ bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64
 bool OCRepPayloadSetPropDouble(OCRepPayload* payload, const char* name, double value);
 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value);
 
+/**
+ * This function allocates memory for the byte string and sets it in the payload.
+ *
+ * @param payload      Pointer to the payload to which byte string needs to be added.
+ * @param name         Name of the byte string.
+ * @param value        Byte string and it's length.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value);
+
+/**
+ * This function sets the byte string in the payload.
+ *
+ * @param payload      Pointer to the payload to which byte string needs to be added.
+ * @param name         Name of the byte string.
+ * @param value        Byte string and it's length.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name,
+        OCByteString* value);
+
+/**
+ * This function gets the byte string from the payload.
+ *
+ * @param payload      Pointer to the payload from which byte string needs to be retrieved.
+ * @param name         Name of the byte string.
+ * @param value        Byte string and it's length.
+ *
+ * @note: Caller needs to invoke OCFree on value.bytes after it is finished using the byte string.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name,
+        OCByteString* value);
+
 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value);
 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value);
 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value);
@@ -72,6 +111,48 @@ bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name,
         OCRepPayload* value);
 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value);
 
+/**
+ * This function allocates memory for the byte string array and sets it in the payload.
+ *
+ * @param payload      Pointer to the payload to which byte string array needs to be added.
+ * @param name         Name of the byte string.
+ * @param array        Byte string array.
+ * @param dimensions   Number of byte strings in above array.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
+        OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+/**
+ * This function sets the byte string array in the payload.
+ *
+ * @param payload      Pointer to the payload to which byte string array needs to be added.
+ * @param name         Name of the byte string.
+ * @param array        Byte string array.
+ * @param dimensions   Number of byte strings in above array.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
+        const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+/**
+ * This function gets the byte string array from the payload.
+ *
+ * @param payload      Pointer to the payload from which byte string array needs to be retrieved.
+ * @param name         Name of the byte string array.
+ * @param value        Byte string array.
+ * @param dimensions   Number of byte strings in above array.
+ *
+ * @note: Caller needs to invoke OICFree on 'bytes' field of all array elements after it is
+ *        finished using the byte string array.
+ *
+ * @return true on success, false upon failure.
+ */
+bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
+        OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
         int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
index 63c9c23..45beceb 100644 (file)
@@ -336,11 +336,8 @@ typedef enum
     /**Remote Access over XMPP.*/
     OC_ADAPTER_REMOTE_ACCESS = (1 << 3),
 #endif
-
-#ifdef TCP_ADAPTER
     /** CoAP over TCP.*/
     OC_ADAPTER_TCP           = (1 << 4)
-#endif
 
 } OCTransportAdapter;
 
@@ -462,11 +459,8 @@ typedef enum
     /** Remote Access over XMPP.*/
     CT_ADAPTER_REMOTE_ACCESS = (1 << 19),
 #endif
-
-#ifdef TCP_ADAPTER
     /** CoAP over TCP.*/
     CT_ADAPTER_TCP          = (1 << 20),
-#endif
 
     /** Insecure transport is the default (subject to change).*/
 
@@ -943,10 +937,21 @@ typedef enum
     OCREP_PROP_DOUBLE,
     OCREP_PROP_BOOL,
     OCREP_PROP_STRING,
+    OCREP_PROP_BYTE_STRING,
     OCREP_PROP_OBJECT,
     OCREP_PROP_ARRAY
 }OCRepPayloadPropType;
 
+/** This structure will be used to represent a binary string for CBOR payloads.*/
+typedef struct
+{
+    /** pointer to data bytes.*/
+    uint8_t* bytes;
+
+    /** number of data bytes.*/
+    size_t   len;
+} OCByteString;
+
 #define MAX_REP_ARRAY_DEPTH 3
 typedef struct
 {
@@ -959,6 +964,10 @@ typedef struct
         double* dArray;
         bool* bArray;
         char** strArray;
+
+        /** pointer to ByteString array.*/
+        OCByteString* ocByteStrArray;
+
         struct OCRepPayload** objArray;
     };
 } OCRepPayloadValueArray;
@@ -973,6 +982,10 @@ typedef struct OCRepPayloadValue
         double d;
         bool b;
         char* str;
+
+        /** ByteString object.*/
+        OCByteString ocByteStr;
+
         struct OCRepPayload* obj;
         OCRepPayloadValueArray arr;
     };
index 1269779..2c181cd 100644 (file)
@@ -26,6 +26,9 @@
 #include <dlog.h>
 #endif
 
+#define __STDC_FORMAT_MACROS
+#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
 #include "rdpayload.h"
 
 #ifdef __cplusplus
@@ -80,7 +83,7 @@ static inline void OCPayloadLogRep(LogLevel level, OCRepPayload* payload)
                     OC_LOG_V(level, PL_TAG, "\t\t%s: NULL", val->name);
                     break;
                 case OCREP_PROP_INT:
-                    OC_LOG_V(level, PL_TAG, "\t\t%s(int):%lld", val->name, val->i);
+                    OC_LOG_V(level, PL_TAG, "\t\t%s(int):%zd", val->name, val->i);
                     break;
                 case OCREP_PROP_DOUBLE:
                     OC_LOG_V(level, PL_TAG, "\t\t%s(double):%f", val->name, val->d);
@@ -91,6 +94,10 @@ static inline void OCPayloadLogRep(LogLevel level, OCRepPayload* payload)
                 case OCREP_PROP_STRING:
                     OC_LOG_V(level, PL_TAG, "\t\t%s(string):%s", val->name, val->str);
                     break;
+                case OCREP_PROP_BYTE_STRING:
+                    OC_LOG_V(level, PL_TAG, "\t\t%s(binary):", val->name);
+                    OC_LOG_BUFFER(level, PL_TAG, val->ocByteStr.bytes, val->ocByteStr.len);
+                    break;
                 case OCREP_PROP_OBJECT:
                     // Note: Only prints the URI (if available), to print further, you'll
                     // need to dig into the object better!
@@ -100,31 +107,37 @@ static inline void OCPayloadLogRep(LogLevel level, OCRepPayload* payload)
                     switch(val->arr.type)
                     {
                         case OCREP_PROP_INT:
-                            OC_LOG_V(level, PL_TAG, "\t\t%s(int array):%lld x %lld x %lld",
+                            OC_LOG_V(level, PL_TAG, "\t\t%s(int array):%zu x %zu x %zu",
                                     val->name,
                                     val->arr.dimensions[0], val->arr.dimensions[1],
                                     val->arr.dimensions[2]);
                             break;
                         case OCREP_PROP_DOUBLE:
-                            OC_LOG_V(level, PL_TAG, "\t\t%s(double array):%lld x %lld x %lld",
+                            OC_LOG_V(level, PL_TAG, "\t\t%s(double array):%zu x %zu x %zu",
                                     val->name,
                                     val->arr.dimensions[0], val->arr.dimensions[1],
                                     val->arr.dimensions[2]);
                             break;
                         case OCREP_PROP_BOOL:
-                            OC_LOG_V(level, PL_TAG, "\t\t%s(bool array):%lld x %lld x %lld",
+                            OC_LOG_V(level, PL_TAG, "\t\t%s(bool array):%zu x %zu x %zu",
                                     val->name,
                                     val->arr.dimensions[0], val->arr.dimensions[1],
                                     val->arr.dimensions[2]);
                             break;
                         case OCREP_PROP_STRING:
-                            OC_LOG_V(level, PL_TAG, "\t\t%s(string array):%lld x %lld x %lld",
+                            OC_LOG_V(level, PL_TAG, "\t\t%s(string array):%zu x %zu x %zu",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_BYTE_STRING:
+                            OC_LOG_V(level, PL_TAG, "\t\t%s(byte array):%lld x %lld x %lld",
                                     val->name,
                                     val->arr.dimensions[0], val->arr.dimensions[1],
                                     val->arr.dimensions[2]);
                             break;
                         case OCREP_PROP_OBJECT:
-                            OC_LOG_V(level, PL_TAG, "\t\t%s(OCRep array):%lld x %lld x %lld",
+                            OC_LOG_V(level, PL_TAG, "\t\t%s(OCRep array):%zu x %zu x %zu",
                                     val->name,
                                     val->arr.dimensions[0], val->arr.dimensions[1],
                                     val->arr.dimensions[2]);
index d1ea32e..dca270d 100644 (file)
@@ -60,8 +60,6 @@ static std::string coapServerResource = "/a/light";
 
 void StripNewLineChar(char* str);
 
-// The handle for the observe registration
-OCDoHandle gObserveDoHandle;
 #ifdef WITH_PRESENCE
 // The handle for observe registration
 OCDoHandle gPresenceHandle;
@@ -162,10 +160,6 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     {
         OC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, method);
     }
-    else if (method == OC_REST_OBSERVE || method == OC_REST_OBSERVE_ALL)
-    {
-        gObserveDoHandle = handle;
-    }
 #ifdef WITH_PRESENCE
     else if (method == OC_REST_PRESENCE)
     {
@@ -279,7 +273,7 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle /*handle*/,
     return OC_STACK_DELETE_TRANSACTION;
 }
 
-OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle /*handle*/,
+OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle,
                                   OCClientResponse * clientResponse)
 {
     if (ctx == (void*)DEFAULT_CONTEXT_VALUE)
@@ -296,11 +290,12 @@ OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle /*handle*/,
         OC_LOG_PAYLOAD(INFO, clientResponse->payload);
         OC_LOG(INFO, TAG, ("=============> Obs Response"));
         gNumObserveNotifies++;
-        if (gNumObserveNotifies == 15) //large number to test observing in DELETE case.
+        if (gNumObserveNotifies > 15) //large number to test observing in DELETE case.
         {
             if (TestCase == TEST_OBS_REQ_NON || TestCase == TEST_OBS_REQ_CON)
             {
-                if (OCCancel (gObserveDoHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
+                OC_LOG(ERROR, TAG, "Cancelling with LOW QOS");
+                if (OCCancel (handle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
                 {
                     OC_LOG(ERROR, TAG, "Observe cancel error");
                 }
@@ -308,7 +303,8 @@ OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle /*handle*/,
             }
             else if (TestCase == TEST_OBS_REQ_NON_CANCEL_IMM)
             {
-                if (OCCancel (gObserveDoHandle, OC_HIGH_QOS, NULL, 0) != OC_STACK_OK)
+                OC_LOG(ERROR, TAG, "Cancelling with HIGH QOS");
+                if (OCCancel (handle, OC_HIGH_QOS, NULL, 0) != OC_STACK_OK)
                 {
                     OC_LOG(ERROR, TAG, "Observe cancel error");
                 }
index 10153d3..ab37a10 100644 (file)
@@ -317,7 +317,7 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
     }
     OCEntityHandlerResult ehResult = OC_EH_OK;
 
-    OC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %d ", __func__, ehRequest->resource);
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %p ", __func__, ehRequest->resource);
 
     /*
      * In the sample below, the application will:
index cf7d754..43694bb 100755 (executable)
@@ -197,6 +197,10 @@ static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
     {
         OICFree(val->str);
     }
+    else if(val->type == OCREP_PROP_BYTE_STRING)
+    {
+        OICFree(val->ocByteStr.bytes);
+    }
     else if (val->type == OCREP_PROP_OBJECT)
     {
         OCRepPayloadDestroy(val->obj);
@@ -220,6 +224,13 @@ static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
                 }
                 OICFree(val->arr.strArray);
                 break;
+            case OCREP_PROP_BYTE_STRING:
+                for (size_t i = 0; i< dimTotal; ++i)
+                {
+                    OICFree(val->arr.ocByteStrArray[i].bytes);
+                }
+                OICFree(val->arr.ocByteStrArray);
+                break;
             case OCREP_PROP_OBJECT:
                 for(size_t i = 0; i< dimTotal;++i)
                 {
@@ -479,6 +490,9 @@ static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
         case OCREP_PROP_STRING:
                val->str = (char*)value;
                return val->str != NULL;
+        case OCREP_PROP_BYTE_STRING:
+               val->ocByteStr = *(OCByteString*)value;
+               break;
         case OCREP_PROP_NULL:
                return val != NULL;
         case OCREP_PROP_ARRAY:
@@ -562,6 +576,62 @@ bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, ch
     return *value != NULL;
 }
 
+bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
+{
+    if (!value.bytes || !value.len)
+    {
+        return false;
+    }
+
+    OCByteString ocByteStr = {
+                    .bytes = (uint8_t*)OICMalloc(value.len * sizeof(uint8_t)),
+                    .len = value.len };
+
+    if(!ocByteStr.bytes)
+    {
+        return false;
+    }
+    memcpy(ocByteStr.bytes, value.bytes, ocByteStr.len);
+
+    bool b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
+
+    if(!b)
+    {
+        OICFree(ocByteStr.bytes);
+    }
+    return b;
+}
+
+bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
+{
+    return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
+}
+
+bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if (!val || val->type != OCREP_PROP_BYTE_STRING)
+    {
+        return false;
+    }
+
+    if (!value)
+    {
+        return false;
+    }
+
+    value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
+    if (!value->bytes)
+    {
+        return false;
+    }
+    value->len = val->ocByteStr.len;
+    memcpy(value->bytes, val->ocByteStr.bytes, value->len);
+
+    return true;
+}
+
 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
         const char* name, bool value)
 {
@@ -626,6 +696,123 @@ size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
     return total;
 }
 
+
+bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
+        OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if (!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_BYTE_STRING;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.ocByteStrArray = array;
+
+    return true;
+}
+
+bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
+        const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    if (!array)
+    {
+        return NULL;
+    }
+
+    size_t dimTotal = calcDimTotal(dimensions);
+    if (dimTotal == 0)
+    {
+        return false;
+    }
+
+    OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
+
+    if (!newArray)
+    {
+        return false;
+    }
+
+    for (size_t i = 0; i < dimTotal; ++i)
+    {
+        newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
+        if (NULL == newArray[i].bytes)
+        {
+            for (size_t j = 0; j < i; ++j)
+            {
+                OICFree(newArray[j].bytes);
+            }
+
+            OICFree(newArray);
+            return false;
+        }
+        newArray[i].len = array[i].len;
+        memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
+    }
+
+    bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
+    if (!b)
+    {
+        for (size_t i = 0; i < dimTotal; ++i)
+        {
+            OICFree(newArray[i].bytes);
+        }
+
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
+        OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
+            || !val->arr.ocByteStrArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if (dimTotal == 0)
+    {
+        return false;
+    }
+
+    *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
+    if (!*array)
+    {
+        return false;
+    }
+
+    for (size_t i = 0; i < dimTotal; ++i)
+    {
+        OCByteString* tmp = &(*array)[i];
+        tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
+        if (NULL == tmp->bytes)
+        {
+            for (size_t j = 0; j < i; ++j)
+            {
+                OCByteString* tmp = &(*array)[j];
+                OICFree(tmp->bytes);
+            }
+            OICFree(*array);
+            *array = NULL;
+
+            return false;
+        }
+        tmp->len = val->arr.ocByteStrArray[i].len;
+        memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
+    }
+
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    return true;
+}
+
+
 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
         int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
 {
index 152774c..4e80fc0 100644 (file)
@@ -166,7 +166,7 @@ static int64_t checkError(int64_t err, CborEncoder* encoder, uint8_t* outPayload
     }
     else if (err != 0)
     {
-        OC_LOG_V(ERROR, TAG, "Convert Payload failed", err);
+        OC_LOG_V(ERROR, TAG, "Convert Payload failed : %zd", err);
         return err;
     }
     else
@@ -175,6 +175,7 @@ static int64_t checkError(int64_t err, CborEncoder* encoder, uint8_t* outPayload
         return 0;
     }
 }
+
 static int64_t OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t* outPayload,
         size_t* size)
 {
@@ -200,7 +201,6 @@ static int64_t OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t* out
 
     err = err | cbor_encoder_close_container(&encoder, &rootArray);
     return checkError(err, &encoder, outPayload, size);
-
 }
 
 static char* OCStringLLJoin(OCStringLL* val)
@@ -578,6 +578,17 @@ static int64_t OCConvertArrayItem(CborEncoder* array, const OCRepPayloadValueArr
                         strlen(valArray->strArray[index]));
             }
             break;
+        case OCREP_PROP_BYTE_STRING:
+            if (!valArray->strArray[index])
+            {
+                err = err | cbor_encode_null(array);
+            }
+            else
+            {
+                err = err | cbor_encode_byte_string(array, valArray->ocByteStrArray[index].bytes,
+                        valArray->ocByteStrArray[index].len);
+            }
+            break;
         case OCREP_PROP_OBJECT:
             if (!valArray->objArray[index])
             {
@@ -735,6 +746,10 @@ static int64_t OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload
                     err = err | cbor_encode_text_string(&repMap,
                             value->str, strlen(value->str));
                     break;
+                case OCREP_PROP_BYTE_STRING:
+                    err = err | cbor_encode_byte_string(&repMap,
+                            value->ocByteStr.bytes, value->ocByteStr.len);
+                    break;
                 case OCREP_PROP_OBJECT:
                     err = err | OCConvertSingleRepPayload(&repMap, value->obj);
                     break;
index d2aaf6a..e33dda4 100644 (file)
@@ -56,7 +56,7 @@ OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
     CborValue rootValue;
     bool err = false;
 
-    OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize);
+    OC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu", payloadSize);
     if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
     {
         OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
@@ -723,6 +723,8 @@ static OCRepPayloadPropType DecodeCborType(CborType type)
                 return OCREP_PROP_BOOL;
             case CborTextStringType:
                 return OCREP_PROP_STRING;
+            case CborByteStringType:
+                return OCREP_PROP_BYTE_STRING;
             case CborMapType:
                 return OCREP_PROP_OBJECT;
             case CborArrayType:
@@ -803,6 +805,8 @@ static size_t getAllocSize(OCRepPayloadPropType type)
             return sizeof (bool);
         case OCREP_PROP_STRING:
             return sizeof (char*);
+        case OCREP_PROP_BYTE_STRING:
+            return sizeof (OCByteString);
         case OCREP_PROP_OBJECT:
             return sizeof (OCRepPayload*);
         default:
@@ -828,6 +832,7 @@ static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX
 
     size_t i = 0;
     char* tempStr = NULL;
+    OCByteString ocByteStr = { .bytes = NULL, .len = 0};
     size_t tempLen = 0;
     OCRepPayload* tempPl = NULL;
 
@@ -900,6 +905,21 @@ static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX
                             );
                     }
                     break;
+                case OCREP_PROP_BYTE_STRING:
+                    if (dimensions[1] == 0)
+                    {
+                        err = err || cbor_value_dup_byte_string(&insideArray,
+                                &(ocByteStr.bytes), &(ocByteStr.len), NULL);
+                        ((OCByteString*)targetArray)[i] = ocByteStr;
+                    }
+                    else
+                    {
+                        err = err || OCParseArrayFillArray(&insideArray, newdim,
+                                type,
+                                &(((OCByteString*)targetArray)[arrayStep(dimensions, i)])
+                                );
+                    }
+                    break;
                 case OCREP_PROP_OBJECT:
                     if (dimensions[1] == 0)
                     {
@@ -993,6 +1013,17 @@ static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* contain
                 err = true;
             }
             break;
+        case OCREP_PROP_BYTE_STRING:
+            if (err || !OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString*)arr, dimensions))
+            {
+                for (size_t i = 0; i < dimTotal; ++i)
+                {
+                    OICFree(((OCByteString*)arr)[i].bytes);
+                }
+                OICFree(arr);
+                err = true;
+            }
+            break;
         case OCREP_PROP_OBJECT:
             if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
             {
@@ -1111,6 +1142,7 @@ static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repPar
             int64_t intval = 0;
             bool boolval = false;
             char* strval = NULL;
+            uint8_t* bytestrval = NULL;
             double doubleval = 0;
             OCRepPayload* pl;
 
@@ -1147,6 +1179,14 @@ static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repPar
                         err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
                     }
                     break;
+                case CborByteStringType:
+                    err = err || cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
+                    if (!err)
+                    {
+                        OCByteString tmp = {.bytes = bytestrval, .len = len};
+                        err = !OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
+                    }
+                    break;
                 case CborMapType:
                     err = err || OCParseSingleRepPayload(&pl, &repMap);
                     if (!err)
old mode 100644 (file)
new mode 100755 (executable)
index a15fcc1..29c55b6
@@ -117,7 +117,7 @@ static void DeleteServerResponse(OCServerResponse * serverResponse)
     if(serverResponse)
     {
         LL_DELETE(serverResponseList, serverResponse);
-        OICFree(serverResponse->payload);
+        OCPayloadDestroy(serverResponse->payload);
         OICFree(serverResponse);
         OC_LOG(INFO, TAG, "Server Response Removed!!");
     }
@@ -442,7 +442,7 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result, OCMe
                    // This should not happen but,
                    // give it a value just in case but output an error
                    caResult = CA_CONTENT;
-                   OC_LOG_V(ERROR, TAG, "Unexpected OC_EH_OK return code for method [d].", method);
+                   OC_LOG_V(ERROR, TAG, "Unexpected OC_EH_OK return code for method [%d].", method);
            }
             break;
         case OC_EH_ERROR:
@@ -634,10 +634,7 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
 #ifdef RA_ADAPTER
                             , CA_ADAPTER_REMOTE_ACCESS
 #endif
-
-#ifdef TCP_ADAPTER
                             , CA_ADAPTER_TCP
-#endif
                         };
 
     size_t size = sizeof(CAConnTypes)/ sizeof(CATransportAdapter_t);
@@ -655,10 +652,7 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
 #ifdef RA_ADAP
                 | CA_ADAPTER_REMOTE_ACCESS
 #endif
-
-#ifdef TCP_ADAPTER
                 | CA_ADAPTER_TCP
-#endif
             );
     }
 
@@ -746,14 +740,16 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
             goto exit;
         }
 
+        OCRepPayload *newPayload = OCRepPayloadClone((OCRepPayload *)ehResponse->payload);
+
         if(!serverResponse->payload)
         {
-            serverResponse->payload = ehResponse->payload;
+            serverResponse->payload = (OCPayload *)newPayload;
         }
         else
         {
             OCRepPayloadAppend((OCRepPayload*)serverResponse->payload,
-                    (OCRepPayload*)ehResponse->payload);
+                    (OCRepPayload*)newPayload);
         }
 
 
index 46a110b..3224ace 100755 (executable)
@@ -30,6 +30,9 @@
 // For POSIX.1-2001 base specification,
 // Refer http://pubs.opengroup.org/onlinepubs/009695399/
 #define _POSIX_C_SOURCE 200112L
+#define __STDC_FORMAT_MACROS
+#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
 #include <string.h>
 #include <ctype.h>
 
@@ -113,10 +116,8 @@ static bool gRASetInfo = false;
 #endif
 OCDeviceEntityHandler defaultDeviceHandler;
 void* defaultDeviceHandlerCallbackParameter = NULL;
-
-#ifdef TCP_ADAPTER
 static const char COAP_TCP[] = "coap+tcp:";
-#endif
+
 
 //-----------------------------------------------------------------------------
 // Macros
@@ -1877,17 +1878,6 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag
         caglobals.clientFlags = (CATransportFlags_t)(caglobals.clientFlags|CA_IPV4|CA_IPV6);
     }
 
-#ifdef TCP_ADAPTER
-    if (!(caglobals.serverFlags & CA_IPFAMILY_MASK))
-    {
-        caglobals.serverFlags = (CATransportFlags_t)(caglobals.serverFlags|CA_IPV4);
-    }
-    if (!(caglobals.clientFlags & CA_IPFAMILY_MASK))
-    {
-        caglobals.clientFlags = (CATransportFlags_t)(caglobals.clientFlags|CA_IPV4);
-    }
-#endif
-
     defaultDeviceHandler = NULL;
     defaultDeviceHandlerCallbackParameter = NULL;
     OCSeedRandom();
@@ -2130,7 +2120,6 @@ static OCStackResult ParseRequestUri(const char *fullUri,
         return OC_STACK_INVALID_URI;
     }
 
-#ifdef TCP_ADAPTER
     // process url scheme
     size_t prefixLen = slash2 - fullUri;
     bool istcp = false;
@@ -2141,7 +2130,6 @@ static OCStackResult ParseRequestUri(const char *fullUri,
             istcp = true;
         }
     }
-#endif
 
     // TODO: this logic should come in with unit tests exercising the various strings
     // processs url prefix, if any
@@ -2173,13 +2161,12 @@ static OCStackResult ParseRequestUri(const char *fullUri,
             {   // ipv4 address
                 colon = strchr(start, ':');
                 end = (colon && colon < slash) ? colon : slash;
-#ifdef TCP_ADAPTER
+
                 if (istcp)
                 {   // coap over tcp
                     adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_TCP);
                 }
                 else
-#endif
                 {
                     adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_IP);
                     flags = (OCTransportFlags)(flags | OC_IP_USE_V4);
@@ -2820,7 +2807,7 @@ OCStackResult OCStartPresence(const uint32_t ttl)
     {
         presenceResource.presenceTTL = ttl;
     }
-    OC_LOG_V(DEBUG, TAG, "Presence TTL is %lu seconds", presenceResource.presenceTTL);
+    OC_LOG_V(DEBUG, TAG, "Presence TTL is %" PRIu32 " seconds", presenceResource.presenceTTL);
 
     if (OC_PRESENCE_UNINITIALIZED == presenceState)
     {
index 20d8735..d7eb9d9 100755 (executable)
@@ -1329,7 +1329,7 @@ OCStackResult BuildCollectionGroupActionCBORResponse(
 #endif
                             if (delay > 0)
                             {
-                                OC_LOG_V(INFO, TAG, "delay_time is %lf seconds.",
+                                OC_LOG_V(INFO, TAG, "delay_time is %ld seconds.",
                                         actionset->timesteps);
 #ifndef WITH_ARDUINO
                                 pthread_mutex_lock(&lock);
index ade8f3f..6654610 100644 (file)
@@ -69,8 +69,9 @@ if env.get('LOGGING'):
 # Source files and Targets
 ######################################################################
 stacktests = stacktest_env.Program('stacktests', ['stacktests.cpp'])
+cbortests = stacktest_env.Program('cbortests', ['cbortests.cpp'])
 
-Alias("test", [stacktests])
+Alias("test", [stacktests, cbortests])
 
 env.AppendTarget('test')
 if env.get('TEST') == '1':
diff --git a/resource/csdk/stack/test/cbortests.cpp b/resource/csdk/stack/test/cbortests.cpp
new file mode 100644 (file)
index 0000000..2e4a202
--- /dev/null
@@ -0,0 +1,222 @@
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+extern "C"
+{
+    #include "ocstack.h"
+    #include "ocpayload.h"
+    #include "ocpayloadcbor.h"
+    #include "logger.h"
+    #include "oic_malloc.h"
+}
+
+#include "gtest/gtest.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+#include <stdint.h>
+
+#include "gtest_helper.h"
+
+class CborByteStringTest : public ::testing::Test {
+    protected:
+        virtual void SetUp() {
+            // Create Payload
+            payload_in = OCRepPayloadCreate();
+            ASSERT_TRUE(payload_in != NULL);
+        }
+
+        virtual void TearDown() {
+            OCPayloadDestroy((OCPayload*)payload_in);
+        }
+
+        OCRepPayload* payload_in;
+};
+
+TEST_F(CborByteStringTest, ByteStringSetGetTest)
+{
+    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
+    OCRepPayloadSetPropInt(payload_in, "scale", 4);
+
+    uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0xA, 0xB, 0xC,
+                        0xD, 0xE, 0xF};
+    OCByteString quakedata_in = { binval, sizeof(binval)};
+
+    EXPECT_EQ(true, OCRepPayloadSetPropByteString(payload_in, "quakedata", quakedata_in));
+
+    OCByteString quakedata_out = { NULL, 0};
+    ASSERT_EQ(true, OCRepPayloadGetPropByteString(payload_in, "quakedata", &quakedata_out));
+
+    EXPECT_EQ(quakedata_in.len, quakedata_out.len);
+    EXPECT_EQ(0, memcmp(quakedata_in.bytes, quakedata_out.bytes, quakedata_in.len));
+
+    // Cleanup
+    OICFree(quakedata_out.bytes);
+}
+
+TEST_F(CborByteStringTest, ByteStringConvertParseTest)
+{
+    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
+    OCRepPayloadSetPropInt(payload_in, "scale", 4);
+
+    uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0xA, 0xB, 0xC,
+                        0xD, 0xE, 0xF};
+    OCByteString quakedata_in = { binval, sizeof(binval)};
+
+    // Set ByteString in Payload
+    EXPECT_EQ(true, OCRepPayloadSetPropByteString(payload_in, "quakedata", quakedata_in));
+
+    // Convert OCPayload to CBOR
+    uint8_t *payload_cbor = NULL;
+    size_t payload_cbor_size = 0;
+    EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, &payload_cbor, &payload_cbor_size));
+
+#ifdef CBOR_BIN_STRING_DEBUG
+    FILE *fp = fopen("binstring.cbor", "wb+");
+    if (fp)
+    {
+        fwrite(payload_cbor, 1, payload_cbor_size, fp);
+        fclose(fp);
+    }
+#endif //CBOR_BIN_STRING_DEBUG
+
+    // Parse CBOR back to OCPayload
+    OCPayload* payload_out = NULL;
+    EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, PAYLOAD_TYPE_REPRESENTATION,
+                 payload_cbor, payload_cbor_size));
+
+    OCByteString quakedata_out = {NULL, 0};
+    ASSERT_EQ(true, OCRepPayloadGetPropByteString((OCRepPayload*)payload_out, "quakedata", &quakedata_out));
+
+    // Compare input and output data
+    EXPECT_EQ(quakedata_in.len, quakedata_out.len);
+    EXPECT_EQ(0, memcmp(quakedata_in.bytes, quakedata_out.bytes, quakedata_in.len));
+
+    // Cleanup
+    OICFree(payload_cbor);
+    OICFree(quakedata_out.bytes);
+    OCPayloadDestroy((OCPayload*)payload_out);
+}
+
+TEST_F(CborByteStringTest, ByteStringArraySetGetTest )
+{
+    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
+    OCRepPayloadSetPropInt(payload_in, "scale", 4);
+
+    size_t dimensions_in[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0};
+    uint8_t binval1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
+    uint8_t binval2[] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};
+    uint8_t binval3[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
+
+    OCByteString quakedata_in[3] = {{binval1, sizeof(binval1)},
+                                    {binval2, sizeof(binval2)},
+                                    {binval3, sizeof(binval3)}};
+
+    EXPECT_EQ(true, OCRepPayloadSetByteStringArray(payload_in, "quakedata",
+                quakedata_in, dimensions_in));
+
+    OCByteString* quakedata_out = NULL;
+    size_t dimensions_out[MAX_REP_ARRAY_DEPTH] = {0};
+    ASSERT_EQ(true, OCRepPayloadGetByteStringArray(payload_in, "quakedata",
+                &quakedata_out, dimensions_out));
+
+    for(size_t i = 0; i < dimensions_in[0]; i++)
+    {
+        EXPECT_EQ(quakedata_in[i].len, quakedata_out[i].len);
+        EXPECT_EQ(0, memcmp(quakedata_in[i].bytes, quakedata_out[i].bytes, quakedata_in[i].len));
+    }
+
+    // Cleanup
+    for(size_t i = 0; i < dimensions_out[0]; i++)
+    {
+        OICFree(quakedata_out[i].bytes);
+    }
+    OICFree(quakedata_out);
+}
+
+
+TEST_F(CborByteStringTest, ByteStringArrayConvertParseTest )
+{
+    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
+    OCRepPayloadSetPropInt(payload_in, "scale", 4);
+
+    size_t dimensions_in[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0};
+    uint8_t binval1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
+    uint8_t binval2[] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};
+    uint8_t binval3[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
+
+    OCByteString quakedata_in[3] = {{binval1, sizeof(binval1)},
+                                    {binval2, sizeof(binval2)},
+                                    {binval3, sizeof(binval3)}};
+
+    EXPECT_EQ(true, OCRepPayloadSetByteStringArray(payload_in, "quakedata",
+                quakedata_in, dimensions_in));
+
+    // Convert OCPayload to CBOR
+    uint8_t *payload_cbor = NULL;
+    size_t payload_cbor_size = 0;
+    EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, &payload_cbor, &payload_cbor_size));
+#ifdef CBOR_BIN_STRING_DEBUG
+    FILE *fp = fopen("binstringarr.cbor", "wb+");
+    if (fp)
+    {
+        fwrite(payload_cbor, 1, payload_cbor_size, fp);
+        fclose(fp);
+    }
+#endif //CBOR_BIN_STRING_DEBUG
+
+    // Parse CBOR back to OCPayload
+    OCPayload* payload_out = NULL;
+    EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, PAYLOAD_TYPE_REPRESENTATION,
+                payload_cbor, payload_cbor_size));
+
+    OCByteString* quakedata_out = NULL;
+    size_t dimensions_out[MAX_REP_ARRAY_DEPTH] = {0};
+    ASSERT_EQ(true, OCRepPayloadGetByteStringArray((OCRepPayload*)payload_out, "quakedata",
+                &quakedata_out, dimensions_out));
+
+    for(size_t i = 0; i < dimensions_in[0]; i++)
+    {
+        EXPECT_EQ(quakedata_in[i].len, quakedata_out[i].len);
+        EXPECT_EQ(0, memcmp(quakedata_in[i].bytes, quakedata_out[i].bytes, quakedata_in[i].len));
+    }
+
+    // Cleanup
+    OICFree(payload_cbor);
+    for(size_t i = 0; i < dimensions_out[0]; i++)
+    {
+        OICFree(quakedata_out[i].bytes);
+    }
+    OICFree(quakedata_out);
+
+    OCPayloadDestroy((OCPayload*)payload_out);
+}
index ab28c07..4ec0ec9 100644 (file)
@@ -666,6 +666,7 @@ INPUT                  = . \
                          ../include/OCResourceRequest.h \
                          ../include/OCResourceResponse.h \
                          ../include/OCResource.h \
+                         ../include/OCProvisioningManager.h \
                          ../csdk/stack/include/octypes.h \
                          ../csdk/stack/include/ocstackconfig.h \
                          guides \
index 84e88e5..f47daf1 100644 (file)
@@ -266,27 +266,10 @@ namespace OC
                     // ambigious conversions in the case where conversions can include a number of
                     // types, such as the string constructor.
                     template<typename T, typename std::enable_if<
-                     std::is_same<T, int>::value ||
-                     std::is_same<T, double>::value ||
-                     std::is_same<T, bool>::value ||
-                     std::is_same<T, std::string>::value ||
-                     std::is_same<T, OCRepresentation>::value ||
-                     std::is_same<T, std::vector<int>>::value ||
-                     std::is_same<T, std::vector<std::vector<int>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<int>>>>::value ||
-                     std::is_same<T, std::vector<double>>::value ||
-                     std::is_same<T, std::vector<std::vector<double>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<double>>>>::value ||
-                     std::is_same<T, std::vector<bool>>::value ||
-                     std::is_same<T, std::vector<std::vector<bool>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<bool>>>>::value ||
-                     std::is_same<T, std::vector<std::string>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::string>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<std::string>>>>::value ||
-                     std::is_same<T, std::vector<OCRepresentation>>::value ||
-                     std::is_same<T, std::vector<std::vector<OCRepresentation>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<OCRepresentation>>>>::value
-                     , int>::type = 0// enable_if
+                        is_component<T,
+                            remove_first<AttributeValue>::type
+                            >::value
+                        , int>::type = 0
                     >
                     operator T() const
                     {
index 87bdf35..8c7c34f 100644 (file)
@@ -112,6 +112,36 @@ namespace OC
     {
         constexpr static bool value = true;
     };
+
+    // type trait to remove the first type from a parameter-packed list
+    template <typename T>
+    struct remove_first;
+
+    // specialization that does all the work
+    template<template <typename...> class Base, typename T, typename ...Rest>
+    struct remove_first< Base<T, Rest...> >
+    {
+        typedef Base<Rest...> type;
+    };
+
+    // type trait that will only pass if ToTest is in the parameter pack of T2
+    template<typename ToTest, typename T2>
+    struct is_component;
+
+    // specialization to handle the single-item case
+    template<typename ToTest, template <typename...> class Base, typename T>
+    struct is_component<ToTest, Base<T>>
+    {
+        static constexpr bool value = std::is_same<ToTest, T>::value;
+    };
+
+    // Recursive specialization to handle cases with multiple values
+    template<typename ToTest, template <typename...> class Base, typename T, typename ...Rest>
+    struct is_component<ToTest, Base<T, Rest...>>
+    {
+        static constexpr bool value = std::is_same<ToTest, T>::value
+            || is_component<ToTest, Base<Rest...>>::value;
+    };
 } // namespace OC
 
 #endif
diff --git a/resource/oc_logger/samples/linux/README b/resource/oc_logger/samples/linux/README
deleted file mode 100644 (file)
index aa8683e..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
--------------------------------------------------------------------------------
-  NOTICE - Transition to SCONS
--------------------------------------------------------------------------------
-
-The IoTivity build system is transitioning to SCONS. Although the
-makefiles are still available (until v1.0) and some developers are
-still using them, they are currently no longer supported. To learn more
-about building using SCONS see Readme.scons.txt in the repository root
-directory. The build steps used in continuous integration can be found
-in auto_build.sh which is also in the the repository root directory.
-
--------------------------------------------------------------------------------
-
-To run the oc_logger C sample app, first build liboctbstack.a
-
-cd <root>/csdk
-
-To enable logging
-make BUILD=debug
-else
-make BUILD=release
-
-Next, build the oc_logger C sample app
-
-cd <root>/oc_logger/samples/linux
-
-To enable logging
-make BUILD=debug
-else
-make BUILD=release
-
-The logger sample has two options, default logging or
-a custom logger that can be supplied by the user application
-
-To run the application with the default logger, run
-
-./debug/test_logging -c 0
-
-To run the application using a built in custom console logger, run
-
-./debug/test_logging -c 1
-
-
-
diff --git a/resource/oc_logger/samples/linux/test_logging.c b/resource/oc_logger/samples/linux/test_logging.c
deleted file mode 100644 (file)
index 533a59a..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-//******************************************************************
-//
-// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#include "logger.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define TAG  ("MAIN")
-
-static int customLogger = 0;
-
-static void PrintUsage()
-{
-    OC_LOG(INFO, TAG, "Usage : test_logging -c <0|1>");
-    OC_LOG(INFO, TAG, "-u <0|1> : 0 - default logging, 1 - custom console logging");
-}
-
-int main(int argc, char* argv[])
-{
-    int opt;
-
-    while ((opt = getopt(argc, argv, "c:")) != -1)
-    {
-        switch(opt)
-        {
-            case 'c':
-                customLogger = atoi(optarg);
-                break;
-            default:
-                PrintUsage();
-                return -1;
-        }
-    }
-
-    if (customLogger == 0)
-    {
-        // Default logger
-        OC_LOG(DEBUG, TAG, "This is a DEBUG");
-        OC_LOG(INFO, TAG, "This is a INFO");
-        OC_LOG(WARNING, TAG, "This is a WARNING");
-        OC_LOG(ERROR, TAG, "This is a ERROR");
-        OC_LOG(FATAL, TAG, "This is a FATAL");
-    }
-    else
-    {
-        // Custom logger, in this case, the console logger
-        oc_log_ctx_t *log = oc_make_console_logger();
-
-        OC_LOG_CONFIG(log);
-
-        OC_LOG(DEBUG, TAG, "This is a DEBUG");
-        OC_LOG(INFO, TAG, "This is a INFO");
-        OC_LOG(WARNING, TAG, "This is a WARNING");
-        OC_LOG(ERROR, TAG, "This is a ERROR");
-        OC_LOG(FATAL, TAG, "This is a FATAL");
-        OC_LOG_SHUTDOWN();
-    }
-
-
-    return 0;
-}
index 8467fc7..47bb950 100644 (file)
@@ -28,10 +28,7 @@ namespace OC {
 
 static const char COAP[] = "coap://";
 static const char COAPS[] = "coaps://";
-
-#ifdef TCP_ADAPTER
 static const char COAP_TCP[] = "coap+tcp://";
-#endif
 
 using OC::nil_guard;
 using OC::result_guard;
@@ -69,7 +66,11 @@ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                         const std::vector<std::string>& interfaces)
  :  m_clientWrapper(clientWrapper), m_uri(uri),
     m_resourceId(serverId, m_uri),
-    m_devAddr{ OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0 },
+    m_devAddr{ OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0
+#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
+    , {0}
+#endif
+    },
     m_isObservable(observable), m_isCollection(false),
     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
     m_observeHandle(nullptr)
@@ -122,13 +123,11 @@ void OCResource::setHost(const std::string& host)
         prefix_len = sizeof(COAPS) - 1;
         m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags & OC_SECURE);
     }
-#ifdef TCP_ADAPTER
     else if (host.compare(0, sizeof(COAP_TCP) - 1, COAP_TCP) == 0)
     {
         prefix_len = sizeof(COAP_TCP) - 1;
         m_devAddr.adapter = static_cast<OCTransportAdapter>(m_devAddr.adapter & OC_ADAPTER_TCP);
     }
-#endif
     else
     {
         throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
@@ -424,12 +423,10 @@ std::string OCResource::host() const
     {
         ss << COAPS;
     }
-#ifdef TCP_ADAPTER
     else if (m_devAddr.adapter & OC_ADAPTER_TCP)
     {
         ss << COAP_TCP;
     }
-#endif
     else
     {
         ss << COAP;
@@ -562,4 +559,3 @@ bool OCResourceIdentifier::operator>=(const OCResourceIdentifier &other) const
 }
 
 } // namespace OC
-
index c254785..06e50c1 100644 (file)
@@ -41,6 +41,7 @@ if target_os == 'linux':
     # Build Common unit tests
        SConscript('c_common/oic_string/test/SConscript')
        SConscript('c_common/oic_malloc/test/SConscript')
+       SConscript('c_common/oic_time/test/SConscript')
 
        # Build C unit tests
        SConscript('csdk/stack/test/SConscript')
index 55ec89f..c4db98c 100644 (file)
@@ -83,6 +83,11 @@ namespace OCResourceTest
         EXPECT_ANY_THROW(ConstructResourceObject("coap://192.168.1.2", "/resource"));
     }
 
+    TEST(ConstructResourceTest, ConstructResourceObjectWithoutPortNumber2)
+    {
+        EXPECT_ANY_THROW(ConstructResourceObject("coap://192.168.1.2:", "/resource"));
+    }
+
     TEST(ConstructResourceTest, ConstructResourceObjectWithLongHostAddress)
     {
         EXPECT_ANY_THROW(ConstructResourceObject(gLongHostAddress, "/resource"));
index aa1ce17..26fb88e 100644 (file)
@@ -303,31 +303,31 @@ void LogProvisioningResponse(OCRepPayloadValue * val) {
         case OCREP_PROP_ARRAY:
             switch (val->arr.type) {
                 case OCREP_PROP_INT:
-                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(int array):%lu x %lu x %lu",
+                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(int array):%zu x %zu x %zu",
                               val->name,
                               val->arr.dimensions[0], val->arr.dimensions[1],
                               val->arr.dimensions[2]);
                     break;
                 case OCREP_PROP_DOUBLE:
-                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(double array):%lu x %lu x %lu",
+                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(double array):%zu x %zu x %zu",
                               val->name,
                               val->arr.dimensions[0], val->arr.dimensions[1],
                               val->arr.dimensions[2]);
                     break;
                 case OCREP_PROP_BOOL:
-                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(bool array):%lu x %lu x %lu",
+                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(bool array):%zu x %zu x %zu",
                               val->name,
                               val->arr.dimensions[0], val->arr.dimensions[1],
                               val->arr.dimensions[2]);
                     break;
                 case OCREP_PROP_STRING:
-                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(string array):%lu x %lu x %lu",
+                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(string array):%zu x %zu x %zu",
                               val->name,
                               val->arr.dimensions[0], val->arr.dimensions[1],
                               val->arr.dimensions[2]);
                     break;
                 case OCREP_PROP_OBJECT:
-                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(OCRep array):%lu x %lu x %lu",
+                    OIC_LOG_V(DEBUG, ES_PROV_TAG, "\t\t%s(OCRep array):%zu x %zu x %zu",
                               val->name,
                               val->arr.dimensions[0], val->arr.dimensions[1],
                               val->arr.dimensions[2]);
index f656f95..7bd6df1 100644 (file)
@@ -98,7 +98,6 @@
                                                                </option>
                                                                <option id="gnu.cpp.compiler.option.include.paths.1501991974" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
-                                                                       <listOptionValue builtIn="false" value="&quot;C:\boost_1_56_0&quot;"/>
                                                                        <listOptionValue builtIn="false" value="&quot;..\..\..\..\..\resource-encapsulation\src\resourceBroker\include&quot;"/>
                                                                        <listOptionValue builtIn="false" value="&quot;..\..\..\..\..\resource-encapsulation\src\resourceCache\include&quot;"/>
                                                                        <listOptionValue builtIn="false" value="&quot;..\..\..\..\..\resource-encapsulation\src\common\utils\include&quot;"/>
index d4e6f42..d9c1130 100644 (file)
@@ -77,7 +77,7 @@ create_list_view(appdata_s *ad)
     // This button is set for devices which doesn't have H/W back key.
     btn = elm_button_add(nf);
     elm_object_style_set(btn, "naviframe/end_btn/default");
-    nf_it = elm_naviframe_item_push(nf, "Resource Encapsulation", btn, NULL, list, NULL);
+    nf_it = elm_naviframe_item_push(nf, "Container Client", btn, NULL, list, NULL);
     elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, ad->win);
 }
 
index b85eb44..6596a8e 100644 (file)
@@ -236,7 +236,7 @@ void containerCreateUI(void *data, Evas_Object *obj, void *event_info)
     evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
     elm_object_part_content_set(layout, "log", log_entry);
 
-    nf_it = elm_naviframe_item_push(nf, "Resource Container", NULL, NULL, scroller, NULL);
+    nf_it = elm_naviframe_item_push(nf, "Container Client", NULL, NULL, scroller, NULL);
     elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, NULL);
 
     // Show the UI list of group APIs
index 5639986..31eb0cb 100644 (file)
@@ -27,8 +27,6 @@ using namespace std;
 
 void *showContainerAPIs(void *data);
 
-void containerCreateUI(void *data);
-
 static void startContainer(void *data, Evas_Object *obj, void *event_info);
 
 static void stopContainer(void *data, Evas_Object *obj, void *event_info);
index 22d080f..ea7886f 100644 (file)
@@ -43,6 +43,6 @@ using namespace OC;
 
 #define ELM_DEMO_EDJ "opt/usr/apps/org.tizen.containerserver/res/ui_controls.edj"
 
-void containerCreateUI(void *data, Evas_Object *obj, void *event_info);
+void containerCreateUI(void *data);
 
 #endif // RCMAIN_H__
index a6f06a0..eb5572b 100644 (file)
@@ -563,7 +563,7 @@ static void startContainer(void *data, Evas_Object *obj, void *event_info)
             s_containerFlag = true;
             s_hueBundleFlag = true;
             logMessage += "CONTAINER STARTED<br>";
-            logMessage += "ADD AND START BUNDLES<br>";
+            logMessage += "HUE BUNDLE STARTED<br>";
         }
         else
         {
@@ -625,11 +625,13 @@ naviframe_pop_cb(void *data, Elm_Object_Item *it)
         evas_object_del(listnew);
         listnew = NULL;
     }
+
+    ui_app_exit();
     return EINA_TRUE;
 }
 
 // Method to set up server screens
-void containerCreateUI(void *data, Evas_Object *obj, void *event_info)
+void containerCreateUI(void *data)
 {
     s_containerFlag = false;
     s_hueBundleFlag = false;
@@ -681,6 +683,6 @@ void containerCreateUI(void *data, Evas_Object *obj, void *event_info)
     evas_object_size_hint_align_set(log_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
     elm_object_part_content_set(layout, "log", log_entry);
 
-    nf_it = elm_naviframe_item_push(nf, "Resource Container", NULL, NULL, scroller, NULL);
+    nf_it = elm_naviframe_item_push(nf, "Container Server", NULL, NULL, scroller, NULL);
     elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, NULL);
 }
index c845270..330a42f 100644 (file)
@@ -65,16 +65,15 @@ create_list_view(appdata_s *ad)
     elm_list_mode_set(list, ELM_LIST_COMPRESS);
     evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL);
 
-    // Main Menu Items Here
-    elm_list_item_append(list, "Resource Container", NULL, NULL, containerCreateUI, nf);
-
     elm_list_go(list);
 
     // This button is set for devices which doesn't have H/W back key.
     btn = elm_button_add(nf);
     elm_object_style_set(btn, "naviframe/end_btn/default");
-    nf_it = elm_naviframe_item_push(nf, "Resource Encapsulation", btn, NULL, list, NULL);
+    nf_it = elm_naviframe_item_push(nf, "Container Server", btn, NULL, list, NULL);
     elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, ad->win);
+
+    containerCreateUI(nf);
 }
 
 
index f890404..915004e 100644 (file)
@@ -224,6 +224,8 @@ public final class RcsResourceObject extends RcsObject {
          *
          * @throws RcsIllegalStateException
          *             if not in locked state
+         * @throws RcsPlatformException
+         *             if auto notify failed
          */
         public void apply() throws RcsIllegalStateException {
             if (mCurrentAttributes == null) {
index 98273c9..ad05590 100644 (file)
@@ -25,6 +25,7 @@
 #include "JniRcsValue.h"
 #include "Log.h"
 #include "Verify.h"
+#include "JavaExceptions.h"
 
 #include "RCSResourceObject.h"
 
@@ -153,7 +154,15 @@ Java_org_iotivity_service_server_RcsLockedAttributes_nativeApply
     auto res = getResource(env, resourceObject);
     VERIFY_NO_EXC(env);
 
-    writeNativeAttributesFromMap(env, cacheObj, res->getAttributes());
+    try
+    {
+        RCSResourceObject::LockGuard lock(res);
+        writeNativeAttributesFromMap(env, cacheObj, res->getAttributes());
+    }
+    catch (const RCSPlatformException& e)
+    {
+        throwPlatformException(env, e);
+    }
 }
 
 JNIEXPORT void JNICALL
@@ -163,7 +172,8 @@ Java_org_iotivity_service_server_RcsLockedAttributes_nativeLock
     auto res = getResource(env, resourceObject);
     VERIFY_NO_EXC(env);
 
-    setSafeNativeHandle< RCSResourceObject::LockGuard >(env, obj, res);
+    setSafeNativeHandle< RCSResourceObject::LockGuard >(env, obj,
+            res, RCSResourceObject::AutoNotifyPolicy::NEVER);
 }
 
 JNIEXPORT void JNICALL
index 4354032..fe47ef8 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "RCSResourceObject.h"
 #include "RCSResponse.h"
+#include "RCSRequest.h"
 #include "RequestHandler.h"
 
 #define LOG_TAG "JNI-RCSResourceObject"
@@ -503,7 +504,7 @@ Java_org_iotivity_service_server_RcsResourceObject_nativeGetAttributes
     auto res = getResource(env, obj);
     VERIFY_NO_EXC_RET_DEF(env);
 
-    RCSResourceObject::LockGuard lock{ res };
+    RCSResourceObject::LockGuard lock{ res, RCSResourceObject::AutoNotifyPolicy::NEVER };
     return newAttributesObject(env, res->getAttributes());
 }
 
index f25cfb2..54a7d46 100644 (file)
@@ -128,6 +128,10 @@ public class ResourceClientActivity extends Activity
             }
 
             mResourceObj.startMonitoring(mOnStateChangedListener);
+
+            if (mResourceObj.isMonitoring()) {
+                printLog("Monitoring started successfully");
+            }
         }
     };
 
@@ -135,8 +139,13 @@ public class ResourceClientActivity extends Activity
         @Override
         public void execute() throws RcsException {
             if (mResourceObj.isMonitoring()) {
+
                 mResourceObj.stopMonitoring();
-                printLog("Stopped Resource Monitoring");
+
+                if (!mResourceObj.isMonitoring()) {
+                    printLog("Monitoring stopped successfully");
+                }
+
             } else {
                 printLog("Monitoring not started");
             }
@@ -168,6 +177,11 @@ public class ResourceClientActivity extends Activity
             }
 
             mResourceObj.startCaching(mOnCacheUpdatedListener);
+
+            if (mResourceObj.isCaching()) {
+                printLog("Caching started successfully");
+            }
+
         }
     };
 
@@ -197,8 +211,21 @@ public class ResourceClientActivity extends Activity
     private Item mStopCaching = new Item("9. Stop Caching") {
         @Override
         public void execute() throws RcsException {
-            mResourceObj.stopCaching();
+            if (mResourceObj.isCaching()) {
+
+                mResourceObj.stopCaching();
+
+                if (!mResourceObj.isCaching()) {
+                    printLog("Caching stopped successfully");
+                } else {
+                    printLog("Stopping caching unsuccessful");
+                }
+
+            } else {
+                printLog("Caching not started");
+            }
         }
+
     };
 
     @Override
@@ -219,10 +246,8 @@ public class ResourceClientActivity extends Activity
     protected void onDestroy() {
         super.onDestroy();
 
-        if (mDiscoveryTask != null)
-            mDiscoveryTask.cancel();
-        if (mResourceObj != null)
-            mResourceObj.destroy();
+        if (mDiscoveryTask != null) mDiscoveryTask.cancel();
+        if (mResourceObj != null) mResourceObj.destroy();
     }
 
     private void initMenuList() {
@@ -414,8 +439,7 @@ public class ResourceClientActivity extends Activity
             super.handleMessage(msg);
 
             ResourceClientActivity activity = mActivityRef.get();
-            if (activity == null)
-                return;
+            if (activity == null) return;
 
             switch (msg.what) {
                 case MSG_ID_RESOURCE_DISCOVERED:
@@ -18,7 +18,6 @@
  *
  ******************************************************************/
 
-#include "PrimitiveResource.h"
 #include "RCSResourceObject.h"
 #include "OCPlatform.h"
 #include "OCApi.h"
@@ -210,8 +209,8 @@ void changeSpeedAttribute(int state)
 }
 
 //hander for get request (if developer choose second option for resource Creation)
-RCSGetResponse requestHandlerForGet(const RCSRequest &request,
-                                    RCSResourceAttributes &attrs)
+RCSGetResponse requestHandlerForGet(const RCSRequest& /*request*/,
+                                    RCSResourceAttributes& /*attrs*/)
 {
     std::cout << "Recieved a Get request from Client" << std::endl;
 
@@ -225,7 +224,7 @@ RCSGetResponse requestHandlerForGet(const RCSRequest &request,
 }
 
 //hander for set request (if developer choose second option for resource Creation)
-RCSSetResponse requestHandlerForSet(const RCSRequest &request,
+RCSSetResponse requestHandlerForSet(const RCSRequest& /*request*/,
                                     RCSResourceAttributes &attrs)
 {
     std::cout << "Recieved a Set request from Client" << std::endl;
index e80012d..12fa444 100644 (file)
@@ -27,77 +27,46 @@ Import('env')
 lib_env = env.Clone()
 SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
 
-ResourceClient_env = lib_env.Clone()
-ResourceServer_env = lib_env.Clone()
-NestedAttributeServer_env = lib_env.Clone()
-NestedAttributeClient_env = lib_env.Clone()
+sample_env = lib_env.Clone()
 
-######################################################################
-# ##### Resource Client #####
-######################################################################
-
-ResourceClient_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
-ResourceClient_env.AppendUnique(LIBS = ['rcs_client', 'rcs_common','oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread'])
-ResourceClient_env.AppendUnique(CPPPATH = ['../../include'])
-ResourceClient_env.AppendUnique(CPPPATH = ['../../src/resourceBroker/include'])
-ResourceClient_env.AppendUnique(CPPPATH = ['../../src/resourceCache/include'])
-ResourceClient_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include'])
+sample_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x'])
+sample_env.AppendUnique(LIBS = [
+    'rcs_common',
+    'oc', 
+    'octbstack', 
+    'oc_logger', 
+    'connectivity_abstraction', 
+    'coap', 
+    'pthread'
+    ])
+sample_env.AppendUnique(CPPPATH = ['../../include'])
 
-######################################################################
-# ##### Nested Attribute Client #####
-######################################################################
+if env.get('SECURED') == '1':
+    sample_env.AppendUnique(LIBS = ['tinydtls'])
 
-NestedAttributeClient_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
-NestedAttributeClient_env.AppendUnique(LIBS = ['rcs_client', 'rcs_common','oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread'])
-NestedAttributeClient_env.AppendUnique(CPPPATH = ['../../include'])
-NestedAttributeClient_env.AppendUnique(CPPPATH = ['../../src/resourceBroker/include'])
-NestedAttributeClient_env.AppendUnique(CPPPATH = ['../../src/resourceCache/include'])
-NestedAttributeClient_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include'])
+if 'rt' in sample_env.get('LIBS'):
+    sample_env.Append(LIBS = ['rt'])
 
 ######################################################################
-# ##### Resource Server #####
+# ##### Client #####
 ######################################################################
+client_env = sample_env.Clone()
+client_env.AppendUnique(LIBS = 'rcs_client')
 
-ResourceServer_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
-ResourceServer_env.AppendUnique(LIBS = ['rcs_server', 'rcs_common','oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread'])
-ResourceServer_env.AppendUnique(CPPPATH = ['../../include'])
-ResourceServer_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include'])
-ResourceServer_env.AppendUnique(CPPPATH = ['../../src/serverBuilder/include'])
+sampleResourceClient = client_env.Program('sampleResourceClient', 'SampleResourceClient.cpp')
+nestedAttributesClient = client_env.Program('nestedAttributesClient', 'NestedAttributesClient.cpp')
+
+client_env.InstallTarget(sampleResourceClient, 'sampleResourceClient')
+client_env.InstallTarget(nestedAttributesClient, 'nestedAttributesClient')
 
 ######################################################################
-# ##### Nested Attribute Server #####
+# ##### Server #####
 ######################################################################
+server_env = sample_env.Clone()
+server_env.AppendUnique(LIBS = 'rcs_server')
 
-NestedAttributeServer_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
-NestedAttributeServer_env.AppendUnique(LIBS = ['rcs_server', 'rcs_common','oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread'])
-NestedAttributeServer_env.AppendUnique(CPPPATH = ['../../include'])
-NestedAttributeServer_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include'])
-NestedAttributeServer_env.AppendUnique(CPPPATH = ['../../src/serverBuilder/include'])
-
-if env.get('SECURED') == '1':
-    ResourceClient_env.AppendUnique(LIBS = ['tinydtls'])
-    NestedAttributeClient_env.AppendUnique(LIBS = ['tinydtls'])
-    ResourceServer_env.AppendUnique(LIBS = ['tinydtls'])
-    NestedAttributeServer_env.AppendUnique(LIBS = ['tinydtls'])
-
-if 'rt' in ResourceClient_env.get('LIBS'):
-    ResourceClient_env.Append(LIBS = ['rt'])
-if 'rt' in NestedAttributeClient_env.get('LIBS'):
-    NestedAttributeClient_env.Append(LIBS = ['rt'])
-if 'rt' in ResourceServer_env.get('LIBS'):
-    ResourceServer_env.Append(LIBS = ['rt'])
-if 'rt' in NestedAttributeServer_env.get('LIBS'):
-    NestedAttributeServer_env.Append(LIBS = ['rt'])
-
-####################################################################
-# Source files and Targets
-####################################################################
-sampleResourceClient = ResourceClient_env.Program('sampleResourceClient', 'SampleResourceClient.cpp')
-nestedAttributeClient = NestedAttributeClient_env.Program('nestedAttributeClient', 'NestedAttributeClient.cpp')
-sampleResourceServer = ResourceServer_env.Program('sampleResourceServer', 'SampleResourceServer.cpp')
-nestedAttributeServer = NestedAttributeServer_env.Program('nestedAttributeServer', 'NestedAttributeServer.cpp')
+sampleResourceServer = server_env.Program('sampleResourceServer', 'SampleResourceServer.cpp')
+nestedAttributesServer = server_env.Program('nestedAttributesServer', 'NestedAttributesServer.cpp')
 
-ResourceClient_env.InstallTarget(sampleResourceClient, 'sampleResourceClient')
-NestedAttributeClient_env.InstallTarget(nestedAttributeClient, 'nestedAttributeClient')
-ResourceServer_env.InstallTarget(sampleResourceServer, 'sampleResourceServer')
-NestedAttributeServer_env.InstallTarget(nestedAttributeServer, 'nestedAttributeServer')
+server_env.InstallTarget(sampleResourceServer, 'sampleResourceServer')
+server_env.InstallTarget(nestedAttributesServer, 'nestedAttributesServer')
index 98d7076..61287a0 100755 (executable)
 
 #include "OCPlatform.h"
 
+#define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
+
 using namespace OC;
 using namespace OIC::Service;
 
-#define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC, __VA_ARGS__ }
-
-void startMonitoring();
-void startMonitoring();
-void stopMonitoring();
-void getAttributeFromRemoteServer();
-void setAttributeToRemoteServer();
-void startCachingWithoutCallback();
-void startCachingWithCallback();
-void getResourceCacheState();
-void getCachedAttributes();
-void getCachedAttribute();
-void stopCaching();
-void discoverResource();
-void cancelDiscovery();
-int processUserInput();
-void selectResource();
-void printAttributes(const RCSResourceAttributes& attributes);
-
-class MenuList;
-
-class MenuItem
+struct CloseApp {};
+
+struct MenuItem
 {
 private:
-    typedef void(*MenuHandler)();
+    typedef void(*Handler)();
 
 public:
-    MenuItem(const char* funcName, MenuHandler handler = nullptr,
-            MenuHandler optionHandler = nullptr, MenuList* state = nullptr)
-        : m_name(funcName), m_handler(handler), m_optionHandler(optionHandler),
-          m_nextState(state)
-    {
-    }
+    const std::string title;
+    const Handler handler;
+};
 
-    MenuList* command() const
-    {
-        std::cout << m_name << " start.." << std::endl;
-        if(m_handler) m_handler();
+typedef void(*Runner)();
 
-        if(m_optionHandler != nullptr) m_optionHandler();
+constexpr int RESOURCE_TEMP = 1;
+constexpr int RESOURCE_LIGHT = 2;
 
-        return m_nextState;
-    }
+const std::string RESOURCE_TYPE_TEMP = "oic.r.temperaturesensor";
+const std::string RESOURCE_TYPE_LIGHT = "oic.r.light";
 
-    const char* getTitle() const
-    {
-        return m_name.c_str();
-    }
+RCSRemoteResourceObject::Ptr g_selectedResource;
+std::vector<RCSRemoteResourceObject::Ptr> g_discoveredResources;
 
-private:
-    const std::string m_name;
-    const MenuHandler m_handler;
-    const MenuHandler m_optionHandler;
-    MenuList* const m_nextState ;
-};
+std::string g_attrKey;
 
-class MenuList
+Runner g_currentRun;
+
+std::ostream& operator<<(std::ostream& os, const RCSRemoteResourceObject::Ptr& object)
 {
-public:
-    MenuList(std::initializer_list<MenuItem> il)
-        :m_menuItemList(std::move(il))
-    {
-    }
+    return os << "\turi : " << object->getUri() << std::endl <<
+            "\thost address : " << object->getAddress();
+}
 
-    void display() const
-    {
-        std::cout << std::endl;
-        int menuNum = 1;
+std::ostream& operator<<(std::ostream& os, const MenuItem& item)
+{
+    return os << item.title;
+}
 
-        for(const auto& menuItem : m_menuItemList)
-        {
-            std::cout.width(2);
-            std::cout << std::right << menuNum++ <<  ". ";
-            std::cout << menuItem.getTitle() << std::endl;
-        }
-    }
+void onSelected(const RCSRemoteResourceObject::Ptr& object)
+{
+    g_selectedResource = object;
+}
 
-    MenuList* select()
-    {
-        int input = processUserInput();
+void onSelected(const MenuItem& item)
+{
+    std::cout << item.title << " start.." << std::endl;
+    item.handler();
+}
 
-        if(input == static_cast<int>(m_menuItemList.size())) return nullptr;
+int processUserInput(int min = std::numeric_limits<int>::min(),
+        int max = std::numeric_limits<int>::max())
+{
+    assert(min <= max);
 
-        if(input > static_cast<int>(m_menuItemList.size()) || input <= 0)
-        {
-            std::cout << "Invalid input, please try again" << std::endl;
-            return this;
-        }
-        auto nextMenuList = m_menuItemList[input-1].command();
+    int input;
 
-        return nextMenuList == nullptr ? this : nextMenuList;
-    }
+    std::cin >> input;
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
 
-private:
-    const std::vector<MenuItem> m_menuItemList;
-};
+    if (!std::cin.fail() && min <= input && input <= max) return input;
 
-constexpr int REQUEST_TEMP = 1;
-constexpr int REQUEST_LIGHT = 2;
+    std::cin.clear();
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
 
-const std::string TEMP = "oic.r.temperaturesensor";
-const std::string LIGHT = "oic.r.light";
+    throw std::runtime_error("Invalid Input, please try again");
+}
 
-std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> discoveryTask;
+template<typename D>
+void displayItem(int width, int index, const D& data)
+{
+    std::cout.width(width);
+    std::cout << std::right << index << ". ";
+    std::cout << data << std::endl;
+}
 
-std::vector<RCSRemoteResourceObject::Ptr> resourceList;
-RCSRemoteResourceObject::Ptr selectedResource;
+template<typename T>
+void displayItems(const std::vector<T>& items)
+{
+    std::cout << std::endl;
 
-std::string defaultKey;
+    const auto width = (items.size() + 1) / 10 + 1;
 
-MenuList* currentMenuList;
+    for(size_t i = 0; i < items.size(); ++i)
+    {
+        displayItem(width, i + 1, items[i]);
+    }
+    displayItem(width, items.size() + 1, "quit");
+}
 
-MenuList resourceMenu = {
-    DECLARE_MENU(startMonitoring),
-    DECLARE_MENU(stopMonitoring),
-    DECLARE_MENU(getAttributeFromRemoteServer),
-    DECLARE_MENU(setAttributeToRemoteServer),
-    DECLARE_MENU(startCachingWithoutCallback),
-    DECLARE_MENU(startCachingWithCallback),
-    DECLARE_MENU(getResourceCacheState),
-    DECLARE_MENU(getCachedAttributes),
-    DECLARE_MENU(getCachedAttribute),
-    DECLARE_MENU(stopCaching),
-    { "quit" }
-};
+template<typename T>
+void selectItem(const std::vector<T>& items)
+{
+    int selected = processUserInput(1, items.size() + 1) - 1;
 
-MenuList cancelDiscoveryMenu = {
-    DECLARE_MENU(cancelDiscovery, selectResource, &resourceMenu),
-    { "quit" }
-};
+    if(selected == static_cast<int>(items.size())) throw CloseApp();
 
-MenuList discoveryMenu = {
-    DECLARE_MENU(discoverResource, nullptr, &cancelDiscoveryMenu),
-    { "quit" }
-};
+    onSelected(items[selected]);
+}
+
+template<typename T>
+void handleItems(const std::vector<T>& items)
+{
+    displayItems(items);
+    selectItem(items);
+}
 
-void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> discoveredResource)
+void printAttribute(const std::string& key, const RCSResourceAttributes::Value& value)
 {
-    std::cout << "onResourceDiscovered callback :: " << std::endl;
+    std::cout << "\tkey : " << key << std::endl
+              << "\tvalue : " << value.toString() << std::endl;
+}
 
-    std::cout << "resourceURI : " << discoveredResource->getUri() << std::endl;
-    std::cout << "hostAddress : " << discoveredResource->getAddress() << std::endl;
+void printAttributes(const RCSResourceAttributes& attributes)
+{
+    if (attributes.empty())
+    {
+       std::cout << "\tattributes is empty" << std::endl;
+    }
 
-    resourceList.push_back(discoveredResource);
+    for(const auto& attr : attributes)
+    {
+        printAttribute(attr.key(), attr.value());
+    }
 }
 
-void onResourceStateChanged(const ResourceState& resourceState)
+void onResourceStateChanged(ResourceState resourceState)
 {
     std::cout << "onResourceStateChanged callback" << std::endl;
 
@@ -220,60 +201,57 @@ void onRemoteAttributesReceived(const RCSResourceAttributes& attributes, int)
 
 void startMonitoring()
 {
-    if (!selectedResource->isMonitoring())
-    {
-        selectedResource->startMonitoring(&onResourceStateChanged);
-        std::cout << "\tHosting Started..." << std::endl;
-    }
-    else
+    if (g_selectedResource->isMonitoring())
     {
         std::cout << "\tAlready Started..." << std::endl;
+        return;
     }
+
+    g_selectedResource->startMonitoring(&onResourceStateChanged);
+    std::cout << "\tMonitoring Started..." << std::endl;
 }
 
 void stopMonitoring()
 {
-    if (selectedResource->isMonitoring())
-    {
-        selectedResource->stopMonitoring();
-        std::cout << "\tHosting stopped..." << std::endl;
-    }
-    else
+    if (!g_selectedResource->isMonitoring())
     {
-       std::cout << "\tHosting not started..." << std::endl;
+        std::cout << "\tMonitoring not started..." << std::endl;
+        return;
     }
+
+    g_selectedResource->stopMonitoring();
+    std::cout << "\tMonitoring stopped..." << std::endl;
 }
 
-void getAttributeFromRemoteServer()
+void getRemoteAttributes()
 {
-    selectedResource->getRemoteAttributes(&onRemoteAttributesReceived);
+    g_selectedResource->getRemoteAttributes(onRemoteAttributesReceived);
 }
 
-void setAttributeToRemoteServer()
+void setRemoteAttributes()
 {
     std::string key;
-    RCSResourceAttributes setAttribute;
 
     std::cout << "\tEnter the Key you want to set : ";
     std::cin >> key;
+
     std::cout << "\tEnter the value(INT) you want to set :";
+    RCSResourceAttributes attrs;
+    attrs[key] = processUserInput();
 
-    setAttribute[key] = processUserInput();
-    selectedResource->setRemoteAttributes(setAttribute,
-                                  &onRemoteAttributesReceived);
+    g_selectedResource->setRemoteAttributes(attrs, onRemoteAttributesReceived);
 }
 
 void startCaching(RCSRemoteResourceObject::CacheUpdatedCallback cb)
 {
-    if (!selectedResource->isCaching())
-    {
-        selectedResource->startCaching(std::move(cb));
-        std::cout << "\tCaching Started..." << std::endl;
-    }
-    else
+    if (g_selectedResource->isCaching())
     {
         std::cout << "\tAlready Started Caching..." << std::endl;
+        return;
     }
+
+    g_selectedResource->startCaching(std::move(cb));
+    std::cout << "\tCaching Started..." << std::endl;
 }
 
 void startCachingWithoutCallback()
@@ -288,7 +266,7 @@ void startCachingWithCallback()
 
 void getResourceCacheState()
 {
-    switch(selectedResource->getCacheState())
+    switch(g_selectedResource->getCacheState())
     {
         case CacheState::READY:
             std::cout << "\tCurrent Cache State : CACHE_STATE::READY" << std::endl;
@@ -310,102 +288,50 @@ void getResourceCacheState()
 
 void getCachedAttributes()
 {
-    try
-    {
-        printAttributes(selectedResource->getCachedAttributes());
-    }
-    catch (const RCSBadRequestException& e)
-    {
-        std::cout << "Exception in getCachedAttributes : " << e.what() << std::endl;
-    }
+    printAttributes(g_selectedResource->getCachedAttributes());
 }
 
 void getCachedAttribute()
 {
-    try
-    {
-        std::cout << "\tkey : " << defaultKey << std::endl
-                  << "\tvalue : " << selectedResource->getCachedAttribute(defaultKey).get< int >()
-                  << std::endl;
-    }
-    catch (const RCSBadRequestException& e)
-    {
-        std::cout << "Exception in getCachedAttribute : " << e.what() << std::endl;
-    }
-    catch (const RCSBadGetException& e)
-    {
-        std::cout << "Exception in getCachedAttribute : " << e.what() << std::endl;
-    }
+    printAttribute(g_attrKey, g_selectedResource->getCachedAttribute(g_attrKey));
 }
 
 void stopCaching()
 {
-    if(selectedResource->isCaching())
-    {
-        selectedResource->stopCaching();
-        std::cout << "\tCaching stopped..." << std::endl;
-    }
-    else
+    if(!g_selectedResource->isCaching())
     {
         std::cout << "\tCaching not started..." << std::endl;
+        return;
     }
-}
 
-void platFormConfigure()
-{
-    PlatformConfig config
-    {
-        OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
-    };
-    OCPlatform::Configure(config);
-}
-
-int processUserInput()
-{
-    int userInput;
-
-    while(true)
-    {
-        std::cin >> userInput;
-        if (std::cin.fail())
-        {
-            std::cin.clear();
-            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
-            std::cout << "Invalid Input, please try again" << std::endl;
-        }
-        else break;
-    }
-    return userInput;
+    g_selectedResource->stopCaching();
+    std::cout << "\tCaching stopped..." << std::endl;
 }
 
-bool selectResourceType(std::string& resourceType)
+std::string selectResourceType()
 {
     std::cout << "========================================================" << std::endl;
     std::cout << "1. Temperature Resource Discovery" << std::endl;
     std::cout << "2. Light Resource Discovery" << std::endl;
     std::cout << "========================================================" << std::endl;
 
-    switch (processUserInput())
+    switch (processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT))
     {
-    case REQUEST_TEMP:
-        resourceType = TEMP;
-        defaultKey = "Temperature";
-        return true;
-    case REQUEST_LIGHT:
-        resourceType = LIGHT;
-        defaultKey = "Brightness";
-        return true;
-    default :
-        std::cout << "Invalid input, please try again" << std::endl;
-        return false;
+    case RESOURCE_TEMP:
+        g_attrKey = "Temperature";
+        return RESOURCE_TYPE_TEMP;
+    case RESOURCE_LIGHT:
+        g_attrKey = "Brightness";
+        return RESOURCE_TYPE_LIGHT;
     }
+
+    throw std::logic_error("unreachable");
 }
 
 RCSAddress inputAddress()
 {
     std::cout << "========================================================" << std::endl;
-    std::cout << "Please input address" << std::endl;
-    std::cout << "(default is multicast. when you want to use unicast, input address" << std::endl;
+    std::cout << "Please input address (empty for multicast)" << std::endl;
     std::cout << "========================================================" << std::endl;
 
     std::string address;
@@ -415,96 +341,109 @@ RCSAddress inputAddress()
     return address.empty() ? RCSAddress::multicast() : RCSAddress::unicast(address);
 }
 
-void discoverResource()
+void printDiscoveryInProgress()
 {
-    std::string resourceType = "";
-
-    while(!selectResourceType(resourceType)) {}
-
-    while(!discoveryTask)
-    {
-        try
-        {
-            discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
-                    inputAddress(), resourceType, &onResourceDiscovered);
-        }
-        catch (const RCSPlatformException& e)
-        {
-            std::cout << e.what() << std::endl;
-        }
-    }
+    std::cout << "Discovery in progress, press '1' to stop." << std::endl;
 }
 
-void displayResourceList()
+void discoverResource()
 {
-    int cnt = 1;
-    for(const auto& resource : resourceList)
+    auto onResourceDiscovered = [](
+            const RCSRemoteResourceObject::Ptr& discoveredResource)
     {
-        std::cout << cnt++ << ".\tresourceURI : " << resource->getUri() << std::endl <<
-                              "\thostAddress : " << resource->getAddress() << std::endl;
-    }
-}
+        std::cout << "onResourceDiscovered callback :: " << std::endl;
 
-void selectResource()
-{
-    displayResourceList();
+        std::cout << "luri : " << discoveredResource->getUri() << std::endl;
+        std::cout << "host address : " << discoveredResource->getAddress() << std::endl;
+
+        g_discoveredResources.push_back(discoveredResource);
+
+        printDiscoveryInProgress();
+    };
+
+    auto resourceType = selectResourceType();
+    auto address = inputAddress();
 
-    std::cout << "select Resource..." << std::endl;
+    printDiscoveryInProgress();
 
-    selectedResource = resourceList[processUserInput()-1];
+    auto discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(address,
+            resourceType, onResourceDiscovered);
 
-    resourceList.clear();
+    while(processUserInput() != 1);
+
+    discoveryTask->cancel();
 }
 
-void cancelDiscovery()
+void runResourceControl()
 {
-    if(!discoveryTask)
-    {
-        std::cout << "There is no discovery request..." << std::endl;
-        return;
-    }
-    discoveryTask->cancel();
+    static std::vector<MenuItem> resourceMenuItems {
+        DECLARE_MENU(startMonitoring),
+        DECLARE_MENU(stopMonitoring),
+        DECLARE_MENU(getRemoteAttributes),
+        DECLARE_MENU(setRemoteAttributes),
+        DECLARE_MENU(startCachingWithoutCallback),
+        DECLARE_MENU(startCachingWithCallback),
+        DECLARE_MENU(getResourceCacheState),
+        DECLARE_MENU(getCachedAttributes),
+        DECLARE_MENU(getCachedAttribute),
+        DECLARE_MENU(stopCaching),
+    };
+
+    handleItems(resourceMenuItems);
 }
 
-void printAttribute(const std::string key, const RCSResourceAttributes::Value& value)
+void runResourceSelection()
 {
-    std::cout << "\tkey : " << key << std::endl
-              << "\tvalue : " << value.toString() << std::endl;
+    handleItems(g_discoveredResources);
+
+    g_currentRun = runResourceControl;
 }
 
-void printAttributes(const RCSResourceAttributes& attributes)
+void runDiscovery()
 {
-    if (attributes.empty())
-    {
-       std::cout << "\tattributes is empty" << std::endl;
-    }
-    for(const auto& attr : attributes)
+    static std::vector<MenuItem> discoveryMenuItems {
+        DECLARE_MENU(discoverResource),
+    };
+
+    handleItems(discoveryMenuItems);
+
+    if (g_discoveredResources.empty()) throw std::runtime_error("No resource found!");
+
+    g_currentRun = runResourceSelection;
+}
+
+void configurePlatform()
+{
+    PlatformConfig config
     {
-        printAttribute(attr.key(), attr.value());
-    }
+        OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
+    };
+    OCPlatform::Configure(config);
 }
 
 int main()
 {
-    platFormConfigure();
+    configurePlatform();
 
-    currentMenuList = &discoveryMenu;
+    g_currentRun = runDiscovery;
 
-    try
+    while (true)
     {
-        while(currentMenuList)
+        try
         {
-            currentMenuList->display();
-
-            currentMenuList = currentMenuList->select();
+            g_currentRun();
+        }
+        catch (const std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+        catch (const CloseApp&)
+        {
+            break;
         }
-    }
-    catch (const std::exception& e)
-    {
-        std::cout << "main exception : " << e.what() << std::endl;
     }
 
-    std::cout << "Stopping the Client" << std::endl;
+    std::cout << "Stopping the client" << std::endl;
 
     return 0;
 }
index e118781..7c4532a 100755 (executable)
  *
  ******************************************************************/
 
-#include "PrimitiveResource.h"
 #include "RCSResourceObject.h"
 #include "OCPlatform.h"
-#include "OCApi.h"
 
-using namespace OC;
 using namespace OC::OCPlatform;
 using namespace OIC::Service;
 
-constexpr int DEFALUT_VALUE = 0;
+struct CloseApp{};
 
-constexpr int REQUEST_TEMP = 1;
-constexpr int REQUEST_LIGHT = 2;
-
-constexpr int PRESENCE_ON = 1;
-constexpr int PRESENCE_OFF = 2;
+constexpr int RESOURCE_TEMP = 1;
+constexpr int RESOURCE_LIGHT = 2;
 
 constexpr int DEFALUT_SERVER = 1;
 constexpr int CUSTOM_SERVER = 2;
-constexpr int STOP = 3;
 
-constexpr int INCREASE_TEMPERATURE = 1;
-constexpr int DECREASE_TEMPERATURE = 2;
-constexpr int STOP_TEMPERATURE_SENSOR = 3;
+constexpr int INCREASE = 1;
+constexpr int DECREASE = 2;
 
-constexpr int INCREASE_BRIGHTNESS = 1;
-constexpr int DECREASE_BRIGHTNESS = 2;
-constexpr int STOP_LIGHT_SENSOR = 3;
+typedef void (*DisplayControlMenuFunc)();
+typedef std::function<void()> Run;
 
-constexpr int CORRECT_INPUT = 1;
-constexpr int INCORRECT_INPUT = 2;
-constexpr int QUIT = 3;
+Run g_currentRun;
 
+bool g_isPresenceStarted = false;
 
-std::string resourceType = "oic.r.temperaturesensor";
-std::string resourceInterface = "oic.if.";
-std::string resourceUri;
-std::string attributeKey;
-int isPresenceOn = PRESENCE_ON;
+RCSResourceObject::Ptr g_resource;
 
-RCSResourceObject::Ptr server;
+int processUserInput(int min, int max)
+{
+    assert(min <= max);
 
-int processUserInput();
+    int input;
 
-enum class Control{
-    INCREASE,
-    DECREASE
-};
+    std::cin >> input;
 
-void displayMenu()
-{
-    std::cout << "====================================================================="
-              << std::endl;
-    std::cout << "   1 - Creation of Resource [Auto control for requests]" << std::endl;
-    std::cout << "   2 - Creation of Resource [Developer control for Get and Set requests]"
-              << std::endl;
-    std::cout << "   3 - Quit" << std::endl;
-    std::cout << "====================================================================="
-              << std::endl;
-}
+    if (!std::cin.fail())
+    {
+        if(input == max + 1) throw CloseApp();
+        if(min <= input && input <= max) return input;
+    }
 
-void displayResourceTypeMenu()
-{
-    std::cout << "========================================================" << std::endl;
-    std::cout << "Select Resource Type" << std::endl;
-    std::cout << "1. Temperature" << std::endl;
-    std::cout << "2. Light" << std::endl;
-    std::cout << "========================================================" << std::endl;
+    std::cin.clear();
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    throw std::runtime_error("Invalid Input, please try again");
 }
 
 void displayControlTemperatureMenu()
 {
-    std::cout << "========================================================" << std::endl;
-    std::cout << "1. Increase Temperature by 1 degree" << std::endl;
-    std::cout << "2. Decrease Temperature by 1 degree" << std::endl;
-    std::cout << "3. Stop the Sensor" << std::endl;
-    std::cout << "========================================================" << std::endl;
+    std::cout << "========================================================\n";
+    std::cout << INCREASE << ". Increase Temperature by 1 degree          \n";
+    std::cout << DECREASE << ". Decrease Temperature by 1 degree          \n";
+    std::cout << DECREASE + 1 << ". Quit                                  \n";
+    std::cout << "========================================================\n";
 }
 
 void displayControlLightMenu()
 {
-    std::cout << "========================================================" << std::endl;
-    std::cout << "1. Increase Brightness by 1 stage" << std::endl;
-    std::cout << "2. Decrease Brightness by 1 stage" << std::endl;
-    std::cout << "3. Stop the Sensor" << std::endl;
-    std::cout << "========================================================" << std::endl;
+    std::cout << "========================================================\n";
+    std::cout << INCREASE << ". Increase Brightness by 1 stage            \n";
+    std::cout << DECREASE << ". Decrease Brightness by 1 stage            \n";
+    std::cout << DECREASE + 1 << ". Quit                                  \n";
+    std::cout << "========================================================\n";
 }
 
-void printAttribute(const RCSResourceAttributes& attrs)
+void printAttributes(const RCSResourceAttributes& attrs)
 {
     for(const auto& attr : attrs)
     {
@@ -115,261 +91,164 @@ void printAttribute(const RCSResourceAttributes& attrs)
     }
 }
 
-//hander for get request (if developer choose second option for resource Creation)
-RCSGetResponse requestHandlerForGet(const RCSRequest& request,
-        RCSResourceAttributes& attrs)
+RCSGetResponse requestHandlerForGet(const RCSRequest&, RCSResourceAttributes& attrs)
 {
     std::cout << "Received a Get request from Client" << std::endl;
-    RCSResourceObject::LockGuard lock(*server);
-    RCSResourceAttributes attributes = server->getAttributes();
+    printAttributes(attrs);
 
-    std::cout << "\nSending response to Client : " << std::endl;
-    printAttribute(attributes);
+    {
+        RCSResourceObject::LockGuard lock(g_resource);
+        std::cout << "\nSending response to Client : " << std::endl;
+        printAttributes(g_resource->getAttributes());
+    }
 
     return RCSGetResponse::defaultAction();
 }
 
-//hander for set request (if developer choose second option for resource Creation)
-RCSSetResponse requestHandlerForSet(const RCSRequest& request,
-        RCSResourceAttributes& attrs)
+RCSSetResponse requestHandlerForSet(const RCSRequest&, RCSResourceAttributes& attrs)
 {
     std::cout << "Received a Set request from Client" << std::endl;
+    printAttributes(attrs);
 
-    std::cout << "\n\nSending response to Client : " << std::endl;
-    RCSResourceObject::LockGuard lock(*server);
-    printAttribute(attrs);
     return RCSSetResponse::defaultAction();
 }
 
-void createResource()
+void initServer(const std::string& resourceUri, const std::string& resourceType,
+        const std::string& attrKey)
 {
-    server = RCSResourceObject::Builder(resourceUri, resourceType,resourceInterface).
+    g_resource = RCSResourceObject::Builder(resourceUri, resourceType, "oic.if.").
             setDiscoverable(true).setObservable(true).build();
+
+    g_resource->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+    g_resource->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
+    g_resource->setAttribute(attrKey, 0);
 }
 
-void initServer()
+void updateAttribute(const std::string& attrKey, int control)
 {
-    try
-    {
-        createResource();
-    }
-    catch (const RCSPlatformException& e)
+    const int diff = control == INCREASE ? 1 : - 1;
+
     {
-        std::cout << "Exception in initServer : " << e.what() << std::endl;
+        RCSResourceObject::LockGuard lock(g_resource);
+        auto& attrs = g_resource->getAttributes();
+        attrs[attrKey] = attrs[attrKey].get<int>() + diff;
     }
 
-    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
-    server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
-    server->setAttribute(attributeKey, DEFALUT_VALUE);
-}
-
-void changeAttribute(Control control)
-{
-    RCSResourceObject::LockGuard lock(server);
-    if(Control::INCREASE == control)
+    if(control == INCREASE)
     {
-        server->getAttributes()[attributeKey] =
-                server->getAttribute<int>(attributeKey) + 1;
-        std::cout << attributeKey << " increased." << std::endl;
+        std::cout << attrKey << " increased." << std::endl;
     }
-    else if(Control::DECREASE == control)
+    else
     {
-        server->getAttributes()[attributeKey] =
-                        server->getAttribute<int>(attributeKey) - 1;
-        std::cout << attributeKey << " Decreased." << std::endl;
+        std::cout << attrKey << " decreased." << std::endl;
     }
-    std::cout << "\nCurrent " << attributeKey << ": "
-            << server->getAttributeValue(attributeKey).get<int>() << std::endl;
+    std::cout << "\nCurrent " << attrKey << ": "
+            << g_resource->getAttributeValue(attrKey).get<int>() << std::endl;
 }
 
-int processUserInput()
+void runResourceControl(DisplayControlMenuFunc displayMenuFunc, const std::string& attrKey)
 {
-    int userInput;
-    std::cin >> userInput;
-    if (std::cin.fail())
-    {
-        std::cin.clear();
-        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
-        return -1;
-    }
-    return userInput;
+    displayMenuFunc();
+    updateAttribute(attrKey, processUserInput(INCREASE, DECREASE));
 }
 
-int selectPresenceMenu()
+void runResourceTypeSelection(int resourceMode)
 {
-    std::cout << "========================================================" << std::endl;
-    std::cout << "1. Presence On" << std::endl;
-    std::cout << "2. Presence Off" << std::endl;
-    std::cout << "========================================================" << std::endl;
-
-    switch(processUserInput())
-        {
-        case PRESENCE_ON:
-            isPresenceOn = PRESENCE_ON;
-            startPresence(3);
-            return CORRECT_INPUT;
-        case PRESENCE_OFF:
-            isPresenceOn = PRESENCE_OFF;
-            return CORRECT_INPUT;
-        default :
-            std::cout << "Invalid input, please try again" << std::endl;
-            return INCORRECT_INPUT;
-        }
-}
+    std::cout << "========================================================\n";
+    std::cout << "Select Resource Type                                    \n";
+    std::cout << RESOURCE_TEMP << ". Temperature                          \n";
+    std::cout << RESOURCE_LIGHT << ". Light                               \n";
+    std::cout << RESOURCE_LIGHT + 1 << ". Quit                            \n";
+    std::cout << "========================================================\n";
 
-int selectResourceTypeMenu()
-{
-    displayResourceTypeMenu();
+    int resourceType = processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT);
+    DisplayControlMenuFunc displayMenuFunc;
+    std::string attrKey;
 
-    switch(processUserInput())
+    switch (resourceType)
     {
-        case REQUEST_TEMP:
-            resourceUri = "/a/TempSensor";
-            resourceType = "oic.r.temperaturesensor";
-            attributeKey = "Temperature";
-            return CORRECT_INPUT;
-        case REQUEST_LIGHT:
-            resourceUri = "/a/light";
-            resourceType = "oic.r.light";
-            attributeKey = "Brightness";
-            return CORRECT_INPUT;
-        default :
-            std::cout << "Invalid input, please try again" << std::endl;
-            return INCORRECT_INPUT;
+        case RESOURCE_TEMP:
+            attrKey = "Temperature";
+            initServer("/a/TempSensor", "oic.r.temperaturesensor", attrKey);
+
+            displayMenuFunc = displayControlTemperatureMenu;
+            break;
+
+        case RESOURCE_LIGHT:
+            attrKey = "Brightness";
+            initServer("/a/light", "oic.r.light", attrKey);
+
+            displayMenuFunc = displayControlLightMenu;
+            break;
     }
-}
 
-int selectServerMenu()
-{
-    switch (processUserInput())
+    if (resourceMode == CUSTOM_SERVER)
     {
-        case DEFALUT_SERVER: // Creation of Resource & Auto control for all requests from Client.
-            while(true)
-            {
-                int ret = selectResourceTypeMenu();
-                if(ret == CORRECT_INPUT) break;
-            }
-            initServer();
-            return CORRECT_INPUT;
-
-        case CUSTOM_SERVER:
-            // Creation of Resource & setting get and set handler for handling get and
-            // set request from client in application.
-            while(true)
-            {
-                int ret = selectResourceTypeMenu();
-                if(ret == CORRECT_INPUT) break;
-            }
-            initServer();
-
-            server->setGetRequestHandler(requestHandlerForGet);
-            server->setSetRequestHandler(requestHandlerForSet);
-            return CORRECT_INPUT;
-        case STOP :
-            return QUIT;
-
-        default :
-            std::cout << "Invalid input, please try again" << std::endl;
-            return INCORRECT_INPUT;
+        g_resource->setGetRequestHandler(requestHandlerForGet);
+        g_resource->setSetRequestHandler(requestHandlerForSet);
     }
+
+    g_currentRun = std::bind(runResourceControl, displayMenuFunc, std::move(attrKey));
 }
 
-int selectControlTemperatureMenu()
+void runResourceModeSelection()
 {
-    displayControlTemperatureMenu();
-
-    switch (processUserInput())
-    {
-       case INCREASE_TEMPERATURE:
-           changeAttribute(Control::INCREASE);
-           return CORRECT_INPUT;
-
-       case DECREASE_TEMPERATURE:
-           changeAttribute(Control::DECREASE);
-           return CORRECT_INPUT;
+    std::cout << "========================================================          \n";
+    std::cout << DEFALUT_SERVER << ". Creation of Simple Resource Without Handlers  \n";
+    std::cout << CUSTOM_SERVER << ". Creation of Resource With Set and Get Handlers \n";
+    std::cout << CUSTOM_SERVER + 1 << ". Quit                                       \n";
+    std::cout << "========================================================          \n";
 
-       case STOP_TEMPERATURE_SENSOR:
-           return QUIT;
-
-       default:
-           std::cout << "Invalid input. Please try again." << std::endl;
-           return INCORRECT_INPUT;
-   }
+    g_currentRun = std::bind(runResourceTypeSelection,
+            processUserInput(DEFALUT_SERVER, CUSTOM_SERVER));
 }
 
-int selectControlLightMenu()
+void runPresenceSelection()
 {
-    displayControlLightMenu();
-
-    switch (processUserInput())
-    {
-        case INCREASE_BRIGHTNESS:
-            changeAttribute(Control::INCREASE);
-            return CORRECT_INPUT;
+    constexpr int PRESENCE_ON = 1;
+    constexpr int PRESENCE_OFF = 2;
 
-        case DECREASE_BRIGHTNESS:
-            changeAttribute(Control::DECREASE);
-            return CORRECT_INPUT;
+    std::cout << "========================================================\n";
+    std::cout << PRESENCE_ON << ". Presence On                            \n";
+    std::cout << PRESENCE_OFF << ". Presence Off                          \n";
+    std::cout << PRESENCE_OFF + 1 << ". Quit                              \n";
+    std::cout << "========================================================\n";
 
-        case STOP_LIGHT_SENSOR:
-            return QUIT;
-
-        default:
-            std::cout << "Invalid input. Please try again." << std::endl;
-            return INCORRECT_INPUT;
-    }
-}
-
-void process()
-{
-    while(true)
+    if (processUserInput(PRESENCE_ON, PRESENCE_OFF) == PRESENCE_ON)
     {
-        int ret = selectPresenceMenu();
-        if(ret == CORRECT_INPUT) break;
+        g_isPresenceStarted = true;
+        startPresence(3);
     }
 
-    while(true)
-    {
-        displayMenu();
-        int ret = selectServerMenu();
+    g_currentRun = runResourceModeSelection;
+}
 
-        if(ret == QUIT) return;
-        if(ret == CORRECT_INPUT) break;
-    }
+int main(void)
+{
+    g_currentRun = runPresenceSelection;
 
     while(true)
     {
-        if(resourceType == "oic.r.temperaturesensor")
+        try
         {
-            int ret = selectControlTemperatureMenu();
-            if (ret == QUIT) return;
-            if (ret == INCORRECT_INPUT) continue;
+            g_currentRun();
         }
-        else if(resourceType == "oic.r.light")
+        catch(const std::exception& e)
         {
-            int ret = selectControlLightMenu();
-            if (ret == QUIT) return;
-            if (ret == INCORRECT_INPUT) continue;
+            std::cout << e.what() << std::endl;
         }
-    }
-}
-
-int main(void)
-{
-    try
-    {
-        process();
-        server = NULL;
-
-        if(isPresenceOn == PRESENCE_ON)
+        catch(const CloseApp&)
         {
-            stopPresence();
+            break;
         }
     }
-    catch (const std::exception& e)
+    std::cout << "Stopping the server" << std::endl;
+
+    g_resource.reset();
+
+    if(g_isPresenceStarted)
     {
-        std::cout << "main exception  : " << e.what() << std::endl;
+        stopPresence();
     }
-    std::cout << "Stopping the Server" << std::endl;
 }
 
index 063a71f..645c228 100644 (file)
 #include <unordered_map>
 #include <vector>
 
-#include <boost/variant.hpp>
-#include <boost/mpl/contains.hpp>
-#include <boost/mpl/find.hpp>
-#include <boost/mpl/distance.hpp>
-#include <boost/mpl/begin_end.hpp>
-#include <boost/scoped_ptr.hpp>
+#include "boost/variant.hpp"
+#include "boost/mpl/contains.hpp"
+#include "boost/mpl/find.hpp"
+#include "boost/mpl/distance.hpp"
+#include "boost/mpl/begin_end.hpp"
+#include "boost/scoped_ptr.hpp"
 
-#include <RCSException.h>
+#include "RCSException.h"
 
 namespace OIC
 {
@@ -582,6 +582,9 @@ namespace OIC
         public:
             ComparisonHelper(const Value&);
 
+            ComparisonHelper(const ComparisonHelper&) = delete;
+            ComparisonHelper& operator=(const ComparisonHelper&) = delete;
+
             template< typename T >
             typename std::enable_if< is_supported_type< T >::value, bool >::type equals(
                     const T& v) const
index 40044c6..d062b3a 100644 (file)
@@ -30,9 +30,8 @@
 #include <mutex>
 #include <thread>
 
-#include <RCSResourceAttributes.h>
-#include <RCSResponse.h>
-#include <RCSRequest.h>
+#include "RCSResourceAttributes.h"
+#include "RCSResponse.h"
 
 namespace OC
 {
@@ -44,6 +43,8 @@ namespace OIC
     namespace Service
     {
 
+        class RCSRequest;
+
         /**
          * @brief Thrown when lock has not been acquired.
          *
@@ -443,12 +444,12 @@ namespace OIC
         private:
             RCSResourceObject(uint8_t, RCSResourceAttributes&&);
 
-            OCEntityHandlerResult entityHandler(std::shared_ptr< OC::OCResourceRequest >);
+            OCEntityHandlerResult entityHandler(const std::shared_ptr< OC::OCResourceRequest >&);
 
-            OCEntityHandlerResult handleRequest(std::shared_ptr< OC::OCResourceRequest >);
-            OCEntityHandlerResult handleRequestGet(std::shared_ptr< OC::OCResourceRequest >);
-            OCEntityHandlerResult handleRequestSet(std::shared_ptr< OC::OCResourceRequest >);
-            OCEntityHandlerResult handleObserve(std::shared_ptr< OC::OCResourceRequest >);
+            OCEntityHandlerResult handleRequest(const std::shared_ptr< OC::OCResourceRequest >&);
+            OCEntityHandlerResult handleRequestGet(const std::shared_ptr< OC::OCResourceRequest >&);
+            OCEntityHandlerResult handleRequestSet(const std::shared_ptr< OC::OCResourceRequest >&);
+            OCEntityHandlerResult handleObserve(const std::shared_ptr< OC::OCResourceRequest >&);
 
             void expectOwnLock() const;
 
@@ -473,8 +474,8 @@ namespace OIC
 
             RCSResourceAttributes m_resourceAttributes;
 
-            GetRequestHandler m_getRequestHandler;
-            SetRequestHandler m_setRequestHandler;
+            std::shared_ptr< GetRequestHandler > m_getRequestHandler;
+            std::shared_ptr< SetRequestHandler > m_setRequestHandler;
 
             AutoNotifyPolicy m_autoNotifyPolicy;
             SetRequestHandlerPolicy m_setRequestHandlerPolicy;
@@ -495,8 +496,10 @@ namespace OIC
          * the RCSResourceObject it is given. When control leaves the scope in which the LockGuard
          * object was created, the LockGuard is destructed and the attributes is unlocked.
          *
-         * Additionally when this is destructed, it tries to notify depending on AutoNotifyPolicy
-         * of the RCSResourceObject.
+         * Additionally when it is destructed and only when destructed not by stack unwinding
+         * caused by an exception, it tries to notify depending on AutoNotifyPolicy.
+         *
+         * @note The destrcutor can throw an exception if auto notify failed.
          */
         class RCSResourceObject::LockGuard
         {
@@ -519,7 +522,13 @@ namespace OIC
             * @overload
             */
             LockGuard(const RCSResourceObject::Ptr, AutoNotifyPolicy);
-            ~LockGuard();
+
+            /**
+             * @throws RCSPlatformException If auto notify operation failed.
+             *
+             * @note The exception will never be thrown while stack unwinding.
+             */
+            ~LockGuard() noexcept(false);
 
             LockGuard(const LockGuard&) = delete;
             LockGuard(LockGuard&&) = delete;
index cb339ec..a9d4cae 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#include <RCSResourceAttributes.h>
+#include "RCSResourceAttributes.h"
 
-#include <ResourceAttributesUtils.h>
-#include <ResourceAttributesConverter.h>
+#include <sstream>
 
-#include <boost/lexical_cast.hpp>
-#include <boost/mpl/advance.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/deref.hpp>
+#include "ResourceAttributesUtils.h"
+#include "ResourceAttributesConverter.h"
+
+#include "boost/lexical_cast.hpp"
+#include "boost/mpl/advance.hpp"
+#include "boost/mpl/size.hpp"
+#include "boost/mpl/deref.hpp"
 
 namespace
 {
 
     using namespace OIC::Service;
 
-    class ToStringVisitor: public boost::static_visitor< std::string >
+    class ToStringVisitor: public boost::static_visitor<>
     {
     public:
         ToStringVisitor() = default;
@@ -43,37 +45,56 @@ namespace
         ToStringVisitor& operator=(const ToStringVisitor&) = delete;
         ToStringVisitor& operator=(ToStringVisitor&&) = delete;
 
-        template < typename T >
-        std::string operator()(const T& value) const
+        template< typename T >
+        void operator()(const T& value)
         {
-            return boost::lexical_cast<std::string>(value);
+            m_stream << boost::lexical_cast< std::string >(value);
         }
 
         template< typename T >
-        std::string operator()(const std::vector< T >&) const
+        void operator()(const std::vector< T >& v)
         {
-            return "Vector";
+            m_stream << "[";
+            for (auto it = v.begin(); it != v.end(); ++it)
+            {
+                if (it != v.begin()) m_stream << ", ";
+                (*this)(*it);
+            }
+            m_stream << "]";
         }
 
-        std::string operator()(std::nullptr_t) const
+        void operator()(std::nullptr_t)
         {
-            return "";
+            m_stream << "";
         }
 
-        std::string operator()(bool value) const
+        void operator()(bool value)
         {
-            return value ? "true" : "false";
+            m_stream << (value ? "true" : "false");
         }
 
-        std::string operator()(const std::string& value) const
+        void operator()(const std::string& value)
         {
-            return value;
+            m_stream << "\"" + value + "\"";
         }
 
-        std::string operator()(const OIC::Service::RCSResourceAttributes&) const
+        void operator()(const RCSResourceAttributes& attrs)
         {
-            return "Attributes";
+            m_stream << "{";
+            for (auto it = attrs.begin(); it != attrs.end(); ++it)
+            {
+                if (it != attrs.begin()) m_stream << ", ";
+                m_stream << "\"" << it->key() << "\" : " << it->value().toString();
+            }
+            m_stream << "}";
+        }
+
+        std::string get() const {
+            return m_stream.str();
         }
+
+    private:
+        std::ostringstream m_stream;
     };
 
     class TypeVisitor: public boost::static_visitor< RCSResourceAttributes::Type >
@@ -333,7 +354,9 @@ namespace OIC
 
         std::string RCSResourceAttributes::Value::toString() const
         {
-            return boost::apply_visitor(ToStringVisitor(), *m_data);
+            ToStringVisitor visitor;
+            boost::apply_visitor(visitor, *m_data);
+            return visitor.get();
         }
 
         void RCSResourceAttributes::Value::swap(Value& rhs) noexcept
index b1429c6..090ef8a 100644 (file)
@@ -85,7 +85,7 @@ namespace OIC
 
             public:
                 void onObserve(const HeaderOptions &_hos,
-                               const ResponseStatement &_rep, int _result, int _seq);
+                               const ResponseStatement &_rep, int _result, unsigned int _seq);
                 void onGet(const HeaderOptions &_hos, const ResponseStatement &_rep, int _result);
             private:
                 void onTimeOut(const unsigned int timerID);
index e21973c..86a1428 100644 (file)
@@ -40,7 +40,7 @@ namespace OIC
         {
             void verifyObserveCB(
                 const HeaderOptions &_hos, const ResponseStatement &_rep,
-                int _result, int _seq, std::weak_ptr<DataCache> rpPtr)
+                int _result, unsigned int _seq, std::weak_ptr<DataCache> rpPtr)
             {
                 std::shared_ptr<DataCache> Ptr = rpPtr.lock();
                 if (Ptr)
@@ -203,7 +203,7 @@ namespace OIC
         }
 
         void DataCache::onObserve(const HeaderOptions & /*_hos*/,
-                                  const ResponseStatement &_rep, int _result, int _seq)
+                                  const ResponseStatement &_rep, int _result, unsigned int _seq)
         {
 
             if (_result != OC_STACK_OK || _rep.getAttributes().empty() || lastSequenceNum > _seq)
index 41c3e6a..ec7cd1c 100644 (file)
@@ -95,7 +95,7 @@ TEST_F(DataCacheTest, initializeDataCache_normalCaseObservable)
         OIC::Service::HeaderOptions hos;
         OIC::Service::RCSResourceAttributes attr;
         OIC::Service::ResponseStatement rep(attr);
-        int seq;
+        int seq = 0;
         callback(hos, rep, OC_STACK_OK, seq);
         return;
     }
index b74de4b..0c2d109 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#include <RCSResourceObject.h>
+#include "RCSResourceObject.h"
 
 #include <string>
 #include <functional>
 #include <vector>
 
-#include <RequestHandler.h>
-#include <AssertUtils.h>
-#include <AtomicHelper.h>
-#include <ResourceAttributesConverter.h>
-#include <ResourceAttributesUtils.h>
+#include "RequestHandler.h"
+#include "AssertUtils.h"
+#include "AtomicHelper.h"
+#include "ResourceAttributesConverter.h"
+#include "ResourceAttributesUtils.h"
+#include "RCSRequest.h"
 
-#include <logger.h>
-#include <OCPlatform.h>
+#include "logger.h"
+#include "OCPlatform.h"
 
 #define LOG_TAG "RCSResourceObject"
 
@@ -56,7 +57,7 @@ namespace
 
     template <typename RESPONSE>
     OCEntityHandlerResult sendResponse(RCSResourceObject& resource,
-            std::shared_ptr< OC::OCResourceRequest > ocRequest, RESPONSE&& response)
+            const std::shared_ptr< OC::OCResourceRequest >& ocRequest, RESPONSE&& response)
     {
         auto ocResponse = response.getHandler()->buildResponse(resource);
         ocResponse->setRequestHandle(ocRequest->getRequestHandle());
@@ -78,7 +79,7 @@ namespace
     }
 
     RCSResourceAttributes getAttributesFromOCRequest(
-            std::shared_ptr< OC::OCResourceRequest > request)
+            const std::shared_ptr< OC::OCResourceRequest >& request)
     {
         return ResourceAttributesConverter::fromOCRepresentation(
                 request->getResourceRepresentation());
@@ -87,11 +88,12 @@ namespace
     template< typename HANDLER, typename RESPONSE =
             typename std::decay<HANDLER>::type::result_type >
     RESPONSE invokeHandler(RCSResourceAttributes& attrs,
-            std::shared_ptr< OC::OCResourceRequest > ocRequest, HANDLER&& handler)
+            const std::shared_ptr< OC::OCResourceRequest >& ocRequest,
+            std::shared_ptr< HANDLER > handler)
     {
         if (handler)
         {
-            return handler(RCSRequest{ ocRequest->getResourceUri() }, attrs);
+            return (*handler)(RCSRequest{ ocRequest->getResourceUri() }, attrs);
         }
 
         return RESPONSE::defaultAction();
@@ -100,7 +102,7 @@ namespace
     typedef void (RCSResourceObject::* AutoNotifyFunc)
             (bool, RCSResourceObject::AutoNotifyPolicy) const;
 
-    std::function <void ()> createAutoNotifyInvoker(AutoNotifyFunc autoNotifyFunc,
+    std::function<void()> createAutoNotifyInvoker(AutoNotifyFunc autoNotifyFunc,
             const RCSResourceObject& resourceObject, const RCSResourceAttributes& resourceAttributes,
             RCSResourceObject::AutoNotifyPolicy autoNotifyPolicy)
     {
@@ -337,12 +339,12 @@ namespace OIC
 
         void RCSResourceObject::setGetRequestHandler(GetRequestHandler h)
         {
-            m_getRequestHandler = std::move(h);
+            m_getRequestHandler = std::make_shared< GetRequestHandler >(std::move(h));
         }
 
         void RCSResourceObject::setSetRequestHandler(SetRequestHandler h)
         {
-            m_setRequestHandler = std::move(h);
+            m_setRequestHandler = std::make_shared< SetRequestHandler >(std::move(h));
         }
 
         void RCSResourceObject::notify() const
@@ -422,7 +424,7 @@ namespace OIC
         }
 
         OCEntityHandlerResult RCSResourceObject::entityHandler(
-                std::shared_ptr< OC::OCResourceRequest > request)
+                const std::shared_ptr< OC::OCResourceRequest >& request)
         {
             OC_LOG(WARNING, LOG_TAG, "entityHandler");
             if (!request)
@@ -457,7 +459,7 @@ namespace OIC
         }
 
         OCEntityHandlerResult RCSResourceObject::handleRequest(
-                std::shared_ptr< OC::OCResourceRequest > request)
+                const std::shared_ptr< OC::OCResourceRequest >& request)
         {
             assert(request != nullptr);
 
@@ -475,7 +477,7 @@ namespace OIC
         }
 
         OCEntityHandlerResult RCSResourceObject::handleRequestGet(
-                std::shared_ptr< OC::OCResourceRequest > request)
+                const std::shared_ptr< OC::OCResourceRequest >& request)
         {
             assert(request != nullptr);
 
@@ -493,7 +495,7 @@ namespace OIC
             auto replaced = requestHandler->applyAcceptanceMethod(response.getAcceptanceMethod(),
                     *this, requstAttrs);
 
-            OC_LOG_V(WARNING, LOG_TAG, "replaced num %d", replaced.size());
+            OC_LOG_V(WARNING, LOG_TAG, "replaced num %zu", replaced.size());
             for (const auto& attrKeyValPair : replaced)
             {
                 std::shared_ptr< AttributeUpdatedListener > foundListener;
@@ -517,7 +519,7 @@ namespace OIC
         }
 
         OCEntityHandlerResult RCSResourceObject::handleRequestSet(
-                std::shared_ptr< OC::OCResourceRequest > request)
+                const std::shared_ptr< OC::OCResourceRequest >& request)
         {
             assert(request != nullptr);
 
@@ -537,7 +539,7 @@ namespace OIC
         }
 
         OCEntityHandlerResult RCSResourceObject::handleObserve(
-                std::shared_ptr< OC::OCResourceRequest >)
+                const std::shared_ptr< OC::OCResourceRequest >&)
         {
             if (!isObservable())
             {
@@ -582,9 +584,9 @@ namespace OIC
             init();
         }
 
-        RCSResourceObject::LockGuard::~LockGuard()
+        RCSResourceObject::LockGuard::~LockGuard() noexcept(false)
         {
-            if (m_autoNotifyFunc) m_autoNotifyFunc();
+            if (!std::uncaught_exception() && m_autoNotifyFunc) m_autoNotifyFunc();
 
             if (m_isOwningLock)
             {
index ba441fd..33431bb 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-#include <UnitTestHelper.h>
+#include "UnitTestHelper.h"
 
-#include <RCSResourceObject.h>
+#include "RCSResourceObject.h"
 
-#include <OCPlatform.h>
+#include "OCPlatform.h"
 
 using namespace std;
 using namespace std::placeholders;
@@ -38,7 +38,7 @@ typedef OCStackResult (*NotifyAllObservers)(OCResourceHandle);
 constexpr char RESOURCE_URI[]{ "a/test" };
 constexpr char RESOURCE_TYPE[]{ "resourcetype" };
 constexpr char KEY[]{ "key" };
-constexpr int value{ 100 };
+constexpr int VALUE{ 100 };
 
 TEST(ResourceObjectBuilderCreateTest, ThrowIfUriIsInvalid)
 {
@@ -122,10 +122,10 @@ TEST_F(ResourceObjectTest, AccessAttributesWithLock)
     {
         RCSResourceObject::LockGuard lock{ server };
         auto& attr = server->getAttributes();
-        attr[KEY] = value;
+        attr[KEY] = VALUE;
     }
 
-    ASSERT_EQ(value, server->getAttribute<int>(KEY));
+    ASSERT_EQ(VALUE, server->getAttribute<int>(KEY));
 }
 
 TEST_F(ResourceObjectTest, ThrowIfTryToAccessAttributesWithoutGuard)
@@ -137,10 +137,10 @@ TEST_F(ResourceObjectTest, SettingAttributesWithinGuardDoesntCauseDeadLock)
 {
     {
         RCSResourceObject::LockGuard guard{ server };
-        server->setAttribute(KEY, value);
+        server->setAttribute(KEY, VALUE);
     }
 
-    ASSERT_EQ(value, server->getAttribute<int>(KEY));
+    ASSERT_EQ(VALUE, server->getAttribute<int>(KEY));
 }
 
 TEST_F(ResourceObjectTest, SettingNestedAttributesIsSameToGettingNestedAttributes)
@@ -197,23 +197,23 @@ TEST_F(AutoNotifyTest, AutoNotifyPolicyCanBeSet)
 TEST_F(AutoNotifyTest, WithUpdatedPolicy_NeverBeNotifiedIfAttributeIsNotChanged)
 {
     server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
-    server->setAttribute(KEY, value);
+    server->setAttribute(KEY, VALUE);
 
     mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
             OC::OCPlatform::notifyAllObservers));
 
-    server->setAttribute(KEY, value);
+    server->setAttribute(KEY, VALUE);
 }
 
 TEST_F(AutoNotifyTest, WithUpdatedPolicy_WillBeNotifiedIfAttributeIsChanged)
 {
     server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
-    server->setAttribute(KEY, value);
+    server->setAttribute(KEY, VALUE);
 
     mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
             OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
 
-    server->setAttribute(KEY, value + 1);
+    server->setAttribute(KEY, VALUE + 1);
 }
 
 TEST_F(AutoNotifyTest, WithUpdatedPolicy_WillBeNotifiedIfValueIsAdded)
@@ -224,7 +224,7 @@ TEST_F(AutoNotifyTest, WithUpdatedPolicy_WillBeNotifiedIfValueIsAdded)
     mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
             OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
 
-    server->setAttribute(newKey, value);
+    server->setAttribute(newKey, VALUE);
 }
 
 TEST_F(AutoNotifyTest, WithNeverPolicy_NeverBeNotifiedEvenIfAttributeIsChanged)
@@ -235,13 +235,13 @@ TEST_F(AutoNotifyTest, WithNeverPolicy_NeverBeNotifiedEvenIfAttributeIsChanged)
             OC::OCPlatform::notifyAllObservers));
 
     RCSResourceObject::LockGuard lock{ server };
-    server->setAttribute(KEY, value);
+    server->setAttribute(KEY, VALUE);
 }
 
 TEST_F(AutoNotifyTest, WithUpdatePolicy_WillBeNotifiedIfAttributeIsDeleted)
 {
     server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
-    server->setAttribute(KEY, value);
+    server->setAttribute(KEY, VALUE);
 
     mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
             OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
@@ -261,7 +261,7 @@ TEST_F(AutoNotifyWithGuardTest, GuardFollowsServerPolicyByDefault)
             OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
 
     RCSResourceObject::LockGuard guard{ server };
-    server->setAttribute(KEY, value);
+    server->setAttribute(KEY, VALUE);
 }
 
 TEST_F(AutoNotifyWithGuardTest, GuardCanOverridePolicy)
@@ -272,7 +272,7 @@ TEST_F(AutoNotifyWithGuardTest, GuardCanOverridePolicy)
             OC::OCPlatform::notifyAllObservers));
 
     RCSResourceObject::LockGuard guard{ server, RCSResourceObject::AutoNotifyPolicy::NEVER };
-    server->getAttributes()[KEY] = value;
+    server->getAttributes()[KEY] = VALUE;
 }
 
 TEST_F(AutoNotifyWithGuardTest, GuardInvokesNotifyWhenDestroyed)
@@ -284,13 +284,13 @@ TEST_F(AutoNotifyWithGuardTest, GuardInvokesNotifyWhenDestroyed)
 
     {
         RCSResourceObject::LockGuard guard{ server, RCSResourceObject::AutoNotifyPolicy::ALWAYS };
-        server->setAttribute(KEY, value);
+        server->setAttribute(KEY, VALUE);
     }
 
     mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
                OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
 
-    server->setAttribute(KEY, value);
+    server->setAttribute(KEY, VALUE);
 }
 
 
@@ -396,7 +396,7 @@ TEST_F(ResourceObjectHandlingRequestTest, SendResponseWithRCSResponseResults)
 TEST_F(ResourceObjectHandlingRequestTest, SendSetResponseWithCustomAttrs)
 {
     constexpr int errorCode{ 1999 };
-    constexpr char value[]{ "value" };
+    constexpr char value[]{ "VALUE" };
 
     server->setSetRequestHandler(
             [](const RCSRequest&, RCSResourceAttributes&) -> RCSSetResponse
@@ -419,6 +419,7 @@ TEST_F(ResourceObjectHandlingRequestTest, SendSetResponseWithCustomAttrs)
 }
 
 
+
 class SetRequestHandlerPolicyTest: public ResourceObjectHandlingRequestTest
 {
 public:
@@ -428,14 +429,7 @@ public:
     OCRepresentation createOCRepresentation()
     {
         OCRepresentation ocRep;
-
-        vector<string> interface{"oic.if.baseline"};
-        vector<string> type{"core.light"};
-
-        ocRep.setUri(RESOURCE_URI);
-        ocRep.setResourceInterfaces(interface);
-        ocRep.setResourceTypes(type);
-
+        ocRep[KEY] = VALUE;
         return ocRep;
     }
 
@@ -460,31 +454,28 @@ TEST_F(SetRequestHandlerPolicyTest, SetRequestHandlerPolicyCanBeSet)
                 server->getSetRequestHandlerPolicy());
 }
 
-TEST_F(SetRequestHandlerPolicyTest, WithNeverPolicy_NotAddedIfReceivedNewKeyValuePair)
+TEST_F(SetRequestHandlerPolicyTest, WithNeverPolicy_DeniedIfKeyIsNew)
 {
-    OCRepresentation ocRep = createOCRepresentation();
-    ocRep.setValue("NewKey", value);
     server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
 
-    handler(createRequest(OC_REST_PUT, ocRep));
+    handler(createRequest(OC_REST_PUT, createOCRepresentation()));
 
     RCSResourceObject::LockGuard guard{ server };
-    ASSERT_FALSE((server->getAttributes()).contains("NewKey"));
+    ASSERT_FALSE(server->getAttributes().contains(KEY));
 }
 
-TEST_F(SetRequestHandlerPolicyTest, WithAcceptancePolicy_WillBeAddedIfReceivedNewKeyValuePair)
+TEST_F(SetRequestHandlerPolicyTest, WithAcceptancePolicy_AcceptedEvenIfKeyIsNew)
 {
-    OCRepresentation ocRep = createOCRepresentation();
-    ocRep.setValue("NewKey", value);
     server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE);
 
-    handler(createRequest(OC_REST_PUT, ocRep));
+    handler(createRequest(OC_REST_PUT, createOCRepresentation()));
 
     RCSResourceObject::LockGuard guard{ server };
-    ASSERT_TRUE((server->getAttributes()).contains("NewKey"));
+    ASSERT_TRUE(server->getAttributes().contains(KEY));
 }
 
 
+
 class ResourceObjectSynchronizationTest: public ResourceObjectHandlingRequestTest
 {
 public:
@@ -580,6 +571,7 @@ TEST_F(ResourceObjectSynchronizationTest, MultipleAccessToServerResourceWithRequ
 }
 
 
+
 class AttributeUpdatedListenerTest: public ResourceObjectHandlingRequestTest
 {
 public:
@@ -589,98 +581,80 @@ public:
     OCRepresentation createOCRepresentation(void)
     {
         OCRepresentation ocRep;
-
-        vector<string> interface{"oic.if.baseline"};
-        vector<string> type{"core.light"};
-
-        ocRep.setUri(RESOURCE_URI);
-        ocRep.setResourceInterfaces(interface);
-        ocRep.setResourceTypes(type);
-        ocRep[KEY] = value;
-
+        ocRep[KEY] = VALUE;
         return ocRep;
     }
 
-    void initMocks()
+protected:
+    void SetUp()
     {
-        ResourceObjectHandlingRequestTest::initMocks();
+        ResourceObjectHandlingRequestTest::SetUp();
         mocks.OnCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
+
+        server->setAttribute(KEY, 0);
     }
 };
 
-class FunctionsForAttributeUpdatedListener
+class AttributeUpdatedListener
 {
 public:
-    virtual void fCalled(const OIC::Service::RCSResourceAttributes::Value&,
-        const OIC::Service::RCSResourceAttributes::Value&)=0;
-    virtual void fNotCalled(const OIC::Service::RCSResourceAttributes::Value&,
+    virtual void onUpdated(const OIC::Service::RCSResourceAttributes::Value&,
         const OIC::Service::RCSResourceAttributes::Value&)=0;
 };
 
-TEST_F(AttributeUpdatedListenerTest, AddListenerRunsAddedFunction)
-{
-    FunctionsForAttributeUpdatedListener *ptrMock =
-        mocks.Mock<FunctionsForAttributeUpdatedListener>();
 
-    server->setAttribute(KEY, 0);
+TEST_F(AttributeUpdatedListenerTest, RemoveListenerReturnsFalseIfListenerIsNotAdded)
+{
+    ASSERT_FALSE(server->removeAttributeUpdatedListener(KEY));
+}
 
-    mocks.ExpectCall(ptrMock, FunctionsForAttributeUpdatedListener::fCalled);
+TEST_F(AttributeUpdatedListenerTest, RemoveListenerReturnsTrueIfListenerIsAdded)
+{
+    auto listener = mocks.Mock< AttributeUpdatedListener >();
 
     server->addAttributeUpdatedListener(KEY,
-        (std::bind(&FunctionsForAttributeUpdatedListener::fCalled, ptrMock, _1, _2)));
+            std::bind(&AttributeUpdatedListener::onUpdated, listener, _1, _2));
 
-    handler(createRequest(OC_REST_PUT, createOCRepresentation()));
+    ASSERT_TRUE(server->removeAttributeUpdatedListener(KEY));
 }
 
-TEST_F(AttributeUpdatedListenerTest, AddListenerRunsAccordingToLastAddedFunction)
+TEST_F(AttributeUpdatedListenerTest, AddListenerRunsAddedFunction)
 {
-    FunctionsForAttributeUpdatedListener *ptrMock =
-        mocks.Mock<FunctionsForAttributeUpdatedListener>();
+    auto listener = mocks.Mock< AttributeUpdatedListener >();
 
-    string duplicateKEY(KEY);
-    server->setAttribute(KEY, 0);
-
-    mocks.ExpectCall(ptrMock, FunctionsForAttributeUpdatedListener::fCalled);
-    mocks.NeverCall(ptrMock, FunctionsForAttributeUpdatedListener::fNotCalled);
-
-    server->addAttributeUpdatedListener(duplicateKEY,
-        (std::bind(&FunctionsForAttributeUpdatedListener::fNotCalled, ptrMock, _1, _2)));
     server->addAttributeUpdatedListener(KEY,
-        (std::bind(&FunctionsForAttributeUpdatedListener::fCalled, ptrMock, _1, _2)));
+            std::bind(&AttributeUpdatedListener::onUpdated, listener, _1, _2));
+
+    mocks.ExpectCall(listener, AttributeUpdatedListener::onUpdated);
 
     handler(createRequest(OC_REST_PUT, createOCRepresentation()));
 }
 
-TEST_F(AttributeUpdatedListenerTest, RemoveListenerReturnsTrueIfListenerIsNotAdded)
+TEST_F(AttributeUpdatedListenerTest, ListenerWithSameKeyOverridesPreviousOne)
 {
-    ASSERT_FALSE(server->removeAttributeUpdatedListener(KEY));
-}
+    auto first = mocks.Mock< AttributeUpdatedListener >();
+    auto second = mocks.Mock< AttributeUpdatedListener >();
 
-TEST_F(AttributeUpdatedListenerTest, RemoveListenerReturnsTrueIfListenerIsAdded)
-{
-    FunctionsForAttributeUpdatedListener *ptrMock =
-        mocks.Mock<FunctionsForAttributeUpdatedListener>();
+    mocks.NeverCall(first, AttributeUpdatedListener::onUpdated);
+    mocks.ExpectCall(second, AttributeUpdatedListener::onUpdated);
 
     server->addAttributeUpdatedListener(KEY,
-        (std::bind(&FunctionsForAttributeUpdatedListener::fNotCalled, ptrMock, _1, _2)));
+            std::bind(&AttributeUpdatedListener::onUpdated, first, _1, _2));
+    server->addAttributeUpdatedListener(KEY,
+            std::bind(&AttributeUpdatedListener::onUpdated, second, _1, _2));
 
-    ASSERT_TRUE(server->removeAttributeUpdatedListener(KEY));
+    handler(createRequest(OC_REST_PUT, createOCRepresentation()));
 }
 
-TEST_F(AttributeUpdatedListenerTest, RemoveListenerNeverRunsRemovedFunc)
+TEST_F(AttributeUpdatedListenerTest, RemovedListenerNotBeInvoked)
 {
-    FunctionsForAttributeUpdatedListener *ptrMock =
-        mocks.Mock<FunctionsForAttributeUpdatedListener>();
+    auto listener = mocks.Mock< AttributeUpdatedListener >();
+    server->addAttributeUpdatedListener(KEY,
+            std::bind(&AttributeUpdatedListener::onUpdated, listener, _1, _2));
 
-    mocks.NeverCall(ptrMock, FunctionsForAttributeUpdatedListener::fNotCalled);
+    mocks.NeverCall(listener, AttributeUpdatedListener::onUpdated);
 
-    server->setAttribute(KEY, 0);
-    server->addAttributeUpdatedListener(KEY,
-        (std::bind(&FunctionsForAttributeUpdatedListener::fNotCalled, ptrMock, _1, _2)));
     server->removeAttributeUpdatedListener(KEY);
 
     handler(createRequest(OC_REST_PUT, createOCRepresentation()));
 }
-
-
-
index 0f965a8..f4087cc 100755 (executable)
@@ -521,23 +521,9 @@ static void findAllResources(void *data, Evas_Object *obj, void *event_info)
     dlog_print(DLOG_INFO, LOG_TAG, "#### calling findCandidateResources ENTRY!!!!");
     std::vector<string> resourceTypes;
     resourceTypes.push_back("oic.wk.con");
-
-    if (NULL != g_groupManager)
-    {
-        g_groupManager->findCandidateResources(resourceTypes, &onFoundCandidateResource,
-                                               FINDRESOURCE_TIMEOUT);
-    }
-
-    resourceTypes.clear();
     resourceTypes.push_back("oic.wk.mnt");
-    if (NULL != g_groupManager)
-    {
-        g_groupManager->findCandidateResources(resourceTypes, &onFoundCandidateResource,
-                                               FINDRESOURCE_TIMEOUT);
-    }
-
-    resourceTypes.clear();
     resourceTypes.push_back("factoryset");
+
     if (NULL != g_groupManager)
     {
         g_groupManager->findCandidateResources(resourceTypes, &onFoundCandidateResource,
@@ -559,6 +545,15 @@ static void getConfiguration(void *data, Evas_Object *obj, void *event_info)
         return;
     }
 
+    if (NULL == g_configurationResource)
+    {
+        dlog_print(DLOG_INFO, LOG_TAG, "Configuration Resource not found.");
+        string logMessage = "FIRST FIND CONFIGURATION RESOURCE <br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
+        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
+        return;
+    }
+
     ConfigurationName name = "all";
     std::vector< ConfigurationName > configurations;
     configurations.push_back(name);
@@ -579,11 +574,11 @@ static void getConfiguration(void *data, Evas_Object *obj, void *event_info)
     dlog_print(DLOG_INFO, LOG_TAG, "#### getConfiguration EXIT!!!!");
 }
 
-// Updates the configuration i.e. region value to INDIA
-static void updateConfiguration(std::string newRegionValue)
+// Updates the configuration i.e. Device name to OIC Device
+static void updateConfiguration(std::string newDeviceName)
 {
     dlog_print(DLOG_INFO, LOG_TAG, "#### updateConfiguration ENTRY!!!!");
-    dlog_print(DLOG_INFO, LOG_TAG, "#### %s", newRegionValue.c_str());
+    dlog_print(DLOG_INFO, LOG_TAG, "#### %s", newDeviceName.c_str());
 
     if (NULL == g_configurationCollection || NULL == g_configurationCollection.get())
     {
@@ -595,9 +590,18 @@ static void updateConfiguration(std::string newRegionValue)
         return;
     }
 
+    if (NULL == g_configurationResource)
+    {
+        dlog_print(DLOG_INFO, LOG_TAG, "Configuration Resource not found.");
+        string logMessage = "FIRST FIND CONFIGURATION RESOURCE <br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
+        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
+        return;
+    }
+
     OCStackResult result;
-    ConfigurationName name = DEFAULT_REGION;
-    ConfigurationValue value = newRegionValue;
+    ConfigurationName name = DEFAULT_DEVICENAME;
+    ConfigurationValue value = newDeviceName;
 
     std::map< ConfigurationName, ConfigurationValue > configurations;
     configurations.insert(std::make_pair(name, value));
@@ -637,6 +641,15 @@ static void factoryReset(void *data, Evas_Object *obj, void *event_info)
         return;
     }
 
+    if (NULL == g_maintenanceResource)
+    {
+        dlog_print(DLOG_INFO, LOG_TAG, "Maintenance Resource not found.");
+        string logMessage = "FIRST FIND MAINTENANCE RESOURCE <br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
+        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
+        return;
+    }
+
     OCStackResult result;
 
     try
@@ -673,6 +686,15 @@ static void reboot(void *data, Evas_Object *obj, void *event_info)
         return;
     }
 
+    if (NULL == g_maintenanceResource)
+    {
+        dlog_print(DLOG_INFO, LOG_TAG, "Maintenance Resource not found.");
+        string logMessage = "FIRST FIND MAINTENANCE RESOURCE <br>";
+        dlog_print(DLOG_INFO, LOG_TAG, " %s", logMessage.c_str());
+        ecore_main_loop_thread_safe_call_sync((void * ( *)(void *))updateConfigLog, &logMessage);
+        return;
+    }
+
     OCStackResult result;
 
     try
@@ -779,7 +801,7 @@ popup_set_clicked_cb(void *data, Evas_Object *obj, void *event_info)
 }
 
 static void
-list_update_region_cb(void *data, Evas_Object *obj, void *event_info)
+list_update_devicename_cb(void *data, Evas_Object *obj, void *event_info)
 {
     if (NULL == g_configurationCollection || NULL == g_configurationCollection.get())
     {
@@ -800,7 +822,7 @@ list_update_region_cb(void *data, Evas_Object *obj, void *event_info)
     elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
     eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL);
     evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-    elm_object_part_text_set(popup, "title,text", "Enter New Region Value");
+    elm_object_part_text_set(popup, "title,text", "Enter new device name to update");
 
     layout = elm_layout_add(popup);
     elm_layout_file_set(layout, ELM_DEMO_EDJ, "popup_region_text");
@@ -813,7 +835,7 @@ list_update_region_cb(void *data, Evas_Object *obj, void *event_info)
     evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
     evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
     eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
-    elm_object_part_text_set(entry, "elm.guide", "region value");
+    elm_object_part_text_set(entry, "elm.guide", "e.g. OIC Device");
     elm_object_part_content_set(layout, "elm.swallow.content" , entry);
 
     region_popup_fields *popup_fields;
@@ -927,8 +949,8 @@ configuration_cb(void *data, Evas_Object *obj, void *event_info)
     elm_list_item_append(list, "Find All Resources",
                          NULL, NULL, findAllResources, NULL);
     elm_list_item_append(list, "Get a Configuration Resource", NULL, NULL, getConfiguration, NULL);
-    elm_list_item_append(list, "Update Attribute (Region)", NULL, NULL,
-                         list_update_region_cb, nf);
+    elm_list_item_append(list, "Update Attribute (Device Name)", NULL, NULL,
+                         list_update_devicename_cb, nf);
     elm_list_item_append(list, "Factory Reset", NULL, NULL, factoryReset, NULL);
     elm_list_item_append(list, "Reboot", NULL, NULL, reboot, NULL);
     elm_list_item_append(list, "Get Supported Configuration Units", NULL, NULL,