Update on android sample resource bundle
[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 // Local function to get representation of light resource
459 void getLightIntensityRepresentation(std::shared_ptr<OCResource> resource)
460 {
461     if (resource)
462     {
463         std::cout << "Getting Light Representation..." << std::endl;
464         // Invoke resource's get API with the callback parameter
465
466         QueryParamsMap test;
467         std::cout << "Sending request to: " << resource->uri() << std::endl;
468         resource->get(test, &onGetForLightIntensitySensor);
469     }
470 }
471
472 // Callback to found resources
473 void foundResource(std::shared_ptr<OCResource> resource)
474 {
475     std::cout << "In foundResource\n";
476     std::string resourceURI = resource->uri();
477     std::string hostAddress;
478     try
479     {
480
481
482         // Do some operations with resource object.
483         if (resource)
484         {
485             std::cout << "DISCOVERED Resource:" << std::endl;
486             // Get the resource URI
487             resourceURI = resource->uri();
488             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
489
490             // Get the resource host address
491             hostAddress = resource->host();
492             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
493
494             // Get the resource types
495             std::cout << "\tList of resource types: " << std::endl;
496             for (auto &resourceTypes : resource->getResourceTypes())
497             {
498                 std::cout << "\t\t" << resourceTypes << std::endl;
499                 /*if (resourceTypes == "oic.r.light")
500                 {
501                     curResource = resource;
502                     // Call a local function which will internally invoke get API on the resource pointer
503                     getLightRepresentation(resource);
504                 }*/
505                 if (resourceTypes == "oic.r.lightsensor")
506                 {
507                     curResource = resource;
508                     // Call a local function which will internally invoke get API on the resource pointer
509                     getLightIntensityRepresentation(resource);
510                 }
511             }
512
513             // Get the resource interfaces
514             std::cout << "\tList of resource interfaces: " << std::endl;
515             for (auto &resourceInterfaces : resource->getResourceInterfaces())
516             {
517                 std::cout << "\t\t" << resourceInterfaces << std::endl;
518             }
519         }
520         else
521         {
522             // Resource is invalid
523             std::cout << "Resource is invalid" << std::endl;
524         }
525
526     }
527     catch (std::exception &e)
528     {
529         std::cerr << "Exception in foundResource: " << e.what() << std::endl;
530     }
531 }
532
533 void printUsage()
534 {
535     std::cout << std::endl;
536     std::cout << "---------------------------------------------------------------------\n";
537     std::cout << "Usage : ContainerSampleClient <ObserveType>" << std::endl;
538     std::cout << "   ObserveType : 1 - Observe" << std::endl;
539     std::cout << "   ObserveType : 2 - ObserveAll" << std::endl;
540     std::cout << "---------------------------------------------------------------------\n\n";
541 }
542
543 void checkObserverValue(int value)
544 {
545     if (value == 1)
546     {
547         OBSERVE_TYPE_TO_USE = ObserveType::Observe;
548         std::cout << "<===Setting ObserveType to Observe===>\n\n";
549     }
550     else if (value == 2)
551     {
552         OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
553         std::cout << "<===Setting ObserveType to ObserveAll===>\n\n";
554     }
555     else
556     {
557         std::cout << "<===Invalid ObserveType selected."
558                   << " Setting ObserveType to Observe===>\n\n";
559     }
560 }
561
562 static FILE *client_open(const char *path, const char *mode)
563 {
564     (void)path;
565
566     return fopen("./oic_svr_db_client.json", mode);
567 }
568
569 int main(int argc, char *argv[])
570 {
571
572     std::ostringstream requestURI;
573     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
574     try
575     {
576         printUsage();
577         if (argc == 1)
578         {
579             std::cout << "<===Setting ObserveType to Observe and ConnectivityType to IP===>\n\n";
580         }
581         else if (argc == 2)
582         {
583             checkObserverValue(std::stoi(argv[1]));
584         }
585         else
586         {
587             std::cout << "<===Invalid number of command line arguments===>\n\n";
588             return -1;
589         }
590     }
591     catch (std::exception &)
592     {
593         std::cout << "<===Invalid input arguments===>\n\n";
594         return -1;
595     }
596
597     // Create PlatformConfig object
598     PlatformConfig cfg
599     {
600         OC::ServiceType::InProc,
601         OC::ModeType::Both,
602         "0.0.0.0",
603         0,
604         OC::QualityOfService::LowQos,
605         &ps
606     };
607
608     OCPlatform::Configure(cfg);
609     try
610     {
611         // makes it so that all boolean values are printed as 'true/false' in this stream
612         std::cout.setf(std::ios::boolalpha);
613         // Find all resources
614         requestURI << OC_RSRVD_WELL_KNOWN_URI;// << "?rt=core.light";
615
616         OCPlatform::findResource("", requestURI.str(),
617                                  CT_DEFAULT, &foundResource);
618         std::cout << "Finding Resource... " << std::endl;
619
620         // Find resource is done twice so that we discover the original resources a second time.
621         // These resources will have the same uniqueidentifier (yet be different objects), so that
622         // we can verify/show the duplicate-checking code in foundResource(above);
623         OCPlatform::findResource("", requestURI.str(),
624                                  CT_DEFAULT, &foundResource);
625         std::cout << "Finding Resource for second time..." << std::endl;
626
627         // A condition variable will free the mutex it is given, then do a non-
628         // intensive block until 'notify' is called on it.  In this case, since we
629         // don't ever call cv.notify, this should be a non-processor intensive version
630         // of while(true);
631         std::mutex blocker;
632         std::condition_variable cv;
633         std::unique_lock<std::mutex> lock(blocker);
634         cv.wait(lock);
635
636     }
637     catch (OCException &e)
638     {
639         oclog() << "Exception in main: " << e.what();
640     }
641
642     return 0;
643 }
644
645