update soft sensor manager into latest version before CA merging
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / SensorProcessor / ResourceFinder.cpp
index 278937e..8f84e34 100644 (file)
@@ -1,36 +1,41 @@
 /******************************************************************
-*
-* Copyright 2014 Samsung Electronics All Rights Reserved.
-*
-*
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************/
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
 #include "ResourceFinder.h"
 
 SSMRESULT CResourceFinder::finalConstruct()
 {
-       SSMRESULT res = SSM_E_FAIL;
+    SSMRESULT res = SSM_E_FAIL;
 
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase**)&m_pTasker));
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IResourceConnectivity, (IBase**)&m_pResourceConnectivity));
+    OC::PlatformConfig cfg(OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0,
+                           OC::QualityOfService::LowQos);
 
-       m_pResourceFinderEvent = NULL;
-       m_pPlatform = (OC::OCPlatform*)m_pResourceConnectivity->getPlatform();
+    SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase **)&m_pTasker));
+
+    OC::OCPlatform::Configure(cfg);
+
+    m_pResourceFinderEvent = NULL;
+
+    m_multicastPresenceHandle = nullptr;
 
 CLEANUP:
-       return res;
+    return res;
 }
 
 void CResourceFinder::finalRelease()
@@ -39,84 +44,228 @@ void CResourceFinder::finalRelease()
 
 SSMRESULT CResourceFinder::registerResourceFinderEvent(IN IResourceFinderEvent *pEvent)
 {
-       m_pResourceFinderEvent = pEvent;
-       return SSM_S_OK;
+    m_pResourceFinderEvent = pEvent;
+    return SSM_S_OK;
 }
 
