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.
31 #include <condition_variable>
33 #include "OCPlatform.h"
38 namespace PH = std::placeholders;
41 void * ChangeLightRepresentation(void *param);
42 void * handleSlowResponse(void *param, std::shared_ptr< OCResourceRequest > pRequest);
44 // Specifies secure or non-secure
45 // false: non-secure resource
46 // true: secure resource
47 bool isSecure = false;
49 /// Specifies whether Entity handler is going to do slow response or not
50 bool isSlowResponse = false;
52 // Forward declaring the entityHandler
54 /// This class represents a single resource named 'lightResource'. This resource has
55 /// two simple properties named 'state' and 'power'
61 /// Access this property from a TB client
63 std::string m_lightUri;
64 OCResourceHandle m_resourceHandle;
65 OCRepresentation m_lightRep;
70 m_power(""), m_lightUri("/a/light"), m_resourceHandle(0)
72 // Initialize representation
73 m_lightRep.setUri(m_lightUri);
75 m_lightRep.setValue("power", m_power);
78 /* Note that this does not need to be a member function: for classes you do not have
79 access to, you can accomplish this with a free function: */
81 /// This function internally calls registerResource API.
84 std::string resourceURI = m_lightUri; //URI of the resource
85 std::string resourceTypeName = "core.light"; //resource type name. In this case, it is light
86 std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
88 EntityHandler cb = std::bind(&LightResource::entityHandler, this, PH::_1);
90 // This will internally create and register the resource.
91 OCStackResult result = OCPlatform::registerResource(m_resourceHandle, resourceURI,
92 resourceTypeName, resourceInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE);
94 if (OC_STACK_OK != result)
96 cout << "Resource creation was unsuccessful\n";
100 cout << "Resource URI : " << resourceURI << endl;
101 cout << "\tResource Type Name : " << resourceTypeName << endl;
102 cout << "\tResource Interface : " << DEFAULT_INTERFACE << endl;
103 cout << "\tResource creation is successful with resource handle : " << m_resourceHandle
108 OCResourceHandle getHandle()
110 return m_resourceHandle;
113 // Puts representation.
114 // Gets values from the representation and
115 // updates the internal state
116 void put(OCRepresentation& rep)
120 if (rep.getValue("power", m_power))
122 cout << "\t\t\t\t" << "power: " << m_power << endl;
126 cout << "\t\t\t\t" << "power not found in the representation" << endl;
131 cout << e.what() << endl;
136 // Post representation.
137 // Post can create new resource or simply act like put.
138 // Gets values from the representation and
139 // updates the internal state
140 OCRepresentation post(OCRepresentation& rep)
146 // gets the updated representation.
147 // Updates the representation with latest internal state before
149 OCRepresentation get()
151 m_lightRep.setValue("power", m_power);
156 void addType(const std::string& type) const
158 OCStackResult result = OCPlatform::bindTypeToResource(m_resourceHandle, type);
159 if (OC_STACK_OK != result)
161 cout << "Binding TypeName to Resource was unsuccessful\n";
165 void addInterface(const std::string& interface) const
167 OCStackResult result = OCPlatform::bindInterfaceToResource(m_resourceHandle, interface);
168 if (OC_STACK_OK != result)
170 cout << "Binding TypeName to Resource was unsuccessful\n";
175 // This is just a sample implementation of entity handler.
176 // Entity handler can be implemented in several ways by the manufacturer
177 OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request)
179 cout << "\tIn Server CPP entity handler:\n";
180 OCEntityHandlerResult ehResult = OC_EH_ERROR;
183 // Get the request type and request flag
184 std::string requestType = request->getRequestType();
185 int requestFlag = request->getRequestHandlerFlag();
187 if (requestFlag & RequestHandlerFlag::InitFlag)
189 cout << "\t\trequestFlag : Init\n";
191 // entity handler to perform resource initialization operations
193 if (requestFlag & RequestHandlerFlag::RequestFlag)
195 cout << "\t\trequestFlag : Request\n";
196 auto pResponse = std::make_shared< OC::OCResourceResponse >();
197 pResponse->setRequestHandle(request->getRequestHandle());
198 pResponse->setResourceHandle(request->getResourceHandle());
200 // If the request type is GET
201 if (requestType == "GET")
203 cout << "\t\t\trequestType : GET\n";
204 if (isSlowResponse) // Slow response case
206 static int startedThread = 0;
209 std::thread t(handleSlowResponse, (void *) this, request);
213 ehResult = OC_EH_SLOW;
215 else // normal response case.
217 pResponse->setErrorCode(200);
218 pResponse->setResponseResult(OC_EH_OK);
219 pResponse->setResourceRepresentation(get());
220 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
226 else if (requestType == "PUT")
228 cout << "\t\t\trequestType : PUT\n";
229 OCRepresentation rep = request->getResourceRepresentation();
231 // Do related operations related to PUT request
232 // Update the lightResource
234 pResponse->setErrorCode(200);
235 pResponse->setResponseResult(OC_EH_OK);
236 pResponse->setResourceRepresentation(get());
237 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
242 else if (requestType == "POST")
244 cout << "\t\t\trequestType : POST\n";
246 OCRepresentation rep = request->getResourceRepresentation();
248 // Do related operations related to POST request
249 OCRepresentation rep_post = post(rep);
250 pResponse->setResourceRepresentation(rep_post);
251 pResponse->setErrorCode(200);
252 if (rep_post.hasAttribute("createduri"))
254 pResponse->setResponseResult(OC_EH_RESOURCE_CREATED);
255 pResponse->setNewResourceUri(
256 rep_post.getValue< std::string >("createduri"));
259 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
264 else if (requestType == "DELETE")
266 // DELETE request operations
272 std::cout << "Request invalid" << std::endl;
279 void * handleSlowResponse(void *param, std::shared_ptr< OCResourceRequest > pRequest)
281 // This function handles slow response case
282 LightResource* lightPtr = (LightResource*) param;
283 // Induce a case for slow response by using sleep
284 std::cout << "SLOW response" << std::endl;
287 auto pResponse = std::make_shared< OC::OCResourceResponse >();
288 pResponse->setRequestHandle(pRequest->getRequestHandle());
289 pResponse->setResourceHandle(pRequest->getResourceHandle());
290 pResponse->setResourceRepresentation(lightPtr->get());
291 pResponse->setErrorCode(200);
292 pResponse->setResponseResult(OC_EH_OK);
294 // Set the slow response flag back to false
295 isSlowResponse = false;
296 OCPlatform::sendResponse(pResponse);
300 int main(int argc, char* argv[])
302 // Create PlatformConfig object
304 { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0",
305 // By setting to "0.0.0.0", it binds to all available interfaces
306 0,// Uses randomly available port
307 OC::QualityOfService::LowQos };
309 OCPlatform::Configure(cfg);
312 // Create the instance of the resource class
313 // (in this case instance of class 'LightResource').
314 LightResource myLight;
316 // Invoke createResource function of class light.
317 myLight.createResource();
319 // A condition variable will free the mutex it is given, then do a non-
320 // intensive block until 'notify' is called on it. In this case, since we
321 // don't ever call cv.notify, this should be a non-processor intensive version
324 std::condition_variable cv;
325 std::unique_lock < std::mutex > lock(blocker);
328 catch (OCException e)
333 // No explicit call to stop the platform.
334 // When OCPlatform::destructor is invoked, internally we do platform cleanup