Change logging method
[platform/upstream/iotivity.git] / resource / src / InProcServerWrapper.cpp
index d60f613..6bc0bae 100644 (file)
 #include <OCResourceRequest.h>
 #include <OCResourceResponse.h>
 #include <ocstack.h>
+#include <ocpayload.h>
+
 #include <OCApi.h>
+#include <oic_malloc.h>
 #include <OCPlatform.h>
 #include <OCUtilities.h>
+#include "logger.h"
+
+#define TAG "OIC_SERVER_WRAPPER"
 
 using namespace std;
 using namespace OC;
@@ -46,7 +52,7 @@ namespace OC
         std::mutex serverWrapperLock;
         std::map <OCResourceHandle, OC::EntityHandler>  entityHandlerMap;
         std::map <OCResourceHandle, std::string> resourceUriMap;
-        EntityHandler defaultDeviceEntityHandler = 0;
+        EntityHandler defaultDeviceEntityHandler;
     }
 }
 
@@ -54,12 +60,11 @@ void formResourceRequest(OCEntityHandlerFlag flag,
                          OCEntityHandlerRequest * entityHandlerRequest,
                          std::shared_ptr<OCResourceRequest> pRequest)
 {
-    pRequest->setRequestHandle(entityHandlerRequest->requestHandle);
-    pRequest->setResourceHandle(entityHandlerRequest->resource);
-
-    if(flag & OC_INIT_FLAG)
+    if(pRequest && entityHandlerRequest)
     {
-        pRequest->setRequestHandlerFlag(OC::RequestHandlerFlag::InitFlag);
+        pRequest->setRequestHandle(entityHandlerRequest->requestHandle);
+        pRequest->setResourceHandle(entityHandlerRequest->resource);
+        pRequest->setMessageID(entityHandlerRequest->messageID);
     }
 
     if(flag & OC_REQUEST_FLAG)
@@ -70,9 +75,8 @@ void formResourceRequest(OCEntityHandlerFlag flag,
         {
             if(entityHandlerRequest->query)
             {
-                std::string querystr(reinterpret_cast<char*>(entityHandlerRequest->query));
-
-                OC::Utilities::QueryParamsKeyVal qp = OC::Utilities::getQueryParams(querystr);
+                OC::Utilities::QueryParamsKeyVal qp = OC::Utilities::getQueryParams(
+                        entityHandlerRequest->query);
 
                 if(qp.size() > 0)
                 {
@@ -83,16 +87,17 @@ void formResourceRequest(OCEntityHandlerFlag flag,
             {
                 //Set the header options here.
                 uint16_t optionID;
-                std::string optionData;
+                char optionData[MAX_HEADER_OPTION_DATA_LENGTH + 1];
                 HeaderOptions headerOptions;
 
+                optionData[MAX_HEADER_OPTION_DATA_LENGTH] = '\0';
                 for(int i = 0;
                     i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions;
                     i++)
                 {
                     optionID = entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionID;
-                    optionData = reinterpret_cast<const char*>
-                             (entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionData);
+                    memcpy(optionData, entityHandlerRequest->rcvdVendorSpecificHeaderOptions[i].optionData,
+                        MAX_HEADER_OPTION_DATA_LENGTH);
                     HeaderOption::OCHeaderOption headerOption(optionID, optionData);
                     headerOptions.push_back(headerOption);
                 }
@@ -106,14 +111,12 @@ void formResourceRequest(OCEntityHandlerFlag flag,
             else if(OC_REST_PUT == entityHandlerRequest->method)
             {
                 pRequest->setRequestType(OC::PlatformCommands::PUT);
-                pRequest->setPayload(std::string(reinterpret_cast<const char*>
-                                            (entityHandlerRequest->reqJSONPayload)));
+                pRequest->setPayload(entityHandlerRequest->payload);
             }
             else if(OC_REST_POST == entityHandlerRequest->method)
             {
                 pRequest->setRequestType(OC::PlatformCommands::POST);
-                pRequest->setPayload(std::string(reinterpret_cast<const char*>
-                                            (entityHandlerRequest->reqJSONPayload)));
+                pRequest->setPayload(entityHandlerRequest->payload);
             }
             else if(OC_REST_DELETE == entityHandlerRequest->method)
             {
@@ -132,6 +135,12 @@ void formResourceRequest(OCEntityHandlerFlag flag,
             OC::ObservationInfo observationInfo;
             observationInfo.action = (OC::ObserveAction) entityHandlerRequest->obsInfo.action;
             observationInfo.obsId = entityHandlerRequest->obsInfo.obsId;
+
+            observationInfo.connectivityType = static_cast<OCConnectivityType>(
+                    (entityHandlerRequest->devAddr.adapter << CT_ADAPTER_SHIFT) |
+                    (entityHandlerRequest->devAddr.flags & CT_MASK_FLAGS));
+            observationInfo.address = entityHandlerRequest->devAddr.addr;
+            observationInfo.port = entityHandlerRequest->devAddr.port;
             pRequest->setObservationInfo(observationInfo);
         }
     }
@@ -139,7 +148,8 @@ void formResourceRequest(OCEntityHandlerFlag flag,
 
 OCEntityHandlerResult DefaultEntityHandlerWrapper(OCEntityHandlerFlag flag,
                                                   OCEntityHandlerRequest * entityHandlerRequest,
-                                                  char* uri)
+                                                  char* uri,
+                                                  void * /*callbackParam*/)
 {
     OCEntityHandlerResult result = OC_EH_ERROR;
 
@@ -178,7 +188,8 @@ OCEntityHandlerResult DefaultEntityHandlerWrapper(OCEntityHandlerFlag flag,
 
 
 OCEntityHandlerResult EntityHandlerWrapper(OCEntityHandlerFlag flag,
-                                           OCEntityHandlerRequest * entityHandlerRequest)
+                                           OCEntityHandlerRequest * entityHandlerRequest,
+                                           void* /*callbackParam*/)
 {
     OCEntityHandlerResult result = OC_EH_ERROR;
 
@@ -247,33 +258,74 @@ namespace OC
 {
     InProcServerWrapper::InProcServerWrapper(
         std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
-     : m_csdkLock(csdkLock)
+     : m_threadRun(false),
+       m_csdkLock(csdkLock),
+       m_cfg { cfg }       
     {
-        OCMode initType;
+        start();
+    }
+
+    OCStackResult InProcServerWrapper::start()
+    {
+        OIC_LOG_V(INFO, TAG, "start ocplatform for server : %d", m_cfg.transportType);
 
-        if(cfg.mode == ModeType::Server)
+        OCMode initType;
+        if(m_cfg.mode == ModeType::Server)
         {
             initType = OC_SERVER;
         }
-        else if (cfg.mode == ModeType::Both)
+        else if (m_cfg.mode == ModeType::Both)
         {
             initType = OC_CLIENT_SERVER;
         }
+        else if (m_cfg.mode == ModeType::Gateway)
+        {
+            initType = OC_GATEWAY;
+        }
         else
         {
             throw InitializeException(OC::InitException::NOT_CONFIGURED_AS_SERVER,
-                                      OC_STACK_INVALID_PARAM);
+                                         OC_STACK_INVALID_PARAM);
         }
 
-        OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, initType);
+        OCTransportFlags serverFlags =
+                            static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
+        OCTransportFlags clientFlags =
+                            static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
+        OCStackResult result = OCInit2(initType, serverFlags, clientFlags,
+                                       m_cfg.transportType);
 
         if(OC_STACK_OK != result)
         {
             throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
         }
 
-        m_threadRun = true;
-        m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
+        if (false == m_threadRun)
+        {
+            m_threadRun = true;
+            m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
+        }
+        return OC_STACK_OK;
+    }
+
+    OCStackResult InProcServerWrapper::stop()
+    {
+        OIC_LOG(INFO, TAG, "stop");
+
+        if(m_processThread.joinable())
+        {
+            m_threadRun = false;
+            m_processThread.join();
+        }
+
+        OCStackResult res = OCStop();
+
+        if (OC_STACK_OK != res)
+        {
+           throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, res);
+        }
+
+        return OC_STACK_OK;
     }
 
     void InProcServerWrapper::processFunc()
@@ -288,9 +340,11 @@ namespace OC
                 result = OCProcess();
             }
 
-            // ...the value of variable result is simply ignored for now.
             if(OC_STACK_ERROR == result)
-             ;
+            {
+                oclog() << "OCProcess failed with result " << result <<std::flush;
+                // ...the value of variable result is simply ignored for now.
+            }
 
             std::this_thread::sleep_for(std::chrono::milliseconds(10));
         }
@@ -308,6 +362,44 @@ namespace OC
         return result;
     }
 
+    OCStackResult InProcServerWrapper::registerPlatformInfo(const OCPlatformInfo platformInfo)
+    {
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if(cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSetPlatformInfo(platformInfo);
+        }
+        return result;
+    }
+
+    OCStackResult InProcServerWrapper::setPropertyValue(OCPayloadType type, const std::string& propName,
+        const std::string& propValue)
+    {
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSetPropertyValue(type, propName.c_str(), (void *)propValue.c_str());
+        }
+        return result;
+    }
+
+    OCStackResult InProcServerWrapper::getPropertyValue(OCPayloadType type, const std::string& propName,
+        std::string& propValue)
+    {
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCGetPropertyValue(type, propName.c_str(), (void **)propValue.c_str());
+        }
+        return result;
+    }
+
     OCStackResult InProcServerWrapper::registerResource(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceURI,
@@ -332,6 +424,7 @@ namespace OC
                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
                             resourceURI.c_str(), // const char * uri
                             EntityHandlerWrapper, // OCEntityHandler entityHandler
+                            NULL,
                             resourceProperties // uint8_t resourceProperties
                             );
             }
@@ -342,6 +435,7 @@ namespace OC
                             resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix this
                             resourceURI.c_str(), // const char * uri
                             NULL, // OCEntityHandler entityHandler
+                            NULL,
                             resourceProperties // uint8_t resourceProperties
                             );
             }
@@ -365,65 +459,7 @@ namespace OC
         return result;
     }
 
