From: David Antler Date: Fri, 1 Jul 2016 21:28:42 +0000 (-0700) Subject: Merge branch 'windows-port' X-Git-Tag: 1.2.0+RC1~258 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a2593578edc02d063c1335a3e89b19a3b5a4b1ad;hp=-c;p=platform%2Fupstream%2Fiotivity.git Merge branch 'windows-port' Add support for Visual Studio 2015 and 2013 builds. Change-Id: I3ce9bee6b3e57ccd548b849b5d147ca0babd872e Signed-off-by: David Antler --- a2593578edc02d063c1335a3e89b19a3b5a4b1ad diff --combined build_common/SConscript index 0e9f9c1,d1f1a07..38a4c8b --- a/build_common/SConscript +++ b/build_common/SConscript @@@ -8,17 -8,18 +8,18 @@@ import platfor # Map of host os and allowed target os (host: allowed target os) host_target_map = { 'linux': ['linux', 'android', 'arduino', 'yocto', 'tizen'], - 'windows': ['windows', 'winrt', 'android', 'arduino'], + 'windows': ['windows', 'android', 'arduino'], 'darwin': ['darwin', 'ios', 'android', 'arduino'], + 'msys_nt' :['msys_nt'], } # Map of os and allowed archs (os: allowed archs) os_arch_map = { - 'linux': ['x86', 'x86_64', 'arm', 'arm64'], - 'tizen': ['x86', 'x86_64', 'arm', 'arm64', 'armeabi-v7a'], + 'linux': ['x86', 'x86_64', 'arm', 'arm-v7a', 'arm64'], + 'tizen': ['x86', 'x86_64', 'arm', 'arm-v7a', 'armeabi-v7a', 'arm64'], 'android': ['x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'armeabi-v7a-hard', 'arm64-v8a'], 'windows': ['x86', 'amd64', 'arm'], - 'winrt': ['arm'], + 'msys_nt':['x86', 'x86_64'], 'darwin': ['i386', 'x86_64'], 'ios': ['i386', 'x86_64', 'armv7', 'armv7s', 'arm64'], 'arduino': ['avr', 'arm'], @@@ -27,6 -28,11 +28,11 @@@ host = platform.system().lower() + # the host string contains version of windows. 6.3, 6.4, 10.0 which is 8.0, 8.1, and 10 respectively. + # Let's canonicalize the msys_nt-XX.X system name by stripping version off. + if 'msys_nt' in host: + host = 'msys_nt' + if not host_target_map.has_key(host): print "\nError: Current system (%s) isn't supported\n" % host Exit(1) @@@ -238,6 -244,9 +244,9 @@@ def __installlib(ienv, targets, name) else: i_n = ienv.Install(user_prefix + '/lib', targets) ienv.Alias("install", i_n) + else: + i_n = ienv.Install(env.get('BUILD_DIR'), targets) + ienv.Alias("install", i_n) def __installbin(ienv, targets, name): user_prefix = env.get('PREFIX') @@@ -249,7 -258,9 +258,9 @@@ def __installheader(ienv, targets, dir user_prefix = env.get('PREFIX') if user_prefix: i_n = ienv.Install(user_prefix + '/include/' + dir ,targets) - ienv.Alias("install", i_n) + else: + i_n = ienv.Install(os.path.join(env.get('BUILD_DIR'), 'include', dir), targets) + ienv.Alias("install", i_n) def __installpcfile(ienv, targets, name): user_prefix = env.get('PREFIX') @@@ -259,7 -270,9 +270,9 @@@ i_n = ienv.Install(user_lib + '/pkgconfig', targets) else: i_n = ienv.Install(user_prefix + '/lib/pkgconfig', targets) - ienv.Alias("install", i_n) + else: + i_n = ienv.Install(env.get('BUILD_DIR') + 'lib/pkgconfig', targets) + ienv.Alias("install", i_n) def __append_target(ienv, name, targets = None): if targets: @@@ -316,8 -329,8 +329,8 @@@ if user_prefix '\@ROUTING_DEFINE\@': routing_define } else: - pc_vars = {'\@PREFIX\@': env.get('BUILD_DIR'), - '\@EXEC_PREFIX\@': env.get('BUILD_DIR'), + pc_vars = {'\@PREFIX\@': env.get('BUILD_DIR').encode('string_escape'), + '\@EXEC_PREFIX\@': env.get('BUILD_DIR').encode('string_escape'), '\@VERSION\@': '1.0.1', '\@LIB_INSTALL_DIR\@': user_lib, '\@ROUTING_DEFINE\@': routing_define @@@ -421,6 -434,52 +434,52 @@@ conf = Configure(env # POSIX_SUPPORTED, 1 if it is supported, 0 otherwise conf.CheckPThreadsSupport() + ###################################################################### + # Generate macros for presence of headers + ###################################################################### + cxx_headers = ['arpa/inet.h', + 'fcntl.h', + 'grp.h', + 'in6addr.h', + 'linux/limits.h', + 'memory.h', + 'netdb.h', + 'netinet/in.h', + 'pthread.h', + 'pwd.h', + 'stdlib.h', + 'string.h', + 'strings.h', + 'sys/socket.h', + 'sys/stat.h', + 'sys/time.h', + 'sys/timeb.h', + 'sys/types.h', + 'sys/unistd.h', + 'syslog.h', + 'time.h', + 'unistd.h', + 'uuid/uuid.h', + 'windows.h', + 'winsock2.h', + 'ws2tcpip.h'] + + if target_os == 'arduino': + # Detection of headers on the Arduino platform is currently broken. + cxx_headers = [] + + if target_os == 'msys_nt': + # WinPThread provides a pthread.h, but we want to use native threads. + cxx_headers.remove('pthread.h') + + def get_define_from_header_file(header_file): + header_file_converted = header_file.replace("/","_").replace(".","_").upper() + return "HAVE_" + header_file_converted + + for header_file_name in cxx_headers: + if conf.CheckCXXHeader(header_file_name): + conf.env.AppendUnique(CPPDEFINES = [get_define_from_header_file(header_file_name)]) + env = conf.Finish() ###################################################################### diff --combined resource/csdk/connectivity/common/src/camutex_pthreads.c index 6d866ad,aa77eb0..6c166b1 --- a/resource/csdk/connectivity/common/src/camutex_pthreads.c +++ b/resource/csdk/connectivity/common/src/camutex_pthreads.c @@@ -36,15 -36,29 +36,29 @@@ #define _POSIX_C_SOURCE 200809L #endif + #ifdef HAVE_STRING_H #include + #endif + #ifdef HAVE_PTHREAD_H #include - #include + #endif + #ifdef HAVE_UNISTD_H #include + #endif + #ifdef HAVE_TIME_H #include + #endif + #ifdef HAVE_SYS_TIME_H #include + #endif + #ifdef HAVE_WINSOCK2_H + #include + #endif + #include + #include #include #include - + #include "platform_features.h" #include "camutex.h" #include "logger.h" @@@ -76,13 -90,21 +90,21 @@@ static const uint64_t NANOSECS_PER_SE typedef struct _tagMutexInfo_t { + #if defined(_WIN32) + CRITICAL_SECTION mutex; + #else pthread_mutex_t mutex; + #endif } ca_mutex_internal; typedef struct _tagEventInfo_t { + #if defined(_WIN32) + CONDITION_VARIABLE cond; + #else pthread_cond_t cond; pthread_condattr_t condattr; + #endif } ca_cond_internal; ca_mutex ca_mutex_new(void) @@@ -91,6 -113,10 +113,10 @@@ ca_mutex_internal *mutexInfo = (ca_mutex_internal*) OICMalloc(sizeof(ca_mutex_internal)); if (NULL != mutexInfo) { + #if defined(_WIN32) + InitializeCriticalSection(&mutexInfo->mutex); + retVal = (ca_mutex)mutexInfo; + #else // create the mutex with the attributes set int ret=pthread_mutex_init(&(mutexInfo->mutex), PTHREAD_MUTEX_DEFAULT); if (0 == ret) @@@ -102,6 -128,11 +128,11 @@@ OIC_LOG_V(ERROR, TAG, "%s Failed to initialize mutex !", __func__); OICFree(mutexInfo); } + #endif + } + else + { + OIC_LOG_V(ERROR, TAG, "%s Failed to allocate mutex!", __func__); } return retVal; @@@ -114,6 -145,11 +145,11 @@@ bool ca_mutex_free(ca_mutex mutex ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex; if (mutexInfo) { + #if defined(_WIN32) + DeleteCriticalSection(&mutexInfo->mutex); + OICFree(mutexInfo); + bRet=true; + #else int ret = pthread_mutex_destroy(&mutexInfo->mutex); if (0 == ret) { @@@ -124,6 -160,7 +160,7 @@@ { OIC_LOG_V(ERROR, TAG, "%s Failed to free mutex !", __func__); } + #endif } else { @@@ -138,12 -175,16 +175,16 @@@ void ca_mutex_lock(ca_mutex mutex ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex; if (mutexInfo) { + #if defined(_WIN32) + EnterCriticalSection(&mutexInfo->mutex); + #else int ret = pthread_mutex_lock(&mutexInfo->mutex); if(ret != 0) { OIC_LOG_V(ERROR, TAG, "Pthread Mutex lock failed: %d", ret); exit(ret); } + #endif } else { @@@ -157,6 -198,9 +198,9 @@@ void ca_mutex_unlock(ca_mutex mutex ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex; if (mutexInfo) { + #if defined(_WIN32) + LeaveCriticalSection(&mutexInfo->mutex); + #else int ret = pthread_mutex_unlock(&mutexInfo->mutex); if(ret != 0) { @@@ -164,11 -208,12 +208,12 @@@ exit(ret); } (void)ret; + #endif } else { - OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex !", __func__); - return; + OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex !", __func__); + return; } } @@@ -178,6 -223,10 +223,10 @@@ ca_cond ca_cond_new(void ca_cond_internal *eventInfo = (ca_cond_internal*) OICMalloc(sizeof(ca_cond_internal)); if (NULL != eventInfo) { + #if defined(_WIN32) + InitializeConditionVariable(&eventInfo->cond); + retVal = (ca_cond) eventInfo; + #else int ret = pthread_condattr_init(&(eventInfo->condattr)); if(0 != ret) { @@@ -187,15 -236,14 +236,15 @@@ return retVal; } - #if defined(__ANDROID__) || _POSIX_TIMERS > 0 - #ifdef __ANDROID__ + #if defined(__ANDROID__) || _POSIX_TIMERS > 0 - #ifdef __ANDROID__ - if (camutex_condattr_setclock) { ++ #ifdef __ANDROID__ + if (camutex_condattr_setclock) + { ret = camutex_condattr_setclock(&(eventInfo->condattr), CLOCK_MONOTONIC); - #else - #else ++ #else { ret = pthread_condattr_setclock(&(eventInfo->condattr), CLOCK_MONOTONIC); - #endif /* __ANDROID__ */ - #endif /* __ANDROID__ */ ++ #endif /* __ANDROID__ */ if(0 != ret) { OIC_LOG_V(ERROR, TAG, "%s: Failed to set condition variable clock %d!", @@@ -205,7 -253,7 +254,7 @@@ return retVal; } } - #endif /* defined(__ANDROID__) || _POSIX_TIMERS > 0 */ + #endif /* defined(__ANDROID__) || _POSIX_TIMERS > 0 */ ret = pthread_cond_init(&(eventInfo->cond), &(eventInfo->condattr)); if (0 == ret) { @@@ -217,6 -265,11 +266,11 @@@ pthread_condattr_destroy(&(eventInfo->condattr)); OICFree(eventInfo); } + #endif + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: Failed to allocate condition variable!", __func__); } return retVal; @@@ -227,6 -280,9 +281,9 @@@ void ca_cond_free(ca_cond cond ca_cond_internal *eventInfo = (ca_cond_internal*) cond; if (eventInfo != NULL) { + #if defined(_WIN32) + OICFree(cond); + #else int ret = pthread_cond_destroy(&(eventInfo->cond)); int ret2 = pthread_condattr_destroy(&(eventInfo->condattr)); if (0 == ret && 0 == ret2) @@@ -238,6 -294,7 +295,7 @@@ OIC_LOG_V(ERROR, TAG, "%s: Failed to destroy condition variable %d, %d", __func__, ret, ret2); } + #endif } else { @@@ -250,11 -307,15 +308,15 @@@ void ca_cond_signal(ca_cond cond ca_cond_internal *eventInfo = (ca_cond_internal*) cond; if (eventInfo != NULL) { + #if defined(_WIN32) + WakeConditionVariable(&eventInfo->cond); + #else int ret = pthread_cond_signal(&(eventInfo->cond)); if (0 != ret) { OIC_LOG_V(ERROR, TAG, "%s: Failed to signal condition variable", __func__); } + #endif } else { @@@ -267,11 -328,15 +329,15 @@@ void ca_cond_broadcast(ca_cond cond ca_cond_internal* eventInfo = (ca_cond_internal*) cond; if (eventInfo != NULL) { + #if defined(_WIN32) + WakeAllConditionVariable(&eventInfo->cond); + #else int ret = pthread_cond_broadcast(&(eventInfo->cond)); if (0 != ret) { OIC_LOG_V(ERROR, TAG, "%s: failed to signal condition variable", __func__); } + #endif } else { @@@ -284,6 -349,14 +350,14 @@@ void ca_cond_wait(ca_cond cond, ca_mute ca_cond_wait_for(cond, mutex, 0L); } + #ifndef TIMEVAL_TO_TIMESPEC + #define TIMEVAL_TO_TIMESPEC(tv, ts) { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ + } + #endif + + #if !defined(_WIN32) struct timespec ca_get_current_time() { #if defined(__ANDROID__) || _POSIX_TIMERS > 0 @@@ -309,6 -382,7 +383,7 @@@ void ca_add_microseconds_to_timespec(st ts->tv_nsec = (totalNs)% NANOSECS_PER_SEC; ts->tv_sec += secPart + secOfNs; } + #endif CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseconds) { @@@ -331,12 -405,30 +406,31 @@@ if (microseconds > 0) { + #if defined(_WIN32) + // Wait for the given time + DWORD milli = (DWORD)(microseconds / 1000); + if (!SleepConditionVariableCS(&eventInfo->cond, &mutexInfo->mutex, milli)) + { + if (GetLastError() == ERROR_TIMEOUT) + { + retVal = CA_WAIT_TIMEDOUT; + } + else + { + OIC_LOG_V(ERROR, TAG, "SleepConditionVariableCS() with Timeout failed %i", GetLastError()); + retVal = CA_WAIT_INVAL; + } + }else + { + retVal = CA_WAIT_SUCCESS; + } + #else int ret; struct timespec abstime; #ifdef __ANDROID__ - if (camutex_cond_timedwait_relative) { + if (camutex_cond_timedwait_relative) + { abstime.tv_sec = microseconds / USECS_PER_SEC; abstime.tv_nsec = (microseconds % USECS_PER_SEC) * NANOSECS_PER_USECS; //Wait for the given time @@@ -369,14 -461,26 +463,26 @@@ retVal = CA_WAIT_INVAL; break; } + #endif } else { + #if defined(_WIN32) + // Wait forever + if (!SleepConditionVariableCS(&eventInfo->cond, &mutexInfo->mutex, INFINITE)) + { + OIC_LOG_V(ERROR, TAG, "SleepConditionVariableCS() w/o Timeout failed %i", GetLastError()); + retVal = CA_WAIT_INVAL; + }else + { + retVal = CA_WAIT_SUCCESS; + } + #else // Wait forever int ret = pthread_cond_wait(&eventInfo->cond, &mutexInfo->mutex); retVal = ret == 0 ? CA_WAIT_SUCCESS : CA_WAIT_INVAL; + #endif } - return retVal; } diff --combined resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c index 566a9f3,5163939..6ca39de --- a/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c +++ b/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c @@@ -25,7 -25,13 +25,13 @@@ #include "oic_string.h" #include "global.h" #include "timer.h" + #if defined(HAVE_WINSOCK2_H) && defined(HAVE_WS2TCPIP_H) + #include + #include + #endif + #ifdef HAVE_NETDB_H #include + #endif /* tinyDTLS library error code */ #define TINY_DTLS_ERROR (-1) @@@ -491,7 -497,7 +497,7 @@@ static int32_t CASendSecureData(dtls_co endpoint.flags = addrInfo->addr.st.ss_family == AF_INET ? CA_IPV4 : CA_IPV6; endpoint.flags |= CA_SECURE; endpoint.adapter = CA_ADAPTER_IP; - endpoint.interface = session->ifindex; + endpoint.ifindex = session->ifindex; int type = 0; //Mutex is not required for g_caDtlsContext. It will be called in same thread. @@@ -554,14 -560,14 +560,14 @@@ static int32_t CAHandleSecureEvent(dtls g_dtlsHandshakeCallback(&endpoint, &errorInfo); } } - else if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_CLOSE_NOTIFY == code) + else if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_HANDSHAKE_FAILURE == code) { - OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection"); + OIC_LOG(INFO, NET_DTLS_TAG, "Failed to DTLS handshake, the peer will be removed."); CARemovePeerFromPeerInfoList(peerAddr, port); } - else if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_HANDSHAKE_FAILURE == code) + else if(DTLS_ALERT_LEVEL_FATAL == level || DTLS_ALERT_CLOSE_NOTIFY == code) { - OIC_LOG(INFO, NET_DTLS_TAG, "Failed to DTLS handshake, the peer will be removed."); + OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection"); CARemovePeerFromPeerInfoList(peerAddr, port); } diff --combined resource/csdk/connectivity/src/caqueueingthread.c index 7516a12,5e62720..3e10065 --- a/resource/csdk/connectivity/src/caqueueingthread.c +++ b/resource/csdk/connectivity/src/caqueueingthread.c @@@ -21,8 -21,12 +21,12 @@@ #include #include #include + #ifdef HAVE_UNISTD_H #include + #endif + #ifdef HAVE_SYS_TYPES_H #include + #endif #include "caqueueingthread.h" #include "oic_malloc.h" @@@ -39,6 -43,7 +43,6 @@@ static void CAQueueingThreadBaseRoutine if (NULL == thread) { OIC_LOG(ERROR, TAG, "thread data passing error!!"); - return; } @@@ -123,30 -128,28 +127,30 @@@ CAResult_t CAQueueingThreadInitialize(C thread->isStop = true; thread->threadTask = task; thread->destroy = destroy; - if(NULL == thread->dataQueue || NULL == thread->threadMutex || NULL == thread->threadCond) + if (NULL == thread->dataQueue || NULL == thread->threadMutex || NULL == thread->threadCond) + { goto ERROR_MEM_FAILURE; + } return CA_STATUS_OK; - ERROR_MEM_FAILURE: - if(thread->dataQueue) + +ERROR_MEM_FAILURE: + if (thread->dataQueue) { u_queue_delete(thread->dataQueue); thread->dataQueue = NULL; } - if(thread->threadMutex) + if (thread->threadMutex) { ca_mutex_free(thread->threadMutex); thread->threadMutex = NULL; } - if(thread->threadCond) + if (thread->threadCond) { ca_cond_free(thread->threadCond); thread->threadCond = NULL; } return CA_MEMORY_ALLOC_FAILED; - } CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread) @@@ -248,7 -251,7 +252,7 @@@ CAResult_t CAQueueingThreadDestroy(CAQu u_queue_message_t *message = u_queue_get_element(thread->dataQueue); // free - if(NULL != message) + if (NULL != message) { if (NULL != thread->destroy) { diff --combined resource/csdk/connectivity/src/caretransmission.c index bf8d03c,5fa0ff3..52482b3 --- a/resource/csdk/connectivity/src/caretransmission.c +++ b/resource/csdk/connectivity/src/caretransmission.c @@@ -46,10 -46,19 +46,19 @@@ #include #ifndef SINGLE_THREAD + #ifdef HAVE_UNISTD_H #include - #include + #endif + #ifdef HAVE_SYS_TIME_H #include #endif + #if HAVE_SYS_TIMEB_H + #include + #endif + #ifdef HAVE_TIME_H + #include + #endif + #endif #if defined(__ANDROID__) #include @@@ -59,7 -68,6 +68,7 @@@ #include "caremotehandler.h" #include "caprotocolmessage.h" #include "oic_malloc.h" +#include "ocrandom.h" #include "logger.h" #define TAG "OIC_CA_RETRANS" @@@ -78,6 -86,7 +87,7 @@@ typedef struc } CARetransmissionData_t; static const uint64_t USECS_PER_SEC = 1000000; + static const uint64_t MSECS_PER_SEC = 1000; /** * @brief getCurrent monotonic time @@@ -95,11 -104,11 +105,11 @@@ uint64_t getCurrentTimeInMicroSeconds() */ static uint64_t CAGetTimeoutValue() { -#if !defined(_WIN32) - return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * (random() & 0xFF)) >> 8)) * +#ifdef HAVE_SRANDOM + return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * OCGetRandomByte()) >> 8)) * (uint64_t) 1000; #else - return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * (rand() & 0xFF)) >> 8)) * + return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * OCGetRandomByte()) >> 8)) * (uint64_t) 1000; #endif } @@@ -652,6 -661,10 +662,10 @@@ uint64_t getCurrentTimeInMicroSeconds( struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); currentTime = ts.tv_sec * USECS_PER_SEC + ts.tv_nsec / 1000; + #elif defined(_WIN32) + struct __timeb64 tb; + _ftime64_s(&tb); + currentTime = tb.time * USECS_PER_SEC + tb.millitm * MSECS_PER_SEC; #else struct timeval tv; gettimeofday(&tv, NULL); diff --combined resource/csdk/connectivity/src/ip_adapter/caipserver.c index 5f056a1,022d585..7e9d2cc --- a/resource/csdk/connectivity/src/ip_adapter/caipserver.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipserver.c @@@ -1,4 -1,4 +1,4 @@@ - /*****************************************************************j + /* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@@ -26,15 -26,30 +26,30 @@@ #endif #include + #if !defined(_WIN32) #include + #endif + + #if defined(_WIN32) + #include + #include + #include + #include + #include + #endif + #include + #if !defined(_MSC_VER) #include + #endif //!defined(_MSC_VER) #include #include + #if !defined(_WIN32) #include #include #include #include + #endif #include #ifdef __linux__ #include @@@ -50,6 -65,12 +65,12 @@@ #include "camutex.h" #include "oic_malloc.h" #include "oic_string.h" + #include "platform_features.h" + + #define USE_IP_MREQN + #if defined(_WIN32) + #undef USE_IP_MREQN + #endif /* * Logging tag for module name @@@ -96,62 -117,67 +117,67 @@@ static char *ipv6mcnames[IPv6_DOMAINS] NULL }; - static CAIPPacketReceivedCallback g_packetReceivedCallback = NULL; + #if defined (_WIN32) + #define IFF_UP_RUNNING_FLAGS (IFF_UP) + char* caips_get_error(){ + static char buffer[32]; + snprintf(buffer, 32, "%i", WSAGetLastError()); + return buffer; + } + #define CAIPS_GET_ERROR \ + caips_get_error() + #else + #define IFF_UP_RUNNING_FLAGS (IFF_UP|IFF_RUNNING) + + #define CAIPS_GET_ERROR \ + strerror(errno) + #endif static CAIPErrorHandleCallback g_ipErrorHandler = NULL; + static CAIPPacketReceivedCallback g_packetReceivedCallback = NULL; + static void CAFindReadyMessage(); + #if !defined(WSA_WAIT_EVENT_0) static void CASelectReturned(fd_set *readFds, int ret); + #else + static void CAEventReturned(CASocketFd_t socket); + #endif static void CAProcessNewInterface(CAInterface_t *ifchanged); - static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags); + static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags); - #define SET(TYPE, FDS) \ - if (caglobals.ip.TYPE.fd != -1) \ - { \ - FD_SET(caglobals.ip.TYPE.fd, FDS); \ - } + static void CAReceiveHandler(void *data) + { + (void)data; - #define ISSET(TYPE, FDS, FLAGS) \ - if (caglobals.ip.TYPE.fd != -1 && FD_ISSET(caglobals.ip.TYPE.fd, FDS)) \ - { \ - fd = caglobals.ip.TYPE.fd; \ - flags = FLAGS; \ + while (!caglobals.ip.terminate) + { + CAFindReadyMessage(); } + } + + #if !defined(WSA_WAIT_EVENT_0) #define CLOSE_SOCKET(TYPE) \ - if (caglobals.ip.TYPE.fd != -1) \ + if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) \ { \ close(caglobals.ip.TYPE.fd); \ - caglobals.ip.TYPE.fd = -1; \ + caglobals.ip.TYPE.fd = OC_INVALID_SOCKET; \ } - void CADeInitializeIPGlobals() - { - CLOSE_SOCKET(u6); - CLOSE_SOCKET(u6s); - CLOSE_SOCKET(u4); - CLOSE_SOCKET(u4s); - CLOSE_SOCKET(m6); - CLOSE_SOCKET(m6s); - CLOSE_SOCKET(m4); - CLOSE_SOCKET(m4s); - - if (caglobals.ip.netlinkFd != -1) - { - close(caglobals.ip.netlinkFd); - caglobals.ip.netlinkFd = -1; + #define SET(TYPE, FDS) \ + if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) \ + { \ + FD_SET(caglobals.ip.TYPE.fd, FDS); \ } - } - - static void CAReceiveHandler(void *data) - { - (void)data; - while (!caglobals.ip.terminate) - { - CAFindReadyMessage(); + #define ISSET(TYPE, FDS, FLAGS) \ + if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET && FD_ISSET(caglobals.ip.TYPE.fd, FDS)) \ + { \ + fd = caglobals.ip.TYPE.fd; \ + flags = FLAGS; \ } - } + static void CAFindReadyMessage() { @@@ -171,11 -197,12 +197,12 @@@ SET(m6s, &readFds) SET(m4, &readFds) SET(m4s, &readFds) + if (caglobals.ip.shutdownFds[0] != -1) { FD_SET(caglobals.ip.shutdownFds[0], &readFds); } - if (caglobals.ip.netlinkFd != -1) + if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET) { FD_SET(caglobals.ip.netlinkFd, &readFds); } @@@ -187,11 -214,12 +214,12 @@@ OIC_LOG_V(DEBUG, TAG, "Packet receiver Stop request received."); return; } + if (ret <= 0) { if (ret < 0) { - OIC_LOG_V(FATAL, TAG, "select error %s", strerror(errno)); + OIC_LOG_V(FATAL, TAG, "select error %s", CAIPS_GET_ERROR); } return; } @@@ -202,7 -230,7 +230,7 @@@ static void CASelectReturned(fd_set *readFds, int ret) { (void)ret; - int fd = -1; + CASocketFd_t fd = OC_INVALID_SOCKET; CATransportFlags_t flags = CA_DEFAULT_FLAGS; while (!caglobals.ip.terminate) @@@ -215,7 -243,7 +243,7 @@@ else ISSET(m6s, readFds, CA_MULTICAST | CA_IPV6 | CA_SECURE) else ISSET(m4, readFds, CA_MULTICAST | CA_IPV4) else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE) - else if (FD_ISSET(caglobals.ip.netlinkFd, readFds)) + else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds)) { CAInterface_t *ifchanged = CAFindInterfaceChange(); if (ifchanged) @@@ -239,22 -267,231 +267,231 @@@ { break; } - (void)CAReceiveMessage(fd, flags); FD_CLR(fd, readFds); } } - static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags) + #else // if defined(WSA_WAIT_EVENT_0) + + #define CLOSE_SOCKET(TYPE) \ + if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) \ + { \ + closesocket(caglobals.ip.TYPE.fd); \ + caglobals.ip.TYPE.fd = OC_INVALID_SOCKET; \ + } + + #define PUSH_HANDLE(HANDLE, ARRAY, INDEX) \ + { \ + ARRAY[INDEX] = HANDLE; \ + INDEX++; \ + } + + // Turn handle into WSAEvent and push to ARRAY + #define PUSH_SOCKET(SOCKET, ARRAY, INDEX) \ + if (SOCKET != OC_INVALID_SOCKET) \ + { \ + WSAEVENT NewEvent; \ + NewEvent = WSACreateEvent(); \ + if (WSA_INVALID_EVENT != NewEvent) \ + { \ + if (0 != WSAEventSelect(SOCKET, NewEvent, FD_READ)) \ + { \ + OIC_LOG_V(ERROR, TAG, "WSAEventSelect failed 0x%08x ", WSAGetLastError()); \ + if (!WSACloseEvent(NewEvent)) \ + { \ + OIC_LOG_V(ERROR, TAG, "WSACloseEvent(NewEvent) failed 0x%08x", WSAGetLastError()); \ + } \ + } \ + else \ + { \ + PUSH_HANDLE(NewEvent, ARRAY, INDEX); \ + } \ + } \ + else \ + { \ + OIC_LOG_V(ERROR, TAG, "WSACreateEvent(NewEvent) failed 0x%08x", WSAGetLastError()); \ + }\ + } + + #define INSERT_SOCKET(FD, ARRAY, INDEX) \ + { \ + if (OC_INVALID_SOCKET != FD) \ + { \ + ARRAY[INDEX] = FD; \ + } \ + } + + + // Inserts the socket into the SOCKET_ARRAY and pushes the socket event into EVENT_ARRAY + #define PUSH_IP_SOCKET(TYPE, EVENT_ARRAY, SOCKET_ARRAY, INDEX) \ + { \ + if (OC_INVALID_SOCKET != caglobals.ip.TYPE.fd) \ + { \ + INSERT_SOCKET(caglobals.ip.TYPE.fd, SOCKET_ARRAY, INDEX); \ + PUSH_SOCKET(caglobals.ip.TYPE.fd, EVENT_ARRAY, INDEX); \ + } \ + } + + #define IS_MATCHING_IP_SOCKET(TYPE, SOCKET, FLAGS) \ + if ((caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) && (caglobals.ip.TYPE.fd == SOCKET)) \ + { \ + fd = caglobals.ip.TYPE.fd; \ + flags = FLAGS; \ + } + + #define EVENT_ARRAY_SIZE 10 + + static void CAFindReadyMessage() + { + CASocketFd_t socketArray[EVENT_ARRAY_SIZE]; + HANDLE eventArray[EVENT_ARRAY_SIZE]; + int arraySize = 0; + int eventIndex; + + // socketArray and eventArray should have same number of elements + OC_STATIC_ASSERT(_countof(socketArray) == _countof(eventArray), "Arrays should have same number of elements"); + + PUSH_IP_SOCKET(u6, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(u6s, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(u4, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(u4s, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(m6, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(m6s, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(m4, eventArray, socketArray, arraySize); + PUSH_IP_SOCKET(m4s, eventArray, socketArray, arraySize); + + if (-1 != caglobals.ip.shutdownEvent) + { + INSERT_SOCKET(OC_INVALID_SOCKET, socketArray, arraySize); + PUSH_HANDLE(caglobals.ip.shutdownEvent, eventArray, arraySize); + } + + /** @todo Support netlink events */ + + // Should not have overflowed buffer + assert(arraySize <= (_countof(socketArray))); + + // Timeout is unnecessary on Windows + assert(-1 == caglobals.ip.selectTimeout); + + while (!caglobals.ip.terminate) + { + int ret = WSAWaitForMultipleEvents(arraySize, eventArray, FALSE, WSA_INFINITE, FALSE); + + switch (ret) + { + case WSA_WAIT_FAILED: + OIC_LOG_V(ERROR, TAG, "WSAWaitForMultipleEvents returned WSA_WAIT_FAILED 0x%08x", WSAGetLastError()); + break; + case WSA_WAIT_IO_COMPLETION: + OIC_LOG_V(ERROR, TAG, "WSAWaitForMultipleEvents returned WSA_WAIT_IO_COMPLETION 0x%08x", WSAGetLastError()); + break; + case WSA_WAIT_TIMEOUT: + OIC_LOG_V(ERROR, TAG, "WSAWaitForMultipleEvents returned WSA_WAIT_TIMEOUT 0x%08x", WSAGetLastError()); + break; + default: + eventIndex = ret - WSA_WAIT_EVENT_0; + if ((eventIndex >= 0) && (eventIndex < arraySize)) + { + if (false == WSAResetEvent(eventArray[eventIndex])) + { + OIC_LOG_V(ERROR, TAG, "WSAResetEvent failed 0x%08x", WSAGetLastError()); + } + + // Break out if shutdownEvent is triggered + if ((caglobals.ip.shutdownEvent != -1) && + (caglobals.ip.shutdownEvent == eventArray[eventIndex])) + { + break; + } + CAEventReturned(socketArray[eventIndex]); + } + else + { + OIC_LOG_V(ERROR, TAG, "WSAWaitForMultipleEvents failed 0x%08x", WSAGetLastError()); + } + break; + } + + } + + while (arraySize > 0) + { + arraySize--; + if (!WSACloseEvent(eventArray[arraySize])) + { + OIC_LOG_V(ERROR, TAG, "WSACloseEvent (Index %i) failed 0x%08x", arraySize, WSAGetLastError()); + } + } + + if (caglobals.ip.terminate) + { + caglobals.ip.shutdownEvent = -1; + WSACleanup(); + } + } + + static void CAEventReturned(CASocketFd_t socket) + { + CASocketFd_t fd = OC_INVALID_SOCKET; + CATransportFlags_t flags = CA_DEFAULT_FLAGS; + + while (!caglobals.ip.terminate) + { + IS_MATCHING_IP_SOCKET(u6, socket, CA_IPV6) + else IS_MATCHING_IP_SOCKET(u6s, socket, CA_IPV6 | CA_SECURE) + else IS_MATCHING_IP_SOCKET(u4, socket, CA_IPV4) + else IS_MATCHING_IP_SOCKET(u4s, socket, CA_IPV4 | CA_SECURE) + else IS_MATCHING_IP_SOCKET(m6, socket, CA_MULTICAST | CA_IPV6) + else IS_MATCHING_IP_SOCKET(m6s, socket, CA_MULTICAST | CA_IPV6 | CA_SECURE) + else IS_MATCHING_IP_SOCKET(m4, socket, CA_MULTICAST | CA_IPV4) + else IS_MATCHING_IP_SOCKET(m4s, socket, CA_MULTICAST | CA_IPV4 | CA_SECURE) + else + { + break; + } + (void)CAReceiveMessage(socket, flags); + // We will never get more than one match per socket, so always break. + break; + } + } + + #endif + + void CADeInitializeIPGlobals() + { + CLOSE_SOCKET(u6); + CLOSE_SOCKET(u6s); + CLOSE_SOCKET(u4); + CLOSE_SOCKET(u4s); + CLOSE_SOCKET(m6); + CLOSE_SOCKET(m6s); + CLOSE_SOCKET(m4); + CLOSE_SOCKET(m4s); + + if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET) + { + #ifdef _WIN32 + closesocket(caglobals.ip.netlinkFd); + #else + close(caglobals.ip.netlinkFd); + #endif + caglobals.ip.netlinkFd = OC_INVALID_SOCKET; + } + } + + static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags) { - char recvBuffer[COAP_MAX_PDU_SIZE]; + char recvBuffer[COAP_MAX_PDU_SIZE] = {0}; size_t len; int level, type, namelen; struct sockaddr_storage srcAddr; unsigned char *pktinfo = NULL; + #if !defined(WSA_CMSG_DATA) struct cmsghdr *cmp = NULL; - struct iovec iov = { recvBuffer, sizeof (recvBuffer) }; + struct iovec iov = { .iov_base = recvBuffer, .iov_len = sizeof (recvBuffer) }; union control { struct cmsghdr cmsg; @@@ -284,7 -521,7 +521,7 @@@ .msg_controllen = CMSG_SPACE(len) }; ssize_t recvLen = recvmsg(fd, &msg, flags); - if (-1 == recvLen) + if (OC_SOCKET_ERROR == recvLen) { OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno)); return CA_STATUS_FAILED; @@@ -300,14 -537,60 +537,60 @@@ } } } + #else // if defined(WSA_CMSG_DATA) + union control + { + WSACMSGHDR cmsg; + uint8_t data[WSA_CMSG_SPACE(sizeof (IN6_PKTINFO))]; + } cmsg; + memset(&cmsg, 0, sizeof(cmsg)); + + if (flags & CA_IPV6) + { + namelen = sizeof (struct sockaddr_in6); + level = IPPROTO_IPV6; + type = IPV6_PKTINFO; + } + else + { + namelen = sizeof (struct sockaddr_in); + level = IPPROTO_IP; + type = IP_PKTINFO; + } + WSABUF iov = {.len = sizeof (recvBuffer), .buf = recvBuffer}; + WSAMSG msg = {.name = &srcAddr, + .namelen = namelen, + .lpBuffers = &iov, + .dwBufferCount = 1, + .Control = {.buf = cmsg.data, .len = sizeof (cmsg)} + }; + + uint32_t recvLen = 0; + uint32_t ret = caglobals.ip.wsaRecvMsg(fd, &msg, &recvLen, 0,0); + OIC_LOG_V(DEBUG, TAG, "WSARecvMsg recvd %u bytes", recvLen); + if (OC_SOCKET_ERROR == ret) + { + OIC_LOG_V(ERROR, TAG, "WSARecvMsg failed %i", WSAGetLastError()); + } + + if (flags & CA_MULTICAST) + { + for (WSACMSGHDR *cmp = WSA_CMSG_FIRSTHDR(&msg); cmp != NULL; + cmp = WSA_CMSG_NXTHDR(&msg, cmp)) + { + if (cmp->cmsg_level == level && cmp->cmsg_type == type) + { + pktinfo = WSA_CMSG_DATA(cmp); + } + } + } + #endif // !defined(WSA_CMSG_DATA) CASecureEndpoint_t sep = {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = flags}}; if (flags & CA_IPV6) { - sep.endpoint.interface = ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id; - ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id = 0; - + /** @todo figure out correct usage for ifindex, and sin6_scope_id.*/ if ((flags & CA_MULTICAST) && pktinfo) { struct in6_addr *addr = &(((struct in6_pktinfo *)pktinfo)->ipi6_addr); @@@ -332,7 -615,7 +615,7 @@@ } } - CAConvertAddrToName(&srcAddr, msg.msg_namelen, sep.endpoint.addr, &sep.endpoint.port); + CAConvertAddrToName(&srcAddr, namelen, sep.endpoint.addr, &sep.endpoint.port); if (flags & CA_SECURE) { @@@ -352,6 -635,7 +635,7 @@@ } return CA_STATUS_OK; + } void CAIPPullData() @@@ -360,29 -644,28 +644,28 @@@ OIC_LOG(DEBUG, TAG, "OUT"); } - static int CACreateSocket(int family, uint16_t *port, bool isMulticast) + static CASocketFd_t CACreateSocket(int family, uint16_t *port, bool isMulticast) { int socktype = SOCK_DGRAM; #ifdef SOCK_CLOEXEC socktype |= SOCK_CLOEXEC; #endif - int fd = socket(family, socktype, IPPROTO_UDP); - if (-1 == fd) + CASocketFd_t fd = socket(family, socktype, IPPROTO_UDP); + if (OC_INVALID_SOCKET == fd) { - OIC_LOG_V(ERROR, TAG, "create socket failed: %s", strerror(errno)); - return -1; + OIC_LOG_V(ERROR, TAG, "create socket failed: %s", CAIPS_GET_ERROR); + return OC_INVALID_SOCKET; } - #ifndef SOCK_CLOEXEC + #if !defined(SOCK_CLOEXEC) && defined(FD_CLOEXEC) int fl = fcntl(fd, F_GETFD); if (-1 == fl || -1 == fcntl(fd, F_SETFD, fl|FD_CLOEXEC)) { OIC_LOG_V(ERROR, TAG, "set FD_CLOEXEC failed: %s", strerror(errno)); close(fd); - return -1; + return OC_INVALID_SOCKET; } #endif - struct sockaddr_storage sa = { .ss_family = family }; socklen_t socklen; @@@ -390,16 -673,20 +673,20 @@@ { int on = 1; - if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on))) + if (OC_SOCKET_ERROR == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, OPTVAL_T(&on), sizeof (on))) { - OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", CAIPS_GET_ERROR); } - if (isMulticast && *port) // only do this for multicast ports + if (isMulticast && *port) // only do this for multicast ports { - if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof (on))) + #if defined(IPV6_RECVPKTINFO) + if (OC_SOCKET_ERROR == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof (on))) + #else + if (OC_SOCKET_ERROR == setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, OPTVAL_T(&on), sizeof (on))) + #endif { - OIC_LOG_V(ERROR, TAG, "IPV6_RECVPKTINFO failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "IPV6_RECVPKTINFO failed: %s",CAIPS_GET_ERROR); } } @@@ -408,12 -695,12 +695,12 @@@ } else { - if (isMulticast && *port) // only do this for multicast ports + if (isMulticast && *port) // only do this for multicast ports { int on = 1; - if (-1 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &on, sizeof (on))) + if (OC_SOCKET_ERROR == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, OPTVAL_T(&on), sizeof (on))) { - OIC_LOG_V(ERROR, TAG, "IP_PKTINFO failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "IP_PKTINFO failed: %s", CAIPS_GET_ERROR); } } @@@ -421,31 -708,43 +708,43 @@@ socklen = sizeof (struct sockaddr_in); } - if (isMulticast && *port) // use the given port + if (isMulticast && *port) // use the given port { int on = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on))) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on), sizeof (on))) { - OIC_LOG_V(ERROR, TAG, "SO_REUSEADDR failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "SO_REUSEADDR failed: %s", CAIPS_GET_ERROR); + #ifdef _WIN32 + closesocket(fd); + #else close(fd); - return -1; + #endif + return OC_INVALID_SOCKET; } } - if (-1 == bind(fd, (struct sockaddr *)&sa, socklen)) + if (OC_SOCKET_ERROR == bind(fd, (struct sockaddr *)&sa, socklen)) { - OIC_LOG_V(ERROR, TAG, "bind socket failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "bind socket failed: %s", CAIPS_GET_ERROR); + #ifdef _WIN32 + closesocket(fd); + #else close(fd); - return -1; + #endif + return OC_INVALID_SOCKET; } - if (!*port) // return the assigned port + if (!*port) // return the assigned port { - if (-1 == getsockname(fd, (struct sockaddr *)&sa, &socklen)) + if (OC_SOCKET_ERROR == getsockname(fd, (struct sockaddr *)&sa, &socklen)) { - OIC_LOG_V(ERROR, TAG, "getsockname failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "getsockname failed: %s", CAIPS_GET_ERROR); + #ifdef _WIN32 + closesocket(fd); + #else close(fd); - return -1; + #endif + return OC_INVALID_SOCKET; } *port = ntohs(family == AF_INET6 ? ((struct sockaddr_in6 *)&sa)->sin6_port : @@@ -460,7 -759,7 +759,7 @@@ caglobals.ip.maxfd = FD; #define NEWSOCKET(FAMILY, NAME, MULTICAST) \ caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \ - if (caglobals.ip.NAME.fd == -1) \ + if (caglobals.ip.NAME.fd == OC_INVALID_SOCKET) \ { \ caglobals.ip.NAME.port = 0; \ caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \ @@@ -469,12 -768,13 +768,13 @@@ static void CAInitializeNetlink() { + caglobals.ip.netlinkFd = OC_INVALID_SOCKET; #ifdef __linux__ // create NETLINK fd for interface change notifications struct sockaddr_nl sa = { AF_NETLINK, 0, 0, RTMGRP_LINK }; caglobals.ip.netlinkFd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE); - if (caglobals.ip.netlinkFd == -1) + if (caglobals.ip.netlinkFd == OC_INVALID_SOCKET) { OIC_LOG_V(ERROR, TAG, "netlink socket failed: %s", strerror(errno)); } @@@ -485,7 -785,7 +785,7 @@@ { OIC_LOG_V(ERROR, TAG, "netlink bind failed: %s", strerror(errno)); close(caglobals.ip.netlinkFd); - caglobals.ip.netlinkFd = -1; + caglobals.ip.netlinkFd = OC_INVALID_SOCKET; } else { @@@ -495,13 -795,28 +795,28 @@@ #endif } - static void CAInitializePipe() + static void CAInitializeFastShutdownMechanism() { - caglobals.ip.selectTimeout = -1; - #ifdef HAVE_PIPE2 - int ret = pipe2(caglobals.ip.shutdownFds, O_CLOEXEC); + caglobals.ip.selectTimeout = -1; // don't poll for shutdown + int ret = -1; + #if defined(WSA_WAIT_EVENT_0) + caglobals.ip.shutdownEvent = -1; + caglobals.ip.shutdownEvent = WSACreateEvent(); + + if (caglobals.ip.shutdownEvent == WSA_INVALID_EVENT) + { + caglobals.ip.shutdownEvent = -1; + } + else + { + ret = 0; + } + #elif defined(HAVE_PIPE2) + ret = pipe2(caglobals.ip.shutdownFds, O_CLOEXEC); + CHECKFD(caglobals.ip.shutdownFds[0]); + CHECKFD(caglobals.ip.shutdownFds[1]); #else - int ret = pipe(caglobals.ip.shutdownFds); + ret = pipe(caglobals.ip.shutdownFds); if (-1 != ret) { ret = fcntl(caglobals.ip.shutdownFds[0], F_GETFD); @@@ -525,10 -840,12 +840,12 @@@ caglobals.ip.shutdownFds[1] = -1; } } + CHECKFD(caglobals.ip.shutdownFds[0]); + CHECKFD(caglobals.ip.shutdownFds[1]); #endif if (-1 == ret) { - OIC_LOG_V(ERROR, TAG, "pipe failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "fast shutdown mechanism init failed: %s", CAIPS_GET_ERROR); caglobals.ip.selectTimeout = SELECT_TIMEOUT; //poll needed for shutdown } } @@@ -541,7 -858,17 +858,17 @@@ CAResult_t CAIPStartServer(const ca_thr { return res; } - + #if defined (_WIN32) + WORD wVersionRequested = MAKEWORD(2, 2); + WSADATA wsaData ={.wVersion = 0}; + int err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) + { + OIC_LOG_V(ERROR, TAG, "WSAStartup failed: %i", err); + return CA_STATUS_FAILED; + } + OIC_LOG(DEBUG, TAG, "WSAStartup Succeeded"); + #endif if (!IPv4MulticastAddress.s_addr) { (void)inet_pton(AF_INET, IPv4_MULTICAST, &IPv4MulticastAddress); @@@ -587,10 -914,19 +914,19 @@@ caglobals.ip.u6.port, caglobals.ip.u6s.port, caglobals.ip.u4.port, caglobals.ip.u4s.port, caglobals.ip.m6.port, caglobals.ip.m6s.port, caglobals.ip.m4.port, caglobals.ip.m4s.port); - // create pipe for fast shutdown - CAInitializePipe(); - CHECKFD(caglobals.ip.shutdownFds[0]); - CHECKFD(caglobals.ip.shutdownFds[1]); + #if defined (SIO_GET_EXTENSION_FUNCTION_POINTER) + caglobals.ip.wsaRecvMsg = NULL; + GUID GuidWSARecvMsg = WSAID_WSARECVMSG; + DWORD copied = 0; + err = WSAIoctl(caglobals.ip.u4.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidWSARecvMsg, sizeof(GuidWSARecvMsg), &(caglobals.ip.wsaRecvMsg), sizeof(caglobals.ip.wsaRecvMsg), &copied, 0, 0); + if (0 != err) + { + OIC_LOG_V(ERROR, TAG, "WSAIoctl failed %i", WSAGetLastError()); + return CA_STATUS_FAILED; + } + #endif + // set up appropriate FD mechanism for fast shutdown + CAInitializeFastShutdownMechanism(); // create source of network interface change notifications CAInitializeNetlink(); @@@ -622,6 -958,7 +958,7 @@@ void CAIPStopServer( caglobals.ip.started = false; caglobals.ip.terminate = true; + #if !defined(WSA_WAIT_EVENT_0) if (caglobals.ip.shutdownFds[1] != -1) { close(caglobals.ip.shutdownFds[1]); @@@ -631,10 -968,18 +968,18 @@@ { // receive thread will stop in SELECT_TIMEOUT seconds. } + #else + // receive thread will stop immediately. + if (!WSASetEvent(caglobals.ip.shutdownEvent)) + { + OIC_LOG_V(DEBUG, TAG, "set shutdown event failed: %#08X", GetLastError()); + } + #endif } void CAWakeUpForChange() { + #if !defined(WSA_WAIT_EVENT_0) if (caglobals.ip.shutdownFds[1] != -1) { ssize_t len = 0; @@@ -647,68 -992,95 +992,95 @@@ OIC_LOG_V(DEBUG, TAG, "write failed: %s", strerror(errno)); } } + #else + if (!WSASetEvent(caglobals.ip.shutdownEvent)) + { + OIC_LOG_V(DEBUG, TAG, "set shutdown event failed: %#08X", GetLastError()); + } + #endif } - static void applyMulticastToInterface4(struct in_addr inaddr) + static void applyMulticastToInterface4(uint32_t ifindex) { if (!caglobals.ip.ipv4enabled) { return; } + #if defined(USE_IP_MREQN) struct ip_mreqn mreq = { .imr_multiaddr = IPv4MulticastAddress, - .imr_address = inaddr, - .imr_ifindex = 0 }; - if (setsockopt(caglobals.ip.m4.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq))) + .imr_address.s_addr = htonl(INADDR_ANY), + .imr_ifindex = ifindex }; + #else + struct ip_mreq mreq = { .imr_multiaddr = IPv4MulticastAddress, + .imr_interface.s_addr = htonl(ifindex) }; + #endif + + int ret = setsockopt(caglobals.ip.m4.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, OPTVAL_T(&mreq), sizeof (mreq)); + if (OC_SOCKET_ERROR == ret) { + #if !defined(WSAEINVAL) if (EADDRINUSE != errno) + #else + if (WSAEINVAL != WSAGetLastError()) // Joining multicast group more than once (IPv4 Flavor) + #endif { - OIC_LOG_V(ERROR, TAG, "IPv4 IP_ADD_MEMBERSHIP failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, " IPv4 IP_ADD_MEMBERSHIP failed: %s", CAIPS_GET_ERROR); } } - if (setsockopt(caglobals.ip.m4s.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq))) + ret = setsockopt(caglobals.ip.m4s.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, OPTVAL_T(&mreq), sizeof (mreq)); + if (OC_SOCKET_ERROR == ret) { + #if !defined(WSAEINVAL) if (EADDRINUSE != errno) + #else + if (WSAEINVAL != WSAGetLastError()) // Joining multicast group more than once (IPv4 Flavor) + #endif { - OIC_LOG_V(ERROR, TAG, "secure IPv4 IP_ADD_MEMBERSHIP failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "SECURE IPv4 IP_ADD_MEMBERSHIP failed: %s", CAIPS_GET_ERROR); } } } - static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t interface) + static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t ifindex) { - struct ipv6_mreq mreq = {.ipv6mr_multiaddr = *addr, .ipv6mr_interface = interface}; - - if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof (mreq))) + struct ipv6_mreq mreq = {.ipv6mr_multiaddr = *addr, + .ipv6mr_interface = ifindex }; + int ret = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, OPTVAL_T(&mreq), sizeof (mreq)); + if (OC_SOCKET_ERROR == ret) { - if (EADDRINUSE != errno) + #if !defined(_WIN32) + if (EADDRINUSE != errno) + #else + if (WSAEINVAL != WSAGetLastError()) // Joining multicast group more than once (IPv6 Flavor) + #endif { - OIC_LOG_V(ERROR, TAG, "IPv6 IP_ADD_MEMBERSHIP failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "IPv6 IPV6_JOIN_GROUP failed: %s", CAIPS_GET_ERROR); } } } - static void applyMulticastToInterface6(uint32_t interface) + static void applyMulticastToInterface6(uint32_t ifindex) { if (!caglobals.ip.ipv6enabled) { return; } - //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressInt, interface); - applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressLnk, interface); - //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressRlm, interface); - //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressAdm, interface); - //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressSit, interface); - //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressOrg, interface); - //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressGlb, interface); - - //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressInt, interface); - applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressLnk, interface); - //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressRlm, interface); - //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressAdm, interface); - //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressSit, interface); - //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressOrg, interface); - //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressGlb, interface); + //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressInt, ifindex); + applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressLnk, ifindex); + //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressRlm, ifindex); + //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressAdm, ifindex); + //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressSit, ifindex); + //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressOrg, ifindex); + //applyMulticast6(caglobals.ip.m6.fd, &IPv6MulticastAddressGlb, ifindex); + + //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressInt, ifindex); + applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressLnk, ifindex); + //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressRlm, ifindex); + //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressAdm, ifindex); + //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressSit, ifindex); + //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressOrg, ifindex); + //applyMulticast6(caglobals.ip.m6s.fd, &IPv6MulticastAddressGlb, ifindex); } CAResult_t CAIPStartListenServer() @@@ -716,7 -1088,7 +1088,7 @@@ u_arraylist_t *iflist = CAIPGetInterfaceInformation(0); if (!iflist) { - OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "CAIPGetInterfaceInformation() failed: %s", strerror(errno)); return CA_STATUS_FAILED; } @@@ -731,21 -1103,19 +1103,19 @@@ { continue; } - if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) + if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS) { continue; } if (ifitem->family == AF_INET) { - struct in_addr inaddr; - inaddr.s_addr = ifitem->ipv4addr; - applyMulticastToInterface4(inaddr); - OIC_LOG_V(DEBUG, TAG, "IPv4 network interface: %s", ifitem->name); + OIC_LOG_V(DEBUG, TAG, "Adding IPv4 interface %i to multicast group", ifitem->index); + applyMulticastToInterface4(ifitem->index); } if (ifitem->family == AF_INET6) { + OIC_LOG_V(DEBUG, TAG, "Adding IPv6 interface %i to multicast group", ifitem->index); applyMulticastToInterface6(ifitem->index); - OIC_LOG_V(DEBUG, TAG, "IPv6 network interface: %s", ifitem->name); } } @@@ -773,25 -1143,20 +1143,20 @@@ CAResult_t CAIPStopListenServer( { continue; } - - if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) + if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS) { continue; } if (ifitem->family == AF_INET) { - close(caglobals.ip.m4.fd); - close(caglobals.ip.m4s.fd); - caglobals.ip.m4.fd = -1; - caglobals.ip.m4s.fd = -1; + CLOSE_SOCKET(m4); + CLOSE_SOCKET(m4s); OIC_LOG_V(DEBUG, TAG, "IPv4 network interface: %s cloed", ifitem->name); } if (ifitem->family == AF_INET6) { - close(caglobals.ip.m6.fd); - close(caglobals.ip.m6s.fd); - caglobals.ip.m6.fd = -1; - caglobals.ip.m6s.fd = -1; + CLOSE_SOCKET(m6); + CLOSE_SOCKET(m6s); OIC_LOG_V(DEBUG, TAG, "IPv6 network interface: %s", ifitem->name); } } @@@ -806,14 -1171,14 +1171,14 @@@ static void CAProcessNewInterface(CAInt OIC_LOG(DEBUG, TAG, "ifitem is null"); return; } + if (ifitem->family == AF_INET6) { applyMulticastToInterface6(ifitem->index); } if (ifitem->family == AF_INET) { - struct in_addr inaddr = { .s_addr = ifitem->ipv4addr }; - applyMulticastToInterface4(inaddr); + applyMulticastToInterface4(ifitem->index); } } @@@ -844,31 -1209,28 +1209,28 @@@ static void sendData(int fd, const CAEn } char *secure = (endpoint->flags & CA_SECURE) ? "secure " : ""; - (void)secure; // eliminates release warning + + (void)cast; // eliminates release warning + (void)fam; + struct sockaddr_storage sock; CAConvertNameToAddr(endpoint->addr, endpoint->port, &sock); socklen_t socklen; if (sock.ss_family == AF_INET6) { - struct sockaddr_in6 *sock6 = (struct sockaddr_in6 *)&sock; - if (!sock6->sin6_scope_id) - { - sock6->sin6_scope_id = endpoint->interface; - } + /** @todo figure out correct usage for ifindex, and sin6_scope_id */ socklen = sizeof(struct sockaddr_in6); } else { socklen = sizeof(struct sockaddr_in); } - + #if !defined(_WIN32) ssize_t len = sendto(fd, data, dlen, 0, (struct sockaddr *)&sock, socklen); - if (-1 == len) + if (OC_SOCKET_ERROR == len) { // If logging is not defined/enabled. - (void)cast; - (void)fam; if (g_ipErrorHandler) { g_ipErrorHandler(endpoint, data, dlen, CA_SEND_FAILED); @@@ -879,6 -1241,45 +1241,45 @@@ { OIC_LOG_V(INFO, TAG, "%s%s %s sendTo is successful: %zd bytes", secure, cast, fam, len); } + #else + int err = 0; + int len = 0; + int sent = 0; + do { + len = sendto(fd, ((char*)data) + sent, dlen - sent, 0, (struct sockaddr *)&sock, socklen); + if (OC_SOCKET_ERROR == len) + { + err = WSAGetLastError(); + if ((WSAEWOULDBLOCK != err) && (WSAENOBUFS != err)) + { + // If logging is not defined/enabled. + if (g_ipErrorHandler) + { + g_ipErrorHandler(endpoint, data, dlen, CA_SEND_FAILED); + } + + OIC_LOG_V(ERROR, TAG, "%s%s %s sendTo failed: %i", secure, cast, fam, err); + } + } + else + { + sent += len; + if (sent != len) + { + OIC_LOG_V(DEBUG, TAG, "%s%s %s sendTo (Partial Send) is successful: " + "currently sent: %ld bytes, " + "total sent: %ld bytes, " + "remaining: %ld bytes", + secure, cast, fam, len, sent, dlen-sent); + } + else + { + OIC_LOG_V(INFO, TAG, "%s%s %s sendTo is successful: %ld bytes", + secure, cast, fam, len); + } + } + } while ((OC_SOCKET_ERROR == len) && ((WSAEWOULDBLOCK == err) || (WSAENOBUFS == err)) || (sent < dlen)); + #endif } static void sendMulticastData6(const u_arraylist_t *iflist, @@@ -909,7 -1310,7 +1310,7 @@@ { continue; } - if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) + if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS) { continue; } @@@ -919,9 -1320,9 +1320,9 @@@ } int index = ifitem->index; - if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index, sizeof (index))) + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, OPTVAL_T(&index), sizeof (index))) { - OIC_LOG_V(ERROR, TAG, "setsockopt6 failed: %s", strerror(errno)); + OIC_LOG_V(ERROR, TAG, "setsockopt6 failed: %s", CAIPS_GET_ERROR); return; } sendData(fd, endpoint, data, datalen, "multicast", "ipv6"); @@@ -934,8 -1335,15 +1335,15 @@@ static void sendMulticastData4(const u_ { VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL"); + #if defined(USE_IP_MREQN) struct ip_mreqn mreq = { .imr_multiaddr = IPv4MulticastAddress, - .imr_ifindex = 0 }; + .imr_address.s_addr = htonl(INADDR_ANY), + .imr_ifindex = 0}; + #else + struct ip_mreq mreq = { .imr_multiaddr = IPv4MulticastAddress, + .imr_interface = {0}}; + #endif + OICStrcpy(endpoint->addr, sizeof(endpoint->addr), IPv4_MULTICAST); int fd = caglobals.ip.u4.fd; @@@ -947,7 -1355,7 +1355,7 @@@ { continue; } - if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) + if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS) { continue; } @@@ -955,14 -1363,15 +1363,15 @@@ { continue; } - - struct in_addr inaddr; - inaddr.s_addr = ifitem->ipv4addr; - mreq.imr_address = inaddr; - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof (mreq))) + #if defined(USE_IP_MREQN) + mreq.imr_ifindex = ifitem->index; + #else + mreq.imr_interface.s_addr = htonl(ifitem->index); + #endif + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, OPTVAL_T(&mreq), sizeof (mreq))) { OIC_LOG_V(ERROR, TAG, "send IP_MULTICAST_IF failed: %s (using defualt)", - strerror(errno)); + CAIPS_GET_ERROR); } sendData(fd, endpoint, data, datalen, "multicast", "ipv4"); } @@@ -1005,7 -1414,7 +1414,7 @@@ void CAIPSendData(CAEndpoint_t *endpoin endpoint->port = isSecure ? CA_SECURE_COAP : CA_COAP; } - int fd; + CASocketFd_t fd; if (caglobals.ip.ipv6enabled && (endpoint->flags & CA_IPV6)) { fd = isSecure ? caglobals.ip.u6s.fd : caglobals.ip.u6.fd; @@@ -1062,7 -1471,7 +1471,7 @@@ CAResult_t CAGetIPInterfaceInformation( } eps[j].adapter = CA_ADAPTER_IP; - eps[j].interface = 0; + eps[j].ifindex = 0; if (ifitem->family == AF_INET6) { @@@ -1073,15 -1482,16 +1482,16 @@@ { eps[j].flags = CA_IPV4; eps[j].port = caglobals.ip.u4.port; - - inet_ntop(AF_INET, &(ifitem->ipv4addr), eps[j].addr, MAX_ADDR_STR_SIZE_CA); + /** @todo eps[j].addr not populated with IPv4 address string. + * it was using ifitem->ipv4addr to accomplish this. + * Need to understand what ipv4addr means to whom*/ } #ifdef __WITH_DTLS__ j++; eps[j].adapter = CA_ADAPTER_IP; - eps[j].interface = 0; + eps[j].ifindex = 0; if (ifitem->family == AF_INET6) { diff --combined resource/csdk/security/include/internal/srmresourcestrings.h index c304887,3ba9e62..7f63d92 --- a/resource/csdk/security/include/internal/srmresourcestrings.h +++ b/resource/csdk/security/include/internal/srmresourcestrings.h @@@ -23,8 -23,13 +23,12 @@@ #include "securevirtualresourcetypes.h" + #ifdef __cplusplus + extern "C" { + #endif + extern const char * SVR_DB_FILE_NAME; extern const char * SVR_DB_DAT_FILE_NAME; -extern const char * OIC_MI_DEF; //AMACL extern const char * OIC_RSRC_TYPE_SEC_AMACL; @@@ -165,5 -170,9 +169,9 @@@ extern char OIC_SEC_REST_QUERY_DELIMETE //Security Version extern const char * DEFAULT_SEC_VERSION; + #ifdef __cplusplus + } + #endif + #endif //IOTVT_SRM_RSRC_STRINGS_H diff --combined resource/csdk/security/include/securevirtualresourcetypes.h index d7d4888,0cc68a4..10c9e50 --- a/resource/csdk/security/include/securevirtualresourcetypes.h +++ b/resource/csdk/security/include/securevirtualresourcetypes.h @@@ -47,6 -47,8 +47,8 @@@ #include "byte_array.h" #endif /* __WITH_X509__ */ + #include "platform_features.h" + #ifdef __cplusplus extern "C" { #endif @@@ -139,7 -141,7 +141,7 @@@ typedef enu /** * Extract Reason Code from Access Response. */ - static inline SRMAccessResponseReasonCode_t GetReasonCode( + INLINE_API SRMAccessResponseReasonCode_t GetReasonCode( SRMAccessResponse_t response) { SRMAccessResponseReasonCode_t reason = @@@ -150,7 -152,7 +152,7 @@@ /** * Returns 'true' iff request should be passed on to RI layer. */ - static inline bool IsAccessGranted(SRMAccessResponse_t response) + INLINE_API bool IsAccessGranted(SRMAccessResponse_t response) { if(ACCESS_GRANTED == (response & ACCESS_GRANTED)) { @@@ -261,13 -263,6 +263,13 @@@ typedef enu OIC_OXM_COUNT }OicSecOxm_t; +typedef enum +{ + OIC_ENCODING_UNKNOW = 0, + OIC_ENCODING_RAW = 1, + OIC_ENCODING_BASE64 = 2 +}OicEncodingType_t; + typedef struct OicSecKey OicSecKey_t; typedef struct OicSecPstat OicSecPstat_t; @@@ -315,10 -310,6 +317,10 @@@ struct OicSecKe { uint8_t *data; size_t len; + + // TODO: This field added as workaround. Will be replaced soon. + OicEncodingType_t encoding; + }; /** @@@ -439,6 -430,9 +441,9 @@@ struct OicSecSac { // :::: //TODO fill in from OIC Security Spec + #if defined(_MSC_VER) + uint8_t unused; // VS doesn't like empty structs + #endif }; /** diff --combined resource/csdk/security/provisioning/SConscript index 8edc329,3588f1a..2fea369 --- a/resource/csdk/security/provisioning/SConscript +++ b/resource/csdk/security/provisioning/SConscript @@@ -33,13 -33,13 +33,13 @@@ provisioning_env.AppendUnique(CPPPATH '../../../c_common/ocrandom/include', '../../logger/include', '../../../oc_logger/include', - '../../ocmalloc/include', + '../../../c_common/oic_malloc/include', 'include', 'include/internal', 'include/oxm', '../../resource/csdk/security/include', '../../../../extlibs/cjson/', - '../../../../../extlibs/tinydtls/', + '../../../../extlibs/tinydtls/', '../../connectivity/inc', '../../connectivity/external/inc', '../../connectivity/common/inc', @@@ -57,17 -57,17 +57,17 @@@ target_os = env.get('TARGET_OS' if target_os != 'tizen': provisioning_env.AppendUnique(CPPPATH = ['../../../../extlibs/sqlite3']) - provisioning_env.AppendUnique(CFLAGS = ['-D__WITH_DTLS__']) - provisioning_env.AppendUnique(CFLAGS = ['-std=c99']) - if target_os not in ['windows', 'winrt']: - provisioning_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread', '-D__WITH_DTLS__']) + provisioning_env.AppendUnique(CPPDEFINES= ['__WITH_DTLS__']) + if target_os not in ['windows']: + provisioning_env.AppendUnique(CFLAGS = ['-std=c99']) + if target_os not in ['windows', 'msys_nt']: + provisioning_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread']) # Note: 'pthread' is in libc for android. On other platform, if use # new gcc(>4.9?) it isn't required, otherwise, it's required if target_os != 'android': provisioning_env.AppendUnique(LIBS = ['-lpthread', '-ldl']) - provisioning_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) provisioning_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap']) @@@ -76,9 -76,12 +76,12 @@@ provisioning_env.AppendUnique(LIBS = [' if env.get('DTLS_WITH_X509') == '1': provisioning_env.AppendUnique(LIBS = ['CKManager', 'asn1']) - if target_os != 'android': + if target_os not in ['msys_nt', 'windows', 'android']: provisioning_env.ParseConfig('pkg-config --libs glib-2.0') + if target_os in ['windows', 'msys_nt']: + provisioning_env.AppendUnique(LIBS = ['ws2_32', 'advapi32', 'iphlpapi', 'timer']) + if target_os == 'tizen': provisioning_env.ParseConfig('pkg-config --cflags --libs sqlite3') @@@ -108,14 -111,18 +111,18 @@@ provisioning_src = if target_os != 'tizen': provisioning_src = provisioning_src + [root_dir+'/extlibs/sqlite3/sqlite3.c' ] - provisioningserver = provisioning_env.SharedLibrary('ocpmapi', provisioning_src) + if target_os == 'windows': + # TODO: Add OC_EXPORT annotations and enable generation of Windows DLL + provisioningserver = provisioning_env.StaticLibrary('ocpmapi', provisioning_src) + else: + provisioningserver = provisioning_env.SharedLibrary('ocpmapi', provisioning_src) - provisioning_env.InstallTarget(provisioningserver, 'libocpmapi') - provisioning_env.UserInstallTargetLib(provisioningserver, 'libocpmapi') + provisioning_env.InstallTarget(provisioningserver, 'ocpmapi') + provisioning_env.UserInstallTargetLib(provisioningserver, 'ocpmapi') if env.get('DTLS_WITH_X509') == '1': SConscript('ck_manager/SConscript') - if target_os in ['linux']: + if target_os in ['linux', 'msys_nt', 'windows']: SConscript('sample/SConscript') diff --combined resource/csdk/security/provisioning/sample/provisioningclient.c index 3807ef8,e1c6d5a..19fd535 --- a/resource/csdk/security/provisioning/sample/provisioningclient.c +++ b/resource/csdk/security/provisioning/sample/provisioningclient.c @@@ -20,8 -20,11 +20,11 @@@ #include #include + #ifdef HAVE_UNISTD_H #include + #endif + #include "platform_features.h" #include "logger.h" #include "oic_malloc.h" #include "oic_string.h" @@@ -50,8 -53,6 +53,8 @@@ extern "C #define _34_CHECK_LINK_STATUS_ 34 #define _40_UNLINK_PAIR_DEVS_ 40 #define _50_REMOVE_SELEC_DEV_ 50 +#define _60_GET_CRED_ 60 +#define _61_GET_ACL_ 61 #define _99_EXIT_PRVN_CLT_ 99 #define ACL_RESRC_MAX_NUM 16 @@@ -151,34 -152,6 +154,34 @@@ static void provisionAclCB(void* ctx, i g_doneCB = true; } +static void getCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError) +{ + if(!hasError) + { + OIC_LOG_V(INFO, TAG, "getCredCB SUCCEEDED - ctx: %s", (char*) ctx); + } + else + { + OIC_LOG_V(ERROR, TAG, "getCredCB FAILED - ctx: %s", (char*) ctx); + printResultList((const OCProvisionResult_t*) arr, nOfRes); + } + g_doneCB = true; +} + +static void getAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError) +{ + if(!hasError) + { + OIC_LOG_V(INFO, TAG, "getAclCB SUCCEEDED - ctx: %s", (char*) ctx); + } + else + { + OIC_LOG_V(ERROR, TAG, "getAclCB FAILED - ctx: %s", (char*) ctx); + printResultList((const OCProvisionResult_t*) arr, nOfRes); + } + g_doneCB = true; +} + static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError) { if(!hasError) @@@ -807,125 -780,6 +810,125 @@@ CKLST_ERROR return -1; } +static int getCred(void) +{ + // check |own_list| for checking selected link status on PRVN DB + if(!g_own_list || 1>g_own_cnt) + { + printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n"); + printf(" > Please Register Unowned Devices first, with [20] Menu\n"); + return 0; // normal case + } + + // select device for checking selected link status on PRVN DB + int dev_num = 0; + for( ; ; ) + { + printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: "); + for(int ret=0; 1!=ret; ) + { + ret = scanf("%d", &dev_num); + for( ; 0x20<=getchar(); ); // for removing overflow garbages + // '0x20<=code' is character region + } + if(0=dev_num) + { + break; + } + printf(" Entered Wrong Number. Please Enter Again\n"); + } + + // call |getDevInst| API actually + // calling this API with callback actually acts like blocking + // for error checking, the return value saved and printed + g_doneCB = false; + OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num); + if(!dev) + { + OIC_LOG(ERROR, TAG, "getDevInst: device instance empty"); + goto PVACL_ERROR; + } + OCStackResult rst = OCGetCredResource((void*) g_ctx, dev, getCredCB); + if(OC_STACK_OK != rst) + { + OIC_LOG_V(ERROR, TAG, "OCGetCred API error: %d", rst); + goto PVACL_ERROR; + } + if(waitCallbackRet()) // input |g_doneCB| flag implicitly + { + OIC_LOG(ERROR, TAG, "OCGetCredResource callback error"); + goto PVACL_ERROR; + } + + // display the result of get credential + printf(" > Get Cred SUCCEEDED\n"); + + return 0; + +PVACL_ERROR: + return -1; +} + +static int getAcl(void) +{ + // check |own_list| for checking selected link status on PRVN DB + if(!g_own_list || 1>g_own_cnt) + { + printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n"); + printf(" > Please Register Unowned Devices first, with [20] Menu\n"); + return 0; // normal case + } + + // select device for checking selected link status on PRVN DB + int dev_num = 0; + for( ; ; ) + { + printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: "); + for(int ret=0; 1!=ret; ) + { + ret = scanf("%d", &dev_num); + for( ; 0x20<=getchar(); ); // for removing overflow garbages + // '0x20<=code' is character region + } + if(0=dev_num) + { + break; + } + printf(" Entered Wrong Number. Please Enter Again\n"); + } + + // call |getDevInst| API actually + // calling this API with callback actually acts like blocking + // for error checking, the return value saved and printed + g_doneCB = false; + OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num); + if(!dev) + { + OIC_LOG(ERROR, TAG, "getDevInst: device instance empty"); + goto PVACL_ERROR; + } + OCStackResult rst = OCGetACLResource((void*) g_ctx, dev, getAclCB); + if(OC_STACK_OK != rst) + { + OIC_LOG_V(ERROR, TAG, "OCGetACLResource API error: %d", rst); + + goto PVACL_ERROR; + } + if(waitCallbackRet()) // input |g_doneCB| flag implicitly + { + OIC_LOG(ERROR, TAG, "OCGetACLResource callback error"); + goto PVACL_ERROR; + } + + // display the result of get credential + printf(" > Get ACL SUCCEEDED\n"); + + return 0; + +PVACL_ERROR: + return -1; +} + static int unlinkPairwise(void) { // check |own_list| for unlinking pairwise devices @@@ -1361,7 -1215,7 +1364,7 @@@ static int waitCallbackRet(void static int selectTwoDiffNum(int* a, int* b, const int max, const char* str) { - if(!a || !b || 2>=max || !str) + if(!a || !b || 2>max || !str) { return -1; } @@@ -1424,10 -1278,6 +1427,10 @@@ static void printMenu(void printf("** [E] REMOVE THE SELECTED DEVICE\n"); printf("** 50. Remove the Selected Device\n\n"); + printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n"); + printf("** 60. Get the Credential resources of the Selected Device\n"); + printf("** 61. Get the ACL resources of the Selected Device\n\n"); + printf("** [F] EXIT PROVISIONING CLIENT\n"); printf("** 99. Exit Provisionong Client\n\n"); @@@ -1546,18 -1396,6 +1549,18 @@@ int main( OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error"); } break; + case _60_GET_CRED_: + if(getCred()) + { + OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error"); + } + break; + case _61_GET_ACL_: + if(getAcl()) + { + OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error"); + } + break; case _99_EXIT_PRVN_CLT_: goto PMCLT_ERROR; default: diff --combined resource/csdk/security/provisioning/src/ownershiptransfermanager.c index 0c2ff43,92b054f..68d8dc6 --- a/resource/csdk/security/provisioning/src/ownershiptransfermanager.c +++ b/resource/csdk/security/provisioning/src/ownershiptransfermanager.c @@@ -30,9 -30,15 +30,15 @@@ #define _POSIX_C_SOURCE 200809L #endif + #ifdef HAVE_TIME_H #include + #endif + #ifdef HAVE_UNISTD_H #include + #endif + #ifdef HAVE_SYS_TIME_H #include + #endif #include #include @@@ -419,28 -425,6 +425,28 @@@ static OCStackResult SaveOwnerPSK(OCPro &ownerKey, &ptDeviceID); VERIFY_NON_NULL(TAG, cred, ERROR); + // TODO: Added as workaround. Will be replaced soon. + cred->privateData.encoding = OIC_ENCODING_RAW; + +#if 1 + // NOTE: Test codes to use BASE64 encoded owner PSK. + uint32_t outSize = 0; + size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1)); + char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize); + VERIFY_NON_NULL(TAG, b64Buf, ERROR); + b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize); + + OICFree( cred->privateData.data ); + cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1); + VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); + + strncpy(cred->privateData.data, b64Buf, outSize); + cred->privateData.data[outSize] = '\0'; + cred->privateData.encoding = OIC_ENCODING_BASE64; + cred->privateData.len = outSize; + OICFree(b64Buf); +#endif //End of Test codes + res = AddCredential(cred); if(res != OC_STACK_OK) { @@@ -975,17 -959,15 +981,17 @@@ static OCStackResult PutOwnerCredential memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t)); //Fill private data as empty string - newCredential.privateData.data = NULL; + newCredential.privateData.data = ""; newCredential.privateData.len = 0; + newCredential.privateData.encoding = ownerCredential->privateData.encoding; #ifdef __WITH_X509__ newCredential.publicData.data = NULL; newCredential.publicData.len = 0; #endif - + int secureFlag = 0; //Send owner credential to new device : PUT /oic/sec/cred [ owner credential ] - if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData, &secPayload->payloadSize)) + if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData, + &secPayload->payloadSize, secureFlag)) { OICFree(secPayload); OIC_LOG(ERROR, TAG, "Error while converting bin to cbor."); diff --combined resource/csdk/security/provisioning/src/pmutility.c index 56bf9b2,618a36b..b72c28c --- a/resource/csdk/security/provisioning/src/pmutility.c +++ b/resource/csdk/security/provisioning/src/pmutility.c @@@ -21,14 -21,17 +21,17 @@@ #define _POSIX_C_SOURCE 200112L #endif + #if HAVE_UNISTD_H #include + #endif + #ifdef HAVE_STRING_H #include - #include - #include + #endif #include "ocstack.h" #include "oic_malloc.h" #include "oic_string.h" + #include "oic_time.h" #include "logger.h" #include "cJSON.h" #include "utlist.h" @@@ -341,31 -344,14 +344,14 @@@ exit */ OCStackResult PMTimeout(unsigned short waittime, bool waitForStackResponse) { - struct timespec startTime = {.tv_sec=0, .tv_nsec=0}; - struct timespec currTime = {.tv_sec=0, .tv_nsec=0}; - OCStackResult res = OC_STACK_OK; - #ifdef _POSIX_MONOTONIC_CLOCK - int clock_res = clock_gettime(CLOCK_MONOTONIC, &startTime); - #else - int clock_res = clock_gettime(CLOCK_REALTIME, &startTime); - #endif - if (0 != clock_res) - { - return OC_STACK_ERROR; - } + + uint64_t startTime = OICGetCurrentTime(TIME_IN_MS); while (OC_STACK_OK == res) { - #ifdef _POSIX_MONOTONIC_CLOCK - clock_res = clock_gettime(CLOCK_MONOTONIC, &currTime); - #else - clock_res = clock_gettime(CLOCK_REALTIME, &currTime); - #endif - if (0 != clock_res) - { - return OC_STACK_TIMEOUT; - } - long elapsed = (currTime.tv_sec - startTime.tv_sec); + uint64_t currTime = OICGetCurrentTime(TIME_IN_MS); + + long elapsed = (long)((currTime - startTime) / MS_PER_SEC); if (elapsed > waittime) { return OC_STACK_OK; @@@ -428,8 -414,8 +414,8 @@@ uint16_t GetSecurePortFromJSON(char* js } bool PMGenerateQuery(bool isSecure, - const char* address, const uint16_t port, - const OCConnectivityType connType, + const char* address, uint16_t port, + OCConnectivityType connType, char* buffer, size_t bufferSize, const char* uri) { if(!address || !buffer || !uri) @@@ -587,7 -573,7 +573,7 @@@ static OCStackApplicationResult SecureP // Use seure port of doxm for OTM and Provision. while (resPayload) { - if (0 == strncmp(resPayload->uri, OIC_RSRC_DOXM_URI, sizeof(OIC_RSRC_DOXM_URI))) + if (0 == strncmp(resPayload->uri, OIC_RSRC_DOXM_URI, strlen(OIC_RSRC_DOXM_URI))) { OIC_LOG_V(INFO,TAG,"resPaylod->uri:%s",resPayload->uri); OIC_LOG(INFO, TAG, "Found doxm resource."); @@@ -710,22 -696,6 +696,22 @@@ static OCStackApplicationResult DeviceD return OC_STACK_KEEP_TRANSACTION; } + res = GetDoxmDeviceID(&myId); + if(OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "Error while getting my UUID."); + DeleteDoxmBinData(ptrDoxm); + return OC_STACK_KEEP_TRANSACTION; + } + //if this is owned discovery and this is PT's reply, discard it + if((pDInfo->isOwnedDiscovery) && + (0 == memcmp(&ptrDoxm->deviceID.id, &myId.id, sizeof(myId.id))) ) + { + OIC_LOG(DEBUG, TAG, "discarding provision tool's reply"); + DeleteDoxmBinData(ptrDoxm); + return OC_STACK_KEEP_TRANSACTION; + } + res = AddDevice(ppDevicesList, clientResponse->devAddr.addr, clientResponse->devAddr.port, clientResponse->devAddr.adapter, diff --combined resource/csdk/security/provisioning/src/secureresourceprovider.c index 1a2a65a,f77bf05..e3f5bba --- a/resource/csdk/security/provisioning/src/secureresourceprovider.c +++ b/resource/csdk/security/provisioning/src/secureresourceprovider.c @@@ -20,7 -20,9 +20,9 @@@ #include #include #include + #ifdef HAVE_UNISTD_H #include + #endif #include "ocprovisioningmanager.h" #include "secureresourceprovider.h" @@@ -91,16 -93,6 +93,16 @@@ struct ACLDat int numOfResults; /**< Number of results in result array.**/ }; +// Structure to carry get security resource APIs data to callback. +typedef struct GetSecData GetSecData_t; +struct GetSecData { + void *ctx; + const OCProvisionDev_t *deviceInfo; /**< Pointer to PMDevInfo_t.**/ + OCProvisionResultCB resultCallback; /**< Pointer to result callback.**/ + OCProvisionResult_t *resArr; /**< Result array.**/ + int numOfResults; /**< Number of results in result array.**/ +}; + /** * Structure to carry PCONF provision API data to callback. */ @@@ -314,9 -306,7 +316,9 @@@ static OCStackResult provisionCredentia return OC_STACK_NO_MEMORY; } secPayload->base.type = PAYLOAD_TYPE_SECURITY; - OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData, &secPayload->payloadSize); + int secureFlag = 0; + OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData, + &secPayload->payloadSize, secureFlag); if((OC_STACK_OK != res) && (NULL == secPayload->securityData)) { OCPayloadDestroy((OCPayload *)secPayload); @@@ -553,9 -543,8 +555,9 @@@ static OCStackResult provisionCertCred( return OC_STACK_NO_MEMORY; } secPayload->base.type = PAYLOAD_TYPE_SECURITY; + int secureFlag = 0; OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData, - &secPayload->payloadSize); + &secPayload->payloadSize, secureFlag); if ((OC_STACK_OK != res) || (NULL == secPayload->securityData)) { @@@ -1722,245 -1711,3 +1724,245 @@@ error OIC_LOG(INFO, TAG, "OUT ERROR case SRPRemoveDevice"); return res; } + +/** + * Internal Function to store results in result array during GetCredResourceCB. + */ +static void registerResultForGetCredResourceCB(GetSecData_t *GetSecData, + OCStackResult stackresult) +{ + OIC_LOG_V(INFO, TAG, "Inside registerResultForGetCredResourceCB " + "GetSecData->numOfResults is %d\n", GetSecData->numOfResults); + memcpy(GetSecData->resArr[(GetSecData->numOfResults)].deviceId.id, + GetSecData->deviceInfo->doxm->deviceID.id, UUID_LENGTH); + GetSecData->resArr[(GetSecData->numOfResults)].res = stackresult; + ++(GetSecData->numOfResults); +} + +/** + * Callback handler of SRPGetCredResource. + * + * @param[in] ctx ctx value passed to callback from calling function. + * @param[in] UNUSED handle to an invocation + * @param[in] clientResponse Response from queries to remote servers. + * @return OC_STACK_DELETE_TRANSACTION to delete the transaction + * and OC_STACK_KEEP_TRANSACTION to keep it. + */ +static OCStackApplicationResult SRPGetCredResourceCB(void *ctx, OCDoHandle UNUSED, + OCClientResponse *clientResponse) +{ + OIC_LOG_V(INFO, TAG, "Inside SRPGetCredResourceCB."); + (void)UNUSED; + VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION); + GetSecData_t *GetSecData = (GetSecData_t*)ctx; + OCProvisionResultCB resultCallback = GetSecData->resultCallback; + + if (clientResponse) + { + if(OC_STACK_OK == clientResponse->result) + { + uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData; + size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize; + + OIC_LOG_BUFFER(DEBUG, TAG, payload, size); + + registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK); + ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults, + GetSecData->resArr, + false); + OICFree(GetSecData->resArr); + OICFree(GetSecData); + + return OC_STACK_DELETE_TRANSACTION; + } + } + registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK); + ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults, + GetSecData->resArr, + false); + OIC_LOG_V(ERROR, TAG, "SRPGetCredResourceCB received Null clientResponse"); + OICFree(GetSecData->resArr); + OICFree(GetSecData); + + return OC_STACK_DELETE_TRANSACTION; +} + + +OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo, + OCProvisionResultCB resultCallback) +{ + VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR, OC_STACK_INVALID_PARAM); + VERIFY_NON_NULL(TAG, resultCallback, ERROR, OC_STACK_INVALID_CALLBACK); + + char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0}; + if(!PMGenerateQuery(true, + selectedDeviceInfo->endpoint.addr, + selectedDeviceInfo->securePort, + selectedDeviceInfo->connType, + query, sizeof(query), OIC_RSRC_CRED_URI)) + { + OIC_LOG(ERROR, TAG, "SRPGetCredResource : Failed to generate query"); + return OC_STACK_ERROR; + } + OIC_LOG_V(DEBUG, TAG, "Query=%s", query); + + OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL}; + cbData.cb = &SRPGetCredResourceCB; + GetSecData_t* GetSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t)); + if (NULL == GetSecData) + { + OIC_LOG(ERROR, TAG, "Unable to allocate memory"); + return OC_STACK_NO_MEMORY; + } + GetSecData->deviceInfo = selectedDeviceInfo; + GetSecData->resultCallback = resultCallback; + GetSecData->numOfResults=0; + GetSecData->ctx = ctx; + + int noOfRiCalls = 1; + GetSecData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t)); + if (NULL == GetSecData->resArr) + { + OICFree(GetSecData); + OIC_LOG(ERROR, TAG, "Unable to allocate memory"); + return OC_STACK_NO_MEMORY; + } + cbData.context = (void *)GetSecData; + cbData.cd = NULL; + OCMethod method = OC_REST_GET; + OCDoHandle handle = NULL; + OIC_LOG(DEBUG, TAG, "Sending Get Cred to resource server"); + OCStackResult ret = OCDoResource(&handle, method, query, NULL, NULL, + selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0); + if (OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "OCStack resource error"); + OICFree(GetSecData->resArr); + OICFree(GetSecData); + } + VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR); + OIC_LOG(DEBUG, TAG, "OUT SRPGetCredResource"); + + return OC_STACK_OK; +} + +/** + * Internal Function to store results in result array during GetACLResourceCB. + */ +static void registerResultForGetACLResourceCB(GetSecData_t *GetSecData, + OCStackResult stackresult) +{ + OIC_LOG_V(INFO, TAG, "Inside registerResultForGetACLResourceCB " + "GetSecData->numOfResults is %d\n", GetSecData->numOfResults); + memcpy(GetSecData->resArr[(GetSecData->numOfResults)].deviceId.id, + GetSecData->deviceInfo->doxm->deviceID.id, UUID_LENGTH); + GetSecData->resArr[(GetSecData->numOfResults)].res = stackresult; + ++(GetSecData->numOfResults); +} + +/** + * Callback handler of SRPGetACLResource. + * + * @param[in] ctx ctx value passed to callback from calling function. + * @param[in] UNUSED handle to an invocation + * @param[in] clientResponse Response from queries to remote servers. + * @return OC_STACK_DELETE_TRANSACTION to delete the transaction + * and OC_STACK_KEEP_TRANSACTION to keep it. + */ +static OCStackApplicationResult SRPGetACLResourceCB(void *ctx, OCDoHandle UNUSED, + OCClientResponse *clientResponse) +{ + OIC_LOG_V(INFO, TAG, "Inside SRPGetACLResourceCB."); + (void)UNUSED; + VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION); + GetSecData_t *GetSecData = (GetSecData_t*)ctx; + OCProvisionResultCB resultCallback = GetSecData->resultCallback; + + if (clientResponse) + { + if(OC_STACK_OK == clientResponse->result) + { + uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData; + size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize; + + OIC_LOG_BUFFER(DEBUG, TAG, payload, size); + + registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK); + ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults, + GetSecData->resArr, + false); + OICFree(GetSecData->resArr); + OICFree(GetSecData); + + return OC_STACK_DELETE_TRANSACTION; + } + } + registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK); + ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults, + GetSecData->resArr, + false); + OIC_LOG_V(ERROR, TAG, "SRPGetACLResourceCB received Null clientResponse"); + OICFree(GetSecData->resArr); + OICFree(GetSecData); + + return OC_STACK_DELETE_TRANSACTION; +} + + +OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo, + OCProvisionResultCB resultCallback) +{ + VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR, OC_STACK_INVALID_PARAM); + VERIFY_NON_NULL(TAG, resultCallback, ERROR, OC_STACK_INVALID_CALLBACK); + + char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0}; + if(!PMGenerateQuery(true, + selectedDeviceInfo->endpoint.addr, + selectedDeviceInfo->securePort, + selectedDeviceInfo->connType, + query, sizeof(query), OIC_RSRC_ACL_URI)) + { + OIC_LOG(ERROR, TAG, "SRPGetACLResource : Failed to generate query"); + return OC_STACK_ERROR; + } + OIC_LOG_V(DEBUG, TAG, "Query=%s", query); + + OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL}; + cbData.cb = &SRPGetACLResourceCB; + GetSecData_t* GetSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t)); + if (NULL == GetSecData) + { + OIC_LOG(ERROR, TAG, "Unable to allocate memory"); + return OC_STACK_NO_MEMORY; + } + GetSecData->deviceInfo = selectedDeviceInfo; + GetSecData->resultCallback = resultCallback; + GetSecData->numOfResults=0; + GetSecData->ctx = ctx; + + int noOfRiCalls = 1; + GetSecData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t)); + if (NULL == GetSecData->resArr) + { + OICFree(GetSecData); + OIC_LOG(ERROR, TAG, "Unable to allocate memory"); + return OC_STACK_NO_MEMORY; + } + cbData.context = (void *)GetSecData; + cbData.cd = NULL; + OCMethod method = OC_REST_GET; + OCDoHandle handle = NULL; + OIC_LOG(DEBUG, TAG, "Sending Get ACL to resource server"); + OCStackResult ret = OCDoResource(&handle, method, query, NULL, NULL, + selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0); + if (OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "OCStack resource error"); + OICFree(GetSecData->resArr); + OICFree(GetSecData); + } + VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR); + OIC_LOG(DEBUG, TAG, "OUT SRPGetACLResource"); + + return OC_STACK_OK; +} diff --combined resource/csdk/security/provisioning/unittest/SConscript index 735f12c,c632e4c..7c36b06 --- a/resource/csdk/security/provisioning/unittest/SConscript +++ b/resource/csdk/security/provisioning/unittest/SConscript @@@ -25,6 -25,7 +25,7 @@@ import os.pat sptest_env = env.Clone() src_dir = sptest_env.get('SRC_DIR') + target_os = env.get('TARGET_OS') ###################################################################### # Build flags @@@ -67,6 -68,7 +68,7 @@@ sptest_env.PrependUnique(LIBS = [ 'oc 'gtest_main']) if env.get('SECURED') == '1': + sptest_env.AppendUnique(LIBS = ['timer']) sptest_env.AppendUnique(LIBS = ['tinydtls']) if env.get('DTLS_WITH_X509') == '1': sptest_env.AppendUnique(LIBS = ['CKManager']) @@@ -75,33 -77,43 +77,44 @@@ if not env.get('RELEASE'): sptest_env.AppendUnique(CPPDEFINES = ['TB_LOG']) + if target_os in ['msys_nt', 'windows']: + sptest_env.AppendUnique(LINKFLAGS = ['/subsystem:CONSOLE']) + sptest_env.AppendUnique(LIBS = ['ws2_32', + 'advapi32', + 'iphlpapi']) + ###################################################################### # Source files and Targets ###################################################################### - unittest = sptest_env.Program('unittest', ['pmutilitytest.cpp', - 'secureresourceprovider.cpp', - 'provisioningdatabasemanager.cpp', - 'ocprovisioningmanager.cpp', 'otmunittest.cpp', - 'credentialgeneratortest.cpp' ]) + unittest_src = ['pmutilitytest.cpp', + 'secureresourceprovider.cpp', + 'provisioningdatabasemanager.cpp', + 'ocprovisioningmanager.cpp', ++ 'credentialgeneratortest.cpp', + ] + + if target_os not in ['windows']: + unittest_src += [ 'otmunittest.cpp' ] - sample_server1 = sptest_env.Program('sample_server1', ['sampleserver1.cpp']) - sample_server2 = sptest_env.Program('sample_server2', ['sampleserver2.cpp']) + unittest = sptest_env.Program('unittest', unittest_src) - provisioning_unittest_src_dir = src_dir + '/resource/csdk/security/provisioning/unittest/' - provisioning_unittest_build_dir = env.get('BUILD_DIR') +'/resource/csdk/security/provisioning/unittest/' + if target_os not in ['windows']: + sample_server1 = sptest_env.Program('sample_server1', ['sampleserver1.cpp']) + sample_server2 = sptest_env.Program('sample_server2', ['sampleserver2.cpp']) + Alias("test", [sample_server1, sample_server2]) - Alias("test", [unittest, sample_server1, sample_server2]) + Alias("test", [unittest]) env.AppendTarget('test') if env.get('TEST') == '1': - target_os = env.get('TARGET_OS') - if target_os == 'linux': + if target_os in ['linux', 'windows']: out_dir = env.get('BUILD_DIR') result_dir = env.get('BUILD_DIR') + '/test_out/' if not os.path.isdir(result_dir): os.makedirs(result_dir) sptest_env.AppendENVPath('GTEST_OUTPUT', ['xml:'+ result_dir]) sptest_env.AppendENVPath('LD_LIBRARY_PATH', [out_dir]) + sptest_env.AppendENVPath('PATH', env.get('BUILD_DIR')) sptest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs']) ut = sptest_env.Command ('ut', None, out_dir + '/resource/csdk/security/provisioning/unittest/unittest') AlwaysBuild ('ut') diff --combined resource/csdk/security/src/aclresource.c index 6151ebe,8d57082..aaa96fb --- a/resource/csdk/security/src/aclresource.c +++ b/resource/csdk/security/src/aclresource.c @@@ -18,9 -18,9 +18,9 @@@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - #ifdef WITH_ARDUINO + #ifdef HAVE_STRING_H #include - #else + #elif HAVE_STRINGS_H #include #endif #include @@@ -422,7 -422,7 +422,7 @@@ OicSecAcl_t* CBORPayloadToAcl(const uin char* tagName = NULL; size_t len = 0; CborType type = cbor_value_get_type(&aclMap); - if (type == CborTextStringType) + if (type == CborTextStringType && cbor_value_is_text_string(&aclMap)) { cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map."); @@@ -444,7 -444,7 +444,7 @@@ char* acName = NULL; size_t acLen = 0; CborType acType = cbor_value_get_type(&aclistMap); - if (acType == CborTextStringType) + if (acType == CborTextStringType && cbor_value_is_text_string(&aclistMap)) { cborFindResult = cbor_value_dup_text_string(&aclistMap, &acName, &acLen, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACLIST Map."); @@@ -492,7 -492,7 +492,7 @@@ char* name = NULL; size_t len = 0; CborType type = cbor_value_get_type(&aclMap); - if (type == CborTextStringType) + if (type == CborTextStringType && cbor_value_is_text_string(&aclMap)) { cborFindResult = cbor_value_dup_text_string(&aclMap, &name, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map."); @@@ -502,7 -502,7 +502,7 @@@ if (name) { // Subject -- Mandatory - if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0) + if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0 && cbor_value_is_text_string(&aclMap)) { char *subject = NULL; cborFindResult = cbor_value_dup_text_string(&aclMap, &subject, &len, NULL); @@@ -539,7 -539,7 +539,7 @@@ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map"); - while(cbor_value_is_valid(&rMap)) + while(cbor_value_is_valid(&rMap) && cbor_value_is_text_string(&rMap)) { char *rMapName = NULL; size_t rMapNameLen = 0; @@@ -603,15 -603,12 +603,15 @@@ // Permissions -- Mandatory if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0) { - cborFindResult = cbor_value_get_uint64(&aclMap, (uint64_t *) &acl->permission); + uint64_t tmp64; + + cborFindResult = cbor_value_get_uint64(&aclMap, &tmp64); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value."); + acl->permission = tmp64; } // Period -- Not mandatory - if (strcmp(name, OIC_JSON_PERIOD_NAME) == 0) + if (strcmp(name, OIC_JSON_PERIOD_NAME) == 0 && cbor_value_is_array(&aclMap)) { CborValue period = { .parser = NULL }; cborFindResult = cbor_value_get_array_length(&aclMap, &acl->prdRecrLen); @@@ -621,7 -618,7 +621,7 @@@ acl->periods = (char**)OICCalloc(acl->prdRecrLen, sizeof(char*)); VERIFY_NON_NULL(TAG, acl->periods, ERROR); int i = 0; - while (cbor_value_is_text_string(&period)) + while (cbor_value_is_text_string(&period) && cbor_value_is_text_string(&period)) { cborFindResult = cbor_value_dup_text_string(&period, &acl->periods[i++], &len, NULL); @@@ -640,7 -637,7 +640,7 @@@ acl->recurrences = (char**)OICCalloc(acl->prdRecrLen, sizeof(char*)); VERIFY_NON_NULL(TAG, acl->recurrences, ERROR); int i = 0; - while (cbor_value_is_text_string(&recurrences)) + while (cbor_value_is_text_string(&recurrences) && cbor_value_is_text_string(&recurrences)) { cborFindResult = cbor_value_dup_text_string(&recurrences, &acl->recurrences[i++], &len, NULL); @@@ -681,7 -678,7 +681,7 @@@ } // TODO : Need to modify headAcl->owners[0].id to headAcl->rowner based on RAML spec. - if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0) + if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&aclMap)) { char *stRowner = NULL; cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL); @@@ -889,20 -886,20 +889,20 @@@ static OCEntityHandlerResult HandleACLG size_t size = 0; OCEntityHandlerResult ehRet; - // Process the REST querystring parameters - if (ehRequest->query) + OicUuid_t subject = {.id= { 0 } }; + + // In case, 'subject' field is included in REST request. + if (ehRequest->query && GetSubjectFromQueryString(ehRequest->query, &subject)) { + OIC_LOG(DEBUG,TAG,"'subject' field is inculded in REST request."); OIC_LOG(DEBUG, TAG, "HandleACLGetRequest processing query"); - OicUuid_t subject = {.id= { 0 } }; char resource[MAX_URI_LENGTH] = { 0 }; OicSecAcl_t *savePtr = NULL; const OicSecAcl_t *currentAce = NULL; // 'Subject' field is MUST for processing a querystring in REST request. - VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR); - GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource)); /* @@@ -944,10 -941,8 +944,10 @@@ } } } + // In case, 'subject' field is not included in REST request. else { + OIC_LOG(DEBUG,TAG,"'subject' field is not inculded in REST request."); // Convert ACL data into CBOR format for transmission. if (OC_STACK_OK != AclToCBORPayload(gAcl, &payload, &size)) { @@@ -1096,7 -1091,7 +1096,7 @@@ static OCStackResult CreateACLResource( ret = OCCreateResource(&gAclHandle, OIC_RSRC_TYPE_SEC_ACL, - OIC_MI_DEF, + OC_RSRVD_INTERFACE_DEFAULT, OIC_RSRC_ACL_URI, ACLEntityHandler, NULL, diff --combined resource/csdk/security/src/amsmgr.c index 0ce3e76,76c2c38..c208d3f --- a/resource/csdk/security/src/amsmgr.c +++ b/resource/csdk/security/src/amsmgr.c @@@ -56,7 -56,7 +56,7 @@@ OCStackResult DiscoverAmsService(PECont OCStackResult ret = OC_STACK_ERROR; const char DOXM_DEVICEID_QUERY_FMT[] = "%s?%s=%s"; - char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {}; + char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0}; OCCallbackData cbData = {.context=NULL}; VERIFY_NON_NULL(TAG, context, ERROR); @@@ -120,7 -120,7 +120,7 @@@ static OCStackApplicationResult AmsMgrD return OC_STACK_KEEP_TRANSACTION; } - OicUuid_t deviceId = {.id={}}; + OicUuid_t deviceId = {.id={0}}; memcpy(&deviceId, &doxm->deviceID, sizeof(deviceId)); OICFree(doxm); @@@ -151,7 -151,7 +151,7 @@@ OCStackResult SendUnicastSecurePortDisc const char RES_DOXM_QUERY_FMT[] = "%s?%s=%s"; OCCallbackData cbData = {.context=NULL}; - char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {}; + char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0}; snprintf(uri, sizeof(uri), RES_DOXM_QUERY_FMT, OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM); @@@ -226,9 -226,12 +226,9 @@@ OCStackResult SendAclReq(PEContext_t *c { OCStackResult ret = OC_STACK_ERROR; const char GET_ACE_QUERY_FMT[] = "%s?%s=%s;%s=%s"; - char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {}; - char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {0}; - uint32_t outLen = 0; + char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0}; OCCallbackData cbData = {.context=NULL}; OCDevAddr destAddr = {.adapter = OC_ADAPTER_IP}; - B64Result b64Ret; char *subID = NULL; VERIFY_NON_NULL(TAG, context, ERROR); @@@ -397,7 -400,7 +397,7 @@@ bool FoundAmaclForRequest(PEContext_t * void ProcessAMSRequest(PEContext_t *context) { - OicUuid_t emptyUuid = {.id={}}; + OicUuid_t emptyUuid = {.id={0}}; OIC_LOG_V(INFO, TAG, "Entering %s", __func__); if (NULL != context) { diff --combined resource/csdk/security/src/credresource.c index 1673b21,ad37dc9..4430793 --- a/resource/csdk/security/src/credresource.c +++ b/resource/csdk/security/src/credresource.c @@@ -21,9 -21,10 +21,10 @@@ #define __STDC_LIMIT_MACROS #include - #ifdef WITH_ARDUINO + #ifdef HAVE_STRING_H #include - #else + #endif + #ifdef HAVE_STRINGS_H #include #endif #include @@@ -124,7 -125,7 +125,7 @@@ static size_t OicSecCredCount(const Oic } OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload, - size_t *cborSize) + size_t *cborSize, int secureFlag) { if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize) { @@@ -180,7 -181,7 +181,7 @@@ mapSize++; } #endif /* __WITH_X509__ */ - if (cred->privateData.data) + if (!secureFlag && cred->privateData.data) { mapSize++; } @@@ -245,7 -246,7 +246,7 @@@ } #endif /*__WITH_X509__*/ //PrivateData -- Not Mandatory - if(cred->privateData.data) + if(!secureFlag && cred->privateData.data) { CborEncoder privateMap; const size_t privateMapSize = 2; @@@ -257,45 -258,20 +258,45 @@@ cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map"); - cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME, - strlen(OIC_JSON_DATA_NAME)); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag."); - cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data, - cred->privateData.len); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value."); - // TODO: Need to data strucure modification for OicSecKey_t. - cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME, - strlen(OIC_JSON_ENCODING_NAME)); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag."); - cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW, - strlen(OIC_SEC_ENCODING_RAW)); - VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value."); + // TODO: Added as workaround, will be replaced soon. + if(OIC_ENCODING_RAW == cred->privateData.encoding) + { + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME, + strlen(OIC_JSON_ENCODING_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag."); + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW, + strlen(OIC_SEC_ENCODING_RAW)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value."); + + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME, + strlen(OIC_JSON_DATA_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag."); + cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data, + cred->privateData.len); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value."); + } + else if(OIC_ENCODING_BASE64 == cred->privateData.encoding) + { + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME, + strlen(OIC_JSON_ENCODING_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag."); + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64, + strlen(OIC_SEC_ENCODING_BASE64)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value."); + + cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME, + strlen(OIC_JSON_DATA_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag."); + cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data), + cred->privateData.len); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value."); + } + else + { + OIC_LOG(ERROR, TAG, "Unknow encoding type for private data."); + VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value."); + } cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map."); @@@ -357,7 -333,7 +358,7 @@@ exit // Since the allocated initial memory failed, double the memory. cborLen += encoder.ptr - encoder.end; cborEncoderResult = CborNoError; - ret = CredToCBORPayload(credS, cborPayload, &cborLen); + ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag); *cborSize = cborLen; } @@@ -400,7 -376,7 +401,7 @@@ OCStackResult CBORPayloadToCred(const u char* tagName = NULL; size_t len = 0; CborType type = cbor_value_get_type(&CredRootMap); - if (type == CborTextStringType) + if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap)) { cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map."); @@@ -444,7 -420,7 +445,7 @@@ VERIFY_NON_NULL(TAG, cred, ERROR); - while(cbor_value_is_valid(&credMap)) + while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap)) { char* name = NULL; CborType type = cbor_value_get_type(&credMap); @@@ -460,10 -436,8 +461,10 @@@ //credid if (strcmp(name, OIC_JSON_CREDID_NAME) == 0) { - cborFindResult = cbor_value_get_uint64(&credMap, (uint64_t *) &cred->credId); + uint64_t credId = 0; + cborFindResult = cbor_value_get_uint64(&credMap, &credId); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId."); + cred->credId = (uint16_t)credId; } // subjectid if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0) @@@ -478,10 -452,8 +479,10 @@@ // credtype if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0) { - cborFindResult = cbor_value_get_uint64(&credMap, (uint64_t *) &cred->credType); + uint64_t credType = 0; + cborFindResult = cbor_value_get_uint64(&credMap, &credType); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType."); + cred->credType = (OicSecCredType_t)credType; } // privatedata if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0) @@@ -493,7 -465,7 +494,7 @@@ { char* privname = NULL; CborType type = cbor_value_get_type(&privateMap); - if (type == CborTextStringType) + if (type == CborTextStringType && cbor_value_is_text_string(&privateMap)) { cborFindResult = cbor_value_dup_text_string(&privateMap, &privname, &len, NULL); @@@ -506,48 -478,14 +507,48 @@@ // PrivateData::privdata -- Mandatory if (strcmp(privname, OIC_JSON_DATA_NAME) == 0) { - cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data, - &cred->privateData.len, NULL); + if(cbor_value_is_byte_string(&privateMap)) + { + cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data, + &cred->privateData.len, NULL); + } + else if(cbor_value_is_text_string(&privateMap)) + { + cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data), + &cred->privateData.len, NULL); + } + else + { + cborFindResult = CborErrorUnknownType; + OIC_LOG(ERROR, TAG, "Unknow type for private data."); + } VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData."); } + // PrivateData::encoding -- Mandatory if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0) { - // TODO: Need to update data structure, just ignore encoding value now. + // TODO: Added as workaround. Will be replaced soon. + char* strEncoding = NULL; + cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType"); + + if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0) + { + cred->privateData.encoding = OIC_ENCODING_RAW; + } + else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0) + { + cred->privateData.encoding = OIC_ENCODING_BASE64; + } + else + { + //For unit test + cred->privateData.encoding = OIC_ENCODING_RAW; + OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data."); + } + + OICFree(strEncoding); } } if (cbor_value_is_valid(&privateMap)) @@@ -569,7 -507,7 +570,7 @@@ { char* pubname = NULL; CborType type = cbor_value_get_type(&pubMap); - if (type == CborTextStringType) + if (type == CborTextStringType && cbor_value_is_text_string(&pubMap)) { cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname, &len, NULL); @@@ -580,7 -518,7 +581,7 @@@ if (pubname) { // PrivateData::privdata -- Mandatory - if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0) + if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap)) { cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data, &cred->publicData.len, NULL); @@@ -626,7 -564,7 +627,7 @@@ } //ROwner -- Mandatory - if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0) + if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap)) { char *stRowner = NULL; cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL); @@@ -697,28 -635,6 +698,28 @@@ OicSecCred_t * GenerateCredential(cons VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); memcpy(cred->privateData.data, privateData->data, privateData->len); cred->privateData.len = privateData->len; + + // TODO: Added as workaround. Will be replaced soon. + cred->privateData.encoding = OIC_ENCODING_RAW; + +#if 0 + // NOTE: Test codes to use base64 for credential. + uint32_t outSize = 0; + size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1)); + char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize); + VERIFY_NON_NULL(TAG, b64Buf, ERROR); + b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize); + + OICFree( cred->privateData.data ); + cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1); + VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR); + + strcpy(cred->privateData.data, b64Buf); + cred->privateData.encoding = OIC_ENCODING_BASE64; + cred->privateData.len = outSize; + OICFree(b64Buf); +#endif //End of Test codes + } VERIFY_NON_NULL(TAG, rownerID, ERROR); @@@ -743,8 -659,7 +744,8 @@@ static bool UpdatePersistentStorage(con { uint8_t *payload = NULL; size_t size = 0; - OCStackResult res = CredToCBORPayload(cred, &payload, &size); + int secureFlag = 0; + OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag); if ((OC_STACK_OK == res) && payload) { if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size)) @@@ -933,35 -848,10 +934,35 @@@ static bool FillPrivateDataOfOwnerPSK(O OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128); //Generate owner credential based on recevied credential information - receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128); - VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR); - receviedCred->privateData.len = OWNER_PSK_LENGTH_128; - memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128); + + // TODO: Added as workaround, will be replaced soon. + if(OIC_ENCODING_RAW == receviedCred->privateData.encoding) + { + receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128); + VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR); + receviedCred->privateData.len = OWNER_PSK_LENGTH_128; + memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128); + } + else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding) + { + uint32_t b64OutSize = 0; + size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1)); + char* b64Buf = OICCalloc(1, b64BufSize); + VERIFY_NON_NULL(TAG, b64Buf, ERROR); + + b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize); + + receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1); + VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR); + receviedCred->privateData.len = b64OutSize; + strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize); + receviedCred->privateData.data[b64OutSize] = '\0'; + } + else + { + // TODO: error + VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR); + } OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully"); @@@ -984,7 -874,6 +985,7 @@@ static OCEntityHandlerResult HandlePutR OicSecCred_t *cred = NULL; uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData); size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize); + OCStackResult res = CBORPayloadToCred(payload, size, &cred); if (res == OC_STACK_OK) { @@@ -1124,34 -1013,6 +1125,34 @@@ return ret; } +/** + * The entity handler determines how to process a GET request. + */ +static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest) +{ + OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request"); + + // Convert Cred data into CBOR for transmission + size_t size = 0; + uint8_t *payload = NULL; + int secureFlag = 1; + + const OicSecCred_t *cred = gCred; + OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag); + + // A device should always have a default cred. Therefore, payload should never be NULL. + OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR; + + // Send response payload to request originator + if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size)) + { + ehRet = OC_EH_ERROR; + OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatGetRequest"); + } + OICFree(payload); + return ehRet; +} + static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest) { OCEntityHandlerResult ret = OC_EH_ERROR; @@@ -1226,7 -1087,7 +1227,7 @@@ OCEntityHandlerResult CredEntityHandler switch (ehRequest->method) { case OC_REST_GET: - ret = OC_EH_FORBIDDEN; + ret = HandleGetRequest(ehRequest);; break; case OC_REST_PUT: ret = HandlePutRequest(ehRequest); @@@ -1254,11 -1115,11 +1255,11 @@@ OCStackResult CreateCredResource( { OCStackResult ret = OCCreateResource(&gCredHandle, OIC_RSRC_TYPE_SEC_CRED, - OIC_MI_DEF, + OC_RSRVD_INTERFACE_DEFAULT, OIC_RSRC_CRED_URI, CredEntityHandler, NULL, - OC_RES_PROP_NONE); + OC_SECURE); if (OC_STACK_OK != ret) { @@@ -1347,7 -1208,7 +1348,7 @@@ int32_t GetDtlsPskCredentials(CADtlsPsk case CA_DTLS_PSK_HINT: case CA_DTLS_PSK_IDENTITY: { - OicUuid_t deviceID = {.id={}}; + OicUuid_t deviceID = {.id={0}}; // Retrieve Device ID from doxm resource if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) ) { @@@ -1387,42 -1248,15 +1388,42 @@@ if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL)) { OIC_LOG (INFO, TAG, "Credentials are expired."); - ret = -1; return ret; } } // Copy PSK. - result_length = cred->privateData.len; - memcpy(result, cred->privateData.data, result_length); - return result_length; + // TODO: Added as workaround. Will be replaced soon. + if(OIC_ENCODING_RAW == cred->privateData.encoding) + { + result_length = cred->privateData.len; + memcpy(result, cred->privateData.data, result_length); + } + else if(OIC_ENCODING_BASE64 == cred->privateData.encoding) + { + size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1)); + uint8_t* outKey = OICCalloc(1, outBufSize); + uint32_t outKeySize; + if(NULL == outKey) + { + OIC_LOG (ERROR, TAG, "Failed to memoray allocation."); + return ret; + } + + if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize)) + { + memcpy(result, outKey, outKeySize); + ret = outKeySize; + } + else + { + OIC_LOG (ERROR, TAG, "Failed to base64 decoding."); + } + + OICFree(outKey); + } + + return ret; } } } @@@ -1431,6 -1265,7 +1432,6 @@@ default: { OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t."); - ret = -1; } break; } @@@ -1463,7 -1298,7 +1464,7 @@@ OCStackResult AddTmpPskWithPIN(const Oi } uint8_t privData[OWNER_PSK_LENGTH_128] = {0,}; - OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128}; + OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW}; OicSecCred_t* cred = NULL; int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id, UUID_LENGTH, PBKDF_ITERATIONS, @@@ -1574,7 -1409,6 +1575,7 @@@ OCStackResult SetCredRownerId(const Oic OCStackResult ret = OC_STACK_ERROR; uint8_t *cborPayload = NULL; size_t size = 0; + int secureFlag = 0; OicUuid_t prevId = {.id={0}}; if(NULL == newROwner) @@@ -1591,7 -1425,7 +1592,7 @@@ memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id)); memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id)); - ret = CredToCBORPayload(gCred, &cborPayload, &size); + ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag); VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size); diff --combined resource/csdk/security/src/dpairingresource.c index d5b059b,8fcb6b0..01eccd0 mode 100644,100755..100644 --- a/resource/csdk/security/src/dpairingresource.c +++ b/resource/csdk/security/src/dpairingresource.c @@@ -42,9 -42,7 +42,7 @@@ #include "ocpayload.h" #include "payload_logging.h" #include - #ifdef WITH_ARDUINO - #include - #else + #ifdef HAVE_STRINGS_H #include #endif @@@ -297,7 -295,7 +295,7 @@@ OCStackResult CBORPayloadToDpair(const dpair = (OicSecDpairing_t *)OICCalloc(1, sizeof(*dpair)); VERIFY_NON_NULL(TAG, dpair, ERROR); - while (cbor_value_is_valid(&dpairMap)) + while (cbor_value_is_valid(&dpairMap) && cbor_value_is_text_string(&dpairMap)) { char *name = NULL; size_t len = 0; @@@ -308,7 -306,7 +306,7 @@@ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a value in DPair map"); type = cbor_value_get_type(&dpairMap); - if (0 == strcmp(OIC_JSON_SPM_NAME, name)) + if (0 == strcmp(OIC_JSON_SPM_NAME, name) && cbor_value_is_integer(&dpairMap)) { cborFindResult = cbor_value_get_int(&dpairMap, (int *) &dpair->spm); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SPM Value"); @@@ -657,7 -655,7 +655,7 @@@ OCStackResult CreateDpairingResource( ret = OCCreateResource(&gDpairHandle, OIC_RSRC_TYPE_SEC_DPAIRING, - OIC_MI_DEF, + OC_RSRVD_INTERFACE_DEFAULT, OIC_RSRC_DPAIRING_URI, DpairingEntityHandler, NULL, diff --combined resource/csdk/security/src/pconfresource.c index 990b6a2,d2491c4..0026762 --- a/resource/csdk/security/src/pconfresource.c +++ b/resource/csdk/security/src/pconfresource.c @@@ -39,9 -39,7 +39,7 @@@ #include #include "psinterface.h" #include "security_internals.h" - #ifdef WITH_ARDUINO - #include - #else + #ifdef HAVE_STRINGS_H #include #endif @@@ -476,7 -474,7 +474,7 @@@ OCStackResult CBORPayloadToPconf(const char *name = NULL; size_t len = 0; CborType type = cbor_value_get_type(&pconfMap); - if (type == CborTextStringType) + if (type == CborTextStringType && cbor_value_is_text_string(&pconfMap)) { cborFindResult = cbor_value_dup_text_string(&pconfMap, &name, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value"); @@@ -487,7 -485,7 +485,7 @@@ if (name) { //EDP -- Mandatory - if(0 == strcmp(OIC_JSON_EDP_NAME, name)) + if(0 == strcmp(OIC_JSON_EDP_NAME, name) && cbor_value_is_boolean(&pconfMap)) { cborFindResult = cbor_value_get_boolean(&pconfMap, &pconf->edp); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value"); @@@ -505,7 -503,7 +503,7 @@@ cborFindResult = cbor_value_enter_container(&pconfMap, &prm); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to eneter array"); - while (cbor_value_is_valid(&prm)) + while (cbor_value_is_valid(&prm) && cbor_value_is_integer(&prm)) { cborFindResult = cbor_value_get_int(&prm, (int *)&pconf->prm[i++]); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value"); @@@ -514,7 -512,7 +512,7 @@@ } } //PIN -- Mandatory - if (0 == strcmp(OIC_JSON_PIN_NAME, name)) + if (0 == strcmp(OIC_JSON_PIN_NAME, name) && cbor_value_is_byte_string(&pconfMap)) { uint8_t *pin = NULL; cborFindResult = cbor_value_dup_byte_string(&pconfMap, &pin, &len, NULL); @@@ -546,7 -544,7 +544,7 @@@ char* name = NULL; size_t len = 0; CborType type = cbor_value_get_type(&pdAclMap); - if (type == CborTextStringType) + if (type == CborTextStringType && cbor_value_is_text_string(&pdAclMap)) { cborFindResult = cbor_value_dup_text_string(&pdAclMap, &name, &len, NULL); @@@ -557,7 -555,7 +555,7 @@@ if (name) { // Resources -- Mandatory - if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0) + if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0 && cbor_value_is_array(&pdAclMap)) { int i = 0; CborValue resources = { .parser = NULL }; @@@ -576,7 -574,7 +574,7 @@@ cborFindResult = cbor_value_enter_container(&resources, &rMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map"); - while(cbor_value_is_valid(&rMap)) + while(cbor_value_is_valid(&rMap) && cbor_value_is_text_string(&rMap)) { char *rMapName = NULL; size_t rMapNameLen = 0; @@@ -640,16 -638,15 +638,16 @@@ } // Permissions -- Mandatory - if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0) + if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0 && cbor_value_is_unsigned_integer(&pdAclMap)) { - cborFindResult = cbor_value_get_uint64(&pdAclMap, - (uint64_t *) &pdacl->permission); + uint64_t permission = 0; + cborFindResult = cbor_value_get_uint64(&pdAclMap, &permission); + pdacl->permission = (uint16_t)permission; VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value"); } // Period -- Not mandatory - if (strcmp(name, OIC_JSON_PERIODS_NAME) == 0) + if (strcmp(name, OIC_JSON_PERIODS_NAME) == 0 && cbor_value_is_array(&pdAclMap)) { int i = 0; CborValue period = { .parser = NULL }; @@@ -661,7 -658,7 +659,7 @@@ pdacl->periods = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*)); VERIFY_NON_NULL(TAG, pdacl->periods, ERROR); - while (cbor_value_is_text_string(&period)) + while (cbor_value_is_text_string(&period) && cbor_value_is_text_string(&period)) { cborFindResult = cbor_value_dup_text_string(&period, &pdacl->periods[i++], &len, NULL); @@@ -673,7 -670,7 +671,7 @@@ } // Recurrence -- Not mandatory - if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0) + if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0 && cbor_value_is_array(&pdAclMap)) { int i = 0; CborValue recurrences = { .parser = NULL }; @@@ -684,7 -681,7 +682,7 @@@ pdacl->recurrences = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*)); VERIFY_NON_NULL(TAG, pdacl->recurrences, ERROR); - while (cbor_value_is_text_string(&recurrences)) + while (cbor_value_is_text_string(&recurrences) && cbor_value_is_text_string(&recurrences)) { cborFindResult = cbor_value_dup_text_string(&recurrences, &pdacl->recurrences[i++], &len, NULL); @@@ -726,7 -723,7 +724,7 @@@ } //PDDev -- Mandatory - if (strcmp(name, OIC_JSON_PDDEV_LIST_NAME) == 0) + if (strcmp(name, OIC_JSON_PDDEV_LIST_NAME) == 0 && cbor_value_is_array(&pconfMap)) { int i = 0; CborValue pddevs = { .parser = NULL }; @@@ -737,7 -734,7 +735,7 @@@ pconf->pddevs = (OicUuid_t *)OICMalloc(pconf->pddevLen * sizeof(OicUuid_t)); VERIFY_NON_NULL(TAG, pconf->pddevs, ERROR); - while (cbor_value_is_valid(&pddevs)) + while (cbor_value_is_valid(&pddevs) && cbor_value_is_text_string(&pddevs)) { char *pddev = NULL; cborFindResult = cbor_value_dup_text_string(&pddevs, &pddev, &len, NULL); @@@ -751,7 -748,7 +749,7 @@@ } //Mandatory - Device Id - if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name)) + if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name) && cbor_value_is_text_string(&pconfMap)) { char *deviceId = NULL; cborFindResult = cbor_value_dup_text_string(&pconfMap, &deviceId, &len, NULL); @@@ -762,7 -759,7 +760,7 @@@ } // ROwner -- Mandatory - if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name)) + if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name) && cbor_value_is_text_string(&pconfMap)) { char *rowner = NULL; cborFindResult = cbor_value_dup_text_string(&pconfMap, &rowner, &len, NULL); @@@ -1011,7 -1008,7 +1009,7 @@@ OCStackResult CreatePconfResource( ret = OCCreateResource(&gPconfHandle, OIC_RSRC_TYPE_SEC_PCONF, - OIC_MI_DEF, + OC_RSRVD_INTERFACE_DEFAULT, OIC_RSRC_PCONF_URI, PconfEntityHandler, NULL, diff --combined resource/csdk/security/unittest/SConscript index 7fe87f3,4d04eba..9707000 --- a/resource/csdk/security/unittest/SConscript +++ b/resource/csdk/security/unittest/SConscript @@@ -25,24 -25,28 +25,25 @@@ import os.pat srmtest_env = env.Clone() src_dir = srmtest_env.get('SRC_DIR') + target_os = env.get('TARGET_OS') ###################################################################### # Build flags ###################################################################### srmtest_env.PrependUnique(CPPPATH = [ - '../../ocmalloc/include', + '../../../c_common/oic_malloc/include', '../../connectivity/inc', '../../connectivity/api', '../../connectivity/external/inc', '../../connectivity/lib/libcoap-4.1.1', - '../include', '../include/internal', '../../logger/include', - '../../ocmalloc/include', '../../stack/include', '../../stack/include/internal', '../../../oc_logger/include', '../../../../extlibs/gtest/gtest-1.7.0/include', '../../../../extlibs/cjson/', - '../provisioning/include', -# '../../../../extlibs/tinydtls/', + '../provisioning/include', '../include' ]) @@@ -59,11 -63,18 +60,18 @@@ srmtest_env.PrependUnique(LIBS = ['ocsr 'gtest_main']) if env.get('SECURED') == '1': - srmtest_env.AppendUnique(LIBS = ['tinydtls']) + srmtest_env.AppendUnique(LIBS = ['tinydtls', 'timer']) - if not env.get('RELEASE'): + if env.get('LOGGING') == '1': srmtest_env.AppendUnique(CPPDEFINES = ['TB_LOG']) + if target_os == 'windows': + srmtest_env.AppendUnique(LINKFLAGS = ['/subsystem:CONSOLE']) + srmtest_env.AppendUnique(LIBS = ['advapi32', 'kernel32', 'ws2_32', 'iphlpapi']) + else: + # TODO: Implement feature check. + srmtest_env.AppendUnique(CPPDEFINES = ['HAVE_LOCALTIME_R']) + ###################################################################### # Source files and Targets ###################################################################### @@@ -85,9 -96,9 +93,9 @@@ unittest = srmtest_env.Program('unittes Alias("test", [unittest]) unittest_src_dir = src_dir + '/resource/csdk/security/unittest/' - unittest_build_dir = env.get('BUILD_DIR') + 'resource/csdk/security/unittest' + unittest_build_dir = os.path.join(env.get('BUILD_DIR'), 'resource', 'csdk', 'security', 'unittest') + os.sep - srmtest_env.AppendUnique(CPPDEFINES = ['SECURITY_BUILD_UNITTEST_DIR='+unittest_build_dir]) + srmtest_env.AppendUnique(CPPDEFINES = ['SECURITY_BUILD_UNITTEST_DIR='+unittest_build_dir.encode('string_escape')]) srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir, unittest_src_dir + 'oic_unittest.json')) @@@ -108,13 -119,14 +116,14 @@@ srmtest_env.Alias("install", srmtest_en env.AppendTarget('test') if env.get('TEST') == '1': target_os = env.get('TARGET_OS') - if target_os == 'linux': + if target_os in ['linux', 'windows']: out_dir = env.get('BUILD_DIR') result_dir = env.get('BUILD_DIR') + '/test_out/' if not os.path.isdir(result_dir): os.makedirs(result_dir) srmtest_env.AppendENVPath('GTEST_OUTPUT', ['xml:'+ result_dir]) srmtest_env.AppendENVPath('LD_LIBRARY_PATH', [out_dir]) + srmtest_env.AppendENVPath('PATH', [os.path.join(out_dir, 'resource', 'csdk')]) srmtest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs']) ut = srmtest_env.Command ('ut', None, out_dir + '/resource/csdk/security/unittest/unittest') AlwaysBuild ('ut') diff --combined resource/csdk/stack/include/internal/ocstackinternal.h index 538c8b5,a985d67..678618c --- a/resource/csdk/stack/include/internal/ocstackinternal.h +++ b/resource/csdk/stack/include/internal/ocstackinternal.h @@@ -66,8 -66,8 +66,8 @@@ extern void* defaultDeviceHandlerCallba /** The coap scheme */ #define OC_COAP_SCHEME "coap://" -/** the first outgoing sequence number will be 5*/ -#define OC_OFFSET_SEQUENCE_NUMBER (4) +/** the first outgoing sequence number will be 2*/ +#define OC_OFFSET_SEQUENCE_NUMBER (1) /** * This structure will be created in occoap and passed up the stack on the server side. @@@ -289,9 -289,9 +289,9 @@@ OCStackResult OCChangeResourceProperty( OCResourceProperty resourceProperties, uint8_t enable); #endif - const char *convertTriggerEnumToString(OCPresenceTrigger trigger); + OC_EXPORT const char *convertTriggerEnumToString(OCPresenceTrigger trigger); - OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr); + OC_EXPORT OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr); void CopyEndpointToDevAddr(const CAEndpoint_t *in, OCDevAddr *out); diff --combined resource/csdk/stack/include/ocpayload.h index 0f472e1,88eba7b..d5c727e --- a/resource/csdk/stack/include/ocpayload.h +++ b/resource/csdk/stack/include/ocpayload.h @@@ -60,34 -60,33 +60,34 @@@ extern "C typedef struct OCResource OCResource; - void OCPayloadDestroy(OCPayload* payload); + OC_EXPORT void OCPayloadDestroy(OCPayload* payload); // Representation Payload - OCRepPayload* OCRepPayloadCreate(); + OC_EXPORT OCRepPayload* OCRepPayloadCreate(); - size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH]); + OC_EXPORT size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH]); - OCRepPayload* OCRepPayloadClone(const OCRepPayload* payload); + OC_EXPORT OCRepPayload* OCRepPayloadClone(const OCRepPayload* payload); - void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child); + OC_EXPORT void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child); - bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri); + OC_EXPORT bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri); - bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType); - bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface); - bool OCRepPayloadAddModelVersion(OCRepPayload* payload, const char* dmv); + OC_EXPORT bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType); + OC_EXPORT bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface); ++OC_EXPORT bool OCRepPayloadAddModelVersion(OCRepPayload* payload, const char* dmv); - bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType); - bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface); + OC_EXPORT bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType); + OC_EXPORT bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface); - bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name); - bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name); + OC_EXPORT bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name); + OC_EXPORT bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name); - bool OCRepPayloadSetPropInt(OCRepPayload* payload, const char* name, int64_t value); - bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value); + OC_EXPORT bool OCRepPayloadSetPropInt(OCRepPayload* payload, const char* name, int64_t value); + OC_EXPORT bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value); - bool OCRepPayloadSetPropDouble(OCRepPayload* payload, const char* name, double value); - bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value); + OC_EXPORT bool OCRepPayloadSetPropDouble(OCRepPayload* payload, const char* name, double value); + OC_EXPORT bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value); /** * This function allocates memory for the byte string and sets it in the payload. @@@ -98,7 -97,7 +98,7 @@@ * * @return true on success, false upon failure. */ - bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value); + OC_EXPORT bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value); /** * This function sets the byte string in the payload. @@@ -109,7 -108,7 +109,7 @@@ * * @return true on success, false upon failure. */ - bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value); /** @@@ -123,20 -122,19 +123,19 @@@ * * @return true on success, false upon failure. */ - bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, + OC_EXPORT 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); + OC_EXPORT bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value); + OC_EXPORT bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value); + OC_EXPORT bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value); - bool OCRepPayloadSetPropBool(OCRepPayload* payload, const char* name, bool value); - bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value); + OC_EXPORT bool OCRepPayloadSetPropBool(OCRepPayload* payload, const char* name, bool value); + OC_EXPORT bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value); - bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value); - bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, - OCRepPayload* value); - bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value); + OC_EXPORT bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value); + OC_EXPORT bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value); + OC_EXPORT 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. @@@ -148,7 -146,7 +147,7 @@@ * * @return true on success, false upon failure. */ - bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name, OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); /** @@@ -161,7 -159,7 +160,7 @@@ * * @return true on success, false upon failure. */ - bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name, const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); /** @@@ -177,104 -175,88 +176,104 @@@ * * @return true on success, false upon failure. */ - bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name, OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name, int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name, const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name, int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name, double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name, const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name, double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name, char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name, const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name, char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name, bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name, const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name, bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name, OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name, const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name, + OC_EXPORT bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name, OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); - void OCRepPayloadDestroy(OCRepPayload* payload); + OC_EXPORT void OCRepPayloadDestroy(OCRepPayload* payload); // Discovery Payload - OCDiscoveryPayload* OCDiscoveryPayloadCreate(); + OC_EXPORT OCDiscoveryPayload* OCDiscoveryPayloadCreate(); - OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size); - void OCSecurityPayloadDestroy(OCSecurityPayload* payload); + OC_EXPORT OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size); + OC_EXPORT void OCSecurityPayloadDestroy(OCSecurityPayload* payload); #ifndef TCP_ADAPTER - void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, - uint16_t securePort); + OC_EXPORT void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, + uint16_t securePort); #else - void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, - uint16_t securePort, uint16_t tcpPort); + OC_EXPORT void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, + uint16_t securePort, uint16_t tcpPort); #endif - void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res); - bool OCResourcePayloadAddStringLL(OCStringLL **payload, const char* type); + OC_EXPORT void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res); + OC_EXPORT bool OCResourcePayloadAddStringLL(OCStringLL **payload, const char* type); - size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload); - OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index); + OC_EXPORT size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload); + OC_EXPORT OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index); - void OCDiscoveryResourceDestroy(OCResourcePayload* payload); - void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload); + OC_EXPORT void OCDiscoveryResourceDestroy(OCResourcePayload* payload); + OC_EXPORT void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload); // Device Payload - OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname, + OC_EXPORT OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname, const OCStringLL *types, const char* specVer, const char* dmVer); - void OCDevicePayloadDestroy(OCDevicePayload* payload); + OC_EXPORT void OCDevicePayloadDestroy(OCDevicePayload* payload); // Platform Payload - OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo); - OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo); - void OCPlatformInfoDestroy(OCPlatformInfo *info); - void OCPlatformPayloadDestroy(OCPlatformPayload* payload); + OC_EXPORT OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo); + OC_EXPORT OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo); + OC_EXPORT void OCPlatformInfoDestroy(OCPlatformInfo *info); + OC_EXPORT void OCPlatformPayloadDestroy(OCPlatformPayload* payload); // Presence Payload - OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge, + OC_EXPORT OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge, OCPresenceTrigger trigger, const char* resourceType); - void OCPresencePayloadDestroy(OCPresencePayload* payload); + OC_EXPORT void OCPresencePayloadDestroy(OCPresencePayload* payload); // Helper API - OCStringLL* CloneOCStringLL (OCStringLL* ll); - void OCFreeOCStringLL(OCStringLL* ll); + OC_EXPORT OCStringLL* CloneOCStringLL (OCStringLL* ll); + OC_EXPORT void OCFreeOCStringLL(OCStringLL* ll); +/** + * This function creates a list from a string (with separated contents if several) + * @param text single string or CSV text fields + * @return newly allocated linked list + * @note separator is ',' (according to rfc4180, ';' is not valid) + **/ - OCStringLL* OCCreateOCStringLL(const char* text); ++OC_EXPORT OCStringLL* OCCreateOCStringLL(const char* text); + +/** + * This function creates a string from a list (with separated contents if several) + * @param ll Pointer to list + * @return newly allocated string + * @note separator is ',' (according to rfc4180) + **/ - char* OCCreateString(const OCStringLL* ll); ++OC_EXPORT char* OCCreateString(const OCStringLL* ll); + #ifdef __cplusplus } #endif diff --combined resource/csdk/stack/include/octypes.h index 3428b35,4a0eea3..42aa770 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@@ -281,8 -281,11 +281,11 @@@ extern "C" #ifdef RA_ADAPTER #define MAX_ADDR_STR_SIZE (256) #else - /** Max Address could be "coap+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:xxxxx" */ - #define MAX_ADDR_STR_SIZE (59) + /** Max Address could be + * "coap+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:yyy.yyy.yyy.yyy]:xxxxx" + * +1 for null terminator. + */ + #define MAX_ADDR_STR_SIZE (65) #endif /** Length of MAC address */ @@@ -477,7 -480,7 +480,7 @@@ typedef struc char addr[MAX_ADDR_STR_SIZE]; /** usually zero for default interface.*/ - uint32_t interface; + uint32_t ifindex; #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) char routeData[MAX_ADDR_STR_SIZE]; //destination GatewayID:ClientId #endif @@@ -849,21 -852,11 +852,21 @@@ typedef enu { OC_EH_OK = 0, OC_EH_ERROR, - OC_EH_RESOURCE_CREATED, - OC_EH_RESOURCE_DELETED, - OC_EH_SLOW, - OC_EH_FORBIDDEN, - OC_EH_RESOURCE_NOT_FOUND + OC_EH_RESOURCE_CREATED, // 2.01 + OC_EH_RESOURCE_DELETED, // 2.02 + OC_EH_SLOW, // 2.05 + OC_EH_FORBIDDEN, // 4.03 + OC_EH_RESOURCE_NOT_FOUND, // 4.04 + OC_EH_VALID, // 2.03 + OC_EH_CHANGED, // 2.04 + OC_EH_CONTENT, // 2.05 + OC_EH_BAD_REQ, // 4.00 + OC_EH_UNAUTHORIZED_REQ, // 4.01 + OC_EH_BAD_OPT, // 4.02 + OC_EH_METHOD_NOT_ALLOWED, // 4.05 + OC_EH_NOT_ACCEPTABLE, // 4.06 + OC_EH_INTERNAL_SERVER_ERROR, // 5.00 + OC_EH_RETRANSMIT_TIMEOUT // 5.04 } OCEntityHandlerResult; /** @@@ -959,8 -952,8 +962,8 @@@ typedef struc OCStringLL *types; /** Pointer to the device specification version.*/ char *specVersion; - /** Pointer to the device data model version.*/ - char *dataModleVersion; + /** Pointer to the device data model versions (in CSV format).*/ + OCStringLL *dataModelVersions; } OCDeviceInfo; #ifdef RA_ADAPTER @@@ -1208,10 -1201,10 +1211,10 @@@ typedef struc char *uri; /** Resource Type */ - char *type; + OCStringLL *type; /** Interface */ - OCStringLL *interface; + OCStringLL *iface; /** This structure holds the old /oic/res response. */ OCResourcePayload *resources; @@@ -1249,7 -1242,7 +1252,7 @@@ typedef struc char *sid; char* deviceName; char* specVersion; - char* dataModelVersion; + OCStringLL *dataModelVersions; OCStringLL *interfaces; OCStringLL *types; } OCDevicePayload; @@@ -1314,9 -1307,6 +1317,9 @@@ typedef struc /** Pointer to the array of the received vendor specific header options.*/ OCHeaderOption * rcvdVendorSpecificHeaderOptions; + /** Message id.*/ + uint16_t messageID; + /** the payload from the request PDU.*/ OCPayload *payload; diff --combined resource/csdk/stack/include/payload_logging.h index 14ca4b0,931e5f3..d04b9cd --- a/resource/csdk/stack/include/payload_logging.h +++ b/resource/csdk/stack/include/payload_logging.h @@@ -46,10 -46,10 +46,10 @@@ extern "C #ifdef TB_LOG #define OIC_LOG_PAYLOAD(level, payload) OCPayloadLog((level),(payload)) #define UUID_SIZE (16) - const char *convertTriggerEnumToString(OCPresenceTrigger trigger); - OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr); + OC_EXPORT const char *convertTriggerEnumToString(OCPresenceTrigger trigger); + OC_EXPORT OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr); - static inline void OCPayloadLogRep(LogLevel level, OCRepPayload* payload) + INLINE_API void OCPayloadLogRep(LogLevel level, OCRepPayload* payload) { OIC_LOG(level, (PL_TAG), "Payload Type: Representation"); OCRepPayload* rep = payload; @@@ -164,7 -164,7 +164,7 @@@ } - static inline void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payload) + INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payload) { OIC_LOG(level, PL_TAG, "Payload Type: Discovery"); int i = 1; @@@ -189,13 -189,10 +189,13 @@@ } if (payload->type) { - OIC_LOG_V(level, PL_TAG, "\tResource Type: %s", payload->type); + for (OCStringLL *strll = payload->type; strll; strll = strll->next) + { + OIC_LOG_V(level, PL_TAG, "\tResource Type: %s", strll->value); + } } OIC_LOG(level, PL_TAG, "\tInterface:"); - for (OCStringLL *itf = payload->interface; itf; itf = itf->next) + for (OCStringLL *itf = payload->iface; itf; itf = itf->next) { OIC_LOG_V(level, PL_TAG, "\t\t%s", itf->value); } @@@ -230,20 -227,13 +230,20 @@@ } } - static inline void OCPayloadLogDevice(LogLevel level, OCDevicePayload* payload) + INLINE_API void OCPayloadLogDevice(LogLevel level, OCDevicePayload* payload) { OIC_LOG(level, PL_TAG, "Payload Type: Device"); OIC_LOG_V(level, PL_TAG, "\tSID:%s", payload->sid); OIC_LOG_V(level, PL_TAG, "\tDevice Name:%s", payload->deviceName); OIC_LOG_V(level, PL_TAG, "\tSpec Version:%s", payload->specVersion); - OIC_LOG_V(level, PL_TAG, "\tData Model Version:%s", payload->dataModelVersion); + if (payload->dataModelVersions) + { + OIC_LOG(level, PL_TAG, "\tData Model Version:"); + for (OCStringLL *strll = payload->dataModelVersions; strll; strll = strll->next) + { + OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value); + } + } if (payload->types) { OIC_LOG(level, PL_TAG, "\tResource Type:"); @@@ -262,7 -252,7 +262,7 @@@ } } - static inline void OCPayloadLogPlatform(LogLevel level, OCPlatformPayload* payload) + INLINE_API void OCPayloadLogPlatform(LogLevel level, OCPlatformPayload* payload) { OIC_LOG(level, PL_TAG, "Payload Type: Platform"); OIC_LOG_V(level, PL_TAG, "\tURI:%s", payload->uri); @@@ -296,7 -286,7 +296,7 @@@ } } - static inline void OCPayloadLogPresence(LogLevel level, OCPresencePayload* payload) + INLINE_API void OCPayloadLogPresence(LogLevel level, OCPresencePayload* payload) { OIC_LOG(level, PL_TAG, "Payload Type: Presence"); OIC_LOG_V(level, PL_TAG, "\tSequence Number:%u", payload->sequenceNumber); @@@ -305,13 -295,13 +305,13 @@@ OIC_LOG_V(level, PL_TAG, "\tResource Type:%s", payload->resourceType); } - static inline void OCPayloadLogSecurity(LogLevel level, OCSecurityPayload* payload) + INLINE_API void OCPayloadLogSecurity(LogLevel level, OCSecurityPayload* payload) { OIC_LOG(level, PL_TAG, "Payload Type: Security"); OIC_LOG_V(level, PL_TAG, "\tSecurity Data: %s", payload->securityData); } - static inline void OCRDPayloadLog(const LogLevel level, const OCRDPayload *payload) + INLINE_API void OCRDPayloadLog(const LogLevel level, const OCRDPayload *payload) { if (!payload) { @@@ -334,7 -324,7 +334,7 @@@ } } - static inline void OCPayloadLog(LogLevel level, OCPayload* payload) + INLINE_API void OCPayloadLog(LogLevel level, OCPayload* payload) { if(!payload) { diff --combined resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp index 9a02020,13cf61b..970565a --- a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp @@@ -23,15 -23,24 +23,25 @@@ #include #include #include + #ifdef HAVE_UNISTD_H #include + #endif + #ifdef HAVE_WINDOWS_H + #include + #endif #include + #ifdef HAVE_PTHREAD_H #include + #endif #include +#include "oic_malloc.h" + #include #include "ocstack.h" #include "logger.h" #include "ocpayload.h" #include "ocserver.h" + #include "common.h" + #include "platform_features.h" //string length of "/a/light/" + std::numeric_limits::digits10 + '\0'" // 9 + 9 + 1 = 19 @@@ -76,7 -85,7 +86,7 @@@ const char *supportUrl = "mySupportUrl" const char *version = "myVersion"; const char *systemTime = "2015-05-15T11.04"; const char *specVersion = "myDeviceSpecVersion"; -const char* dataModleVersion = "myDeviceModleVersion"; +const char *dataModelVersions = "myDeviceModelVersions"; // Entity handler should check for resourceTypeName and ResourceInterface in order to GET // the existence of a known resource @@@ -665,8 -674,7 +675,7 @@@ void *ChangeLightRepresentation (void * OCStackResult result = OC_STACK_ERROR; uint8_t j = 0; - uint8_t numNotifies = (SAMPLE_MAX_NUM_OBSERVATIONS)/2; - OCObservationId obsNotify[numNotifies]; + OCObservationId obsNotify[(SAMPLE_MAX_NUM_OBSERVATIONS)/2]; while (!gQuitFlag) { @@@ -818,7 -826,7 +827,7 @@@ void DeleteDeviceInfo( { free (deviceInfo.deviceName); free (deviceInfo.specVersion); - free (deviceInfo.dataModleVersion); + OCFreeOCStringLL (deviceInfo.dataModelVersions); } bool DuplicateString(char** targetString, const char* sourceString) @@@ -922,7 -930,7 +931,7 @@@ OCStackResult SetPlatformInfo(const cha return OC_STACK_ERROR; } -OCStackResult SetDeviceInfo(const char* deviceName, const char* specVersion, const char* dataModleVersion) +OCStackResult SetDeviceInfo(const char* deviceName, const char* specVersion, const char* dataModelVersions) { if(!DuplicateString(&deviceInfo.deviceName, deviceName)) { @@@ -932,9 -940,7 +941,9 @@@ { return OC_STACK_ERROR; } - if(!DuplicateString(&deviceInfo.dataModleVersion, dataModleVersion)) + OCFreeOCStringLL(deviceInfo.dataModelVersions); + deviceInfo.dataModelVersions = OCCreateOCStringLL(dataModelVersions); + if (!deviceInfo.dataModelVersions) { return OC_STACK_ERROR; } @@@ -1058,7 -1064,7 +1067,7 @@@ int main(int argc, char* argv[] exit (EXIT_FAILURE); } - registrationResult = SetDeviceInfo(deviceName, specVersion, dataModleVersion); + registrationResult = SetDeviceInfo(deviceName, specVersion, dataModelVersions); if (registrationResult != OC_STACK_OK) { @@@ -1116,12 -1122,16 +1125,16 @@@ if (observeThreadStarted) { + #ifdef HAVE_PTHREAD_H pthread_cancel(threadId_observe); pthread_join(threadId_observe, NULL); + #endif } + #ifdef HAVE_PTHREAD_H pthread_cancel(threadId_presence); pthread_join(threadId_presence, NULL); + #endif OIC_LOG(INFO, TAG, "Exiting ocserver main loop..."); diff --combined resource/csdk/stack/samples/linux/secure/occlientbasicops.cpp index 5111cb4,91ba8cb..0fcee04 --- a/resource/csdk/stack/samples/linux/secure/occlientbasicops.cpp +++ b/resource/csdk/stack/samples/linux/secure/occlientbasicops.cpp @@@ -22,9 -22,20 +22,20 @@@ #include #include #include + #ifdef HAVE_UNISTD_H #include + #endif + #ifdef HAVE_WINDOWS_H + #include + /** @todo stop-gap for naming issue. Windows.h does not like us to use ERROR */ + #ifdef ERROR + #undef ERROR + #endif + #endif #include #include + #include + #include "platform_features.h" #include "ocstack.h" #include "logger.h" #include "occlientbasicops.h" @@@ -53,7 -64,6 +64,7 @@@ static OCConnectivityType ocConnType static char CRED_FILE_DEVOWNER[] = "oic_svr_db_client_devowner.dat"; static char CRED_FILE_NONDEVOWNER[] = "oic_svr_db_client_nondevowner.dat"; const char * OIC_RSRC_DOXM_URI = "/oic/sec/doxm"; +const char * OIC_RSRC_PSTAT_URI = "/oic/sec/pstat"; int gQuitFlag = 0; @@@ -92,8 -102,8 +103,8 @@@ static void PrintUsage( OIC_LOG(INFO, TAG, "-t 3 : Discover Resources and Initiate Confirmable Get/Put/Post Requests"); OIC_LOG(INFO, TAG, "-c 0 : Default auto-selection"); OIC_LOG(INFO, TAG, "-c 1 : IP Connectivity Type"); - OIC_LOG(INFO, TAG, "-d 0 : Client as Device Owner"); - OIC_LOG(INFO, TAG, "-d 1 : Client as Non Device Owner"); + OIC_LOG(INFO, TAG, "-d 0 : Client as Non Device Owner"); + OIC_LOG(INFO, TAG, "-d 1 : Client as Device Owner"); } OCStackResult InvokeOCDoResource(std::ostringstream &query, @@@ -424,12 -434,6 +435,12 @@@ int parseClientResponse(OCClientRespons res = res->next; continue; } + if (0 == strcmp(coapServerResource.c_str(),OIC_RSRC_PSTAT_URI)) + { + OIC_LOG(INFO,TAG,"Skip: pstat is secure virtual resource"); + res = res->next; + continue; + } if (res->secure) { OIC_LOG_V(INFO,TAG,"SECUREPORT: %d",res->port); diff --combined resource/csdk/stack/samples/tizen/build/packaging/com.oic.ri.spec index 5ec325e,09d3093..0af830f --- a/resource/csdk/stack/samples/tizen/build/packaging/com.oic.ri.spec +++ b/resource/csdk/stack/samples/tizen/build/packaging/com.oic.ri.spec @@@ -49,7 -49,7 +49,7 @@@ cp -f %{ROOTDIR}/resource/csdk/connecti cp -f %{ROOTDIR}/resource/csdk/connectivity/lib/libcoap-4.1.1/libcoap.a %{buildroot}/%{_libdir} cp /usr/lib/libuuid.so.1 %{buildroot}%{_libdir} if echo %{SECURED}|grep -qi '1'; then - cp -f %{ROOTDIR}/extlibs/tinydtls/libtinydtls.a %{buildroot}/%{_libdir} + cp -f %{ROOTDIR}/out/tizen/*/*/extlibs/tinydtls/libtinydtls.a %{buildroot}/%{_libdir} fi cp -rf %{ROOTDIR}/resource/csdk/stack/include/ocstack.h* %{DEST_INC_DIR}/ @@@ -66,7 -66,6 +66,7 @@@ cp resource/oc_logger/include/targets/o cp resource/csdk/stack/include/ocpresence.h %{DEST_INC_DIR} cp resource/csdk/stack/include/ocpayload.h %{DEST_INC_DIR} cp resource/c_common/platform_features.h %{DEST_INC_DIR} +cp resource/c_common/*/include/*.h %{DEST_INC_DIR} cp resource/csdk/stack/include/payload_logging.h %{DEST_INC_DIR} cp resource/csdk/stack/include/rdpayload.h %{DEST_INC_DIR} cp extlibs/tinycbor/tinycbor/src/cbor.h %{DEST_INC_DIR} diff --combined resource/csdk/stack/src/ocpayload.c index 09ec90f,8815d47..be9b080 --- a/resource/csdk/stack/src/ocpayload.c +++ b/resource/csdk/stack/src/ocpayload.c @@@ -18,10 -18,7 +18,10 @@@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// Required for strok_r +#define _POSIX_C_SOURCE 200112L +#include #include "ocpayload.h" #include "octypes.h" #include @@@ -33,7 -30,6 +33,7 @@@ #include "rdpayload.h" #define TAG "OIC_RI_PAYLOAD" +#define CSV_SEPARATOR ',' static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val); @@@ -428,14 -424,14 +428,14 @@@ bool OCRepPayloadAddResourceTypeAsOwner } } - bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface) + bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface) { - return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(interface)); + return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface)); } - bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface) + bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface) { - if (!payload || !interface) + if (!payload || !iface) { return false; } @@@ -453,7 -449,7 +453,7 @@@ { return false; } - cur->next->value = interface; + cur->next->value = iface; return true; } else @@@ -463,7 -459,7 +463,7 @@@ { return false; } - payload->interfaces->value = interface; + payload->interfaces->value = iface; return true; } } @@@ -753,7 -749,7 +753,7 @@@ bool OCRepPayloadSetByteStringArray(OCR { if (!array) { - return NULL; + return false; } size_t dimTotal = calcDimTotal(dimensions); @@@ -1285,84 -1281,6 +1285,84 @@@ OCStringLL* CloneOCStringLL (OCStringLL return headOfClone; } +OCStringLL* OCCreateOCStringLL(const char* text) +{ + char *token = NULL; + char *head = NULL; + char *tail = NULL; + char *backup = NULL; + OCStringLL* result = NULL; + OCStringLL* iter = NULL; + OCStringLL* prev = NULL; + static const char delim[] = { CSV_SEPARATOR, '\0' }; + + VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter"); + backup = OICStrdup(text); + VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory"); + + for (head = backup; ; head = NULL) + { + token = (char *) strtok_r(head, delim, &tail); + if (!token) break; + iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL)); + VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory"); + if (!result) + { + result = iter; + } + else + { + prev->next = iter; + } + iter->value = OICStrdup(token); + VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory"); + prev = iter; + iter = iter->next; + } + OICFree(backup); + return result; + +exit: + OICFree(backup); + OCFreeOCStringLL(result); + return NULL; +} + +char* OCCreateString(const OCStringLL* ll) +{ + char *str = NULL; + char *pos = NULL; + size_t len = 0; + size_t sublen = 0; + int count = 0; + + if (!ll) return NULL; + + for (const OCStringLL *it = ll; it ; it = it->next ) + { + len += strlen(it->value) + 1; + } + str = (char*) malloc(len + 1); + if (!str) + return NULL; + + pos = str; + for (const OCStringLL *it = ll; it ; it = it->next ) + { + sublen = strlen(it->value) + 1; + count = snprintf(pos, len + 1, "%s%c", it->value, CSV_SEPARATOR); + if (countsid); OICFree(payload->baseURI); OICFree(payload->uri); - OICFree(payload->type); + OCFreeOCStringLL(payload->type); OICFree(payload->name); - OCFreeOCStringLL(payload->interface); + OCFreeOCStringLL(payload->iface); OCDiscoveryResourceDestroy(payload->resources); OICFree(payload); } @@@ -1709,8 -1627,8 +1709,8 @@@ OCDevicePayload* OCDevicePayloadCreate( goto exit; } - payload->dataModelVersion = OICStrdup(dmVer); - if (dmVer && !payload->dataModelVersion) + payload->dataModelVersions = OCCreateOCStringLL(dmVer); + if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value)) { goto exit; } @@@ -1741,7 -1659,7 +1741,7 @@@ void OCDevicePayloadDestroy(OCDevicePay OICFree(payload->sid); OICFree(payload->deviceName); OICFree(payload->specVersion); - OICFree(payload->dataModelVersion); + OCFreeOCStringLL(payload->dataModelVersions); OCFreeOCStringLL(payload->types); OCFreeOCStringLL(payload->interfaces); OICFree(payload); diff --combined resource/csdk/stack/src/ocpayloadconvert.c index 033e837,9b791ea..890b527 --- a/resource/csdk/stack/src/ocpayloadconvert.c +++ b/resource/csdk/stack/src/ocpayloadconvert.c @@@ -38,9 -38,6 +38,9 @@@ // Discovery Links Map Length. #define LINKS_MAP_LEN 4 +// Default data model versions in CVS form +#define DEFAULT_DATA_MODEL_VERSIONS "res.1.1.0,sh.1.1.0" + // Functions all return either a CborError, or a negative version of the OC_STACK return values static int64_t OCConvertPayloadHelper(OCPayload *payload, uint8_t *outPayload, size_t *size); static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *outPayload, @@@ -68,7 -65,7 +68,7 @@@ OCStackResult OCConvertPayload(OCPayloa // TinyCbor Version 47a78569c0 or better on master is required for the re-allocation // strategy to work. If you receive the following assertion error, please do a git-pull // from the extlibs/tinycbor/tinycbor directory - #define CborNeedsUpdating (CborErrorOutOfMemory < CborErrorDataTooLarge) + #define CborNeedsUpdating (((unsigned int)CborErrorOutOfMemory) < ((unsigned int)CborErrorDataTooLarge)) OC_STATIC_ASSERT(!CborNeedsUpdating, "tinycbor needs to be updated to at least 47a78569c0"); #undef CborNeedsUpdating @@@ -232,7 -229,7 +232,7 @@@ static int64_t OCConvertDiscoveryPayloa [ // rootArray { // rootMap "di" : UUID, // device ID - "rt": "oic.wk.res" + "rt": ["oic.wk.res"] "n":"MyDevice" "if":"oic.if.ll oic.if.baseline" "di": "0685B960-736F-46F7-BEC0-9E6CBD61ADC1", @@@ -272,13 -269,14 +272,13 @@@ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting device id"); // Insert Resource Type - err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_RESOURCE_TYPE, - sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->type); + err |= OCStringLLJoin(&rootMap, OC_RSRVD_RESOURCE_TYPE, payload->type); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting RT"); // Insert interfaces - if (payload->interface) + if (payload->iface) { - err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->interface); + err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->iface); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types tag/value"); } @@@ -337,14 -335,15 +337,14 @@@ err |= cbor_encode_uint(&policyMap, resource->bitmap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap value to policy map"); - if (resource->secure) - { - err |= cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE, - sizeof(OC_RSRVD_SECURE) - 1); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure tag to policy map"); - err |= cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure value to policy map"); - } - if ((resource->secure && resource->port != 0) || payload->baseURI) + // Secure + err |= cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE, + sizeof(OC_RSRVD_SECURE) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure tag to policy map"); + err |= cbor_encode_boolean(&policyMap, resource->secure); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure value to policy map"); + + if (resource->secure || payload->baseURI) { err |= cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT, sizeof(OC_RSRVD_HOSTING_PORT) - 1); @@@ -392,7 -391,6 +392,7 @@@ static int64_t OCConvertDevicePayload(O } int64_t err = CborNoError; CborEncoder encoder; + char *dataModelVersions = 0; cbor_encoder_init(&encoder, outPayload, *size, 0); CborEncoder repMap; @@@ -428,20 -426,10 +428,20 @@@ sizeof(OC_RSRVD_SPEC_VERSION) - 1, payload->specVersion); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding data spec version"); - // Device data Model Version + // Device data Model Versions + if (payload->dataModelVersions) + { + OIC_LOG(INFO, TAG, "Payload has data model versions"); + dataModelVersions = OCCreateString(payload->dataModelVersions); + } + else + { + dataModelVersions = OICStrdup(DEFAULT_DATA_MODEL_VERSIONS); + } err |= ConditionalAddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION, - sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1, payload->dataModelVersion); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding data model version"); + sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1, dataModelVersions); + OICFree(dataModelVersions); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding data model versions"); err |= cbor_encoder_close_container(&encoder, &repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing device map"); diff --combined resource/csdk/stack/src/ocpayloadparse.c index a103059,dfd1ec7..ef9dc8a mode 100644,100755..100644 --- a/resource/csdk/stack/src/ocpayloadparse.c +++ b/resource/csdk/stack/src/ocpayloadparse.c @@@ -35,6 -35,7 +35,7 @@@ #include "ocstackinternal.h" #include "payload_logging.h" #include "rdpayload.h" + #include "platform_features.h" #define TAG "OIC_RI_PAYLOADPARSE" @@@ -248,7 -249,7 +249,7 @@@ static OCStackResult OCParseDiscoveryPa err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal); if (cbor_value_is_valid(&curVal)) { - err = cbor_value_dup_text_string(&curVal, &(out->type), &len, NULL); + err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &out->type); VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value"); } @@@ -256,11 -257,11 +257,11 @@@ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal); if (cbor_value_is_valid(&curVal)) { - err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &out->interface); + err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &out->iface); } - if (!out->interface) + if (!out->iface) { - if (!OCResourcePayloadAddStringLL(&out->interface, OC_RSRVD_INTERFACE_LL)) + if (!OCResourcePayloadAddStringLL(&out->iface, OC_RSRVD_INTERFACE_LL)) { err = CborErrorOutOfMemory; } @@@ -444,17 -445,13 +445,17 @@@ static OCStackResult OCParseDevicePaylo err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload"); } - // Data Model Version + // Data Model Versions err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal); - VERIFY_CBOR_SUCCESS(TAG, err, "to find data model ver tag"); + VERIFY_CBOR_SUCCESS(TAG, err, "to find data model versions tag"); if (cbor_value_is_valid(&curVal)) { - err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL); - VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload"); + size_t len = 0; + char * str = NULL; + err = cbor_value_dup_text_string(&curVal, &str, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, err, "to find data model versions in device payload"); + out->dataModelVersions = OCCreateOCStringLL(str); + OICFree(str); } err = cbor_value_advance(rootValue); VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload"); @@@ -1190,21 -1187,17 +1191,21 @@@ static OCStackResult OCParsePresencePay if (cbor_value_is_map(rootValue)) { CborValue curVal; + uint64_t temp = 0; // Sequence Number CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag"); - err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber); + err = cbor_value_get_uint64(&curVal, &temp); + payload->sequenceNumber = (uint32_t)temp; VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value"); // Max Age err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag"); - err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge); + temp = 0; + err = cbor_value_get_uint64(&curVal, &temp); + payload->maxAge = (uint32_t)temp; VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value"); // Trigger diff --combined resource/csdk/stack/src/ocresource.c index 8303948,a4370f3..fc36619 --- a/resource/csdk/stack/src/ocresource.c +++ b/resource/csdk/stack/src/ocresource.c @@@ -26,9 -26,10 +26,10 @@@ // Refer http://pubs.opengroup.org/onlinepubs/009695399/ #define _POSIX_C_SOURCE 200112L - #ifdef WITH_ARDUINO + #ifdef WITH_STRING_H #include - #else + #endif + #ifdef WITH_STRINGS_H #include #endif @@@ -64,6 -65,8 +65,8 @@@ #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \ TAG, #arg " is NULL"); return (retVal); } } + #include "platform_features.h" + extern OCResource *headResource; static OCPlatformInfo savedPlatformInfo = {0}; static OCDeviceInfo savedDeviceInfo = {0}; @@@ -328,8 -331,8 +331,8 @@@ OCStackResult BuildVirtualResourceRespo securePort = devAddr->port; } - #ifdef TCP_ADAPTER uint16_t tcpPort = 0; + #ifdef TCP_ADAPTER if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK) { tcpPort = 0; @@@ -752,6 -755,13 +755,6 @@@ static OCStackResult HandleVirtualResou for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next) { bool result = false; - if (resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE) - { - if (resourceTypeQuery && resourceMatchesRTFilter(resource, resourceTypeQuery)) - { - result = true; - } - } if (resource->resourceProperties & OC_DISCOVERABLE) { result = true; @@@ -766,7 -776,8 +769,7 @@@ } else { - if ((interfaceQuery && (0 != strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL))) || - !interfaceQuery) + if (interfaceQuery && (0 != strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL))) { discPayload->uri = OICStrdup(OC_RSRVD_WELL_KNOWN_URI); VERIFY_NON_NULL(discPayload->uri, ERROR, OC_STACK_NO_MEMORY); @@@ -775,13 -786,11 +778,13 @@@ discPayload->name = OICStrdup(savedDeviceInfo.deviceName); VERIFY_NON_NULL(discPayload->name, ERROR, OC_STACK_NO_MEMORY); } - discPayload->type = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES); + discPayload->type = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL)); VERIFY_NON_NULL(discPayload->type, ERROR, OC_STACK_NO_MEMORY); + discPayload->type->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES); + VERIFY_NON_NULL(discPayload->type->value, ERROR, OC_STACK_NO_MEMORY); - OCResourcePayloadAddStringLL(&discPayload->interface, OC_RSRVD_INTERFACE_LL); - OCResourcePayloadAddStringLL(&discPayload->interface, OC_RSRVD_INTERFACE_DEFAULT); - VERIFY_NON_NULL(discPayload->interface, ERROR, OC_STACK_NO_MEMORY); + OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_LL); + OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_DEFAULT); + VERIFY_NON_NULL(discPayload->iface, ERROR, OC_STACK_NO_MEMORY); } bool foundResourceAtRD = false; for (;resource && discoveryResult == OC_STACK_OK; resource = resource->next) @@@ -864,24 -873,15 +867,24 @@@ } else { - payload = (OCPayload*) OCDevicePayloadCreate(deviceId, savedDeviceInfo.deviceName, - savedDeviceInfo.types, savedDeviceInfo.specVersion, savedDeviceInfo.dataModleVersion); - if (!payload) + char *dataModelVersions = OCCreateString(savedDeviceInfo.dataModelVersions); + if (!dataModelVersions) { discoveryResult = OC_STACK_NO_MEMORY; } else { - discoveryResult = OC_STACK_OK; + payload = (OCPayload*) OCDevicePayloadCreate(deviceId, savedDeviceInfo.deviceName, + savedDeviceInfo.types, savedDeviceInfo.specVersion, dataModelVersions); + if (!payload) + { + discoveryResult = OC_STACK_NO_MEMORY; + } + else + { + discoveryResult = OC_STACK_OK; + } + OICFree(dataModelVersions); } } } @@@ -990,8 -990,7 +993,8 @@@ HandleDefaultDeviceEntityHandler (OCSer request->numRcvdVendorSpecificHeaderOptions, request->rcvdVendorSpecificHeaderOptions, (OCObserveAction)request->observationOption, - (OCObservationId)0); + (OCObservationId)0, + request->coapID); VERIFY_SUCCESS(result, OC_STACK_OK); // At this point we know for sure that defaultDeviceHandler exists @@@ -1055,8 -1054,7 +1058,8 @@@ HandleResourceWithEntityHandler (OCServ request->numRcvdVendorSpecificHeaderOptions, request->rcvdVendorSpecificHeaderOptions, (OCObserveAction)request->observationOption, - 0); + 0, + request->coapID); VERIFY_SUCCESS(result, OC_STACK_OK); if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION) @@@ -1103,13 -1101,13 +1106,13 @@@ } else { - result = OC_STACK_OK; - // The error in observeResult for the request will be used when responding to this // request by omitting the observation option/sequence number. request->observeResult = OC_STACK_ERROR; OIC_LOG(ERROR, TAG, "Observer Addition failed"); ehFlag = OC_REQUEST_FLAG; + FindAndDeleteServerRequest(request); + goto exit; } } @@@ -1139,9 -1137,10 +1142,10 @@@ } else { - result = OC_STACK_OK; request->observeResult = OC_STACK_ERROR; OIC_LOG(ERROR, TAG, "Observer Removal failed"); + FindAndDeleteServerRequest(request); + goto exit; } } else @@@ -1190,8 -1189,7 +1194,8 @@@ HandleCollectionResourceDefaultEntityHa request->numRcvdVendorSpecificHeaderOptions, request->rcvdVendorSpecificHeaderOptions, (OCObserveAction)request->observationOption, - (OCObservationId)0); + (OCObservationId)0, + request->coapID); if(result == OC_STACK_OK) { result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest); @@@ -1349,10 -1347,10 +1353,10 @@@ void DeleteDeviceInfo( OICFree(savedDeviceInfo.deviceName); OCFreeOCStringLL(savedDeviceInfo.types); OICFree(savedDeviceInfo.specVersion); - OICFree(savedDeviceInfo.dataModleVersion); + OCFreeOCStringLL(savedDeviceInfo.dataModelVersions); savedDeviceInfo.deviceName = NULL; savedDeviceInfo.specVersion = NULL; - savedDeviceInfo.dataModleVersion = NULL; + savedDeviceInfo.dataModelVersions = NULL; } static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info) @@@ -1394,10 -1392,10 +1398,10 @@@ } } - if (info.dataModleVersion) + if (info.dataModelVersions) { - savedDeviceInfo.dataModleVersion = OICStrdup(info.dataModleVersion); - if(!savedDeviceInfo.dataModleVersion && info.dataModleVersion) + savedDeviceInfo.dataModelVersions = CloneOCStringLL(info.dataModelVersions); + if(!savedDeviceInfo.dataModelVersions && info.dataModelVersions) { DeleteDeviceInfo(); return OC_STACK_NO_MEMORY; @@@ -1405,13 -1403,8 +1409,13 @@@ } else { - savedDeviceInfo.dataModleVersion = OICStrdup(OC_DATA_MODEL_VERSION); - if(!savedDeviceInfo.dataModleVersion && OC_DATA_MODEL_VERSION) + savedDeviceInfo.dataModelVersions = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL)); + if (!savedDeviceInfo.dataModelVersions) + { + return OC_STACK_NO_MEMORY; + } + savedDeviceInfo.dataModelVersions->value = OICStrdup(OC_DATA_MODEL_VERSION); + if(!savedDeviceInfo.dataModelVersions->value && OC_DATA_MODEL_VERSION) { DeleteDeviceInfo(); return OC_STACK_NO_MEMORY; diff --combined resource/csdk/stack/src/ocserverrequest.c index 27ba09f,592f27a..24f734f --- a/resource/csdk/stack/src/ocserverrequest.c +++ b/resource/csdk/stack/src/ocserverrequest.c @@@ -362,8 -362,7 +362,8 @@@ OCStackResult FormOCEntityHandlerReques uint8_t numVendorOptions, OCHeaderOption * vendorOptions, OCObserveAction observeAction, - OCObservationId observeID) + OCObservationId observeID, + uint16_t messageID) { if (entityHandlerRequest) { @@@ -374,7 -373,6 +374,7 @@@ entityHandlerRequest->query = queryBuf; entityHandlerRequest->obsInfo.action = observeAction; entityHandlerRequest->obsInfo.obsId = observeID; + entityHandlerRequest->messageID = messageID; if(payload && payloadSize) { @@@ -421,67 -419,49 +421,67 @@@ void FindAndDeleteServerRequest(OCServe CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result, OCMethod method) { - CAResponseResult_t caResult; + CAResponseResult_t caResult = CA_BAD_REQ; switch (result) { - case OC_EH_OK: - switch (method) - { - case OC_REST_PUT: - case OC_REST_POST: - // This Response Code is like HTTP 204 "No Content" but only used in - // response to POST and PUT requests. - caResult = CA_CHANGED; - break; - case OC_REST_GET: - // This Response Code is like HTTP 200 "OK" but only used in response to - // GET requests. - caResult = CA_CONTENT; - break; - default: - // This should not happen but, - // give it a value just in case but output an error - caResult = CA_CONTENT; - OIC_LOG_V(ERROR, TAG, "Unexpected OC_EH_OK return code for method [%d].", method); - } + // Successful Client Request + case OC_EH_RESOURCE_CREATED: // 2.01 + if (method == OC_REST_POST || method == OC_REST_PUT) + { + caResult = CA_CREATED; + } break; - case OC_EH_ERROR: - caResult = CA_BAD_REQ; + case OC_EH_RESOURCE_DELETED: // 2.02 + if (method == OC_REST_POST || method == OC_REST_DELETE) + { + caResult = CA_DELETED; + } break; - case OC_EH_RESOURCE_CREATED: - caResult = CA_CREATED; + case OC_EH_SLOW: // 2.05 + caResult = CA_CONTENT; break; - case OC_EH_RESOURCE_DELETED: - caResult = CA_DELETED; + case OC_EH_OK: // 2.04/2.05 + if (method == OC_REST_POST || method == OC_REST_PUT) + { + caResult = CA_CHANGED; + } + else if (method == OC_REST_GET) + { + caResult = CA_CONTENT; + } break; - case OC_EH_SLOW: - caResult = CA_CONTENT; + case OC_EH_VALID: // 2.03 + caResult = CA_VALID; break; - case OC_EH_FORBIDDEN: + case OC_EH_CHANGED: // 2.04 + caResult = CA_CHANGED; + break; + // Unsuccessful Client Request + case OC_EH_UNAUTHORIZED_REQ: // 4.01 caResult = CA_UNAUTHORIZED_REQ; break; - case OC_EH_RESOURCE_NOT_FOUND: + case OC_EH_BAD_OPT: // 4.02 + caResult = CA_BAD_OPT; + break; + case OC_EH_FORBIDDEN: // 4.03 + caResult = CA_FORBIDDEN_REQ; + break; + case OC_EH_RESOURCE_NOT_FOUND: // 4.04 caResult = CA_NOT_FOUND; break; + case OC_EH_METHOD_NOT_ALLOWED: // 4.05 + caResult = CA_METHOD_NOT_ALLOWED; + break; + case OC_EH_NOT_ACCEPTABLE: // 4.06 + caResult = CA_NOT_ACCEPTABLE; + break; + case OC_EH_INTERNAL_SERVER_ERROR: // 5.00 + caResult = CA_INTERNAL_SERVER_ERROR; + break; + case OC_EH_RETRANSMIT_TIMEOUT: // 5.04 + caResult = CA_RETRANSMIT_TIMEOUT; + break; default: caResult = CA_BAD_REQ; break; @@@ -515,7 -495,6 +515,7 @@@ OCStackResult HandleSingleResponse(OCEn CopyDevAddrToEndpoint(&serverRequest->devAddr, &responseEndpoint); + responseInfo.info.messageId = serverRequest->coapID; responseInfo.info.resourceUri = serverRequest->resourceUrl; responseInfo.result = ConvertEHResultToCAResult(ehResponse->ehResult, serverRequest->method); @@@ -535,8 -514,6 +535,8 @@@ else if(!serverRequest->notificationFlag && serverRequest->slowFlag && serverRequest->qos == OC_HIGH_QOS) { + // To assign new messageId in CA. + responseInfo.info.messageId = 0; responseInfo.info.type = CA_MSG_CONFIRM; } else if(!serverRequest->notificationFlag) @@@ -549,14 -526,14 +549,14 @@@ responseInfo.info.type = CA_MSG_NONCONFIRM; } - char rspToken[CA_MAX_TOKEN_LEN + 1] = {}; + char rspToken[CA_MAX_TOKEN_LEN + 1] = {0}; + responseInfo.info.messageId = serverRequest->coapID; responseInfo.info.token = (CAToken_t)rspToken; memcpy(responseInfo.info.token, serverRequest->requestToken, serverRequest->tokenLength); responseInfo.info.tokenLength = serverRequest->tokenLength; - // De-register observe option should not be included in the response header - if((serverRequest->observeResult == OC_STACK_OK) && (serverRequest->observationOption != OC_OBSERVE_DEREGISTER)) + if(serverRequest->observeResult == OC_STACK_OK) { responseInfo.info.numOptions = ehResponse->numSendVendorSpecificHeaderOptions + 1; } @@@ -775,6 -752,7 +775,6 @@@ OCStackResult HandleAggregateResponse(O (OCRepPayload*)newPayload); } - (serverRequest->numResponses)--; if(serverRequest->numResponses == 0) @@@ -795,3 -773,4 +795,3 @@@ exit: return stackRet; } - diff --combined resource/csdk/stack/src/ocstack.c index a63026b,405bc4d..ac14ccd --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@@ -72,16 -72,17 +72,17 @@@ #include "directpairing.h" //#endif - #ifdef WITH_ARDUINO + #ifdef HAVE_ARDUINO_TIME_H #include "Time.h" - #else + #endif + #ifdef HAVE_SYS_TIME_H #include #endif #include "coap_time.h" #include "utlist.h" #include "pdu.h" - #ifndef ARDUINO + #ifdef HAVE_ARPA_INET_H #include #endif @@@ -437,7 -438,7 +438,7 @@@ void CopyEndpointToDevAddr(const CAEndp out->flags = CAToOCTransportFlags(in->flags); OICStrcpy(out->addr, sizeof(out->addr), in->addr); out->port = in->port; - out->interface = in->interface; + out->ifindex = in->ifindex; #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) memcpy(out->routeData, in->routeData, sizeof(out->routeData)); #endif @@@ -455,7 -456,7 +456,7 @@@ void CopyDevAddrToEndpoint(const OCDevA memcpy(out->routeData, in->routeData, sizeof(out->routeData)); #endif out->port = in->port; - out->interface = in->interface; + out->ifindex = in->ifindex; } void FixUpClientResponse(OCClientResponse *cr) @@@ -518,8 -519,7 +519,8 @@@ OCStackResult OCStackFeedBack(CAToken_ NULL, PAYLOAD_TYPE_REPRESENTATION, NULL, 0, 0, NULL, OC_OBSERVE_DEREGISTER, - observer->observeId); + observer->observeId, + 0); if(result != OC_STACK_OK) { return result; @@@ -570,8 -570,7 +571,8 @@@ NULL, PAYLOAD_TYPE_REPRESENTATION, NULL, 0, 0, NULL, OC_OBSERVE_DEREGISTER, - observer->observeId); + observer->observeId, + 0); if(result != OC_STACK_OK) { return OC_STACK_ERROR; @@@ -1151,7 -1150,7 +1152,7 @@@ void OCHandleResponse(const CAEndpoint_ OCClientResponse response = {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}}; - response.sequenceNumber = OC_OBSERVE_NO_OPTION; + response.sequenceNumber = -1; CopyEndpointToDevAddr(endPoint, &response.devAddr); FixUpClientResponse(&response); response.resourceUri = responseInfo->info.resourceUri; @@@ -2642,6 -2641,12 +2643,6 @@@ OCStackResult OCDoResource(OCDoHandle * requestInfo.info.payloadFormat = CA_FORMAT_UNDEFINED; } - if (result != OC_STACK_OK) - { - OIC_LOG(ERROR, TAG, "CACreateEndpoint error"); - goto exit; - } - // prepare for response #ifdef WITH_PRESENCE if (method == OC_REST_PRESENCE) @@@ -4399,11 -4404,7 +4400,11 @@@ void insertResourceInterface(OCResourc previous = pointer; pointer = pointer->next; } - previous->next = newInterface; + + if (previous) + { + previous->next = newInterface; + } } } diff --combined resource/examples/simpleclient.cpp index 42c0d6f,6bc6efe..c4aff50 --- a/resource/examples/simpleclient.cpp +++ b/resource/examples/simpleclient.cpp @@@ -20,10 -20,18 +20,18 @@@ // OCClient.cpp : Defines the entry point for the console application. // + #ifdef HAVE_UNISTD_H + #include + #endif + #ifdef HAVE_PTHREAD_H + #include + #endif + #ifdef HAVE_WINDOWS_H + #include + #endif #include #include #include - #include #include #include #include "OCPlatform.h" @@@ -65,12 -73,16 +73,12 @@@ void onObserve(const HeaderOptions /*he { try { - if(eCode == OC_STACK_OK && sequenceNumber != OC_OBSERVE_NO_OPTION) + if(eCode == OC_STACK_OK && sequenceNumber != -1) { if(sequenceNumber == OC_OBSERVE_REGISTER) { std::cout << "Observe registration action is successful" << std::endl; } - else if(sequenceNumber == OC_OBSERVE_DEREGISTER) - { - std::cout << "Observe De-registration action is successful" << std::endl; - } std::cout << "OBSERVE RESULT:"< #include #include @@@ -99,13 -98,28 +98,28 @@@ namespace O // this fix will work in the meantime. OCRepresentation(): m_interfaceType(InterfaceType::None){} + #if defined(_MSC_VER) && (_MSC_VER < 1900) + OCRepresentation(OCRepresentation&& o) + { + std::memmove(this, &o, sizeof(o)); + } + #else OCRepresentation(OCRepresentation&&) = default; + #endif OCRepresentation(const OCRepresentation&) = default; OCRepresentation& operator=(const OCRepresentation&) = default; + #if defined(_MSC_VER) && (_MSC_VER < 1900) + OCRepresentation& operator=(OCRepresentation&& o) + { + std::memmove(this, &o, sizeof(o)); + return *this; + } + #else OCRepresentation& operator=(OCRepresentation&&) = default; + #endif virtual ~OCRepresentation(){} @@@ -131,8 -145,6 +145,8 @@@ const std::vector& getResourceTypes() const; + const std::vector& getDataModelVersions() const; + void setResourceTypes(const std::vector& resourceTypes); void addResourceType(const std::string& str); @@@ -143,8 -155,6 +157,8 @@@ void addResourceInterface(const std::string& str); + void addDataModelVersion(const std::string& str); + bool emptyData() const; int numberOfAttributes() const; @@@ -310,12 -320,38 +324,38 @@@ // Enable-if required to prevent conversions to alternate types. This prevents // ambigious conversions in the case where conversions can include a number of // types, such as the string constructor. + #if (defined(_MSC_VER) ) || (defined(__GNUC__) && (__GNUC__ <= 5)) + template::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value || + std::is_same>::value || + std::is_same>>::value || + std::is_same>>>::value + , int>::type = 0// enable_if + > + #else template::type >::value , int>::type = 0 > + #endif operator T() const { return this->getValue(); @@@ -460,7 -496,6 +500,7 @@@ mutable std::map m_values; std::vector m_resourceTypes; std::vector m_interfaces; + std::vector m_dataModelVersions; InterfaceType m_interfaceType; }; diff --combined resource/include/OCResourceRequest.h index a2e13c1,64ffa7e..538a134 --- a/resource/include/OCResourceRequest.h +++ b/resource/include/OCResourceRequest.h @@@ -51,7 -51,6 +51,7 @@@ namespace O m_resourceUri{}, m_queryParameters{}, m_requestHandlerFlag{}, + m_messageID{}, m_representation{}, m_observationInfo{}, m_headerOptions{}, @@@ -60,8 -59,36 +60,36 @@@ { } + #if defined(_MSC_VER) && (_MSC_VER < 1900) + OCResourceRequest(OCResourceRequest&& o): + m_requestType(std::move(o.m_requestType)), + m_resourceUri(std::move(o.m_resourceUri)), + m_queryParameters(std::move(o.m_queryParameters)), + m_requestHandlerFlag(o.m_requestHandlerFlag), + m_representation(std::move(o.m_representation)), + m_observationInfo(std::move(o.m_observationInfo)), + m_headerOptions(std::move(o.m_headerOptions)), + m_requestHandle(std::move(o.m_requestHandle)), + m_resourceHandle(std::move(o.m_resourceHandle)) + { + } + OCResourceRequest& operator=(OCResourceRequest&& o) + { + m_requestType = std::move(o.m_requestType); + m_resourceUri = std::move(o.m_resourceUri); + m_queryParameters = std::move(o.m_queryParameters); + m_requestHandlerFlag = o.m_requestHandlerFlag; + m_representation = std::move(o.m_representation); + m_observationInfo = std::move(o.m_observationInfo); + m_headerOptions = std::move(o.m_headerOptions); + m_requestHandle = std::move(o.m_requestHandle); + m_resourceHandle = std::move(o.m_resourceHandle); + } + #else OCResourceRequest(OCResourceRequest&&) = default; OCResourceRequest& operator=(OCResourceRequest&&) = default; + #endif + /** * Virtual destructor */ @@@ -155,19 -182,11 +183,19 @@@ return m_resourceHandle; } + /** + * This API retrieves the request message ID + * + * @return int16_t value of message ID + */ + int16_t getMessageID() const {return m_messageID;} + private: std::string m_requestType; std::string m_resourceUri; QueryParamsMap m_queryParameters; int m_requestHandlerFlag; + int16_t m_messageID; OCRepresentation m_representation; ObservationInfo m_observationInfo; HeaderOptions m_headerOptions; @@@ -195,11 -214,6 +223,11 @@@ m_requestHandlerFlag = requestHandlerFlag; } + void setMessageID(int16_t messageID) + { + m_messageID = messageID; + } + void setObservationInfo(const ObservationInfo& observationInfo) { m_observationInfo = observationInfo; diff --combined resource/src/InProcServerWrapper.cpp index 82f0172,ef9317f..2fd1c19 --- a/resource/src/InProcServerWrapper.cpp +++ b/resource/src/InProcServerWrapper.cpp @@@ -47,7 -47,7 +47,7 @@@ namespace O std::mutex serverWrapperLock; std::map entityHandlerMap; std::map resourceUriMap; - EntityHandler defaultDeviceEntityHandler = 0; + EntityHandler defaultDeviceEntityHandler; } } @@@ -59,7 -59,6 +59,7 @@@ void formResourceRequest(OCEntityHandle { pRequest->setRequestHandle(entityHandlerRequest->requestHandle); pRequest->setResourceHandle(entityHandlerRequest->resource); + pRequest->setMessageID(entityHandlerRequest->messageID); } if(flag & OC_REQUEST_FLAG) diff --combined resource/src/OCRepresentation.cpp index 68a14fc,8818821..06b2083 --- a/resource/src/OCRepresentation.cpp +++ b/resource/src/OCRepresentation.cpp @@@ -82,10 -82,9 +82,10 @@@ namespace O rep[OC_RSRVD_SPEC_VERSION] = payload->specVersion ? std::string(payload->specVersion) : std::string(); - rep[OC_RSRVD_DATA_MODEL_VERSION] = payload->dataModelVersion ? - std::string(payload->dataModelVersion) : - std::string(); + for (OCStringLL *strll = payload->dataModelVersions; strll; strll = strll->next) + { + rep.addDataModelVersion(strll->value); + } for (OCStringLL *strll = payload->types; strll; strll = strll->next) { rep.addResourceType(strll->value); @@@ -315,11 -314,13 +315,13 @@@ namespace O ((int64_t*)array)[pos] = item; } + #if !defined(_MSC_VER) template<> void get_payload_array::copy_to_array(std::_Bit_reference br, void* array, size_t pos) { ((bool*)array)[pos] = static_cast(br); } + #endif template<> void get_payload_array::copy_to_array(std::string item, void* array, size_t pos) @@@ -756,16 -757,6 +758,16 @@@ m_interfaces = resourceInterfaces; } + const std::vector& OCRepresentation::getDataModelVersions() const + { + return m_dataModelVersions; + } + + void OCRepresentation::addDataModelVersion(const std::string& str) + { + m_dataModelVersions.push_back(str); + } + bool OCRepresentation::hasAttribute(const std::string& str) const { return m_values.find(str) != m_values.end(); @@@ -786,8 -777,7 +788,8 @@@ else if ((m_interfaceType == InterfaceType::None || m_interfaceType==InterfaceType::DefaultChild || m_interfaceType==InterfaceType::LinkChild) - && (m_resourceTypes.size()>0 || m_interfaces.size()>0)) + && (m_resourceTypes.size()>0 || m_interfaces.size()>0 + || m_dataModelVersions.size()>0)) { return false; } @@@ -903,13 -893,13 +905,13 @@@ namespace O // contains the inner most vector-type typedef T base_type; // contains the AttributeType for this item - constexpr static AttributeType enum_type = + BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeTypeConvert::type; // contains the AttributeType for this base-type - constexpr static AttributeType enum_base_type = + BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = AttributeTypeConvert::type; // depth of the vector - constexpr static size_t depth = 0; + BOOST_STATIC_CONSTEXPR size_t depth = 0; }; template @@@ -923,10 -913,10 +925,10 @@@ { typedef T type; typedef typename type_info::base_type base_type; - constexpr static AttributeType enum_type = AttributeType::Vector; - constexpr static AttributeType enum_base_type = + BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Vector; + BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = type_info::enum_base_type; - constexpr static size_t depth = 1 + + BOOST_STATIC_CONSTEXPR size_t depth = 1 + type_info::depth; }; @@@ -936,9 -926,9 +938,9 @@@ { typedef std::vector type; typedef std::vector base_type; - constexpr static AttributeType enum_type = AttributeType::Binary; - constexpr static AttributeType enum_base_type = AttributeType::Binary; - constexpr static size_t depth = 0; + BOOST_STATIC_CONSTEXPR AttributeType enum_type = AttributeType::Binary; + BOOST_STATIC_CONSTEXPR AttributeType enum_base_type = AttributeType::Binary; + BOOST_STATIC_CONSTEXPR size_t depth = 0; }; diff --combined service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript index ba0e9bb,f885fde..eb2ab43 --- a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript @@@ -40,13 -40,13 +40,13 @@@ if env.get('LOGGING') env.AppendUnique(CPPDEFINES = ['CPP_MEDIATOR']) - if target_os not in ['windows', 'winrt']: + if target_os not in ['windows']: mediator_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x']) mediator_env.PrependUnique(CPPPATH = [ env.get('SRC_DIR') + '/resource/include', env.get('SRC_DIR') + '/resource/oc_logger/include', - env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include', + env.get('SRC_DIR') + '/resource/c_common/oic_malloc/include', env.get('SRC_DIR') + '/resource/csdk/stack/include', env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include', env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal',