Merge branch 'connectivity-abstraction' to master
[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(IN 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_MULTICAST_PORT <<
80                        "/oc/core?rt=SoftSensorManager.Sensor";
81
82             ret = OC::OCPlatform::findResource("", requestURI.str(), OC_ETHERNET,
83                                                std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
84
85             if (ret != OC_STACK_OK)
86                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
87
88             ret = OC::OCPlatform::findResource("", requestURI.str(), OC_WIFI,
89                                                std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
90
91             if (ret != OC_STACK_OK)
92                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
93
94             break;
95
96         case OC_STACK_PRESENCE_STOPPED:
97         case OC_STACK_PRESENCE_TIMEOUT:
98             if (m_mapResources.find(hostAddress) != m_mapResources.end())
99             {
100                 while (!m_mapResources[hostAddress].empty())
101                 {
102                     pMessage = new intptr_t[2];
103                     pMessage[0] = RESOURCE_DISCOVER_UNINSTALL_RESOURCE;
104                     pMessage[1] = reinterpret_cast<intptr_t> (m_mapResourceHandler[m_mapResources[hostAddress].back()]);
105                     m_mapResources[hostAddress].pop_back();
106                     m_pTasker->addTask(this, pMessage);
107                 }
108
109                 m_mapResources.erase(hostAddress);
110             }
111             break;
112
113         case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
114             break;
115
116         default:
117             break;
118     }
119
120 CLEANUP:
121     ;
122 }
123
124 SSMRESULT CResourceFinder::startResourceFinder()
125 {
126     SSMRESULT res = SSM_E_FAIL;
127     OCStackResult ret = OC_STACK_ERROR;
128
129     std::ostringstream requestURI;
130     requestURI << OC_WELL_KNOWN_QUERY << "?rt=SoftSensorManager.Sensor";
131
132     ret = OC::OCPlatform::findResource("", requestURI.str(), OC_ETHERNET,
133                                        std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
134
135     if (ret != OC_STACK_OK)
136         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
137
138     ret = OC::OCPlatform::findResource("", requestURI.str(), OC_WIFI,
139                                        std::bind(&CResourceFinder::onResourceFound, this, std::placeholders::_1));
140
141     if (ret != OC_STACK_OK)
142         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
143
144     ret = OC::OCPlatform::subscribePresence(m_multicastPresenceHandle, OC_MULTICAST_IP,
145                                             "SoftSensorManager.Sensor", OC_ETHERNET, std::bind(&CResourceFinder::presenceHandler, this,
146                                                     std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
147
148     if (ret != OC_STACK_OK)
149         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
150
151     ret = OC::OCPlatform::subscribePresence(m_multicastPresenceHandle, OC_MULTICAST_IP,
152                                             "SoftSensorManager.Sensor", OC_WIFI, std::bind(&CResourceFinder::presenceHandler, this,
153                                                     std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
154
155     if (ret != OC_STACK_OK)
156         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
157
158     res = SSM_S_OK;
159
160 CLEANUP:
161     return res;
162 }
163
164 SSMRESULT CResourceFinder::stopResourceFinder()
165 {
166     SSMRESULT res = SSM_E_FAIL;
167     OCStackResult ret = OC_STACK_ERROR;
168
169     ret = OC::OCPlatform::unsubscribePresence(m_multicastPresenceHandle);
170
171     if (ret != OC_STACK_OK)
172         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
173
174     m_multicastPresenceHandle = nullptr;
175
176     res = SSM_S_OK;
177
178 CLEANUP:
179     return res;
180 }
181
182 SSMRESULT CResourceFinder::startObserveResource(IN ISSMResource *pSensor, IN IEvent *pEvent)
183 {
184     return m_mapResourceHandler[pSensor->name]->startObserve(pEvent);
185 }
186
187 SSMRESULT CResourceFinder::stopObserveResource(IN ISSMResource *pSensor)
188 {
189     return m_mapResourceHandler[pSensor->name]->stopObserve();
190 }
191
192 void CResourceFinder::onExecute(IN void *pArg)
193 {
194     SSMRESULT res = SSM_E_FAIL;
195     OCStackResult ret = OC_STACK_ERROR;
196     OC::QueryParamsMap queryParams;
197     OICResourceHandler *pResourceHandler = NULL;
198     intptr_t                 *pMessage =  reinterpret_cast<intptr_t *>(pArg);
199     std::shared_ptr< OC::OCResource > *pResource = NULL;
200     OC::OCPlatform::OCPresenceHandle presenceHandle = NULL;
201
202     std::string resourceHostAddress = "";
203     std::string resourceFullPath = "";
204
205     switch (pMessage[0])
206     {
207         case RESOURCE_DISCOVER_REQUESTPROFILE:
208             pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
209             pResourceHandler = new OICResourceHandler();
210             SSM_CLEANUP_ASSERT(pResourceHandler->initHandler(*pResource, this));
211
212             resourceFullPath = pResource->get()->host() + pResource->get()->uri();
213
214             resourceHostAddress = pResource->get()->host();
215             resourceHostAddress.erase(0, 7);        // erase 'coap://'
216
217             m_mapResourceHandler[resourceFullPath] = pResourceHandler;
218
219             m_mapResources[resourceHostAddress].push_back(resourceFullPath);
220
221             ret = pResource->get()->get(queryParams, std::bind(&OICResourceHandler::onGetResourceProfile,
222                                         pResourceHandler, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
223
224             if (ret != OC_STACK_OK)
225                 SSM_CLEANUP_ASSERT(SSM_E_FAIL);
226
227             break;
228
229         case RESOURCE_DISCOVER_INSTALL_RESOURCE:
230             if (m_mapResourcePresenceHandles.find(((ISSMResource *)pMessage[1])->ip) ==
231                 m_mapResourcePresenceHandles.end())
232             {
233                 ret = OC::OCPlatform::subscribePresence(presenceHandle, ((ISSMResource *)pMessage[1])->ip,
234                                                         "SoftSensorManager.Sensor", OC_ETHERNET, std::bind(&CResourceFinder::presenceHandler, this,
235                                                                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
236
237                 if (ret != OC_STACK_OK)
238                     SSM_CLEANUP_ASSERT(SSM_E_FAIL);
239
240                 ret = OC::OCPlatform::subscribePresence(presenceHandle, ((ISSMResource *)pMessage[1])->ip,
241                                                         "SoftSensorManager.Sensor", OC_WIFI, std::bind(&CResourceFinder::presenceHandler, this,
242                                                                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
243
244                 if (ret != OC_STACK_OK)
245                     SSM_CLEANUP_ASSERT(SSM_E_FAIL);
246
247                 m_mapResourcePresenceHandles[((ISSMResource *)pMessage[1])->ip] = presenceHandle;
248             }
249
250             m_pResourceFinderEvent->onResourceFound((ISSMResource *) pMessage[1]);
251             break;
252
253         case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
254             m_pResourceFinderEvent->onResourceLost(&((OICResourceHandler *) pMessage[1])->m_SSMResource);
255
256             if (m_mapResourcePresenceHandles.find(((OICResourceHandler *)pMessage[1])->m_SSMResource.ip) !=
257                 m_mapResourcePresenceHandles.end())
258             {
259                 ret = OC::OCPlatform::unsubscribePresence(m_mapResourcePresenceHandles[((
260                             OICResourceHandler *)pMessage[1])->m_SSMResource.ip]);
261
262                 if (ret != OC_STACK_OK)
263                     SSM_CLEANUP_ASSERT(SSM_E_FAIL);
264
265                 m_mapResourcePresenceHandles.erase(((OICResourceHandler *)pMessage[1])->m_SSMResource.ip);
266             }
267
268             m_mapResourceHandler.erase(((OICResourceHandler *) pMessage[1])->m_SSMResource.name);
269             break;
270     }
271
272 CLEANUP:
273     ;
274 }
275
276 void CResourceFinder::onTerminate(IN void *pArg)
277 {
278     std::shared_ptr< OC::OCResource > *pResource = NULL;
279     intptr_t *pMessage = (intptr_t *)pArg;
280
281     switch (pMessage[0])
282     {
283         case RESOURCE_DISCOVER_REQUESTPROFILE:
284             pResource = (std::shared_ptr< OC::OCResource > *) pMessage[1];
285             delete pResource;
286             break;
287
288         case RESOURCE_DISCOVER_INSTALL_RESOURCE:
289             break;
290
291         case RESOURCE_DISCOVER_UNINSTALL_RESOURCE:
292             break;
293     }
294
295     delete[] pMessage;
296 }