1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 /// This sample shows how one could create a resource (collection) with children.
28 #include <condition_variable>
30 #include "OCPlatform.h"
37 // Forward declaring the entityHandler (room)
38 OCEntityHandlerResult entityHandlerRoom(std::shared_ptr<OCResourceRequest> request);
39 OCEntityHandlerResult entityHandlerLight(std::shared_ptr<OCResourceRequest> request);
40 OCEntityHandlerResult entityHandlerFan(std::shared_ptr<OCResourceRequest> request);
42 /// Specifies whether default collection entity handler is used or not
43 bool useDefaultCollectionEH = false;
50 std::string m_roomUri;
51 std::string m_roomName;
52 std::vector<std::string> m_roomTypes;
53 std::vector<std::string> m_roomInterfaces;
54 OCResourceHandle m_roomHandle;
55 OCRepresentation m_roomRep;
60 std::string m_lightUri;
61 std::vector<std::string> m_lightTypes;
62 std::vector<std::string> m_lightInterfaces;
63 OCResourceHandle m_lightHandle;
64 OCRepresentation m_lightRep;
70 std::vector<std::string> m_fanTypes;
71 std::vector<std::string> m_fanInterfaces;
72 OCResourceHandle m_fanHandle;
73 OCRepresentation m_fanRep;
77 RoomResource(): m_roomName("John's Room"), m_lightState(false),
78 m_lightColor(0), m_fanState(false), m_fanSpeed(0)
80 m_lightUri = "/a/light"; // URI of the resource
81 m_lightTypes.push_back("core.light"); // resource type name. In this case, it is light
82 m_lightInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
84 m_lightRep.setUri(m_lightUri);
85 m_lightRep.setResourceTypes(m_lightTypes);
86 m_lightRep.setResourceInterfaces(m_lightInterfaces);
87 m_lightRep.setValue("state", m_lightState);
88 m_lightRep.setValue("color", m_lightColor);
90 m_fanUri = "/a/fan"; // URI of the resource
91 m_fanTypes.push_back("core.fan"); // resource type name. In this case, it is light
92 m_fanInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
94 m_fanRep.setUri(m_fanUri);
95 m_fanRep.setResourceTypes(m_fanTypes);
96 m_fanRep.setResourceInterfaces(m_fanInterfaces);
97 m_fanRep.setValue("state", m_fanState);
98 m_fanRep.setValue("speed", m_fanSpeed);
100 m_roomUri = "/a/room"; // URI of the resource
101 m_roomTypes.push_back("core.room"); // resource type name. In this case, it is light
102 m_roomInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
103 m_roomInterfaces.push_back(BATCH_INTERFACE); // resource interface.
104 m_roomInterfaces.push_back(LINK_INTERFACE); // resource interface.
105 m_roomRep.setValue("name", m_roomName);
106 m_roomRep.setUri(m_roomUri);
107 m_roomRep.setResourceTypes(m_roomTypes);
108 m_roomRep.setResourceInterfaces(m_roomInterfaces);
111 /// This function internally calls registerResource API.
112 void createResources()
114 // This function internally creates and registers the resource.
115 using namespace OC::OCPlatform;
116 OCStackResult result = OC_STACK_ERROR;
118 // Based on the case, we will use default collection EH (by passing NULL in entity handler
119 // parameter) or use application entity handler.
120 if(useDefaultCollectionEH)
122 result = registerResource(
123 m_roomHandle, m_roomUri, m_roomTypes[0],
124 m_roomInterfaces[0], NULL,
125 OC_DISCOVERABLE | OC_OBSERVABLE);
129 result = registerResource(
130 m_roomHandle, m_roomUri, m_roomTypes[0],
131 m_roomInterfaces[0], entityHandlerRoom,
132 OC_DISCOVERABLE | OC_OBSERVABLE);
135 if (OC_STACK_OK != result)
137 cout << "Resource creation (room) was unsuccessful\n";
140 result = bindInterfaceToResource(m_roomHandle, m_roomInterfaces[1]);
141 if (OC_STACK_OK != result)
143 cout << "Binding TypeName to Resource was unsuccessful\n";
146 result = bindInterfaceToResource(m_roomHandle, m_roomInterfaces[2]);
147 if (OC_STACK_OK != result)
149 cout << "Binding TypeName to Resource was unsuccessful\n";
152 result = registerResource(m_lightHandle, m_lightUri, m_lightTypes[0],
153 m_lightInterfaces[0], entityHandlerLight,
154 OC_DISCOVERABLE | OC_OBSERVABLE);
156 if (OC_STACK_OK != result)
158 cout << "Resource creation (light) was unsuccessful\n";
161 result = registerResource(m_fanHandle, m_fanUri, m_fanTypes[0],
162 m_fanInterfaces[0], entityHandlerFan,
163 OC_DISCOVERABLE | OC_OBSERVABLE);
165 if (OC_STACK_OK != result)
167 cout << "Resource creation (fan) was unsuccessful\n";
170 result = bindResource(m_roomHandle, m_lightHandle);
171 if (OC_STACK_OK != result)
173 cout << "Binding fan resource to room was unsuccessful\n";
176 result = bindResource(m_roomHandle, m_fanHandle);
177 if (OC_STACK_OK != result)
179 cout << "Binding light resource to room was unsuccessful\n";
184 void setLightRepresentation(OCRepresentation& rep)
186 bool tempState = false;
189 // If both entries exist
190 if(rep.getValue("state", tempState) && rep.getValue("color", tempColor))
192 m_lightState = tempState;
193 m_lightColor= tempColor;
195 cout << "\t\t\t\t" << "state: " << m_lightState << endl;
196 cout << "\t\t\t\t" << "color: " << m_lightColor << endl;
200 void setFanRepresentation(OCRepresentation& rep)
202 bool tempState = false;
205 // If both entries exist
206 if(rep.getValue("state", tempState) && rep.getValue("speed", tempSpeed))
208 m_fanState = tempState;
209 m_fanSpeed = tempSpeed;
211 cout << "\t\t\t\t" << "state: " << m_fanState << endl;
212 cout << "\t\t\t\t" << "speed: " << m_fanSpeed << endl;
217 OCRepresentation getLightRepresentation()
219 m_lightRep.setValue("state", m_lightState);
220 m_lightRep.setValue("color", m_lightColor);
225 OCRepresentation getFanRepresentation()
227 m_fanRep.setValue("state", m_fanState);
228 m_fanRep.setValue("speed", m_fanSpeed);
232 OCRepresentation getRoomRepresentation(void)
234 m_roomRep.clearChildren();
236 m_roomRep.addChild(getLightRepresentation());
237 m_roomRep.addChild(getFanRepresentation());
243 // Create the instance of the resource class (in this case instance of class 'RoomResource').
244 RoomResource myRoomResource;
246 OCStackResult sendRoomResponse(std::shared_ptr<OCResourceRequest> pRequest)
248 auto pResponse = std::make_shared<OC::OCResourceResponse>();
249 pResponse->setRequestHandle(pRequest->getRequestHandle());
250 pResponse->setResourceHandle(pRequest->getResourceHandle());
252 // Check for query params (if any)
253 QueryParamsMap queryParamsMap = pRequest->getQueryParameters();
255 cout << "\t\t\tquery params: \n";
256 for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
258 cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
261 OCRepresentation rep;
262 rep = myRoomResource.getRoomRepresentation();
264 auto findRes = queryParamsMap.find("if");
266 if(findRes != queryParamsMap.end())
268 pResponse->setResourceRepresentation(rep, findRes->second);
272 pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
275 pResponse->setErrorCode(200);
276 pResponse->setResponseResult(OC_EH_OK);
278 return OCPlatform::sendResponse(pResponse);
281 // This function prepares a response for any incoming request to Light resource.
282 bool prepareLightResponse(std::shared_ptr<OCResourceRequest> request)
284 cout << "\tIn Server CPP (Light) prepareLightResponse:\n";
288 // Get the request type and request flag
289 std::string requestType = request->getRequestType();
290 int requestFlag = request->getRequestHandlerFlag();
292 if(requestFlag == RequestHandlerFlag::InitFlag)
294 cout << "\t\trequestFlag : Init\n";
296 // entity handler to perform resource initialization operations
298 else if(requestFlag == RequestHandlerFlag::RequestFlag)
300 cout << "\t\trequestFlag : Request\n";
302 // If the request type is GET
303 if(requestType == "GET")
305 cout << "\t\t\trequestType : GET\n";
306 // GET operations are directly handled while sending the response
307 // in the sendLightResponse function
310 else if(requestType == "PUT")
312 cout << "\t\t\trequestType : PUT\n";
313 OCRepresentation rep = request->getResourceRepresentation();
315 // Do related operations related to PUT request
316 myRoomResource.setLightRepresentation(rep);
319 else if(requestType == "POST")
321 // POST request operations
323 else if(requestType == "DELETE")
325 // DELETE request operations
328 else if(requestFlag == RequestHandlerFlag::ObserverFlag)
330 cout << "\t\trequestFlag : Observer\n";
335 std::cout << "Request invalid" << std::endl;
341 // This function prepares a response for any incoming request to Fan resource.
342 bool prepareFanResponse(std::shared_ptr<OCResourceRequest> request)
344 cout << "\tIn Server CPP (Fan) prepareFanResponse:\n";
349 // Get the request type and request flag
350 std::string requestType = request->getRequestType();
351 int requestFlag = request->getRequestHandlerFlag();
353 if(requestFlag == RequestHandlerFlag::InitFlag)
355 cout << "\t\trequestFlag : Init\n";
357 // entity handler to perform resource initialization operations
359 else if(requestFlag == RequestHandlerFlag::RequestFlag)
361 cout << "\t\trequestFlag : Request\n";
363 // If the request type is GET
364 if(requestType == "GET")
366 cout << "\t\t\trequestType : GET\n";
367 // GET operations are directly handled while sending the response
368 // in the sendLightResponse function
371 else if(requestType == "PUT")
373 cout << "\t\t\trequestType : PUT\n";
375 OCRepresentation rep = request->getResourceRepresentation();
377 // Do related operations related to PUT request
378 myRoomResource.setFanRepresentation(rep);
381 else if(requestType == "POST")
383 // POST request operations
385 else if(requestType == "DELETE")
387 // DELETE request operations
390 else if(requestFlag == RequestHandlerFlag::ObserverFlag)
392 cout << "\t\trequestFlag : Observer\n";
397 std::cout << "Request invalid" << std::endl;
403 OCEntityHandlerResult entityHandlerRoom(std::shared_ptr<OCResourceRequest> request)
405 cout << "\tIn Server CPP entity handler:\n";
406 OCEntityHandlerResult ehResult = OC_EH_ERROR;
410 // Get the request type and request flag
411 std::string requestType = request->getRequestType();
412 int requestFlag = request->getRequestHandlerFlag();
414 if(requestFlag == RequestHandlerFlag::InitFlag)
416 cout << "\t\trequestFlag : Init\n";
418 // entity handler to perform resource initialization operations
420 else if(requestFlag == RequestHandlerFlag::RequestFlag)
422 cout << "\t\trequestFlag : Request\n";
424 // If the request type is GET
425 if(requestType == "GET")
427 cout << "\t\t\trequestType : GET\n";
428 if(OC_STACK_OK == sendRoomResponse(request))
433 else if(requestType == "PUT")
435 cout << "\t\t\trequestType : PUT\n";
436 // Call these functions to prepare the response for child resources and
437 // then send the final response using sendRoomResponse function
438 prepareLightResponse(request);
439 prepareFanResponse(request);
440 if(OC_STACK_OK == sendRoomResponse(request))
445 else if(requestType == "POST")
447 // POST request operations
449 else if(requestType == "DELETE")
451 // DELETE request operations
454 else if(requestFlag == RequestHandlerFlag::ObserverFlag)
456 cout << "\t\trequestFlag : Observer\n";
461 std::cout << "Request invalid" << std::endl;
467 OCStackResult sendLightResponse(std::shared_ptr<OCResourceRequest> pRequest)
469 auto pResponse = std::make_shared<OC::OCResourceResponse>();
470 pResponse->setRequestHandle(pRequest->getRequestHandle());
471 pResponse->setResourceHandle(pRequest->getResourceHandle());
472 pResponse->setResourceRepresentation(myRoomResource.getLightRepresentation());
473 pResponse->setErrorCode(200);
474 pResponse->setResponseResult(OC_EH_OK);
476 return OCPlatform::sendResponse(pResponse);
481 OCEntityHandlerResult entityHandlerLight(std::shared_ptr<OCResourceRequest> request)
483 cout << "\tIn Server CPP (Light) entity handler:\n";
484 OCEntityHandlerResult ehResult = OC_EH_ERROR;
486 if(prepareLightResponse(request))
488 if(OC_STACK_OK == sendLightResponse(request))
494 std::cout << "sendLightResponse failed." << std::endl;
499 std::cout << "PrepareLightResponse failed." << std::endl;
504 OCStackResult sendFanResponse(std::shared_ptr<OCResourceRequest> pRequest)
506 auto pResponse = std::make_shared<OC::OCResourceResponse>();
507 pResponse->setRequestHandle(pRequest->getRequestHandle());
508 pResponse->setResourceHandle(pRequest->getResourceHandle());
509 pResponse->setResourceRepresentation(myRoomResource.getFanRepresentation());
510 pResponse->setErrorCode(200);
511 pResponse->setResponseResult(OC_EH_OK);
513 return OCPlatform::sendResponse(pResponse);
517 OCEntityHandlerResult entityHandlerFan(std::shared_ptr<OCResourceRequest> request)
519 cout << "\tIn Server CPP (Fan) entity handler:\n";
520 OCEntityHandlerResult ehResult = OC_EH_ERROR;
521 if(prepareFanResponse(request))
523 if(OC_STACK_OK == sendFanResponse(request))
529 std::cout << "sendFanResponse failed." << std::endl;
534 std::cout << "PrepareFanResponse failed." << std::endl;
542 std::cout << std::endl;
543 std::cout << "Usage : roomserver <value>\n";
544 std::cout << "1 : Create room resource with default collection entity handler.\n";
545 std::cout << "2 : Create room resource with application collection entity handler.\n";
548 int main(int argc, char* argv[])
554 int value = atoi(argv[1]);
558 useDefaultCollectionEH = true;
570 // Create PlatformConfig object
572 OC::ServiceType::InProc,
573 OC::ModeType::Server,
574 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
575 0, // Uses randomly available port
576 OC::QualityOfService::LowQos
579 OCPlatform::Configure(cfg);
583 myRoomResource.createResources();
585 // A condition variable will free the mutex it is given, then do a non-
586 // intensive block until 'notify' is called on it. In this case, since we
587 // don't ever call cv.notify, this should be a non-processor intensive version
590 std::condition_variable cv;
591 std::unique_lock<std::mutex> lock(blocker);
597 std::cout << "Exception in main: " << e.what();
600 // No explicit call to stop the platform.
601 // When OCPlatform destructor is invoked, internally we do platform cleanup