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