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