switch to cdbus code from libcdbus.so
parent
3898a88d10
commit
da2edb9c0e
File diff suppressed because it is too large
Load Diff
@ -1,140 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2008,2009,2010,2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains interface to the D-Bus helpers code
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef HELPERS_H__6C2107A6_A5E3_4806_869B_4BE609535BA2__INCLUDED
|
||||
#define HELPERS_H__6C2107A6_A5E3_4806_869B_4BE609535BA2__INCLUDED
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
extern DBusConnection * cdbus_g_dbus_connection;
|
||||
extern DBusError cdbus_g_dbus_error;
|
||||
|
||||
bool cdbus_iter_get_dict_entry(DBusMessageIter * iter_ptr, const char * key, void * value, int * type, int * size);
|
||||
bool cdbus_iter_get_dict_entry_string(DBusMessageIter * iter_ptr, const char * key, const char ** value);
|
||||
bool cdbus_iter_append_variant(DBusMessageIter * iter, int type, const void * arg);
|
||||
bool cdbus_iter_append_dict_entry(DBusMessageIter *iter, int type, const char * key, const void * value, int length);
|
||||
bool cdbus_maybe_add_dict_entry_string(DBusMessageIter *dict_iter_ptr, const char * key, const char * value);
|
||||
bool cdbus_add_dict_entry_uint32(DBusMessageIter * dict_iter_ptr, const char * key, dbus_uint32_t value);
|
||||
bool cdbus_add_dict_entry_bool(DBusMessageIter * dict_iter_ptr, const char * key, dbus_bool_t value);
|
||||
|
||||
DBusMessage *
|
||||
cdbus_call_raw(
|
||||
unsigned int timeout, /* in milliseconds */
|
||||
DBusMessage * request_ptr);
|
||||
|
||||
bool
|
||||
cdbus_call(
|
||||
unsigned int timeout, /* in milliseconds */
|
||||
const char * service,
|
||||
const char * object,
|
||||
const char * iface,
|
||||
const char * method,
|
||||
const char * input_signature,
|
||||
...);
|
||||
|
||||
bool
|
||||
cdbus_call_async(
|
||||
DBusMessage * request_ptr,
|
||||
void * context,
|
||||
void * cookie,
|
||||
size_t cookie_size,
|
||||
void (* callback)(void * context, void * cookie, DBusMessage * reply_ptr));
|
||||
|
||||
DBusMessage *
|
||||
cdbus_new_method_call_message(
|
||||
const char * service,
|
||||
const char * object,
|
||||
const char * iface,
|
||||
const char * method,
|
||||
const char * input_signature,
|
||||
...);
|
||||
|
||||
bool
|
||||
cdbus_register_object_signal_handler(
|
||||
DBusConnection * connection,
|
||||
const char * service,
|
||||
const char * object,
|
||||
const char * iface,
|
||||
const char * const * signals,
|
||||
DBusHandleMessageFunction handler,
|
||||
void * handler_data);
|
||||
|
||||
bool
|
||||
cdbus_unregister_object_signal_handler(
|
||||
DBusConnection * connection,
|
||||
const char * service,
|
||||
const char * object,
|
||||
const char * iface,
|
||||
const char * const * signals,
|
||||
DBusHandleMessageFunction handler,
|
||||
void * handler_data);
|
||||
|
||||
struct cdbus_signal_hook
|
||||
{
|
||||
const char * signal_name;
|
||||
void (* hook_function)(void * context, DBusMessage * message_ptr);
|
||||
};
|
||||
|
||||
bool
|
||||
cdbus_register_object_signal_hooks(
|
||||
DBusConnection * connection,
|
||||
const char * service,
|
||||
const char * object,
|
||||
const char * iface,
|
||||
void * hook_context,
|
||||
const struct cdbus_signal_hook * signal_hooks);
|
||||
|
||||
void
|
||||
cdbus_unregister_object_signal_hooks(
|
||||
DBusConnection * connection,
|
||||
const char * service,
|
||||
const char * object,
|
||||
const char * iface);
|
||||
|
||||
bool
|
||||
cdbus_register_service_lifetime_hook(
|
||||
DBusConnection * connection,
|
||||
const char * service,
|
||||
void (* hook_function)(bool appeared));
|
||||
|
||||
void
|
||||
cdbus_unregister_service_lifetime_hook(
|
||||
DBusConnection * connection,
|
||||
const char * service);
|
||||
|
||||
void cdbus_call_last_error_cleanup(void);
|
||||
bool cdbus_call_last_error_is_name(const char * name);
|
||||
const char * cdbus_call_last_error_get_message(void);
|
||||
|
||||
#include "method.h"
|
||||
#include "signal.h"
|
||||
#include "interface.h"
|
||||
#include "object_path.h"
|
||||
|
||||
#endif /* #ifndef HELPERS_H__6C2107A6_A5E3_4806_869B_4BE609535BA2__INCLUDED */
|
@ -1,67 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2008,2009,2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains D-Bus interface dispatcher
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "../common.h"
|
||||
#include "helpers.h"
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Execute a method's function if the method specified in the method call
|
||||
* object exists in the method array. Return true if the method was found,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool cdbus_interface_default_handler(const struct cdbus_interface_descriptor * iface_ptr, struct cdbus_method_call * call_ptr)
|
||||
{
|
||||
const struct cdbus_method_descriptor * method_ptr;
|
||||
|
||||
for (method_ptr = iface_ptr->methods; method_ptr->name != NULL; method_ptr++)
|
||||
{
|
||||
if (strcmp(call_ptr->method_name, method_ptr->name) == 0)
|
||||
{
|
||||
call_ptr->iface = iface_ptr;
|
||||
method_ptr->handler(call_ptr);
|
||||
/* If the method handler didn't construct a return message create a void one here */
|
||||
// TODO: Also handle cases where the sender doesn't need a reply
|
||||
if (call_ptr->reply == NULL)
|
||||
{
|
||||
call_ptr->reply = dbus_message_new_method_return(call_ptr->message);
|
||||
if (call_ptr->reply == NULL)
|
||||
{
|
||||
log_error("Failed to construct void method return");
|
||||
}
|
||||
}
|
||||
|
||||
/* Known method */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unknown method */
|
||||
return false;
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2008,2009,2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains declaration of macros used to define D-Bus interfaces
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __CDBUS_INTERFACE_H__
|
||||
#define __CDBUS_INTERFACE_H__
|
||||
|
||||
typedef bool (* cdbus_interface_handler)(const struct cdbus_interface_descriptor *, struct cdbus_method_call *);
|
||||
|
||||
struct cdbus_interface_descriptor
|
||||
{
|
||||
const char * name;
|
||||
cdbus_interface_handler handler;
|
||||
const struct cdbus_method_descriptor * methods;
|
||||
const struct cdbus_signal_descriptor * signals;
|
||||
};
|
||||
|
||||
bool cdbus_interface_default_handler(const struct cdbus_interface_descriptor * interface, struct cdbus_method_call * call_ptr);
|
||||
|
||||
#define CDBUS_INTERFACE_BEGIN(iface_var, iface_name) \
|
||||
const struct cdbus_interface_descriptor iface_var = \
|
||||
{ \
|
||||
.name = iface_name,
|
||||
|
||||
#define CDBUS_INTERFACE_DEFAULT_HANDLER \
|
||||
.handler = cdbus_interface_default_handler,
|
||||
|
||||
#define CDBUS_INTERFACE_HANDLER(handler_func) \
|
||||
.handler = handler_func,
|
||||
|
||||
#define CDBUS_INTERFACE_EXPOSE_METHODS \
|
||||
.methods = methods_dtor,
|
||||
|
||||
#define CDBUS_INTERFACE_EXPOSE_SIGNALS \
|
||||
.signals = signals_dtor,
|
||||
|
||||
#define CDBUS_INTERFACE_END \
|
||||
};
|
||||
|
||||
#define CDBUS_INTERFACE_DEFAULT_HANDLER_METHODS_ONLY(iface_var, iface_name) \
|
||||
CDBUS_INTERFACE_BEGIN(iface_var, iface_name) \
|
||||
CDBUS_INTERFACE_DEFAULT_HANDLER \
|
||||
CDBUS_INTERFACE_EXPOSE_METHODS \
|
||||
CDBUS_INTERFACE_END
|
||||
|
||||
#define CDBUS_INTERFACE_DEFAULT_HANDLER_SIGNALS_ONLY(iface_var, iface_name) \
|
||||
CDBUS_INTERFACE_BEGIN(iface_var, iface_name) \
|
||||
CDBUS_INTERFACE_DEFAULT_HANDLER \
|
||||
CDBUS_INTERFACE_EXPOSE_SIGNALS \
|
||||
CDBUS_INTERFACE_END
|
||||
|
||||
#define CDBUS_INTERFACE_DEFAULT_HANDLER_METHODS_AND_SIGNALS(iface_var, iface_name) \
|
||||
CDBUS_INTERFACE_BEGIN(iface_var, iface_name) \
|
||||
CDBUS_INTERFACE_DEFAULT_HANDLER \
|
||||
CDBUS_INTERFACE_EXPOSE_METHODS \
|
||||
CDBUS_INTERFACE_EXPOSE_SIGNALS \
|
||||
CDBUS_INTERFACE_END
|
||||
|
||||
#endif /* __CDBUS_INTERFACE_H__ */
|
@ -1,12 +0,0 @@
|
||||
cdbus_sources = [
|
||||
'helpers.c',
|
||||
'interface.c',
|
||||
'method.c',
|
||||
'object_path.c',
|
||||
'signal.c',
|
||||
]
|
||||
|
||||
cdbuslib = static_library('cdbus', cdbus_sources,
|
||||
include_directories : inc,
|
||||
dependencies : dbus_dep,
|
||||
install : false)
|
@ -1,198 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2008,2009,2010,2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains D-Bus methods helpers
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "../common.h"
|
||||
#include "helpers.h"
|
||||
#include "method.h"
|
||||
|
||||
void cdbus_error(struct cdbus_method_call * call_ptr, const char * err_name, const char * format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char message[1024];
|
||||
const char *interface_name;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
vsnprintf(message, sizeof(message), format, ap);
|
||||
message[sizeof(message) - 1] = '\0';
|
||||
|
||||
va_end(ap);
|
||||
|
||||
if (call_ptr != NULL)
|
||||
{
|
||||
interface_name = (call_ptr->iface && call_ptr->iface->name && call_ptr->iface->name[0]) ? call_ptr->iface->name : "<unknown>";
|
||||
|
||||
log_error("In method %s.%s: %s", interface_name, call_ptr->method_name, message);
|
||||
|
||||
call_ptr->reply = dbus_message_new_error(call_ptr->message, err_name, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("%s", message);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a void method return.
|
||||
*
|
||||
* The operation can only fail due to lack of memory, in which case
|
||||
* there's no sense in trying to construct an error return. Instead,
|
||||
* call_ptr->reply will be set to NULL and handled in send_method_return().
|
||||
*/
|
||||
void cdbus_method_return_new_void(struct cdbus_method_call * call_ptr)
|
||||
{
|
||||
if (!(call_ptr->reply = dbus_message_new_method_return(call_ptr->message))) {
|
||||
log_error("Ran out of memory trying to construct method return");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a method return which holds a single argument or, if
|
||||
* the type parameter is DBUS_TYPE_INVALID, no arguments at all
|
||||
* (a void message).
|
||||
*
|
||||
* The operation can only fail due to lack of memory, in which case
|
||||
* there's no sense in trying to construct an error return. Instead,
|
||||
* call_ptr->reply will be set to NULL and handled in send_method_return().
|
||||
*/
|
||||
void cdbus_method_return_new_single(struct cdbus_method_call * call_ptr, int type, const void * arg)
|
||||
{
|
||||
if (!call_ptr || !arg) {
|
||||
log_error("Invalid arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
call_ptr->reply = dbus_message_new_method_return(call_ptr->message);
|
||||
|
||||
if (!call_ptr->reply)
|
||||
goto fail_no_mem;
|
||||
|
||||
/* Prevent crash on NULL input string. */
|
||||
if (type == DBUS_TYPE_STRING && !(*((const char **) arg)))
|
||||
*((const char **) arg) = "";
|
||||
|
||||
DBusMessageIter iter;
|
||||
|
||||
dbus_message_iter_init_append(call_ptr->reply, &iter);
|
||||
|
||||
if (dbus_message_iter_append_basic(&iter, type, arg))
|
||||
return;
|
||||
|
||||
dbus_message_unref(call_ptr->reply);
|
||||
call_ptr->reply = NULL;
|
||||
|
||||
fail_no_mem:
|
||||
log_error("Ran out of memory trying to construct method return");
|
||||
}
|
||||
|
||||
void cdbus_method_return_new_valist(struct cdbus_method_call * call_ptr, int type, ...)
|
||||
{
|
||||
if (!call_ptr) {
|
||||
log_error("Call pointer is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == DBUS_TYPE_INVALID) {
|
||||
log_error("No argument(s) supplied");
|
||||
return;
|
||||
}
|
||||
|
||||
va_list argp;
|
||||
|
||||
call_ptr->reply = dbus_message_new_method_return(call_ptr->message);
|
||||
if (!call_ptr->reply)
|
||||
goto fail_no_mem;
|
||||
|
||||
va_start(argp, type);
|
||||
|
||||
if (dbus_message_append_args_valist(call_ptr->reply, type, argp)) {
|
||||
va_end(argp);
|
||||
return;
|
||||
}
|
||||
|
||||
va_end(argp);
|
||||
|
||||
dbus_message_unref(call_ptr->reply);
|
||||
call_ptr->reply = NULL;
|
||||
|
||||
fail_no_mem:
|
||||
log_error("Ran out of memory trying to construct method return");
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a method return.
|
||||
*
|
||||
* If call_ptr->reply is NULL, i.e. a previous attempt to construct
|
||||
* a return has failed, attempt to send a void return.
|
||||
*/
|
||||
void cdbus_method_return_send(struct cdbus_method_call * call_ptr)
|
||||
{
|
||||
if (call_ptr->reply) {
|
||||
retry_send:
|
||||
if (!dbus_connection_send(call_ptr->connection, call_ptr->reply, NULL))
|
||||
log_error("Ran out of memory trying to queue "
|
||||
"method return");
|
||||
else
|
||||
dbus_connection_flush(call_ptr->connection);
|
||||
|
||||
dbus_message_unref(call_ptr->reply);
|
||||
call_ptr->reply = NULL;
|
||||
} else {
|
||||
log_debug("Message was NULL, trying to construct a void return");
|
||||
|
||||
if ((call_ptr->reply = dbus_message_new_method_return(call_ptr->message))) {
|
||||
log_debug("Constructed a void return, trying to queue it");
|
||||
goto retry_send;
|
||||
} else {
|
||||
log_error("Failed to construct method return!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cdbus_method_return_verify(DBusMessage * msg, const char ** str)
|
||||
{
|
||||
if (!msg || dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR)
|
||||
return true;
|
||||
|
||||
const char *ptr;
|
||||
|
||||
if (!dbus_message_get_args(msg, &cdbus_g_dbus_error,
|
||||
DBUS_TYPE_STRING, &ptr,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
log_error("Cannot read description from D-Bus error message: %s ",
|
||||
cdbus_g_dbus_error.message);
|
||||
dbus_error_free(&cdbus_g_dbus_error);
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
if (str)
|
||||
*str = ptr;
|
||||
|
||||
return false;
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2008,2009,2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains interface to D-Bus methods helpers
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __CDBUS_METHOD_H__
|
||||
#define __CDBUS_METHOD_H__
|
||||
|
||||
struct cdbus_method_call
|
||||
{
|
||||
DBusConnection * connection;
|
||||
const char * method_name;
|
||||
DBusMessage * message;
|
||||
DBusMessage * reply;
|
||||
const struct cdbus_interface_descriptor * iface;
|
||||
void * iface_context;
|
||||
};
|
||||
|
||||
struct cdbus_method_arg_descriptor
|
||||
{
|
||||
const char * name;
|
||||
const char * type;
|
||||
const bool direction_in; /* false == out, true == in */
|
||||
};
|
||||
|
||||
typedef void (* cdbus_method_handler)(struct cdbus_method_call * call_ptr);
|
||||
|
||||
struct cdbus_method_descriptor
|
||||
{
|
||||
const char * name;
|
||||
const cdbus_method_handler handler;
|
||||
const struct cdbus_method_arg_descriptor * args;
|
||||
};
|
||||
|
||||
void cdbus_error(struct cdbus_method_call * call_ptr, const char * err_name, const char * format, ...);
|
||||
|
||||
void cdbus_method_return_new_void(struct cdbus_method_call * call_ptr);
|
||||
void cdbus_method_return_new_single(struct cdbus_method_call * call_ptr, int type, const void * arg);
|
||||
void cdbus_method_return_new_valist(struct cdbus_method_call * call_ptr, int type, ...);
|
||||
bool cdbus_method_return_verify(DBusMessage * msg, const char ** str);
|
||||
void cdbus_method_return_send(struct cdbus_method_call * call_ptr);
|
||||
void cdbus_method_default_handler(DBusPendingCall * pending, void * data);
|
||||
|
||||
#define CDBUS_METHOD_ARGS_BEGIN(method_name, descr) \
|
||||
static const struct cdbus_method_arg_descriptor method_name ## _args_dtor[] = \
|
||||
{
|
||||
|
||||
#define CDBUS_METHOD_ARG_DESCRIBE_IN(arg_name, arg_type, descr) \
|
||||
{ \
|
||||
.name = arg_name, \
|
||||
.type = arg_type, \
|
||||
.direction_in = true \
|
||||
},
|
||||
|
||||
#define CDBUS_METHOD_ARG_DESCRIBE_OUT(arg_name, arg_type, descr)\
|
||||
{ \
|
||||
.name = arg_name, \
|
||||
.type = arg_type, \
|
||||
.direction_in = false \
|
||||
},
|
||||
|
||||
#define CDBUS_METHOD_ARGS_END \
|
||||
{ \
|
||||
.name = NULL, \
|
||||
} \
|
||||
};
|
||||
|
||||
#define CDBUS_METHODS_BEGIN \
|
||||
static const struct cdbus_method_descriptor methods_dtor[] = \
|
||||
{
|
||||
|
||||
#define CDBUS_METHOD_DESCRIBE(method_name, handler_name) \
|
||||
{ \
|
||||
.name = # method_name, \
|
||||
.handler = handler_name, \
|
||||
.args = method_name ## _args_dtor \
|
||||
},
|
||||
|
||||
#define CDBUS_METHODS_END \
|
||||
{ \
|
||||
.name = NULL, \
|
||||
.handler = NULL, \
|
||||
.args = NULL \
|
||||
} \
|
||||
};
|
||||
|
||||
#endif /* __CDBUS_METHOD_H__ */
|
@ -1,436 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2008,2009,2010,2011,2012 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains D-Bus object path helpers
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "../common.h"
|
||||
#include "helpers.h"
|
||||
|
||||
struct cdbus_object_path_interface
|
||||
{
|
||||
const struct cdbus_interface_descriptor * iface;
|
||||
void * iface_context;
|
||||
};
|
||||
|
||||
struct cdbus_object_path
|
||||
{
|
||||
char * name;
|
||||
DBusMessage * introspection;
|
||||
struct cdbus_object_path_interface * ifaces;
|
||||
bool registered;
|
||||
};
|
||||
|
||||
#define write_buf(args...) buf_ptr += sprintf(buf_ptr, ## args)
|
||||
|
||||
DBusMessage * cdbus_introspection_new(struct cdbus_object_path * opath_ptr)
|
||||
{
|
||||
char *xml_data, *buf_ptr;
|
||||
const struct cdbus_object_path_interface * iface_ptr;
|
||||
const struct cdbus_method_descriptor * method_ptr;
|
||||
const struct cdbus_method_arg_descriptor * method_arg_ptr;
|
||||
const struct cdbus_signal_descriptor * signal_ptr;
|
||||
const struct cdbus_signal_arg_descriptor * signal_arg_ptr;
|
||||
DBusMessage * msg;
|
||||
DBusMessageIter iter;
|
||||
|
||||
log_debug("Creating introspection message");
|
||||
|
||||
/*
|
||||
* Create introspection XML data.
|
||||
*/
|
||||
|
||||
/* TODO: we assume that 16 KiB is enough to hold introspection xml.
|
||||
* If it gets larger, memory corruption will occur.
|
||||
* Use realloc-like algorithm instead */
|
||||
xml_data = malloc(16384);
|
||||
if (xml_data == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf_ptr = xml_data;
|
||||
|
||||
write_buf("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
|
||||
" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
||||
"<node name=\"%s\">\n", opath_ptr->name);
|
||||
|
||||
/* Add the object path's interfaces. */
|
||||
for (iface_ptr = opath_ptr->ifaces; iface_ptr->iface != NULL; iface_ptr++)
|
||||
{
|
||||
write_buf(" <interface name=\"%s\">\n", iface_ptr->iface->name);
|
||||
if (iface_ptr->iface->methods != NULL)
|
||||
{
|
||||
/* Add the interface's methods. */
|
||||
for (method_ptr = iface_ptr->iface->methods; method_ptr->name != NULL; method_ptr++)
|
||||
{
|
||||
write_buf(" <method name=\"%s\">\n", method_ptr->name);
|
||||
/* Add the method's arguments. */
|
||||
for (method_arg_ptr = method_ptr->args; method_arg_ptr->name != NULL; method_arg_ptr++)
|
||||
{
|
||||
write_buf(
|
||||
" <arg name=\"%s\" type=\"%s\" direction=\"%s\" />\n",
|
||||
method_arg_ptr->name,
|
||||
method_arg_ptr->type,
|
||||
method_arg_ptr->direction_in ? "in" : "out");
|
||||
}
|
||||
write_buf(" </method>\n");
|
||||
}
|
||||
}
|
||||
if (iface_ptr->iface->signals != NULL)
|
||||
{
|
||||
/* Add the interface's signals. */
|
||||
for (signal_ptr = iface_ptr->iface->signals; signal_ptr->name != NULL; signal_ptr++)
|
||||
{
|
||||
write_buf(" <signal name=\"%s\">\n", signal_ptr->name);
|
||||
/* Add the signal's arguments. */
|
||||
for (signal_arg_ptr = signal_ptr->args; signal_arg_ptr->name != NULL; signal_arg_ptr++)
|
||||
{
|
||||
write_buf(" <arg name=\"%s\" type=\"%s\" />\n", signal_arg_ptr->name, signal_arg_ptr->type);
|
||||
}
|
||||
write_buf(" </signal>\n");
|
||||
}
|
||||
}
|
||||
write_buf(" </interface>\n");
|
||||
}
|
||||
write_buf("</node>\n");
|
||||
|
||||
/*
|
||||
* Create a D-Bus message from the XML data.
|
||||
*/
|
||||
|
||||
if ((msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN)))
|
||||
{
|
||||
dbus_message_iter_init_append(msg, &iter);
|
||||
if (dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, (const void *) &xml_data))
|
||||
{
|
||||
dbus_message_set_no_reply(msg, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbus_message_unref(msg);
|
||||
msg = NULL;
|
||||
log_error("Failed to append data to introspection message");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Failed to create introspection message");
|
||||
}
|
||||
|
||||
free(xml_data);
|
||||
return msg;
|
||||
}
|
||||
|
||||
#undef write_buf
|
||||
|
||||
void cdbus_introspection_destroy(struct cdbus_object_path *path)
|
||||
{
|
||||
log_debug("Destroying introspection message");
|
||||
|
||||
if (path && path->introspection) {
|
||||
dbus_message_unref(path->introspection);
|
||||
path->introspection = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug("Nothing to destroy");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
cdbus_introspection_handler(
|
||||
const struct cdbus_interface_descriptor * UNUSED(interface),
|
||||
struct cdbus_method_call * call_ptr)
|
||||
{
|
||||
if (strcmp(call_ptr->method_name, "Introspect") != 0)
|
||||
{
|
||||
/* The requested method wasn't "Introspect". */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Try to construct the instrospection message */
|
||||
call_ptr->reply = dbus_message_copy(call_ptr->iface_context); /* context contains the reply message */
|
||||
if (call_ptr->reply == NULL)
|
||||
{
|
||||
log_error("Ran out of memory trying to copy introspection message");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!dbus_message_set_destination(call_ptr->reply, dbus_message_get_sender(call_ptr->message)))
|
||||
{
|
||||
log_error("dbus_message_set_destination() failed.");
|
||||
goto unref_reply;
|
||||
}
|
||||
|
||||
if (!dbus_message_set_reply_serial(call_ptr->reply, dbus_message_get_serial(call_ptr->message)))
|
||||
{
|
||||
log_error("dbus_message_set_reply_serial() failed.");
|
||||
goto unref_reply;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
unref_reply:
|
||||
dbus_message_unref(call_ptr->reply);
|
||||
call_ptr->reply = NULL;
|
||||
|
||||
fail:
|
||||
/* Even after an error we need to return true, because the
|
||||
handler is only supposed to return false if a nonexistent
|
||||
method is requested. */
|
||||
return true;
|
||||
}
|
||||
|
||||
CDBUS_METHOD_ARGS_BEGIN(Introspect, "Get introspection XML")
|
||||
CDBUS_METHOD_ARG_DESCRIBE_OUT("xml_data", "s", "XML description of the object")
|
||||
CDBUS_METHOD_ARGS_END
|
||||
|
||||
CDBUS_METHODS_BEGIN
|
||||
CDBUS_METHOD_DESCRIBE(Introspect, NULL)
|
||||
CDBUS_METHODS_END
|
||||
|
||||
CDBUS_INTERFACE_BEGIN(g_dbus_interface_dtor_introspectable, "org.freedesktop.DBus.Introspectable")
|
||||
CDBUS_INTERFACE_HANDLER(cdbus_introspection_handler)
|
||||
CDBUS_INTERFACE_EXPOSE_METHODS
|
||||
CDBUS_INTERFACE_END
|
||||
|
||||
cdbus_object_path cdbus_object_path_new(const char *name, const struct cdbus_interface_descriptor * iface1_ptr, ...)
|
||||
{
|
||||
struct cdbus_object_path * opath_ptr;
|
||||
va_list ap;
|
||||
const struct cdbus_interface_descriptor * iface_src_ptr;
|
||||
struct cdbus_object_path_interface * iface_dst_ptr;
|
||||
size_t len;
|
||||
|
||||
log_debug("Creating object path");
|
||||
|
||||
opath_ptr = malloc(sizeof(struct cdbus_object_path));
|
||||
if (opath_ptr == NULL)
|
||||
{
|
||||
log_error("malloc() failed to allocate struct cdbus_object_path.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
opath_ptr->name = strdup(name);
|
||||
if (opath_ptr->name == NULL)
|
||||
{
|
||||
log_error("malloc() failed to allocate struct cdbus_object_path.");
|
||||
goto free;
|
||||
}
|
||||
|
||||
va_start(ap, iface1_ptr);
|
||||
iface_src_ptr = iface1_ptr;
|
||||
len = 0;
|
||||
while (iface_src_ptr != NULL)
|
||||
{
|
||||
va_arg(ap, void *); /* skip interface context */
|
||||
iface_src_ptr = va_arg(ap, const struct cdbus_interface_descriptor *);
|
||||
len++;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
opath_ptr->ifaces = malloc((len + 2) * sizeof(struct cdbus_object_path_interface));
|
||||
if (opath_ptr->ifaces == NULL)
|
||||
{
|
||||
log_error("malloc failed to allocate interfaces array");
|
||||
goto free_name;
|
||||
}
|
||||
|
||||
va_start(ap, iface1_ptr);
|
||||
iface_src_ptr = iface1_ptr;
|
||||
iface_dst_ptr = opath_ptr->ifaces;
|
||||
while (iface_src_ptr != NULL)
|
||||
{
|
||||
iface_dst_ptr->iface = iface_src_ptr;
|
||||
iface_dst_ptr->iface_context = va_arg(ap, void *);
|
||||
iface_src_ptr = va_arg(ap, const struct cdbus_interface_descriptor *);
|
||||
iface_dst_ptr++;
|
||||
len--;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
ASSERT(len == 0);
|
||||
|
||||
iface_dst_ptr->iface = NULL;
|
||||
opath_ptr->introspection = cdbus_introspection_new(opath_ptr);
|
||||
if (opath_ptr->introspection == NULL)
|
||||
{
|
||||
log_error("introspection_new() failed.");
|
||||
goto free_ifaces;
|
||||
}
|
||||
|
||||
iface_dst_ptr->iface = &g_dbus_interface_dtor_introspectable;
|
||||
iface_dst_ptr->iface_context = opath_ptr->introspection;
|
||||
iface_dst_ptr++;
|
||||
iface_dst_ptr->iface = NULL;
|
||||
|
||||
opath_ptr->registered = false;
|
||||
|
||||
return (cdbus_object_path)opath_ptr;
|
||||
|
||||
free_ifaces:
|
||||
free(opath_ptr->ifaces);
|
||||
free_name:
|
||||
free(opath_ptr->name);
|
||||
free:
|
||||
free(opath_ptr);
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define opath_ptr ((struct cdbus_object_path *)data)
|
||||
|
||||
void cdbus_object_path_unregister(DBusConnection * connection_ptr, cdbus_object_path data)
|
||||
{
|
||||
ASSERT(opath_ptr->registered);
|
||||
|
||||
if (!dbus_connection_unregister_object_path(connection_ptr, opath_ptr->name))
|
||||
{
|
||||
log_error("dbus_connection_unregister_object_path() failed.");
|
||||
}
|
||||
}
|
||||
|
||||
void cdbus_object_path_destroy(DBusConnection * connection_ptr, cdbus_object_path data)
|
||||
{
|
||||
log_debug("Destroying object path");
|
||||
|
||||
if (opath_ptr->registered && connection_ptr != NULL && !dbus_connection_unregister_object_path(connection_ptr, opath_ptr->name))
|
||||
{
|
||||
log_error("dbus_connection_unregister_object_path() failed.");
|
||||
}
|
||||
|
||||
cdbus_introspection_destroy(opath_ptr);
|
||||
free(opath_ptr->ifaces);
|
||||
free(opath_ptr->name);
|
||||
free(opath_ptr);
|
||||
}
|
||||
|
||||
static DBusHandlerResult cdbus_object_path_handler(DBusConnection * connection, DBusMessage * message, void * data)
|
||||
{
|
||||
const char * iface_name;
|
||||
const struct cdbus_object_path_interface * iface_ptr;
|
||||
struct cdbus_method_call call;
|
||||
|
||||
/* Check if the message is a method call. If not, ignore it. */
|
||||
if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
|
||||
{
|
||||
goto handled;
|
||||
}
|
||||
|
||||
/* Get the invoked method's name and make sure it's non-NULL. */
|
||||
call.method_name = dbus_message_get_member(message);
|
||||
if (call.method_name == NULL)
|
||||
{
|
||||
cdbus_error(&call, DBUS_ERROR_UNKNOWN_METHOD, "Received method call with empty method name");
|
||||
goto send_return;
|
||||
}
|
||||
|
||||
/* Initialize our data. */
|
||||
call.connection = connection;
|
||||
call.message = message;
|
||||
call.iface = NULL; /* To be set by the default interface handler */
|
||||
call.reply = NULL;
|
||||
|
||||
/* Check if there's an interface specified for this method call. */
|
||||
iface_name = dbus_message_get_interface(message);
|
||||
if (iface_name != NULL)
|
||||
{
|
||||
for (iface_ptr = opath_ptr->ifaces; iface_ptr->iface != NULL; iface_ptr++)
|
||||
{
|
||||
if (strcmp(iface_name, iface_ptr->iface->name) == 0)
|
||||
{
|
||||
call.iface_context = iface_ptr->iface_context;
|
||||
if (!iface_ptr->iface->handler(iface_ptr->iface, &call))
|
||||
{
|
||||
/* unknown method */
|
||||
break;
|
||||
}
|
||||
|
||||
goto send_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No interface was specified so we have to try them all. D-Bus spec states:
|
||||
*
|
||||
* Optionally, the message has an INTERFACE field giving the interface the method is a part of.
|
||||
* In the absence of an INTERFACE field, if two interfaces on the same object have a method with
|
||||
* the same name, it is undefined which of the two methods will be invoked.
|
||||
* Implementations may also choose to return an error in this ambiguous case.
|
||||
* However, if a method name is unique implementations must not require an interface field.
|
||||
*/
|
||||
for (iface_ptr = opath_ptr->ifaces; iface_ptr->iface != NULL; iface_ptr++)
|
||||
{
|
||||
call.iface_context = iface_ptr->iface_context;
|
||||
if (!iface_ptr->iface->handler(iface_ptr->iface, &call))
|
||||
{
|
||||
/* known method */
|
||||
goto send_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cdbus_error(&call, DBUS_ERROR_UNKNOWN_METHOD, "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist", call.method_name, dbus_message_get_signature(message), iface_name);
|
||||
|
||||
send_return:
|
||||
cdbus_method_return_send(&call);
|
||||
|
||||
handled:
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
static void cdbus_object_path_handler_unregister(DBusConnection * UNUSED(connection_ptr), void * data)
|
||||
{
|
||||
log_debug("Message handler of object path %s was unregistered", (opath_ptr && opath_ptr->name) ? opath_ptr->name : "<unknown>");
|
||||
}
|
||||
|
||||
bool cdbus_object_path_register(DBusConnection * connection_ptr, cdbus_object_path data)
|
||||
{
|
||||
log_debug("Registering object path \"%s\"", opath_ptr->name);
|
||||
|
||||
ASSERT(!opath_ptr->registered);
|
||||
|
||||
DBusObjectPathVTable vtable =
|
||||
{
|
||||
cdbus_object_path_handler_unregister,
|
||||
cdbus_object_path_handler,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
if (!dbus_connection_register_object_path(connection_ptr, opath_ptr->name, &vtable, opath_ptr))
|
||||
{
|
||||
log_error("dbus_connection_register_object_path() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
opath_ptr->registered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef opath_ptr
|
@ -1,40 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2008,2009,2010,2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains interface to D-Bus object path helpers
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __CDBUS_OBJECT_PATH_H__
|
||||
#define __CDBUS_OBJECT_PATH_H__
|
||||
|
||||
typedef struct cdbus_object_path_tag { int unused; } * cdbus_object_path;
|
||||
|
||||
cdbus_object_path cdbus_object_path_new(const char * name, const struct cdbus_interface_descriptor * iface, ...);
|
||||
bool cdbus_object_path_register(DBusConnection * connection_ptr, cdbus_object_path opath);
|
||||
void cdbus_object_path_unregister(DBusConnection * connection_ptr, cdbus_object_path opath);
|
||||
void cdbus_object_path_destroy(DBusConnection * connection_ptr, cdbus_object_path opath);
|
||||
|
||||
#endif /* __CDBUS_OBJECT_PATH_H__ */
|
@ -1,111 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2009,2010,2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains D-Bus signal helpers
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "../common.h"
|
||||
#include <stdarg.h>
|
||||
#include "helpers.h"
|
||||
|
||||
void cdbus_signal_send(DBusConnection * connection_ptr, DBusMessage * message_ptr)
|
||||
{
|
||||
if (!dbus_connection_send(connection_ptr, message_ptr, NULL))
|
||||
{
|
||||
log_error("Ran out of memory trying to queue signal");
|
||||
}
|
||||
|
||||
dbus_connection_flush(connection_ptr);
|
||||
}
|
||||
|
||||
void
|
||||
cdbus_signal_emit(
|
||||
DBusConnection * connection_ptr,
|
||||
const char * path,
|
||||
const char * interface,
|
||||
const char * name,
|
||||
const char * signature,
|
||||
...)
|
||||
{
|
||||
DBusMessage * message_ptr;
|
||||
va_list ap;
|
||||
int type;
|
||||
DBusSignatureIter sig_iter;
|
||||
DBusMessageIter iter;
|
||||
void * parameter_ptr;
|
||||
|
||||
log_debug("Sending signal %s.%s from %s", interface, name, path);
|
||||
|
||||
va_start(ap, signature);
|
||||
|
||||
ASSERT(signature != NULL);
|
||||
|
||||
if (!dbus_signature_validate(signature, NULL))
|
||||
{
|
||||
log_error("signature '%s' is invalid", signature);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dbus_signature_iter_init(&sig_iter, signature);
|
||||
|
||||
message_ptr = dbus_message_new_signal(path, interface, name);
|
||||
if (message_ptr == NULL)
|
||||
{
|
||||
log_error("dbus_message_new_signal() failed.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dbus_message_iter_init_append(message_ptr, &iter);
|
||||
|
||||
while (*signature != '\0')
|
||||
{
|
||||
type = dbus_signature_iter_get_current_type(&sig_iter);
|
||||
if (!dbus_type_is_basic(type))
|
||||
{
|
||||
log_error("non-basic input parameter '%c' (%d)", *signature, type);
|
||||
goto unref;
|
||||
}
|
||||
|
||||
parameter_ptr = va_arg(ap, void *);
|
||||
|
||||
if (!dbus_message_iter_append_basic(&iter, type, parameter_ptr))
|
||||
{
|
||||
log_error("dbus_message_iter_append_basic() failed.");
|
||||
goto unref;
|
||||
}
|
||||
|
||||
dbus_signature_iter_next(&sig_iter);
|
||||
signature++;
|
||||
}
|
||||
|
||||
cdbus_signal_send(connection_ptr, message_ptr);
|
||||
|
||||
unref:
|
||||
dbus_message_unref(message_ptr);
|
||||
|
||||
exit:
|
||||
va_end(ap);
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/* -*- Mode: C ; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2008,2009,2010,2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains interface to D-Bus signal helpers
|
||||
**************************************************************************
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* LADI Session Handler is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LADI Session Handler is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
|
||||
* or write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __CDBUS_SIGNAL_H__
|
||||
#define __CDBUS_SIGNAL_H__
|
||||
|
||||
struct cdbus_signal_arg_descriptor
|
||||
{
|
||||
const char * name;
|
||||
const char * type;
|
||||
};
|
||||
|
||||
struct cdbus_signal_descriptor
|
||||
{
|
||||
const char * name;
|
||||
const struct cdbus_signal_arg_descriptor * args;
|
||||
};
|
||||
|
||||
void cdbus_signal_send(DBusConnection * connection_ptr, DBusMessage * message_ptr);
|
||||
|
||||
void
|
||||
cdbus_signal_emit(
|
||||
DBusConnection * connection_ptr,
|
||||
const char * path,
|
||||
const char * interface,
|
||||
const char * name,
|
||||
const char * signature,
|
||||
...);
|
||||
|
||||
#define CDBUS_SIGNAL_ARGS_BEGIN(signal_name, descr) \
|
||||
static const struct cdbus_signal_arg_descriptor signal_name ## _args_dtor[] = \
|
||||
{
|
||||
|
||||
#define CDBUS_SIGNAL_ARG_DESCRIBE(arg_name, arg_type, descr) \
|
||||
{ \
|
||||
.name = arg_name, \
|
||||
.type = arg_type \
|
||||
},
|
||||
|
||||
#define CDBUS_SIGNAL_ARGS_END \
|
||||
{ \
|
||||
.name = NULL, \
|
||||
.type = NULL \
|
||||
} \
|
||||
};
|
||||
|
||||
#define CDBUS_SIGNALS_BEGIN \
|
||||
static const struct cdbus_signal_descriptor signals_dtor[] = \
|
||||
{
|
||||
|
||||
#define CDBUS_SIGNAL_DESCRIBE(signal_name) \
|
||||
{ \
|
||||
.name = # signal_name, \
|
||||
.args = signal_name ## _args_dtor \
|
||||
},
|
||||
|
||||
#define CDBUS_SIGNALS_END \
|
||||
{ \
|
||||
.name = NULL, \
|
||||
.args = NULL \
|
||||
} \
|
||||
};
|
||||
|
||||
#endif /* __CDBUS_SIGNAL_H__ */
|