replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-container / examples / ContainerSampleClient.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
22 #include <string>
23 #include <map>
24 #include <cstdlib>
25 #include <pthread.h>
26 #include <mutex>
27 #include <condition_variable>
28 #include "OCPlatform.h"
29 #include "OCApi.h"
30
31 using namespace OC;
32
33 typedef std::map<OCResourceIdentifier, std::shared_ptr<OCResource>> DiscoveredResourceMap;
34
35 DiscoveredResourceMap discoveredResources;
36 std::shared_ptr<OCResource> curResource;
37 std::shared_ptr<OCResource> DISensorResource;
38 static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe;
39 std::mutex curResourceLock;
40
41 class Light
42 {
43     public:
44
45         bool m_on_off;
46         int m_color;
47         int m_dim;
48         std::string m_name;
49
50
51         Light() : m_on_off(false), m_color(0), m_dim(0), m_name("")
52         {
53         }
54 };
55
56 class LightSensor
57 {
58 public:
59         int m_intensity;
60
61         std::string m_name;
62
63         LightSensor() : m_intensity(0), m_name("")
64         {
65         }
66 };
67
68 Light mylight;
69
70 int observe_count()
71 {
72     static int oc = 0;
73     return ++oc;
74 }
75
76 void onObserve(const HeaderOptions headerOptions, const OCRepresentation &rep,
77                const int &eCode, const int &sequenceNumber)
78 {
79     (void)headerOptions;
80     try
81     {
82         if (eCode == OC_STACK_OK)
83         {
84             std::cout << "OBSERVE RESULT:" << std::endl;
85             std::cout << "\tSequenceNumber: " << sequenceNumber << std::endl;
86             rep.getValue("on-off", mylight.m_on_off);
87             rep.getValue("color", mylight.m_color);
88             rep.getValue("dim", mylight.m_dim);
89             rep.getValue("name", mylight.m_name);
90
91             std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
92             std::cout << "\tcolor: " << mylight.m_color << std::endl;
93             std::cout << "\tdim: " << mylight.m_dim << std::endl;
94
95             if (observe_count() > 10)
96             {
97                 std::cout << "Cancelling Observe..." << std::endl;
98                 OCStackResult result = curResource->cancelObserve();
99
100                 std::cout << "Cancel result: " << result << std::endl;
101                 sleep(10);
102                 std::cout << "DONE" << std::endl;
103                 std::exit(0);
104             }
105         }
106         else
107         {
108             std::cout << "onObserve Response error: " << eCode << std::endl;
109         }
110     }
111     catch (std::exception &e)
112     {
113         std::cout << "Exception: " << e.what() << " in onObserve" << std::endl;
114     }
115
116 }
117
118
119 void onLightIntensityObserve(const HeaderOptions headerOptions, const OCRepresentation &rep,
120                const int &eCode, const int &sequenceNumber)
121 {
122     (void)headerOptions;
123     try
124     {
125         if (eCode == OC_STACK_OK)
126         {
127             std::cout << "OBSERVE RESULT:" << std::endl;
128             std::cout << "\tSequenceNumber: " << sequenceNumber << std::endl;
129
130
131             std::cout << "\tintensity: " << rep.getValue<int>("intensity") << std::endl;
132
133
134             if (observe_count() > 10)
135             {
136                 std::cout << "Cancelling Observe..." << std::endl;
137                 OCStackResult result = curResource->cancelObserve();
138
139                 std::cout << "Cancel result: " << result << std::endl;
140                 sleep(10);
141                 std::cout << "DONE" << std::endl;
142                 std::exit(0);
143             }
144         }
145         else
146         {
147             std::cout << "onObserve Response error: " << eCode << std::endl;
148         }
149     }
150     catch (std::exception &e)
151     {
152         std::cout << "Exception: " << e.what() << " in onObserve" << std::endl;
153     }
154
155 }
156
157 void onPost2(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
158 {
159     (void)headerOptions;
160     try
161     {
162         if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
163         {
164             std::cout << "POST request was successful" << std::endl;
165
166             if (rep.hasAttribute("createduri"))
167             {
168                 std::cout << "\tUri of the created resource: "
169                           << rep.getValue<std::string>("createduri") << std::endl;
170             }
171             else
172             {
173                 rep.getValue("on-off", mylight.m_on_off);
174                 rep.getValue("color", mylight.m_color);
175                 rep.getValue("dim", mylight.m_dim);
176
177                 std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
178                 std::cout << "\tcolor: " << mylight.m_color << std::endl;
179                 std::cout << "\tdim: " << mylight.m_dim << std::endl;
180             }
181
182             if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
183             {
184                 std::cout << std::endl << "Observe is used." << std::endl << std::endl;
185             }
186             else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
187             {
188                 std::cout << std::endl << "ObserveAll is used." << std::endl << std::endl;
189             }
190
191             curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve);
192
193         }
194         else
195         {
196             std::cout << "onPost2 Response error: " << eCode << std::endl;
197         }
198     }
199     catch (std::exception &e)
200     {
201         std::cout << "Exception: " << e.what() << " in onPost2" << std::endl;
202     }
203
204 }
205
206 void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
207 {
208     (void)headerOptions;
209     try
210     {
211         if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
212         {
213             std::cout << "POST request was successful" << std::endl;
214
215             if (rep.hasAttribute("createduri"))
216             {
217                 std::cout << "\tUri of the created resource: "
218                           << rep.getValue<std::string>("createduri") << std::endl;
219             }
220             else
221             {
222                 rep.getValue("on-off", mylight.m_on_off);
223                 rep.getValue("color", mylight.m_color);
224                 rep.getValue("dim", mylight.m_dim);
225
226                 std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
227                 std::cout << "\tcolor: " << mylight.m_color << std::endl;
228                 std::cout << "\tdim: " << mylight.m_dim << std::endl;
229             }
230
231             OCRepresentation rep2;
232
233             std::cout << "Posting light representation..." << std::endl;
234
235             mylight.m_on_off = true;
236
237             rep2.setValue("on-off", mylight.m_on_off);
238
239             curResource->post(rep2, QueryParamsMap(), &onPost2);
240         }
241         else
242         {
243             std::cout << "onPost Response error: " << eCode << std::endl;
244         }
245     }
246     catch (std::exception &e)
247     {
248         std::cout << "Exception: " << e.what() << " in onPost" << std::endl;
249     }
250 }
251
252 // Local function to put a different state for this re<< std::endlsource
253 void postLightRepresentation(std::shared_ptr<OCResource> resource)
254 {
255     if (resource)
256     {
257         OCRepresentation rep;
258
259         std::cout << "Posting light representation..." << std::endl;
260
261         mylight.m_on_off = false;
262
263         rep.setValue("on-off", mylight.m_on_off);
264
265         // Invoke resource's post API with rep, query map and the callback parameter
266         resource->post(rep, QueryParamsMap(), &onPost);
267     }
268 }
269
270 // callback handler on PUT request
271 void onPut(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
272 {
273     (void)headerOptions;
274     (void)rep;
275     try
276     {
277         if (eCode == OC_STACK_OK)
278         {
279             std::cout << "PUT request was successful" << std::endl;
280
281             /*rep.getValue("on-off", mylight.m_on_off);
282             rep.getValue("dim", mylight.m_dim);
283             rep.getValue("color", mylight.m_color);
284
285             std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
286             std::cout << "\tcolor: " << mylight.m_color << std::endl;
287             std::cout << "\tdim: " << mylight.m_dim << std::endl;*/
288
289             //postLightRepresentation(curResource);
290         }
291         else
292         {
293             std::cout << "onPut Response error: " << eCode << std::endl;
294         }
295     }
296     catch (std::exception &e)
297     {
298         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
299     }
300 }
301
302 void onPutForDISensor(const HeaderOptions &headerOptions, const OCRepresentation &rep,
303                       const int eCode)
304 {
305     void onGetForDISensor(const HeaderOptions & headerOptions, const OCRepresentation & rep,
306                           const int eCode);
307
308     (void)headerOptions;
309     (void)rep;
310     try
311     {
312         if (eCode == OC_STACK_OK)
313         {
314             std::cout << "PUT request was successful" << std::endl;
315
316             QueryParamsMap test;
317             std::cout << "Sending request to: " << DISensorResource->uri() << std::endl;
318             DISensorResource->get(test, &onGetForDISensor);
319         }
320         else
321         {
322             std::cout << "onPut Response error: " << eCode << std::endl;
323         }
324     }
325     catch (std::exception &e)
326     {
327         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
328     }
329 }
330
331 // Local function to put a different state for this resource
332 void putLightRepresentation(std::shared_ptr<OCResource> resource)
333 {
334     if (resource)
335     {
336         OCRepresentation rep;
337
338         std::cout << "Putting light representation..." << std::endl;
339
340         mylight.m_on_off = true;
341
342         std::cout << "Sending request to: " << resource->uri() << std::endl;
343         rep.setValue("on-off", mylight.m_on_off);
344
345         // Invoke resource's put API with rep, query map and the callback parameter
346
347         resource->post(rep, QueryParamsMap(), &onPut);
348     }
349 }
350
351 // Callback handler on GET request
352 void onGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
353 {
354     (void)headerOptions;
355     try
356     {
357         if (eCode == OC_STACK_OK)
358         {
359             std::cout << "GET request was successful" << std::endl;
360             std::cout << "Resource URI: " << rep.getUri() << std::endl;
361
362             std::cout << "Payload: " << rep.getPayload() << std::endl;
363             std::cout << "On-off: " << rep.getValueToString("on-off") << std::endl;
364
365             rep.getValue("on-off", mylight.m_on_off);
366
367             std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
368
369             postLightRepresentation(curResource);
370         }
371         else
372         {
373             std::cout << "onGET Response error: " << eCode << std::endl;
374         }
375     }
376     catch (std::exception &e)
377     {
378         std::cout << "Exception: " << e.what() << " in onGet" << std::endl;
379     }
380 }
381
382 void onGetForDISensor(const HeaderOptions &headerOptions, const OCRepresentation &rep,
383                       const int eCode)
384 {
385     (void)headerOptions;
386     try
387     {
388         if (eCode == OC_STACK_OK)
389         {
390             std::cout << "GET request was successful" << std::endl;
391             std::cout << "Resource URI: " << DISensorResource->uri() << std::endl;
392
393             std::cout << "Payload: " << rep.getPayload() << std::endl;
394
395             std::cout << "\tdiscomfortIndex: " << rep.getValue<std::string>("discomfortIndex") << std::endl;
396         }
397         else
398         {
399             std::cout << "onGET Response error: " << eCode << std::endl;
400         }
401     }
402     catch (std::exception &e)
403     {
404         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
405     }
406 }
407
408
409 void onGetForLightIntensitySensor(const HeaderOptions &headerOptions, const OCRepresentation &rep,
410                       const int eCode)
411 {
412     (void)headerOptions;
413     try
414     {
415         if (eCode == OC_STACK_OK)
416         {
417             std::cout << "GET request was successful" << std::endl;
418             //std::cout << "Resource URI: " << DISensorResource->uri() << std::endl;
419
420             std::cout << "Payload: " << rep.getPayload() << std::endl;
421
422             std::cout << "\tlightIntensity: " << rep.getValue<int>("intensity") << std::endl;
423
424             // iterating over all elements
425             OCRepresentation::const_iterator itr = rep.begin();
426             OCRepresentation::const_iterator endItr = rep.end();
427
428             for(;itr!=endItr;++itr)
429             {
430                 std::cout << itr->attrname() << " ";
431                 std::cout << itr->getValue<int>() << std::endl;
432             }
433
434             curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onLightIntensityObserve);
435         }
436         else
437         {
438             std::cout << "onGET Response error: " << eCode << std::endl;
439         }
440     }
441     catch (std::exception &e)
442     {
443         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
444     }
445 }
446
447 // Local function to get representation of light resource
448 void getLightRepresentation(std::shared_ptr<OCResource> resource)
449 {
450     if (resource)
451     {
452         std::cout << "Getting Light Representation..." << std::endl;
453         // Invoke resource's get API with the callback parameter
454
455         QueryParamsMap test;
456         std::cout << "Sending request to: " << resource->uri() << std::endl;
457         resource->get(test, &onGet);
458     }
459 }
460
461 void onGetDiscomfortIndex(const HeaderOptions &headerOptions, const OCRepresentation &rep,
462                       const int eCode)
463 {
464     (void)headerOptions;
465     std::cout << "onGetDiscomfortIndex" << std::endl;
466     try
467     {
468         if (eCode == OC_STACK_OK)
469         {
470             std::cout << "GET request was successful" << std::endl;
471
472             std::cout << "Payload: " << rep.getPayload() << std::endl;
473
474             std::cout << "\tdiscomfortIndex: " << rep.getValue<double>("discomfortIndex") << std::endl;
475         }
476         else
477         {
478             std::cout << "onGET Response error: " << eCode << std::endl;
479         }
480     }
481     catch (std::exception &e)
482     {
483         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
484     }
485 }
486
487 void onObserveDiscomfort(const HeaderOptions headerOptions, const OCRepresentation &rep,
488                const int &eCode, const int &sequenceNumber)
489 {
490     (void)headerOptions;
491     try
492     {
493         if (eCode == OC_STACK_OK)
494         {
495             std::cout << "OBSERVE RESULT:" << std::endl;
496             std::cout << "\tSequenceNumber: " << sequenceNumber << std::endl;
497             std::cout << "\tdiscomfortIndex: " << rep.getValue<double>("discomfortIndex") << std::endl;
498
499             if (observe_count() > 10)
500             {
501                 std::cout << "Cancelling Observe..." << std::endl;
502                 OCStackResult result = curResource->cancelObserve();
503
504                 std::cout << "Cancel result: " << result << std::endl;
505                 sleep(10);
506                 std::cout << "DONE" << std::endl;
507                 std::exit(0);
508             }
509         }
510         else
511         {
512             std::cout << "onObserve Response error: " << eCode << std::endl;
513         }
514     }
515     catch (std::exception &e)
516     {
517         std::cout << "Exception: " << e.what() << " in onObserve" << std::endl;
518     }
519
520 }
521
522 // Local function to get representation of light resource
523 void getDiscomfortRepresentation(std::shared_ptr<OCResource> resource)
524 {
525     if (resource)
526     {
527         std::cout << "Getting Discomfort Representation..." << std::endl;
528         // Invoke resource's get API with the callback parameter
529
530         QueryParamsMap test;
531         std::cout << "Sending request to: " << resource->uri() << std::endl;
532         resource->get(test, &onGetDiscomfortIndex);
533         //resource->observe(ObserveType::Observe, QueryParamsMap(), &onObserve);
534     }
535 }
536
537
538
539
540 // Local function to get representation of light resource
541 void getLightIntensityRepresentation(std::shared_ptr<OCResource> resource)
542 {
543     if (resource)
544     {
545         std::cout << "Getting Light Representation..." << std::endl;
546         // Invoke resource's get API with the callback parameter
547
548         QueryParamsMap test;
549         std::cout << "Sending request to: " << resource->uri() << std::endl;
550         resource->get(test, &onGetForLightIntensitySensor);
551     }
552 }
553
554 // Callback to found resources
555 void foundResource(std::shared_ptr<OCResource> resource)
556 {
557     std::cout << "In foundResource\n";
558     std::string resourceURI = resource->uri();
559     std::string hostAddress;
560     try
561     {
562
563
564         // Do some operations with resource object.
565         if (resource)
566         {
567             std::cout << "DISCOVERED Resource:" << std::endl;
568             // Get the resource URI
569             resourceURI = resource->uri();
570             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
571
572             // Get the resource host address
573             hostAddress = resource->host();
574             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
575
576             // Get the resource types
577             std::cout << "\tList of resource types: " << std::endl;
578             for (auto &resourceTypes : resource->getResourceTypes())
579             {
580                 std::cout << "\t\t" << resourceTypes << std::endl;
581                 /*if (resourceTypes == "oic.r.light")
582                 {
583                     curResource = resource;
584                     // Call a local function which will internally invoke get API on the resource pointer
585                     getLightRepresentation(resource);
586                 }*/
587                 if (resourceTypes == "oic.r.discomfortindex")
588                 {
589                     curResource = resource;
590                     std::cout << "\t\tGet discomfort representation " << std::endl;
591                     // Call a local function which will internally invoke get API on the resource pointer
592                     getDiscomfortRepresentation(resource);
593                 }
594             }
595
596             // Get the resource interfaces
597             std::cout << "\tList of resource interfaces: " << std::endl;
598             for (auto &resourceInterfaces : resource->getResourceInterfaces())
599             {
600                 std::cout << "\t\t" << resourceInterfaces << std::endl;
601             }
602         }
603         else
604         {
605             // Resource is invalid
606             std::cout << "Resource is invalid" << std::endl;
607         }
608
609     }
610     catch (std::exception &e)
611     {
612         std::cerr << "Exception in foundResource: " << e.what() << std::endl;
613     }
614 }
615
616 void printUsage()
617 {
618     std::cout << std::endl;
619     std::cout << "---------------------------------------------------------------------\n";
620     std::cout << "Usage : ContainerSampleClient <ObserveType>" << std::endl;
621     std::cout << "   ObserveType : 1 - Observe" << std::endl;
622     std::cout << "   ObserveType : 2 - ObserveAll" << std::endl;
623     std::cout << "---------------------------------------------------------------------\n\n";
624 }
625
626 void checkObserverValue(int value)
627 {
628     if (value == 1)
629     {
630         OBSERVE_TYPE_TO_USE = ObserveType::Observe;
631         std::cout << "<===Setting ObserveType to Observe===>\n\n";
632     }
633     else if (value == 2)
634     {
635         OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
636         std::cout << "<===Setting ObserveType to ObserveAll===>\n\n";
637     }
638     else
639     {
640         std::cout << "<===Invalid ObserveType selected."
641                   << " Setting ObserveType to Observe===>\n\n";
642     }
643 }
644
645 static FILE *client_open(const char *path, const char *mode)
646 {
647     (void)path;
648
649     return fopen("./oic_svr_db_client.json", mode);
650 }
651
652 int main(int argc, char *argv[])
653 {
654
655     std::ostringstream requestURI;
656     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
657     try
658     {
659         printUsage();
660         if (argc == 1)
661         {
662             std::cout << "<===Setting ObserveType to Observe and ConnectivityType to IP===>\n\n";
663         }
664         else if (argc == 2)
665         {
666             checkObserverValue(std::stoi(argv[1]));
667         }
668         else
669         {
670             std::cout << "<===Invalid number of command line arguments===>\n\n";
671             return -1;
672         }
673     }
674     catch (std::exception &)
675     {
676         std::cout << "<===Invalid input arguments===>\n\n";
677         return -1;
678     }
679
680     // Create PlatformConfig object
681     PlatformConfig cfg
682     {
683         OC::ServiceType::InProc,
684         OC::ModeType::Both,
685         "0.0.0.0",
686         0,
687         OC::QualityOfService::LowQos,
688         &ps
689     };
690
691     OCPlatform::Configure(cfg);
692     try
693     {
694         // makes it so that all boolean values are printed as 'true/false' in this stream
695         std::cout.setf(std::ios::boolalpha);
696         // Find all resources
697         requestURI << OC_RSRVD_WELL_KNOWN_URI;// << "?rt=core.light";
698
699         OCPlatform::findResource("", requestURI.str(),
700                                  CT_DEFAULT, &foundResource);
701         std::cout << "Finding Resource... " << std::endl;
702
703         // Find resource is done twice so that we discover the original resources a second time.
704         // These resources will have the same uniqueidentifier (yet be different objects), so that
705         // we can verify/show the duplicate-checking code in foundResource(above);
706         OCPlatform::findResource("", requestURI.str(),
707                                  CT_DEFAULT, &foundResource);
708         std::cout << "Finding Resource for second time..." << std::endl;
709
710         // A condition variable will free the mutex it is given, then do a non-
711         // intensive block until 'notify' is called on it.  In this case, since we
712         // don't ever call cv.notify, this should be a non-processor intensive version
713         // of while(true);
714         std::mutex blocker;
715         std::condition_variable cv;
716         std::unique_lock<std::mutex> lock(blocker);
717         cv.wait(lock);
718
719     }
720     catch (const OCException &e)
721     {
722         std::cout << "Exception in main: " << e.what();
723     }
724
725     return 0;
726 }
727
728