#include <iostream>
#include "RCSDiscoveryManager.h"
+#include "RCSRepresentation.h"
#include "RCSRemoteResourceObject.h"
#include "RCSResourceAttributes.h"
#include "RCSAddress.h"
#include "OCPlatform.h"
+#define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
+
using namespace OC;
using namespace OIC::Service;
-#define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC, __VA_ARGS__ }
-
-void startMonitoring();
-void startMonitoring();
-void stopMonitoring();
-void getAttributeFromRemoteServer();
-void setAttributeToRemoteServer();
-void startCachingWithoutCallback();
-void startCachingWithCallback();
-void getResourceCacheState();
-void getCachedAttributes();
-void getCachedAttribute();
-void stopCaching();
-void discoverResource();
-void cancelDiscovery();
-int processUserInput();
-void selectResource();
-void printAttributes(const RCSResourceAttributes& attributes);
-
-class MenuList;
-
-class MenuItem
+struct CloseApp {};
+
+struct MenuItem
{
private:
- typedef void(*MenuHandler)();
+ typedef void(*Handler)();
public:
- MenuItem(const char* funcName, MenuHandler handler = nullptr,
- MenuHandler optionHandler = nullptr, MenuList* state = nullptr)
- : m_name(funcName), m_handler(handler), m_optionHandler(optionHandler),
- m_nextState(state)
- {
- }
+ const std::string title;
+ const Handler handler;
+};
- MenuList* command() const
- {
- std::cout << m_name << " start.." << std::endl;
- if(m_handler) m_handler();
+typedef void(*Runner)();
- if(m_optionHandler != nullptr) m_optionHandler();
+constexpr int RESOURCE_TEMP = 1;
+constexpr int RESOURCE_LIGHT = 2;
- return m_nextState;
- }
+const std::string RESOURCE_TYPE_TEMP = "oic.r.temperaturesensor";
+const std::string RESOURCE_TYPE_LIGHT = "oic.r.light";
- const char* getTitle() const
- {
- return m_name.c_str();
- }
+RCSRemoteResourceObject::Ptr g_selectedResource;
+std::vector<RCSRemoteResourceObject::Ptr> g_discoveredResources;
-private:
- const std::string m_name;
- const MenuHandler m_handler;
- const MenuHandler m_optionHandler;
- MenuList* const m_nextState ;
-};
+std::string g_attrKey;
-class MenuList
+Runner g_currentRun;
+
+std::ostream& operator<<(std::ostream& os, const RCSRemoteResourceObject::Ptr& object)
{
-public:
- MenuList(std::initializer_list<MenuItem> il)
- :m_menuItemList(std::move(il))
+ return os << "\turi : " << object->getUri() << std::endl <<
+ "\thost address : " << object->getAddress();
+}
+
+std::ostream& operator<<(std::ostream& os, const MenuItem& item)
+{
+ return os << item.title;
+}
+
+void onSelected(const RCSRemoteResourceObject::Ptr& object)
+{
+ g_selectedResource = object;
+}
+
+void onSelected(const MenuItem& item)
+{
+ std::cout << item.title << " start.." << std::endl;
+ item.handler();
+}
+
+int processUserInput(int min = std::numeric_limits<int>::min(),
+ int max = std::numeric_limits<int>::max())
+{
+ assert(min <= max);
+
+ int input;
+
+ std::cin >> input;
+ std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+ if (!std::cin.fail() && min <= input && input <= max) return input;
+
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+ throw std::runtime_error("Invalid Input, please try again");
+}
+
+template<typename D>
+void displayItem(int width, int index, const D& data)
+{
+ std::cout.width(width);
+ std::cout << std::right << index << ". ";
+ std::cout << data << std::endl;
+}
+
+template<typename T>
+void displayItems(const std::vector<T>& items)
+{
+ std::cout << std::endl;
+
+ const auto width = (items.size() + 1) / 10 + 1;
+
+ for(size_t i = 0; i < items.size(); ++i)
{
+ displayItem(width, i + 1, items[i]);
}
+ displayItem(width, items.size() + 1, "quit");
+}
- void display() const
- {
- std::cout << std::endl;
- int menuNum = 1;
+template<typename T>
+void selectItem(const std::vector<T>& items)
+{
+ int selected = processUserInput(1, items.size() + 1) - 1;
- for(const auto& menuItem : m_menuItemList)
- {
- std::cout.width(2);
- std::cout << std::right << menuNum++ << ". ";
- std::cout << menuItem.getTitle() << std::endl;
- }
- }
+ if(selected == static_cast<int>(items.size())) throw CloseApp();
- MenuList* select()
- {
- int input = processUserInput();
+ onSelected(items[selected]);
+}
- if(input == static_cast<int>(m_menuItemList.size())) return nullptr;
+template<typename T>
+void handleItems(const std::vector<T>& items)
+{
+ displayItems(items);
+ selectItem(items);
+}
- if(input > static_cast<int>(m_menuItemList.size()) || input <= 0)
- {
- std::cout << "Invalid input, please try again" << std::endl;
- return this;
- }
- auto nextMenuList = m_menuItemList[input-1].command();
+std::string inputInterface()
+{
+ std::string interfaceName;
- return nextMenuList == nullptr ? this : nextMenuList;
- }
+ std::cout << "\tInput the Interface you want to set : ";
+ std::cin >> interfaceName;
-private:
- const std::vector<MenuItem> m_menuItemList;
-};
+ return interfaceName;
+}
-constexpr int REQUEST_TEMP = 1;
-constexpr int REQUEST_LIGHT = 2;
+RCSResourceAttributes inputKeyValue()
+{
+ std::string key;
-const std::string TEMP = "oic.r.temperaturesensor";
-const std::string LIGHT = "oic.r.light";
+ std::cout << "\tEnter the Key you want to set : ";
+ std::cin >> key;
-std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> discoveryTask;
+ std::cout << "\tEnter the value(INT) you want to set :";
+ RCSResourceAttributes attrs;
+ attrs[key] = processUserInput();
-std::vector<RCSRemoteResourceObject::Ptr> resourceList;
-RCSRemoteResourceObject::Ptr selectedResource;
+ return attrs;
+}
-std::string defaultKey;
+void printAttribute(const std::string& key, const RCSResourceAttributes::Value& value)
+{
+ std::cout << "\tkey : " << key << std::endl
+ << "\tvalue : " << value.toString() << std::endl;
+}
-MenuList* currentMenuList;
+void printAttributes(const RCSResourceAttributes& attributes)
+{
+ if (attributes.empty())
+ {
+ std::cout << "\tattributes is empty" << std::endl;
+ }
-MenuList resourceMenu = {
- DECLARE_MENU(startMonitoring),
- DECLARE_MENU(stopMonitoring),
- DECLARE_MENU(getAttributeFromRemoteServer),
- DECLARE_MENU(setAttributeToRemoteServer),
- DECLARE_MENU(startCachingWithoutCallback),
- DECLARE_MENU(startCachingWithCallback),
- DECLARE_MENU(getResourceCacheState),
- DECLARE_MENU(getCachedAttributes),
- DECLARE_MENU(getCachedAttribute),
- DECLARE_MENU(stopCaching),
- { "quit" }
-};
+ for(const auto& attr : attributes)
+ {
+ printAttribute(attr.key(), attr.value());
+ }
+}
-MenuList cancelDiscoveryMenu = {
- DECLARE_MENU(cancelDiscovery, selectResource, &resourceMenu),
- { "quit" }
-};
+void print(const std::string& name, const std::vector< std::string >& elements)
+{
+ if (elements.empty())
+ {
+ std::cout << "\t" << name << " is empty" << std::endl;
+ return;
+ }
-MenuList discoveryMenu = {
- DECLARE_MENU(discoverResource, nullptr, &cancelDiscoveryMenu),
- { "quit" }
-};
+ std::cout << "\t" << name << " : " << std::endl;
+ for(const auto& item : elements)
+ {
+ std::cout << item << " ";
+ }
+ std::cout << std::endl;
+}
+
+void printUri(const std::string& uri)
+{
+ if(uri.empty())
+ {
+ std::cout << "\turi is empty" << std::endl;
+ }
+ else
+ {
+ std::cout << "\turi : " << uri << std::endl;
+ }
+}
-void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> discoveredResource)
+void printRepresentation(const RCSRepresentation& rep)
{
- std::cout << "onResourceDiscovered callback :: " << std::endl;
+ printUri(rep.getUri());
+ print("interfaces", rep.getInterfaces());
+ print("resourceTypes", rep.getResourceTypes());
+ printAttributes(rep.getAttributes());
- std::cout << "resourceURI : " << discoveredResource->getUri() << std::endl;
- std::cout << "hostAddress : " << discoveredResource->getAddress() << std::endl;
+ const auto& children = rep.getChildren();
- resourceList.push_back(discoveredResource);
+ if(children.empty())
+ {
+ std::cout << "\tchildren is empty" << std::endl;
+ }
+ else
+ {
+ int cnt = 0;
+ for(const auto& child : children)
+ {
+ std::cout << "========================================================" << std::endl;
+ std::cout << ++cnt << " chlid" << std::endl;
+ printRepresentation(child);
+ std::cout << "========================================================" << std::endl;
+ }
+ }
}
-void onResourceStateChanged(const ResourceState& resourceState)
+void onResourceStateChanged(ResourceState resourceState)
{
std::cout << "onResourceStateChanged callback" << std::endl;
printAttributes(attributes);
}
+void onRemoteGetReceived(const HeaderOpts&, const RCSRepresentation& rep, int)
+{
+ std::cout << "onRemoteGetReceived callback" << std::endl;
+
+ printRepresentation(rep);
+}
+
+void onRemoteSetReceived(const HeaderOpts&, const RCSRepresentation& rep, int)
+{
+ std::cout << "onRemoteSetReceived callback" << std::endl;
+
+ printRepresentation(rep);
+}
+
void startMonitoring()
{
- if (!selectedResource->isMonitoring())
- {
- selectedResource->startMonitoring(&onResourceStateChanged);
- std::cout << "\tHosting Started..." << std::endl;
- }
- else
+ if (g_selectedResource->isMonitoring())
{
std::cout << "\tAlready Started..." << std::endl;
+ return;
}
+
+ g_selectedResource->startMonitoring(&onResourceStateChanged);
+ std::cout << "\tMonitoring Started..." << std::endl;
}
void stopMonitoring()
{
- if (selectedResource->isMonitoring())
+ if (!g_selectedResource->isMonitoring())
{
- selectedResource->stopMonitoring();
- std::cout << "\tHosting stopped..." << std::endl;
- }
- else
- {
- std::cout << "\tHosting not started..." << std::endl;
+ std::cout << "\tMonitoring not started..." << std::endl;
+ return;
}
+
+ g_selectedResource->stopMonitoring();
+ std::cout << "\tMonitoring stopped..." << std::endl;
}
-void getAttributeFromRemoteServer()
+void getRemoteAttributes()
{
- selectedResource->getRemoteAttributes(&onRemoteAttributesReceived);
+ g_selectedResource->getRemoteAttributes(onRemoteAttributesReceived);
}
-void setAttributeToRemoteServer()
+void setRemoteAttributes()
{
- std::string key;
- RCSResourceAttributes setAttribute;
+ g_selectedResource->setRemoteAttributes(inputKeyValue(), onRemoteAttributesReceived);
+}
- std::cout << "\tEnter the Key you want to set : ";
- std::cin >> key;
- std::cout << "\tEnter the value(INT) you want to set :";
+void getWithInterface()
+{
+ RCSQueryParams queryParams;
+ queryParams.setResourceInterface(inputInterface());
+
+ g_selectedResource->get(queryParams, onRemoteGetReceived);
+}
+
+void setWithInterface()
+{
+ RCSQueryParams queryParams;
+ queryParams.setResourceInterface(inputInterface());
- setAttribute[key] = processUserInput();
- selectedResource->setRemoteAttributes(setAttribute,
- &onRemoteAttributesReceived);
+ g_selectedResource->set(queryParams, inputKeyValue(), onRemoteSetReceived);
}
void startCaching(RCSRemoteResourceObject::CacheUpdatedCallback cb)
{
- if (!selectedResource->isCaching())
- {
- selectedResource->startCaching(std::move(cb));
- std::cout << "\tCaching Started..." << std::endl;
- }
- else
+ if (g_selectedResource->isCaching())
{
std::cout << "\tAlready Started Caching..." << std::endl;
+ return;
}
+
+ g_selectedResource->startCaching(std::move(cb));
+ std::cout << "\tCaching Started..." << std::endl;
}
void startCachingWithoutCallback()
void getResourceCacheState()
{
- switch(selectedResource->getCacheState())
+ switch(g_selectedResource->getCacheState())
{
case CacheState::READY:
std::cout << "\tCurrent Cache State : CACHE_STATE::READY" << std::endl;
void getCachedAttributes()
{
- try
- {
- printAttributes(selectedResource->getCachedAttributes());
- }
- catch (const RCSBadRequestException& e)
- {
- std::cout << "Exception in getCachedAttributes : " << e.what() << std::endl;
- }
+ printAttributes(g_selectedResource->getCachedAttributes());
}
void getCachedAttribute()
{
- try
- {
- std::cout << "\tkey : " << defaultKey << std::endl
- << "\tvalue : " << selectedResource->getCachedAttribute(defaultKey).get< int >()
- << std::endl;
- }
- catch (const RCSBadRequestException& e)
- {
- std::cout << "Exception in getCachedAttribute : " << e.what() << std::endl;
- }
- catch (const RCSBadGetException& e)
- {
- std::cout << "Exception in getCachedAttribute : " << e.what() << std::endl;
- }
+ printAttribute(g_attrKey, g_selectedResource->getCachedAttribute(g_attrKey));
}
void stopCaching()
{
- if(selectedResource->isCaching())
- {
- selectedResource->stopCaching();
- std::cout << "\tCaching stopped..." << std::endl;
- }
- else
+ if(!g_selectedResource->isCaching())
{
std::cout << "\tCaching not started..." << std::endl;
+ return;
}
-}
-
-void platFormConfigure()
-{
- PlatformConfig config
- {
- OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
- };
- OCPlatform::Configure(config);
-}
-int processUserInput()
-{
- int userInput;
-
- while(true)
- {
- std::cin >> userInput;
- if (std::cin.fail())
- {
- std::cin.clear();
- std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
- std::cout << "Invalid Input, please try again" << std::endl;
- }
- else break;
- }
- return userInput;
+ g_selectedResource->stopCaching();
+ std::cout << "\tCaching stopped..." << std::endl;
}
-bool selectResourceType(std::string& resourceType)
+std::string selectResourceType()
{
std::cout << "========================================================" << std::endl;
std::cout << "1. Temperature Resource Discovery" << std::endl;
std::cout << "2. Light Resource Discovery" << std::endl;
std::cout << "========================================================" << std::endl;
- switch (processUserInput())
+ switch (processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT))
{
- case REQUEST_TEMP:
- resourceType = TEMP;
- defaultKey = "Temperature";
- return true;
- case REQUEST_LIGHT:
- resourceType = LIGHT;
- defaultKey = "Brightness";
- return true;
- default :
- std::cout << "Invalid input, please try again" << std::endl;
- return false;
+ case RESOURCE_TEMP:
+ g_attrKey = "Temperature";
+ return RESOURCE_TYPE_TEMP;
+ case RESOURCE_LIGHT:
+ g_attrKey = "Brightness";
+ return RESOURCE_TYPE_LIGHT;
}
+
+ throw std::logic_error("unreachable");
}
RCSAddress inputAddress()
{
std::cout << "========================================================" << std::endl;
- std::cout << "Please input address" << std::endl;
- std::cout << "(default is multicast. when you want to use unicast, input address" << std::endl;
+ std::cout << "Please input address (empty for multicast)" << std::endl;
std::cout << "========================================================" << std::endl;
std::string address;
return address.empty() ? RCSAddress::multicast() : RCSAddress::unicast(address);
}
-void discoverResource()
+void printDiscoveryInProgress()
{
- std::string resourceType = "";
-
- while(!selectResourceType(resourceType)) {}
-
- while(!discoveryTask)
- {
- try
- {
- discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
- inputAddress(), resourceType, &onResourceDiscovered);
- }
- catch (const RCSPlatformException& e)
- {
- std::cout << e.what() << std::endl;
- }
- }
+ std::cout << "Discovery in progress, press '1' to stop." << std::endl;
}
-void displayResourceList()
+void discoverResource()
{
- int cnt = 1;
- for(const auto& resource : resourceList)
+ auto onResourceDiscovered = [](
+ const RCSRemoteResourceObject::Ptr& discoveredResource)
{
- std::cout << cnt++ << ".\tresourceURI : " << resource->getUri() << std::endl <<
- "\thostAddress : " << resource->getAddress() << std::endl;
- }
-}
+ std::cout << "onResourceDiscovered callback :: " << std::endl;
-void selectResource()
-{
- displayResourceList();
+ std::cout << "uri : " << discoveredResource->getUri() << std::endl;
+ std::cout << "host address : " << discoveredResource->getAddress() << std::endl;
+
+ g_discoveredResources.push_back(discoveredResource);
+
+ printDiscoveryInProgress();
+ };
- std::cout << "select Resource..." << std::endl;
+ auto resourceType = selectResourceType();
+ auto address = inputAddress();
- selectedResource = resourceList[processUserInput()-1];
+ printDiscoveryInProgress();
- resourceList.clear();
+ auto discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(address,
+ resourceType, onResourceDiscovered);
+
+ while(processUserInput() != 1);
+
+ discoveryTask->cancel();
}
-void cancelDiscovery()
+void runResourceControl()
{
- if(!discoveryTask)
- {
- std::cout << "There is no discovery request..." << std::endl;
- return;
- }
- discoveryTask->cancel();
+ static std::vector<MenuItem> resourceMenuItems {
+ DECLARE_MENU(startMonitoring),
+ DECLARE_MENU(stopMonitoring),
+ DECLARE_MENU(getRemoteAttributes),
+ DECLARE_MENU(setRemoteAttributes),
+ DECLARE_MENU(getWithInterface),
+ DECLARE_MENU(setWithInterface),
+ DECLARE_MENU(startCachingWithoutCallback),
+ DECLARE_MENU(startCachingWithCallback),
+ DECLARE_MENU(getResourceCacheState),
+ DECLARE_MENU(getCachedAttributes),
+ DECLARE_MENU(getCachedAttribute),
+ DECLARE_MENU(stopCaching),
+ };
+
+ handleItems(resourceMenuItems);
}
-void printAttribute(const std::string key, const RCSResourceAttributes::Value& value)
+void runResourceSelection()
{
- std::cout << "\tkey : " << key << std::endl
- << "\tvalue : " << value.toString() << std::endl;
+ handleItems(g_discoveredResources);
+
+ g_currentRun = runResourceControl;
}
-void printAttributes(const RCSResourceAttributes& attributes)
+void runDiscovery()
{
- if (attributes.empty())
- {
- std::cout << "\tattributes is empty" << std::endl;
- }
- for(const auto& attr : attributes)
+ static std::vector<MenuItem> discoveryMenuItems {
+ DECLARE_MENU(discoverResource),
+ };
+
+ handleItems(discoveryMenuItems);
+
+ if (g_discoveredResources.empty()) throw std::runtime_error("No resource found!");
+
+ g_currentRun = runResourceSelection;
+}
+
+void configurePlatform()
+{
+ PlatformConfig config
{
- printAttribute(attr.key(), attr.value());
- }
+ OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
+ };
+ OCPlatform::Configure(config);
}
int main()
{
- platFormConfigure();
+ configurePlatform();
- currentMenuList = &discoveryMenu;
+ g_currentRun = runDiscovery;
- try
+ while (true)
{
- while(currentMenuList)
+ try
{
- currentMenuList->display();
-
- currentMenuList = currentMenuList->select();
+ g_currentRun();
+ }
+ catch (const std::exception& e)
+ {
+ std::cout << e.what() << std::endl;
+ }
+ catch (const CloseApp&)
+ {
+ break;
}
- }
- catch (const std::exception& e)
- {
- std::cout << "main exception : " << e.what() << std::endl;
}
- std::cout << "Stopping the Client" << std::endl;
+ std::cout << "Stopping the client" << std::endl;
return 0;
}