tizen 2.3 release
[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     char xdbg_dbus_server[STR_LEN];
52     char xdbg_dbus_path[STR_LEN];
53 };
54
55 static DBusHandlerResult
56 _xDbgDBusClinetMsgFilter (DBusConnection *conn, DBusMessage *msg, void *data)
57 {
58     XDbgDBusClientInfo *info = (XDbgDBusClientInfo*)data;
59
60     /* If we get disconnected, then take everything down, and attempt to
61      * reconnect immediately (assuming it's just a restart).  The
62      * connection isn't valid at this point, so throw it out immediately. */
63     if (dbus_message_is_signal (msg, DBUS_INTERFACE_LOCAL, "Disconnected"))
64     {
65         XDBG_LOG ("[CLIENT:%s] disconnected by signal\n", info->client);
66         info->conn = NULL;
67
68         return DBUS_HANDLER_RESULT_HANDLED;
69     }
70
71     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
72 }
73
74 static Bool
75 _xDbgDBusClinetInit (XDbgDBusClientInfo *info)
76 {
77     DBusError err;
78     int ret;
79     char *display_num;
80
81     if(!(display_num = getenv("DISPLAY")))
82     {
83         XDBG_LOG ("[CLIENT:%s] failed: get DISPLAY ENV\n", info->client);
84         return FALSE;
85     }
86
87     snprintf(info->xdbg_dbus_server, sizeof(info->xdbg_dbus_path), "org.x.dbg.server%d", atoi(display_num));
88     snprintf(info->xdbg_dbus_path, sizeof(info->xdbg_dbus_path), "/org/x/dbg/path/%d", atoi(display_num));
89
90     XDBG_LOG ("[CLIENT:%s] display number :%d\n", info->client, atoi(display_num));
91
92     dbus_error_init (&err);
93     RETURN_VAL_IF_FAIL (info->conn == NULL, FALSE);
94
95     info->conn = dbus_bus_get (DBUS_BUS_SYSTEM, &err);
96     if (dbus_error_is_set (&err))
97     {
98         XDBG_LOG ("[CLIENT:%s] failed: connection (%s)\n", info->client, err.message);
99         goto err_get;
100     }
101     if (!info->conn)
102     {
103         XDBG_LOG ("[CLIENT:%s] failed: connection NULL\n", info->client);
104         goto err_get;
105     }
106
107     dbus_connection_set_exit_on_disconnect (info->conn, FALSE);
108
109     if (!dbus_connection_add_filter (info->conn, _xDbgDBusClinetMsgFilter, info, NULL))
110     {
111         XDBG_LOG ("[CLIENT:%s] failed: add filter (%s)\n", info->client, err.message);
112         goto err_get;
113     }
114
115     ret = dbus_bus_request_name (info->conn, info->reqname,
116                                  DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
117     if (dbus_error_is_set (&err))
118     {
119         XDBG_LOG ("[CLIENT:%s] failed: request name (%s)\n", info->client, err.message);
120         goto err_request;
121     }
122     if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
123     {
124         XDBG_LOG ("[CLIENT:%s] failed: Not Primary Owner (%d)\n", info->client, ret);
125         goto err_request;
126     }
127
128     dbus_error_free (&err);
129
130 //    XDBG_LOG ("[CLIENT:%s] connected\n", info->client);
131
132     return TRUE;
133
134 err_request:
135     dbus_connection_remove_filter (info->conn, _xDbgDBusClinetMsgFilter, info);
136
137 err_get:
138     if (info->conn)
139     {
140         dbus_connection_unref (info->conn);
141         info->conn = NULL;
142     }
143
144     dbus_error_free (&err);
145
146     return FALSE;
147 }
148
149
150 static void
151 _xDbgDBusClinetDeinit (XDbgDBusClientInfo *info)
152 {
153     DBusError err;
154
155     if (!info->conn)
156         return;
157
158     dbus_error_init (&err);
159     dbus_bus_release_name (info->conn, info->reqname, &err);
160     if (dbus_error_is_set (&err))
161         XDBG_LOG ("[CLIENT:%s] failed: release name (%s)\n", info->client, err.message);
162     dbus_error_free (&err);
163
164     dbus_connection_remove_filter (info->conn, _xDbgDBusClinetMsgFilter, info);
165     dbus_connection_unref (info->conn);
166     info->conn = NULL;
167
168 //    XDBG_LOG ("[CLIENT:%s] disconnected\n", info->client);
169 }
170
171 XDbgDBusClientInfo*
172 xDbgDBusClientConnect (void)
173 {
174     XDbgDBusClientInfo *info = NULL;
175
176     info = calloc (1, sizeof (XDbgDBusClientInfo));
177     GOTO_IF_FAIL (info != NULL, err_conn);
178
179     snprintf (info->client, STR_LEN, "%d", getpid());
180     snprintf (info->reqname, STR_LEN, "%s%d", XDBG_DBUS_CLIENT, getpid());
181
182     if (!_xDbgDBusClinetInit (info))
183         goto err_conn;
184
185     return info;
186
187 err_conn:
188     if (info)
189         free (info);
190
191     return NULL;
192 }
193
194 void
195 xDbgDBusClientDisconnect (XDbgDBusClientInfo* info)
196 {
197     if (!info)
198         return;
199
200     _xDbgDBusClinetDeinit (info);
201
202     free (info);
203 }
204
205 void
206 xDbugDBusClientSendMessage (XDbgDBusClientInfo *info, int argc, char **argv)
207 {
208     DBusMessage *msg = NULL;
209     DBusMessage *reply_msg = NULL;
210     DBusMessageIter iter;
211     DBusError err;
212     char *arg = NULL;
213     int i;
214
215     RETURN_IF_FAIL (info != NULL);
216     RETURN_IF_FAIL (info->conn != NULL);
217     RETURN_IF_FAIL (argc > 0);
218     RETURN_IF_FAIL (argv[0] != '\0');
219
220     dbus_error_init (&err);
221
222     msg = dbus_message_new_method_call (info->xdbg_dbus_server, info->xdbg_dbus_path,
223                                         XDBG_DBUS_INTERFACE, XDBG_DBUS_METHOD);
224     GOTO_IF_FAIL (msg != NULL, err_send);
225
226     dbus_message_iter_init_append (msg, &iter);
227     for (i = 0; i < argc; i++)
228         if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &argv[i]))
229         {
230             XDBG_LOG ("[CLIENT:%s] failed: append\n", info->client);
231             goto err_send;
232         }
233
234     reply_msg = dbus_connection_send_with_reply_and_block (info->conn, msg,
235                                                            REPLY_TIME, &err);
236     if (dbus_error_is_set (&err))
237     {
238         XDBG_LOG ("[CLIENT:%s] failed: send (%s)\n", info->client, err.message);
239         goto err_send;
240     }
241     GOTO_IF_FAIL (reply_msg != NULL, err_send);
242
243     if (!dbus_message_iter_init (reply_msg, &iter))
244     {
245         XDBG_LOG ("[CLIENT:%s] Message has no arguments\n", info->client);
246         goto err_send;
247     }
248
249     do
250     {
251         arg = NULL;
252
253         if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
254         {
255             XDBG_LOG ("[CLIENT:%s] Argument is not string!\n", info->client);
256             goto err_send;
257         }
258
259         dbus_message_iter_get_basic (&iter, &arg);
260         if (!arg)
261         {
262             XDBG_LOG ("[CLIENT:%s] arg is NULL\n", info->client);
263             goto err_send;
264         }
265         else
266             XDBG_LOG ("%s\n", arg);
267     } while (dbus_message_iter_has_next (&iter) &&
268            dbus_message_iter_next (&iter));
269
270 err_send:
271     if (msg)
272         dbus_message_unref(msg);
273     if (reply_msg)
274         dbus_message_unref(reply_msg);
275 }