1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
20 #include "ContextExecutor.h"
22 SSMRESULT CContextExecutor::finalConstruct()
24 SSMRESULT res = SSM_E_FAIL;
28 SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase **)&m_pTasker));
29 SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IContextRepository, (IBase **)&m_pContextRepository));
30 SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IContextDataReader, (IBase **)&m_pContextDataReader));
32 SSM_CLEANUP_ASSERT(m_pContextRepository->registerResourceFinderEvent(this));
38 void CContextExecutor::finalRelease()
42 void CContextExecutor::registerCallback(ICtxEvent *pEvent)
47 //Data from soft sensors
48 void CContextExecutor::addOutput(std::vector<ContextData> contextData)
51 std::map<std::string, CallbackData>::iterator itor;
52 std::string type = contextData[0].rootName;
54 //TODO: name must be a this soft sensors identifier
55 //m_mtxRequestedContextCallback.Lock();
56 itor = m_requestedContextCallback.find(type);
57 if (itor != m_requestedContextCallback.end())
59 TypeofEvent callType = itor->second.m_callType;
60 itor->second.m_pCallbackEvent->onEvent(type, callType, contextData);
61 if (callType == SSM_ONCE)
63 unregisterContext(callType, m_registeredResources[type], this);
67 //m_mtxRequestedContextCallback.Unlock();
70 void CContextExecutor::getDataFromDatabase(std::string modelName, int startIndex, int count,
71 std::vector<ContextData> *data, int *pLastIndex)
73 m_pContextDataReader->getContextData(modelName, startIndex, count, data, pLastIndex);
76 void CContextExecutor::registerContext(TypeofEvent callType, ISSMResource *pSSMResource,
79 //will make check routine for One resource has callbacks.
80 std::vector<ISSMResource *> baseList;
82 CallbackData callbackData(callType, pSSMResource->name, pEvent);
84 //m_mtxRequestedContextCallback.Lock();
85 m_registeredResources[pSSMResource->type] = pSSMResource;
86 m_requestedContextCallback[pSSMResource->type] = callbackData;
87 //m_mtxRequestedContextCallback.Unlock();
89 //This is stand-alone sensor
90 if (pSSMResource->inputList.size() == 0)
93 std::vector<ContextData> inputData;
94 switch (pSSMResource->location)
96 case SENSOR_LOCATION_LOCAL:
97 runLogic(inputData, pSSMResource->type);
100 case SENSOR_LOCATION_REMOTE:
102 m_pContextRepository->startObserveResource(pSSMResource, this);
107 m_pContextRepository->getPrimitiveSensorList(&baseList);
108 m_pContextRepository->getSoftSensorList(&baseList);
110 for (unsigned int i = 0; i < pSSMResource->inputList.size(); ++i)
112 ISSMResource *pKeyResource = NULL;
113 if (findString(&baseList, pSSMResource->inputList[i],
114 &pKeyResource) != SSM_E_FAIL) //if element of inputList is in the primitive resources.
116 if (m_relatedSoftSensor.find(pKeyResource->type) != m_relatedSoftSensor.end()) //already exists
119 //check related Context needs insert or not. if softSensor resource is not a member of related context then insert.
120 std::vector<std::string> softSensorList = m_relatedSoftSensor[pKeyResource->type];
122 for (unsigned int j = 0; j < softSensorList.size(); ++j)
124 if (softSensorList[j].compare(pSSMResource->type) != 0)
126 m_relatedSoftSensor[pKeyResource->type].push_back(pSSMResource->type);
131 else // If first time
134 //insert resource in the all map and vector
135 m_relatedSoftSensor[pKeyResource->type].push_back(pSSMResource->type);
138 registerContext(callType, pKeyResource, this);
141 else //unable to find installed sensors. take it to keep list
143 m_mapResourceLookup[pSSMResource->inputList[i]].push_back(CallbackData(callType, pSSMResource->type,
149 void CContextExecutor::onExecute(void *pArg)
151 intptr_t *pMessage = (intptr_t *)pArg;
153 RESOURCE_EVENT_TYPE eventType = (RESOURCE_EVENT_TYPE)pMessage[0];
154 ISSMResource *pResource = (ISSMResource *)pMessage[1];
158 case SSM_EVENT_NORMAL:
161 case SSM_EVENT_ADDED:
162 if (m_mapResourceLookup.find(pResource->type) != m_mapResourceLookup.end())
164 CallbackData *callBack = NULL;
166 for (size_t i = 0; i < m_mapResourceLookup[pResource->type].size(); i++)
168 callBack = &m_mapResourceLookup[pResource->type][i];
170 m_relatedSoftSensor[pResource->type].push_back(callBack->m_name);
172 registerContext(callBack->m_callType, pResource, callBack->m_pCallbackEvent);
175 m_mapResourceLookup.erase(m_mapResourceLookup.find(pResource->type));
190 void CContextExecutor::onTerminate(void *pArg)
192 intptr_t *pMessage = (intptr_t *)pArg;
197 int CContextExecutor::onResourceEvent(RESOURCE_EVENT_TYPE eventType, ISSMResource *pSSMResource,
200 intptr_t *pMessage = new intptr_t [2];
202 pMessage[0] = eventType;
203 pMessage[1] = reinterpret_cast<intptr_t>(pSSMResource);
204 return (int)m_pTasker->addTask(this, (void *)pMessage);
207 SSMRESULT CContextExecutor::findString(std::vector<ISSMResource *> *sList, const std::string str,
208 ISSMResource **ppResource)
210 SSMRESULT ret = SSM_E_FAIL;
211 for (unsigned int i = 0 ; i < sList->size() ; ++i)
213 if ((*sList)[i]->type == str)
215 *ppResource = (*sList)[i];
223 std::map<std::string, std::vector<ContextData> > CContextExecutor::getPreparedContextList(
224 std::string primitiveSensor)
226 //check m_relatedSoftSensor / apply timestamp
228 SSMRESULT ret = SSM_E_FAIL;
230 std::map<std::string, std::vector<ContextData> > returnData;
231 std::vector<ContextData> contextDataList;
233 for (unsigned int i = 0; i < m_relatedSoftSensor[primitiveSensor].size(); ++i)
235 std::string softSensorName = m_relatedSoftSensor[primitiveSensor][i];
236 if (m_registeredResources.find(softSensorName) != m_registeredResources.end())
239 std::vector<std::string> inputList = m_registeredResources[softSensorName]->inputList;
240 for (unsigned int j = 0; j < inputList.size(); j++) //check all "inputlist" arrived or not
242 if (m_storedPrimitiveSensorData.find(inputList[j]) == m_storedPrimitiveSensorData.end())
244 //Still we have partial data
250 //Copy all properties of current primitiveSensor data to outputs
251 for (std::vector<ContextData>::iterator itor = m_storedPrimitiveSensorData[inputList[j]].begin();
252 itor != m_storedPrimitiveSensorData[inputList[j]].end(); ++itor)
254 contextDataList.push_back(*itor);
262 returnData.insert(std::make_pair(softSensorName, contextDataList));
264 contextDataList.clear();
271 //Data from every primitive sensors
272 int CContextExecutor::onEvent(std::string type, TypeofEvent callType,
273 std::vector<ContextData> ctxData)
275 //std::string root_name = ctxData.at(0).root_name; //-> deviceId+ctxData.root_name
277 if (m_relatedSoftSensor.find(type) != m_relatedSoftSensor.end()) //already registered?
279 //update recent values(overwrite)
280 m_storedPrimitiveSensorData[type] = ctxData;
283 std::map<std::string, std::vector<ContextData> > readyContextList = getPreparedContextList(type);
285 //Run SoftSensor! readyContextList has all data for run
286 std::map<std::string, std::vector<ContextData> >::iterator iter;
287 for (iter = readyContextList.begin(); iter != readyContextList.end(); ++iter)
289 std::string softSensorName = iter->first;
290 std::vector<ContextData> inputData = iter->second;
292 runLogic(inputData, softSensorName);
295 else if (m_registeredResources.find(type) != m_registeredResources.end()) //This data is primitive
303 void CContextExecutor::unregisterContext(TypeofEvent callType, ISSMResource *pSSMResource,
306 std::vector<ISSMResource *> baseList;
309 ///TODO: Need to clean up m_mapResourceLookup list
312 //This is primitive sensor
313 if (pSSMResource->inputList.size() == 0)
316 std::vector<ContextData> inputData;
317 switch (pSSMResource->location)
319 case SENSOR_LOCATION_LOCAL:
320 //TODO: Must free soft sensor
321 if (m_libraryList.find(pSSMResource->type) != m_libraryList.end() && callType != SSM_ONCE)
323 m_pContextRepository->unloadSoftSensor(m_libraryList[pSSMResource->type]);
324 m_libraryList.erase(m_libraryList.find(pSSMResource->type));
327 if (m_ctxEventList.find(pSSMResource->type) != m_ctxEventList.end())
329 m_ctxEventList.erase(m_ctxEventList.find(pSSMResource->type));
333 case SENSOR_LOCATION_REMOTE:
334 //Let observer stop work!
335 m_pContextRepository->stopObserveResource(pSSMResource);
340 //m_mtxRequestedContextCallback.Lock();
341 if (m_requestedContextCallback.find(pSSMResource->type) != m_requestedContextCallback.end())
343 m_requestedContextCallback.erase(m_requestedContextCallback.find(pSSMResource->type));
345 if (m_registeredResources.find(pSSMResource->type) != m_registeredResources.end())
347 m_registeredResources.erase(m_registeredResources.find(pSSMResource->type));
349 //m_mtxRequestedContextCallback.Unlock();
351 //TODO: support multiple concurrent query reference
352 m_pContextRepository->getPrimitiveSensorList(&baseList);
353 m_pContextRepository->getSoftSensorList(&baseList);
355 for (unsigned int i = 0 ; i < pSSMResource->inputList.size() ; ++i)
357 ISSMResource *pPrimitiveSensor = NULL;
358 if (findString(&baseList, pSSMResource->inputList[i], &pPrimitiveSensor) != SSM_E_FAIL)
360 std::vector<std::string> *softSensorList = &m_relatedSoftSensor[pPrimitiveSensor->type];
361 for (unsigned int j = 0; j < softSensorList->size(); ++j)
363 if (!(*softSensorList)[j].compare(pSSMResource->type))
365 softSensorList->erase(softSensorList->begin() + j);
367 if (softSensorList->size() == 0) //no more related context.
369 m_relatedSoftSensor.erase(m_relatedSoftSensor.find(pPrimitiveSensor->type));
372 unregisterContext(callType, pPrimitiveSensor, this);
381 //Called when soft sensor try to work
382 void CContextExecutor::runLogic(std::vector<ContextData> inputData, std::string softSensor)
384 m_mtxLibraryIO.lock();
385 if (m_ctxEventList.find(softSensor) == m_ctxEventList.end())
387 void *hSoftSensor = NULL;
388 if (m_pContextRepository->loadSoftSensor(softSensor, this, &hSoftSensor) == SSM_S_OK)
390 m_libraryList[softSensor] = hSoftSensor;
391 m_ctxEventList[softSensor] = ctxEvent;
392 m_ctxEventList[softSensor]->onCtxEvent(SPF_START, inputData);
397 m_ctxEventList[softSensor]->onCtxEvent(SPF_START, inputData);
399 m_mtxLibraryIO.unlock();