# Build liboc
SConscript('src/SConscript')
-if target_os not in ['arduino','darwin','ios','android']:
+if target_os not in ['arduino','darwin','ios','android','tizen']:
# Build examples
SConscript('examples/SConscript')
#else
#define DEBUG DLOG_DEBUG
#define INFO DLOG_INFO
-#define WARNING DLOG_WARNING
+#define WARNING DLOG_WARN
#define ERROR DLOG_ERROR
#define FATAL DLOG_ERROR
#endif
#ifdef __cplusplus
}
#endif // __cplusplus
-#endif /* U_LOGGER_H_ */
-
+#endif /* U_LOGGER_H_ */
\ No newline at end of file
va_end(ap);
}
-#endif //ARDUINO
-
+#endif //ARDUINO
\ No newline at end of file
* This file provides the APIs for EDR Network Monitor.
*/
+#include <glib.h>
#include <string.h>
#include <bluetooth.h>
#include "caqueueingthread.h"
#include "caremotehandler.h"
+static GMainLoop *g_mainloop = NULL;
+static ca_thread_pool_t g_threadPoolHandle = NULL;
+
/**
* @var g_edrNetworkChangeCallback
* @brief Maintains the callback to be notified on local bluetooth adapter status change.
static void CAEDRAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState,
void *userData);
+void *GMainLoopThread (void *param)
+{
+ g_main_loop_run(g_mainloop);
+ return NULL;
+}
+
CAResult_t CAEDRInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
{
OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
-
- // Initialize Bluetooth service
- int err = bt_initialize();
- if (BT_ERROR_NONE != err)
- {
- OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth initialization failed!, error num [%x]",
- err);
- return CA_STATUS_FAILED;
- }
-
+ g_threadPoolHandle = threadPool;
OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
{
OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
+ g_mainloop = g_main_loop_new(NULL, 0);
+ if(!g_mainloop)
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "g_main_loop_new failed\n");
+ return CA_STATUS_FAILED;
+ }
+
+ if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, GMainLoopThread, (void *) NULL))
+ {
+ OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create thread!");
+ return CA_STATUS_FAILED;
+ }
+
+ // Initialize Bluetooth service
+ int err = bt_initialize();
+ if (BT_ERROR_NONE != err)
+ {
+ OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Bluetooth initialization failed!, error num [%x]",
+ err);
+ return CA_STATUS_FAILED;
+ }
+
int ret = bt_adapter_set_state_changed_cb(CAEDRAdapterStateChangeCallback, NULL);
if(BT_ERROR_NONE != ret)
{
OIC_LOG(ERROR, EDR_ADAPTER_TAG, "bt_adapter_set_state_changed_cb failed");
return CA_STATUS_FAILED;
}
+
+ if (g_mainloop)
+ g_main_loop_unref(g_mainloop);
+
OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
#ifdef __ANDROID__
#include <android/log.h>
+#elif defined(__TIZEN__)
+#include <dlog.h>
#elif defined ARDUINO
#include "Arduino.h"
#include <avr/pgmspace.h>
FATAL
} LogLevel;
+#ifdef __TIZEN__
-#ifndef ARDUINO
+int OCGetTizenLogLevel(LogLevel level);
+#endif
+
+#ifdef __TIZEN__
+#define OCLog(level,tag,mes)
+#define OCLogv(level,tag,fmt,args...)
+#elif defined(ANDROID) || defined(__linux__) || defined(__APPLE__)
/**
* Configure logger to use a context that defines a custom logger function
*
#endif
#ifdef TB_LOG
- // These macros are defined for Linux, Android, and Arduino
+#ifdef __TIZEN__
+ #define OC_LOG(level,tag,mes) LOG_(LOG_ID_MAIN, OCGetTizenLogLevel(level), tag, mes)
+ #define OC_LOG_V(level,tag,fmt,args...) LOG_(LOG_ID_MAIN, OCGetTizenLogLevel(level), tag, fmt,##args)
+ #define OC_LOG_BUFFER(level, tag, buffer, bufferSize)
+#else // These macros are defined for Linux, Android, and Arduino
#define OC_LOG_INIT() OCLogInit()
#define OC_LOG(level, tag, logStr) OCLog((level), (tag), (logStr))
#define OC_LOG_BUFFER(level, tag, buffer, bufferSize) OCLogBuffer((level), (tag), (buffer), (bufferSize))
// Define variable argument log function for Linux and Android
#define OC_LOG_V(level, tag, ...) OCLogv((level), (tag), __VA_ARGS__)
#endif
-
+#endif
#else
#define OC_LOG_CONFIG(ctx)
#define OC_LOG_SHUTDOWN()
#include "oc_logger.h"
#include "oc_console_logger.h"
+#ifndef __TIZEN__
static oc_log_ctx_t *logCtx = 0;
static oc_log_level LEVEL_XTABLE[] = {OC_LOG_DEBUG, OC_LOG_INFO, OC_LOG_WARNING, OC_LOG_ERROR, OC_LOG_FATAL};
+#endif
static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1; // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
// Convert LogLevel to platform-specific severity level. Store in PROGMEM on Arduino
#ifndef ARDUINO
+#ifdef __TIZEN__
+
+int OCGetTizenLogLevel(LogLevel level)
+{
+ switch(level)
+ {
+ case DEBUG:
+ return DLOG_DEBUG;
+ case INFO:
+ return DLOG_INFO;
+ case WARNING:
+ return DLOG_WARN;
+ case ERROR:
+ return DLOG_ERROR;
+ case FATAL:
+ return DLOG_FATAL;
+ }
+ return DLOG_DEBUG;
+}
+#else
void OCLogConfig(oc_log_ctx_t *ctx) {
logCtx = ctx;
}
OCLog(level, tag, lineBuffer);
}
}
-
+#endif //__TIZEN__
#else
/**
* Initialize the serial logger for Arduino
--- /dev/null
+##
+# This script includes generic build options:
+# release/debug, target os, target arch, cross toolchain, build environment etc
+##
+import os
+import platform
+
+print "Inside the Config SConscript"
+# 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', 'tizen'],
+ 'darwin': ['darwin', 'ios', 'android', 'arduino'],
+ }
+
+# Map of os and allowed archs (os: allowed archs)
+os_arch_map = {
+ 'linux': ['x86', 'x86_64', 'arm', 'arm64'],
+ 'android': ['x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'armeabi-v7a-hard', 'arm64-v8a'],
+ 'windows': ['x86', 'amd64', 'arm'],
+ 'winrt': ['arm'],
+ 'darwin': ['i386', 'x86_64'],
+ 'ios': ['i386', 'x86_64', 'armv7', 'armv7s', 'arm64'],
+ 'arduino': ['avr', 'arm'],
+ 'yocto': ['x86', 'x86_64'],
+ 'tizen': ['armv7'],
+ }
+
+host = platform.system().lower()
+
+if not host_target_map.has_key(host):
+ print "\nError: Current system (%s) isn't supported\n" % host
+ Exit(1)
+
+######################################################################
+# Get build options (the optins from command line)
+######################################################################
+target_os = ARGUMENTS.get('TARGET_OS', host).lower() # target os
+
+if target_os not in host_target_map[host]:
+ print "\nError: Unknown target os: %s (Allow values: %s)\n" % (target_os, host_target_map[host])
+ Exit(1)
+
+default_arch = platform.machine()
+if default_arch not in os_arch_map[target_os]:
+ default_arch = os_arch_map[target_os][0].lower()
+
+target_arch = ARGUMENTS.get('TARGET_ARCH', default_arch) # target arch
+
+######################################################################
+# Common build options (release, target os, target arch)
+######################################################################
+help_vars = Variables()
+help_vars.Add(BoolVariable('RELEASE', 'Build for release?', True)) # set to 'no', 'false' or 0 for debug
+help_vars.Add(EnumVariable('TARGET_OS', 'Target platform', host, host_target_map[host]))
+help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'ALL', ['ALL', 'IP', 'BT', 'BLE']))
+help_vars.Add(EnumVariable('TARGET_ARCH', 'Target architecture', default_arch, os_arch_map[target_os]))
+help_vars.Add(EnumVariable('SECURED', 'Build with DTLS', '0', allowed_values=('0', '1')))
+
+######################################################################
+# Platform(build target) specific options: SDK/NDK & toolchain
+######################################################################
+targets_support_cc = ['linux', 'arduino', 'tizen']
+
+if target_os in targets_support_cc:
+ # Set cross compile toolchain
+ help_vars.Add('TC_PREFIX', "Toolchain prefix (Generally only be required for cross-compiling)", os.environ.get('TC_PREFIX'))
+ help_vars.Add(PathVariable('TC_PATH',
+ 'Toolchain path (Generally only be required for cross-compiling)',
+ os.environ.get('TC_PATH')))
+
+if target_os in ['android', 'arduino']: # Android/Arduino always uses GNU compiler regardless of the host
+ env = Environment(variables = help_vars,
+ tools = ['gnulink', 'gcc', 'g++', 'ar', 'as']
+ )
+else:
+ env = Environment(variables = help_vars, TARGET_ARCH = target_arch, TARGET_OS = target_os)
+
+Help(help_vars.GenerateHelpText(env))
+
+tc_set_msg = '''
+************************************ Warning **********************************
+* Enviornment variable TC_PREFIX/TC_PATH is set. It will change the default *
+* toolchain, if it isn't what you expect you should unset it, otherwise it may*
+* cause inexplicable errors. *
+*******************************************************************************
+'''
+
+if target_os in targets_support_cc:
+ prefix = env.get('TC_PREFIX')
+ tc_path = env.get('TC_PATH')
+ if prefix:
+ env.Replace(CC = prefix + 'gcc')
+ env.Replace(CXX = prefix + 'g++')
+ env.Replace(AR = prefix + 'ar')
+ env.Replace(AS = prefix + 'as')
+ env.Replace(LINK = prefix + 'ld')
+ env.Replace(RANLIB = prefix + 'ranlib')
+
+ if tc_path:
+ env.PrependENVPath('PATH', tc_path)
+ sys_root = os.path.abspath(tc_path + '/../')
+ env.AppendUnique(CCFLAGS = ['--sysroot=' + sys_root])
+ env.AppendUnique(LINKFLAGS = ['--sysroot=' + sys_root])
+
+ if prefix or tc_path:
+ print tc_set_msg
+
+# Ensure scons be able to change its working directory
+env.SConscriptChdir(1)
+
+# Set the source directory and build directory
+# Source directory: 'dir'
+# Build directory: 'dir'/out/<target_os>/<target_arch>/<release or debug>/
+#
+# You can get the directory as following:
+# env.get('SRC_DIR')
+# env.get('BUILD_DIR')
+
+def __set_dir(env, dir):
+ if not os.path.exists(dir + '/SConstruct'):
+ print '''
+*************************************** Error *********************************
+* The directory(%s) seems isn't a source code directory, no SConstruct file is
+* found. *
+*******************************************************************************
+''' % dir
+ Exit(1)
+
+ if env.get('RELEASE'):
+ build_dir = dir + '/out/' + target_os + '/' + target_arch + '/release/'
+ else:
+ build_dir = dir + '/out/' + target_os + '/' + target_arch + '/debug/'
+ env.VariantDir(build_dir, dir, duplicate=0)
+
+ env.Replace(BUILD_DIR = build_dir)
+ env.Replace(SRC_DIR = dir)
+
+def __src_to_obj(env, src, home = ''):
+ obj = env.get('BUILD_DIR') + src.replace(home, '')
+ if env.get('OBJSUFFIX'):
+ obj += env.get('OBJSUFFIX')
+ return env.Object(obj, src)
+
+def __install(ienv, targets, name):
+ i_n = ienv.Install(env.get('BUILD_DIR'), targets)
+ Alias(name, i_n)
+ env.AppendUnique(TS = [name])
+
+def __append_target(ienv, target):
+ env.AppendUnique(TS = [target])
+
+def __print_targets(env):
+ Help('''
+===============================================================================
+Targets:\n ''')
+ for t in env.get('TS'):
+ Help(t + ' ')
+ Help('''
+\nDefault all targets will be built. You can specify the target to build:
+
+ $ scons [options] [target]
+===============================================================================
+''')
+
+env.AddMethod(__set_dir, 'SetDir')
+env.AddMethod(__print_targets, 'PrintTargets')
+env.AddMethod(__src_to_obj, 'SrcToObj')
+env.AddMethod(__append_target, 'AppendTarget')
+env.AddMethod(__install, 'InstallTarget')
+env.SetDir(env.GetLaunchDir())
+env['ROOT_DIR']=env.GetLaunchDir()
+
+Export('env')
+
+######################################################################
+# Link scons to Yocto cross-toolchain ONLY when target_os is yocto
+######################################################################
+if target_os == "yocto":
+ '''
+ This code injects Yocto cross-compilation tools+flags into scons'
+ build environment in order to invoke the relevant tools while
+ performing a build.
+ '''
+ import os.path
+ try:
+ CC = os.environ['CC']
+ target_prefix = CC.split()[0]
+ target_prefix = target_prefix[:len(target_prefix)-3]
+ tools = {"CC" : target_prefix+"gcc",
+ "CXX" : target_prefix+"g++",
+ "AS" : target_prefix+"as",
+ "LD" : target_prefix+"ld",
+ "GDB" : target_prefix+"gdb",
+ "STRIP" : target_prefix+"strip",
+ "RANLIB" : target_prefix+"ranlib",
+ "OBJCOPY" : target_prefix+"objcopy",
+ "OBJDUMP" : target_prefix+"objdump",
+ "AR" : target_prefix+"ar",
+ "NM" : target_prefix+"nm",
+ "M4" : "m4",
+ "STRINGS": target_prefix+"strings"}
+ PATH = os.environ['PATH'].split(os.pathsep)
+ for tool in tools:
+ if tool in os.environ:
+ for path in PATH:
+ if os.path.isfile(os.path.join(path, tools[tool])):
+ env[tool] = os.path.join(path, os.environ[tool])
+ break
+ except:
+ print "ERROR in Yocto cross-toolchain environment"
+ Exit(1)
+ '''
+ Now reset TARGET_OS to linux so that all linux specific build configurations
+ hereupon apply for the entirety of the build process.
+ '''
+ env['TARGET_OS'] = 'linux'
+ '''
+ We want to preserve debug symbols to allow BitBake to generate both DEBUG and
+ RELEASE packages for OIC.
+ '''
+ env['CCFLAGS'].append('-g')
+ Export('env')
+else:
+ '''
+ If target_os is not Yocto, continue with the regular build process
+ '''
+ # Load config of target os
+ env.SConscript(target_os + '/SConscript')
+
+# Delete the temp files of configuration
+if env.GetOption('clean'):
+ dir = env.get('SRC_DIR')
+
+ if os.path.exists(dir + '/config.log'):
+ Execute(Delete(dir + '/config.log'))
+ Execute(Delete(dir + '/.sconsign.dblite'))
+ Execute(Delete(dir + '/.sconf_temp'))
+
+Return('env')
+
--- /dev/null
+##
+# The main build script
+#
+##
+
+# Load common build config
+# Load common build config
+SConscript('SConscript')
+
+Import('env')
+
+target_os = env.get('TARGET_OS')
+transport = env.get('TARGET_TRANSPORT')
+
+print "Given Transport is %s" % transport
+print "Given OS is %s" % target_os
+print "Secured %s" % env.get('SECURED')
+
+if target_os == 'tizen':
+ SConscript('scons/SConscript')
+else:
+ print "Given platform is not supported"
+
--- /dev/null
+<manifest>
+ <define>
+ <domain name="risample" />
+ <permit>
+ <smack permit="system::use_internet" type="rwx"/>
+ </permit>
+ <request>
+ <smack request="system::use_internet" type="rwx"/>
+ <smack request="bt-service" type="rwx"/>
+ <smack request="sap" type="rwx"/>
+ <smack request="bt-service::spp" type="rwx"/>
+ <smack request="bt-service::gap" type="rwx"/>
+ <smack request="bt-service::admin" type="rwx"/>
+ <smack request="bt-service::manager" type="rwx"/>
+ <smack request="bt-service::public" type="rwx"/>
+ <smack request="bt-service::platform" type="rwx"/>
+ </request>
+ </define>
+ <assign>
+ <filesystem path="/opt/apps/com.oic.ri.sample/bin/sample" exec_label="sample" />
+ </assign>
+ <request>
+ <domain name="risample" />
+ </request>
+</manifest>
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" package="com.oic.ri.sample" version="0.1.12" install-location="internal-only">
+ <label>risample</label>
+ <author email="oic" href="www.iotivity.org">OIC</author>
+ <description>risample</description>
+ <ui-application appid="com.oic.ri.sample" exec="/usr/apps/com.oic.ri.sample/bin/sample" nodisplay="false" multiple="false" type="capp" taskmanage="true">
+ <icon>com.oic.ri.sample.png</icon>
+ <label>risample</label>
+ <label xml:lang="en-us">risample</label>
+ <label xml:lang="nl-nl">risample</label>
+ </ui-application>
+ <privileges>
+ <privilege>http://tizen.org/privilege/socket</privilege>
+ </privileges>
+
+</manifest>
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ocstack.h>
+
+const char *getResult(OCStackResult result)
+{
+ switch (result)
+ {
+ case OC_STACK_OK:
+ return "OC_STACK_OK";
+ case OC_STACK_RESOURCE_CREATED:
+ return "OC_STACK_RESOURCE_CREATED";
+ case OC_STACK_RESOURCE_DELETED:
+ return "OC_STACK_RESOURCE_DELETED";
+ case OC_STACK_INVALID_URI:
+ return "OC_STACK_INVALID_URI";
+ case OC_STACK_INVALID_QUERY:
+ return "OC_STACK_INVALID_QUERY";
+ case OC_STACK_INVALID_IP:
+ return "OC_STACK_INVALID_IP";
+ case OC_STACK_INVALID_PORT:
+ return "OC_STACK_INVALID_PORT";
+ case OC_STACK_INVALID_CALLBACK:
+ return "OC_STACK_INVALID_CALLBACK";
+ case OC_STACK_INVALID_METHOD:
+ return "OC_STACK_INVALID_METHOD";
+ case OC_STACK_NO_MEMORY:
+ return "OC_STACK_NO_MEMORY";
+ case OC_STACK_COMM_ERROR:
+ return "OC_STACK_COMM_ERROR";
+ case OC_STACK_INVALID_PARAM:
+ return "OC_STACK_INVALID_PARAM";
+ case OC_STACK_NOTIMPL:
+ return "OC_STACK_NOTIMPL";
+ case OC_STACK_NO_RESOURCE:
+ return "OC_STACK_NO_RESOURCE";
+ case OC_STACK_RESOURCE_ERROR:
+ return "OC_STACK_RESOURCE_ERROR";
+ case OC_STACK_SLOW_RESOURCE:
+ return "OC_STACK_SLOW_RESOURCE";
+ case OC_STACK_NO_OBSERVERS:
+ return "OC_STACK_NO_OBSERVERS";
+#ifdef WITH_PRESENCE
+ case OC_STACK_PRESENCE_STOPPED:
+ return "OC_STACK_PRESENCE_STOPPED";
+ case OC_STACK_PRESENCE_TIMEOUT:
+ return "OC_STACK_PRESENCE_TIMEOUT";
+#endif
+ case OC_STACK_ERROR:
+ return "OC_STACK_ERROR";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+void StripNewLineChar(char* str)
+{
+ int i = 0;
+ if (str)
+ {
+ while( str[i])
+ {
+ if (str[i] == '\n')
+ {
+ str[i] = '\0';
+ }
+ i++;
+ }
+ }
+}
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <iostream>
+#include <sstream>
+#include "ocstack.h"
+#include "logger.h"
+#include "occlient.h"
+#include "ocpayload.h"
+using namespace std;
+
+// Tracking user input
+static int UNICAST_DISCOVERY = 0;
+static int TEST_CASE = 0;
+static int CONNECTIVITY = 0;
+
+static const char * UNICAST_DEVICE_DISCOVERY_QUERY = "coap://%s/oic/d";
+static const char * MULTICAST_DEVICE_DISCOVERY_QUERY = "/oic/d";
+static const char * UNICAST_PLATFORM_DISCOVERY_QUERY = "coap://%s/oic/p";
+static const char * MULTICAST_PLATFORM_DISCOVERY_QUERY = "/oic/p";
+
+static const char * UNICAST_RESOURCE_DISCOVERY_QUERY = "coap://%s/oic/res";
+static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
+// The following variable determines the interface protocol (IPv4, IPv6, etc)
+//to be used for sending unicast messages. Default set to IPv4.
+static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
+static std::string coapServerIP = "255.255.255.255";
+static std::string coapServerPort = "5683";
+static std::string coapServerResource = "/a/light";
+// Size to hold ADDRESS
+static const int MAX_ADDR_SIZE = 24;
+//Use unicastAddr for both InitDiscovery and InitPlatformOrDeviceDiscovery
+char unicastAddr[MAX_ADDR_SIZE];
+void StripNewLineChar(char* str);
+
+// The handle for the observe registration
+OCDoHandle gObserveDoHandle;
+#ifdef WITH_PRESENCE
+// The handle for observe registration
+OCDoHandle gPresenceHandle;
+#endif
+// After this crosses a threshold client deregisters for further notifications
+int gNumObserveNotifies = 0;
+
+#ifdef WITH_PRESENCE
+int gNumPresenceNotifies = 0;
+#endif
+
+int gQuitFlag = 0;
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+ if (signum == SIGINT)
+ {
+ gQuitFlag = 1;
+ }
+}
+
+OCPayload* putPayload()
+{
+ OCRepPayload* payload = OCRepPayloadCreate();
+
+ if(!payload)
+ {
+ std::cout << "Failed to create put payload object"<<std::endl;
+ std::exit(1);
+ }
+
+ OCRepPayloadSetPropInt(payload, "power", 15);
+ OCRepPayloadSetPropBool(payload, "state", true);
+
+ return (OCPayload*) payload;
+}
+
+static void PrintUsage()
+{
+ cout << "Hello";
+ cout << "\nUsage : occlient -u <0|1> -t <1..17> -c <0|1|2>";
+ cout << "\n-u <0|1> : Perform multicast/unicast discovery of resources";
+ cout << "\n-c 0 : Default IPv4 and IPv6 auto-selection";
+ cout << "\n-c 1 : IPv4 Connectivity Type";
+ cout << "\n-c 2 : IPv6 Connectivity Type (IPv6 not currently supported)";
+ cout << "\n-c 3 : EDR Connectivity Type (IPv6 not currently supported)";
+ cout << "\n-t 1 : Discover Resources";
+ cout << "\n-t 2 : Discover Resources and Initiate Nonconfirmable Get Request";
+ cout << "\n-t 3 : Discover Resources and Initiate Nonconfirmable Get Request with query filter";
+ cout << "\n-t 4 : Discover Resources and Initiate Nonconfirmable Put Requests";
+ cout << "\n-t 5 : Discover Resources and Initiate Nonconfirmable Post Requests";
+ cout << "\n-t 6 : Discover Resources and Initiate Nonconfirmable Delete Requests";
+ cout << "\n-t 7 : Discover Resources and Initiate Nonconfirmable Observe Requests";
+ cout << "\n-t 8 : Discover Resources and Initiate Nonconfirmable Get Request for a resource";
+ cout << "which is unavailable";
+ cout << "\n-t 9 : Discover Resources and Initiate Confirmable Get Request";
+ cout << "\n-t 10 : Discover Resources and Initiate Confirmable Post Request";
+ cout << "\n-t 11 : Discover Resources and Initiate Confirmable Delete Requests";
+ cout << "\n-t 12 : Discover Resources and Initiate Confirmable Observe Requests and";
+ cout << "cancel with Low QoS";
+
+#ifdef WITH_PRESENCE
+ cout << "\n-t 13 : Discover Resources and Initiate Nonconfirmable presence";
+ cout << "\n-t 14 : Discover Resources and Initiate Nonconfirmable presence with filter";
+ cout << "\n-t 15 : Discover Resources and Initiate Nonconfirmable presence with 2 filters";
+ cout << "\n-t 16 : Discover Resources and Initiate Nonconfirmable multicast presence.";
+#endif
+
+ cout << "\n-t 17 : Discover Resources and Initiate Nonconfirmable Observe Requests";
+ cout << "then cancel immediately with High QOS";
+ cout << "\n-t 18 : Discover Resources and Initiate Nonconfirmable Get Request and add";
+ cout << "vendor specific header options";
+ cout << "\n-t 19 : Discover Platform";
+ cout << "\n-t 20 : Discover Devices";
+}
+
+OCStackResult InvokeOCDoResource(std::ostringstream &query,
+ OCMethod method,
+ OCQualityOfService qos,
+ OCClientResponseHandler cb,
+ OCHeaderOption * options,
+ uint8_t numOptions)
+{
+ OCStackResult ret;
+ OCCallbackData cbData;
+ OCDoHandle handle;
+
+ cbData.cb = cb;
+ cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ ret = OCDoResource(&handle, method, query.str().c_str(), 0,
+ (method == OC_REST_PUT) ? putPayload() : NULL,
+ (OC_CONNTYPE), qos, &cbData, options, numOptions);
+
+ if (ret != OC_STACK_OK)
+ {
+ cout << "\nOCDoResource returns error "<< ret;
+ cout << " with method " << method;
+ }
+ else if (method == OC_REST_OBSERVE || method == OC_REST_OBSERVE_ALL)
+ {
+ gObserveDoHandle = handle;
+ }
+#ifdef WITH_PRESENCE
+ else if (method == OC_REST_PRESENCE)
+ {
+ gPresenceHandle = handle;
+ }
+#endif
+
+ return ret;
+}
+
+OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+ if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for PUT recvd successfully";
+ }
+
+ if(clientResponse)
+ {
+ cout << "\nStackResult: " << getResult(clientResponse->result);
+ cout << "\nJSON = " << clientResponse->payload;
+ }
+ else
+ {
+ cout << "\nputReqCB received Null clientResponse";
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle, OCClientResponse *clientResponse)
+{
+ if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for POST recvd successfully";
+ }
+
+ if(clientResponse)
+ {
+ cout << "\nStackResult: " << getResult(clientResponse->result);
+ cout << "\nJSON = " << clientResponse->payload;
+ }
+ else
+ {
+ cout << "\npostReqCB received Null clientResponse";
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult deleteReqCB(void *ctx,
+ OCDoHandle handle, OCClientResponse *clientResponse)
+{
+ if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for DELETE recvd successfully";
+ }
+
+ if(clientResponse)
+ {
+ cout << "\nStackResult: " << getResult(clientResponse->result);
+ //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+ }
+ else
+ {
+ cout << "\ndeleteReqCB received Null clientResponse";
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+ if(clientResponse == NULL)
+ {
+ cout << "\ngetReqCB received NULL clientResponse";
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for GET query recvd successfully";
+ }
+
+ cout << "\nStackResult: " << getResult(clientResponse->result);
+ cout << "\nSEQUENCE NUMBER: " << clientResponse->sequenceNumber;
+ //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+ if(clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
+ {
+ cout << "\nReceived vendor specific options";
+ uint8_t i = 0;
+ OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions;
+ for( i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
+ {
+ if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
+ {
+ cout << "\nReceived option ID " << ((OCHeaderOption)rcvdOptions[i]).optionID;
+ }
+ }
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+ if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for OBS query recvd successfully";
+ }
+
+ if(clientResponse)
+ {
+ cout << "\nStackResult: " << getResult(clientResponse->result);
+ cout << "\nSEQUENCE NUMBER: " << clientResponse->sequenceNumber;
+ cout << "\nCallback Context for OBSERVE notification recvd successfully ";
+ //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+ gNumObserveNotifies++;
+ if (gNumObserveNotifies == 15) //large number to test observing in DELETE case.
+ {
+ if(TEST_CASE == TEST_OBS_REQ_NON || TEST_CASE == TEST_OBS_REQ_CON)
+ {
+ if (OCCancel (gObserveDoHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
+ {
+ cout << "\nObserve cancel error";
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ else if(TEST_CASE == TEST_OBS_REQ_NON_CANCEL_IMM)
+ {
+ if (OCCancel (gObserveDoHandle, OC_HIGH_QOS, NULL, 0) != OC_STACK_OK)
+ {
+ cout << "\nObserve cancel error";
+ }
+ }
+ }
+ if(clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
+ {
+ cout << "\nThis also serves as a registration confirmation";
+ }
+ else if(clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
+ {
+ cout << "\nThis also serves as a deregistration confirmation";
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ else if(clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
+ {
+ cout << "\nThis also tells you that registration/deregistration failed";
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ else
+ {
+ cout << "\nobsReqCB received Null clientResponse";
+ }
+ return OC_STACK_KEEP_TRANSACTION;
+}
+#ifdef WITH_PRESENCE
+OCStackApplicationResult presenceCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+ if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for Presence recvd successfully";
+ }
+
+ if (clientResponse)
+ {
+ cout << "\nStackResult: " << getResult(clientResponse->result);
+ cout << "\nNONCE NUMBER: " << clientResponse->sequenceNumber;
+ cout << "\nCallback Context for Presence notification recvd successfully ";
+ //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+ gNumPresenceNotifies++;
+ if (gNumPresenceNotifies == 20)
+ {
+ if (OCCancel(gPresenceHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
+ {
+ cout << "\nPresence cancel error";
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ else
+ {
+ cout << "\npresenceCB received Null clientResponse";
+ }
+ return OC_STACK_KEEP_TRANSACTION;
+}
+#endif
+
+// This is a function called back when a device is discovered
+OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for DISCOVER query recvd successfully";
+ }
+
+ if (clientResponse)
+ {
+ cout << "\nStackResult: " << getResult(clientResponse->result);
+
+ std::string connectionType = getConnectivityType (clientResponse->connType);
+ cout << "\nDiscovered on " << connectionType.c_str();
+ cout << "\nDevice ======> Discovered ";
+ cout << clientResponse->devAddr.addr;
+ //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
+ if (65600 == clientResponse->connType)
+ {
+ cout << ":" << clientResponse->devAddr.port;
+ }
+ //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+ cout << "\nConnectivity type: " << clientResponse->connType;
+ OC_CONNTYPE = clientResponse->connType;
+ parseClientResponse(clientResponse);
+
+ switch(TEST_CASE)
+ {
+ case TEST_GET_REQ_NON:
+ InitGetRequest(OC_LOW_QOS, 0, 0);
+ break;
+ case TEST_GET_REQ_NON_WITH_FILTERS:
+ InitGetRequest(OC_LOW_QOS, 0, 1);
+ break;
+ case TEST_PUT_REQ_NON:
+ InitPutRequest(OC_LOW_QOS);
+ break;
+ case TEST_POST_REQ_NON:
+ InitPostRequest(OC_LOW_QOS);
+ break;
+ case TEST_DELETE_REQ_NON:
+ InitDeleteRequest(OC_LOW_QOS);
+ break;
+ case TEST_OBS_REQ_NON:
+ case TEST_OBS_REQ_NON_CANCEL_IMM:
+ InitObserveRequest(OC_LOW_QOS);
+ break;
+ case TEST_GET_UNAVAILABLE_RES_REQ_NON:
+ InitGetRequestToUnavailableResource(OC_LOW_QOS);
+ break;
+ case TEST_GET_REQ_CON:
+ InitGetRequest(OC_HIGH_QOS, 0, 0);
+ break;
+ case TEST_POST_REQ_CON:
+ InitPostRequest(OC_HIGH_QOS);
+ break;
+ case TEST_DELETE_REQ_CON:
+ InitDeleteRequest(OC_HIGH_QOS);
+ break;
+ case TEST_OBS_REQ_CON:
+ InitObserveRequest(OC_HIGH_QOS);
+ break;
+#ifdef WITH_PRESENCE
+ case TEST_OBS_PRESENCE:
+ case TEST_OBS_PRESENCE_WITH_FILTER:
+ case TEST_OBS_PRESENCE_WITH_FILTERS:
+ case TEST_OBS_MULTICAST_PRESENCE:
+ InitPresence();
+ break;
+#endif
+ case TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS:
+ InitGetRequest(OC_LOW_QOS, 1, 0);
+ break;
+ case TEST_DISCOVER_PLATFORM_REQ:
+ InitPlatformDiscovery(OC_LOW_QOS);
+ break;
+ case TEST_DISCOVER_DEV_REQ:
+ InitDeviceDiscovery(OC_LOW_QOS);
+ break;
+ default:
+ PrintUsage();
+ break;
+ }
+ }
+ else
+ {
+ cout << "\ndiscoveryReqCB received Null clientResponse";
+ }
+ return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult PlatformDiscoveryReqCB (void* ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for Platform DISCOVER query recvd successfully";
+ }
+
+ if(clientResponse)
+ {
+ //OC_LOG truncates the response as it is too long.
+ //OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+ }
+ else
+ {
+ cout << "\nPlatformDiscoveryReqCB received Null clientResponse";
+ }
+
+ return (UNICAST_DISCOVERY) ? OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+ {
+ cout << "\nCallback Context for Device DISCOVER query recvd successfully";
+ }
+
+ if(clientResponse)
+ {
+ //OC_LOG truncates the response as it is too long.
+ cout << "\nDiscovery response: ";
+ cout << clientResponse->payload;
+ }
+ else
+ {
+ cout << "\nPlatformDiscoveryReqCB received Null clientResponse";
+ }
+
+ return (UNICAST_DISCOVERY) ? OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION;
+}
+
+#ifdef WITH_PRESENCE
+int InitPresence()
+{
+ OCStackResult result = OC_STACK_OK;
+ cout << "\nExecuting " << __func__;
+ std::ostringstream query;
+ std::ostringstream querySuffix;
+ query << "coap://" << coapServerIP << ":" << coapServerPort << OC_RSRVD_PRESENCE_URI;
+ if(TEST_CASE == TEST_OBS_PRESENCE)
+ {
+ result = InvokeOCDoResource(query, OC_REST_PRESENCE, OC_LOW_QOS,
+ presenceCB, NULL, 0);
+ }
+ if(TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTER || TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTERS)
+ {
+ querySuffix.str("");
+ querySuffix << query.str() << "?rt=core.led";
+ result = InvokeOCDoResource(querySuffix, OC_REST_PRESENCE, OC_LOW_QOS,
+ presenceCB, NULL, 0);
+ }
+ if(TEST_CASE == TEST_OBS_PRESENCE_WITH_FILTERS)
+ {
+ if(result == OC_STACK_OK)
+ {
+ querySuffix.str("");
+ querySuffix << query.str() << "?rt=core.fan";
+ result = InvokeOCDoResource(querySuffix, OC_REST_PRESENCE, OC_LOW_QOS,
+ presenceCB, NULL, 0);
+ }
+ }
+ if(TEST_CASE == TEST_OBS_MULTICAST_PRESENCE)
+ {
+ if(result == OC_STACK_OK)
+ {
+ std::ostringstream multicastPresenceQuery;
+ multicastPresenceQuery.str("");
+ multicastPresenceQuery << "coap://" << OC_MULTICAST_PREFIX << OC_RSRVD_PRESENCE_URI;
+ result = InvokeOCDoResource(multicastPresenceQuery, OC_REST_PRESENCE, OC_LOW_QOS,
+ presenceCB, NULL, 0);
+ }
+ }
+ return result;
+}
+#endif
+
+int InitGetRequestToUnavailableResource(OCQualityOfService qos)
+{
+ cout << "\nExecuting " << __func__;
+ std::ostringstream query;
+
+ //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
+ if (65600 == OC_CONNTYPE)
+ {
+ query << "coap://" << coapServerIP << ":" << coapServerPort << "/SomeUnknownResource";
+ }
+ else
+ {
+ query << "coap://" << coapServerIP << "/SomeUnknownResource";
+ }
+
+ return (InvokeOCDoResource(query, OC_REST_GET, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS,
+ getReqCB, NULL, 0));
+}
+
+int InitObserveRequest(OCQualityOfService qos)
+{
+ cout << "\nExecuting " << __func__;
+ std::ostringstream query;
+ //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
+ if (65600 == OC_CONNTYPE)
+ {
+ query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+ }
+ else
+ {
+ query << "coap://" << coapServerIP << coapServerResource;
+ }
+ return (InvokeOCDoResource(query,
+ OC_REST_OBSERVE, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS, obsReqCB, NULL, 0));
+}
+
+int InitPutRequest(OCQualityOfService qos)
+{
+ cout << "\nExecuting " << __func__;
+ std::ostringstream query;
+ //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
+ if (65600 == OC_CONNTYPE)
+ {
+ query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+ }
+ else
+ {
+ query << "coap://" << coapServerIP << coapServerResource;
+ }
+ return (InvokeOCDoResource(query, OC_REST_PUT, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS,
+ putReqCB, NULL, 0));
+}
+
+int InitPostRequest(OCQualityOfService qos)
+{
+ OCStackResult result;
+ cout << "\nExecuting " << __func__;
+ std::ostringstream query;
+
+ //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
+ if (65600 == OC_CONNTYPE)
+ {
+ query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+ }
+ else
+ {
+ query << "coap://" << coapServerIP << coapServerResource;
+ }
+
+ // First POST operation (to create an Light instance)
+ result = InvokeOCDoResource(query, OC_REST_POST,
+ ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
+ postReqCB, NULL, 0);
+ if (OC_STACK_OK != result)
+ {
+ // Error can happen if for example, network connectivity is down
+ cout << "\nFirst POST call did not succeed";
+ }
+
+ // Second POST operation (to create an Light instance)
+ result = InvokeOCDoResource(query, OC_REST_POST,
+ ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
+ postReqCB, NULL, 0);
+ if (OC_STACK_OK != result)
+ {
+ cout << "\nSecond POST call did not succeed";
+ }
+
+ // This POST operation will update the original resourced /a/light
+ return (InvokeOCDoResource(query, OC_REST_POST,
+ ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
+ postReqCB, NULL, 0));
+}
+
+void* RequestDeleteDeathResourceTask(void* myqos)
+{
+ sleep (30);//long enough to give the server time to finish deleting the resource.
+ std::ostringstream query;
+
+ //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
+ if (65600 == OC_CONNTYPE)
+ {
+ query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+ }
+ else
+ {
+ query << "coap://" << coapServerIP << coapServerResource;
+ }
+
+ cout << "\nExecuting " << __func__;
+
+ // Second DELETE operation to delete the resource that might have been removed already.
+ OCQualityOfService qos;
+ if (myqos == NULL)
+ {
+ qos = OC_LOW_QOS;
+ }
+ else
+ {
+ qos = OC_HIGH_QOS;
+ }
+
+ OCStackResult result = InvokeOCDoResource(query, OC_REST_DELETE,
+ qos,
+ deleteReqCB, NULL, 0);
+
+ if (OC_STACK_OK != result)
+ {
+ cout << "\nSecond DELETE call did not succeed";
+ }
+
+ return NULL;
+}
+
+int InitDeleteRequest(OCQualityOfService qos)
+{
+ OCStackResult result;
+ std::ostringstream query;
+ //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
+ if (65600 == OC_CONNTYPE)
+ {
+ query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+ }
+ else
+ {
+ query << "coap://" << coapServerIP << coapServerResource;
+ }
+
+ cout << "\nExecuting " << __func__;
+
+ // First DELETE operation
+ result = InvokeOCDoResource(query, OC_REST_DELETE,
+ qos,
+ deleteReqCB, NULL, 0);
+ if (OC_STACK_OK != result)
+ {
+ // Error can happen if for example, network connectivity is down
+ cout << "\nFirst DELETE call did not succeed";
+ }
+ else
+ {
+ //Create a thread to delete this resource again
+ pthread_t threadId;
+ pthread_create (&threadId, NULL, RequestDeleteDeathResourceTask, (void*)qos);
+ }
+
+ cout << "\nExit " << __func__;
+ return result;
+}
+
+int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions, bool getWithQuery)
+{
+
+ OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+ cout << "\nExecuting " << __func__;
+ std::ostringstream query;
+
+ //TODO: Bug in RI layer. Its returning 65600 instead of CT_ADAPTER_IP
+ if (65600 == OC_CONNTYPE)
+ {
+ query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+ }
+ else
+ {
+ query << "coap://" << coapServerIP << coapServerResource;
+ }
+
+ // ocserver is written to only process "power<X" query.
+ if (getWithQuery)
+ {
+ cout << "\nUsing query power<30";
+ query << "?power<50";
+ }
+
+ if (withVendorSpecificHeaderOptions)
+ {
+ uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
+ memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
+ options[0].protocolID = OC_COAP_ID;
+ options[0].optionID = 2048;
+ memcpy(options[0].optionData, option0, sizeof(option0));
+ options[0].optionLength = 10;
+ options[1].protocolID = OC_COAP_ID;
+ options[1].optionID = 3000;
+ memcpy(options[1].optionData, option1, sizeof(option1));
+ options[1].optionLength = 10;
+ }
+ if (withVendorSpecificHeaderOptions)
+ {
+ return (InvokeOCDoResource(query, OC_REST_GET,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, getReqCB, options, 2));
+ }
+ else
+ {
+ return (InvokeOCDoResource(query, OC_REST_GET,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, getReqCB, NULL, 0));
+ }
+}
+
+int InitPlatformDiscovery(OCQualityOfService qos)
+{
+ cout << "\nExecuting " << __func__;
+
+ OCStackResult ret;
+ OCCallbackData cbData;
+ char szQueryUri[64] = { 0 };
+
+ cbData.cb = PlatformDiscoveryReqCB;
+ cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ if(UNICAST_DISCOVERY)
+ {
+ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PLATFORM_DISCOVERY_QUERY, unicastAddr);
+ }
+ else
+ {
+ strncpy(szQueryUri, MULTICAST_PLATFORM_DISCOVERY_QUERY, sizeof(szQueryUri) -1 );
+ }
+ szQueryUri[sizeof(szQueryUri) -1] = '\0';
+
+ if(UNICAST_DISCOVERY)
+ {
+ ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+ }
+ else
+ {
+
+ ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+ }
+
+ if (ret != OC_STACK_OK)
+ {
+ cout << "\nOCStack device error";
+ }
+
+ return ret;
+}
+
+int InitDeviceDiscovery(OCQualityOfService qos)
+{
+ cout << "\nExecuting " << __func__;
+
+ OCStackResult ret;
+ OCCallbackData cbData;
+ char szQueryUri[64] = { 0 };
+
+ cbData.cb = DeviceDiscoveryReqCB;
+ cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ if(UNICAST_DISCOVERY)
+ {
+ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_DEVICE_DISCOVERY_QUERY, unicastAddr);
+ }
+ else
+ {
+ strncpy(szQueryUri, MULTICAST_DEVICE_DISCOVERY_QUERY, sizeof(szQueryUri) -1 );
+ }
+ szQueryUri[sizeof(szQueryUri) -1] = '\0';
+
+ if(UNICAST_DISCOVERY)
+ {
+ ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+ }
+ else
+ {
+ ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+ }
+
+ if (ret != OC_STACK_OK)
+ {
+ cout << "\nOCStack device error";
+ }
+
+ return ret;
+}
+
+int InitDiscovery(OCQualityOfService qos)
+{
+ OCStackResult ret;
+ OCCallbackData cbData;
+ /* Start a discovery query*/
+ char szQueryUri[64] = { 0 };
+
+ if (UNICAST_DISCOVERY)
+ {
+ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_RESOURCE_DISCOVERY_QUERY, unicastAddr);
+ }
+ else
+ {
+ strcpy(szQueryUri, MULTICAST_RESOURCE_DISCOVERY_QUERY);
+ }
+
+ cbData.cb = discoveryReqCB;
+ cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+ if(UNICAST_DISCOVERY)
+ {
+ ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+ }
+ else
+ {
+ ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, 0, 0, OC_CONNTYPE,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, &cbData, NULL, 0);
+ }
+ if (ret != OC_STACK_OK)
+ {
+ cout << "\nOCStack resource error";
+ }
+ return ret;
+}
+
+int main(int argc, char* argv[])
+{
+ int opt;
+
+ while ((opt = getopt(argc, argv, "u:t:c:")) != -1)
+ {
+ switch(opt)
+ {
+ case 'u':
+ UNICAST_DISCOVERY = atoi(optarg);
+ break;
+ case 't':
+ TEST_CASE = atoi(optarg);
+ break;
+ case 'c':
+ CONNECTIVITY = atoi(optarg);
+ break;
+ default:
+ PrintUsage();
+ return -1;
+ }
+ }
+
+ if ((UNICAST_DISCOVERY != 0 && UNICAST_DISCOVERY != 1) ||
+ (TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS) ||
+ (CONNECTIVITY < CT_ADAPTER_DEFAULT || CONNECTIVITY >= MAX_CT))
+ {
+ PrintUsage();
+ return -1;
+ }
+
+ cout << "\nEntering occlient main loop...\n";
+
+ /* Initialize OCStack*/
+ if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
+ {
+ cout << "\nOCStack init error";
+ return 0;
+ }
+
+ if(CONNECTIVITY == CT_ADAPTER_DEFAULT || CONNECTIVITY == CT_IPV4)
+ {
+ OC_CONNTYPE = CT_ADAPTER_IP;
+ }
+ else if(CONNECTIVITY == CT_IPV6)
+ {
+ //TODO: Remove when IPv6 is available.
+ cout << "\nIPv6 is currently not supported !!!!";
+ PrintUsage();
+ return -1;
+ }
+ else if(CONNECTIVITY == CT_EDR)
+ {
+ OC_CONNTYPE = CT_ADAPTER_RFCOMM_BTEDR;
+
+ cout << "\nSelected EDR Adapter!!! Device is scanning for OIC supported Servers....\n";
+ // Sleep is added as after initialization, EDR adapter needs to start scanning and find
+ // the devices.
+ sleep(10);
+ }
+ else
+ {
+ cout << "\nDefault Connectivity type selected...";
+ PrintUsage();
+ }
+
+ if (UNICAST_DISCOVERY)
+ {
+ cout << "\nEnter address of Server hosting resource as given below:";
+ cout << "\nIP Adapter: 192.168.0.15:45454(IP:Port)";
+ cout << "\nEDR/BLE Adapter: AB:BC:CD:DE:EF:FG(MAC Address)";
+ cout << "\nInput: ";
+
+ if (fgets(unicastAddr, MAX_ADDR_SIZE, stdin))
+ {
+ //Strip newline char from unicastAddr
+ StripNewLineChar(unicastAddr);
+ }
+ else
+ {
+ cout << "\n!! Bad input for IPV4 address. !!";
+ return OC_STACK_INVALID_PARAM;
+ }
+ }
+
+ if(UNICAST_DISCOVERY == 0 && TEST_CASE == TEST_DISCOVER_DEV_REQ)
+ {
+ InitDeviceDiscovery(OC_LOW_QOS);
+ }
+ else if(UNICAST_DISCOVERY == 0 && TEST_CASE == TEST_DISCOVER_PLATFORM_REQ)
+ {
+ InitPlatformDiscovery(OC_LOW_QOS);
+ }
+ else
+ {
+ InitDiscovery(OC_LOW_QOS);
+ }
+
+ // Break from loop with Ctrl+C
+ signal(SIGINT, handleSigInt);
+ while (!gQuitFlag)
+ {
+
+ if (OCProcess() != OC_STACK_OK)
+ {
+ cout << "\nOCStack process error\n";
+ return 0;
+ }
+
+ sleep(2);
+ }
+
+ cout << "\nExiting occlient main loop...\n";
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ cout << "\nOCStack stop error\n";
+ }
+
+ return 0;
+}
+
+std::string getIPAddrTBServer(OCClientResponse * clientResponse)
+{
+ if (!clientResponse)
+ {
+ return "";
+ }
+ if (!clientResponse->addr)
+ {
+ return "";
+ }
+
+ return std::string(clientResponse->devAddr.addr);
+}
+
+std::string getPortTBServer(OCClientResponse * clientResponse)
+{
+ if (!clientResponse)
+ {
+ return "";
+ }
+ if (!clientResponse->addr)
+ {
+ return "";
+ }
+ std::ostringstream ss;
+ ss << clientResponse->devAddr.port;
+ return ss.str();
+}
+
+std::string getConnectivityType (OCConnectivityType connType)
+{
+ switch (connType & CT_MASK_ADAPTER)
+ {
+ case CT_ADAPTER_IP:
+ return "IP";
+
+ case CT_IP_USE_V4:
+ return "IPv4";
+
+ case CT_IP_USE_V6:
+ return "IPv6";
+
+ case CT_ADAPTER_GATT_BTLE:
+ return "GATT";
+
+ case CT_ADAPTER_RFCOMM_BTEDR:
+ return "RFCOMM";
+
+ default:
+ return "Incorrect connectivity";
+ }
+}
+
+std::string getQueryStrForGetPut(OCClientResponse * clientResponse)
+{
+
+ return "/a/light";
+}
+
+void parseClientResponse(OCClientResponse * clientResponse)
+{
+ coapServerIP = getIPAddrTBServer(clientResponse);
+ coapServerPort = getPortTBServer(clientResponse);
+ coapServerResource = getQueryStrForGetPut(clientResponse);
+}
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OCCLIENT_H_
+#define OCCLIENT_H_
+
+#include "ocstack.h"
+
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+#define TAG "occlient"
+#define DEFAULT_CONTEXT_VALUE 0x99
+#ifndef MAX_LENGTH_IPv4_ADDR
+#define MAX_LENGTH_IPv4_ADDR 16
+#endif
+
+//-----------------------------------------------------------------------------
+// Typedefs
+//-----------------------------------------------------------------------------
+
+/**
+ * List of methods that can be initiated from the client
+ */
+typedef enum {
+ TEST_DISCOVER_REQ = 1,
+ TEST_GET_REQ_NON,
+ TEST_GET_REQ_NON_WITH_FILTERS,
+ TEST_PUT_REQ_NON,
+ TEST_POST_REQ_NON,
+ TEST_DELETE_REQ_NON,
+ TEST_OBS_REQ_NON,
+ TEST_GET_UNAVAILABLE_RES_REQ_NON,
+ TEST_GET_REQ_CON,
+ TEST_POST_REQ_CON,
+ TEST_DELETE_REQ_CON,
+ TEST_OBS_REQ_CON,
+#ifdef WITH_PRESENCE
+ TEST_OBS_PRESENCE,
+ TEST_OBS_PRESENCE_WITH_FILTER,
+ TEST_OBS_PRESENCE_WITH_FILTERS,
+ TEST_OBS_MULTICAST_PRESENCE,
+#endif
+ TEST_OBS_REQ_NON_CANCEL_IMM,
+ TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS,
+ TEST_DISCOVER_PLATFORM_REQ,
+ TEST_DISCOVER_DEV_REQ,
+ MAX_TESTS
+} CLIENT_TEST;
+
+/**
+ * List of connectivity types that can be initiated from the client
+ * Required for user input validation
+ */
+typedef enum {
+ CT_ADAPTER_DEFAULT = 0,
+ CT_IPV4,
+ CT_IPV6,
+ CT_EDR,
+ MAX_CT
+} CLIENT_CONNECTIVITY_TYPE;
+
+#ifdef WITH_PRESENCE
+int InitPresence();
+#endif
+
+//----------------------------------------------------------------------------
+// Function prototype
+//----------------------------------------------------------------------------
+std::string getConnectivityType (OCConnectivityType connType);
+
+/* call getResult in common.cpp to get the result in string format. */
+const char *getResult(OCStackResult result);
+
+/* Get the IP address of the server */
+std::string getIPAddrTBServer(OCClientResponse * clientResponse);
+
+/* Get the port number the server is listening on */
+std::string getPortTBServer(OCClientResponse * clientResponse);
+
+/* Returns the query string for GET and PUT operations */
+std::string getQueryStrForGetPut(OCClientResponse * clientResponse);
+
+/* Following are initialization functions for GET, Observe, PUT
+ * POST, Delete & Discovery operations
+ */
+int InitGetRequestToUnavailableResource(OCQualityOfService qos);
+int InitObserveRequest(OCQualityOfService qos);
+int InitPutRequest(OCQualityOfService qos);
+int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions, bool getWithQuery);
+int InitPostRequest(OCQualityOfService qos);
+int InitDeleteRequest(OCQualityOfService qos);
+int InitGetRequest(OCQualityOfService qos);
+int InitDeviceDiscovery(OCQualityOfService qos);
+int InitPlatformDiscovery(OCQualityOfService qos);
+int InitDiscovery(OCQualityOfService qos);
+
+/* Function to retrieve ip address, port no. of the server
+ * and query for the operations to be performed.
+ */
+void parseClientResponse(OCClientResponse * clientResponse);
+
+/* Call delete operation on already deleted resource */
+void* RequestDeleteDeathResourceTask(void* myqos);
+
+/* This method calls OCDoResource() which in turn makes calls
+ * to the lower layers
+ */
+OCStackResult InvokeOCDoResource(std::ostringstream &query,
+ OCMethod method, OCQualityOfService qos,
+ OCClientResponseHandler cb, OCHeaderOption * options, uint8_t numOptions);
+
+//-----------------------------------------------------------------------------
+// Callback functions
+//-----------------------------------------------------------------------------
+
+/* Following are callback functions for the GET, Observe, PUT
+ * POST, Delete, Presence & Discovery operations
+ */
+OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse);
+
+OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle, OCClientResponse *clientResponse);
+
+OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse);
+
+OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse);
+
+OCStackApplicationResult presenceCB(void* ctx,
+ OCDoHandle handle, OCClientResponse * clientResponse);
+
+OCStackApplicationResult deleteReqCB(void *ctx,
+ OCDoHandle handle, OCClientResponse *clientResponse);
+
+OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse);
+
+
+#endif
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <glib.h>
+#include <stdio.h>
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+#include <array>
+#include "ocstack.h"
+#include "logger.h"
+#include "ocpayload.h"
+#include "ocserver.h"
+using namespace std;
+
+//string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
+// 9 + 9 + 1 = 19
+const int URI_MAXSIZE = 19;
+
+static int gObserveNotifyType = 3;
+
+int gQuitFlag = 0;
+int gLightUnderObservation = 0;
+
+static LightResource Light;
+// This variable determines instance number of the Light resource.
+// Used by POST method to create a new instance of Light resource.
+static int gCurrLightInstance = 0;
+
+static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
+
+Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
+
+#ifdef WITH_PRESENCE
+static int stopPresenceCount = 10;
+#define numPresenceResources (2)
+#endif
+
+char *gResourceUri= (char *)"/a/light";
+const char *dateOfManufacture = "myDateOfManufacture";
+const char *deviceName = "myDeviceName";
+const char *deviceUUID = "myDeviceUUID";
+const char *firmwareVersion = "myFirmwareVersion";
+const char *manufacturerName = "myName";
+const char *operatingSystemVersion = "myOS";
+const char *hardwareVersion = "myHardwareVersion";
+const char* platformID = "myPlatformID";
+const char *manufacturerUrl = "myManufacturerUrl";
+const char *modelNumber = "myModelNumber";
+const char *platformVersion = "myPlatformVersion";
+const char *supportUrl = "mySupportUrl";
+const char *version = "myVersion";
+const char *systemTime = "2015-05-15T11.04";
+
+// Entity handler should check for resourceTypeName and ResourceInterface in order to GET
+// the existence of a known resource
+const char *resourceTypeName = "core.light";
+const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
+
+OCPlatformInfo platformInfo;
+OCDeviceInfo deviceInfo;
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+ OCRepPayload* payload = OCRepPayloadCreate();
+ if(!payload)
+ {
+ cout << "Failed to allocate Payload";
+ return nullptr;
+ }
+
+ OCRepPayloadSetUri(payload, uri);
+ OCRepPayloadSetPropBool(payload, "state", state);
+ OCRepPayloadSetPropInt(payload, "power", power);
+
+ return payload;
+}
+
+//This function takes the request as an input and returns the response
+OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
+{
+ if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+ {
+ cout << "Incoming payload not a representation";
+ return nullptr;
+ }
+
+ OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
+
+ LightResource *currLightResource = &Light;
+
+ if (ehRequest->resource == gLightInstance[0].handle)
+ {
+ currLightResource = &gLightInstance[0];
+ gResourceUri = (char *) "a/light/0";
+ }
+ else if (ehRequest->resource == gLightInstance[1].handle)
+ {
+ currLightResource = &gLightInstance[1];
+ gResourceUri = (char *) "a/light/1";
+ }
+
+ if(OC_REST_PUT == ehRequest->method)
+ {
+ // Get pointer to query
+ int64_t pow;
+ if(OCRepPayloadGetPropInt(input, "power", &pow))
+ {
+ currLightResource->power =pow;
+ }
+
+ bool state;
+ if(OCRepPayloadGetPropBool(input, "state", &state))
+ {
+ currLightResource->state = state;
+ }
+ }
+
+ return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
+}
+
+/*
+ * Very simple example of query parsing.
+ * The query may have multiple filters separated by ';'.
+ * It is upto the entity handler to parse the query for the individual filters,
+ * VALIDATE them and respond as it sees fit.
+
+ * This function only returns false if the query is exactly "power<X" and
+ * current power is greater than X. If X cannot be parsed for an int,
+ * true is returned.
+ */
+bool checkIfQueryForPowerPassed(char * query)
+{
+ if (query && strncmp(query, "power<", strlen("power<")) == 0)
+ {
+ char * pointerToOperator = strstr(query, "<");
+
+ if (pointerToOperator)
+ {
+ int powerRequested = atoi(pointerToOperator + 1);
+ if (Light.power > powerRequested)
+ {
+ cout << "\nCurrent power: "<< Light.power << "Requested: " << powerRequested;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/*
+ * Application should validate and process these as desired.
+ */
+OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
+{
+ cout << "\nReceived query %s" << entityHandlerRequest->query;
+ cout << "\nNot processing query";
+ return OC_EH_OK;
+}
+
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+ OCRepPayload **payload)
+{
+ OCEntityHandlerResult ehResult;
+ bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
+
+ // Empty payload if the query has no match.
+ if (queryPassed)
+ {
+ OCRepPayload *getResp = constructResponse(ehRequest);
+ if(!getResp)
+ {
+ cout << "\nconstructResponse failed";
+ return OC_EH_ERROR;
+ }
+
+ *payload = getResp;
+ ehResult = OC_EH_OK;
+ }
+ else
+ {
+ ehResult = OC_EH_OK;
+ }
+
+ return ehResult;
+}
+
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+ OCRepPayload** payload)
+{
+ OCEntityHandlerResult ehResult;
+ OCRepPayload *putResp = constructResponse(ehRequest);
+
+ if(!putResp)
+ {
+ cout << "\nFailed to construct response";
+ return OC_EH_ERROR;
+ }
+
+ *payload = putResp;
+ ehResult = OC_EH_OK;
+
+ return ehResult;
+}
+
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+ OCEntityHandlerResponse *response, OCRepPayload** payload)
+{
+ OCEntityHandlerResult ehResult = OC_EH_OK;
+ OCRepPayload *respPLPost_light = nullptr;
+
+ /*
+ * The entity handler determines how to process a POST request.
+ * Per the REST paradigm, POST can also be used to update representation of existing
+ * resource or create a new resource.
+ * In the sample below, if the POST is for /a/light then a new instance of the Light
+ * resource is created with default representation (if representation is included in
+ * POST payload it can be used as initial values) as long as the instance is
+ * lesser than max new instance count. Once max instance count is reached, POST on
+ * /a/light updated the representation of /a/light (just like PUT).
+ */
+
+ if (ehRequest->resource == Light.handle)
+ {
+ if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
+ {
+ // Create new Light instance
+ char newLightUri[URI_MAXSIZE];
+ snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
+
+ respPLPost_light = OCRepPayloadCreate();
+ OCRepPayloadSetUri(respPLPost_light, gResourceUri);
+ OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
+
+ if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
+ {
+ cout << "\nCreated new Light instance";
+ gLightInstance[gCurrLightInstance].state = 0;
+ gLightInstance[gCurrLightInstance].power = 0;
+ gCurrLightInstance++;
+ strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
+ ehResult = OC_EH_RESOURCE_CREATED;
+ }
+ }
+ else
+ {
+ // Update repesentation of /a/light
+ Light.state = true;
+ Light.power = 11;
+ respPLPost_light = constructResponse(ehRequest);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
+ {
+ if (ehRequest->resource == gLightInstance[i].handle)
+ {
+ gLightInstance[i].state = true;
+ gLightInstance[i].power = 22;
+ if (i == 0)
+ {
+ respPLPost_light = constructResponse(ehRequest);
+ break;
+ }
+ else if (i == 1)
+ {
+ respPLPost_light = constructResponse(ehRequest);
+ }
+ }
+ }
+ }
+
+ if ((respPLPost_light != NULL))
+ {
+ *payload = respPLPost_light;
+ }
+ else
+ {
+ cout << "\n Payload was NULL";
+ ehResult = OC_EH_ERROR;
+ }
+
+ return ehResult;
+}
+
+OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
+{
+ if(ehRequest == NULL)
+ {
+ cout << "\nThe ehRequest is NULL";
+ return OC_EH_ERROR;
+ }
+ OCEntityHandlerResult ehResult = OC_EH_OK;
+
+ cout << "\nExecuting " << __func__ << " for resource " << ehRequest->resource;
+
+ /*
+ * In the sample below, the application will:
+ * 1a. pass the delete request to the c stack
+ * 1b. internally, the c stack figures out what needs to be done and does it accordingly
+ * (e.g. send observers notification, remove observers...)
+ * 1c. the c stack returns with the result whether the request is fullfilled.
+ * 2. optionally, app removes observers out of its array 'interestedObservers'
+ */
+
+ if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
+ {
+ //Step 1: Ask stack to do the work.
+ OCStackResult result = OCDeleteResource(ehRequest->resource);
+
+ if (result == OC_STACK_OK)
+ {
+ cout << "\nDelete Resource operation succeeded.";
+ ehResult = OC_EH_OK;
+
+ //Step 2: clear observers who wanted to observe this resource at the app level.
+ for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
+ {
+ if (interestedObservers[i].resourceHandle == ehRequest->resource)
+ {
+ interestedObservers[i].valid = false;
+ interestedObservers[i].observationId = 0;
+ interestedObservers[i].resourceHandle = NULL;
+ }
+ }
+ }
+ else if (result == OC_STACK_NO_RESOURCE)
+ {
+ cout << "\nThe resource doesn't exist or it might have been deleted.";
+ ehResult = OC_EH_RESOURCE_DELETED;
+ }
+ else
+ {
+ cout << "\nEncountered error from OCDeleteResource().";
+ ehResult = OC_EH_ERROR;
+ }
+ }
+ else if (ehRequest->resource != Light.handle)
+ {
+ //Let's this app not supporting DELETE on some resources so
+ //consider the DELETE request is received for a non-support resource.
+ cout << "\nThe request is received for a non-support resource.";
+ ehResult = OC_EH_FORBIDDEN;
+ }
+
+ return ehResult;
+}
+
+OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest)
+{
+ cout << "\nExecuting " << __func__;
+
+ return OC_EH_RESOURCE_NOT_FOUND;
+}
+
+void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
+{
+ cout << "\nReceived observation registration request with observation Id "
+ << ehRequest->obsInfo.obsId;
+ for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
+ {
+ if (interestedObservers[i].valid == false)
+ {
+ interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
+ interestedObservers[i].valid = true;
+ gLightUnderObservation = 1;
+ break;
+ }
+ }
+}
+
+void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
+{
+ bool clientStillObserving = false;
+
+ cout << "\nReceived observation deregistration request for observation Id "
+ << ehRequest->obsInfo.obsId;
+ for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
+ {
+ if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
+ {
+ interestedObservers[i].valid = false;
+ }
+ if (interestedObservers[i].valid == true)
+ {
+ // Even if there is one single client observing we continue notifying entity handler
+ clientStillObserving = true;
+ }
+ }
+ if (clientStillObserving == false)
+ gLightUnderObservation = 0;
+}
+
+OCEntityHandlerResult
+OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest, char* uri, void* callbackParam)
+{
+ cout << "\nInside device default entity handler - flags: " << flag << ", uri: %s" << uri;
+
+ OCEntityHandlerResult ehResult = OC_EH_OK;
+ OCEntityHandlerResponse response;
+
+ // Validate pointer
+ if (!entityHandlerRequest)
+ {
+ cout << "\nInvalid request pointer";
+ return OC_EH_ERROR;
+ }
+ // Initialize certain response fields
+ response.numSendVendorSpecificHeaderOptions = 0;
+ memset(response.sendVendorSpecificHeaderOptions, 0,
+ sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.resourceUri, 0, sizeof response.resourceUri);
+ OCRepPayload* payload = nullptr;
+
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ cout << "\nFlag includes OC_REQUEST_FLAG";
+
+ if (entityHandlerRequest->resource == NULL)
+ {
+ cout << "\nReceived request from client to a non-existing resource";
+ ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
+ }
+ else if (OC_REST_GET == entityHandlerRequest->method)
+ {
+ cout << "\nReceived OC_REST_GET from client";
+ ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+ }
+ else if (OC_REST_PUT == entityHandlerRequest->method)
+ {
+ cout << "\nReceived OC_REST_PUT from client";
+ ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+ }
+ else if (OC_REST_DELETE == entityHandlerRequest->method)
+ {
+ cout << "\nReceived OC_REST_DELETE from client";
+ ehResult = ProcessDeleteRequest (entityHandlerRequest);
+ }
+ else
+ {
+ cout << "\nReceived unsupported method " << entityHandlerRequest->method
+ << " from client";
+ ehResult = OC_EH_ERROR;
+ }
+ // If the result isn't an error or forbidden, send response
+ if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
+ {
+ // Format the response. Note this requires some info about the request
+ response.requestHandle = entityHandlerRequest->requestHandle;
+ response.resourceHandle = entityHandlerRequest->resource;
+ response.ehResult = ehResult;
+ response.payload = reinterpret_cast<OCPayload*>(payload);
+ // Indicate that response is NOT in a persistent buffer
+ response.persistentBufferFlag = 0;
+
+ // Send the response
+ if (OCDoResponse(&response) != OC_STACK_OK)
+ {
+ cout << "\nError sending response";
+ ehResult = OC_EH_ERROR;
+ }
+ }
+ }
+ if (flag & OC_OBSERVE_FLAG)
+ {
+ cout << "\nFlag includes OC_OBSERVE_FLAG";
+ if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
+ {
+ cout << "\nReceived OC_OBSERVE_REGISTER from client";
+ }
+ else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
+ {
+ cout << "\nReceived OC_OBSERVE_DEREGISTER from client";
+ }
+ }
+
+ return ehResult;
+}
+
+OCEntityHandlerResult
+OCNOPEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest, void* callbackParam)
+{
+ // This is callback is associated with the 2 presence notification
+ // resources. They are non-operational.
+ return OC_EH_OK;
+}
+
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest, void* callback)
+{
+ cout << "\nInside entity handler - flags: " << flag;
+
+ OCEntityHandlerResult ehResult = OC_EH_OK;
+ OCEntityHandlerResponse response;
+
+ // Validate pointer
+ if (!entityHandlerRequest)
+ {
+ cout << "\nInvalid request pointer";
+ return OC_EH_ERROR;
+ }
+
+ // Initialize certain response fields
+ response.numSendVendorSpecificHeaderOptions = 0;
+ memset(response.sendVendorSpecificHeaderOptions,
+ 0, sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.resourceUri, 0, sizeof response.resourceUri);
+ OCRepPayload* payload = nullptr;
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ cout << "\n=================================\n";
+ cout << "\nFlag includes OC_REQUEST_FLAG\n";
+
+ if (OC_REST_GET == entityHandlerRequest->method)
+ {
+ cout << "\nReceived OC_REST_GET from client";
+ ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+ cout << "\n=================================\n";
+ }
+ else if (OC_REST_PUT == entityHandlerRequest->method)
+ {
+ cout << "\nReceived OC_REST_PUT from client";
+ ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+ cout << "\n=================================\n";
+ }
+ else if (OC_REST_POST == entityHandlerRequest->method)
+ {
+ cout << "\nReceived OC_REST_POST from client";
+ ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
+ cout << "\n=================================\n";
+ }
+ else if (OC_REST_DELETE == entityHandlerRequest->method)
+ {
+ cout << "\nReceived OC_REST_DELETE from client";
+ ehResult = ProcessDeleteRequest (entityHandlerRequest);
+ cout << "\n=================================\n";
+ }
+ else
+ {
+ cout << "\nReceived unsupported method " << entityHandlerRequest->method << " from client";
+ ehResult = OC_EH_ERROR;
+ }
+ // If the result isn't an error or forbidden, send response
+ if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
+ {
+ // Format the response. Note this requires some info about the request
+ response.requestHandle = entityHandlerRequest->requestHandle;
+ response.resourceHandle = entityHandlerRequest->resource;
+ response.ehResult = ehResult;
+ response.payload = reinterpret_cast<OCPayload*>(payload);
+ // Indicate that response is NOT in a persistent buffer
+ response.persistentBufferFlag = 0;
+
+ // Handle vendor specific options
+ if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
+ entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
+ {
+ cout << "\nReceived vendor specific options";
+ uint8_t i = 0;
+ OCHeaderOption * rcvdOptions =
+ entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
+ for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
+ {
+ if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
+ {
+ cout << "\nReceived option with ID " << ((OCHeaderOption)rcvdOptions[i]).optionID;
+ }
+ }
+ OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
+ uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
+ uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
+ sendOptions[0].protocolID = OC_COAP_ID;
+ sendOptions[0].optionID = 2248;
+ memcpy(sendOptions[0].optionData, option2, sizeof(option2));
+ sendOptions[0].optionLength = 10;
+ sendOptions[1].protocolID = OC_COAP_ID;
+ sendOptions[1].optionID = 2600;
+ memcpy(sendOptions[1].optionData, option3, sizeof(option3));
+ sendOptions[1].optionLength = 10;
+ response.numSendVendorSpecificHeaderOptions = 2;
+ }
+
+ // Send the response
+ if (OCDoResponse(&response) != OC_STACK_OK)
+ {
+ cout << "\nError sending response";
+ ehResult = OC_EH_ERROR;
+ }
+ }
+ }
+ if (flag & OC_OBSERVE_FLAG)
+ {
+ cout << "\nFlag includes OC_OBSERVE_FLAG";
+
+ if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
+ {
+ cout << "\nReceived OC_OBSERVE_REGISTER from client";
+ ProcessObserveRegister (entityHandlerRequest);
+ }
+ else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
+ {
+ cout << "\nReceived OC_OBSERVE_DEREGISTER from client";
+ ProcessObserveDeregister (entityHandlerRequest);
+ }
+ }
+
+ return ehResult;
+}
+
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+ if (signum == SIGINT)
+ {
+ gQuitFlag = 1;
+ }
+}
+
+void *ChangeLightRepresentation (void *param)
+{
+ (void)param;
+ OCStackResult result = OC_STACK_ERROR;
+
+ uint8_t j = 0;
+ uint8_t numNotifies = (SAMPLE_MAX_NUM_OBSERVATIONS)/2;
+ OCObservationId obsNotify[numNotifies];
+
+ while (!gQuitFlag)
+ {
+ sleep(3);
+ Light.power += 5;
+ if (gLightUnderObservation)
+ {
+ cout << "\n=====> Notifying stack of new power level" << Light.power;
+ if (gObserveNotifyType == 1)
+ {
+ // Notify list of observers. Alternate observers on the list will be notified.
+ j = 0;
+ for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; (i=i+2))
+ {
+ if (interestedObservers[i].valid == true)
+ {
+ obsNotify[j] = interestedObservers[i].observationId;
+ j++;
+ }
+ }
+
+ OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
+ result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
+ payload, OC_NA_QOS);
+ OCRepPayloadDestroy(payload);
+ }
+ else if (gObserveNotifyType == 0)
+ {
+ // Notifying all observers
+ result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
+ if (OC_STACK_NO_OBSERVERS == result)
+ {
+ cout << "\n=====> No more observers exist, stop sending observations";
+ gLightUnderObservation = 0;
+ }
+ }
+ else
+ {
+ cout << "\nIncorrect notification type selected";
+ }
+ }
+#ifdef WITH_PRESENCE
+ if(stopPresenceCount > 0)
+ {
+ cout << "\n=====> Counting down to stop presence " << stopPresenceCount;
+ }
+ if(!stopPresenceCount--)
+ {
+ cout << "\n=====> stopping presence";
+ OCStopPresence();
+ }
+#endif
+ }
+ return NULL;
+}
+
+#ifdef WITH_PRESENCE
+void *presenceNotificationGenerator(void *param)
+{
+ sleep(10);
+ (void)param;
+ OCDoHandle presenceNotificationHandles[numPresenceResources];
+ OCStackResult res = OC_STACK_OK;
+
+ std::array<std::string, numPresenceResources> presenceNotificationResources { {
+ std::string("core.fan"),
+ std::string("core.led") } };
+ std::array<std::string, numPresenceResources> presenceNotificationUris { {
+ std::string("/a/fan"),
+ std::string("/a/led") } };
+
+ for(int i=0; i<numPresenceResources; i++)
+ {
+ if(res == OC_STACK_OK)
+ {
+ sleep(1);
+ res = OCCreateResource(&presenceNotificationHandles[i],
+ presenceNotificationResources.at(i).c_str(),
+ OC_RSRVD_INTERFACE_DEFAULT,
+ presenceNotificationUris.at(i).c_str(),
+ OCNOPEntityHandlerCb,
+ NULL,
+ OC_DISCOVERABLE|OC_OBSERVABLE);
+ }
+ if(res != OC_STACK_OK)
+ {
+ cout << "\nPresence Notification Generator failed[" << getResult(res)
+ << "] to create resource " << presenceNotificationResources.at(i).c_str();
+ break;
+ }
+ cout << "\nCreated " << presenceNotificationUris[i].c_str() << " for presence notification";
+ }
+ sleep(5);
+ for(int i=0; i<numPresenceResources; i++)
+ {
+ if(res == OC_STACK_OK)
+ {
+ res = OCDeleteResource(presenceNotificationHandles[i]);
+ }
+ if(res != OC_STACK_OK)
+ {
+ cout << "\nPresence Notification Generator failed to delete resource"
+ << presenceNotificationResources.at(i).c_str();
+ break;
+ }
+ cout << "\nDeleted " << presenceNotificationUris[i].c_str() << " for presence notification";
+ }
+ return NULL;
+}
+#endif
+
+int createLightResource (char *uri, LightResource *lightResource)
+{
+ if (!uri)
+ {
+ cout << "\nResource URI cannot be NULL";
+ return -1;
+ }
+
+ lightResource->state = false;
+ lightResource->power= 0;
+ OCStackResult res = OCCreateResource(&(lightResource->handle),
+ "core.light",
+ "oc.mi.def",
+ uri,
+ OCEntityHandlerCb,
+ NULL,
+ OC_DISCOVERABLE|OC_OBSERVABLE);
+ cout << "\nCreated Light resource with result " << getResult(res);
+
+ return 0;
+}
+
+void DeletePlatformInfo()
+{
+ free (platformInfo.platformID);
+ free (platformInfo.manufacturerName);
+ free (platformInfo.manufacturerUrl);
+ free (platformInfo.modelNumber);
+ free (platformInfo.dateOfManufacture);
+ free (platformInfo.platformVersion);
+ free (platformInfo.operatingSystemVersion);
+ free (platformInfo.hardwareVersion);
+ free (platformInfo.firmwareVersion);
+ free (platformInfo.supportUrl);
+ free (platformInfo.systemTime);
+}
+
+void DeleteDeviceInfo()
+{
+ free (deviceInfo.deviceName);
+}
+
+bool DuplicateString(char** targetString, const char* sourceString)
+{
+ if(!sourceString)
+ {
+ return false;
+ }
+ else
+ {
+ *targetString = (char *) malloc(strlen(sourceString) + 1);
+
+ if(*targetString)
+ {
+ strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
+ return true;
+ }
+ }
+ return false;
+}
+
+OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
+ const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
+ const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
+ const char *firmwareVersion, const char* supportUrl, const char* systemTime)
+{
+
+ bool success = true;
+
+ if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if(!DuplicateString(&platformInfo.platformID, platformID))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
+ {
+ success = false;
+ }
+
+ if(!DuplicateString(&platformInfo.systemTime, systemTime))
+ {
+ success = false;
+ }
+
+ if(success)
+ {
+ return OC_STACK_OK;
+ }
+
+ DeletePlatformInfo();
+ return OC_STACK_ERROR;
+}
+
+OCStackResult SetDeviceInfo(const char* deviceName)
+{
+ if(!DuplicateString(&deviceInfo.deviceName, deviceName))
+ {
+ return OC_STACK_ERROR;
+ }
+ return OC_STACK_OK;
+}
+
+static void PrintUsage()
+{
+ cout << "\nUsage : ocserver -o <0|1>";
+ cout << "\n-o 0 : Notify all observers";
+ cout << "\n-o 1 : Notify list of observers";
+}
+
+int main(int argc, char* argv[])
+{
+ pthread_t threadId;
+ pthread_t threadId_presence;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "o:")) != -1)
+ {
+ switch(opt)
+ {
+ case 'o':
+ gObserveNotifyType = atoi(optarg);
+ break;
+ default:
+ PrintUsage();
+ return -1;
+ }
+ }
+
+ if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
+ {
+ PrintUsage();
+ return -1;
+ }
+
+ cout << "\nOCServer is starting...";
+
+ if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+ {
+ cout << "\nOCStack init error";
+ return 0;
+ }
+#ifdef WITH_PRESENCE
+ if (OCStartPresence(0) != OC_STACK_OK)
+ {
+ cout << "\nOCStack presence/discovery error";
+ return 0;
+ }
+#endif
+
+ OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
+
+ OCStackResult registrationResult =
+ SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
+ dateOfManufacture, platformVersion, operatingSystemVersion, hardwareVersion,
+ firmwareVersion, supportUrl, systemTime);
+
+ if (registrationResult != OC_STACK_OK)
+ {
+ cout << "\nPlatform info setting failed locally!";
+ exit (EXIT_FAILURE);
+ }
+
+ registrationResult = OCSetPlatformInfo(platformInfo);
+
+ if (registrationResult != OC_STACK_OK)
+ {
+ cout << "\nPlatform Registration failed!";
+ exit (EXIT_FAILURE);
+ }
+
+ registrationResult = SetDeviceInfo(deviceName);
+
+ if (registrationResult != OC_STACK_OK)
+ {
+ cout << "\nDevice info setting failed locally!";
+ exit (EXIT_FAILURE);
+ }
+
+ registrationResult = OCSetDeviceInfo(deviceInfo);
+
+ if (registrationResult != OC_STACK_OK)
+ {
+ cout << "\nDevice Registration failed!";
+ exit (EXIT_FAILURE);
+ }
+
+ /*
+ * Declare and create the example resource: Light
+ */
+ createLightResource(gResourceUri, &Light);
+
+ // Initialize observations data structure for the resource
+ for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
+ {
+ interestedObservers[i].valid = false;
+ }
+
+ /*
+ * Create a thread for changing the representation of the Light
+ */
+ pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
+
+ /*
+ * Create a thread for generating changes that cause presence notifications
+ * to be sent to clients
+ */
+
+ #ifdef WITH_PRESENCE
+ pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
+ #endif
+
+ // Break from loop with Ctrl-C
+ cout << "\nEntering ocserver main loop...";
+
+ DeletePlatformInfo();
+ DeleteDeviceInfo();
+
+ signal(SIGINT, handleSigInt);
+
+ while (!gQuitFlag)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ cout << "\nOCStack process error";
+ return 0;
+ }
+
+ sleep(2);
+ }
+
+ /*
+ * Cancel the Light thread and wait for it to terminate
+ */
+ pthread_cancel(threadId);
+ pthread_join(threadId, NULL);
+ pthread_cancel(threadId_presence);
+ pthread_join(threadId_presence, NULL);
+
+ cout << "\nExiting ocserver main loop...\n";
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ cout << "\nOCStack process error";
+ }
+
+ return 0;
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OCSERVER_H_
+#define OCSERVER_H_
+
+#include "ocstack.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+#define TAG "ocserver"
+#define SAMPLE_MAX_NUM_OBSERVATIONS 8
+#define SAMPLE_MAX_NUM_POST_INSTANCE 2
+
+//-----------------------------------------------------------------------------
+// Typedefs
+//-----------------------------------------------------------------------------
+
+/* Structure to represent a Light resource */
+typedef struct LIGHTRESOURCE
+{
+ OCResourceHandle handle;
+ bool state;
+ int power;
+} LightResource;
+
+/* Structure to represent the observers */
+typedef struct
+{
+ OCObservationId observationId;
+ bool valid;
+ OCResourceHandle resourceHandle;
+} Observers;
+
+//-----------------------------------------------------------------------------
+// Function prototype
+//-----------------------------------------------------------------------------
+
+/* call getResult in common.cpp to get the result in string format. */
+const char *getResult(OCStackResult result);
+
+/* Function that creates a new Light resource by calling the
+ * OCCreateResource() method.
+ */
+int createLightResource (char *uri, LightResource *lightResource);
+
+/* This method converts the payload to JSON format */
+char* constructJsonResponse (OCEntityHandlerRequest *ehRequest);
+
+/* This method changes the Light power using an independent thread
+ * and notifies the observers of new state of the resource.
+ */
+void *ChangeLightRepresentation (void *param);
+
+/* This method check the validity of resourceTypeName and resource interfaces
+ * Entity Handler has to parse the query string in order to process it
+ */
+OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest);
+
+/* Following methods process the PUT, GET, POST, Delete,
+ * & Observe requests */
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+ char *payload,
+ uint16_t maxPayloadSize);
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+ char *payload,
+ uint16_t maxPayloadSize);
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+ OCEntityHandlerResponse *response,
+ char *payload,
+ uint16_t maxPayloadSize);
+OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
+ char *payload,
+ uint16_t maxPayloadSize);
+
+OCEntityHandlerResult ProcessNonExistingResourceRequest (OCEntityHandlerRequest *ehRequest,
+ char *payload,
+ uint16_t maxPayloadSize);
+
+void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest);
+void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest);
+
+void DeleteDeviceInfo();
+
+OCStackResult SetDeviceInfo(const char *contentType, const char *dateOfManufacture,
+ const char *deviceName, const char *deviceUUID, const char *firmwareVersion,
+ const char *hostName, const char *manufacturerName, const char *manufacturerUrl,
+ const char *modelNumber, const char *platformVersion, const char *supportUrl,
+ const char *version);
+
+
+//-----------------------------------------------------------------------------
+// Callback functions
+//-----------------------------------------------------------------------------
+
+/* Entity Handler callback functions */
+OCEntityHandlerResult
+OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest, char* uri);
+
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest);
+
+
+#endif
+
--- /dev/null
+%define PREFIX /usr/apps/com.oic.ri.sample
+%define ROOTDIR %{_builddir}/%{name}-%{version}
+
+Name: com-oic-ri-sample
+Version: 0.1
+Release: 1
+Summary: Tizen adapter interfacesample application
+URL: http://slp-source.sec.samsung.net
+Source: %{name}-%{version}.tar.gz
+License: Apache-2.0
+Group: Applications/OICSample
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: boost-devel
+BuildRequires: boost-thread
+BuildRequires: boost-system
+BuildRequires: boost-filesystem
+BuildRequires: pkgconfig(capi-network-wifi)
+BuildRequires: pkgconfig(capi-network-bluetooth)
+BuildRequires: scons
+BuildRequires: com-oic-ri
+
+
+%description
+OIC RIsample application
+
+%prep
+%setup -q
+
+%build
+
+scons TARGET_OS=tizen -c
+scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT} SECURED=%{SECURED} RELEASE=%{RELEASE}
+
+%install
+
+mkdir -p %{buildroot}%{_datadir}/packages
+mkdir -p %{buildroot}/%{_sysconfdir}/smack/accesses2.d
+mkdir -p %{buildroot}/usr/apps/com.oic.ri.sample/bin/
+mkdir -p %{buildroot}/usr/apps/com.oic.ri.sample/bin/internal
+
+cp -rf %{ROOTDIR}/com.oic.ri.sample.xml %{buildroot}/%{_datadir}/packages
+cp -rf %{ROOTDIR}/scons/occlient %{buildroot}/usr/apps/com.oic.ri.sample/bin/
+cp -rf %{ROOTDIR}/scons/ocserver %{buildroot}/usr/apps/com.oic.ri.sample/bin/
+
+%files
+%manifest com.oic.ri.sample.manifest
+%defattr(-,root,root,-)
+/usr/apps/com.oic.ri.sample/bin/occlient
+/usr/apps/com.oic.ri.sample/bin/ocserver
+/%{_datadir}/packages/com.oic.ri.sample.xml
+
+
--- /dev/null
+#******************************************************************
+#
+# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('env')
+
+target_os = env.get('TARGET_OS')
+transport = env.get('TARGET_TRANSPORT')
+secured = env.get('SECURED')
+
+OIC_LIB = 'oic'
+root_dir = env.get('ROOT_DIR')
+build_dir = env.get('BUILD_DIR')
+sample_dir = build_dir
+
+env.AppendUnique(CPPFLAGS = ['-std=c++11', '-fPIC', '-D__TIZEN__','-DWITH_POSIX', '-Wall', '-DSLP_SDK_LOG', '-g','-D_GNU_SOURCE','-DTIZEN_DEBUG_ENABLE', '-DTB_LOG','`pkg-config', '--cflags', '--libs','dlog', 'com.oic.ri', 'capi-network-wifi',
+ 'gobject-2.0','glib-2.0`'])
+
+env.Append(LIBS=[
+ '-lm', '-lpthread', '-lrt', '-ldl', '-lstdc++', '-lgobject-2.0', '-lgio-2.0', '-lglib-2.0', '-lcapi-network-wifi', '-ldlog', '-lcapi-network-bluetooth', '-lconnectivity_abstraction', 'coap', '-loctbstack', 'ocsrm', 'c_common'
+])
+
+if secured == '1':
+ env.PrependUnique(CPPPATH = [root_dir + '/external/inc/'])
+ env.AppendUnique(CPPDEFINES = ['__WITH_DTLS__'])
+ env.Append(LIBS=['-ltinydtls'])
+
+if 'ALL' in transport:
+ env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER','BT_ADAPTER_TEST','BLE_ADAPTER_TEST'])
+ print "CA Transport is ALL"
+else:
+ if 'BT' in transport:
+ env.AppendUnique(CPPDEFINES = ['EDR_ADAPTER','BT_ADAPTER_TEST'])
+ print "CA Transport is BT"
+ else:
+ env.AppendUnique(CPPDEFINES = ['NO_EDR_ADAPTER'])
+
+ if 'BLE' in transport:
+ env.AppendUnique(CPPDEFINES = ['LE_ADAPTER','BLE_ADAPTER_TEST'])
+ print "CA Transport is BLE"
+ else:
+ env.AppendUnique(CPPDEFINES = ['NO_LE_ADAPTER'])
+
+ if 'IP' in transport:
+ env.AppendUnique(CPPDEFINES = ['IP_ADAPTER'])
+ print "CA Transport is IP"
+ else:
+ env.AppendUnique(CPPDEFINES = ['NO_IP_ADAPTER'])
+
+#ri_sample_src = [sample_dir + '/occlient.cpp']
+
+#print " ri sample src %s" % ri_sample_src
+
+#env.Program('ri_sample', [ri_sample_src,])
+
+env.Program('occlient', [sample_dir + 'occlient.cpp', sample_dir + 'common.cpp'])
+env.Program('ocserver', [sample_dir + 'ocserver.cpp', sample_dir + 'common.cpp'])
\ No newline at end of file
--- /dev/null
+##
+# CA build script
+##
+
+SConscript('./resource/csdk/connectivity/build/SConscript')
+
+Import('env')
+
+target_os = env.get('TARGET_OS')
+transport = env.get('TARGET_TRANSPORT')
+buildsample = env.get('BUILD_SAMPLE')
+release_mode = env.get('RELEASE')
+secured = env.get('SECURED')
+logging = env.get('LOGGING')
+
+print "Given Transport is %s" % transport
+print "Given OS is %s" % target_os
+
+if target_os == 'tizen':
+ command = "sh resource/csdk/stack/samples/tizen/build/gbsbuild.sh %s %s %s %s %s" % (transport, secured, buildsample, release_mode, logging)
+ print "Created Command is %s" % command
+ gbs_script = env.Command('gbs_build', None, command)
+ AlwaysBuild ('gbs_script')
\ No newline at end of file
--- /dev/null
+##
+# The main build script
+#
+##
+
+# Load common build config
+
+# Load common build config
+env = SConscript('SConscript')
+
+target_os = env.get('TARGET_OS')
+transport = env.get('TARGET_TRANSPORT')
+release_mode = env.get('RELEASE')
+
+print "Given Transport is %s" % transport
+print "Given OS is %s" % target_os
+print "Given release mode is %s" % release_mode
+
+env.SConscript('scons/SConscript')
--- /dev/null
+<manifest>
+ <define>
+ <domain name="rilib" />
+ <permit>
+ <smack permit="system::use_internet" type="rwx"/>
+ </permit>
+ <request>
+ <smack request="system::use_internet" type="rwx"/>
+ <smack request="bt-service" type="rwx"/>
+ <smack request="sap" type="rwx"/>
+ <smack request="bt-service::spp" type="rwx"/>
+ <smack request="bt-service::gap" type="rwx"/>
+ <smack request="bt-service::admin" type="rwx"/>
+ <smack request="bt-service::manager" type="rwx"/>
+ <smack request="bt-service::public" type="rwx"/>
+ <smack request="bt-service::platform" type="rwx"/>
+ </request>
+ </define>
+ <request>
+ <domain name="rilib" />
+ </request>
+</manifest>
+
--- /dev/null
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include/OICHeaders
+
+Name: com-oic-ca
+Description: Oic core library
+Version: 1.0
+Cflags: -I${includedir}
+
--- /dev/null
+#!/bin/sh
+
+spec=`ls ./resource/csdk/stack/samples/tizen/build/packaging/*.spec`
+version=`rpm --query --queryformat '%{version}\n' --specfile $spec`
+
+name=`echo $name|cut -d" " -f 1`
+version=`echo $version|cut -d" " -f 1`
+
+name=oicri
+
+echo $1
+export TARGET_TRANSPORT=$1
+
+echo $2
+export SECURED=$2
+
+echo $3
+export BUILD_SAMPLE=$3
+
+echo $4
+export RELEASE=$4
+
+echo $5
+export LOGGING=$5
+
+
+echo $TARGET_TRANSPORT
+echo $BUILD_SAMPLE
+
+rm -rf $name-$version
+
+builddir=`pwd`
+sourcedir=`pwd`
+
+echo `pwd`
+
+mkdir ./tmp
+mkdir ./tmp/extlibs/
+mkdir ./tmp/packaging
+cp -R ./extlibs/tinycbor $sourcedir/tmp/extlibs
+cp -R ./extlibs/cjson $sourcedir/tmp/extlibs
+cp -R ./extlibs/tinydtls $sourcedir/tmp/extlibs
+cp -R ./extlibs/timer $sourcedir/tmp/extlibs
+cp -R ./extlibs/rapidxml $sourcedir/tmp/extlibs
+cp -R ./resource/csdk/stack/samples/tizen/build/packaging/*.spec $sourcedir/tmp/packaging
+cp -R ./resource $sourcedir/tmp/
+cp -R ./build_common/external_libs.scons $sourcedir/tmp/
+
+cd $sourcedir
+cd ./resource/csdk/stack/samples/tizen/build/
+
+cp -R ./* $sourcedir/tmp/
+rm -f $sourcedir/tmp/SConscript
+cp SConstruct $sourcedir/tmp/
+cp scons/SConscript $sourcedir/tmp/scons/
+
+mkdir -p $sourcedir/tmp/iotivityconfig
+cd $sourcedir/build_common/
+cp -R ./iotivityconfig/* $sourcedir/tmp/iotivityconfig/
+cp -R ./SConscript $sourcedir/tmp/
+
+cd $sourcedir/tmp
+
+echo `pwd`
+
+whoami
+# Initialize Git repository
+if [ ! -d .git ]; then
+ git init ./
+ git config user.email "you@example.com"
+ git config user.name "Your Name"
+ git add ./
+ git commit -m "Initial commit"
+fi
+
+echo "Calling core gbs build command"
+gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-RI --include-all --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --repository ./"
+echo $gbscommand
+if eval $gbscommand; then
+ echo "Core build is successful"
+else
+ echo "Core build failed. Try 'sudo find . -type f -exec dos2unix {} \;' in the 'connectivity/' folder"
+ cd $sourcedir
+ rm -rf $sourcedir/tmp
+ exit
+fi
+
+if echo $BUILD_SAMPLE|grep -qi '^ON$'; then
+ cd resource/csdk/stack/samples/tizen/SimpleClientServer
+ echo `pwd`
+ # Initialize Git repository
+ if [ ! -d .git ]; then
+ git init ./
+ git config user.email "you@example.com"
+ git config user.name "Your Name"
+ git add ./
+ git commit -m "Initial commit"
+ fi
+ echo "Calling sample gbs build command"
+ gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-RI --include-all --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --repository ./"
+ echo $gbscommand
+ if eval $gbscommand; then
+ echo "Sample build is successful"
+ else
+ echo "Sample build is failed. Try 'sudo find . -type f -exec dos2unix {} \;' in the 'connectivity/' folder"
+ fi
+else
+ echo "Sample build is not enabled"
+fi
+
+
+cd $sourcedir
+rm -rf $sourcedir/tmp
+
--- /dev/null
+%define PREFIX /usr/apps/com.oic.ri
+%define ROOTDIR %{_builddir}/%{name}-%{version}
+%define DEST_INC_DIR %{buildroot}/%{_includedir}/OICHeaders
+%define DEST_LIB_DIR %{buildroot}/%{_libdir}
+
+Name: com-oic-ri
+Version: 0.1
+Release: 1
+Summary: Tizen oicri application
+URL: http://slp-source.sec.samsung.net
+Source: %{name}-%{version}.tar.gz
+License: Apache-2.0
+Group: Applications/OIC
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(capi-network-wifi)
+BuildRequires: pkgconfig(capi-network-bluetooth)
+BuildRequires: pkgconfig(uuid)
+BuildRequires: boost-devel
+BuildRequires: boost-thread
+BuildRequires: boost-system
+BuildRequires: boost-filesystem
+BuildRequires: scons
+
+
+%description
+SLP oicri application
+
+%prep
+
+%setup -q
+
+%build
+
+echo %{ROOTDIR}
+
+scons TARGET_OS=tizen -c
+scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT} SECURED=%{SECURED} RELEASE=%{RELEASE} LOGGING=%{LOGGING}
+
+%install
+mkdir -p %{DEST_INC_DIR}
+mkdir -p %{DEST_LIB_DIR}/pkgconfig
+
+cp -f %{ROOTDIR}/resource/csdk/liboctbstack.so %{buildroot}/%{_libdir}
+cp -f %{ROOTDIR}/resource/c_common/libc_common.a %{buildroot}/%{_libdir}
+cp -f %{ROOTDIR}/resource/csdk/security/libocsrm.a %{buildroot}/%{_libdir}
+cp -f %{ROOTDIR}/resource/csdk/connectivity/src/libconnectivity_abstraction.so %{buildroot}/%{_libdir}
+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}/con/extlibs/tinydtls/libtinydtls.a %{buildroot}/%{_libdir}
+fi
+
+cp -rf %{ROOTDIR}/resource/csdk/stack/include/ocstack.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/resource/csdk/stack/include/ocstackconfig.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/resource/csdk/stack/include/octypes.h* %{DEST_INC_DIR}/
+cp -rf %{ROOTDIR}/resource/csdk/logger/include/logger.h* %{DEST_INC_DIR}/
+cp resource/oc_logger/include/oc_logger.hpp %{DEST_INC_DIR}/
+cp resource/oc_logger/include/oc_log_stream.hpp %{DEST_INC_DIR}/
+cp resource/oc_logger/include/oc_logger.h %{DEST_INC_DIR}/
+cp resource/oc_logger/include/oc_logger_types.h %{DEST_INC_DIR}/
+cp resource/oc_logger/include/targets/oc_console_logger.h %{DEST_INC_DIR}
+cp resource/oc_logger/include/targets/oc_ostream_logger.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 extlibs/cjson/cJSON.h %{DEST_INC_DIR}
+cp -rf %{ROOTDIR}/com.oic.ri.pc %{DEST_LIB_DIR}/pkgconfig/
+
+%files
+%manifest com.oic.ri.manifest
+%defattr(-,root,root,-)
+%{_libdir}/lib*.so*
+%{_libdir}/lib*.a*
+%{_includedir}/OICHeaders/*
+%{_libdir}/pkgconfig/*.pc
+
--- /dev/null
+##
+# 'resource' sub-project main build script
+#
+##
+
+Import('env')
+
+target_os = env.get('TARGET_OS')
+transport = env.get('TARGET_TRANSPORT')
+
+print "Given Transport is %s" % transport
+
+if env.get('RELEASE'):
+ env.AppendUnique(CFLAGS = ['-std=c99', '-fPIC', '-D__TIZEN__','-DWITH_POSIX', '-Wall','-D_GNU_SOURCE','-DTIZEN_DEBUG_ENABLE'])
+else:
+ env.AppendUnique(CFLAGS = ['-std=c99', '-fPIC', '-D__TIZEN__','-DWITH_POSIX', '-Wall', '-DSLP_SDK_LOG', '-g','-D_GNU_SOURCE','-DTIZEN_DEBUG_ENABLE'])
+
+if env.get('LOGGING'):
+ env.AppendUnique(CPPDEFINES = ['-DTB_LOG'])
+
+env.ParseConfig("pkg-config --cflags --libs capi-network-wifi dlog glib-2.0")
+if 'ALL' in transport:
+ env.AppendUnique(CPPDEFINES = ['WIFI_ADAPTER', 'NO_ETHERNET_ADAPTER','EDR_ADAPTER','LE_ADAPTER'])
+ print "CA Transport is ALL"
+else:
+ if 'BT' in transport:
+ env.AppendUnique(CPPDEFINES = ['EDR_ADAPTER'])
+ print "CA Transport is BT"
+ else:
+ env.AppendUnique(CPPDEFINES = ['NO_EDR_ADAPTER'])
+
+ if 'BLE' in transport:
+ env.AppendUnique(CPPDEFINES = ['LE_ADAPTER'])
+ print "CA Transport is BLE"
+ else:
+ env.AppendUnique(CPPDEFINES = ['NO_LE_ADAPTER'])
+
+ if 'IP' in transport:
+ env.AppendUnique(CPPDEFINES = ['WIFI_ADAPTER'])
+ print "CA Transport is WIFI"
+ else:
+ env.AppendUnique(CPPDEFINES = ['NO_WIFI_ADAPTER'])
+
+env.SConscript(['../resource/SConscript'])