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 "RCSRemoteResourceObject.h"
25 #include "RCSResourceAttributes.h"
26 #include "RCSAddress.h"
28 #include "OCPlatform.h"
30 #define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
33 using namespace OIC::Service;
40 typedef void(*Handler)();
43 const std::string title;
44 const Handler handler;
47 typedef void(*Runner)();
49 constexpr int RESOURCE_TEMP = 1;
50 constexpr int RESOURCE_LIGHT = 2;
52 const std::string RESOURCE_TYPE_TEMP = "oic.r.temperaturesensor";
53 const std::string RESOURCE_TYPE_LIGHT = "oic.r.light";
55 RCSRemoteResourceObject::Ptr g_selectedResource;
56 std::vector<RCSRemoteResourceObject::Ptr> g_discoveredResources;
58 std::string g_attrKey;
62 std::ostream& operator<<(std::ostream& os, const RCSRemoteResourceObject::Ptr& object)
64 return os << "\turi : " << object->getUri() << std::endl <<
65 "\thost address : " << object->getAddress();
68 std::ostream& operator<<(std::ostream& os, const MenuItem& item)
70 return os << item.title;
73 void onSelected(const RCSRemoteResourceObject::Ptr& object)
75 g_selectedResource = object;
78 void onSelected(const MenuItem& item)
80 std::cout << item.title << " start.." << std::endl;
84 int processUserInput(int min = std::numeric_limits<int>::min(),
85 int max = std::numeric_limits<int>::max())
92 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
94 if (!std::cin.fail() && min <= input && input <= max) return input;
97 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
99 throw std::runtime_error("Invalid Input, please try again");
103 void displayItem(int width, int index, const D& data)
105 std::cout.width(width);
106 std::cout << std::right << index << ". ";
107 std::cout << data << std::endl;
111 void displayItems(const std::vector<T>& items)
113 std::cout << std::endl;
115 const auto width = (items.size() + 1) / 10 + 1;
117 for(size_t i = 0; i < items.size(); ++i)
119 displayItem(width, i + 1, items[i]);
121 displayItem(width, items.size() + 1, "quit");
125 void selectItem(const std::vector<T>& items)
127 int selected = processUserInput(1, items.size() + 1) - 1;
129 if(selected == static_cast<int>(items.size())) throw CloseApp();
131 onSelected(items[selected]);
135 void handleItems(const std::vector<T>& items)
141 void printAttribute(const std::string& key, const RCSResourceAttributes::Value& value)
143 std::cout << "\tkey : " << key << std::endl
144 << "\tvalue : " << value.toString() << std::endl;
147 void printAttributes(const RCSResourceAttributes& attributes)
149 if (attributes.empty())
151 std::cout << "\tattributes is empty" << std::endl;
154 for(const auto& attr : attributes)
156 printAttribute(attr.key(), attr.value());
160 void onResourceStateChanged(ResourceState resourceState)
162 std::cout << "onResourceStateChanged callback" << std::endl;
164 switch(resourceState)
166 case ResourceState::NONE:
167 std::cout << "\tState changed to : NOT_MONITORING" << std::endl;
170 case ResourceState::ALIVE:
171 std::cout << "\tState changed to : ALIVE" << std::endl;
174 case ResourceState::REQUESTED:
175 std::cout << "\tState changed to : REQUESTED" << std::endl;
178 case ResourceState::LOST_SIGNAL:
179 std::cout << "\tState changed to : LOST_SIGNAL" << std::endl;
182 case ResourceState::DESTROYED:
183 std::cout << "\tState changed to : DESTROYED" << std::endl;
188 void onCacheUpdated(const RCSResourceAttributes& attributes)
190 std::cout << "onCacheUpdated callback" << std::endl;
192 printAttributes(attributes);
195 void onRemoteAttributesReceived(const RCSResourceAttributes& attributes, int)
197 std::cout << "onRemoteAttributesReceived callback" << std::endl;
199 printAttributes(attributes);
202 void startMonitoring()
204 if (g_selectedResource->isMonitoring())
206 std::cout << "\tAlready Started..." << std::endl;
210 g_selectedResource->startMonitoring(&onResourceStateChanged);
211 std::cout << "\tMonitoring Started..." << std::endl;
214 void stopMonitoring()
216 if (!g_selectedResource->isMonitoring())
218 std::cout << "\tMonitoring not started..." << std::endl;
222 g_selectedResource->stopMonitoring();
223 std::cout << "\tMonitoring stopped..." << std::endl;
226 void getRemoteAttributes()
228 g_selectedResource->getRemoteAttributes(onRemoteAttributesReceived);
231 void setRemoteAttributes()
235 std::cout << "\tEnter the Key you want to set : ";
238 std::cout << "\tEnter the value(INT) you want to set :";
239 RCSResourceAttributes attrs;
240 attrs[key] = processUserInput();
242 g_selectedResource->setRemoteAttributes(attrs, onRemoteAttributesReceived);
245 void startCaching(RCSRemoteResourceObject::CacheUpdatedCallback cb)
247 if (g_selectedResource->isCaching())
249 std::cout << "\tAlready Started Caching..." << std::endl;
253 g_selectedResource->startCaching(std::move(cb));
254 std::cout << "\tCaching Started..." << std::endl;
257 void startCachingWithoutCallback()
259 startCaching(nullptr);
262 void startCachingWithCallback()
264 startCaching(onCacheUpdated);
267 void getResourceCacheState()
269 switch(g_selectedResource->getCacheState())
271 case CacheState::READY:
272 std::cout << "\tCurrent Cache State : CACHE_STATE::READY" << std::endl;
275 case CacheState::UNREADY:
276 std::cout << "\tCurrent Cache State : CACHE_STATE::UNREADY" << std::endl;
279 case CacheState::LOST_SIGNAL:
280 std::cout << "\tCurrent Cache State : CACHE_STATE::LOST_SIGNAL" << std::endl;
283 case CacheState::NONE:
284 std::cout << "\tCurrent Cache State : CACHE_STATE::NONE" << std::endl;
289 void getCachedAttributes()
291 printAttributes(g_selectedResource->getCachedAttributes());
294 void getCachedAttribute()
296 printAttribute(g_attrKey, g_selectedResource->getCachedAttribute(g_attrKey));
301 if(!g_selectedResource->isCaching())
303 std::cout << "\tCaching not started..." << std::endl;
307 g_selectedResource->stopCaching();
308 std::cout << "\tCaching stopped..." << std::endl;
311 std::string selectResourceType()
313 std::cout << "========================================================" << std::endl;
314 std::cout << "1. Temperature Resource Discovery" << std::endl;
315 std::cout << "2. Light Resource Discovery" << std::endl;
316 std::cout << "========================================================" << std::endl;
318 switch (processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT))
321 g_attrKey = "Temperature";
322 return RESOURCE_TYPE_TEMP;
324 g_attrKey = "Brightness";
325 return RESOURCE_TYPE_LIGHT;
328 throw std::logic_error("unreachable");
331 RCSAddress inputAddress()
333 std::cout << "========================================================" << std::endl;
334 std::cout << "Please input address (empty for multicast)" << std::endl;
335 std::cout << "========================================================" << std::endl;
339 if(std::cin.peek() != '\n') std::cin >> address;
341 return address.empty() ? RCSAddress::multicast() : RCSAddress::unicast(address);
344 void printDiscoveryInProgress()
346 std::cout << "Discovery in progress, press '1' to stop." << std::endl;
349 void discoverResource()
351 auto onResourceDiscovered = [](
352 const RCSRemoteResourceObject::Ptr& discoveredResource)
354 std::cout << "onResourceDiscovered callback :: " << std::endl;
356 std::cout << "luri : " << discoveredResource->getUri() << std::endl;
357 std::cout << "host address : " << discoveredResource->getAddress() << std::endl;
359 g_discoveredResources.push_back(discoveredResource);
361 printDiscoveryInProgress();
364 auto resourceType = selectResourceType();
365 auto address = inputAddress();
367 printDiscoveryInProgress();
369 auto discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(address,
370 resourceType, onResourceDiscovered);
372 while(processUserInput() != 1);
374 discoveryTask->cancel();
377 void runResourceControl()
379 static std::vector<MenuItem> resourceMenuItems {
380 DECLARE_MENU(startMonitoring),
381 DECLARE_MENU(stopMonitoring),
382 DECLARE_MENU(getRemoteAttributes),
383 DECLARE_MENU(setRemoteAttributes),
384 DECLARE_MENU(startCachingWithoutCallback),
385 DECLARE_MENU(startCachingWithCallback),
386 DECLARE_MENU(getResourceCacheState),
387 DECLARE_MENU(getCachedAttributes),
388 DECLARE_MENU(getCachedAttribute),
389 DECLARE_MENU(stopCaching),
392 handleItems(resourceMenuItems);
395 void runResourceSelection()
397 handleItems(g_discoveredResources);
399 g_currentRun = runResourceControl;
404 static std::vector<MenuItem> discoveryMenuItems {
405 DECLARE_MENU(discoverResource),
408 handleItems(discoveryMenuItems);
410 if (g_discoveredResources.empty()) throw std::runtime_error("No resource found!");
412 g_currentRun = runResourceSelection;
415 void configurePlatform()
417 PlatformConfig config
419 OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
421 OCPlatform::Configure(config);
428 g_currentRun = runDiscovery;
436 catch (const std::exception& e)
438 std::cout << e.what() << std::endl;
440 catch (const CloseApp&)
446 std::cout << "Stopping the client" << std::endl;