RDServer discovery functionality
authorHabib Virji <habib.virji@samsung.com>
Wed, 29 Jul 2015 13:04:20 +0000 (14:04 +0100)
committerHabib Virji <habib.virji@samsung.com>
Mon, 10 Aug 2015 10:45:29 +0000 (10:45 +0000)
1. rd_server.h defines three API's.
- API to start a RD server
- API to stop a RD server and clean up

2. rd_payload.h includes API's to create CBOR payload
(has few additions in cstack to support the functionality).

3. rd_types.h defines various different types used to represent
RD structure in payload and internally on the RD server.

4. rd_server.c
- includes functionality to start and stop a RD server
- initializes resource /oic/rd?rt="oic.wk.rd"
- handles discover message from the RD client.
- Discover responds with the biasFactor (currently hardcoded)

5. rd_payload.c contains all functionality for handling CBOR payload.

6. resource/csdk/SConscript
- Includes resource directory in cstack as library if build with WITH_RD

7. octypes.h
- Adds CT_ADAPTER_SHIFT for 32 bit and 16 bit. Previous value of 10 does not work for 32 bit.
- Add PAYLOAD_TYPE_RD in OCPayloadType.

8. ocpayload/ocpayloadconvert/ocpayloadparse
- Payload parsing, converting and destoy for the RD packet

9. Added entry to generate docs for the resource directory.

Change-Id: I699636d386bea829b65339c6dff24abcb056e9b8
Signed-off-by: Habib Virji <habib.virji@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2155
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
17 files changed:
auto_build.sh
build_common/SConscript
resource/csdk/SConscript
resource/csdk/stack/include/ocpayload.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/include/payload_logging.h
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/src/ocpayloadconvert.c
resource/csdk/stack/src/ocpayloadparse.c
resource/docs/Doxyfile
service/SConscript
service/resource-directory/SConscript [new file with mode: 0755]
service/resource-directory/include/rd_payload.h [new file with mode: 0644]
service/resource-directory/include/rd_server.h [new file with mode: 0644]
service/resource-directory/include/rd_types.h [new file with mode: 0644]
service/resource-directory/src/rd_payload.c [new file with mode: 0644]
service/resource-directory/src/rd_server.c [new file with mode: 0644]

index 568920e..80db2ab 100755 (executable)
@@ -12,6 +12,8 @@ function build_all()
                build_linux_secured $1 $2
                build_linux_unsecured_with_ra $1 $2
                build_linux_secured_with_ra $1 $2
+               build_linux_unsecured_with_rd $1 $2
+               build_linux_secured_with_rd $1 $2
        fi
 
        build_android $1 $2
@@ -58,6 +60,18 @@ function build_linux_secured_with_ra()
        scons RELEASE=$1 WITH_RA=1 SECURED=1 $2
 }
 
+function build_linux_unsecured_with_rd()
+{
+       echo "*********** Build for linux With Resource Directory *************"
+       scons RELEASE=$1 WITH_RD=1 $2
+}
+
+function build_linux_secured_with_rd()
+{
+       echo "*********** Build for linux With Resource Directory & Security ************"
+       scons RELEASE=$1 WITH_RD=1 SECURED=1 $2
+}
+
 function build_android()
 {
        # Note: for android, as oic-resource uses C++11 feature stoi and to_string,
@@ -132,8 +146,8 @@ function  help()
        echo "Usage:"
         echo "  build:"
         echo "     `basename $0` <target_build>"
-       echo "      Allowed values for <target_build>: all, linux_unsecured, linux_secured, linux_unsecured_with_ra, linux_secured_with_ra, android, arduino, tizen, darwin"
-       echo "      Note: \"linux\" will build \"linux_unsecured\", \"linux_secured\", \"linux_unsecured_with_ra\" & \"linux_secured_with_ra\"."
+       echo "      Allowed values for <target_build>: all, linux_unsecured, linux_secured, linux_unsecured_with_ra, linux_secured_with_ra, linux_unsecured_with_rd, linux_secured_with_rd, android, arduino, tizen, darwin"
+       echo "      Note: \"linux\" will build \"linux_unsecured\", \"linux_secured\", \"linux_unsecured_with_ra\", \"linux_secured_with_ra\", \"linux_secured_with_rd\" & \"linux_unsecured_with_rd\"."
        echo "      Any selection will build both debug and release versions of all available targets in the scope you've"
        echo "      selected. To choose any specific command, please use the SCons commandline directly. Please refer"
        echo "      to [IOTIVITY_REPO]/Readme.scons.txt."
@@ -176,6 +190,14 @@ then
        then
                build_linux_secured_with_ra true
                build_linux_secured_with_ra false
+       elif [ $1 = 'linux_unsecured_with_rd' ]
+       then
+               build_linux_unsecured_with_rd true
+               build_linux_unsecured_with_rd false
+       elif [ $1 = 'linux_secured_with_rd' ]
+       then
+               build_linux_secured_with_rd true
+               build_linux_secured_with_rd false
        elif [ $1 = 'android' ]
        then
                build_android true
index 7f4c650..180d490 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(EnumVariable('WITH_RD', 'Build including Resource Directory', '0', allowed_values=('0', '1')))
 
 if target_os in targets_disallow_multitransport:
        help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'IP', ['BT', 'BLE', 'IP']))
