Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / linux / SampleResourceClient.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include<iostream>
22 #include "mutex"
23 #include "condition_variable"
24
25 #include "RCSDiscoveryManager.h"
26 #include "RCSRemoteResourceObject.h"
27 #include "RCSResourceAttributes.h"
28 #include "RCSAddress.h"
29
30 #include "OCPlatform.h"
31
32 using namespace OC;
33 using namespace OIC::Service;
34
35 constexpr int CORRECT_INPUT = 1;
36 constexpr int INCORRECT_INPUT = 2;
37 constexpr int QUIT_INPUT = 3;
38
39 std::shared_ptr<RCSRemoteResourceObject>  resource;
40
41 const std::string defaultKey = "Temperature";
42 const std::string resourceType = "?rt=core.TemperatureSensor";
43 const std::string targetUri = OC_RSRVD_WELL_KNOWN_URI + resourceType;
44
45 std::mutex mtx;
46 std::condition_variable cond;
47
48 void startMonitoring();
49 void startMonitoring();
50 void stopMonitoring();
51 void getAttributeFromRemoteServer();
52 void setAttributeToRemoteServer();
53 void startCachingWithoutCallback();
54 void startCachingWithCallback();
55 void getResourceCacheState();
56 void getCachedAttributes();
57 void getCachedAttribute();
58 void stopCaching();
59
60 enum Menu
61 {
62     START_MONITORING = 1,
63     STOP_MONITORING,
64     GET_ATTRIBUTE,
65     SET_ATTRIBUTE,
66     START_CACHING_NO_UPDATE,
67     START_CACHING_UPDATE,
68     GET_RESOURCE_CACHE_STATE,
69     GET_CACHED_ATTRIBUTES,
70     GET_CACHED_ATTRIBUTE,
71     STOP_CACHING,
72     QUIT,
73     END_OF_MENU
74 };
75
76 typedef void(*ClientMenuHandler)();
77 typedef int ReturnValue;
78
79 struct ClientMenu
80 {
81     Menu m_menu;
82     ClientMenuHandler m_handler;
83     ReturnValue m_result;
84 };
85
86 ClientMenu clientMenu[] = {
87         {Menu::START_MONITORING, startMonitoring, CORRECT_INPUT},
88         {Menu::STOP_MONITORING, stopMonitoring, CORRECT_INPUT},
89         {Menu::GET_ATTRIBUTE, getAttributeFromRemoteServer, CORRECT_INPUT},
90         {Menu::SET_ATTRIBUTE, setAttributeToRemoteServer, CORRECT_INPUT},
91         {Menu::START_CACHING_NO_UPDATE, startCachingWithoutCallback, CORRECT_INPUT},
92         {Menu::START_CACHING_UPDATE, startCachingWithCallback, CORRECT_INPUT},
93         {Menu::GET_RESOURCE_CACHE_STATE, getResourceCacheState, CORRECT_INPUT},
94         {Menu::GET_CACHED_ATTRIBUTES, getCachedAttributes, CORRECT_INPUT},
95         {Menu::GET_CACHED_ATTRIBUTE, getCachedAttribute, CORRECT_INPUT},
96         {Menu::STOP_CACHING, stopCaching, CORRECT_INPUT},
97         {Menu::QUIT, [](){}, QUIT_INPUT},
98         {Menu::END_OF_MENU, nullptr, INCORRECT_INPUT}
99     };
100
101 void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
102 {
103     std::cout << "onResourceDiscovered callback" << std::endl;
104
105     std::string resourceURI = foundResource->getUri();
106     std::string hostAddress = foundResource->getAddress();
107
108     std::cout << "\t\tResource URI : " << resourceURI << std::endl;
109     std::cout << "\t\tResource Host : " << hostAddress << std::endl;
110
111     resource = foundResource;
112
113     cond.notify_all();
114 }
115
116 void onResourceStateChanged(const ResourceState& resourceState)
117 {
118     std::cout << "onResourceStateChanged callback" << std::endl;
119
120     switch(resourceState)
121     {
122         case ResourceState::NONE:
123             std::cout << "\tState changed to : NOT_MONITORING" << std::endl;
124             break;
125
126         case ResourceState::ALIVE:
127             std::cout << "\tState changed to : ALIVE" << std::endl;
128             break;
129
130         case ResourceState::REQUESTED:
131             std::cout << "\tState changed to : REQUESTED" << std::endl;
132             break;
133
134         case ResourceState::LOST_SIGNAL:
135             std::cout << "\tState changed to : LOST_SIGNAL" << std::endl;
136             resource = nullptr;
137             break;
138
139         case ResourceState::DESTROYED:
140             std::cout << "\tState changed to : DESTROYED" << std::endl;
141             break;
142     }
143 }
144
145 void onCacheUpdated(const RCSResourceAttributes& attributes)
146 {
147     std::cout << "onCacheUpdated callback" << std::endl;
148
149     if (attributes.empty())
150     {
151         std::cout << "\tAttribute is Empty" << std::endl;
152         return;
153     }
154
155     for(const auto& attr : attributes)
156     {
157         std::cout << "\tkey : " << attr.key() << std::endl
158                   << "\tvalue : " << attr.value().toString() << std::endl;
159     }
160 }
161
162 void onRemoteAttributesReceivedCallback(const RCSResourceAttributes& attributes)
163 {
164     std::cout << "onRemoteAttributesReceivedCallback callback" << std::endl;
165
166     if (attributes.empty())
167     {
168         std::cout << "\tAttribute is Empty" << std::endl;
169         return;
170     }
171
172     for(const auto& attr : attributes)
173     {
174         std::cout << "\tkey : " << attr.key() << std::endl
175                   << "\tvalue : " << attr.value().toString() << std::endl;
176     }
177 }
178
179 void displayMenu()
180 {
181     std::cout << std::endl;
182     std::cout << "1 :: Start Monitoring" << std::endl;
183     std::cout << "2 :: Stop Monitoring" << std::endl;
184     std::cout << "3 :: Get Attribute" << std::endl;
185     std::cout << "4 :: Set Attribute" << std::endl;
186     std::cout << "5 :: Start Caching (No update to Application)" << std::endl;
187     std::cout << "6 :: Start Caching (Update the application when data change)"<< std::endl;
188     std::cout << "7 :: Get Resource cache State" << std::endl;
189     std::cout << "8 :: Get Cached Attributes" << std::endl;
190     std::cout << "9 :: Get Cached Attribute"  << std::endl;
191     std::cout << "10 :: Stop Caching" << std::endl;
192     std::cout << "11 :: Stop Server" << std::endl;
193 }
194
195 int processUserInput()
196 {
197     int userInput;
198     std::cin >> userInput;
199     if (std::cin.fail())
200     {
201         std::cin.clear();
202         std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
203         return -1;
204     }
205     return userInput;
206 }
207
208 void startMonitoring()
209 {
210     if (!resource->isMonitoring())
211     {
212         resource->startMonitoring(&onResourceStateChanged);
213         std::cout << "\tHosting Started..." << std::endl;
214     }
215     else
216     {
217         std::cout << "\tAlready Started..." << std::endl;
218     }
219 }
220
221 void stopMonitoring()
222 {
223     if (resource->isMonitoring())
224     {
225         resource->stopMonitoring();
226         std::cout << "\tHosting stopped..." << std::endl;
227     }
228     else
229     {
230        std::cout << "\tHosting not started..." << std::endl;
231     }
232 }
233
234 void getAttributeFromRemoteServer()
235 {
236     resource->getRemoteAttributes(&onRemoteAttributesReceivedCallback);
237 }
238
239 void setAttributeToRemoteServer()
240 {
241     std::string key;
242     int value;
243
244     RCSResourceAttributes setAttribute;
245
246     std::cout << "\tEnter the Key you want to set : ";
247     std::cin >> key;
248     std::cout << "\tEnter the value you want to set :";
249     std::cin >> value;
250
251     setAttribute[key] = value;
252     resource->setRemoteAttributes(setAttribute,
253                                   &onRemoteAttributesReceivedCallback);
254 }
255
256 void startCaching(std::function <void (const RCSResourceAttributes&)>cb)
257 {
258     if (!resource->isCaching())
259     {
260         if(cb) resource->startCaching(&onCacheUpdated);
261
262         else resource->startCaching();
263
264         std::cout << "\tCaching Started..." << std::endl;
265     }
266     else
267     {
268         std::cout << "\tAlready Started Caching..." << std::endl;
269     }
270 }
271
272 void startCachingWithoutCallback()
273 {
274     startCaching(nullptr);
275 }
276
277 void startCachingWithCallback()
278 {
279     startCaching(onCacheUpdated);
280 }
281
282 void getResourceCacheState()
283 {
284     switch(resource->getCacheState())
285     {
286         case CacheState::READY:
287             std::cout << "\tCurrent Cache State : " << "CACHE_STATE ::READY" << std::endl;
288             break;
289
290         case CacheState::UNREADY:
291             std::cout << "\tCurrent Cache State : " << "CACHE_STATE ::UNREADY" << std::endl;
292             break;
293
294         case CacheState::LOST_SIGNAL:
295             std::cout << "\tCurrent Cache State : " << "CACHE_STATE ::LOST_SIGNAL" << std::endl;
296             break;
297
298         case CacheState::NONE:
299             std::cout << "\tCurrent Cache State : " << "CACHE_STATE ::NONE" << std::endl;
300             break;
301
302         default:
303             break;
304     }
305 }
306
307 void getCachedAttributes()
308 {
309     try
310     {
311         if (resource->getCachedAttributes().empty())
312         {
313             std::cout << "\tReceived cached attribute is empty" << std::endl;
314         }
315         else
316         {
317             for(const auto& attr : resource->getCachedAttributes())
318             {
319                 std::cout << "\tkey : " << attr.key() << std::endl
320                           << "\tvalue : " << attr.value().toString() << std::endl;
321             }
322         }
323     }
324     catch (const BadRequestException& e)
325     {
326         std::cout << "Exception in getCachedAttributes : " << e.what() << std::endl;
327     }
328 }
329
330 void getCachedAttribute()
331 {
332     try
333     {
334         std::cout << "\tkey : " << defaultKey << std::endl
335                   << "\tvalue : " << resource->getCachedAttribute(defaultKey).get< int >()
336                   << std::endl;
337     }
338     catch (const BadRequestException& e)
339     {
340         std::cout << "Exception in getCachedAttribute : " << e.what() << std::endl;
341     }
342     catch (const BadGetException& e)
343     {
344         std::cout << "Exception in getCachedAttribute : " << e.what() << std::endl;
345     }
346 }
347
348 void stopCaching()
349 {
350     if(resource->isCaching())
351     {
352         resource->stopCaching();
353         std::cout << "\tCaching stopped..." << std::endl;
354     }
355     else
356     {
357         std::cout << "\tCaching not started..." << std::endl;
358     }
359 }
360
361 int selectClientMenu(int selectedMenu)
362 {
363     for(int i = 0; clientMenu[i].m_menu != Menu::END_OF_MENU; i++)
364     {
365         if(clientMenu[i].m_menu == selectedMenu)
366         {
367             clientMenu[i].m_handler();
368             return clientMenu[i].m_result;
369         }
370     }
371
372     std::cout << "Invalid input, please try again" << std::endl;
373
374     return INCORRECT_INPUT;
375 }
376
377 void process()
378 {
379     while(true)
380     {
381         displayMenu();
382
383         if(selectClientMenu(processUserInput()) == QUIT_INPUT) break;
384     }
385 }
386
387 void platFormConfigure()
388 {
389     PlatformConfig config
390     {
391         OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos
392     };
393     OCPlatform::Configure(config);
394 }
395
396 bool discoverResource()
397 {
398     std::cout << "Wait 2 seconds until discovered." << std::endl;
399
400     RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(), targetUri,
401                                                          &onResourceDiscovered);
402
403     std::unique_lock<std::mutex> lck(mtx);
404     cond.wait_for(lck,std::chrono::seconds(2));
405
406     return resource != nullptr;
407 }
408
409 int main()
410 {
411     platFormConfigure();
412
413     if (!discoverResource())
414     {
415         std::cout << "Can't discovered Server... Exiting the Client." << std::endl;
416         return -1;
417     }
418
419     try
420     {
421         process();
422     }
423     catch (const std::exception& e)
424     {
425         std::cout << "main exception : " << e.what() << std::endl;
426     }
427
428     std::cout << "Stopping the Client" << std::endl;
429
430     return 0;
431 }
432