From 557cee5f0e8a33285651d97ffe9196fd79bb8cdb Mon Sep 17 00:00:00 2001 From: "arya.k" Date: Wed, 16 Sep 2015 16:37:46 +0530 Subject: [PATCH] RE - Enriched Linux sample application with nested resource attributes. Change-Id: Ieea592f3d490f56de6ab058078dbc1a7f1910a12 Signed-off-by: arya.k Reviewed-on: https://gerrit.iotivity.org/gerrit/2575 Tested-by: jenkins-iotivity Reviewed-by: Madan Lanka --- .../examples/linux/NestedAttributeClient.cpp | 328 ++++++++++++++++++ .../examples/linux/NestedAttributeServer.cpp | 367 +++++++++++++++++++++ .../examples/linux/SConscript | 33 ++ 3 files changed, 728 insertions(+) create mode 100644 service/resource-encapsulation/examples/linux/NestedAttributeClient.cpp create mode 100644 service/resource-encapsulation/examples/linux/NestedAttributeServer.cpp diff --git a/service/resource-encapsulation/examples/linux/NestedAttributeClient.cpp b/service/resource-encapsulation/examples/linux/NestedAttributeClient.cpp new file mode 100644 index 0000000..0de5e53 --- /dev/null +++ b/service/resource-encapsulation/examples/linux/NestedAttributeClient.cpp @@ -0,0 +1,328 @@ +//****************************************************************** +// +// 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 +#include "mutex" +#include "condition_variable" + +#include "RCSDiscoveryManager.h" +#include "RCSRemoteResourceObject.h" +#include "RCSResourceAttributes.h" +#include "RCSAddress.h" + +#include "OCPlatform.h" + +#define nestedAtrribute std::vector> + +using namespace OC; +using namespace OIC::Service; + +constexpr int CORRECT_INPUT = 1; +constexpr int INCORRECT_INPUT = 2; +constexpr int QUIT_INPUT = 3; + +std::shared_ptr resource; + +const std::string defaultKey = "deviceInfo"; +const std::string resourceType = "core.ac"; +const std::string relativetUri = OC_RSRVD_WELL_KNOWN_URI; + +RCSResourceAttributes model; +RCSResourceAttributes speed; +RCSResourceAttributes airCirculation; +RCSResourceAttributes temperature; +RCSResourceAttributes humidity; +RCSResourceAttributes power; +RCSResourceAttributes capacity; +RCSResourceAttributes weight; +RCSResourceAttributes dimensions; +RCSResourceAttributes red; +RCSResourceAttributes green; + +std::vector generalInfo; +std::vector fan; +std::vector tempSensor; +std::vector efficiency; +std::vector light; + + +std::mutex mtx; +std::condition_variable cond; + +void getAttributeFromRemoteServer(); +void setAttributeToRemoteServer(); + +enum Menu +{ + GET_ATTRIBUTE = 1, + SET_ATTRIBUTE, + QUIT, + END_OF_MENU +}; + +typedef void(*ClientMenuHandler)(); +typedef int ReturnValue; + +struct ClientMenu +{ + Menu m_menu; + ClientMenuHandler m_handler; + ReturnValue m_result; +}; + +ClientMenu clientMenu[] = +{ + {Menu::GET_ATTRIBUTE, getAttributeFromRemoteServer, CORRECT_INPUT}, + {Menu::SET_ATTRIBUTE, setAttributeToRemoteServer, CORRECT_INPUT}, + {Menu::QUIT, [](){}, QUIT_INPUT}, + {Menu::END_OF_MENU, nullptr, INCORRECT_INPUT} +}; + +void displayMenu() +{ + std::cout << std::endl; + std::cout << "1 :: Get Attribute" << std::endl; + std::cout << "2 :: Set Attribute" << std::endl; +} + +void onResourceDiscovered(std::shared_ptr foundResource) +{ + std::cout << "onResourceDiscovered callback" << std::endl; + + std::string resourceURI = foundResource->getUri(); + std::string hostAddress = foundResource->getAddress(); + + std::cout << "\t\tResource URI : " << resourceURI << std::endl; + std::cout << "\t\tResource Host : " << hostAddress << std::endl; + + resource = foundResource; + + cond.notify_all(); +} + +void onRemoteAttributesReceivedCallback(const RCSResourceAttributes &attributes) +{ + std::cout << "onRemoteAttributesReceivedCallback callback\n" << std::endl; + + if (attributes.empty()) + { + std::cout << "\tAttribute is Empty" << std::endl; + return; + } + + for (const auto & attr : attributes) + { + std::cout << "\tkey : " << attr.key() << "\n\tvalue : " + << attr.value().toString() << std::endl; + std::cout << "=============================================\n" << std::endl; + + OIC::Service::RCSResourceAttributes::Value attrValue = attr.value(); + std::vector< std::vector> attrVector = + attrValue.get>>(); + + for (auto itr = attrVector.begin(); itr != attrVector.end(); ++itr) + { + std::vector attrKeyVector = *itr; + for (auto itrKey = attrKeyVector.begin(); itrKey != attrKeyVector.end(); ++itrKey) + { + for (const auto & attribute : *itrKey) + { + std::cout << "\t" << attribute.key() << " : " << attribute.value().toString() << std::endl; + } + } + std::cout << std::endl; + } + } + std::cout << "=============================================\n" << std::endl; + displayMenu(); +} + +nestedAtrribute createNestedAttribute(int speedValue, int aircValue) +{ + nestedAtrribute *acServer = new nestedAtrribute(); + + model["model"] = "SamsungAC"; + + speed["speed"] = speedValue; + airCirculation["air"] = aircValue; + + temperature["temp"] = 30; + humidity["humidity"] = 30; + + power["power"] = 1600; + capacity["capacity"] = 1; + + weight["weight"] = 3; + dimensions["dimensions"] = "10x25x35"; + + red["red"] = 50; + green["green"] = 60; + + generalInfo.clear(); + generalInfo.push_back(model); + generalInfo.push_back(weight); + generalInfo.push_back(dimensions); + + fan.clear(); + fan.push_back(speed); + fan.push_back(airCirculation); + + tempSensor.clear(); + tempSensor.push_back(temperature); + tempSensor.push_back(humidity); + + efficiency.clear(); + efficiency.push_back(power); + efficiency.push_back(capacity); + + light.clear(); + light.push_back(red); + light.push_back(green); + + if (nullptr == acServer) + { + std::cout << "Null nestedAtrribute" << std::endl; + } + else + { + acServer->push_back(generalInfo); + acServer->push_back(fan); + acServer->push_back(tempSensor); + acServer->push_back(efficiency); + acServer->push_back(light); + } + + return *acServer; +} + +int processUserInput() +{ + int userInput; + std::cin >> userInput; + if (std::cin.fail()) + { + std::cin.clear(); + std::cin.ignore(std::numeric_limits::max(), '\n'); + return -1; + } + return userInput; +} + +void getAttributeFromRemoteServer() +{ + if(nullptr == resource) + return; + + resource->getRemoteAttributes(&onRemoteAttributesReceivedCallback); +} + +void setAttributeToRemoteServer() +{ + if(nullptr == resource) + return; + + int speed, airc; + + std::cout << "\tEnter the Fan Speed you want to set : "; + std::cin >> speed; + std::cout << "\tEnter the Air circulation value you want to set :"; + std::cin >> airc; + + nestedAtrribute nestedAttr = createNestedAttribute(speed, airc); + + RCSResourceAttributes setAttribute; + setAttribute[defaultKey] = nestedAttr; + + resource->setRemoteAttributes(setAttribute, + &onRemoteAttributesReceivedCallback); +} + +int selectClientMenu(int selectedMenu) +{ + for (int i = 0; clientMenu[i].m_menu != Menu::END_OF_MENU; i++) + { + if (clientMenu[i].m_menu == selectedMenu) + { + clientMenu[i].m_handler(); + return clientMenu[i].m_result; + } + } + + std::cout << "Invalid input, please try again" << std::endl; + + return INCORRECT_INPUT; +} + +void process() +{ + while (true) + { + displayMenu(); + + if (selectClientMenu(processUserInput()) == QUIT_INPUT) + break; + } +} + +void platFormConfigure() +{ + PlatformConfig config + { + OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos + }; + OCPlatform::Configure(config); +} + +bool discoverResource() +{ + std::cout << "Wait 2 seconds until discovered." << std::endl; + + RCSDiscoveryManager::getInstance()->discoverResourceByType(RCSAddress::multicast(), + relativetUri, resourceType, &onResourceDiscovered); + + std::unique_lock lck(mtx); + cond.wait_for(lck, std::chrono::seconds(2)); + + return resource != nullptr; +} + +int main() +{ + platFormConfigure(); + + if (!discoverResource()) + { + std::cout << "Can't discovered Server... Exiting the Client." << std::endl; + return -1; + } + + try + { + process(); + } + catch (const std::exception &e) + { + std::cout << "main exception : " << e.what() << std::endl; + } + + std::cout << "Stopping the Client" << std::endl; + + return 0; +} diff --git a/service/resource-encapsulation/examples/linux/NestedAttributeServer.cpp b/service/resource-encapsulation/examples/linux/NestedAttributeServer.cpp new file mode 100644 index 0000000..ba1383b --- /dev/null +++ b/service/resource-encapsulation/examples/linux/NestedAttributeServer.cpp @@ -0,0 +1,367 @@ +/****************************************************************** + * + * 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 "PrimitiveResource.h" +#include "RCSResourceObject.h" +#include "OCPlatform.h" +#include "OCApi.h" + +#define nestedAtrribute std::vector> + +using namespace OC; +using namespace OC::OCPlatform; +using namespace OIC::Service; + +constexpr int DEFAULT_SPEED = 30; +constexpr int UP_SPEED = 50; +constexpr int DOWN_SPEED = 10; + +constexpr int DEFALUT_SERVER = 1; +constexpr int CUSTOM_SERVER = 2; +constexpr int STOP = 3; + +constexpr int PRINT_ATTRIBUTES = 1; +constexpr int INCREASE_SPEEDATTRIBUTE = 2; +constexpr int DECREASE_SPEEDATTRIBUTE = 3; +constexpr int STOP_SENSOR = 4; + +constexpr int CORRECT_INPUT = 1; +constexpr int INCORRECT_INPUT = 2; +constexpr int QUIT = 3; + +std::string resourceUri = "/a/airConditioner"; +std::string resourceType = "core.ac"; +std::string resourceInterface = "oic.if."; +std::string attributeKey = "deviceInfo"; + +RCSResourceAttributes model; +RCSResourceAttributes speed; +RCSResourceAttributes airCirculation; +RCSResourceAttributes temperature; +RCSResourceAttributes humidity; +RCSResourceAttributes power; +RCSResourceAttributes capacity; +RCSResourceAttributes weight; +RCSResourceAttributes dimensions; +RCSResourceAttributes red; +RCSResourceAttributes green; + +std::vector generalInfo; +std::vector fan; +std::vector tempSensor; +std::vector efficiency; +std::vector light; + +RCSResourceObject::Ptr server; + +void displayMenu() +{ + std::cout << "=====================================================================" + << std::endl; + std::cout << " 1 - Creation of Resource [Auto control for requests]" << std::endl; + std::cout << " 2 - Creation of Resource [Developer control for Get and Set requests]" + << std::endl; + std::cout << " 3 - Quit" << std::endl; + std::cout << "=====================================================================" + << std::endl; +} + +void displayControlMenu() +{ + std::cout << "========================================================" << std::endl; + std::cout << "1. Print Nested attributes" << std::endl; + std::cout << "2. Increase Speed attributes" << std::endl; + std::cout << "3. Decrease Speed attributes" << std::endl; + std::cout << "4. Stop the Sensor" << std::endl; + std::cout << "========================================================" << std::endl; +} + +nestedAtrribute createNestedAttribute(int speedValue) +{ + nestedAtrribute *acServer = new nestedAtrribute(); + + model["model"] = "SamsungAC"; + + speed["speed"] = speedValue; + airCirculation["air"] = 425; + + temperature["temp"] = 30; + humidity["humidity"] = 30; + + power["power"] = 1600; + capacity["capacity"] = 1; + + weight["weight"] = 3; + dimensions["dimensions"] = "10x25x35"; + + red["red"] = 50; + green["green"] = 60; + + generalInfo.clear(); + generalInfo.push_back(model); + generalInfo.push_back(weight); + generalInfo.push_back(dimensions); + + fan.clear(); + fan.push_back(speed); + fan.push_back(airCirculation); + + tempSensor.clear(); + tempSensor.push_back(temperature); + tempSensor.push_back(humidity); + + efficiency.clear(); + efficiency.push_back(power); + efficiency.push_back(capacity); + + light.clear(); + light.push_back(red); + light.push_back(green); + + if (nullptr == acServer) + { + std::cout << "Null nestedAtrribute" << std::endl; + } + else + { + acServer->push_back(generalInfo); + acServer->push_back(fan); + acServer->push_back(tempSensor); + acServer->push_back(efficiency); + acServer->push_back(light); + } + + return *acServer; +} + +void printAttribute(const RCSResourceAttributes &attrs) +{ + for (const auto & attr : attrs) + { + std::cout << "\tkey : " << attr.key() << "\n\tvalue : " + << attr.value().toString() << std::endl; + std::cout << "=============================================\n" << std::endl; + + OIC::Service::RCSResourceAttributes::Value attrValue = attr.value(); + std::vector< std::vector> attrVector = + attrValue.get>>(); + + for (auto itr = attrVector.begin(); itr != attrVector.end(); ++itr) + { + std::vector attrKeyVector = *itr; + for (auto itrKey = attrKeyVector.begin(); itrKey != attrKeyVector.end(); ++itrKey) + { + for (const auto & attribute : *itrKey) + { + std::cout << "\t" << attribute.key() << " : " << attribute.value().toString() << std::endl; + } + } + std::cout << std::endl; + } + std::cout << "=============================================\n" << std::endl; + } +} + +void printNestedAttribute() +{ + RCSResourceObject::LockGuard lock(*server); + RCSResourceAttributes attributes = server->getAttributes(); + + std::cout << "\nPrinting nested attributes" << std::endl; + printAttribute(attributes); + return; +} + +void changeSpeedAttribute(int state) +{ + nestedAtrribute attr; + + if (INCREASE_SPEEDATTRIBUTE == state) + { + std::cout << "Increasing speed attribute to : " << UP_SPEED << std::endl; + attr = createNestedAttribute(UP_SPEED); + } + else if (DECREASE_SPEEDATTRIBUTE == state) + { + std::cout << "Decreasing speed attribute to : " << DOWN_SPEED << std::endl; + attr = createNestedAttribute(DOWN_SPEED); + } + + RCSResourceObject::LockGuard lock(*server); + server->getAttributes()[attributeKey] = attr; + printNestedAttribute(); +} + +//hander for get request (if developer choose second option for resource Creation) +RCSGetResponse requestHandlerForGet(const RCSRequest &request, + RCSResourceAttributes &attrs) +{ + std::cout << "Recieved a Get request from Client" << std::endl; + + RCSResourceObject::LockGuard lock(*server); + RCSResourceAttributes attributes = server->getAttributes(); + + std::cout << "\nSending response to Client : " << std::endl; + printAttribute(attributes); + + return RCSGetResponse::defaultAction(); +} + +//hander for set request (if developer choose second option for resource Creation) +RCSSetResponse requestHandlerForSet(const RCSRequest &request, + RCSResourceAttributes &attrs) +{ + std::cout << "Recieved a Set request from Client" << std::endl; + + std::cout << "\n\nSending response to Client : " << std::endl; + RCSResourceObject::LockGuard lock(*server); + printAttribute(attrs); + return RCSSetResponse::defaultAction(); +} + +void createResource() +{ + server = RCSResourceObject::Builder(resourceUri, resourceType, + resourceInterface).setDiscoverable(true).setObservable(true).build(); +} + +void initServer() +{ + try + { + createResource(); + } + catch (const PlatformException &e) + { + std::cout << "Exception in initServer : " << e.what() << std::endl; + } + + if (nullptr == server) + { + std::cout << "Null server resource" << std::endl; + return; + } + + server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED); + server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER); + + nestedAtrribute attr = createNestedAttribute(DEFAULT_SPEED); + server->setAttribute(attributeKey, attr); +} + +int processUserInput() +{ + int userInput; + std::cin >> userInput; + if (std::cin.fail()) + { + std::cin.clear(); + std::cin.ignore(std::numeric_limits::max(), '\n'); + return -1; + } + return userInput; +} + +int selectControlMenu() +{ + switch (processUserInput()) + { + case PRINT_ATTRIBUTES: + printNestedAttribute(); + return CORRECT_INPUT; + + case INCREASE_SPEEDATTRIBUTE: + changeSpeedAttribute(INCREASE_SPEEDATTRIBUTE); + return CORRECT_INPUT; + + case DECREASE_SPEEDATTRIBUTE: + changeSpeedAttribute(DECREASE_SPEEDATTRIBUTE); + return CORRECT_INPUT; + + case STOP_SENSOR: + return QUIT; + + default: + std::cout << "Invalid input. Please try again." << std::endl; + return INCORRECT_INPUT; + } +} + +int selectServerMenu() +{ + switch (processUserInput()) + { + case DEFALUT_SERVER: // Creation of Resource & Auto control for all requests from Client. + initServer(); + return CORRECT_INPUT; + + case CUSTOM_SERVER: + // Creation of Resource & setting get and set handler for handling get and + // set request from client in application. + initServer(); + + server->setGetRequestHandler(requestHandlerForGet); + server->setSetRequestHandler(requestHandlerForSet); + return CORRECT_INPUT; + case STOP : + return QUIT; + + default : + std::cout << "Invalid input, please try again" << std::endl; + return INCORRECT_INPUT; + } +} + +void process() +{ + while (true) + { + displayMenu(); + + int ret = selectServerMenu(); + + if (ret == QUIT) return; + if (ret == CORRECT_INPUT) break; + } + + while (true) + { + displayControlMenu(); + + if (selectControlMenu() == QUIT) return; + } +} + +int main(void) +{ + startPresence(3); + + try + { + process(); + server = NULL; + } + catch (const std::exception &e) + { + std::cout << "main exception : " << e.what() << std::endl; + } + + std::cout << "Stopping the Server" << std::endl; +} diff --git a/service/resource-encapsulation/examples/linux/SConscript b/service/resource-encapsulation/examples/linux/SConscript index 0ea8989..e80012d 100644 --- a/service/resource-encapsulation/examples/linux/SConscript +++ b/service/resource-encapsulation/examples/linux/SConscript @@ -29,6 +29,8 @@ SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env') ResourceClient_env = lib_env.Clone() ResourceServer_env = lib_env.Clone() +NestedAttributeServer_env = lib_env.Clone() +NestedAttributeClient_env = lib_env.Clone() ###################################################################### # ##### Resource Client ##### @@ -42,6 +44,17 @@ ResourceClient_env.AppendUnique(CPPPATH = ['../../src/resourceCache/include']) ResourceClient_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include']) ###################################################################### +# ##### Nested Attribute Client ##### +###################################################################### + +NestedAttributeClient_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x']) +NestedAttributeClient_env.AppendUnique(LIBS = ['rcs_client', 'rcs_common','oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread']) +NestedAttributeClient_env.AppendUnique(CPPPATH = ['../../include']) +NestedAttributeClient_env.AppendUnique(CPPPATH = ['../../src/resourceBroker/include']) +NestedAttributeClient_env.AppendUnique(CPPPATH = ['../../src/resourceCache/include']) +NestedAttributeClient_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include']) + +###################################################################### # ##### Resource Server ##### ###################################################################### @@ -51,20 +64,40 @@ ResourceServer_env.AppendUnique(CPPPATH = ['../../include']) ResourceServer_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include']) ResourceServer_env.AppendUnique(CPPPATH = ['../../src/serverBuilder/include']) +###################################################################### +# ##### Nested Attribute Server ##### +###################################################################### + +NestedAttributeServer_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x']) +NestedAttributeServer_env.AppendUnique(LIBS = ['rcs_server', 'rcs_common','oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap', 'pthread']) +NestedAttributeServer_env.AppendUnique(CPPPATH = ['../../include']) +NestedAttributeServer_env.AppendUnique(CPPPATH = ['../../src/common/primitiveResource/include']) +NestedAttributeServer_env.AppendUnique(CPPPATH = ['../../src/serverBuilder/include']) + if env.get('SECURED') == '1': ResourceClient_env.AppendUnique(LIBS = ['tinydtls']) + NestedAttributeClient_env.AppendUnique(LIBS = ['tinydtls']) ResourceServer_env.AppendUnique(LIBS = ['tinydtls']) + NestedAttributeServer_env.AppendUnique(LIBS = ['tinydtls']) if 'rt' in ResourceClient_env.get('LIBS'): ResourceClient_env.Append(LIBS = ['rt']) +if 'rt' in NestedAttributeClient_env.get('LIBS'): + NestedAttributeClient_env.Append(LIBS = ['rt']) if 'rt' in ResourceServer_env.get('LIBS'): ResourceServer_env.Append(LIBS = ['rt']) +if 'rt' in NestedAttributeServer_env.get('LIBS'): + NestedAttributeServer_env.Append(LIBS = ['rt']) #################################################################### # Source files and Targets #################################################################### sampleResourceClient = ResourceClient_env.Program('sampleResourceClient', 'SampleResourceClient.cpp') +nestedAttributeClient = NestedAttributeClient_env.Program('nestedAttributeClient', 'NestedAttributeClient.cpp') sampleResourceServer = ResourceServer_env.Program('sampleResourceServer', 'SampleResourceServer.cpp') +nestedAttributeServer = NestedAttributeServer_env.Program('nestedAttributeServer', 'NestedAttributeServer.cpp') ResourceClient_env.InstallTarget(sampleResourceClient, 'sampleResourceClient') +NestedAttributeClient_env.InstallTarget(nestedAttributeClient, 'nestedAttributeClient') ResourceServer_env.InstallTarget(sampleResourceServer, 'sampleResourceServer') +NestedAttributeServer_env.InstallTarget(nestedAttributeServer, 'nestedAttributeServer') -- 2.7.4