From: Habib Virji Date: Wed, 29 Jul 2015 13:04:20 +0000 (+0100) Subject: RDServer discovery functionality X-Git-Tag: 1.0.0-RC2^2^2~16 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=76fb78dadb6c0d3f8f930f3f63101bfdbcba8201;p=contrib%2Fiotivity.git RDServer discovery functionality 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 Reviewed-on: https://gerrit.iotivity.org/gerrit/2155 Tested-by: jenkins-iotivity --- diff --git a/auto_build.sh b/auto_build.sh index 568920e..80db2ab 100755 --- a/auto_build.sh +++ b/auto_build.sh @@ -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` " - echo " Allowed values for : 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 : 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 diff --git a/build_common/SConscript b/build_common/SConscript index 7f4c650..180d490 100644 --- a/build_common/SConscript +++ b/build_common/SConscript @@ -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'])) diff --git a/resource/csdk/SConscript b/resource/csdk/SConscript index a9e30c8..1f3b67b 100644 --- a/resource/csdk/SConscript +++ b/resource/csdk/SConscript @@ -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']) ###################################################################### diff --git a/resource/csdk/stack/include/ocpayload.h b/resource/csdk/stack/include/ocpayload.h index 4850d92..7abe6ab 100644 --- a/resource/csdk/stack/include/ocpayload.h +++ b/resource/csdk/stack/include/ocpayload.h @@ -26,6 +26,10 @@ #include "logger.h" #include "octypes.h" +#ifdef WITH_RD +#include "rd_payload.h" +#endif + #ifdef __cplusplus extern "C" { diff --git a/resource/csdk/stack/include/octypes.h b/resource/csdk/stack/include/octypes.h index 5f602ff..53c3fec 100644 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@ -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 diff --git a/resource/csdk/stack/include/payload_logging.h b/resource/csdk/stack/include/payload_logging.h index acc207a..5bfb5bb 100644 --- a/resource/csdk/stack/include/payload_logging.h +++ b/resource/csdk/stack/include/payload_logging.h @@ -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; diff --git a/resource/csdk/stack/src/ocpayload.c b/resource/csdk/stack/src/ocpayload.c index 7b9b9a3..020ae2a 100644 --- a/resource/csdk/stack/src/ocpayload.c +++ b/resource/csdk/stack/src/ocpayload.c @@ -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); diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c index d72c136..4da86c4 100644 --- a/resource/csdk/stack/src/ocpayloadconvert.c +++ b/resource/csdk/stack/src/ocpayloadconvert.c @@ -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; diff --git a/resource/csdk/stack/src/ocpayloadparse.c b/resource/csdk/stack/src/ocpayloadparse.c index 05c6b59..b3b789c 100644 --- a/resource/csdk/stack/src/ocpayloadparse.c +++ b/resource/csdk/stack/src/ocpayloadparse.c @@ -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; diff --git a/resource/docs/Doxyfile b/resource/docs/Doxyfile index 77c863d..cf72346 100644 --- a/resource/docs/Doxyfile +++ b/resource/docs/Doxyfile @@ -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 diff --git a/service/SConscript b/service/SConscript index 5389725..7d3a5d2 100644 --- a/service/SConscript +++ b/service/SConscript @@ -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 index 0000000..a710a0b --- /dev/null +++ b/service/resource-directory/SConscript @@ -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 index 0000000..924e446 --- /dev/null +++ b/service/resource-directory/include/rd_payload.h @@ -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 + +#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 index 0000000..bc61032 --- /dev/null +++ b/service/resource-directory/include/rd_server.h @@ -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 index 0000000..a43beff --- /dev/null +++ b/service/resource-directory/include/rd_types.h @@ -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 index 0000000..441b192 --- /dev/null +++ b/service/resource-directory/src/rd_payload.c @@ -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 + +#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 index 0000000..c605bb8 --- /dev/null +++ b/service/resource-directory/src/rd_server.c @@ -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; +}