Fixed svase-warnings for iotivity-product's SQA on |credresource|
[platform/upstream/iotivity.git] / resource / examples / simpleclient.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 static const char* SVR_DB_FILE_NAME = "./oic_svr_db_client.dat";
35 typedef std::map<OCResourceIdentifier, std::shared_ptr<OCResource>> DiscoveredResourceMap;
36
37 DiscoveredResourceMap discoveredResources;
38 std::shared_ptr<OCResource> curResource;
39 static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe;
40 std::mutex curResourceLock;
41
42 class Light
43 {
44 public:
45
46     bool m_state;
47     int m_power;
48     std::string m_name;
49
50     Light() : m_state(false), m_power(0), m_name("")
51     {
52     }
53 };
54
55 Light mylight;
56
57 int observe_count()
58 {
59     static int oc = 0;
60     return ++oc;
61 }
62
63 void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation& rep,
64                     const int& eCode, const int& sequenceNumber)
65 {
66     try
67     {
68         if(eCode == OC_STACK_OK && sequenceNumber != -1)
69         {
70             if(sequenceNumber == OC_OBSERVE_REGISTER)
71             {
72                 std::cout << "Observe registration action is successful" << std::endl;
73             }
74
75             std::cout << "OBSERVE RESULT:"<<std::endl;
76             std::cout << "\tSequenceNumber: "<< sequenceNumber << std::endl;
77             rep.getValue("state", mylight.m_state);
78             rep.getValue("power", mylight.m_power);
79             rep.getValue("name", mylight.m_name);
80
81             std::cout << "\tstate: " << mylight.m_state << std::endl;
82             std::cout << "\tpower: " << mylight.m_power << std::endl;
83             std::cout << "\tname: " << mylight.m_name << std::endl;
84
85             if(observe_count() == 11)
86             {
87                 std::cout<<"Cancelling Observe..."<<std::endl;
88                 OCStackResult result = curResource->cancelObserve();
89
90                 std::cout << "Cancel result: "<< result <<std::endl;
91                 sleep(10);
92                 std::cout << "DONE"<<std::endl;
93                 std::exit(0);
94             }
95         }
96         else
97         {
98             if(eCode == OC_STACK_OK)
99             {
100                 std::cout << "Observe registration failed or de-registration action failed/succeeded" << std::endl;
101             }
102             else
103             {
104                 std::cout << "onObserve Response error: " << eCode << std::endl;
105                 std::exit(-1);
106             }
107         }
108     }
109     catch(std::exception& e)
110     {
111         std::cout << "Exception: " << e.what() << " in onObserve" << std::endl;
112     }
113
114 }
115
116 void onPost2(const HeaderOptions& /*headerOptions*/,
117         const OCRepresentation& rep, const int eCode)
118 {
119     try
120     {
121         if(eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
122         {
123             std::cout << "POST request was successful" << std::endl;
124
125             if(rep.hasAttribute("createduri"))
126             {
127                 std::cout << "\tUri of the created resource: "
128                     << rep.getValue<std::string>("createduri") << std::endl;
129             }
130             else
131             {
132                 rep.getValue("state", mylight.m_state);
133                 rep.getValue("power", mylight.m_power);
134                 rep.getValue("name", mylight.m_name);
135
136                 std::cout << "\tstate: " << mylight.m_state << std::endl;
137                 std::cout << "\tpower: " << mylight.m_power << std::endl;
138                 std::cout << "\tname: " << mylight.m_name << std::endl;
139             }
140
141             if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
142                 std::cout << std::endl << "Observe is used." << std::endl << std::endl;
143             else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
144                 std::cout << std::endl << "ObserveAll is used." << std::endl << std::endl;
145
146             curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve);
147
148         }
149         else
150         {
151             std::cout << "onPost2 Response error: " << eCode << std::endl;
152             std::exit(-1);
153         }
154     }
155     catch(std::exception& e)
156     {
157         std::cout << "Exception: " << e.what() << " in onPost2" << std::endl;
158     }
159
160 }
161
162 void onPost(const HeaderOptions& /*headerOptions*/,
163         const OCRepresentation& rep, const int eCode)
164 {
165     try
166     {
167         if(eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED)
168         {
169             std::cout << "POST request was successful" << std::endl;
170
171             if(rep.hasAttribute("createduri"))
172             {
173                 std::cout << "\tUri of the created resource: "
174                     << rep.getValue<std::string>("createduri") << std::endl;
175             }
176             else
177             {
178                 rep.getValue("state", mylight.m_state);
179                 rep.getValue("power", mylight.m_power);
180                 rep.getValue("name", mylight.m_name);
181
182                 std::cout << "\tstate: " << mylight.m_state << std::endl;
183                 std::cout << "\tpower: " << mylight.m_power << std::endl;
184                 std::cout << "\tname: " << mylight.m_name << std::endl;
185             }
186
187             OCRepresentation rep2;
188
189             std::cout << "Posting light representation..."<<std::endl;
190
191             mylight.m_state = true;
192             mylight.m_power = 55;
193
194             rep2.setValue("state", mylight.m_state);
195             rep2.setValue("power", mylight.m_power);
196
197             curResource->post(rep2, QueryParamsMap(), &onPost2);
198         }
199         else
200         {
201             std::cout << "onPost Response error: " << eCode << std::endl;
202             std::exit(-1);
203         }
204     }
205     catch(std::exception& e)
206     {
207         std::cout << "Exception: " << e.what() << " in onPost" << std::endl;
208     }
209 }
210
211 // Local function to put a different state for this resource
212 void postLightRepresentation(std::shared_ptr<OCResource> resource)
213 {
214     if(resource)
215     {
216         OCRepresentation rep;
217
218         std::cout << "Posting light representation..."<<std::endl;
219
220         mylight.m_state = false;
221         mylight.m_power = 105;
222
223         rep.setValue("state", mylight.m_state);
224         rep.setValue("power", mylight.m_power);
225
226         // Invoke resource's post API with rep, query map and the callback parameter
227         resource->post(rep, QueryParamsMap(), &onPost);
228     }
229 }
230
231 // callback handler on PUT request
232 void onPut(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
233 {
234     try
235     {
236         if(eCode == OC_STACK_OK)
237         {
238             std::cout << "PUT request was successful" << std::endl;
239
240             rep.getValue("state", mylight.m_state);
241             rep.getValue("power", mylight.m_power);
242             rep.getValue("name", mylight.m_name);
243
244             std::cout << "\tstate: " << mylight.m_state << std::endl;
245             std::cout << "\tpower: " << mylight.m_power << std::endl;
246             std::cout << "\tname: " << mylight.m_name << std::endl;
247
248             postLightRepresentation(curResource);
249         }
250         else
251         {
252             std::cout << "onPut Response error: " << eCode << std::endl;
253             std::exit(-1);
254         }
255     }
256     catch(std::exception& e)
257     {
258         std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
259     }
260 }
261
262 // Local function to put a different state for this resource
263 void putLightRepresentation(std::shared_ptr<OCResource> resource)
264 {
265     if(resource)
266     {
267         OCRepresentation rep;
268
269         std::cout << "Putting light representation..."<<std::endl;
270
271         mylight.m_state = true;
272         mylight.m_power = 15;
273
274         rep.setValue("state", mylight.m_state);
275         rep.setValue("power", mylight.m_power);
276
277         // Invoke resource's put API with rep, query map and the callback parameter
278         resource->put(rep, QueryParamsMap(), &onPut);
279     }
280 }
281
282 // Callback handler on GET request
283 void onGet(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
284 {
285     try
286     {
287         if(eCode == OC_STACK_OK)
288         {
289             std::cout << "GET request was successful" << std::endl;
290             std::cout << "Resource URI: " << rep.getUri() << std::endl;
291
292             rep.getValue("state", mylight.m_state);
293             rep.getValue("power", mylight.m_power);
294             rep.getValue("name", mylight.m_name);
295
296             std::cout << "\tstate: " << mylight.m_state << std::endl;
297             std::cout << "\tpower: " << mylight.m_power << std::endl;
298             std::cout << "\tname: " << mylight.m_name << std::endl;
299
300             putLightRepresentation(curResource);
301         }
302         else
303         {
304             std::cout << "onGET Response error: " << eCode << std::endl;
305             std::exit(-1);
306         }
307     }
308     catch(std::exception& e)
309     {
310         std::cout << "Exception: " << e.what() << " in onGet" << std::endl;
311     }
312 }
313
314 // Local function to get representation of light resource
315 void getLightRepresentation(std::shared_ptr<OCResource> resource)
316 {
317     if(resource)
318     {
319         std::cout << "Getting Light Representation..."<<std::endl;
320         // Invoke resource's get API with the callback parameter
321
322         QueryParamsMap test;
323         resource->get(test, &onGet);
324     }
325 }
326
327 // Callback to found resources
328 void foundResource(std::shared_ptr<OCResource> resource)
329 {
330     std::cout << "In foundResource\n";
331     std::string resourceURI;
332     std::string hostAddress;
333     try
334     {
335         {
336             std::lock_guard<std::mutex> lock(curResourceLock);
337             if(discoveredResources.find(resource->uniqueIdentifier()) == discoveredResources.end())
338             {
339                 std::cout << "Found resource " << resource->uniqueIdentifier() <<
340                     " for the first time on server with ID: "<< resource->sid()<<std::endl;
341                 discoveredResources[resource->uniqueIdentifier()] = resource;
342             }
343             else
344             {
345                 std::cout<<"Found resource "<< resource->uniqueIdentifier() << " again!"<<std::endl;
346             }
347
348             if(curResource)
349             {
350                 std::cout << "Found another resource, ignoring"<<std::endl;
351                 return;
352             }
353         }
354
355         // Do some operations with resource object.
356         if(resource)
357         {
358             std::cout<<"DISCOVERED Resource:"<<std::endl;
359             // Get the resource URI
360             resourceURI = resource->uri();
361             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
362
363             // Get the resource host address
364             hostAddress = resource->host();
365             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
366
367             // Get the resource types
368             std::cout << "\tList of resource types: " << std::endl;
369             for(auto &resourceTypes : resource->getResourceTypes())
370             {
371                 std::cout << "\t\t" << resourceTypes << std::endl;
372             }
373
374             // Get the resource interfaces
375             std::cout << "\tList of resource interfaces: " << std::endl;
376             for(auto &resourceInterfaces : resource->getResourceInterfaces())
377             {
378                 std::cout << "\t\t" << resourceInterfaces << std::endl;
379             }
380
381             if(resourceURI == "/a/light")
382             {
383                 curResource = resource;
384                 // Call a local function which will internally invoke get API on the resource pointer
385                 getLightRepresentation(resource);
386             }
387         }
388         else
389         {
390             // Resource is invalid
391             std::cout << "Resource is invalid" << std::endl;
392         }
393
394     }
395     catch(std::exception& e)
396     {
397         std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
398     }
399 }
400
401 void printUsage()
402 {
403     std::cout << std::endl;
404     std::cout << "---------------------------------------------------------------------\n";
405     std::cout << "Usage : simpleclient <ObserveType>" << std::endl;
406     std::cout << "   ObserveType : 1 - Observe" << std::endl;
407     std::cout << "   ObserveType : 2 - ObserveAll" << std::endl;
408     std::cout << "---------------------------------------------------------------------\n\n";
409 }
410
411 void checkObserverValue(int value)
412 {
413     if (value == 1)
414     {
415         OBSERVE_TYPE_TO_USE = ObserveType::Observe;
416         std::cout << "<===Setting ObserveType to Observe===>\n\n";
417     }
418     else if (value == 2)
419     {
420         OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
421         std::cout << "<===Setting ObserveType to ObserveAll===>\n\n";
422     }
423     else
424     {
425         std::cout << "<===Invalid ObserveType selected."
426                   <<" Setting ObserveType to Observe===>\n\n";
427     }
428 }
429
430 static FILE* client_open(const char* /*path*/, const char *mode)
431 {
432     return fopen(SVR_DB_FILE_NAME, mode);
433 }
434
435 int main(int argc, char* argv[]) {
436
437     std::ostringstream requestURI;
438     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
439     try
440     {
441         printUsage();
442         if (argc == 1)
443         {
444             std::cout << "<===Setting ObserveType to Observe and ConnectivityType to IP===>\n\n";
445         }
446         else if (argc == 2)
447         {
448             checkObserverValue(std::stoi(argv[1]));
449         }
450         else
451         {
452             std::cout << "<===Invalid number of command line arguments===>\n\n";
453             return -1;
454         }
455     }
456     catch(std::exception& )
457     {
458         std::cout << "<===Invalid input arguments===>\n\n";
459         return -1;
460     }
461
462     // Create PlatformConfig object
463     PlatformConfig cfg {
464         OC::ServiceType::InProc,
465         OC::ModeType::Both,
466         "0.0.0.0",
467         0,
468         OC::QualityOfService::HighQos,
469         &ps
470     };
471
472     OCPlatform::Configure(cfg);
473     try
474     {
475         // makes it so that all boolean values are printed as 'true/false' in this stream
476         std::cout.setf(std::ios::boolalpha);
477         // Find all resources
478         requestURI << OC_RSRVD_WELL_KNOWN_URI;// << "?rt=core.light";
479
480         OCPlatform::findResource("", requestURI.str(),
481                 CT_DEFAULT, &foundResource);
482         std::cout<< "Finding Resource... " <<std::endl;
483
484         // Find resource is done twice so that we discover the original resources a second time.
485         // These resources will have the same uniqueidentifier (yet be different objects), so that
486         // we can verify/show the duplicate-checking code in foundResource(above);
487         OCPlatform::findResource("", requestURI.str(),
488                 CT_DEFAULT, &foundResource);
489         std::cout<< "Finding Resource for second time..." << std::endl;
490
491         // A condition variable will free the mutex it is given, then do a non-
492         // intensive block until 'notify' is called on it.  In this case, since we
493         // don't ever call cv.notify, this should be a non-processor intensive version
494         // of while(true);
495         std::mutex blocker;
496         std::condition_variable cv;
497         std::unique_lock<std::mutex> lock(blocker);
498         cv.wait(lock);
499
500     }catch(OCException& e)
501     {
502         oclog() << "Exception in main: "<<e.what();
503     }
504
505     return 0;
506 }
507
508