switch to cdbus code from libcdbus.so

This commit is contained in:
Nedko Arnaudov 2023-05-01 07:46:34 +03:00
parent 3898a88d10
commit da2edb9c0e
19 changed files with 20 additions and 2529 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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)

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

View File

@ -175,6 +175,7 @@ ladish_log_enabled(
return level != LADISH_LOG_LEVEL_DEBUG;
}
__attribute__((visibility("default")))
void
ladish_log(
unsigned int level,

2
conf.c
View File

@ -33,7 +33,7 @@
#include <fcntl.h>
#include <errno.h>
#include "cdbus/helpers.h"
#include <cdbus/cdbus.h>
#include "dbus_constants.h"
#include "common/catdup.h"
#include "common/dirhelpers.h"

View File

@ -32,7 +32,7 @@
#include <errno.h>
#include <uuid/uuid.h>
#include "../cdbus/helpers.h"
#include <cdbus/cdbus.h>
/* ~/BASE_DIR is where studio, room and project xml files are stored */
#define BASE_DIR "/." BASE_NAME

View File

@ -25,7 +25,7 @@
*/
#include "internal.h"
#include "../cdbus/helpers.h"
#include <cdbus/cdbus.h>
#include <dbus/dbus-glib-lowlevel.h>
bool dbus_init(void)

View File

@ -31,7 +31,7 @@
#include <jack/jack.h>
#include <jack/midiport.h>
#include "cdbus/helpers.h"
#include <cdbus/cdbus.h>
#include "dbus_constants.h"
extern const struct cdbus_interface_descriptor g_interface;

2
log.h
View File

@ -49,6 +49,8 @@
# endif
#endif
#define ladish_log cdbus_log
#ifdef __cplusplus
extern "C"
#endif

View File

@ -28,7 +28,7 @@
#define COMMON_H__0710E3D5_9B69_4C10_BDDB_80E0D92F44AF__INCLUDED
#include "../common.h"
#include "../cdbus/helpers.h"
#include <cdbus/cdbus.h>
#include "../dbus_constants.h"
#endif /* #ifndef COMMON_H__0710E3D5_9B69_4C10_BDDB_80E0D92F44AF__INCLUDED */

59
wscript
View File

@ -138,6 +138,13 @@ def configure(conf):
else:
conf.env['DBUS_SERVICES_DIR'] = os.path.join(os.path.normpath(conf.env['PREFIX']), 'share', 'dbus-1', 'services')
conf.check_cfg(
package = 'cdbus-1',
atleast_version = '1.0.0',
mandatory = True,
errmsg = "not installed, see https://github.com/LADI/cdbus.git",
args = '--cflags --libs')
if Options.options.libdir:
conf.env['LIBDIR'] = Options.options.libdir
else:
@ -362,7 +369,7 @@ def build(bld):
daemon = bld.program(source = [], features = 'c cprogram', includes = [bld.path.get_bld()])
daemon.target = 'ladishd'
daemon.uselib = 'DBUS-1 UUID EXPAT DL UTIL'
daemon.uselib = 'DBUS-1 CDBUS-1 UUID EXPAT DL UTIL'
daemon.ver_header = 'version.h'
# Make backtrace function lookup to work for functions in the executable itself
daemon.env.append_value("LINKFLAGS", ["-Wl,-E"])
@ -433,15 +440,6 @@ def build(bld):
]:
daemon.source.append(os.path.join("proxies", source))
for source in [
'signal.c',
'method.c',
'object_path.c',
'interface.c',
'helpers.c',
]:
daemon.source.append(os.path.join("cdbus", source))
for source in [
'log.c',
'time.c',
@ -459,7 +457,7 @@ def build(bld):
# jmcore
jmcore = bld.program(source = [], features = 'c cprogram', includes = [bld.path.get_bld()])
jmcore.target = 'jmcore'
jmcore.uselib = 'DBUS-1 JACK'
jmcore.uselib = 'DBUS-1 CDBUS-1 JACK'
jmcore.defines = ['LOG_OUTPUT_STDOUT']
jmcore.source = ['jmcore.c']
@ -468,22 +466,13 @@ def build(bld):
]:
jmcore.source.append(os.path.join("common", source))
for source in [
#'signal.c',
'method.c',
'object_path.c',
'interface.c',
'helpers.c',
]:
jmcore.source.append(os.path.join("cdbus", source))
create_service_taskgen(bld, DBUS_NAME_BASE + '.jmcore.service', DBUS_NAME_BASE + ".jmcore", jmcore.target)
#####################################################
# conf
ladiconfd = bld.program(source = [], features = 'c cprogram', includes = [bld.path.get_bld()])
ladiconfd.target = 'ladiconfd'
ladiconfd.uselib = 'DBUS-1'
ladiconfd.uselib = 'DBUS-1 CDBUS-1'
ladiconfd.defines = ['LOG_OUTPUT_STDOUT']
ladiconfd.source = ['conf.c']
@ -494,15 +483,6 @@ def build(bld):
]:
ladiconfd.source.append(os.path.join("common", source))
for source in [
'signal.c',
'method.c',
'object_path.c',
'interface.c',
'helpers.c',
]:
ladiconfd.source.append(os.path.join("cdbus", source))
create_service_taskgen(bld, DBUS_NAME_BASE + '.conf.service', DBUS_NAME_BASE + ".conf", ladiconfd.target)
#####################################################
@ -520,7 +500,7 @@ def build(bld):
# liblash
if bld.env['BUILD_LIBLASH']:
liblash = bld.shlib(source = [], features = 'c cshlib', includes = [bld.path.get_bld()])
liblash.uselib = 'DBUS-1'
liblash.uselib = 'DBUS-1 CDBUS-1'
liblash.target = 'lash'
liblash.vnum = "1.1.1"
liblash.defines = ['LOG_OUTPUT_STDOUT']
@ -534,14 +514,6 @@ def build(bld):
]:
liblash.source.append(os.path.join("common", source))
for source in [
'method.c',
'object_path.c',
'interface.c',
'helpers.c',
]:
liblash.source.append(os.path.join("cdbus", source))
bld.install_files('${PREFIX}/include/lash-1.0/lash', bld.path.ant_glob('lash_compat/liblash/lash/*.h'))
# process lash-1.0.pc.in -> lash-1.0.pc
@ -578,7 +550,7 @@ def build(bld):
gladish = bld.program(source = [], features = 'c cxx cxxprogram', includes = [bld.path.get_bld()])
gladish.target = 'gladish'
gladish.defines = ['LOG_OUTPUT_STDOUT']
gladish.uselib = 'DBUS-1 DBUS-GLIB-1 GTKMM-2.4 LIBGNOMECANVASMM-2.6 GTK+-2.0'
gladish.uselib = 'DBUS-1 CDBUS-1 DBUS-GLIB-1 GTKMM-2.4 LIBGNOMECANVASMM-2.6 GTK+-2.0'
gladish.source = ["string_constants.c"]
@ -636,12 +608,6 @@ def build(bld):
]:
gladish.source.append(os.path.join("proxies", source))
for source in [
'method.c',
'helpers.c',
]:
gladish.source.append(os.path.join("cdbus", source))
for source in [
'log.c',
'catdup.c',
@ -693,7 +659,6 @@ def get_tags_dirs():
source_root = os.path.relpath(source_root)
paths = source_root
paths += " " + os.path.join(source_root, "common")
paths += " " + os.path.join(source_root, "cdbus")
paths += " " + os.path.join(source_root, "proxies")
paths += " " + os.path.join(source_root, "daemon")
paths += " " + os.path.join(source_root, "gui")