[IOT-1482] fix getPlatformInfo and getDeviceInfo of C++-SDK sample app.
[platform/upstream/iotivity.git] / resource / examples / roomclient.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 <cstdlib>
25 #include <pthread.h>
26 #include <mutex>
27 #include <condition_variable>
28
29 #include "OCPlatform.h"
30 #include "OCApi.h"
31
32 using namespace OC;
33
34 const int SUCCESS_RESPONSE = 0;
35 std::shared_ptr<OCResource> curResource;
36 std::mutex resourceLock;
37
38 int observe_count()
39 {
40     static int oc = 0;
41     return ++oc;
42 }
43
44 static void printUsage()
45 {
46     std::cout << "Usage roomclient <0|1>" << std::endl;
47     std::cout<<"connectivityType: Default" << std::endl;
48     std::cout << "connectivityType 0: IP" << std::endl;
49 }
50 // Forward declaration
51 void putRoomRepresentation(std::shared_ptr<OCResource> resource);
52 void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
53
54 void printRoomRepresentation(const OCRepresentation& rep)
55 {
56     std::cout << "\tResource URI: " << rep.getUri() << std::endl;
57
58     if(rep.hasAttribute("name"))
59     {
60         std::cout << "\tRoom name: " << rep.getValue<std::string>("name") << std::endl;
61     }
62
63     std::vector<OCRepresentation> children = rep.getChildren();
64
65     for(auto oit = children.begin(); oit != children.end(); ++oit)
66     {
67         std::cout << "\t\tChild Resource URI: " << oit->getUri() << std::endl;
68         if(oit->getUri().find("light") != std::string::npos)
69         {
70             if(oit->hasAttribute("state") && oit->hasAttribute("color"))
71             {
72                 std::cout << "\t\tstate:" << oit->getValue<bool>("state")  << std::endl;
73                 std::cout << "\t\tcolor:" << oit->getValue<int>("color")  << std::endl;
74             }
75         }
76         else if(oit->getUri().find("fan") != std::string::npos)
77         {
78             if(oit->hasAttribute("state") && oit->hasAttribute("speed"))
79             {
80                 std::cout << "\t\tstate:" << oit->getValue<bool>("state") << std::endl;
81                 std::cout << "\t\tspeed:" << oit->getValue<int>("speed") << std::endl;
82             }
83         }
84     }
85 }
86
87 // callback handler on GET request
88 void onGet(const HeaderOptions& /*headerOptions*/,
89         const OCRepresentation& rep, const int eCode)
90 {
91     if(eCode == SUCCESS_RESPONSE)
92     {
93         std::cout << "GET request was successful" << std::endl;
94
95         printRoomRepresentation(rep);
96
97         putRoomRepresentation(curResource);
98     }
99     else
100     {
101         std::cout << "onGET Response error: " << eCode << std::endl;
102         std::exit(-1);
103     }
104 }
105
106 void onGet1(const HeaderOptions& /*headerOptions*/,
107         const OCRepresentation& rep, const int eCode)
108 {
109     if(eCode == SUCCESS_RESPONSE)
110     {
111         std::cout << "GET request was successful" << std::endl;
112
113         printRoomRepresentation(rep);
114     }
115     else
116     {
117         std::cout << "onGET Response error: " << eCode << std::endl;
118         std::exit(-1);
119     }
120 }
121
122 // Local function to get representation of room resource
123 void getRoomRepresentation(std::shared_ptr<OCResource> resource,
124                             std::string interface, GetCallback getCallback)
125 {
126     if(resource)
127     {
128         std::cout << "Getting room representation on: "<< interface << std::endl;
129
130         resource->get("core.room", interface, QueryParamsMap(), getCallback);
131     }
132 }
133
134 // Local function to put a different state for this resource
135 void putRoomRepresentation(std::shared_ptr<OCResource> resource)
136 {
137     if(resource)
138     {
139         OCRepresentation rep;
140         std::cout << "Putting room representation on: " << BATCH_INTERFACE << std::endl;
141
142         bool state = true;
143         int speed = 10;
144         rep.setValue("state", state);
145         rep.setValue("speed", speed);
146
147         // Invoke resource's pit API with attribute map, query map and the callback parameter
148         resource->put("core.room", BATCH_INTERFACE, rep, QueryParamsMap(), &onPut);
149     }
150 }
151
152 // callback handler on PUT request
153 void onPut(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
154 {
155     if(eCode == SUCCESS_RESPONSE)
156     {
157         std::cout << "PUT request was successful" << std::endl;
158
159         printRoomRepresentation(rep);
160
161         getRoomRepresentation(curResource, DEFAULT_INTERFACE, onGet1);
162     }
163     else
164     {
165         std::cout << "onPut Response error: " << eCode << std::endl;
166         std::exit(-1);
167     }
168 }
169
170 void receivedPlatformInfo(const OCRepresentation& rep)
171 {
172     std::cout << "\nPlatform Information received ---->\n";
173     std::string value;
174     std::string values[] =
175     {
176         "pi",   "Platform ID                    ",
177         "mnmn", "Manufacturer name              ",
178         "mnml", "Manufacturer url               ",
179         "mnmo", "Manufacturer Model No          ",
180         "mndt", "Manufactured Date              ",
181         "mnpv", "Manufacturer Platform Version  ",
182         "mnos", "Manufacturer OS version        ",
183         "mnhw", "Manufacturer hardware version  ",
184         "mnfv", "Manufacturer firmware version  ",
185         "mnsl", "Manufacturer support url       ",
186         "st",   "Manufacturer system time       "
187     };
188
189     for (unsigned int i = 0; i < sizeof(values) / sizeof(values[0]); i += 2)
190     {
191         if(rep.getValue(values[i], value))
192         {
193             std::cout << values[i + 1] << " : "<< value << std::endl;
194         }
195     }
196 }
197
198 void receivedDeviceInfo(const OCRepresentation& rep)
199 {
200     std::cout << "\nDevice Information received ---->\n";
201     std::string value;
202     std::string values[] =
203     {
204         "di",  "Device ID        ",
205         "n",   "Device name      ",
206         "lcv", "Spec version url ",
207         "dmv", "Data Model Model ",
208     };
209
210     for (unsigned int i = 0; i < sizeof(values) / sizeof(values[0]); i += 2)
211     {
212         if (rep.getValue(values[i], value))
213         {
214             std::cout << values[i + 1] << " : " << value << std::endl;
215         }
216     }
217 }
218
219 // Callback to found resources
220 void foundResource(std::shared_ptr<OCResource> resource)
221 {
222     std::lock_guard<std::mutex> lock(resourceLock);
223     if(curResource)
224     {
225         std::cout << "Found another resource, ignoring"<<std::endl;
226         return;
227     }
228
229     std::string resourceURI;
230     std::string hostAddress;
231     std::string platformDiscoveryURI = "/oic/p";
232     std::string deviceDiscoveryURI   = "/oic/d";
233     try
234     {
235         // Do some operations with resource object.
236         if(resource)
237         {
238             std::cout<<"DISCOVERED Resource:"<<std::endl;
239             // Get the resource URI
240             resourceURI = resource->uri();
241             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
242
243             // Get the resource host address
244             hostAddress = resource->host();
245             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
246
247             // Get the resource types
248             std::cout << "\tList of resource types: " << std::endl;
249             for(auto &resourceTypes : resource->getResourceTypes())
250             {
251                 std::cout << "\t\t" << resourceTypes << std::endl;
252             }
253
254             // Get the resource interfaces
255             std::cout << "\tList of resource interfaces: " << std::endl;
256             for(auto &resourceInterfaces : resource->getResourceInterfaces())
257             {
258                 std::cout << "\t\t" << resourceInterfaces << std::endl;
259             }
260
261             OCStackResult ret;
262             std::cout << "Querying for platform information... " << std::endl;
263
264             ret = OCPlatform::getPlatformInfo(resource->host(), platformDiscoveryURI,
265                                               resource->connectivityType(),
266                                               &receivedPlatformInfo);
267
268             if (ret == OC_STACK_OK)
269             {
270                 std::cout << "Get platform information is done." << std::endl;
271             }
272             else
273             {
274                 std::cout << "Get platform information failed." << std::endl;
275             }
276
277             std::cout << "Querying for device information... " << std::endl;
278
279             ret = OCPlatform::getDeviceInfo(resource->host(), deviceDiscoveryURI,
280                                             resource->connectivityType(),
281                                             &receivedDeviceInfo);
282             if (ret == OC_STACK_OK)
283             {
284                 std::cout << "Getting device information is done." << std::endl;
285             }
286             else
287             {
288                 std::cout << "Getting device information failed." << std::endl;
289             }
290
291             if(resourceURI == "/a/room")
292             {
293                 curResource = resource;
294                 // Call a local function which will internally invoke get API on the resource pointer
295                 getRoomRepresentation(resource, BATCH_INTERFACE, onGet);
296             }
297         }
298         else
299         {
300             // Resource is invalid
301             std::cout << "Resource is invalid" << std::endl;
302         }
303
304     }
305     catch(std::exception& e)
306     {
307         std::cerr << "Exception caught in Found Resource: "<< e.what() <<std::endl;
308     }
309 }
310
311 int main(int argc, char* argv[]) {
312
313     std::ostringstream requestURI;
314
315     OCConnectivityType connectivityType = CT_ADAPTER_IP;
316     if(argc == 2)
317     {
318         try
319         {
320             std::size_t inputValLen;
321             int optionSelected = std::stoi(argv[1], &inputValLen);
322
323             if(inputValLen == strlen(argv[1]))
324             {
325                 if(optionSelected == 0)
326                 {
327                     std::cout << "Using IP."<< std::endl;
328                     connectivityType = CT_ADAPTER_IP;
329                 }
330                 else
331                 {
332                     std::cout << "Invalid connectivity type selected. Using default IP"<< std::endl;
333                 }
334             }
335             else
336             {
337                 std::cout << "Invalid connectivity type selected. Using default IP" << std::endl;
338             }
339         }
340         catch(std::exception&)
341         {
342             std::cout << "Invalid input argument. Using IP as connectivity type" << std::endl;
343         }
344     }
345     else
346     {
347         std::cout << "Default input argument. Using IP as Default connectivity type" << std::endl;
348         printUsage();
349     }
350
351     // Create PlatformConfig object
352     PlatformConfig cfg {
353         OC::ServiceType::InProc,
354         OC::ModeType::Client,
355         "0.0.0.0",
356         0,
357         OC::QualityOfService::LowQos
358     };
359
360     OCPlatform::Configure(cfg);
361
362     try
363     {
364         // Find all resources
365         requestURI << OC_RSRVD_WELL_KNOWN_URI;
366
367         OCPlatform::findResource("", requestURI.str(), connectivityType, &foundResource);
368         std::cout<< "Finding Resource... " <<std::endl;
369
370         // A condition variable will free the mutex it is given, then do a non-
371         // intensive block until 'notify' is called on it.  In this case, since we
372         // don't ever call cv.notify, this should be a non-processor intensive version
373         // of while(true);
374         std::mutex blocker;
375         std::condition_variable cv;
376         std::unique_lock<std::mutex> lock(blocker);
377         cv.wait(lock);
378
379     }catch(OCException& e)
380     {
381         oclog() << "Exception in main: "<< e.what();
382     }
383
384     return 0;
385 }
386
387