Initial version jpld D-Bus service

The interface functions are not imlemented yet.
This commit is contained in:
Nedko Arnaudov 2023-12-26 12:02:03 +02:00
parent 3aca0d71f1
commit 384eb0e9b3
3 changed files with 268 additions and 1 deletions

3
dbus.service.in Normal file
View File

@ -0,0 +1,3 @@
[D-BUS Service]
Name=@dbus_object_path@
Exec=@daemon_bin_path@

222
jpld.c Normal file
View File

@ -0,0 +1,222 @@
/* -*- Mode: C ; c-basic-offset: 2 -*- */
/*
* SPDX-FileCopyrightText: Copyright © 2023 Nedko Arnaudov
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <cdbus/cdbus.h>
#include <cdbus/log.h>
#if HAVE_GITVERSION_H
#include "gitversion.h"
#endif
#include "loader.h"
bool g_quit;
const char * g_dbus_unique_name;
cdbus_object_path g_dbus_object;
extern const struct cdbus_interface_descriptor jpl_appman_cdbus_interface_org_ladish_ApplicationManager0;
#define SERVICE_NAME DBUS_NAME_BASE
#define DBUS_OBJECT_PATH DBUS_BASE_PATH
void
jpld_log(
void * ctx,
bool error,
const char * format,
...)
{
va_list ap;
FILE * stream;
//printf("jpl_log()\n");
stream = error ? stderr : stdout;
va_start(ap, format);
vfprintf(stream, format, ap);
va_end(ap);
fflush(stream);
}
void
jpl_cdbus_log(
unsigned int level,
const char * file,
unsigned int line,
const char * func,
const char * format,
...)
{
va_list ap;
FILE * stream;
//printf("jpl_cdbus_log()\n");
stream = stdout;
va_start(ap, format);
vfprintf(stream, format, ap);
va_end(ap);
fputc('\n', stream);
fflush(stream);
}
#define log_error(fmt, args...) jpld_log(NULL, true, fmt "\n", ## args)
#define log_info( fmt, args...) jpld_log(NULL, false, fmt "\n", ## args)
#define log_debug(fmt, args...) jpld_log(NULL, false, fmt "\n", ## args)
static bool connect_dbus(void)
{
int ret;
dbus_error_init(&cdbus_g_dbus_error);
cdbus_g_dbus_connection = dbus_bus_get(DBUS_BUS_SESSION, &cdbus_g_dbus_error);
if (dbus_error_is_set(&cdbus_g_dbus_error))
{
log_error("Failed to get bus: %s", cdbus_g_dbus_error.message);
dbus_error_free(&cdbus_g_dbus_error);
goto fail;
}
g_dbus_unique_name = dbus_bus_get_unique_name(cdbus_g_dbus_connection);
if (g_dbus_unique_name == NULL)
{
log_error("Failed to read unique bus name");
goto unref_connection;
}
log_info("Connected to local session bus, unique name is \"%s\"", g_dbus_unique_name);
ret = dbus_bus_request_name(cdbus_g_dbus_connection, SERVICE_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE, &cdbus_g_dbus_error);
if (ret == -1)
{
log_error("Failed to acquire bus name: %s", cdbus_g_dbus_error.message);
dbus_error_free(&cdbus_g_dbus_error);
goto unref_connection;
}
if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
{
log_error("Requested connection name already exists");
goto unref_connection;
}
g_dbus_object = cdbus_object_path_new(
DBUS_OBJECT_PATH,
&jpl_appman_cdbus_interface_org_ladish_ApplicationManager0,
NULL,
NULL);
if (g_dbus_object == NULL)
{
goto unref_connection;
}
if (!cdbus_object_path_register(cdbus_g_dbus_connection, g_dbus_object))
{
goto destroy_dbus_object;
}
return true;
destroy_dbus_object:
cdbus_object_path_destroy(cdbus_g_dbus_connection, g_dbus_object);
unref_connection:
dbus_connection_unref(cdbus_g_dbus_connection);
fail:
return false;
}
static void disconnect_dbus(void)
{
cdbus_object_path_destroy(cdbus_g_dbus_connection, g_dbus_object);
dbus_connection_unref(cdbus_g_dbus_connection);
cdbus_call_last_error_cleanup();
}
void term_signal_handler(int signum)
{
log_info("Caught signal %d (%s), terminating", signum, strsignal(signum));
g_quit = true;
}
bool install_term_signal_handler(int signum, bool ignore_if_already_ignored)
{
sig_t sigh;
sigh = signal(signum, term_signal_handler);
if (sigh == SIG_ERR)
{
log_error("signal() failed to install handler function for signal %d.", signum);
return false;
}
if (sigh == SIG_IGN && ignore_if_already_ignored)
{
signal(SIGTERM, SIG_IGN);
}
return true;
}
int main(void)
{
int ret;
ret = EXIT_FAILURE;
cdbus_log_setup(jpl_cdbus_log);
log_info("JACK Plugin Launcher daemon, version " JPL_VERSION);
log_info("Copyleft JACK Plugin Authors");
#if defined(GIT_VERSION)
log_info("built from " GIT_VERSION);
#endif
log_info("built on " BUILD_TIMESTAMP);
/* install the signal handlers */
install_term_signal_handler(SIGTERM, false);
install_term_signal_handler(SIGINT, true);
install_term_signal_handler(SIGHUP, true);
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
{
log_error("signal(SIGPIPE, SIG_IGN).");
}
if (!connect_dbus())
{
log_error("Failed to connect to D-Bus");
goto exit;
}
while (!g_quit)
{
dbus_connection_read_write_dispatch(cdbus_g_dbus_connection, 50);
//jpl_run();
}
ret = EXIT_SUCCESS;
log_debug("Finished, cleaning up");
disconnect_dbus();
exit:
return ret;
}

