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