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_roomHandle(nullptr), m_lightState(false),
78 m_lightColor(0),m_lightHandle(nullptr), m_fanState(false), m_fanSpeed(0),
81 m_lightUri = "/a/light"; // URI of the resource
82 m_lightTypes.push_back("core.light"); // resource type name. In this case, it is light
83 m_lightInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
85 m_lightRep.setUri(m_lightUri);
86 m_lightRep.setResourceTypes(m_lightTypes);
87 m_lightRep.setResourceInterfaces(m_lightInterfaces);
88 m_lightRep.setValue("state", m_lightState);
89 m_lightRep.setValue("color", m_lightColor);
91 m_fanUri = "/a/fan"; // URI of the resource
92 m_fanTypes.push_back("core.fan"); // resource type name. In this case, it is light
93 m_fanInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
95 m_fanRep.setUri(m_fanUri);
96 m_fanRep.setResourceTypes(m_fanTypes);
97 m_fanRep.setResourceInterfaces(m_fanInterfaces);
98 m_fanRep.setValue("state", m_fanState);
99 m_fanRep.setValue("speed", m_fanSpeed);
101 m_roomUri = "/a/room"; // URI of the resource
102 m_roomTypes.push_back("core.room"); // resource type name. In this case, it is light
103 m_roomInterfaces.push_back(DEFAULT_INTERFACE); // resource interface.
104 m_roomInterfaces.push_back(BATCH_INTERFACE); // resource interface.
105 m_roomInterfaces.push_back(LINK_INTERFACE); // resource interface.
106 m_roomRep.setValue("name", m_roomName);
107 m_roomRep.setUri(m_roomUri);
108 m_roomRep.setResourceTypes(m_roomTypes);
109 m_roomRep.setResourceInterfaces(m_roomInterfaces);
112 /// This function internally calls registerResource API.
113 void createResources()
115 // This function internally creates and registers the resource.
116 using namespace OC::OCPlatform;
117 OCStackResult result = OC_STACK_ERROR;
119 // Based on the case, we will use default collection EH (by passing NULL in entity handler
120 // parameter) or use application entity handler.
121 if(useDefaultCollectionEH)
123 result = registerResource(
124 m_roomHandle, m_roomUri, m_roomTypes[0],
125 m_roomInterfaces[0], NULL,
126 OC_DISCOVERABLE | OC_OBSERVABLE);
130 result = registerResource(
131 m_roomHandle, m_roomUri, m_roomTypes[0],
132 m_roomInterfaces[0], entityHandlerRoom,
133 OC_DISCOVERABLE | OC_OBSERVABLE);
136 if (OC_STACK_OK != result)
138 cout << "Resource creation (room) was unsuccessful\n";
141 result = bindInterfaceToResource(m_roomHandle, m_roomInterfaces[1]);
142 if (OC_STACK_OK != result)
144 cout << "Binding TypeName to Resource was unsuccessful\n";
147 result = bindInterfaceToResource(m_roomHandle, m_roomInterfaces[2]);
148 if (OC_STACK_OK != result)
150 cout << "Binding TypeName to Resource was unsuccessful\n";
153 result = registerResource(m_lightHandle, m_lightUri, m_lightTypes[0],
154 m_lightInterfaces[0], entityHandlerLight,
155 OC_DISCOVERABLE | OC_OBSERVABLE);
157 if (OC_STACK_OK != result)
159 cout << "Resource creation (light) was unsuccessful\n";
162 result = registerResource(m_fanHandle, m_fanUri, m_fanTypes[0],
163 m_fanInterfaces[0], entityHandlerFan,
164 OC_DISCOVERABLE | OC_OBSERVABLE);
166 if (OC_STACK_OK != result)
168 cout << "Resource creation (fan) was unsuccessful\n";
171 result = bindResource(m_roomHandle, m_lightHandle);
172 if (OC_STACK_OK != result)
174 cout << "Binding fan resource to room was unsuccessful\n";
177 result = bindResource(m_roomHandle, m_fanHandle);
178 if (OC_STACK_OK != result)
180 cout << "Binding light resource to room was unsuccessful\n";
185 void setLightRepresentation(OCRepresentation& rep)
187 bool tempState = false;
190 // If both entries exist
191 if(rep.getValue("state", tempState) && rep.getValue("color", tempColor))
193 m_lightState = tempState;
194 m_lightColor= tempColor;
196 cout << "\t\t\t\t" << "state: " << m_lightState << endl;
197 cout << "\t\t\t\t" << "color: " << m_lightColor << endl;
201 void setFanRepresentation(OCRepresentation& rep)
203 bool tempState = false;
206 // If both entries exist
207 if(rep.getValue("state", tempState) && rep.getValue("speed", tempSpeed))
209 m_fanState = tempState;
210 m_fanSpeed = tempSpeed;
212 cout << "\t\t\t\t" << "state: " << m_fanState << endl;
213 cout << "\t\t\t\t" << "speed: " << m_fanSpeed << endl;
218 OCRepresentation getLightRepresentation()
220 m_lightRep.setValue("state", m_lightState);
221 m_lightRep.setValue("color", m_lightColor);
226 OCRepresentation getFanRepresentation()
228 m_fanRep.setValue("state", m_fanState);
229 m_fanRep.setValue("speed", m_fanSpeed);
233 OCRepresentation getRoomRepresentation(void)
235 m_roomRep.clearChildren();
237 m_roomRep.addChild(getLightRepresentation());
238 m_roomRep.addChild(getFanRepresentation());
244 // Create the instance of the resource class (in this case instance of class 'RoomResource').
245 RoomResource myRoomResource;
247 OCStackResult sendRoomResponse(std::shared_ptr<OCResourceRequest> pRequest)
249 auto pResponse = std::make_shared<OC::OCResourceResponse>();
250 pResponse->setRequestHandle(pRequest->getRequestHandle());
251 pResponse->setResourceHandle(pRequest->getResourceHandle());
253 // Check for query params (if any)
254 QueryParamsMap queryParamsMap = pRequest->getQueryParameters();
256 cout << "\t\t\tquery params: \n";
257 for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
259 cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
262 OCRepresentation rep;
263 rep = myRoomResource.getRoomRepresentation();
265 auto findRes = queryParamsMap.find("if");
267 if(findRes != queryParamsMap.end())
269 pResponse->setResourceRepresentation(rep, findRes->second);
273 pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
276 pResponse->setErrorCode(200);
277 pResponse->setResponseResult(OC_EH_OK);
279 return OCPlatform::sendResponse(pResponse);
282 // This function prepares a response for any incoming request to Light resource.
283 bool prepareLightResponse(std::shared_ptr<OCResourceRequest> request)
285 cout << "\tIn Server CPP (Light) prepareLightResponse:\n";
289 // Get the request type and request flag
290 std::string requestType = request->getRequestType();
291 int requestFlag = request->getRequestHandlerFlag();
293 if(requestFlag == RequestHandlerFlag::RequestFlag)
295 cout << "\t\trequestFlag : Request\n";
297 // If the request type is GET
298 if(requestType == "GET")
300 cout << "\t\t\trequestType : GET\n";
301 // GET operations are directly handled while sending the response
302 // in the sendLightResponse function
305 else if(requestType == "PUT")
307 cout << "\t\t\trequestType : PUT\n";
308 OCRepresentation rep = request->getResourceRepresentation();
310 // Do related operations related to PUT request
311 myRoomResource.setLightRepresentation(rep);
314 else if(requestType == "POST")
316 // POST request operations
318 else if(requestType == "DELETE")
320 // DELETE request operations
323 else if(requestFlag == RequestHandlerFlag::ObserverFlag)
325 cout << "\t\trequestFlag : Observer\n";
330 std::cout << "Request invalid" << std::endl;
336 // This function prepares a response for any incoming request to Fan resource.
337 bool prepareFanResponse(std::shared_ptr<OCResourceRequest> request)
339 cout << "\tIn Server CPP (Fan) prepareFanResponse:\n";
344 // Get the request type and request flag
345 std::string requestType = request->getRequestType();
346 int requestFlag = request->getRequestHandlerFlag();
348 if(requestFlag == RequestHandlerFlag::RequestFlag)
350 cout << "\t\trequestFlag : Request\n";
352 // If the request type is GET
353 if(requestType == "GET")
355 cout << "\t\t\trequestType : GET\n";
356 // GET operations are directly handled while sending the response
357 // in the sendLightResponse function
360 else if(requestType == "PUT")
362 cout << "\t\t\trequestType : PUT\n";
364 OCRepresentation rep = request->getResourceRepresentation();
366 // Do related operations related to PUT request
367 myRoomResource.setFanRepresentation(rep);
370 else if(requestType == "POST")
372 // POST request operations
374 else if(requestType == "DELETE")
376 // DELETE request operations
379 else if(requestFlag == RequestHandlerFlag::ObserverFlag)
381 cout << "\t\trequestFlag : Observer\n";
386 std::cout << "Request invalid" << std::endl;
392 OCEntityHandlerResult entityHandlerRoom(std::shared_ptr<OCResourceRequest> request)
394 cout << "\tIn Server CPP entity handler:\n";
395 OCEntityHandlerResult ehResult = OC_EH_ERROR;
399 // Get the request type and request flag
400 std::string requestType = request->getRequestType();
401 int requestFlag = request->getRequestHandlerFlag();
403 if(requestFlag == RequestHandlerFlag::RequestFlag)
405 cout << "\t\trequestFlag : Request\n";
407 // If the request type is GET
408 if(requestType == "GET")
410 cout << "\t\t\trequestType : GET\n";
411 if(OC_STACK_OK == sendRoomResponse(request))
416 else if(requestType == "PUT")
418 cout << "\t\t\trequestType : PUT\n";
419 // Call these functions to prepare the response for child resources and
420 // then send the final response using sendRoomResponse function
421 prepareLightResponse(request);
422 prepareFanResponse(request);
423 if(OC_STACK_OK == sendRoomResponse(request))
428 else if(requestType == "POST")
430 // POST request operations
432 else if(requestType == "DELETE")
434 // DELETE request operations
437 else if(requestFlag == RequestHandlerFlag::ObserverFlag)
439 cout << "\t\trequestFlag : Observer\n";
444 std::cout << "Request invalid" << std::endl;
450 OCStackResult sendLightResponse(std::shared_ptr<OCResourceRequest> pRequest)
452 auto pResponse = std::make_shared<OC::OCResourceResponse>();
453 pResponse->setRequestHandle(pRequest->getRequestHandle());
454 pResponse->setResourceHandle(pRequest->getResourceHandle());
455 pResponse->setResourceRepresentation(myRoomResource.getLightRepresentation());
456 pResponse->setErrorCode(200);
457 pResponse->setResponseResult(OC_EH_OK);
459 return OCPlatform::sendResponse(pResponse);
464 OCEntityHandlerResult entityHandlerLight(std::shared_ptr<OCResourceRequest> request)
466 cout << "\tIn Server CPP (Light) entity handler:\n";
467 OCEntityHandlerResult ehResult = OC_EH_ERROR;
469 if(prepareLightResponse(request))
471 if(OC_STACK_OK == sendLightResponse(request))
477 std::cout << "sendLightResponse failed." << std::endl;
482 std::cout << "PrepareLightResponse failed." << std::endl;
487 OCStackResult sendFanResponse(std::shared_ptr<OCResourceRequest> pRequest)
489 auto pResponse = std::make_shared<OC::OCResourceResponse>();
490 pResponse->setRequestHandle(pRequest->getRequestHandle());
491 pResponse->setResourceHandle(pRequest->getResourceHandle());
492 pResponse->setResourceRepresentation(myRoomResource.getFanRepresentation());
493 pResponse->setErrorCode(200);
494 pResponse->setResponseResult(OC_EH_OK);
496 return OCPlatform::sendResponse(pResponse);
500 OCEntityHandlerResult entityHandlerFan(std::shared_ptr<OCResourceRequest> request)
502 cout << "\tIn Server CPP (Fan) entity handler:\n";
503 OCEntityHandlerResult ehResult = OC_EH_ERROR;
504 if(prepareFanResponse(request))
506 if(OC_STACK_OK == sendFanResponse(request))
512 std::cout << "sendFanResponse failed." << std::endl;
517 std::cout << "PrepareFanResponse failed." << std::endl;
525 std::cout << std::endl;
526 std::cout << "Usage : roomserver <value>\n";
527 std::cout << "1 : Create room resource with default collection entity handler.\n";
528 std::cout << "2 : Create room resource with application collection entity handler.\n";
531 int main(int argc, char* argv[])
537 int value = atoi(argv[1]);
541 useDefaultCollectionEH = true;
553 // Create PlatformConfig object
555 OC::ServiceType::InProc,
556 OC::ModeType::Server,
557 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
558 0, // Uses randomly available port
559 OC::QualityOfService::LowQos
562 OCPlatform::Configure(cfg);
566 myRoomResource.createResources();
568 // A condition variable will free the mutex it is given, then do a non-
569 // intensive block until 'notify' is called on it. In this case, since we
570 // don't ever call cv.notify, this should be a non-processor intensive version
573 std::condition_variable cv;
574 std::unique_lock<std::mutex> lock(blocker);
578 catch(OCException &e)
580 std::cout << "Exception in main: " << e.what();
583 // No explicit call to stop the platform.
584 // When OCPlatform destructor is invoked, internally we do platform cleanup