Imported Upstream version 1.0.1
[platform/upstream/iotivity.git] / service / simulator / src / service-provider / simulator_resource_server_impl.cpp
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20
21 #include "simulator_resource_server_impl.h"
22 #include "simulator_utils.h"
23 #include "simulator_logger.h"
24 #include "logger.h"
25
26 #define TAG "SIM_RESOURCE_SERVER"
27
28 SimulatorResourceServerImpl::SimulatorResourceServerImpl()
29     :   m_resourceHandle(NULL)
30 {
31     m_property = static_cast<OCResourceProperty>(OC_DISCOVERABLE | OC_OBSERVABLE);
32     m_interfaceType.assign(OC::DEFAULT_INTERFACE);
33 }
34
35 bool SimulatorResourceServerImpl::isObservable() const
36 {
37     return (m_property & OC_OBSERVABLE);
38 }
39
40 void SimulatorResourceServerImpl::setURI(const std::string &uri)
41 {
42     m_uri = uri;
43 }
44
45 void SimulatorResourceServerImpl::setResourceType(const std::string &resourceType)
46 {
47     m_resourceType = resourceType;
48 }
49
50 void SimulatorResourceServerImpl::setInterfaceType(const std::string &interfaceType)
51 {
52     m_interfaceType = interfaceType;
53 }
54
55 void SimulatorResourceServerImpl::setName(const std::string &name)
56 {
57     m_name = name;
58 }
59
60 void SimulatorResourceServerImpl::setObservable(bool state)
61 {
62     if (true == state)
63         m_property = static_cast<OCResourceProperty>(m_property | OC_OBSERVABLE);
64     else
65         m_property = static_cast<OCResourceProperty>(m_property ^ OC_OBSERVABLE);
66 }
67
68 int SimulatorResourceServerImpl::startUpdateAutomation(AutomationType type,
69         int updateInterval, updateCompleteCallback callback)
70 {
71     if (!callback)
72     {
73         OC_LOG(ERROR, TAG, "Invalid callback!");
74         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
75     }
76
77     if (!m_resourceHandle)
78     {
79         OC_LOG(ERROR, TAG, "Invalid resource!");
80         throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
81     }
82
83     return m_updateAutomationMgr.startResourceAutomation(this, type, updateInterval, callback);
84 }
85
86 int SimulatorResourceServerImpl::startUpdateAutomation(const std::string &attrName,
87         AutomationType type, int updateInterval,
88         updateCompleteCallback callback)
89 {
90     if (!callback)
91     {
92         OC_LOG(ERROR, TAG, "Invalid callback!");
93         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
94     }
95
96     if (!m_resourceHandle)
97     {
98         OC_LOG(ERROR, TAG, "Invalid resource!");
99         throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
100     }
101
102     return m_updateAutomationMgr.startAttributeAutomation(this, attrName, type, updateInterval, callback);
103 }
104
105 std::vector<int> SimulatorResourceServerImpl::getResourceAutomationIds()
106 {
107     return m_updateAutomationMgr.getResourceAutomationIds();
108 }
109
110 std::vector<int> SimulatorResourceServerImpl::getAttributeAutomationIds()
111 {
112     return m_updateAutomationMgr.getAttributeAutomationIds();
113 }
114
115 void SimulatorResourceServerImpl::stopUpdateAutomation(const int id)
116 {
117     m_updateAutomationMgr.stop(id);
118 }
119
120 void SimulatorResourceServerImpl::setModelChangeCallback(ResourceModelChangedCB callback)
121 {
122     m_callback = callback;
123 }
124
125 void SimulatorResourceServerImpl::setObserverCallback(ObserverCB callback)
126 {
127     m_observeCallback = callback;
128 }
129
130 std::vector<ObserverInfo> SimulatorResourceServerImpl::getObserversList()
131 {
132     return m_observersList;
133 }
134
135 void SimulatorResourceServerImpl::notify(uint8_t id)
136 {
137     if (!m_resourceHandle)
138     {
139         OC_LOG(ERROR, TAG, "Invalid resource!");
140         throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
141     }
142
143     std::shared_ptr<OC::OCResourceResponse> resourceResponse =
144     {std::make_shared<OC::OCResourceResponse>()};
145
146     resourceResponse->setErrorCode(200);
147     resourceResponse->setResponseResult(OC_EH_OK);
148     resourceResponse->setResourceRepresentation(getOCRepresentation(), OC::DEFAULT_INTERFACE);
149
150     OC::ObservationIds observers;
151     observers.push_back(id);
152
153     SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending notification to observer with id " << id);
154
155     typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &,
156             const std::shared_ptr<OC::OCResourceResponse>);
157
158     invokeocplatform(static_cast<NotifyListOfObservers>(OC::OCPlatform::notifyListOfObservers),
159                      m_resourceHandle,
160                      observers,
161                      resourceResponse);
162 }
163
164 void SimulatorResourceServerImpl::notifyAll()
165 {
166     if (!m_resourceHandle)
167     {
168         OC_LOG(ERROR, TAG, "Invalid resource!");
169         throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
170     }
171
172     if (!m_observersList.size())
173     {
174         OC_LOG(ERROR, TAG, "Observers list is empty!");
175         return;
176     }
177
178     std::shared_ptr<OC::OCResourceResponse> resourceResponse =
179     {std::make_shared<OC::OCResourceResponse>()};
180
181     resourceResponse->setErrorCode(200);
182     resourceResponse->setResponseResult(OC_EH_OK);
183     resourceResponse->setResourceRepresentation(getOCRepresentation(), OC::DEFAULT_INTERFACE);
184
185     OC::ObservationIds observers;
186     for (auto & observer : m_observersList)
187         observers.push_back(observer.id);
188
189     SIM_LOG(ILogger::INFO, "[" << m_uri << "] Sending notification to all observers");
190
191     typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &,
192             const std::shared_ptr<OC::OCResourceResponse>);
193
194     invokeocplatform(static_cast<NotifyListOfObservers>(OC::OCPlatform::notifyListOfObservers),
195                      m_resourceHandle,
196                      observers,
197                      resourceResponse);
198 }
199
200 void SimulatorResourceServerImpl::start()
201 {
202     if (m_uri.empty() || m_resourceType.empty() ||
203         m_interfaceType.empty() || m_name.empty() || !m_callback)
204     {
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!");
207     }
208
209     if (m_resourceHandle)
210     {
211         OC_LOG(ERROR, TAG, "Resource already registered!");
212         throw SimulatorException(SIMULATOR_ERROR, "Resource already registered!");
213     }
214
215     typedef OCStackResult (*RegisterResource)(OCResourceHandle &, std::string &, const std::string &,
216             const std::string &, OC::EntityHandler, uint8_t);
217
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);
222 }
223
224 void SimulatorResourceServerImpl::stop()
225 {
226     if (!m_resourceHandle)
227     {
228         OC_LOG(ERROR, TAG, "Invalid resource!");
229         throw SimulatorException(SIMULATOR_NO_RESOURCE, "Invalid resource!");
230     }
231
232     typedef OCStackResult (*UnregisterResource)(const OCResourceHandle &);
233
234     invokeocplatform(static_cast<UnregisterResource>(OC::OCPlatform::unregisterResource),
235                      m_resourceHandle);
236
237     m_resourceHandle = nullptr;
238 }
239
240 void SimulatorResourceServerImpl::notifyApp()
241 {
242     // Notify the application callback
243     if (m_callback)
244     {
245         m_callback(m_uri, m_resModel);
246     }
247 }
248
249 OC::OCRepresentation SimulatorResourceServerImpl::getOCRepresentation()
250 {
251     return m_resModel.getOCRepresentation();
252 }
253
254 bool SimulatorResourceServerImpl::modifyResourceModel(OC::OCRepresentation &ocRep)
255 {
256     bool status = m_resModel.update(ocRep);
257     if (true == status)
258     {
259         resourceModified();
260     }
261     return status;
262 }
263
264 void SimulatorResourceServerImpl::resourceModified()
265 {
266     if (!m_resourceHandle)
267     {
268         return;
269     }
270
271     // Notify all the subscribers
272     notifyAll();
273
274     // Notify the application callback
275     if (m_callback)
276     {
277         m_callback(m_uri, m_resModel);
278     }
279 }
280
281 OCEntityHandlerResult SimulatorResourceServerImpl::entityHandler(
282     std::shared_ptr<OC::OCResourceRequest>
283     request)
284 {
285     OCEntityHandlerResult errCode = OC_EH_ERROR;
286     if (!request)
287     {
288         return OC_EH_ERROR;
289     }
290
291     if (OC::RequestHandlerFlag::RequestFlag & request->getRequestHandlerFlag())
292     {
293         auto response = std::make_shared<OC::OCResourceResponse>();
294         response->setRequestHandle(request->getRequestHandle());
295         response->setResourceHandle(request->getResourceHandle());
296
297         if ("GET" == request->getRequestType())
298         {
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)
303
304             response->setErrorCode(200);
305             response->setResponseResult(OC_EH_OK);
306             response->setResourceRepresentation(getOCRepresentation());
307
308             if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
309             {
310                 errCode = OC_EH_OK;
311             }
312         }
313         else if ("PUT" == request->getRequestType())
314         {
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)
319
320             if (true == modifyResourceModel(rep))
321             {
322                 response->setErrorCode(200);
323                 response->setResponseResult(OC_EH_OK);
324                 response->setResourceRepresentation(getOCRepresentation());
325             }
326             else
327             {
328                 response->setErrorCode(400);
329                 response->setResponseResult(OC_EH_ERROR);
330             }
331
332             if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
333             {
334                 errCode = OC_EH_OK;
335             }
336         }
337         else if ("POST" == request->getRequestType())
338         {
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)
343
344             if (true == modifyResourceModel(rep))
345             {
346                 response->setErrorCode(200);
347                 response->setResponseResult(OC_EH_OK);
348                 response->setResourceRepresentation(getOCRepresentation());
349             }
350             else
351             {
352                 response->setErrorCode(400);
353                 response->setResponseResult(OC_EH_ERROR);
354             }
355
356             if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
357             {
358                 errCode = OC_EH_OK;
359             }
360         }
361         else if ("DELETE" == request->getRequestType())
362         {
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)
367
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))
372             {
373                 errCode = OC_EH_OK;
374             }
375         }
376         else
377         {
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)
382
383             response->setResponseResult(OC_EH_ERROR);
384             if (OC_STACK_OK == OC::OCPlatform::sendResponse(response))
385             {
386                 errCode = OC_EH_ERROR;
387             }
388         }
389     }
390
391     if (OC::RequestHandlerFlag::ObserverFlag & request->getRequestHandlerFlag())
392     {
393         if (false == isObservable())
394         {
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")
397             return OC_EH_ERROR;
398         }
399
400         OC::ObservationInfo observationInfo = request->getObservationInfo();
401         if (OC::ObserveAction::ObserveRegister == observationInfo.action)
402         {
403             SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE REGISTER request received");
404
405             ObserverInfo info {observationInfo.obsId, observationInfo.address, observationInfo.port};
406             m_observersList.push_back(info);
407
408             //Inform about addition of observer
409             if (m_observeCallback)
410             {
411                 m_observeCallback(m_uri, ObservationStatus::OBSERVE_REGISTER, info);
412             }
413         }
414         else if (OC::ObserveAction::ObserveUnregister == observationInfo.action)
415         {
416             SIM_LOG(ILogger::INFO, "[" << m_uri << "] OBSERVE UNREGISTER request received");
417
418             ObserverInfo info;
419             for (auto iter = m_observersList.begin(); iter != m_observersList.end(); iter++)
420             {
421                 if ((info = *iter), info.id == observationInfo.obsId)
422                 {
423                     m_observersList.erase(iter);
424                     break;
425                 }
426             }
427
428             // Inform about cancellation of observer
429             if (m_observeCallback)
430             {
431                 m_observeCallback(m_uri, ObservationStatus::OBSERVE_UNREGISTER, info);
432             }
433         }
434         errCode = OC_EH_OK;
435     }
436
437     return errCode;
438 }