- Support multiple ins query for deleting resource.
- Reset ins value of deleted resource.
- Enable RD build in all platforms.
- https://jira.iotivity.org/browse/IOT-1386
Change-Id: If7f19f63592ccfa6d298561da5ad173b0965d32c
Signed-off-by: Habib Virji <habib.virji@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/12183
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
cc_sample_app_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x', '-pthread'])
cc_sample_app_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
cc_sample_app_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
-cc_sample_app_env.PrependUnique(LIBS = ['oc', 'octbstack', 'pthread'])
+cc_sample_app_env.PrependUnique(LIBS = ['oc', 'octbstack', 'pthread', 'resource_directory'])
cc_sample_app_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD', 'RD_CLIENT'])
SConscript('#resource/third_party_libs.scons', 'lib_env')
examples_env = lib_env.Clone()
+rd_mode = lib_env.get('RD_MODE')
######################################################################
# Build flags
if env.get('WITH_CLOUD'):
examples_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
+ examples_env.AppendUnique(LIBS = ['resource_directory'])
+
######################################################################
# Source files and Targets
######################################################################
Alias("examples", [OICMiddle])
env.AppendTarget('examples')
-
-
-
target_os = env.get('TARGET_OS')
src_dir = env.get('SRC_DIR')
+rd_mode = env.get('RD_MODE')
# Build C Common dependencies
SConscript('c_common/SConscript')
# Build Routing
SConscript('csdk/routing/SConscript')
-if target_os in ['linux', 'android']:
- rd_mode = env.get('RD_MODE')
- if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
- SConscript('csdk/resource-directory/SConscript')
+if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
+ SConscript('csdk/resource-directory/SConscript')
# Build libocsrm
SConscript('csdk/security/SConscript')
liboctbstack_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
if 'SERVER' in rd_mode:
liboctbstack_env.AppendUnique(CPPDEFINES = ['RD_SERVER'])
- if target_os in ['linux', 'android']:
- liboctbstack_env.Prepend(LIBS = ['resource_directory'])
- liboctbstack_env.PrependUnique(CPPPATH = [env.get('BUILD_DIR') + 'resource/csdk/resource-directory/include'])
- liboctbstack_env.PrependUnique(LIBPATH = [env.get('BUILD_DIR') + 'resource/csdk/resource-directory/include'])
if with_tcp == True:
liboctbstack_src.append(OCTBSTACK_SRC + 'oickeepalive.c')
OCGetResourceProperties
OCGetResourceTypeName
OCGetResourceUri
+OCGetResourceIns
OCGetServerInstanceIDString
OCInit
OCInit1
OCRepPayloadSetPropDouble
OCRepPayloadSetPropByteString
OCRepPayloadSetPropInt
+OCRepPayloadSetPropObjectArray
OCRepPayloadSetPropObjectArrayAsOwner
OCRepPayloadSetPropObjectAsOwner
OCRepPayloadSetPropString
OCStartPresence
OCStop
OCStopPresence
+OCStopMulticastServer
OCUnBindResource
OCSetHeaderOption
OCGetHeaderOption
######################################################################
# Build flags
######################################################################
-rd_env.AppendUnique(CPPPATH = ['include', 'src/internal', '../stack/include'])
+rd_env.AppendUnique(CPPPATH = ['include', 'src/internal', '../stack/include', '../../oc_logger/include'])
if 'CLIENT' in rd_mode:
rd_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
if 'SERVER' in rd_mode:
rd_env.AppendUnique(CPPDEFINES = ['RD_SERVER'])
-rd_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap'])
+rd_env.AppendUnique(LIBPATH = [rd_env.get('BUILD_DIR')])
+rd_env.AppendUnique(LIBS = ['octbstack'])
if target_os not in ['windows']:
rd_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra'])
-if target_os in ['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'])
######################################################################
RD_SRC_DIR = 'src/'
rd_src = []
+
if 'SERVER' in rd_mode:
rd_src += [
- RD_SRC_DIR + 'internal/rd_database.c',
- RD_SRC_DIR + 'rd_server.c',
- ]
+ RD_SRC_DIR + 'internal/rd_database.c',
+ RD_SRC_DIR + 'rd_server.c',
+ ]
if target_os not in ['tizen'] :
rd_src += [ '../../../extlibs/sqlite3/sqlite3.c' ]
+
if 'CLIENT' in rd_mode:
rd_src += [RD_SRC_DIR + 'rd_client.c',]
-if target_os in ['tizen'] :
+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, 'resource_directory')
rd_env.UserInstallTargetLib(rdsdk, 'resource_directory')
+
if 'CLIENT' in rd_mode:
rd_env.UserInstallTargetHeader('include/rd_client.h', 'service/resource-directory', 'rd_client.h')
extern "C" {
#endif // __cplusplus
+#ifdef RD_CLIENT
+
#define OIC_RD_PUBLISH_TTL 86400
#define OIC_RD_DEFAULT_RESOURCE 2
OCResourceHandle *resourceHandles, uint8_t nHandles,
OCCallbackData *cbData, OCQualityOfService qos);
+#endif
+
#ifdef __cplusplus
}
#endif // __cplusplus
extern "C" {
#endif // __cplusplus
+#ifdef RD_SERVER
+
/**
* This function creates resource /oic/rd.
*
OCStackResult OCRDCheckPublishedResource(const char *interfaceType, const char *resourceType,
OCDiscoveryPayload **payload);
+#endif
+
#ifdef __cplusplus
}
#endif // __cplusplus
}
else
{
- for (OCStringLL *tmp = *type; tmp->next; tmp = tmp->next);
+ OCStringLL *tmp = *type;
+ for (; tmp->next; tmp = tmp->next);
tmp->next = temp;
}
return OC_STACK_OK;
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "rd_client.h"
+#include <stdlib.h>
+
#include "oic_malloc.h"
#include "oic_string.h"
#include "octypes.h"
}
OCRepPayloadSetPropInt(rdPayload, OC_RSRVD_DEVICE_TTL, OIC_RD_PUBLISH_TTL);
- const OCRepPayload *linkArr[nPubResHandles];
- size_t dimensions[MAX_REP_ARRAY_DEPTH] = {nPubResHandles, 0, 0};
+ OCRepPayload **linkArr = OICCalloc(nPubResHandles, sizeof(OCRepPayload *));
+ if (!linkArr)
+ {
+ OCRepPayloadDestroy(rdPayload);
+ return OC_STACK_NO_MEMORY;
+ }
+ size_t dimensions[MAX_REP_ARRAY_DEPTH] = {nPubResHandles, 0, 0};
for (uint8_t j = 0; j < nPubResHandles; j++)
{
OCResourceHandle handle = pubResHandle[j];
OIC_LOG_V(DEBUG, TAG, "value: %s", value);
rt[i] = OICStrdup(value);
}
- OCRepPayloadSetStringArray(link, OC_RSRVD_RESOURCE_TYPE, (const char **)rt, rtDim);
+ OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_RESOURCE_TYPE, rt, rtDim);
}
numElement = 0;
OIC_LOG_V(DEBUG, TAG, "value: %s", value);
itf[i] = OICStrdup(value);
}
- OCRepPayloadSetStringArray(link, OC_RSRVD_INTERFACE, (const char **)itf, ifDim);
+ OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_INTERFACE, itf, ifDim);
}
uint8_t ins = 0;
size_t mtDim[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
char **mediaType = (char **)OICMalloc(sizeof(char *) * 1);
mediaType[0] = OICStrdup(DEFAULT_MESSAGE_TYPE);
- OCRepPayloadSetStringArray(link, OC_RSRVD_MEDIA_TYPE, (const char **)mediaType,
+ OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_MEDIA_TYPE, mediaType,
mtDim);
OCResourceProperty p = OCGetResourceProperties(handle);
OCRepPayloadSetPropObjectArray(rdPayload, OC_RSRVD_LINKS, linkArr, dimensions);
OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
+ for (uint8_t i = 0; i < nPubResHandles; i++)
+ {
+ OCRepPayloadDestroy(linkArr[i]);
+ }
+ OICFree(linkArr);
+
return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload,
connectivityType, qos, cbData, NULL, 0);
}
return OCDoResource(NULL, OC_REST_DELETE, targetUri, NULL, NULL, connectivityType,
qos, cbData, NULL, 0);
}
-
#endif
*/
uint32_t GetTicks(uint32_t milliSeconds);
+#if defined(RD_CLIENT) || defined(RD_SERVER)
+/**
+ * This function binds an resource unique ins value to the resource. This can be only called
+ * when stack is received response from resource-directory.
+ *
+ * @param requestUri URI of the resource.
+ * @param response Response from queries to remote servers.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri,
+ const OCClientResponse *response);
+#endif
+
#ifdef __cplusplus
}
#endif // __cplusplus
}
else
{
+#ifdef RD_CLIENT
+ // if request uri is '/oic/rd', update ins value of resource.
+ char *targetUri = strstr(cbNode->requestUri, OC_RSRVD_RD_URI);
+ if (targetUri)
+ {
+ OCUpdateResourceInsWithResponse(cbNode->requestUri, &response);
+ }
+#endif
OCStackApplicationResult appFeedback = cbNode->callBack(cbNode->context,
cbNode->handle,
&response);
return OC_STACK_OK;
}
+OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri,
+ const OCClientResponse *response)
+{
+ // Validate input parameters
+ VERIFY_NON_NULL(requestUri, ERROR, OC_STACK_INVALID_PARAM);
+ VERIFY_NON_NULL(response, ERROR, OC_STACK_INVALID_PARAM);
+
+ char *targetUri = (char *) OICMalloc(strlen(requestUri) + 1);
+ if (!targetUri)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+ strncpy(targetUri, requestUri, strlen(requestUri) + 1);
+
+ if (response->result == OC_STACK_RESOURCE_CHANGED) // publish message
+ {
+ OIC_LOG(DEBUG, TAG, "update the ins of published resource");
+
+ char rdPubUri[MAX_URI_LENGTH] = { 0 };
+ snprintf(rdPubUri, MAX_URI_LENGTH, "%s?rt=%s", OC_RSRVD_RD_URI,
+ OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
+
+ if (strcmp(rdPubUri, targetUri) == 0)
+ {
+ // Update resource unique id in stack.
+ if (response)
+ {
+ if (response->payload)
+ {
+ OCRepPayload *rdPayload = (OCRepPayload *) response->payload;
+ OCRepPayload **links = NULL;
+ size_t dimensions[MAX_REP_ARRAY_DEPTH];
+ if (OCRepPayloadGetPropObjectArray(rdPayload, OC_RSRVD_LINKS,
+ &links, dimensions))
+ {
+ size_t i = 0;
+ for (; i < dimensions[0]; i++)
+ {
+ char *uri = NULL;
+ if (OCRepPayloadGetPropString(links[i], OC_RSRVD_HREF, &uri))
+ {
+ OCResourceHandle handle = OCGetResourceHandleAtUri(uri);
+ int64_t ins = 0;
+ if (OCRepPayloadGetPropInt(links[i], OC_RSRVD_INS, &ins))
+ {
+ OCBindResourceInsToResource(handle, ins);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (response->result == OC_STACK_RESOURCE_DELETED) // delete message
+ {
+ OIC_LOG(DEBUG, TAG, "update the ins of deleted resource with 0");
+
+ uint8_t numResources = 0;
+ OCGetNumberOfResources(&numResources);
+
+ char *ins = strstr(targetUri, OC_RSRVD_INS);
+ if (!ins)
+ {
+ for (uint8_t i = 0; i < numResources; i++)
+ {
+ OCResourceHandle resHandle = OCGetResourceHandle(i);
+ if (resHandle)
+ {
+ OCBindResourceInsToResource(resHandle, 0);
+ }
+ }
+ }
+ else
+ {
+ const char *token = "&";
+ char *iterTokenPtr = NULL;
+ char *start = strtok_r(targetUri, token, &iterTokenPtr);
+
+ while (start != NULL)
+ {
+ char *query = start;
+ query = strstr(query, OC_RSRVD_INS);
+ if (query)
+ {
+ uint8_t queryIns = atoi(query + 4);
+ for (uint8_t i = 0; i < numResources; i++)
+ {
+ OCResourceHandle resHandle = OCGetResourceHandle(i);
+ if (resHandle)
+ {
+ uint8_t resIns = 0;
+ OCGetResourceIns(resHandle, &resIns);
+ if (queryIns && queryIns == resIns)
+ {
+ OCBindResourceInsToResource(resHandle, 0);
+ break;
+ }
+ }
+ }
+ }
+ start = strtok_r(NULL, token, &iterTokenPtr);
+ }
+ }
+ }
+
+ OICFree(targetUri);
+ return OC_STACK_OK;
+}
+
OCResourceHandle OCGetResourceHandleAtUri(const char *uri)
{
if (!uri)
}
return OC_STACK_ERROR;
}
+#endif
OCStackResult OCSetHeaderOption(OCHeaderOption* ocHdrOpt, size_t* numOptions, uint16_t optionID,
- void* optionData, size_t optionDataLength)
+ void* optionData, size_t optionDataLength)
{
if (!ocHdrOpt)
{
return OC_STACK_OK;
}
-OCStackResult OCGetHeaderOption(OCHeaderOption* ocHdrOpt, size_t numOptions, uint16_t optionID,
- void* optionData, size_t optionDataLength, uint16_t* receivedDataLength)
+
+OCStackResult OCGetHeaderOption(OCHeaderOption* ocHdrOpt, size_t numOptions,
+ uint16_t optionID, void* optionData, size_t optionDataLength,
+ uint16_t* receivedDataLength)
{
if (!ocHdrOpt || !numOptions)
{
}
return OC_STACK_OK;
}
-#endif
void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled)
{
SConscript('#resource/third_party_libs.scons', 'lib_env')
examples_env = lib_env.Clone()
target_os = examples_env.get('TARGET_OS')
+rd_mode = examples_env.get('RD_MODE')
+
######################################################################
# Build flags
######################################################################
if examples_env.get('LOGGING'):
examples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
+ examples_env.AppendUnique(LIBS = ['resource_directory'])
+
def make_single_file_cpp_program(program_name):
return examples_env.Program(program_name, program_name + ".cpp")
try
{
- // Update resource unique id in stack.
- if (clientResponse)
- {
- if (clientResponse->payload)
- {
- OCRepPayload *rdPayload = (OCRepPayload *) clientResponse->payload;
- OCRepPayload **links = NULL;
-
- size_t dimensions[MAX_REP_ARRAY_DEPTH];
- OCRepPayloadGetPropObjectArray(rdPayload, OC_RSRVD_LINKS, &links, dimensions);
- for(size_t i = 0; i < dimensions[0]; i++)
- {
- char *uri = NULL;
- OCRepPayloadGetPropString(links[i], OC_RSRVD_HREF, &uri);
- OCResourceHandle handle = OCGetResourceHandleAtUri(uri);
- int64_t ins = 0;
- OCRepPayloadGetPropInt(links[i], OC_RSRVD_INS, &ins);
- OCBindResourceInsToResource(handle, ins);
- }
- }
- OCRepresentation rep = parseRDResponseCallback(clientResponse);
- std::thread exec(context->callback, rep, clientResponse->result);
- exec.detach();
- }
+ OCRepresentation rep = parseRDResponseCallback(clientResponse);
+ std::thread exec(context->callback, rep, clientResponse->result);
+ exec.detach();
}
catch (OC::OCException& e)
{
<<e.what() <<std::flush;
}
- return OC_STACK_KEEP_TRANSACTION;
+ return OC_STACK_DELETE_TRANSACTION;
}
OCStackResult InProcServerWrapper::publishResourceToRD(const std::string& host,
target_os = oclib_env.get('TARGET_OS')
with_cloud = oclib_env.get('WITH_CLOUD')
with_mq = oclib_env.get('WITH_MQ')
+rd_mode = oclib_env.get('RD_MODE')
######################################################################
# Build flags
if 'BROKER' in with_mq:
oclib_env.AppendUnique(CPPDEFINES = ['MQ_BROKER', 'WITH_MQ'])
-if target_os in ['linux', 'android'] and oclib_env.get('RD_MODE'):
- rd_mode = oclib_env.get('RD_MODE')
- oclib_env.AppendUnique(LIBPATH = [os.path.join(oclib_env.get('BUILD_DIR'), 'resource', 'csdk','resource-directory')])
- oclib_env.AppendUnique(CPPPATH = ['../csdk/resource-directory/include'])
- oclib_env.AppendUnique(LIBS=['resource_directory'])
-
+if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
if 'CLIENT' in rd_mode:
- oclib_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
-
+ oclib_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
if 'SERVER' in rd_mode:
oclib_env.AppendUnique(CPPDEFINES = ['RD_SERVER'])
+ oclib_env.AppendUnique(LIBS = ['resource_directory'])
+ oclib_env.AppendUnique(CPPPATH = [oclib_env.get('BUILD_DIR') + 'resource/csdk/resource-directory/include'])
######################################################################
# Source files and Targets
src_dir = unittests_env.get('SRC_DIR')
target_os = unittests_env.get('TARGET_OS')
with_mq = unittests_env.get('WITH_MQ')
+rd_mode = unittests_env.get('RD_MODE')
######################################################################
# Build flags
if unittests_env.get('WITH_CLOUD'):
unittests_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
+ unittests_env.AppendUnique(LIBS = ['resource_directory'])
+
######################################################################
# Source files and Targets
######################################################################