7541ee76cd6f8d29d69df5f424edafb1e7fb9fd3
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / SensorProcessor / ResourceFinder.cpp
1 /******************************************************************
2  *
3  * Copyright 2014 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 #include "ResourceFinder.h"
21
22 SSMRESULT CResourceFinder::finalConstruct()
23 {
24     SSMRESULT res = SSM_E_FAIL;
25
26     OC::PlatformConfig cfg(OC::ServiceType::InProc, OC::ModeType::Both, "0.0.0.0", 0,
27                            OC::QualityOfService::LowQos);
28
29     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase **)&m_pTasker));
30
31     OC::OCPlatform::Configure(cfg);
32
33     m_pResourceFinderEvent = NULL;
34
35     m_multicastPresenceHandle = nullptr;
36
37 CLEANUP:
38     return res;
39 }
40
41 void CResourceFinder::finalRelease()
42 {
43 }
44
45 SSMRESULT CResourceFinder::registerResourceFinderEvent(IResourceFinderEvent *pEvent)
46 {
47     m_pResourceFinderEvent = pEvent;
48     return SSM_S_OK;
49 }
50
51 void CResourceFinder::onResourceFound(std::shared_ptr< OC::OCResource > resource)
52 {
53     if (resource)
54     {
55         std::string path = resource->host() + resource->uri();
56
57         if (m_mapResourceHandler.find(path) != m_mapResourceHandler.end())
58             return;
59
60         intptr_t      *pMessage = new intptr_t [2];
61         pMessage[0] = RESOURCE_DISCOVER_REQUESTPROFILE;
62         pMessage[1] = reinterpret_cast<intptr_t> (new  std::shared_ptr<OC::OCResource>(resource));
63
64         m_pTasker->addTask(this, pMessage);
65     }
66 }
67
68 void CResourceFinder::presenceHandler(OCStackResult result, const unsigned int nonce,
69                                       const std::string &hostAddress)
70 {
71     SSMRESULT res = SSM_E_FAIL;
72     OCStackResult ret = OC_STACK_ERROR;
73     intptr_t *pMessage = NULL;
74     std::ostringstream requestURI;
75
76     switch (result)
77     {
78         case OC_STACK_OK:
79             requestURI << "coap://" << hostAddress << "/oc/core?rt=SSManager.Sensor";
80
81             ret = OC::OCPlatform::findResource("", requestURI.str(), OC_ALL,
82                                                std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
83
84             if (ret != OC_STACK_OK)
85                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
86
87             break;
88
89         case OC_STACK_PRESENCE_STOPPED:
90             if (m_mapResources.find(hostAddress) != m_mapResources.end())
91             {
92                 while (!m_mapResources[hostAddress].empty())
93                 {
94                     pMessage = new intptr_t[2];
95                     pMessage[0] = RESOURCE_DISCOVER_UNINSTALL_RESOURCE;
96                     pMessage[1] = reinterpret_cast<intptr_t> (m_mapResourceHandler[m_mapResources[hostAddress].back()]);
97                     m_mapResources[hostAddress].pop_back();
98                     m_pTasker->addTask(this, pMessage);
99                 }
100
101                 m_mapResources.erase(hostAddress);
102             }
103             break;
104
105         case OC_STACK_PRESENCE_TIMEOUT:
106             break;
107
108         case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
109             break;
110
111         default:
112             break;
113     }
114
115 CLEANUP:
116     ;
117 }
118
119 SSMRESULT CResourceFinder::startResourceFinder()
120 {
121     SSMRESULT res = SSM_E_FAIL;
122     OCStackResult ret = OC_STACK_ERROR;
123
124     std::ostringstream requestURI;
125     requestURI << OC_MULTICAST_DISCOVERY_URI << "?rt=SSManager.Sensor";
126
127     std::ostringstream multicastPresenceURI;
128     multicastPresenceURI << "coap://" << OC_MULTICAST_PREFIX;
129
130     ret = OC::OCPlatform::findResource("", requestURI.str(), OC_ALL,
131                                        std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
132
133     if (ret != OC_STACK_OK)
134         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
135
136     ret = OC::OCPlatform::subscribePresence(m_multicastPresenceHandle, multicastPresenceURI.str(),
137                                             "SSManager.Sensor", OC_ALL, std::bind(&CResourceFinder::presenceHandler, this,
138                                                     std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
139
140     if (ret != OC_STACK_OK)
141         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
142
143     res = SSM_S_OK;
144
145 CLEANUP:
146     return res;
147 }
148
149 SSMRESULT CResourceFinder::stopResourceFinder()
150 {
151     SSMRESULT res = SSM_E_FAIL;
152     OCStackResult ret = OC_STACK_ERROR;
153
154     ret = OC::OCPlatform::unsubscribePresence(m_multicastPresenceHandle);
155
156     if (ret != OC_STACK_OK)
157         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
158
159     m_multicastPresenceHandle = nullptr;
160
161     res = SSM_S_OK;
162
163 CLEANUP:
164     return res;
165 }
166
167 SSMRESULT CResourceFinder::startObserveResource(ISSMResource *pSensor, IEvent *pEvent)
168 {
169     return m_mapResourceHandler[pSensor->name]->startObserve(pEvent);
170 }
171
172 SSMRESULT CResourceFinder::stopObserveResource(ISSMResource *pSensor)
173 {
174     return m_mapResourceHandler[pSensor->name]->stopObserve();
175 }
176
177 void CResourceFinder::onExecute(void *pArg)
178 {
179     SSMRESULT res = SSM_E_FAIL;
180     OCStackResult ret = OC_STACK_ERROR;
181     OC::QueryParamsMap queryParams;
182     OICResourceHandler *pResourceHandler = NULL;
183     intptr_t                 *pMessage = reinterpret_cast<intptr_t *>(pArg);
184     std::shared_ptr< OC::OCResource > *pResource = NULL;
185     OC::OCPlatform::OCPresenceHandle presenceHandle = NULL;
186
187     std::string resourceHostAddress = "";
188     std::string resourceFullPath = "";
189
190     switch (pMessage[0])
191     {
192         case RESOURCE_DISCOVER_REQUESTPROFILE:
193             pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
194             pResourceHandler = new OICResourceHandler();
195             SSM_CLEANUP_ASSERT(pResourceHandler->initHandler(*pResource, this));
196
197             resourceFullPath = pResource->get()->host() + pResource->get()->uri();
198
199             resourceHostAddress = pResource->get()->host();
200             resourceHostAddress.erase(0, 7);        // erase 'coap://'
201
202             m_mapResourceHandler[resourceFullPath] = pResourceHandler;
203
204             m_mapResources[resourceHostAddress].push_back(resourceFullPath);
205
206             ret = pResource->get()->get(queryParams, std::bind(&OICResourceHandler::onGetResourceProfile,
207                                         pResourceHandler, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
208
209             if (ret != OC_STACK_OK)
210                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
211
212             break;
213
214         case RESOURCE_DISCOVER_INSTALL_RESOURCE:
215             if (m_mapResourcePresenceHandles.find(((ISSMResource *)pMessage[1])->ip) ==
216                 m_mapResourcePresenceHandles.end())
217             {
218                 ret = OC::OCPlatform::subscribePresence(presenceHandle, ((ISSMResource *)pMessage[1])->ip,
219                                                         "SSManager.Sensor", OC_ALL, std::bind(&CResourceFinder::presenceHandler, this,
220                                                                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
221
222                 if (ret != OC_STACK_OK)
223                     SSM_CLEANUP_ASSERT(SSM_E_FAIL);
224
225                 m_mapResourcePresenceHandles[((ISSMResource *)pMessage[1])->ip] = presenceHandle;
226             }
227
228             m_pResourceFinderEvent->onResourceFound((ISSMResource *)pMessage[1]);
229
230             if (ret != OC_STACK_OK)
231                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
232
233             break;
234
235         case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
236             m_pResourceFinderEvent->onResourceLost(&((OICResourceHandler *) pMessage[1])->m_SSMResource);
237
238             if (m_mapResourcePresenceHandles.find(((OICResourceHandler *)pMessage[1])->m_SSMResource.ip) !=
239                 m_mapResourcePresenceHandles.end())
240             {
241                 ret = OC::OCPlatform::unsubscribePresence(m_mapResourcePresenceHandles[((
242                             OICResourceHandler *)pMessage[1])->m_SSMResource.ip]);
243
244                 if (ret != OC_STACK_OK)
245                     SSM_CLEANUP_ASSERT(SSM_E_FAIL);
246
247                 m_mapResourcePresenceHandles.erase(((OICResourceHandler *)pMessage[1])->m_SSMResource.ip);
248             }
249
250             delete m_mapResourceHandler[((OICResourceHandler *)pMessage[1])->m_SSMResource.name];
251             m_mapResourceHandler.erase(((OICResourceHandler *) pMessage[1])->m_SSMResource.name);
252             break;
253     }
254
255 CLEANUP:
256     ;
257 }
258
259 void CResourceFinder::onTerminate(void *pArg)
260 {
261     std::shared_ptr< OC::OCResource > *pResource = NULL;
262     intptr_t *pMessage = (intptr_t *)pArg;
263
264     switch (pMessage[0])
265     {
266         case RESOURCE_DISCOVER_REQUESTPROFILE:
267             pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
268             delete pResource;
269             break;
270
271         case RESOURCE_DISCOVER_INSTALL_RESOURCE:
272             break;
273
274         case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
275             break;
276     }
277
278     delete[] pMessage;
279 }