1 /******************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
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 #include "simulator_resource_server_impl.h"
22 #include "simulator_utils.h"
23 #include "simulator_logger.h"
26 #define TAG "SIM_RESOURCE_SERVER"
28 SimulatorResourceServerImpl::SimulatorResourceServerImpl()
29 : m_resourceHandle(NULL)
31 m_property = static_cast<OCResourceProperty>(OC_DISCOVERABLE | OC_OBSERVABLE);
32 m_interfaceType.assign(OC::DEFAULT_INTERFACE);
35 bool SimulatorResourceServerImpl::isObservable() const
37 return (m_property & OC_OBSERVABLE);
40 void SimulatorResourceServerImpl::setURI(const std::string &uri)
45 void SimulatorResourceServerImpl::setResourceType(const std::string &resourceType)
47 m_resourceType = resourceType;
50 void SimulatorResourceServerImpl::setInterfaceType(const std::string &interfaceType)
52 m_interfaceType = interfaceType;
55 void SimulatorResourceServerImpl::setName(const std::string &name)
60 void SimulatorResourceServerImpl::setObservable(bool state)
63 m_property = static_cast<OCResourceProperty>(m_property | OC_OBSERVABLE);
65 m_property = static_cast<OCResourceProperty>(m_property ^ OC_OBSERVABLE);
68 int SimulatorResourceServerImpl::startUpdateAutomation(AutomationType type,
69 int updateInterval, updateCompleteCallback callback)
73 OC_LOG(ERROR, TAG, "Invalid callback!");
74 throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
77 if (!m_resourceHandle)
79 OC_LOG(ERROR, TAG, "Invalid resource!");
80 throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
83 return m_updateAutomationMgr.startResourceAutomation(this, type, updateInterval, callback);
86 int SimulatorResourceServerImpl::startUpdateAutomation(const std::string &attrName,
87 AutomationType type, int updateInterval,
88 updateCompleteCallback callback)
92 OC_LOG(ERROR, TAG, "Invalid callback!");
93 throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
96 if (!m_resourceHandle)
98 OC_LOG(ERROR, TAG, "Invalid resource!");
99 throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
102 return m_updateAutomationMgr.startAttributeAutomation(this, attrName, type, updateInterval, callback);
105 std::vector<int> SimulatorResourceServerImpl::getResourceAutomationIds()
107 return m_updateAutomationMgr.getResourceAutomationIds();
110 std::vector<int> SimulatorResourceServerImpl::getAttributeAutomationIds()
112 return m_updateAutomationMgr.getAttributeAutomationIds();
115 void SimulatorResourceServerImpl::stopUpdateAutomation(const int id)
117 m_updateAutomationMgr.stop(id);
120 void SimulatorResourceServerImpl::setModelChangeCallback(ResourceModelChangedCB callback)
122 m_callback = callback;
125 void SimulatorResourceServerImpl::setObserverCallback(ObserverCB callback)
127 m_observeCallback = callback;
130 std::vector<ObserverInfo> SimulatorResourceServerImpl::getObserversList()
132 return m_observersList;
135 void SimulatorResourceServerImpl::notify(uint8_t id)
137 if (!m_resourceHandle)
139 OC_LOG(ERROR, TAG, "Invalid resource!");
140 throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
143 std::shared_ptr<OC::OCResourceResponse> resourceResponse =
144 {std::make_shared<OC::OCResourceResponse>()};
146 resourceResponse->setErrorCode(200);
147 resourceResponse->setResponseResult(OC_EH_OK);
148 resourceResponse->setResourceRepresentation(getOCRepresentation(), OC::DEFAULT_INTERFACE);
150 OC::ObservationIds observers;
151 observers.push_back(id);
153 SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending notification to observer with id " << id);
155 typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &,
156 const std::shared_ptr<OC::OCResourceResponse>);
158 invokeocplatform(static_cast<NotifyListOfObservers>(OC::OCPlatform::notifyListOfObservers),
164 void SimulatorResourceServerImpl::notifyAll()
166 if (!m_resourceHandle)
168 OC_LOG(ERROR, TAG, "Invalid resource!");
169 throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
172 if (!m_observersList.size())
174 OC_LOG(ERROR, TAG, "Observers list is empty!");
178 std::shared_ptr<OC::OCResourceResponse> resourceResponse =
179 {std::make_shared<OC::OCResourceResponse>()};
181 resourceResponse->setErrorCode(200);
182 resourceResponse->setResponseResult(OC_EH_OK);
183 resourceResponse->setResourceRepresentation(getOCRepresentation(), OC::DEFAULT_INTERFACE);
185 OC::ObservationIds observers;
186 for (auto & observer : m_observersList)
187 observers.push_back(observer.id);
189 SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending notification to all observers");
191 typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &,
192 const std::shared_ptr<OC::OCResourceResponse>);
194 invokeocplatform(static_cast<NotifyListOfObservers>(OC::OCPlatform::notifyListOfObservers),
200 void SimulatorResourceServerImpl::start()
202 if (m_uri.empty() || m_resourceType.empty() ||
203 m_interfaceType.empty() || m_name.empty() || !m_callback)
205 OC_LOG(ERROR, TAG, "Invalid data found to register the resource!");
206 throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid data found to register the resource!");
209 if (m_resourceHandle)
211 OC_LOG(ERROR, TAG, "Resource already registered!");
212 throw SimulatorException(SIMULATOR_ERROR, "Resource already registered!");
215 typedef OCStackResult (*RegisterResource)(OCResourceHandle &, std::string &, const std::string &,
216 const std::string &, OC::EntityHandler, uint8_t);
218 invokeocplatform(static_cast<RegisterResource>(OC::OCPlatform::registerResource),
219 m_resourceHandle, m_uri, m_resourceType, m_interfaceType,
220 std::bind(&SimulatorResourceServerImpl::entityHandler,
221 this, std::placeholders::_1), m_property);
224 void SimulatorResourceServerImpl::stop()
226 if (!m_resourceHandle)
228 OC_LOG(ERROR, TAG, "Invalid resource!");
229 throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
232 typedef OCStackResult (*UnregisterResource)(const OCResourceHandle &);
234 invokeocplatform(static_cast<UnregisterResource>(OC::OCPlatform::unregisterResource),
237 m_resourceHandle = nullptr;
240 void SimulatorResourceServerImpl::notifyApp()
242 // Notify the application callback
245 m_callback(m_uri, m_resModel);
249 OC::OCRepresentation SimulatorResourceServerImpl::getOCRepresentation()
251 return m_resModel.getOCRepresentation();
254 bool SimulatorResourceServerImpl::modifyResourceModel(OC::OCRepresentation &ocRep)
256 bool status = m_resModel.update(ocRep);
264 void SimulatorResourceServerImpl::resourceModified()
266 if (!m_resourceHandle)
271 // Notify all the subscribers
274 // Notify the application callback
277 m_callback(m_uri, m_resModel);
281 OCEntityHandlerResult SimulatorResourceServerImpl::entityHandler(
282 std::shared_ptr<OC::OCResourceRequest>
285 OCEntityHandlerResult errCode = OC_EH_ERROR;
291 if (OC::RequestHandlerFlag::RequestFlag & request->getRequestHandlerFlag())
293 auto response = std::make_shared<OC::OCResourceResponse>();
294 response->setRequestHandle(request->getRequestHandle());
295 response->setResourceHandle(request->getResourceHandle());
297 if ("GET" == request->getRequestType())
299 OC::OCRepresentation rep = request->getResourceRepresentation();
300 std::string payload = getPayloadString(rep);
301 SIM_LOG(ILogger::INFO, "[" << m_uri <<
302 "] GET request received. \n**Payload details**" << payload)
304 response->setErrorCode(200);
305 response->setResponseResult(OC_EH_OK);
306 response->setResourceRepresentation(getOCRepresentation());
308 if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
313 else if ("PUT" == request->getRequestType())
315 OC::OCRepresentation rep = request->getResourceRepresentation();
316 std::string payload = getPayloadString(rep);
317 SIM_LOG(ILogger::INFO, "[" << m_uri <<
318 "] PUT request received. \n**Payload details**" << payload)
320 if (true == modifyResourceModel(rep))
322 response->setErrorCode(200);
323 response->setResponseResult(OC_EH_OK);
324 response->setResourceRepresentation(getOCRepresentation());
328 response->setErrorCode(400);
329 response->setResponseResult(OC_EH_ERROR);
332 if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
337 else if ("POST" == request->getRequestType())
339 OC::OCRepresentation rep = request->getResourceRepresentation();
340 std::string payload = getPayloadString(rep);
341 SIM_LOG(ILogger::INFO, "[" << m_uri <<
342 "] POST request received. \n**Payload details**" << payload)
344 if (true == modifyResourceModel(rep))
346 response->setErrorCode(200);
347 response->setResponseResult(OC_EH_OK);
348 response->setResourceRepresentation(getOCRepresentation());
352 response->setErrorCode(400);
353 response->setResponseResult(OC_EH_ERROR);
356 if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
361 else if ("DELETE" == request->getRequestType())
363 OC::OCRepresentation rep = request->getResourceRepresentation();
364 std::string payload = getPayloadString(rep);
365 SIM_LOG(ILogger::INFO, "[" << m_uri <<
366 "] DELETE request received. \n**Payload details**" << payload)
368 // DELETE request handling not supported right now
369 response->setErrorCode(400);
370 response->setResponseResult(OC_EH_ERROR);
371 if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
378 OC::OCRepresentation rep = request->getResourceRepresentation();
379 std::string payload = getPayloadString(rep);
380 SIM_LOG(ILogger::INFO, "[" << m_uri <<
381 "] UNKNOWN type request received. \n**Payload details**" << payload)
383 response->setResponseResult(OC_EH_ERROR);
384 if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
386 errCode = OC_EH_ERROR;
391 if (OC::RequestHandlerFlag::ObserverFlag & request->getRequestHandlerFlag())
393 if (false == isObservable())
395 SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE request received")
396 SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending error as resource is in unobservable state")
400 OC::ObservationInfo observationInfo = request->getObservationInfo();
401 if (OC::ObserveAction::ObserveRegister == observationInfo.action)
403 SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE REGISTER request received");
405 ObserverInfo info {observationInfo.obsId, observationInfo.address, observationInfo.port};
406 m_observersList.push_back(info);
408 //Inform about addition of observer
409 if (m_observeCallback)
411 m_observeCallback(m_uri, ObservationStatus::OBSERVE_REGISTER, info);
414 else if (OC::ObserveAction::ObserveUnregister == observationInfo.action)
416 SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE UNREGISTER request received");
419 for (auto iter = m_observersList.begin(); iter != m_observersList.end(); iter++)
421 if ((info = *iter), info.id == observationInfo.obsId)
423 m_observersList.erase(iter);
428 // Inform about cancellation of observer
429 if (m_observeCallback)
431 m_observeCallback(m_uri, ObservationStatus::OBSERVE_UNREGISTER, info);