2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "../access_control/Privilege.h"
19 #include "../ContextManager.h"
20 #include "ContextMonitor.h"
21 #include "IContextListener.h"
22 #include "FactRequest.h"
25 using namespace trigger;
30 ContextMonitor *ContextMonitor::__instance = NULL;
31 ContextManager *ContextMonitor::__contextMgr = NULL;
33 static int __generateReqId()
45 ContextMonitor::ContextMonitor()
49 ContextMonitor::~ContextMonitor()
53 void ContextMonitor::setContextManager(ContextManager* ctxMgr)
55 __contextMgr = ctxMgr;
58 ContextMonitor* ContextMonitor::getInstance()
60 IF_FAIL_RETURN_TAG(__contextMgr, NULL, _E, "Context manager is needed");
62 IF_FAIL_RETURN(!__instance, __instance);
64 __instance = new(std::nothrow) ContextMonitor();
65 IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory alllocation failed");
70 void ContextMonitor::destroy()
78 int ContextMonitor::subscribe(int ruleId, std::string subject, CtxJson1 option, IContextListener* listener)
80 int reqId = __subscribe(subject.c_str(), &option, listener);
81 IF_FAIL_RETURN_TAG(reqId > 0, reqId, _E, "Subscribe event failed");
82 _D(YELLOW("Subscribe event(rule%d). req%d"), ruleId, reqId);
87 int ContextMonitor::__subscribe(const char* subject, CtxJson1* option, IContextListener* listener)
89 IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
91 int rid = __findSub(REQ_SUBSCRIBE, subject, option);
93 __addListener(REQ_SUBSCRIBE, rid, listener);
94 _D("Duplicated request for %s", subject);
98 rid = __generateReqId();
100 FactRequest *req = new(std::nothrow) FactRequest(REQ_SUBSCRIBE,
101 rid, subject, option ? option->str().c_str() : NULL, this);
102 IF_FAIL_RETURN_TAG(req, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
104 __contextMgr->assignRequest(req);
105 __addSub(REQ_SUBSCRIBE, rid, subject, option, listener);
107 if (__lastErr != ERR_NONE) {
108 __removeSub(REQ_SUBSCRIBE, rid);
109 _E("Subscription request failed: %#x", __lastErr);
116 int ContextMonitor::unsubscribe(int ruleId, std::string subject, CtxJson1 option, IContextListener* listener)
118 int rid = __findSub(REQ_SUBSCRIBE, subject.c_str(), &option);
120 _D("Invalid unsubscribe request");
121 return ERR_INVALID_PARAMETER;
124 if (__removeListener(REQ_SUBSCRIBE, rid, listener) <= 0) {
125 __unsubscribe(subject.c_str(), rid);
127 _D(YELLOW("Unsubscribe event(rule%d). req%d"), ruleId, rid);
132 void ContextMonitor::__unsubscribe(const char *subject, int subscriptionId)
134 FactRequest *req = new(std::nothrow) FactRequest(REQ_UNSUBSCRIBE, subscriptionId, subject, NULL, NULL);
135 IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed");
137 __contextMgr->assignRequest(req);
138 __removeSub(REQ_SUBSCRIBE, subscriptionId);
141 int ContextMonitor::read(std::string subject, CtxJson1 option, IContextListener* listener)
143 int reqId = __read(subject.c_str(), &option, listener);
144 IF_FAIL_RETURN_TAG(reqId > 0, ERR_OPERATION_FAILED, _E, "Read condition failed");
145 _D(YELLOW("Read condition(%s). req%d"), subject.c_str(), reqId);
150 int ContextMonitor::__read(const char* subject, CtxJson1* option, IContextListener* listener)
152 IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
154 int rid = __findSub(REQ_READ, subject, option);
156 __addListener(REQ_READ, rid, listener);
157 _D("Duplicated request for %s", subject);
161 rid = __generateReqId();
163 FactRequest *req = new(std::nothrow) FactRequest(REQ_READ,
164 rid, subject, option ? option->str().c_str() : NULL, this);
165 IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed");
167 __contextMgr->assignRequest(req);
168 __addSub(REQ_READ, rid, subject, option, listener);
170 if (__lastErr != ERR_NONE) {
171 _E("Read request failed: %#x", __lastErr);
178 bool ContextMonitor::isSupported(std::string subject)
180 return __contextMgr->isSupported(subject.c_str());
183 bool ContextMonitor::isAllowed(const char *client, const char *subject)
185 //TODO: re-implement this in the proper 3.0 style
186 //return __contextMgr->isAllowed(client, subject);
190 int ContextMonitor::__findSub(RequestType type, const char* subject, CtxJson1* option)
192 // @return request id
193 std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap;
200 for (auto it = map->begin(); it != map->end(); ++it) {
201 if ((*(it->second)).subject == subject && (*(it->second)).option == jOpt) {
209 bool ContextMonitor::__addSub(RequestType type, int sid, const char* subject, CtxJson1* option, IContextListener* listener)
211 std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap;
213 SubscrInfo *info = new(std::nothrow) SubscrInfo(sid, subject, option);
214 IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
215 info->listenerList.push_back(listener);
217 map->insert(std::pair<int, SubscrInfo*>(sid, info));
221 void ContextMonitor::__removeSub(RequestType type, const char* subject, CtxJson1* option)
223 std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap;
230 for (auto it = map->begin(); it != map->end(); ++it) {
231 if ((*(it->second)).subject == subject && (*(it->second)).option == jOpt) {
239 void ContextMonitor::__removeSub(RequestType type, int sid)
241 std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap;
243 SubscrInfo* info = map->at(sid);
244 info->listenerList.clear();
252 int ContextMonitor::__addListener(RequestType type, int sid, IContextListener* listener)
254 // @return number of listeners for the corresponding sid
255 std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap;
257 auto it = map->find(sid);
259 SubscrInfo* info = it->second;
260 info->listenerList.push_back(listener);
262 return info->listenerList.size();
265 int ContextMonitor::__removeListener(RequestType type, int sid, IContextListener* listener)
267 // @return number of listeners for the corresponding sid
268 std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &__readMap;
270 auto it = map->find(sid);
272 SubscrInfo* info = it->second;
274 for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) {
275 if (*it2 == listener) {
276 info->listenerList.erase(it2);
281 return info->listenerList.size();
284 void ContextMonitor::replyResult(int reqId, int error, CtxJson1* requestResult)
286 _D("Request result received: %d", reqId);
292 void ContextMonitor::replyResult(int reqId, int error, const char* subject, CtxJson1* option, CtxJson1* fact)
294 _D(YELLOW("Condition received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str());
296 auto it = __readMap.find(reqId);
297 IF_FAIL_VOID_TAG(it != __readMap.end(), _E, "Request id not found");
299 SubscrInfo* info = it->second;
300 for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) {
301 (*it2)->onConditionReceived(subject, *option, *fact);
304 __removeSub(REQ_READ, reqId);
307 void ContextMonitor::publishFact(int reqId, int error, const char* subject, CtxJson1* option, CtxJson1* fact)
309 _D(YELLOW("Event received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str());
311 auto it = __subscrMap.find(reqId);
312 IF_FAIL_VOID_TAG(it != __subscrMap.end(), _E, "Request id not found");
314 SubscrInfo* info = it->second;
315 for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) {
316 (*it2)->onEventReceived(subject, *option, *fact);