-    OCStackResult InProcServerWrapper::registerResourceWithHost(
-                    OCResourceHandle& resourceHandle,
-                    std::string& resourceHOST,
-                    std::string& resourceURI,
-                    const std::string& resourceTypeName,
-                    const std::string& resourceInterface,
-                    EntityHandler& eHandler,
-                    uint8_t resourceProperties)
-
-    {
-        OCStackResult result = OC_STACK_ERROR;
-
-        auto cLock = m_csdkLock.lock();
-
-        if (cLock)
-        {
-            std::lock_guard < std::recursive_mutex > lock(*cLock);
-
-            if (NULL != eHandler)
-            {
-                result = OCCreateResourceWithHost(&resourceHandle, // OCResourceHandle *handle
-                        resourceTypeName.c_str(), // const char * resourceTypeName
-                        resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix
-                        resourceHOST.c_str(), // const char * host
-                        (resourceHOST + resourceURI).c_str(), // const char * uri
-                        EntityHandlerWrapper, // OCEntityHandler entityHandler
-                        resourceProperties // uint8_t resourceProperties
-                        );
-            }
-            else
-            {
-                result = OCCreateResourceWithHost(&resourceHandle, // OCResourceHandle *handle
-                        resourceTypeName.c_str(), // const char * resourceTypeName
-                        resourceInterface.c_str(), //const char * resourceInterfaceName //TODO fix
-                        resourceHOST.c_str(), // const char * host
-                        (resourceHOST + resourceURI).c_str(), // const char * uri
-                        nullptr, // OCEntityHandler entityHandler
-                        resourceProperties // uint8_t resourceProperties
-                        );
-            }
-
-            if (result != OC_STACK_OK)
-            {
-                resourceHandle = nullptr;
-            }
-            else
-            {
-                std::lock_guard<std::mutex> lock(OC::details::serverWrapperLock);
-                OC::details::entityHandlerMap[resourceHandle] = eHandler;
-                OC::details::resourceUriMap[resourceHandle] = resourceURI;
-            }
-        }
-        else
-        {
-            result = OC_STACK_ERROR;
-        }
 
-        return result;
-    }
 
     OCStackResult InProcServerWrapper::setDefaultDeviceEntityHandler
                                         (EntityHandler entityHandler)
