Merge branch 'easysetup'
[platform/upstream/iotivity.git] / service / resource-container / examples / ContainerSample.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 #if defined(__linux__)
22 #include <unistd.h>
23 #include <string.h>
24 #endif
25
26 #include "RCSResourceContainer.h"
27 #include "RCSBundleInfo.h"
28
29 #include <iostream>
30 #include <functional>
31 #include <limits>
32 #include <stdexcept>
33 #include <string>
34
35 using namespace OIC::Service;
36
37 namespace
38 {
39     typedef enum
40     {
41         START_RC = 1, STOP_RC,
42         ADD_SAMPLE_BUNDLE, START_SAMPLE_BUNDLE,
43         STOP_SAMPLE_BUNDLE, REMOVE_SAMPLE_BUNDLE,
44         ADD_SAMPLE_RESOURCE, REMOVE_SAMPLE_RESOURCE,
45         LIST_BUNDLES, LIST_RESOURCES,
46         EXIT = 11
47     } APPMenu;
48
49     struct CloseApp {};
50
51     const int MAX_PATH = 2048;
52
53     const std::string EXAMPLE_CONFIG_PATH = "/examples/ResourceContainerConfig.xml";
54     const std::string EXAMPLE_BUNDLE_ID = "oic.bundle.hueSample";
55     const std::string EXAMPLE_BUNDLE_URI = "/hueSample";
56     const std::string EXAMPLE_BUNDLE_PATH = "libHueBundle.so";
57     const std::string EXAMPLE_BUNDLE_ACTIVATOR = "huesample";
58     const std::string EXAMPLE_RESOURCE_URI = "/hue/light/sample";
59     const std::string EXAMPLE_RESOURCE_TYPE = "oic.r.light";
60     const std::string EXAMPLE_ADDRESS = "http://192.168.0.2/api/newdeveloper/lights/1";
61 };
62
63 bool g_bContainerStarted = false;
64 bool g_bSampleBundleStarted = false;
65 RCSResourceContainer *g_pResourceContainer = nullptr;
66
67 void getCurrentPath(std::string *pPath)
68 {
69     char buffer[MAX_PATH];
70
71     if (!pPath->empty())
72         pPath->clear();
73
74 #if defined(__linux__)
75     char *strPath = NULL;
76     int length = readlink("/proc/self/exe", buffer, MAX_PATH - 1);
77
78     if (length != -1)
79     {
80         buffer[length] = '\0';
81         strPath = strrchr(buffer, '/');
82
83         if (strPath != NULL)
84             *strPath = '\0';
85     }
86 #endif
87     pPath->append(buffer);
88 }
89
90 int processUserInput(int min, int max)
91 {
92     int input;
93
94     std::cin >> input;
95
96     if (!std::cin.fail() && min <= input && input <= max)
97         return input;
98
99     std::cin.clear();
100     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
101     throw std::runtime_error("Invalid Input, please try again");
102 }
103
104 std::string processUserStringInput()
105 {
106     std::string input;
107
108     std::cin >> input;
109
110     return input;
111 }
112
113 void displayMenu()
114 {
115     std::cout << "================================================================" << std::endl;
116     std::cout << "          IoTivity Resource Container Test Application              " << std::endl;
117     std::cout << "================================================================" << std::endl;
118     std::cout << "   1.  Start Resource Container                                 " << std::endl;
119     std::cout << "   2.  Stop Resource Container                                  " << std::endl;
120     std::cout << "   3.  Add Sample Bundle                                        " << std::endl;
121     std::cout << "   4.  Start Sample Bundle                                      " << std::endl;
122     std::cout << "   5.  Stop Sample Bundle                                       " << std::endl;
123     std::cout << "   6.  Remove Sample Bundle                                     " << std::endl;
124     std::cout << "   7.  Add Sample Resource                                      " << std::endl;
125     std::cout << "   8.  Remove Sample Resource                                   " << std::endl;
126     std::cout << "   9.  List Bundles                                             " << std::endl;
127     std::cout << "   10. List Resources                                           " << std::endl;
128     std::cout << "   11. Exit                                                     " << std::endl;
129     std::cout << "================================================================" << std::endl;
130     std::cout << "   Please Enter the NO: ";
131 }
132
133 bool checkBundleRegistered(std::string bundleId)
134 {
135     std::list< std::unique_ptr< RCSBundleInfo > > bundleList;
136
137     if (g_bContainerStarted)
138     {
139         bundleList = g_pResourceContainer->listBundles();
140
141         for (auto &bundle : bundleList)
142         {
143             if (bundle->getID().compare(bundleId) == 0)
144                 return true;
145         }
146     }
147
148     std::cout << "Bundle \'" << bundleId << "\' is not registered." << std::endl;
149     return false;
150 }
151
152 bool checkResourceRegistered(std::string bundleId, std::string resourceUri)
153 {
154     std::list< std::string > resourceList;
155
156     if (g_bContainerStarted && checkBundleRegistered(bundleId))
157     {
158         resourceList = g_pResourceContainer->listBundleResources(bundleId);
159
160         for (auto &resource : resourceList)
161         {
162             if (resource.compare(resourceUri) == 0)
163                 return true;
164         }
165     }
166
167     std::cout << "Resource \'" << resourceUri << "\' is not registered." << std::endl;
168     return false;
169 }
170
171 void StartContainer(std::string configPath)
172 {
173     if (!g_bContainerStarted)
174     {
175         g_pResourceContainer->startContainer(configPath);
176         g_bContainerStarted = true;
177     }
178     else
179     {
180         std::cout << "Container is already started." << std::endl;
181     }
182 }
183
184 void StopContainer()
185 {
186     if (g_pResourceContainer && g_bContainerStarted)
187     {
188         g_pResourceContainer->stopContainer();
189         g_bContainerStarted = false;
190     }
191     else
192     {
193         std::cout << "Container is not started." << std::endl;
194     }
195 }
196
197 void AddSampleBundle()
198 {
199     std::map< std::string, std::string > bundleParams;
200
201     if (g_pResourceContainer && g_bContainerStarted)
202     {
203         g_pResourceContainer->addBundle(EXAMPLE_BUNDLE_ID, EXAMPLE_BUNDLE_URI,
204                                         EXAMPLE_BUNDLE_PATH, EXAMPLE_BUNDLE_ACTIVATOR,
205                                         bundleParams);
206     }
207     else
208     {
209         std::cout << "Container is not started." << std::endl;
210     }
211 }
212
213 void StartSampleBundle()
214 {
215     if (g_pResourceContainer && g_bContainerStarted)
216     {
217         if (checkBundleRegistered(EXAMPLE_BUNDLE_ID))
218         {
219             g_pResourceContainer->startBundle(EXAMPLE_BUNDLE_ID);
220             g_bSampleBundleStarted = true;
221         }
222     }
223     else
224     {
225         std::cout << "Container is not started." << std::endl;
226     }
227 }
228
229 void StopSampleBundle()
230 {
231     if (g_pResourceContainer && g_bContainerStarted)
232     {
233         if (checkBundleRegistered(EXAMPLE_BUNDLE_ID) && g_bSampleBundleStarted)
234         {
235             g_pResourceContainer->stopBundle(EXAMPLE_BUNDLE_ID);
236             g_bSampleBundleStarted = false;
237         }
238         else
239             std::cout << "Sample Bundle is not started." << std::endl;
240     }
241     else
242     {
243         std::cout << "Container is not started." << std::endl;
244     }
245 }
246
247 void RemoveSampleBundle()
248 {
249     if (g_pResourceContainer && g_bContainerStarted)
250     {
251         if (checkBundleRegistered(EXAMPLE_BUNDLE_ID))
252             g_pResourceContainer->removeBundle(EXAMPLE_BUNDLE_ID);
253     }
254     else
255     {
256         std::cout << "Container is not started." << std::endl;
257     }
258 }
259
260 void AddSampleBundleResource()
261 {
262     std::map< std::string, std::string > resourceParams;
263
264     if (g_pResourceContainer && g_bContainerStarted)
265     {
266         if (checkBundleRegistered(EXAMPLE_BUNDLE_ID) && g_bSampleBundleStarted)
267         {
268             resourceParams.insert(std::make_pair("resourceType", EXAMPLE_RESOURCE_TYPE));
269             resourceParams.insert(std::make_pair("address", EXAMPLE_ADDRESS));
270
271             g_pResourceContainer->addResourceConfig(EXAMPLE_BUNDLE_ID, EXAMPLE_RESOURCE_URI,
272                                                     resourceParams);
273         }
274         else
275             std::cout << "Sample Bundle is not started." << std::endl;
276     }
277     else
278     {
279         std::cout << "Container is not started." << std::endl;
280     }
281 }
282
283 void RemoveSampleBundleResource()
284 {
285     if (g_pResourceContainer && g_bContainerStarted)
286     {
287         if (checkResourceRegistered(EXAMPLE_BUNDLE_ID, EXAMPLE_RESOURCE_URI)
288             && g_bSampleBundleStarted)
289             g_pResourceContainer->removeResourceConfig(EXAMPLE_BUNDLE_ID, EXAMPLE_RESOURCE_URI);
290         else
291             std::cout << "Sample Bundle is not started." << std::endl;
292     }
293     else
294     {
295         std::cout << "Container is not started." << std::endl;
296     }
297 }
298
299 void printBundleList(std::list< std::unique_ptr< RCSBundleInfo > > &list)
300 {
301     std::cout << std::endl;
302     for (auto &bundleinfo : list)
303     {
304         std::cout << "-- " << bundleinfo->getID() << std::endl;
305     }
306     std::cout << std::endl;
307 }
308
309 void ListBundles()
310 {
311     std::list< std::unique_ptr< RCSBundleInfo > > bundles;
312
313     if (g_pResourceContainer && g_bContainerStarted)
314     {
315         bundles = g_pResourceContainer->listBundles();
316         printBundleList(bundles);
317     }
318     else
319     {
320         std::cout << "Container is not started." << std::endl;
321     }
322 }
323
324 void printResourceList(std::list< std::string > &list)
325 {
326     std::cout << std::endl;
327     for (auto &bundleResource : list)
328     {
329         std::cout << "-- " << bundleResource << std::endl;
330     }
331     std::cout << std::endl;
332 }
333
334 void ListResources(std::string bundleId)
335 {
336     std::list< std::string > resources;
337
338     if (g_pResourceContainer && g_bContainerStarted)
339     {
340         if (checkBundleRegistered(bundleId))
341         {
342             resources = g_pResourceContainer->listBundleResources(bundleId);
343             printResourceList(resources);
344         }
345     }
346     else
347     {
348         std::cout << "Container is not started." << std::endl;
349     }
350 }
351
352 void ExecuteCommand(APPMenu menu)
353 {
354     switch (menu)
355     {
356         case APPMenu::START_RC:
357             {
358                 std::string filePath;
359                 std::cout << "Type Configuration File Path (Press \'0\' to start with example): ";
360
361                 if ((filePath = processUserStringInput()).compare("0") == 0)
362                 {
363                     getCurrentPath(&filePath);
364                     filePath.append(EXAMPLE_CONFIG_PATH);
365                 }
366
367                 StartContainer(filePath);
368             }
369             break;
370         case APPMenu::STOP_RC:
371             StopContainer();
372             break;
373         case APPMenu::ADD_SAMPLE_BUNDLE:
374             AddSampleBundle();
375             break;
376         case APPMenu::START_SAMPLE_BUNDLE:
377             StartSampleBundle();
378             break;
379         case APPMenu::STOP_SAMPLE_BUNDLE:
380             StopSampleBundle();
381             break;
382         case APPMenu::REMOVE_SAMPLE_BUNDLE:
383             RemoveSampleBundle();
384             break;
385         case APPMenu::ADD_SAMPLE_RESOURCE:
386             AddSampleBundleResource();
387             break;
388         case APPMenu::REMOVE_SAMPLE_RESOURCE:
389             RemoveSampleBundleResource();
390             break;
391         case APPMenu::LIST_BUNDLES:
392             ListBundles();
393             break;
394         case APPMenu::LIST_RESOURCES:
395             {
396                 std::string bundleId;
397                 std::cout <<
398                           "Type Bundle Id to get Resource List (Press \'0\' to get example resource list): ";
399
400                 if ((bundleId = processUserStringInput()).compare("0") == 0)
401                 {
402                     bundleId = EXAMPLE_BUNDLE_ID;
403                 }
404
405                 ListResources(bundleId);
406             }
407             break;
408         case APPMenu::EXIT:
409             throw CloseApp();
410             break;
411     }
412 }
413
414 int main()
415 {
416     g_pResourceContainer = RCSResourceContainer::getInstance();
417
418     while (true)
419     {
420         try
421         {
422             displayMenu();
423             ExecuteCommand((APPMenu)processUserInput(APPMenu::START_RC, APPMenu::EXIT));
424         }
425         catch (const std::exception &e)
426         {
427             std::cout << e.what() << std::endl;
428         }
429         catch (const CloseApp &)
430         {
431             break;
432         }
433     }
434
435     if (g_bContainerStarted)
436         g_pResourceContainer->stopContainer();
437
438     g_pResourceContainer = nullptr;
439
440     return 0;
441 }