72a5b07197cac49a82a0d039f5ed51bdb23b2031
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / QueryProcessor / ContextModel.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 "ContextModel.h"
21 #include "ConditionedModel.h"
22
23 SSMRESULT CContextModel::finalConstruct()
24 {
25     SSMRESULT res = SSM_E_FAIL;
26     ModelProperty       defaultModelProperty;
27
28     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase **)&m_pTasker));
29
30     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IEvaluationEngine, (IBase **)&m_pEvaluationEngine));
31
32     m_modelId = 0;
33
34     m_pContextModelEvent = NULL;
35
36     m_activationCount = 0;
37
38     m_constructionType = CONSTRUCTION_TYPE_INTERNAL;
39
40     m_secLifeTime = "2147483647";
41
42     defaultModelProperty.propertyName = "dataId";
43     defaultModelProperty.propertyType = ModelProperty::TYPE_INTEGER;
44     m_modelProperties.push_back(defaultModelProperty);
45
46     defaultModelProperty.propertyName = "lastTime";
47     defaultModelProperty.propertyType = ModelProperty::TYPE_INTEGER;
48     m_modelProperties.push_back(defaultModelProperty);
49
50     defaultModelProperty.propertyName = "lifetime";
51     defaultModelProperty.propertyType = ModelProperty::TYPE_INTEGER;
52     m_modelProperties.push_back(defaultModelProperty);
53
54     defaultModelProperty.propertyName = "available";
55     defaultModelProperty.propertyType = ModelProperty::TYPE_TEXT;
56     m_modelProperties.push_back(defaultModelProperty);
57
58 CLEANUP:
59     return res;
60 }
61
62 void CContextModel::finalRelease()
63 {
64     SSMRESULT       res = SSM_E_FAIL;
65     std::map<int, IntVec>::iterator     itorDeviceId = m_mapDeviceDataIds.begin();
66     m_pContextModelEvent = NULL;
67
68     for (unsigned int i = 0; i < m_mapDeviceDataIds.size(); i++)
69     {
70         //Other Device
71         if (itorDeviceId->first > 1)
72         {
73             for (unsigned int j = 0; j < itorDeviceId->second.size(); j++)
74             {
75                 SSM_CLEANUP_ASSERT(deleteModelData(itorDeviceId->second[j]));
76             }
77         }
78
79         itorDeviceId++;
80     }
81
82     //for(std::vector<IConditionedModel*>::iterator itor = m_ConditionedModels.begin();
83     //  itor != m_ConditionedModels.end(); ++itor)
84     //{
85     //  (*itor)->Release();
86     //}
87
88 CLEANUP:
89     return;
90 }
91
92 void CContextModel::registerSSMResource(ActivationType activationType, int targetDeviceDataId,
93                                         ISSMResource *pSSMResource)
94 {
95     intptr_t     *pData = NULL;
96
97     m_mtxActivationCount.lock();
98     switch (activationType)
99     {
100         case ACTIVATION_TYPE_SUBSCRIBE:
101             if (m_mapSubscribedDevice.find(targetDeviceDataId) == m_mapSubscribedDevice.end())
102             {
103                 pData = new intptr_t  [2];
104                 pData[0] = STATUS_ACTIVATE;
105                 pData[1] = reinterpret_cast<intptr_t>(pSSMResource);
106                 m_pTasker->addTask(this, (void *)pData);
107                 m_mapSubscribedDevice[targetDeviceDataId] = 1;
108             }
109             else
110             {
111                 m_mapSubscribedDevice[targetDeviceDataId]++;
112             }
113             break;
114
115         case ACTIVATION_TYPE_GET:
116             if (m_mapSubscribedDevice.find(targetDeviceDataId) == m_mapSubscribedDevice.end())
117             {
118                 if (m_mapGetDevice.find(targetDeviceDataId) == m_mapGetDevice.end())
119                 {
120                     pData = new intptr_t[2];
121                     pData[0] = STATUS_START_READ_VALUE;
122                     pData[1] = reinterpret_cast<intptr_t>(pSSMResource);
123                     m_pTasker->addTask(this, (void *)pData);
124                     m_mapGetDevice[targetDeviceDataId] = 1;
125                 }
126                 else
127                 {
128                     m_mapGetDevice[targetDeviceDataId]++;
129                 }
130             }
131             break;
132
133         default:
134             break;
135     }
136     m_mtxActivationCount.unlock();
137 }
138
139 void CContextModel::unregisterSSMResource(ActivationType activationType,
140         int targetDeviceDataId, ISSMResource *pSSMResource)
141 {
142     intptr_t     *pData = NULL;
143
144     m_mtxActivationCount.lock();
145     switch (activationType)
146     {
147         case ACTIVATION_TYPE_SUBSCRIBE:
148             if (m_mapSubscribedDevice.find(targetDeviceDataId) != m_mapSubscribedDevice.end())
149             {
150                 if (--m_mapSubscribedDevice[targetDeviceDataId] == 0)
151                 {
152                     pData = new intptr_t [2];
153                     pData[0] = STATUS_DEACTIVATE;
154                     pData[1] = reinterpret_cast<intptr_t>(pSSMResource);
155                     m_pTasker->addTask(this, (void *)pData);
156                     m_mapSubscribedDevice.erase(targetDeviceDataId);
157                 }
158             }
159             break;
160
161         case ACTIVATION_TYPE_GET:
162             if (m_mapGetDevice.find(targetDeviceDataId) != m_mapGetDevice.end())
163             {
164                 if (--m_mapGetDevice[targetDeviceDataId] == 0)
165                 {
166                     pData = new intptr_t [2];
167                     pData[0] = STATUS_STOP_READ_VALUE;
168                     pData[1] = reinterpret_cast<intptr_t>(pSSMResource);
169                     m_pTasker->addTask(this, (void *)pData);
170                 }
171             }
172             break;
173
174         default:
175             break;
176     }
177     m_mtxActivationCount.unlock();
178 }
179
180 SSMRESULT CContextModel::create(ConstructionType constructionType,
181                                 IContextModel *pParentModel, std::string modelName, ModelPropertyVec *pModelProperties)
182 {
183     SSMRESULT res = SSM_E_FAIL;
184     int         modelId = 1;
185
186     if (pParentModel)
187     {
188         SSM_CLEANUP_ASSERT(pParentModel->queryInterface(OID_IContextModel, (IBase **)&m_pParentModel));
189         modelId = pParentModel->getModelId();
190     }
191
192     m_constructionType = constructionType;
193     m_modelName = modelName;
194
195     SSM_CLEANUP_ASSERT(m_pEvaluationEngine->createModel(modelId, modelName.c_str(), pModelProperties,
196                        &m_modelId));
197
198     for (ModelPropertyVec::iterator itor = pModelProperties->begin();
199          itor != pModelProperties->end(); ++itor)
200     {
201         m_modelProperties.push_back(*itor);
202     }
203
204 CLEANUP:
205     return res;
206 }
207
208 SSMRESULT CContextModel::registerContextModelEvent(IContextModelEvent *pContextModelEvent)
209 {
210     m_pContextModelEvent = pContextModelEvent;
211     return SSM_S_OK;
212 }
213
214 void CContextModel::onExecute(void *pArg)
215 {
216     intptr_t *pData = (intptr_t *)pArg;
217
218     if (m_pContextModelEvent)
219     {
220         m_pContextModelEvent->onModelStatusChange((Status)pData[0], (ISSMResource *)pData[1], this);
221     }
222 }
223
224 void CContextModel::onTerminate(void *pArg)
225 {
226     intptr_t *pData = (intptr_t *)pArg;
227     SAFE_ARRAY_DELETE(pData);
228 }
229
230 //TODO: called when new data arrived
231 int CContextModel::onEvent(std::string deviceID, TypeofEvent callType,
232                            std::vector<ContextData> ctxData)
233 {
234     SSMRESULT           res = SSM_E_FAIL;
235     int                 dataId = 0;
236     ModelProperty       modelProperty;
237     ModelPropertyVec    modelProperties;
238     IntVec              *deviceDataIds = NULL;
239     std::map<int, IntVec>::iterator     itorDeviceDataIds;
240     int                 idxUpdate = 0;
241
242     if (m_modelName != ctxData[0].rootName)
243     {
244         SSM_CLEANUP_ASSERT(SSM_E_POINTER);
245     }
246
247     if (m_mapSSM.find(deviceID) == m_mapSSM.end())
248     {
249         SSM_CLEANUP_ASSERT(SSM_E_POINTER);
250     }
251
252     itorDeviceDataIds = m_mapDeviceDataIds.find(m_mapSSM[deviceID].first);
253
254     if (itorDeviceDataIds != m_mapDeviceDataIds.end())
255     {
256         deviceDataIds = &(itorDeviceDataIds->second);
257     }
258
259     for (std::vector<ContextData>::iterator itorContextData =
260              ctxData.begin(); itorContextData != ctxData.end(); ++itorContextData)
261     {
262         for (std::vector<std::map<std::string, std::string> >::iterator itor =
263                  (*itorContextData).outputProperty.begin(); itor != (*itorContextData).outputProperty.end();
264              ++itor)
265         {
266             if (itor->find("error") != itor->end())
267             {
268                 modelProperty.propertyName = "available";
269                 modelProperty.propertyValue = "false";
270                 modelProperty.propertyType = ModelProperty::TYPE_TEXT;
271                 modelProperties.push_back(modelProperty);
272                 break;
273             }
274
275             modelProperty.propertyName = (*itor)["name"];
276             modelProperty.propertyValue = (*itor)["value"];
277             if ((*itor)["type"] == "string")
278             {
279                 modelProperty.propertyType = ModelProperty::TYPE_TEXT;
280             }
281             else if ((*itor)["type"] == "int")
282             {
283                 modelProperty.propertyType = ModelProperty::TYPE_INTEGER;
284             }
285             else if ((*itor)["type"] == "double")
286             {
287                 modelProperty.propertyType = ModelProperty::TYPE_REAL;
288             }
289             else if ((*itor)["type"] == "float")
290             {
291                 modelProperty.propertyType = ModelProperty::TYPE_REAL;
292             }
293             else
294             {
295                 modelProperty.propertyType = ModelProperty::TYPE_TEXT;
296             }
297             modelProperties.push_back(modelProperty);
298         }
299
300         //Add lifetime to field
301         modelProperty.propertyName = "lifetime";
302         modelProperty.propertyValue = m_secLifeTime;
303         modelProperty.propertyType = ModelProperty::TYPE_INTEGER;
304
305         modelProperties.push_back(modelProperty);
306
307         if (deviceDataIds == NULL)
308         {
309             SSM_CLEANUP_ASSERT(addModelData(m_mapSSM[deviceID].first, &modelProperties, &dataId));
310             m_mapDeviceDataIds[m_mapSSM[deviceID].first].push_back(dataId);
311         }
312         else
313         {
314             SSM_CLEANUP_ASSERT(updateModelData(m_mapDeviceDataIds[m_mapSSM[deviceID].first][idxUpdate++],
315                                                &modelProperties));
316         }
317
318         modelProperties.clear();
319     }
320
321 CLEANUP:
322     return 0;
323 }
324
325 int CContextModel::getModelId()
326 {
327     return m_modelId;
328 }
329
330 std::string CContextModel::getModelName()
331 {
332     return m_modelName;
333 }
334
335 IContextModel::ConstructionType CContextModel::getConstructionType()
336 {
337     return m_constructionType;
338 }
339
340 SSMRESULT CContextModel::getParentDataId(int dataId, IContextModel *pParentModel,
341         int *pParentDataId)
342 {
343     return m_pEvaluationEngine->getParentDataId(m_modelId, dataId, pParentModel->getModelId(),
344             pParentDataId);
345 }
346
347 SSMRESULT CContextModel::getChildDataId(int dataId, IContextModel *pChildModel,
348                                         IntVec *pChildDataIds)
349 {
350     return m_pEvaluationEngine->getChildDataId(m_modelId, dataId, pChildModel->getModelId(),
351             pChildDataIds);
352 }
353
354 SSMRESULT CContextModel::activate(ActivationType activationType, int targetDeviceDataId)
355 {
356     if (targetDeviceDataId < 0 && activationType == ACTIVATION_TYPE_SUBSCRIBE)
357     {
358         m_mtxActivationCount.lock();
359         m_activationCount++;
360         m_mtxActivationCount.unlock();
361     }
362
363     for (std::map<std::string, std::pair<int, ISSMResource> >::iterator itor = m_mapSSM.begin();
364          itor != m_mapSSM.end(); ++itor)
365     {
366         if (targetDeviceDataId < 0)
367         {
368             registerSSMResource(activationType, itor->second.first, &itor->second.second);
369         }
370         else if (itor->second.first == targetDeviceDataId)
371         {
372             registerSSMResource(activationType, itor->second.first, &itor->second.second);
373             break;
374         }
375     }
376
377     return SSM_S_OK;
378 }
379
380 SSMRESULT CContextModel::deactivate(ActivationType activationType, int targetDeviceDataId)
381 {
382     if (targetDeviceDataId < 0 && activationType == ACTIVATION_TYPE_SUBSCRIBE)
383     {
384         m_mtxActivationCount.lock();
385         m_activationCount--;
386         m_mtxActivationCount.unlock();
387     }
388
389     for (std::map<std::string, std::pair<int, ISSMResource> >::iterator itor = m_mapSSM.begin();
390          itor != m_mapSSM.end(); ++itor)
391     {
392         if (targetDeviceDataId < 0)
393         {
394             unregisterSSMResource(activationType, itor->second.first, &itor->second.second);
395         }
396         else if (itor->second.first == targetDeviceDataId)
397         {
398             unregisterSSMResource(activationType, itor->second.first, &itor->second.second);
399             break;
400         }
401     }
402
403     return SSM_S_OK;
404 }
405 /*
406 SSMRESULT CContextModel::GetModelSchema(ModelPropertyVec *pModelProperties)
407 {
408     return m_pEvaluationEngine->GetModelSchema(m_ModelId, pModelProperties);
409 }
410 */
411 SSMRESULT CContextModel::addModelData(int parentDataId, ModelPropertyVec *pData,
412                                       int *pDataId)
413 {
414     return m_pEvaluationEngine->addModelData(m_modelId, m_pParentModel->getModelId(), parentDataId,
415             pData, pDataId);
416 }
417
418 SSMRESULT CContextModel::updateModelData(int dataId, ModelPropertyVec *pData)
419 {
420     return m_pEvaluationEngine->updateModelData(m_modelId, dataId, pData);
421 }
422
423 SSMRESULT CContextModel::deleteModelData(int dataId)
424 {
425     return m_pEvaluationEngine->deleteModelData(m_modelId, dataId);
426 }
427
428 SSMRESULT CContextModel::getModelData(int dataId, ModelPropertyVec *pData)
429 {
430     SSMRESULT res = SSM_E_FAIL;
431     int     i = 0;
432
433     SSM_CLEANUP_ASSERT(m_pEvaluationEngine->getModelData(m_modelId, dataId, pData));
434     for (ModelPropertyVec::iterator itor = pData->begin(); itor != pData->end(); ++itor)
435     {
436         itor->propertyName = m_modelProperties[i++].propertyName;
437     }
438
439 CLEANUP:
440     return res;
441 }
442
443 SSMRESULT CContextModel::getModelDataSet(int startIndex, int count,
444         std::vector<ModelPropertyVec> *pDataSet, int *pLastIndex)
445 {
446     SSMRESULT res = SSM_E_FAIL;
447     int     i;
448
449     SSM_CLEANUP_ASSERT(m_pEvaluationEngine->getModelDataSet(m_modelId, startIndex, count, pDataSet,
450                        pLastIndex));
451
452     for (std::vector<ModelPropertyVec>::iterator itorModelProperty = pDataSet->begin();
453          itorModelProperty != pDataSet->end(); ++itorModelProperty)
454     {
455         i = 0;
456         for (ModelPropertyVec::iterator itor = itorModelProperty->begin(); itor != itorModelProperty->end();
457              ++itor)
458         {
459             itor->propertyName = m_modelProperties[i++].propertyName;
460         }
461     }
462
463 CLEANUP:
464     return res;
465 }
466
467 SSMRESULT CContextModel::createConditionedModel(ModelConditionVec *pModelConditionVec,
468         IConditionedModel **ppConditionedModel)
469 {
470     SSMRESULT res = SSM_E_FAIL;
471     CObject<CConditionedModel>                  *pConditionedModel;
472
473     SSM_CLEANUP_ASSERT(CreateInstance(OID_IConditionedModel, (IBase **)&pConditionedModel));
474     SSM_CLEANUP_ASSERT(pConditionedModel->create(this, pModelConditionVec));
475     SSM_CLEANUP_ASSERT(pConditionedModel->queryInterface(OID_IConditionedModel,
476                        (IBase **)ppConditionedModel));
477
478     //(*ppConditionedModel)->AddRef();
479     //m_ConditionedModels.push_back(*ppConditionedModel);
480
481 CLEANUP:
482     SAFE_RELEASE(pConditionedModel);
483     return res;
484 }
485 /*
486 SSMRESULT CContextModel::CleanUpModelData()
487 {
488     SSMRESULT res = SSM_E_FAIL;
489
490     for(std::map<int,int>::iterator itor = m_mapDataId.begin();
491         itor != m_mapDataId.end(); ++itor)
492     {
493         CHK_SSMRESULT(DeleteModelData(itor->second));
494     }
495
496     res = SSM_S_OK;
497
498 CLEANUP:
499     return res;
500 }
501 */
502
503 //Called new install or re install
504 void CContextModel::addSSMResourceAndDeviceDataId(std::string deviceId, int deviceDataId,
505         ISSMResource *pSSMResource)
506 {
507     if (deviceDataId == 1)
508     {
509         IntVec dataId;
510         m_pParentModel->getChildDataId(deviceDataId, this, &dataId);
511         if (dataId.size() > 0)
512         {
513             m_mapDeviceDataIds[deviceDataId] = dataId;
514         }
515     }
516
517     if (m_mapSSM.find(deviceId) != m_mapSSM.end())
518     {
519         m_mtxActivationCount.lock();
520         if (m_activationCount > 0)
521         {
522             unregisterSSMResource(ACTIVATION_TYPE_SUBSCRIBE, deviceDataId, &m_mapSSM[deviceId].second);
523         }
524         m_mtxActivationCount.unlock();
525     }
526     else
527     {
528         m_mapSSM[deviceId] = std::pair<int, ISSMResource>(deviceDataId, *pSSMResource);
529     }
530
531     m_mtxActivationCount.lock();
532     if (m_activationCount > 0)
533     {
534         registerSSMResource(ACTIVATION_TYPE_SUBSCRIBE, deviceDataId, &m_mapSSM[deviceId].second);
535     }
536     m_mtxActivationCount.unlock();
537 }
538
539 void CContextModel::setLifeTime(std::string seconds)
540 {
541     if (atoi(seconds.c_str()) > 0)
542     {
543         m_secLifeTime = seconds;
544     }
545 }