@@ -437,12 +473,12 @@ namespace OC
 
         if(entityHandler)
         {
-            result = OCSetDefaultDeviceEntityHandler(DefaultEntityHandlerWrapper);
+            result = OCSetDefaultDeviceEntityHandler(DefaultEntityHandlerWrapper, NULL);
         }
         else
         {
             // If Null passed we unset
-            result = OCSetDefaultDeviceEntityHandler(NULL);
+            result = OCSetDefaultDeviceEntityHandler(NULL, NULL);
         }
 
         return result;
@@ -498,6 +534,28 @@ namespace OC
         return result;
     }
 
+    OCStackResult InProcServerWrapper::resetResourceTypes(const OCResourceHandle& resourceHandle,
+                     const std::string& newResourceType)
+    {
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result;
+        if(cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCResetResourceTypes(resourceHandle, newResourceType.c_str());
+        }
+        else
+        {
+            result = OC_STACK_ERROR;
+        }
+
+        if (result != OC_STACK_OK)
+        {
+            throw OCException(OC::Exception::BIND_TYPE_FAILED, result);
+        }
+        return result;
+    }
+
     OCStackResult InProcServerWrapper::bindInterfaceToResource(
                      const OCResourceHandle& resourceHandle,
                      const std::string& resourceInterfaceName)
