Imported Upstream version 1.1.1
[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 <OCApi.h>
36 #include <oic_malloc.h>
37 #include <OCPlatform.h>
38 #include <OCUtilities.h>
39
40 using namespace std;
41 using namespace OC;
42
43 namespace OC
44 {
45     namespace details
46     {
47         std::mutex serverWrapperLock;
48         std::map <OCResourceHandle, OC::EntityHandler>  entityHandlerMap;
49         std::map <OCResourceHandle, std::string> resourceUriMap;
50         EntityHandler defaultDeviceEntityHandler = 0;
51     }
52 }
53
54 void formResourceRequest(OCEntityHandlerFlag flag,
55                          OCEntityHandlerRequest * entityHandlerRequest,
56                          std::shared_ptr<OCResourceRequest> pRequest)
57 {
58     if(pRequest && entityHandlerRequest)
59     {
60         pRequest->setRequestHandle(entityHandlerRequest->requestHandle);
61         pRequest->setResourceHandle(entityHandlerRequest->resource);
62         pRequest->setMessageID(entityHandlerRequest->messageID);
63     }
64
65     if(flag & OC_REQUEST_FLAG)
66     {
67         pRequest->setRequestHandlerFlag(OC::RequestHandlerFlag::RequestFlag);
68
69         if(entityHandlerRequest)
70         {
71             if(entityHandlerRequest->query)
72             {
73                 OC::Utilities::QueryParamsKeyVal qp = OC::Utilities::getQueryParams(
74                         entityHandlerRequest->query);
75
76                 if(qp.size() > 0)
77                 {
78                     pRequest->setQueryParams(qp);
79                 }
80             }
81             if(entityHandlerRequest->numRcvdVendorSpecificHeaderOptions != 0)
82             {
83                 //Set the header options here.
84                 uint16_t optionID;
85                 std::string optionData;
86                 HeaderOptions headerOptions;
87
88                 for(int i = 0;
89                     i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions;
90                     i++)
91                 {
92                     optionID = entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionID;
93                     optionData = reinterpret_cast<const char*>
94                              (entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionData);
95                     HeaderOption::OCHeaderOption headerOption(optionID, optionData);
96                     headerOptions.push_back(headerOption);
97                 }
98                 pRequest->setHeaderOptions(headerOptions);
99             }
100
101             if(OC_REST_GET == entityHandlerRequest->method)
102             {
103                 pRequest->setRequestType(OC::PlatformCommands::GET);
104             }
105             else if(OC_REST_PUT == entityHandlerRequest->method)
106             {
107                 pRequest->setRequestType(OC::PlatformCommands::PUT);
108                 pRequest->setPayload(entityHandlerRequest->payload);
109             }
110             else if(OC_REST_POST == entityHandlerRequest->method)
111             {
112                 pRequest->setRequestType(OC::PlatformCommands::POST);
113                 pRequest->setPayload(entityHandlerRequest->payload);
114             }
115             else if(OC_REST_DELETE == entityHandlerRequest->method)
116             {
117                 pRequest->setRequestType(OC::PlatformCommands::DELETE);
118             }
119         }
120     }
121
122     if(flag & OC_OBSERVE_FLAG)
123     {
124         pRequest->setRequestHandlerFlag(
125                    OC::RequestHandlerFlag::RequestFlag | OC::RequestHandlerFlag::ObserverFlag);
126
127         if(entityHandlerRequest)
128         {
129             OC::ObservationInfo observationInfo;
130             observationInfo.action = (OC::ObserveAction) entityHandlerRequest->obsInfo.action;
131             observationInfo.obsId = entityHandlerRequest->obsInfo.obsId;
132
133             observationInfo.connectivityType = static_cast<OCConnectivityType>(
134                     (entityHandlerRequest->devAddr.adapter << CT_ADAPTER_SHIFT) |
135                     (entityHandlerRequest->devAddr.flags & CT_MASK_FLAGS));
136             observationInfo.address = entityHandlerRequest->devAddr.addr;
137             observationInfo.port = entityHandlerRequest->devAddr.port;
138             pRequest->setObservationInfo(observationInfo);
139         }
140     }
141 }
142
143 OCEntityHandlerResult DefaultEntityHandlerWrapper(OCEntityHandlerFlag flag,
144                                                   OCEntityHandlerRequest * entityHandlerRequest,
145                                                   char* uri,
146                                                   void * /*callbackParam*/)
147 {
148     OCEntityHandlerResult result = OC_EH_ERROR;
149
150     OC::oclog() << "In Default device entity handler wrapper";
151
152     if(NULL == entityHandlerRequest)
153     {
154         oclog() << "Entity handler request is NULL.";
155         return OC_EH_ERROR;
156     }
157
158     auto pRequest = std::make_shared<OC::OCResourceRequest>();
159
160     formResourceRequest(flag, entityHandlerRequest, pRequest);
161
162     pRequest->setResourceUri(std::string(uri));
163
164     EntityHandler defHandler;
165     {
166         std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
167         defHandler = OC::details::defaultDeviceEntityHandler;
168     }
169
170     if(defHandler)
171     {
172         result = defHandler(pRequest);
173     }
174     else
175     {
176         oclog() << "Default device entity handler was not set.";
177         return OC_EH_ERROR;
178     }
179
180     return result;
181 }
182
183
184 OCEntityHandlerResult EntityHandlerWrapper(OCEntityHandlerFlag flag,
185                                            OCEntityHandlerRequest * entityHandlerRequest,
186                                            void* /*callbackParam*/)
187 {
188     OCEntityHandlerResult result = OC_EH_ERROR;
189
190     oclog() << "\nIn entity handler wrapper: " << endl;
191
192     if(NULL == entityHandlerRequest)
193     {
194         oclog() << "Entity handler request is NULL."  << endl;
195         return OC_EH_ERROR;
196     }
197
198     auto pRequest = std::make_shared<OC::OCResourceRequest>();
199
200     formResourceRequest(flag, entityHandlerRequest, pRequest);
201
202     std::map <OCResourceHandle, std::string>::iterator resourceUriEntry;
203     std::map <OCResourceHandle, std::string>::iterator resourceUriEnd;
204     {
205         std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
206         resourceUriEntry = OC::details::resourceUriMap.find(entityHandlerRequest->resource);
207         resourceUriEnd = OC::details::resourceUriMap.end();
208     }
209     // Finding the corresponding URI for a resource handle and set the URI in the request
210     if(resourceUriEntry != resourceUriEnd)
211     {
212         pRequest->setResourceUri(resourceUriEntry->second);
213     }
214     else
215     {
216         oclog() << "Resource handle not found; Resource URI not set in request";
217         return OC_EH_ERROR;
218     }
219
220     std::map <OCResourceHandle, OC::EntityHandler>::iterator entityHandlerEntry;
221     std::map <OCResourceHandle, OC::EntityHandler>::iterator entityHandlerEnd;
222     {
223         // Finding the corresponding CPP Application entityHandler for a given resource
224         std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
225         entityHandlerEntry = OC::details::entityHandlerMap.find(entityHandlerRequest->resource);
226         entityHandlerEnd = OC::details::entityHandlerMap.end();
227     }
228
229     if(entityHandlerEntry != entityHandlerEnd)
230     {
231         // Call CPP Application Entity Handler
232         if(entityHandlerEntry->second)
233         {
234             result = entityHandlerEntry->second(pRequest);
235         }
236         else
237         {
238             oclog() << "C stack should not call again for parent resource\n";
239             return OC_EH_ERROR;
240         }
241     }
242     else
243     {
244         oclog() << "No entity handler found."  << endl;
245         return OC_EH_ERROR;
246     }
247
248     return result;
249 }
250
251 namespace OC
252 {
253     InProcServerWrapper::InProcServerWrapper(
254         std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
255      : m_csdkLock(csdkLock)
256     {
257         OCMode initType;
258
259         if(cfg.mode == ModeType::Server)
260         {
261             initType = OC_SERVER;
262         }
263         else if (cfg.mode == ModeType::Both)
264         {
265             initType = OC_CLIENT_SERVER;
266         }
267         else if (cfg.mode == ModeType::Gateway)
268         {
269             initType = OC_GATEWAY;
270         }
271         else
272         {
273             throw InitializeException(OC::InitException::NOT_CONFIGURED_AS_SERVER,
274                                          OC_STACK_INVALID_PARAM);
275         }
276
277         OCTransportFlags serverFlags =
278                             static_cast<OCTransportFlags>(cfg.serverConnectivity & CT_MASK_FLAGS);
279         OCTransportFlags clientFlags =
280                             static_cast<OCTransportFlags>(cfg.clientConnectivity & CT_MASK_FLAGS);
281         OCStackResult result = OCInit1(initType, serverFlags, clientFlags);
282
283         if(OC_STACK_OK != result)
284         {
285             throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
286         }
287
288         m_threadRun = true;
289         m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
290     }
291
292     void InProcServerWrapper::processFunc()
293     {
294         auto cLock = m_csdkLock.lock();
295         while(cLock && m_threadRun)
296         {
297             OCStackResult result;
298
299             {
300                 std::lock_guard<std::recursive_mutex> lock(*cLock);
301                 result = OCProcess();
302             }
303
304             if(OC_STACK_ERROR == result)
305             {
306                 oclog() << "OCProcess failed with result " << result <<std::flush;
307                 // ...the value of variable result is simply ignored for now.
308             }
309
310             std::this_thread::sleep_for(std::chrono::milliseconds(10));
311         }
312     }
313
314     OCStackResult InProcServerWrapper::registerDeviceInfo(const OCDeviceInfo deviceInfo)
315     {
316         auto cLock = m_csdkLock.lock();
317         OCStackResult result = OC_STACK_ERROR;
318         if(cLock)
319         {
320             std::lock_guard<std::recursive_mutex> lock(*cLock);
321             result = OCSetDeviceInfo(deviceInfo);
322         }
323         return result;
324     }
325
326      OCStackResult InProcServerWrapper::registerPlatformInfo(const OCPlatformInfo platformInfo)
327     {
328         auto cLock = m_csdkLock.lock();
329         OCStackResult result = OC_STACK_ERROR;
330         if(cLock)
331         {
332             std::lock_guard<std::recursive_mutex> lock(*cLock);
333             result = OCSetPlatformInfo(platformInfo);
334         }
335         return result;
336     }
337
338     OCStackResult InProcServerWrapper::registerResource(
339                     OCResourceHandle& resourceHandle,
340                     std::string& resourceURI,
341                     const std::string& resourceTypeName,
342                     const std::string& resourceInterface,
343                     EntityHandler& eHandler,
344                     uint8_t resourceProperties)
345
346     {
347         OCStackResult result = OC_STACK_ERROR;
348
349         auto cLock = m_csdkLock.lock();
350
351         if(cLock)
352         {
353             std::lock_guard<std::recursive_mutex> lock(*cLock);
354
355             if(NULL != eHandler)
356             {
357                 result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
358                             resourceTypeName.c_str(), // const char * resourceTypeName
359                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
360                             resourceURI.c_str(), // const char * uri
361                             EntityHandlerWrapper, // OCEntityHandler entityHandler
362                             NULL,
363                             resourceProperties // uint8_t resourceProperties
364                             );
365             }
366             else
367             {
368                 result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
369                             resourceTypeName.c_str(), // const char * resourceTypeName
370                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
371                             resourceURI.c_str(), // const char * uri
372                             NULL, // OCEntityHandler entityHandler
373                             NULL,
374                             resourceProperties // uint8_t resourceProperties
375                             );
376             }
377
378             if(result != OC_STACK_OK)
379             {
380                 resourceHandle = (OCResourceHandle) 0;
381             }
382             else
383             {
384                 std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
385                 OC::details::entityHandlerMap[resourceHandle] = eHandler;
386                 OC::details::resourceUriMap[resourceHandle] = resourceURI;
387             }
388         }
389         else
390         {
391             result = OC_STACK_ERROR;
392         }
393
394         return result;
395     }
396
397
398
399     OCStackResult InProcServerWrapper::setDefaultDeviceEntityHandler
400                                         (EntityHandler entityHandler)
401     {
402         OCStackResult result = OC_STACK_ERROR;
403
404         {
405             std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
406             OC::details::defaultDeviceEntityHandler = entityHandler;
407         }
408
409         if(entityHandler)
410         {
411             result = OCSetDefaultDeviceEntityHandler(DefaultEntityHandlerWrapper, NULL);
412         }
413         else
414         {
415             // If Null passed we unset
416             result = OCSetDefaultDeviceEntityHandler(NULL, NULL);
417         }
418
419         return result;
420     }
421
422     OCStackResult InProcServerWrapper::unregisterResource(const OCResourceHandle& resourceHandle)
423     {
424         auto cLock = m_csdkLock.lock();
425         OCStackResult result = OC_STACK_ERROR;
426
427         if(cLock)
428         {
429             std::lock_guard<std::recursive_mutex> lock(*cLock);
430             result = OCDeleteResource(resourceHandle);
431
432             if(result == OC_STACK_OK)
433             {
434                 std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
435                 OC::details::resourceUriMap.erase(resourceHandle);
436             }
437             else
438             {
439                 throw OCException(OC::Exception::RESOURCE_UNREG_FAILED, result);
440             }
441         }
442         else
443         {
444             result = OC_STACK_ERROR;
445         }
446
447         return result;
448     }
449
450     OCStackResult InProcServerWrapper::bindTypeToResource(const OCResourceHandle& resourceHandle,
451                      const std::string& resourceTypeName)
452     {
453         auto cLock = m_csdkLock.lock();
454         OCStackResult result;
455         if(cLock)
456         {
457             std::lock_guard<std::recursive_mutex> lock(*cLock);
458             result = OCBindResourceTypeToResource(resourceHandle, resourceTypeName.c_str());
459         }
460         else
461         {
462             result = OC_STACK_ERROR;
463         }
464
465         if (result != OC_STACK_OK)
466         {
467             throw OCException(OC::Exception::BIND_TYPE_FAILED, result);
468         }
469         return result;
470     }
471
472     OCStackResult InProcServerWrapper::bindInterfaceToResource(
473                      const OCResourceHandle& resourceHandle,
474                      const std::string& resourceInterfaceName)
475     {
476         auto cLock = m_csdkLock.lock();
477         OCStackResult result;
478         if(cLock)
479         {
480             std::lock_guard<std::recursive_mutex> lock(*cLock);
481             result = OCBindResourceInterfaceToResource(resourceHandle,
482                         resourceInterfaceName.c_str());
483         }
484         else
485         {
486             result = OC_STACK_ERROR;
487         }
488
489         if (result != OC_STACK_OK)
490         {
491             throw OCException(OC::Exception::BIND_INTERFACE_FAILED, result);
492         }
493         return result;
494     }
495
496     OCStackResult InProcServerWrapper::startPresence(const unsigned int seconds)
497     {
498         auto cLock = m_csdkLock.lock();
499         OCStackResult result = OC_STACK_ERROR;
500         if(cLock)
501         {
502             std::lock_guard<std::recursive_mutex> lock(*cLock);
503             result = OCStartPresence(seconds);
504         }
505
506         if(result != OC_STACK_OK)
507         {
508             throw OCException(OC::Exception::START_PRESENCE_FAILED, result);
509         }
510         return result;
511     }
512
513     OCStackResult InProcServerWrapper::stopPresence()
514     {
515         auto cLock = m_csdkLock.lock();
516         OCStackResult result = OC_STACK_ERROR;
517         if(cLock)
518         {
519             std::lock_guard<std::recursive_mutex> lock(*cLock);
520             result = OCStopPresence();
521         }
522
523         if(result != OC_STACK_OK)
524         {
525             throw OCException(OC::Exception::END_PRESENCE_FAILED, result);
526         }
527         return result;
528     }
529
530     OCStackResult InProcServerWrapper::sendResponse(
531         const std::shared_ptr<OCResourceResponse> pResponse)
532     {
533         auto cLock = m_csdkLock.lock();
534         OCStackResult result = OC_STACK_ERROR;
535
536         if(!pResponse)
537         {
538             result = OC_STACK_MALFORMED_RESPONSE;
539             throw OCException(OC::Exception::STR_NULL_RESPONSE, OC_STACK_MALFORMED_RESPONSE);
540         }
541         else
542         {
543             OCEntityHandlerResponse response;
544 //            OCRepPayload* payLoad = pResponse->getPayload();
545             HeaderOptions serverHeaderOptions = pResponse->getHeaderOptions();
546
547             response.requestHandle = pResponse->getRequestHandle();
548             response.resourceHandle = pResponse->getResourceHandle();
549             response.ehResult = pResponse->getResponseResult();
550
551             response.payload = reinterpret_cast<OCPayload*>(pResponse->getPayload());
552
553             response.persistentBufferFlag = 0;
554
555             response.numSendVendorSpecificHeaderOptions = serverHeaderOptions.size();
556             int i = 0;
557             for (auto it=serverHeaderOptions.begin(); it != serverHeaderOptions.end(); ++it)
558             {
559                 response.sendVendorSpecificHeaderOptions[i].protocolID = OC_COAP_ID;
560                 response.sendVendorSpecificHeaderOptions[i].optionID =
561                     static_cast<uint16_t>(it->getOptionID());
562                 response.sendVendorSpecificHeaderOptions[i].optionLength =
563                     (it->getOptionData()).length() + 1;
564                 std::string optionData = it->getOptionData();
565                 std::copy(optionData.begin(),
566                          optionData.end(),
567                          response.sendVendorSpecificHeaderOptions[i].optionData);
568                 response.sendVendorSpecificHeaderOptions[i].optionData[it->getOptionData().length()]
569                     = '\0';
570                 i++;
571             }
572
573             if(OC_EH_RESOURCE_CREATED == response.ehResult)
574             {
575                 pResponse->getNewResourceUri().copy(response.resourceUri,
576                         sizeof (response.resourceUri) - 1);
577                 response.resourceUri[pResponse->getNewResourceUri().length()] = '\0';
578             }
579
580             if(cLock)
581             {
582                 std::lock_guard<std::recursive_mutex> lock(*cLock);
583                 result = OCDoResponse(&response);
584             }
585             else
586             {
587                 OICFree(response.payload);
588                 result = OC_STACK_ERROR;
589             }
590
591             if(result != OC_STACK_OK)
592             {
593                 oclog() << "Error sending response\n";
594             }
595             return result;
596         }
597     }
598
599     InProcServerWrapper::~InProcServerWrapper()
600     {
601         if(m_processThread.joinable())
602         {
603             m_threadRun = false;
604             m_processThread.join();
605         }
606
607         OCStop();
608     }
609 }
610