Rebase remote-access over master 39/1639/13
authorSakthivel Samidurai <sakthivel.samidurai@intel.com>
Fri, 17 Jul 2015 16:34:36 +0000 (09:34 -0700)
committerErich Keane <erich.keane@intel.com>
Fri, 17 Jul 2015 23:21:26 +0000 (23:21 +0000)
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>
27 files changed:
auto_build.sh
build_common/SConscript
build_common/external_libs.scons
extlibs/raxmpp/SConscript [new file with mode: 0644]
extra_options.scons
resource/csdk/SConscript
resource/csdk/connectivity/SConscript
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/api/cainterface.h
resource/csdk/connectivity/inc/cainterfacecontroller.h
resource/csdk/connectivity/inc/caraadapter.h [new file with mode: 0644]
resource/csdk/connectivity/samples/linux/SConscript
resource/csdk/connectivity/src/SConscript
resource/csdk/connectivity/src/caconnectivitymanager.c
resource/csdk/connectivity/src/cainterfacecontroller.c
resource/csdk/connectivity/src/canetworkconfigurator.c
resource/csdk/connectivity/src/ra_adapter/SConscript [new file with mode: 0644]
resource/csdk/connectivity/src/ra_adapter/caraadapter.c [new file with mode: 0644]
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/samples/linux/SimpleClientServer/SConscript
resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp [new file with mode: 0644]
resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h [new file with mode: 0644]
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/src/ocserverrequest.c
resource/csdk/stack/src/ocstack.c
resource/src/InProcClientWrapper.cpp

index adb514d..4defa66 100755 (executable)
@@ -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,
index 544bd1a..575288c 100644 (file)
@@ -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')))
index cc60e2d..52f0546 100644 (file)
@@ -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 (file)
index 0000000..29d5cad
--- /dev/null
@@ -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)
index 4403138..c8453c6 100644 (file)
@@ -30,3 +30,4 @@ Import('env')
 target_os = env.get('TARGET_OS')
 target_arch = env.get('TARGET_ARCH')
 src_dir = env.get('SRC_DIR')
+
index 9519797..cee8dc9 100644 (file)
@@ -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':
index ae0e16b..4c0f448 100644 (file)
@@ -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')
 
index e8a59e2..00dac16 100644 (file)
@@ -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)
  */
index 5a65ee0..27b4ff2 100644 (file)
@@ -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__
 
index b322237..034e374 100644 (file)
@@ -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 (file)
index 0000000..3f08647
--- /dev/null
@@ -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_
+
index bd3bfe9..9bcc7e2 100755 (executable)
@@ -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')
index f1ca463..7a91274 100755 (executable)
@@ -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'))
index b8e9f42..98b3ffd 100644 (file)
@@ -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;
 }
 
index 1a91252..6c4a81f 100644 (file)
 #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)
index fa776c0..01e9d4d 100644 (file)
@@ -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 (file)
index 0000000..2b077bb
--- /dev/null
@@ -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 (file)
index 0000000..7413035
--- /dev/null
@@ -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 <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;
+}
index 86ec2b9..44c926d 100644 (file)
@@ -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.
  *
index a9603ea..93fa702 100644 (file)
@@ -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.
index 6f9a37e..ba5da01 100644 (file)
@@ -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 (file)
index 0000000..89da3ff
--- /dev/null
@@ -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 <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;
+}
diff --git a/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h b/resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.h
new file mode 100644 (file)
index 0000000..f121a12
--- /dev/null
@@ -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
+
index b0acb2c..02ef935 100644 (file)
@@ -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...");
 
index db84e9e..4f883a2 100644 (file)
@@ -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
index d2c730a..63fa7c3 100644 (file)
@@ -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<numConnTypes; i++)
index a022c61..bb794e1 100644 (file)
@@ -755,7 +755,7 @@ namespace OC
         auto cLock = m_csdkLock.lock();
 
         std::ostringstream os;
-        os << host << OC_RSRVD_PRESENCE_URI;;
+        os << host << OC_RSRVD_PRESENCE_URI;
 
         if(!resourceType.empty())
         {