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
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,
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."
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
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']))
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'])
if liboctbstack_env.get('ROUTING') in ['GW', 'EP']:
#include <inttypes.h>
#include "octypes.h"
+#ifdef WITH_RD
+#include "rd_payload.h"
+#endif
+
#ifdef __cplusplus
extern "C"
{
PAYLOAD_TYPE_PLATFORM,
PAYLOAD_TYPE_REPRESENTATION,
PAYLOAD_TYPE_SECURITY,
- PAYLOAD_TYPE_PRESENCE
+ PAYLOAD_TYPE_PRESENCE,
+ PAYLOAD_TYPE_RD
} OCPayloadType;
typedef struct
case PAYLOAD_TYPE_SECURITY:
OCPayloadLogSecurity(level, (OCSecurityPayload*)payload);
break;
+#ifdef WITH_RD
+ case PAYLOAD_TYPE_RD:
+ OCRDPayloadLog(level, tag, (OCRDPayload*)payload);
+ break;
+#endif
default:
OC_LOG_V(level, PL_TAG, "Unknown Payload Type: %d", payload->type);
break;
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);
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;
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);
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;
#include "secureresourcemanager.h"
#include "cacommon.h"
#include "cainterface.h"
+
+#ifdef WITH_RD
+#include "rd_server.h"
+#endif
+
#ifdef ROUTING_GATEWAY
#include "routingmanager.h"
#endif
return OCDoResponse(&response);
}
+#ifdef WITH_RD
+static OCStackResult checkResourceExistsAtRD(const char *interfaceType, const char *resourceType, OCRepPayload **repPayload)
+{
+ char *uri = NULL;
+ char *rt = NULL;
+ char *itf = NULL;
+
+ if (OCRDCheckPublishedResource(interfaceType, resourceType, &uri, &rt, &itf) == OC_STACK_OK)
+ {
+ if (!uri || !rt || !itf)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
+ // if any of the parameter has memory allocated free each one of them.
+ OICFree(uri);
+ OICFree(rt);
+ OICFree(itf);
+ return OC_STACK_NO_MEMORY;
+ }
+
+ OCRepPayload *rdResource = OICCalloc(1, sizeof(OCRepPayload));
+ if (!rdResource)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
+ OICFree(uri);
+ OICFree(rt);
+ OICFree(itf);
+ return OC_STACK_NO_MEMORY;
+ }
+
+ rdResource->uri = uri;
+
+ rdResource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+ if(!rdResource->types)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
+ OICFree(uri);
+ OICFree(rt);
+ OICFree(itf);
+ OICFree(rdResource);
+ return OC_STACK_NO_MEMORY;
+ }
+ rdResource->types->value = rt;
+
+ rdResource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+ if(!rdResource->interfaces)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
+ OICFree(uri);
+ OICFree(rt);
+ OICFree(itf);
+ OICFree(rdResource);
+ return OC_STACK_NO_MEMORY;
+ }
+ rdResource->interfaces->value = itf;
+
+ *repPayload = rdResource;
+
+ return OC_STACK_OK;
+ }
+ else
+ {
+ OC_LOG_V(ERROR, TAG, "The resource type or interface type doe not exist \
+ on the resource directory");
+ }
+ return OC_STACK_ERROR;
+}
+#endif
+
static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
{
if (!request || !resource)
{
for(;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
{
- if(includeThisResourceInResponse(resource, filterOne, filterTwo))
+ bool foundResourceAtRD = false;
+#ifdef WITH_RD
+ if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
+ {
+ OCRepPayload *repPayload = NULL;
+ discoveryResult = checkResourceExistsAtRD(filterOne, filterTwo, &repPayload);
+ if (discoveryResult != OC_STACK_OK)
+ {
+ break;
+ }
+ discoveryResult = BuildVirtualResourceResponse((OCResource *)repPayload,
+ (OCDiscoveryPayload*)payload,
+ &request->devAddr);
+ foundResourceAtRD = true;
+ }
+#endif
+ if(!foundResourceAtRD && includeThisResourceInResponse(resource, filterOne, filterTwo))
{
discoveryResult = BuildVirtualResourceResponse(resource,
(OCDiscoveryPayload*)payload,
../../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
if target_os not in ['tizen']:
SConscript('resource-encapsulation/SConscript')
+ # Build resource directory project
+ if env.get('WITH_RD') == '1':
+ SConscript('resource-directory/SConscript')
--- /dev/null
+#******************************************************************
+#
+# 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 + '/internal/rd_storage.c',
+ RD_SRC_DIR + 'rd_server.c',
+ RD_SRC_DIR + 'rd_payload.c',
+ RD_SRC_DIR + 'rd_client.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')
+
+######################################################################
+# Samples for the resource directory
+######################################################################
+SConscript('samples/SConscript')
--- /dev/null
+//******************************************************************
+//
+// 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_CLIENT_H_
+#define _RESOURCE_DIRECTORY_CLIENT_H_
+
+// Iotivity Base CAPI
+#include "ocstack.h"
+
+#include "rd_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/**
+ * Discovers the resource directory.
+ * This function searches a RD server and obtain the bias factor.
+ *
+ * @param cbBiasFactor callback function invoked when bias factor is returned by
+ * the Resource Directory Server
+ *
+ * @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR in case of error.
+ */
+OCStackResult OCRDDiscover(OCRDBiasFactorCB cbBiasFactor);
+
+/**
+ * Publish resource on the RD.
+ *
+ * @param addr The IP address of the RD, it could be either retrieved via OCRDDiscover().
+ * @param port The port of the RD.
+ * @param num This denotes the number of registered resource handles being passed
+ * for the remaining arguments.
+ *
+ * @returns ::OC_STACK_OK when successful and OC_STACK_ERROR when query failed.
+ */
+OCStackResult OCRDPublish(char *addr, uint16_t port, int num, ...);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif //_RESOURCE_DIRECTORY_CLIENT_H_
--- /dev/null
+//******************************************************************
+//
+// 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 <cbor.h>
+
+#include "rd_types.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);
+
+/**
+ * Creates the links payload, which is then embedded inside OCRDPublishPayload.
+ *
+ * @param uri The Web Link Address of the resource.
+ * @param rt The resource type of the published resource.
+ * @param itf The interface type of the published resource.
+ * @param linkPayload The address of the allocated memory or NULL in case if failed
+ * to allocate memory.
+ */
+void OCRDLinksPayloadCreate(const char *uri, const char *rt, const char *itf,
+ OCRDLinksPayload **linkPayload);
+
+/**
+ * Creates the links payload, which is then embedded inside OCRDPublishPayload.
+ *
+ * @param ttl Time to live of the published resource..
+ * @param linkPayload The link payload with uri, rt and itf.
+ *
+ * @return Allocated memory of OCRDPublishPayload or NULL in case if failed
+ * to allocate memory.
+ */
+OCRDPublishPayload *OCRDPublishPayloadCreate(const int ttl,
+ OCRDLinksPayload *linkPayload);
+
+/**
+ * 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);
+
+/**
+ * Logs the subset of the OCRDPayload, prints separately OCRDPublish.
+ *
+ * @param level Log level DEBUG or INFO or ERROR.
+ * @param tag File specific tag to use.
+ * @param payload Pointer to already allocated memory for OCRDPublish.
+ */
+void OCRDPublishPayloadLog(LogLevel level, const char *tag,
+ const OCRDPublishPayload *rdPublish);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
--- /dev/null
+//******************************************************************
+//
+// 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();
+
+/**
+ * Checks based on the resource type if the entity exists in the resource directory.
+ *
+ * @param interfaceType a interface type that is being queried.
+ * @param resourceType a resource type that is being queried.
+ * @param uri A URI of the resource found;
+ * @param rt A resource type of the message queried.
+ * @param itf A resource type of the interface.
+ *
+ * @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR is returned except
+ * the case that OC_STACK_SUCCESS is returned.
+ */
+OCStackResult OCRDCheckPublishedResource(const char *interfaceType, const char *resourceType,
+ char **uri, char **rt, char **itf);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif //_RESOURCE_DIRECTORY_H_
--- /dev/null
+//******************************************************************
+//
+// 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"
+
+/** RD Discovery bias factor type. */
+#define OC_RSRVD_RD_DISCOVERY_SEL "sel"
+
+/** To represent resource type with Publish RD.*/
+#define OC_RSRVD_RESOURCE_TYPE_RDPUBLISH "oic.wk.rdPub"
+
+/** Max ADDR SIZE */
+#define MAX_ADDR_STR_SIZE (40)
+
+/** Callback function for returning RDDiscovery Result. */
+typedef int (* OCRDBiasFactorCB)(char addr[MAX_ADDR_STR_SIZE], uint16_t port);
+
+/** Context structure used sending it as part of the callback context. */
+typedef struct
+{
+ /** Stores the context value of the message sent. */
+ void *context;
+ /** Pointing to the callback function that OCRDDiscover() received. */
+ OCRDBiasFactorCB cbFunc;
+} OCRDClientContextCB;
+
+/**
+ * Structure holding discovery payload.
+ */
+typedef struct
+{
+ /** Value holding the bias factor of the RD. */
+ uint8_t sel;
+} OCRDDiscoveryPayload;
+
+/**
+ * Structure holding RD Links Payload. It is a sub-structure used in
+ * OCRDPublishPayload.
+ */
+typedef struct OCRDLinksPayload
+{
+ /** Web Link Address of the resource. */
+ char *href;
+ /** Resource type of the resource. */
+ char *rt;
+ /** Interace type of the resource. */
+ char *itf;
+ /** Holding address of the next resource. */
+ struct OCRDLinksPayload *next;
+} OCRDLinksPayload;
+
+/**
+ * Structure holding RD Publish payload.
+ */
+typedef struct
+{
+ /** Device Name. */
+ OCDeviceInfo deviceName;
+ /** Device id. */
+ OCIdentity deviceId;
+ /** Time to keep holding resource.*/
+ uint32_t ttl;
+ /** List of resource information that will be stored at RD.*/
+ OCRDLinksPayload *links;
+} OCRDPublishPayload;
+
+/**
+ * Enum values of multiple RD type payload.
+ */
+typedef enum
+{
+ /** Value pf the RD discovery payload. */
+ RD_PAYLOAD_TYPE_DISCOVERY,
+ /** Value of the RD publish payload. */
+ RD_PAYLOAD_TYPE_PUBLISH
+} 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;
+ /** Pointer to the publish payload.*/
+ OCRDPublishPayload *rdPublish;
+} OCRDPayload;
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
--- /dev/null
+##
+# ResourceDirectory Sample Apps build script
+##
+
+Import('env')
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+rd_sample_app_env = lib_env.Clone()
+
+######################################################################
+# Build flags
+######################################################################
+rd_sample_app_env.AppendUnique(CPPPATH = ['../include'])
+
+rd_sample_app_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x'])
+rd_sample_app_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+rd_sample_app_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
+rd_sample_app_env.PrependUnique(LIBS = ['resource_directory', 'oc', 'octbstack'])
+
+if env.get('SECURED') == '1':
+ rd_sample_app_env.AppendUnique(LIBS = ['tinydtls'])
+
+####################################################################
+# Source files and Targets
+######################################################################
+rd_server = rd_sample_app_env.Program('rd_server', 'rd_main.c')
+rd_publishingClient = rd_sample_app_env.Program('rd_publishingClient', 'rd_publishingClient.cpp')
+rd_queryClient = rd_sample_app_env.Program('rd_queryClient', 'rd_queryClient.cpp')
+
+Alias("resource_directory", [rd_server, rd_publishingClient])
+
+env.AppendTarget('resource_directory')
--- /dev/null
+//******************************************************************
+//
+// 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 <signal.h>
+#include <unistd.h>
+
+int g_quitFlag = 0;
+
+void handleSigInt(int signum);
+
+/*
+* This method is an entry point of Resource Directory.
+* This function should be run only on the device that it could be host device.
+*/
+
+int main()
+{
+ printf("OCResourceDirectory is starting...\n");
+
+ if (OCRDStart() != OC_STACK_OK)
+ {
+ printf("OCRDStart failed...\n");
+ return 0;
+ }
+
+ printf("OCRDStart successfully...\n");
+
+ signal(SIGINT, handleSigInt);
+ while (!g_quitFlag)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ OCRDStop();
+ printf("OCStack process error\n");
+ return 0;
+ }
+ }
+
+ if (OCRDStop() != OC_STACK_OK)
+ {
+ printf("OCRDStop failed...\n");
+ }
+ else
+ {
+ printf("OCRDStop success...\n");
+ }
+
+ printf("Exiting OCResourceDirectory main loop...\n");
+ return 0;
+
+}
+
+/*
+* This is a signal handling function for SIGINT(CTRL+C).
+* A Resource Directory handle the SIGINT signal for safe exit.
+*
+* @param[in] signal
+* signal number of caught signal.
+*/
+void handleSigInt(int signum)
+{
+ if (signum == SIGINT)
+ {
+ g_quitFlag = 1;
+ }
+}
--- /dev/null
+//******************************************************************
+//
+// 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 <iostream>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "oic_string.h"
+
+#include "rd_client.h"
+
+using namespace OC;
+
+OCResourceHandle g_curResource_t = NULL;
+OCResourceHandle g_curResource_l = NULL;
+char rdAddress[MAX_ADDR_STR_SIZE];
+uint16_t rdPort;
+
+void registerLocalResources()
+{
+ std::string resourceURI_thermostat = "/a/thermostat";
+ std::string resourceTypeName_thermostat = "core.thermostat";
+ std::string resourceURI_light = "/a/light";
+ std::string resourceTypeName_light = "core.light";
+ std::string resourceInterface = DEFAULT_INTERFACE;
+ uint8_t resourceProperty = OC_DISCOVERABLE;
+
+ OCStackResult result = OCPlatform::registerResource(g_curResource_t,
+ resourceURI_thermostat,
+ resourceTypeName_thermostat,
+ resourceInterface,
+ NULL,
+ resourceProperty);
+
+ if (OC_STACK_OK != result)
+ {
+ throw std::runtime_error(
+ std::string("Device Resource failed to start") + std::to_string(result));
+ }
+
+ result = OCPlatform::registerResource(g_curResource_l,
+ resourceURI_light,
+ resourceTypeName_light,
+ resourceInterface,
+ NULL,
+ resourceProperty);
+
+ if (OC_STACK_OK != result)
+ {
+ throw std::runtime_error(
+ std::string("Device Resource failed to start") + std::to_string(result));
+ }
+}
+
+void printHelp()
+{
+ std::cout << std::endl;
+ std::cout << "********************************************" << std::endl;
+ std::cout << "* method Type : 1 - Discover RD *" << std::endl;
+ std::cout << "* method Type : 2 - Publish *" << std::endl;
+ std::cout << "* method Type : 3 - Update *" << std::endl;
+ std::cout << "* method Type : 4 - Delete *" << std::endl;
+ std::cout << "* method Type : 5 - Status *" << std::endl;
+ std::cout << "********************************************" << std::endl;
+ std::cout << std::endl;
+}
+
+int biasFactorCB(char addr[MAX_ADDR_STR_SIZE], uint16_t port)
+{
+ OICStrcpy(rdAddress, MAX_ADDR_STR_SIZE, addr);
+ rdPort = port;
+ std::cout << "RD Address is : " << addr << ":" << port << std::endl;
+ return 0;
+}
+
+int main(int argc , char *argv[])
+{
+ int in;
+ PlatformConfig cfg;
+
+ OCPlatform::Configure(cfg);
+
+ std::cout << "Created Platform..." << std::endl;
+
+ registerLocalResources();
+
+ while (1)
+ {
+ sleep(2);
+
+ if (g_curResource_t == NULL || g_curResource_l == NULL)
+ {
+ continue;
+ }
+ printHelp();
+
+ in = 0;
+ std::cin >> in;
+
+ if (std::cin.fail())
+ {
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+ std::cout << "Invalid input type, please try again" << std::endl;
+ continue;
+ }
+
+ try
+ {
+ switch ((int)in)
+ {
+ case 1:
+ OCRDDiscover(biasFactorCB);
+ break;
+ case 2:
+ OCRDPublish(rdAddress, rdPort, 2, g_curResource_t, g_curResource_l);
+ break;
+ case 3:
+ break;
+ default:
+ std::cout << "Invalid input, please try again" << std::endl;
+ break;
+ }
+ }
+ catch (OCException e)
+ {
+ std::cout << "Caught OCException [Code: " << e.code() << " Reason: " << e.reason() << std::endl;
+ }
+ }
+ return 0;
+}
--- /dev/null
+//******************************************************************
+//
+// 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 <vector>
+
+#include "OCApi.h"
+#include "OCPlatform.h"
+
+bool g_foundResource = true;
+
+void foundResource(std::shared_ptr< OC::OCResource > resource)
+{
+ try
+ {
+ std::cout << "Found resource response." << std::endl;
+ if (resource)
+ {
+ if (resource->uri() == "/a/light")
+ {
+ std::cout << "Found Resource at @ URI: " << resource->uri() << "\tHost Address: " <<
+ resource->host() << std::endl;
+ }
+ }
+ else
+ {
+ std::cout << "Resource is invalid " << resource->uri() << std::endl;
+ }
+ g_foundResource = false;
+ exit(0);
+ }
+ catch (std::exception &ex)
+ {
+ std::cout << "Exception: " << ex.what() << " in foundResource" << std::endl;
+ exit(1);
+ }
+}
+
+int main()
+{
+ OC::PlatformConfig cfg;
+ OC::OCPlatform::Configure(cfg);
+ bool sendRequest = true;
+
+ std::cout << "Created Platform..." << std::endl;
+
+ while (g_foundResource)
+ {
+ try
+ {
+ if (sendRequest)
+ {
+ sendRequest = false;
+ std::cout << "Finding Resource light" << std::endl;
+ OC::OCPlatform::findResource("", "/oic/res?rt=core.light", CT_DEFAULT, &foundResource);
+ }
+ }
+ catch (OC::OCException &ex)
+ {
+ sendRequest = true;
+ std::cout << "Exception finding resources : " << ex.reason() << std::endl;
+ }
+ }
+}
--- /dev/null
+//******************************************************************
+//
+// 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_storage.h"
+
+#include <pthread.h>
+
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "logger.h"
+
+#include "rd_payload.h"
+
+#define TAG PCF("RDStorage")
+
+pthread_mutex_t storageMutex = PTHREAD_MUTEX_INITIALIZER;
+// This variable holds the published resources on the RD.
+static OCRDStorePublishResources *g_rdStorage = NULL;
+
+static void printStoragedResources(OCRDStorePublishResources *payload)
+{
+ OC_LOG_V(DEBUG, TAG, "Print Storage Resources ... ");
+ for (OCRDStorePublishResources *temp = payload; temp; temp = temp->next)
+ {
+ if (temp->publishResource)
+ {
+ OCRDPublishPayloadLog(DEBUG, TAG, temp->publishResource);
+ }
+ }
+}
+
+OCStackResult OCRDStorePublishedResources(OCRDPublishPayload *payload)
+{
+ OCRDStorePublishResources *storeResource = OICCalloc(1, sizeof(OCRDStorePublishResources));
+ if (!storeResource)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed allocating memory for OCRDStorePublishResources.");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ OC_LOG_V(DEBUG, TAG, "Storing Resources ... ");
+
+ OCRDLinksPayload* linksPayload = NULL;
+ for ( OCRDLinksPayload* links = payload->links ; links; links = links->next)
+ {
+ OCRDLinksPayloadCreate(links->href, links->rt, links->itf, &linksPayload);
+ }
+
+ storeResource->publishResource = OCRDPublishPayloadCreate(payload->ttl, linksPayload);
+ if (!storeResource->publishResource)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed allocating memory for OCRDPublishResources.");
+ OICFree(storeResource);
+ return OC_STACK_NO_MEMORY;
+ }
+ storeResource->next = NULL;
+
+ pthread_mutex_lock(&storageMutex);
+ if (g_rdStorage)
+ {
+ OCRDStorePublishResources *temp = g_rdStorage;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = storeResource;
+ }
+ else
+ {
+ g_rdStorage = storeResource;
+ }
+ pthread_mutex_unlock(&storageMutex);
+
+ printStoragedResources(g_rdStorage);
+ return OC_STACK_OK;
+}
+
+OCStackResult OCRDCheckPublishedResource(const char *interfaceType, const char *resourceType,
+ char **uri, char **rt, char **itf)
+{
+ // ResourceType and InterfaceType if both are NULL it will return. If either is
+ // not null it will continue execution.
+ if (!resourceType && !interfaceType)
+ {
+ OC_LOG_V(DEBUG, TAG, "Missing resource type and interace type.");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OC_LOG_V(DEBUG, TAG, "Check Resource in RD");
+
+ if (g_rdStorage && g_rdStorage->publishResource && g_rdStorage->publishResource->links)
+ {
+ for (OCRDLinksPayload *tLinks = g_rdStorage->publishResource->links; tLinks; tLinks = tLinks->next)
+ {
+ bool found = false;
+ // If either rt or itf are NULL, it should skip remaining code execution.
+ if (!tLinks->rt || !tLinks->itf)
+ {
+ OC_LOG_V(DEBUG, TAG, "Either resource type and interface type are missing.");
+ continue;
+ }
+ OC_LOG_V(DEBUG, TAG, "Resource Type: %s %s", resourceType, tLinks->rt);
+ OC_LOG_V(DEBUG, TAG, "Resource Type: %s %s", interfaceType, tLinks->itf);
+ if (resourceType && strcmp(resourceType, tLinks->rt) == 0)
+ {
+ found = true;
+ }
+
+ if (interfaceType && strcmp(interfaceType, tLinks->itf) == 0)
+ {
+ found = true;
+ }
+
+ if (found)
+ {
+ *uri = OICStrdup(tLinks->href);
+ if (!*uri)
+ {
+ OC_LOG_V(ERROR, TAG, "Copy failed..");
+ return false;
+ }
+ *rt = OICStrdup(tLinks->rt);
+ if (!*rt)
+ {
+ OC_LOG_V(ERROR, TAG, "Copy failed..");
+ OICFree(*uri);
+ return false;
+ }
+ *itf = OICStrdup(tLinks->itf);
+ if (!*itf)
+ {
+ OC_LOG_V(ERROR, TAG, "Copy failed..");
+ OICFree(*uri);
+ OICFree(*rt);
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
--- /dev/null
+//******************************************************************
+//
+// 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_STORAGE_H_
+#define _RESOURCE_DIRECTORY_SERVER_STORAGE_H_
+
+#include "rd_types.h"
+
+/** Stucture holding Published Resources on the Resource Directory. */
+typedef struct OCRDStorePublishResources
+{
+ /** Publish resource. */
+ OCRDPublishPayload *publishResource;
+ /** Linked list pointing to next published resource. */
+ struct OCRDStorePublishResources *next;
+} OCRDStorePublishResources;
+
+/**
+ * Stores the publish resources.
+ *
+ * @param payload RDPublish payload sent from the remote device.
+ *
+ * @return ::OC_STACK_OK upon success, ::OC_STACK_ERROR in case of error.
+ */
+OCStackResult OCRDStorePublishedResources(OCRDPublishPayload *payload);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif //_RESOURCE_DIRECTORY_SERVER_STORAGE_H_
--- /dev/null
+//******************************************************************
+//
+// 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 <stdarg.h>
+
+#include "rd_client.h"
+
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#include "rd_payload.h"
+
+#define DEFAULT_CONTEXT_VALUE 0x99
+#define OC_RD_PUBLISH_TTL 86400
+
+#define TAG PCF("RDClient")
+
+static OCStackResult sendRequest(OCMethod method, char *uri, OCDevAddr *addr,
+ OCPayload *payload, OCCallbackData cbData)
+{
+ OCDoHandle handle;
+ OCStackResult result;
+
+ result = OCDoResource(&handle,
+ method,
+ uri,
+ addr,
+ payload,
+ CT_ADAPTER_IP,
+ OC_LOW_QOS,
+ &cbData,
+ NULL,
+ 0);
+
+ if (result == OC_STACK_OK)
+ {
+ OC_LOG_V(DEBUG, TAG, "Resource Directory send successful...");
+ }
+ else
+ {
+ OC_LOG_V(ERROR, TAG, "Resource Directory send failed...");
+ }
+
+ return result;
+}
+
+static OCStackApplicationResult handlePublishCB(void *ctx,
+ OCDoHandle handle, OCClientResponse *clientResponse)
+{
+ OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
+ OC_LOG_V(DEBUG, TAG, "Successfully published resources.");
+
+ // TOOO: Stop multicast traffic on the client.
+
+ return ret;
+}
+
+static void retreiveRDDetails(OCClientResponse *clientResponse, OCRDBiasFactorCB clientCB)
+{
+ OC_LOG_V(DEBUG, TAG, "\tAddress of the RD: %s:%d", clientResponse->devAddr.addr,
+ clientResponse->devAddr.port);
+
+ OCRDPayload *payload = (OCRDPayload *) clientResponse->payload;
+ OCRDPayloadLog(DEBUG, TAG, payload);
+
+ // TODO: Multiple Resource Directory will have different biasFactor,
+ // needs to cache here detail
+ // and after certain timeout then decide based on the biasFactor.
+ //if (biasFactor > 75)
+ if (clientCB)
+ {
+ clientCB(clientResponse->devAddr.addr, clientResponse->devAddr.port);
+ }
+}
+
+static OCStackApplicationResult handleDiscoverCB(void *ctx,
+ OCDoHandle handle, OCClientResponse *clientResponse)
+{
+ OC_LOG(DEBUG, TAG, "Found Resource Directory");
+ OCStackApplicationResult ret = OC_STACK_DELETE_TRANSACTION;
+
+ OCRDClientContextCB *cb = (OCRDClientContextCB *)ctx;
+ if (!cb)
+ {
+ OC_LOG(ERROR, TAG, "RD Context Invalid Parameters.");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (cb->context != (void *) DEFAULT_CONTEXT_VALUE)
+ {
+ OC_LOG(ERROR, TAG, "RD Context Invalid Context Value Parameters.");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OC_LOG(DEBUG, TAG, "Callback Context for DISCOVER query received successfully.");
+
+ if (clientResponse && clientResponse->result == OC_STACK_OK)
+ {
+ retreiveRDDetails(clientResponse, cb->cbFunc);
+ }
+ else
+ {
+ OC_LOG(ERROR, TAG, "Discovery of RD Failed");
+ }
+
+ OICFree(cb);
+
+ return ret;
+}
+
+OCStackResult OCRDDiscover(OCRDBiasFactorCB cbBiasFactor)
+{
+ if (!cbBiasFactor)
+ {
+ OC_LOG(DEBUG, TAG, "No callback function specified.");
+ return OC_STACK_INVALID_CALLBACK;
+ }
+
+ /* Start a discovery query*/
+ char queryUri[MAX_URI_LENGTH] = { '\0' };
+ snprintf(queryUri, MAX_URI_LENGTH, "coap://%s%s", OC_MULTICAST_PREFIX, OC_RSRVD_RD_URI);
+
+ OC_LOG_V(DEBUG, TAG, "Querying RD: %s\n", queryUri);
+
+ OCRDClientContextCB *cbContext = OICCalloc(1, sizeof(OCRDClientContextCB));
+ if (!cbContext)
+ {
+ OC_LOG(ERROR, TAG, "Failed allocating memory.");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ cbContext->context = (void *)DEFAULT_CONTEXT_VALUE;
+ cbContext->cbFunc = cbBiasFactor;
+
+ OCCallbackData cbData;
+ cbData.cb = handleDiscoverCB;
+ cbData.context = (void *)(cbContext);
+ cbData.cd = NULL;
+
+ return sendRequest(OC_REST_DISCOVER, queryUri, NULL, NULL, cbData);
+}
+
+OCStackResult OCRDPublish(char *addr, uint16_t port, int numArg, ... )
+{
+ if (!addr)
+ {
+ OC_LOG_V(ERROR, TAG, "RD address not specified.");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ char targetUri[MAX_URI_LENGTH];
+ snprintf(targetUri, MAX_URI_LENGTH, "coap://%s:%d%s?rt=%s", addr, port,
+ OC_RSRVD_RD_URI, OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
+ OC_LOG_V(DEBUG, TAG, "Target URI : %s", targetUri);
+
+ // Gather all resources locally and do publish
+ OCCallbackData cbData = { 0 };
+ cbData.cb = &handlePublishCB;
+ cbData.cd = NULL;
+ cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+
+ OCRDLinksPayload* linksPayload = NULL;
+
+ va_list arguments;
+ va_start (arguments, numArg);
+
+ for (int j = 0 ; j < numArg; j++)
+ {
+ OCResourceHandle handle = va_arg(arguments, OCResourceHandle);
+ if (handle)
+ {
+ const char* uri = OCGetResourceUri(handle);
+ const char* rt = OCGetResourceTypeName(handle, 0);
+ const char* itf = OCGetResourceInterfaceName(handle, 0);
+ if (uri && rt && itf)
+ {
+ OCRDLinksPayloadCreate(uri, rt, itf, &linksPayload);
+ }
+ }
+ }
+ va_end(arguments);
+
+ OCRDPayload *rdPayload = OCRDPayloadCreate(RD_PAYLOAD_TYPE_PUBLISH);
+ if (!rdPayload)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
+ return OC_STACK_NO_MEMORY;
+ }
+ rdPayload->rdPublish = OCRDPublishPayloadCreate(OC_RD_PUBLISH_TTL, linksPayload);
+ if (!rdPayload->rdPublish)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ OCDevAddr rdAddr = { 0 };
+ OICStrcpy(rdAddr.addr, MAX_ADDR_STR_SIZE, addr);
+ rdAddr.port = port;
+
+ OCRDPayloadLog(DEBUG, TAG, rdPayload);
+
+ return sendRequest(OC_REST_POST, targetUri, &rdAddr, (OCPayload *)rdPayload, cbData);
+}
--- /dev/null
+//******************************************************************
+//
+// 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 "oic_malloc.h"
+#include "oic_string.h"
+
+#include "octypes.h"
+#include "ocstack.h"
+#include "logger.h"
+
+#define TAG PCF("OCRDPayload")
+
+#define CBOR_ROOT_ARRAY_LENGTH 2
+#define CBOR_LINK_ARRAY_LENGTH 3
+
+static void linksPayloadDestroy(OCRDLinksPayload *linkPayload)
+{
+ OCRDLinksPayload *links = linkPayload;
+
+ while (links)
+ {
+ OICFree(links->href);
+ OICFree(links->rt);
+ OICFree(links->itf);
+ OCRDLinksPayload *tmp = links;
+ links = links->next;
+ OICFree(tmp);
+ }
+}
+
+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;
+
+ OCRDPayloadLog(DEBUG, TAG, rdPayload);
+
+ CborEncoder encoder;
+ int flags = 0;
+ cbor_encoder_init(&encoder, *outPayload, *size, flags);
+
+ CborEncoder rootArray;
+ CborError cborEncoderResult;
+ cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, CBOR_ROOT_ARRAY_LENGTH);
+ 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;
+ }
+ }
+ else
+ {
+ OC_LOG_V(ERROR, TAG, "Missing sel parameter in the discovery payload.");
+ goto exit;
+ }
+ }
+ else if (rdPayload->payloadType == RD_PAYLOAD_TYPE_PUBLISH)
+ {
+ cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_TTL, sizeof(OC_RSRVD_TTL) - 1);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish ttl type.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encode_uint(&map, rdPayload->rdPublish->ttl);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish ttl value.");
+ goto exit;
+ }
+
+ CborEncoder linksArray;
+ cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) - 1);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish links type.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encoder_create_array(&map, &linksArray, CborIndefiniteLength);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish links array.");
+ goto exit;
+ }
+
+ {
+ OCRDLinksPayload *rtPtr = rdPayload->rdPublish->links;
+ while(rtPtr)
+ {
+ CborEncoder linksMap;
+ cborEncoderResult = cbor_encoder_create_map(&linksArray, &linksMap, CBOR_LINK_ARRAY_LENGTH);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish map.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_HREF,
+ sizeof(OC_RSRVD_HREF) - 1);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish href type.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->href,
+ strlen(rtPtr->href));
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish href value.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_INTERFACE,
+ sizeof(OC_RSRVD_INTERFACE) - 1);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish itf type.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->itf,
+ strlen(rtPtr->itf));
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish itf value.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_RESOURCE_TYPE,
+ sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish rt type.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->rt,
+ strlen(rtPtr->rt));
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed setting publish rt value.");
+ goto exit;
+ }
+
+ cborEncoderResult = cbor_encoder_close_container(&linksArray, &linksMap);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed closing linksMap publish map.");
+ goto exit;
+ }
+
+ rtPtr = rtPtr->next;
+ }
+ }
+ cborEncoderResult = cbor_encoder_close_container(&map, &linksArray);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed closing linksArray container.");
+ goto exit;
+ }
+ }
+
+ cborEncoderResult = cbor_encoder_close_container(&rootArray, &map);
+ if (CborNoError != cborEncoderResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed closing map 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))
+ {
+ OC_LOG_V(ERROR, TAG, "RD CBOR Payload is not in map format.");
+ return OC_STACK_ERROR;
+ }
+ else
+ {
+ 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;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(biasFactor);
+ if (!rdPayload->rdDiscovery)
+ {
+ goto no_memory;
+ }
+ }
+ else
+ { // TTL
+ int ttl = 0;
+ cborFindResult = cbor_value_map_find_value(rdCBORPayload, OC_RSRVD_TTL, &curVal);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_TTL type in the payload.");
+ goto exit;
+ }
+
+ cborFindResult = cbor_value_get_int(&curVal, &ttl);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_TTL value in the payload.");
+ goto exit;
+ }
+
+ // Link Array
+ CborValue linkArray;
+ cborFindResult = cbor_value_map_find_value(rdCBORPayload, OC_RSRVD_LINKS, &linkArray);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_LINKS type in the payload.");
+ goto exit;
+ }
+
+ CborValue linkVal;
+ cborFindResult = cbor_value_enter_container(&linkArray, &linkVal);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed entering linkArray container in the payload.");
+ goto exit;
+ }
+
+ OCRDLinksPayload *links = NULL;
+ while(cbor_value_is_map(&linkVal))
+ {
+ char *href = NULL;
+ char *itf = NULL;
+ char *rt = NULL;
+ size_t len;
+
+ cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_HREF, &curVal);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_HREF type in the payload.");
+ goto exit;
+ }
+
+ cborFindResult = cbor_value_dup_text_string(&curVal, &href, &len, NULL);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_HREF value in the payload.");
+ goto exit;
+ }
+
+ cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_INTERFACE, &curVal);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_INTERFACE type in the payload.");
+ goto exit;
+ }
+
+ cborFindResult = cbor_value_dup_text_string(&curVal, &itf, &len, NULL);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_INTERFACE value in the payload.");
+ goto exit;
+ }
+
+ cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_RESOURCE_TYPE type in the payload.");
+ goto exit;
+ }
+
+ cborFindResult = cbor_value_dup_text_string(&curVal, &rt, &len, NULL);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_RESOURCE_TYPE value in the payload.");
+ goto exit;
+ }
+
+ OCRDLinksPayloadCreate(href, rt, itf, &links);
+ if (!links)
+ {
+ goto no_memory;
+ }
+
+ cborFindResult = cbor_value_advance(&linkVal);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed advancing the linkVal payload.");
+ goto exit;
+ }
+ }
+ cborFindResult = cbor_value_advance(&linkArray);
+ if (CborNoError != cborFindResult)
+ {
+ OC_LOG_V(ERROR, TAG, "Failed advancing the linkArray payload.");
+ goto exit;
+ }
+ rdPayload->rdPublish = OCRDPublishPayloadCreate(ttl, links);
+ if (!rdPayload->rdPublish)
+ {
+ goto no_memory;
+ }
+ }
+
+ OCRDPayloadLog(DEBUG, TAG, rdPayload);
+ 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;
+}
+
+void OCRDLinksPayloadCreate(const char *uri, const char *rt, const char *itf,
+ OCRDLinksPayload **linksPayload)
+{
+ OCRDLinksPayload *payload = OICCalloc(1, sizeof(OCRDLinksPayload));
+ if (!payload)
+ {
+ goto no_memory;
+ }
+
+ payload->href = OICStrdup(uri);
+ if (!payload->href)
+ {
+ goto no_memory;
+ }
+
+ payload->rt = OICStrdup(rt);
+ if (!payload->rt)
+ {
+ goto no_memory;
+ }
+
+ payload->itf = OICStrdup(itf);
+ if (!payload->itf)
+ {
+ goto no_memory;
+ }
+
+ payload->next = NULL;
+
+ if (*linksPayload == NULL)
+ {
+ *linksPayload = payload;
+ }
+ else
+ {
+ OCRDLinksPayload *temp = *linksPayload;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = payload;
+ }
+ return;
+
+no_memory:
+ OC_LOG_V(ERROR, TAG, "Memory allocation failed.");
+ linksPayloadDestroy(payload);
+}
+
+OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(int biasFactor)
+{
+ OCRDDiscoveryPayload *discoveryPayload = OICCalloc(1, sizeof(OCRDDiscoveryPayload));
+
+ if (!discoveryPayload)
+ {
+ return NULL;
+ }
+ discoveryPayload->sel = biasFactor;
+
+ return discoveryPayload;
+}
+
+
+OCRDPublishPayload* OCRDPublishPayloadCreate(int ttl,
+ OCRDLinksPayload *linksPayload)
+{
+ OCRDPublishPayload *rdPublish = OICCalloc(1, sizeof(OCRDPublishPayload));
+ if (!rdPublish)
+ {
+ return NULL;
+ }
+
+ //TODO: Find way of device device id.
+ // rdPayload->rdPublish->id = (uint8_t *)OICCalloc(1, UUID_SIZE);
+ // memcpy(rdPayload->rdPublish->id, , UUID_SIZE);
+ //TODO: Find way of device device name.
+ // rdPayload->rdPublish->n = (char*)OICCalloc(1, strlen(name));
+ // memcpy(rdPayload->rdPublish->n, , strlen(name));
+ rdPublish->ttl = ttl; // TODO Expose API to allow user to set this value.
+ rdPublish->links = linksPayload;
+
+ return rdPublish;
+}
+
+void OCRDPayloadDestroy(OCRDPayload *payload)
+{
+ if (!payload)
+ {
+ return;
+ }
+
+ if (payload->rdDiscovery)
+ {
+ OICFree(payload->rdDiscovery);
+ }
+
+ if (payload->rdPublish)
+ {
+ if (payload->rdPublish->links)
+ {
+ linksPayloadDestroy(payload->rdPublish->links);
+ }
+
+ if (payload->rdPublish->deviceName.deviceName)
+ {
+ OICFree(payload->rdPublish->deviceName.deviceName);
+ }
+
+ OICFree(payload->rdPublish);
+ }
+
+ 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);
+ }
+ OCRDPublishPayloadLog(level, tag, payload->rdPublish);
+}
+
+void OCRDPublishPayloadLog(LogLevel level, const char *tag, const OCRDPublishPayload *rdPublish)
+{
+ if (rdPublish)
+ {
+ if (rdPublish->deviceName.deviceName)
+ {
+ OC_LOG_V(level, tag, "RD Payload Pulish Name : %s", rdPublish->deviceName.deviceName);
+ }
+
+ if (rdPublish->deviceId.id)
+ {
+ OC_LOG_V(level, tag, "RD Payload Publish ID : %s", rdPublish->deviceId.id);
+ }
+
+ OC_LOG_V(level, tag, "RD Payload Publish TTL : %d", rdPublish->ttl);
+
+ if (rdPublish->links)
+ {
+ for (OCRDLinksPayload *temp = rdPublish->links; temp; temp = temp->next)
+ {
+ OC_LOG_V(level, tag, "RD Payload Publish Link HREF : %s", temp->href);
+ OC_LOG_V(level, tag, "RD Payload Publish Link RT : %s", temp->rt);
+ OC_LOG_V(level, tag, "RD Payload Publish Link ITF : %s", temp->itf);
+ }
+ }
+ }
+}
--- /dev/null
+// 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 "rd_storage.h"
+
+#include "logger.h"
+
+#define TAG PCF("RDServer")
+
+// This is temporary hardcoded value for bias factor.
+#define OC_RD_DISC_SEL 100
+
+static OCStackResult sendResponse(const OCEntityHandlerRequest *ehRequest, OCRDPayload *rdPayload)
+{
+ OCEntityHandlerResponse response = { 0 };
+ response.requestHandle = ehRequest->requestHandle;
+ response.resourceHandle = ehRequest->resource;
+ response.ehResult = OC_EH_OK;
+ response.payload = (OCPayload*)(rdPayload);
+ response.payload->type = PAYLOAD_TYPE_RD;
+
+ return OCDoResponse(&response);
+}
+
+/**
+ * This internal method handles RD discovery request.
+ * Responds with the RD discovery payload message.
+ */
+static OCEntityHandlerResult handleGetRequest(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);
+
+ if (sendResponse(ehRequest, rdPayload) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "Sending response failed.");
+ ehResult = OC_EH_ERROR;
+ }
+
+ OCRDPayloadDestroy(rdPayload);
+
+ return ehResult;
+}
+
+/**
+ * This internal method handles RD publish request.
+ * Responds with the RD success message.
+ */
+static OCEntityHandlerResult handlePublishRequest(const OCEntityHandlerRequest *ehRequest)
+{
+ OCEntityHandlerResult ehResult = OC_EH_OK;
+
+ OC_LOG_V(DEBUG, TAG, "Received OC_REST_PUT from client with query: %s.", ehRequest->query);
+
+ if (!ehRequest)
+ {
+ OC_LOG_V(DEBUG, TAG, "Invalid request pointer");
+ return OC_EH_ERROR;
+ }
+
+ OCRDPayload *payload = (OCRDPayload *)ehRequest->payload;
+ if (payload->payloadType == RD_PAYLOAD_TYPE_PUBLISH)
+ {
+ OCRDStorePublishedResources(payload->rdPublish);
+ }
+
+ 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:
+ handleGetRequest(ehRequest);
+ break;
+ case OC_REST_POST:
+ handlePublishRequest(ehRequest);
+ break;
+ 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);
+ OCResourceHandle rdHandle = NULL;
+
+ if (result == OC_STACK_OK)
+ {
+ result = OCCreateResource(&rdHandle,
+ 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;
+}