Added the remote adapter code in connectivity/src/ra_adapter folder.
Adding plumbing throughout the stack for applications to do requests
over remote access.
Added a C sample app ocremoteaccessclient that makes all it's requests
ONLY through the RA adapter.
Change-Id: Ie1b250a0fad584e85631f66e3d2ec4f44607320d
Signed-off-by: Mandeep Shetty <mandeep.shetty@intel.com>
Signed-off-by: Sakthivel Samidurai <sakthivel.samidurai@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1639
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Erich Keane <erich.keane@intel.com>
{
if [ $(uname -s) = "Linux" ]
then
- echo "*********** Build for linux *************"
+ echo "*********** Build for linux ************"
scons RELEASE=$3
- echo "*********** Build for linux with Security*************"
+ echo "*********** Build for linux with Security *************"
scons RELEASE=$3 SECURED=1
+
+ echo "*********** Build for linux With Remote Access *************"
+ scons RELEASE=$3 WITH_RA=1
+
+ echo "*********** Build for linux With Remote Access & Security ************"
+ scons RELEASE=$3 WITH_RA=1 SECURED=1
fi
# Note: for android, as oic-resource uses C++11 feature stoi and to_string,
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(BoolVariable('WITH_RA', 'Build with Remote Access module', False))
+
if target_os in targets_disallow_multitransport:
- help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'IP', ['BT', 'BLE', 'IP']))
+ help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'IP', ['BT', 'BLE', 'IP']))
else:
- help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'ALL', ['ALL', 'BT', 'BLE', 'IP']))
+ help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'ALL', ['ALL', 'BT', 'BLE', 'IP']))
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')))
# tinycbor build/fetch
SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'tinycbor', 'SConscript'))
+with_ra = env.get('WITH_RA')
+if with_ra:
+ SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'raxmpp', 'SConscript'))
+
+
env.AddMethod(__prepare_lib, "PrepareLib")
env.AddMethod(__configure, "Configure")
env.AddMethod(__download, "Download")
--- /dev/null
+#******************************************************************
+#
+# Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+######################################################################
+# raxmpp library build script
+#
+######################################################################
+import os
+import commands
+
+Import('env')
+
+src_dir = env.get('SRC_DIR')
+target_os = env.get('TARGET_OS')
+target_arch = env.get('TARGET_ARCH')
+with_ra = env.get('WITH_RA')
+if with_ra:
+ # check 'raxmppl' library, if it doesn't exits, ask user to download it
+ if not os.path.exists('raxmpp'):
+ print '''
+ *********************************** Error: ***********************************************
+ * Please download ra_xmpp as following :
+ * $ git clone https://gerrit.iotivity.org/gerrit/iotivity-xmpp extlibs/raxmpp/raxmpp
+ ******************************************************************************************
+ '''
+ Exit(1)
+
+ print 'building with ra_xmpp'
+ if env.get('RELEASE'):
+ print src_dir
+ build_dir = os.path.join(src_dir, 'extlibs/raxmpp/raxmpp/out', target_os, target_arch, 'release/')
+ else:
+ build_dir = os.path.join(src_dir, 'extlibs/raxmpp/raxmpp/out/', target_os, target_arch, 'debug/')
+ os.chdir('raxmpp')
+ sconsflags = ' RELEASE=true' if env['RELEASE'] else ' RELEASE=false'
+ foo=commands.getoutput('scons external' + sconsflags )
+ print foo
+ foo=commands.getoutput('scons' + sconsflags )
+ print foo
+
+ env.AppendUnique(CPPPATH = src_dir+'/extlibs/raxmpp/raxmpp/ra_xmpp/',
+ LIBPATH=build_dir,
+ RPATH = build_dir)
target_os = env.get('TARGET_OS')
target_arch = env.get('TARGET_ARCH')
src_dir = env.get('SRC_DIR')
+
liboctbstack_env = lib_env.Clone()
target_os = env.get('TARGET_OS')
+with_ra = env.get('WITH_RA')
# As in the source code, it includes arduino Time library (C++)
# It requires compile the .c with g++
if target_os == 'arduino':
liboctbstack_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
-if target_os in ['android', 'linux', 'tizen']:
+if target_os in ['android', 'linux','tizen']:
liboctbstack_env.AppendUnique(LIBS = ['connectivity_abstraction'])
+ if with_ra:
+ liboctbstack_env.AppendUnique(LIBS = ['ra_xmpp'])
liboctbstack_env.AppendUnique(LIBS = ['coap', 'm'])
if target_os == 'tizen':
target_os = env.get('TARGET_OS')
transport = env.get('TARGET_TRANSPORT')
build_sample = env.get('BUILD_SAMPLE')
+with_ra = env.get('WITH_RA')
print "Given Transport is %s" % transport
print "Given OS is %s" % target_os
Exit(1)
if 'ALL' in transport:
+ if with_ra == True:
+ env.AppendUnique(CPPDEFINES = ['RA_ADAPTER'])
if target_os == 'linux':
env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','NO_EDR_ADAPTER','NO_LE_ADAPTER'])
elif target_os == 'tizen':
env.SConscript('./src/SConscript')
if build_sample == 'ON':
- if target_os in ['linux', 'arduino', 'android']:
- env.SConscript('./samples/' + target_os + '/SConscript')
+ if target_os in ['linux', 'arduino', 'android', 'darwin']:
+ target_path = target_os
+ if target_os == 'darwin':
+ target_path = 'linux'
+ env.SConscript('./samples/' + target_path + '/SConscript')
#define CA_IPADDR_SIZE 16
/**
+ * @brief Remote Access jabber ID length.
+ */
+#define CA_RAJABBERID_SIZE 256
+
+/**
* @brief Mac address length for BT port
*/
#define CA_MACADDR_SIZE 18
// The following flags are the same as the equivalent OIC values in
// octypes.h, allowing direct copying with slight fixup.
// The CA layer should used the OC types when build allows that.
+#ifdef RA_ADAPTER
+#define MAX_ADDR_STR_SIZE_CA (256)
+#else
#define MAX_ADDR_STR_SIZE_CA (40)
+#endif
typedef enum
{
CA_DEFAULT_ADAPTER = 0,
// value zero indicates discovery
- CA_ADAPTER_IP = (1 << 0), // IPv4 and IPv6, including 6LoWPAN
- CA_ADAPTER_GATT_BTLE = (1 << 1), // GATT over Bluetooth LE
- CA_ADAPTER_RFCOMM_BTEDR = (1 << 2), // RFCOMM over Bluetooth EDR
+ CA_ADAPTER_IP = (1 << 0), // IPv4 and IPv6, including 6LoWPAN
+ CA_ADAPTER_GATT_BTLE = (1 << 1), // GATT over Bluetooth LE
+ CA_ADAPTER_RFCOMM_BTEDR = (1 << 2), // RFCOMM over Bluetooth EDR
+
+ #ifdef RA_ADAPTER
+ CA_ADAPTER_REMOTE_ACCESS = (1 << 3) // Remote Access over XMPP.
+ #endif
} CATransportAdapter_t;
typedef enum
} CAErrorInfo_t;
/**
+ * @brief CA Remote Access information for XMPP Client
+ *
+ */
+typedef struct
+{
+ char *hostname; /**< XMPP server hostname */
+ uint16_t port; /**< XMPP server serivce port */
+ char *xmpp_domain; /**< XMPP login domain */
+ char *username; /**< login username */
+ char *password; /**< login password */
+ char *resource; /**< specific resource for login */
+ char *user_jid; /**< specific JID for login */
+} CARAInfo_t;
+
+
+/**
* @brief Hold global variables for CA layer (also used by RI layer)
*/
typedef struct
*/
CAResult_t CAHandleRequestResponse();
+#ifdef RA_ADAPTER
+/**
+ * @brief Set Remote Access information for XMPP Client.
+ * @param caraInfo [IN] remote access info.
+ *
+ * @return #CA_STATUS_OK
+ */
+CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo);
+#endif
+
#ifdef __WITH_DTLS__
*/
void CAStopAdapter(CATransportAdapter_t transportType);
+#ifdef RA_ADAPTER
+/**
+ * @brief Set Remote Access information for XMPP Client.
+ * @param caraInfo [IN] remote access info.
+ *
+ * @return CA_STATUS_OK
+ */
+CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo);
+#endif
+
/**
* @brief Get network information such as ipaddress and mac information
* @param info [OUT] connectivity information such as ipaddress and mac information
--- /dev/null
+/******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+******************************************************************/
+
+/**
+ * @file caraadapter.h
+ * @brief This file contains the APIs for IP Adapter.
+ */
+#ifndef CA_RA_ADAPTER_H_
+#define CA_RA_ADAPTER_H_
+
+#include "cacommon.h"
+#include "caadapterinterface.h"
+#include "cathreadpool.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/**
+ * @brief API to initialize RA Interface.
+ * @param registerCallback [IN] Callback to register RA interfaces to Connectivity
+ * Abstraction Layer
+ * @param networkPacketCallback [IN] Callback to notify request and response messages from server(s)
+ * started at Connectivity Abstraction Layer.
+ * @param netCallback [IN] Callback to notify the network additions to Connectivity
+ * Abstraction Layer.
+ * @param handle [IN] Threadpool Handle
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback networkPacketCallback,
+ CANetworkChangeCallback netCallback,
+ ca_thread_pool_t handle);
+
+
+/**
+ * @brief Start RA Interface adapter.
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAStartRA();
+
+/**
+ * @brief Sends data to the endpoint using the adapter connectivity.
+ * @param endpoint [IN] Remote Endpoint information (like ipaddress , port,
+ * reference uri and transport type) to which the unicast data has to be sent.
+ * @param data [IN] Data which is required to be sent.
+ * @param dataLen [IN] Size of data to be sent.
+ * @return The number of bytes sent on the network. Return value equal to -1 indicates error.
+ * @remarks dataLen must be > 0.
+ */
+int32_t CASendRAUnicastData(const CAEndpoint_t *endpoint, const void *data,
+ uint32_t dataLen);
+
+/**
+ * @brief Get RA Connectivity network information
+ * @param info [OUT] Local connectivity information structures
+ * @param size [OUT] Number of local connectivity structures.
+ * @return #CA_STATUS_OK or Appropriate error code
+ * @remarks info is allocated in this API and should be freed by the caller.
+ */
+CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size);
+
+/**
+ * @brief Stops RA server and de-register XMPP callback listeners
+ * @return #CA_STATUS_OK or Appropriate error code
+ */
+CAResult_t CAStopRA();
+
+/**
+ * @brief Terminate the RA connectivity adapter.
+ * Configuration information will be deleted from further use
+ * @return NONE
+ */
+void CATerminateRA();
+
+/**
+ * @brief Set Remote Access information for XMPP Client.
+ * @param caraInfo [IN] remote access info.
+ *
+ * @return CA_STATUS_OK
+ */
+CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo);
+
+/**
+ * These functions are not applicable to Remote Access adapter
+ */
+int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
+ const void *data, uint32_t dataLen);
+/**
+ * @brief Start listening server for receiving search requests.
+ * @return #CA_NOT_SUPPORTED
+ */
+CAResult_t CAStartRAListeningServer();
+
+/**
+ * @brief Start discovery servers for receiving advertisements.
+ * @return #CA_NOT_SUPPORTED
+ */
+CAResult_t CAStartRADiscoveryServer();
+
+/**
+ * @brief Read Synchronous API callback.
+ * @return #CA_NOT_SUPPORTED
+ */
+CAResult_t CAReadRAData();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif //CA_RA_ADAPTER_H_
+
ca_os = sample_env.get('TARGET_OS')
ca_transport = sample_env.get('TARGET_TRANSPORT')
secured = sample_env.get('SECURED')
+with_ra = sample_env.get('WITH_RA')
root_dir = './../../'
#####################################################################
print " sample src %s" % sample_src
#env.StaticLibrary('casample', sample_src)
-sample_env.PrependUnique(LIBPATH = [sample_env.get('BUILD_DIR'), '.',])
+sample_env.PrependUnique(LIBPATH = [sample_env.get('BUILD_DIR'), '.'])
sample_env.PrependUnique(RPATH = [sample_env.get('BUILD_DIR'), '.',])
-sample_env.PrependUnique(LIBS = ['connectivity_abstraction', 'coap', 'pthread', 'rt'])
+sample_env.PrependUnique(LIBS = ['connectivity_abstraction'])
+if with_ra:
+ sample_env.AppendUnique(LIBS = ['ra_xmpp'])
+sample_env.AppendUnique(LIBS = ['coap', 'pthread'])
+
+if ca_os not in ['darwin']:
+ sample_env.PrependUnique(LIBS = ['rt'])
if secured == '1':
current_dir=env.get('SRC_DIR')
ca_os = env.get('TARGET_OS')
ca_transport = env.get('TARGET_TRANSPORT')
secured = env.get('SECURED')
+with_ra = env.get ('WITH_RA')
root_dir = os.pardir
ca_path = os.curdir
env.AppendUnique(CA_SRC = ca_common_src)
if 'ALL' in ca_transport:
- transports = [ 'ip_adapter', 'bt_edr_adapter', 'bt_le_adapter' ]
- env.SConscript(dirs = [
- os.path.join(ca_path, d) for d in transports ])
+ transports = [ 'ip_adapter', 'bt_edr_adapter', 'bt_le_adapter' ]
+ if with_ra:
+ transports.append ('ra_adapter')
+ env.SConscript(dirs = [
+ os.path.join(ca_path, d) for d in transports ])
if 'IP' in ca_transport:
env.SConscript(os.path.join(ca_path, 'ip_adapter/SConscript'))
res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns error : %d", res);
}
+
+ #ifdef RA_ADAPTER
+ else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
+ {
+ res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
+ OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns error : %d",
+ res);
+ }
+ #endif
else
{
res = CA_NOT_SUPPORTED;
}
-
return res;
}
res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns error : %d", res);
}
+ #ifdef RA_ADAPTER
+ else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
+ {
+ res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
+ OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns error : %d",
+ res);
+ }
+ #endif
else
{
res = CA_STATUS_FAILED;
}
-
return res;
}
#include "caremotehandler.h"
#include "cathreadpool.h"
#include "caipadapter.h"
+#include "cainterface.h"
+
+#ifdef RA_ADAPTER
+#include "caraadapter.h"
+#endif
#define TAG "CA_INTRFC_CNTRLR"
+#ifdef RA_ADAPTER
+#include "caraadapter.h"
+#endif
+
#define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
{OIC_LOG(ERROR, TAG, "memory error");goto memory_error_exit;} }
+#ifdef RA_ADAPTER
+#define CA_TRANSPORT_TYPE_NUM 4
+#else
#define CA_TRANSPORT_TYPE_NUM 3
+#endif
static CAConnectivityHandler_t g_adapterHandler[CA_TRANSPORT_TYPE_NUM] = {};
return 1;
case CA_ADAPTER_RFCOMM_BTEDR:
return 2;
+
+ #ifdef RA_ADAPTER
+ case CA_ADAPTER_REMOTE_ACCESS:
+ return 3;
+ #endif
+
default:
break;
}
-
- OIC_LOG(DEBUG, TAG, "CA_TRANSPORT_TYPE_NUM is not 3");
-
return -1;
}
OIC_LOG(DEBUG, TAG, "OUT");
}
+#ifdef RA_ADAPTER
+CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo)
+{
+ return CASetRAInfo(caraInfo);
+}
+#endif
+
static void CAReceivedPacketCallback(const CAEndpoint_t *endpoint, void *data, uint32_t dataLen)
{
OIC_LOG(DEBUG, TAG, "IN");
CAAdapterErrorHandleCallback, handle);
#endif /* LE_ADAPTER */
+#ifdef RA_ADAPTER
+ CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
+ handle);
+#endif /* RA_ADAPTER */
+
+
}
void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
static uint32_t NETWORK_RFCOMM = CA_ADAPTER_RFCOMM_BTEDR;
static uint32_t NETWORK_GATT = CA_ADAPTER_GATT_BTLE;
+#ifdef RA_ADAPTER
+static uint32_t NETWORK_RA = CA_ADAPTER_REMOTE_ACCESS;
+#endif
+
CAResult_t CAAddNetworkType(CATransportAdapter_t transportType)
{
OIC_LOG(DEBUG, TAG, "IN");
}
res = u_arraylist_add(g_selectedNetworkList, &NETWORK_GATT);
break;
+
+#ifdef RA_ADAPTER
+ case CA_ADAPTER_REMOTE_ACCESS:
+
+ OIC_LOG(DEBUG, TAG, "Add network type(RA)");
+ if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_RA))
+ {
+ goto exit;
+ }
+ res = u_arraylist_add(g_selectedNetworkList, &NETWORK_RA);
+ break;
+#endif /* RA_ADAPTER */
+
default:
break;
}
OIC_LOG(DEBUG, TAG, "Remove network type(LE)");
u_arraylist_remove(g_selectedNetworkList, index);
#endif /* LE_ADAPTER */
+
+ break;
+#ifdef RA_ADAPTER
+ case CA_ADAPTER_REMOTE_ACCESS:
+ OIC_LOG(DEBUG, TAG, "Remove network type(RA)");
+ u_arraylist_remove(g_selectedNetworkList, index);
break;
+#endif /* RA_ADAPTER */
default:
break;
--- /dev/null
+#******************************************************************
+#
+# Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('env')
+import os
+
+print "Reading RA adapter script"
+
+target_os = env.get('TARGET_OS')
+inc_files = env.get('CPPPATH')
+src_dir = './ra_adapter'
+
+#Source files to build in Linux platform
+env.AppendUnique(CA_SRC=[os.path.join(src_dir, 'caraadapter.c')])
--- /dev/null
+/******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+******************************************************************/
+
+#include "caraadapter.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "caadapterutils.h"
+#include "camutex.h"
+#include "uarraylist.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ra_xmpp.h"
+#include "caremotehandler.h"
+#include "cacommon.h"
+
+/**
+ * @def RA_ADAPTER_TAG
+ * @brief Logging tag for module name
+ */
+#define RA_ADAPTER_TAG "RA_ADAP"
+
+/**
+ * @var g_networkPacketCallback
+ * @brief Network Packet Received Callback to CA
+ */
+static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
+
+/**
+ * @var g_networkChangeCallback
+ * @brief Network Changed Callback to CA
+ */
+static CANetworkChangeCallback g_networkChangeCallback = NULL;
+
+/**
+ * @var CARAXmppData
+ * @brief Holds XMPP data information.
+ */
+typedef struct
+{
+ xmpp_context_t context;
+ xmpp_handle_t handle;
+ xmpp_connection_callback_t connection_callback;
+ xmpp_connection_handle_t connection_handle;
+ xmpp_message_context_t message_context;
+ xmpp_message_callback_t message_callback;
+ CANetworkStatus_t connection_status;
+ xmpp_host_t g_host;
+ xmpp_identity_t g_identity;
+ char jabberID[CA_RAJABBERID_SIZE];
+} CARAXmppData_t;
+
+static ca_mutex g_raadapterMutex = NULL;
+
+static CARAXmppData_t g_xmppData = {};
+
+static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
+
+static void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
+ const char *const bound_jid,
+ xmpp_connection_handle_t connection);
+
+static void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
+ xmpp_connection_handle_t connection);
+
+static void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
+ const void *const recipient, const void *const msg, size_t messageOctets);
+
+static void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
+ const void *const sender, const void *const msg, size_t messageOctets);
+
+void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
+{
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
+
+ CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+ CA_ADAPTER_REMOTE_ACCESS,
+ address, 0);
+ if (!localEndpoint)
+ {
+ OIC_LOG(ERROR, RA_ADAPTER_TAG, "localEndpoint creation failed!");
+ return;
+ }
+ CANetworkChangeCallback networkChangeCallback = g_networkChangeCallback;
+ if (networkChangeCallback)
+ {
+ networkChangeCallback(localEndpoint, status);
+ }
+ else
+ {
+ OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
+ }
+
+ CAFreeEndpoint(localEndpoint);
+
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
+}
+
+void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
+ const char *const bound_jid,
+ xmpp_connection_handle_t connection)
+{
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB IN");
+ CANetworkStatus_t connection_status;
+ if (XMPP_ERR_OK == result)
+ {
+ printf("\n\n\t\t===>your jid: %s\n\n", bound_jid);
+
+ ca_mutex_lock (g_raadapterMutex);
+ OICStrcpy (g_xmppData.jabberID, CA_RAJABBERID_SIZE, bound_jid);
+
+ g_xmppData.connection_status = CA_INTERFACE_UP;
+ connection_status = CA_INTERFACE_UP;
+ g_xmppData.connection_handle = connection;
+ g_xmppData.message_callback.on_received = CARAXmppMessageReceivedCB;
+ g_xmppData.message_callback.on_sent = CARAXmppMessageSentCB;
+ g_xmppData.message_context = xmpp_message_context_create(g_xmppData.connection_handle,
+ g_xmppData.message_callback);
+ }
+ else
+ {
+ g_xmppData.connection_status = CA_INTERFACE_DOWN;
+ connection_status = CA_INTERFACE_DOWN;
+ OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "XMPP connected callback status: %d", result);
+ }
+
+ ca_mutex_unlock (g_raadapterMutex);
+ // Notify network change to CA
+ CARANotifyNetworkChange(bound_jid, connection_status);
+
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB OUT");
+}
+
+void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
+ xmpp_connection_handle_t connection)
+{
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB IN");
+ char jabberID[CA_RAJABBERID_SIZE];
+ ca_mutex_lock (g_raadapterMutex);
+
+ g_xmppData.connection_status = CA_INTERFACE_DOWN;
+ xmpp_message_context_destroy(g_xmppData.message_context);
+ OICStrcpy (jabberID, CA_RAJABBERID_SIZE, g_xmppData.jabberID);
+
+ ca_mutex_unlock (g_raadapterMutex);
+
+ // Notify network change to CA
+ CARANotifyNetworkChange(jabberID, CA_INTERFACE_DOWN);
+
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB OUT");
+}
+
+void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
+ const void *const recipient, const void *const msg, size_t messageOctets)
+{
+ OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending message to %s has result %d",
+ recipient, result);
+}
+
+void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
+ const void *const sender, const void *const msg, size_t messageOctets)
+{
+ if (g_networkPacketCallback)
+ {
+ VERIFY_NON_NULL_VOID(sender, RA_ADAPTER_TAG, "sender is NULL");
+ VERIFY_NON_NULL_VOID(msg, RA_ADAPTER_TAG, "message is NULL");
+
+ OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message received from %s", sender);
+ OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message reception result %d", result);
+
+ CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+ CA_ADAPTER_REMOTE_ACCESS, sender, 0);
+ if (!endPoint)
+ {
+ OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
+ return;
+ }
+
+ void *buf = OICMalloc(messageOctets);
+ if (!buf)
+ {
+ OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
+ CAFreeEndpoint(endPoint);
+ return;
+ }
+ memcpy(buf, msg, messageOctets);
+ CANetworkPacketReceivedCallback networkPacketCallback = g_networkPacketCallback;
+ if (networkPacketCallback)
+ {
+ g_networkPacketCallback(endPoint, buf, messageOctets);
+ }
+
+ CAFreeEndpoint (endPoint);
+ }
+ else
+ {
+ OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
+ }
+}
+
+CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback networkPacketCallback,
+ CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
+{
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
+ if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
+ {
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ g_networkChangeCallback = netCallback;
+ g_networkPacketCallback = networkPacketCallback;
+
+ CAConnectivityHandler_t raHandler = {};
+ raHandler.startAdapter = CAStartRA;
+ raHandler.startListenServer = CAStartRAListeningServer;
+ raHandler.startDiscoveryServer = CAStartRADiscoveryServer;
+ raHandler.sendData = CASendRAUnicastData;
+ raHandler.sendDataToAll = CASendRAMulticastData;
+ raHandler.GetnetInfo = CAGetRAInterfaceInformation;
+ raHandler.readData = CAReadRAData;
+ raHandler.stopAdapter = CAStopRA;
+ raHandler.terminate = CATerminateRA;
+ registerCallback(raHandler, CA_ADAPTER_REMOTE_ACCESS);
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
+{
+ if (!caraInfo)
+ {
+ return CA_STATUS_INVALID_PARAM;
+ }
+ xmpp_identity_init(&g_xmppData.g_identity, caraInfo->username, caraInfo->password,
+ caraInfo->user_jid, XMPP_TRY_IN_BAND_REGISTER);
+ xmpp_host_init(&g_xmppData.g_host, caraInfo->hostname, caraInfo->port,
+ caraInfo->xmpp_domain, XMPP_PROTOCOL_XMPP);
+ return CA_STATUS_OK;
+}
+
+void CATerminateRA()
+{
+ CAStopRA();
+}
+
+CAResult_t CAStartRA()
+{
+ if (g_xmppData.handle.abstract_handle)
+ {
+ OIC_LOG(WARNING, RA_ADAPTER_TAG, "RA adapter already started");
+ return CA_STATUS_OK;
+ }
+
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
+
+ g_raadapterMutex = ca_mutex_new ();
+ if (!g_raadapterMutex)
+ {
+ OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ ca_mutex_lock (g_raadapterMutex);
+
+ xmpp_context_init(&g_xmppData.context);
+ g_xmppData.handle = xmpp_startup(&g_xmppData.context);
+
+ // Wire up connection callbacks and call API to connect to XMPP server
+ g_xmppData.connection_callback.on_connected = CARAXmppConnectedCB;
+ g_xmppData.connection_callback.on_disconnected = CARAXmppDisonnectedCB;
+
+ xmpp_error_code_t ret = xmpp_connect(g_xmppData.handle, &g_xmppData.g_host,
+ &g_xmppData.g_identity, g_xmppData.connection_callback);
+
+ // Destroy host and identity structures as they are only
+ // required to establish initial connection
+ xmpp_identity_destroy(&g_xmppData.g_identity);
+ xmpp_host_destroy(&g_xmppData.g_host);
+
+ ca_mutex_unlock (g_raadapterMutex);
+
+ if (XMPP_ERR_OK != ret)
+ {
+ OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to init XMPP connection status: %d",
+ ret);
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAStopRA()
+{
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
+
+ xmpp_error_code_t ret = xmpp_close(g_xmppData.connection_handle);
+ if (XMPP_ERR_OK != ret)
+ {
+ OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to close XMPP connection, status: %d",
+ ret);
+ return CA_STATUS_FAILED;
+ }
+
+ xmpp_shutdown_xmpp(g_xmppData.handle);
+ xmpp_context_destroy(&g_xmppData.context);
+ ca_mutex_free (g_raadapterMutex);
+ g_raadapterMutex = NULL;
+
+ OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
+ return CA_STATUS_OK;
+}
+
+int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
+ uint32_t dataLength)
+{
+ if (!remoteEndpoint || !data)
+ {
+ OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
+ return -1;
+ }
+
+ if (0 == dataLength)
+ {
+ OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
+ return 0;
+ }
+
+ OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
+ ca_mutex_lock (g_raadapterMutex);
+
+ if (CA_INTERFACE_UP != g_xmppData.connection_status)
+ {
+ OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
+ ca_mutex_unlock (g_raadapterMutex);
+ return -1;
+ }
+
+ xmpp_error_code_t res = xmpp_send_message(g_xmppData.message_context,
+ remoteEndpoint->addr, data, dataLength,
+ XMPP_MESSAGE_TRANSMIT_DEFAULT);
+ if (XMPP_ERR_OK != res)
+ {
+ OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, status: %d", res);
+ ca_mutex_unlock (g_raadapterMutex);
+ return -1;
+ }
+ ca_mutex_unlock (g_raadapterMutex);
+
+ OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
+ dataLength, remoteEndpoint->addr);
+
+ return dataLength;
+}
+
+CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
+{
+ VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
+ VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
+
+ ca_mutex_lock (g_raadapterMutex);
+
+ if (CA_INTERFACE_UP != g_xmppData.connection_status)
+ {
+ OIC_LOG(ERROR, RA_ADAPTER_TAG, "Failed to get interface info, RA not Connected");
+ ca_mutex_unlock (g_raadapterMutex);
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ ca_mutex_unlock (g_raadapterMutex);
+
+ CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+ CA_ADAPTER_REMOTE_ACCESS,
+ g_xmppData.jabberID, 0);
+
+ *size = 1;
+ *info = localEndpoint;
+
+ return CA_STATUS_OK;
+}
+
+int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
+ const void *data, uint32_t dataLength)
+{
+ OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
+ return 0;
+}
+
+CAResult_t CAStartRAListeningServer()
+{
+ OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
+ return CA_NOT_SUPPORTED;
+}
+
+CAResult_t CAStartRADiscoveryServer()
+{
+ OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
+ return CA_NOT_SUPPORTED;
+}
+
+CAResult_t CAReadRAData()
+{
+ OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
+ return CA_NOT_SUPPORTED;
+}
*/
OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode);
+#ifdef RA_ADAPTER
+/**
+ * @brief Set Remote Access information for XMPP Client.
+ * @param raInfo [IN] remote access info.
+ *
+ * @return #CA_STATUS_OK
+ */
+OCStackResult OCSetRAInfo(const OCRAInfo_t *raInfo);
+#endif
+
/**
* Stop the OC stack. Use for a controlled shutdown.
*
//-----------------------------------------------------------------------------
// Typedefs
//-----------------------------------------------------------------------------
-
+#ifdef RA_ADAPTER
+#define MAX_ADDR_STR_SIZE (256)
+#else
#define MAX_ADDR_STR_SIZE (40)
+ #endif
+
#define MAX_IDENTITY_SIZE (32)
+
/*
* These enums (OCTransportAdapter and OCTransportFlags) must
* be kept synchronized with OCConnectivityType (below) as well as
OC_DEFAULT_ADAPTER = 0,
// value zero indicates discovery
- OC_ADAPTER_IP = (1 << 0), // IPv4 and IPv6, including 6LoWPAN
- OC_ADAPTER_GATT_BTLE = (1 << 1), // GATT over Bluetooth LE
- OC_ADAPTER_RFCOMM_BTEDR = (1 << 2), // RFCOMM over Bluetooth EDR
+ OC_ADAPTER_IP = (1 << 0), // IPv4 and IPv6, including 6LoWPAN
+ OC_ADAPTER_GATT_BTLE = (1 << 1), // GATT over Bluetooth LE
+ OC_ADAPTER_RFCOMM_BTEDR = (1 << 2), // RFCOMM over Bluetooth EDR
+
+ #ifdef RA_ADAPTER
+ OC_ADAPTER_REMOTE_ACCESS = (1 << 3) // Remote Access over XMPP.
+ #endif
} OCTransportAdapter;
// enum layout assumes some targets have 16-bit integer (e.g., Arduino)
CT_ADAPTER_IP = (1 << 10), // IPv4 and IPv6, including 6LoWPAN
CT_ADAPTER_GATT_BTLE = (1 << 11), // GATT over Bluetooth LE
CT_ADAPTER_RFCOMM_BTEDR = (1 << 12), // RFCOMM over Bluetooth EDR
+ #ifdef RA_ADAPTER
+ CT_ADAPTER_REMOTE_ACCESS = (1 << 13), // Remote Access over XMPP
+ #endif
#define CT_ADAPTER_SHIFT 10
#define CT_MASK_FLAGS 0x03FF
#define CT_MASK_ADAPTER 0xFC00
CT_ADAPTER_IP = (1 << 16), // IPv4 and IPv6, including 6LoWPAN
CT_ADAPTER_GATT_BTLE = (1 << 17), // GATT over Bluetooth LE
CT_ADAPTER_RFCOMM_BTEDR = (1 << 18), // RFCOMM over Bluetooth EDR
+ #ifdef RA_ADAPTER
+ CT_ADAPTER_REMOTE_ACCESS = (1 << 19), // Remote Access over XMPP
+ #endif
#define CT_ADAPTER_SHIFT 16
#define CT_MASK_FLAGS 0xFFFF
#define CT_MASK_ADAPTER 0xFFFF0000
} OCPlatformInfo;
+#ifdef RA_ADAPTER
+/**
+ * @brief CA Remote Access information for XMPP Client
+ *
+ */
+typedef struct
+{
+ char *hostname; /**< XMPP server hostname */
+ uint16_t port; /**< XMPP server serivce port */
+ char *xmpp_domain; /**< XMPP login domain */
+ char *username; /**< login username */
+ char *password; /**< login password */
+ char *resource; /**< specific resource for login */
+ char *user_jid; /**< specific JID for login */
+} OCRAInfo_t;
+#endif /* RA_ADAPTER */
+
/**
* This structure is expected as input for device properties.
* device name is mandatory and expected from the application.
Import('env')
target_os = env.get('TARGET_OS')
samples_env = env.Clone()
+with_ra = env.get ('WITH_RA')
######################################################################
# Build flags
######################################################################
occlientcoll = samples_env.Program('occlientcoll', ['occlientcoll.cpp', 'common.cpp'])
ocserverbasicops = samples_env.Program('ocserverbasicops', ['ocserverbasicops.cpp', 'common.cpp'])
occlientbasicops = samples_env.Program('occlientbasicops', ['occlientbasicops.cpp', 'common.cpp'])
+if with_ra:
+ ocremoteaccessclient = samples_env.Program('ocremoteaccessclient',
+ ['ocremoteaccessclient.cpp','common.cpp'])
-Alias("samples", [ocserver, occlient,
+list_of_samples = [ocserver, occlient,
ocservercoll, occlientcoll,
ocserverbasicops, occlientbasicops,
ocserverslow, occlientslow
- ])
+ ]
+if with_ra:
+ list_of_samples.append (ocremoteaccessclient)
+Alias("samples", list_of_samples)
env.AppendTarget('samples')
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <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 "ocpayload.h"
+#include "ocremoteaccessclient.h"
+
+// Tracking user input
+static int TEST_CASE = 0;
+
+static const char * MULTICAST_DEVICE_DISCOVERY_QUERY = "/oic/d";
+static const char * MULTICAST_PLATFORM_DISCOVERY_QUERY = "/oic/p";
+static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
+
+static std::string coapServerIP = "255.255.255.255";
+static std::string coapServerPort = "5683";
+static std::string coapServerResource = "/a/light";
+static OCDevAddr responseAddr;
+//Use ipv4addr for both InitDiscovery and InitPlatformOrDeviceDiscovery
+char remoteServerJabberID[MAX_ADDR_STR_SIZE];
+void StripNewLineChar(char* str);
+static uint16_t maxNotification = 15;
+
+// 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", 42);
+ OCRepPayloadSetPropBool(payload, "state", true);
+ return (OCPayload*) payload;
+}
+
+static void PrintUsage()
+{
+ OC_LOG(INFO, TAG, "This sample makes all requests via the remote access adapter");
+ OC_LOG(INFO, TAG, "Usage : ocremoteaccessclient -t <number>");
+ OC_LOG(INFO, TAG, "-t 1 : Discover Resources");
+ OC_LOG(INFO, TAG, "-t 2 : Discover & Get");
+ OC_LOG(INFO, TAG, "-t 3 : Discover & Put");
+ OC_LOG(INFO, TAG, "-t 4 : Discover & Post");
+ OC_LOG(INFO, TAG, "-t 5 : Discover & Delete");
+ OC_LOG(INFO, TAG, "-t 6 : Discover & Observe");
+ OC_LOG(INFO, TAG, "-t 7 : Discover & Observe then cancel immediately with High QOS");
+}
+
+OCStackResult InvokeOCDoResource(std::ostringstream &query,
+ OCMethod method,
+ OCQualityOfService qos,
+ OCClientResponseHandler cb,
+ OCHeaderOption * options,
+ uint8_t numOptions)
+{
+ OCCallbackData cbData;
+ OCDoHandle handle;
+
+ cbData.cb = cb;
+ cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ OCStackResult ret = OCDoResource(
+ &handle,
+ method,
+ query.str().c_str(),
+ &responseAddr,
+ (method == OC_REST_PUT) ? putPayload() : NULL,
+ CT_ADAPTER_REMOTE_ACCESS,
+ qos,
+ &cbData,
+ options,
+ numOptions);
+
+ if (ret != OC_STACK_OK)
+ {
+ OC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, method);
+ }
+ else if (method == OC_REST_OBSERVE || method == OC_REST_OBSERVE_ALL)
+ {
+ gObserveDoHandle = handle;
+ }
+#ifdef WITH_PRESENCE
+ else if (method == OC_REST_PRESENCE)
+ {
+ gPresenceHandle = handle;
+ }
+#endif
+
+ return ret;
+}
+
+OCStackApplicationResult restRequestCB(void* ctx,
+ OCDoHandle handle, OCClientResponse * clientResponse)
+{
+ if(clientResponse == NULL)
+ {
+ OC_LOG(INFO, TAG, "Received NULL response");
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+ {
+ OC_LOG(INFO, TAG, "Callback Context recvd successfully");
+ }
+
+ OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
+ OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
+ OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+ if(clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
+ {
+ OC_LOG (INFO, TAG, "Received vendor specific options. Ignoring");
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+ if(!clientResponse)
+ {
+ OC_LOG_V(INFO, TAG, "obsReqCB received NULL response");
+ }
+ if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+ {
+ OC_LOG(INFO, TAG, "Callback Context recvd successfully");
+ }
+ OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
+ OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
+ OC_LOG_V(INFO, TAG, "OBSERVE notification %d recvd", gNumObserveNotifies);
+ OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+ gNumObserveNotifies++;
+ if (gNumObserveNotifies == maxNotification)
+ {
+ if (OCCancel (gObserveDoHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "Observe cancel error");
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ if (gNumObserveNotifies == 1 && TEST_CASE == TEST_OBS_REQ_NON_CANCEL_IMM)
+ {
+ if (OCCancel (gObserveDoHandle, OC_HIGH_QOS, NULL, 0) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "Observe cancel error");
+ }
+ }
+ if(clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
+ {
+ OC_LOG(INFO, TAG, "Registration confirmed");
+ }
+ else if(clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
+ {
+ OC_LOG(INFO, TAG, "de-registration confirmed");
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ else if(clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
+ {
+ OC_LOG(INFO, TAG, "Registration/deregistration failed");
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ return OC_STACK_KEEP_TRANSACTION;
+}
+#ifdef WITH_PRESENCE
+OCStackApplicationResult presenceCB(void* ctx,
+ OCDoHandle handle, OCClientResponse * clientResponse)
+{
+ if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
+ {
+ OC_LOG(INFO, TAG, "Callback Context recvd successfully");
+ }
+
+ if (clientResponse)
+ {
+ OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
+ OC_LOG_V(INFO, TAG, "NONCE NUMBER: %u", clientResponse->sequenceNumber);
+ OC_LOG_V(INFO, TAG, "PRESENCE notification %d recvd", gNumPresenceNotifies);
+ OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+ gNumPresenceNotifies++;
+ if (gNumPresenceNotifies == maxNotification)
+ {
+ if (OCCancel(gPresenceHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "Presence cancel error");
+ }
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "presenceCB 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)
+ {
+ OC_LOG(INFO, TAG, "DISCOVER callback recvd");
+ }
+
+ if (!clientResponse)
+ {
+ OC_LOG_V(INFO, TAG, "discoveryReqCB received Null clientResponse");
+ }
+
+ OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
+ OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+
+ responseAddr = clientResponse->devAddr;
+
+ switch(TEST_CASE)
+ {
+ OC_LOG_V(INFO, TAG, "TEST_CASE %u\n", TEST_CASE);
+ case TEST_GET_REQ_NON:
+ InitGetRequest(OC_LOW_QOS);
+ 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;
+ default:
+ PrintUsage();
+ break;
+ }
+ return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult PlatformDiscoveryReqCB (void* ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+ {
+ OC_LOG(INFO, TAG, "Callback Context for Platform DISCOVER query recvd successfully");
+ }
+
+ if(clientResponse)
+ {
+ OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
+ }
+
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+ {
+ OC_LOG(INFO, TAG, "Callback Context for Device DISCOVER query recvd successfully");
+ }
+
+ if(clientResponse)
+ {
+ OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "PlatformDiscoveryReqCB received Null clientResponse");
+ }
+
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+int InitObserveRequest(OCQualityOfService qos)
+{
+ OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+ std::ostringstream query;
+ query << coapServerResource;
+ return (InvokeOCDoResource(query,
+ OC_REST_OBSERVE, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS, obsReqCB, NULL, 0));
+}
+
+int InitPutRequest(OCQualityOfService qos)
+{
+ OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+ std::ostringstream query;
+ query << coapServerResource;
+ return (InvokeOCDoResource(query, OC_REST_PUT, (qos == OC_HIGH_QOS)? OC_HIGH_QOS:OC_LOW_QOS,
+ restRequestCB, NULL, 0));
+}
+
+int InitPostRequest(OCQualityOfService qos)
+{
+ OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+ std::ostringstream query;
+ query << coapServerResource;
+ // First POST operation (to create an Light instance)
+ OCStackResult result = InvokeOCDoResource(query, OC_REST_POST,
+ ((qos == OC_HIGH_QOS) ? OC_HIGH_QOS: OC_LOW_QOS),
+ restRequestCB, NULL, 0);
+ if (OC_STACK_OK != result)
+ {
+ // Error can happen if for example, network connectivity is down
+ OC_LOG(INFO, TAG, "First 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),
+ restRequestCB, NULL, 0);
+ if (OC_STACK_OK != result)
+ {
+ OC_LOG(INFO, TAG, "Second 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),
+ restRequestCB, NULL, 0));
+}
+
+int InitDeleteRequest(OCQualityOfService qos)
+{
+ std::ostringstream query;
+ query << coapServerResource;
+ OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+
+ // First DELETE operation
+ OCStackResult result = InvokeOCDoResource(query, OC_REST_DELETE,
+ qos,
+ restRequestCB, NULL, 0);
+ if (OC_STACK_OK != result)
+ {
+ // Error can happen if for example, network connectivity is down
+ OC_LOG(INFO, TAG, "DELETE call did not succeed");
+ }
+ return result;
+}
+
+int InitGetRequest(OCQualityOfService qos)
+{
+ OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+ std::ostringstream query;
+ query << coapServerResource;
+ return (InvokeOCDoResource(query, OC_REST_GET,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, restRequestCB, NULL, 0));
+}
+
+int InitDiscovery(OCQualityOfService qos)
+{
+ OCCallbackData cbData;
+ cbData.cb = discoveryReqCB;
+ cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ OCDevAddr dest;
+ dest.adapter = OC_ADAPTER_REMOTE_ACCESS;
+ dest.flags = OC_DEFAULT_FLAGS;
+ strncpy (dest.addr, remoteServerJabberID, MAX_ADDR_STR_SIZE - 1);
+
+ OCStackResult ret = OCDoResource(NULL,
+ OC_REST_GET,
+ MULTICAST_RESOURCE_DISCOVERY_QUERY,
+ &dest,
+ NULL,
+ CT_ADAPTER_REMOTE_ACCESS,
+ (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+ &cbData,
+ NULL,
+ 0
+ );
+
+ if (ret != OC_STACK_OK)
+ {
+ OC_LOG_V(ERROR, TAG, "Error %u in OCDoResource with discovery", ret);
+ }
+ return ret;
+}
+
+OCStackResult initRemoteAccessAdapter ()
+{
+ OCRAInfo_t rainfo;
+ rainfo.hostname = "localhost";
+ rainfo.port = 5222;
+ rainfo.xmpp_domain = "localhost";
+ rainfo.username = "test1";
+ rainfo.password = "intel123";
+ rainfo.resource = "";
+ rainfo.user_jid = "";
+
+ return OCSetRAInfo(&rainfo);
+}
+
+int main(int argc, char* argv[])
+{
+ int opt;
+
+ while ((opt = getopt(argc, argv, "t:")) != -1)
+ {
+ switch(opt)
+ {
+ case 't':
+ TEST_CASE = atoi(optarg);
+ break;
+ default:
+ PrintUsage();
+ return -1;
+ }
+ }
+
+ if (initRemoteAccessAdapter() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "Error initiating remote access adapter");
+ return 0;
+ }
+
+ if ((TEST_CASE < TEST_DISCOVER_REQ || TEST_CASE >= MAX_TESTS))
+ {
+ PrintUsage();
+ return -1;
+ }
+
+ if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack init error");
+ return 0;
+ }
+
+ OC_LOG(INFO, TAG, "Enter JID of remote server");
+ if (fgets(remoteServerJabberID, MAX_ADDR_STR_SIZE, stdin))
+ {
+ StripNewLineChar(remoteServerJabberID);
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, "Bad input for jabberID");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ InitDiscovery(OC_LOW_QOS);
+
+ // Break from loop with Ctrl+C
+ OC_LOG(INFO, TAG, "Press CTRL+C to stop the stack");
+ signal(SIGINT, handleSigInt);
+ while (!gQuitFlag)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ return 0;
+ }
+
+ sleep(2);
+ }
+ OC_LOG(INFO, TAG, "Exiting ocremoteaccessclient main loop...");
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack stop error");
+ }
+
+ return 0;
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OCREMOTECLIENT_H_
+#define OCREMOTECLIENT_H_
+
+#include "ocstack.h"
+
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+#define TAG "occlient_remoteaccess"
+#define DEFAULT_CONTEXT_VALUE 0x99
+#ifndef MAX_LENGTH_IPv4_ADDR
+#define MAX_LENGTH_IPv4_ADDR 16
+#endif
+
+/**
+ * List of methods that can be initiated from the client
+ */
+typedef enum {
+ TEST_DISCOVER_REQ = 1,
+ TEST_GET_REQ_NON,
+ TEST_PUT_REQ_NON,
+ TEST_POST_REQ_NON,
+ TEST_DELETE_REQ_NON,
+ TEST_OBS_REQ_NON,
+ TEST_OBS_REQ_NON_CANCEL_IMM,
+ TEST_DISCOVER_PLATFORM_REQ,
+ TEST_DISCOVER_DEV_REQ,
+ MAX_TESTS
+} CLIENT_TEST;
+
+/* call getResult in common.cpp to get the result in string format. */
+const char *getResult(OCStackResult result);
+
+/* 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);
+int InitPostRequest(OCQualityOfService qos);
+int InitDeleteRequest(OCQualityOfService qos);
+int InitDeviceDiscovery(OCQualityOfService qos);
+int InitPlatformDiscovery(OCQualityOfService qos);
+int InitDiscovery(OCQualityOfService qos);
+
+
+/*
+ * 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);
+
+/*
+ * 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
+
PrintUsage();
return -1;
}
+ #ifdef RA_ADAPTER
+ OCRAInfo_t rainfo;
+ rainfo.hostname = "localhost";
+ rainfo.port = 5222;
+ rainfo.xmpp_domain = "localhost";
+ rainfo.username = "test1";
+ rainfo.password = "intel123";
+ rainfo.resource = "";
+ rainfo.user_jid = "";
+
+ OCSetRAInfo(&rainfo);
+ #endif
OC_LOG(DEBUG, TAG, "OCServer is starting...");
}
#ifdef WITH_PRESENCE
- CATransportAdapter_t CAConnTypes[] = {CA_ADAPTER_IP, CA_ADAPTER_GATT_BTLE,
- CA_ADAPTER_RFCOMM_BTEDR};
- const char * connTypes[] = {"ip" , "ble", "edr"};
+ CATransportAdapter_t CAConnTypes[] = {
+ CA_ADAPTER_IP,
+ CA_ADAPTER_GATT_BTLE,
+ CA_ADAPTER_RFCOMM_BTEDR
+
+ #ifdef RA_ADAPTER
+ , CA_ADAPTER_REMOTE_ACCESS
+ #endif
+ };
+ const char * connTypes[] = {"ip" , "ble", "edr"
+ #ifdef RA_ADAPTER
+ , "ra"
+ #endif
+ };
int size = sizeof(CAConnTypes)/ sizeof(CATransportAdapter_t);
+
CATransportAdapter_t adapter = responseEndpoint.adapter;
CAResult_t caResult = CA_STATUS_FAILED;
result = OC_STACK_OK;
if (adapter == CA_DEFAULT_ADAPTER)
{
adapter =
- (CATransportAdapter_t)(CA_ADAPTER_IP | CA_ADAPTER_GATT_BTLE | CA_ADAPTER_RFCOMM_BTEDR);
+ (CATransportAdapter_t)(
+ CA_ADAPTER_IP |
+ CA_ADAPTER_GATT_BTLE |
+ CA_ADAPTER_RFCOMM_BTEDR
+
+ #ifdef RA_ADAP
+ | CA_ADAPTER_REMOTE_ACCESS
+ #endif
+ );
}
for(int i = 0; i < size; i++ )
caResult = CASendResponse(&responseEndpoint, &responseInfo);
if(caResult != CA_STATUS_OK)
{
- OC_LOG_V(ERROR, TAG, "CASendResponse failed on %s", connTypes[i]);
+ OC_LOG_V(ERROR, TAG, "CASendResponse failed with CA error %u", caResult);
result = CAResultToOCResult(caResult);
}
- else
- {
- OC_LOG_V(INFO, TAG, "CASendResponse succeeded on %s", connTypes[i]);
- }
}
}
#else
#endif
static OCMode myStackMode;
+#ifdef RA_ADAPTER
+//TODO: revisit this design
+static bool gRASetInfo = false;
+#endif
OCDeviceEntityHandler defaultDeviceHandler;
void* defaultDeviceHandlerCallbackParameter = NULL;
//-----------------------------------------------------------------------------
// Public APIs
//-----------------------------------------------------------------------------
+#ifdef RA_ADAPTER
+OCStackResult OCSetRAInfo(const OCRAInfo_t *raInfo)
+{
+ if (!raInfo ||
+ !raInfo->username ||
+ !raInfo->hostname ||
+ !raInfo->xmpp_domain)
+ {
+
+ return OC_STACK_INVALID_PARAM;
+ }
+ OCStackResult result = CAResultToOCResult(CASetRAInfo((const CARAInfo_t *) raInfo));
+ gRASetInfo = (result == OC_STACK_OK)? true : false;
+
+ return result;
+}
+#endif
OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
{
(void) ipAddr;
(void) port;
-
+#ifdef RA_ADAPTER
+ if(!gRASetInfo)
+ {
+ OC_LOG(ERROR, TAG, PCF("Need to call OCSetRAInfo before calling OCInit"));
+ return OC_STACK_ERROR;
+ }
+#endif
return OCInit1(mode, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS);
}
CATransportAdapter_t connTypes[] = {
CA_ADAPTER_IP,
CA_ADAPTER_RFCOMM_BTEDR,
- CA_ADAPTER_GATT_BTLE};
+ CA_ADAPTER_GATT_BTLE
+
+ #ifdef RA_ADAPTER
+ ,CA_ADAPTER_REMOTE_ACCESS
+ #endif
+ };
int numConnTypes = sizeof(connTypes)/sizeof(connTypes[0]);
for(int i = 0; i<numConnTypes; i++)
auto cLock = m_csdkLock.lock();
std::ostringstream os;
- os << host << OC_RSRVD_PRESENCE_URI;;
+ os << host << OC_RSRVD_PRESENCE_URI;
if(!resourceType.empty())
{