@@ -522,8 +580,33 @@ namespace OC
         return result;
     }
 
+    OCStackResult InProcServerWrapper::resetResourceInterfaces(
+                     const OCResourceHandle& resourceHandle,
+                     const std::string& newResourceInterface)
+    {
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result;
+        if(cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCResetResourceInterfaces(resourceHandle,
+                        newResourceInterface.c_str());
+        }
+        else
+        {
+            result = OC_STACK_ERROR;
+        }
+
+        if (result != OC_STACK_OK)
+        {
+            throw OCException(OC::Exception::BIND_INTERFACE_FAILED, result);
+        }
+        return result;
+    }
+
     OCStackResult InProcServerWrapper::startPresence(const unsigned int seconds)
     {
+#ifdef WITH_PRESENCE
         auto cLock = m_csdkLock.lock();
         OCStackResult result = OC_STACK_ERROR;
         if(cLock)
@@ -537,10 +620,14 @@ namespace OC
             throw OCException(OC::Exception::START_PRESENCE_FAILED, result);
         }
         return result;
+#else
+        return OC_STACK_NOT_IMPLEMENTED;
+#endif
     }
 
     OCStackResult InProcServerWrapper::stopPresence()
     {
+#ifdef WITH_PRESENCE
         auto cLock = m_csdkLock.lock();
         OCStackResult result = OC_STACK_ERROR;
         if(cLock)
@@ -554,6 +641,9 @@ namespace OC
             throw OCException(OC::Exception::END_PRESENCE_FAILED, result);
         }
         return result;
