1 /**************************************************************************
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
7 Contact: Boram Park <boram1288.park@samsung.com>
8 Sangjin LEE <lsj119@samsung.com>
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:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
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.
30 **************************************************************************/
39 #include <dbus/dbus.h>
44 #include "xdbg_dbus_server.h"
47 #define REP_MSG_SIZE 8192
50 #define RECONNECT_TIME 1000
51 #define DISPATCH_TIME 50
53 typedef struct _XDbgDBusServerInfo
57 XDbgDbusServerMethod *methods;
62 static XDbgDBusServerInfo server_info;
64 static CARD32 _xDbgDBusServerTimeout (OsTimerPtr timer, CARD32 time, pointer arg);
65 static Bool _xDbgDBusServerInit (XDbgDBusServerInfo *info);
66 static void _xDbgDBusServerDeinit (XDbgDBusServerInfo *info);
69 _xDbgDBusServerReplyMessage (XDbgDBusServerInfo *info, DBusMessage *msg, char *reply)
71 DBusMessage *reply_msg = NULL;
74 XDBG_RETURN_VAL_IF_FAIL (info->conn != NULL, FALSE);
76 reply_msg = dbus_message_new_method_return (msg);
77 XDBG_RETURN_VAL_IF_FAIL (reply_msg != NULL, FALSE);
79 dbus_message_iter_init_append (reply_msg, &iter);
80 if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reply))
82 XDBG_ERROR (MDBUS, "[SERVER] out of memory\n");
83 dbus_message_unref (reply_msg);
87 if (!dbus_connection_send (info->conn, reply_msg, NULL))
89 XDBG_ERROR (MDBUS, "[SERVER] failed: send reply\n");
90 dbus_message_unref (reply_msg);
94 XDBG_INFO (MDBUS, "[SERVER] send reply\n");
96 dbus_connection_flush (info->conn);
97 dbus_message_unref (reply_msg);
103 _xDbgDBusServerProcessMessage (XDbgDBusServerInfo *info, DBusMessage *msg)
105 XDbgDbusServerMethod **prev;
107 char err_buf[REP_MSG_SIZE] = {0,};
108 char *argv[ARGV_NUM] = {0,};
112 snprintf (err_buf, REP_MSG_SIZE, "error message!\n");
114 dbus_error_init (&err);
116 XDBG_INFO (MDBUS, "[SERVER] Process a message (%s.%s)\n",
117 dbus_message_get_interface (msg), dbus_message_get_member (msg));
119 XDBG_RETURN_IF_FAIL (info->conn != NULL);
121 for (prev = &info->methods; *prev; prev = &(*prev)->next)
123 XDbgDbusServerMethod *method = *prev;
125 if (!strcmp (dbus_message_get_member (msg), method->name))
127 DBusMessageIter iter;
128 char reply[REP_MSG_SIZE] = {0,};
132 if (!dbus_message_iter_init (msg, &iter))
134 XDBG_ERROR (MDBUS, "[SERVER] Message has no arguments!\n");
135 snprintf (err_buf, REP_MSG_SIZE, "Message has no arguments!\n");
143 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
145 XDBG_ERROR (MDBUS, "[SERVER] Argument is not string!\n");
146 snprintf (err_buf, REP_MSG_SIZE, "Argument is not string!\n");
150 dbus_message_iter_get_basic (&iter, &p);
154 XDBG_ERROR (MDBUS, "[SERVER] Can't get string!\n");
155 snprintf (err_buf, REP_MSG_SIZE, "Can't get string!\n");
159 argv[argc] = strdup (p);
161 } while (dbus_message_iter_has_next (&iter) &&
162 dbus_message_iter_next (&iter) &&
165 len = REP_MSG_SIZE - 1;
168 method->func (method->data, argc, argv, reply, &len);
170 _xDbgDBusServerReplyMessage (info, msg, reply);
172 for (i = 0; i < ARGV_NUM; i++)
175 dbus_error_free (&err);
184 _xDbgDBusServerReplyMessage (info, msg, err_buf);
186 for (i = 0; i < ARGV_NUM; i++)
189 dbus_error_free (&err);
193 _xDbgDBusServerWakeupHandler (pointer data, int error, pointer pRead)
195 XDbgDBusServerInfo *info = (XDbgDBusServerInfo*)data;
197 if (!info || !info->conn || info->fd < 0)
200 if (FD_ISSET(info->fd, (fd_set*)pRead))
202 dbus_connection_ref (info->conn);
205 dbus_connection_read_write_dispatch (info->conn, 0);
206 } while (info->conn &&
207 dbus_connection_get_is_connected (info->conn) &&
208 dbus_connection_get_dispatch_status (info->conn) ==
209 DBUS_DISPATCH_DATA_REMAINS);
211 dbus_connection_unref (info->conn);
215 static DBusHandlerResult
216 _xDbgDBusServerMsgHandler (DBusConnection *connection, DBusMessage *msg, void *data)
218 XDbgDBusServerInfo *info = (XDbgDBusServerInfo*)data;
220 if (!info || !info->conn || !msg)
221 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
223 XDBG_INFO (MDBUS, "[SERVER] Got a message (%s.%s)\n",
224 dbus_message_get_interface (msg), dbus_message_get_member (msg));
226 if (!dbus_message_is_method_call (msg, XDBG_DBUS_INTERFACE, XDBG_DBUS_METHOD))
227 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
229 _xDbgDBusServerProcessMessage (info, msg);
231 return DBUS_HANDLER_RESULT_HANDLED;
234 static DBusHandlerResult
235 _xDbgDBusServerMsgFilter (DBusConnection *conn, DBusMessage *msg, void *data)
237 XDbgDBusServerInfo *info = (XDbgDBusServerInfo*)data;
240 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
242 if (dbus_message_is_signal (msg, DBUS_INTERFACE_LOCAL, "Disconnected"))
244 XDBG_INFO (MDBUS, "[SERVER] disconnected by signal\n");
245 _xDbgDBusServerDeinit (info);
248 TimerFree(info->timer);
249 info->timer = TimerSet(NULL, 0, 1, _xDbgDBusServerTimeout, info);
251 return DBUS_HANDLER_RESULT_HANDLED;
254 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
258 _xDbgDBusServerTimeout (OsTimerPtr timer, CARD32 time, pointer arg)
260 XDbgDBusServerInfo *info = (XDbgDBusServerInfo*)arg;
265 XDBG_DEBUG (MDBUS, "[SERVER] timeout\n");
267 if (_xDbgDBusServerInit (info))
269 TimerFree (info->timer);
274 return RECONNECT_TIME;
278 _xDbgDBusServerInit (XDbgDBusServerInfo *info)
280 DBusObjectPathVTable vtable = {.message_function = _xDbgDBusServerMsgHandler, };
284 dbus_error_init (&err);
286 XDBG_RETURN_VAL_IF_FAIL (info->conn == NULL, FALSE);
288 info->conn = dbus_bus_get (DBUS_BUS_SYSTEM, &err);
289 if (dbus_error_is_set (&err))
291 XDBG_ERROR (MDBUS, "[SERVER] failed: connection (%s)\n", err.message);
296 XDBG_ERROR (MDBUS, "[SERVER] failed: connection NULL\n");
300 ret = dbus_bus_request_name (info->conn, XDBG_DBUS_SERVER,
301 DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
302 if (dbus_error_is_set (&err))
304 XDBG_ERROR (MDBUS, "[SERVER] failed: request name (%s)\n", err.message);
307 if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
309 XDBG_ERROR (MDBUS, "[SERVER] failed: Not Primary Owner (%d)\n", ret);
313 snprintf (info->rule, sizeof (info->rule), "type='method_call',interface='%s'",
314 XDBG_DBUS_INTERFACE);
316 /* blocks until we get a reply. */
317 dbus_bus_add_match (info->conn, info->rule, &err);
318 if (dbus_error_is_set (&err))
320 XDBG_ERROR (MDBUS, "[SERVER] failed: add match (%s)\n", err.message);
324 if (!dbus_connection_register_object_path (info->conn,
325 XDBG_DBUS_PATH, &vtable,
328 XDBG_ERROR (MDBUS, "[SERVER] failed: register object path\n");
332 dbus_connection_set_exit_on_disconnect (info->conn, FALSE);
334 if (!dbus_connection_add_filter (info->conn, _xDbgDBusServerMsgFilter, info, NULL))
336 XDBG_ERROR (MDBUS, "[SERVER] failed: add filter (%s)\n", err.message);
340 if (!dbus_connection_get_unix_fd (info->conn, &info->fd) || info->fd < 0)
342 XDBG_ERROR (MDBUS, "[SERVER] failed: get fd\n");
346 AddGeneralSocket (info->fd);
347 RegisterBlockAndWakeupHandlers ((BlockHandlerProcPtr)NoopDDA,
348 _xDbgDBusServerWakeupHandler, info);
350 XDBG_INFO (MDBUS, "[SERVER] connected\n");
352 dbus_error_free (&err);
357 dbus_connection_remove_filter (info->conn, _xDbgDBusServerMsgFilter, info);
359 dbus_connection_unregister_object_path (info->conn, XDBG_DBUS_PATH);
361 dbus_bus_remove_match (info->conn, info->rule, &err);
362 dbus_error_free (&err);
364 dbus_bus_release_name (info->conn, XDBG_DBUS_SERVER, &err);
365 dbus_error_free (&err);
367 dbus_connection_close (info->conn);
369 dbus_error_free (&err);
377 _xDbgDBusServerDeinit (XDbgDBusServerInfo *info)
381 TimerFree (info->timer);
388 dbus_error_init (&err);
389 dbus_connection_remove_filter (info->conn, _xDbgDBusServerMsgFilter, info);
390 dbus_connection_unregister_object_path (info->conn, XDBG_DBUS_PATH);
391 dbus_bus_remove_match (info->conn, info->rule, &err);
392 dbus_error_free (&err);
393 dbus_bus_release_name (info->conn, XDBG_DBUS_SERVER, &err);
394 dbus_error_free (&err);
395 dbus_connection_unref (info->conn);
399 RemoveBlockAndWakeupHandlers ((BlockHandlerProcPtr)NoopDDA,
400 _xDbgDBusServerWakeupHandler, info);
403 RemoveGeneralSocket (info->fd);
407 XDBG_INFO (MDBUS, "[SERVER] disconnected\n");
411 xDbgDBusServerConnect (void)
413 XDBG_DEBUG (MDBUS, "[SERVER] connecting\n");
415 memset (&server_info, 0, sizeof(server_info));
418 server_info.timer = TimerSet (NULL, 0, 1, _xDbgDBusServerTimeout, &server_info);
424 xDbgDBusServerDisconnect (void)
426 XDBG_DEBUG (MDBUS, "[SERVER] disconnecting\n");
428 _xDbgDBusServerDeinit (&server_info);
432 xDbgDBusServerAddMethod (XDbgDbusServerMethod *method)
434 XDbgDbusServerMethod **prev;
436 for (prev = &server_info.methods; *prev; prev = &(*prev)->next);
445 xDbgDBusServerRemoveMethod (XDbgDbusServerMethod *method)
447 XDbgDbusServerMethod **prev;
449 for (prev = &server_info.methods; *prev; prev = &(*prev)->next)
452 *prev = method->next;