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
--- /dev/null
+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.
+
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_')
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) {
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,
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) {
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;
}
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)
{
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");
}
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");
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:
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)
{
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");
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");
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:
#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
/* 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) \
((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) \
#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) \
((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
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);
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);
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),
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.
/* 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,
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;
}
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)
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),
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);
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;
}
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");
p += sizeof(uint8);
- /* client certificate type extension */
+ /* server certificate type extension */
dtls_int_to_uint16(p, TLS_EXT_SERVER_CERTIFICATE_TYPE);
p += sizeof(uint16);
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);
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);
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;
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);
}
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);
}
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'),
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')])
######################################################################
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)
--- /dev/null
+//******************************************************************
+//
+// 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_
--- /dev/null
+//******************************************************************
+//
+// 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, ¤t)) != -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(¤t, 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;
+}
+
--- /dev/null
+#******************************************************************
+#
+# 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')
--- /dev/null
+//******************************************************************
+//
+// 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);
+}
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']:
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')
-
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) {
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;
// 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)
{
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);
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);
*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;
// 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);
}
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)
)
{
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));
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);
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);
}
transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)data)[0] >> 4);
}
else
+#else
+ (void) endpoint;
#endif
{
transport = coap_udp;
}
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);
}
}
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
transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)pdu->hdr)[0] >> 4);
}
else
+#else
+ (void) endpoint;
#endif
{
transport = coap_udp;
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)
{
transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)pdu_hdr)[0] >> 4);
}
else
+#else
+ (void) endpoint;
#endif
{
transport = coap_udp;
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;
}
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()
CAResult_t CAIPStopNetworkMonitor()
{
- return CA_STATUS_OK;
+ return CAIPDestroyJniInterface();
}
int CAGetPollingInterval(int interval)
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)
{
{
(void)data;
OIC_LOG(DEBUG, TAG, "IN");
-
while (!caglobals.ip.terminate)
{
CAFindReadyMessage();
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)
{
}
break;
}
+ else
+ {
+ break;
+ }
(void)CAReceiveMessage(fd, flags);
FD_CLR(fd, readFds);
//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);
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;
{
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);
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,
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))
/*
* 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
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;
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)
{
!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)
{
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.
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;
}
}
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;
(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)
exit:
context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
SRMSendResponse(context->retVal);
- FreeCARequestInfo(context->amsMgrContext->requestInfo);
- OICFree(context->amsMgrContext->endpoint);
return OC_STACK_DELETE_TRANSACTION;
}
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);
if(OC_STACK_OK == DiscoverAmsService(context))
{
context->retVal = ACCESS_WAITING_FOR_AMS;
+ context->state = AWAITING_AMS_RESPONSE;
}
else
{
}
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))
{
(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
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
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.
// 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);
*/
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;
}
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;
}
{
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;
}
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!");
}
}
{
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);
}
exit:
- //Resting PE state to AWAITING_REQUEST
+ //Resetting PE state to AWAITING_REQUEST
SetPolicyEngineState(&g_policyEngineContext, AWAITING_REQUEST);
}
{
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);
}
}
}
#ifndef OCPAYLOAD_H_
#define OCPAYLOAD_H_
+#define __STDC_FORMAT_MACROS
+#define __STDC_LIMIT_MACROS
#include <stdbool.h>
#include <inttypes.h>
#include "octypes.h"
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);
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,
/**Remote Access over XMPP.*/
OC_ADAPTER_REMOTE_ACCESS = (1 << 3),
#endif
-
-#ifdef TCP_ADAPTER
/** CoAP over TCP.*/
OC_ADAPTER_TCP = (1 << 4)
-#endif
} OCTransportAdapter;
/** 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).*/
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
{
double* dArray;
bool* bArray;
char** strArray;
+
+ /** pointer to ByteString array.*/
+ OCByteString* ocByteStrArray;
+
struct OCRepPayload** objArray;
};
} OCRepPayloadValueArray;
double d;
bool b;
char* str;
+
+ /** ByteString object.*/
+ OCByteString ocByteStr;
+
struct OCRepPayload* obj;
OCRepPayloadValueArray arr;
};
#include <dlog.h>
#endif
+#define __STDC_FORMAT_MACROS
+#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
#include "rdpayload.h"
#ifdef __cplusplus
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);
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!
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]);
void StripNewLineChar(char* str);
-// The handle for the observe registration
-OCDoHandle gObserveDoHandle;
#ifdef WITH_PRESENCE
// The handle for observe registration
OCDoHandle gPresenceHandle;
{
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)
{
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)
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");
}
}
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");
}
}
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:
{
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);
}
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)
{
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:
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)
{
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])
{
}
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
return 0;
}
}
+
static int64_t OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t* outPayload,
size_t* size)
{
err = err | cbor_encoder_close_container(&encoder, &rootArray);
return checkError(err, &encoder, outPayload, size);
-
}
static char* OCStringLLJoin(OCStringLL* val)
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])
{
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;
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);
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:
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:
size_t i = 0;
char* tempStr = NULL;
+ OCByteString ocByteStr = { .bytes = NULL, .len = 0};
size_t tempLen = 0;
OCRepPayload* tempPl = NULL;
);
}
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)
{
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))
{
int64_t intval = 0;
bool boolval = false;
char* strval = NULL;
+ uint8_t* bytestrval = NULL;
double doubleval = 0;
OCRepPayload* pl;
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)
if(serverResponse)
{
LL_DELETE(serverResponseList, serverResponse);
- OICFree(serverResponse->payload);
+ OCPayloadDestroy(serverResponse->payload);
OICFree(serverResponse);
OC_LOG(INFO, TAG, "Server Response Removed!!");
}
// 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:
#ifdef RA_ADAPTER
, CA_ADAPTER_REMOTE_ACCESS
#endif
-
-#ifdef TCP_ADAPTER
, CA_ADAPTER_TCP
-#endif
};
size_t size = sizeof(CAConnTypes)/ sizeof(CATransportAdapter_t);
#ifdef RA_ADAP
| CA_ADAPTER_REMOTE_ACCESS
#endif
-
-#ifdef TCP_ADAPTER
| CA_ADAPTER_TCP
-#endif
);
}
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);
}
// 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>
#endif
OCDeviceEntityHandler defaultDeviceHandler;
void* defaultDeviceHandlerCallbackParameter = NULL;
-
-#ifdef TCP_ADAPTER
static const char COAP_TCP[] = "coap+tcp:";
-#endif
+
//-----------------------------------------------------------------------------
// Macros
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();
return OC_STACK_INVALID_URI;
}
-#ifdef TCP_ADAPTER
// process url scheme
size_t prefixLen = slash2 - fullUri;
bool istcp = false;
istcp = true;
}
}
-#endif
// TODO: this logic should come in with unit tests exercising the various strings
// processs url prefix, if any
{ // 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);
{
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)
{
#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);
# 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':
--- /dev/null
+//******************************************************************
+//
+// 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);
+}
../include/OCResourceRequest.h \
../include/OCResourceResponse.h \
../include/OCResource.h \
+ ../include/OCProvisioningManager.h \
../csdk/stack/include/octypes.h \
../csdk/stack/include/ocstackconfig.h \
guides \
// 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
{
{
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
+++ /dev/null
--------------------------------------------------------------------------------
- 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
-
-
-
+++ /dev/null
-//******************************************************************
-//
-// 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;
-}
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;
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)
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(),
{
ss << COAPS;
}
-#ifdef TCP_ADAPTER
else if (m_devAddr.adapter & OC_ADAPTER_TCP)
{
ss << COAP_TCP;
}
-#endif
else
{
ss << COAP;
}
} // namespace OC
-
# 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')
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"));
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]);
</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=""${workspace_loc:/${ProjName}/inc}""/>
- <listOptionValue builtIn="false" value=""C:\boost_1_56_0""/>
<listOptionValue builtIn="false" value=""..\..\..\..\..\resource-encapsulation\src\resourceBroker\include""/>
<listOptionValue builtIn="false" value=""..\..\..\..\..\resource-encapsulation\src\resourceCache\include""/>
<listOptionValue builtIn="false" value=""..\..\..\..\..\resource-encapsulation\src\common\utils\include""/>
// 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);
}
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
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);
#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__
s_containerFlag = true;
s_hueBundleFlag = true;
logMessage += "CONTAINER STARTED<br>";
- logMessage += "ADD AND START BUNDLES<br>";
+ logMessage += "HUE BUNDLE STARTED<br>";
}
else
{
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;
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);
}
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);
}
*
* @throws RcsIllegalStateException
* if not in locked state
+ * @throws RcsPlatformException
+ * if auto notify failed
*/
public void apply() throws RcsIllegalStateException {
if (mCurrentAttributes == null) {
#include "JniRcsValue.h"
#include "Log.h"
#include "Verify.h"
+#include "JavaExceptions.h"
#include "RCSResourceObject.h"
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
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
#include "RCSResourceObject.h"
#include "RCSResponse.h"
+#include "RCSRequest.h"
#include "RequestHandler.h"
#define LOG_TAG "JNI-RCSResourceObject"
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());
}
}
mResourceObj.startMonitoring(mOnStateChangedListener);
+
+ if (mResourceObj.isMonitoring()) {
+ printLog("Monitoring started successfully");
+ }
}
};
@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");
}
}
mResourceObj.startCaching(mOnCacheUpdatedListener);
+
+ if (mResourceObj.isCaching()) {
+ printLog("Caching started successfully");
+ }
+
}
};
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
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() {
super.handleMessage(msg);
ResourceClientActivity activity = mActivityRef.get();
- if (activity == null)
- return;
+ if (activity == null) return;
switch (msg.what) {
case MSG_ID_RESOURCE_DISCOVERED:
*
******************************************************************/
-#include "PrimitiveResource.h"
#include "RCSResourceObject.h"
#include "OCPlatform.h"
#include "OCApi.h"
}
//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;
}
//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;
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')
#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;
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()
void getResourceCacheState()
{
- switch(selectedResource->getCacheState())
+ switch(g_selectedResource->getCacheState())
{
case CacheState::READY:
std::cout << "\tCurrent Cache State : CACHE_STATE::READY" << std::endl;
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;
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;
}
*
******************************************************************/
-#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)
{
}
}
-//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;
}
#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
{
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
#include <mutex>
#include <thread>
-#include <RCSResourceAttributes.h>
-#include <RCSResponse.h>
-#include <RCSRequest.h>
+#include "RCSResourceAttributes.h"
+#include "RCSResponse.h"
namespace OC
{
namespace Service
{
+ class RCSRequest;
+
/**
* @brief Thrown when lock has not been acquired.
*
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;
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;
* 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
{
* @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;
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#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;
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 >
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
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);
{
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)
}
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)
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;
}
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#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"
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());
}
RCSResourceAttributes getAttributesFromOCRequest(
- std::shared_ptr< OC::OCResourceRequest > request)
+ const std::shared_ptr< OC::OCResourceRequest >& request)
{
return ResourceAttributesConverter::fromOCRepresentation(
request->getResourceRepresentation());
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();
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)
{
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
}
OCEntityHandlerResult RCSResourceObject::entityHandler(
- std::shared_ptr< OC::OCResourceRequest > request)
+ const std::shared_ptr< OC::OCResourceRequest >& request)
{
OC_LOG(WARNING, LOG_TAG, "entityHandler");
if (!request)
}
OCEntityHandlerResult RCSResourceObject::handleRequest(
- std::shared_ptr< OC::OCResourceRequest > request)
+ const std::shared_ptr< OC::OCResourceRequest >& request)
{
assert(request != nullptr);
}
OCEntityHandlerResult RCSResourceObject::handleRequestGet(
- std::shared_ptr< OC::OCResourceRequest > request)
+ const std::shared_ptr< OC::OCResourceRequest >& request)
{
assert(request != nullptr);
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;
}
OCEntityHandlerResult RCSResourceObject::handleRequestSet(
- std::shared_ptr< OC::OCResourceRequest > request)
+ const std::shared_ptr< OC::OCResourceRequest >& request)
{
assert(request != nullptr);
}
OCEntityHandlerResult RCSResourceObject::handleObserve(
- std::shared_ptr< OC::OCResourceRequest >)
+ const std::shared_ptr< OC::OCResourceRequest >&)
{
if (!isObservable())
{
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)
{
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#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;
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)
{
{
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)
{
{
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)
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)
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)
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);
OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
RCSResourceObject::LockGuard guard{ server };
- server->setAttribute(KEY, value);
+ server->setAttribute(KEY, VALUE);
}
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)
{
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);
}
TEST_F(ResourceObjectHandlingRequestTest, SendSetResponseWithCustomAttrs)
{
constexpr int errorCode{ 1999 };
- constexpr char value[]{ "value" };
+ constexpr char value[]{ "VALUE" };
server->setSetRequestHandler(
[](const RCSRequest&, RCSResourceAttributes&) -> RCSSetResponse
}
+
class SetRequestHandlerPolicyTest: public ResourceObjectHandlingRequestTest
{
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;
}
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:
}
+
class AttributeUpdatedListenerTest: public ResourceObjectHandlingRequestTest
{
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()));
}
-
-
-
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,
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);
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())
{
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));
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
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
}
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())
{
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");
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;
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,