2 * Copyright (c) 2014 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.
20 #include <types_internal.h>
21 #include <scope_mutex.h>
22 #include "response_handler.h"
23 #include "dbus_client.h"
25 static GDBusConnection *dbus_connection = NULL;
26 static GDBusNodeInfo *dbus_node_info = NULL;
28 static const gchar introspection_xml[] =
30 " <interface name='"DBUS_IFACE"'>"
31 " <method name='"METHOD_RESPOND"'>"
32 " <arg type='i' name='"ARG_REQID"' direction='in'/>"
33 " <arg type='s' name='"ARG_SUBJECT"' direction='in'/>"
34 " <arg type='i' name='"ARG_RESULT_ERR"' direction='in'/>"
35 " <arg type='s' name='"ARG_OUTPUT"' direction='in'/>"
40 static void handle_response(const gchar *sender, GVariant *param, GDBusMethodInvocation *invocation)
43 const gchar *subject = NULL;
45 const gchar *data = NULL;
47 g_variant_get(param, "(i&si&s)", &req_id, &subject, &error, &data);
49 _I("[Response] ReqId: %d, Subject: %s, Error: %d", req_id, subject, error);
52 ctx::response_handler::deliver(subject, req_id, error, data);
54 g_dbus_method_invocation_return_value(invocation, NULL);
57 static void handle_method_call(GDBusConnection *conn, const gchar *sender,
58 const gchar *obj_path, const gchar *iface, const gchar *method_name,
59 GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
61 IF_FAIL_VOID_TAG(STR_EQ(obj_path, DBUS_PATH), _W, "Invalid path: %s", obj_path);
62 IF_FAIL_VOID_TAG(STR_EQ(iface, DBUS_IFACE), _W, "Invalid interface: %s", obj_path);
64 if (STR_EQ(method_name, METHOD_RESPOND)) {
65 handle_response(sender, param, invocation);
67 _W("Invalid method: %s", method_name);
71 ctx::dbus_client::dbus_client()
75 ctx::dbus_client::~dbus_client()
80 bool ctx::dbus_client::init()
82 static GMutex connection_mutex;
83 ctx::scope_mutex sm(&connection_mutex);
85 if (dbus_connection) {
91 dbus_node_info = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
92 IF_FAIL_RETURN_TAG(dbus_node_info != NULL, false, _E, "Initialization failed");
94 gchar *addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &gerr);
96 IF_FAIL_RETURN_TAG(addr != NULL, false, _E, "Getting address failed");
97 _SD("Address: %s", addr);
99 dbus_connection = g_dbus_connection_new_for_address_sync(addr,
100 (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
104 IF_FAIL_RETURN_TAG(dbus_connection != NULL, false, _E, "Connection failed");
106 GDBusInterfaceVTable vtable;
107 vtable.method_call = handle_method_call;
108 vtable.get_property = NULL;
109 vtable.set_property = NULL;
111 guint reg_id = g_dbus_connection_register_object(dbus_connection, DBUS_PATH,
112 dbus_node_info->interfaces[0], &vtable, NULL, NULL, &gerr);
114 IF_FAIL_RETURN_TAG(reg_id>0, false, _E, "Object registration failed");
116 _I("Dbus connection established: %s", g_dbus_connection_get_unique_name(dbus_connection));
120 void ctx::dbus_client::release()
122 if (dbus_connection) {
123 g_dbus_connection_flush_sync(dbus_connection, NULL, NULL);
124 g_dbus_connection_close_sync(dbus_connection, NULL, NULL);
125 g_object_unref(dbus_connection);
126 dbus_connection = NULL;
129 if (dbus_node_info) {
130 g_dbus_node_info_unref(dbus_node_info);
131 dbus_node_info = NULL;
135 int ctx::dbus_client::request(
136 int type, int req_id, const char* subject, const char* input,
137 std::string* req_result, std::string* data_read)
139 _I("Requesting: %d, %d, %s, %s", type, req_id, subject, input);
141 if (subject == NULL) {
142 subject = EMPTY_STRING;
146 input = EMPTY_JSON_OBJECT;
149 /* FIXME: the second param is the security cookie, which is deprected in 3.0.
150 * We need to completely REMOVE this parameter from the dbus protocol. */
151 GVariant *param = g_variant_new("(isiss)", type, "", req_id, subject, input);
152 IF_FAIL_RETURN_TAG(param, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
155 GVariant *response = g_dbus_connection_call_sync(dbus_connection, DBUS_DEST, DBUS_PATH, DBUS_IFACE,
156 METHOD_REQUEST, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &err);
158 IF_FAIL_RETURN_TAG(response, ERR_OPERATION_FAILED, _E, "Method call failed");
160 gint _error = ERR_OPERATION_FAILED;
161 const gchar *_req_result = NULL;
162 const gchar *_data_read = NULL;
164 g_variant_get(response, "(i&s&s)", &_error, &_req_result, &_data_read);
166 *req_result = _req_result;
169 *data_read = _data_read;
172 g_variant_unref(response);
177 int ctx::dbus_client::request_with_no_reply(
178 int type, int req_id, const char* subject, const char* input)
180 _I("Requesting: %d, %d, %s, %s", type, req_id, subject, input);
182 if (subject == NULL) {
183 subject = EMPTY_STRING;
187 input = EMPTY_JSON_OBJECT;
190 /* FIXME: the second param is the security cookie, which is deprected in 3.0.
191 * We need to completely REMOVE this parameter from the dbus protocol. */
192 GVariant *param = g_variant_new("(isiss)", type, "", req_id, subject, input);
193 IF_FAIL_RETURN_TAG(param, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
196 g_dbus_connection_call(dbus_connection, DBUS_DEST, DBUS_PATH, DBUS_IFACE,
197 METHOD_REQUEST, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, &err);
201 return ERR_OPERATION_FAILED;