iotivity 0.9.0
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / SensorProcessor / ContextRepository.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 "ContextRepository.h"
21
22 static inline std::string trim_both(const std::string &str)
23 {
24
25     int npos = str.find_first_not_of(" \t\v\n");
26     if (npos == -1)
27     {
28         return "";
29     }
30     unsigned int n = (unsigned int)npos;
31     std::string tempString = n == std::string::npos ? str : str.substr(n, str.length());
32
33     n = tempString.find_last_not_of(" \t\v\n");
34     return n == std::string::npos ? tempString : tempString.substr(0, n + 1);
35 }
36
37 SSMRESULT CContextRepository::finalConstruct()
38 {
39     SSMRESULT res = SSM_E_FAIL;
40
41     SSM_CLEANUP_ASSERT(CreateInstance(OID_IResourceFinder, (IBase **)&m_resourceFinder));
42     SSM_CLEANUP_ASSERT(m_resourceFinder->registerResourceFinderEvent(this));
43
44 CLEANUP:
45     return res;
46 }
47
48 SSMRESULT CContextRepository::startResourceFinder()
49 {
50     SSMRESULT res = SSM_E_FAIL;
51
52     SSM_CLEANUP_ASSERT(m_resourceFinder->startResourceFinder());
53
54 CLEANUP:
55     return res;
56 }
57
58 SSMRESULT CContextRepository::registerResourceFinderEvent(IN IResourceEvent *pResourceEvent)
59 {
60     m_resourceEvents.push_back(pResourceEvent);
61     return SSM_S_OK;
62 }
63
64 void CContextRepository::finalRelease()
65 {
66 }
67
68 SSMRESULT CContextRepository::initRepository(IN std::string name, IN std::string type,
69         IN std::string pathSoftSensors, IN std::string pathDescription)
70 {
71     SSMRESULT res = SSM_E_FAIL;
72
73     std::vector<DictionaryData> dict;
74
75     m_name = name;
76     m_type = type;
77
78     if (pathSoftSensors.length() == 0)
79     {
80         SSM_CLEANUP_ASSERT(GetCurrentPath(&m_pathSoftSensors));
81         m_pathSoftSensors.append("/");
82     }
83     else
84     {
85         m_pathSoftSensors = pathSoftSensors;
86     }
87
88     if (pathDescription.length() == 0)
89     {
90         SSM_CLEANUP_ASSERT(GetCurrentPath(&m_pathSoftSensorsDescription));
91         m_pathSoftSensorsDescription.append("/");
92         m_pathSoftSensorsDescription.append(DEFAULT_PATH_SOFT_SENSORS);
93     }
94     else
95     {
96         m_pathSoftSensorsDescription = pathDescription;
97     }
98
99
100     SSM_CLEANUP_ASSERT(loadXMLFromFile(m_pathSoftSensorsDescription.c_str(), &dict));
101     SSM_CLEANUP_ASSERT(makeSSMResourceListForDictionaryData(dict, &m_lstSoftSensor));
102
103 CLEANUP:
104     return res;
105 }
106
107 SSMRESULT CContextRepository::loadXMLFromString(char *xmlData,
108         std::vector<DictionaryData> *dataList)
109 {
110     // use  rapidxml-----------------------
111     SSMRESULT res = SSM_E_FAIL;
112     rapidxml::xml_document< char > xmlDoc;
113     //xmlDoc.parse< 0 >( &xmlData.front() );
114     xmlDoc.parse< 0 >(xmlData);
115
116     std::string keyStr;
117     std::string valueStr;
118
119     rapidxml::xml_node< char > *item;
120     rapidxml::xml_node< char > *subItem;
121     rapidxml::xml_node< char > *subItem2;
122     rapidxml::xml_node< char > *subItem3;
123
124     // get value
125     rapidxml::xml_node< char > *root = xmlDoc.first_node();
126
127     if (!root)
128     {
129         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
130     }
131
132     for ( item = root->first_node(); item; item = item->next_sibling() )
133     {
134         DictionaryData dictionaryData;
135         for ( subItem = item->first_node(); subItem ; subItem = subItem->next_sibling() )
136         {
137             //root name
138             keyStr = subItem->name();  // key
139             valueStr = subItem->value();   // value
140
141             if (!keyStr.compare("name"))
142             {
143                 dictionaryData.rootName = trim_both(valueStr);
144             }
145             ////std::cout<<keyStr << " : " << subItem->value() <<std::endl<<std::endl; //root_name
146             for (subItem2 = subItem->first_node(); subItem2 ; subItem2 = subItem2->next_sibling())
147             {
148                 std::map<std::string, std::string> propertyMap;
149                 std::vector<std::string> enterconditionVector;
150
151                 keyStr = subItem2->name();  // key
152                 valueStr = subItem2->value();   // value
153
154                 if (!keyStr.compare("input"))
155                 {
156                     dictionaryData.inputs.push_back(trim_both(valueStr));
157                 }
158                 ////std::cout<<name << " :: " << subItem2->value() <<std::endl<<std::endl;
159                 for (subItem3 = subItem2->first_node(); subItem3 ; subItem3 = subItem3->next_sibling())
160                 {
161                     std::string newKeyStr = subItem3->name();  // key
162                     valueStr = subItem3->value();   // value
163
164                     if (!keyStr.compare("attribute") || !keyStr.compare("output") )
165                     {
166                         propertyMap.insert(std::make_pair(trim_both(newKeyStr), trim_both(valueStr)));
167                     }
168                 }
169                 if (!keyStr.compare("attribute"))
170                 {
171                     dictionaryData.attributeProperty.push_back(propertyMap);
172                 }
173                 else if (!keyStr.compare("output"))
174                 {
175                     dictionaryData.outputProperty.push_back(propertyMap);
176                 }
177             }
178         }
179         //for accurate data.
180         /*
181         dictionaryData.app_input_count = std::to_string((long long)dictionaryData.app_inputs.size());
182         dictionaryData.input_count = std::to_string((long long)dictionaryData.inputs.size());
183         dictionaryData.attribute_property_count = std::to_string((long long)dictionaryData.attribute_property.size());
184         dictionaryData.output_property_count = std::to_string((long long)dictionaryData.output_property.size());
185         */
186
187         dataList->push_back(dictionaryData);
188     }
189
190     res = SSM_S_OK;
191
192 CLEANUP:
193     return res;
194 }
195
196 SSMRESULT CContextRepository::loadXMLFromFile(std::string descriptionFilePath,
197         std::vector<DictionaryData> *dataList)
198 {
199     SSMRESULT res = SSM_E_FAIL;
200     std::basic_ifstream< char > xmlFile(descriptionFilePath.c_str());
201
202     //path loaded
203     if (!xmlFile.fail())
204     {
205         xmlFile.seekg(0, std::ios::end);
206         unsigned int size = (unsigned int)xmlFile.tellg();
207         xmlFile.seekg(0);
208
209         std::vector< char > xmlData(size + 1);
210         xmlData[size] = 0;
211
212         xmlFile.read(&xmlData.front(), (std::streamsize)size);
213         xmlFile.close();
214         SSM_CLEANUP_ASSERT(loadXMLFromString(&xmlData.front(), dataList));
215     }
216     else
217     {
218         //let work with no soft sensor manager
219         res = SSM_S_OK;
220     }
221
222 CLEANUP:
223     return res;
224 }
225
226 SSMRESULT CContextRepository::getSoftSensorList(OUT std::vector<ISSMResource *> *pSoftSensorList)
227 {
228     for (size_t i = 0; i < m_lstSoftSensor.size(); i++)
229     {
230         pSoftSensorList->push_back(m_lstSoftSensor.at(i));
231     }
232
233     return SSM_S_OK;
234 }
235
236 SSMRESULT CContextRepository::getPrimitiveSensorList(OUT std::vector<ISSMResource *>
237         *pPrimitiveSensorList)
238 {
239     for (size_t i = 0; i < m_lstPrimitiveSensor.size(); i++)
240     {
241         pPrimitiveSensorList->push_back(m_lstPrimitiveSensor.at(i));
242     }
243
244     return SSM_S_OK;
245 }
246
247 SSMRESULT CContextRepository::onResourceFound(IN ISSMResource *pSensor)
248 {
249     m_lstPrimitiveSensor.push_back(pSensor);
250
251     for (size_t i = 0; i < m_resourceEvents.size(); i++)
252     {
253         m_resourceEvents.at(i)->onResourceEvent(SSM_EVENT_ADDED, pSensor, "");
254     }
255
256     return SSM_S_OK;
257 }
258
259 SSMRESULT CContextRepository::onResourceLost(IN ISSMResource *pSensor)
260 {
261     std::vector<ISSMResource *>::iterator    itor;
262     itor = std::find(m_lstPrimitiveSensor.begin(), m_lstPrimitiveSensor.end(), pSensor);
263
264     if (itor != m_lstPrimitiveSensor.end())
265     {
266         m_lstPrimitiveSensor.erase(itor);
267         return SSM_S_OK;
268     }
269
270     return SSM_E_FAIL;
271 }
272
273 SSMRESULT CContextRepository::startObserveResource(IN ISSMResource *pSensor, IN IEvent *pEvent)
274 {
275     return m_resourceFinder->startObserveResource(pSensor, pEvent);
276 }
277
278 SSMRESULT CContextRepository::stopObserveResource(IN ISSMResource *pSensor)
279 {
280     return m_resourceFinder->stopObserveResource(pSensor);
281 }
282
283 //TODO: Need to fix
284 SSMRESULT CContextRepository::makeSSMResourceListForDictionaryData(std::vector<DictionaryData>
285         dataList, std::vector<ISSMResource *> *pList)
286 {
287     SSMRESULT res = SSM_E_FAIL;
288
289     for (unsigned int i = 0 ; i < dataList.size() ; ++i)
290     {
291         ISSMResource *pResource = new ISSMResource();
292         pResource->location = SENSOR_LOCATION_LOCAL;
293         pResource->type = dataList[i].rootName;
294         pResource->name = std::string("coap://127.0.0.1/") + dataList[i].rootName;
295         pResource->ip = "coap://127.0.0.1/";
296
297         pResource->inputList = dataList[i].inputs;
298
299         for (unsigned int j = 0; j < dataList[i].outputProperty.size(); ++j)
300         {
301             pResource->outputProperty.push_back(dataList[i].outputProperty[j]);
302         }
303         for (unsigned int j = 0; j < dataList[i].attributeProperty.size(); ++j)
304         {
305             pResource->outputProperty.push_back(dataList[i].attributeProperty[j]);
306         }
307         pList->push_back(pResource);
308     }
309
310     res = SSM_S_OK;
311
312     return res;
313 }
314
315 SSMRESULT CContextRepository::loadSoftSensor(std::string softSensorName, ICtxDelegate *pDelegate,
316         void **hSoftSensor)
317 {
318     std::stringstream   sstream;
319     SSMRESULT           res = SSM_E_FAIL;
320
321     typedef void(*InitContext)(IN ICtxDelegate *);
322     InitContext InitializeContextFunction = NULL;
323
324     // load dll(so)
325
326 #ifdef WIN32
327     sstream << m_pathSoftSensors << softSensorName.c_str() << ".dll" << std::ends;
328
329     HINSTANCE hModule = NULL;
330     hModule = LoadLibraryA(sstream.str().c_str());
331
332     if (hModule != NULL)
333     {
334         InitializeContextFunction = (InitContext)GetProcAddress(hModule, "InitializeContext");
335     }
336 #else
337     //sstream << "/data/data/com.example.javaproject/lib/lib" << modelName <<".so" << std::ends;
338     sstream << m_pathSoftSensors << "lib" << softSensorName.c_str() << ".so" << std::ends;
339
340     void *hModule = NULL;
341     hModule = dlopen(sstream.str().c_str(), RTLD_LOCAL | RTLD_LAZY);
342
343     if (hModule != NULL)
344     {
345         InitializeContextFunction = (InitContext)dlsym(hModule, "InitializeContext");
346     }
347 #endif
348     if (hModule == NULL)
349     {
350         //load library failed. raise error
351         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
352     }
353
354     if (InitializeContextFunction != NULL)
355     {
356         InitializeContextFunction(pDelegate);
357         *hSoftSensor = hModule;
358         res = SSM_S_OK;
359     }
360     else
361     {
362         //Unload module and return error
363         SSM_CLEANUP_ASSERT(unloadSoftSensor(hModule));
364         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
365     }
366
367 CLEANUP:
368     return res;
369 }
370
371 SSMRESULT CContextRepository::unloadSoftSensor(void *hSoftSensor)
372 {
373     SSMRESULT           res = SSM_E_FAIL;
374
375 #ifdef WIN32
376     SSM_CLEANUP_COND_ASSERT(FreeLibrary((HINSTANCE)hSoftSensor), TRUE, "FreeLibrary failed");
377 #else
378     SSM_CLEANUP_COND_ASSERT(dlclose(hSoftSensor), 0, "dlclose failed");
379 #endif
380
381     res = SSM_S_OK;
382
383 CLEANUP:
384     return res;
385 }
386
387 SSMRESULT CContextRepository::GetCurrentPath(std::string *path)
388 {
389     char        buffer[2048];
390     SSMRESULT   res = SSM_E_FAIL;
391 #if defined(WIN32)
392     DWORD length = GetModuleFileNameA(NULL, buffer, 2047);
393
394     if (length == 0)
395     {
396         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
397     }
398
399     buffer[length] = '\0';
400     if (PathRemoveFileSpecA(buffer) == 0)
401     {
402         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
403     }
404
405 #elif defined(LINUX)
406     char    *strPath = NULL;
407     int length = ::readlink("/proc/self/exe", buffer, 2047);
408
409     if (length == -1)
410     {
411         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
412     }
413
414     buffer[length] = '\0';
415
416     strPath = strrchr(buffer, '/');
417
418     if (strPath == NULL)
419     {
420         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
421     }
422
423     *strPath = '\0';
424 #endif
425
426     path->append(buffer);
427     res = SSM_S_OK;
428
429 CLEANUP:
430     return res;
431 }