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)
101 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
103 throw std::runtime_error("Invalid Input, please try again");
107 void displayItem(int width, int index, const D& data)
109 std::cout.width(width);
110 std::cout << std::right << index << ". ";
111 std::cout << data << std::endl;
115 void displayItems(const std::vector<T>& items)
117 std::cout << std::endl;
119 const auto width = (items.size() + 1) / 10 + 1;
121 for (size_t i = 0; i < items.size(); ++i)
123 displayItem(width, i + 1, items[i]);
125 displayItem(width, items.size() + 1, "quit");
129 void selectItem(const std::vector<T>& items)
131 int selected = processUserInput(1, items.size() + 1) - 1;
133 if (selected == static_cast<int>(items.size()))
138 onSelected(items[selected]);
142 void handleItems(const std::vector<T>& items)
148 std::string inputInterface()
150 std::string interfaceName;
152 std::cout << "\tInput the Interface you want to set : ";
153 std::cin >> interfaceName;
155 return interfaceName;
158 RCSResourceAttributes inputKeyValue()
162 std::cout << "\tEnter the Key you want to set : ";
165 std::cout << "\tEnter the value(INT) you want to set :";
166 RCSResourceAttributes attrs;
167 attrs[key] = processUserInput();
172 void printAttribute(const std::string& key, const RCSResourceAttributes::Value& value)
174 std::cout << "\tkey : " << key << std::endl
175 << "\tvalue : " << value.toString() << std::endl;
178 void printAttributes(const RCSResourceAttributes& attributes)
180 if (attributes.empty())
182 std::cout << "\tattributes is empty" << std::endl;
185 for (const auto& attr : attributes)
187 printAttribute(attr.key(), attr.value());
191 void print(const std::string& name, const std::vector< std::string >& elements)
193 if (elements.empty())
195 std::cout << "\t" << name << " is empty" << std::endl;
199 std::cout << "\t" << name << " : " << std::endl;
200 for (const auto& item : elements)
202 std::cout << item << " ";
204 std::cout << std::endl;
207 void printUri(const std::string& uri)
211 std::cout << "\turi is empty" << std::endl;
215 std::cout << "\turi : " << uri << std::endl;
219 void printRepresentation(const RCSRepresentation& rep)
221 printUri(rep.getUri());
222 print("interfaces", rep.getInterfaces());
223 print("resourceTypes", rep.getResourceTypes());
224 printAttributes(rep.getAttributes());
226 const auto& children = rep.getChildren();
228 if (children.empty())
230 std::cout << "\tchildren is empty" << std::endl;
235 for (const auto& child : children)
237 std::cout << "========================================================" << std::endl;
238 std::cout << ++cnt << " chlid" << std::endl;
239 printRepresentation(child);
240 std::cout << "========================================================" << std::endl;
245 void onResourceStateChanged(ResourceState resourceState)
247 std::cout << "onResourceStateChanged callback" << std::endl;
249 switch (resourceState)
251 case ResourceState::NONE:
252 std::cout << "\tState changed to : NOT_MONITORING" << std::endl;
255 case ResourceState::ALIVE:
256 std::cout << "\tState changed to : ALIVE" << std::endl;
259 case ResourceState::REQUESTED:
260 std::cout << "\tState changed to : REQUESTED" << std::endl;
263 case ResourceState::LOST_SIGNAL:
264 std::cout << "\tState changed to : LOST_SIGNAL" << std::endl;
267 case ResourceState::DESTROYED:
268 std::cout << "\tState changed to : DESTROYED" << std::endl;
273 void onCacheUpdated(const RCSResourceAttributes& attributes, int eCode)
275 std::cout << "onCacheUpdated callback : " << eCode << std::endl;
277 printAttributes(attributes);
280 void onRemoteAttributesReceived(const RCSResourceAttributes& attributes, int)
282 std::cout << "onRemoteAttributesReceived callback" << std::endl;
284 printAttributes(attributes);
287 void onRemoteGetReceived(const HeaderOpts&, const RCSRepresentation& rep, int)
289 std::cout << "onRemoteGetReceived callback" << std::endl;
291 printRepresentation(rep);
294 void onRemoteSetReceived(const HeaderOpts&, const RCSRepresentation& rep, int)
296 std::cout << "onRemoteSetReceived callback" << std::endl;
298 printRepresentation(rep);
301 void startMonitoring()
303 if (g_selectedResource->isMonitoring())
305 std::cout << "\tAlready Started..." << std::endl;
309 g_selectedResource->startMonitoring(&onResourceStateChanged);
310 std::cout << "\tMonitoring Started..." << std::endl;
313 void stopMonitoring()
315 if (!g_selectedResource->isMonitoring())
317 std::cout << "\tMonitoring not started..." << std::endl;
321 g_selectedResource->stopMonitoring();
322 std::cout << "\tMonitoring stopped..." << std::endl;
325 void getRemoteAttributes()
327 g_selectedResource->getRemoteAttributes(onRemoteAttributesReceived);
330 void setRemoteAttributes()
332 g_selectedResource->setRemoteAttributes(inputKeyValue(), onRemoteAttributesReceived);
335 void getWithInterface()
337 RCSQueryParams queryParams;
338 queryParams.setResourceInterface(inputInterface());
340 g_selectedResource->get(queryParams, onRemoteGetReceived);
343 void setWithInterface()
345 RCSQueryParams queryParams;
346 queryParams.setResourceInterface(inputInterface());
348 g_selectedResource->set(queryParams, inputKeyValue(), onRemoteSetReceived);
351 void startCaching(RCSRemoteResourceObject::CacheUpdatedCallback cb)
353 if (g_selectedResource->isCaching())
355 std::cout << "\tAlready Started Caching..." << std::endl;
359 g_selectedResource->startCaching(std::move(cb));
360 std::cout << "\tCaching Started..." << std::endl;
363 void startCachingWithoutCallback()
365 startCaching(nullptr);
368 void startCachingWithCallback()
370 startCaching(onCacheUpdated);
373 void getResourceCacheState()
375 switch(g_selectedResource->getCacheState())
377 case CacheState::READY:
378 std::cout << "\tCurrent Cache State : CACHE_STATE::READY" << std::endl;
381 case CacheState::UNREADY:
382 std::cout << "\tCurrent Cache State : CACHE_STATE::UNREADY" << std::endl;
385 case CacheState::LOST_SIGNAL:
386 std::cout << "\tCurrent Cache State : CACHE_STATE::LOST_SIGNAL" << std::endl;
389 case CacheState::NONE:
390 std::cout << "\tCurrent Cache State : CACHE_STATE::NONE" << std::endl;
395 void getCachedAttributes()
397 printAttributes(g_selectedResource->getCachedAttributes());
400 void getCachedAttribute()
402 printAttribute(g_attrKey, g_selectedResource->getCachedAttribute(g_attrKey));
407 if (!g_selectedResource->isCaching())
409 std::cout << "\tCaching not started..." << std::endl;
413 g_selectedResource->stopCaching();
414 std::cout << "\tCaching stopped..." << std::endl;
417 std::string selectResourceType()
419 std::cout << "========================================================" << std::endl;
420 std::cout << "1. Temperature Resource Discovery" << std::endl;
421 std::cout << "2. Light Resource Discovery" << std::endl;
422 std::cout << "========================================================" << std::endl;
424 switch (processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT))
428 g_attrKey = "Temperature";
429 return RESOURCE_TYPE_TEMP;
433 g_attrKey = "Brightness";
434 return RESOURCE_TYPE_LIGHT;
438 throw std::logic_error("unreachable");
441 RCSAddress inputAddress()
443 std::cout << "========================================================" << std::endl;
444 std::cout << "Please input address (empty for multicast)" << std::endl;
445 std::cout << "========================================================" << std::endl;
449 if (std::cin.peek() != '\n')
454 return address.empty() ? RCSAddress::multicast() : RCSAddress::unicast(address);
457 void printDiscoveryInProgress()
459 std::cout << "Discovery in progress, press '1' to stop." << std::endl;
462 void discoverResource()
464 auto onResourceDiscovered = [](
465 const RCSRemoteResourceObject::Ptr& discoveredResource)
467 std::cout << "onResourceDiscovered callback :: " << std::endl;
469 std::cout << "uri : " << discoveredResource->getUri() << std::endl;
470 std::cout << "host address : " << discoveredResource->getAddress() << std::endl;
472 g_discoveredResources.push_back(discoveredResource);
474 printDiscoveryInProgress();
477 auto resourceType = selectResourceType();
478 auto address = inputAddress();
480 printDiscoveryInProgress();
482 auto discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(address,
483 resourceType, onResourceDiscovered);
485 while (processUserInput() != 1);
487 discoveryTask->cancel();
490 void runResourceControl()
492 static std::vector<MenuItem> resourceMenuItems {
493 DECLARE_MENU(startMonitoring),
494 DECLARE_MENU(stopMonitoring),
495 DECLARE_MENU(getRemoteAttributes),
496 DECLARE_MENU(setRemoteAttributes),
497 DECLARE_MENU(getWithInterface),
498 DECLARE_MENU(setWithInterface),
499 DECLARE_MENU(startCachingWithoutCallback),
500 DECLARE_MENU(startCachingWithCallback),
501 DECLARE_MENU(getResourceCacheState),
502 DECLARE_MENU(getCachedAttributes),
503 DECLARE_MENU(getCachedAttribute),
504 DECLARE_MENU(stopCaching),
507 handleItems(resourceMenuItems);
510 void runResourceSelection()
512 handleItems(g_discoveredResources);
514 g_currentRun = runResourceControl;
519 static std::vector<MenuItem> discoveryMenuItems {
520 DECLARE_MENU(discoverResource),
523 handleItems(discoveryMenuItems);
525 if (g_discoveredResources.empty())
527 throw std::runtime_error("No resource found!");
530 g_currentRun = runResourceSelection;
533 void configurePlatform()
535 PlatformConfig config
537 OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
539 OCPlatform::Configure(config);
546 g_currentRun = runDiscovery;
554 catch (const std::exception& e)
556 std::cout << e.what() << std::endl;
558 catch (const CloseApp&)
564 std::cout << "Stopping the client" << std::endl;