Merge branch 'master' into ra.to.merge
authorMandeep Shetty <mandeep.shetty@intel.com>
Thu, 10 Sep 2015 00:58:44 +0000 (17:58 -0700)
committerMandeep Shetty <mandeep.shetty@intel.com>
Thu, 10 Sep 2015 00:58:44 +0000 (17:58 -0700)
Conflicts:
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp

Change-Id: I70ecb709845861789f326053b2135ca964bd21a5
Signed-off-by: Mandeep Shetty <mandeep.shetty@intel.com>
13 files changed:
README-building-and-running-remote-access-sample.txt [new file with mode: 0644]
Readme.scons.txt
build_common/SConscript
build_common/external_libs.scons
extlibs/libstrophe/SConscript [new file with mode: 0644]
extlibs/libstrophe/strophe-xmpp_conn_is_secured.patch [new file with mode: 0644]
extlibs/wksxmppxep/SConscript [new file with mode: 0644]
resource/csdk/SConscript
resource/csdk/connectivity/samples/linux/SConscript
resource/csdk/connectivity/src/ra_adapter/SConscript
resource/csdk/connectivity/src/ra_adapter/caraadapter.c
resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp

diff --git a/README-building-and-running-remote-access-sample.txt b/README-building-and-running-remote-access-sample.txt
new file mode 100644 (file)
index 0000000..79d7fbd
--- /dev/null
@@ -0,0 +1,42 @@
+== Quick guide: build and run IoTivity(remote access) projects on Ubuntu ==
+
+1. Build
+       Go to the top directory of 'iotivity' project
+    (Note: should always run 'scons' command in this directory)
+
+    Install external libraries:
+      $ sudo apt-get install libboost-dev libboost-program-options-dev libexpat1-dev libboost-thread-dev uuid-dev libssl-dev
+      $ sudo apt-get install libglib2.0-dev autoconf libtool
+
+    Build release binaries:
+      $ scons WITH_RA=1 WITH_RA_IBB=1
+(Note: C sdk requires tiny-cbor. Please follow the instruction in the build
+message to install tiny-cbor)
+
+    Build debug binaries:
+      $ scons WITH_RA=1 WITH_RA_IBB=1 RELEASE=false
+
+    Help:
+      $ scons -h
+
+    Clear:
+      $ scons -c
+
+2. Run the remote access testing
+    remote access samples in <iotivity>/out/linux/x86_64/release/resource/csdk/stack/samples/linux/SimpleClientServer
+
+    before testing,
+      setup a XMPP server and create an account in XMPP server
+      ex: account: user1@localhost / password: 1234
+
+    oic server:
+      $ ocserver -o 1 -u user1 -d localhost -w 1234 -s localhost
+
+    oic client:
+      $ ocremoteaccessclient -t 1 -u user1 -d localhost -w 1234 -s localhost
+
+    test steps:
+      1. run ocserver, and copy the bound jid
+      2. run ocremoteaccessclient on the another term, and paste the bound jid of ocserver and press 'Enter'
+        use '-t' to change testcase.
+
index bc0c411..ae2dab5 100644 (file)
@@ -5,7 +5,7 @@
 command in this directory)
 
     Install external libraries:
-      $ sudo apt-get install libboost-dev libboost-program-options-dev libexpat1-dev libboost-thread-dev uuid-dev libssl-dev
+      $ sudo apt-get install libboost-dev libboost-program-options-dev libexpat1-dev libboost-thread-dev uuid-dev libssl-dev libtool
 
     Build release binaries:
       $ scons
@@ -137,7 +137,7 @@ to skip it.
 
 1. Build IoTivity project for Linux
       $ cd <top directory of the project>
-      $ sudo apt-get install libboost-dev libexpat1-dev libboost-thread-dev libssl-dev
+      $ sudo apt-get install libboost-dev libexpat1-dev libboost-thread-dev libssl-dev libtool
       $ scons
 
 2. Build IoTivity project for Android
index 9bda366..9c0b73e 100644 (file)
@@ -79,6 +79,7 @@ help_vars.Add(EnumVariable('TARGET_OS', 'Target platform', host, host_target_map
 
 
 help_vars.Add(BoolVariable('WITH_RA', 'Build with Remote Access module', False))
+help_vars.Add(BoolVariable('WITH_RA_IBB', 'Build with Remote Access module(workssys)', False))
 
 if target_os in targets_disallow_multitransport:
        help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'IP', ['BT', 'BLE', 'IP']))
