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.
19 #include "access_control/Privilege.h"
21 #include "ProviderHandler.h"
25 std::map<std::string, ProviderHandler*> ProviderHandler::__instanceMap;
27 ProviderHandler::ProviderHandler(const char *subject) :
32 ProviderHandler::~ProviderHandler()
34 for (RequestInfo*& info : __subscribeRequests) {
37 __subscribeRequests.clear();
39 for (RequestInfo*& info : __readRequests) {
42 __readRequests.clear();
47 /* TODO: Return proper error code */
48 ProviderHandler* ProviderHandler::getInstance(const char *subject, bool force)
50 InstanceMap::iterator it = __instanceMap.find(subject);
52 if (it != __instanceMap.end())
58 ProviderHandler *handle = new(std::nothrow) ProviderHandler(subject);
59 IF_FAIL_RETURN_TAG(handle, NULL, _E, "Memory allocation failed");
61 if (!handle->__loadProvider()) {
66 __instanceMap[subject] = handle;
71 void ProviderHandler::purge()
73 for (InstanceMap::iterator it = __instanceMap.begin(); it != __instanceMap.end(); ++it) {
77 __instanceMap.clear();
80 bool ProviderHandler::isSupported()
82 return __provider->isSupported();
85 bool ProviderHandler::isAllowed(const Credentials *creds)
87 IF_FAIL_RETURN(creds, true); /* In case of internal requests */
89 std::vector<const char*> priv;
90 __provider->getPrivilege(priv);
92 for (unsigned int i = 0; i < priv.size(); ++i) {
93 if (!privilege_manager::isAllowed(creds, priv[i]))
100 void ProviderHandler::subscribe(RequestInfo *request)
102 _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->getClient(), __subject, request->getId());
105 int error = __provider->subscribe(request->getDescription().str(), &requestResult);
107 if (!request->reply(error, requestResult) || error != ERR_NONE) {
112 __subscribeRequests.push_back(request);
115 void ProviderHandler::unsubscribe(RequestInfo *request)
117 _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->getClient(), __subject, request->getId());
119 /* Search the subscribe request to be removed */
120 auto target = __findRequest(__subscribeRequests, request->getClient(), request->getId());
121 if (target == __subscribeRequests.end()) {
122 _W("Unknown request");
127 /* Keep the pointer to the request found */
128 RequestInfo *reqFound = *target;
130 /* Remove the request from the list */
131 __subscribeRequests.erase(target);
133 /* Check if there exist the same requests */
134 if (__findRequest(__subscribeRequests, reqFound->getDescription()) != __subscribeRequests.end()) {
135 /* Do not stop detecting the subject */
136 _D("A same request from '%s' exists", reqFound->getClient());
137 request->reply(ERR_NONE);
143 /* Stop detecting the subject */
144 int error = __provider->unsubscribe(reqFound->getDescription());
145 request->reply(error);
150 void ProviderHandler::read(RequestInfo *request)
152 _I(CYAN("'%s' reads '%s' (RID-%d)"), request->getClient(), __subject, request->getId());
155 int error = __provider->read(request->getDescription().str(), &requestResult);
157 if (!request->reply(error, requestResult) || error != ERR_NONE) {
162 __readRequests.push_back(request);
165 void ProviderHandler::write(RequestInfo *request)
167 _I(CYAN("'%s' writes '%s' (RID-%d)"), request->getClient(), __subject, request->getId());
170 int error = __provider->write(request->getDescription(), &requestResult);
172 request->reply(error, requestResult);
176 bool ProviderHandler::publish(Json &option, int error, Json &dataUpdated)
178 auto end = __subscribeRequests.end();
179 auto target = __findRequest(__subscribeRequests.begin(), end, option);
181 while (target != end) {
182 if (!(*target)->publish(error, dataUpdated)) {
185 target = __findRequest(++target, end, option);
191 bool ProviderHandler::replyToRead(Json &option, int error, Json &dataRead)
193 auto end = __readRequests.end();
194 auto target = __findRequest(__readRequests.begin(), end, option);
199 while (target != end) {
200 (*target)->reply(error, dummy, dataRead);
202 target = __findRequest(++target, end, option);
205 __readRequests.erase(prev);
211 bool ProviderHandler::__loadProvider()
213 __provider = __loader.load(__subject);
214 return (__provider != NULL);
217 ProviderHandler::RequestList::iterator
218 ProviderHandler::__findRequest(RequestList &reqList, Json &option)
220 return __findRequest(reqList.begin(), reqList.end(), option);
223 ProviderHandler::RequestList::iterator
224 ProviderHandler::__findRequest(RequestList &reqList, std::string client, int reqId)
226 for (auto it = reqList.begin(); it != reqList.end(); ++it) {
227 if (client == (*it)->getClient() && reqId == (*it)->getId()) {
231 return reqList.end();
234 ProviderHandler::RequestList::iterator
235 ProviderHandler::__findRequest(RequestList::iterator begin, RequestList::iterator end, Json &option)
237 for (auto it = begin; it != end; ++it) {
238 if (option == (*it)->getDescription()) {