New APIs : hasAttribute, numberOfAttributes, erase in OCRepresentation.
[platform/upstream/iotivity.git] / examples / roomserver.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 ///
22 /// This sample shows how one could create a resource (collection) with children.
23 ///
24
25 #include <functional>
26
27 #include <pthread.h>
28
29 #include "OCPlatform.h"
30 #include "OCApi.h"
31
32 using namespace OC;
33 using namespace std;
34
35
36 // Forward declaring the entityHandler (room)
37 void entityHandlerRoom(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
38 void entityHandlerLight(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
39 void entityHandlerFan(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response);
40
41 class RoomResource
42 {
43 public:
44
45     // Room members
46     std::string m_roomUri;
47     std::vector<std::string> m_roomTypes;
48     std::vector<std::string> m_roomInterfaces;
49     OCResourceHandle m_roomHandle;
50     OCRepresentation m_roomRep;
51
52     // light members
53     bool m_lightState;
54     int m_lightColor;
55     std::string m_lightUri;
56     std::vector<std::string> m_lightTypes;
57     std::vector<std::string> m_lightInterfaces;
58     OCResourceHandle m_lightHandle;
59     OCRepresentation m_lightRep;
60
61     // fan members
62     bool m_fanState;
63     int m_fanSpeed;
64     std::string m_fanUri;
65     std::vector<std::string> m_fanTypes;
66     std::vector<std::string> m_fanInterfaces;
67     OCResourceHandle m_fanHandle;
68     OCRepresentation m_fanRep;
69
70 public:
71     /// Constructor
72     RoomResource(): m_lightState(false), m_lightColor(0), m_fanState(false), m_fanSpeed(0)
73     {
74         m_lightUri = "/a/light"; // URI of the resource
75         m_lightTypes.push_back("core.light"); // resource type name. In this case, it is light
76         m_lightInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
77
78         m_lightRep.setUri(m_lightUri);
79         m_lightRep.setResourceTypes(m_lightTypes);
80         m_lightRep.setResourceInterfaces(m_lightInterfaces);
81         m_lightRep.setValue("state", m_lightState);
82         m_lightRep.setValue("color", m_lightColor);
83
84         m_fanUri = "/a/fan"; // URI of the resource
85         m_fanTypes.push_back("core.fan"); // resource type name. In this case, it is light
86         m_fanInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
87
88         m_fanRep.setUri(m_fanUri);
89         m_fanRep.setResourceTypes(m_fanTypes);
90         m_fanRep.setResourceInterfaces(m_fanInterfaces);
91         m_fanRep.setValue("state", m_fanState);
92         m_fanRep.setValue("speed", m_fanSpeed);
93
94         m_roomUri = "/a/room"; // URI of the resource
95         m_roomTypes.push_back("core.room"); // resource type name. In this case, it is light
96         m_roomInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
97         m_roomInterfaces.push_back(BATCH_INTERFACE); // resource interface.
98         m_roomInterfaces.push_back(LINK_INTERFACE); // resource interface.
99         m_roomRep.setUri(m_roomUri);
100         m_roomRep.setResourceTypes(m_roomTypes);
101         m_roomRep.setResourceInterfaces(m_roomInterfaces);
102     }
103
104     /// This function internally calls registerResource API.
105     void createResources(OC::OCPlatform& platform)
106     {
107         // This will internally create and register the resource.
108         OCStackResult result = platform.registerResource(
109                                     m_roomHandle, m_roomUri, m_roomTypes[0],
110                                     m_roomInterfaces[0], NULL, //entityHandlerRoom,
111                                     OC_DISCOVERABLE | OC_OBSERVABLE
112                                   );
113
114         if (OC_STACK_OK != result)
115         {
116             cout << "Resource creation (room) was unsuccessful\n";
117         }
118
119         result = platform.bindInterfaceToResource(m_roomHandle, m_roomInterfaces[1]);
120         if (OC_STACK_OK != result)
121         {
122             cout << "Binding TypeName to Resource was unsuccessful\n";
123         }
124
125         result = platform.bindInterfaceToResource(m_roomHandle, m_roomInterfaces[2]);
126         if (OC_STACK_OK != result)
127         {
128             cout << "Binding TypeName to Resource was unsuccessful\n";
129         }
130
131         result = platform.registerResource(
132                                     m_lightHandle, m_lightUri, m_lightTypes[0],
133                                     m_lightInterfaces[0], entityHandlerLight,
134                                     OC_DISCOVERABLE | OC_OBSERVABLE
135                                    );
136
137         if (OC_STACK_OK != result)
138         {
139             cout << "Resource creation (light) was unsuccessful\n";
140         }
141
142         result = platform.registerResource(
143                                     m_fanHandle, m_fanUri, m_fanTypes[0],
144                                     m_fanInterfaces[0], entityHandlerFan,
145                                     OC_DISCOVERABLE | OC_OBSERVABLE
146                                    );
147
148         if (OC_STACK_OK != result)
149         {
150             cout << "Resource creation (fan) was unsuccessful\n";
151         }
152
153         result = platform.bindResource(m_roomHandle, m_lightHandle);
154         if (OC_STACK_OK != result)
155         {
156             cout << "Binding fan resource to room was unsuccessful\n";
157         }
158
159         result = platform.bindResource(m_roomHandle, m_fanHandle);
160         if (OC_STACK_OK != result)
161         {
162             cout << "Binding light resource to room was unsuccessful\n";
163         }
164
165     }
166
167     void setLightRepresentation(OCRepresentation& rep)
168     {
169         bool tempState = false;
170         int tempColor = 0;
171
172         // If both entries exist
173         if(rep.getValue("state", tempState) && rep.getValue("color", tempColor))
174         {
175             m_lightState = tempState;
176             m_lightColor= tempColor;
177
178             cout << "\t\t\t\t" << "state: " << m_lightState << endl;
179             cout << "\t\t\t\t" << "color: " << m_lightColor << endl;
180         }
181     }
182
183     void setFanRepresentation(OCRepresentation& rep)
184     {
185         bool tempState = false;
186         int tempSpeed = 0;
187
188         // If both entries exist
189         if(rep.getValue("state", tempState) && rep.getValue("speed", tempSpeed))
190         {
191             m_fanState = tempState;
192             m_fanSpeed = tempSpeed;
193
194             cout << "\t\t\t\t" << "state: " << m_fanState << endl;
195             cout << "\t\t\t\t" << "speed: " << m_fanSpeed << endl;
196         }
197     }
198
199
200     OCRepresentation getLightRepresentation()
201     {
202         m_lightRep.setValue("state", m_lightState);
203         m_lightRep.setValue("color", m_lightColor);
204
205         return m_lightRep;
206     }
207
208     OCRepresentation getFanRepresentation()
209     {
210         m_fanRep.setValue("state", m_fanState);
211         m_fanRep.setValue("speed", m_fanSpeed);
212         return m_fanRep;
213     }
214
215     OCRepresentation getRoomRepresentation(void)
216     {
217         std::vector<OCRepresentation> children;
218
219         OCRepresentation light = getLightRepresentation();
220         children.push_back(light);
221
222         OCRepresentation fan = getFanRepresentation();
223         children.push_back(fan);
224
225         m_roomRep.setChildren(children);
226
227         return m_roomRep;
228     }
229
230 };
231
232 // Create the instance of the resource class (in this case instance of class 'RoomResource').
233 RoomResource myRoomResource;
234
235 void entityHandlerRoom(std::shared_ptr<OCResourceRequest> request,
236                        std::shared_ptr<OCResourceResponse> response)
237 {
238     cout << "\tIn Server CPP entity handler:\n";
239
240     if(request)
241     {
242         // Get the request type and request flag
243         std::string requestType = request->getRequestType();
244         int requestFlag = request->getRequestHandlerFlag();
245
246         if(requestFlag == RequestHandlerFlag::InitFlag)
247         {
248             cout << "\t\trequestFlag : Init\n";
249
250             // entity handler to perform resource initialization operations
251         }
252         else if(requestFlag == RequestHandlerFlag::RequestFlag)
253         {
254             cout << "\t\trequestFlag : Request\n";
255
256             // If the request type is GET
257             if(requestType == "GET")
258             {
259                 cout << "\t\t\trequestType : GET\n";
260
261                 // Check for query params (if any)
262                 QueryParamsMap queryParamsMap = request->getQueryParameters();
263
264                 cout << "\t\t\tquery params: \n";
265                 for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
266                 {
267                     cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
268                 }
269
270                 OCRepresentation rep;
271                 rep = myRoomResource.getRoomRepresentation();
272
273                 if(response)
274                 {
275                     // TODO Error Code
276                     response->setErrorCode(200);
277
278                     auto findRes = queryParamsMap.find("if");
279
280                     if(findRes != queryParamsMap.end())
281                     {
282                         response->setResourceRepresentation(rep, findRes->second);
283                     }
284                     else
285                     {
286                         response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
287                     }
288                 }
289
290             }
291             else if(requestType == "PUT")
292             {
293                 cout << "\t\t\trequestType : PUT\n";
294
295                 entityHandlerLight(request, response);
296                 entityHandlerFan(request, response);
297
298                 if(response)
299                 {
300                     response->setResourceRepresentation(myRoomResource.getRoomRepresentation());
301                 }
302             }
303             else if(requestType == "POST")
304             {
305                 // POST request operations
306             }
307             else if(requestType == "DELETE")
308             {
309                 // DELETE request operations
310             }
311         }
312         else if(requestFlag == RequestHandlerFlag::ObserverFlag)
313         {
314             cout << "\t\trequestFlag : Observer\n";
315         }
316     }
317     else
318     {
319         std::cout << "Request invalid" << std::endl;
320     }
321 }
322
323 void entityHandlerLight(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
324 {
325     cout << "\tIn Server CPP (Light) entity handler:\n";
326
327     if(request)
328     {
329         // Get the request type and request flag
330         std::string requestType = request->getRequestType();
331         int requestFlag = request->getRequestHandlerFlag();
332
333         if(requestFlag == RequestHandlerFlag::InitFlag)
334         {
335             cout << "\t\trequestFlag : Init\n";
336
337             // entity handler to perform resource initialization operations
338         }
339         else if(requestFlag == RequestHandlerFlag::RequestFlag)
340         {
341             cout << "\t\trequestFlag : Request\n";
342
343             // If the request type is GET
344             if(requestType == "GET")
345             {
346                 cout << "\t\t\trequestType : GET\n";
347
348                 if(response)
349                 {
350                     // TODO Error Code
351                     response->setErrorCode(200);
352                     response->setResourceRepresentation(myRoomResource.getLightRepresentation());
353                 }
354
355             }
356             else if(requestType == "PUT")
357             {
358                 cout << "\t\t\trequestType : PUT\n";
359
360                 OCRepresentation rep = request->getResourceRepresentation();
361
362                 // Do related operations related to PUT request
363                 myRoomResource.setLightRepresentation(rep);
364
365                 if(response)
366                 {
367                     // TODO Error Code
368                     response->setErrorCode(200);
369                     response->setResourceRepresentation(myRoomResource.getLightRepresentation());
370                 }
371
372             }
373             else if(requestType == "POST")
374             {
375                 // POST request operations
376             }
377             else if(requestType == "DELETE")
378             {
379                 // DELETE request operations
380             }
381         }
382         else if(requestFlag == RequestHandlerFlag::ObserverFlag)
383         {
384             cout << "\t\trequestFlag : Observer\n";
385         }
386     }
387     else
388     {
389         std::cout << "Request invalid" << std::endl;
390     }
391 }
392
393 void entityHandlerFan(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
394 {
395     cout << "\tIn Server CPP (Fan) entity handler:\n";
396
397     if(request)
398     {
399         // Get the request type and request flag
400         std::string requestType = request->getRequestType();
401         int requestFlag = request->getRequestHandlerFlag();
402
403         if(requestFlag == RequestHandlerFlag::InitFlag)
404         {
405             cout << "\t\trequestFlag : Init\n";
406
407             // entity handler to perform resource initialization operations
408         }
409         else if(requestFlag == RequestHandlerFlag::RequestFlag)
410         {
411             cout << "\t\trequestFlag : Request\n";
412
413             // If the request type is GET
414             if(requestType == "GET")
415             {
416                 cout << "\t\t\trequestType : GET\n";
417
418                 if(response)
419                 {
420                     // TODO Error Code
421                     response->setErrorCode(200);
422
423                     response->setResourceRepresentation(myRoomResource.getFanRepresentation());
424                 }
425
426             }
427             else if(requestType == "PUT")
428             {
429                 cout << "\t\t\trequestType : PUT\n";
430
431                 OCRepresentation rep = request->getResourceRepresentation();
432
433                 // Do related operations related to PUT request
434                 myRoomResource.setFanRepresentation(rep);
435
436                 if(response)
437                 {
438                     // TODO Error Code
439                     response->setErrorCode(200);
440                     response->setResourceRepresentation(myRoomResource.getFanRepresentation());
441                 }
442             }
443             else if(requestType == "POST")
444             {
445                 // POST request operations
446             }
447             else if(requestType == "DELETE")
448             {
449                 // DELETE request operations
450             }
451         }
452         else if(requestFlag == RequestHandlerFlag::ObserverFlag)
453         {
454             cout << "\t\trequestFlag : Observer\n";
455         }
456     }
457     else
458     {
459         std::cout << "Request invalid" << std::endl;
460     }
461 }
462
463 int main()
464 {
465     // Create PlatformConfig object
466     PlatformConfig cfg {
467         OC::ServiceType::InProc,
468         OC::ModeType::Server,
469         "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
470         0,         // Uses randomly available port
471         OC::QualityOfService::NonConfirmable
472     };
473
474     // Create a OCPlatform instance.
475     // Note: Platform creation is synchronous call.
476     try
477     {
478         OCPlatform platform(cfg);
479
480         // Invoke createResource function of class light.
481
482         myRoomResource.createResources(platform);
483
484         // Perform app tasks
485         while(true)
486         {
487             // some tasks
488         }
489     }
490     catch(OCException e)
491     {
492         std::cout << "Exception in main: " << e.what();
493     }
494
495     // No explicit call to stop the platform.
496     // When OCPlatform destructor is invoked, internally we do platform cleanup
497 }