From 074d5ecdd557332ca4550e08f9718dfc35279f60 Mon Sep 17 00:00:00 2001 From: Sakthivel Samidurai Date: Fri, 17 Jul 2015 09:34:36 -0700 Subject: [PATCH] Rebase remote-access over master 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 Signed-off-by: Sakthivel Samidurai Reviewed-on: https://gerrit.iotivity.org/gerrit/1639 Tested-by: jenkins-iotivity Reviewed-by: Erich Keane --- auto_build.sh | 10 +- build_common/SConscript | 7 +- build_common/external_libs.scons | 5 + extlibs/raxmpp/SConscript | 60 ++ extra_options.scons | 1 + resource/csdk/SConscript | 5 +- resource/csdk/connectivity/SConscript | 10 +- resource/csdk/connectivity/api/cacommon.h | 35 +- resource/csdk/connectivity/api/cainterface.h | 10 + .../connectivity/inc/cainterfacecontroller.h | 10 + resource/csdk/connectivity/inc/caraadapter.h | 131 +++++ .../connectivity/samples/linux/SConscript | 11 +- resource/csdk/connectivity/src/SConscript | 9 +- .../connectivity/src/caconnectivitymanager.c | 19 +- .../connectivity/src/cainterfacecontroller.c | 35 +- .../connectivity/src/canetworkconfigurator.c | 24 + .../connectivity/src/ra_adapter/SConscript | 31 ++ .../connectivity/src/ra_adapter/caraadapter.c | 427 ++++++++++++++ resource/csdk/stack/include/ocstack.h | 10 + resource/csdk/stack/include/octypes.h | 40 +- .../linux/SimpleClientServer/SConscript | 11 +- .../ocremoteaccessclient.cpp | 523 ++++++++++++++++++ .../SimpleClientServer/ocremoteaccessclient.h | 93 ++++ .../linux/SimpleClientServer/ocserver.cpp | 12 + resource/csdk/stack/src/ocserverrequest.c | 34 +- resource/csdk/stack/src/ocstack.c | 36 +- resource/src/InProcClientWrapper.cpp | 2 +- 27 files changed, 1563 insertions(+), 38 deletions(-) create mode 100644 extlibs/raxmpp/SConscript create mode 100644 resource/csdk/connectivity/inc/caraadapter.h create mode 100644 resource/csdk/connectivity/src/ra_adapter/SConscript create mode 100644 resource/csdk/connectivity/src/ra_adapter/caraadapter.c create mode 100644 resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp create mode 100644 resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h diff --git a/auto_build.sh b/auto_build.sh index adb514dea..4defa6626 100755 --- a/auto_build.sh +++ b/auto_build.sh @@ -16,11 +16,17 @@ function build() { 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, diff --git a/build_common/SConscript b/build_common/SConscript index 544bd1af7..575288c3b 100644 --- a/build_common/SConscript +++ b/build_common/SConscript @@ -77,10 +77,13 @@ help_vars.Add(BoolVariable('VERBOSE', 'Show compilation', False)) 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'))) diff --git a/build_common/external_libs.scons b/build_common/external_libs.scons index cc60e2d20..52f05460e 100644 --- a/build_common/external_libs.scons +++ b/build_common/external_libs.scons @@ -124,6 +124,11 @@ SConscript('tools/UnpackAll.py') # 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") diff --git a/extlibs/raxmpp/SConscript b/extlibs/raxmpp/SConscript new file mode 100644 index 000000000..29d5cad0d --- /dev/null +++ b/extlibs/raxmpp/SConscript @@ -0,0 +1,60 @@ +#****************************************************************** +# +# 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) diff --git a/extra_options.scons b/extra_options.scons index 4403138e2..c8453c61a 100644 --- a/extra_options.scons +++ b/extra_options.scons @@ -30,3 +30,4 @@ Import('env') target_os = env.get('TARGET_OS') target_arch = env.get('TARGET_ARCH') src_dir = env.get('SRC_DIR') + diff --git a/resource/csdk/SConscript b/resource/csdk/SConscript index 951979727..cee8dc948 100644 --- a/resource/csdk/SConscript +++ b/resource/csdk/SConscript @@ -29,6 +29,7 @@ SConscript(env.get('SRC_DIR') + '/resource/third_party_libs.scons', 'lib_env') 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': @@ -65,8 +66,10 @@ if target_os not in ['windows', 'winrt']: 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': diff --git a/resource/csdk/connectivity/SConscript b/resource/csdk/connectivity/SConscript index ae0e16b64..4c0f448a6 100644 --- a/resource/csdk/connectivity/SConscript +++ b/resource/csdk/connectivity/SConscript @@ -7,6 +7,7 @@ Import('env') 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 @@ -21,6 +22,8 @@ if target_os in targets_disallow_multitransport: 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': @@ -60,6 +63,9 @@ else: 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') diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index e8a59e2c5..00dac1677 100644 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -41,6 +41,11 @@ extern "C" */ #define CA_IPADDR_SIZE 16 +/** + * @brief Remote Access jabber ID length. + */ +#define CA_RAJABBERID_SIZE 256 + /** * @brief Mac address length for BT port */ @@ -113,16 +118,24 @@ typedef char *CAToken_t; // 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 @@ -348,6 +361,22 @@ typedef struct helpful to identify the error */ } 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) */ diff --git a/resource/csdk/connectivity/api/cainterface.h b/resource/csdk/connectivity/api/cainterface.h index 5a65ee07b..27b4ff2eb 100644 --- a/resource/csdk/connectivity/api/cainterface.h +++ b/resource/csdk/connectivity/api/cainterface.h @@ -245,6 +245,16 @@ CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size); */ 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__ diff --git a/resource/csdk/connectivity/inc/cainterfacecontroller.h b/resource/csdk/connectivity/inc/cainterfacecontroller.h index b322237d5..034e374a2 100644 --- a/resource/csdk/connectivity/inc/cainterfacecontroller.h +++ b/resource/csdk/connectivity/inc/cainterfacecontroller.h @@ -88,6 +88,16 @@ CAResult_t CAStartAdapter(CATransportAdapter_t transportType); */ 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 diff --git a/resource/csdk/connectivity/inc/caraadapter.h b/resource/csdk/connectivity/inc/caraadapter.h new file mode 100644 index 000000000..3f0864743 --- /dev/null +++ b/resource/csdk/connectivity/inc/caraadapter.h @@ -0,0 +1,131 @@ +/****************************************************************** +// +// 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_ + diff --git a/resource/csdk/connectivity/samples/linux/SConscript b/resource/csdk/connectivity/samples/linux/SConscript index bd3bfe9bf..9bcc7e25d 100755 --- a/resource/csdk/connectivity/samples/linux/SConscript +++ b/resource/csdk/connectivity/samples/linux/SConscript @@ -9,6 +9,7 @@ sample_env = env.Clone() 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 = './../../' ##################################################################### @@ -35,9 +36,15 @@ sample_src = ['./sample_main.c',] 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') diff --git a/resource/csdk/connectivity/src/SConscript b/resource/csdk/connectivity/src/SConscript index f1ca463ae..7a912740f 100755 --- a/resource/csdk/connectivity/src/SConscript +++ b/resource/csdk/connectivity/src/SConscript @@ -9,6 +9,7 @@ Import('env') 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 @@ -89,9 +90,11 @@ ca_common_src = [ 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')) diff --git a/resource/csdk/connectivity/src/caconnectivitymanager.c b/resource/csdk/connectivity/src/caconnectivitymanager.c index b8e9f42cc..98b3ffd1d 100644 --- a/resource/csdk/connectivity/src/caconnectivitymanager.c +++ b/resource/csdk/connectivity/src/caconnectivitymanager.c @@ -253,11 +253,19 @@ CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork) 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; } @@ -287,11 +295,18 @@ CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork) 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; } diff --git a/resource/csdk/connectivity/src/cainterfacecontroller.c b/resource/csdk/connectivity/src/cainterfacecontroller.c index 1a912525a..6c4a81f51 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller.c @@ -33,13 +33,26 @@ #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] = {}; @@ -59,12 +72,15 @@ static int CAGetAdapterIndex(CATransportAdapter_t cType) 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; } @@ -100,6 +116,13 @@ static void CARegisterCallback(CAConnectivityHandler_t handler, CATransportAdapt 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"); @@ -167,6 +190,12 @@ void CAInitializeAdapters(ca_thread_pool_t handle) CAAdapterErrorHandleCallback, handle); #endif /* LE_ADAPTER */ +#ifdef RA_ADAPTER + CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, + handle); +#endif /* RA_ADAPTER */ + + } void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback) diff --git a/resource/csdk/connectivity/src/canetworkconfigurator.c b/resource/csdk/connectivity/src/canetworkconfigurator.c index fa776c048..01e9d4dfa 100644 --- a/resource/csdk/connectivity/src/canetworkconfigurator.c +++ b/resource/csdk/connectivity/src/canetworkconfigurator.c @@ -32,6 +32,10 @@ static uint32_t NETWORK_IP = CA_ADAPTER_IP; 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"); @@ -90,6 +94,19 @@ CAResult_t CAAddNetworkType(CATransportAdapter_t transportType) } 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; } @@ -164,7 +181,14 @@ CAResult_t CARemoveNetworkType(CATransportAdapter_t transportType) 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; diff --git a/resource/csdk/connectivity/src/ra_adapter/SConscript b/resource/csdk/connectivity/src/ra_adapter/SConscript new file mode 100644 index 000000000..2b077bb9b --- /dev/null +++ b/resource/csdk/connectivity/src/ra_adapter/SConscript @@ -0,0 +1,31 @@ +#****************************************************************** +# +# 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')]) diff --git a/resource/csdk/connectivity/src/ra_adapter/caraadapter.c b/resource/csdk/connectivity/src/ra_adapter/caraadapter.c new file mode 100644 index 000000000..7413035d3 --- /dev/null +++ b/resource/csdk/connectivity/src/ra_adapter/caraadapter.c @@ -0,0 +1,427 @@ +/****************************************************************** +// +// 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 +#include +#include +#include + +#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; +} diff --git a/resource/csdk/stack/include/ocstack.h b/resource/csdk/stack/include/ocstack.h index 86ec2b90c..44c926de5 100644 --- a/resource/csdk/stack/include/ocstack.h +++ b/resource/csdk/stack/include/ocstack.h @@ -62,6 +62,16 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag */ 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. * diff --git a/resource/csdk/stack/include/octypes.h b/resource/csdk/stack/include/octypes.h index a9603ea4f..93fa7027e 100644 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@ -126,10 +126,15 @@ extern "C" { //----------------------------------------------------------------------------- // 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 @@ -141,9 +146,13 @@ typedef enum 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) @@ -217,6 +226,9 @@ typedef enum 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 @@ -224,6 +236,9 @@ typedef enum 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 @@ -515,6 +530,23 @@ typedef struct } 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. diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/SConscript b/resource/csdk/stack/samples/linux/SimpleClientServer/SConscript index 6f9a37e92..ba5da01f3 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/SConscript +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/SConscript @@ -21,6 +21,7 @@ Import('env') target_os = env.get('TARGET_OS') samples_env = env.Clone() +with_ra = env.get ('WITH_RA') ###################################################################### # Build flags ###################################################################### @@ -59,12 +60,18 @@ ocservercoll = samples_env.Program('ocservercoll', ['ocservercoll.cpp', 'com 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') diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp b/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp new file mode 100644 index 000000000..89da3ff61 --- /dev/null +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp @@ -0,0 +1,523 @@ +//****************************************************************** +// +// 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 +#include +#include +#include +#include +#include +#include +#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"<"); + 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; +} diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h b/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h new file mode 100644 index 000000000..f121a1244 --- /dev/null +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h @@ -0,0 +1,93 @@ +//****************************************************************** +// +// 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 + diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp index b0acb2cce..02ef93581 100644 --- a/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp +++ b/resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp @@ -949,6 +949,18 @@ int main(int argc, char* argv[]) 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..."); diff --git a/resource/csdk/stack/src/ocserverrequest.c b/resource/csdk/stack/src/ocserverrequest.c index db84e9e64..4f883a2d5 100644 --- a/resource/csdk/stack/src/ocserverrequest.c +++ b/resource/csdk/stack/src/ocserverrequest.c @@ -537,10 +537,22 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) } #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; @@ -549,7 +561,15 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) 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++ ) @@ -562,13 +582,9 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse) 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 diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index d2c730abd..63fa7c3de 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -98,6 +98,10 @@ static uint32_t PresenceTimeOut[] = {50, 75, 85, 95, 100}; #endif static OCMode myStackMode; +#ifdef RA_ADAPTER +//TODO: revisit this design +static bool gRASetInfo = false; +#endif OCDeviceEntityHandler defaultDeviceHandler; void* defaultDeviceHandlerCallbackParameter = NULL; @@ -1527,12 +1531,35 @@ bool validatePlatformInfo(OCPlatformInfo info) //----------------------------------------------------------------------------- // 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); } @@ -3800,7 +3827,12 @@ CAResult_t OCSelectNetwork() 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