1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 #include "RCSDiscoveryManager.h"
24 #include "RCSRepresentation.h"
25 #include "RCSRemoteResourceObject.h"
26 #include "RCSResourceAttributes.h"
27 #include "RCSAddress.h"
29 #include "OCPlatform.h"
31 #define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
34 using namespace OIC::Service;
41 typedef void(*Handler)();
44 const std::string title;
45 const Handler handler;
48 typedef void(*Runner)();
50 constexpr int RESOURCE_TEMP = 1;
51 constexpr int RESOURCE_LIGHT = 2;
53 const std::string RESOURCE_TYPE_TEMP = "oic.r.temperaturesensor";
54 const std::string RESOURCE_TYPE_LIGHT = "oic.r.light";
56 RCSRemoteResourceObject::Ptr g_selectedResource;
57 std::vector<RCSRemoteResourceObject::Ptr> g_discoveredResources;
59 std::string g_attrKey;
63 std::ostream& operator<<(std::ostream& os, const RCSRemoteResourceObject::Ptr& object)
65 return os << "\turi : " << object->getUri() << std::endl <<
66 "\thost address : " << object->getAddress();
69 std::ostream& operator<<(std::ostream& os, const MenuItem& item)
71 return os << item.title;
74 void onSelected(const RCSRemoteResourceObject::Ptr& object)
76 g_selectedResource = object;
79 void onSelected(const MenuItem& item)
81 std::cout << item.title << " start.." << std::endl;
85 int processUserInput(int min = std::numeric_limits<int>::min(),
86 int max = std::numeric_limits<int>::max())
93 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
95 if (!std::cin.fail() && min <= input && input <= max) return input;
98 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
100 throw std::runtime_error("Invalid Input, please try again");
104 void displayItem(int width, int index, const D& data)
106 std::cout.width(width);
107 std::cout << std::right << index << ". ";
108 std::cout << data << std::endl;
112 void displayItems(const std::vector<T>& items)
114 std::cout << std::endl;
116 const auto width = (items.size() + 1) / 10 + 1;
118 for(size_t i = 0; i < items.size(); ++i)
120 displayItem(width, i + 1, items[i]);
122 displayItem(width, items.size() + 1, "quit");
126 void selectItem(const std::vector<T>& items)
128 int selected = processUserInput(1, items.size() + 1) - 1;
130 if(selected == static_cast<int>(items.size())) throw CloseApp();
132 onSelected(items[selected]);
136 void handleItems(const std::vector<T>& items)
142 std::string inputInterface()
144 std::string interfaceName;
146 std::cout << "\tInput the Interface you want to set : ";
147 std::cin >> interfaceName;
149 return interfaceName;
152 RCSResourceAttributes inputKeyValue()
156 std::cout << "\tEnter the Key you want to set : ";
159 std::cout << "\tEnter the value(INT) you want to set :";
160 RCSResourceAttributes attrs;
161 attrs[key] = processUserInput();
166 void printAttribute(const std::string& key, const RCSResourceAttributes::Value& value)
168 std::cout << "\tkey : " << key << std::endl
169 << "\tvalue : " << value.toString() << std::endl;
172 void printAttributes(const RCSResourceAttributes& attributes)
174 if (attributes.empty())
176 std::cout << "\tattributes is empty" << std::endl;
179 for(const auto& attr : attributes)
181 printAttribute(attr.key(), attr.value());
185 void print(const std::string& name, const std::vector< std::string >& elements)
187 if (elements.empty())
189 std::cout << "\t" << name << " is empty" << std::endl;
193 std::cout << "\t" << name << " : " << std::endl;
194 for(const auto& item : elements)
196 std::cout << item << " ";
198 std::cout << std::endl;
201 void printUri(const std::string& uri)
205 std::cout << "\turi is empty" << std::endl;
209 std::cout << "\turi : " << uri << std::endl;
213 void printRepresentation(const RCSRepresentation& rep)
215 printUri(rep.getUri());
216 print("interfaces", rep.getInterfaces());
217 print("resourceTypes", rep.getResourceTypes());
218 printAttributes(rep.getAttributes());
220 const auto& children = rep.getChildren();
224 std::cout << "\tchildren is empty" << std::endl;
229 for(const auto& child : children)
231 std::cout << "========================================================" << std::endl;
232 std::cout << ++cnt << " chlid" << std::endl;
233 printRepresentation(child);
234 std::cout << "========================================================" << std::endl;
239 void onResourceStateChanged(ResourceState resourceState)
241 std::cout << "onResourceStateChanged callback" << std::endl;
243 switch(resourceState)
245 case ResourceState::NONE:
246 std::cout << "\tState changed to : NOT_MONITORING" << std::endl;
249 case ResourceState::ALIVE:
250 std::cout << "\tState changed to : ALIVE" << std::endl;
253 case ResourceState::REQUESTED:
254 std::cout << "\tState changed to : REQUESTED" << std::endl;
257 case ResourceState::LOST_SIGNAL:
258 std::cout << "\tState changed to : LOST_SIGNAL" << std::endl;
261 case ResourceState::DESTROYED:
262 std::cout << "\tState changed to : DESTROYED" << std::endl;
267 void onCacheUpdated(const RCSResourceAttributes& attributes)
269 std::cout << "onCacheUpdated callback" << std::endl;
271 printAttributes(attributes);
274 void onRemoteAttributesReceived(const RCSResourceAttributes& attributes, int)
276 std::cout << "onRemoteAttributesReceived callback" << std::endl;
278 printAttributes(attributes);
281 void onRemoteGetReceived(const HeaderOpts&, const RCSRepresentation& rep, int)
283 std::cout << "onRemoteGetReceived callback" << std::endl;
285 printRepresentation(rep);
288 void onRemoteSetReceived(const HeaderOpts&, const RCSRepresentation& rep, int)
290 std::cout << "onRemoteSetReceived callback" << std::endl;
292 printRepresentation(rep);
295 void startMonitoring()
297 if (g_selectedResource->isMonitoring())
299 std::cout << "\tAlready Started..." << std::endl;
303 g_selectedResource->startMonitoring(&onResourceStateChanged);
304 std::cout << "\tMonitoring Started..." << std::endl;
307 void stopMonitoring()
309 if (!g_selectedResource->isMonitoring())
311 std::cout << "\tMonitoring not started..." << std::endl;
315 g_selectedResource->stopMonitoring();
316 std::cout << "\tMonitoring stopped..." << std::endl;
319 void getRemoteAttributes()
321 g_selectedResource->getRemoteAttributes(onRemoteAttributesReceived);
324 void setRemoteAttributes()
326 g_selectedResource->setRemoteAttributes(inputKeyValue(), onRemoteAttributesReceived);
329 void getWithInterface()
331 RCSQueryParams queryParams;
332 queryParams.setResourceInterface(inputInterface());
334 g_selectedResource->get(queryParams, onRemoteGetReceived);
337 void setWithInterface()
339 RCSQueryParams queryParams;
340 queryParams.setResourceInterface(inputInterface());
342 g_selectedResource->set(queryParams, inputKeyValue(), onRemoteSetReceived);
345 void startCaching(RCSRemoteResourceObject::CacheUpdatedCallback cb)
347 if (g_selectedResource->isCaching())
349 std::cout << "\tAlready Started Caching..." << std::endl;
353 g_selectedResource->startCaching(std::move(cb));
354 std::cout << "\tCaching Started..." << std::endl;
357 void startCachingWithoutCallback()
359 startCaching(nullptr);
362 void startCachingWithCallback()
364 startCaching(onCacheUpdated);
367 void getResourceCacheState()
369 switch(g_selectedResource->getCacheState())
371 case CacheState::READY:
372 std::cout << "\tCurrent Cache State : CACHE_STATE::READY" << std::endl;
375 case CacheState::UNREADY:
376 std::cout << "\tCurrent Cache State : CACHE_STATE::UNREADY" << std::endl;
379 case CacheState::LOST_SIGNAL:
380 std::cout << "\tCurrent Cache State : CACHE_STATE::LOST_SIGNAL" << std::endl;
383 case CacheState::NONE:
384 std::cout << "\tCurrent Cache State : CACHE_STATE::NONE" << std::endl;
389 void getCachedAttributes()
391 printAttributes(g_selectedResource->getCachedAttributes());
394 void getCachedAttribute()
396 printAttribute(g_attrKey, g_selectedResource->getCachedAttribute(g_attrKey));
401 if(!g_selectedResource->isCaching())
403 std::cout << "\tCaching not started..." << std::endl;
407 g_selectedResource->stopCaching();
408 std::cout << "\tCaching stopped..." << std::endl;
411 std::string selectResourceType()
413 std::cout << "========================================================" << std::endl;
414 std::cout << "1. Temperature Resource Discovery" << std::endl;
415 std::cout << "2. Light Resource Discovery" << std::endl;
416 std::cout << "========================================================" << std::endl;
418 switch (processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT))
421 g_attrKey = "Temperature";
422 return RESOURCE_TYPE_TEMP;
424 g_attrKey = "Brightness";
425 return RESOURCE_TYPE_LIGHT;
428 throw std::logic_error("unreachable");
431 RCSAddress inputAddress()
433 std::cout << "========================================================" << std::endl;
434 std::cout << "Please input address (empty for multicast)" << std::endl;
435 std::cout << "========================================================" << std::endl;
439 if(std::cin.peek() != '\n') std::cin >> address;
441 return address.empty() ? RCSAddress::multicast() : RCSAddress::unicast(address);
444 void printDiscoveryInProgress()
446 std::cout << "Discovery in progress, press '1' to stop." << std::endl;
449 void discoverResource()
451 auto onResourceDiscovered = [](
452 const RCSRemoteResourceObject::Ptr& discoveredResource)
454 std::cout << "onResourceDiscovered callback :: " << std::endl;
456 std::cout << "uri : " << discoveredResource->getUri() << std::endl;
457 std::cout << "host address : " << discoveredResource->getAddress() << std::endl;
459 g_discoveredResources.push_back(discoveredResource);
461 printDiscoveryInProgress();
464 auto resourceType = selectResourceType();
465 auto address = inputAddress();
467 printDiscoveryInProgress();
469 auto discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(address,
470 resourceType, onResourceDiscovered);
472 while(processUserInput() != 1);
474 discoveryTask->cancel();
477 void runResourceControl()
479 static std::vector<MenuItem> resourceMenuItems {
480 DECLARE_MENU(startMonitoring),
481 DECLARE_MENU(stopMonitoring),
482 DECLARE_MENU(getRemoteAttributes),
483 DECLARE_MENU(setRemoteAttributes),
484 DECLARE_MENU(getWithInterface),
485 DECLARE_MENU(setWithInterface),
486 DECLARE_MENU(startCachingWithoutCallback),
487 DECLARE_MENU(startCachingWithCallback),
488 DECLARE_MENU(getResourceCacheState),
489 DECLARE_MENU(getCachedAttributes),
490 DECLARE_MENU(getCachedAttribute),
491 DECLARE_MENU(stopCaching),
494 handleItems(resourceMenuItems);
497 void runResourceSelection()
499 handleItems(g_discoveredResources);
501 g_currentRun = runResourceControl;
506 static std::vector<MenuItem> discoveryMenuItems {
507 DECLARE_MENU(discoverResource),
510 handleItems(discoveryMenuItems);
512 if (g_discoveredResources.empty()) throw std::runtime_error("No resource found!");
514 g_currentRun = runResourceSelection;
517 void configurePlatform()
519 PlatformConfig config
521 OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
523 OCPlatform::Configure(config);
530 g_currentRun = runDiscovery;
538 catch (const std::exception& e)
540 std::cout << e.what() << std::endl;
542 catch (const CloseApp&)
548 std::cout << "Stopping the client" << std::endl;