c64528d0370e50399d384412e55692cd8f5ed411
[platform/upstream/iotivity.git] / resource / examples / garageclient.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 // garageclient.cpp is the client program for garageserver.cpp, which
22 // uses different representation in OCRepresention.
23
24 #include <string>
25 #include <cstdlib>
26 #include <mutex>
27 #include <condition_variable>
28 #include "OCPlatform.h"
29 #include "OCApi.h"
30
31 using namespace OC;
32
33 const int SUCCESS_RESPONSE = 0;
34 std::shared_ptr<OCResource> curResource;
35 std::mutex curResourceLock;
36
37 class Garage
38 {
39 public:
40
41     bool m_state;
42     std::string m_name;
43     std::vector<bool> m_lightStates;
44     std::vector<int> m_lightPowers;
45     OCRepresentation m_lightRep;
46     std::vector<OCRepresentation> m_reps;
47     std::vector<std::vector<int>> m_hingeStates;
48
49     Garage() : m_state(false), m_name("")
50     {
51     }
52 };
53
54 Garage myGarage;
55
56 void printRepresentation(const OCRepresentation& rep)
57 {
58
59         // Check if attribute "name" exists, and then getValue
60         if(rep.hasAttribute("name"))
61         {
62             myGarage.m_name = rep["name"];
63         }
64         std::cout << "\tname: " << myGarage.m_name << std::endl;
65
66         // You can directly try to get the value. this function
67         // return false if there is no attribute "state"
68         if(!rep.getValue("state", myGarage.m_state))
69         {
70             std::cout << "Attribute state doesn't exist in the representation\n";
71         }
72         std::cout << "\tstate: " << myGarage.m_state << std::endl;
73
74         OCRepresentation rep2 = rep;
75
76         std::cout << "Number of attributes in rep2: "
77                   << rep2.numberOfAttributes() << std::endl;
78
79         if(rep2.erase("name"))
80         {
81             std::cout << "attribute: name, was removed successfully from rep2.\n";
82         }
83
84         std::cout << "Number of attributes in rep2: "
85                   << rep2.numberOfAttributes() << std::endl;
86
87
88         if(rep.isNULL("nullAttribute"))
89         {
90             std::cout << "\tnullAttribute is null." << std::endl;
91         }
92         else
93         {
94             std::cout << "\tnullAttribute is not null." << std::endl;
95         }
96
97         myGarage.m_lightRep = rep["light"];
98
99         myGarage.m_lightStates = myGarage.m_lightRep["states"];
100         myGarage.m_lightPowers = myGarage.m_lightRep["powers"];
101
102         std::cout << "\tlightRep: states: ";
103
104         int first = 1;
105         for(auto state: myGarage.m_lightStates)
106         {
107             if(first)
108             {
109                 std::cout << state;
110                 first = 0;
111             }
112             else
113             {
114                 std::cout << "," << state;
115             }
116         }
117
118         std::cout << std::endl;
119         std::cout << "\tlightRep: powers: ";
120         first = 1;
121         for(auto power: myGarage.m_lightPowers)
122         {
123             if(first)
124             {
125                 std::cout << power;
126                 first = 0;
127             }
128             else
129             {
130                 std::cout << "," << power;
131             }
132         }
133         std::cout << std::endl;
134
135         // Get vector of representations
136         myGarage.m_reps = rep["reps"];
137
138         int ct = 0;
139         for(auto& rep : myGarage.m_reps)
140         {
141             for(auto& attribute : rep)
142             {
143                 std::cout<< "\treps["<<ct<<"]."<<attribute.attrname()<<":"
144                     << attribute.type()<<" with value " <<attribute.getValueToString() <<std::endl;
145             }
146             ++ct;
147         }
148
149         std::cout << "\tjson: " << rep["json"] << std::endl;
150         myGarage.m_hingeStates = rep["hinges"];
151
152         std::cout<< "\tHinge parameter is type: " << rep["hinges"].type() << " with depth "<<
153             rep["hinges"].depth() << " and a base type of "<< rep["hinges"].base_type()<<std::endl;
154
155
156 }
157 // callback handler on PUT request
158 void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
159 {
160     if(eCode == SUCCESS_RESPONSE)
161     {
162         std::cout << "PUT request was successful" << std::endl;
163
164         printRepresentation(rep);
165     }
166     else
167     {
168         std::cout << "onPut Response error: " << eCode << std::endl;
169         std::exit(-1);
170     }
171 }
172
173 // Local function to put a different state for this resource
174 void putLightRepresentation(std::shared_ptr<OCResource> resource)
175 {
176     if(resource)
177     {
178         OCRepresentation rep;
179
180         std::cout << "Putting light representation..."<<std::endl;
181
182         myGarage.m_state = true;
183
184         rep["state"] = myGarage.m_state;
185
186         // Create QueryParameters Map and add query params (if any)
187         QueryParamsMap queryParamsMap;
188
189         // Invoke resource's pit API with rep, query map and the callback parameter
190         resource->put(rep, queryParamsMap, &onPut);
191     }
192 }
193
194 // Callback handler on GET request
195 void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
196 {
197     if(eCode == SUCCESS_RESPONSE)
198     {
199         std::cout << "GET request was successful" << std::endl;
200         std::cout << "Resource URI: " << rep.getUri() << std::endl;
201
202         printRepresentation(rep);
203
204         putLightRepresentation(curResource);
205     }
206     else
207     {
208         std::cout << "onGET Response error: " << eCode << std::endl;
209         std::exit(-1);
210     }
211 }
212
213 // Local function to get representation of light resource
214 void getLightRepresentation(std::shared_ptr<OCResource> resource)
215 {
216     if(resource)
217     {
218         std::cout << "Getting Light Representation..."<<std::endl;
219         // Invoke resource's get API with the callback parameter
220
221         QueryParamsMap test;
222         resource->get(test, &onGet);
223     }
224 }
225
226 // Callback to found resources
227 void foundResource(std::shared_ptr<OCResource> resource)
228 {
229     std::lock_guard<std::mutex> lock(curResourceLock);
230     if(curResource)
231     {
232         std::cout << "Found another resource, ignoring"<<std::endl;
233         return;
234     }
235
236     std::string resourceURI;
237     std::string hostAddress;
238     try
239     {
240         // Do some operations with resource object.
241         if(resource)
242         {
243             std::cout<<"DISCOVERED Resource:"<<std::endl;
244             // Get the resource URI
245             resourceURI = resource->uri();
246             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
247
248             // Get the resource host address
249             hostAddress = resource->host();
250             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
251
252             // Get the resource types
253             std::cout << "\tList of resource types: " << std::endl;
254             for(auto &resourceTypes : resource->getResourceTypes())
255             {
256                 std::cout << "\t\t" << resourceTypes << std::endl;
257             }
258
259             // Get the resource interfaces
260             std::cout << "\tList of resource interfaces: " << std::endl;
261             for(auto &resourceInterfaces : resource->getResourceInterfaces())
262             {
263                 std::cout << "\t\t" << resourceInterfaces << std::endl;
264             }
265
266             if(resourceURI == "/a/garage")
267             {
268                 curResource = resource;
269                 // Call a local function which will internally invoke
270                 // get API on the resource pointer
271                 getLightRepresentation(resource);
272             }
273         }
274         else
275         {
276             // Resource is invalid
277             std::cout << "Resource is invalid" << std::endl;
278         }
279
280     }
281     catch(std::exception& e)
282     {
283         std::cerr << "Exception in foundResource: "<< e.what()<<std::endl;
284     }
285 }
286
287 int main(int argc, char* argv[]) {
288
289     std::ostringstream requestURI;
290
291     // Create PlatformConfig object
292     PlatformConfig cfg {
293         OC::ServiceType::InProc,
294         OC::ModeType::Client,
295         "0.0.0.0",
296         0,
297         OC::QualityOfService::LowQos
298     };
299
300     OCPlatform::Configure(cfg);
301     try
302     {
303         // Find all resources
304         requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=core.garage";
305
306         OCPlatform::findResource("", requestURI.str(),
307                 OC_ALL, &foundResource);
308
309         std::cout<< "Finding Resource... " <<std::endl;
310
311         // A condition variable will free the mutex it is given, then do a non-
312         // intensive block until 'notify' is called on it.  In this case, since we
313         // don't ever call cv.notify, this should be a non-processor intensive version
314         // of while(true);
315         std::mutex blocker;
316         std::condition_variable cv;
317         std::unique_lock<std::mutex> lock(blocker);
318         cv.wait(lock);
319     }
320     catch(OCException& e)
321     {
322         std::cerr << "Exception in GarageClient: "<<e.what();
323     }
324
325     return 0;
326 }
327
328