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