-void CResourceFinder::onResourceFound(std::shared_ptr<OC::OCResource> resource)
+void CResourceFinder::onResourceFound(std::shared_ptr< OC::OCResource > resource)
 {
-       if (resource)
-       {
-               int             *pMessage = new int[2];
-               pMessage[0] = RESOURCE_DISCOVER_REQUESTPROFILE;
-               pMessage[1] = (int)new std::shared_ptr<OC::OCResource>(resource);
-
-               m_pTasker->addTask(this, pMessage);
-       }
+    if (resource)
+    {
+        std::string path = resource->host() + resource->uri();
+
+        if (m_mapResourceHandler.find(path) != m_mapResourceHandler.end())
+            return;
+
+        intptr_t      *pMessage = new intptr_t [2];
+        pMessage[0] = RESOURCE_DISCOVER_REQUESTPROFILE;
+        pMessage[1] = reinterpret_cast<intptr_t> (new  std::shared_ptr<OC::OCResource>(resource));
+
+        m_pTasker->addTask(this, pMessage);
+    }
+}
+
+void CResourceFinder::presenceHandler(OCStackResult result, const unsigned int nonce,
+                                      const std::string &hostAddress)
+{
+    SSMRESULT res = SSM_E_FAIL;
+    OCStackResult ret = OC_STACK_ERROR;
+    intptr_t *pMessage = NULL;
+    std::ostringstream requestURI;
+
+    switch (result)
+    {
+        case OC_STACK_OK:
+            requestURI << "coap://" << hostAddress << ":" << OC_MULTICAST_PORT <<
+                       "/oc/core?rt=SoftSensorManager.Sensor";
+
+            ret = OC::OCPlatform::findResource("", requestURI.str(), OC_WIFI,
+                                               std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
+
+            if (ret != OC_STACK_OK)
+                SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+            break;
+
+        case OC_STACK_PRESENCE_STOPPED:
+        case OC_STACK_PRESENCE_TIMEOUT:
+            if (m_mapResources.find(hostAddress) != m_mapResources.end())
+            {
+                while (!m_mapResources[hostAddress].empty())
+                {
+                    pMessage = new intptr_t[2];
+                    pMessage[0] = RESOURCE_DISCOVER_UNINSTALL_RESOURCE;
+                    pMessage[1] = reinterpret_cast<intptr_t> (m_mapResourceHandler[m_mapResources[hostAddress].back()]);
+                    m_mapResources[hostAddress].pop_back();
+                    m_pTasker->addTask(this, pMessage);
+                }
+
+                m_mapResources.erase(hostAddress);
+            }
+            break;
+
+        case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
+            break;
+
+        default:
+            break;
+    }
+
+CLEANUP:
+    ;
 }
 
 SSMRESULT CResourceFinder::startResourceFinder()
 {
-       //m_pPlatform->findResource("", "oc/core/service/SoftSensorManager/SoftSensor",
-       m_pPlatform->findResource("", "coap://224.0.1.187/oc/core?rt=SoftSensorManager.Sensor",
-               std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
+    SSMRESULT res = SSM_E_FAIL;
+    OCStackResult ret = OC_STACK_ERROR;
+
+    std::ostringstream requestURI;
+    requestURI << OC_WELL_KNOWN_QUERY << "?rt=SoftSensorManager.Sensor";
+
+    ret = OC::OCPlatform::findResource("", requestURI.str(), OC_WIFI,
+                                       std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
+
+    if (ret != OC_STACK_OK)
+        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+    ret = OC::OCPlatform::subscribePresence(m_multicastPresenceHandle, OC_MULTICAST_IP,
+                                            "SoftSensorManager.Sensor", OC_WIFI, std::bind(&CResourceFinder::presenceHandler, this,
+                                                    std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+
+    if (ret != OC_STACK_OK)
+        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+    res = SSM_S_OK;
+
+CLEANUP:
+    return res;
+}
+
+SSMRESULT CResourceFinder::stopResourceFinder()
+{
+    SSMRESULT res = SSM_E_FAIL;
+    OCStackResult ret = OC_STACK_ERROR;
+
+    ret = OC::OCPlatform::unsubscribePresence(m_multicastPresenceHandle);
+
+    if (ret != OC_STACK_OK)
+        SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+    m_multicastPresenceHandle = nullptr;
+
+    res = SSM_S_OK;
 
-       return SSM_S_OK;
+CLEANUP:
+    return res;
 }
 
 SSMRESULT CResourceFinder::startObserveResource(IN ISSMResource *pSensor, IN IEvent *pEvent)
 {
-       return m_mapResourceHandler[pSensor->name]->startObserve(pEvent);
+    return m_mapResourceHandler[pSensor->name]->startObserve(pEvent);
 }
 
 SSMRESULT CResourceFinder::stopObserveResource(IN ISSMResource *pSensor)
 {
-       return m_mapResourceHandler[pSensor->name]->stopObserve();
+    return m_mapResourceHandler[pSensor->name]->stopObserve();
 }
 
-void CResourceFinder::onExecute(IN voidpArg)
+void CResourceFinder::onExecute(IN void *pArg)
 {
-       SSMRESULT res = SSM_E_FAIL;
-       OC::QueryParamsMap      queryParams;
-       OICResourceHandler      *pResourceHandler = NULL;
-       int                                     *pMessage = (int*)pArg;
-       std::shared_ptr<OC::OCResource> *pResource = NULL;
-
-       switch (pMessage[0])
-       {
-       case RESOURCE_DISCOVER_REQUESTPROFILE:
-               pResource = (std::shared_ptr<OC::OCResource>*)pMessage[1];
-               pResourceHandler = new OICResourceHandler();
-               SSM_CLEANUP_ASSERT(pResourceHandler->initHandler(*pResource, this));
-               m_mapResourceHandler[pResource->get()->host() + pResource->get()->uri()] = pResourceHandler;
-               pResource->get()->get(queryParams, std::bind(&OICResourceHandler::onGetResourceProfile,
-                       pResourceHandler, std::placeholders::_1, std::placeholders::_2));
-               break;
-
-       case RESOURCE_DISCOVER_SETUP_RESOURCE:
-               m_pResourceFinderEvent->onResourceFound((ISSMResource*)pMessage[1]);
-               break;
-       }
+    SSMRESULT res = SSM_E_FAIL;
+    OCStackResult ret = OC_STACK_ERROR;
+    OC::QueryParamsMap queryParams;
+    OICResourceHandler *pResourceHandler = NULL;
+    intptr_t                 *pMessage = reinterpret_cast<intptr_t *>(pArg);
+    std::shared_ptr< OC::OCResource > *pResource = NULL;
+    OC::OCPlatform::OCPresenceHandle presenceHandle = NULL;
+
+    std::string resourceHostAddress = "";
+    std::string resourceFullPath = "";
+
+    switch (pMessage[0])
+    {
+        case RESOURCE_DISCOVER_REQUESTPROFILE:
+            pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
+            pResourceHandler = new OICResourceHandler();
+            SSM_CLEANUP_ASSERT(pResourceHandler->initHandler(*pResource, this));
+
+            resourceFullPath = pResource->get()->host() + pResource->get()->uri();
+
+            resourceHostAddress = pResource->get()->host();
+            resourceHostAddress.erase(0, 7);        // erase 'coap://'
+
+            m_mapResourceHandler[resourceFullPath] = pResourceHandler;
+
+            m_mapResources[resourceHostAddress].push_back(resourceFullPath);
+
+            ret = pResource->get()->get(queryParams, std::bind(&OICResourceHandler::onGetResourceProfile,
+                                        pResourceHandler, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+
+            if (ret != OC_STACK_OK)
+                SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+            break;
+
+        case RESOURCE_DISCOVER_INSTALL_RESOURCE:
+            if (m_mapResourcePresenceHandles.find(((ISSMResource *)pMessage[1])->ip) ==
+                m_mapResourcePresenceHandles.end())
+            {
+                ret = OC::OCPlatform::subscribePresence(presenceHandle, ((ISSMResource *)pMessage[1])->ip,
+                                                        "SoftSensorManager.Sensor", OC_WIFI, std::bind(&CResourceFinder::presenceHandler, this,
+                                                                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+
+                if (ret != OC_STACK_OK)
+                    SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+                m_mapResourcePresenceHandles[((ISSMResource *)pMessage[1])->ip] = presenceHandle;
+            }
+
+            m_pResourceFinderEvent->onResourceFound((ISSMResource *) pMessage[1]);
+            break;
+
+        case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
+            m_pResourceFinderEvent->onResourceLost(&((OICResourceHandler *) pMessage[1])->m_SSMResource);
+
+            if (m_mapResourcePresenceHandles.find(((OICResourceHandler *)pMessage[1])->m_SSMResource.ip) !=
+                m_mapResourcePresenceHandles.end())
+            {
+                ret = OC::OCPlatform::unsubscribePresence(m_mapResourcePresenceHandles[((
+                            OICResourceHandler *)pMessage[1])->m_SSMResource.ip]);
+
+                if (ret != OC_STACK_OK)
+                    SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+
+                m_mapResourcePresenceHandles.erase(((OICResourceHandler *)pMessage[1])->m_SSMResource.ip);
+            }
+
+            delete m_mapResourceHandler[((OICResourceHandler *)pMessage[1])->m_SSMResource.name];
+            m_mapResourceHandler.erase(((OICResourceHandler *) pMessage[1])->m_SSMResource.name);
+            break;
+    }
 
 CLEANUP:
-       ;
+    ;
 }
 
-void CResourceFinder::onTerminate(IN voidpArg)
+void CResourceFinder::onTerminate(IN void *pArg)
 {
-       std::shared_ptr<OC::OCResource>         *pResource = NULL;
-       int                                     *pMessage = (int*)pArg;
+    std::shared_ptr< OC::OCResource > *pResource = NULL;
+    intptr_t *pMessage = (intptr_t *)pArg;
+
+    switch (pMessage[0])
+    {
+        case RESOURCE_DISCOVER_REQUESTPROFILE:
+            pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
+            delete pResource;
+            break;
 
-       switch (pMessage[0])
-       {
-       case RESOURCE_DISCOVER_REQUESTPROFILE:
-               pResource = (std::shared_ptr<OC::OCResource>*)pMessage[1];
-               delete pResource;
-               break;
+        case RESOURCE_DISCOVER_INSTALL_RESOURCE:
+            break;
 
-       case RESOURCE_DISCOVER_SETUP_RESOURCE:
-               break;
-       }
+        case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
+            break;
+    }
 
-       delete[] pMessage;
+    delete[] pMessage;
 }