index a9e30c8..1f3b67b 100644 (file)
@@ -96,6 +96,11 @@ if env.get('SECURED') == '1':
 if env.get('LOGGING'):
        liboctbstack_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
+if env.get('WITH_RD') == '1':
+       liboctbstack_env.PrependUnique(CPPPATH = ['../../service/resource-directory/include'])
+       liboctbstack_env.AppendUnique(CPPDEFINES = ['-DWITH_RD'])
+       liboctbstack_env.AppendUnique(LIBS = ['resource_directory'])
+
 liboctbstack_env.Append(LIBS = ['c_common'])
 
 ######################################################################
index 4850d92..7abe6ab 100644 (file)
 #include "logger.h"
 #include "octypes.h"
 
+#ifdef WITH_RD
+#include "rd_payload.h"
+#endif
+
 #ifdef __cplusplus
 extern "C"
 {
index 5f602ff..53c3fec 100644 (file)
@@ -853,7 +853,8 @@ typedef enum
     PAYLOAD_TYPE_PLATFORM,
     PAYLOAD_TYPE_REPRESENTATION,
     PAYLOAD_TYPE_SECURITY,
-    PAYLOAD_TYPE_PRESENCE
+    PAYLOAD_TYPE_PRESENCE,
+    PAYLOAD_TYPE_RD
 } OCPayloadType;
 
 typedef struct