index 52f0546..65c25ec 100644 (file)
@@ -128,6 +128,10 @@ with_ra = env.get('WITH_RA')
 if with_ra:
        SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'raxmpp', 'SConscript'))
 
+with_ra_ibb = env.get('WITH_RA_IBB')
+if with_ra_ibb:
+       SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'wksxmppxep', 'SConscript'))
+
 
 env.AddMethod(__prepare_lib, "PrepareLib")
 env.AddMethod(__configure, "Configure")
diff --git a/extlibs/libstrophe/SConscript b/extlibs/libstrophe/SConscript
new file mode 100644 (file)
index 0000000..55871d6
--- /dev/null
@@ -0,0 +1,75 @@
+######################################################################
+# ref. raxmpp library build script
+#
+######################################################################
+import os
+import commands
+
+Import('env')
+
+base_dir = env.get('SRC_DIR')
+target_os = env.get('TARGET_OS')
+target_arch = env.get('TARGET_ARCH')
+build_path = Dir('.').abspath
+
+with_ra_ibb = env.get('WITH_RA_IBB')
+PKG_NAME = 'strophe'
+SRC_NAME = 'libstrophe'
+EXT_NAME = 'libstrophe'
+EXT_BASE = 'extlibs/' + EXT_NAME
+EXT_PATH = EXT_BASE + '/' + SRC_NAME
+SRC_PATH = base_dir + '/' + EXT_PATH
+INC_PATH = SRC_PATH
+LIB_PATH = SRC_PATH + '/' + '.libs'
+
+if with_ra_ibb:
+       # check 'libstrophe' library, if it doesn't exits, ask user to download it
+       if not os.path.exists(SRC_NAME):
+               raxmpp_env = Environment(ENV = os.environ)
+               c = raxmpp_env.Action(['git clone https://github.com/strophe/libstrophe.git ' + SRC_NAME,
+                       'cd ' + SRC_NAME + ' && git checkout 527bc0573a52f2af3ecad5b9ef39aeec7b669f77'
+                       ])
+
+               print 'Downloading xmpp library ...'
+               if raxmpp_env.Execute(c):
+                       print '''
+       *********************************** Error: ***********************************************
+       * Please download ra_xmpp as following:
+       *     $ git clone https://github.com/strophe/libstrophe.git extlibs/libstrophe/libstrophe
+       *     $ cd  extlibs/libstrophe/libstrophe
+       *     $ git checkout 527bc0573a52f2af3ecad5b9ef39aeec7b669f77
+       ******************************************************************************************
+       '''
+                       Exit(1)
+               else:
+                       print 'Download xmpp library complete'
+
+       print 'Building with ' + SRC_NAME
+       #print 'base_dir', base_dir
+       #print 'target_os', target_os
+       #print 'target_arch', target_arch
+
+       foo=commands.getoutput('patch -N -p1 -d libstrophe < strophe-xmpp_conn_is_secured.patch')
+       print foo
+
+       os.chdir(SRC_NAME)
+       #sconsflags = ' RELEASE=true' if  env['RELEASE'] else ' RELEASE=false'
+       if not os.path.exists('configure') :
+               foo=commands.getoutput('./bootstrap.sh')
+               #print foo
+       if not os.path.exists('config.status') :
+               foo=commands.getoutput('./configure')
+               #print foo
+       if not os.path.exists('.libs/libstrophe.a') :
+               foo=commands.getoutput('make libstrophe.la')
+               #print foo
+       if not os.path.exists('.libs/libstrophe.a') :
+               print 'Building with ' + SRC_NAME + ' failed.'
+               Exit(2)
+
+       print 'Building with ' + SRC_NAME + ' Completely.'
+       env.AppendUnique(CPPPATH = [INC_PATH], RALIBS = ['strophe', 'ssl', 'crypto', 'resolv', 'expat'], RALIBPATH = [LIB_PATH], RARPATH = [LIB_PATH])
+
+if env.GetOption('clean') :
+       act = env.Action(['cd ' + SRC_PATH, 'make clean'])
+       env.Execute(act)
diff --git a/extlibs/libstrophe/strophe-xmpp_conn_is_secured.patch b/extlibs/libstrophe/strophe-xmpp_conn_is_secured.patch
new file mode 100644 (file)
index 0000000..958783b
--- /dev/null
@@ -0,0 +1,28 @@
+diff --git a/src/conn.c b/src/conn.c
+index d72386f..e4f0a39 100644
+--- a/src/conn.c
++++ b/src/conn.c
+@@ -742,6 +742,11 @@ void xmpp_conn_disable_tls(xmpp_conn_t * const conn)
+     conn->tls_disabled = 1;
+ }
++int xmpp_conn_is_secured(xmpp_conn_t * const conn)
++{
++    return conn->secured == 1 && conn->tls_failed == 0 ? 1 : 0;
++}
++
+ static void _log_open_tag(xmpp_conn_t *conn, char **attrs)
+ {
+     char buf[4096];
+diff --git a/strophe.h b/strophe.h
+index 80a5390..64b2352 100644
+--- a/strophe.h
++++ b/strophe.h
+@@ -215,6 +215,7 @@ const char *xmpp_conn_get_pass(const xmpp_conn_t * const conn);
+ void xmpp_conn_set_pass(xmpp_conn_t * const conn, const char * const pass);
+ xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn);
+ void xmpp_conn_disable_tls(xmpp_conn_t * const conn);
++int xmpp_conn_is_secured(xmpp_conn_t * const conn);
+ int xmpp_connect_client(xmpp_conn_t * const conn, 
+                         const char * const altdomain,
diff --git a/extlibs/wksxmppxep/SConscript b/extlibs/wksxmppxep/SConscript
new file mode 100644 (file)
index 0000000..9dc9833
--- /dev/null
@@ -0,0 +1,55 @@
+######################################################################
+# Ref. libstrophe library build script
+#
+######################################################################
+import os
+import commands
+
+Import('env')
+
+base_dir = env.get('SRC_DIR')
+target_os = env.get('TARGET_OS')
+target_arch = env.get('TARGET_ARCH')
+
+with_ra_ibb = env.get('WITH_RA_IBB')
+
+SRC_NAME = 'wks_xep0047'
+EXT_NAME = 'wksxmppxep'
+EXT_BASE = 'extlibs/' + EXT_NAME
+EXT_PATH = EXT_BASE + '/' + SRC_NAME
+SRC_PATH = base_dir + '/' + EXT_PATH
+INC_PATH = SRC_PATH + '/include'
+LIB_PATH = SRC_PATH
+
+if with_ra_ibb:
+       env.SConscript(base_dir + '/extlibs/libstrophe/SConscript')
+       if not os.path.exists(SRC_NAME):
+               raxmpp_env = Environment(ENV = os.environ)
+               c = raxmpp_env.Action(['git clone https://github.com/WorksSystems/wks_xep0047.git ' + SRC_NAME,
+                       'cd ' + SRC_NAME + ' && git checkout b95f22064241d1319c4dc967878706b4a446d186'
+        ])
+
+               print 'Downloading', SRC_NAME ,'library ...'
+               if raxmpp_env.Execute(c):
+                       print '''
+       *********************************** Error: ***********************************************
+       * Please download ra_xmpp as following:
+       *     $ git clone https://github.com/WorksSystems/wksxmpp_chat.git extlibs/wksxmppxep/wksxmpp_chat
+       *     $ cd extlibs/wksxmppxep/wksxmpp_chat
+       *     $ git checkout 9f5d726df9779bec5d3036acfbca70c97958921d
+       ******************************************************************************************
+       '''
+                       Exit(1)
+               else:
+                       print 'Download', SRC_NAME, 'library complete'
+
+       os.chdir(SRC_NAME)
+       if not os.path.exists(SRC_NAME + '/libwksxmppxep.so') :
+               LIBSTROPHE_BASE=base_dir + '/extlibs/libstrophe/libstrophe'
+               foo=commands.getoutput('make LIBSTROPHE_BASE=' + LIBSTROPHE_BASE + ' libraries')
+               #print foo
+       env.PrependUnique(CPPPATH = [INC_PATH], RALIBS = ['wksxmppxep', 'm', 'crypto'], RALIBPATH = [LIB_PATH], RARPATH = [LIB_PATH])
+
+if env.GetOption('clean') :
+       act = env.Action(['cd ' + SRC_PATH, 'make clean'])
+       env.Execute(act)
index 9070aeb..e0f0651 100644 (file)
@@ -30,6 +30,7 @@ liboctbstack_env = lib_env.Clone()
 
 target_os = env.get('TARGET_OS')
 with_ra = env.get('WITH_RA')
+with_ra_ibb = env.get('WITH_RA_IBB')
 # As in the source code, it includes arduino Time library (C++)
 # It requires compile the .c with g++
 if target_os == 'arduino':
@@ -68,9 +69,11 @@ liboctbstack_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
 
 if target_os in ['android', 'linux', 'tizen']:
        liboctbstack_env.PrependUnique(LIBS = ['connectivity_abstraction'])
-       if with_ra:
-               liboctbstack_env.AppendUnique(LIBS = ['ra_xmpp'])
-
+       if with_ra_ibb:
+               liboctbstack_env.AppendUnique(LIBS = liboctbstack_env['RALIBS'], LIBPATH = liboctbstack_env['RALIBPATH'], RPATH = liboctbstack_env['RARPATH'])
+       else :
+               if with_ra:
+                       liboctbstack_env.AppendUnique(LIBS = ['ra_xmpp'])
 liboctbstack_env.AppendUnique(LIBS = ['coap', 'm'])
 
 if target_os == 'tizen':
index 9bcc7e2..71c7388 100644 (file)
@@ -10,6 +10,7 @@ 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')
+with_ra_ibb = sample_env.get('WITH_RA_IBB')
 root_dir = './../../'
 
 #####################################################################
@@ -39,8 +40,11 @@ print " sample src %s" % sample_src
 sample_env.PrependUnique(LIBPATH = [sample_env.get('BUILD_DIR'), '.'])
 sample_env.PrependUnique(RPATH = [sample_env.get('BUILD_DIR'), '.',])
 sample_env.PrependUnique(LIBS = ['connectivity_abstraction'])
-if with_ra:
-       sample_env.AppendUnique(LIBS = ['ra_xmpp'])
+if with_ra_ibb:
+       sample_env.AppendUnique(LIBPATH = sample_env['RALIBPATH'], RPATH = sample_env['RARPATH'], LIBS = sample_env['RALIBS'])
+else :
+       if with_ra:
+               sample_env.AppendUnique(LIBS = ['ra_xmpp'])
 sample_env.AppendUnique(LIBS = ['coap', 'pthread'])
 
 if ca_os not in ['darwin']:
index 2b077bb..3cce282 100644 (file)
@@ -25,7 +25,11 @@ print "Reading RA adapter script"
 
 target_os = env.get('TARGET_OS')
 inc_files = env.get('CPPPATH')
+with_ra_ibb = env.get('WITH_RA_IBB')
 src_dir = './ra_adapter'
 
 #Source files to build in Linux platform
 env.AppendUnique(CA_SRC=[os.path.join(src_dir, 'caraadapter.c')])
+
+if with_ra_ibb:
+       env.AppendUnique(CPPDEFINES = ['RA_ADAPTER_IBB'])
index 4ae741f..4ace491 100644 (file)
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
-#include "ra_xmpp.h"
 #include "caremotehandler.h"
 #include "cacommon.h"
 
+#ifdef RA_ADAPTER_IBB
+#include "caprotocolmessage.h"
+#include "xmpp_helper.h"
+#include "xmpp_utils.h"
+#include "xmpp_ibb.h"
+#include "xmpp_utils.h"
+#else
+#include "ra_xmpp.h"
+#endif
+
+#ifdef RA_ADAPTER_IBB
+/**
+ * Logging tag for module name.
+ */
+#define RA_ADAPTER_TAG "RA_ADAP_IBB"
+
+/**
+ * Network Packet Received Callback to CA.
+ */
+static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
+
+/**
+ * Network Changed Callback to CA.
+ */
+static CANetworkChangeCallback g_networkChangeCallback = NULL;
+
+/**
+ * Holds XMPP data information.
+ */
+#define RA_MAX_HOSTNAME_LENGTH 256
+#define RA_MAX_PASSWORD_LENGTH 64
+typedef struct
+{
+    xmpp_t     *xmpp;
+    int         port;
+    char        hostname[RA_MAX_HOSTNAME_LENGTH];
+    char        password[RA_MAX_PASSWORD_LENGTH];
+    char        jid[CA_RAJABBERID_SIZE];
+    CANetworkStatus_t connection_status;
+} CARAXmppData_t;
+
+static ca_mutex g_raadapterMutex = NULL;
+
+static CARAXmppData_t g_xmppData = {.xmpp = NULL, .port = 5222, .hostname = {0},
+    .password = {0}, .jid = {0}, .connection_status = CA_INTERFACE_DOWN};
+
+static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
+
+void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
+{
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
+
+    g_xmppData.connection_status = status;
+
+    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");
+}
+
+#define MAX_IBB_SESSION_ID_LENGTH 32
+/* Ref. octypes.h */
+#define OBSERVE_REGISTER    0
+#define OBSERVE_DEREGISTER  1
+/* Ref. octypes.h */
+
+static ilist_t * g_observerList = NULL;
+
+typedef struct _obs_item_t
+{
+    char sessid[MAX_IBB_SESSION_ID_LENGTH + 1];
+    int  option;
+} obs_item_t;
+
+static bool CARAFindSessID(obs_item_t *item, char *key)
+{
+    if (item == NULL || key == NULL)
+    {
+        return false;
+    }
+    if (strcmp(item->sessid, key) == 0)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+static bool CARAPDUIsRequest(uint32_t x)
+{
+    return (x == CA_GET || x == CA_POST || x == CA_PUT || x == CA_DELETE);
+}
+
+static void CARAUpdateObsList(int option, char *sid)
+{
+    if (option == OBSERVE_REGISTER)
+    {
+        obs_item_t *item = (obs_item_t *) OICMalloc(sizeof(*item));
+        OICStrcpy(item->sessid, sizeof(item->sessid), sid);
+        item->option = OBSERVE_REGISTER;
+        ilist_add(g_observerList, item);
+    }
+    else if (option == OBSERVE_DEREGISTER)
+    {
+        obs_item_t *item = ilist_finditem_func(g_observerList, CARAFindSessID, sid);
+        if (item != NULL)
+        {
+            item->option = OBSERVE_DEREGISTER;
+        }
+    }
+}
+
+static int CARAGetReqObsOption(coap_pdu_t *pdu)
+{
+    uint32_t obsopt = -1;
+
+    CARequestInfo_t *reqInfo = (CARequestInfo_t *) OICMalloc(sizeof(*reqInfo));
+    VERIFY_NON_NULL_RET(reqInfo, RA_ADAPTER_TAG, "Memory alloc of CARequestInfo_t failed!", -1);
+
+    CAResult_t result = CAGetRequestInfoFromPDU(pdu, reqInfo);
+    if (CA_STATUS_OK != result)
+    {
+        OICFree(reqInfo);
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "Get Request Info failed!");
+        return -1;
+    }
+    if (!CARAPDUIsRequest(reqInfo->method))
+    {
+        OICFree(reqInfo);
+        OIC_LOG(DEBUG, RA_ADAPTER_TAG, "It is not a request data.");
+        return -1;
+    }
+
+    uint8_t numOpt = reqInfo->info.numOptions;
+    CAHeaderOption_t *options = reqInfo->info.options;
+    for (uint8_t i = 0; i < numOpt; i++)
+    {
+        if(options[i].protocolID == CA_COAP_ID &&
+                options[i].optionID == COAP_OPTION_OBSERVE)
+        {
+            obsopt = options[i].optionData[0];
+            break;
+        }
+    }
+    OICFree(reqInfo);
+    return obsopt;
+}
+
+static int CARAErrorCB(xmpp_ibb_session_t *sess, xmpperror_t *xerr)
+{
+    OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): code(%d) tyep'%s' mesg'%s'",
+            __FUNCTION__, xerr->code, xerr->type, xerr->mesg);
+    return 0;
+}
+
+static int CARAOpenCB(xmpp_ibb_session_t *sess, char *type)
+{
+    OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): set type '%s'", __FUNCTION__, type);
+    return 0;
+}
+
+static int CARACloseCB(xmpp_ibb_session_t *sess, char *type)
+{
+    OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): set type '%s'", __FUNCTION__, type);
+    char *sid = xmpp_ibb_get_sid(sess);
+    obs_item_t *item = ilist_finditem_func(g_observerList, CARAFindSessID, sid);
+    if (item != NULL)
+    {
+        ilist_remove(g_observerList, item);
+        OICFree(item);
+    }
+    return 0;
+}
+
+static char *CARAGetSIDFromPDU(coap_pdu_t *pdu)
+{
+    static char s_sid[MAX_IBB_SESSION_ID_LENGTH + 1] = {0};
+
+    VERIFY_NON_NULL_RET(pdu, RA_ADAPTER_TAG, "Invalid parameter!", NULL);
+
+    if (pdu->hdr->token_length * 2 > MAX_IBB_SESSION_ID_LENGTH)
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "Token length more than expected!");
+        return NULL;
+    }
+
+    char hex[3] = {0};
+    for (int i = 0; i < pdu->hdr->token_length; i++)
+    {
+        snprintf(hex, 3, "%02x", pdu->hdr->token[i]);
+        OICStrcat(s_sid, sizeof(s_sid), hex);
+    }
+
+    return s_sid;
+}
+
+static int CARARecvCB(xmpp_ibb_session_t *sess, xmppdata_t *xdata)
+{
+    if (xdata == NULL)
+    {
+        /* xdata == NULL, send ack result */
+        return 0;
+    }
+
+    char *msg = xdata->data;
+    char *from = xmpp_ibb_get_remote_jid(sess);
+    if (g_networkPacketCallback)
+    {
+        VERIFY_NON_NULL_RET(from, RA_ADAPTER_TAG, "from sender is NULL", -1);
+        VERIFY_NON_NULL_RET(msg, RA_ADAPTER_TAG, "message is NULL", -1);
+
+        OIC_LOG_V (DEBUG, RA_ADAPTER_TAG, "Message received from %s", from);
+
+        CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+                        CA_ADAPTER_REMOTE_ACCESS, from, 0);
+        if (!endPoint)
+        {
+            OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
+            return -1;
+        }
+        uint32_t code = CA_NOT_FOUND;
+        coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU(xdata->data, xdata->size, &code);
+        char *sid = CARAGetSIDFromPDU(pdu);
+        int obsopt = CARAGetReqObsOption(pdu);
+        coap_delete_pdu(pdu);
+
+        if (CARAPDUIsRequest(code))
+        {
+            OIC_LOG(DEBUG, RA_ADAPTER_TAG, "this is a request data");
+            if (obsopt == OBSERVE_DEREGISTER || obsopt == OBSERVE_REGISTER)
+            {
+                CARAUpdateObsList(obsopt, sid);
+            }
+        }
+        else
+        {
+            OIC_LOG(DEBUG, RA_ADAPTER_TAG, "this is a response data");
+            obs_item_t *item = ilist_finditem_func(g_observerList, CARAFindSessID, sid);
+            if (item != NULL)
+            {
+                if (item->option == OBSERVE_DEREGISTER)
+                {
+                    xmpp_ibb_close(sess);
+                    ilist_remove(g_observerList, item);
+                    OICFree(item);
+                }
+            }
+            else
+            {
+                xmpp_ibb_close(sess);
+            }
+        }
+
+        void *buf = NULL;
+        xmpp_ibb_userdata_alloc(sess, &buf, xdata->size);
+        if (!buf)
+        {
+            OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
+            CAFreeEndpoint(endPoint);
+            return -1;
+        }
+        memcpy(buf, xdata->data, xdata->size);
+        g_networkPacketCallback(endPoint, buf, xdata->size);
+
+        CAFreeEndpoint (endPoint);
+    }
+    else
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
+    }
+    return 0;
+}
+
+static int CARAConnHandler(xmpp_t *xmpp, xmppconn_info_t *conninfo, void *udata)
+{
+    if (conninfo->connevent != 0)
+    {
+        OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, " status(%d) error(%d) errorType(%d) errorText '%s'\n",
+                conninfo->connevent, conninfo->error, conninfo->errortype,
+                conninfo->errortext);
+        CARANotifyNetworkChange(g_xmppData.jid, CA_INTERFACE_DOWN);
+        return -1;
+    }
+    OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "\n\n  Bound JID: '%s'\n\n\n", xmpphelper_get_bound_jid(xmpp));
+    CARANotifyNetworkChange(xmpphelper_get_bound_jid(xmpp), CA_INTERFACE_UP);
+    return 0;
+}
+
+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)
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    g_networkChangeCallback = netCallback;
+    g_networkPacketCallback = networkPacketCallback;
+
+    CAConnectivityHandler_t raHandler = {
+        .startAdapter = CAStartRA,
+        .startListenServer = CAStartRAListeningServer,
+        .startDiscoveryServer = CAStartRADiscoveryServer,
+        .sendData = CASendRAUnicastData,
+        .sendDataToAll = CASendRAMulticastData,
+        .GetnetInfo = CAGetRAInterfaceInformation,
+        .readData = CAReadRAData,
+        .stopAdapter = CAStopRA,
+        .terminate = CATerminateRA};
+    registerCallback(raHandler, CA_ADAPTER_REMOTE_ACCESS);
+
+    g_xmppData.xmpp = xmpphelper_new(CARAConnHandler, NULL);
+    xmpphelper_force_tls(g_xmppData.xmpp);
+    g_observerList = ilist_new();
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
+{
+    if (!caraInfo)
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+    if (caraInfo->hostname != NULL)
+    {
+        OICStrcpy(g_xmppData.hostname, sizeof(g_xmppData.hostname), caraInfo->hostname);
+    }
+    else
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+    if (caraInfo->username != NULL && strlen(caraInfo->username) != 0)
+    {
+        OICStrcpy(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->username);
+    }
+    else
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+    if (caraInfo->xmpp_domain != NULL && strlen(caraInfo->xmpp_domain) != 0)
+    {
+        OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), "@");
+        OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->xmpp_domain);
+        if (caraInfo->resource != NULL && strlen(caraInfo->resource) != 0)
+        {
+            OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), "/");
+            OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->resource);
+        }
+    }
+    if (caraInfo->password != NULL)
+    {
+        OICStrcpy(g_xmppData.password, sizeof(g_xmppData.password), caraInfo->password);
+    }
+    g_xmppData.port = caraInfo->port;
+
+    return CA_STATUS_OK;
+}
+
+void CATerminateRA()
+{
+    CAStopRA();
+    ilist_destroy(g_observerList);
+    xmpphelper_join(g_xmppData.xmpp);
+    xmpphelper_release(g_xmppData.xmpp);
+    g_xmppData.xmpp = NULL;
+}
+
+CAResult_t CAStartRA()
+{
+    OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
+
+    if (!g_xmppData.xmpp)
+    {
+        OIC_LOG (ERROR, RA_ADAPTER_TAG, "CAStartRA(): g_xmppData.xmpp == NULL");
+        return CA_STATUS_FAILED;
+    }
+
+    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);
+
+    xmpphelper_connect(g_xmppData.xmpp, g_xmppData.hostname, g_xmppData.port,
+                    g_xmppData.jid, g_xmppData.password);
+    xmpp_ibb_reg_funcs_t regfuncs;
+    regfuncs.open_cb = CARAOpenCB;
+    regfuncs.close_cb = CARACloseCB;
+    regfuncs.recv_cb = CARARecvCB;
+    regfuncs.error_cb = CARAErrorCB;
+    xmpp_ibb_register(xmpphelper_get_conn(g_xmppData.xmpp), &regfuncs);
+
+    xmpphelper_run(g_xmppData.xmpp);
+
+    ca_mutex_unlock (g_raadapterMutex);
+
+    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"));
+
+    xmpphelper_stop(g_xmppData.xmpp);
+    xmpp_ibb_unregister(xmpphelper_get_conn(g_xmppData.xmpp));
+    if (!g_raadapterMutex)
+    {
+        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(DEBUG, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
+
+    uint32_t code = CA_NOT_FOUND;
+    coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU(data, dataLength, &code);
+    char *sid = CARAGetSIDFromPDU(pdu);
+    int obsopt = CARAGetReqObsOption(pdu);
+    coap_delete_pdu(pdu);
+
+    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_ibb_session_t *sess = xmpp_ibb_get_session_by_sid(sid);
+    if (sess == NULL)
+    {
+        sess = xmpp_ibb_open(xmpphelper_get_conn(g_xmppData.xmpp), remoteEndpoint->addr, sid);
+        if (sess == NULL)
+        {
+            OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB session establish failed!");
+            ca_mutex_unlock (g_raadapterMutex);
+            return -1;
+        }
+    }
+    if (CARAPDUIsRequest(code))
+    {
+        if (obsopt == OBSERVE_REGISTER || obsopt == OBSERVE_DEREGISTER)
+        {
+            CARAUpdateObsList(obsopt, sid);
+        }
+    }
+    xmppdata_t xdata = {.data = data, .size = dataLength};
+    int rc = xmpp_ibb_send_data(sess, &xdata);
+    ca_mutex_unlock (g_raadapterMutex);
+    if (rc < 0)
+    {
+        OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB send data failed!");
+        return -1;
+    }
+
+    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");
+    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;
+}
+
+#else /* #ifdef RA_ADAPTER_IBB */
+
 /**
  * Logging tag for module name.
  */
@@ -421,3 +961,4 @@ CAResult_t CAReadRAData()
     OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
     return CA_NOT_SUPPORTED;
 }
