[IoTivity Simulator] Handling resource interfaces.
[platform/upstream/iotivity.git] / service / simulator / examples / server / simulator_server.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 "simulator_manager.h"
22
23 std::vector<SimulatorSingleResourceSP> g_singleResources;
24 std::vector<SimulatorCollectionResourceSP> g_collectionResources;
25
26 std::string getPropertyTypeString(SimulatorResourceModel::AttributeProperty::Type type)
27 {
28     switch(type)
29     {
30         case SimulatorResourceModel::AttributeProperty::Type::RANGE:
31             return "RANGE";
32         case SimulatorResourceModel::AttributeProperty::Type::VALUE_SET:
33             return "VALUE_SET";
34         default:
35             break;
36     }
37
38     return "UNKNOWN";
39 }
40
41 class AppLogger : public ILogger
42 {
43     public:
44         void write(std::string time, ILogger::Level level, std::string message)
45         {
46             std::cout << "[APPLogger] " << time << " " << ILogger::getString(level) << " "
47                       << message;
48         }
49 };
50 std::shared_ptr<AppLogger> gAppLogger(new AppLogger());
51
52 int selectResource()
53 {
54     if (0 == g_singleResources.size())
55     {
56         std::cout << "No resouces!" << std::endl;
57         return -1;
58     }
59
60     int index = 1;
61     for (auto & resource : g_singleResources)
62     {
63         std::cout << index++ << ": " << resource->getURI().c_str() << std::endl;
64     }
65
66     int choice = -1;
67     std::cout << "Choose the resource: ";
68     std::cin >> choice;
69
70     if (choice < 1 || choice > index - 1)
71     {
72         std::cout << "Invalid choice !" << std::endl;
73         choice = -1;
74     }
75
76     return choice;
77 }
78
79 void simulateResource()
80 {
81     try
82     {
83         // Resource model change callback
84         SimulatorResource::ResourceModelChangedCallback modelChangeCB =
85         [](const std::string &uri, SimulatorResourceModel &resModel)
86         {
87             std::cout << "[callback] Resource model is changed URI: " << uri.c_str() << std::endl;
88             std::cout << "#### Modified attributes are ####" << std::endl;
89             std::cout << "#### Updated resource model ####" << std::endl;
90             std::cout << resModel.toString() << std::endl;
91             std::cout << "########################" << std::endl;
92         };
93
94         // Observer added/removed callback
95         SimulatorResource::ObserverCallback observerCB =
96         [] (const std::string &uri, ObservationStatus state, const ObserverInfo &observerInfo)
97         {
98             std::cout << "[callback] Observer notification received..." << uri << std::endl;
99
100             std::ostringstream out;
101             out << "ID:  " << (int) observerInfo.id << std::endl;
102             out << " [address: " << observerInfo.address << " port: " << observerInfo.port
103                 << "]" << std::endl;
104             std::cout << out.str();
105         };
106
107         // Get the RAML file path from user
108         std::string configPath;
109         std::cout << "Enter RAML path: ";
110         std::cin>>configPath;
111
112         SimulatorResourceSP resource =
113             SimulatorManager::getInstance()->createResource(configPath);
114
115         // Add resource to appropriate list
116         if (SimulatorResource::Type::SINGLE_RESOURCE == resource->getType())
117         {
118             std::cout << "Single type resource created [URI:  " << resource->getURI() << " ]" << std::endl;
119             SimulatorSingleResourceSP singleRes =
120                 std::dynamic_pointer_cast<SimulatorSingleResource>(resource);
121             singleRes->setModelChangeCallback(modelChangeCB);
122             singleRes->setObserverCallback(observerCB);
123             g_singleResources.push_back(singleRes);
124         }
125         else
126         {
127             std::cout << "Collection type resource created [URI:  " << resource->getURI() << " ]" << std::endl;
128             SimulatorCollectionResourceSP collectionRes =
129                 std::dynamic_pointer_cast<SimulatorCollectionResource>(resource);
130             collectionRes->setObserverCallback(observerCB);
131             g_collectionResources.push_back(collectionRes);
132         }
133     }
134     catch (InvalidArgsException &e)
135     {
136         std::cout << "InvalidArgsException occured [code : " << e.code() << " Details: "
137                   << e.what() << "]" << std::endl;
138     }
139     catch (SimulatorException &e)
140     {
141         std::cout << "SimulatorException occured [code : " << e.code() << " Details: "
142                   << e.what() << "]" << std::endl;
143     }
144 }
145
146 void displayResource()
147 {
148     int index = selectResource();
149     if (-1 == index)
150         return;
151
152     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
153
154     std::cout << "#############################" << std::endl;
155     std::cout << "Name: " << resource->getName() << std::endl;
156     std::cout << "URI: " << resource->getURI() << std::endl;
157     std::cout << "Resource type: " << resource->getResourceType() << std::endl;
158     std::cout << "Interface type:";
159     for (auto &interfaceType : resource->getInterface())
160         std::cout << " " << interfaceType << std::endl;
161
162     // Attributes
163     SimulatorResourceModel resModel = resource->getResourceModel();
164     std::map<std::string, SimulatorResourceModel::Attribute> attributes =
165         resModel.getAttributes();
166     std::cout << "##### Attributes [" << attributes.size() << "]" << std::endl;
167     for (auto & attribute : attributes)
168     {
169         std::cout << (attribute.second).getName() << " :  {" << std::endl;
170         std::cout << "value: " << (attribute.second).toString() << std::endl;
171         SimulatorResourceModel::AttributeProperty prop = (attribute.second).getProperty();
172         std::cout << "Supported values given by : " << getPropertyTypeString(prop.type()) << std::endl;
173         if (SimulatorResourceModel::AttributeProperty::Type::RANGE == prop.type())
174         {
175             std::cout << "Min: " << prop.min() << std::endl;
176             std::cout << "Max: " << prop.max() << std::endl;
177         }
178         else if (SimulatorResourceModel::AttributeProperty::Type::VALUE_SET == prop.type())
179         {
180             std::cout << "Value set: " << prop.valueSetToString() << std::endl;
181         }
182
183         std::cout << "}" << std::endl << std::endl;
184     }
185     std::cout << "#############################" << std::endl;
186 }
187
188 void startResource()
189 {
190     int index = selectResource();
191     if (-1 == index)
192         return;
193
194     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
195     resource->start();
196     std::cout << "Resource started!" << std::endl;
197 }
198
199 void stopResource()
200 {
201     int index = selectResource();
202     if (-1 == index)
203         return;
204
205     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
206     resource->stop();
207     std::cout << "Resource stopped!" << std::endl;
208 }
209
210 void automateResourceUpdate()
211 {
212     updateCompleteCallback callback = [](const std::string &uri, const int id)
213     {
214         std::cout << "Update automation is completed [URI: " << uri
215                   << "  AutomationID: " << id << "] ###" << std::endl;
216     };
217
218     int index = selectResource();
219     if (-1 == index)
220         return;
221
222     AutomationType type = AutomationType::NORMAL;
223     int choice = 0;
224     std::cout << "Press 1 if you want recurrent automation: ";
225     std::cin >> choice;
226     if (1 == choice)
227         type = AutomationType::RECURRENT;
228
229     try
230     {
231         int id = g_singleResources[index - 1]->startResourceUpdation(type, -1, callback);
232
233         std::cout << "startUpdateAutomation() returned succces : " << id << std::endl;
234     }
235     catch (SimulatorException &e)
236     {
237         std::cout << "SimulatorException occured [code : " << e.code() << " Details: " <<
238                   e.what() << "]" << std::endl;
239     }
240 }
241
242 void automateAttributeUpdate()
243 {
244     updateCompleteCallback callback = [](const std::string &uri, const int id)
245     {
246         std::cout << "Update automation is completed [URI: " << uri
247                   << "  AutomationID: " << id << "] ###" << std::endl;
248     };
249
250     int index = selectResource();
251     if (-1 == index)
252         return;
253
254     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
255     SimulatorResourceModel resModel = resource->getResourceModel();
256     std::map<std::string, SimulatorResourceModel::Attribute> attributes =
257         resModel.getAttributes();
258     int size = 0;
259     for (auto & attribute : attributes)
260     {
261         std::cout << ++size << ": " << attribute.first.c_str() << std::endl;
262     }
263
264     if (0 == size)
265     {
266         std::cout << "This resource doest not contain any attributes!" << std::endl;
267         return;
268     }
269
270     int choice = -1;
271     std::cout << "Select the attribute which you want to automate for updation: " <<
272               std::endl;
273     std::cin >> choice;
274     if (choice < 0 || choice > size)
275     {
276         std::cout << "Invalid selection!" << std::endl;
277         return;
278     }
279
280     int count = 0;
281     std::string attributeName;
282     for (auto & attribute : attributes)
283     {
284         if (count == choice - 1)
285         {
286             attributeName = attribute.first;
287             break;
288         }
289
290         count++;
291     }
292
293     AutomationType type = AutomationType::NORMAL;
294     std::cout << "Press 1 if you want recurrent automation: ";
295     std::cin >> choice;
296     if (1 == choice)
297         type = AutomationType::RECURRENT;
298
299     std::cout << "Requesting attribute automation for " << attributeName <<
300               std::endl;
301
302     try
303     {
304
305         int id = resource->startAttributeUpdation(attributeName, type, -1, callback);
306         std::cout << "startUpdateAutomation() returned succces : " << id << std::endl;
307     }
308     catch (SimulatorException &e)
309     {
310         std::cout << "SimulatorException occured [Error: " << e.code() << " Details: " <<
311                   e.what() << "]" << std::endl;
312     }
313 }
314
315 void stopAutomation()
316 {
317     int index = selectResource();
318     if (-1 == index)
319         return;
320
321     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
322
323     // Select the automation to stop
324     std::vector<int> ids;
325     {
326         std::vector<int> rids = resource->getResourceUpdationIds();
327         std::vector<int> aids = resource->getAttributeUpdationIds();
328         ids.insert(ids.end(), rids.begin(), rids.end());
329         ids.insert(ids.end(), aids.begin(), aids.end());
330     }
331
332     if (!ids.size())
333     {
334         std::cout << "No automation operation is going on this resource right now!" <<
335                   std::endl;
336         return;
337     }
338
339     for (auto & id : ids)
340     {
341         std::cout <<  id  << " ";
342         resource->stopUpdation(id);
343     }
344 }
345
346 void getObservers()
347 {
348     int index = selectResource();
349     if (-1 == index)
350         return;
351
352     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
353
354     std::vector<ObserverInfo> observersList = resource->getObserversList();
355
356     std::cout << "##### Number of Observers [" << observersList.size() << "]" << std::endl;
357     for (auto & observerInfo : observersList)
358     {
359         std::cout << " ID :  " << (int) observerInfo.id << " [address: " <<
360                   observerInfo.address << " port: " << observerInfo.port << "]" << std::endl;
361     }
362     std::cout << "########################" << std::endl;
363 }
364
365 void printMainMenu()
366 {
367     std::cout << "############### MAIN MENU###############" << std::endl;
368     std::cout << "1. Simulate resource" << std::endl;
369     std::cout << "2. Display resource information" << std::endl;
370     std::cout << "3. Start resource" << std::endl;
371     std::cout << "4. Stop resource" << std::endl;
372     std::cout << "5. Automate resource update" << std::endl;
373     std::cout << "6. Automate attributes update" << std::endl;
374     std::cout << "7. Stop Automation" << std::endl;
375     std::cout << "8. Get Observers of a resource" << std::endl;
376     std::cout << "9. Set Logger" << std::endl;
377     std::cout << "10. Set Device Info" << std::endl;
378     std::cout << "11. Set Platform Info" << std::endl;
379     std::cout << "12. Add Interface" << std::endl;
380     std::cout << "13. Remove Interface" << std::endl;
381     std::cout << "14. Help" << std::endl;
382     std::cout << "0. Exit" << std::endl;
383     std::cout << "######################################" << std::endl;
384 }
385
386 void setLogger()
387 {
388     std::cout << "1. Default console logger" << std::endl;
389     std::cout << "2. Default file logger" << std::endl;
390     std::cout << "3. custom logger" << std::endl;
391
392     int choice = -1;
393     std::cin >> choice;
394     if (choice <= 0 || choice > 3)
395     {
396         std::cout << "Invalid selection !" << std::endl;
397         return;
398     }
399
400     switch (choice)
401     {
402         case 1:
403             {
404                 if (false == SimulatorManager::getInstance()->setConsoleLogger())
405                     std::cout << "Failed to set the default console logger" << std::endl;
406             } break;
407         case 2:
408             {
409                 std::string filePath;
410                 std::cout << "Enter the file path (without file name) : ";
411                 std::cin >> filePath;
412                 if (false == SimulatorManager::getInstance()->setFileLogger(filePath))
413                     std::cout << "Failed to set default file logger" << std::endl;
414             } break;
415         case 3: SimulatorManager::getInstance()->setLogger(gAppLogger);
416     }
417 }
418
419 void setDeviceInfo()
420 {
421     SimulatorManager::getInstance()->setDeviceInfo("IoTivity Simulator Linux Sample");
422     std::cout << "Setting Device Info is successful" << std::endl;
423 }
424
425 void setPlatformInfo()
426 {
427     PlatformInfo pInfo;
428     pInfo.setPlatformID("Samsung Platform Identifier");
429     pInfo.setFirmwareVersion("FirwareVersion01");
430     pInfo.setHardwareVersion("HardwareVersion01");
431     pInfo.setManufacturerName("Samsung");
432     pInfo.setManufacturerUrl("www.samsung.com");
433     pInfo.setModelNumber("Samsung Model Num01");
434     pInfo.setOSVersion("OSVersion01");
435     pInfo.setPlatformVersion("PlatformVersion01");
436     pInfo.setSupportUrl("http://www.samsung.com/support");
437     pInfo.setSystemTime("2015-09-10T11:10:30Z");
438     pInfo.setDateOfManfacture("2015-09-10T11:10:30Z");
439
440     SimulatorManager::getInstance()->setPlatformInfo(pInfo);
441     std::cout << "Setting Platform Info is successful" << std::endl;
442 }
443
444 void addInterface()
445 {
446     int index = selectResource();
447     if (-1 == index)
448         return;
449
450     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
451
452     std::vector<std::string> interfaces;
453     interfaces.push_back("oic.if.s");
454     interfaces.push_back("oic.if.a");
455
456     resource->addInterface(interfaces);
457 }
458
459 void removeInterface()
460 {
461     int index = selectResource();
462     if (-1 == index)
463         return;
464
465     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
466
467     std::vector<std::string> interfaces;
468     interfaces.push_back("oic.if.s");
469     interfaces.push_back("oic.if.a");
470
471     resource->removeInterface(interfaces);
472 }
473
474 int main(int argc, char *argv[])
475 {
476     printMainMenu();
477     bool cont = true;
478     while (cont == true)
479     {
480         int choice = -1;
481         std::cout << "Enter your choice: ";
482         std::cin >> choice;
483         if (choice < 0 || choice > 14)
484         {
485             std::cout << "Invaild choice !" << std::endl; continue;
486         }
487
488         switch (choice)
489         {
490             case 1 : simulateResource(); break;
491             case 2 : displayResource(); break;
492             case 3 : startResource(); break;
493             case 4 : stopResource(); break;
494             case 5 : automateResourceUpdate(); break;
495             case 6 : automateAttributeUpdate(); break;
496             case 7 : stopAutomation(); break;
497             case 8 : getObservers(); break;
498             case 9 : setLogger(); break;
499             case 10: setDeviceInfo(); break;
500             case 11: setPlatformInfo(); break;
501             case 12: addInterface(); break;
502             case 13: removeInterface(); break;
503             case 14: printMainMenu(); break;
504             case 0: cont = false;
505         }
506     }
507
508     std::cout << "Terminating test !!!" << std::endl;
509 }