+#else
+        return OC_STACK_NOT_IMPLEMENTED;
+#endif
     }
 
     OCStackResult InProcServerWrapper::sendResponse(
@@ -570,17 +660,15 @@ namespace OC
         else
         {
             OCEntityHandlerResponse response;
-            std::string payLoad;
-            HeaderOptions serverHeaderOptions;
-
-            payLoad = pResponse->getPayload();
-            serverHeaderOptions = pResponse->getHeaderOptions();
+//            OCRepPayload* payLoad = pResponse->getPayload();
+            HeaderOptions serverHeaderOptions = pResponse->getHeaderOptions();
 
             response.requestHandle = pResponse->getRequestHandle();
             response.resourceHandle = pResponse->getResourceHandle();
             response.ehResult = pResponse->getResponseResult();
-            response.payload = (unsigned char*) payLoad.c_str();
-            response.payloadSize = payLoad.length() + 1;
+
+            response.payload = reinterpret_cast<OCPayload*>(pResponse->getPayload());
+
             response.persistentBufferFlag = 0;
 
             response.numSendVendorSpecificHeaderOptions = serverHeaderOptions.size();
@@ -592,18 +680,20 @@ namespace OC
                     static_cast<uint16_t>(it->getOptionID());
                 response.sendVendorSpecificHeaderOptions[i].optionLength =
                     (it->getOptionData()).length() + 1;
-                memcpy(response.sendVendorSpecificHeaderOptions[i].optionData,
-                    (it->getOptionData()).c_str(),
-                    (it->getOptionData()).length() + 1);
+                std::string optionData = it->getOptionData();
+                std::copy(optionData.begin(),
+                         optionData.end(),
+                         response.sendVendorSpecificHeaderOptions[i].optionData);
+                response.sendVendorSpecificHeaderOptions[i].optionData[it->getOptionData().length()]
+                    = '\0';
                 i++;
             }
 
             if(OC_EH_RESOURCE_CREATED == response.ehResult)
             {
-                std::string createdUri = pResponse->getNewResourceUri();
-                strncpy(reinterpret_cast<char*>(response.resourceUri),
-                        createdUri.c_str(),
-                        createdUri.length() + 1);
+                pResponse->getNewResourceUri().copy(response.resourceUri,
+                        sizeof (response.resourceUri) - 1);
+                response.resourceUri[pResponse->getNewResourceUri().length()] = '\0';
             }
 
             if(cLock)
@@ -620,18 +710,67 @@ namespace OC
             {
                 oclog() << "Error sending response\n";
             }
+
+            OCPayloadDestroy(response.payload);
             return result;
         }
     }
 
-    InProcServerWrapper::~InProcServerWrapper()
+    OCStackResult InProcServerWrapper::notifyAllObservers(OCResourceHandle resourceHandle,
+                                                          QualityOfService QoS)
     {
-        if(m_processThread.joinable())
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
         {
-            m_threadRun = false;
-            m_processThread.join();
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCNotifyAllObservers(resourceHandle, static_cast<OCQualityOfService>(QoS));
         }
 
-        OCStop();
+        return result;
+    }
+
+    OCStackResult InProcServerWrapper::notifyListOfObservers(OCResourceHandle resourceHandle,
+                                               ObservationIds& observationIds,
+                                               const std::shared_ptr<OCResourceResponse> pResponse,
+                                               QualityOfService QoS)
+    {
+        if (!pResponse)
+        {
+            return OC_STACK_ERROR;
+        }
+
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+
+            OCRepPayload* pl = pResponse->getResourceRepresentation().getPayload();
+            result = OCNotifyListOfObservers(resourceHandle,
+                                             &observationIds[0],
+                                             observationIds.size(),
+                                             pl,
+                                             static_cast<OCQualityOfService>(QoS));
+            OCRepPayloadDestroy(pl);
+        }
+
+        if (result != OC_STACK_OK)
+        {
+            throw OCException(OC::Exception::NOTIFY_LIST_OBSERVERS_FAILED, result);
+        }
+        return result;
+    }
+
+    InProcServerWrapper::~InProcServerWrapper()
+    {
+        try
+        {
+            stop();
+        }
+        catch (InitializeException &e)
+        {
+            OIC_LOG_V(INFO, TAG, "Exception in stop (%s)", e.what());
+        }
     }
 }