Add support for Visual Studio 2015 and 2013 builds.
Change-Id: I3ce9bee6b3e57ccd548b849b5d147ca0babd872e
Signed-off-by: David Antler <david.a.antler@intel.com>
# 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'],
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)
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')
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')
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:
'\@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
# 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()
######################################################################
#define _POSIX_C_SOURCE 200809L
#endif
+ #ifdef HAVE_STRING_H
#include <string.h>
+ #endif
+ #ifdef HAVE_PTHREAD_H
#include <pthread.h>
- #include <errno.h>
+ #endif
+ #ifdef HAVE_UNISTD_H
#include <unistd.h>
+ #endif
+ #ifdef HAVE_TIME_H
#include <time.h>
+ #endif
+ #ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+ #endif
+ #ifdef HAVE_WINSOCK2_H
+ #include <winsock2.h>
+ #endif
+ #include <stdio.h>
+ #include <errno.h>
#include <assert.h>
#include <oic_malloc.h>
-
+ #include "platform_features.h"
#include "camutex.h"
#include "logger.h"
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)
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)
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;
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)
{
{
OIC_LOG_V(ERROR, TAG, "%s Failed to free mutex !", __func__);
}
+ #endif
}
else
{
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
{
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)
{
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;
}
}
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)
{
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!",
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)
{
pthread_condattr_destroy(&(eventInfo->condattr));
OICFree(eventInfo);
}
+ #endif
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: Failed to allocate condition variable!", __func__);
}
return retVal;
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)
OIC_LOG_V(ERROR, TAG, "%s: Failed to destroy condition variable %d, %d",
__func__, ret, ret2);
}
+ #endif
}
else
{
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
{
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
{
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
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)
{
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
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;
}
#include "oic_string.h"
#include "global.h"
#include "timer.h"
+ #if defined(HAVE_WINSOCK2_H) && defined(HAVE_WS2TCPIP_H)
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+ #endif
+ #ifdef HAVE_NETDB_H
#include <netdb.h>
+ #endif
/* tinyDTLS library error code */
#define TINY_DTLS_ERROR (-1)
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.
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);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+ #ifdef HAVE_UNISTD_H
#include <unistd.h>
+ #endif
+ #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
+ #endif
#include "caqueueingthread.h"
#include "oic_malloc.h"
if (NULL == thread)
{
OIC_LOG(ERROR, TAG, "thread data passing error!!");
-
return;
}
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)
u_queue_message_t *message = u_queue_get_element(thread->dataQueue);
// free
- if(NULL != message)
+ if (NULL != message)
{
if (NULL != thread->destroy)
{
#include <string.h>
#ifndef SINGLE_THREAD
+ #ifdef HAVE_UNISTD_H
#include <unistd.h>
- #include <time.h>
+ #endif
+ #ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
+ #if HAVE_SYS_TIMEB_H
+ #include <sys/timeb.h>
+ #endif
+ #ifdef HAVE_TIME_H
+ #include <time.h>
+ #endif
+ #endif
#if defined(__ANDROID__)
#include <linux/time.h>
#include "caremotehandler.h"
#include "caprotocolmessage.h"
#include "oic_malloc.h"
+#include "ocrandom.h"
#include "logger.h"
#define TAG "OIC_CA_RETRANS"
} CARetransmissionData_t;
static const uint64_t USECS_PER_SEC = 1000000;
+ static const uint64_t MSECS_PER_SEC = 1000;
/**
* @brief getCurrent monotonic time
*/
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
}
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);
- /*****************************************************************j
+ /* ****************************************************************
*
* Copyright 2014 Samsung Electronics All Rights Reserved.
*
#endif
#include <sys/types.h>
+ #if !defined(_WIN32)
#include <sys/socket.h>
+ #endif
+
+ #if defined(_WIN32)
+ #include <assert.h>
+ #include <winsock2.h>
+ #include <ws2def.h>
+ #include <mswsock.h>
+ #include <ws2tcpip.h>
+ #endif
+
#include <stdio.h>
+ #if !defined(_MSC_VER)
#include <unistd.h>
+ #endif //!defined(_MSC_VER)
#include <sys/types.h>
#include <fcntl.h>
+ #if !defined(_WIN32)
#include <sys/select.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
+ #endif
#include <errno.h>
#ifdef __linux__
#include <linux/netlink.h>
#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
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()
{
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);
}
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;
}
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)
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)
{
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;
.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;
}
}
}
+ #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);
}
}
- CAConvertAddrToName(&srcAddr, msg.msg_namelen, sep.endpoint.addr, &sep.endpoint.port);
+ CAConvertAddrToName(&srcAddr, namelen, sep.endpoint.addr, &sep.endpoint.port);
if (flags & CA_SECURE)
{
}
return CA_STATUS_OK;
+
}
void CAIPPullData()
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;
{
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);
}
}
}
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);
}
}
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 :
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); \
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));
}
{
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
{
#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);
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
}
}
{
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);
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();
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]);
{
// 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;
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()
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;
}
{
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);
}
}
{
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);
}
}
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);
}
}
}
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);
{
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,
{
continue;
}
- if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+ if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS)
{
continue;
}
}
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");
{
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;
{
continue;
}
- if ((ifitem->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+ if ((ifitem->flags & IFF_UP_RUNNING_FLAGS) != IFF_UP_RUNNING_FLAGS)
{
continue;
}
{
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");
}
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;
}
eps[j].adapter = CA_ADAPTER_IP;
- eps[j].interface = 0;
+ eps[j].ifindex = 0;
if (ifitem->family == AF_INET6)
{
{
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)
{
#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;
//Security Version
extern const char * DEFAULT_SEC_VERSION;
+ #ifdef __cplusplus
+ }
+ #endif
+
#endif //IOTVT_SRM_RSRC_STRINGS_H
#include "byte_array.h"
#endif /* __WITH_X509__ */
+ #include "platform_features.h"
+
#ifdef __cplusplus
extern "C" {
#endif
/**
* Extract Reason Code from Access Response.
*/
- static inline SRMAccessResponseReasonCode_t GetReasonCode(
+ INLINE_API SRMAccessResponseReasonCode_t GetReasonCode(
SRMAccessResponse_t response)
{
SRMAccessResponseReasonCode_t reason =
/**
* 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))
{
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;
{
uint8_t *data;
size_t len;
+
+ // TODO: This field added as workaround. Will be replaced soon.
+ OicEncodingType_t encoding;
+
};
/**
{
// <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
//TODO fill in from OIC Security Spec
+ #if defined(_MSC_VER)
+ uint8_t unused; // VS doesn't like empty structs
+ #endif
};
/**
'../../../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',
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'])
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')
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')
#include <stdio.h>
#include <string.h>
+ #ifdef HAVE_UNISTD_H
#include <unistd.h>
+ #endif
+ #include "platform_features.h"
#include "logger.h"
#include "oic_malloc.h"
#include "oic_string.h"
#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
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)
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 && g_own_cnt>=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 && g_own_cnt>=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
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;
}
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");
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:
#define _POSIX_C_SOURCE 200809L
#endif
+ #ifdef HAVE_TIME_H
#include <time.h>
+ #endif
+ #ifdef HAVE_UNISTD_H
#include <unistd.h>
+ #endif
+ #ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+ #endif
#include <stdbool.h>
#include <string.h>
&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)
{
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.");
#define _POSIX_C_SOURCE 200112L
#endif
+ #if HAVE_UNISTD_H
#include <unistd.h>
+ #endif
+ #ifdef HAVE_STRING_H
#include <string.h>
- #include <time.h>
- #include <sys/time.h>
+ #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"
*/
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;
}
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)
// 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.");
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,
#include <stdio.h>
#include <string.h>
#include <stdint.h>
+ #ifdef HAVE_UNISTD_H
#include <unistd.h>
+ #endif
#include "ocprovisioningmanager.h"
#include "secureresourceprovider.h"
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.
*/
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);
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))
{
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;
+}
sptest_env = env.Clone()
src_dir = sptest_env.get('SRC_DIR')
+ target_os = env.get('TARGET_OS')
######################################################################
# Build flags
'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'])
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')
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- #ifdef WITH_ARDUINO
+ #ifdef HAVE_STRING_H
#include <string.h>
- #else
+ #elif HAVE_STRINGS_H
#include <strings.h>
#endif
#include <stdlib.h>
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.");
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.");
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.");
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);
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;
// 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);
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);
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);
}
// 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);
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));
/*
}
}
}
+ // 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))
{
ret = OCCreateResource(&gAclHandle,
OIC_RSRC_TYPE_SEC_ACL,
- OIC_MI_DEF,
+ OC_RSRVD_INTERFACE_DEFAULT,
OIC_RSRC_ACL_URI,
ACLEntityHandler,
NULL,
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);
return OC_STACK_KEEP_TRANSACTION;
}
- OicUuid_t deviceId = {.id={}};
+ OicUuid_t deviceId = {.id={0}};
memcpy(&deviceId, &doxm->deviceID, sizeof(deviceId));
OICFree(doxm);
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);
{
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);
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)
{
#define __STDC_LIMIT_MACROS
#include <stdlib.h>
- #ifdef WITH_ARDUINO
+ #ifdef HAVE_STRING_H
#include <string.h>
- #else
+ #endif
+ #ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include <stdint.h>
}
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)
{
mapSize++;
}
#endif /* __WITH_X509__ */
- if (cred->privateData.data)
+ if (!secureFlag && cred->privateData.data)
{
mapSize++;
}
}
#endif /*__WITH_X509__*/
//PrivateData -- Not Mandatory
- if(cred->privateData.data)
+ if(!secureFlag && cred->privateData.data)
{
CborEncoder privateMap;
const size_t privateMapSize = 2;
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.");
// 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;
}
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.");
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);
//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)
// 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)
{
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);
// 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))
{
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);
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);
}
//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);
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);
{
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))
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");
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)
{
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;
switch (ehRequest->method)
{
case OC_REST_GET:
- ret = OC_EH_FORBIDDEN;
+ ret = HandleGetRequest(ehRequest);;
break;
case OC_REST_PUT:
ret = HandlePutRequest(ehRequest);
{
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)
{
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) )
{
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;
}
}
}
default:
{
OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
- ret = -1;
}
break;
}
}
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,
OCStackResult ret = OC_STACK_ERROR;
uint8_t *cborPayload = NULL;
size_t size = 0;
+ int secureFlag = 0;
OicUuid_t prevId = {.id={0}};
if(NULL == newROwner)
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);
#include "ocpayload.h"
#include "payload_logging.h"
#include <stdlib.h>
- #ifdef WITH_ARDUINO
- #include <string.h>
- #else
+ #ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
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;
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");
ret = OCCreateResource(&gDpairHandle,
OIC_RSRC_TYPE_SEC_DPAIRING,
- OIC_MI_DEF,
+ OC_RSRVD_INTERFACE_DEFAULT,
OIC_RSRC_DPAIRING_URI,
DpairingEntityHandler,
NULL,
#include <stdlib.h>
#include "psinterface.h"
#include "security_internals.h"
- #ifdef WITH_ARDUINO
- #include <string.h>
- #else
+ #ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
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");
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");
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");
}
}
//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);
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);
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 };
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;
}
// 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 };
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);
}
// 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 };
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);
}
//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 };
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);
}
//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);
}
// 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);
ret = OCCreateResource(&gPconfHandle,
OIC_RSRC_TYPE_SEC_PCONF,
- OIC_MI_DEF,
+ OC_RSRVD_INTERFACE_DEFAULT,
OIC_RSRC_PCONF_URI,
PconfEntityHandler,
NULL,
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'
])
'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
######################################################################
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'))
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')
/** 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.
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);
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.
*
* @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.
*
* @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);
/**
*
* @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.
*
* @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]);
/**
*
* @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]);
/**
*
* @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);
- OCStringLL* OCCreateOCStringLL(const char* text);
+/**
+ * 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)
+ **/
- char* OCCreateString(const OCStringLL* ll);
++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)
+ **/
++OC_EXPORT char* OCCreateString(const OCStringLL* ll);
+
#ifdef __cplusplus
}
#endif
#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 */
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
{
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;
/**
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
char *uri;
/** Resource Type */
- char *type;
+ OCStringLL *type;
/** Interface */
- OCStringLL *interface;
+ OCStringLL *iface;
/** This structure holds the old /oic/res response. */
OCResourcePayload *resources;
char *sid;
char* deviceName;
char* specVersion;
- char* dataModelVersion;
+ OCStringLL *dataModelVersions;
OCStringLL *interfaces;
OCStringLL *types;
} OCDevicePayload;
/** 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;
#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;
}
- 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;
}
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);
}
}
}
- 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:");
}
}
- 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);
}
}
- 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);
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)
{
}
}
- static inline void OCPayloadLog(LogLevel level, OCPayload* payload)
+ INLINE_API void OCPayloadLog(LogLevel level, OCPayload* payload)
{
if(!payload)
{
#include <string.h>
#include <string>
#include <stdlib.h>
+ #ifdef HAVE_UNISTD_H
#include <unistd.h>
+ #endif
+ #ifdef HAVE_WINDOWS_H
+ #include <windows.h>
+ #endif
#include <signal.h>
+ #ifdef HAVE_PTHREAD_H
#include <pthread.h>
+ #endif
#include <array>
+#include "oic_malloc.h"
+ #include <getopt.h>
#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<int>::digits10 + '\0'"
// 9 + 9 + 1 = 19
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
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)
{
{
free (deviceInfo.deviceName);
free (deviceInfo.specVersion);
- free (deviceInfo.dataModleVersion);
+ OCFreeOCStringLL (deviceInfo.dataModelVersions);
}
bool DuplicateString(char** targetString, const char* sourceString)
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))
{
{
return OC_STACK_ERROR;
}
- if(!DuplicateString(&deviceInfo.dataModleVersion, dataModleVersion))
+ OCFreeOCStringLL(deviceInfo.dataModelVersions);
+ deviceInfo.dataModelVersions = OCCreateOCStringLL(dataModelVersions);
+ if (!deviceInfo.dataModelVersions)
{
return OC_STACK_ERROR;
}
exit (EXIT_FAILURE);
}
- registrationResult = SetDeviceInfo(deviceName, specVersion, dataModleVersion);
+ registrationResult = SetDeviceInfo(deviceName, specVersion, dataModelVersions);
if (registrationResult != OC_STACK_OK)
{
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...");
#include <stdlib.h>
#include <string.h>
#include <signal.h>
+ #ifdef HAVE_UNISTD_H
#include <unistd.h>
+ #endif
+ #ifdef HAVE_WINDOWS_H
+ #include <windows.h>
+ /** @todo stop-gap for naming issue. Windows.h does not like us to use ERROR */
+ #ifdef ERROR
+ #undef ERROR
+ #endif
+ #endif
#include <iostream>
#include <sstream>
+ #include <getopt.h>
+ #include "platform_features.h"
#include "ocstack.h"
#include "logger.h"
#include "occlientbasicops.h"
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;
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,
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);
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}/
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}
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// Required for strok_r
+#define _POSIX_C_SOURCE 200112L
+#include <stdio.h>
#include "ocpayload.h"
#include "octypes.h"
#include <string.h>
#include "rdpayload.h"
#define TAG "OIC_RI_PAYLOAD"
+#define CSV_SEPARATOR ','
static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
}
}
- 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;
}
{
return false;
}
- cur->next->value = interface;
+ cur->next->value = iface;
return true;
}
else
{
return false;
}
- payload->interfaces->value = interface;
+ payload->interfaces->value = iface;
return true;
}
}
{
if (!array)
{
- return NULL;
+ return false;
}
size_t dimTotal = calcDimTotal(dimensions);
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 (count<sublen)
+ {
+ free(str);
+ return NULL;
+ }
+ len-=sublen;
+ pos+=count;
+ }
+
+ return str;
+}
+
OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
{
if (!payload)
OICFree(payload->sid);
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);
}
goto exit;
}
- payload->dataModelVersion = OICStrdup(dmVer);
- if (dmVer && !payload->dataModelVersion)
+ payload->dataModelVersions = OCCreateOCStringLL(dmVer);
+ if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value))
{
goto exit;
}
OICFree(payload->sid);
OICFree(payload->deviceName);
OICFree(payload->specVersion);
- OICFree(payload->dataModelVersion);
+ OCFreeOCStringLL(payload->dataModelVersions);
OCFreeOCStringLL(payload->types);
OCFreeOCStringLL(payload->interfaces);
OICFree(payload);
// 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,
// 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
[ // 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",
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");
}
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);
}
int64_t err = CborNoError;
CborEncoder encoder;
+ char *dataModelVersions = 0;
cbor_encoder_init(&encoder, outPayload, *size, 0);
CborEncoder repMap;
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");
#include "ocstackinternal.h"
#include "payload_logging.h"
#include "rdpayload.h"
+ #include "platform_features.h"
#define TAG "OIC_RI_PAYLOADPARSE"
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");
}
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;
}
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");
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
// Refer http://pubs.opengroup.org/onlinepubs/009695399/
#define _POSIX_C_SOURCE 200112L
- #ifdef WITH_ARDUINO
+ #ifdef WITH_STRING_H
#include <string.h>
- #else
+ #endif
+ #ifdef WITH_STRINGS_H
#include <strings.h>
#endif
#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};
securePort = devAddr->port;
}
- #ifdef TCP_ADAPTER
uint16_t tcpPort = 0;
+ #ifdef TCP_ADAPTER
if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK)
{
tcpPort = 0;
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;
}
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);
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);
- OCResourcePayloadAddStringLL(&discPayload->interface, OC_RSRVD_INTERFACE_LL);
- OCResourcePayloadAddStringLL(&discPayload->interface, OC_RSRVD_INTERFACE_DEFAULT);
- VERIFY_NON_NULL(discPayload->interface, 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->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)
}
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);
}
}
}
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
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)
}
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;
}
}
}
else
{
- result = OC_STACK_OK;
request->observeResult = OC_STACK_ERROR;
OIC_LOG(ERROR, TAG, "Observer Removal failed");
+ FindAndDeleteServerRequest(request);
+ goto exit;
}
}
else
request->numRcvdVendorSpecificHeaderOptions,
request->rcvdVendorSpecificHeaderOptions,
(OCObserveAction)request->observationOption,
- (OCObservationId)0);
+ (OCObservationId)0,
+ request->coapID);
if(result == OC_STACK_OK)
{
result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest);
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)
}
}
- 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;
}
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;
uint8_t numVendorOptions,
OCHeaderOption * vendorOptions,
OCObserveAction observeAction,
- OCObservationId observeID)
+ OCObservationId observeID,
+ uint16_t messageID)
{
if (entityHandlerRequest)
{
entityHandlerRequest->query = queryBuf;
entityHandlerRequest->obsInfo.action = observeAction;
entityHandlerRequest->obsInfo.obsId = observeID;
+ entityHandlerRequest->messageID = messageID;
if(payload && payloadSize)
{
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;
CopyDevAddrToEndpoint(&serverRequest->devAddr, &responseEndpoint);
+ responseInfo.info.messageId = serverRequest->coapID;
responseInfo.info.resourceUri = serverRequest->resourceUrl;
responseInfo.result = ConvertEHResultToCAResult(ehResponse->ehResult, serverRequest->method);
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)
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;
}
(OCRepPayload*)newPayload);
}
-
(serverRequest->numResponses)--;
if(serverRequest->numResponses == 0)
exit:
return stackRet;
}
-
#include "directpairing.h"
//#endif
- #ifdef WITH_ARDUINO
+ #ifdef HAVE_ARDUINO_TIME_H
#include "Time.h"
- #else
+ #endif
+ #ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include "coap_time.h"
#include "utlist.h"
#include "pdu.h"
- #ifndef ARDUINO
+ #ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
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
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)
NULL, PAYLOAD_TYPE_REPRESENTATION,
NULL, 0, 0, NULL,
OC_OBSERVE_DEREGISTER,
- observer->observeId);
+ observer->observeId,
+ 0);
if(result != OC_STACK_OK)
{
return result;
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;
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;
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)
previous = pointer;
pointer = pointer->next;
}
- previous->next = newInterface;
+
+ if (previous)
+ {
+ previous->next = newInterface;
+ }
}
}
// OCClient.cpp : Defines the entry point for the console application.
//
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ #ifdef HAVE_PTHREAD_H
+ #include <pthread.h>
+ #endif
+ #ifdef HAVE_WINDOWS_H
+ #include <Windows.h>
+ #endif
#include <string>
#include <map>
#include <cstdlib>
- #include <pthread.h>
#include <mutex>
#include <condition_variable>
#include "OCPlatform.h"
{
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:"<<std::endl;
std::cout << "\tSequenceNumber: "<< sequenceNumber << std::endl;
}
else
{
- if(sequenceNumber == OC_OBSERVE_NO_OPTION)
+ if(eCode == OC_STACK_OK)
{
- std::cout << "Observe registration or de-registration action is failed" << std::endl;
+ std::cout << "Observe registration failed or de-registration action failed/succeeded" << std::endl;
}
else
{
OC::ModeType::Both,
"0.0.0.0",
0,
- OC::QualityOfService::LowQos,
+ OC::QualityOfService::HighQos,
&ps
};
#ifndef OC_REPRESENTATION_H_
#define OC_REPRESENTATION_H_
-
#include <string>
#include <sstream>
#include <vector>
// 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(){}
const std::vector<std::string>& getResourceTypes() const;
+ const std::vector<std::string>& getDataModelVersions() const;
+
void setResourceTypes(const std::vector<std::string>& resourceTypes);
void addResourceType(const std::string& str);
void addResourceInterface(const std::string& str);
+ void addDataModelVersion(const std::string& str);
+
bool emptyData() const;
int numberOfAttributes() const;
// 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<typename T, typename std::enable_if<
+ std::is_same<T, int>::value ||
+ std::is_same<T, double>::value ||
+ std::is_same<T, bool>::value ||
+ std::is_same<T, std::string>::value ||
+ std::is_same<T, OCRepresentation>::value ||
+ std::is_same<T, std::vector<int>>::value ||
+ std::is_same<T, std::vector<std::vector<int>>>::value ||
+ std::is_same<T, std::vector<std::vector<std::vector<int>>>>::value ||
+ std::is_same<T, std::vector<double>>::value ||
+ std::is_same<T, std::vector<std::vector<double>>>::value ||
+ std::is_same<T, std::vector<std::vector<std::vector<double>>>>::value ||
+ std::is_same<T, std::vector<bool>>::value ||
+ std::is_same<T, std::vector<std::vector<bool>>>::value ||
+ std::is_same<T, std::vector<std::vector<std::vector<bool>>>>::value ||
+ std::is_same<T, std::vector<std::string>>::value ||
+ std::is_same<T, std::vector<std::vector<std::string>>>::value ||
+ std::is_same<T, std::vector<std::vector<std::vector<std::string>>>>::value ||
+ std::is_same<T, std::vector<OCRepresentation>>::value ||
+ std::is_same<T, std::vector<std::vector<OCRepresentation>>>::value ||
+ std::is_same<T, std::vector<std::vector<std::vector<OCRepresentation>>>>::value
+ , int>::type = 0// enable_if
+ >
+ #else
template<typename T, typename std::enable_if<
is_component<T,
remove_first<AttributeValue>::type
>::value
, int>::type = 0
>
+ #endif
operator T() const
{
return this->getValue<T>();
mutable std::map<std::string, AttributeValue> m_values;
std::vector<std::string> m_resourceTypes;
std::vector<std::string> m_interfaces;
+ std::vector<std::string> m_dataModelVersions;
InterfaceType m_interfaceType;
};
m_resourceUri{},
m_queryParameters{},
m_requestHandlerFlag{},
+ m_messageID{},
m_representation{},
m_observationInfo{},
m_headerOptions{},
{
}
+ #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
*/
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;
m_requestHandlerFlag = requestHandlerFlag;
}
+ void setMessageID(int16_t messageID)
+ {
+ m_messageID = messageID;
+ }
+
void setObservationInfo(const ObservationInfo& observationInfo)
{
m_observationInfo = observationInfo;
std::mutex serverWrapperLock;
std::map <OCResourceHandle, OC::EntityHandler> entityHandlerMap;
std::map <OCResourceHandle, std::string> resourceUriMap;
- EntityHandler defaultDeviceEntityHandler = 0;
+ EntityHandler defaultDeviceEntityHandler;
}
}
{
pRequest->setRequestHandle(entityHandlerRequest->requestHandle);
pRequest->setResourceHandle(entityHandlerRequest->resource);
+ pRequest->setMessageID(entityHandlerRequest->messageID);
}
if(flag & OC_REQUEST_FLAG)
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);
((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<bool>(br);
}
+ #endif
template<>
void get_payload_array::copy_to_array(std::string item, void* array, size_t pos)
m_interfaces = resourceInterfaces;
}
+ const std::vector<std::string>& 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();
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;
}
// 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<T>::type;
// contains the AttributeType for this base-type
- constexpr static AttributeType enum_base_type =
+ BOOST_STATIC_CONSTEXPR AttributeType enum_base_type =
AttributeTypeConvert<T>::type;
// depth of the vector
- constexpr static size_t depth = 0;
+ BOOST_STATIC_CONSTEXPR size_t depth = 0;
};
template<typename T>
{
typedef T type;
typedef typename type_info<typename T::value_type>::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<typename T::value_type>::enum_base_type;
- constexpr static size_t depth = 1 +
+ BOOST_STATIC_CONSTEXPR size_t depth = 1 +
type_info<typename T::value_type>::depth;
};
{
typedef std::vector<uint8_t> type;
typedef std::vector<uint8_t> 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;
};
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',