44
wscript
View File

@ -18,6 +18,7 @@ from waftoolchainflags import WafToolchainFlags
APPNAME='jpl'
VERSION='0-dev'
DBUS_NAME_BASE = 'org.ladish.jpl'
# these variables are mandatory ('/' are converted automatically)
srcdir = '.'
@ -90,7 +91,16 @@ def configure(conf):
conf.check_cfg(package='libevent', mandatory=True, args='--cflags --libs')
conf.check_cfg(package='liblo', mandatory=True, args='--cflags --libs')
conf.check_cfg(package='dbus-1', mandatory=False, args='--cflags --libs')
dbus_dir = conf.check_cfg(package='dbus-1', args='--variable=session_bus_services_dir', msg="Retrieving D-Bus services dir")
if not dbus_dir:
dbus_dir = os.path.join(os.path.normpath(conf.env['PREFIX']), 'share', 'dbus-1', 'services')
dbus_dir = dbus_dir.strip()
conf.env['DBUS_SERVICES_DIR'] = dbus_dir
conf.check_cfg(package='cdbus-1', mandatory=False, args='--cflags --libs')
if Options.options.mandir:
@ -98,8 +108,13 @@ def configure(conf):
else:
conf.env['MANDIR'] = conf.env['PREFIX'] + '/share/man'
conf.env['LIBEXEC_DIR'] = conf.env['PREFIX'] + '/libexec/'
conf.define('JPL_VERSION', VERSION)
conf.define('HAVE_GITVERSION_H', 1)
conf.define('DBUS_NAME_BASE', DBUS_NAME_BASE)
conf.define('DBUS_BASE_PATH', '/' + DBUS_NAME_BASE.replace('.', '/'))
conf.define('BASE_NAME', APPNAME)
conf.define('BUILD_TIMESTAMP', time.ctime())
conf.write_config_header('config.h')
@ -151,11 +166,25 @@ def configure(conf):
print()
display_msg(conf, "Install prefix", conf.env['PREFIX'], 'CYAN')
display_msg(conf, "bin dir", conf.env['BINDIR'], 'CYAN')
display_msg(conf, "libexec dir", conf.env['LIBEXEC_DIR'], 'CYAN')
display_msg(conf, "man dir", conf.env['MANDIR'], 'CYAN')
display_msg(conf, "D-Bus services dir", conf.env['DBUS_SERVICES_DIR'], 'CYAN')
display_msg(conf, "Compiler", conf.env['CC'][0], 'CYAN')
conf.summarize_auto_options()
flags.print()
print()
def create_service_taskgen(bld, target, opath, binary):
bld(
features = 'subst', # the feature 'subst' overrides the source/target processing
source = ['dbus.service.in'], # list of string or nodes
target = target, # list of strings or nodes
install_path = bld.env['DBUS_SERVICES_DIR'] + os.path.sep,
# variables to use in the substitution
dbus_object_path = opath,
daemon_bin_path = binary)
def build(bld):
bld(rule=git_ver,
target='gitversion.h',
@ -175,13 +204,26 @@ def build(bld):
prog = bld(features=['c', 'cprogram'])
prog.source = [
'main.c',
'appman.c',
]
prog.includes = '.' # config.h, gitverson.h include path
prog.target = 'jpl'
prog.use = ['LIBEVENT', 'LIBLO', 'DBUS-1', 'CDBUS-1']
prog.defines = ["HAVE_CONFIG_H"]
daemon = bld(features=['c', 'cprogram'])
daemon.source = [
'jpld.c',
'appman.c',
]
daemon.includes = '.' # config.h, gitverson.h include path
daemon.target = 'jpld'
daemon.use = ['LIBEVENT', 'LIBLO', 'DBUS-1', 'CDBUS-1']
daemon.defines = ["HAVE_CONFIG_H"]
daemon.install_path = bld.env['LIBEXEC_DIR']
# process dbus.service.in -> jpld.service
create_service_taskgen(bld, DBUS_NAME_BASE + '.service', DBUS_NAME_BASE, os.path.join(daemon.install_path, daemon.target))
# install man pages
man_pages = [
#TODO: "jpl.1",