Add required header file in sceneserver and sceneclient
[platform/upstream/iotivity.git] / service / scene-manager / sampleapp / linux / sceneclient.cpp
1 //******************************************************************
2 //
3 // Copyright 2016 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 <vector>
23 #include <algorithm>
24 #include <condition_variable>
25
26 #include "OCPlatform.h"
27 #include "RCSDiscoveryManager.h"
28 #include "RCSRemoteResourceObject.h"
29 #include "RCSAddress.h"
30 #include "RemoteSceneList.h"
31
32 using namespace OC;
33 using namespace OIC::Service;
34
35 constexpr int CREATE_REMOTE_SCENE_LIST = 1;
36
37 constexpr int CREATE_REMOTE_SCENE_COLLECTION = 1;
38 constexpr int SHOW_REMOTE_SCENE_COLLECTION = 2;
39
40 constexpr int CREATE_REMOTE_SCENE = 1;
41 constexpr int CREATE_REMOTE_SCENE_ACTION = 1;
42
43 constexpr int EXECUTE_REMOTE_SCENE = 1;
44
45 constexpr int SCENE_RESULT_OK = 200;
46
47 constexpr int numCreatedSceneAction = 2;
48 static int numRecvSceneActionCreationResp = 0;
49
50 typedef std::function< void() > Run;
51 Run g_currentRun;
52
53 const std::string scene_name = "Night mode";
54 const std::string relativetUri = OC_RSRVD_WELL_KNOWN_URI;
55 const std::vector<std::string> resourceTypes{ "oic.wk.scenelist", "core.light", "core.fan" };
56
57 std::mutex g_mtx;
58 std::mutex g_discoverymtx;
59 std::condition_variable g_cond;
60
61 std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> g_discoveryTask;
62
63 RCSRemoteResourceObject::Ptr g_foundListResource;
64 RCSRemoteResourceObject::Ptr g_foundLightResource;
65 RCSRemoteResourceObject::Ptr g_foundFanResource;
66
67 RemoteSceneList::Ptr g_sceneList;
68 RemoteSceneCollection::Ptr g_sceneCollection;
69 RemoteScene::Ptr g_scene;
70
71 void displaySceneList();
72 void runCreateRemoteSceneList();
73 void runRemoteSceneCollection();
74 void runCreateRemoteScene();
75 void runCreateRemoteSceneAction();
76 void runExecuteCreatedRemoteScene();
77 void runExecuteExistingRemoteScene();
78
79 // Scene Manager Remote API sample ---
80 void onRemoteSceneListCreated(RemoteSceneList::Ptr remoteSceneList, int eCode)
81 {
82     std::cout << __func__ << " - error code : " << eCode << std::endl;
83
84     if (eCode == SCENE_RESULT_OK)
85     {
86         g_sceneList = std::move(remoteSceneList);
87         g_currentRun = runRemoteSceneCollection;
88     }
89     else
90     {
91         std::cout << "Create Remote scene list failed." << std::endl;
92         g_currentRun = runCreateRemoteSceneList;
93     }
94     g_currentRun();
95 }
96
97 void onRemoteSceneCollectionCreated(RemoteSceneCollection::Ptr remoteSceneCol, int eCode)
98 {
99     std::cout << __func__ << " - error code : " << eCode << std::endl;
100
101     if (eCode == SCENE_RESULT_OK)
102     {
103         g_sceneCollection = remoteSceneCol;
104         g_currentRun = runCreateRemoteScene;
105     }
106     else
107     {
108         std::cout << "Create Remote scene collection failed." << std::endl;
109         g_currentRun = runRemoteSceneCollection;
110     }
111
112     g_currentRun();
113 }
114
115 void onRemoteSceneCreated(RemoteScene::Ptr remoteScene, int eCode)
116 {
117     std::cout << __func__ << " - error code : " << eCode << std::endl;
118
119     if (eCode == SCENE_RESULT_OK)
120     {
121         g_scene = remoteScene;
122
123         g_currentRun = runCreateRemoteSceneAction;
124     }
125     else
126     {
127         std::cout << "Create Remote scene failed." << std::endl;
128         g_currentRun = runCreateRemoteScene;
129     }
130
131     g_currentRun();
132 }
133
134 void onRemoteSceneActionCreated(RemoteSceneAction::Ptr, int eCode)
135 {
136     std::cout << __func__ << " - error code : " << eCode << std::endl;
137
138     if (eCode == SCENE_RESULT_OK)
139     {
140         g_currentRun = runExecuteCreatedRemoteScene;
141     }
142     else
143     {
144         std::cout << "Create Remote scene action failed." << std::endl;
145         g_currentRun = runCreateRemoteSceneAction;
146     }
147
148     numRecvSceneActionCreationResp++;
149
150     if(numCreatedSceneAction == numRecvSceneActionCreationResp)
151         g_currentRun();
152 }
153
154 void onRemoteSceneExecuted(const std::string &sceneName, int eCode)
155 {
156     std::cout << __func__ << " - scene name : " << sceneName
157               <<  ", error code : " << eCode << std::endl;
158
159     if (eCode != SCENE_RESULT_OK)
160     {
161         std::cout << "Execute scene failed." << std::endl;
162     }
163
164     g_currentRun();
165 }
166
167 // --- Scene Manager Remote API sample
168
169 void createRemoteSceneList()
170 {
171     if (g_foundListResource)
172     {
173         RemoteSceneList::createInstance(g_foundListResource, onRemoteSceneListCreated);
174     }
175     else
176     {
177         std::cout << "Scene List Resource is not discovered." << std::endl;
178         g_currentRun();
179     }
180 }
181
182 void createRemoteSceneCollection()
183 {
184     if (!g_sceneList) return;
185
186     g_sceneList->addNewSceneCollection(onRemoteSceneCollectionCreated);
187 }
188
189 void showRemoteSceneCollection()
190 {
191     if (!g_sceneList) return;
192
193     if (g_sceneList->getRemoteSceneCollections().size() == 0) return;
194
195     g_sceneCollection = g_sceneList->getRemoteSceneCollections().at(0);
196
197     if( g_sceneCollection->getRemoteScenes().size() == 0) return;
198
199     g_scene = g_sceneCollection->getRemoteScenes().begin()->second;
200 }
201
202 void createRemoteScene()
203 {
204     if (!g_sceneCollection) return;
205
206     g_sceneCollection->addNewScene(scene_name, onRemoteSceneCreated);
207 }
208
209 void createRemoteSceneAction(
210     RemoteScene::Ptr scene, RCSRemoteResourceObject::Ptr member,
211     const std::string &key, const std::string &value)
212 {
213     if (scene && member)
214     {
215         g_scene->addNewSceneAction(member, key, RCSResourceAttributes::Value(value),
216             onRemoteSceneActionCreated);
217     }
218 }
219
220 void createRemoteSceneActions()
221 {
222     createRemoteSceneAction(g_scene, g_foundLightResource, "power", "on");
223     createRemoteSceneAction(g_scene, g_foundFanResource, "speed", "50");
224 }
225
226 void executeScene()
227 {
228     displaySceneList();
229
230     if (g_scene)
231     {
232         g_scene->execute(onRemoteSceneExecuted);
233         std::cout << "\n\t'" << g_scene->getName() << "' is executed!\n" << std::endl;
234     }
235 }
236
237 // --- Scene Manager Remote API sample
238
239 void configurePlatform()
240 {
241     PlatformConfig config
242     {
243         OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos
244     };
245     OCPlatform::Configure(config);
246 }
247
248 int processUserInput(int min, int max)
249 {
250     assert(min <= max);
251
252     int input;
253
254     std::cin >> input;
255
256     if (!std::cin.fail())
257     {
258         if (input == max + 1)  exit(0);
259         if (min <= input && input <= max) return input;
260     }
261
262     std::cin.clear();
263     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
264
265     throw std::runtime_error("Invalid Input, please try again");
266 }
267
268 void displaySceneList()
269 {
270     if (!g_sceneList) return;
271
272     std::cout << "\t" << g_sceneList->getName() << "(SceneList)" << std::endl;
273
274     if (!g_sceneCollection) return;
275
276     std::cout << "\t\t   |_ _ _ " << g_sceneCollection->getId() << " (SceneCollection)" << std::endl;
277
278     for( const auto &it_scene : g_sceneCollection->getRemoteScenes() )
279     {
280         std::cout << "\t\t\t   |_ _ _ " << it_scene.first << " (Scene)" << std::endl;
281
282         auto sceneActionList = it_scene.second->getRemoteSceneActions();
283         for (const auto &it : sceneActionList)
284         {
285             auto attr = it->getExecutionParameter();
286             for (const auto &att : attr)
287             {
288                 std::cout << "\t\t\t      \t\t|_ _ _ ";
289                 std::cout << it->getRemoteResourceObject()->getUri() << " : ";
290                 std::cout << att.key() << " - " << att.value().toString() << std::endl;
291             }
292         }
293     }
294 }
295
296 void displayClear(Run runFunc)
297 {
298     auto ret = std::system("/usr/bin/clear");
299     if(ret == -1)
300     {
301         std::cout << "clear error!" << std::endl;
302     }
303     g_currentRun = runFunc;
304 }
305
306 void displayCreateRemoteSceneListMenu()
307 {
308     std::cout << "========================================================\n";
309     std::cout << CREATE_REMOTE_SCENE_LIST  << ". Create a RemoteSceneList \n";
310     std::cout << CREATE_REMOTE_SCENE_LIST + 1  << ". Quit                 \n";
311     std::cout << "========================================================\n";
312 }
313
314 void displayRemoteSceneCollectionMenu()
315 {
316     std::cout << "========================================================               \n";
317     std::cout << CREATE_REMOTE_SCENE_COLLECTION  << ". Create a RemoteSceneCollection    \n";
318     std::cout << SHOW_REMOTE_SCENE_COLLECTION  << ". Show existing RemoteSceneCollection \n";
319     std::cout << SHOW_REMOTE_SCENE_COLLECTION + 1  << ". Quit                            \n";
320     std::cout << "========================================================               \n";
321 }
322
323 void displayRemoteSceneCreationMenu()
324 {
325     std::cout << "========================================================\n";
326     std::cout << CREATE_REMOTE_SCENE  << ". Create a RemoteScene          \n";
327     std::cout << CREATE_REMOTE_SCENE + 1  << ". Quit                      \n";
328     std::cout << "========================================================\n";
329 }
330
331 void displayRemoteSceneActionCreationMenu()
332 {
333     std::cout << "========================================================   \n";
334     std::cout << CREATE_REMOTE_SCENE_ACTION  << ". Create RemoteSceneActions \n";
335     std::cout << CREATE_REMOTE_SCENE_ACTION + 1  << ". Quit                  \n";
336     std::cout << "========================================================   \n";
337 }
338
339 void displayExecuteCreatedRemoteSceneCreationMenu()
340 {
341     std::cout << "========================================================\n";
342     std::cout << EXECUTE_REMOTE_SCENE  << ". Execute RemoteScene          \n";
343     std::cout << EXECUTE_REMOTE_SCENE + 1  << ". Quit                     \n";
344     std::cout << "========================================================\n";
345 }
346
347 void displayExecuteExistingRemoteSceneCreationMenu()
348 {
349     std::cout << "========================================================\n";
350     std::cout << EXECUTE_REMOTE_SCENE  << ". Execute a first RemoteScene  \n";
351     std::cout << EXECUTE_REMOTE_SCENE + 1  << ". Quit                     \n";
352     std::cout << "========================================================\n";
353 }
354
355 void runExecuteExistingRemoteScene()
356 {
357     displaySceneList();
358
359     displayExecuteExistingRemoteSceneCreationMenu();
360
361     try
362     {
363         int command = processUserInput(EXECUTE_REMOTE_SCENE, EXECUTE_REMOTE_SCENE);
364         switch(command)
365         {
366             case EXECUTE_REMOTE_SCENE:
367                 executeScene();
368                 displayClear(runExecuteExistingRemoteScene);
369                 break;
370         }
371     } catch (std::exception &e)
372     {
373         std::cout << e.what() << std::endl;
374         g_currentRun();
375     }
376 }
377
378 void runExecuteCreatedRemoteScene()
379 {
380     displaySceneList();
381
382     displayExecuteCreatedRemoteSceneCreationMenu();
383
384     try
385     {
386         int command = processUserInput(EXECUTE_REMOTE_SCENE, EXECUTE_REMOTE_SCENE);
387         switch(command)
388         {
389             case EXECUTE_REMOTE_SCENE:
390                 executeScene();
391                 displayClear(runExecuteCreatedRemoteScene);
392                 break;
393         }
394     } catch (std::exception &e)
395     {
396         std::cout << e.what() << std::endl;
397         g_currentRun();
398     }
399 }
400
401 void runCreateRemoteSceneAction()
402 {
403     displaySceneList();
404
405     displayRemoteSceneActionCreationMenu();
406
407     try
408     {
409         int command = processUserInput(CREATE_REMOTE_SCENE_ACTION, CREATE_REMOTE_SCENE_ACTION);
410         switch(command)
411         {
412             case CREATE_REMOTE_SCENE_ACTION:
413                 createRemoteSceneActions();
414                 displayClear(runExecuteCreatedRemoteScene);
415                 break;
416         }
417     } catch (std::exception &e)
418     {
419         std::cout << e.what() << std::endl;
420         g_currentRun();
421     }
422 }
423
424 void runCreateRemoteScene()
425 {
426     displaySceneList();
427
428     displayRemoteSceneCreationMenu();
429
430     try
431     {
432         int command = processUserInput(CREATE_REMOTE_SCENE, CREATE_REMOTE_SCENE);
433         switch(command)
434         {
435             case CREATE_REMOTE_SCENE:
436                 createRemoteScene();
437                 displayClear(runCreateRemoteSceneAction);
438                 break;
439         }
440     } catch (std::exception &e)
441     {
442         std::cout << e.what() << std::endl;
443         g_currentRun();
444     }
445 }
446
447 void runRemoteSceneCollection()
448 {
449     displaySceneList();
450
451     displayRemoteSceneCollectionMenu();
452
453     try
454     {
455         int command = processUserInput(CREATE_REMOTE_SCENE_COLLECTION, SHOW_REMOTE_SCENE_COLLECTION);
456         switch(command)
457         {
458             case CREATE_REMOTE_SCENE_COLLECTION:
459                 createRemoteSceneCollection();
460                 displayClear(runCreateRemoteScene);
461                 break;
462             case SHOW_REMOTE_SCENE_COLLECTION:
463                 showRemoteSceneCollection();
464                 displayClear(runExecuteExistingRemoteScene);
465                 g_currentRun();
466                 break;
467         }
468     } catch (std::exception &e)
469     {
470         std::cout << e.what() << std::endl;
471         g_currentRun();
472     }
473 }
474
475 void runCreateRemoteSceneList()
476 {
477     displayCreateRemoteSceneListMenu();
478
479     try
480     {
481         int command = processUserInput(CREATE_REMOTE_SCENE_LIST, CREATE_REMOTE_SCENE_LIST);
482         switch(command)
483         {
484             case CREATE_REMOTE_SCENE_LIST:
485                 createRemoteSceneList();
486                 displayClear(runRemoteSceneCollection);
487                 break;
488         }
489     } catch (std::exception &e)
490     {
491         std::cout << e.what() << std::endl;
492         g_currentRun();
493     }
494 }
495
496 void onResourceDiscovered(std::shared_ptr<RCSRemoteResourceObject> foundResource)
497 {
498     std::lock_guard< std::mutex > lock(g_discoverymtx);
499     std::cout << "onResourceDiscovered callback" << std::endl;
500
501     std::string resourceURI = foundResource->getUri();
502     std::string hostAddress = foundResource->getAddress();
503     std::vector< std::string > vecRTs = foundResource->getTypes();
504
505     std::cout << "\t\tResource URI : " << resourceURI << std::endl;
506     std::cout << "\t\tResource Host : " << hostAddress << std::endl;
507
508     // if the found resource is a scene list resource
509     if (std::find(vecRTs.begin(), vecRTs.end(), "oic.wk.scenelist") != vecRTs.end())
510         g_foundListResource = foundResource;
511
512     // if the found resource is a light resource
513     else if (std::find(vecRTs.begin(), vecRTs.end(), "core.light") != vecRTs.end())
514     {
515         g_foundLightResource = foundResource;
516     }
517
518     // if the found resource is a fan resource
519     else if (std::find(vecRTs.begin(), vecRTs.end(), "core.fan") != vecRTs.end())
520     {
521         g_foundFanResource = foundResource;
522     }
523
524     if (g_foundListResource && g_foundLightResource && g_foundFanResource)
525     {
526         g_discoveryTask->cancel();
527         return;
528     }
529
530     g_cond.notify_all();
531 }
532
533 void discoverResource()
534 {
535     std::cout << "Wait 4 seconds until discovered." << std::endl;
536
537     try
538     {
539         g_discoveryTask
540             = RCSDiscoveryManager::getInstance()->discoverResourceByTypes(RCSAddress::multicast(),
541                     relativetUri, resourceTypes, &onResourceDiscovered);
542     }
543     catch (const RCSPlatformException &e)
544     {
545         std::cout << e.what() << std::endl;
546     }
547     std::unique_lock<std::mutex> lck(g_mtx);
548
549     g_cond.wait_for(lck, std::chrono::seconds(4));
550     return;
551 }
552
553 int main()
554 {
555     configurePlatform();
556
557     try
558     {
559         discoverResource();
560
561         g_currentRun = runCreateRemoteSceneList;
562         g_currentRun();
563     }
564     catch(std::exception &e)
565     {
566         std::cout << e.what() << std::endl;
567         return 0;
568     }
569
570     while (true) { }
571
572     std::cout << "Stopping the scene client" << std::endl;
573
574     return 0;
575 }