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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 /// The purpose of this server is to simulate a refridgerator that contains a device resource for
22 /// its description, a light resource for the internal light, and 2 door resources for the purpose
23 /// of representing the doors attached to this fridge. This is used by the fridgeclient to
24 /// demonstrate using std::bind to attach to instances of a class as well as using
25 /// constructResourceObject
32 #include "OCPlatform.h"
36 namespace PH = std::placeholders;
38 // Option ID for API version and client token
39 const uint16_t API_VERSION = 2048;
40 const uint16_t TOKEN = 3000;
42 // Setting API version and token (shared out of band with client)
43 // This assumes the fact that this server responds
44 // only with a server with below version and token
45 const std::string FRIDGE_CLIENT_API_VERSION = "v.1.0";
46 const std::string FRIDGE_CLIENT_TOKEN = "21ae43gf";
51 OCResourceHandle m_resourceHandle;
52 OCRepresentation m_rep;
53 virtual OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request,
54 std::shared_ptr<OCResourceResponse> response)=0;
57 class DeviceResource : public Resource
63 std::string resourceURI = "/device";
64 std::string resourceTypeName = "intel.fridge";
65 std::string resourceInterface = DEFAULT_INTERFACE;
66 EntityHandler cb = std::bind(&DeviceResource::entityHandler, this,PH::_1, PH::_2);
68 EntityHandler defaultEH = std::bind(&DeviceResource::defaultEntityHandler, this,
71 std::cout << "Setting device default entity handler\n";
72 OCPlatform::setDefaultDeviceEntityHandler(defaultEH);
74 uint8_t resourceProperty = OC_DISCOVERABLE;
75 OCStackResult result = OCPlatform::registerResource(m_resourceHandle,
82 if(OC_STACK_OK != result)
84 throw std::runtime_error(
85 std::string("Device Resource failed to start")+std::to_string(result));
89 OCRepresentation get()
91 m_rep.setValue("device_name", std::string("Intel Powered 2 door, 1 light refridgerator"));
95 void deleteDeviceResource()
97 OCStackResult result = OCPlatform::unregisterResource(m_resourceHandle);
98 if(OC_STACK_OK != result)
100 throw std::runtime_error(
101 std::string("Device Resource failed to unregister/delete") + std::to_string(result));
105 std::string m_modelName;
107 virtual OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request,
108 std::shared_ptr<OCResourceResponse> response)
112 // Get the header options from the request
113 HeaderOptions headerOptions = request->getHeaderOptions();
114 std::string clientAPIVersion;
115 std::string clientToken;
117 // Search the header options map and look for API version and Client token
118 for (auto it = headerOptions.begin(); it != headerOptions.end(); ++it)
120 uint16_t optionID = it->getOptionID();
121 if(optionID == API_VERSION)
123 clientAPIVersion = it->getOptionData();
124 std::cout << " Client API version: " << clientAPIVersion << std::endl;
126 else if(optionID == TOKEN)
128 clientToken = it->getOptionData();
129 std::cout << " Client token: " << clientToken << std::endl;
133 std::cout << " Invalid header option " << std::endl;
137 // In this case Server entity handler verifies API version
138 // and client token. If they are valid, client requests are handled.
139 if(clientAPIVersion == FRIDGE_CLIENT_API_VERSION && clientToken == FRIDGE_CLIENT_TOKEN)
141 HeaderOptions serverHeaderOptions;
144 // Set API version from server side
145 HeaderOption::OCHeaderOption apiVersion(API_VERSION, FRIDGE_CLIENT_API_VERSION);
146 serverHeaderOptions.push_back(apiVersion);
148 catch(OCException& e)
150 std::cout << "Error creating HeaderOption in server: " << e.what() << std::endl;
153 if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
155 if(request->getRequestType() == "GET")
159 std::cout<<"DeviceResource Get Request"<<std::endl;
160 response->setErrorCode(200);
161 response->setHeaderOptions(serverHeaderOptions);
162 response->setResourceRepresentation(get(), "");
165 if(request->getRequestType() == "DELETE")
169 std::cout<<"DeviceResource Delete Request"<<std::endl;
170 deleteDeviceResource();
171 response->setErrorCode(200);
172 response->setHeaderOptions(serverHeaderOptions);
177 std::cout <<"DeviceResource unsupported request type "
178 << request->getRequestType() << std::endl;
183 std::cout << "DeviceResource unsupported request flag" <<std::endl;
188 std::cout << "Unsupported/invalid header options/values" << std::endl;
195 virtual OCEntityHandlerResult defaultEntityHandler(std::shared_ptr<OCResourceRequest> request,
196 std::shared_ptr<OCResourceResponse> response)
200 std::cout << "In Default Entity Handler, uri received: "
201 << request->getResourceUri() << std::endl;
203 if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
205 if(request->getRequestType() == "GET")
209 std::cout<<"Default Entity Handler: Get Request"<<std::endl;
210 response->setErrorCode(200);
211 response->setResourceRepresentation(get(), "");
216 std::cout <<"Default Entity Handler: unsupported request type "
217 << request->getRequestType() << std::endl;
222 std::cout << "Default Entity Handler: unsupported request flag" <<std::endl;
231 class LightResource : public Resource
236 std::string resourceURI = "/light";
237 std::string resourceTypeName = "intel.fridge.light";
238 std::string resourceInterface = DEFAULT_INTERFACE;
239 EntityHandler cb = std::bind(&LightResource::entityHandler, this,PH::_1, PH::_2);
240 uint8_t resourceProperty = 0;
241 OCStackResult result = OCPlatform::registerResource(m_resourceHandle,
248 if(OC_STACK_OK != result)
250 throw std::runtime_error(
251 std::string("Light Resource failed to start")+std::to_string(result));
255 OCRepresentation get()
257 m_rep.setValue("on", m_isOn);
261 void put(OCRepresentation rep)
263 rep.getValue("on", m_isOn);
268 virtual OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request,
269 std::shared_ptr<OCResourceResponse> response)
273 std::cout << "In entity handler for Light, URI is : "
274 << request->getResourceUri() << std::endl;
276 if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
278 if(request->getRequestType() == "GET")
282 std::cout<<"Light Get Request"<<std::endl;
283 response->setErrorCode(200);
284 response->setResourceRepresentation(get(), "");
287 else if(request->getRequestType() == "PUT")
291 std::cout <<"Light Put Request"<<std::endl;
292 put(request->getResourceRepresentation());
294 response->setErrorCode(200);
295 response->setResourceRepresentation(get(),"");
300 std::cout << "Light unsupported request type"
301 << request->getRequestType() << std::endl;
306 std::cout << "Light unsupported request flag" <<std::endl;
314 class DoorResource : public Resource
317 DoorResource(const std::string& side):m_side(side)
320 std::string resourceURI = "/door/"+ side;
321 std::string resourceTypeName = "intel.fridge.door";
322 std::string resourceInterface = DEFAULT_INTERFACE;
323 EntityHandler cb = std::bind(&DoorResource::entityHandler, this,PH::_1, PH::_2);
325 uint8_t resourceProperty = 0;
326 OCStackResult result = OCPlatform::registerResource(m_resourceHandle,
333 if(OC_STACK_OK != result)
335 throw std::runtime_error(
336 std::string("Door Resource failed to start")+std::to_string(result));
341 OCRepresentation get()
343 m_rep.setValue("open", m_isOpen);
344 m_rep.setValue("side", m_side);
348 void put(OCRepresentation rep)
350 rep.getValue("open", m_isOpen);
351 // Note, we won't let the user change the door side!
356 virtual OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request,
357 std::shared_ptr<OCResourceResponse> response)
359 std::cout << "EH of door invoked " << std::endl;
362 std::cout << "In entity handler for Door, URI is : "
363 << request->getResourceUri() << std::endl;
365 if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
367 if(request->getRequestType() == "GET")
371 // note that we know the side because std::bind gives us the
372 // appropriate object
373 std::cout<<m_side << " Door Get Request"<<std::endl;
374 response->setErrorCode(200);
375 response->setResourceRepresentation(get(), "");
378 else if(request->getRequestType() == "PUT")
382 std::cout <<m_side <<" Door Put Request"<<std::endl;
383 put(request->getResourceRepresentation());
384 response->setErrorCode(200);
385 response->setResourceRepresentation(get(),"");
390 std::cout <<m_side<<" Door unsupported request type "
391 << request->getRequestType() << std::endl;
396 std::cout << "Door unsupported request flag" <<std::endl;
417 LightResource m_light;
418 DeviceResource m_device;
419 DoorResource m_leftdoor;
420 DoorResource m_rightdoor;
429 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
430 0, // Uses randomly available port
431 QualityOfService::LowQos
434 OCPlatform::Configure(cfg);
437 // we will keep the server alive for at most 30 minutes
438 std::this_thread::sleep_for(std::chrono::minutes(30));