From dce4477840e6916459041f30ee7486227a793278 Mon Sep 17 00:00:00 2001 From: YounghyunJoo Date: Mon, 18 Jul 2016 10:04:44 +0900 Subject: [PATCH] Add Cloud interface consumer sample example code - modify sample example code to support cloud interface - modify example SConscript to build with cloud interface when get WITH_TCP & WITH_CLOUD environment Change-Id: If9ab0a30672d4a09e63169ef3d146af6cb26670a Signed-off-by: YounghyunJoo Reviewed-on: https://gerrit.iotivity.org/gerrit/9413 Tested-by: jenkins-iotivity Reviewed-by: Uze Choi Tested-by: Uze Choi --- service/notification/examples/linux/SConscript | 18 +- .../notification/examples/linux/cloud_connector.c | 292 +++++++++++++++++++++ .../notification/examples/linux/cloud_connector.h | 40 +++ .../examples/linux/notificationconsumer.c | 67 ++++- 4 files changed, 410 insertions(+), 7 deletions(-) create mode 100644 service/notification/examples/linux/cloud_connector.c create mode 100644 service/notification/examples/linux/cloud_connector.h diff --git a/service/notification/examples/linux/SConscript b/service/notification/examples/linux/SConscript index 8be91a7..5a8eb31 100644 --- a/service/notification/examples/linux/SConscript +++ b/service/notification/examples/linux/SConscript @@ -24,8 +24,6 @@ notification_sample_env.PrependUnique(LIBS = [ 'connectivity_abstraction', 'libcoap' ]) - - if target_os not in ['windows', 'winrt']: notification_sample_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x']) @@ -42,6 +40,20 @@ if target_os == 'android': if not env.get('RELEASE'): notification_sample_env.AppendUnique(LIBS = ['log']) + +notification_sample_consumer_src = 'notificationconsumer.c' + +if env.get('WITH_CLOUD') == True: + notification_sample_env.AppendUnique(CPPPATH = ['../../src/consumer']) + notification_sample_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD']) + CONSUMER_CLOUD = File('cloud_connector.c') + notification_sample_consumer_src = ['notificationconsumer.c', CONSUMER_CLOUD] + +if env.get('WITH_TCP') == True: + notification_sample_env.AppendUnique(CPPDEFINES = ['WITH_TCP']) + + + #################################################################### # Source files and Targets ###################################################################### @@ -53,5 +65,5 @@ i_notificationprovider = notification_sample_provider_env.Install(env.get('BUILD notification_sample_consumer_env = notification_sample_env.Clone() notification_sample_consumer_env.AppendUnique(LIBS = 'libnotification_consumer') -notificationconsumer = notification_sample_consumer_env.Program('notificationconsumer', 'notificationconsumer.c') +notificationconsumer = notification_sample_consumer_env.Program('notificationconsumer', notification_sample_consumer_src) i_notificationprovider = notification_sample_consumer_env.Install(env.get('BUILD_DIR'), notificationconsumer) diff --git a/service/notification/examples/linux/cloud_connector.c b/service/notification/examples/linux/cloud_connector.c new file mode 100644 index 0000000..1312ff3 --- /dev/null +++ b/service/notification/examples/linux/cloud_connector.c @@ -0,0 +1,292 @@ +//****************************************************************** +// +// Copyright 2016 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 "cloud_connector.h" + +#include +#include + +#include "oic_string.h" +#include "oic_malloc.h" + +#include "ocpayload.h" + +#include "rdpayload.h" + +#define OC_RD_PUBLISH_TTL 86400 +#define DEFAULT_CONTEXT_VALUE 0x99 + +#define DEFAULT_COAP_TCP_HOST "coap+tcp://" +#define DEFAULT_COAP_TCP_PORT 5683 + +#define DEFAULT_COAP_TCP_SECURE_HOST "coaps+tcp://" +#define DEFAULT_COAP_TCP_SECURE_PORT 5864 + +#define DEFAULT_AUTH_REGISTER_LOGIN "/oic/auth/?reqtype=register" +#define DEFAULT_AUTH_LOGIN "/oic/auth/?reqtype=login" +#define DEFAULT_AUTH_LOGOUT "/oic/auth/?reqtype=logout" + +static OCStackResult createStringLL(uint8_t numElements, OCResourceHandle handle, + const char *(*getValue)(OCResourceHandle handle, uint8_t i), OCStringLL **stringLL) +{ + for (uint8_t i = 0; i < numElements; ++i) + { + const char *value = getValue(handle, i); + if (!*stringLL) + { + *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); + if (!*stringLL) + { + return OC_STACK_NO_MEMORY; + } + (*stringLL)->value = OICStrdup(value); + if (!(*stringLL)->value) + { + return OC_STACK_NO_MEMORY; + } + } + else + { + OCStringLL *cur = *stringLL; + while (cur->next) + { + cur = cur->next; + } + cur->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); + if (!cur->next) + { + return OC_STACK_NO_MEMORY; + } + cur->next->value = OICStrdup(value); + if (!cur->next->value) + { + return OC_STACK_NO_MEMORY; + } + } + } + return OC_STACK_OK; +} + +OCStackResult OCCloudRegisterLogin(const char *host, const char *auth_provider, + const char *auth_code, OCClientResponseHandler response) +{ + char targetUri[MAX_URI_LENGTH * 2] = { 0, }; + snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, DEFAULT_AUTH_REGISTER_LOGIN); + + OCCallbackData cbData; + memset(&cbData, 0, sizeof(OCCallbackData)); + cbData.cb = response; + cbData.cd = NULL; + cbData.context = (void *)DEFAULT_CONTEXT_VALUE; + + OCRepPayload *registerPayload = OCRepPayloadCreate(); + if (!registerPayload) + { + goto no_memory; + } + + OCRepPayloadSetPropString(registerPayload, "authprovider", auth_provider); + OCRepPayloadSetPropString(registerPayload, "authcode", auth_code); + + return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)registerPayload, + CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0); + +no_memory: + OCRepPayloadDestroy(registerPayload); + return OC_STACK_NO_MEMORY; +} + +OCStackResult OCCloudLoginout(const char *host, const char *query, const char *auth_session, + OCClientResponseHandler response) +{ + char targetUri[MAX_URI_LENGTH * 2] = { 0, }; + snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query); + + OCCallbackData cbData; + memset(&cbData, 0, sizeof(OCCallbackData)); + cbData.cb = response; + cbData.cd = NULL; + cbData.context = (void *)DEFAULT_CONTEXT_VALUE; + + OCRepPayload *loginoutPayload = OCRepPayloadCreate(); + if (!loginoutPayload) + { + goto no_memory; + } + + OCRepPayloadSetPropString(loginoutPayload, "session", auth_session); + + return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)loginoutPayload, + CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0); + +no_memory: + OCRepPayloadDestroy(loginoutPayload); + return OC_STACK_NO_MEMORY; +} + + +OCStackResult OCCloudLogin(const char *host, const char *auth_session, + OCClientResponseHandler response) +{ + return OCCloudLoginout(host, DEFAULT_AUTH_LOGIN, auth_session, response); +} + +OCStackResult OCCloudLogout(const char *host, const char *auth_session, + OCClientResponseHandler response) +{ + return OCCloudLoginout(host, DEFAULT_AUTH_LOGOUT, auth_session, response); +} + +OCStackResult OCCloudPublish(const char *host, const char *query, + OCClientResponseHandler response, int numArg, ...) +{ + char targetUri[MAX_URI_LENGTH * 2] = { 0, }; + snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query); + + // Gather all resources locally and do publish + OCCallbackData cbData; + memset(&cbData, 0, sizeof(OCCallbackData)); + cbData.cb = response; + cbData.cd = NULL; + cbData.context = (void *)DEFAULT_CONTEXT_VALUE; + + OCTagsPayload *tagsPayload = NULL; + OCLinksPayload *linksPayload = NULL; + OCStringLL *rt = NULL; + OCStringLL *itf = NULL; + OCStringLL *mt = NULL; + + OCRDPayload *rdPayload = OCRDPayloadCreate(); + if (!rdPayload) + { + goto no_memory; + } + + const unsigned char *id = (unsigned char *)OCGetServerInstanceIDString(); + tagsPayload = OCCopyTagsResources(NULL, id, + NULL, OC_DISCOVERABLE, 0, 0, NULL, NULL, OC_RD_PUBLISH_TTL); + if (!tagsPayload) + { + goto no_memory; + } + + va_list arguments; + va_start(arguments, numArg); + + for (int j = 0; j < numArg; j++) + { + OCResourceHandle handle = va_arg(arguments, OCResourceHandle); + if (handle) + { + rt = itf = mt = NULL; + const char *uri = OCGetResourceUri(handle); + uint8_t numElement; + if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement)) + { + OCStackResult res = createStringLL(numElement, handle, OCGetResourceTypeName, &rt); + if (res != OC_STACK_OK || !rt) + { + goto no_memory; + } + } + + if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement)) + { + OCStackResult res = createStringLL(numElement, handle, OCGetResourceInterfaceName, &itf); + if (res != OC_STACK_OK || !itf) + { + goto no_memory; + } + } + + mt = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); + if (!mt) + { + goto no_memory; + } + mt->value = OICStrdup("application/cbor"); + if (!mt->value) + { + goto no_memory; + } + + if (!linksPayload) + { + linksPayload = OCCopyLinksResources(uri, rt, itf, NULL, 0, NULL, + NULL, j, mt);; + if (!linksPayload) + { + goto no_memory; + } + } + else + { + OCLinksPayload *temp = linksPayload; + while (temp->next) + { + temp = temp->next; + } + temp->next = OCCopyLinksResources(uri, rt, itf, NULL, 0, NULL, + NULL, j, mt); + if (!temp->next) + { + goto no_memory; + } + } + OCFreeOCStringLL(rt); + OCFreeOCStringLL(itf); + OCFreeOCStringLL(mt); + } + } + va_end(arguments); + + rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload); + if (!rdPayload->rdPublish) + { + goto no_memory; + } + + return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload, + CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0); + +no_memory: + va_end(arguments); + if (rt) + { + OCFreeOCStringLL(rt); + } + if (itf) + { + OCFreeOCStringLL(itf); + } + if (mt) + { + OCFreeOCStringLL(mt); + } + if (tagsPayload) + { + OCFreeTagsResource(tagsPayload); + } + if (linksPayload) + { + OCFreeLinksResource(linksPayload); + } + OCRDPayloadDestroy(rdPayload); + return OC_STACK_NO_MEMORY; +} diff --git a/service/notification/examples/linux/cloud_connector.h b/service/notification/examples/linux/cloud_connector.h new file mode 100644 index 0000000..fbb8821 --- /dev/null +++ b/service/notification/examples/linux/cloud_connector.h @@ -0,0 +1,40 @@ +//****************************************************************** +// +// Copyright 2016 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 "ocstack.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +OCStackResult OCCloudRegisterLogin(const char *host, const char *auth_provider, + const char *auth_code, OCClientResponseHandler response); +OCStackResult OCCloudLogin(const char *host, const char *auth_session, + OCClientResponseHandler response); +OCStackResult OCCloudLogout(const char *host, const char *auth_session, + OCClientResponseHandler response); +OCStackResult OCCloudPublish(const char *host, const char *query, + OCClientResponseHandler response, int numArg, ...); + +#ifdef __cplusplus +} +#endif // __cplusplus + diff --git a/service/notification/examples/linux/notificationconsumer.c b/service/notification/examples/linux/notificationconsumer.c index 029ea02..9d526e7 100644 --- a/service/notification/examples/linux/notificationconsumer.c +++ b/service/notification/examples/linux/notificationconsumer.c @@ -1,9 +1,22 @@ #include - #include + +#include "ocstack.h" #include "NSCommon.h" #include "NSConsumerInterface.h" -#include "ocstack.h" + +#ifdef WITH_CLOUD +#include "NSConstants.h" +#include "NSConsumerCommon.h" +#include "cloud_connector.h" +#include "oic_malloc.h" + +#define CLOUD_CONTEXT_VALUE 0x99 +#define CLOUD_PRESENCE_SUBSCRIBE_QUERY "" // refer to IoTivity Cloud Module Sample + +#define CLOUD_HOST_ADDRESS "" // refer to IoTivity Cloud Module Sample +#define CLOUD_IOTIVITYNS_SESSION "" // refer to IoTivity Cloud Module Sample +#endif void onDiscoverNotification(NSProvider * provider) { @@ -20,7 +33,7 @@ void onSubscriptionAccepted(NSProvider * provider) void onNotificationPosted(NSMessage * notification) { - printf("id : %lu\n", notification->messageId); + printf("id : %lld\n", notification->messageId); printf("title : %s\n", notification->title); printf("content : %s\n", notification->contentText); printf("source : %s\n", notification->sourceName); @@ -29,10 +42,50 @@ void onNotificationPosted(NSMessage * notification) void onNotificationSync(NSSyncInfo * sync) { - printf("Sync ID : %lu\n", sync->messageId); + printf("Sync ID : %lld\n", sync->messageId); printf("Sync STATE : %d\n", sync->state); } +#ifdef WITH_CLOUD +OCStackApplicationResult handleLoginoutCB(void *ctx, + OCDoHandle handle, + OCClientResponse *clientResponse) +{ + (void)handle; + if (ctx != (void *)CLOUD_CONTEXT_VALUE) + { + NS_LOG(DEBUG, "Invalid Login/out callback received"); + } + + NS_LOG(DEBUG, "Login/out response received"); + + if (clientResponse->payload != NULL && + clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION) + { + NS_LOG(DEBUG, "PAYLOAD_TYPE_REPRESENTATION received"); + + OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values; + + while (val) + { + val = val->next; + } + NS_LOG(DEBUG, "Get payload values"); + + OCDevAddr * addr = NULL; + addr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr)); + memcpy(addr, clientResponse->addr, sizeof(OCDevAddr)); + + NSTask * task = NSMakeTask(TASK_EVENT_CONNECTED_TCP, addr); + + NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, OC_STACK_KEEP_TRANSACTION, NSOICFree(addr)); + NSConsumerPushEvent(task); + } + + return OC_STACK_KEEP_TRANSACTION; +} +#endif + int main(void) { @@ -57,6 +110,12 @@ int main(void) printf("error discoverNoti %d\n", ret); } +#ifdef WITH_CLOUD + NS_LOG(DEBUG, "process OCCloudLogin..."); + OCCloudLogin(CLOUD_HOST_ADDRESS, CLOUD_IOTIVITYNS_SESSION, handleLoginoutCB); + NS_LOG(DEBUG, "OCCloudLogin return"); +#endif + while (true) { usleep(2000); -- 2.7.4