1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 // Copyright 2014 Samsung Electronics All Rights Reserved.
6 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
12 // http://www.apache.org/licenses/LICENSE-2.0
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
20 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 /// This sample provides steps to define an interface for a resource
24 /// (properties and methods) and host this resource on the server.
34 #include <condition_variable>
36 #include "OCPlatform.h"
41 namespace PH = std::placeholders;
44 void * ChangeLightRepresentation (void *param);
45 void * handleSlowResponse (void *param, std::shared_ptr<OCResourceRequest> pRequest);
47 // Specifies secure or non-secure
48 // false: non-secure resource
49 // true: secure resource
50 bool isSecure = false;
52 /// Specifies whether Entity handler is going to do slow response or not
53 bool isSlowResponse = false;
55 // Forward declaring the entityHandler
57 /// This class represents a single resource named 'lightResource'. This resource has
58 /// one simple attribute, power
64 /// Access this property from a TB client
66 std::string m_lightUri;
67 OCResourceHandle m_resourceHandle;
68 OCRepresentation m_lightRep;
73 :m_power(""), m_lightUri("/a/light") {
74 // Initialize representation
75 m_lightRep.setUri(m_lightUri);
77 m_lightRep.setValue("power", m_power);
80 /* Note that this does not need to be a member function: for classes you do not have
81 access to, you can accomplish this with a free function: */
83 /// This function internally calls registerResource API.
86 std::string resourceURI = m_lightUri; //URI of the resource
87 std::string resourceTypeName = "core.light"; //resource type name. In this case, it is light
88 std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
90 EntityHandler cb = std::bind(&LightResource::entityHandler, this,PH::_1);
92 // This will internally create and register the resource.
93 OCStackResult result = OCPlatform::registerResource(
94 m_resourceHandle, resourceURI, resourceTypeName,
95 resourceInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE);
97 if (OC_STACK_OK != result)
99 cout << "Resource creation was unsuccessful\n";
103 OCResourceHandle getHandle()
105 return m_resourceHandle;
108 // Puts representation.
109 // Gets values from the representation and
110 // updates the internal state
111 void put(OCRepresentation& rep)
114 if (rep.getValue("power", m_power))
116 cout << "\t\t\t\t" << "power: " << m_power << endl;
120 cout << "\t\t\t\t" << "power not found in the representation" << endl;
125 cout << e.what() << endl;
130 // Post representation.
131 // Post can create new resource or simply act like put.
132 // Gets values from the representation and
133 // updates the internal state
134 OCRepresentation post(OCRepresentation& rep)
141 // gets the updated representation.
142 // Updates the representation with latest internal state before
144 OCRepresentation get()
146 m_lightRep.setValue("power", m_power);
151 void addType(const std::string& type) const
153 OCStackResult result = OCPlatform::bindTypeToResource(m_resourceHandle, type);
154 if (OC_STACK_OK != result)
156 cout << "Binding TypeName to Resource was unsuccessful\n";
160 void addInterface(const std::string& interface) const
162 OCStackResult result = OCPlatform::bindInterfaceToResource(m_resourceHandle, interface);
163 if (OC_STACK_OK != result)
165 cout << "Binding TypeName to Resource was unsuccessful\n";
170 // This is just a sample implementation of entity handler.
171 // Entity handler can be implemented in several ways by the manufacturer
172 OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
174 cout << "\tIn Server CPP entity handler:\n";
175 OCEntityHandlerResult ehResult = OC_EH_ERROR;
178 // Get the request type and request flag
179 std::string requestType = request->getRequestType();
180 int requestFlag = request->getRequestHandlerFlag();
182 if(requestFlag & RequestHandlerFlag::RequestFlag)
184 cout << "\t\trequestFlag : Request\n";
185 auto pResponse = std::make_shared<OC::OCResourceResponse>();
186 pResponse->setRequestHandle(request->getRequestHandle());
187 pResponse->setResourceHandle(request->getResourceHandle());
189 // If the request type is GET
190 if(requestType == "GET")
192 cout << "\t\t\trequestType : GET\n";
193 if(isSlowResponse) // Slow response case
195 static int startedThread = 0;
198 std::thread t(handleSlowResponse, (void *)this, request);
202 ehResult = OC_EH_SLOW;
204 else // normal response case.
206 pResponse->setErrorCode(200);
207 pResponse->setResponseResult(OC_EH_OK);
208 pResponse->setResourceRepresentation(get());
209 if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
215 else if(requestType == "PUT")
217 cout << "\t\t\trequestType : PUT\n";
218 OCRepresentation rep = request->getResourceRepresentation();
220 // Do related operations related to PUT request
221 // Update the lightResource
223 pResponse->setErrorCode(200);
224 pResponse->setResponseResult(OC_EH_OK);
225 pResponse->setResourceRepresentation(get());
226 if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
231 else if(requestType == "POST")
233 cout << "\t\t\trequestType : POST\n";
235 OCRepresentation rep = request->getResourceRepresentation();
237 // Do related operations related to POST request
238 OCRepresentation rep_post = post(rep);
239 pResponse->setResourceRepresentation(rep_post);
240 pResponse->setErrorCode(200);
241 if(rep_post.hasAttribute("createduri"))
243 pResponse->setResponseResult(OC_EH_RESOURCE_CREATED);
244 pResponse->setNewResourceUri(rep_post.getValue<std::string>("createduri"));
247 if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
252 else if(requestType == "DELETE")
254 // DELETE request operations
260 std::cout << "Request invalid" << std::endl;
267 void * handleSlowResponse (void *param, std::shared_ptr<OCResourceRequest> pRequest)
269 // This function handles slow response case
270 LightResource* lightPtr = (LightResource*) param;
271 // Induce a case for slow response by using sleep
272 std::cout << "SLOW response" << std::endl;
275 auto pResponse = std::make_shared<OC::OCResourceResponse>();
276 pResponse->setRequestHandle(pRequest->getRequestHandle());
277 pResponse->setResourceHandle(pRequest->getResourceHandle());
278 pResponse->setResourceRepresentation(lightPtr->get());
279 pResponse->setErrorCode(200);
280 pResponse->setResponseResult(OC_EH_OK);
282 // Set the slow response flag back to false
283 isSlowResponse = false;
284 OCPlatform::sendResponse(pResponse);
289 int main(int /*argc*/, char** /*argv[]*/)
291 // Create PlatformConfig object
293 OC::ServiceType::InProc,
294 OC::ModeType::Server,
295 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
296 0, // Uses randomly available port
297 OC::QualityOfService::LowQos
300 OCPlatform::Configure(cfg);
303 // Create the instance of the resource class
304 // (in this case instance of class 'LightResource').
305 LightResource myLight;
307 // Invoke createResource function of class light.
308 myLight.createResource();
310 myLight.addType(std::string("core.brightlight"));
311 myLight.addInterface(std::string(LINK_INTERFACE));
313 // A condition variable will free the mutex it is given, then do a non-
314 // intensive block until 'notify' is called on it. In this case, since we
315 // don't ever call cv.notify, this should be a non-processor intensive version
318 std::condition_variable cv;
319 std::unique_lock<std::mutex> lock(blocker);
322 catch(OCException& e)
324 oclog() << "Exception in main: "<< e.what();
327 // No explicit call to stop the platform.
328 // When OCPlatform::destructor is invoked, internally we do platform cleanup