index acc207a..5bfb5bb 100644 (file)
@@ -253,6 +253,11 @@ static inline void OCPayloadLog(LogLevel level, const char* tag, OCPayload* payl
         case PAYLOAD_TYPE_SECURITY:
             OCPayloadLogSecurity(level, tag, (OCSecurityPayload*)payload);
             break;
+#ifdef WITH_RD
+        case PAYLOAD_TYPE_RD:
+            OCRDPayloadLog(level, tag, (OCRDPayload*)payload);
+            break;
+#endif
         default:
             OC_LOG_V(level, tag, "Unknown Payload Type: %d", payload->type);
             break;
index 7b9b9a3..020ae2a 100644 (file)
@@ -59,6 +59,11 @@ void OCPayloadDestroy(OCPayload* payload)
         case PAYLOAD_TYPE_SECURITY:
             OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
             break;
+#ifdef WITH_RD
+        case PAYLOAD_TYPE_RD:
+           OCRDPayloadDestroy((OCRDPayload*)payload);
+           break;
+#endif
         default:
             OC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
             OICFree(payload);
index d72c136..4da86c4 100644 (file)
@@ -65,6 +65,10 @@ OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t*
             return OCConvertPresencePayload((OCPresencePayload*)payload, outPayload, size);
         case PAYLOAD_TYPE_SECURITY:
             return OCConvertSecurityPayload((OCSecurityPayload*)payload, outPayload, size);
+#ifdef WITH_RD
+        case PAYLOAD_TYPE_RD:
+            return OCRDPayloadToCbor((OCRDPayload*)payload, outPayload, size);
+#endif
         default:
             OC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
             return OC_STACK_NOTIMPL;
index 05c6b59..b3b789c 100644 (file)
@@ -42,7 +42,7 @@ OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, siz
     CborValue rootValue;
     bool err = false;
 
-    OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize, payload);
+    OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize);
     if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
     {
         OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
@@ -90,6 +90,11 @@ OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, siz
         case PAYLOAD_TYPE_SECURITY:
             result = OCParseSecurityPayload(outPayload, &arrayValue);
             break;
+#ifdef WITH_RD
+        case PAYLOAD_TYPE_RD:
+            result = OCRDCborToPayload(&arrayValue, outPayload);
+            break;
+#endif
         default:
             OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
             result = OC_STACK_ERROR;
index 77c863d..cf72346 100644 (file)
@@ -674,6 +674,7 @@ INPUT                  = . \
                          ../../service/protocol-plugin/plugin-manager/src/PluginManager.h \
                          ../../service/notification-manager/NotificationManager/include/hosting.h \
                          ../../service/resource-encapsulation/include \
+                         ../../service/resource-directory/include \
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
index 5389725..7d3a5d2 100644 (file)
@@ -45,6 +45,9 @@ if target_os not in ['arduino','darwin','ios']:
        # Build resource-encapsulation project
        if target_os not in ['android', 'tizen']:
                SConscript('resource-encapsulation/SConscript')
+
+       # Build resource directory project
+       if env.get('WITH_RD') == '1':
+               SConscript('resource-directory/SConscript')
 #else:
 #      SConscript('notification-manager/SampleApp/arduino/SConscript')
-
diff --git a/service/resource-directory/SConscript b/service/resource-directory/SConscript
new file mode 100755 (executable)
index 0000000..a710a0b
--- /dev/null
@@ -0,0 +1,76 @@
+#******************************************************************
+#
+# Copyright 2015 Samsung Electronics 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# Resource Directory build script
+##
+
+Import('env')
+
+if env.get('RELEASE'):
+       env.AppendUnique(CCFLAGS = ['-Os'])
+       env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+       env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+       env.AppendUnique(CPPDEFINES = ['-DTB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+rd_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+rd_env.AppendUnique(CPPPATH = ['include'])
+rd_env.AppendUnique(CPPPATH = ['src/internal'])
+rd_env.AppendUnique(CPPPATH = ['../../resource/csdk/logger/include'])
+rd_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'libcoap'])
+
+if target_os not in ['windows', 'winrt']:
+       rd_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra'])
+
+if target_os == 'linux':
+       rd_env.AppendUnique(LIBS = ['pthread'])
+
+if target_os == 'android':
+       rd_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+       rd_env.AppendUnique(LIBS = ['gnustl_static'])
+
+       if not env.get('RELEASE'):
+               rd_env.AppendUnique(LIBS = ['log'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+RD_SRC_DIR = 'src/'
+rd_src = [
+               RD_SRC_DIR + 'rd_server.c',
+               RD_SRC_DIR + 'rd_payload.c',
+        ]
+
+if target_os in ['tizen'] :
+    rdsdk = rd_env.SharedLibrary('resource_directory', rd_src)
+else :
+    rdsdk = rd_env.StaticLibrary('resource_directory', rd_src)
+
+rd_env.InstallTarget(rdsdk, 'libresource_directory')
diff --git a/service/resource-directory/include/rd_payload.h b/service/resource-directory/include/rd_payload.h
new file mode 100644 (file)
index 0000000..924e446
--- /dev/null
@@ -0,0 +1,104 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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 _RESOURCE_DIRECTORY_PAYLOAD_H_
+#define _RESOURCE_DIRECTORY_PAYLOAD_H_
+
+#include "rd_types.h"
+
+#include <cbor.h>
+
+#include "octypes.h"
+#include "ocstack.h"
+#include "logger.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/**
+ * Converts RD payload from structure to CBOR format. It creates the outPayload
+ * which is then transmitted over the wire.
+ *
+ * @param rdPayload Contains structure holding values of OCRDPayload.
+ * @param outPayload The payload in the CBOR format converting OCRDPayload
+ * structure.
+ * @param size Length of the payload.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in creating CBOR.
+ */
+OCStackResult OCRDPayloadToCbor(const OCRDPayload *rdPayload,
+                                 uint8_t **outPayload, size_t *size);
+
+/**
+ * Converts CBOR to OCRDPayload.
+ *
+ * @param rdCBORPayload Payload received from other end in CBOR format.
+ * @param outPayload Parsing the values from CBOR into OCRDPayload structure.
+ *
+ * @return ::OC_STACK_OK returns if successful and OC_STACK_ERROR returns if
+ * failed in parsing CBOR.
+ */
+OCStackResult OCRDCborToPayload(const CborValue *rdCBORPayload, OCPayload **outPayload);
+
+/**
+ * Initializes RD payload structure.
+ *
+ * @param payloadType Defines whether payload is RD_PAYLOAD_TYPE_DISCOVERY or
+ * RD_PAYLOAD_TYPE_PUBLISH.
+ *
+ * @return Allocated memory for the OCRDPayload and NULL in case if failed to
+ * allocate memory
+ */
+OCRDPayload *OCRDPayloadCreate(OCRDPayloadType payloadType);
+
+/**
+ * Initializes RD Discovery payload structure and sets the bias factor.
+ *
+ * @param biasFactor Value specifies the selection factor. It is weigthage of
+ * CPU, Memory, Network, Load and Power capability of the RD server.
+ *
+ * @return Allocated memory for the OCRDDiscoveryPayload and NULL in case if
+ * failed to allocate memory.
+ */
+OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(int biasFactor);
+
+/**
+ * Free memory allocation of the RDPayload and its internal structure.
+ *
+ * @param payload Pointer to already allocated memory for OCRDPayload.
+ */
+void OCRDPayloadDestroy(OCRDPayload *payload);
+
+/**
+ * Logs the content of the OCRDPayload.
+ *
+ * @param level Log level DEBUG or INFO or ERROR.
+ * @param tag File specific tag to use.
+ * @param payload Pointer to already allocated memory for OCRDPayload.
+ */
+void OCRDPayloadLog(LogLevel level, const char *tag, const OCRDPayload *payload);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
diff --git a/service/resource-directory/include/rd_server.h b/service/resource-directory/include/rd_server.h
new file mode 100644 (file)
index 0000000..bc61032
--- /dev/null
@@ -0,0 +1,53 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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 _RESOURCE_DIRECTORY_SERVER_H_
+#define _RESOURCE_DIRECTORY_SERVER_H_
+
+// Iotivity Base CAPI
+#include "ocstack.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/**
+* Starts resource directory.
+* This function creates a RD server and create resource /oic/rd.
+*
+* @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR in case of error.
+*/
+OCStackResult OCRDStart();
+
+/**
+* Stops resource directory.
+* This function will stop the resource directory and removes all published
+* resources information.
+*
+* @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR is returned except
+* the case that OC_STACK_SUCCESS is returned.
+*/
+OCStackResult OCRDStop();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif //_RESOURCE_DIRECTORY_H_
diff --git a/service/resource-directory/include/rd_types.h b/service/resource-directory/include/rd_types.h
new file mode 100644 (file)
index 0000000..a43beff
--- /dev/null
@@ -0,0 +1,72 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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 _RESOURCE_DIRECTORY_TYPES_H_
+#define _RESOURCE_DIRECTORY_TYPES_H_
+
+#include "ocpayload.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/** Resource Directory URI used to Discover RD and Publish resources.*/
+#define OC_RSRVD_RD_URI                  "/oic/rd"
+
+/** To represent resource type with rd.*/
+#define OC_RSRVD_RESOURCE_TYPE_RD        "oic.wk.rd"
+
+#define OC_RSRVD_RD_DISCOVERY_SEL        "sel"
+
+/**
+ * Structure holding discovery payload.
+ */
+typedef struct
+{
+    /** Value holding the bias factor of the RD. */
+    uint8_t sel;
+} OCRDDiscoveryPayload;
+
+/**
+ * Enum values of multiple RD type payload.
+ */
+typedef enum
+{
+    /** Value pf the RD discovery payload. */
+    RD_PAYLOAD_TYPE_DISCOVERY
+} OCRDPayloadType;
+
+/**
+ * RD Payload that will be transmitted over the wire.
+ */
+typedef struct
+{
+    /** Used in ocpayload to check type of the packet. This matches other OC payload.*/
+    OCPayload base;
+    /** Used internally in RD to check the payload whether discovery or publish.*/
+    OCRDPayloadType payloadType;
+    /** Pointer to the discovery response payload.*/
+    OCRDDiscoveryPayload *rdDiscovery;
+} OCRDPayload;
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
diff --git a/service/resource-directory/src/rd_payload.c b/service/resource-directory/src/rd_payload.c
new file mode 100644 (file)
index 0000000..441b192
--- /dev/null
@@ -0,0 +1,293 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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 "rd_payload.h"
+
+#include <cbor.h>
+
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#ifdef WITH_RD
+#include "rd_payload.h"
+#endif
+
+#define TAG PCF("OCRDPayload")
+
+OCStackResult OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t **outPayload, size_t *size)
+{
+    if (!outPayload || !size)
+    {
+        OC_LOG_V(ERROR, TAG, "Invalid parameters.");
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = (uint8_t *)OICCalloc(1, MAX_REQUEST_LENGTH);
+    if (!*outPayload)
+    {
+        goto no_memory;
+    }
+
+    *size = MAX_REQUEST_LENGTH;
+
+    CborEncoder encoder;
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+
+    OC_LOG_V(DEBUG, TAG, "RD Payload : %d", rdPayload->base.type);
+    OC_LOG_V(DEBUG, TAG, "RD Payload Type: %d", rdPayload->payloadType);
+
+    CborEncoder rootArray;
+    CborError cborEncoderResult;
+    cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, 2);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed creating cbor array.");
+        goto exit;
+    }
+
+    cborEncoderResult = cbor_encode_uint(&rootArray, rdPayload->base.type);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed setting rdPayload->base.type.");
+        goto exit;
+    }
+
+    CborEncoder map;
+    cborEncoderResult = cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed creating cbor map.");
+        goto exit;
+    }
+
+    cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_CONTENT_TYPE,
+        sizeof(OC_RSRVD_CONTENT_TYPE) - 1);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed setting content type.");
+        goto exit;
+    }
+
+    cborEncoderResult = cbor_encode_uint(&map, rdPayload->payloadType);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed setting rdPayload->payloadType.");
+        goto exit;
+    }
+
+    if (rdPayload->payloadType == RD_PAYLOAD_TYPE_DISCOVERY)
+    {
+        if (rdPayload->rdDiscovery && rdPayload->rdDiscovery->sel)
+        {
+            cborEncoderResult = cbor_encode_text_string(&map,
+                OC_RSRVD_RD_DISCOVERY_SEL, sizeof(OC_RSRVD_RD_DISCOVERY_SEL) -1);
+            if (CborNoError !=  cborEncoderResult)
+            {
+                OC_LOG_V(ERROR, TAG, "Failed setting discovery sel type.");
+                goto exit;
+            }
+            cborEncoderResult = cbor_encode_uint(&map, rdPayload->rdDiscovery->sel);
+            if (CborNoError != cborEncoderResult)
+            {
+                OC_LOG_V(ERROR, TAG, "Failed setting discovery sel value.");
+                goto exit;
+            }
+            OC_LOG_V(DEBUG, TAG, "RD Payload bias factor: %d", rdPayload->rdDiscovery->sel);
+        }
+    }
+    cborEncoderResult = cbor_encoder_close_container(&rootArray, &map);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed closing rootArray container.");
+        goto exit;
+    }
+
+    cborEncoderResult = cbor_encoder_close_container(&encoder, &rootArray);
+    if (CborNoError != cborEncoderResult)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed closing encoder container.");
+        goto exit;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t *tempPayload = (uint8_t *)OICRealloc(*outPayload, *size);
+    if (!tempPayload)
+    {
+        goto no_memory;
+    }
+
+    *outPayload = tempPayload;
+
+    return OC_STACK_OK;
+
+no_memory:
+    OC_LOG_V(ERROR, TAG, "Memory allocation failed.");
+    OICFree(*outPayload);
+    return OC_STACK_NO_MEMORY;
+
+exit:
+    OICFree(*outPayload);
+    return OC_STACK_ERROR;
+}
+
+OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload)
+{
+    CborValue *rdCBORPayload = (CborValue *)cborPayload;
+    OCRDPayload *rdPayload = NULL;
+
+    if (cbor_value_is_map(rdCBORPayload))
+    {
+        CborValue curVal;
+        CborError cborFindResult;
+        cborFindResult = cbor_value_map_find_value(rdCBORPayload,
+            OC_RSRVD_CONTENT_TYPE, &curVal);
+        if (CborNoError != cborFindResult)
+        {
+            OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_CONTENT_TYPE type in the payload.");
+            goto exit;
+        }
+
+        int payloadType = 0 ;
+        if (cbor_value_is_valid(&curVal))
+        {
+            cborFindResult = cbor_value_get_int(&curVal, &payloadType);
+            if (CborNoError != cborFindResult)
+            {
+                OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_CONTENT_TYPE value in the payload.");
+                goto exit;
+            }
+            OC_LOG_V(DEBUG, TAG, "RD Payload Type : %d ", payloadType);
+        }
+
+        rdPayload = OCRDPayloadCreate(payloadType);
+        if (!rdPayload)
+        {
+            goto no_memory;
+        }
+
+        if (RD_PAYLOAD_TYPE_DISCOVERY == payloadType)
+        {
+            cborFindResult = cbor_value_map_find_value(rdCBORPayload,
+                OC_RSRVD_RD_DISCOVERY_SEL, &curVal);
+            if (CborNoError != cborFindResult)
+            {
+                OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL type in the payload.");
+                goto exit;
+            }
+
+            int biasFactor = 0;
+            if (cbor_value_is_valid(&curVal))
+            {
+                cborFindResult = cbor_value_get_int(&curVal, &biasFactor);
+                if (CborNoError != cborFindResult)
+                {
+                    OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL value in the payload.");
+                    goto exit;
+                }
+            }
+            OC_LOG_V(DEBUG, TAG, "Bias Factor : %d ", biasFactor);
+
+            rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(biasFactor);
+            if (!rdPayload->rdDiscovery)
+            {
+                goto no_memory;
+            }
+        }
+
+        cborFindResult = cbor_value_advance(rdCBORPayload);
+        if (CborNoError != cborFindResult)
+        {
+            OC_LOG_V(ERROR, TAG, "Failed advancing the payload.");
+            goto exit;
+        }
+
+        *outPayload = (OCPayload *)rdPayload;
+    }
+
+    return OC_STACK_OK;
+
+no_memory:
+    OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
+    OCRDPayloadDestroy(rdPayload);
+    return OC_STACK_NO_MEMORY;
+
+exit:
+    OCRDPayloadDestroy(rdPayload);
+    return OC_STACK_ERROR;
+}
+
+OCRDPayload *OCRDPayloadCreate(OCRDPayloadType payloadType)
+{
+    OCRDPayload *rdPayload = (OCRDPayload *)OICCalloc(1, sizeof(OCRDPayload));
+
+    if (!rdPayload)
+    {
+        return NULL;
+    }
+
+    rdPayload->base.type = PAYLOAD_TYPE_RD;
+    rdPayload->payloadType = payloadType;
+
+    return rdPayload;
+}
+
+OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(int biasFactor)
+{
+    OCRDDiscoveryPayload *discoveryPayload = (OCRDDiscoveryPayload *)
+        OICCalloc(1, sizeof(OCRDDiscoveryPayload));
+
+    if (!discoveryPayload)
+    {
+        return NULL;
+    }
+    discoveryPayload->sel = biasFactor;
+
+    return discoveryPayload;
+}
+
+void OCRDPayloadDestroy(OCRDPayload *payload)
+{
+    if (!payload)
+    {
+        return;
+    }
+
+    if (payload->rdDiscovery)
+    {
+        OICFree(payload->rdDiscovery);
+    }
+
+    OICFree(payload);
+}
+
+void OCRDPayloadLog(LogLevel level, const char *tag, const OCRDPayload *payload)
+{
+    if (!payload)
+    {
+        return;
+    }
+
+    OC_LOG_V(level, tag, "BaseType : %d", payload->base.type);
+    OC_LOG_V(level, tag, "RD Payload Type : %d", payload->payloadType);
+
+    if (payload->rdDiscovery)
+    {
+        OC_LOG_V(level, tag, "RD Payload Discovery BIAS : %d", payload->rdDiscovery->sel);
+    }
+}
diff --git a/service/resource-directory/src/rd_server.c b/service/resource-directory/src/rd_server.c
new file mode 100644 (file)
index 0000000..c605bb8
--- /dev/null
@@ -0,0 +1,164 @@
+// Copyright 2015 Samsung Electronics 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 "rd_server.h"
+#include "rd_types.h"
+#include "rd_payload.h"
+
+#include "logger.h"
+
+#define TAG  PCF("RDServer")
+
+// This is temporary hardcoded value for bias factor.
+#define OC_RD_DISC_SEL 100
+
+static OCResourceHandle gRDHandle = NULL;
+
+/**
+ * This internal method handles RD discovery request.
+ * Responds with the RD discovery payload message.
+ */
+static OCEntityHandlerResult HandleRDGetRequest(const OCEntityHandlerRequest *ehRequest)
+{
+    if (!ehRequest)
+    {
+        OC_LOG_V(DEBUG, TAG, "Invalid request pointer.");
+        return OC_EH_ERROR;
+    }
+
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+    OC_LOG_V(DEBUG, TAG, "Received OC_REST_GET from client with query: %s.", ehRequest->query);
+
+    OCRDPayload *rdPayload = OCRDPayloadCreate(RD_PAYLOAD_TYPE_DISCOVERY);
+    if (!rdPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(OC_RD_DISC_SEL);
+    if (!rdPayload->rdDiscovery)
+    {
+        OCRDPayloadDestroy(rdPayload);
+        return OC_STACK_NO_MEMORY;
+    }
+
+    OCRDPayloadLog(DEBUG, TAG, rdPayload);
+
+    OCEntityHandlerResponse ehResponse = {};
+    ehResponse.requestHandle = ehRequest->requestHandle;
+    ehResponse.resourceHandle = ehRequest->resource;
+    ehResponse.payload = (OCPayload *)rdPayload;
+    ehResponse.ehResult = ehResult;
+
+    if (OCDoResponse(&ehResponse) != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "Sending response failed.");
+        ehResult = OC_EH_ERROR;
+    }
+
+    OCRDPayloadDestroy(rdPayload);
+
+    return ehResult;
+}
+
+/*
+ * This internal method is the entity handler for RD resources and
+ * will handle REST request (GET/PUT/POST/DEL) for them.
+ */
+static OCEntityHandlerResult RDEntityHandler(OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *ehRequest, void *callbackParameter)
+{
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+    if (!ehRequest)
+    {
+        return ehRet;
+    }
+
+    if (flag & OC_REQUEST_FLAG)
+    {
+        OC_LOG_V(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG.");
+        switch (ehRequest->method)
+        {
+            case OC_REST_GET:
+            case OC_REST_DISCOVER:
+                HandleRDGetRequest(ehRequest);
+                break;
+            case OC_REST_POST:
+            case OC_REST_PUT:
+            case OC_REST_DELETE:
+            case OC_REST_OBSERVE:
+            case OC_REST_OBSERVE_ALL:
+            case OC_REST_CANCEL_OBSERVE:
+            case OC_REST_PRESENCE:
+            case OC_REST_NOMETHOD:
+                break;
+        }
+    }
+
+    return ehRet;
+}
+
+/**
+ * Starts resource directory server and registers RD resource
+ */
+OCStackResult OCRDStart()
+{
+    OCStackResult result = OCInit(NULL, 0, OC_CLIENT_SERVER);
+
+    if (result == OC_STACK_OK)
+    {
+        result = OCCreateResource(&gRDHandle,
+                                  OC_RSRVD_RESOURCE_TYPE_RD,
+                                  OC_RSRVD_INTERFACE_DEFAULT,
+                                  OC_RSRVD_RD_URI,
+                                  RDEntityHandler,
+                                  NULL,
+                                  (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE));
+
+        if (result == OC_STACK_OK)
+        {
+            OC_LOG_V(DEBUG, TAG, "Resource Directory Started.");
+        }
+        else
+        {
+            OC_LOG(ERROR, TAG, "Failed starting Resource Directory.");
+        }
+    }
+
+    return result;
+}
+
+/**
+ * Stops resource directory server
+ */
+OCStackResult OCRDStop()
+{
+    OCStackResult result = OCStop();
+
+    if (result == OC_STACK_OK)
+    {
+        OC_LOG_V(DEBUG, TAG, "Resource Directory Stopped.");
+    }
+    else
+    {
+        OC_LOG(ERROR, TAG, "Failed stopping Resource Directory.");
+    }
+    return result;
+}