Merge branch 'tizen' into tizen_5.5
[platform/upstream/iotivity.git] / resource / src / InProcServerWrapper.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 <random>
22 #include <cstring>
23 #include <cstdlib>
24 #include <iostream>
25 #include <algorithm>
26 #include <map>
27 #include <sstream>
28 #include <string>
29
30 #include <InProcServerWrapper.h>
31 #include <InitializeException.h>
32 #include <OCResourceRequest.h>
33 #include <OCResourceResponse.h>
34 #include <ocstack.h>
35 #include <ocpayload.h>
36
37 #include <OCApi.h>
38 #include <oic_malloc.h>
39 #include <OCPlatform.h>
40 #include <OCUtilities.h>
41 #include "logger.h"
42
43 #define TAG "OIC_SERVER_WRAPPER"
44
45 using namespace std;
46 using namespace OC;
47
48 namespace OC
49 {
50     namespace details
51     {
52         std::mutex serverWrapperLock;
53         std::map <OCResourceHandle, OC::EntityHandler>  entityHandlerMap;
54         std::map <OCResourceHandle, std::string> resourceUriMap;
55         EntityHandler defaultDeviceEntityHandler;
56     }
57 }
58
59 void formResourceRequest(OCEntityHandlerFlag flag,
60                          OCEntityHandlerRequest * entityHandlerRequest,
61                          std::shared_ptr<OCResourceRequest> pRequest)
62 {
63     if(pRequest && entityHandlerRequest)
64     {
65         pRequest->setRequestHandle(entityHandlerRequest->requestHandle);
66         pRequest->setResourceHandle(entityHandlerRequest->resource);
67         pRequest->setMessageID(entityHandlerRequest->messageID);
68     }
69
70     if(flag & OC_REQUEST_FLAG)
71     {
72         pRequest->setRequestHandlerFlag(OC::RequestHandlerFlag::RequestFlag);
73
74         if(entityHandlerRequest)
75         {
76             if(entityHandlerRequest->query)
77             {
78                 OC::Utilities::QueryParamsKeyVal qp = OC::Utilities::getQueryParams(
79                         entityHandlerRequest->query);
80
81                 if(qp.size() > 0)
82                 {
83                     pRequest->setQueryParams(qp);
84                 }
85             }
86             if(entityHandlerRequest->numRcvdVendorSpecificHeaderOptions != 0)
87             {
88                 //Set the header options here.
89                 uint16_t optionID;
90                 char optionData[MAX_HEADER_OPTION_DATA_LENGTH + 1];
91                 HeaderOptions headerOptions;
92
93                 optionData[MAX_HEADER_OPTION_DATA_LENGTH] = '\0';
94                 for(int i = 0;
95                     i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions;
96                     i++)
97                 {
98                     optionID = entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionID;
99                     memcpy(optionData, entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionData,
100                         MAX_HEADER_OPTION_DATA_LENGTH);
101                     HeaderOption::OCHeaderOption headerOption(optionID, optionData);
102                     headerOptions.push_back(headerOption);
103                 }
104                 pRequest->setHeaderOptions(headerOptions);
105             }
106
107             if(OC_REST_GET == entityHandlerRequest->method)
108             {
109                 pRequest->setRequestType(OC::PlatformCommands::GET);
110             }
111             else if(OC_REST_PUT == entityHandlerRequest->method)
112             {
113                 pRequest->setRequestType(OC::PlatformCommands::PUT);
114                 pRequest->setPayload(entityHandlerRequest->payload);
115             }
116             else if(OC_REST_POST == entityHandlerRequest->method)
117             {
118                 pRequest->setRequestType(OC::PlatformCommands::POST);
119                 pRequest->setPayload(entityHandlerRequest->payload);
120             }
121             else if(OC_REST_DELETE == entityHandlerRequest->method)
122             {
123                 pRequest->setRequestType(OC::PlatformCommands::DELETE);
124             }
125         }
126     }
127
128     if(flag & OC_OBSERVE_FLAG)
129     {
130         pRequest->setRequestHandlerFlag(
131                    OC::RequestHandlerFlag::RequestFlag | OC::RequestHandlerFlag::ObserverFlag);
132
133         if(entityHandlerRequest)
134         {
135             OC::ObservationInfo observationInfo;
136             observationInfo.action = (OC::ObserveAction) entityHandlerRequest->obsInfo.action;
137             observationInfo.obsId = entityHandlerRequest->obsInfo.obsId;
138
139             observationInfo.connectivityType = static_cast<OCConnectivityType>(
140                     (entityHandlerRequest->devAddr.adapter << CT_ADAPTER_SHIFT) |
141                     (entityHandlerRequest->devAddr.flags & CT_MASK_FLAGS));
142             observationInfo.address = entityHandlerRequest->devAddr.addr;
143             observationInfo.port = entityHandlerRequest->devAddr.port;
144             pRequest->setObservationInfo(observationInfo);
145         }
146     }
147 }
148
149 OCEntityHandlerResult DefaultEntityHandlerWrapper(OCEntityHandlerFlag flag,
150                                                   OCEntityHandlerRequest * entityHandlerRequest,
151                                                   char* uri,
152                                                   void * /*callbackParam*/)
153 {
154     OCEntityHandlerResult result = OC_EH_ERROR;
155
156     OC::oclog() << "In Default device entity handler wrapper";
157
158     if(NULL == entityHandlerRequest)
159     {
160         oclog() << "Entity handler request is NULL.";
161         return OC_EH_ERROR;
162     }
163
164     auto pRequest = std::make_shared<OC::OCResourceRequest>();
165
166     formResourceRequest(flag, entityHandlerRequest, pRequest);
167
168     pRequest->setResourceUri(std::string(uri));
169
170     EntityHandler defHandler;
171     {
172         std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
173         defHandler = OC::details::defaultDeviceEntityHandler;
174     }
175
176     if(defHandler)
177     {
178         result = defHandler(pRequest);
179     }
180     else
181     {
182         oclog() << "Default device entity handler was not set.";
183         return OC_EH_ERROR;
184     }
185
186     return result;
187 }
188
189
190 OCEntityHandlerResult EntityHandlerWrapper(OCEntityHandlerFlag flag,
191                                            OCEntityHandlerRequest * entityHandlerRequest,
192                                            void* /*callbackParam*/)
193 {
194     OCEntityHandlerResult result = OC_EH_ERROR;
195
196     oclog() << "\nIn entity handler wrapper: " << endl;
197
198     if(NULL == entityHandlerRequest)
199     {
200         oclog() << "Entity handler request is NULL."  << endl;
201         return OC_EH_ERROR;
202     }
203
204     auto pRequest = std::make_shared<OC::OCResourceRequest>();
205
206     formResourceRequest(flag, entityHandlerRequest, pRequest);
207
208     std::map <OCResourceHandle, std::string>::iterator resourceUriEntry;
209     std::map <OCResourceHandle, std::string>::iterator resourceUriEnd;
210     {
211         std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
212         resourceUriEntry = OC::details::resourceUriMap.find(entityHandlerRequest->resource);
213         resourceUriEnd = OC::details::resourceUriMap.end();
214     }
215     // Finding the corresponding URI for a resource handle and set the URI in the request
216     if(resourceUriEntry != resourceUriEnd)
217     {
218         pRequest->setResourceUri(resourceUriEntry->second);
219     }
220     else
221     {
222         oclog() << "Resource handle not found; Resource URI not set in request";
223         return OC_EH_ERROR;
224     }
225
226     std::map <OCResourceHandle, OC::EntityHandler>::iterator entityHandlerEntry;
227     std::map <OCResourceHandle, OC::EntityHandler>::iterator entityHandlerEnd;
228     {
229         // Finding the corresponding CPP Application entityHandler for a given resource
230         std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
231         entityHandlerEntry = OC::details::entityHandlerMap.find(entityHandlerRequest->resource);
232         entityHandlerEnd = OC::details::entityHandlerMap.end();
233     }
234
235     if(entityHandlerEntry != entityHandlerEnd)
236     {
237         // Call CPP Application Entity Handler
238         if(entityHandlerEntry->second)
239         {
240             result = entityHandlerEntry->second(pRequest);
241         }
242         else
243         {
244             oclog() << "C stack should not call again for parent resource\n";
245             return OC_EH_ERROR;
246         }
247     }
248     else
249     {
250         oclog() << "No entity handler found."  << endl;
251         return OC_EH_ERROR;
252     }
253
254     return result;
255 }
256
257 namespace OC
258 {
259     InProcServerWrapper::InProcServerWrapper(
260         std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
261      : m_threadRun(false),
262        m_csdkLock(csdkLock),
263        m_cfg { cfg }
264     {
265         start();
266     }
267
268     OCStackResult InProcServerWrapper::start()
269     {
270         OIC_LOG_V(INFO, TAG, "start ocplatform for server : %d", m_cfg.transportType);
271
272         OCMode initType;
273         if(m_cfg.mode == ModeType::Server)
274         {
275             initType = OC_SERVER;
276         }
277         else if (m_cfg.mode == ModeType::Both)
278         {
279             initType = OC_CLIENT_SERVER;
280         }
281         else if (m_cfg.mode == ModeType::Gateway)
282         {
283             initType = OC_GATEWAY;
284         }
285         else
286         {
287             throw InitializeException(OC::InitException::NOT_CONFIGURED_AS_SERVER,
288                                          OC_STACK_INVALID_PARAM);
289         }
290
291 #ifdef WITH_PROCESS_EVENT
292         if (false == m_threadRun)
293         {
294             m_processEvent = oc_event_new();
295             if (!m_processEvent)
296             {
297                 OIC_LOG(INFO, TAG, "oc_event_new failed!");
298                 return OC_STACK_ERROR;
299             }
300         }
301 #endif
302
303         OCTransportFlags serverFlags =
304                             static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
305         OCTransportFlags clientFlags =
306                             static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
307         OCStackResult result = OCInit2(initType, serverFlags, clientFlags,
308                                        m_cfg.transportType);
309
310         if(OC_STACK_OK != result)
311         {
312             throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
313         }
314
315         if (false == m_threadRun)
316         {
317             m_threadRun = true;
318 #ifdef WITH_PROCESS_EVENT
319             OCRegisterProcessEvent(m_processEvent);
320 #endif
321             m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
322         }
323         return OC_STACK_OK;
324     }
325
326     OCStackResult InProcServerWrapper::stop()
327     {
328         OIC_LOG(INFO, TAG, "stop");
329
330         if(m_processThread.joinable())
331         {
332             m_threadRun = false;
333 #ifdef WITH_PROCESS_EVENT
334             if (m_processEvent)
335             {
336                 oc_event_signal(m_processEvent);
337             }
338 #endif
339             m_processThread.join();
340         }
341
342         OCStackResult res = OCStop();
343
344         if (OC_STACK_OK != res)
345         {
346            throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, res);
347         }
348
349 #ifdef WITH_PROCESS_EVENT
350         if (m_processEvent)
351         {
352             oc_event_free(m_processEvent);
353             m_processEvent = NULL;
354         }
355 #endif
356
357         return OC_STACK_OK;
358     }
359
360     void InProcServerWrapper::processFunc()
361     {
362 #ifdef WITH_PROCESS_EVENT
363         uint32_t nextEventTime;
364 #endif
365         auto cLock = m_csdkLock.lock();
366         while(cLock && m_threadRun)
367         {
368             OCStackResult result;
369
370             {
371                 std::lock_guard<std::recursive_mutex> lock(*cLock);
372 #ifdef WITH_PROCESS_EVENT
373                 result = OCProcessEvent(&nextEventTime);
374 #else
375                 result = OCProcess();
376 #endif
377             }
378
379             if(OC_STACK_ERROR == result)
380             {
381                 oclog() << "OCProcess failed with result " << result <<std::flush;
382                 // ...the value of variable result is simply ignored for now.
383             }
384
385  #ifdef WITH_PROCESS_EVENT
386             oc_event_wait_for(m_processEvent, nextEventTime);
387 #else
388             std::this_thread::sleep_for(std::chrono::milliseconds(10));
389 #endif
390         }
391     }
392
393     OCStackResult InProcServerWrapper::registerDeviceInfo(const OCDeviceInfo deviceInfo)
394     {
395         auto cLock = m_csdkLock.lock();
396         OCStackResult result = OC_STACK_ERROR;
397         if(cLock)
398         {
399             std::lock_guard<std::recursive_mutex> lock(*cLock);
400             result = OCSetDeviceInfo(deviceInfo);
401         }
402         return result;
403     }
404
405     OCStackResult InProcServerWrapper::registerPlatformInfo(const OCPlatformInfo platformInfo)
406     {
407         auto cLock = m_csdkLock.lock();
408         OCStackResult result = OC_STACK_ERROR;
409         if(cLock)
410         {
411             std::lock_guard<std::recursive_mutex> lock(*cLock);
412             result = OCSetPlatformInfo(platformInfo);
413         }
414         return result;
415     }
416
417     OCStackResult InProcServerWrapper::setPropertyValue(OCPayloadType type, const std::string& propName,
418         const std::string& propValue)
419     {
420         auto cLock = m_csdkLock.lock();
421         OCStackResult result = OC_STACK_ERROR;
422         if (cLock)
423         {
424             std::lock_guard<std::recursive_mutex> lock(*cLock);
425             result = OCSetPropertyValue(type, propName.c_str(), (void *)propValue.c_str());
426         }
427         return result;
428     }
429
430     OCStackResult InProcServerWrapper::getPropertyValue(OCPayloadType type, const std::string& propName,
431         std::string& propValue)
432     {
433         auto cLock = m_csdkLock.lock();
434         OCStackResult result = OC_STACK_ERROR;
435         if (cLock)
436         {
437             std::lock_guard<std::recursive_mutex> lock(*cLock);
438             result = OCGetPropertyValue(type, propName.c_str(), (void **)propValue.c_str());
439         }
440         return result;
441     }
442
443     OCStackResult InProcServerWrapper::registerResource(
444                     OCResourceHandle& resourceHandle,
445                     std::string& resourceURI,
446                     const std::string& resourceTypeName,
447                     const std::string& resourceInterface,
448                     EntityHandler& eHandler,
449                     uint8_t resourceProperties)
450
451     {
452         OCStackResult result = OC_STACK_ERROR;
453
454         auto cLock = m_csdkLock.lock();
455
456         if(cLock)
457         {
458             std::lock_guard<std::recursive_mutex> lock(*cLock);
459
460             if(NULL != eHandler)
461             {
462                 result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
463                             resourceTypeName.c_str(), // const char * resourceTypeName
464                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
465                             resourceURI.c_str(), // const char * uri
466                             EntityHandlerWrapper, // OCEntityHandler entityHandler
467                             NULL,
468                             resourceProperties // uint8_t resourceProperties
469                             );
470             }
471             else
472             {
473                 result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
474                             resourceTypeName.c_str(), // const char * resourceTypeName
475                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
476                             resourceURI.c_str(), // const char * uri
477                             NULL, // OCEntityHandler entityHandler
478                             NULL,
479                             resourceProperties // uint8_t resourceProperties
480                             );
481             }
482
483             if(result != OC_STACK_OK)
484             {
485                 resourceHandle = (OCResourceHandle) 0;
486             }
487             else
488             {
489                 std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
490                 OC::details::entityHandlerMap[resourceHandle] = eHandler;
491                 OC::details::resourceUriMap[resourceHandle] = resourceURI;
492             }
493         }
494         else
495         {
496             result = OC_STACK_ERROR;
497         }
498
499         return result;
500     }
501
502
503
504     OCStackResult InProcServerWrapper::setDefaultDeviceEntityHandler
505                                         (EntityHandler entityHandler)
506     {
507         OCStackResult result = OC_STACK_ERROR;
508
509         {
510             std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
511             OC::details::defaultDeviceEntityHandler = entityHandler;
512         }
513
514         if(entityHandler)
515         {
516             result = OCSetDefaultDeviceEntityHandler(DefaultEntityHandlerWrapper, NULL);
517         }
518         else
519         {
520             // If Null passed we unset
521             result = OCSetDefaultDeviceEntityHandler(NULL, NULL);
522         }
523
524         return result;
525     }
526
527     OCStackResult InProcServerWrapper::unregisterResource(const OCResourceHandle& resourceHandle)
528     {
529         auto cLock = m_csdkLock.lock();
530         OCStackResult result = OC_STACK_ERROR;
531
532         if(cLock)
533         {
534             std::lock_guard<std::recursive_mutex> lock(*cLock);
535             result = OCDeleteResource(resourceHandle);
536
537             if(result == OC_STACK_OK)
538             {
539                 std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
540                 OC::details::resourceUriMap.erase(resourceHandle);
541             }
542             else
543             {
544                 throw OCException(OC::Exception::RESOURCE_UNREG_FAILED, result);
545             }
546         }
547         else
548         {
549             result = OC_STACK_ERROR;
550         }
551
552         return result;
553     }
554
555     OCStackResult InProcServerWrapper::bindTypeToResource(const OCResourceHandle& resourceHandle,
556                      const std::string& resourceTypeName)
557     {
558         auto cLock = m_csdkLock.lock();
559         OCStackResult result;
560         if(cLock)
561         {
562             std::lock_guard<std::recursive_mutex> lock(*cLock);
563             result = OCBindResourceTypeToResource(resourceHandle, resourceTypeName.c_str());
564         }
565         else
566         {
567             result = OC_STACK_ERROR;
568         }
569
570         if (result != OC_STACK_OK)
571         {
572             throw OCException(OC::Exception::BIND_TYPE_FAILED, result);
573         }
574         return result;
575     }
576
577     OCStackResult InProcServerWrapper::resetResourceTypes(const OCResourceHandle& resourceHandle,
578                      const std::string& newResourceType)
579     {
580         auto cLock = m_csdkLock.lock();
581         OCStackResult result;
582         if(cLock)
583         {
584             std::lock_guard<std::recursive_mutex> lock(*cLock);
585             result = OCResetResourceTypes(resourceHandle, newResourceType.c_str());
586         }
587         else
588         {
589             result = OC_STACK_ERROR;
590         }
591
592         if (result != OC_STACK_OK)
593         {
594             throw OCException(OC::Exception::BIND_TYPE_FAILED, result);
595         }
596         return result;
597     }
598
599     OCStackResult InProcServerWrapper::bindInterfaceToResource(
600                      const OCResourceHandle& resourceHandle,
601                      const std::string& resourceInterfaceName)
602     {
603         auto cLock = m_csdkLock.lock();
604         OCStackResult result;
605         if(cLock)
606         {
607             std::lock_guard<std::recursive_mutex> lock(*cLock);
608             result = OCBindResourceInterfaceToResource(resourceHandle,
609                         resourceInterfaceName.c_str());
610         }
611         else
612         {
613             result = OC_STACK_ERROR;
614         }
615
616         if (result != OC_STACK_OK)
617         {
618             throw OCException(OC::Exception::BIND_INTERFACE_FAILED, result);
619         }
620         return result;
621     }
622
623     OCStackResult InProcServerWrapper::resetResourceInterfaces(
624                      const OCResourceHandle& resourceHandle,
625                      const std::string& newResourceInterface)
626     {
627         auto cLock = m_csdkLock.lock();
628         OCStackResult result;
629         if(cLock)
630         {
631             std::lock_guard<std::recursive_mutex> lock(*cLock);
632             result = OCResetResourceInterfaces(resourceHandle,
633                         newResourceInterface.c_str());
634         }
635         else
636         {
637             result = OC_STACK_ERROR;
638         }
639
640         if (result != OC_STACK_OK)
641         {
642             throw OCException(OC::Exception::BIND_INTERFACE_FAILED, result);
643         }
644         return result;
645     }
646
647     OCStackResult InProcServerWrapper::startPresence(const unsigned int seconds)
648     {
649 #ifdef WITH_PRESENCE
650         auto cLock = m_csdkLock.lock();
651         OCStackResult result = OC_STACK_ERROR;
652         if(cLock)
653         {
654             std::lock_guard<std::recursive_mutex> lock(*cLock);
655             result = OCStartPresence(seconds);
656         }
657
658         if(result != OC_STACK_OK)
659         {
660             throw OCException(OC::Exception::START_PRESENCE_FAILED, result);
661         }
662         return result;
663 #else
664         return OC_STACK_NOT_IMPLEMENTED;
665 #endif
666     }
667
668     OCStackResult InProcServerWrapper::stopPresence()
669     {
670 #ifdef WITH_PRESENCE
671         auto cLock = m_csdkLock.lock();
672         OCStackResult result = OC_STACK_ERROR;
673         if(cLock)
674         {
675             std::lock_guard<std::recursive_mutex> lock(*cLock);
676             result = OCStopPresence();
677         }
678
679         if(result != OC_STACK_OK)
680         {
681             throw OCException(OC::Exception::END_PRESENCE_FAILED, result);
682         }
683         return result;
684 #else
685         return OC_STACK_NOT_IMPLEMENTED;
686 #endif
687     }
688
689     OCStackResult InProcServerWrapper::sendResponse(
690         const std::shared_ptr<OCResourceResponse> pResponse)
691     {
692         auto cLock = m_csdkLock.lock();
693         OCStackResult result = OC_STACK_ERROR;
694
695         if(!pResponse)
696         {
697             result = OC_STACK_MALFORMED_RESPONSE;
698             throw OCException(OC::Exception::STR_NULL_RESPONSE, OC_STACK_MALFORMED_RESPONSE);
699         }
700         else
701         {
702             OCEntityHandlerResponse response;
703 //            OCRepPayload* payLoad = pResponse->getPayload();
704             HeaderOptions serverHeaderOptions = pResponse->getHeaderOptions();
705
706             response.requestHandle = pResponse->getRequestHandle();
707             response.resourceHandle = pResponse->getResourceHandle();
708             response.ehResult = pResponse->getResponseResult();
709
710             response.payload = reinterpret_cast<OCPayload*>(pResponse->getPayload());
711
712             response.persistentBufferFlag = 0;
713
714             response.numSendVendorSpecificHeaderOptions = serverHeaderOptions.size();
715             int i = 0;
716             for (auto it=serverHeaderOptions.begin(); it != serverHeaderOptions.end(); ++it)
717             {
718                 response.sendVendorSpecificHeaderOptions[i].protocolID = OC_COAP_ID;
719                 response.sendVendorSpecificHeaderOptions[i].optionID =
720                     static_cast<uint16_t>(it->getOptionID());
721                 response.sendVendorSpecificHeaderOptions[i].optionLength =
722                     (it->getOptionData()).length() + 1;
723                 std::string optionData = it->getOptionData();
724                 std::copy(optionData.begin(),
725                          optionData.end(),
726                          response.sendVendorSpecificHeaderOptions[i].optionData);
727                 response.sendVendorSpecificHeaderOptions[i].optionData[it->getOptionData().length()]
728                     = '\0';
729                 i++;
730             }
731
732             if(OC_EH_RESOURCE_CREATED == response.ehResult)
733             {
734                 pResponse->getNewResourceUri().copy(response.resourceUri,
735                         sizeof (response.resourceUri) - 1);
736                 response.resourceUri[pResponse->getNewResourceUri().length()] = '\0';
737             }
738
739             if(cLock)
740             {
741                 std::lock_guard<std::recursive_mutex> lock(*cLock);
742                 result = OCDoResponse(&response);
743             }
744             else
745             {
746                 result = OC_STACK_ERROR;
747             }
748
749             if(result != OC_STACK_OK)
750             {
751                 oclog() << "Error sending response\n";
752             }
753
754             OCPayloadDestroy(response.payload);
755             return result;
756         }
757     }
758
759     OCStackResult InProcServerWrapper::notifyAllObservers(OCResourceHandle resourceHandle,
760                                                           QualityOfService QoS)
761     {
762         auto cLock = m_csdkLock.lock();
763         OCStackResult result = OC_STACK_ERROR;
764         if (cLock)
765         {
766             std::lock_guard<std::recursive_mutex> lock(*cLock);
767             result = OCNotifyAllObservers(resourceHandle, static_cast<OCQualityOfService>(QoS));
768         }
769
770         return result;
771     }
772
773     OCStackResult InProcServerWrapper::notifyListOfObservers(OCResourceHandle resourceHandle,
774                                                ObservationIds& observationIds,
775                                                const std::shared_ptr<OCResourceResponse> pResponse,
776                                                QualityOfService QoS)
777     {
778         if (!pResponse)
779         {
780             return OC_STACK_ERROR;
781         }
782
783         auto cLock = m_csdkLock.lock();
784         OCStackResult result = OC_STACK_ERROR;
785         if (cLock)
786         {
787             std::lock_guard<std::recursive_mutex> lock(*cLock);
788
789             OCRepPayload* pl = pResponse->getResourceRepresentation().getPayload();
790             result = OCNotifyListOfObservers(resourceHandle,
791                                              &observationIds[0],
792                                              observationIds.size(),
793                                              pl,
794                                              static_cast<OCQualityOfService>(QoS));
795             OCRepPayloadDestroy(pl);
796         }
797
798         if (result != OC_STACK_OK)
799         {
800             throw OCException(OC::Exception::NOTIFY_LIST_OBSERVERS_FAILED, result);
801         }
802         return result;
803     }
804
805     InProcServerWrapper::~InProcServerWrapper()
806     {
807         try
808         {
809             stop();
810         }
811         catch (InitializeException &e)
812         {
813             OIC_LOG_V(INFO, TAG, "Exception in stop (%s)", e.what());
814         }
815     }
816 }