diff options
Diffstat (limited to 'service/things-manager')
39 files changed, 10026 insertions, 0 deletions
diff --git a/service/things-manager/.gitignore b/service/things-manager/.gitignore new file mode 100644 index 000000000..e3c5f74fa --- /dev/null +++ b/service/things-manager/.gitignore @@ -0,0 +1,38 @@ +IDE/VS2010_TEST/Simulator/Debug/ +IDE/VS2010_TEST/GroupManager/Debug/ +IDE/VS2010_TEST/Debug/ +IDE/VS2010_TEST/GroupManager/GroupManager.sdf +IDE/VS2010_TEST/GroupManager/GroupManager.sln.docstates.suo +IDE/VS2010_TEST/Simulation.opensdf +IDE/VS2010_TEST/Simulation.sln.docstates.suo +IDE/VS2010_TEST/Simulation.suo +IDE/VS2010_TEST/Simulationv11.sln +IDE/VS2010_TEST/Simulator/Simulator.vcxproj.user +IDE/VS2010_TEST/ipch/groupmanager-b37860cb/2.ipch +IDE/VS2010_TEST/ipch/simulator-d2ec10fb/1.ipch +IDE/VS2010_TEST/Simulation.sdf +IDE/VS2010_TEST/ipch/ +*.ipch +IDE/VS2010_TEST/GroupManager/GroupManager.vcxproj.user + + + +IDE/VS2010/GroupManager/GroupManager.vcxproj.user +TestApp/InProcClientWrapper.o +TestApp/InProcServerWrapper.o +TestApp/OCLib.a +TestApp/OCPlatform.o +TestApp/OCReflect.o +TestApp/OCResource.o +TestApp/tgmclient +TestApp/tgmclient.o +TestApp/tgmserver +TestApp/tgmserver.o +SourceCode/tgmtest +IDE/LINUX_TEST/tgmtest +inc4.7/ +.settings/ +.cproject +.project +TestApp/introspection/tgmclient +TestApp/introspection/introspectionServer
\ No newline at end of file diff --git a/service/things-manager/Readme.txt b/service/things-manager/Readme.txt new file mode 100755 index 000000000..15cb473ab --- /dev/null +++ b/service/things-manager/Readme.txt @@ -0,0 +1,83 @@ +/****************************************************************** +* +* Copyright 2014 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. +* +******************************************************************/ + + +=============================================================================== +== How to Build Things Manager == +=============================================================================== + +Once the source code is downloaded in your local specific folder, you may follow +the steps to build and execute Things Manager and its applications. +In this context, we assume that the code was downloaded into 'oic' folder. + +======================================= +1. Download source code +======================================= + +From the url, you can download Things Manager source code; +https://www.iotivity.org/downloads + +Once you download the codes, and Make sure that the downloaded code structure is as follows; +Four directories for oic; extlib, resource, service, and tools. + +oic/extlib +oic/resource +oic/service +oic/tools + +The path for Things Manager is as following; + +oic/service/things-manager + +The things-manager directory includes following sub directories; + +Directories Description +oic/service/things-manager/sdk : The SDK APIs for applications is located. + The main functionality of this SDK is to provide + developer-friendly APIs of Things manager component + to application developers. +oic/service/things-manager/sampleapp : It is the sample application on Ubuntu. + Basically, the input and output of application + on Ubuntu are displayed in the console. +oic/service/things-manager/build : Whole library files and binary files would be made + in this folder + + + +======================================= +2. Build +======================================= +Simply, type "make" to build things manager as follows; + +/oic/service/things-manager/build/linux$ make + +======================================= +3. Build the API reference documentation +======================================= +To build the API reference documentation: +a. Navigate to oic-resource/docs folder using the terminal window. +b. Run the following command: + + $ doxygen + +This command builds the API reference documentation in the output directory. + +The output directory for this command is oic-resource/docs/html/index.html. + diff --git a/service/things-manager/SConscript b/service/things-manager/SConscript new file mode 100644 index 000000000..412907ce1 --- /dev/null +++ b/service/things-manager/SConscript @@ -0,0 +1,35 @@ +## +# things_manager project build script +## + +Import('env') + +# Add third party libraries +lib_env = env.Clone() +SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env') + +things_manager_env = lib_env.Clone() +target_os = env.get('TARGET_OS') +###################################################################### +# Build flags +###################################################################### +things_manager_env.AppendUnique(CPPPATH = ['sdk/inc', 'sdk/src']) + +if target_os not in ['windows', 'winrt']: + things_manager_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall']) + if target_os != 'android': + things_manager_env.AppendUnique(CXXFLAGS = ['-pthread']) + +if target_os == 'android': + things_manager_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions']) + +###################################################################### +# Source files and Targets +###################################################################### +tgm_src = env.Glob('sdk/src/*.cpp') +tgmsdk = things_manager_env.StaticLibrary('TGMSDKLibrary', tgm_src) + +things_manager_env.InstallTarget(tgmsdk, 'libTGMSDK') + +#Go to build sample apps +SConscript('sampleapp/SConscript') diff --git a/service/things-manager/build/linux/makefile b/service/things-manager/build/linux/makefile new file mode 100644 index 000000000..4fc7d7e20 --- /dev/null +++ b/service/things-manager/build/linux/makefile @@ -0,0 +1,32 @@ +.PHONY : pre resource sdk sampleapp +#.PHONY : lib tgm sdk sampleapp +all: .PHONY + +pre: + -mkdir release + +resource: + cd ../../../../resource && $(MAKE) + + +sdk: + cd ../../sdk/build/linux && $(MAKE) + cp -Rdp ../../sdk/build/linux/*.a release/ + +sampleapp: + cd ../../sampleapp/linux && $(MAKE) + cp -Rdp ../../sampleapp/linux/configuration/con-server release/ + cp -Rdp ../../sampleapp/linux/configuration/con-client release/ + cp -Rdp ../../sampleapp/linux/configuration/bootstrapserver release/ + cp -Rdp ../../sampleapp/linux/groupaction/groupserver release/ + cp -Rdp ../../sampleapp/linux/groupaction/bookmark release/ + cp -Rdp ../../sampleapp/linux/groupaction/lightserver release/ + cp -Rdp ../../sampleapp/linux/groupsyncaction/group release/ + cp -Rdp ../../sampleapp/linux/groupsyncaction/musicplayer release/ + cp -Rdp ../../sampleapp/linux/groupsyncaction/phone release/ + cp -Rdp ../../sampleapp/linux/groupsyncaction/speaker release/ + +clean: + cd ../../sdk/build/linux && $(MAKE) clean + cd ../../sampleapp/linux && $(MAKE) clean + rm -rf ./release diff --git a/service/things-manager/sampleapp/SConscript b/service/things-manager/sampleapp/SConscript new file mode 100644 index 000000000..7fe88ad57 --- /dev/null +++ b/service/things-manager/sampleapp/SConscript @@ -0,0 +1,24 @@ +## +# sampleapp build script +## + +Import('env') + +# Add third party libraries +lib_env = env.Clone() +SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env') +sample_env = lib_env.Clone() +target_os = env.get('TARGET_OS') + +###################################################################### +# Build flags +###################################################################### + +###################################################################### +# Source files and Targets +###################################################################### +if target_os == 'linux' : + # Build linux sample app + SConscript('linux/configuration/SConscript') + SConscript('linux/groupaction/SConscript') + SConscript('linux/groupsyncaction/SConscript') diff --git a/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.cpp b/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.cpp new file mode 100644 index 000000000..7ee28d19c --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.cpp @@ -0,0 +1,591 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample shows how one could create a resource (collection) with children. +/// + +#include <functional> +#include <thread> + +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" +#include "ConfigurationCollection.h" + +using namespace OC; + +/// This function internally calls registerResource API. +void ConfigurationCollection::createResources(ResourceEntityHandler callback) +{ + using namespace OC::OCPlatform; + + if (callback == NULL) + { + std::cout << "callback should be binded\t"; + return; + } + + // This will internally create and register the resource. + OCStackResult result = registerResource(m_configurationHandle, m_configurationUri, + m_configurationTypes[0], m_configurationInterfaces[0], callback, + OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (configuration) was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_configurationHandle, m_configurationInterfaces[1]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_configurationHandle, m_configurationInterfaces[2]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = registerResource(m_regionHandle, m_regionUri, m_regionTypes[0], m_regionInterfaces[0], + callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (region) was unsuccessful\n"; + } + + result = registerResource(m_timeHandle, m_timeUri, m_timeTypes[0], m_timeInterfaces[0], + callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (time) was unsuccessful\n"; + } + + result = registerResource(m_networkHandle, m_networkUri, m_networkTypes[0], + m_networkInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (network) was unsuccessful\n"; + } + + result = registerResource(m_securityHandle, m_securityUri, m_securityTypes[0], + m_securityInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (security) was unsuccessful\n"; + } + + result = bindResource(m_configurationHandle, m_regionHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding region resource to room was unsuccessful\n"; + } + + result = bindResource(m_configurationHandle, m_timeHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding time resource to room was unsuccessful\n"; + } + + result = bindResource(m_configurationHandle, m_networkHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding network resource to room was unsuccessful\n"; + } + + result = bindResource(m_configurationHandle, m_securityHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding security resource to room was unsuccessful\n"; + } + + std::cout << "Configuration Collection is Created!(URI: " << m_configurationUri << ") \n"; + + myTimeCollection->createResources(callback); + myNetworkCollection->createResources(callback); + mySecurityCollection->createResources(callback); + +} + +void ConfigurationCollection::setConfigurationRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_configurationValue = value; + + std::cout << "\t\t\t\t" << "m_configurationValue: " << m_configurationValue << std::endl; + } +} + +void ConfigurationCollection::setTimeRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("link", value)) + { + // NOT ALLOWED + + std::cout << "\t\t\t\t" << "link: " << m_timeLink << std::endl; + } +} + +void ConfigurationCollection::setNetworkRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("link", value)) + { + // NOT ALLOWED + + std::cout << "\t\t\t\t" << "link: " << m_networkLink << std::endl; + } +} + +void ConfigurationCollection::setSecurityRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("link", value)) + { + // NOT ALLOWED + + std::cout << "\t\t\t\t" << "link: " << m_securityLink << std::endl; + } +} + +void ConfigurationCollection::setRegionRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_regionValue = value; + + std::cout << "\t\t\t\t" << "value: " << m_regionValue << std::endl; + } +} + +OCRepresentation ConfigurationCollection::getTimeRepresentation() +{ + m_timeRep.setValue("link", m_timeLink); + + return m_timeRep; +} + +OCRepresentation ConfigurationCollection::getNetworkRepresentation() +{ + m_networkRep.setValue("link", m_networkLink); + + return m_networkRep; +} + +OCRepresentation ConfigurationCollection::getSecurityRepresentation() +{ + m_securityRep.setValue("link", m_securityLink); + + return m_securityRep; +} + +OCRepresentation ConfigurationCollection::getRegionRepresentation() +{ + m_regionRep.setValue("value", m_regionValue); + + return m_regionRep; +} + +OCRepresentation ConfigurationCollection::getConfigurationRepresentation() +{ + m_configurationRep.clearChildren(); + + m_configurationRep.addChild(getRegionRepresentation()); + m_configurationRep.addChild(getTimeRepresentation()); + m_configurationRep.addChild(getNetworkRepresentation()); + m_configurationRep.addChild(getSecurityRepresentation()); + + m_configurationRep.setValue("value", m_configurationValue); + + return m_configurationRep; +} + +std::string ConfigurationCollection::getConfigurationUri() +{ + return m_configurationUri; +} + +std::string ConfigurationCollection::getTimeUri() +{ + return m_timeUri; +} + +std::string ConfigurationCollection::getNetworkUri() +{ + return m_networkUri; +} + +std::string ConfigurationCollection::getSecurityUri() +{ + return m_securityUri; +} + +std::string ConfigurationCollection::getRegionUri() +{ + return m_regionUri; +} + +void ConfigurationCollection::factoryReset() +{ + m_configurationValue = defaultConfigurationValue; + m_regionValue = defaultRegionValue; + m_timeLink = defaultTimeLink; + m_networkLink = defaultNetworkLink; + m_securityLink = defaultSecurityLink; + + myTimeCollection->factoryReset(); + myNetworkCollection->factoryReset(); + mySecurityCollection->factoryReset(); +} + +/// This function internally calls registerResource API. +void TimeCollection::createResources(ResourceEntityHandler callback) +{ + using namespace OC::OCPlatform; + + if (callback == NULL) + { + std::cout << "callback should be binded\t"; + return; + } + + // This will internally create and register the resource. + OCStackResult result = registerResource(m_timeHandle, m_timeUri, m_timeTypes[0], + m_timeInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (time) was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_timeHandle, m_timeInterfaces[1]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_timeHandle, m_timeInterfaces[2]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = registerResource(m_currentTimeHandle, m_currentTimeUri, m_currentTimeTypes[0], + m_currentTimeInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (currentTime) was unsuccessful\n"; + } + + result = bindResource(m_timeHandle, m_currentTimeHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding currentTime resource to room was unsuccessful\n"; + } + + std::cout << "Time Collection is Created!(URI: " << m_timeUri << ") \n"; +} + +void TimeCollection::setTimeRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_timeValue = value; + + std::cout << "\t\t\t\t" << "m_timeValue: " << m_timeValue << std::endl; + } +} + +void TimeCollection::setCurrentTimeRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("currentTime", value)) + { + m_currentTimeValue = value; + + std::cout << "\t\t\t\t" << "value: " << m_currentTimeValue << std::endl; + } +} + +OCRepresentation TimeCollection::getCurrentTimeRepresentation() +{ + m_currentTimeRep.setValue("value", m_currentTimeValue); + + return m_currentTimeRep; +} + +OCRepresentation TimeCollection::getTimeRepresentation() +{ + m_timeRep.clearChildren(); + + m_timeRep.addChild(getCurrentTimeRepresentation()); + + m_timeRep.setValue("value", m_timeValue); + + return m_timeRep; +} + +std::string TimeCollection::getTimeUri() +{ + return m_timeUri; +} + +std::string TimeCollection::getCurrentTimeUri() +{ + return m_currentTimeUri; +} + +void TimeCollection::factoryReset() +{ + m_timeValue = defaultTimeValue; + m_currentTimeValue = defaultCurrentTimeValue; +} + +/// This function internally calls registerResource API. +void NetworkCollection::createResources(ResourceEntityHandler callback) +{ + using namespace OC::OCPlatform; + + if (callback == NULL) + { + std::cout << "callback should be binded\t"; + return; + } + + // This will internally create and register the resource. + OCStackResult result = registerResource(m_networkHandle, m_networkUri, m_networkTypes[0], + m_networkInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (network) was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_networkHandle, m_networkInterfaces[1]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_networkHandle, m_networkInterfaces[2]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = registerResource(m_IPAddressHandle, m_IPAddressUri, m_IPAddressTypes[0], + m_IPAddressInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (IPAddress) was unsuccessful\n"; + } + + result = bindResource(m_networkHandle, m_IPAddressHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding IPAddress resource to room was unsuccessful\n"; + } + + std::cout << "Network Collection is Created!(URI: " << m_networkUri << ") \n"; +} + +void NetworkCollection::setNetworkRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_networkValue = value; + + std::cout << "\t\t\t\t" << "m_networkValue: " << m_networkValue << std::endl; + } +} + +void NetworkCollection::setIPAddressRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("IPAddress", value)) + { + m_IPAddressValue = value; + + std::cout << "\t\t\t\t" << "value: " << m_IPAddressValue << std::endl; + } +} +OCRepresentation NetworkCollection::getIPAddressRepresentation() +{ + m_IPAddressRep.setValue("value", m_IPAddressValue); + + return m_IPAddressRep; +} + +OCRepresentation NetworkCollection::getNetworkRepresentation() +{ + m_networkRep.clearChildren(); + + m_networkRep.addChild(getIPAddressRepresentation()); + + m_networkRep.setValue("value", m_networkValue); + + return m_networkRep; +} + +std::string NetworkCollection::getNetworkUri() +{ + return m_networkUri; +} + +std::string NetworkCollection::getIPAddressUri() +{ + return m_IPAddressUri; +} + +void NetworkCollection::factoryReset() +{ + m_networkValue = defaultNetworkValue; + m_IPAddressValue = defaultIPAddressValue; +} + +/// This function internally calls registerResource API. +void SecurityCollection::createResources(ResourceEntityHandler callback) +{ + using namespace OC::OCPlatform; + + if (callback == NULL) + { + std::cout << "callback should be binded\t"; + return; + } + + // This will internally create and register the resource. + OCStackResult result = registerResource(m_securityHandle, m_securityUri, m_securityTypes[0], + m_securityInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (security) was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_securityHandle, m_securityInterfaces[1]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_securityHandle, m_securityInterfaces[2]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = registerResource(m_modeHandle, m_modeUri, m_modeTypes[0], m_modeInterfaces[0], + callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (mode) was unsuccessful\n"; + } + + result = bindResource(m_securityHandle, m_modeHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding mode resource to room was unsuccessful\n"; + } + + std::cout << "Security Collection is Created!(URI: " << m_securityUri << ") \n"; +} + +void SecurityCollection::setSecurityRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_securityValue = value; + + std::cout << "\t\t\t\t" << "m_securityValue: " << m_securityValue << std::endl; + } +} + +void SecurityCollection::setModeRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("mode", value)) + { + m_modeValue = value; + + std::cout << "\t\t\t\t" << "value: " << m_modeValue << std::endl; + } +} + +OCRepresentation SecurityCollection::getModeRepresentation() +{ + m_modeRep.setValue("value", m_modeValue); + + return m_modeRep; +} + +OCRepresentation SecurityCollection::getSecurityRepresentation() +{ + m_securityRep.clearChildren(); + + m_securityRep.addChild(getModeRepresentation()); + + m_securityRep.setValue("value", m_securityValue); + + return m_securityRep; +} + +std::string SecurityCollection::getSecurityUri() +{ + return m_securityUri; +} + +std::string SecurityCollection::getModeUri() +{ + return m_modeUri; +} + +void SecurityCollection::factoryReset() +{ + m_securityValue = defaultSecurityValue; + m_modeValue = defaultModeValue; +} + diff --git a/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.h b/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.h new file mode 100644 index 000000000..cbc1db52f --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/ConfigurationCollection.h @@ -0,0 +1,535 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample shows how one could create a resource (collection) with children. +/// + +#include <functional> +#include <thread> + +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" + +#pragma once + +using namespace OC; + +typedef std::function< OCEntityHandlerResult(std::shared_ptr< OCResourceRequest > request) > ResourceEntityHandler; + +static std::string defaultURIPrefix = "/oic/con"; +static std::string defaultResourceTypePrefix = "oic.con"; + +extern std::string defaultTimeValue; +extern std::string defaultCurrentTimeValue; + +class TimeCollection +{ +public: + + // diagnostics members + std::string m_timeUri; + std::string m_timeValue; + std::vector< std::string > m_timeTypes; + std::vector< std::string > m_timeInterfaces; + OCResourceHandle m_timeHandle; + OCRepresentation m_timeRep; + + // factory reset members + std::string m_currentTimeUri; + std::string m_currentTimeValue; + std::vector< std::string > m_currentTimeTypes; + std::vector< std::string > m_currentTimeInterfaces; + OCResourceHandle m_currentTimeHandle; + OCRepresentation m_currentTimeRep; + +public: + /// Constructor + TimeCollection() : + m_timeValue(defaultTimeValue), m_currentTimeValue(defaultCurrentTimeValue) + { + m_currentTimeUri = defaultURIPrefix + "/time/0/currentTime"; // URI of the resource + m_currentTimeTypes.push_back("oic.con.time.currentTime"); // resource type name. + m_currentTimeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_currentTimeRep.setUri(m_currentTimeUri); + m_currentTimeRep.setResourceTypes(m_currentTimeTypes); + m_currentTimeRep.setResourceInterfaces(m_currentTimeInterfaces); + m_currentTimeRep.setValue("value", m_currentTimeValue); + m_currentTimeHandle = NULL; + + m_timeUri = defaultURIPrefix + "/time"; // URI of the resource + m_timeTypes.push_back("oic.con.time"); // resource type name. + m_timeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_timeInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_timeInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_timeRep.setValue("value", m_timeValue); + m_timeRep.setUri(m_timeUri); + m_timeRep.setResourceTypes(m_timeTypes); + m_timeRep.setResourceInterfaces(m_timeInterfaces); + m_timeHandle = NULL; + } + ; + + /// Constructor + TimeCollection(std::string URIPrefix, std::string ResourceTypePrefix) : + m_timeValue(defaultTimeValue), m_currentTimeValue(defaultCurrentTimeValue) + { + m_currentTimeUri = URIPrefix + "/time/0/currentTime"; // URI of the resource + m_currentTimeTypes.push_back(ResourceTypePrefix + ".time.currentTime"); // type name. + m_currentTimeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_currentTimeRep.setUri(m_currentTimeUri); + m_currentTimeRep.setResourceTypes(m_currentTimeTypes); + m_currentTimeRep.setResourceInterfaces(m_currentTimeInterfaces); + m_currentTimeRep.setValue("value", m_currentTimeValue); + m_currentTimeHandle = NULL; + + m_timeUri = URIPrefix + "/time"; // URI of the resource + m_timeTypes.push_back(ResourceTypePrefix + ".time"); // resource type name. + m_timeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_timeInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_timeInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_timeRep.setValue("value", m_timeValue); + m_timeRep.setUri(m_timeUri); + m_timeRep.setResourceTypes(m_timeTypes); + m_timeRep.setResourceInterfaces(m_timeInterfaces); + m_timeHandle = NULL; + } + ; + + /// This function internally calls registerResource API. + void createResources(ResourceEntityHandler callback); + + void setTimeRepresentation(OCRepresentation& rep); + void setCurrentTimeRepresentation(OCRepresentation& rep); + + OCRepresentation getTimeRepresentation(); + OCRepresentation getCurrentTimeRepresentation(); + + std::string getTimeUri(); + std::string getCurrentTimeUri(); + + void factoryReset(); + +}; + +extern std::string defaultNetworkValue; +extern std::string defaultIPAddressValue; + +class NetworkCollection +{ +public: + + // diagnostics members + std::string m_networkUri; + std::string m_networkValue; + std::vector< std::string > m_networkTypes; + std::vector< std::string > m_networkInterfaces; + OCResourceHandle m_networkHandle; + OCRepresentation m_networkRep; + + // factory reset members + std::string m_IPAddressUri; + std::string m_IPAddressValue; + std::vector< std::string > m_IPAddressTypes; + std::vector< std::string > m_IPAddressInterfaces; + OCResourceHandle m_IPAddressHandle; + OCRepresentation m_IPAddressRep; + +public: + + /// Constructor + NetworkCollection() : + m_networkValue(defaultNetworkValue), m_IPAddressValue(defaultIPAddressValue) + { + m_IPAddressUri = defaultURIPrefix + "/network/0/IPAddress"; // URI of the resource + m_IPAddressTypes.push_back("oic.con.network.IPAddress"); // resource type name. + m_IPAddressInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_IPAddressRep.setUri(m_IPAddressUri); + m_IPAddressRep.setResourceTypes(m_IPAddressTypes); + m_IPAddressRep.setResourceInterfaces(m_IPAddressInterfaces); + m_IPAddressRep.setValue("value", m_IPAddressValue); + m_IPAddressHandle = NULL; + + m_networkUri = defaultURIPrefix + "/network"; // URI of the resource + m_networkTypes.push_back("oic.con.network"); // resource type name. + m_networkInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_networkInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_networkInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_networkRep.setValue("value", m_networkValue); + m_networkRep.setUri(m_networkUri); + m_networkRep.setResourceTypes(m_networkTypes); + m_networkRep.setResourceInterfaces(m_networkInterfaces); + m_networkHandle = NULL; + } + ; + + /// Constructor + NetworkCollection(std::string URIPrefix, std::string ResourceTypePrefix) : + m_networkValue(defaultNetworkValue), m_IPAddressValue(defaultIPAddressValue) + { + m_IPAddressUri = URIPrefix + "/network/0/IPAddress"; // URI of the resource + m_IPAddressTypes.push_back(ResourceTypePrefix + "network.IPAddress"); // resource type name. + m_IPAddressInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_IPAddressRep.setUri(m_IPAddressUri); + m_IPAddressRep.setResourceTypes(m_IPAddressTypes); + m_IPAddressRep.setResourceInterfaces(m_IPAddressInterfaces); + m_IPAddressRep.setValue("value", m_IPAddressValue); + m_IPAddressHandle = NULL; + + m_networkUri = URIPrefix + "/network"; // URI of the resource + m_networkTypes.push_back(ResourceTypePrefix + ".network"); // resource type name. + m_networkInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_networkInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_networkInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_networkRep.setValue("value", m_networkValue); + m_networkRep.setUri(m_networkUri); + m_networkRep.setResourceTypes(m_networkTypes); + m_networkRep.setResourceInterfaces(m_networkInterfaces); + m_networkHandle = NULL; + } + ; + + /// This function internally calls registerResource API. + void createResources(ResourceEntityHandler callback); + + void setNetworkRepresentation(OCRepresentation& rep); + void setIPAddressRepresentation(OCRepresentation& rep); + + OCRepresentation getNetworkRepresentation(); + OCRepresentation getIPAddressRepresentation(); + + std::string getNetworkUri(); + std::string getIPAddressUri(); + + void factoryReset(); + +}; + +extern std::string defaultSecurityValue; +extern std::string defaultModeValue; + +class SecurityCollection +{ +public: + + // diagnostics members + std::string m_securityUri; + std::string m_securityValue; + std::vector< std::string > m_securityTypes; + std::vector< std::string > m_securityInterfaces; + OCResourceHandle m_securityHandle; + OCRepresentation m_securityRep; + + // factory reset members + std::string m_modeUri; + std::string m_modeValue; + std::vector< std::string > m_modeTypes; + std::vector< std::string > m_modeInterfaces; + OCResourceHandle m_modeHandle; + OCRepresentation m_modeRep; + +public: + /// Constructor + SecurityCollection() : + m_securityValue(defaultSecurityValue), m_modeValue(defaultModeValue) + { + m_modeUri = defaultURIPrefix + "/security/0/mode"; // URI of the resource + m_modeTypes.push_back("oic.con.security.mode"); // resource type name. + m_modeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_modeRep.setUri(m_modeUri); + m_modeRep.setResourceTypes(m_modeTypes); + m_modeRep.setResourceInterfaces(m_modeInterfaces); + m_modeRep.setValue("value", m_modeValue); + m_modeHandle = NULL; + + m_securityUri = defaultURIPrefix + "/security"; // URI of the resource + m_securityTypes.push_back("oic.con.security"); // resource type name. + m_securityInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_securityInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_securityInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_securityRep.setValue("value", m_securityValue); + m_securityRep.setUri(m_securityUri); + m_securityRep.setResourceTypes(m_securityTypes); + m_securityRep.setResourceInterfaces(m_securityInterfaces); + m_securityHandle = NULL; + } + ; + + /// Constructor + SecurityCollection(std::string URIPrefix, std::string ResourceTypePrefix) : + m_securityValue(defaultSecurityValue), m_modeValue(defaultModeValue) + { + m_modeUri = URIPrefix + "/security/0/mode"; // URI of the resource + m_modeTypes.push_back(ResourceTypePrefix + ".security.mode"); // resource type name. + m_modeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_modeRep.setUri(m_modeUri); + m_modeRep.setResourceTypes(m_modeTypes); + m_modeRep.setResourceInterfaces(m_modeInterfaces); + m_modeRep.setValue("value", m_modeValue); + m_modeHandle = NULL; + + m_securityUri = URIPrefix + "/security"; // URI of the resource + m_securityTypes.push_back(ResourceTypePrefix + ".security"); // resource type name. + m_securityInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_securityInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_securityInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_securityRep.setValue("value", m_securityValue); + m_securityRep.setUri(m_securityUri); + m_securityRep.setResourceTypes(m_securityTypes); + m_securityRep.setResourceInterfaces(m_securityInterfaces); + m_securityHandle = NULL; + } + ; + + /// This function internally calls registerResource API. + void createResources(ResourceEntityHandler callback); + + void setSecurityRepresentation(OCRepresentation& rep); + void setModeRepresentation(OCRepresentation& rep); + + OCRepresentation getSecurityRepresentation(); + OCRepresentation getModeRepresentation(); + + std::string getSecurityUri(); + std::string getModeUri(); + + void factoryReset(); + +}; + +extern std::string defaultConfigurationValue; +extern std::string defaultRegionValue; +static std::string defaultTimeLink = "/con/con/0/time"; +static std::string defaultNetworkLink = "/con/con/0/network"; +static std::string defaultSecurityLink = "/con/con/0/security"; + +class ConfigurationCollection +{ +public: + TimeCollection *myTimeCollection; + NetworkCollection *myNetworkCollection; + SecurityCollection *mySecurityCollection; + +public: + // Configuration members + std::string m_configurationUri; + std::string m_configurationValue; + std::vector< std::string > m_configurationTypes; + std::vector< std::string > m_configurationInterfaces; + OCResourceHandle m_configurationHandle; + OCRepresentation m_configurationRep; + + // Security members + std::string m_regionUri; + std::string m_regionValue; + std::vector< std::string > m_regionTypes; + std::vector< std::string > m_regionInterfaces; + OCResourceHandle m_regionHandle; + OCRepresentation m_regionRep; + + // Time members + std::string m_timeUri; + std::string m_timeLink; + std::vector< std::string > m_timeTypes; + std::vector< std::string > m_timeInterfaces; + OCResourceHandle m_timeHandle; + OCRepresentation m_timeRep; + + // Network members + std::string m_networkUri; + std::string m_networkLink; + std::vector< std::string > m_networkTypes; + std::vector< std::string > m_networkInterfaces; + OCResourceHandle m_networkHandle; + OCRepresentation m_networkRep; + + // Security members + std::string m_securityUri; + std::string m_securityLink; + std::vector< std::string > m_securityTypes; + std::vector< std::string > m_securityInterfaces; + OCResourceHandle m_securityHandle; + OCRepresentation m_securityRep; + +public: + /// Constructor + ConfigurationCollection() : + m_configurationValue(defaultConfigurationValue), m_regionValue(defaultRegionValue), m_timeLink( + defaultTimeLink), m_networkLink(defaultNetworkLink), m_securityLink( + defaultSecurityLink) + { + m_regionUri = defaultURIPrefix + "/0/region"; // URI of the resource + m_regionTypes.push_back(defaultResourceTypePrefix + ".region"); // resource type name. + m_regionInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_regionRep.setUri(m_regionUri); + m_regionRep.setResourceTypes(m_regionTypes); + m_regionRep.setResourceInterfaces(m_regionInterfaces); + m_regionRep.setValue("value", m_regionValue); + m_regionHandle = NULL; + + m_timeUri = defaultURIPrefix + "/0/time"; // URI of the resource + m_timeTypes.push_back(defaultResourceTypePrefix + ".time"); // resource type name. + m_timeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_timeRep.setUri(m_timeUri); + m_timeRep.setResourceTypes(m_timeTypes); + m_timeRep.setResourceInterfaces(m_timeInterfaces); + m_timeRep.setValue("link", m_timeLink); + m_timeHandle = NULL; + + m_networkUri = defaultURIPrefix + "/0/net"; // URI of the resource + m_networkTypes.push_back(defaultResourceTypePrefix + ".net"); // resource type name. + m_networkInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_networkRep.setUri(m_networkUri); + m_networkRep.setResourceTypes(m_networkTypes); + m_networkRep.setResourceInterfaces(m_networkInterfaces); + m_networkRep.setValue("link", m_networkLink); + m_networkHandle = NULL; + + m_securityUri = defaultURIPrefix + "/0/sec"; // URI of the resource + m_securityTypes.push_back(defaultResourceTypePrefix + ".sec"); // resource type name. + m_securityInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_securityRep.setUri(m_securityUri); + m_securityRep.setResourceTypes(m_securityTypes); + m_securityRep.setResourceInterfaces(m_securityInterfaces); + m_securityRep.setValue("link", m_securityLink); + m_securityHandle = NULL; + + m_configurationUri = defaultURIPrefix + ""; // URI of the resource + m_configurationTypes.push_back(defaultResourceTypePrefix + ""); // resource type name. + m_configurationInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_configurationInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_configurationInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_configurationRep.setValue("value", m_configurationValue); + m_configurationRep.setUri(m_configurationUri); + m_configurationRep.setResourceTypes(m_configurationTypes); + m_configurationRep.setResourceInterfaces(m_configurationInterfaces); + m_configurationHandle = NULL; + + myTimeCollection = new TimeCollection(); + myNetworkCollection = new NetworkCollection(); + mySecurityCollection = new SecurityCollection(); + } + ; + + /// Constructor + ConfigurationCollection(std::string URIPrefix, std::string ResourceTypePrefix) : + m_configurationValue(defaultConfigurationValue), m_regionValue(defaultRegionValue), m_timeLink( + defaultTimeLink), m_networkLink(defaultNetworkLink), m_securityLink( + defaultSecurityLink) + { + m_regionUri = URIPrefix + "/0/region"; // URI of the resource + m_regionTypes.push_back(ResourceTypePrefix + ".region"); // type name. + m_regionInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_regionRep.setUri(m_regionUri); + m_regionRep.setResourceTypes(m_regionTypes); + m_regionRep.setResourceInterfaces(m_regionInterfaces); + m_regionRep.setValue("value", m_regionValue); + m_regionHandle = NULL; + + m_timeUri = URIPrefix + "/0/time"; // URI of the resource + m_timeTypes.push_back(ResourceTypePrefix + ".time"); // resource type name. + m_timeInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_timeRep.setUri(m_timeUri); + m_timeRep.setResourceTypes(m_timeTypes); + m_timeRep.setResourceInterfaces(m_timeInterfaces); + m_timeRep.setValue("link", m_timeLink); + m_timeHandle = NULL; + + m_networkUri = URIPrefix + "/0/net"; // URI of the resource + m_networkTypes.push_back(ResourceTypePrefix + ".net"); // resource type name. + m_networkInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_networkRep.setUri(m_networkUri); + m_networkRep.setResourceTypes(m_networkTypes); + m_networkRep.setResourceInterfaces(m_networkInterfaces); + m_networkRep.setValue("link", m_networkLink); + m_networkHandle = NULL; + + m_securityUri = URIPrefix + "/0/sec"; // URI of the resource + m_securityTypes.push_back(ResourceTypePrefix + ".sec"); // resource type name. + m_securityInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_securityRep.setUri(m_securityUri); + m_securityRep.setResourceTypes(m_securityTypes); + m_securityRep.setResourceInterfaces(m_securityInterfaces); + m_securityRep.setValue("link", m_securityLink); + m_securityHandle = NULL; + + m_configurationUri = URIPrefix + ""; // URI of the resource + m_configurationTypes.push_back(ResourceTypePrefix + ""); // resource type name. + m_configurationInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_configurationInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_configurationInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_configurationRep.setValue("value", m_configurationValue); + m_configurationRep.setUri(m_configurationUri); + m_configurationRep.setResourceTypes(m_configurationTypes); + m_configurationRep.setResourceInterfaces(m_configurationInterfaces); + m_configurationHandle = NULL; + + myTimeCollection = new TimeCollection(URIPrefix, ResourceTypePrefix); + myNetworkCollection = new NetworkCollection(URIPrefix, ResourceTypePrefix); + mySecurityCollection = new SecurityCollection(URIPrefix, ResourceTypePrefix); + } + ; + + ~ConfigurationCollection() + { + free(myTimeCollection); + free(myNetworkCollection); + free(mySecurityCollection); + } + + /// This function internally calls registerResource API. + void createResources(ResourceEntityHandler callback); + + void setConfigurationRepresentation(OCRepresentation& rep); + void setTimeRepresentation(OCRepresentation& rep); + void setNetworkRepresentation(OCRepresentation& rep); + void setSecurityRepresentation(OCRepresentation& rep); + void setRegionRepresentation(OCRepresentation& rep); + + OCRepresentation getTimeRepresentation(); + OCRepresentation getNetworkRepresentation(); + OCRepresentation getSecurityRepresentation(); + OCRepresentation getRegionRepresentation(); + OCRepresentation getConfigurationRepresentation(); + + std::string getConfigurationUri(); + std::string getTimeUri(); + std::string getNetworkUri(); + std::string getSecurityUri(); + std::string getRegionUri(); + + void factoryReset(); + +}; diff --git a/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.cpp b/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.cpp new file mode 100644 index 000000000..31eaf1edd --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.cpp @@ -0,0 +1,245 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample shows how one could create a resource (collection) with children. +/// + +#include <functional> +#include <thread> + +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" +#include "DiagnosticsCollection.h" + +using namespace OC; + +/// This function internally calls registerResource API. +void DiagnosticsCollection::createResources(ResourceEntityHandler callback) +{ + using namespace OC::OCPlatform; + + if (callback == NULL) + { + std::cout << "callback should be binded\t"; + return; + } + + // This will internally create and register the resource. + OCStackResult result = registerResource(m_diagnosticsHandle, m_diagnosticsUri, + m_diagnosticsTypes[0], m_diagnosticsInterfaces[0], callback, + OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (diagnostics) was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_diagnosticsHandle, m_diagnosticsInterfaces[1]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_diagnosticsHandle, m_diagnosticsInterfaces[2]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = registerResource(m_factoryResetHandle, m_factoryResetUri, m_factoryResetTypes[0], + m_factoryResetInterfaces[0], callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (factoryReset) was unsuccessful\n"; + } + + result = registerResource(m_rebootHandle, m_rebootUri, m_rebootTypes[0], m_rebootInterfaces[0], + callback, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (reboot) was unsuccessful\n"; + } + + result = registerResource(m_startCollectionHandle, m_startCollectionUri, + m_startCollectionTypes[0], m_startCollectionInterfaces[0], callback, + OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (startCollection) was unsuccessful\n"; + } + + result = bindResource(m_diagnosticsHandle, m_factoryResetHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding installedLocation resource to room was unsuccessful\n"; + } + + result = bindResource(m_diagnosticsHandle, m_rebootHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding time resource to room was unsuccessful\n"; + } + + result = bindResource(m_diagnosticsHandle, m_startCollectionHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding network resource to room was unsuccessful\n"; + } + + thread exec( + std::function< void(int second) >( + std::bind(&DiagnosticsCollection::diagnosticsMonitor, this, + std::placeholders::_1)), 10); // every 10 seconds + exec.detach(); + + std::cout << "Diagnostics Collection is Created!\n"; +} + +void DiagnosticsCollection::setDiagnosticsRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_diagnosticsValue = value; + + std::cout << "\t\t\t\t" << "m_diagnosticsValue: " << m_diagnosticsValue << std::endl; + } +} + +void DiagnosticsCollection::setFactoryResetRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_factoryResetValue = value; + + std::cout << "\t\t\t\t" << "value: " << m_factoryResetValue << std::endl; + } +} + +void DiagnosticsCollection::setRebootRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_rebootValue = value; + + std::cout << "\t\t\t\t" << "value: " << m_rebootValue << std::endl; + } +} + +void DiagnosticsCollection::setStartCollectionRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_startCollectionValue = value; + + std::cout << "\t\t\t\t" << "value: " << m_startCollectionValue << std::endl; + } +} + +OCRepresentation DiagnosticsCollection::getFactoryResetRepresentation() +{ + m_factoryResetRep.setValue("value", m_factoryResetValue); + + return m_factoryResetRep; +} + +OCRepresentation DiagnosticsCollection::getRebootRepresentation() +{ + m_rebootRep.setValue("value", m_rebootValue); + + return m_rebootRep; +} + +OCRepresentation DiagnosticsCollection::getStartCollectionRepresentation() +{ + m_startCollectionRep.setValue("value", m_startCollectionValue); + + return m_startCollectionRep; +} + +OCRepresentation DiagnosticsCollection::getDiagnosticsRepresentation() +{ + m_diagnosticsRep.clearChildren(); + + m_diagnosticsRep.addChild(getFactoryResetRepresentation()); + m_diagnosticsRep.addChild(getRebootRepresentation()); + m_diagnosticsRep.addChild(getStartCollectionRepresentation()); + + m_diagnosticsRep.setValue("value", m_diagnosticsValue); + + return m_diagnosticsRep; +} + +std::string DiagnosticsCollection::getDiagnosticsUri() +{ + return m_diagnosticsUri; +} + +std::string DiagnosticsCollection::getFactoryResetUri() +{ + return m_factoryResetUri; +} + +std::string DiagnosticsCollection::getRebootUri() +{ + return m_rebootUri; +} + +std::string DiagnosticsCollection::getStartCollectionUri() +{ + return m_startCollectionUri; +} + +void DiagnosticsCollection::diagnosticsMonitor(int second) +{ + while (1) + { + sleep(second); + + if (m_rebootValue == "true") + { + int res; + std::cout << "Reboot will be soon..." << std::endl; + m_rebootValue = defaultReboot; + res = system("sudo reboot"); // System reboot + + std::cout << "return: " << res << std::endl; + + } + else if (m_factoryResetValue == "true") + { + std::cout << "Factory Reset will be soon..." << std::endl; + m_factoryResetValue = defaultFactoryReset; + factoryReset(); + } + } +} diff --git a/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.h b/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.h new file mode 100644 index 000000000..df4c83e07 --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/DiagnosticsCollection.h @@ -0,0 +1,150 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample shows how one could create a resource (collection) with children. +/// + +#include <functional> +#include <thread> + +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" + +#pragma once + +using namespace OC; + +typedef std::function< OCEntityHandlerResult(std::shared_ptr< OCResourceRequest > request) > ResourceEntityHandler; + +static std::string defaultDiagnosticsValue = "false"; +static std::string defaultFactoryReset = "false"; +static std::string defaultReboot = "false"; +static std::string defaultStartCollection = "false"; + +class DiagnosticsCollection +{ +public: + + // diagnostics members + std::string m_diagnosticsUri; + std::string m_diagnosticsValue; + std::vector< std::string > m_diagnosticsTypes; + std::vector< std::string > m_diagnosticsInterfaces; + OCResourceHandle m_diagnosticsHandle; + OCRepresentation m_diagnosticsRep; + + // factory reset members + std::string m_factoryResetUri; + std::string m_factoryResetValue; + std::vector< std::string > m_factoryResetTypes; + std::vector< std::string > m_factoryResetInterfaces; + OCResourceHandle m_factoryResetHandle; + OCRepresentation m_factoryResetRep; + + // reboot members + std::string m_rebootUri; + std::string m_rebootValue; + std::vector< std::string > m_rebootTypes; + std::vector< std::string > m_rebootInterfaces; + OCResourceHandle m_rebootHandle; + OCRepresentation m_rebootRep; + + // startcollection members + std::string m_startCollectionUri; + std::string m_startCollectionValue; + std::vector< std::string > m_startCollectionTypes; + std::vector< std::string > m_startCollectionInterfaces; + OCResourceHandle m_startCollectionHandle; + OCRepresentation m_startCollectionRep; + +public: + /// Constructor + DiagnosticsCollection() : + m_diagnosticsValue(defaultDiagnosticsValue), m_factoryResetValue(defaultFactoryReset), m_rebootValue( + defaultReboot), m_startCollectionValue(defaultStartCollection) + { + m_factoryResetUri = "/oic/diag/0/factoryReset"; // URI of the resource + m_factoryResetTypes.push_back("oic.diag.factoryReset"); // resource type name. + m_factoryResetInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_factoryResetRep.setUri(m_factoryResetUri); + m_factoryResetRep.setResourceTypes(m_factoryResetTypes); + m_factoryResetRep.setResourceInterfaces(m_factoryResetInterfaces); + m_factoryResetRep.setValue("value", m_factoryResetValue); + m_factoryResetHandle = NULL; + + m_rebootUri = "/oic/diag/0/reboot"; // URI of the resource + m_rebootTypes.push_back("oic.diag.reboot"); // resource type name. + m_rebootInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_rebootRep.setUri(m_rebootUri); + m_rebootRep.setResourceTypes(m_rebootTypes); + m_rebootRep.setResourceInterfaces(m_rebootInterfaces); + m_rebootRep.setValue("value", m_rebootValue); + m_rebootHandle = NULL; + + m_startCollectionUri = "/oic/diag/0/startCollection"; // URI of the resource + m_startCollectionTypes.push_back("oic.diag.startCollection"); // resource type name. + m_startCollectionInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_startCollectionRep.setUri(m_startCollectionUri); + m_startCollectionRep.setResourceTypes(m_startCollectionTypes); + m_startCollectionRep.setResourceInterfaces(m_startCollectionInterfaces); + m_startCollectionRep.setValue("value", m_startCollectionValue); + m_startCollectionHandle = NULL; + + m_diagnosticsUri = "/oic/diag"; // URI of the resource + m_diagnosticsTypes.push_back("oic.diag"); // resource type name. + m_diagnosticsInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_diagnosticsInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_diagnosticsInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_diagnosticsRep.setValue("value", m_diagnosticsValue); + m_diagnosticsRep.setUri(m_diagnosticsUri); + m_diagnosticsRep.setResourceTypes(m_diagnosticsTypes); + m_diagnosticsRep.setResourceInterfaces(m_diagnosticsInterfaces); + m_diagnosticsHandle = NULL; + } + ; + + /// This function internally calls registerResource API. + void createResources(ResourceEntityHandler callback); + + void setDiagnosticsRepresentation(OCRepresentation& rep); + void setFactoryResetRepresentation(OCRepresentation& rep); + void setRebootRepresentation(OCRepresentation& rep); + void setStartCollectionRepresentation(OCRepresentation& rep); + + OCRepresentation getDiagnosticsRepresentation(); + OCRepresentation getFactoryResetRepresentation(); + OCRepresentation getRebootRepresentation(); + OCRepresentation getStartCollectionRepresentation(); + + std::string getDiagnosticsUri(); + std::string getFactoryResetUri(); + std::string getRebootUri(); + std::string getStartCollectionUri(); + + void diagnosticsMonitor(int second); + + std::function< void() > factoryReset; +}; + diff --git a/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.cpp b/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.cpp new file mode 100644 index 000000000..d05009618 --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.cpp @@ -0,0 +1,141 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample shows how one could create a resource (collection) with children. +/// + +#include <functional> +#include <thread> + +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" +#include "FactorySetCollection.h" + +using namespace OC; + +/// This function internally calls registerResource API. +void FactorySetCollection::createResources(ResourceEntityHandler callback) +{ + using namespace OC::OCPlatform; + + if (callback == NULL) + { + std::cout << "callback should be binded\t"; + return; + } + + // This will internally create and register the resource. + OCStackResult result = registerResource(m_factorySetHandle, m_factorySetUri, + m_factorySetTypes[0], m_factorySetInterfaces[0], callback, + OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (configuration) was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_factorySetHandle, m_factorySetInterfaces[1]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = bindInterfaceToResource(m_factorySetHandle, m_factorySetInterfaces[2]); + if (OC_STACK_OK != result) + { + std::cout << "Binding TypeName to Resource was unsuccessful\n"; + } + + result = registerResource(m_configurationCollectionHandle, m_configurationCollectionUri, + m_configurationCollectionTypes[0], m_configurationCollectionInterfaces[0], callback, + OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + std::cout << "Resource creation (installedLocation) was unsuccessful\n"; + } + + result = bindResource(m_factorySetHandle, m_configurationCollectionHandle); + if (OC_STACK_OK != result) + { + std::cout << "Binding installedLocation resource to room was unsuccessful\n"; + } + + defaultConfigurationCollection = new ConfigurationCollection(defaultConfigurationURIPrefix, + defaultConfigurationResourceTypePrefix); + //defaultConfigurationCollection->bindEntityHander(callback); + defaultConfigurationCollection->createResources(callback); + + std::cout << "FactorySet Collection is Created!\n"; +} + +void FactorySetCollection::setFactorySetRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("value", value)) + { + m_factorySetValue = value; + + std::cout << "\t\t\t\t" << "m_factorySetValue: " << m_factorySetValue << std::endl; + } +} + +void FactorySetCollection::setConfigurationCollectionRepresentation(OCRepresentation& rep) +{ + string value; + + if (rep.getValue("link", value)) + { + // NOT ALLOWED + + std::cout << "\t\t\t\t" << "link: " << m_configurationCollectionLink << std::endl; + } +} + +OCRepresentation FactorySetCollection::getConfigurationCollectionRepresentation() +{ + m_configurationCollectionRep.setValue("link", m_configurationCollectionLink); + + return m_configurationCollectionRep; +} + +OCRepresentation FactorySetCollection::getFactorySetRepresentation() +{ + m_factorySetRep.clearChildren(); + + m_factorySetRep.addChild(getConfigurationCollectionRepresentation()); + + m_factorySetRep.setValue("value", m_factorySetValue); + + return m_factorySetRep; +} + +std::string FactorySetCollection::getFactorySetUri() +{ + return m_factorySetUri; +} + +std::string FactorySetCollection::getConfigurationCollectionUri() +{ + return m_configurationCollectionUri; +} diff --git a/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.h b/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.h new file mode 100644 index 000000000..bc20a71a7 --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/FactorySetCollection.h @@ -0,0 +1,120 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample shows how one could create a resource (collection) with children. +/// + +#include <functional> +#include <thread> + +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" +#include "ConfigurationCollection.h" + +#pragma once + +using namespace OC; + +typedef std::function< OCEntityHandlerResult(std::shared_ptr< OCResourceRequest > request) > ResourceEntityHandler; + +extern std::string defaultFactorySetValue; +static std::string defaultConfigurationCollectionLink = "/factorySet/oic/con"; + +static std::string defaultConfigurationURIPrefix = "/factorySet/oic/con"; +static std::string defaultConfigurationResourceTypePrefix = "factorySet.oic.con"; + +class FactorySetCollection +{ +public: + + ConfigurationCollection *defaultConfigurationCollection; + +public: + + // diagnostics members + std::string m_factorySetUri; + std::string m_factorySetValue; + std::vector< std::string > m_factorySetTypes; + std::vector< std::string > m_factorySetInterfaces; + OCResourceHandle m_factorySetHandle; + OCRepresentation m_factorySetRep; + + // Configuration members + std::string m_configurationCollectionUri; + std::string m_configurationCollectionLink; + std::vector< std::string > m_configurationCollectionTypes; + std::vector< std::string > m_configurationCollectionInterfaces; + OCResourceHandle m_configurationCollectionHandle; + OCRepresentation m_configurationCollectionRep; + +public: + /// Constructor + FactorySetCollection() : + m_factorySetValue(defaultFactorySetValue), m_configurationCollectionLink( + defaultConfigurationCollectionLink) + { + m_configurationCollectionUri = "/factorySet/0/con"; // URI of the resource + m_configurationCollectionTypes.push_back("factorySet.con"); // resource type name. + m_configurationCollectionInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + + m_configurationCollectionRep.setUri(m_configurationCollectionUri); + m_configurationCollectionRep.setResourceTypes(m_configurationCollectionTypes); + m_configurationCollectionRep.setResourceInterfaces(m_configurationCollectionInterfaces); + m_configurationCollectionRep.setValue("link", m_configurationCollectionLink); + m_configurationCollectionHandle = NULL; + + m_factorySetUri = "/factorySet"; // URI of the resource + m_factorySetTypes.push_back("factorySet"); // resource type name. + m_factorySetInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_factorySetInterfaces.push_back(BATCH_INTERFACE); // resource interface. + m_factorySetInterfaces.push_back(LINK_INTERFACE); // resource interface. + m_factorySetRep.setValue("value", m_factorySetValue); + m_factorySetRep.setUri(m_factorySetUri); + m_factorySetRep.setResourceTypes(m_factorySetTypes); + m_factorySetRep.setResourceInterfaces(m_factorySetInterfaces); + m_factorySetHandle = NULL; + + defaultConfigurationCollection = NULL; + } + ; + + ~FactorySetCollection() + { + if (defaultConfigurationCollection != NULL) + free(defaultConfigurationCollection); + } + ; + + /// This function internally calls registerResource API. + void createResources(ResourceEntityHandler callback); + + void setFactorySetRepresentation(OCRepresentation& rep); + void setConfigurationCollectionRepresentation(OCRepresentation& rep); + + OCRepresentation getFactorySetRepresentation(); + OCRepresentation getConfigurationCollectionRepresentation(); + + std::string getFactorySetUri(); + std::string getConfigurationCollectionUri(); + +}; + diff --git a/service/things-manager/sampleapp/linux/configuration/SConscript b/service/things-manager/sampleapp/linux/configuration/SConscript new file mode 100644 index 000000000..d4a8c5d98 --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/SConscript @@ -0,0 +1,34 @@ +## +# linux sample app build script +## + +Import('env') + +# Add third party libraries +lib_env = env.Clone() +SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env') +linux_sample_env = lib_env.Clone() + +###################################################################### +# Build flags +###################################################################### +linux_sample_env.AppendUnique(CPPPATH = ['include']) +linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/inc']) +linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/src']) +linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread']) +linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX']) +linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) +linux_sample_env.AppendUnique(LIBS = ['libTGMSDKLibrary', 'oc', 'octbstack', 'libcoap', 'liboc_logger', 'dl', 'pthread']) + +###################################################################### +#build sampleapp +###################################################################### +conserver = linux_sample_env.Program('con-server', ['ConfigurationCollection.cpp', 'DiagnosticsCollection.cpp', 'FactorySetCollection.cpp', 'con-server.cpp']) +conclient = linux_sample_env.Program('con-client', 'con-client.cpp') +bootstrapserver = linux_sample_env.Program('bootstrapserver', 'bootstrapserver.cpp') +Alias("ConServerApp", conserver) +Alias("ConCleintApp", conclient) +Alias("BootstrapServerApp", bootstrapserver) +env.AppendTarget('ConServerApp') +env.AppendTarget('ConClientApp') +env.AppendTarget('BootstrapServerApp') diff --git a/service/things-manager/sampleapp/linux/configuration/bootstrapserver.cpp b/service/things-manager/sampleapp/linux/configuration/bootstrapserver.cpp new file mode 100644 index 000000000..e53f61ce0 --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/bootstrapserver.cpp @@ -0,0 +1,237 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample shows how one could create a resource (collection) with children. +/// + +#include <functional> + +#include <pthread.h> + +#include "OCPlatform.h" +#include "OCApi.h" + +using namespace OC; +using namespace std; + +// Forward declaring the entityHandler (bootstrap) +bool prepareResponse(std::shared_ptr< OCResourceRequest > request); +OCStackResult sendResponse(std::shared_ptr< OCResourceRequest > pRequest); +OCEntityHandlerResult entityHandlerBootstrap(std::shared_ptr< OCResourceRequest > request); + +#define DefaultConfigurationValue "Configuration Collection" +#define DefaultRegionValue "Seoul, Korea" +#define DefaultTimeValue "Time Collection" +#define DefaultCurrentTimeValue "00:00:00" +#define DefaultNetworkValue "Network Collection" +#define DefaultIPAddressValue "192.168.0.2" +#define DefaultSecurityValue "SecurityValue" +#define DefaultModeValue "NoSec" +#define DefaultFactorySetValue "FactorySet Value" + +class BootstrapResource +{ +public: + // Room members + std::string m_bootstrapUri; + std::vector< std::string > m_bootstrapTypes; + std::vector< std::string > m_bootstrapInterfaces; + OCResourceHandle m_bootstrapHandle; + OCRepresentation m_bootstrapRep; + +public: + /// Constructor + BootstrapResource() + { + m_bootstrapUri = "/bootstrap"; // URI of the resource + m_bootstrapTypes.push_back("bootstrap"); // resource type name. In this case, it is light + m_bootstrapInterfaces.push_back(DEFAULT_INTERFACE); // resource interface. + m_bootstrapRep.setUri(m_bootstrapUri); + m_bootstrapRep.setResourceTypes(m_bootstrapTypes); + m_bootstrapRep.setResourceInterfaces(m_bootstrapInterfaces); + m_bootstrapHandle = NULL; + } + + /// This function internally calls registerResource API. + void createResources() + { + using namespace OC::OCPlatform; + // This will internally create and register the resource. + OCStackResult result = registerResource(m_bootstrapHandle, m_bootstrapUri, + m_bootstrapTypes[0], m_bootstrapInterfaces[0], entityHandlerBootstrap, + OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + cout << "Resource creation (room) was unsuccessful\n"; + } + } + + void setBootstrapRepresentation(OCRepresentation& rep) + { + // Not allowed + } + + OCRepresentation getBootstrapRepresentation() + { + m_bootstrapRep.setValue< std::string >("regionValue", DefaultRegionValue); + m_bootstrapRep.setValue< std::string >("timeValue", DefaultTimeValue); + m_bootstrapRep.setValue< std::string >("currentTimeValue", DefaultCurrentTimeValue); + m_bootstrapRep.setValue< std::string >("networkValue", DefaultNetworkValue); + m_bootstrapRep.setValue< std::string >("IPAddressValue", DefaultIPAddressValue); + m_bootstrapRep.setValue< std::string >("securityValue", DefaultSecurityValue); + m_bootstrapRep.setValue< std::string >("modeValue", DefaultModeValue); + m_bootstrapRep.setValue< std::string >("configurationValue", DefaultConfigurationValue); + m_bootstrapRep.setValue< std::string >("factorySetValue", DefaultFactorySetValue); + + return m_bootstrapRep; + } +}; + +// Create the instance of the resource class (in this case instance of class 'RoomResource'). +BootstrapResource myBootstrapResource; + +// This function prepares a response for any incoming request to Light resource. +bool prepareResponse(std::shared_ptr< OCResourceRequest > request) +{ + cout << "\tIn Server CPP prepareResponse:\n"; + bool result = false; + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag == RequestHandlerFlag::InitFlag) + { + cout << "\t\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + else if (requestFlag == RequestHandlerFlag::RequestFlag) + { + cout << "\t\trequestFlag : Request\n"; + + // If the request type is GET + if (requestType == "GET") + { + cout << "\t\t\trequestType : GET\n"; + // GET operations are directly handled while sending the response + // in the sendLightResponse function + result = true; + } + else if (requestType == "PUT") + { + cout << "\t\t\trequestType : PUT\n"; + + OCRepresentation rep = request->getResourceRepresentation(); + + // Do related operations related to PUT request + myBootstrapResource.setBootstrapRepresentation(rep); + result = true; + } + else if (requestType == "POST") + { + // POST request operations + } + else if (requestType == "DELETE") + { + // DELETE request operations + } + } + else if (requestFlag == RequestHandlerFlag::ObserverFlag) + { + cout << "\t\trequestFlag : Observer\n"; + } + } + else + { + std::cout << "Request invalid" << std::endl; + } + + return result; +} + +OCStackResult sendResponse(std::shared_ptr< OCResourceRequest > pRequest) +{ + auto pResponse = std::make_shared< OC::OCResourceResponse >(); + pResponse->setRequestHandle(pRequest->getRequestHandle()); + pResponse->setResourceHandle(pRequest->getResourceHandle()); + pResponse->setResourceRepresentation(myBootstrapResource.getBootstrapRepresentation()); + pResponse->setErrorCode(200); + pResponse->setResponseResult(OC_EH_OK); + + return OCPlatform::sendResponse(pResponse); +} + +OCEntityHandlerResult entityHandlerBootstrap(std::shared_ptr< OCResourceRequest > request) +{ + cout << "\tIn Server CPP (entityHandlerBootstrap) entity handler:\n"; + OCEntityHandlerResult ehResult = OC_EH_ERROR; + + if (prepareResponse(request)) + { + if (OC_STACK_OK == sendResponse(request)) + { + ehResult = OC_EH_OK; + } + else + { + std::cout << "sendResponse failed." << std::endl; + } + } + else + { + std::cout << "PrepareResponse failed." << std::endl; + } + return ehResult; +} + +int main() +{ + // Create PlatformConfig object + PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0", + // By setting to "0.0.0.0", it binds to all available interfaces + 0,// Uses randomly available port + OC::QualityOfService::LowQos }; + + OCPlatform::Configure(cfg); + try + { + + myBootstrapResource.createResources(); + + // Perform app tasks + while (true) + { + // some tasks + } + } + catch (OCException e) + { + std::cout << "Exception in main: " << e.what(); + } + + // No explicit call to stop the platform. + // When OCPlatform destructor is invoked, internally we do platform cleanup +} + diff --git a/service/things-manager/sampleapp/linux/configuration/con-client.cpp b/service/things-manager/sampleapp/linux/configuration/con-client.cpp new file mode 100644 index 000000000..278c3e268 --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/con-client.cpp @@ -0,0 +1,449 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +// OCClient.cpp : Defines the entry point for the console application. +// +#include <string> +#include <cstdlib> +#include <pthread.h> +#include <map> +#include <vector> +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" + +using namespace OC; +using namespace OIC; + +int g_Steps = 0; +int isWaiting = 0; //0: none to wait, 1: wait for the response of "getConfigurationValue" + +static ThingsManager* g_thingsmanager; + +OCResourceHandle configurationCollectionHandle; +std::shared_ptr< OCResource > g_configurationCollection; // for a group of multiple resources +std::shared_ptr< OCResource > g_configurationResource; // For a single resource + +OCResourceHandle diagnosticsCollectionHandle; +std::shared_ptr< OCResource > g_diagnosticsCollection; // for a group of multiple resources +std::shared_ptr< OCResource > g_diagnosticsResource; // For a single resource + +OCResourceHandle setCollectionHandle; +std::shared_ptr< OCResource > g_setCollection; // for a group of multiple resources +std::shared_ptr< OCResource > g_setResource; // For a single resource + +std::map< std::string, std::shared_ptr< OCResource > > resourceTable; +std::vector< OCResourceHandle > resourceHandleVector; + +typedef std::function< + void(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) > ConfigurationCallback; +typedef std::function< + void(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) > DiagnosticsCallback; + +typedef std::string ConfigurationName; +typedef std::string ConfigurationValue; + +void onReboot(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) +{ + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + std::cout << "\t\tReboot:" << rep.getValue< std::string >("value") << std::endl; + + isWaiting = 0; +} + +void onFactoryReset(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) +{ + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + std::cout << "\t\tFactoryReset:" << rep.getValue< std::string >("value") << std::endl; + isWaiting = 0; +} + +void onUpdate(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) +{ + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + std::cout << "\t\tvalue:" << rep.getValue< std::string >("value") << std::endl; + + isWaiting = 0; +} + +void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) +{ + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + if (rep.hasAttribute("value")) + std::cout << "\t\tvalue:" << rep.getValue< std::string >("value") << std::endl; + else if (rep.hasAttribute("link")) + std::cout << "\t\tlink:" << rep.getValue< std::string >("link") << std::endl; + + std::vector< OCRepresentation > children = rep.getChildren(); + + for (auto oit = children.begin(); oit != children.end(); ++oit) + { + std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl; + + if (oit->hasAttribute("value")) + std::cout << "\t\tvalue:" << oit->getValue< std::string >("value") << std::endl; + else if (oit->hasAttribute("link")) + std::cout << "\t\tlink:" << oit->getValue< std::string >("link") << std::endl; + } + + isWaiting = 0; +} + +// Callback to found collection resource +void onFoundCollectionResource(std::vector< std::shared_ptr< OCResource > > resources) +{ + + std::string resourceURI; + std::string hostAddress; + try + { + // Do some operations with resource object. + for (unsigned int i = 0; i < resources.size(); ++i) + { + std::shared_ptr< OCResource > resource = resources.at(i); + + if (resource) + { + if (resource->uri() == "/core/a/configuration/resourceset") + g_configurationCollection = resource; + else if (resource->uri() == "/core/a/diagnostics/resourceset") + g_diagnosticsCollection = resource; + else if (resource->uri() == "/core/a/factoryset/resourceset") + g_setCollection = resource; + else + { + isWaiting = 0; + return; + } + } + else + { + // Resource is invalid + std::cout << "Resource is invalid" << std::endl; + } + } + + } + catch (std::exception& e) + { + //log(e.what()); + } + + if (g_configurationCollection != NULL && g_diagnosticsCollection != NULL + && g_setCollection != NULL) + isWaiting = 0; +} + +// Callback to found resources +void onFoundCandidateCollection(std::vector< std::shared_ptr< OCResource > > resources) +{ + + std::string resourceURI; + std::string hostAddress; + + static bool flagForCon = false, flagForDiag = false, flagForSet = false; + + try + { + // Do some operations with resource object. + for (unsigned int i = 0; i < resources.size(); ++i) + { + std::shared_ptr< OCResource > resource = resources.at(i); + + if (resource) + { + // Check if the resource is new one. If so, store it. + + std::map< std::string, std::shared_ptr< OCResource > >::iterator iter = + resourceTable.find(resource->host() + resource->uri()); + + if (iter == resourceTable.end()) // new one + { + resourceTable[resource->host() + resource->uri()] = resource; + + OCResourceHandle foundResourceHandle; + OCStackResult result = OCPlatform::registerResource(foundResourceHandle, + resource); + std::cout << "\tResource ( " << resource->host() << " ) is registed!\t" + << std::endl; + if (result == OC_STACK_OK) + { + if (resource->uri() == "/oic/con") + { + flagForCon = true; + OCPlatform::bindResource(configurationCollectionHandle, + foundResourceHandle); + if (g_configurationResource == NULL) + g_configurationResource = resource; + } + else if (resource->uri() == "/oic/diag") + { + flagForDiag = true; + OCPlatform::bindResource(diagnosticsCollectionHandle, + foundResourceHandle); + if (g_diagnosticsResource == NULL) + g_diagnosticsResource = resource; + } + else if (resource->uri() == "/factorySet") + { + flagForSet = true; + OCPlatform::bindResource(setCollectionHandle, foundResourceHandle); + if (g_setResource == NULL) + g_setResource = resource; + } + + resourceHandleVector.push_back(foundResourceHandle); + } + else + { + cout << "\tresource Error!" << endl; + } + + } + + } + else + { + // Resource is invalid + std::cout << "Resource is invalid" << std::endl; + } + } + + } + catch (std::exception& e) + { + //log(e.what()); + } + + if (flagForCon && flagForDiag && flagForSet) + isWaiting = 0; +} + +int main(int argc, char* argv[]) +{ + + //************************************************************** + // STEP 0 + PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos }; + + OCPlatform::Configure(cfg); + g_thingsmanager = new ThingsManager(); + + //************************************************************** + + while (true) + { + + if (isWaiting > 0) + continue; + + isWaiting = 0; + + cout << endl << endl << "(0) Quit" << std::endl; + cout << "(1) Find all resources(URI: /oic/con, /oic/diag, /factoryset)" << std::endl; + cout << "(2) Find all groups" << std::endl; + cout << "(3) Get a new value (of \"Configuration\" Collection)" << std::endl; + cout << "(4) Update a value (of \"Region\" Resource)" << std::endl; + cout << "(5) Get a value (for \"Region\" Resource)" << std::endl; + cout << "(6) FactoryReset (for the group)" << std::endl; + cout << "(7) Reboot (for the group)" << std::endl; + cout << "(10) Show Configuration Units" << std::endl; + + cin >> g_Steps; + // + if (g_Steps == 0) + break; + else if (g_Steps == 1) + { + std::vector< std::string > types; + { // For Registering a collection resource for configuration resources + + string resourceURI = "/core/a/configuration/resourceset"; + string resourceTypeName = "core.configuration.resourceset"; + string resourceInterface = BATCH_INTERFACE; + + if (configurationCollectionHandle != NULL) + { + std::cout << "already exists" << std::endl; + continue; + } + + OCPlatform::registerResource(configurationCollectionHandle, resourceURI, + resourceTypeName, resourceInterface, NULL, + //&entityHandler, // entityHandler + OC_DISCOVERABLE); + + OCPlatform::bindInterfaceToResource(configurationCollectionHandle, GROUP_INTERFACE); + OCPlatform::bindInterfaceToResource(configurationCollectionHandle, + DEFAULT_INTERFACE); + + // instead of registration + types.push_back("oic.con"); + std::cout << "Finding Configuration Resource... " << std::endl; + } + + { // For Registering a collection resource for diagnostics resources + + string resourceURI = "/core/a/diagnostics/resourceset"; + string resourceTypeName = "core.diagnostics.resourceset"; + string resourceInterface = BATCH_INTERFACE; + + if (diagnosticsCollectionHandle != NULL) + { + std::cout << "already exists" << std::endl; + continue; + } + + OCPlatform::registerResource(diagnosticsCollectionHandle, resourceURI, + resourceTypeName, resourceInterface, NULL, + //&entityHandler, // entityHandler + OC_DISCOVERABLE); + + OCPlatform::bindInterfaceToResource(diagnosticsCollectionHandle, GROUP_INTERFACE); + OCPlatform::bindInterfaceToResource(diagnosticsCollectionHandle, DEFAULT_INTERFACE); + + // instead of registration + types.push_back("oic.diag"); + std::cout << "Finding Diagnostics Resource... " << std::endl; + + } + + { // For Registering a collection resource for set resources + + string resourceURI = "/core/a/factoryset/resourceset"; + string resourceTypeName = "core.factoryset.resourceset"; + string resourceInterface = BATCH_INTERFACE; + + if (setCollectionHandle != NULL) + { + std::cout << "already exists" << std::endl; + continue; + } + + OCPlatform::registerResource(setCollectionHandle, resourceURI, resourceTypeName, + resourceInterface, NULL, + //&entityHandler, // entityHandler + OC_DISCOVERABLE); + + OCPlatform::bindInterfaceToResource(setCollectionHandle, GROUP_INTERFACE); + OCPlatform::bindInterfaceToResource(setCollectionHandle, DEFAULT_INTERFACE); + + // instead of registration + types.push_back("factorySet"); + std::cout << "Finding Set Resource... " << std::endl; + } + + g_thingsmanager->findCandidateResources(types, &onFoundCandidateCollection, 5); + + isWaiting = 1; + } + else if (g_Steps == 2) // make a group with found things + { + std::vector< std::string > types; + types.push_back("core.configuration.resourceset"); + types.push_back("core.diagnostics.resourceset"); + types.push_back("core.factoryset.resourceset"); + + g_thingsmanager->findCandidateResources(types, &onFoundCollectionResource, 5); + + std::cout << "Finding Collection resource... " << std::endl; + isWaiting = 1; + + } + else if (g_Steps == 3) + { + // get a value + + ConfigurationName name = "configuration"; + + std::cout << "For example, get configuration collection's value" << std::endl; + + std::vector< ConfigurationName > configurations; + + configurations.push_back(name); + + if (g_thingsmanager->getConfigurations(g_configurationResource, configurations, &onGet) + != OC_STACK_ERROR) + isWaiting = 1; + } + else if (g_Steps == 4) + { + ConfigurationName name = "region"; + ConfigurationValue value = "U.S.A (new region)"; + + std::cout << "For example, change region resource's value" << std::endl; + std::cout << g_configurationCollection->uri() << std::endl; + + std::map< ConfigurationName, ConfigurationValue > configurations; + + configurations.insert(std::make_pair(name, value)); + + if (g_thingsmanager->updateConfigurations(g_configurationCollection, configurations, + &onUpdate) != OC_STACK_ERROR) + isWaiting = 1; + } + else if (g_Steps == 5) + { + // get a value + + ConfigurationName name = "region"; + + std::cout << "For example, get region resource's value" << std::endl; + + std::vector< ConfigurationName > configurations; + + configurations.push_back(name); + + if (g_thingsmanager->getConfigurations(g_configurationCollection, configurations, + &onGet) != OC_STACK_ERROR) + isWaiting = 1; + } + else if (g_Steps == 6) + { + // factory reset + if (g_thingsmanager->factoryReset(g_diagnosticsCollection, &onFactoryReset) + != OC_STACK_ERROR) + isWaiting = 1; + } + else if (g_Steps == 7) + { + // reboot + if (g_thingsmanager->reboot(g_diagnosticsCollection, &onReboot) != OC_STACK_ERROR) + isWaiting = 1; + } + else if (g_Steps == 10) + { + std::cout << g_thingsmanager->getListOfSupportedConfigurationUnits() << std::endl; + + } + + } + + return 0; +} + diff --git a/service/things-manager/sampleapp/linux/configuration/con-server.cpp b/service/things-manager/sampleapp/linux/configuration/con-server.cpp new file mode 100755 index 000000000..c83c7a09b --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/con-server.cpp @@ -0,0 +1,358 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample shows how one could create a resource (collection) with children. +/// + +#include <functional> +#include <thread> + +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" +#include "ConfigurationCollection.h" +#include "DiagnosticsCollection.h" +#include "FactorySetCollection.h" + +using namespace OC; +using namespace OIC; + +const int SUCCESS_RESPONSE = 0; +int g_Steps = 0; +int isWaiting = 0; + +// Default system configuration value's variables +// The variable's names should be same as the names of "extern" variables defined in +// "ConfigurationCollection.h" +std::string defaultRegionValue; +std::string defaultTimeValue; +std::string defaultCurrentTimeValue; +std::string defaultNetworkValue; +std::string defaultIPAddressValue; +std::string defaultSecurityValue; +std::string defaultModeValue; +std::string defaultConfigurationValue; +std::string defaultFactorySetValue; + +static ThingsManager* g_thingsmanager; + +// Forward declaring the entityHandler (Configuration) +bool prepareResponseForResource(std::shared_ptr< OCResourceRequest > request); +OCStackResult sendResponseForResource(std::shared_ptr< OCResourceRequest > pRequest); +OCEntityHandlerResult entityHandlerForResource(std::shared_ptr< OCResourceRequest > request); + +ConfigurationCollection *myConfigurationCollection; +DiagnosticsCollection *myDiagnosticsCollection; +FactorySetCollection *myFactorySetCollection; + +typedef std::function< void(OCRepresentation&) > putFunc; +typedef std::function< OCRepresentation(void) > getFunc; + +getFunc getGetFunction(std::string uri) +{ + getFunc res = NULL; + + if (uri == myConfigurationCollection->getTimeUri()) + { + res = std::bind(&ConfigurationCollection::getTimeRepresentation, myConfigurationCollection); + } + else if (uri == myConfigurationCollection->getConfigurationUri()) + { + res = std::bind(&ConfigurationCollection::getConfigurationRepresentation, + myConfigurationCollection); + } + else if (uri == myConfigurationCollection->myTimeCollection->getCurrentTimeUri()) + { + res = std::bind(&TimeCollection::getCurrentTimeRepresentation, + myConfigurationCollection->myTimeCollection); + } + else if (uri == myConfigurationCollection->getRegionUri()) + { + res = std::bind(&ConfigurationCollection::getRegionRepresentation, + myConfigurationCollection); + } + else if (uri == myDiagnosticsCollection->getFactoryResetUri()) + { + res = std::bind(&DiagnosticsCollection::getFactoryResetRepresentation, + myDiagnosticsCollection); + } + else if (uri == myDiagnosticsCollection->getRebootUri()) + { + res = std::bind(&DiagnosticsCollection::getRebootRepresentation, myDiagnosticsCollection); + } + + return res; +} + +putFunc getPutFunction(std::string uri) +{ + putFunc res = NULL; + + if (uri == myConfigurationCollection->getRegionUri()) + { + res = std::bind(&ConfigurationCollection::setRegionRepresentation, + myConfigurationCollection, std::placeholders::_1); + } + else if (uri == myConfigurationCollection->myTimeCollection->getCurrentTimeUri()) + { + res = std::bind(&TimeCollection::setCurrentTimeRepresentation, + myConfigurationCollection->myTimeCollection, std::placeholders::_1); + } + else if (uri == myDiagnosticsCollection->getFactoryResetUri()) + { + res = std::bind(&DiagnosticsCollection::setFactoryResetRepresentation, + myDiagnosticsCollection, std::placeholders::_1); + } + else if (uri == myDiagnosticsCollection->getRebootUri()) + { + res = std::bind(&DiagnosticsCollection::setRebootRepresentation, myDiagnosticsCollection, + std::placeholders::_1); + } + + return res; +} + +// This function prepares a response for any incoming request to Light resource. +bool prepareResponseForResource(std::shared_ptr< OCResourceRequest > request) +{ + std::cout << "\tIn Server CPP prepareResponseForResource:\n"; + bool result = false; + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag == RequestHandlerFlag::InitFlag) + { + std::cout << "\t\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + else if (requestFlag == RequestHandlerFlag::RequestFlag) + { + std::cout << "\t\trequestFlag : Request\n"; + + // If the request type is GET + if (requestType == "GET") + { + std::cout << "\t\t\trequestType : GET\n"; + // GET operations are directly handled while sending the response + // in the sendLightResponse function + result = true; + } + else if (requestType == "PUT") + { + std::cout << "\t\t\trequestType : PUT\n"; + putFunc putFunction; + OCRepresentation rep = request->getResourceRepresentation(); + + putFunction = getPutFunction(request->getResourceUri()); + + // Do related operations related to PUT request + putFunction(rep); + result = true; + } + else if (requestType == "POST") + { + // POST request operations + } + else if (requestType == "DELETE") + { + // DELETE request operations + } + } + else if (requestFlag == RequestHandlerFlag::ObserverFlag) + { + std::cout << "\t\trequestFlag : Observer\n"; + } + } + else + { + std::cout << "Request invalid" << std::endl; + } + + return result; +} + +OCStackResult sendResponseForResource(std::shared_ptr< OCResourceRequest > pRequest) +{ + auto pResponse = std::make_shared< OC::OCResourceResponse >(); + + // Check for query params (if any) + QueryParamsMap queryParamsMap = pRequest->getQueryParameters(); + + pResponse->setRequestHandle(pRequest->getRequestHandle()); + pResponse->setResourceHandle(pRequest->getResourceHandle()); + + getFunc getFunction; + getFunction = getGetFunction(pRequest->getResourceUri()); + + OCRepresentation rep; + rep = getFunction(); + + auto findRes = queryParamsMap.find("if"); + + if (findRes != queryParamsMap.end()) + { + pResponse->setResourceRepresentation(rep, findRes->second); + } + else + { + pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE); + } + + pResponse->setErrorCode(200); + pResponse->setResponseResult(OC_EH_OK); + + return OCPlatform::sendResponse(pResponse); +} + +OCEntityHandlerResult entityHandlerForResource(std::shared_ptr< OCResourceRequest > request) +{ + std::cout << "\tIn Server CPP (entityHandlerForResource) entity handler:\n"; + OCEntityHandlerResult ehResult = OC_EH_ERROR; + + if (prepareResponseForResource(request)) + { + if (OC_STACK_OK == sendResponseForResource(request)) + { + ehResult = OC_EH_OK; + } + else + { + std::cout << "sendResponse failed." << std::endl; + } + } + else + { + std::cout << "PrepareResponse failed." << std::endl; + } + return ehResult; +} + +// callback handler on GET request +void onBootstrap(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) +{ + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "\n\nGET request was successful" << std::endl; + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + defaultRegionValue = rep.getValue< std::string >("regionValue"); + defaultTimeValue = rep.getValue< std::string >("timeValue"); + defaultCurrentTimeValue = rep.getValue< std::string >("currentTimeValue"); + defaultNetworkValue = rep.getValue< std::string >("networkValue"); + defaultIPAddressValue = rep.getValue< std::string >("IPAddressValue"); + defaultSecurityValue = rep.getValue< std::string >("securityValue"); + defaultModeValue = rep.getValue< std::string >("modeValue"); + defaultConfigurationValue = rep.getValue< std::string >("configurationValue"); + defaultFactorySetValue = rep.getValue< std::string >("factorySetValue"); + + std::cout << "\tregionValue : " << defaultRegionValue << std::endl; + std::cout << "\ttimeValue : " << defaultTimeValue << std::endl; + std::cout << "\tcurrentTimeValue : " << defaultCurrentTimeValue << std::endl; + std::cout << "\tnetworkValue : " << defaultNetworkValue << std::endl; + std::cout << "\tIPAddressValue : " << defaultIPAddressValue << std::endl; + std::cout << "\tsecurityValue : " << defaultSecurityValue << std::endl; + std::cout << "\tmodeValue : " << defaultModeValue << std::endl; + std::cout << "\tconfigurationValue : " << defaultConfigurationValue << std::endl; + std::cout << "\tfactorySetValue : " << defaultFactorySetValue << std::endl; + + } + else + { + std::cout << "onGET Response error: " << eCode << std::endl; + std::exit(-1); + } + isWaiting = 0; +} + +int main() +{ + //************************************************************** + // STEP 0 + // Create PlatformConfig object + PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos }; + + OCPlatform::Configure(cfg); + g_thingsmanager = new ThingsManager(); + //************************************************************** + + if (getuid() != 0) + { + std::cout << "NOTE: You may gain the root privilege (e.g, reboot)\n"; + std::cout << "NOTE: Now, you don't have it.\n"; + } + + try + { + // Perform app tasks + while (true) + { + + if (isWaiting > 0) + continue; + + isWaiting = 0; + + std::cout << endl << endl << "(0) Quit" << std::endl; + std::cout << "(1) Bootstrap" << std::endl; + std::cout << "(2) Create Configuration Resources" << std::endl; + + cin >> g_Steps; + // + if (g_Steps == 0) + break; + else if (g_Steps == 1) + { + if( g_thingsmanager->doBootstrap(&onBootstrap) == OC_STACK_OK) + isWaiting = 1; + else + std::cout << "A callback pointer of the function is NULL." << std::endl; + } + else if (g_Steps == 2) + { + myConfigurationCollection = new ConfigurationCollection(); + myConfigurationCollection->createResources(&entityHandlerForResource); + + myDiagnosticsCollection = new DiagnosticsCollection(); + myDiagnosticsCollection->createResources(&entityHandlerForResource); + + myFactorySetCollection = new FactorySetCollection(); + myFactorySetCollection->createResources(&entityHandlerForResource); + myDiagnosticsCollection->factoryReset = std::function < void() + > (std::bind(&ConfigurationCollection::factoryReset, + myConfigurationCollection)); + isWaiting = 1; + } + } + } + catch (OCException e) + { + std::cout << "Exception in main: " << e.what(); + } + + // No explicit call to stop the platform. + // When OCPlatform destructor is invoked, internally we do platform cleanup +} + diff --git a/service/things-manager/sampleapp/linux/configuration/makefile b/service/things-manager/sampleapp/linux/configuration/makefile new file mode 100644 index 000000000..37824a9f0 --- /dev/null +++ b/service/things-manager/sampleapp/linux/configuration/makefile @@ -0,0 +1,71 @@ +TGMROOT=../../../ +IOT_BASE=${TGMROOT}../../resource +RST_NAME=. +TARGET1=con-server +TARGET2=con-client +TARGET3=bootstrapserver + +OBJS = ConfigurationCollection.o DiagnosticsCollection.o FactorySetCollection.o con-server.o +SRCS = $(OBJS:.o=.c) + +# C++ type Compile Flag define. +CXX=g++ +CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl + +CXX_INC := -I../../ -I../../inc/ -I../../../sdk/inc/ -I../../../sdk/src/ +CXX_INC += -I${IOT_BASE}/include/ +CXX_INC += -I${IOT_BASE}/oc_logger/include +CXX_INC += -I${IOT_BASE}/csdk/stack/include +CXX_INC += -I${IOT_BASE}/csdk/ocsocket/include +CXX_INC += -I${IOT_BASE}/csdk/ocrandom/include +CXX_INC += -I${IOT_BASE}/csdk/logger/include +CXX_INC += -I${IOT_BASE}/dependencies/cereal/include + +CXX_LIB=-L"" + +CXX_SRCPATH=${wildcard ../../src/*.cpp} +CXX_SRCLIST=${notdir ${CXX_SRCPATH}} +CXX_USESRCS=${filter-out ${EXCLUDE_LIST}, ${CXX_SRCLIST}} +CXX_OBJLIST=${CXX_USESRCS:.cpp=.o} + + +TGM = ../../ +SDK = ${TGMROOT}sdk +TGM_INC = -I${TGMROOT}sdk/inc +SDK_LIB = ${TGMROOT}sdk/build/linux/libTGMSDKLibrary.a + +LIB_OC_LOGGER := $(IOT_BASE)/oc_logger/lib/oc_logger.a + +LD_LIB := $(IOT_BASE)/release/obj/liboc.a +LD_LIB += $(IOT_BASE)/csdk/linux/release/liboctbstack.a +LD_LIB += $(LIB_OC_LOGGER) + + +# Force metatargets to build: +.PHONY: all clean + +all: ${TARGET1} ${TARGET2} ${TARGET3} + +.cpp.o: + $(CXX) $(CXX_FLAGS) -c -o $@ $< $(CXX_INC) $(TGM_INC) + +$(TARGET1): $(OBJS) + $(CXX) $(CXX_FLAGS) -o $@ ${OBJS} $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +${TARGET2}: con-client.cpp + $(CXX) $(CXX_FLAGS) -o ${TARGET2} $< $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +${TARGET3}: bootstrapserver.cpp + $(CXX) $(CXX_FLAGS) -o ${TARGET3} $< $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + + +dep: + gccmakedep $(SRCS) + +clean: + rm -f -v *.o con-client + rm -f -v *.o con-server + rm -f -v *.o bootstrapserver + +#dep: +# gccmakedep $(SRCS) diff --git a/service/things-manager/sampleapp/linux/groupaction/SConscript b/service/things-manager/sampleapp/linux/groupaction/SConscript new file mode 100644 index 000000000..1ed0695af --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupaction/SConscript @@ -0,0 +1,35 @@ +## +# linux sample app build script +## + +Import('env') + +# Add third party libraries +lib_env = env.Clone() +SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env') +linux_sample_env = lib_env.Clone() + +###################################################################### +# Build flags +###################################################################### +linux_sample_env.AppendUnique(CPPPATH = ['include']) +linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/inc']) +linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/src']) +linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread']) +linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX']) +linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) +linux_sample_env.AppendUnique(LIBS = ['libTGMSDKLibrary', 'oc', 'octbstack', 'libcoap', 'liboc_logger', 'dl', 'pthread']) + + +###################################################################### +#build sampleapp +###################################################################### +groupserver = linux_sample_env.Program('groupserver', 'groupserver.cpp') +lightserver = linux_sample_env.Program('lightserver', 'lightserver.cpp') +bookmark = linux_sample_env.Program('bookmark', 'bookmark.cpp') +Alias("GroupServerApp", groupserver) +Alias("LightServerApp", lightserver) +Alias("BookmarkApp", bookmark) +env.AppendTarget('GroupServerApp') +env.AppendTarget('LightServerApp') +env.AppendTarget('BookmarkApp') diff --git a/service/things-manager/sampleapp/linux/groupaction/bookmark.cpp b/service/things-manager/sampleapp/linux/groupaction/bookmark.cpp new file mode 100644 index 000000000..6f67aef7f --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupaction/bookmark.cpp @@ -0,0 +1,235 @@ +//****************************************************************** +// +// Copyright 2014 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 <functional> +#include <pthread.h> + +#include "OCPlatform.h" +#include "OCApi.h" + +using namespace OC; +using namespace std; + +namespace PH = std::placeholders; + +unsigned int startedThread; +unsigned int gObservation; +pthread_t threadId; + +void* ObserveHandler(void *param); + +class BookmarkResource +{ + +private: + OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request) + { + OCEntityHandlerResult ehResult = OC_EH_ERROR; + + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag & RequestHandlerFlag::InitFlag) + { + cout << "\t\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + else if (requestFlag & RequestHandlerFlag::RequestFlag) + { + auto pResponse = std::make_shared< OC::OCResourceResponse >(); + pResponse->setRequestHandle(request->getRequestHandle()); + pResponse->setResourceHandle(request->getResourceHandle()); + + // If the request type is GET + if (requestType == "GET") + { + } + else if (requestType == "PUT") + { + cout << "\t\t\trequestType : PUT\n"; + } + else if (requestType == "POST") + { + // POST request operations + } + else if (requestType == "DELETE") + { + // DELETE request operations + } + + pResponse->setErrorCode(200); + pResponse->setResponseResult(OC_EH_OK); + pResponse->setResourceRepresentation(getRepresentation()); + if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) + { + ehResult = OC_EH_OK; + } + } + + if (requestFlag & RequestHandlerFlag::ObserverFlag) + { + cout << "\t\trequestFlag : Observer\n"; + + if (!startedThread) + { + pthread_create(&threadId, NULL, ObserveHandler, (void *) NULL); + startedThread = 1; + gObservation = 1; + } + + ehResult = OC_EH_OK; + } + } + else + { + std::cout << "Request invalid" << std::endl; + } + + return ehResult; + } + +public: + /// Constructor + BookmarkResource() + { + m_pressure = 0; + + m_BookmarkUri = "/core/bookmark"; // URI of the resource + m_BookmarkType = "core.bookmark"; // resource type name. In this case, it is light + + m_BookmarkInterface = DEFAULT_INTERFACE; // resource interface. + m_BookmarkHandle = 0; + } + + /// This function internally calls registerResource API. + void createResources() + { + EntityHandler cb = std::bind(&BookmarkResource::entityHandler, this, PH::_1); + + // This will internally create and register the resource. + OCStackResult result = OC::OCPlatform::registerResource(m_BookmarkHandle, m_BookmarkUri, + m_BookmarkType, m_BookmarkInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + cout << "Resource creation (bookmark) was unsuccessful\n"; + } + else + { + cout << "Resource URI : " << m_BookmarkUri << endl; + cout << "\tResource Type Name : " << m_BookmarkType << endl; + cout << "\tResource Interface : " << DEFAULT_INTERFACE << endl; + cout << "\tResource creation is successful with resource handle : " << m_BookmarkHandle + << endl; + } + } + + void setRepresentation(OCRepresentation& rep) + { + // AttributeMap attributeMap = rep.getAttributeMap(); + // if(rep.getValue("level", m_pressure) == true) + { + std::cout << m_pressure << endl; + } + } + + OCRepresentation getRepresentation() + { + OCRepresentation rep; + + rep.setValue("level", (int) m_pressure); + + return rep; + } + +public: + // Members of Bookmark + std::string m_BookmarkUri; + std::string m_BookmarkType; + std::string m_BookmarkInterface; + unsigned int m_pressure; + OCResourceHandle m_BookmarkHandle; +}; + +// Create the instance of the resource class (in this case instance of class 'BookmarkResource'). +BookmarkResource myBookmarkResource; + +void* ObserveHandler(void *param) +{ + while (startedThread) + { + sleep(1); + + cout << "input a integer(0:opened, 5:close) : "; + cin >> myBookmarkResource.m_pressure; + + if (myBookmarkResource.m_pressure == 0 || // When your book opened. + myBookmarkResource.m_pressure == 5) // When your book closed. + { + cout << "notifyObservers call!" << endl; + + OCStackResult result = OCPlatform::notifyAllObservers( + myBookmarkResource.m_BookmarkHandle); + + if (OC_STACK_NO_OBSERVERS == result) + { + cout << "No More observers, stopping notifications" << endl; + gObservation = 0; + startedThread = 0; + } + } + } + + return NULL; +} + +int main() +{ + // Create PlatformConfig object + + OC::PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0", + // By setting to "0.0.0.0", it binds to all available interfaces + 0,// Uses randomly available port + OC::QualityOfService::LowQos }; + + // Create a OCPlatform instance. + // Note: Platform creation is synchronous call. + try + { + + // Invoke createResource function of class bookmark. + myBookmarkResource.createResources(); + + // Perform app tasks + while (true) + { + // some tasks + } + } + catch (OCException e) + { + std::cout << "Exception in main: " << e.what(); + } +} diff --git a/service/things-manager/sampleapp/linux/groupaction/groupserver.cpp b/service/things-manager/sampleapp/linux/groupaction/groupserver.cpp new file mode 100644 index 000000000..47177c7a1 --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupaction/groupserver.cpp @@ -0,0 +1,433 @@ +//****************************************************************** +// +// Copyright 2014 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 <OCPlatform.h> +#include <OCApi.h> + +#include <functional> +#include <pthread.h> +#include <iostream> + +#include <ThingsManager.h> + +using namespace std; +using namespace OC; +using namespace OIC; +namespace PH = std::placeholders; + +bool isReady = false; + +OCResourceHandle resourceHandle; +std::vector< OCResourceHandle > resourceHandleVector; + +shared_ptr< OCResource > g_resource; +vector< string > lights; + +ThingsManager *thingsMgr = new ThingsManager(); + +void onGet(const HeaderOptions& opt, const OCRepresentation &rep, const int eCode); + +void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode); + +void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode); + +void onObserve(const HeaderOptions headerOptions, const OCRepresentation& rep, const int& eCode, + const int& sequenceNumber); + +void allBulbOn(); +void allBulbOff(); + +void foundResources(std::vector< std::shared_ptr< OC::OCResource > > listOfResource) +{ + + for (auto rsrc = listOfResource.begin(); rsrc != listOfResource.end(); ++rsrc) + { + std::string resourceURI = (*rsrc)->uri(); + std::string hostAddress = (*rsrc)->host(); + + if (resourceURI == "/a/light") + { + + cout << "\tResource URI : " << resourceURI << endl; + cout << "\tResource Host : " << hostAddress << endl; + + OCResourceHandle foundResourceHandle; + OCStackResult result = OCPlatform::registerResource(foundResourceHandle, (*rsrc)); + cout << "\tresource registed!" << endl; + if (result == OC_STACK_OK) + { + OCPlatform::bindResource(resourceHandle, foundResourceHandle); + resourceHandleVector.push_back(foundResourceHandle); + } + else + { + cout << "\tresource Error!" << endl; + } + + lights.push_back((hostAddress + resourceURI)); + } + } + + isReady = true; +} + +void foundResource(std::shared_ptr< OCResource > resource) +{ + std::string resourceURI; + std::string hostAddress; + + try + { + cout << "FOUND RESOURCE" << endl; + + if (resource) + { + resourceURI = resource->uri(); + hostAddress = resource->host(); + if (resourceURI == "/core/a/collection") + { + g_resource = resource; + + // g_resource->get("", DEFAULT_INTERFACE, QueryParamsMap(), onGet); + + printf("\tHOST :: %s\n", resource->host().c_str()); + } + else if (resourceURI == "/core/bookmark") + { + resource->observe(ObserveType::Observe, QueryParamsMap(), &onObserve); + } + + // p_platform.bindResource(resourceHandle, foundResourceHandle); + + } + } + catch (std::exception& e) + { + std::cout << "" << std::endl; + } +} + +void onGet(const HeaderOptions& opt, const OCRepresentation &rep, const int eCode) +{ + // std::vector<OCRepresentation> children = rep.getChildren(); + + // cout << "\n\n\nCHILD RESOURCE OF GROUP" << endl; + // for( auto iter = children.begin(); iter != children.end(); ++iter ) + // { + // lights.push_back((*iter).getUri()); + // cout << "\tURI :: " << (*iter).getUri() << endl; + // } +} + +void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) +{ + printf("\nonPut\n"); +} + +void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) +{ + printf("\nonPost\n"); + + if (rep.hasAttribute("ActionSet")) + { + std::string plainText; + + if (rep.getValue("ActionSet", plainText)) + { + ActionSet *actionset = thingsMgr->getActionSetfromString(plainText); + if (actionset != NULL) + { + cout << endl << "\tACTIONSET NAME :: " << actionset->actionsetName << endl; + for (auto actIter = actionset->listOfAction.begin(); + actIter != actionset->listOfAction.end(); ++actIter) + { + cout << "\t\tTARGET :: " << (*actIter)->target << endl; + + for (auto capaIter = (*actIter)->listOfCapability.begin(); + capaIter != (*actIter)->listOfCapability.end(); ++capaIter) + { + cout << "\t\t\t" << (*capaIter)->capability << " :: " << (*capaIter)->status + << endl; + } + } + } + delete actionset; + } + + // printf( "\tPlain Text :: %s\n", plainText.c_str() ); + } + else if (rep.hasAttribute("DoAction")) + { + std::string plainText; + if (rep.getValue("DoAction", plainText)) + { + cout << "\t" << plainText << endl; + } + } + else + { + + } +} + +void allBulbOff() +{ + OCRepresentation rep; + + rep.setValue("DoAction", std::string("AllBulbOff")); + + if (g_resource) + { + g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(), &onPost); + } +} + +void allBulbOn() +{ + OCRepresentation rep; + + rep.setValue("DoAction", std::string("AllBulbOn")); + + if (g_resource) + { + g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(), &onPost); + } +} + +void onObserve(const HeaderOptions headerOptions, const OCRepresentation& rep, const int& eCode, + const int& sequenceNumber) +{ + if (eCode == OC_STACK_OK) + { + int level; + + std::cout << "OBSERVE RESULT:" << std::endl; + std::cout << "\tSequenceNumber: " << sequenceNumber << endl; + + if (rep.getValue("level", level)) + { + if (level == 0) + { + allBulbOn(); + } + else + { + allBulbOff(); + } + } + std::cout << "\tlevel: " << level << std::endl; + } + else + { + std::cout << "onObserve Response error: " << eCode << std::endl; + std::exit(-1); + } +} + +void createActionSet_AllBulbOff() +{ + string actionsetDesc; + ActionSet *allBulbOff = new ActionSet(); + allBulbOff->actionsetName = "AllBulbOff"; + + for (auto iter = lights.begin(); iter != lights.end(); ++iter) + { + Action *action = new Action(); + action->target = (*iter); + + Capability *capa = new Capability(); + capa->capability = "power"; + capa->status = "off"; + + action->listOfCapability.push_back(capa); + allBulbOff->listOfAction.push_back(action); + } + // actionsetDesc = thingsMgr->getStringFromActionSet(allBulbOff); + + // cout << "ActionSet :: " << actionsetDesc << endl; + + // OCRepresentation rep; + // rep.setValue("ActionSet", actionsetDesc); + + if (g_resource) + { + thingsMgr->addActionSet(g_resource, allBulbOff, onPut); + // g_resource->put("a.collection", GROUP_INTERFACE, rep, + // QueryParamsMap(), &onPut); + } + + delete allBulbOff; +} + +void createActionSet_AllBulbOn() +{ + string actionsetDesc; + ActionSet *allBulbOff = new ActionSet(); + allBulbOff->actionsetName = "AllBulbOn"; + + for (auto iter = lights.begin(); iter != lights.end(); ++iter) + { + Action *action = new Action(); + action->target = (*iter); + + Capability *capa = new Capability(); + capa->capability = "power"; + capa->status = "on"; + + action->listOfCapability.push_back(capa); + allBulbOff->listOfAction.push_back(action); + } + // actionsetDesc = thingsMgr->getStringFromActionSet(allBulbOff); + + // cout << "ActionSet :: " << actionsetDesc << endl; + + // OCRepresentation rep; + // rep.setValue("ActionSet", actionsetDesc); + + if (g_resource) + { + thingsMgr->addActionSet(g_resource, allBulbOff, onPut); + // g_resource->put("a.collection", GROUP_INTERFACE, rep, + // QueryParamsMap(), &onPut); + } + + delete allBulbOff; +} + +int main() +{ + PlatformConfig config + { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos }; + + try + { + string resourceURI = "/core/a/collection"; + string resourceTypeName = "a.collection"; + string resourceInterface = BATCH_INTERFACE; + OCPlatform::Configure(config); + + // Find lights for group creation. + vector< string > types; + types.push_back("core.light"); + thingsMgr->findCandidateResources(types, &foundResources, 5); + + OCPlatform::registerResource(resourceHandle, resourceURI, resourceTypeName, + resourceInterface, NULL, + //&entityHandler, // entityHandler + OC_DISCOVERABLE); + + cout << "registerResource is called." << endl; + + OCPlatform::bindInterfaceToResource(resourceHandle, GROUP_INTERFACE); + OCPlatform::bindInterfaceToResource(resourceHandle, DEFAULT_INTERFACE); + + bool isRun = true; + + while (isRun) + { + while (isReady) + { + int n; + + cout << endl; + cout << "1 :: CREATE ACTIONSET 2 :: EXECUTE ACTIONSET(ALLBULBON)" + << "3 :: EXECUTE ACTIONSET(ALLBULBOFF)" << endl; + cout << "4 :: GET ACTIONSET 5 :: DELETE ACTIONSET 6 :: QUIT" << endl; + cout << "9 :: FIND GROUP 0 :: FIND BOOKMARK TO OBSERVE" << endl; + + fflush(stdin); + cin >> n; + + if (n == 9) + { + OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=a.collection", + &foundResource); + } + else if (n == 0) + { + OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.bookmark", + &foundResource); + } + else if (n == 1) + { + + // Craete Action Set + // "AllBulbOff" + //"movieTime*uri=coap://10.251.44.228:49858/a/light|power=10"; + createActionSet_AllBulbOff(); + createActionSet_AllBulbOn(); + + } + else if (n == 2) + { + + allBulbOn(); + // thingsMgr->executeActionSet(g_resource, "AllBulbOn", onPost); + + } + else if (n == 3) + { + + allBulbOff(); + // thingsMgr->executeActionSet(g_resource, "AllBulbOff", onPost); + + } + else if (n == 4) + { + // OCRepresentation rep; + + // rep.setValue("GetActionSet", std::string("AllBulbOff")); + + // if(g_resource) + // { + // g_resource->post("a.collection", GROUP_INTERFACE, rep, + // QueryParamsMap(), &onPost); + // } + + thingsMgr->getActionSet(g_resource, "AllBulbOff", onPost); + } + else if (n == 5) + { + // OCRepresentation rep; + + // rep.setValue("DelActionSet", std::string("AllBulbOff")); + + // if(g_resource) + // { + // g_resource->put("a.collection", GROUP_INTERFACE, rep, + // QueryParamsMap(), &onPut); + // } + thingsMgr->deleteActionSet(g_resource, "AllBulbOff", onPut); + } + else if (n == 6) + { + isRun = false; + break; + } + } + } + } + catch (OCException& e) + { + + } + + return 0; +} diff --git a/service/things-manager/sampleapp/linux/groupaction/lightserver.cpp b/service/things-manager/sampleapp/linux/groupaction/lightserver.cpp new file mode 100644 index 000000000..d73bf5e9e --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupaction/lightserver.cpp @@ -0,0 +1,337 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample provides steps to define an interface for a resource +/// (properties and methods) and host this resource on the server. +/// + +#include <functional> + +#include <pthread.h> +#include <mutex> +#include <condition_variable> + +#include "OCPlatform.h" +#include "OCApi.h" + +using namespace OC; +using namespace std; +namespace PH = std::placeholders; + +int gObservation = 0; +void * ChangeLightRepresentation(void *param); +void * handleSlowResponse(void *param, std::shared_ptr< OCResourceRequest > pRequest); + +// Specifies secure or non-secure +// false: non-secure resource +// true: secure resource +bool isSecure = false; + +/// Specifies whether Entity handler is going to do slow response or not +bool isSlowResponse = false; + +// Forward declaring the entityHandler + +/// This class represents a single resource named 'lightResource'. This resource has +/// two simple properties named 'state' and 'power' + +class LightResource +{ + +public: + /// Access this property from a TB client + std::string m_power; + std::string m_lightUri; + OCResourceHandle m_resourceHandle; + OCRepresentation m_lightRep; + +public: + /// Constructor + LightResource() : + m_power(""), m_lightUri("/a/light"), m_resourceHandle(0) + { + // Initialize representation + m_lightRep.setUri(m_lightUri); + + m_lightRep.setValue("power", m_power); + } + + /* Note that this does not need to be a member function: for classes you do not have + access to, you can accomplish this with a free function: */ + + /// This function internally calls registerResource API. + void createResource() + { + std::string resourceURI = m_lightUri; //URI of the resource + std::string resourceTypeName = "core.light"; //resource type name. In this case, it is light + std::string resourceInterface = DEFAULT_INTERFACE; // resource interface. + + EntityHandler cb = std::bind(&LightResource::entityHandler, this, PH::_1); + + // This will internally create and register the resource. + OCStackResult result = OCPlatform::registerResource(m_resourceHandle, resourceURI, + resourceTypeName, resourceInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE); + + if (OC_STACK_OK != result) + { + cout << "Resource creation was unsuccessful\n"; + } + else + { + cout << "Resource URI : " << resourceURI << endl; + cout << "\tResource Type Name : " << resourceTypeName << endl; + cout << "\tResource Interface : " << DEFAULT_INTERFACE << endl; + cout << "\tResource creation is successful with resource handle : " << m_resourceHandle + << endl; + } + } + + OCResourceHandle getHandle() + { + return m_resourceHandle; + } + + // Puts representation. + // Gets values from the representation and + // updates the internal state + void put(OCRepresentation& rep) + { + try + { + if (rep.getValue("power", m_power)) + { + cout << "\t\t\t\t" << "power: " << m_power << endl; + } + else + { + cout << "\t\t\t\t" << "power not found in the representation" << endl; + } + } + catch (exception& e) + { + cout << e.what() << endl; + } + + } + + // Post representation. + // Post can create new resource or simply act like put. + // Gets values from the representation and + // updates the internal state + OCRepresentation post(OCRepresentation& rep) + { + put(rep); + return get(); + } + + // gets the updated representation. + // Updates the representation with latest internal state before + // sending out. + OCRepresentation get() + { + m_lightRep.setValue("power", m_power); + + return m_lightRep; + } + + void addType(const std::string& type) const + { + OCStackResult result = OCPlatform::bindTypeToResource(m_resourceHandle, type); + if (OC_STACK_OK != result) + { + cout << "Binding TypeName to Resource was unsuccessful\n"; + } + } + + void addInterface(const std::string& interface) const + { + OCStackResult result = OCPlatform::bindInterfaceToResource(m_resourceHandle, interface); + if (OC_STACK_OK != result) + { + cout << "Binding TypeName to Resource was unsuccessful\n"; + } + } + +private: +// This is just a sample implementation of entity handler. +// Entity handler can be implemented in several ways by the manufacturer + OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request) + { + cout << "\tIn Server CPP entity handler:\n"; + OCEntityHandlerResult ehResult = OC_EH_ERROR; + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag & RequestHandlerFlag::InitFlag) + { + cout << "\t\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + if (requestFlag & RequestHandlerFlag::RequestFlag) + { + cout << "\t\trequestFlag : Request\n"; + auto pResponse = std::make_shared< OC::OCResourceResponse >(); + pResponse->setRequestHandle(request->getRequestHandle()); + pResponse->setResourceHandle(request->getResourceHandle()); + + // If the request type is GET + if (requestType == "GET") + { + cout << "\t\t\trequestType : GET\n"; + if (isSlowResponse) // Slow response case + { + static int startedThread = 0; + if (!startedThread) + { + std::thread t(handleSlowResponse, (void *) this, request); + startedThread = 1; + t.detach(); + } + ehResult = OC_EH_SLOW; + } + else // normal response case. + { + pResponse->setErrorCode(200); + pResponse->setResponseResult(OC_EH_OK); + pResponse->setResourceRepresentation(get()); + if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) + { + ehResult = OC_EH_OK; + } + } + } + else if (requestType == "PUT") + { + cout << "\t\t\trequestType : PUT\n"; + OCRepresentation rep = request->getResourceRepresentation(); + + // Do related operations related to PUT request + // Update the lightResource + put(rep); + pResponse->setErrorCode(200); + pResponse->setResponseResult(OC_EH_OK); + pResponse->setResourceRepresentation(get()); + if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) + { + ehResult = OC_EH_OK; + } + } + else if (requestType == "POST") + { + cout << "\t\t\trequestType : POST\n"; + + OCRepresentation rep = request->getResourceRepresentation(); + + // Do related operations related to POST request + OCRepresentation rep_post = post(rep); + pResponse->setResourceRepresentation(rep_post); + pResponse->setErrorCode(200); + if (rep_post.hasAttribute("createduri")) + { + pResponse->setResponseResult(OC_EH_RESOURCE_CREATED); + pResponse->setNewResourceUri( + rep_post.getValue< std::string >("createduri")); + } + + if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) + { + ehResult = OC_EH_OK; + } + } + else if (requestType == "DELETE") + { + // DELETE request operations + } + } + } + else + { + std::cout << "Request invalid" << std::endl; + } + + return ehResult; + } +}; + +void * handleSlowResponse(void *param, std::shared_ptr< OCResourceRequest > pRequest) +{ + // This function handles slow response case + LightResource* lightPtr = (LightResource*) param; + // Induce a case for slow response by using sleep + std::cout << "SLOW response" << std::endl; + sleep(10); + + auto pResponse = std::make_shared< OC::OCResourceResponse >(); + pResponse->setRequestHandle(pRequest->getRequestHandle()); + pResponse->setResourceHandle(pRequest->getResourceHandle()); + pResponse->setResourceRepresentation(lightPtr->get()); + pResponse->setErrorCode(200); + pResponse->setResponseResult(OC_EH_OK); + + // Set the slow response flag back to false + isSlowResponse = false; + OCPlatform::sendResponse(pResponse); + return NULL; +} + +int main(int argc, char* argv[]) +{ + // Create PlatformConfig object + PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0", + // By setting to "0.0.0.0", it binds to all available interfaces + 0,// Uses randomly available port + OC::QualityOfService::LowQos }; + + OCPlatform::Configure(cfg); + try + { + // Create the instance of the resource class + // (in this case instance of class 'LightResource'). + LightResource myLight; + + // Invoke createResource function of class light. + myLight.createResource(); + + // A condition variable will free the mutex it is given, then do a non- + // intensive block until 'notify' is called on it. In this case, since we + // don't ever call cv.notify, this should be a non-processor intensive version + // of while(true); + std::mutex blocker; + std::condition_variable cv; + std::unique_lock < std::mutex > lock(blocker); + cv.wait(lock); + } + catch (OCException e) + { + //log(e.what()); + } + + // No explicit call to stop the platform. + // When OCPlatform::destructor is invoked, internally we do platform cleanup + + return 0; +} diff --git a/service/things-manager/sampleapp/linux/groupaction/makefile b/service/things-manager/sampleapp/linux/groupaction/makefile new file mode 100644 index 000000000..6604c3cdd --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupaction/makefile @@ -0,0 +1,70 @@ + +TGMROOT=../../../ +IOT_BASE=${TGMROOT}../../resource +RST_NAME=. + + + +# C++ type Compile Flag define. +CXX=g++ +CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl + +DEPEND_DIR:= ../../../../../resource/dependencies/ +CEREAL_DIR:= $(DEPEND_DIR)/cereal + +CXX_INC := -I../../ -I../../inc/ +CXX_INC += -I${IOT_BASE}/include/ +CXX_INC += -I${IOT_BASE}/oc_logger/include +CXX_INC += -I${IOT_BASE}/csdk/stack/include +CXX_INC += -I${IOT_BASE}/csdk/ocsocket/include +CXX_INC += -I${IOT_BASE}/csdk/ocrandom/include +CXX_INC += -I${IOT_BASE}/csdk/logger/include +CXX_INC += -I$(CEREAL_DIR)/include +CXX_INC += -I../../../sdk/inc +CXX_INC += -I../../../sdk/src + + +CXX_LIB=-L"" + +CXX_SRCPATH=${wildcard ../../src/*.cpp} +CXX_SRCLIST=${notdir ${CXX_SRCPATH}} +CXX_USESRCS=${filter-out ${EXCLUDE_LIST}, ${CXX_SRCLIST}} +CXX_OBJLIST=${CXX_USESRCS:.cpp=.o} + + +TGM = ../../ +SDK = ${TGMROOT}sdk +TGM_INC = -I${TGMROOT}sdk/inc +SDK_LIB = ${TGMROOT}sdk/build/linux/libTGMSDKLibrary.a + +LIB_OC_LOGGER := $(IOT_BASE)/oc_logger/lib/oc_logger.a + +LD_LIB := $(IOT_BASE)/release/obj/liboc.a +LD_LIB += $(IOT_BASE)/csdk/linux/release/liboctbstack.a +LD_LIB += $(LIB_OC_LOGGER) + + +# Force metatargets to build: +.PHONY: all clean + +all: bookmark lightserver groupserver + +#groupclient +bookmark: ./bookmark.cpp + $(CXX) $(CXX_FLAGS) -o bookmark ./bookmark.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +lightserver: ./lightserver.cpp + $(CXX) $(CXX_FLAGS) -o lightserver ./lightserver.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +groupserver: ./groupserver.cpp + $(CXX) $(CXX_FLAGS) -o groupserver ./groupserver.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +# groupclient: ./groupclient.cpp +# $(CXX) $(CXX_FLAGS) -o groupclient ./groupclient.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +clean: + rm -f -v *.o ${TARGET} + rm -f groupserver + rm -f groupclient + rm -f lightserver + rm -f bookmark diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/SConscript b/service/things-manager/sampleapp/linux/groupsyncaction/SConscript new file mode 100644 index 000000000..25d9b492e --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupsyncaction/SConscript @@ -0,0 +1,38 @@ +## +# linux sample app build script +## + +Import('env') + +# Add third party libraries +lib_env = env.Clone() +SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env') +linux_sample_env = lib_env.Clone() + +###################################################################### +# Build flags +###################################################################### +linux_sample_env.AppendUnique(CPPPATH = ['include']) +linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/inc']) +linux_sample_env.AppendUnique(CPPPATH = ['../../../sdk/src']) +linux_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread']) +linux_sample_env.AppendUnique(CPPDEFINES = ['LINUX']) +linux_sample_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) +linux_sample_env.AppendUnique(LIBS = ['libTGMSDKLibrary', 'oc', 'octbstack', 'libcoap', 'liboc_logger', 'dl', 'pthread']) + + +###################################################################### +#build sampleapp +###################################################################### +group = linux_sample_env.Program('group', 'group.cpp') +musicplayer = linux_sample_env.Program('musicplayer', 'musicplayer.cpp') +phone = linux_sample_env.Program('phone', 'phone.cpp') +speaker = linux_sample_env.Program('speaker', 'speaker.cpp') +Alias("GroupApp", group) +Alias("ConCleintApp", musicplayer) +Alias("PhoneApp", phone) +Alias("SpeakerApp", speaker) +env.AppendTarget('GroupApp') +env.AppendTarget('MusicplayerApp') +env.AppendTarget('PhoneApp') +env.AppendTarget('SpeakerApp') diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/group.cpp b/service/things-manager/sampleapp/linux/groupsyncaction/group.cpp new file mode 100644 index 000000000..d8b1082c8 --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupsyncaction/group.cpp @@ -0,0 +1,223 @@ +//****************************************************************** +// +// Copyright 2014 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 <string> +#include <cstdlib> +#include <pthread.h> +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" + +using namespace OC; +using namespace OIC; + +static ThingsManager* gThingManager = NULL; + +static std::vector< OCResourceHandle > gResourceHandleList; + +static std::string collectionResourceType = "core.group"; + +void onFindResource(std::shared_ptr< OCResource > resource) +{ + cout << "onFindResource" << endl; + + if (resource) + { + OCResourceHandle resourceHandle; + OCStackResult result = OCPlatform::registerResource(resourceHandle, resource); + if (OC_STACK_OK == result) + { + cout << "onFindResource : Resource creation was successful\n"; + } + else + { + cout << "onFindResource : Resource creation was unsuccessful\n"; + return; + } + + result = gThingManager->joinGroup(collectionResourceType, resourceHandle); + if (OC_STACK_OK == result) + { + cout << "onFindResource : Joining group was successful\n"; + } + else + { + cout << "onFindResource : Joining group was unsuccessful\n"; + + OCPlatform::unregisterResource(resourceHandle); + return; + } + + gResourceHandleList.push_back(resourceHandle); + } + else + { + cout << "onFindResource : There is no found resource." << endl; + } +} + +int main(int argc, char* argv[]) +{ + + // Create PlatformConfig object + PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Both/*OC::ModeType::Server*/, "0.0.0.0", 0, + OC::QualityOfService::LowQos }; + + OCPlatform::Configure(cfg); + gThingManager = new ThingsManager(); + + int selectedMenu; + OCStackResult result; + + try + { + while (true) + { + // some operations + cout << "(1) CREATE GROUP " << endl; + cout << "(11) FIND MUSIC PLAYER & JOIN GROUP | (12) FIND SPEAKER & JOIN GROUP" << endl; + cout << "(21) LEAVE GROUP - MUSIC PLAYER | (22) LEAVE GROUP - SPEAKER" << endl; + cout << "(31) DELETE GROUP " << endl; + + std::cin >> selectedMenu; + + if (selectedMenu == 1) + { + result = gThingManager->createGroup(collectionResourceType); + if (OC_STACK_OK == result) + { + cout << "Group creation was successful\n"; + } + else + { + cout << "Group creation was unsuccessful\n"; + } + } + else if (selectedMenu == 11) + { + result = OCPlatform::findResource("", + "coap://224.0.1.187/oc/core?rt=core.musicplayer", onFindResource); + if (OC_STACK_OK == result) + { + cout << "Finding music player was successful\n"; + } + else + { + cout << "Finding music player was unsuccessful\n"; + } + } + else if (selectedMenu == 12) + { + result = OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.speaker", + onFindResource); + if (OC_STACK_OK == result) + { + cout << "Finding speaker was successful\n"; + } + else + { + cout << "Finding speaker was unsuccessful\n"; + } + } + else if (selectedMenu == 21) + { + std::vector< OCResourceHandle >::iterator It; + OCResourceHandle resourceHandle; + for (It = gResourceHandleList.begin(); It != gResourceHandleList.end(); ++It) + { + resourceHandle = (*It); + std::string mpType = "core.musicplayer"; + std::string type = OCGetResourceTypeName(resourceHandle, 0); + if (0 == mpType.compare(type)) + { + result = gThingManager->leaveGroup(collectionResourceType, resourceHandle); + if (OC_STACK_OK == result) + { + cout << "Leaving group of music player was successful\n"; + } + else + { + cout << "Leaving group of music player was unsuccessful\n"; + } + break; + } + } + + gResourceHandleList.erase(It); + result = OCPlatform::unregisterResource(resourceHandle); + if (OC_STACK_OK == result) + { + cout << "Unregistering music player was successful\n"; + } + else + { + cout << "Unregistering music player was unsuccessful\n"; + } + } + else if (selectedMenu == 22) + { + std::vector< OCResourceHandle >::iterator It; + OCResourceHandle resourceHandle; + for (It = gResourceHandleList.begin(); It != gResourceHandleList.end(); ++It) + { + resourceHandle = (*It); + std::string mpType = "core.speaker"; + std::string type = OCGetResourceTypeName(resourceHandle, 0); + if (0 == mpType.compare(type)) + { + result = gThingManager->leaveGroup(collectionResourceType, resourceHandle); + if (OC_STACK_OK == result) + { + cout << "Leaving group of speaker was successful\n"; + } + else + { + cout << "Leaving group of speaker was unsuccessful\n"; + } + break; + } + } + + gResourceHandleList.erase(It); + result = OCPlatform::unregisterResource(resourceHandle); + if (OC_STACK_OK == result) + { + cout << "Unregistering speaker was successful\n"; + } + else + { + cout << "Unregistering speaker was unsuccessful\n"; + } + } + else if (selectedMenu == 31) + { + gThingManager->deleteGroup(collectionResourceType); + } + } + } + catch (OCException& e) + { + //log(e.what()); + } + + return 0; +} + diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/makefile b/service/things-manager/sampleapp/linux/groupsyncaction/makefile new file mode 100644 index 000000000..0ee1e5ccb --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupsyncaction/makefile @@ -0,0 +1,65 @@ + +TGMROOT=../../../ +IOT_BASE=${TGMROOT}../../resource +RST_NAME=. +TARGET1=group +TARGET2=phone +TARGET3=musicplayer +TARGET4=speaker +BUILD:=release + +# C++ type Compile Flag define. +CXX=g++ +CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl + +CXX_INC := -I../../ -I../../inc/ -I../../../sdk/inc/ -I../../../sdk/src/ +CXX_INC += -I${IOT_BASE}/include/ +CXX_INC += -I${IOT_BASE}/oc_logger/include +CXX_INC += -I${IOT_BASE}/csdk/stack/include +CXX_INC += -I${IOT_BASE}/csdk/ocsocket/include +CXX_INC += -I${IOT_BASE}/csdk/ocrandom/include +CXX_INC += -I${IOT_BASE}/csdk/logger/include +CXX_INC += -I${IOT_BASE}/dependencies/cereal/include + +CXX_LIB=-L"" + +CXX_SRCPATH=${wildcard ../../src/*.cpp} +CXX_SRCLIST=${notdir ${CXX_SRCPATH}} +CXX_USESRCS=${filter-out ${EXCLUDE_LIST}, ${CXX_SRCLIST}} +CXX_OBJLIST=${CXX_USESRCS:.cpp=.o} + + +TGM = ../../ +SDK = ${TGMROOT}sdk +TGM_INC = -I${TGMROOT}sdk/inc +SDK_LIB = ${TGMROOT}sdk/build/linux/libTGMSDKLibrary.a + +LIB_OC_LOGGER := $(IOT_BASE)/oc_logger/lib/oc_logger.a + +LD_LIB := $(IOT_BASE)/$(BUILD)/obj/liboc.a +LD_LIB += $(IOT_BASE)/csdk/linux/$(BUILD)/liboctbstack.a +LD_LIB += $(LIB_OC_LOGGER) + + +# Force metatargets to build: +.PHONY: all clean + +all: ${TARGET1} ${TARGET2} ${TARGET3} ${TARGET4} + +${TARGET1}: ./group.cpp + $(CXX) $(CXX_FLAGS) -o ${TARGET1} ./group.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +${TARGET2}: ./phone.cpp + $(CXX) $(CXX_FLAGS) -o ${TARGET2} ./phone.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +${TARGET3}: ./musicplayer.cpp + $(CXX) $(CXX_FLAGS) -o ${TARGET3} ./musicplayer.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +${TARGET4}: ./speaker.cpp + $(CXX) $(CXX_FLAGS) -o ${TARGET4} ./speaker.cpp $(CXX_INC) ${LD_LIB} $(TGM_INC) $(SDK_LIB) + +clean: + rm -f -v *.o ${TARGET1} + rm -f -v *.o ${TARGET2} + rm -f -v *.o ${TARGET3} + rm -f -v *.o ${TARGET4} diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/musicplayer.cpp b/service/things-manager/sampleapp/linux/groupsyncaction/musicplayer.cpp new file mode 100644 index 000000000..9a898a3db --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupsyncaction/musicplayer.cpp @@ -0,0 +1,163 @@ +//****************************************************************** +// +// Copyright 2014 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 <string> +#include <cstdlib> +#include <pthread.h> +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" + +using namespace OC; + +OCEntityHandlerResult mpEntityHandler(const std::shared_ptr< OCResourceRequest > request) +{ + cout << "mpEntityHandler:\n"; + + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + std::string action; + + if (requestFlag == RequestHandlerFlag::InitFlag) + { + cout << "\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + else if (requestFlag == RequestHandlerFlag::RequestFlag) + { + cout << "\trequestFlag : Request\n"; + + OCRepresentation rp = request->getResourceRepresentation(); + + // If the request type is GET + if (requestType == "GET") + { + cout << "\t\trequestType : GET\n"; + } + else if (requestType == "PUT") + { + cout << "\t\trequestType : PUT\n"; + + action = rp.getValue< std::string >("play"); + cout << "\t\t\tplay : " << action << endl; + } + else if (requestType == "POST") + { + cout << "\t\trequestType : POST\n"; + } + else if (requestType == "DELETE") + { + cout << "\t\trequestType : DELETE\n"; + } + } + else if (requestFlag == RequestHandlerFlag::ObserverFlag) + { + cout << "\trequestFlag : Observer\n"; + } + } + else + { + cout << "Request invalid" << endl; + } + + return OC_EH_OK; +} + +int main(int argc, char* argv[]) +{ + // Create PlatformConfig object + PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos }; + + OCPlatform::Configure(cfg); + + int selectedMenu; + OCStackResult result; + OCResourceHandle mpResourceHandle = NULL; + + try + { + while (true) + { + // some operations + cout << "(1) CREATE MUSIC PLAYER | (2) DELETE MUSIC PLAYER" << endl; + + std::cin >> selectedMenu; + + if (selectedMenu == 1) + { + if (mpResourceHandle) + { + cout << "Music player resource is registered already." << endl; + continue; + } + + std::string resourceURi = "/core/musicplayer"; + std::string resourceTypeName = "core.musicplayer"; + std::string resourceInterface = DEFAULT_INTERFACE; + + result = OCPlatform::registerResource(mpResourceHandle, resourceURi, + resourceTypeName, resourceInterface, mpEntityHandler, + OC_DISCOVERABLE | OC_OBSERVABLE); + if (OC_STACK_OK == result) + { + cout << "To register music player resource was successful\n"; + } + else + { + cout << "To register music player resource was unsuccessful\n"; + } + } + else if (selectedMenu == 2) + { + if (NULL == mpResourceHandle) + { + cout + << "Error! No resource to unregister. Register resource first!" + << endl; + continue; + } + + result = OCPlatform::unregisterResource(mpResourceHandle); + if (OC_STACK_OK == result) + { + cout << "To unregister music player resource was successful\n"; + } + else + { + cout << "To unregister music player resource was unsuccessful\n"; + } + + mpResourceHandle = NULL; + } + } + } + catch (OCException& e) + { + //log(e.what()); + } + + return 0; +} + diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/phone.cpp b/service/things-manager/sampleapp/linux/groupsyncaction/phone.cpp new file mode 100644 index 000000000..57494d086 --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupsyncaction/phone.cpp @@ -0,0 +1,478 @@ +//****************************************************************** +// +// Copyright 2014 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 <string> +#include <cstdlib> +#include <pthread.h> +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" + +using namespace OC; +using namespace OIC; + +static ThingsManager* gThingManager = NULL; + +static OCResourceHandle gPhoneResourceHandle = NULL; + +static std::shared_ptr< OCResource > gFindGroup = NULL; + +static std::string collectionResourceType = "core.group"; + +static ActionSet* gPlayStart; + +static ActionSet* gPlayStop; + +void onFindGroup(std::shared_ptr< OCResource > resource) +{ + if (resource) + { + if (NULL == gPhoneResourceHandle) + { + cout + << "onFindGroup : Error! No resource to join group. Register resource first!" + << endl; + return; + } + + if (gFindGroup) + { + cout << "onFindGroup : Found group is already saved." << endl; + } + else + { + cout << "onFindGroup : Found group is saved now." << endl; + gFindGroup = resource; + } + + gThingManager->joinGroup(gFindGroup, gPhoneResourceHandle); + } + else + { + cout << "onFindGroup : Resource is invalid. So a new Group Resource has to be created." + << endl; + } +} + +void onAction(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) +{ + if (eCode == OC_STACK_OK) + { + cout << "onAction" << endl; + } + else + { + cout << "onAction : error - " << eCode << endl; + } +} + +void onGetChild(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) +{ + if (eCode == OC_STACK_OK) + { + gPlayStart = new ActionSet(); + gPlayStop = new ActionSet(); + + gPlayStart->actionsetName = "playstart"; + gPlayStop->actionsetName = "playstop"; + + std::vector< OCRepresentation > childList = rep.getChildren(); + OCRepresentation child; + std::string resourceURI; + + QueryParamsMap query; + OCRepresentation rep; + std::string playStart; + std::string playStop; + + std::vector< std::string > types; + std::string resType; + + OCStackResult result; + + for (unsigned int i = 0; i < childList.size(); ++i) + { +// cout << "\n\tchild resource - " << i + 1 << endl; + + child = childList.at(i); + resourceURI = child.getUri(); + +// cout << "\t\tURI of the resource: " << resourceURI << endl; + +// cout << "\t\tList of resource types: " << endl; + + types = child.getResourceTypes(); + + for (unsigned int j = 0; j < types.size(); ++j) + { + resType = types.at(j); +// cout << "\t\t\t" << resType << endl; + + if (std::string::npos != resType.find("musicplayer")) + { + Capability *pStartCapa = new Capability; + pStartCapa->capability = "play"; + pStartCapa->status = "on"; + + Action* pPlayStart = new Action(); + pPlayStart->target = resourceURI; + pPlayStart->listOfCapability.push_back(pStartCapa); + + gPlayStart->listOfAction.push_back(pPlayStart); + + Capability *pStopCapa = new Capability; + pStopCapa->capability = "play"; + pStopCapa->status = "off"; + + Action* pPlayStop = new Action(); + pPlayStop->target = resourceURI; + pPlayStop->listOfCapability.push_back(pStopCapa); + + gPlayStop->listOfAction.push_back(pPlayStop); + } + else if (std::string::npos != resType.find("speaker")) + { + Capability *pStartCapa = new Capability; + pStartCapa->capability = "volume"; + pStartCapa->status = "50"; + + Action* pPlayStart = new Action(); + pPlayStart->target = resourceURI; + pPlayStart->listOfCapability.push_back(pStartCapa); + + gPlayStart->listOfAction.push_back(pPlayStart); + + Capability *pStopCapa = new Capability; + pStopCapa->capability = "volume"; + pStopCapa->status = "0"; + + Action* pPlayStop = new Action(); + pPlayStop->target = resourceURI; + pPlayStop->listOfCapability.push_back(pStopCapa); + + gPlayStop->listOfAction.push_back(pPlayStop); + } + } + } + +// std::string temp = gThingManager->getStringFromActionSet (gPlayStart); +// cout << "play start - " << temp << endl; + +// temp = gThingManager->getStringFromActionSet (gPlayStop); +// cout << "play stop - " << temp << endl; + + if (0 == gPlayStart->listOfAction.empty()) + { + result = gThingManager->addActionSet(gFindGroup, gPlayStart, onAction); + if (OC_STACK_OK == result) + { + cout << "addActionSet(gPlayStart) was successful\n"; + } + else + { + cout << "addActionSet(gPlayStart) was unsuccessful. result = " << result << endl; + } + } + + if (0 == gPlayStop->listOfAction.empty()) + { + result = gThingManager->addActionSet(gFindGroup, gPlayStop, onAction); + if (OC_STACK_OK == result) + { + cout << "addActionSet(gPlayStop) was successful\n"; + } + else + { + cout << "addActionSet(gPlayStop) was unsuccessful. result = " << result << endl; + } + } + } + else + { + cout << "onGetChild : error - " << eCode << endl; + } +} + +int main(int argc, char* argv[]) +{ + // Create PlatformConfig object + PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos }; + + OCPlatform::Configure(cfg); + gThingManager = new ThingsManager(); + + int selectedMenu; + OCStackResult result; + + try + { + while (true) + { + // some operations + cout << "(1) CREATE PHONE" << endl; + cout + << "(11) FIND & JOIN GROUP | (12) ADD GROUP ACTION | (13) PLAY START" + << " | (14) PLAY STOP"<< endl; + cout << "(15) DELETE GROUP ACTION | (16) LEAVE GROUP" << endl; + cout << "(21) DELETE PHONE" << endl; + + std::cin >> selectedMenu; + + if (selectedMenu == 1) + { + if (gPhoneResourceHandle) + { + cout << "Phone resource is registered already." << endl; + continue; + } + + std::string resourceURi = "/core/phone"; + std::string resourceTypeName = "core.phone"; + std::string resourceInterface = DEFAULT_INTERFACE; + + result = OCPlatform::registerResource(gPhoneResourceHandle, resourceURi, + resourceTypeName, resourceInterface, NULL, OC_DISCOVERABLE | OC_OBSERVABLE); + if (OC_STACK_OK == result) + { + cout << "To register phone resource was successful\n"; + } + else + { + cout << "To register phone resource was unsuccessful. result = " << result + << endl; + } + } + else if (selectedMenu == 11) + { + std::vector< std::string > types; + types.clear(); + types.push_back(collectionResourceType); + + result = gThingManager->findGroup(types, &onFindGroup); + if (OC_STACK_OK == result) + { + cout << "Finding group was successful\n"; + } + else + { + cout << "Finding group was unsuccessful. result = " << result << endl; + } + } + else if (selectedMenu == 12) + { + if (!gFindGroup) + { + cout << "gFindGroup is NULL. Please process step 1 and step 11 first." << endl; + continue; + } + + QueryParamsMap queryParamsMap; + result = gFindGroup->get("", DEFAULT_INTERFACE, queryParamsMap, onGetChild); + if (OC_STACK_OK == result) + { + cout << "gFindGroup->get was successful\n"; + } + else + { + cout << "gFindGroup->get was unsuccessful. result = " << result << endl; + } + } + else if (selectedMenu == 13) + { + if (!gFindGroup) + { + cout << "gFindGroup is NULL. Please process step 1 and step 11 first." << endl; + continue; + } + + if (!gPlayStart) + { + cout << "gPlayStart is NULL. Please process step 12 first." << endl; + continue; + } + + result = gThingManager->executeActionSet(gFindGroup, "playstart", onAction); + if (OC_STACK_OK == result) + { + cout << "DoAction(playstart) was successful\n"; + } + else + { + cout << "DoAction(playstart) was unsuccessful. result = " << result << endl; + } + } + else if (selectedMenu == 14) + { + if (!gFindGroup) + { + cout << "gFindGroup is NULL. Please process step 1 and step 11 first." << endl; + continue; + } + + if (!gPlayStop) + { + cout << "gPlayStop is NULL. Please process step 12 first." << endl; + continue; + } + + result = gThingManager->executeActionSet(gFindGroup, "playstop", onAction); + if (OC_STACK_OK == result) + { + cout << "DoAction(playstop) was successful\n"; + } + else + { + cout << "DoAction(playstop) was unsuccessful. result = " << result << endl; + } + } + else if (selectedMenu == 15) + { + if (!gFindGroup) + { + cout << "gFindGroup is NULL. Please process step 1 and step 11 first." << endl; + continue; + } + + if (!gPlayStart) + { + cout << "gPlayStart is NULL. Please process step 12 first." << endl; + continue; + } + + if (!gPlayStop) + { + cout << "gPlayStop is NULL. Please process step 12 first." << endl; + continue; + } + + result = gThingManager->deleteActionSet(gFindGroup, "playstart", onAction); + if (OC_STACK_OK == result) + { + cout << "Delete Action(playstart) was successful\n"; + } + else + { + cout << "Delete Action(playstart) was unsuccessful. result = " << result + << endl; + } + + result = gThingManager->deleteActionSet(gFindGroup, "playstop", onAction); + if (OC_STACK_OK == result) + { + cout << "Delete Action(playstop) was successful\n"; + } + else + { + cout << "Delete Action(playstop) was unsuccessful. result = " << result << endl; + } + + Action* a; + Capability* c; + + for (auto actionIter = gPlayStart->listOfAction.begin(); + actionIter != gPlayStart->listOfAction.end(); ++actionIter) + { + a = (*actionIter); + + for (auto capaIter = a->listOfCapability.begin(); + capaIter != a->listOfCapability.end(); ++capaIter) + { + c = (*capaIter); + delete c; + } + + delete a; + } + + delete gPlayStart; + gPlayStart = NULL; + + for (auto actionIter = gPlayStop->listOfAction.begin(); + actionIter != gPlayStop->listOfAction.end(); ++actionIter) + { + a = (*actionIter); + + for (auto capaIter = a->listOfCapability.begin(); + capaIter != a->listOfCapability.end(); ++capaIter) + { + c = (*capaIter); + delete c; + } + + delete a; + } + + delete gPlayStop; + gPlayStop = NULL; + } + else if (selectedMenu == 16) + { + if (NULL == gPhoneResourceHandle) + { + cout + << "Error! No resource to leave group. Register resource first!" + << endl; + continue; + } + + result = gThingManager->leaveGroup(collectionResourceType, gPhoneResourceHandle); + if (OC_STACK_OK == result) + { + cout << "Leaving group was successful\n"; + } + else + { + cout << "Leaving group was unsuccessful. result = " << result << endl; + } + } + else if (selectedMenu == 21) + { + if (NULL == gPhoneResourceHandle) + { + cout + << "Error! No resource to unregister. Register resource first!" + << endl; + continue; + } + + result = OCPlatform::unregisterResource(gPhoneResourceHandle); + if (OC_STACK_OK == result) + { + cout << "To unregister phone resource was successful\n"; + } + else + { + cout << "To unregister phone resource was unsuccessful. result = " << result + << endl; + } + gPhoneResourceHandle = NULL; + } + } + + } + catch (OCException& e) + { + //log(e.what()); + } + + return 0; +} + diff --git a/service/things-manager/sampleapp/linux/groupsyncaction/speaker.cpp b/service/things-manager/sampleapp/linux/groupsyncaction/speaker.cpp new file mode 100644 index 000000000..41abb367a --- /dev/null +++ b/service/things-manager/sampleapp/linux/groupsyncaction/speaker.cpp @@ -0,0 +1,165 @@ +//****************************************************************** +// +// Copyright 2014 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 <string> +#include <cstdlib> +#include <pthread.h> +#include "OCPlatform.h" +#include "OCApi.h" +#include "ThingsManager.h" + +using namespace OC; + +OCEntityHandlerResult speakerEntityHandler(const std::shared_ptr< OCResourceRequest > request) +{ + cout << "speakerEntityHandler:\n"; + + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + std::string action; + + if (requestFlag == RequestHandlerFlag::InitFlag) + { + cout << "\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + else if (requestFlag == RequestHandlerFlag::RequestFlag) + { + cout << "\trequestFlag : Request\n"; + + OCRepresentation rp = request->getResourceRepresentation(); + + // If the request type is GET + if (requestType == "GET") + { + cout << "\t\trequestType : GET\n"; + } + else if (requestType == "PUT") + { + cout << "\t\trequestType : PUT\n"; + + action = rp.getValue< std::string >("volume"); + cout << "\t\t\tvolume : " << action << endl; + } + else if (requestType == "POST") + { + cout << "\t\trequestType : POST\n"; + } + else if (requestType == "DELETE") + { + cout << "\t\trequestType : DELETE\n"; + } + } + else if (requestFlag == RequestHandlerFlag::ObserverFlag) + { + cout << "\trequestFlag : Observer\n"; + } + } + else + { + cout << "Request invalid" << endl; + } + + return OC_EH_OK; +} + +int main(int argc, char* argv[]) +{ + + // Create PlatformConfig object + PlatformConfig cfg + { OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos }; + + OCPlatform::Configure(cfg); + + int selectedMenu; + OCStackResult result; + OCResourceHandle speakerResourceHandle = NULL; + + try + { + while (true) + { + // some operations + cout << "(1) CREATE SPEAKER | (2) DELETE SPEAKER" << endl; + + std::cin >> selectedMenu; + + if (selectedMenu == 1) + { + if (speakerResourceHandle) + { + cout << "Speaker resource is registered already." << endl; + continue; + } + + std::string resourceURi = "/core/speaker"; + std::string resourceTypeName = "core.speaker"; + + std::string resourceInterface = DEFAULT_INTERFACE; + + result = OCPlatform::registerResource(speakerResourceHandle, resourceURi, + resourceTypeName, resourceInterface, speakerEntityHandler, + OC_DISCOVERABLE | OC_OBSERVABLE); + if (OC_STACK_OK == result) + { + cout << "To register speaker resource was successful\n"; + } + else + { + cout << "To register speaker resource was unsuccessful\n"; + } + } + else if (selectedMenu == 2) + { + if (NULL == speakerResourceHandle) + { + cout + << "Error! No resource to unregister. Register resource first!" + << endl; + continue; + } + + result = OCPlatform::unregisterResource(speakerResourceHandle); + if (OC_STACK_OK == result) + { + cout << "To unregister speaker resource was successful\n"; + } + else + { + cout << "To unregister speaker resource was unsuccessful\n"; + } + + speakerResourceHandle = NULL; + } + } + } + catch (OCException& e) + { + //log(e.what()); + } + + return 0; +} + diff --git a/service/things-manager/sampleapp/linux/makefile b/service/things-manager/sampleapp/linux/makefile new file mode 100644 index 000000000..092d768e0 --- /dev/null +++ b/service/things-manager/sampleapp/linux/makefile @@ -0,0 +1,21 @@ +MAKE=make + +DIRLIST=configuration groupaction groupsyncaction + +# Force metatargets to build: +.PHONY: all clean + +all: build + +build: + @for subdir in ${DIRLIST} ; do \ + ${MAKE} -C $${subdir} ; \ + echo " " ; \ + done + @echo " " + +clean: + @for subdir in ${DIRLIST} ; do \ + ${MAKE} clean -C $${subdir} ; \ + echo " " ; \ + done diff --git a/service/things-manager/sdk/build/linux/Makefile b/service/things-manager/sdk/build/linux/Makefile new file mode 100644 index 000000000..0e5ec03b4 --- /dev/null +++ b/service/things-manager/sdk/build/linux/Makefile @@ -0,0 +1,82 @@ + + +#OIC_ROOT=../../../resource/ +IOT_BASE=../../../../../resource +#BOOST=${BOOST_DIR} +RST_NAME=. + + +# Insert your project name. +TARGET=libTGMSDKLibrary.a +EXCLUDE_LIST= + +# C++ type Compile Flag define. +CXX=g++ +CXX_FLAGS=-std=c++0x -Wall -pthread -DLINUX -ldl + + +CXX_INC := -I../../ -I../../inc/ -I../../src/ +CXX_INC += -I${IOT_BASE}/include/ +CXX_INC += -I${IOT_BASE}/oc_logger/include +CXX_INC += -I${IOT_BASE}/csdk/stack/include +CXX_INC += -I${IOT_BASE}/csdk/ocsocket/include +CXX_INC += -I${IOT_BASE}/csdk/ocrandom/include +CXX_INC += -I${IOT_BASE}/csdk/logger/include +CXX_INC += -I${IOT_BASE}/dependencies/cereal/include + +CXX_LIB=-L"" + +CXX_SRCPATH=${wildcard ../../src/*.cpp} +CXX_SRCLIST=${notdir ${CXX_SRCPATH}} +CXX_USESRCS=${filter-out ${EXCLUDE_LIST}, ${CXX_SRCLIST}} +CXX_OBJLIST=${CXX_USESRCS:.cpp=.o} + + + + + + +# Linker FLAGS define. +# LIBS=-lajdaemon -lalljoyn -lssl -lcrypto -ldl -llog -lz -lm -lc -lstdc++ -lgcc -lgnustl_static +# LD_FLAGS=-std=c++11 -Wall -shared -lpthread -ldl +GAR=ar +#LD_LIB=${IOT_BASE}/OCLib.a ${IOT_BASE}/csdk/liboctbstack.a $(JSONLIB)/libjsoncpp.a + + +# Force metatargets to build: +.PHONY: all clean + +all: pre_job ${TARGET} post_job + +pre_job: + @echo " " + @echo "Build Begin." + @echo " " + +${TARGET}: ${CXX_OBJLIST} + #$(CXX) $(LD_FLAGS) -o ./${RST_NAME}/$@ $^ ${LD_LIB} // shared object. + @for sublib in ${LD_LIB} ; do \ + echo "${GAR} -x $${sublib}" ; \ + cd ./${RST_NAME} ; \ + ${GAR} -x ../$${sublib} ; \ + cd ../ ; \ + done + ${GAR} -r ./${RST_NAME}/$@ ./${RST_NAME}/*.o + @echo " " + + + + +%.o : ../../src/%.cpp + ${CXX} ${CXX_FLAGS} -c $< ${CXX_INC} -o ./${RST_NAME}/$@ + @echo " " + +post_job: + @echo " " + @echo "Build Successful." + @echo " " + + +clean: + rm -f -v *.o ${TARGET} + diff --git a/service/things-manager/sdk/inc/ThingsManager.h b/service/things-manager/sdk/inc/ThingsManager.h new file mode 100644 index 000000000..de7c365fb --- /dev/null +++ b/service/things-manager/sdk/inc/ThingsManager.h @@ -0,0 +1,408 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file ThingsManager.h +/// +/// @brief This file contains the declaration of ThingsManager class +/// and its members related to ThingsManager. + +#ifndef __OC_THINGSMANAGER__ +#define __OC_THINGSMANAGER__ + +#include <string> +#include <vector> +#include <map> +#include <cstdlib> +#include "OCPlatform.h" +#include "OCApi.h" +#include "GroupManager.h" + +using namespace OC; + +namespace OIC +{ + /** + * @class ThingsManager + * @brief This class provides a set of functions regarding group management, + * synchronization of group, configuration of things, and diagnostics about things. + * + */ + class ThingsManager + { + public: + /** + * Constructor for ThingsManager + */ + ThingsManager(void); + + /** + * Virtual destructor for ThingsManager + */ + ~ThingsManager(void); + + /** + * API for discoverying candidate resources. + * Callback is called when all resource types are found. + * + * @param resourceTypes - required resource types(called "candidate") + * @param candidateCallback - callback. Returns OCResource vector. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult findCandidateResources(std::vector< std::string > resourceTypes, + std::function< void(std::vector< std::shared_ptr< OCResource > >) > callback, + int waitsec = -1); + + /** + * API for subscribing child's state. + * + * @param resource - collection resource for subscribing presence of all child resources. + * @param callback - callback funcion for result of child's presence. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult subscribeCollectionPresence(std::shared_ptr< OCResource > resource, + std::function< void(std::string, OCStackResult) > callback); + + /** + * API for register and bind resource to group. + * + * @param childHandle - child resource handle. It will be filled from resource param. + * @param resource - resource for register and bind to group. It has all data. + * @param collectionHandle - collection resource handle. It will be added child resource. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult bindResourceToGroup(OCResourceHandle& childHandle, + std::shared_ptr< OCResource > resource, OCResourceHandle& collectionHandle); + + // Group Synchronization + + /** + * API for finding a specific remote group when a resource tries to join a group. + * Callback is called when a group is found or not. + * + * @param collectionResourceTypes - resource types of a group to find and join + * @param callback - callback. It has OCResource param. + * If a group is found, OCResource has the group resource. + * Otherwise, OCResource is NULL. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult findGroup(std::vector< std::string > collectionResourceTypes, + FindCallback callback); + + /** + * API for creating a new group. + * + * @param collectionResourceType - resource type of a group to create + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult createGroup(std::string collectionResourceType); + + /** + * API for joining a group. This API is used when a resource that has a group tries + * to find a specific remote resource and makes it join a group + * + * @param collectionResourceType - resource type of a group to join. + * @param resourceHandle - resource handle to join a group. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult joinGroup(std::string collectionResourceType, + OCResourceHandle resourceHandle); + + /** + * API for joining a group. This API is used when a resource that + * doesn't have a group tries to find and join a specific remote group. + * + * @param resource - group resource pointer to join. + * It can be the callback result of findGroup(). + * @param resourceHandle - resource handle to join a group. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult joinGroup(const std::shared_ptr< OCResource > resource, + OCResourceHandle resourceHandle); + + /** + * API for leaving a joined group. + * + * @param collectionResourceType - resource type of a group to leave. + * @param resourceHandle - resource handle to leave a group. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult leaveGroup(std::string collectionResourceType, + OCResourceHandle resourceHandle); + + /** + * API for deleting a group. + * + * @param collectionResourceType - resource type of a group to delete. + * + * @return void + */ + void deleteGroup(std::string collectionResourceType); + + /** + * API for getting a list of joined groups. + * + * @param void + * + * @return std::map - return value of this API. + * It returns group resource type and group resource handle as a map type. + */ + std::map< std::string, OCResourceHandle > getGroupList(void); + + // Things Configuration + + /** + * API for updating configuration value of multiple things of a target group + * or a single thing. + * Callback is called when a response arrives. + * Before using the below function, a developer should acquire a resource pointer of + * (collection) resource that he wants to send a request by calling findResource() function + * provided in OCPlatform. And he should also notice a "Configuration Name" term which + * represents a nickname of a target attribute of a resource that he wants to update. + * The base motivation to introduce the term is to avoid a usage of URI to access a resource + * from a developer. Thus, a developer should know which configuration names are supported + * by Things Configuration class and what the configuration name means. + * To get a list of supported configuration names, + * use getListOfSupportedConfigurationUnits() + * function, which provides the list in JSON format. + * + * @param resource - resource pointer representing the target group or the single thing. + * @param configurations - ConfigurationUnit: a nickname of attribute of target resource + * (e.g., installedlocation, currency, (IP)address) + * Value : a value to be updated + * @param callback - callback for updateConfigurations. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult updateConfigurations(std::shared_ptr< OCResource > resource, + std::map< std::string, std::string > configurations, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) > callback); + + /** + * API for getting configuration value of multiple things of a target group + * or a single thing. + * Callback is called when a response arrives. + * + * @param resource - resource pointer representing the target group or the single thing. + * @param configurations - ConfigurationUnit: a nickname of attribute of target resource. + * @param callback - callback for getConfigurations. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult getConfigurations(std::shared_ptr< OCResource > resource, + std::vector< std::string > configurations, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) > callback); + + /** + * API for showing the list of supported configuration units (configurable parameters) + * Callback is called when a response arrives. + * + * @param void + * @return std::string - return value of this API. + * It returns the list in JSON format + */ + std::string getListOfSupportedConfigurationUnits(); + + /** + * API for boostrapping system configuration parameters from a bootstrap server. + * Callback call when a response from the bootstrap server arrives. + * + * @param callback - callback for doBootstrap. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult doBootstrap( + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) > callback); + + // Things Diagnostics + + /** + * API to let thing(device) reboot. + * The target thing could be a group of multiple things or a single thing. + * Callback is called when a response arrives. + * + * @param resource - resource pointer representing the target group + * @param callback - callback for reboot. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult reboot(std::shared_ptr< OCResource > resource, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) > callback); + + /** + * API for factory reset on thing(device). + * The target thing could be a group of multiple things or a single thing. + * Callback is called when a response arrives. + * + * @param resource - resource pointer representing the target group + * @param callback - callback for factoryReset. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult factoryReset(std::shared_ptr< OCResource > resource, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) > callback); + + // Group Action. + + /** + * API for extracting Action Set string from the Action Set class instance + * + * @param newActionSet - pointer of Action Set + * + * @return std::string - return value of this API. + * It returns Action Set String. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + std::string getStringFromActionSet(const ActionSet *newActionSet); + + /** + * API for extrracting Action Set class instance from Action Set String. + * + * @param desc - description of Action set + * + * @return ActionSet* - return value of this API. + * It returns pointer of ActionSet. + */ + ActionSet* getActionSetfromString(std::string desc); + + /** + * API for adding an Action Set. + * Callback is called when the response of PUT operation arrives. + * + * @param resource - resource pointer of the group resource + * @param newActionSet - pointer of Action Set + * @param callback - callback for PUT operation. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult addActionSet(std::shared_ptr< OCResource > resource, + const ActionSet* newActionSet, PutCallback cb); + + /** + * API for executing the Action Set. + * Callback is called when the response of POST operation arrives. + * + * @param resource - resource pointer of the group resource + * @param actionsetName - Action Set name for executing the Action set + * @param callback - callback for POST operation. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult executeActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, PostCallback cb); + + /** + * API for reading the Action Set. + * Callback is called when the response of GET operation arrives. + * + * @param resource - resource pointer of the group resource + * @param actionsetName - Action Set name for reading the Action set + * @param callback - callback for GET operation. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult getActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, GetCallback cb); + + /** + * API for removing the Action Set. + * Callback is called when the response of POST operation arrives. + * + * @param resource - resource pointer of the group resource + * @param actionsetName - Action Set name for removing the Action set + * @param callback - callback for POST operation. + * + * @return OCStackResult - return value of this API. + * It returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult deleteActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, PostCallback); + + }; +} +#endif /* __OC_THINGSMANAGER__*/ diff --git a/service/things-manager/sdk/src/GroupManager.cpp b/service/things-manager/sdk/src/GroupManager.cpp new file mode 100644 index 000000000..d3ddab4e8 --- /dev/null +++ b/service/things-manager/sdk/src/GroupManager.cpp @@ -0,0 +1,600 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file GroupManager.cpp +/// @brief + +#include "GroupManager.h" +#include <algorithm> +#include <thread> +#include <unistd.h> + +#include <string.h> + +#define PLAIN_DELIMITER "\"" +#define ACTION_DELIMITER "*" +#define DESC_DELIMITER "|" +#define ATTR_DELIMITER "=" + +using namespace OC; + +namespace OIC +{ +std::map< std::vector< std::string >, CandidateCallback > candidateRequest; +std::map< std::vector< std::string >, CandidateCallback > candidateRequestForTimer; +std::map< std::string, std::map< std::string, std::shared_ptr< OCResource > > > rtForResourceList; +std::vector< std::string > allFoundResourceTypes; + +template< typename T > +bool IsSubset(std::vector< T > full, std::vector< T > sub) +{ + std::sort(full.begin(), full.end()); + std::sort(sub.begin(), sub.end()); + return std::includes(full.begin(), full.end(), sub.begin(), sub.end()); +} +std::vector< std::string > &str_split(const std::string &s, char delim, + std::vector< std::string > &elems) +{ + std::stringstream ss(s); + std::string item; + while (std::getline(ss, item, delim)) + { + elems.push_back(item); + } + return elems; +} + +std::vector< std::string > str_split(const std::string &s, char delim) +{ + std::vector< std::string > elems; + str_split(s, delim, elems); + return elems; +} + +void GroupManager::onFoundResource(std::shared_ptr< OCResource > resource, int waitsec) +{ + + std::string resourceURI; + std::string hostAddress; + try + { + // Do some operations with resource object. + if (resource) + { + + std::cout << "DISCOVERED Resource:" << std::endl; + // Get the resource URI + resourceURI = resource->uri(); + std::cout << "\tURI of the resource: " << resourceURI << std::endl; + + // Get the resource host address + hostAddress = resource->host(); + std::cout << "\tHost address of the resource: " << hostAddress << std::endl; + + // Get the resource types + std::cout << "\tList of resource types: " << std::endl; + + hostAddress.append(resourceURI); + + for (auto &resourceTypes : resource->getResourceTypes()) + { + std::cout << "\t\t" << resourceTypes << std::endl; + + if (std::find(allFoundResourceTypes.begin(), allFoundResourceTypes.end(), + resourceTypes) == allFoundResourceTypes.end()) + { + allFoundResourceTypes.push_back(resourceTypes); + } + + rtForResourceList[resourceTypes][hostAddress] = resource; + } + + // Get the resource interfaces + std::cout << "\tList of resource interfaces: " << std::endl; + for (auto &resourceInterfaces : resource->getResourceInterfaces()) + { + std::cout << "\t\t" << resourceInterfaces << std::endl; + } + + if (waitsec == -1) + { + findPreparedRequest(candidateRequest); + } + } + else + { + // Resource is invalid + std::cout << "Resource is invalid" << std::endl; + } + + } + catch (std::exception& e) + { + //log(e.what()); + } +} + +GroupManager::GroupManager(void) +{ + ; +} + +/** + * Virtual destructor + */ +GroupManager::~GroupManager(void) +{ + candidateRequest.clear(); + candidateRequestForTimer.clear(); + rtForResourceList.clear(); + allFoundResourceTypes.clear(); +} + +void GroupManager::findPreparedRequest( + std::map< std::vector< std::string >, CandidateCallback > &request) +{ + std::vector< std::shared_ptr< OCResource > > resources; + + for (auto it = request.begin(); it != request.end();) + { + + if (IsSubset(allFoundResourceTypes, it->first)) + { + //std::cout << "IS SUBSET !!! \n"; + + for (unsigned int i = 0; i < it->first.size(); ++i) + { + + for (auto secondIt = rtForResourceList[it->first.at(i)].begin(); + secondIt != rtForResourceList[it->first.at(i)].end(); ++secondIt) + { + resources.push_back(secondIt->second); + } + } + + it->second(resources); + + //TODO : decide policy - callback only once + request.erase(it++); + } + else + { + ++it; + } + + } + +} + +void GroupManager::lazyCallback(int second) +{ + sleep(second); + findPreparedRequest(candidateRequestForTimer); + +} + +OCStackResult GroupManager::findCandidateResources(std::vector< std::string > resourceTypes, + CandidateCallback callback, int waitsec) +{ + if (resourceTypes.size() < 1) + { + return OC_STACK_ERROR; + } + + std::sort(resourceTypes.begin(), resourceTypes.end()); + resourceTypes.erase(std::unique(resourceTypes.begin(), resourceTypes.end()), + resourceTypes.end()); + + if (waitsec != -1) + { + candidateRequestForTimer.insert(std::make_pair(resourceTypes, callback)); + } + else + { + candidateRequest.insert(std::make_pair(resourceTypes, callback)); + } + + for (unsigned int i = 0; i < resourceTypes.size(); ++i) + { + std::cout << "resourceTypes : " << resourceTypes.at(i) << std::endl; + std::string query = "coap://224.0.1.187/oc/core?rt="; + query.append(resourceTypes.at(i)); + OCPlatform::findResource("", query.c_str(), + std::function < void(std::shared_ptr < OCResource > resource) + > (std::bind(&GroupManager::onFoundResource, this, + std::placeholders::_1, waitsec))); + } + + if (waitsec != -1) + { + std::thread exec( + std::function< void(int second) >( + std::bind(&GroupManager::lazyCallback, this, std::placeholders::_1)), + waitsec); + exec.detach(); + } + + return OC_STACK_OK; +} + +/* + Presence Check + */ + +std::map< std::string, CollectionPresenceCallback > presenceCallbacks; + +// Callback to presence +void GroupManager::collectionPresenceHandler(OCStackResult result, const unsigned int nonce, + const std::string& hostAddress, std::string host, std::string uri) +{ + std::cout << "uri : " << uri << std::endl; + std::cout << "host : " << host << std::endl; + std::cout << "result : " << result << std::endl; + switch (result) + { + case OC_STACK_OK: + std::cout << "Nonce# " << nonce << std::endl; + break; + case OC_STACK_PRESENCE_STOPPED: + std::cout << "Presence Stopped\n"; + break; + case OC_STACK_PRESENCE_DO_NOT_HANDLE: + std::cout << "Presence do not handle\n"; + break; + case OC_STACK_PRESENCE_TIMEOUT: + std::cout << "Presence TIMEOUT\n"; + break; + default: + std::cout << "Error\n"; + break; + } + + if (presenceCallbacks.find(uri) != presenceCallbacks.end()) + { + (presenceCallbacks.find(uri)->second)(uri, result); + } +} + +void GroupManager::checkCollectionRepresentation(const OCRepresentation& rep, + CollectionPresenceCallback callback) +{ + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + /* //bug not found + if(rep.hasAttribute("name")) + { + std::cout << "\tRoom name: " << rep.getValue<std::string>("name") << std::endl; + } + */ + std::vector< OCRepresentation > children = rep.getChildren(); + + for (auto oit = children.begin(); oit != children.end(); ++oit) + { + std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl; + std::vector< std::string > hostAddressVector = str_split(oit->getUri(), '/'); + std::string hostAddress = ""; + for (unsigned int i = 0; i < hostAddressVector.size(); ++i) + { + if (i < 3) + { + hostAddress.append(hostAddressVector.at(i)); + if (i != 2) + { + hostAddress.append("/"); + } + } + } + + std::vector< std::string > resourceTypes = oit->getResourceTypes(); + for (unsigned int i = 0; i < resourceTypes.size(); ++i) + { + std::cout << "\t\t\tresourcetype :" << resourceTypes.at(i) << std::endl; + } + + std::string resourceType = "core."; + resourceType.append(str_split(oit->getUri(), '/').at(4)); + std::cout << "\t\tconvertRT : " << resourceType << std::endl; + std::cout << "\t\thost : " << hostAddress << std::endl; + OCPlatform::OCPresenceHandle presenceHandle; + OCStackResult result = OCPlatform::subscribePresence(presenceHandle, hostAddress, + resourceType, + std::function< + void(OCStackResult result, const unsigned int nonce, + const std::string& hostAddress) >( + std::bind(&GroupManager::collectionPresenceHandler, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, hostAddress, oit->getUri()))); + + if (result == OC_STACK_OK) + { + std::cout << "\t\tOK!" << std::endl; + presenceCallbacks.insert(std::make_pair(oit->getUri(), callback)); + } + else + { + callback("", OC_STACK_ERROR); + } + + } +} + +void GroupManager::onGetForPresence(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, CollectionPresenceCallback callback) +{ + if (eCode == OC_STACK_OK) + { + std::cout << "GET request was successful" << std::endl; + std::cout << "Resource URI: " << rep.getUri() << std::endl; + + checkCollectionRepresentation(rep, callback); + + } + else + { + std::cout << "onGET Response error: " << eCode << std::endl; + callback("", OC_STACK_ERROR); + std::exit(-1); + } +} + +OCStackResult GroupManager::subscribeCollectionPresence( + std::shared_ptr< OCResource > collectionResource, CollectionPresenceCallback callback) +{ + OCStackResult result = OC_STACK_OK; + //callback("core.room",OC_STACK_OK); + + QueryParamsMap queryParam; + + //parameter 1 = resourceType + collectionResource->get("", DEFAULT_INTERFACE, queryParam, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&GroupManager::onGetForPresence, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, callback))); + + return result; +} + +/* + Group Action + */ + +std::string GroupManager::getStringFromActionSet(const ActionSet *newActionSet) +{ + std::string message = ""; + + message = newActionSet->actionsetName; + message.append("*"); + for (auto iterAction = newActionSet->listOfAction.begin(); + iterAction != newActionSet->listOfAction.end(); iterAction++) + { + message.append("uri="); + message.append((*iterAction)->target); + message.append("|"); + + for (auto iterCapa = (*iterAction)->listOfCapability.begin(); + iterCapa != (*iterAction)->listOfCapability.end(); iterCapa++) + { + message.append((*iterCapa)->capability); + message.append("="); + message.append((*iterCapa)->status); + + if (iterCapa + 1 != (*iterAction)->listOfCapability.end()) + message.append("|"); + } + + if (iterAction + 1 != newActionSet->listOfAction.end()) + { + message.append("*"); + } + } + + return message; +} + +ActionSet* GroupManager::getActionSetfromString(std::string desc) +{ + + char *token = NULL; + char *plainText = NULL; + char *plainPtr = NULL; + + ActionSet *actionset = new ActionSet(); + plainText = new char[(desc.length() + 1)]; + strcpy(plainText, desc.c_str()); + + token = strtok_r(plainText, ACTION_DELIMITER, &plainPtr); + + if (token != NULL) + { + actionset->actionsetName = std::string(token); + token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr); + } + else + { + delete actionset; + delete[] plainText; + return NULL; + } + + while (token) + { + char *descPtr = NULL; + char *desc = new char[(strlen(token) + 1)]; + + if (desc != NULL) + { + Action *action = NULL; + strcpy(desc, token); + token = strtok_r(desc, DESC_DELIMITER, &descPtr); + + // cout << "desc :: " << token << endl; + while (token != NULL) + { + char *attrPtr = NULL; + char *attr = new char[(strlen(token) + 1)]; + + strcpy(attr, token); + + // cout << "attr :: " << attr << endl; + + token = strtok_r(attr, ATTR_DELIMITER, &attrPtr); + while (token != NULL) + { + if (strcmp(token, "uri") == 0) + { + token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr); + action = new Action(); + + if (action != NULL) + { + action->target = std::string(token); + } + else + { + delete actionset; + delete[] attr; + delete desc; + delete[] plainText; + return NULL; + } + } + else + { + Capability *capa = new Capability(); + capa->capability = std::string(token); + token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr); + capa->status = std::string(token); + + if (action != NULL) + { + action->listOfCapability.push_back(capa); + } + else + { + delete capa; + delete actionset; + delete[] attr; + delete[] plainText; + delete desc; + return NULL; + } + } + + token = strtok_r(NULL, ATTR_DELIMITER, &attrPtr); + } + + delete[] attr; + token = strtok_r(NULL, DESC_DELIMITER, &descPtr); + } + + actionset->listOfAction.push_back(action); + //delete action; + } + else + { + delete actionset; + delete[] plainText; + return NULL; + } + + delete[] desc; + + token = strtok_r(NULL, ACTION_DELIMITER, &plainPtr); + } + + delete plainText; + return actionset; +} + +OCStackResult GroupManager::addActionSet(std::shared_ptr< OCResource > resource, + const ActionSet* newActionSet, PutCallback cb) +{ + // BUILD message of ActionSet which it is included delimiter. + if ((resource != NULL) && (newActionSet != NULL)) + { + std::string message = getStringFromActionSet(newActionSet); + OCRepresentation rep; + + rep.setValue("ActionSet", message); + + return resource->put(resource->getResourceTypes().front(), GROUP_INTERFACE, rep, + QueryParamsMap(), cb); + } + else + { + return OC_STACK_ERROR; + } +} + +OCStackResult GroupManager::executeActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, PostCallback cb) +{ + if (resource != NULL) + { + OCRepresentation rep; + + rep.setValue("DoAction", actionsetName); + return resource->post(resource->getResourceTypes().front(), GROUP_INTERFACE, rep, + QueryParamsMap(), cb); + } + else + { + return OC_STACK_ERROR; + } +} + +OCStackResult GroupManager::getActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, PostCallback cb) +{ + if (resource != NULL) + { + OCRepresentation rep; + + rep.setValue("GetActionSet", actionsetName); + + return resource->post(resource->getResourceTypes().front(), GROUP_INTERFACE, rep, + QueryParamsMap(), cb); + } + else + { + return OC_STACK_ERROR; + } +} + +OCStackResult GroupManager::deleteActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, PutCallback cb) +{ + if (resource != NULL) + { + OCRepresentation rep; + + rep.setValue("DelActionSet", actionsetName); + + return resource->put(resource->getResourceTypes().front(), GROUP_INTERFACE, rep, + QueryParamsMap(), cb); + } + else + { + return OC_STACK_ERROR; + } +} +} diff --git a/service/things-manager/sdk/src/GroupManager.h b/service/things-manager/sdk/src/GroupManager.h new file mode 100644 index 000000000..d0dad4534 --- /dev/null +++ b/service/things-manager/sdk/src/GroupManager.h @@ -0,0 +1,151 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file GroupManager.h + +/// @brief This file contains the declaration of classes and its members related to GroupManager + +#ifndef __OC_GROUPMANAGER__ +#define __OC_GROUPMANAGER__ + +#include <string> +#include <vector> +#include <map> +#include <cstdlib> +#include "OCPlatform.h" +#include "OCApi.h" + +using namespace OC; + +namespace OIC +{ +typedef std::function< void(std::vector< std::shared_ptr< OCResource > >) > CandidateCallback; +typedef std::function< void(std::string, OCStackResult) > CollectionPresenceCallback; + +typedef std::function< void(const HeaderOptions&, const OCRepresentation&, const int) > GetCallback; +typedef std::function< void(const HeaderOptions&, const OCRepresentation&, const int) > PostCallback; +typedef std::function< void(const HeaderOptions&, const OCRepresentation&, const int) > PutCallback; + +class Capability +{ +public: + std::string capability; + std::string status; +}; + +class Action +{ +public: + Action() : + target("") + { + } + ~Action() + { + listOfCapability.clear(); + } + std::string target; + + std::vector< Capability* > listOfCapability; +}; + +class ActionSet +{ +public: + ActionSet() : + actionsetName("") + { + } + ~ActionSet() + { + listOfAction.clear(); + } + std::string actionsetName; + + std::vector< Action* > listOfAction; +}; + +class GroupManager +{ +public: + /** + * Constructor for GroupManager. Constructs a new GroupManager + */ + GroupManager(void); + + /** + * Virtual destructor + */ + ~GroupManager(void); + + /** + * API for candidate resources discovery. + * Callback only call when all resource types found. + * + * @param resourceTypes - required resource types(called "candidate") + * @param candidateCallback - callback. OCResource vector. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult findCandidateResources(std::vector< std::string > resourceTypes, + CandidateCallback callback, int waitsec = -1); + + /** + * API for Collection member's state subscribe. + * + * NOTE: NOT IMPLEMENT YET + */ + OCStackResult subscribeCollectionPresence(std::shared_ptr< OCResource > resource, + CollectionPresenceCallback); + +private: + + void onFoundResource(std::shared_ptr< OCResource > resource, int waitsec); + void findPreparedRequest(std::map< std::vector< std::string >, CandidateCallback > &request); + void lazyCallback(int second); + + void onGetForPresence(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, CollectionPresenceCallback callback); + void checkCollectionRepresentation(const OCRepresentation& rep, + CollectionPresenceCallback callback); + void collectionPresenceHandler(OCStackResult result, const unsigned int nonce, + const std::string& hostAddress, std::string host, std::string uri); + + /** + * API for Collection(Group) action. + */ + +public: + std::string getStringFromActionSet(const ActionSet *newActionSet); + ActionSet* getActionSetfromString(std::string desc); + + OCStackResult addActionSet(std::shared_ptr< OCResource > resource, + const ActionSet* newActionSet, PutCallback cb); + OCStackResult executeActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, PostCallback cb); + OCStackResult getActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, + PostCallback cb); + OCStackResult deleteActionSet(std::shared_ptr< OCResource > resource, std::string actionsetName, + PostCallback); +}; +} +#endif /* __OC_GROUPMANAGER__*/ diff --git a/service/things-manager/sdk/src/GroupSynchronization.cpp b/service/things-manager/sdk/src/GroupSynchronization.cpp new file mode 100644 index 000000000..dd2c96cfc --- /dev/null +++ b/service/things-manager/sdk/src/GroupSynchronization.cpp @@ -0,0 +1,1277 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file GroupSynchronization.cpp +/// @brief + +#include "GroupSynchronization.h" + +using namespace OC; + +namespace OIC +{ + +GroupSynchronization* GroupSynchronization::groupSyncnstance = NULL; + +GroupSynchronization* GroupSynchronization::getInstance() +{ + if (groupSyncnstance == NULL) + { + groupSyncnstance = new GroupSynchronization(); + } + return groupSyncnstance; +} + +void GroupSynchronization::deleteInstance() +{ + if (groupSyncnstance) + { + delete groupSyncnstance; + groupSyncnstance = NULL; + } +} + +OCStackResult GroupSynchronization::findGroup( + std::vector< std::string > collectionResourceTypes, FindCallback callback) +{ + cout << "GroupSynchronization::findGroup" << endl; + + foundGroupResourceList.clear(); + + findCallback = callback; + + for (unsigned int i = 0; i < collectionResourceTypes.size(); ++i) + { + std::string query = "coap://224.0.1.187/oc/core?rt="; + query.append(collectionResourceTypes.at(i)); + cout << "GroupSynchronization::findGroup - " << query << endl; + + OCPlatform::findResource("", query, + std::bind(&GroupSynchronization::onFindGroup, this, std::placeholders::_1)); + } + + // thread to check if GroupSynchronization::onFoundGroup is called or not. + std::thread t(std::bind(&GroupSynchronization::checkFindGroup, this)); + t.detach(); + + return OC_STACK_OK; +} + +OCStackResult GroupSynchronization::createGroup(std::string collectionResourceType) +{ + foundGroupResourceList.clear(); + + OCResourceHandle collectionResHandle = NULL; + OCResourceHandle groupSyncResHandle = NULL; + + if (0 != collectionResourceType.length()) + { + cout << "GroupSynchronization::createGroup - The created group is added." << endl; + + OCStackResult result; + + // creating master collection resource + std::string collectionUri = "/" + collectionResourceType; + int i; + while ((i = collectionUri.find(".")) != std::string::npos) + { + collectionUri.replace(i, 1, "/"); + } + cout << "GroupSynchronization::createGroup : collection uri - " << collectionUri + << ", type - " << collectionResourceType << endl; + + std::string resourceInterface = DEFAULT_INTERFACE; + + result = OCPlatform::registerResource(collectionResHandle, collectionUri, + collectionResourceType, resourceInterface, NULL, + OC_DISCOVERABLE | OC_OBSERVABLE); + if (result != OC_STACK_OK) + { + cout << "To register resource (" << collectionUri << ") was unsuccessful. result - " + << result << endl; + goto Error; + } + + OCPlatform::bindInterfaceToResource(collectionResHandle, GROUP_INTERFACE); + if (result != OC_STACK_OK) + { + cout << "To bind Interface (collection) was unsuccessful. result - " << result + << endl; + } + + collectionResourceHandleList[collectionResourceType] = collectionResHandle; + + // creating master group sync resource + std::string groupSyncUri = collectionUri + "/groupsync"; + std::string groupSyncResType = collectionResourceType + ".groupsync"; + +// cout << "GroupSynchronization::createGroup : groupSync uri - " << groupSyncUri +// << ", type - " << collectionResourceType << endl; + + result = OCPlatform::registerResource(groupSyncResHandle, groupSyncUri, + groupSyncResType, resourceInterface, + std::bind(&GroupSynchronization::groupEntityHandler, this, + std::placeholders::_1), OC_DISCOVERABLE | OC_OBSERVABLE); + if (result != OC_STACK_OK) + { + cout << "To register resource (groupsync) was unsuccessful. result - " << result + << endl; + goto Error; + } + + groupSyncResourceHandleList[collectionResourceType] = groupSyncResHandle; + + return OC_STACK_OK; + } + else + { + cout << "GroupSynchronization::createGroup : Error! Input params are wrong." << endl; + return OC_STACK_INVALID_PARAM; + } + + Error: + + if (collectionResHandle) + { + OCPlatform::unregisterResource(collectionResHandle); + auto iterator = collectionResourceHandleList.find(collectionResourceType); + if (iterator != collectionResourceHandleList.end()) + { + collectionResourceHandleList.erase(iterator); + } + } + + if (groupSyncResHandle) + { + OCPlatform::unregisterResource(groupSyncResHandle); + auto iterator = groupSyncResourceHandleList.find(collectionResourceType); + if (iterator != groupSyncResourceHandleList.end()) + { + groupSyncResourceHandleList.erase(iterator); + } + } + + return OC_STACK_NO_RESOURCE; +} + +OCStackResult GroupSynchronization::joinGroup(std::string collectionResourceType, + OCResourceHandle resourceHandle) +{ + if ((0 != collectionResourceType.length()) && (resourceHandle)) + { + auto resIt = collectionResourceHandleList.find(collectionResourceType); + if (resIt == groupSyncResourceHandleList.end()) + { + cout << "GroupSynchronization::joinGroup : error! There is no collection to join" + << endl; + return OC_STACK_INVALID_PARAM; + } + + OCResourceHandle collectionResHandle = resIt->second; + + OCStackResult result = OCPlatform::bindResource(collectionResHandle, resourceHandle); + if (result != OC_STACK_OK) + { + cout << "GroupSynchronization::joinGroup : To bind resource was unsuccessful." + << "result - " << result << endl; + return OC_STACK_ERROR; + } + cout << "GroupSynchronization::joinGroup : " + << "To bind collectionResHandle and resourceHandle" << endl; + + std::vector< OCResourceHandle > childHandleList; + + auto childIt = childResourceHandleList.find(collectionResHandle); + if (childIt != childResourceHandleList.end()) + { + childHandleList = childIt->second; + } + + childHandleList.push_back(resourceHandle); + childResourceHandleList[collectionResHandle] = childHandleList; + + deviceResourceHandleList.push_back(resourceHandle); + + debugGroupSync(); + } + else + { + cout << "GroupSynchronization::joinGroup : Error! input params are wrong." << endl; + return OC_STACK_INVALID_PARAM; + } + + return OC_STACK_OK; +} + +OCStackResult GroupSynchronization::joinGroup(const std::shared_ptr< OCResource > resource, + OCResourceHandle resourceHandle) +{ + if ((resource) && (resourceHandle)) + { + cout << "GroupSynchronization::joinGroup" << endl; + + // making representation to join group + std::string method = "joinGroup"; + std::vector< std::string > type = resource->getResourceTypes(); + std::string resourceType; + resourceType.append(OCGetResourceTypeName(resourceHandle, 0)); + + OCRepresentation rep; + rep.setValue("method", method); + rep.setValue("collectionResourceType", type[0]); + rep.setValue("resourceType", resourceType); + + cout << "\tmethod - " << method << endl; + cout << "\tcollectionResourceType - " << type[0] << endl; + cout << "\tresourceType - " << resourceType << endl; + + // creating group sync resource with the received collection resource. + // entity handler of group sync is used to join group. + std::string host = resource->host(); + std::string uri = resource->uri() + "/groupsync"; + + std::vector< std::string > resourceTypes; + std::string temp; + for (unsigned int i = 0; i < type.size(); ++i) + { + temp = type[0] + ".groupsync"; + resourceTypes.push_back(temp); + } + + std::vector< std::string > resourceInterface; + resourceInterface.push_back(DEFAULT_INTERFACE); + + OCResource::Ptr groupSyncResource = OCPlatform::constructResourceObject(host, uri, 1, + resourceTypes, resourceInterface); + groupSyncResourceList[type[0]] = groupSyncResource; + + cout << "GroupSynchronization::joinGroup : creating groupSyncResource." << endl; + + // Create QueryParameters Map and add query params (if any) + QueryParamsMap queryParamsMap; + + // request to join group to the remote group sync resource + OCStackResult result = groupSyncResource->put(rep, queryParamsMap, + std::bind(&GroupSynchronization::onJoinGroup, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3)); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::joinGroup : groupSyncResource->put was successful." + << endl; + } + else + { + cout << "GroupSynchronization::joinGroup : " + << "groupSyncResource->put was unsuccessful. result - " << result << endl; + } + + // saving the remote collection resource. + // It is used in onJoinGroup() and onGetJoinedRemoteChild(). + remoteCollectionResource = resource; + + // saving the resource handle to join. It is used in onGetJoinedRemoteChild() + deviceResourceHandle = resourceHandle; + + return OC_STACK_OK; + } + else + { + cout << "GroupSynchronization::joinGroup : Error! Input params are wrong." << endl; + return OC_STACK_INVALID_PARAM; + } +} + +OCStackResult GroupSynchronization::leaveGroup(std::string collectionResourceType, + OCResourceHandle resourceHandle) +{ + if ((0 != collectionResourceType.length()) && (resourceHandle)) + { + cout << "GroupSynchronization::leaveGroup : collectionResourceType - " + << collectionResourceType << endl; + + OCResourceHandle collectionResHandle; + + auto handleIt = groupSyncResourceHandleList.find(collectionResourceType); + + // if groupSyncResourceHandleList has resourceType, + // this app created collection resource handle. + if (handleIt != groupSyncResourceHandleList.end()) + { + handleIt = collectionResourceHandleList.find(collectionResourceType); + if (handleIt == collectionResourceHandleList.end()) + { + cout << "GroupSynchronization::leaveGroup : " + << "Error! There is no collection resource handle to leave." << endl; + return OC_STACK_INVALID_PARAM; + } + + collectionResHandle = handleIt->second; +// cout << "GroupSynchronization::leaveGroup : collection handle uri - " +// << OCGetResourceUri(collectionResHandle) << endl; + + OCStackResult result = OCPlatform::unbindResource(collectionResHandle, + resourceHandle); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::leaveGroup : " + << "To unbind resource was successful." << endl; + } + else + { + cout << "GroupSynchronization::leaveGroup : " + << "To unbind resource was unsuccessful. result - " << result << endl; + } + + auto It = std::find(deviceResourceHandleList.begin(), + deviceResourceHandleList.end(), resourceHandle); + if (It == deviceResourceHandleList.end()) // there is no resource handle to find + { + result = OCPlatform::unregisterResource(resourceHandle); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::leaveGroup : " + << "To unregister resource was successful." << endl; + } + else + { + cout << "GroupSynchronization::leaveGroup : " + << "To unregister resource was unsuccessful. result - " << result + << endl; + } + } + else + { + cout << "GroupSynchronization::leaveGroup : " + << "This resource cannot be unregistered." << endl; + deviceResourceHandleList.erase(It); + } + + auto handleListIt = childResourceHandleList.find(collectionResHandle); + if (handleListIt == childResourceHandleList.end()) + { + cout << "GroupSynchronization::leaveGroup : " + << "Error! There is no child resource list to delete." << endl; + return OC_STACK_INVALID_PARAM; + } + + std::vector< OCResourceHandle > childList = handleListIt->second; + auto childIt = std::find(childList.begin(), childList.end(), resourceHandle); + if (childIt != childList.end()) + { + cout << "GroupSynchronization::groupEntityHandler : " + << "Found! The resource to leave is found." << endl; + childList.erase(childIt); + } + + childResourceHandleList[collectionResHandle] = childList; + + debugGroupSync(); + } + else // requesting to unbind this resourceHandle to the remote collection resource + { + auto resourceIt = groupSyncResourceList.find(collectionResourceType); + + if (resourceIt == groupSyncResourceList.end()) + { + cout << "GroupSynchronization::leaveGroup : " + << "Error! There is no collectin resource type to leave." << endl; + return OC_STACK_INVALID_PARAM; + } + + std::shared_ptr< OCResource > resource = resourceIt->second; +// cout << "GroupSynchronization::leaveGroup : group sync resource uri - " +// << resource->uri() << endl; + + handleIt = collectionResourceHandleList.find(collectionResourceType); + if (handleIt == collectionResourceHandleList.end()) + { + cout << "GroupSynchronization::leaveGroup : " + << "Error! There is no collection resource handle to leave." << endl; + return OC_STACK_INVALID_PARAM; + } + + collectionResHandle = handleIt->second; + + // making representation to leave group + std::string method = "leaveGroup"; + std::string type = OCGetResourceTypeName(collectionResHandle, 0); + std::string resourceType; + resourceType.append(OCGetResourceTypeName(resourceHandle, 0)); + + OCRepresentation rep; + rep.setValue("method", method); + rep.setValue("collectionResourceType", type); + rep.setValue("resourceType", resourceType); + + cout << "\tmethod - " << method << endl; + cout << "\tcollectionResourceType - " << type << endl; + cout << "\tresourceType - " << resourceType << endl; + + QueryParamsMap queryParamsMap; + + // request to leave group to the remote group sync resource + OCStackResult result = resource->put(rep, queryParamsMap, + std::bind(&GroupSynchronization::onLeaveGroup, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3)); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::leaveGroup : " + << "groupSyncResource->put was successful." << endl; + } + else + { + cout << "GroupSynchronization::leaveGroup : " + << "groupSyncResource->put was unsuccessful. result - " << result + << endl; + } + + // deleting all remote resources. These are copied in onGetJoinedRemoteChild() + deleteGroup(collectionResourceType); + } + } + else + { + cout << "GroupSynchronization::leaveGroup : Error! Input params are wrong." << endl; + return OC_STACK_INVALID_PARAM; + } + + return OC_STACK_OK; +} + +void GroupSynchronization::deleteGroup(std::string collectionResourceType) +{ + if (0 != collectionResourceType.length()) + { + cout << "GroupSynchronization::deleteGroup" << endl; + + OCStackResult result; + + auto handleIt = collectionResourceHandleList.find(collectionResourceType); + if (handleIt == collectionResourceHandleList.end()) + { + cout << "GroupSynchronization::deleteGroup : " + << "Error! There is no collection resource handle to delete." << endl; + return; + } + OCResourceHandle collectionResHandle = handleIt->second; + + collectionResourceHandleList.erase(handleIt); + + auto handleListIt = childResourceHandleList.find(collectionResHandle); + if (handleListIt == childResourceHandleList.end()) + { + cout << "GroupSynchronization::deleteGroup : " + << "Error! There is no child resource list to delete." << endl; + return; + } + std::vector< OCResourceHandle > childList = handleListIt->second; + + childResourceHandleList.erase(handleListIt); + + result = OCPlatform::unbindResources(collectionResHandle, childList); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::deleteGroup : " + << "To unbind resources was successful." << endl; + } + else + { + cout << "GroupSynchronization::deleteGroup : " + << "To unbind resources was unsuccessful. result - " << result << endl; + } + + result = OCPlatform::unregisterResource(collectionResHandle); + if (result != OC_STACK_OK) + { + cout << "GroupSynchronization::deleteGroup : " + << "To unregister collection resource handle was successful." << endl; + } + else + { + cout << "GroupSynchronization::deleteGroup : " + << " To unregister collection resource handle was unsuccessful. result - " + << result << endl; + } + + OCResourceHandle resourceHandle; + std::vector< OCResourceHandle >::iterator It; + + for (unsigned int i = 0; i < childList.size(); i++) + { + resourceHandle = childList.at(i); + + It = std::find(deviceResourceHandleList.begin(), deviceResourceHandleList.end(), + resourceHandle); + if (It != deviceResourceHandleList.end()) // find !! + { + deviceResourceHandleList.erase(It); + } + else + { + result = OCPlatform::unregisterResource(resourceHandle); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::deleteGroup : UnregisterResource(" << i + 1 + << ") was successful." << endl; + } + else + { + cout << "GroupSynchronization::deleteGroup : UnregisterResource(" << i + 1 + << ") was unsuccessful. result - " << result << endl; + } + } + } + + handleIt = groupSyncResourceHandleList.find(collectionResourceType); + + // if groupSyncResourceHandleList has resourceType, + // group sync of this app created collection resource. + if (handleIt != groupSyncResourceHandleList.end()) + { + resourceHandle = handleIt->second; // group sync resource handle + result = OCPlatform::unregisterResource(resourceHandle); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::deleteGroup : " + << "To unregister group sync resource handle was successful." << endl; + } + else + { + cout << "GroupSynchronization::deleteGroup : " + << "To unregister group sync resource handle was unsuccessful. " + << "result - " << result << endl; + } + + groupSyncResourceHandleList.erase(handleIt); + } + + auto resourceIt = groupSyncResourceList.find(collectionResourceType); + if (resourceIt != groupSyncResourceList.end()) + { + groupSyncResourceList.erase(resourceIt); + } + + debugGroupSync(); + } + else + { + cout << "GroupSynchronization::deleteGroup : Error! Input params are wrong." << endl; + } +} + +std::map< std::string, OCResourceHandle > GroupSynchronization::getGroupList() +{ + return collectionResourceHandleList; +} + +OCEntityHandlerResult GroupSynchronization::groupEntityHandler( + const std::shared_ptr< OCResourceRequest > request) +{ + cout << "GroupSynchronization::groupEntityHandler\n"; + + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag == RequestHandlerFlag::InitFlag) + { + cout << "\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + else if (requestFlag == RequestHandlerFlag::RequestFlag) + { + cout << "\trequestFlag : Request\n"; + + // If the request type is GET + if (requestType == "GET") + { + cout << "\t\trequestType : GET\n"; + } + else if (requestType == "PUT") + { + cout << "\t\trequestType : PUT\n"; + + //get method name, group resource type and resource type to join group + OCRepresentation rp = request->getResourceRepresentation(); + std::string methodType = rp.getValue< std::string >("method"); + std::string collectionResourceType = rp.getValue< std::string >( + "collectionResourceType"); + std::string resourceType = rp.getValue< std::string >("resourceType"); + + cout << "\t\t\tmethod : " << methodType << endl; + cout << "\t\t\tcollection resourceType : " << collectionResourceType << endl; + cout << "\t\t\tresourceType : " << resourceType << endl; + + auto handleIt = collectionResourceHandleList.find(collectionResourceType); + if (handleIt == collectionResourceHandleList.end()) + { + cout << "GroupSynchronization::groupEntityHandler : " + << "Error! There is no collection resource handle to delete." + << endl; + return OC_EH_ERROR; + } + collectionResourceHandle = handleIt->second; + // in case of join group it is used in onFindResource() + + if (methodType == "joinGroup") + { + std::string resourceName = "coap://224.0.1.187/oc/core?rt="; + resourceName += resourceType; + cout << "\t\t\tresourceName : " << resourceName << endl; + + resourceRequest = request; + + OCPlatform::findResource("", resourceName, + std::bind(&GroupSynchronization::onFindResource, this, + std::placeholders::_1)); + } + else if (methodType == "leaveGroup") + { + auto it = childResourceHandleList.find(collectionResourceHandle); + if (it == childResourceHandleList.end()) + { + cout << "GroupSynchronization::groupEntityHandler : " + << "Error! There is no child resource list." << endl; + return OC_EH_ERROR; + } + + std::vector< OCResourceHandle > childList = it->second; + OCResourceHandle resourceHandle; + for (auto childIt = childList.begin(); childIt != childList.end();) + { + resourceHandle = (*childIt); + char* type = (char*) OCGetResourceTypeName(resourceHandle, 0); + + if (0 == resourceType.compare(type)) + { + cout << "GroupSynchronization::groupEntityHandler : " + << "Found! The resource to leave is found. - " << type + << endl; + + childIt = childList.erase(childIt++); + + OCStackResult result = OCPlatform::unbindResource( + collectionResourceHandle, resourceHandle); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::groupEntityHandler : " + << "To unbind resource was successful." << endl; + } + else + { + cout << "GroupSynchronization::groupEntityHandler : " + << "To unbind resource was unsuccessful. result - " + << result << endl; + } + + result = OCPlatform::unregisterResource(resourceHandle); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::groupEntityHandler : " + << "To unregister resource was successful." << endl; + } + else + { + cout << "GroupSynchronization::groupEntityHandler : " + << "To unregister resource was unsuccessful. result - " + << result << endl; + } + +// break; + } + else + { + ++childIt; + } + + } + + childResourceHandleList[collectionResourceHandle] = childList; + + debugGroupSync(); + + auto pResponse = std::make_shared< OC::OCResourceResponse >(); + pResponse->setRequestHandle(request->getRequestHandle()); + pResponse->setResourceHandle(request->getResourceHandle()); + pResponse->setErrorCode(200); + pResponse->setResponseResult(OC_EH_OK); + + OCRepresentation rep = request->getResourceRepresentation(); + pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE); + if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) + { + cout << "GroupSynchronization::groupEntityHandler : " + << "sendResponse is successful." << endl; + } + } + + if (methodType != "") //TODO: Check groupmethodtype NULL + { + } + } + else if (requestType == "POST") + { + // POST request operations + } + else if (requestType == "DELETE") + { + // DELETE request operations + } + } + else if (requestFlag == RequestHandlerFlag::ObserverFlag) + { + cout << "\trequestFlag : Observer\n"; + } + } + else + { + std::cout << "Request invalid" << std::endl; + } + + return OC_EH_OK; +} + +void GroupSynchronization::onFindGroup(std::shared_ptr< OCResource > resource) +{ + cout << "GroupSynchronization::onFindGroup" << endl; + + try + { + if (resource) + { +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////debugging + std::string resourceURI; + std::string hostAddress; + + // Get the resource URI + resourceURI = resource->uri(); + cout << "\tURI of the resource: " << resourceURI << endl; + + // Get the resource host address + hostAddress = resource->host(); + cout << "\tHost address of the resource: " << hostAddress << endl; + + hostAddress.append(resourceURI); + + // Get the resource types + cout << "\tList of resource types: " << endl; + + for (auto &resourceTypes : resource->getResourceTypes()) + { + cout << "\t\t" << resourceTypes << endl; + } + + // Get the resource interfaces + cout << "\tList of resource interfaces: " << endl; + for (auto &resourceInterfaces : resource->getResourceInterfaces()) + { + cout << "\t\t" << resourceInterfaces << endl; + } +////////////////////////////////////////////////////////////////////////////////////////////////// + + if (false == IsSameGroup(resource)) + { + saveGroup(resource); + findCallback(resource); + } + } + else + { + // Resource is invalid + cout << "Resource is invalid" << endl; + findCallback(NULL); + } + + } + catch (std::exception& e) + { + //log(e.what()); + } +} + +void GroupSynchronization::checkFindGroup(void) +{ + cout << "GroupSynchronization::checkFindGroup" << endl; + + for (int i = 0; i < 15; i++) + { + std::chrono::milliseconds workTime(300); + std::this_thread::sleep_for(workTime); + + std::lock_guard < std::mutex > guard(foundGroupMutex); + + if (false == foundGroupResourceList.empty()) + { + cout << "GroupSynchronization::checkFoundGroup : " << "Some group is received." + << endl; + return; + } + } + + cout << "GroupSynchronization::checkFoundGroup : " + << "It is failed to find resource within 3s." << endl; + + onFindGroup(NULL); + return; +} + +bool GroupSynchronization::IsSameGroup(std::shared_ptr< OCResource > resource) +{ + std::lock_guard < std::mutex > guard(foundGroupMutex); + + if (true == foundGroupResourceList.empty()) + { + cout << "GroupSynchronization::IsSameGroup : There is no found group." << endl; + return false; + } + + std::string foundHostAddress, savedHostAddress; + foundHostAddress = resource->host(); +// foundHostAddress.append (resource->uri()); + + for (unsigned int i = 0; i < foundGroupResourceList.size(); ++i) + { + savedHostAddress = (foundGroupResourceList.at(i))->host(); +// savedHostAddress.append ((foundGroupResourceList.at(i))->uri()); +// cout << "GroupSynchronization::IsSameGroup : foundHostAddress - " << foundHostAddress +// << ", savedHostAddress - " << savedHostAddress << endl; + + if (0 == foundHostAddress.compare(savedHostAddress.c_str())) + { + cout << "GroupSynchronization::IsSameGroup : Found! The same group is found." + << endl; + return true; + } + } + + cout << "GroupSynchronization::IsSameGroup : There is no same group." << endl; + return false; +} + +void GroupSynchronization::saveGroup(std::shared_ptr< OCResource > resource) +{ + cout << "GroupSynchronization::saveGroup" << endl; + + std::lock_guard < std::mutex > guard(foundGroupMutex); + + foundGroupResourceList.push_back(resource); +} + +void GroupSynchronization::onJoinGroup(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) +{ + if (eCode == OC_STACK_OK) + { + cout << "GroupSynchronization::onJoinGroup : " << endl; + + if (remoteCollectionResource) + { + std::string resourceInterface = DEFAULT_INTERFACE; + QueryParamsMap queryParamsMap; + + OCStackResult result = remoteCollectionResource->get("", resourceInterface, + queryParamsMap, + std::bind(&GroupSynchronization::onGetJoinedRemoteChild, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::onJoinGroup : " + << "remoteCollectionResource->get was successful." << endl; + } + else + { + cout << "GroupSynchronization::onJoinGroup : " + << "remoteCollectionResource->get was unsuccessful. result - " << result + << endl; + } + } + } + else + { + cout << "GroupSynchronization::onJoinGroup : error - " << eCode << endl; + } +} + +void GroupSynchronization::onFindResource(std::shared_ptr< OCResource > resource) +{ + cout << "GroupSynchronization::onFindResource" << endl; + + if (resource) + { +////////////////////////////////////////////////////////////////////////////////////////////////// +////////// debugging + std::string resourceURI; + std::string hostAddress; + + // Get the resource URI + resourceURI = resource->uri(); + cout << "\tURI of the resource: " << resourceURI << endl; + + // Get the resource host address + hostAddress = resource->host(); + cout << "\tHost address of the resource: " << hostAddress << endl; + + hostAddress.append(resourceURI); + + // Get the resource types + cout << "\tList of resource types: " << endl; + + for (auto &resourceTypes : resource->getResourceTypes()) + { + cout << "\t\t" << resourceTypes << endl; + } + + // Get the resource interfaces + cout << "\tList of resource interfaces: " << endl; + for (auto &resourceInterfaces : resource->getResourceInterfaces()) + { + cout << "\t\t" << resourceInterfaces << endl; + } +////////////////////////////////////////////////////////////////////////////////////////////////// + + OCResourceHandle resourceHandle; + OCStackResult result = OCPlatform::registerResource(resourceHandle, resource); + if (result != OC_STACK_OK) + { + cout << "GroupSynchronization::" + << "onFindResource - Resource to join creation was unsuccessful. result - " + << result << endl; + return; + } +// cout << "GroupSynchronization::onFindResource : creating resourceHandle. resource type - " +// << OCGetResourceTypeName(resourceHandle, 0) << endl; + + result = OCPlatform::bindResource(collectionResourceHandle, resourceHandle); + if (result != OC_STACK_OK) + { + cout << "GroupSynchronization::onFindResource : " + << "To bind resource was unsuccessful. result - " << result << endl; + return; + } + cout << "GroupSynchronization::onFindResource : " + << "To bind joinGroupHandle and resourceHandle was successful." << endl; + + auto it = childResourceHandleList.find(collectionResourceHandle); + std::vector< OCResourceHandle > childHandleList; + if (it != childResourceHandleList.end()) + { + childHandleList = it->second; + } + + childHandleList.push_back(resourceHandle); + childResourceHandleList[collectionResourceHandle] = childHandleList; + + auto pResponse = std::make_shared< OC::OCResourceResponse >(); + pResponse->setRequestHandle(resourceRequest->getRequestHandle()); + pResponse->setResourceHandle(resourceRequest->getResourceHandle()); + pResponse->setErrorCode(200); + pResponse->setResponseResult(OC_EH_OK); + + OCRepresentation rep = resourceRequest->getResourceRepresentation(); + pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE); + if (OC_STACK_OK == OCPlatform::sendResponse(pResponse)) + { + cout << "GroupSynchronization::onFindResource : sendResponse is successful." + << endl; + } + } + else + { + cout << "GroupSynchronization::onFindResource : " + << "Resource is invalid. So a new Group Resource has to be created." << endl; + } + + debugGroupSync(); +} + +void GroupSynchronization::onGetJoinedRemoteChild(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) +{ + if (eCode == OC_STACK_OK) + { + cout << "GroupSynchronization::onGetJoinedRemoteChild" << endl; + +////////////////////////////////////////////////////////////////////////////////////////////////// +////////// debugging + std::string resourceURI; + + // Get the resource URI + resourceURI = rep.getUri(); + cout << "\tURI of the resource: " << resourceURI << endl; + + // Get the resource types + cout << "\tList of resource types: " << endl; + + for (auto &resourceTypes : rep.getResourceTypes()) + { + cout << "\t\t" << resourceTypes << endl; + } + + // Get the resource interfaces + cout << "\tList of resource interfaces: " << endl; + for (auto &resourceInterfaces : rep.getResourceInterfaces()) + { + cout << "\t\t" << resourceInterfaces << endl; + } + + std::vector< OCRepresentation > childList = rep.getChildren(); + OCRepresentation child; + for (unsigned int i = 0; i < childList.size(); ++i) + { + cout << "\n\tchild resource - " << i + 1 << endl; + + child = childList.at(i); + resourceURI = child.getUri(); + cout << "\t\tURI of the resource: " << resourceURI << endl; + + cout << "\t\tList of resource types: " << endl; + for (auto &types : child.getResourceTypes()) + { + cout << "\t\t\t" << types << endl; + } + + cout << "\tList of resource interfaces: " << endl; + for (auto &interfaces : child.getResourceInterfaces()) + { + cout << "\t\t\t" << interfaces << endl; + } + } +////////////////////////////////////////////////////////////////////////////////////////////////// + + // creating remote collection resource handle + OCResourceHandle remoteCollectionResourceHandle; + resourceURI = remoteCollectionResource->uri(); + std::vector< std::string > types = remoteCollectionResource->getResourceTypes(); + std::vector< std::string > interfaces = + remoteCollectionResource->getResourceInterfaces(); + + OCStackResult result = OCPlatform::registerResource(remoteCollectionResourceHandle, + resourceURI, types[0], interfaces[0], NULL, OC_OBSERVABLE); + if (result != OC_STACK_OK) + { + cout << "GroupSynchronization::onGetJoinedRemoteChild - " + << "To register remoteCollectionResourceHandle" + << " was unsuccessful. result - " << result << endl; + return; + } + cout << "GroupSynchronization::onGetJoinedRemoteChild : " + "To register remoteCollectionResourceHandle was successful." << endl; + + // binding remote collection resource handle and resource handle to join + collectionResourceHandleList[types[0]] = remoteCollectionResourceHandle; + + result = OCPlatform::bindResource(remoteCollectionResourceHandle, deviceResourceHandle); + if (OC_STACK_OK == result) + { + cout << "GroupSynchronization::onGetJoinedRemoteChild : " + << "binding remoteCollectionResourceHandle and deviceResourceHandle" + << endl; + } + else + { + cout << "GroupSynchronization::onGetJoinedRemoteChild - " + << "To bind remoteCollectionResourceHandle and deviceResourceHandle " + << "was unsuccessful. result - " << result << endl; + } + + std::vector< OCResourceHandle > childHandleList; + childHandleList.push_back(deviceResourceHandle); + deviceResourceHandleList.push_back(deviceResourceHandle); + + // binding copied remote collection resource handle and copied remote resource + OCResourceHandle resourceHandle; + for (unsigned int i = 0; i < childList.size(); ++i) + { + cout << "\tremote resource - " << i + 1 << endl; + + child = childList.at(i); + resourceURI = child.getUri(); + types = child.getResourceTypes(); + interfaces = child.getResourceInterfaces(); + + if (0 == types[0].compare(OCGetResourceTypeName(deviceResourceHandle, 0))) + { + cout << "GroupSynchronization::onGetJoinedRemoteChild : " << types[0] + << " is bind already." << endl; + continue; + } + + result = OCPlatform::registerResource(resourceHandle, resourceURI, types[0], + interfaces[0], NULL, OC_OBSERVABLE); + if (OC_STACK_OK == result) + { + result = OCPlatform::bindResource(remoteCollectionResourceHandle, + resourceHandle); + if (result != OC_STACK_OK) + { + cout << "GroupSynchronization::onGetJoinedRemoteChild - " + << "binding remoteCollectionResourceHandle and resourceHandle " + << "was unsuccessful. result - " << result << endl; + OCPlatform::unregisterResource(resourceHandle); + } + + childHandleList.push_back(resourceHandle); + cout << "GroupSynchronization::onGetJoinedRemoteChild : " + << "binding remoteCollectionResourceHandle and resourceHandle" << endl; + } + else + { + cout << "GroupSynchronization::onGetJoinedRemoteChild - " + << "To register remoteCollectionResourceHandle was unsuccessful." + << " result - " << result << endl; + } + } + + childResourceHandleList[remoteCollectionResourceHandle] = childHandleList; + // this handle list is used to leave group + } + else + { + cout << "GroupSynchronization::onGetJoinedRemoteChild : error - " << eCode << endl; + } + + debugGroupSync(); +} + +void GroupSynchronization::onLeaveGroup(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) +{ + if (eCode == OC_STACK_OK) + { + cout << "GroupSynchronization::onLeaveGroup" << endl; + } + else + { + cout << "GroupSynchronization::onLeaveGroup : error - " << eCode << endl; + } + debugGroupSync(); +} + +void GroupSynchronization::debugGroupSync(void) +{ + cout << "GroupSynchronization::debugGroupSync" << endl; + + unsigned int i; + std::map< std::string, OCResourceHandle >::iterator handleIt; + std::map< OCResourceHandle, std::vector< OCResourceHandle > >::iterator childIt; + std::string type; + OCResourceHandle resourceHandle; + std::vector< OCResourceHandle > handleList; + std::shared_ptr< OCResource > resource; + + cout << "Resource Handle Created by App" << endl; + for (i = 0; i < deviceResourceHandleList.size(); i++) + { + resourceHandle = deviceResourceHandleList.at(i); + + cout << i + 1 << ". details" << endl; + cout << " uri - " << OCGetResourceUri(resourceHandle) << endl; + cout << " resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl; + cout << " resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0) + << endl << endl; + } + + cout << "\nGroup Sync Resource Handle List. The number is " + << groupSyncResourceHandleList.size() << endl; + i = 1; + for (handleIt = groupSyncResourceHandleList.begin(); + handleIt != groupSyncResourceHandleList.end(); ++handleIt) + { + type = handleIt->first; + cout << "\t" << i << ". group sync resource type - " << type << endl; + cout << "\t details" << endl; + + resourceHandle = handleIt->second; + cout << "\t uri - " << OCGetResourceUri(resourceHandle) << endl; + cout << "\t resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl; + cout << "\t resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0) + << endl << endl; + ; + i++; + } + + cout << "Copied Remote Group Sync Resource List. The number is " + << groupSyncResourceList.size() << endl; + std::vector< std::string > list; + i = 1; + for (auto resourceIt = groupSyncResourceList.begin(); + resourceIt != groupSyncResourceList.end(); ++resourceIt) + { + type = resourceIt->first; + cout << "\t" << i << ". group sync resource type - " << type << endl; + cout << "\t details" << endl; + + resource = resourceIt->second; + cout << "\t host - " << resource->host() << endl; + cout << "\t uri - " << resource->uri() << endl; + list = resource->getResourceTypes(); + cout << "\t resource type - " << list[0] << endl; + list = resource->getResourceInterfaces(); + cout << "\t resource interface - " << list[0] << endl << endl; + i++; + } + +// cout << "The number of collection Resource Handle is " << collectionResourceHandleList.size() +// << endl; +// cout << "The number of child resource handle list is " << childResourceHandleList.size() +// << endl; + + cout << "Collection Resource Handle List" << endl; + i = 1; + for (handleIt = collectionResourceHandleList.begin(); + handleIt != collectionResourceHandleList.end(); ++handleIt) + { + type = handleIt->first; + cout << "\t" << i << ". collection resource type - " << type << endl; + cout << "\t details" << endl; + + resourceHandle = handleIt->second; + cout << "\t uri - " << OCGetResourceUri(resourceHandle) << endl; + cout << "\t resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl; + cout << "\t resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0) + << endl << endl; + + childIt = childResourceHandleList.find(resourceHandle); + if (childIt != childResourceHandleList.end()) + { + handleList = childIt->second; + for (unsigned int j = 0; j < handleList.size(); j++) + { + + cout << "\t\t" << j + 1 << ". child resource details" << endl; + + resourceHandle = handleList.at(j); + cout << "\t\t uri - " << OCGetResourceUri(resourceHandle) << endl; + cout << "\t\t resource type - " << OCGetResourceTypeName(resourceHandle, 0) + << endl; + cout << "\t\t resource interface - " + << OCGetResourceInterfaceName(resourceHandle, 0) << endl << endl; + } + } + + i++; + } +} +} diff --git a/service/things-manager/sdk/src/GroupSynchronization.h b/service/things-manager/sdk/src/GroupSynchronization.h new file mode 100644 index 000000000..da5f15326 --- /dev/null +++ b/service/things-manager/sdk/src/GroupSynchronization.h @@ -0,0 +1,138 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file GroupSynchronization.h + +/// @brief This file contains the declaration of classes and +///its members related to GroupSynchronization. + +#ifndef __OC_GROUPSYNCHRONIZATION__ +#define __OC_GROUPSYNCHRONIZATION__ + +#include <string> +#include <vector> +#include <map> +#include <cstdlib> +#include "OCPlatform.h" +#include "OCApi.h" + +using namespace OC; + +namespace OIC +{ +class GroupSynchronization +{ +private: + + std::map< std::string, OCResourceHandle > collectionResourceHandleList; + // collection resource handle list + std::map< OCResourceHandle, std::vector< OCResourceHandle > > childResourceHandleList; + + std::map< std::string, OCResourceHandle > groupSyncResourceHandleList; + // group sync resource handle list + std::map< std::string, std::shared_ptr< OCResource > > groupSyncResourceList; + // remote group sync resource list + + std::vector< OCResourceHandle > deviceResourceHandleList; // these cannot be removed. + OCResourceHandle deviceResourceHandle; + + OCResourceHandle collectionResourceHandle; // collection handle + std::shared_ptr< OCResource > remoteCollectionResource; + + FindCallback findCallback; + + std::vector< std::shared_ptr< OCResource > > foundGroupResourceList; + + std::mutex foundGroupMutex; +// std::mutex groupSyncMutex; + + std::shared_ptr< OCResourceRequest > resourceRequest; // this is used for slow response + + static GroupSynchronization* groupSyncnstance; + + GroupSynchronization() + { + collectionResourceHandleList.clear(); + childResourceHandleList.clear(); + groupSyncResourceHandleList.clear(); + groupSyncResourceList.clear(); + deviceResourceHandleList.clear(); + + deviceResourceHandle = NULL; + collectionResourceHandle = NULL; + remoteCollectionResource = NULL; + findCallback = NULL; + } + ; + + ~GroupSynchronization() + { + std::map< std::string, OCResourceHandle >::iterator handleIt; + for (handleIt = collectionResourceHandleList.begin(); + handleIt != collectionResourceHandleList.end(); ++handleIt) + { + deleteGroup(handleIt->first); + } + } + ; + +public: + + static GroupSynchronization* getInstance(); + void deleteInstance(); + + OCStackResult findGroup(std::vector< std::string > collectionResourceTypes, + FindCallback callback); + OCStackResult createGroup(std::string collectionResourceType); + OCStackResult joinGroup(std::string collectionResourceTyps, + OCResourceHandle resourceHandle); + OCStackResult joinGroup(const std::shared_ptr< OCResource > resource, + OCResourceHandle resourceHandle); + OCStackResult leaveGroup(std::string collectionResourceType, + OCResourceHandle resourceHandle); + void deleteGroup(std::string collectionResourceType); + + std::map< std::string, OCResourceHandle > getGroupList(); + +private: + + OCEntityHandlerResult groupEntityHandler( + const std::shared_ptr< OCResourceRequest > request); + + void onFindGroup(std::shared_ptr< OCResource > resource); + void onJoinGroup(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode); + void onFindResource(std::shared_ptr< OCResource > resource); + void onGetJoinedRemoteChild(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode); + void onLeaveGroup(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode); +// void onSubscribePresence (OCStackResult result, +// const unsigned int nonce/*, std::string resourceType, std::string host*/); + + void checkFindGroup(void); + bool IsSameGroup(std::shared_ptr< OCResource > resource); + void saveGroup(std::shared_ptr< OCResource > resource); + + void debugGroupSync(void); + +}; +} +#endif // __OC_GROUPSYNCHRONIZATION__ diff --git a/service/things-manager/sdk/src/ThingsConfiguration.cpp b/service/things-manager/sdk/src/ThingsConfiguration.cpp new file mode 100755 index 000000000..5a4777fa9 --- /dev/null +++ b/service/things-manager/sdk/src/ThingsConfiguration.cpp @@ -0,0 +1,612 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file ThingsConfiguration.cpp +/// @brief + +#include <OCApi.h> +#include <OCPlatform.h> +#include <cstdlib> +#include <algorithm> +#include "ThingsConfiguration.h" + +using namespace OC; + +namespace OIC +{ + const int SUCCESS_RESPONSE = 0; + int cnt = 0; + + std::map< std::string, ConfigurationRequestEntry > configurationRequestTable; + + ThingsConfiguration* ThingsConfiguration::thingsConfigurationInstance = NULL; + + ConfigurationCallback g_bootstrapCallback; + + ThingsConfiguration* ThingsConfiguration::getInstance() + { + if (thingsConfigurationInstance == NULL) + { + thingsConfigurationInstance = new ThingsConfiguration(); + } + return thingsConfigurationInstance; + } + + void ThingsConfiguration::deleteInstance() + { + if (thingsConfigurationInstance) + { + delete thingsConfigurationInstance; + thingsConfigurationInstance = NULL; + } + } + + std::string ThingsConfiguration::getAttributeByConfigurationName(ConfigurationName name) + { + for (auto it = ConfigurationUnitTable.begin(); ConfigurationUnitTable.end() != it; it++) + { + if ((*it).m_name == name) + return (*it).m_attribute; + } + + return ""; + } + + std::string ThingsConfiguration::getUriByConfigurationName(ConfigurationName name) + { + for (auto it = ConfigurationUnitTable.begin(); ConfigurationUnitTable.end() != it; it++) + { + if ((*it).m_name == name) + return (*it).m_uri; + } + + return ""; + } + + std::string ThingsConfiguration::getUpdateVal(std::string conf) + { + std::map< std::string, ConfigurationRequestEntry >::iterator it = + configurationRequestTable.find(conf); + + if (it == configurationRequestTable.end()) + return NULL; + else + return it->second.m_updateVal; + + } + std::shared_ptr< OCResource > ThingsConfiguration::getResource(std::string conf) + { + std::map< std::string, ConfigurationRequestEntry >::iterator it = + configurationRequestTable.find(conf); + + if (it == configurationRequestTable.end()) + return NULL; + else + return it->second.m_resource; + } + + ConfigurationCallback ThingsConfiguration::getCallback(std::string conf) + { + std::map< std::string, ConfigurationRequestEntry >::iterator it = + configurationRequestTable.find(conf); + + if (it == configurationRequestTable.end()) + return NULL; + else + return it->second.m_callback; + } + + std::string ThingsConfiguration::getListOfSupportedConfigurationUnits() + { + std::string res; + + res = "{\"Configuration Units\":["; + + auto it = ConfigurationUnitTable.begin(); + while (1) + { + res = res + (*it).getJSON(); + it++; + + if (it == ConfigurationUnitTable.end()) + break; + else + res += ","; + } + + res += "]}"; + + return res; + } + + std::string ThingsConfiguration::getHostFromURI(std::string oldUri) + { + size_t f; + std::string newUri; + + if ((f = oldUri.find("/factoryset/oic/")) != string::npos) + newUri = oldUri.replace(f, oldUri.size(), ""); + else if ((f = oldUri.find("/oic/")) != string::npos) + newUri = oldUri.replace(f, oldUri.size(), ""); + + return newUri; + } + + void ThingsConfiguration::onDeleteActionSet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf) + { + std::shared_ptr < OCResource > resource = getResource(conf); + + std::cout << __func__ << std::endl; + + if (resource) + { + QueryParamsMap query; + + // After deletion of the left action set, find target child resource's URIs by sending + // GET message. Note that, this resource is surely a collection resource which has child + // resources. + resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsConfiguration::onGetChildInfoForUpdate, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, conf))); + + } + + } + + void ThingsConfiguration::onGetChildInfoForUpdate(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "GET request was successful" << std::endl; + + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + std::vector < OCRepresentation > children = rep.getChildren(); + for (auto oit = children.begin(); oit != children.end(); ++oit) + { + std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl; + } + + // Get information by using configuration name(conf) + std::shared_ptr < OCResource > resource = getResource(conf); + std::string actionstring = conf; + std::string uri = getUriByConfigurationName(conf); + std::string attr = getAttributeByConfigurationName(conf); + + if (uri == "") + return; + + if (resource) + { + // In this nest, we create a new action set of which name is the configuration name. + // Required information consists of a host address, URI, attribute key, and + // attribute value. + ActionSet *newActionSet = new ActionSet(); + newActionSet->actionsetName = conf; + + for (auto oit = children.begin(); oit != children.end(); ++oit) + { + Action *newAction = new Action(); + + // oit->getUri() includes a host address as well as URI. + // We should split these to each other and only use the host address to create + // a child resource's URI. Note that the collection resource and its child + // resource are located in same host. + newAction->target = getHostFromURI(oit->getUri()) + uri; + + Capability *newCapability = new Capability(); + newCapability->capability = attr; + newCapability->status = getUpdateVal(conf); + + newAction->listOfCapability.push_back(newCapability); + newActionSet->listOfAction.push_back(newAction); + } + + // Request to create a new action set by using the above actionSet + g_groupmanager->addActionSet(resource, newActionSet, + std::function< + void(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) >( + std::bind(&ThingsConfiguration::onCreateActionSet, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, conf))); + + free(newActionSet); + } + + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + void ThingsConfiguration::onGetChildInfoForGet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "GET request was successful" << std::endl; + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + std::shared_ptr< OCResource > resource, tempResource; + std::vector < std::shared_ptr< OCResource > > p_resources; + std::vector < std::string > m_if; + std::string uri = getUriByConfigurationName(conf); + + if (uri == "") + return; + + if (uri == "/oic/con" || uri == "/factoryset" || uri == "/factoryset/oic/con") + m_if.push_back(BATCH_INTERFACE); + else + m_if.push_back(DEFAULT_INTERFACE); + + std::vector < OCRepresentation > children = rep.getChildren(); + for (auto oit = children.begin(); oit != children.end(); ++oit) + { + std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl; + + // Using a host address and child URIs, we can dynamically create resource objects. + // Note that the child resources have not found before, we have no resource objects. + // For this reason, we create the resource objects. + + std::string host = getHostFromURI(oit->getUri()); + tempResource = OCPlatform::constructResourceObject(host, uri, true, + oit->getResourceTypes(), m_if); + + p_resources.push_back(tempResource); + } + + // Send GET messages to the child resources in turn. + for (unsigned int i = 0; i < p_resources.size(); ++i) + { + resource = p_resources.at(i); + if (resource) + { + try + { + if (isSimpleResource(resource)) + { + QueryParamsMap test; + resource->get(test, getCallback(conf)); + } + else + { + QueryParamsMap test; + resource->get(resource->getResourceTypes().at(0), BATCH_INTERFACE, test, + getCallback(conf)); + } + } + catch (OCException& e) + { + std::cout << e.reason() << std::endl; + } + + } + } + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + void ThingsConfiguration::onCreateActionSet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "PUT request was successful" << std::endl; + + std::shared_ptr < OCResource > resource = getResource(conf); + if (resource) + { + // Now, it is time to execute the action set. + g_groupmanager->executeActionSet(resource, conf, + std::function< + void(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) >( + std::bind(&ThingsConfiguration::onExecuteForGroupAction, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, conf))); + } + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + void ThingsConfiguration::onExecuteForGroupAction(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "PUT request was successful" << std::endl; + + getCallback(conf)(headerOptions, rep, eCode); + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + bool ThingsConfiguration::isSimpleResource(std::shared_ptr< OCResource > resource) + { + + for (unsigned int i = 0; i < resource->getResourceTypes().size(); ++i) + { + if (resource->getResourceTypes().at(i).find(".resourceset", 0) != std::string::npos) + return false; + } + + return true; + } + + bool ThingsConfiguration::hasBatchInterface(std::shared_ptr< OCResource > resource) + { + for (unsigned int i = 0; i < resource->getResourceInterfaces().size(); ++i) + { + if (resource->getResourceInterfaces().at(i) == BATCH_INTERFACE) + return true; + } + + return false; + } + + void ThingsConfiguration::onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, std::string conf) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "Get request was successful" << std::endl; + + getCallback(conf)(headerOptions, rep, eCode); + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + void ThingsConfiguration::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, std::string conf) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "PUT request was successful" << std::endl; + + // Callback + getCallback(conf)(headerOptions, rep, eCode); + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + OCStackResult ThingsConfiguration::updateConfigurations(std::shared_ptr< OCResource > resource, + std::map< ConfigurationName, ConfigurationValue > configurations, + ConfigurationCallback callback) + { + // For M2, # of configurations is 1 + // First, mapping a semantic name(ConfigurationUnit) into resource's name(uri ...) + if (configurations.size() == 0) + { + std::cout << "# of request configuration is 0" << std::endl; + return OC_STACK_ERROR; + } + + if (!resource) + { + std::cout << "resource is NULL\n"; + return OC_STACK_ERROR; + } + + std::map< ConfigurationName, ConfigurationValue >::iterator it = configurations.begin(); + std::string conf = it->first; // configuration name + std::transform(conf.begin(), conf.end(), conf.begin(), ::tolower); // to lower case + + // Check the request queue if a previous request is still left. If so, remove it. + std::map< std::string, ConfigurationRequestEntry >::iterator iter = + configurationRequestTable.find(conf); + if (iter != configurationRequestTable.end()) + configurationRequestTable.erase(iter); + + // Create new request entry stored in the queue + ConfigurationRequestEntry newCallback(conf, callback, resource, it->second); + configurationRequestTable.insert(std::make_pair(conf, newCallback)); + + OCRepresentation rep; + QueryParamsMap query; + if (isSimpleResource(resource)) + { + // This resource does not need to use a group manager. Just send a PUT message + rep.setValue(getAttributeByConfigurationName(conf), getUpdateVal(conf)); + return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsConfiguration::onGet, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, conf))); + } + else + { + // This resource is a collection resource which uses group manager functionalities. + // First, delete an existing action set of which name is same as a current action set + // name. As of now, the name is determined by "Configuration Name" which a user just + // specifies. + return g_groupmanager->deleteActionSet(resource, conf, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsConfiguration::onDeleteActionSet, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, conf))); + } + } + + OCStackResult ThingsConfiguration::getConfigurations(std::shared_ptr< OCResource > resource, + std::vector< ConfigurationName > configurations, ConfigurationCallback callback) + { + // For M2, # of configurations is 1 + // First, mapping a semantic name(ConfigurationUnit) into resource's name(uri ...) + if (configurations.size() == 0) + { + std::cout << "# of request configuration is 0" << std::endl; + return OC_STACK_ERROR; + } + if (!resource) + { + std::cout << "resource is NULL\n"; + return OC_STACK_ERROR; + } + + std::vector< ConfigurationName >::iterator it = configurations.begin(); + std::string conf = (*it); // configuration name + std::transform(conf.begin(), conf.end(), conf.begin(), ::tolower); // to lower case + + // Check the request queue if a previous request is still left. If so, remove it. + std::map< std::string, ConfigurationRequestEntry >::iterator iter = + configurationRequestTable.find(conf); + if (iter != configurationRequestTable.end()) + configurationRequestTable.erase(iter); + + // Create new request entry stored in the queue + ConfigurationRequestEntry newCallback(conf, callback, resource, conf); + configurationRequestTable.insert(std::make_pair(conf, newCallback)); + + QueryParamsMap query; + OCRepresentation rep; + + if (isSimpleResource(resource)) + { + // This resource is a simple resource. Just send a PUT message + std::string m_if = DEFAULT_INTERFACE; + + if (hasBatchInterface(resource)) + m_if = BATCH_INTERFACE; + + return resource->get(resource->getResourceTypes().at(0), m_if, query, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsConfiguration::onGet, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, conf))); + } + else + { + // This resource is a collection resource. On the contrary of a update, it does not use + // group manager functionality. It just acquires child resource's URI and send GET + // massages to the child resources in turn. + // First, request the child resources's URI. + return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsConfiguration::onGetChildInfoForGet, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, conf))); + } + + } + +// callback handler on GET request + void ThingsConfiguration::onGetBootstrapInformation(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) + { + if (eCode == SUCCESS_RESPONSE) + { + g_bootstrapCallback(headerOptions, rep, eCode); + } + + else + { + std::cout << "onGET Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + void ThingsConfiguration::onFoundBootstrapServer( + std::vector< std::shared_ptr< OCResource > > resources) + { + std::string resourceURI; + std::string hostAddress; + + try + { + // Do some operations with resource object. + for (unsigned int i = 0; i < resources.size(); ++i) + { + std::shared_ptr < OCResource > resource = resources.at(i); + + if (resource) + { // Request configuration resources + + std::cout << "Getting bootstrap server representation on: " << DEFAULT_INTERFACE + << std::endl; + + resource->get("bootstrap", DEFAULT_INTERFACE, QueryParamsMap(), + &onGetBootstrapInformation); + + } + else + { + // Resource is invalid + std::cout << "Resource is invalid" << std::endl; + } + } + + } + catch (std::exception& e) + { + //log(e.what()); + } + } + + OCStackResult ThingsConfiguration::doBootstrap(ConfigurationCallback callback) + { + if(callback == NULL) + return OC_STACK_ERROR; + else + g_bootstrapCallback = callback; + + // Find bootstrap server. + std::vector < std::string > type; + type.push_back("bootstrap"); + + std::cout << "Finding Bootstrap Server resource... " << std::endl; + return g_groupmanager->findCandidateResources(type, &onFoundBootstrapServer); + } +} diff --git a/service/things-manager/sdk/src/ThingsConfiguration.h b/service/things-manager/sdk/src/ThingsConfiguration.h new file mode 100644 index 000000000..79e2579c8 --- /dev/null +++ b/service/things-manager/sdk/src/ThingsConfiguration.h @@ -0,0 +1,546 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file ThingsConfiguration.h + +/// @brief This file contains the declaration of classes and its members related to +/// ThingsConfiguration. + +#ifndef __OC_THINGSCONFIGURATION__ +#define __OC_THINGSCONFIGURATION__ + +#include <string> +#include <vector> +#include <map> +#include <cstdlib> +#include "GroupManager.h" +#include "OCPlatform.h" +#include "OCApi.h" + +using namespace OC; + +namespace OIC +{ +/// Declearation of Configuation Callback funtion type + typedef std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) + > ConfigurationCallback; + + typedef std::string ConfigurationName; + typedef std::string ConfigurationValue; + + /** + * @brief + * The following class is used as a item stacking in request queue. The class stores a request + * and referential information (e.g., a configuration name, a target resource object, a callback + * function passed from the applications, and a update value). When the function for updating/ + * getting configuration value is called from applications, this class instance is created and + * stored in the request queue. The queue is maintained in a std::map structure so if desiring + * to find a specific request, you can find it by querying a configuration name. + */ + class ConfigurationRequestEntry + { + public: + ConfigurationRequestEntry(std::string ID, ConfigurationCallback callback, + std::shared_ptr< OCResource > resource, std::string updateVal): + m_ID(ID), m_callback(callback), m_resource(resource), m_updateVal(updateVal) + { + } + ; + + // Configuration Name (used in key value in std::map structure) + // e.g., time, network, security, and so on + std::string m_ID; + // Reference callback pointer + ConfigurationCallback m_callback; + // Reference resource object + std::shared_ptr< OCResource > m_resource; + // Update value only used for configuration update + std::string m_updateVal; + }; + + /** + * @brief + * The following class is used to store providing configuration name and its relevant + * information. The relevant information includes a brief description, uri, and attribute key. + * Note that a developer only specifies a configuration name, not URI nor attribute key, to + * update/get a value to a remote. Thus, using configuration name, we convert it to more + * specific information (i.e. uri and attribute key) to send a request. This class is reponsible + * to storing these information. + */ + class ConfigurationUnitInfo + { + public: + + std::string m_name; + std::string m_description; + std::string m_uri; + std::string m_attribute; + + ConfigurationUnitInfo(std::string name, std::string description, std::string uri, + std::string attribute) : + m_name(name), m_description(description), m_uri(uri), m_attribute(attribute) + { + } + ; + + // If a developer wants to know a list of configuration names, gives it in JSON format. + std::string getJSON() + { + std::string res; + + res = "{\"name\":\"" + m_name + "\",\"description\":\"" + m_description + "\"}"; + + return res; + } + }; + +#define NUMCONFUNIT 6 + typedef std::string ConfigurationName; + typedef std::string ConfigurationValue; + + class ThingsConfiguration + { + public: + /** + * Constructor for ThingsConfiguration. Constructs a new ThingsConfiguration + */ + ThingsConfiguration(void) + { + ConfigurationUnitInfo unit[] = + { + { "configuration", "Configuration Collection's value and its child resource's value", + "/oic/con", "value" }, + { "region", "the current region in which the device is located geographically", + "/oic/con/0/region", "value" }, + { "timelink", "link of time collection.", "/oic/con/0/time", "link" }, + { "ipaddress", "IP Address", "/oic/con/network/0/IPAddress", "value" }, + { "securitymode", + "Resource for security information (credentials, access control list etc.)", + "/oic/con/security/0/mode", "value" }, + { "getfactoryset", "get all default configuration value", "/factoryset/oic/con", + "value" } }; + + for (int i = 0; i < NUMCONFUNIT; i++) + ConfigurationUnitTable.push_back(unit[i]); + } + ; + + /** + * Virtual destructor + */ + ~ThingsConfiguration(void) + { + } + ; + + static ThingsConfiguration *thingsConfigurationInstance; + static ThingsConfiguration* getInstance(); + void deleteInstance(); + + void setGroupManager(GroupManager *groupmanager) + { + g_groupmanager = groupmanager; + } + ; + + /** + * API for updating configuration value of multiple things of a target group or a single + * thing. + * Callback is called when a response arrives. + * Before using the below function, a developer should acquire a resource pointer of + * (collection) resource that he want to send a request by calling findResource() function + * provided in OCPlatform. And he should also notice a "Configuration Name" term which + * represents a nickname of a target attribute of a resource that he wants to update. + * The base motivation to introduce the term is to avoid a usage of URI to access a resource + * from a developer. Thus, a developer should know which configuration names are supported + * by Things Configuration class and what the configuration name means. + * To get a list of supported configuration names, use getListOfSupportedConfigurationUnits( + * ) function, which provides the list in JSON format. + * NOTICE: A series of callback functions is called from updateConfigurations() function: + * (1) For a collection resource + * updateConfiguration()->onDeleteActionSet()->onGetChildInfoForUpdate()->onCreateActionSet( + * )->...(CoAP msg. is transmitted)->OnExecuteForGroupAction()->callback function in APP. + * (2) For a simple resource + * updateConfiguration()->...(CoAP msg. is transmitted)->OnPut()->callback function in APP. + * + * @param resource - resource pointer representing the target group or the single thing. + * @param configurations - ConfigurationUnit: a nickname of attribute of target resource + * (e.g., installedlocation, currency, (IP)address) + * Value : a value to be updated + * @param callback - callback. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult updateConfigurations(std::shared_ptr< OCResource > resource, + std::map< ConfigurationName, ConfigurationValue > configurations, + ConfigurationCallback callback); + + /** + * API for getting configuration value of multiple things of a target group or a single + * thing. + * Callback is called when a response arrives. + * NOTICE: A series of callback functions is called from getConfigurations() function: + * (1) For a collection resource + * getConfigurations()->onGetChildInfoForGet()->...(CoAP msg. is transmitted) + * ->callback function in APP. + * (2) For a simple resource + * getConfigurations()->...(CoAP msg. is transmitted)->onGet()->callback function in APP. + * + * @param resource - resource pointer representing the target group or the single thing. + * @param configurations - ConfigurationUnit: a nickname of attribute of target resource. + * @param callback - callback. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult getConfigurations(std::shared_ptr< OCResource > resource, + std::vector< ConfigurationName > configurations, ConfigurationCallback callback); + + /** + * API to show a list of supported configuration units (configurable parameters) + * Callback call when a response arrives. + * + * @return the list in JSON format + */ + std::string getListOfSupportedConfigurationUnits(); + + /** + * API for bootstrapping functionality. Find a bootstrap server and get configuration + * information from the bootstrap server. With the information, make a configuration + * resource. + * + * @param callback - callback. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult doBootstrap(ConfigurationCallback callback); + + private: + + GroupManager *g_groupmanager; + + std::vector< ConfigurationUnitInfo > ConfigurationUnitTable; + + void onExecuteForGroupAction(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onGetChildInfoForUpdate(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onGetChildInfoForGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, std::string conf); + void onCreateActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, std::string conf); + void onGetActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, std::string conf); + void onDeleteActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, std::string conf); + void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode, + std::string conf); + void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode, + std::string conf); + static void onFoundBootstrapServer(std::vector< std::shared_ptr< OCResource > > resources); + static void onGetBootstrapInformation(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode); + // Copyright 2014 Samsung Electronics All Rights Reserved. + + /// @file ThingsConfiguration.h + + /// @brief This file contains the declaration of classes and its members related to + /// ThingsConfiguration. + +#ifndef __OC_THINGSCONFIGURATION__ +#define __OC_THINGSCONFIGURATION__ + +#include <string> +#include <vector> +#include <map> +#include <cstdlib> +#include "GroupManager.h" +#include "OCPlatform.h" +#include "OCApi.h" + + using namespace OC; + +/// Declearation of Configuation Callback funtion type + typedef std::function< + void(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) > ConfigurationCallback; + + typedef std::string ConfigurationName; + typedef std::string ConfigurationValue; + + /** + * @brief + * The following class is used as a item stacking in request queue. The class stores a + * request and referential information (e.g., a configuration name, a target resource + * object, a callback function passed from the applications, and a update value). When the + * function for updating/getting configuration value is called from applications, this class + * instance is created and stored in the request queue. The queue is maintained in + * a std::map structure so if desiring to find a specific request, you can find it + * by querying a configuration name. + */ + class ConfigurationRequestEntry + { + public: + ConfigurationRequestEntry(std::string ID, ConfigurationCallback callback, + std::shared_ptr< OCResource > resource, std::string updateVal) : + m_ID(ID), m_callback(callback), m_resource(resource), m_updateVal(updateVal) + { + } + ; + + // Configuration Name (used in key value in std::map structure) + // e.g., time, network, security, and so on + std::string m_ID; + // Reference callback pointer + ConfigurationCallback m_callback; + // Reference resource object + std::shared_ptr< OCResource > m_resource; + // Update value only used for configuration update + std::string m_updateVal; + }; + + /** + * @brief + * The following class is used to store providing configuration name and its relevant + * information. The relevant information includes a brief description, uri, and attribute + * key. Note that a developer only specifies a configuration name, not URI nor attribute + * key, to update/get a value to a remote. Thus, using configuration name, we convert it to + * more specific information (i.e. uri and attribute key) to send a request. This class is + * reponsible to storing these information. + */ + class ConfigurationUnitInfo + { + public: + + std::string m_name; + std::string m_description; + std::string m_uri; + std::string m_attribute; + + ConfigurationUnitInfo(std::string name, std::string description, std::string uri, + std::string attribute) : + m_name(name), m_description(description), m_uri(uri), m_attribute(attribute) + { + } + ; + + // If a developer wants to know a list of configuration names, gives it in JSON format. + std::string getJSON() + { + std::string res; + + res = "{\"name\":\"" + m_name + "\",\"description\":\"" + m_description + "\"}"; + + return res; + } + }; + +#define NUMCONFUNIT 6 + typedef std::string ConfigurationName; + typedef std::string ConfigurationValue; + + class ThingsConfiguration + { + public: + /** + * Constructor for ThingsConfiguration. Constructs a new ThingsConfiguration + */ + ThingsConfiguration(void) + { + ConfigurationUnitInfo unit[] = + { + { "configuration", "Configuration value and its child resource's value", + "/oic/con", "value"}, + { "region", "the current region in which the Thing is located geographically", + "/oic/con/0/region", "value"}, + { "timelink", "link of time collection.", "/oic/con/0/time", "link"}, + { "ipaddress", "IP Address", "/oic/con/network/0/IPAddress", "value"}, + { "securitymode", + "Resource for security information (credentials, access control list etc.)", + "/oic/con/security/0/mode", "value"}, + { "getfactoryset", "get all default configuration value", + "/factoryset/oic/con", "value"}}; + + for (int i = 0; i < NUMCONFUNIT; i++) + ConfigurationUnitTable.push_back(unit[i]); + } + ; + + /** + * Virtual destructor + */ + ~ThingsConfiguration(void) + { + } + ; + + static ThingsConfiguration *thingsConfigurationInstance; + static ThingsConfiguration* getInstance(); + void deleteInstance(); + + void setGroupManager(GroupManager *groupmanager) + { + g_groupmanager = groupmanager; + } + ; + + /** + * API for updating configuration value of multiple things of a target group or a single + * thing. + * Callback is called when a response arrives. + * Before using the below function, a developer should acquire a resource pointer of + * (collection) resource that he want to send a request by calling findResource() + * function provided in OCPlatform. And he should also notice a "Configuration Name" + * term which represents a nickname of a target attribute of a resource that he wants to + * update. + * The base motivation to introduce the term is to avoid a usage of URI to access + * a resource from a developer. Thus, a developer should know which configuration names + * are supported by Things Configuration class and what the configuration name means. + * To get a list of supported configuration names, use getListOfSupportedConfigurationU- + * nits() function, which provides the list in JSON format. + * NOTICE: A series of callback functions is called from updateConfigurations() function + * (1) For a collection resource + * updateConfiguration()->onDeleteActionSet()->onGetChildInfoForUpdate()->onCreateActio- + * nSet()->...(CoAP msg. is transmitted)->OnExecuteForGroupAction()->callback function + * in APP. + * (2) For a simple resource + * updateConfiguration()->...(CoAP msg. is transmitted)->OnPut()->callback function in + * APP. + * + * @param resource - resource pointer representing the target group or the single thing. + * @param configurations - ConfigurationUnit: a nickname of attribute of target resource + * (e.g., installedlocation, currency, (IP)address) + * Value : a value to be updated + * @param callback - callback. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult updateConfigurations(std::shared_ptr< OCResource > resource, + std::map< ConfigurationName, ConfigurationValue > configurations, + ConfigurationCallback callback); + + /** + * API for getting configuration value of multiple things of a target group or a single + * thing. + * Callback is called when a response arrives. + * NOTICE: A series of callback functions is called from getConfigurations() function: + * (1) For a collection resource + * getConfigurations()->onGetChildInfoForGet()->...(CoAP msg. is transmitted) + * ->callback function in APP. + * (2) For a simple resource + * getConfigurations()->...(CoAP msg. is transmitted)->onGet()->callback function in APP + * + * @param resource - resource pointer representing the target group or the single thing. + * @param configurations - ConfigurationUnit: a nickname of attribute of target resource + * @param callback - callback. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult getConfigurations(std::shared_ptr< OCResource > resource, + std::vector< ConfigurationName > configurations, ConfigurationCallback callback); + + /** + * API to show a list of supported configuration units (configurable parameters) + * Callback call when a response arrives. + * + * @return the list in JSON format + */ + std::string getListOfSupportedConfigurationUnits(); + + /** + * API for bootstrapping functionality. Find a bootstrap server and get configuration + * information from the bootstrap server. With the information, make a configuration + * resource. + * + * @param callback - callback. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult doBootstrap(ConfigurationCallback callback); + + private: + + GroupManager *g_groupmanager; + + std::vector< ConfigurationUnitInfo > ConfigurationUnitTable; + + void onExecuteForGroupAction(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onGetChildInfoForUpdate(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onGetChildInfoForGet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onCreateActionSet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onGetActionSet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onDeleteActionSet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onGet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onPut(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + static void onFoundBootstrapServer(std::vector< std::shared_ptr< OCResource > + > resources); + static void onGetBootstrapInformation(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode); + + std::shared_ptr< OCResource > getResource(std::string conf); + ConfigurationCallback getCallback(std::string conf); + std::string getUpdateVal(std::string conf); + std::string getAttributeByConfigurationName(ConfigurationName name); + std::string getUriByConfigurationName(ConfigurationName name); + + std::string getHostFromURI(std::string oldUri); + + bool isSimpleResource(std::shared_ptr< OCResource > resource); + bool hasBatchInterface(std::shared_ptr< OCResource > resource); + + }; + +#endif /* __OC_THINGSCONFIGURATION__*/ + + std::shared_ptr< OCResource > getResource(std::string conf); + ConfigurationCallback getCallback(std::string conf); + std::string getUpdateVal(std::string conf); + std::string getAttributeByConfigurationName(ConfigurationName name); + std::string getUriByConfigurationName(ConfigurationName name); + + std::string getHostFromURI(std::string oldUri); + + bool isSimpleResource(std::shared_ptr< OCResource > resource); + bool hasBatchInterface(std::shared_ptr< OCResource > resource); + + }; +} +#endif /* __OC_THINGSCONFIGURATION__*/ + diff --git a/service/things-manager/sdk/src/ThingsDiagnostics.cpp b/service/things-manager/sdk/src/ThingsDiagnostics.cpp new file mode 100644 index 000000000..7eccc6269 --- /dev/null +++ b/service/things-manager/sdk/src/ThingsDiagnostics.cpp @@ -0,0 +1,395 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file ThingsDiagnostics.cpp +/// @brief + +#include <OCApi.h> +#include <OCPlatform.h> +#include <cstdlib> + +#include "ThingsDiagnostics.h" + +using namespace OC; + +namespace OIC +{ + const int SUCCESS_RESPONSE = 0; + + std::map< std::string, DiagnosticsRequestEntry > diagnosticsRequestTable; + + ThingsDiagnostics* ThingsDiagnostics::thingsDiagnosticsInstance = NULL; + + ThingsDiagnostics* ThingsDiagnostics::getInstance() + { + if (thingsDiagnosticsInstance == NULL) + { + thingsDiagnosticsInstance = new ThingsDiagnostics(); + } + return thingsDiagnosticsInstance; + } + + void ThingsDiagnostics::deleteInstance() + { + if (thingsDiagnosticsInstance) + { + delete thingsDiagnosticsInstance; + thingsDiagnosticsInstance = NULL; + } + } + + std::string ThingsDiagnostics::getAttributeByDiagnosticsName(DiagnosticsName name) + { + for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++) + { + if ((*it).m_name == name) + return (*it).m_attribute; + } + + return ""; + } + + std::string ThingsDiagnostics::getUriByDiagnosticsName(DiagnosticsName name) + { + for (auto it = DiagnosticsUnitTable.begin(); DiagnosticsUnitTable.end() != it; it++) + { + if ((*it).m_name == name) + return (*it).m_uri; + } + + return ""; + } + + std::string ThingsDiagnostics::getUpdateVal(std::string diag) + { + std::map< std::string, DiagnosticsRequestEntry >::iterator it = + diagnosticsRequestTable.find(diag); + + if (it == diagnosticsRequestTable.end()) + return NULL; + else + return it->second.m_updateVal; + + } + std::shared_ptr< OCResource > ThingsDiagnostics::getResource(std::string diag) + { + std::map< std::string, DiagnosticsRequestEntry >::iterator it = + diagnosticsRequestTable.find(diag); + + if (it == diagnosticsRequestTable.end()) + return NULL; + else + return it->second.m_resource; + } + + DiagnosticsCallback ThingsDiagnostics::getCallback(std::string diag) + { + std::map< std::string, DiagnosticsRequestEntry >::iterator it = + diagnosticsRequestTable.find(diag); + + if (it == diagnosticsRequestTable.end()) + return NULL; + else + return it->second.m_callback; + } + + std::string ThingsDiagnostics::getHostFromURI(std::string oldUri) + { + size_t f; + std::string newUri; + + if ((f = oldUri.find("/factoryset/oic/")) != string::npos) + newUri = oldUri.replace(f, oldUri.size(), ""); + else if ((f = oldUri.find("/oic/")) != string::npos) + newUri = oldUri.replace(f, oldUri.size(), ""); + + return newUri; + } + + std::string ThingsDiagnostics::getListOfSupportedDiagnosticsUnits() + { + std::string res; + + res = "{\"Diagnostics Units\":["; + + auto it = DiagnosticsUnitTable.begin(); + while (1) + { + res = res + (*it).getJSON(); + it++; + + if (it == DiagnosticsUnitTable.end()) + break; + else + res += ","; + } + + res += "]}"; + + return res; + } + + void ThingsDiagnostics::onGetChildInfoForUpdate(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string diag) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "GET request was successful" << std::endl; + + std::cout << "\tResource URI: " << rep.getUri() << std::endl; + + std::vector < OCRepresentation > children = rep.getChildren(); + for (auto oit = children.begin(); oit != children.end(); ++oit) + { + std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl; + } + + // Get information by using diagnostics name(diag) + std::shared_ptr < OCResource > resource = getResource(diag); + std::string actionstring = diag; + std::string uri = getUriByDiagnosticsName(diag); + std::string attr = getAttributeByDiagnosticsName(diag); + + if (uri == "") + return; + + if (resource) + { + // In this nest, we create a new action set of which name is the dignostics name. + // Required information consists of a host address, URI, attribute key, and + // attribute value. + ActionSet *newActionSet = new ActionSet(); + newActionSet->actionsetName = diag; + + for (auto oit = children.begin(); oit != children.end(); ++oit) + { + Action *newAction = new Action(); + + // oit->getUri() includes a host address as well as URI. + // We should split these to each other and only use the host address to create + // a child resource's URI. Note that the collection resource and its child + // resource are located in same host. + newAction->target = getHostFromURI(oit->getUri()) + uri; + + Capability *newCapability = new Capability(); + newCapability->capability = attr; + newCapability->status = getUpdateVal(diag); + + newAction->listOfCapability.push_back(newCapability); + newActionSet->listOfAction.push_back(newAction); + } + + // Request to create a new action set by using the above actionSet + g_groupmanager->addActionSet(resource, newActionSet, + std::function< + void(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) >( + std::bind(&ThingsDiagnostics::onCreateActionSet, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, diag))); + + free(newActionSet); + + } + + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + void ThingsDiagnostics::onCreateActionSet(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string diag) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "PUT request was successful" << std::endl; + + std::shared_ptr < OCResource > resource = getResource(diag); + if (resource) + { + // Now, it is time to execute the action set. + g_groupmanager->executeActionSet(resource, diag, + std::function< + void(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode) >( + std::bind(&ThingsDiagnostics::onExecuteForGroupAction, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, diag))); + } + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + void ThingsDiagnostics::onExecuteForGroupAction(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string diag) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "PUT request was successful" << std::endl; + + getCallback(diag)(headerOptions, rep, eCode); + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + void ThingsDiagnostics::onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, std::string diag) + { + if (eCode == SUCCESS_RESPONSE) + { + std::cout << "PUT request was successful" << std::endl; + + getCallback(diag)(headerOptions, rep, eCode); + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); + } + } + + bool ThingsDiagnostics::isSimpleResource(std::shared_ptr< OCResource > resource) + { + for (unsigned int i = 0; i < resource->getResourceTypes().size(); ++i) + { + if (resource->getResourceTypes().at(0).find(".resourceset", 0) != std::string::npos) + return false; + } + + return true; + } + + OCStackResult ThingsDiagnostics::reboot(std::shared_ptr< OCResource > resource, + DiagnosticsCallback callback) + { + if (!resource) + { + std::cout << "resource is NULL\n"; + return OC_STACK_ERROR; + } + + std::string diag = "reboot"; + + // Check the request queue if a previous request is still left. If so, remove it. + std::map< std::string, DiagnosticsRequestEntry >::iterator iter = + diagnosticsRequestTable.find(diag); + if (iter != diagnosticsRequestTable.end()) + diagnosticsRequestTable.erase(iter); + + // Create new request entry stored in the queue + DiagnosticsRequestEntry newCallback(diag, callback, resource, "true"); + diagnosticsRequestTable.insert(std::make_pair(diag, newCallback)); + + QueryParamsMap query; + OCRepresentation rep; + + if (isSimpleResource(resource)) + { + // This resource is a simple resource. Just send a PUT message + OCRepresentation rep; + rep.setValue < std::string > (diag, "true"); + + return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, diag))); + } + else + { + // This resource is a collection resource. It just acquires child resource's URI and + // send GET massages to the child resources in turn. + // First, request the child resources's URI. + // TODO: Add a deletion of actionset + return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, diag))); + } + } + + OCStackResult ThingsDiagnostics::factoryReset(std::shared_ptr< OCResource > resource, + DiagnosticsCallback callback) + { + if (!resource) + { + std::cout << "resource is NULL\n"; + return OC_STACK_ERROR; + } + + std::string diag = "factoryreset"; + + // Check the request queue if a previous request is still left. If so, remove it. + std::map< std::string, DiagnosticsRequestEntry >::iterator iter = + diagnosticsRequestTable.find(diag); + if (iter != diagnosticsRequestTable.end()) + diagnosticsRequestTable.erase(iter); + + // Create new request entry stored in the queue + DiagnosticsRequestEntry newCallback(diag, callback, resource, "true"); + diagnosticsRequestTable.insert(std::make_pair(diag, newCallback)); + + QueryParamsMap query; + OCRepresentation rep; + + if (isSimpleResource(resource)) + { + // This resource is a simple resource. Just send a PUT message + OCRepresentation rep; + rep.setValue < std::string > ("value", "true"); + + return resource->put(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, rep, query, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsDiagnostics::onPut, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, diag))); + } + else + { + // This resource is a collection resource. It just acquires child resource's URI and + // send GET massages to the child resources in turn. + // First, request the child resources's URI. + // TODO: Add a deletion of actionset + return resource->get(resource->getResourceTypes().at(0), DEFAULT_INTERFACE, query, + std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode) >( + std::bind(&ThingsDiagnostics::onGetChildInfoForUpdate, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, diag))); + } + } +} diff --git a/service/things-manager/sdk/src/ThingsDiagnostics.h b/service/things-manager/sdk/src/ThingsDiagnostics.h new file mode 100644 index 000000000..dda93621c --- /dev/null +++ b/service/things-manager/sdk/src/ThingsDiagnostics.h @@ -0,0 +1,223 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file ThingsDiagnostics.h + +/// @brief This file contains the declaration of classes and its members related to +/// ThingsDiagnostics. + +#ifndef __OC_THINGSDIAGNOSTICS__ +#define __OC_THINGSDIAGNOSTICS__ + +#include <string> +#include <vector> +#include <map> +#include <cstdlib> +#include "OCPlatform.h" +#include "OCApi.h" +#include "GroupManager.h" + +using namespace OC; +namespace OIC +{ + + /// Declearation of Diagnostics Callback funtion type + typedef std::function< + void(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) + > DiagnosticsCallback; + + /** + * @brief + * The following class is used as a item stacking in request queue. The class stores a request + * and referential information (e.g., a diagnostics name, a target resource object, a callback + * function passed from the applications, and a update value). When the function for updating/ + * getting diagnostics value is called from applications, this class instance is created and + * stored in the request queue. The queue is maintained in a std::map structure so if desiring + * to find a specific request, you can find it by querying a diagnostics name. + */ + class DiagnosticsRequestEntry + { + public: + DiagnosticsRequestEntry(std::string ID, DiagnosticsCallback callback, + std::shared_ptr< OCResource > resource, std::string updateVal) : + m_ID(ID), m_callback(callback), m_resource(resource), m_updateVal(updateVal) + { + } + ; + + // Diagnostics Name (used in key value in std::map structure) + // e.g., reboot and factoryset + std::string m_ID; + + // Reference callback pointer + DiagnosticsCallback m_callback; + + // Reference resource object + std::shared_ptr< OCResource > m_resource; + + // Update value only used for diagnostics update (always "true") + std::string m_updateVal; + }; + + /** + * @brief + * The following class is used to store providing diagnostics name and its relevant information + * The relevant information includes a brief description, uri, and attribute key. + * Note that a developer only specifies a diagnostics name, not URI nor attribute key, to + * update a value to a remote. Thus, using diagnostics name, we convert it to more specific + * information (i.e. uri and attribute key) to send a request. This class is reponsible to + * storing these information. + */ + class DiagnosticsUnitInfo + { + public: + DiagnosticsUnitInfo(std::string name, std::string description, std::string uri, + std::string attribute) : + m_name(name), m_description(description), m_uri(uri), m_attribute(attribute) + { + } + ; + + std::string m_name; + std::string m_description; + std::string m_uri; + std::string m_attribute; + + // If a developer wants to know a list of diagnostics names, gives it in JSON format. + std::string getJSON() + { + std::string res; + + res = "{\"name\":\"" + m_name + "\",\"description\":\"" + m_description + "\"}"; + + return res; + } + }; + +#define NUMDIAGUNIT 3 + typedef std::string DiagnosticsName; + typedef std::string DiagnosticsValue; + + class ThingsDiagnostics + { + public: + /** + * Constructor for ThingsDiagnostics. Constructs a new ThingsDiagnostics + */ + ThingsDiagnostics(void) + { + DiagnosticsUnitInfo unit[] = + { + { "reboot", "reboot", "/oic/diag/0/reboot", "value" }, + { "value", + "Collecting any device statistics", + "/oic/diag/0/startCollection", "value" }, + { "factoryreset", "restore all configuration values to default values", + "/oic/diag/0/factoryReset", "value" } }; + + for (int i = 0; i < NUMDIAGUNIT; i++) + DiagnosticsUnitTable.push_back(unit[i]); + } + ; + + /** + * Virtual destructor + */ + ~ThingsDiagnostics(void) + { + } + ; + + static ThingsDiagnostics *thingsDiagnosticsInstance; + static ThingsDiagnostics* getInstance(); + void deleteInstance(); + + void setGroupManager(GroupManager *groupmanager) + { + g_groupmanager = groupmanager; + } + ; + + /** + * API to make things reboot + * Callback call when a response arrives. + * + * @param resource - resource pointer representing the target group + * @param callback - callback. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + OCStackResult reboot(std::shared_ptr< OCResource > resource, DiagnosticsCallback callback); + + /** + * API for factory reset on device + * Callback call when a response arrives. + * + * @param resource - resource pointer representing the target group + * @param callback - callback. + * + * @return OCStackResult return value of this API. Returns OC_STACK_OK if success. + * + * NOTE: OCStackResult is defined in ocstack.h. + */ + + OCStackResult factoryReset(std::shared_ptr< OCResource > resource, + DiagnosticsCallback callback); + + /** + * API to show a list of supported diagnostics units + * Callback call when a response arrives. + * + * @return the list in JSON format + */ + std::string getListOfSupportedDiagnosticsUnits(); + + private: + + GroupManager *g_groupmanager; + + std::vector< DiagnosticsUnitInfo > DiagnosticsUnitTable; + + void onExecuteForGroupAction(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onGetChildInfoForUpdate(const HeaderOptions& headerOptions, + const OCRepresentation& rep, const int eCode, std::string conf); + void onCreateActionSet(const HeaderOptions& headerOptions, const OCRepresentation& rep, + const int eCode, std::string conf); + void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode, + std::string conf); + void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode, + std::string conf); + + std::shared_ptr< OCResource > getResource(std::string conf); + DiagnosticsCallback getCallback(std::string conf); + std::string getUpdateVal(std::string conf); + std::string getAttributeByDiagnosticsName(DiagnosticsName name); + std::string getUriByDiagnosticsName(DiagnosticsName name); + + std::string getHostFromURI(std::string oldUri); + + bool isSimpleResource(std::shared_ptr< OCResource > resource); + + }; +} +#endif /* __OC_THINGSCONFIGURATION__*/ diff --git a/service/things-manager/sdk/src/ThingsManager.cpp b/service/things-manager/sdk/src/ThingsManager.cpp new file mode 100644 index 000000000..a65b987dc --- /dev/null +++ b/service/things-manager/sdk/src/ThingsManager.cpp @@ -0,0 +1,188 @@ +//****************************************************************** +// +// Copyright 2014 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file ThingsManager.cpp + +#include "ThingsManager.h" +#include "GroupManager.h" +#include "GroupSynchronization.h" +#include "ThingsConfiguration.h" +#include "ThingsDiagnostics.h" +#include <algorithm> +#include <thread> + +using namespace OC; +namespace OIC +{ + + GroupManager *g_groupManager; + GroupSynchronization *g_groupSync = NULL; + ThingsConfiguration *g_thingsConf = NULL; + ThingsDiagnostics *g_thingsDiag = NULL; + + ThingsManager::ThingsManager(void) + { + g_groupManager = new GroupManager(); + g_groupSync = GroupSynchronization::getInstance(); + g_thingsConf = ThingsConfiguration::getInstance(); + g_thingsDiag = ThingsDiagnostics::getInstance(); + g_thingsConf->setGroupManager(g_groupManager); + g_thingsDiag->setGroupManager(g_groupManager); + } + + /** + * Virtual destructor + */ + ThingsManager::~ThingsManager(void) + { + delete g_groupManager; + g_groupSync->deleteInstance(); + g_thingsConf->deleteInstance(); + g_thingsDiag->deleteInstance(); + } + + OCStackResult ThingsManager::findCandidateResources(std::vector< std::string > resourceTypes, + std::function< void(std::vector< std::shared_ptr< OCResource > >) > callback, + int waitsec) + { + OCStackResult result = g_groupManager->findCandidateResources(resourceTypes, callback, + waitsec); + + return result; + } + + OCStackResult ThingsManager::subscribeCollectionPresence(std::shared_ptr< OCResource > resource, + std::function< void(std::string, OCStackResult) > callback) + { + OCStackResult result = g_groupManager->subscribeCollectionPresence(resource, callback); + + return result; + } + + OCStackResult ThingsManager::findGroup(std::vector< std::string > collectionResourceTypes, + FindCallback callback) + { + OCStackResult result = g_groupSync->findGroup(collectionResourceTypes, callback); + + return result; + } + + OCStackResult ThingsManager::createGroup(std::string collectionResourceType) + { + OCStackResult result = g_groupSync->createGroup(collectionResourceType); + + return result; + } + + OCStackResult ThingsManager::joinGroup(std::string collectionResourceType, + OCResourceHandle resourceHandle) + { + OCStackResult result = g_groupSync->joinGroup(collectionResourceType, resourceHandle); + + return result; + } + + OCStackResult ThingsManager::joinGroup(const std::shared_ptr< OCResource > resource, + OCResourceHandle resourceHandle) + { + OCStackResult result = g_groupSync->joinGroup(resource, resourceHandle); + + return result; + } + + OCStackResult ThingsManager::leaveGroup(std::string collectionResourceType, + OCResourceHandle resourceHandle) + { + OCStackResult result = g_groupSync->leaveGroup(collectionResourceType, resourceHandle); + + return result; + } + + void ThingsManager::deleteGroup(std::string collectionResourceType) + { + g_groupSync->deleteGroup(collectionResourceType); + } + + std::map< std::string, OCResourceHandle > ThingsManager::getGroupList() + { + return g_groupSync->getGroupList(); + } + + OCStackResult ThingsManager::updateConfigurations(std::shared_ptr< OCResource > resource, + std::map< ConfigurationName, ConfigurationValue > configurations, + ConfigurationCallback callback) + { + return g_thingsConf->updateConfigurations(resource, configurations, callback); + } + OCStackResult ThingsManager::getConfigurations(std::shared_ptr< OCResource > resource, + std::vector< ConfigurationName > configurations, ConfigurationCallback callback) + { + return g_thingsConf->getConfigurations(resource, configurations, callback); + } + std::string ThingsManager::getListOfSupportedConfigurationUnits() + { + return g_thingsConf->getListOfSupportedConfigurationUnits(); + } + + OCStackResult ThingsManager::doBootstrap(ConfigurationCallback callback) + { + return g_thingsConf->doBootstrap(callback); + } + + OCStackResult ThingsManager::reboot(std::shared_ptr< OCResource > resource, + ConfigurationCallback callback) + { + return g_thingsDiag->reboot(resource, callback); + } + OCStackResult ThingsManager::factoryReset(std::shared_ptr< OCResource > resource, + ConfigurationCallback callback) + { + return g_thingsDiag->factoryReset(resource, callback); + } + + std::string ThingsManager::getStringFromActionSet(const ActionSet *newActionSet) + { + return g_groupManager->getStringFromActionSet(newActionSet); + } + ActionSet* ThingsManager::getActionSetfromString(std::string desc) + { + return g_groupManager->getActionSetfromString(desc); + } + OCStackResult ThingsManager::addActionSet(std::shared_ptr< OCResource > resource, + const ActionSet* newActionSet, PutCallback cb) + { + return g_groupManager->addActionSet(resource, newActionSet, cb); + } + OCStackResult ThingsManager::executeActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, PostCallback cb) + { + return g_groupManager->executeActionSet(resource, actionsetName, cb); + } + OCStackResult ThingsManager::getActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, GetCallback cb) + { + return g_groupManager->getActionSet(resource, actionsetName, cb); + } + OCStackResult ThingsManager::deleteActionSet(std::shared_ptr< OCResource > resource, + std::string actionsetName, PostCallback cb) + { + return g_groupManager->deleteActionSet(resource, actionsetName, cb); + } +} |