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