Cleaned up JNI wrapper, android light sensor resource example, notification mechanism...
[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 void onPost2(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
120 {
121     (void)headerOptions;
122     try
123     {
124         if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
125         {
126             std::cout << "POST request was successful" << std::endl;
127
128             if (rep.hasAttribute("createduri"))
129             {
130                 std::cout << "\tUri of the created resource: "
131                           << rep.getValue<std::string>("createduri") << std::endl;
132             }
133             else
134             {
135                 rep.getValue("on-off", mylight.m_on_off);
136                 rep.getValue("color", mylight.m_color);
137                 rep.getValue("dim", mylight.m_dim);
138
139                 std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
140                 std::cout << "\tcolor: " << mylight.m_color << std::endl;
141                 std::cout << "\tdim: " << mylight.m_dim << std::endl;
142             }
143
144             if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
145                 std::cout << std::endl << "Observe is used." << std::endl << std::endl;
146             else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
147                 std::cout << std::endl << "ObserveAll is used." << std::endl << std::endl;
148
149             curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve);
150
151         }
152         else
153         {
154             std::cout << "onPost2 Response error: " << eCode << std::endl;
155         }
156     }
157     catch (std::exception &e)
158     {
159         std::cout << "Exception: " << e.what() << " in onPost2" << std::endl;
160     }
161
162 }
163
164 void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
165 {
166     (void)headerOptions;
167     try
168     {
169         if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
170         {
171             std::cout << "POST request was successful" << std::endl;
172
173             if (rep.hasAttribute("createduri"))
174             {
175                 std::cout << "\tUri of the created resource: "
176                           << rep.getValue<std::string>("createduri") << std::endl;
177             }
178             else
179             {
180                 rep.getValue("on-off", mylight.m_on_off);
181                 rep.getValue("color", mylight.m_color);
182                 rep.getValue("dim", mylight.m_dim);
183
184                 std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
185                 std::cout << "\tcolor: " << mylight.m_color << std::endl;
186                 std::cout << "\tdim: " << mylight.m_dim << std::endl;
187             }
188
189             OCRepresentation rep2;
190
191             std::cout << "Posting light representation..." << std::endl;
192
193             mylight.m_on_off = true;
194
195             rep2.setValue("on-off", mylight.m_on_off);
196
197             curResource->post(rep2, QueryParamsMap(), &onPost2);
198         }
199         else
200         {
201             std::cout << "onPost Response error: " << eCode << std::endl;
202         }
203     }
204     catch (std::exception &e)
205     {
206         std::cout << "Exception: " << e.what() << " in onPost" << std::endl;
207     }
208 }
209
210 // Local function to put a different state for this re<< std::endlsource
211 void postLightRepresentation(std::shared_ptr<OCResource> resource)
212 {
213     if (resource)
214     {
215         OCRepresentation rep;
216
217         std::cout << "Posting light representation..." << std::endl;
218
219         mylight.m_on_off = "false";
220
221         rep.setValue("on-off", mylight.m_on_off);
222
223         // Invoke resource's post API with rep, query map and the callback parameter
224         resource->post(rep, QueryParamsMap(), &onPost);
225     }
226 }
227
228 // callback handler on PUT request
229 void onPut(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
230 {
231     (void)headerOptions;
232     (void)rep;
233     try
234     {
235         if (eCode == OC_STACK_OK)
236         {
237             std::cout << "PUT request was successful" << std::endl;
238
239             /*rep.getValue("on-off", mylight.m_on_off);
240             rep.getValue("dim", mylight.m_dim);
241             rep.getValue("color", mylight.m_color);
242
243             std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
244             std::cout << "\tcolor: " << mylight.m_color << std::endl;
245             std::cout << "\tdim: " << mylight.m_dim << std::endl;*/
246
247             //postLightRepresentation(curResource);
248         }
249         else
250         {
251             std::cout << "onPut Response error: " << eCode << std::endl;
252         }
253     }
254     catch (std::exception &e)
255     {
256         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
257     }
258 }
259
260 void onPutForDISensor(const HeaderOptions &headerOptions, const OCRepresentation &rep,
261                       const int eCode)
262 {
263     void onGetForDISensor(const HeaderOptions & headerOptions, const OCRepresentation & rep,
264                           const int eCode);
265
266     (void)headerOptions;
267     (void)rep;
268     try
269     {
270         if (eCode == OC_STACK_OK)
271         {
272             std::cout << "PUT request was successful" << std::endl;
273
274             QueryParamsMap test;
275             std::cout << "Sending request to: " << DISensorResource->uri() << std::endl;
276             DISensorResource->get(test, &onGetForDISensor);
277         }
278         else
279         {
280             std::cout << "onPut Response error: " << eCode << std::endl;
281         }
282     }
283     catch (std::exception &e)
284     {
285         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
286     }
287 }
288
289 // Local function to put a different state for this resource
290 void putLightRepresentation(std::shared_ptr<OCResource> resource)
291 {
292     if (resource)
293     {
294         OCRepresentation rep;
295
296         std::cout << "Putting light representation..." << std::endl;
297
298         mylight.m_on_off = true;
299
300         std::cout << "Sending request to: " << resource->uri() << std::endl;
301         rep.setValue("on-off", mylight.m_on_off);
302
303         // Invoke resource's put API with rep, query map and the callback parameter
304
305         resource->put(rep, QueryParamsMap(), &onPut);
306     }
307 }
308
309 // Callback handler on GET request
310 void onGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode)
311 {
312     (void)headerOptions;
313     try
314     {
315         if (eCode == OC_STACK_OK)
316         {
317             std::cout << "GET request was successful" << std::endl;
318             std::cout << "Resource URI: " << rep.getUri() << std::endl;
319
320             std::cout << "Payload: " << rep.getPayload() << std::endl;
321             std::cout << "On-off: " << rep.getValueToString("on-off") << std::endl;
322
323             rep.getValue("on-off", mylight.m_on_off);
324
325             std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
326
327             putLightRepresentation(curResource);
328         }
329         else
330         {
331             std::cout << "onGET Response error: " << eCode << std::endl;
332         }
333     }
334     catch (std::exception &e)
335     {
336         std::cout << "Exception: " << e.what() << " in onGet" << std::endl;
337     }
338 }
339
340 void onGetForDISensor(const HeaderOptions &headerOptions, const OCRepresentation &rep,
341                       const int eCode)
342 {
343     (void)headerOptions;
344     try
345     {
346         if (eCode == OC_STACK_OK)
347         {
348             std::cout << "GET request was successful" << std::endl;
349             std::cout << "Resource URI: " << DISensorResource->uri() << std::endl;
350
351             std::cout << "Payload: " << rep.getPayload() << std::endl;
352
353             std::cout << "\tdiscomfortIndex: " << rep.getValue<std::string>("discomfortIndex") << std::endl;
354         }
355         else
356         {
357             std::cout << "onGET Response error: " << eCode << std::endl;
358         }
359     }
360     catch (std::exception &e)
361     {
362         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
363     }
364 }
365
366
367 void onGetForLightIntensitySensor(const HeaderOptions &headerOptions, const OCRepresentation &rep,
368                       const int eCode)
369 {
370     (void)headerOptions;
371     try
372     {
373         if (eCode == OC_STACK_OK)
374         {
375             std::cout << "GET request was successful" << std::endl;
376             //std::cout << "Resource URI: " << DISensorResource->uri() << std::endl;
377
378             std::cout << "Payload: " << rep.getPayload() << std::endl;
379
380             std::cout << "\lightIntensity: " << rep.getValue<int>("lightintensity") << std::endl;
381         }
382         else
383         {
384             std::cout << "onGET Response error: " << eCode << std::endl;
385         }
386     }
387     catch (std::exception &e)
388     {
389         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
390     }
391 }
392
393 // Local function to get representation of light resource
394 void getLightRepresentation(std::shared_ptr<OCResource> resource)
395 {
396     if (resource)
397     {
398         std::cout << "Getting Light Representation..." << std::endl;
399         // Invoke resource's get API with the callback parameter
400
401         QueryParamsMap test;
402         std::cout << "Sending request to: " << resource->uri() << std::endl;
403         resource->get(test, &onGet);
404     }
405 }
406
407 // Local function to get representation of light resource
408 void getLightIntensityRepresentation(std::shared_ptr<OCResource> resource)
409 {
410     if (resource)
411     {
412         std::cout << "Getting Light Representation..." << std::endl;
413         // Invoke resource's get API with the callback parameter
414
415         QueryParamsMap test;
416         std::cout << "Sending request to: " << resource->uri() << std::endl;
417         resource->get(test, &onGetForLightIntensitySensor);
418     }
419 }
420
421 // Callback to found resources
422 void foundResource(std::shared_ptr<OCResource> resource)
423 {
424     std::cout << "In foundResource\n";
425     std::string resourceURI = resource->uri();
426     std::string hostAddress;
427     try
428     {
429
430
431         // Do some operations with resource object.
432         if (resource)
433         {
434             std::cout << "DISCOVERED Resource:" << std::endl;
435             // Get the resource URI
436             resourceURI = resource->uri();
437             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
438
439             // Get the resource host address
440             hostAddress = resource->host();
441             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
442
443             // Get the resource types
444             std::cout << "\tList of resource types: " << std::endl;
445             for (auto &resourceTypes : resource->getResourceTypes())
446             {
447                 std::cout << "\t\t" << resourceTypes << std::endl;
448                 /*if (resourceTypes == "oic.r.light")
449                 {
450                     curResource = resource;
451                     // Call a local function which will internally invoke get API on the resource pointer
452                     getLightRepresentation(resource);
453                 }*/
454                 if (resourceTypes == "oic.r.lightintensity")
455                 {
456                     curResource = resource;
457                     // Call a local function which will internally invoke get API on the resource pointer
458                     getLightIntensityRepresentation(resource);
459                 }
460             }
461
462             // Get the resource interfaces
463             std::cout << "\tList of resource interfaces: " << std::endl;
464             for (auto &resourceInterfaces : resource->getResourceInterfaces())
465             {
466                 std::cout << "\t\t" << resourceInterfaces << std::endl;
467             }
468         }
469         else
470         {
471             // Resource is invalid
472             std::cout << "Resource is invalid" << std::endl;
473         }
474
475     }
476     catch (std::exception &e)
477     {
478         std::cerr << "Exception in foundResource: " << e.what() << std::endl;
479     }
480 }
481
482 void printUsage()
483 {
484     std::cout << std::endl;
485     std::cout << "---------------------------------------------------------------------\n";
486     std::cout << "Usage : ContainerSampleClient <ObserveType>" << std::endl;
487     std::cout << "   ObserveType : 1 - Observe" << std::endl;
488     std::cout << "   ObserveType : 2 - ObserveAll" << std::endl;
489     std::cout << "---------------------------------------------------------------------\n\n";
490 }
491
492 void checkObserverValue(int value)
493 {
494     if (value == 1)
495     {
496         OBSERVE_TYPE_TO_USE = ObserveType::Observe;
497         std::cout << "<===Setting ObserveType to Observe===>\n\n";
498     }
499     else if (value == 2)
500     {
501         OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
502         std::cout << "<===Setting ObserveType to ObserveAll===>\n\n";
503     }
504     else
505     {
506         std::cout << "<===Invalid ObserveType selected."
507                   << " Setting ObserveType to Observe===>\n\n";
508     }
509 }
510
511 static FILE *client_open(const char *path, const char *mode)
512 {
513     (void)path;
514
515     return fopen("./oic_svr_db_client.json", mode);
516 }
517
518 int main(int argc, char *argv[])
519 {
520
521     std::ostringstream requestURI;
522     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
523     try
524     {
525         printUsage();
526         if (argc == 1)
527         {
528             std::cout << "<===Setting ObserveType to Observe and ConnectivityType to IP===>\n\n";
529         }
530         else if (argc == 2)
531         {
532             checkObserverValue(std::stoi(argv[1]));
533         }
534         else
535         {
536             std::cout << "<===Invalid number of command line arguments===>\n\n";
537             return -1;
538         }
539     }
540     catch (std::exception &)
541     {
542         std::cout << "<===Invalid input arguments===>\n\n";
543         return -1;
544     }
545
546     // Create PlatformConfig object
547     PlatformConfig cfg
548     {
549         OC::ServiceType::InProc,
550         OC::ModeType::Both,
551         "0.0.0.0",
552         0,
553         OC::QualityOfService::LowQos,
554         &ps
555     };
556
557     OCPlatform::Configure(cfg);
558     try
559     {
560         // makes it so that all boolean values are printed as 'true/false' in this stream
561         std::cout.setf(std::ios::boolalpha);
562         // Find all resources
563         requestURI << OC_RSRVD_WELL_KNOWN_URI;// << "?rt=core.light";
564
565         OCPlatform::findResource("", requestURI.str(),
566                                  CT_DEFAULT, &foundResource);
567         std::cout << "Finding Resource... " << std::endl;
568
569         // Find resource is done twice so that we discover the original resources a second time.
570         // These resources will have the same uniqueidentifier (yet be different objects), so that
571         // we can verify/show the duplicate-checking code in foundResource(above);
572         OCPlatform::findResource("", requestURI.str(),
573                                  CT_DEFAULT, &foundResource);
574         std::cout << "Finding Resource for second time..." << std::endl;
575
576         // A condition variable will free the mutex it is given, then do a non-
577         // intensive block until 'notify' is called on it.  In this case, since we
578         // don't ever call cv.notify, this should be a non-processor intensive version
579         // of while(true);
580         std::mutex blocker;
581         std::condition_variable cv;
582         std::unique_lock<std::mutex> lock(blocker);
583         cv.wait(lock);
584
585     }
586     catch (OCException &e)
587     {
588         oclog() << "Exception in main: " << e.what();
589     }
590
591     return 0;
592 }
593
594