+#endif
index 918d3e0..9f1c672 100644 (file)
@@ -438,38 +438,48 @@ int InitDiscovery(OCQualityOfService qos)
     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;
+    OCRAInfo_t rainfo = {.hostname = "localhost", .port = 5222,
+        .xmpp_domain = "localhost", .username = "test1", .password = "intel123",
+        .resource = "", .user_jid = ""};
 
-    while ((opt = getopt(argc, argv, "t:")) != -1)
+    int opt = 0;
+    while ((opt = getopt(argc, argv, "t:s:p:d:u:w:r:j:")) != -1)
     {
         switch(opt)
         {
             case 't':
                 TEST_CASE = atoi(optarg);
                 break;
+            case 's':
+                rainfo.hostname = optarg;
+                break;
+            case 'p':
+                rainfo.port = atoi(optarg);
+                break;
+            case 'd':
+                rainfo.xmpp_domain = optarg;
+                break;
+            case 'u':
+                rainfo.username = optarg;
+                break;
+            case 'w':
+                rainfo.password = optarg;
+                break;
+            case 'j':
+                rainfo.user_jid = optarg;
+                break;
+            case 'r':
+                rainfo.resource = optarg;
+                break;
             default:
                 PrintUsage();
                 return -1;
         }
     }
 
-    if (initRemoteAccessAdapter() != OC_STACK_OK)
+    if (OCSetRAInfo(&rainfo) != OC_STACK_OK)
     {
         OC_LOG(ERROR, TAG, "Error initiating remote access adapter");
         return 0;
index 66441a0..d8908ba 100644 (file)
@@ -932,15 +932,44 @@ int main(int argc, char* argv[])
 {
     pthread_t threadId;
     pthread_t threadId_presence;
-    int opt;
 
-    while ((opt = getopt(argc, argv, "o:")) != -1)
+#ifdef RA_ADAPTER
+    OCRAInfo_t rainfo = {.hostname = "localhost", .port = 5222,
+        .xmpp_domain = "localhost", .username = "test1", .password = "intel123",
+        .resource = "", .user_jid = ""};
+#endif
+
+    int opt = 0;
+    while ((opt = getopt(argc, argv, "o:s:p:d:u:w:r:j:")) != -1)
     {
         switch(opt)
         {
             case 'o':
                 gObserveNotifyType = atoi(optarg);
                 break;
+#ifdef RA_ADAPTER
+            case 's':
+                rainfo.hostname = optarg;
+                break;
+            case 'p':
+                rainfo.port = atoi(optarg);
+                break;
+            case 'd':
+                rainfo.xmpp_domain = optarg;
+                break;
+            case 'u':
+                rainfo.username = optarg;
+                break;
+            case 'w':
+                rainfo.password = optarg;
+                break;
+            case 'j':
+                rainfo.user_jid = optarg;
+                break;
+            case 'r':
+                rainfo.resource = optarg;
+                break;
+#endif
             default:
                 PrintUsage();
                 return -1;
@@ -952,6 +981,7 @@ int main(int argc, char* argv[])
         PrintUsage();
         return -1;
     }
+
 #ifdef RA_ADAPTER
     OCRAInfo_t rainfo;
     rainfo.hostname = "localhost";