Initialize Tizen 2.3
[adaptation/xorg/driver/xserver-xorg-module-xdbg.git] / common / xdbg_dbus_client.c
1 /**************************************************************************
2
3 xdbg
4
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8          Sangjin LEE <lsj119@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <sys/types.h>
37 #include <unistd.h>
38
39 #include "xdbg_types.h"
40 #include "xdbg_dbus_client.h"
41
42 #define REPLY_TIME 1000
43 #define STR_LEN  128
44
45 struct _XDbgDBusClientInfo
46 {
47     DBusConnection *conn;
48     char reqname[STR_LEN];
49     char client[STR_LEN];
50     int  pid;
51 };
52
53 static DBusHandlerResult
54 _xDbgDBusClinetMsgFilter (DBusConnection *conn, DBusMessage *msg, void *data)
55 {
56     XDbgDBusClientInfo *info = (XDbgDBusClientInfo*)data;
57
58     /* If we get disconnected, then take everything down, and attempt to
59      * reconnect immediately (assuming it's just a restart).  The
60      * connection isn't valid at this point, so throw it out immediately. */
61     if (dbus_message_is_signal (msg, DBUS_INTERFACE_LOCAL, "Disconnected"))
62     {
63         XDBG_LOG ("[CLIENT:%s] disconnected by signal\n", info->client);
64         info->conn = NULL;
65
66         return DBUS_HANDLER_RESULT_HANDLED;
67     }
68
69     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
70 }
71
72 static Bool
73 _xDbgDBusClinetInit (XDbgDBusClientInfo *info)
74 {
75     DBusError err;
76     int ret;
77
78     dbus_error_init (&err);
79     RETURN_VAL_IF_FAIL (info->conn == NULL, FALSE);
80
81     info->conn = dbus_bus_get (DBUS_BUS_SYSTEM, &err);
82     if (dbus_error_is_set (&err))
83     {
84         XDBG_LOG ("[CLIENT:%s] failed: connection (%s)\n", info->client, err.message);
85         goto err_get;
86     }
87     if (!info->conn)
88     {
89         XDBG_LOG ("[CLIENT:%s] failed: connection NULL\n", info->client);
90         goto err_get;
91     }
92
93     dbus_connection_set_exit_on_disconnect (info->conn, FALSE);
94
95     if (!dbus_connection_add_filter (info->conn, _xDbgDBusClinetMsgFilter, info, NULL))
96     {
97         XDBG_LOG ("[CLIENT:%s] failed: add filter (%s)\n", info->client, err.message);
98         goto err_get;
99     }
100
101     ret = dbus_bus_request_name (info->conn, info->reqname,
102                                  DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
103     if (dbus_error_is_set (&err))
104     {
105         XDBG_LOG ("[CLIENT:%s] failed: request name (%s)\n", info->client, err.message);
106         goto err_request;
107     }
108     if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
109     {
110         XDBG_LOG ("[CLIENT:%s] failed: Not Primary Owner (%d)\n", info->client, ret);
111         goto err_request;
112     }
113
114     dbus_error_free (&err);
115
116 //    XDBG_LOG ("[CLIENT:%s] connected\n", info->client);
117
118     return TRUE;
119
120 err_request:
121     dbus_connection_remove_filter (info->conn, _xDbgDBusClinetMsgFilter, info);
122
123 err_get:
124     if (info->conn)
125     {
126         dbus_connection_unref (info->conn);
127         info->conn = NULL;
128     }
129
130     dbus_error_free (&err);
131
132     return FALSE;
133 }
134
135
136 static void
137 _xDbgDBusClinetDeinit (XDbgDBusClientInfo *info)
138 {
139     DBusError err;
140
141     if (!info->conn)
142         return;
143
144     dbus_error_init (&err);
145     dbus_bus_release_name (info->conn, info->reqname, &err);
146     if (dbus_error_is_set (&err))
147         XDBG_LOG ("[CLIENT:%s] failed: release name (%s)\n", info->client, err.message);
148     dbus_error_free (&err);
149
150     dbus_connection_remove_filter (info->conn, _xDbgDBusClinetMsgFilter, info);
151     dbus_connection_unref (info->conn);
152     info->conn = NULL;
153
154 //    XDBG_LOG ("[CLIENT:%s] disconnected\n", info->client);
155 }
156
157 XDbgDBusClientInfo*
158 xDbgDBusClientConnect (void)
159 {
160     XDbgDBusClientInfo *info = NULL;
161
162     info = calloc (1, sizeof (XDbgDBusClientInfo));
163     GOTO_IF_FAIL (info != NULL, err_conn);
164
165     snprintf (info->client, STR_LEN, "%d", getpid());
166     snprintf (info->reqname, STR_LEN, "%s%d", XDBG_DBUS_CLIENT, getpid());
167
168     if (!_xDbgDBusClinetInit (info))
169         goto err_conn;
170
171     return info;
172
173 err_conn:
174     if (info)
175         free (info);
176
177     return NULL;
178 }
179
180 void
181 xDbgDBusClientDisconnect (XDbgDBusClientInfo* info)
182 {
183     if (!info)
184         return;
185
186     _xDbgDBusClinetDeinit (info);
187
188     free (info);
189 }
190
191 void
192 xDbugDBusClientSendMessage (XDbgDBusClientInfo *info, int argc, char **argv)
193 {
194     DBusMessage *msg = NULL;
195     DBusMessage *reply_msg = NULL;
196     DBusMessageIter iter;
197     DBusError err;
198     char *arg = NULL;
199     int i;
200
201     RETURN_IF_FAIL (info != NULL);
202     RETURN_IF_FAIL (info->conn != NULL);
203     RETURN_IF_FAIL (argc > 0);
204     RETURN_IF_FAIL (argv[0] != '\0');
205
206     dbus_error_init (&err);
207
208     msg = dbus_message_new_method_call (XDBG_DBUS_SERVER, XDBG_DBUS_PATH,
209                                         XDBG_DBUS_INTERFACE, XDBG_DBUS_METHOD);
210     GOTO_IF_FAIL (msg != NULL, err_send);
211
212     dbus_message_iter_init_append (msg, &iter);
213     for (i = 0; i < argc; i++)
214         if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &argv[i]))
215         {
216             XDBG_LOG ("[CLIENT:%s] failed: append\n", info->client);
217             goto err_send;
218         }
219
220     reply_msg = dbus_connection_send_with_reply_and_block (info->conn, msg,
221                                                            REPLY_TIME, &err);
222     if (dbus_error_is_set (&err))
223     {
224         XDBG_LOG ("[CLIENT:%s] failed: send (%s)\n", info->client, err.message);
225         goto err_send;
226     }
227     GOTO_IF_FAIL (reply_msg != NULL, err_send);
228
229     if (!dbus_message_iter_init (reply_msg, &iter))
230     {
231         XDBG_LOG ("[CLIENT:%s] Message has no arguments\n", info->client);
232         goto err_send;
233     }
234
235     do
236     {
237         arg = NULL;
238
239         if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
240         {
241             XDBG_LOG ("[CLIENT:%s] Argument is not string!\n", info->client);
242             goto err_send;
243         }
244
245         dbus_message_iter_get_basic (&iter, &arg);
246         if (!arg)
247         {
248             XDBG_LOG ("[CLIENT:%s] arg is NULL\n", info->client);
249             goto err_send;
250         }
251         else
252             XDBG_LOG ("%s\n", arg);
253     } while (dbus_message_iter_has_next (&iter) &&
254            dbus_message_iter_next (&iter));
255
256 err_send:
257     if (msg)
258         dbus_message_unref(msg);
259     if (reply_msg)
260         dbus_message_unref(reply_msg);
261 }