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.
22 #include <types_internal.h>
23 #include <scope_mutex.h>
24 #include <request_handler.h>
25 #include "response_handler.h"
26 #include "dbus_client.h"
28 typedef std::map<std::string, ctx::request_handler::subject_response_cb> response_cb_map_t;
30 static ctx::dbus_client *dbus_handle = NULL;
31 static response_cb_map_t *response_cb_map = NULL;
37 ~exit_handler() { delete dbus_handle; }
41 static exit_handler _exit_handler;
43 static int generate_req_id()
45 static GMutex rid_mutex;
46 static int req_id = 0;
48 ctx::scope_mutex sm(&rid_mutex);
58 static bool initialize()
60 static GMutex init_mutex;
61 ctx::scope_mutex sm(&init_mutex);
67 response_cb_map = new(std::nothrow) response_cb_map_t;
68 IF_FAIL_CATCH_TAG(response_cb_map, _E, "Memory allocation failed");
70 dbus_handle = new(std::nothrow) ctx::dbus_client();
71 IF_FAIL_CATCH_TAG(dbus_handle, _E, "Memory allocation failed");
72 IF_FAIL_CATCH_TAG(dbus_handle->init(), _E, "Dbus initialization failed");
78 delete response_cb_map;
80 response_cb_map = NULL;
84 int ctx::request_handler::subscribe(const char* subject, ctx::json* option, int* req_id, ctx::json* request_result)
86 ASSERT_NOT_NULL(subject);
87 ASSERT_NOT_NULL(req_id);
88 IF_FAIL_RETURN_TAG(initialize(), ERR_OPERATION_FAILED, _E, "Connection failed");
90 *req_id = generate_req_id();
94 opt_str = option->dup_cstr();
95 IF_FAIL_RETURN_TAG(opt_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
98 _I("[Subscribe] ReqId: %d, Subject: %s", *req_id, subject);
100 std::string result_str;
101 int error = dbus_handle->request(REQ_SUBSCRIBE, *req_id, subject, opt_str, &result_str, NULL);
104 if (request_result) {
105 *request_result = result_str;
108 _D("Error: %#x", error);
109 _SD("Result: %s", result_str.c_str());
114 int ctx::request_handler::unsubscribe(const char* subject, int req_id)
116 ASSERT_NOT_NULL(subject);
117 IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
118 _I("[Unsubscribe] ReqId: %d, Subject: %s", req_id, subject);
119 return dbus_handle->request(REQ_UNSUBSCRIBE, req_id, subject, NULL, NULL, NULL);
122 int ctx::request_handler::read(const char* subject, ctx::json* option, int* req_id, ctx::json* request_result)
124 ASSERT_NOT_NULL(subject);
125 ASSERT_NOT_NULL(req_id);
126 IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
128 *req_id = generate_req_id();
130 char *opt_str = NULL;
132 opt_str = option->dup_cstr();
133 IF_FAIL_RETURN_TAG(opt_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
136 _I("[Read] ReqId: %d, Subject: %s", *req_id, subject);
138 std::string result_str;
139 int error = dbus_handle->request(REQ_READ, *req_id, subject, opt_str, &result_str, NULL);
142 if (request_result) {
143 *request_result = result_str;
146 _D("Error: %#x", error);
147 _SD("Result: %s", result_str.c_str());
152 int ctx::request_handler::read_sync(const char* subject, ctx::json* option, int* req_id, ctx::json* data_read)
154 ASSERT_NOT_NULL(subject);
155 ASSERT_NOT_NULL(req_id);
156 ASSERT_NOT_NULL(data_read);
157 IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
159 *req_id = generate_req_id();
161 char *opt_str = NULL;
163 opt_str = option->dup_cstr();
164 IF_FAIL_RETURN_TAG(opt_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
167 _I("[ReadSync] ReqId: %d, Subject: %s", *req_id, subject);
169 std::string data_str;
170 int error = dbus_handle->request(REQ_READ_SYNC, *req_id, subject, opt_str, NULL, &data_str);
173 *data_read = data_str;
175 _D("Error: %#x", error);
176 _SD("Data: %s", data_str.c_str());
181 int ctx::request_handler::write(const char* subject, ctx::json* data)
183 ASSERT_NOT_NULL(subject);
184 ASSERT_NOT_NULL(data);
185 IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
187 int req_id = generate_req_id();
188 char *data_str = data->dup_cstr();
189 IF_FAIL_RETURN_TAG(data_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
191 _I("[Write] ReqId: %d, Subject: %s", req_id, subject);
192 _SD("Data: %s", data_str);
194 int error = dbus_handle->request_with_no_reply(REQ_WRITE, req_id, subject, data_str);
197 _D("Error: %#x", error);
202 int ctx::request_handler::write_with_reply(const char* subject, ctx::json* data, ctx::json* request_result)
204 ASSERT_NOT_NULL(subject);
205 ASSERT_NOT_NULL(data);
206 IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
208 int req_id = generate_req_id();
209 char *data_str = data->dup_cstr();
210 IF_FAIL_RETURN_TAG(data_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
212 _I("[Write with reply] ReqId: %d, Subject: %s", req_id, subject);
213 _SD("Data: %s", data_str);
215 std::string result_str;
216 int error = dbus_handle->request(REQ_WRITE, req_id, subject, data_str, &result_str, NULL);
219 if (request_result) {
220 *request_result = result_str;
223 _D("Error: %#x", error);
224 _SD("Result: %s", result_str.c_str());
229 int ctx::request_handler::is_supported(const char* subject)
231 ASSERT_NOT_NULL(subject);
232 IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
233 return dbus_handle->request(REQ_SUPPORT, generate_req_id(), subject, NULL, NULL, NULL);
236 bool ctx::request_handler::register_callback(const char* subject, subject_response_cb callback)
238 IF_FAIL_RETURN_TAG(subject && callback, false, _E, "Invalid parameter");
239 IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
241 _D("Registering callback for subject '%s'", subject);
243 static GMutex cb_list_mutex;
244 ctx::scope_mutex sm(&cb_list_mutex);
246 (*response_cb_map)[subject] = callback;
251 void ctx::response_handler::deliver(const char* subject, int req_id, int error, const char* data)
253 response_cb_map_t::iterator it = response_cb_map->find(subject);
254 IF_FAIL_VOID_TAG(it != response_cb_map->end(), _E, "Unknown subject '%s'", subject);
256 it->second(subject, req_id, error, data);