1 /* -*- Mode: C ; c-basic-offset: 4 -*- */
3 Copyright (C) 2007-2024 Nedko Arnaudov
4 Copyright (C) 2007-2008 Juuso Alasuutari
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #if defined(HAVE_CONFIG_H)
27 #include <dbus/dbus.h>
30 #include <sys/sysinfo.h>
33 #include "controller.h"
34 #include "controller_internal.h"
36 #include "device_reservation.h"
38 struct jack_dbus_interface_descriptor
* g_jackcontroller_interfaces
[] =
40 &g_jack_controller_iface_introspectable
,
41 &g_jack_controller_iface_control
,
42 &g_jack_controller_iface_configure
,
43 &g_jack_controller_iface_patchbay
,
44 &g_jack_controller_iface_session_manager
,
45 &g_jack_controller_iface_transport
,
51 jack_controller_find_driver(
52 jackctl_server_t
*server
,
53 const char *driver_name
)
55 const JSList
* node_ptr
;
57 node_ptr
= jackctl_server_get_drivers_list(server
);
61 if (strcmp(jackctl_driver_get_name((jackctl_driver_t
*)node_ptr
->data
), driver_name
) == 0)
63 return node_ptr
->data
;
66 node_ptr
= jack_slist_next(node_ptr
);
72 static bool jack_controller_check_slave_driver(struct jack_controller
* controller_ptr
, const char * name
)
74 struct list_head
* node_ptr
;
75 struct jack_controller_slave_driver
* driver_ptr
;
77 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
79 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
80 if (strcmp(name
, driver_ptr
->name
) == 0)
89 static bool jack_controller_load_slave_drivers(struct jack_controller
* controller_ptr
)
91 struct list_head
* node_ptr
;
92 struct jack_controller_slave_driver
* driver_ptr
;
94 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
96 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
98 assert(driver_ptr
->handle
!= NULL
);
99 assert(!driver_ptr
->loaded
);
101 if (!jackctl_server_add_slave(controller_ptr
->server
, driver_ptr
->handle
))
103 jack_error("Driver \"%s\" cannot be loaded", driver_ptr
->name
);
107 driver_ptr
->loaded
= true;
113 static void jack_controller_unload_slave_drivers(struct jack_controller
* controller_ptr
)
115 struct list_head
* node_ptr
;
116 struct jack_controller_slave_driver
* driver_ptr
;
118 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
120 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
121 if (driver_ptr
->loaded
)
123 jackctl_server_remove_slave(controller_ptr
->server
, driver_ptr
->handle
);
124 driver_ptr
->loaded
= false;
129 static void jack_controller_remove_slave_drivers(struct jack_controller
* controller_ptr
)
131 struct jack_controller_slave_driver
* driver_ptr
;
133 while (!list_empty(&controller_ptr
->slave_drivers
))
135 driver_ptr
= list_entry(controller_ptr
->slave_drivers
.next
, struct jack_controller_slave_driver
, siblings
);
136 assert(!driver_ptr
->loaded
);
137 list_del(&driver_ptr
->siblings
);
138 free(driver_ptr
->name
);
142 controller_ptr
->slave_drivers_vparam_value
.str
[0] = 0;
147 jack_controller_find_internal(
148 jackctl_server_t
*server
,
149 const char *internal_name
)
151 const JSList
* node_ptr
;
153 node_ptr
= jackctl_server_get_internals_list(server
);
157 if (strcmp(jackctl_internal_get_name((jackctl_internal_t
*)node_ptr
->data
), internal_name
) == 0)
159 return node_ptr
->data
;
162 node_ptr
= jack_slist_next(node_ptr
);
169 jack_controller_select_driver(
170 struct jack_controller
* controller_ptr
,
171 const char * driver_name
)
173 if (!jack_params_set_driver(controller_ptr
->params
, driver_name
))
178 jack_info("driver \"%s\" selected", driver_name
);
185 jack_controller_xrun(void * arg
)
187 ((struct jack_controller
*)arg
)->xruns
++;
193 jack_controller_start_server(
194 struct jack_controller
* controller_ptr
,
195 void *dbus_call_context_ptr
)
199 jack_info("Starting jack server...");
201 assert(!controller_ptr
->started
); /* should be ensured by caller */
203 controller_ptr
->xruns
= 0;
205 if (!jackctl_server_open(
206 controller_ptr
->server
,
207 jack_params_get_driver(controller_ptr
->params
)))
209 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to open server");
213 jack_controller_load_slave_drivers(controller_ptr
);
215 if (!jackctl_server_start(
216 controller_ptr
->server
))
218 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to start server");
219 goto fail_close_server
;
222 controller_ptr
->client
= jack_client_open(
226 if (controller_ptr
->client
== NULL
)
228 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to create dbusapi jack client");
229 goto fail_stop_server
;
232 ret
= jack_set_xrun_callback(controller_ptr
->client
, jack_controller_xrun
, controller_ptr
);
235 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to set xrun callback. error is %d", ret
);
236 goto fail_close_client
;
239 if (!jack_controller_patchbay_init(controller_ptr
))
241 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to initialize patchbay district");
242 goto fail_close_client
;
245 ret
= jack_activate(controller_ptr
->client
);
248 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "failed to activate dbusapi jack client. error is %d", ret
);
249 goto fail_patchbay_uninit
;
252 controller_ptr
->started
= true;
256 fail_patchbay_uninit
:
257 jack_controller_patchbay_uninit(controller_ptr
);
260 ret
= jack_client_close(controller_ptr
->client
);
263 jack_error("jack_client_close() failed with error %d", ret
);
266 controller_ptr
->client
= NULL
;
269 if (!jackctl_server_stop(controller_ptr
->server
))
271 jack_error("failed to stop jack server");
275 jack_controller_unload_slave_drivers(controller_ptr
);
277 if (!jackctl_server_close(controller_ptr
->server
))
279 jack_error("failed to close jack server");
287 jack_controller_stop_server(
288 struct jack_controller
* controller_ptr
,
289 void *dbus_call_context_ptr
)
293 pthread_mutex_lock(&controller_ptr
->lock
);
294 if (!list_empty(&controller_ptr
->session_pending_commands
))
296 pthread_mutex_unlock(&controller_ptr
->lock
);
297 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Refusing to stop JACK server because of pending session commands");
300 pthread_mutex_unlock(&controller_ptr
->lock
);
302 jack_info("Stopping jack server...");
304 assert(controller_ptr
->started
); /* should be ensured by caller */
306 ret
= jack_deactivate(controller_ptr
->client
);
309 jack_error("failed to deactivate dbusapi jack client. error is %d", ret
);
312 jack_controller_patchbay_uninit(controller_ptr
);
314 ret
= jack_client_close(controller_ptr
->client
);
317 jack_error("jack_client_close() failed with error %d", ret
);
320 controller_ptr
->client
= NULL
;
322 if (!jackctl_server_stop(controller_ptr
->server
))
324 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to stop server");
328 jack_controller_unload_slave_drivers(controller_ptr
);
330 if (!jackctl_server_close(controller_ptr
->server
))
332 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to close server");
336 controller_ptr
->started
= false;
342 jack_controller_switch_master(
343 struct jack_controller
* controller_ptr
,
344 void *dbus_call_context_ptr
)
346 assert(controller_ptr
->started
); /* should be ensured by caller */
348 if (!jackctl_server_switch_master(
349 controller_ptr
->server
,
350 jack_params_get_driver(controller_ptr
->params
)))
352 jack_dbus_error(dbus_call_context_ptr
, JACK_DBUS_ERROR_GENERIC
, "Failed to switch master");
353 controller_ptr
->started
= false;
360 #define controller_ptr ((struct jack_controller *)obj)
362 static bool slave_drivers_parameter_is_set(void * obj
)
364 return controller_ptr
->slave_drivers_set
;
367 static bool slave_drivers_parameter_reset(void * obj
)
369 if (controller_ptr
->started
)
371 jack_error("Cannot modify slave-drivers when server is started");
375 jack_controller_remove_slave_drivers(controller_ptr
);
376 controller_ptr
->slave_drivers_set
= false;
380 static union jackctl_parameter_value
slave_drivers_parameter_get_value(void * obj
)
382 return controller_ptr
->slave_drivers_vparam_value
;
385 static bool slave_drivers_parameter_set_value(void * obj
, const union jackctl_parameter_value
* value_ptr
)
390 struct list_head old_list
;
391 struct list_head new_list
;
392 union jackctl_parameter_value old_value
;
393 union jackctl_parameter_value new_value
;
396 if (controller_ptr
->started
)
398 jack_error("Cannot modify slave-drivers when server is started");
402 old_set
= controller_ptr
->slave_drivers_set
;
403 old_value
= controller_ptr
->slave_drivers_vparam_value
;
404 controller_ptr
->slave_drivers_vparam_value
.str
[0] = 0;
405 old_list
= controller_ptr
->slave_drivers
;
406 INIT_LIST_HEAD(&controller_ptr
->slave_drivers
);
408 buffer
= strdup(value_ptr
->str
);
411 jack_error("strdup() failed.");
415 token
= strtok_r(buffer
, ",", &save
);
418 //jack_info("slave driver '%s'", token);
419 if (!jack_controller_add_slave_driver(controller_ptr
, token
))
421 jack_controller_remove_slave_drivers(controller_ptr
);
422 controller_ptr
->slave_drivers
= old_list
;
423 controller_ptr
->slave_drivers_vparam_value
= old_value
;
424 controller_ptr
->slave_drivers_set
= old_set
;
431 token
= strtok_r(NULL
, ",", &save
);
434 new_value
= controller_ptr
->slave_drivers_vparam_value
;
435 new_list
= controller_ptr
->slave_drivers
;
436 controller_ptr
->slave_drivers
= old_list
;
437 jack_controller_remove_slave_drivers(controller_ptr
);
438 controller_ptr
->slave_drivers_vparam_value
= new_value
;
439 controller_ptr
->slave_drivers
= new_list
;
440 controller_ptr
->slave_drivers_set
= true;
447 static union jackctl_parameter_value
slave_drivers_parameter_get_default_value(void * obj
)
449 union jackctl_parameter_value value
;
454 #undef controller_ptr
457 jack_controller_create(
458 DBusConnection
*connection
)
461 struct jack_controller
*controller_ptr
;
462 const char * address
[PARAM_ADDRESS_SIZE
];
463 DBusObjectPathVTable vtable
=
465 jack_dbus_message_handler_unregister
,
466 jack_dbus_message_handler
,
470 controller_ptr
= malloc(sizeof(struct jack_controller
));
473 jack_error("Ran out of memory trying to allocate struct jack_controller");
477 error
= pthread_mutex_init(&controller_ptr
->lock
, NULL
);
480 jack_error("Failed to initialize mutex. error %d", error
);
484 INIT_LIST_HEAD(&controller_ptr
->session_pending_commands
);
486 controller_ptr
->server
= jackctl_server_create(
487 device_reservation_acquire
,
488 device_reservation_release
);
489 if (controller_ptr
->server
== NULL
)
491 jack_error("Failed to create server object");
492 goto fail_uninit_mutex
;
495 controller_ptr
->params
= jack_params_create(controller_ptr
->server
);
496 if (controller_ptr
->params
== NULL
)
498 jack_error("Failed to initialize parameter tree");
499 goto fail_destroy_server
;
502 controller_ptr
->client
= NULL
;
503 controller_ptr
->started
= false;
505 controller_ptr
->pending_save
= 0;
507 INIT_LIST_HEAD(&controller_ptr
->slave_drivers
);
508 controller_ptr
->slave_drivers_set
= false;
509 controller_ptr
->slave_drivers_vparam_value
.str
[0] = 0;
511 controller_ptr
->slave_drivers_vparam
.obj
= controller_ptr
;
513 controller_ptr
->slave_drivers_vparam
.vtable
.is_set
= slave_drivers_parameter_is_set
;
514 controller_ptr
->slave_drivers_vparam
.vtable
.reset
= slave_drivers_parameter_reset
;
515 controller_ptr
->slave_drivers_vparam
.vtable
.get_value
= slave_drivers_parameter_get_value
;
516 controller_ptr
->slave_drivers_vparam
.vtable
.set_value
= slave_drivers_parameter_set_value
;
517 controller_ptr
->slave_drivers_vparam
.vtable
.get_default_value
= slave_drivers_parameter_get_default_value
;
519 controller_ptr
->slave_drivers_vparam
.type
= JackParamString
;
520 controller_ptr
->slave_drivers_vparam
.name
= "slave-drivers";
521 controller_ptr
->slave_drivers_vparam
.short_decr
= "Slave drivers to use";
522 controller_ptr
->slave_drivers_vparam
.long_descr
= "A comma separated list of slave drivers";
523 controller_ptr
->slave_drivers_vparam
.constraint_flags
= 0;
525 address
[0] = PTNODE_ENGINE
;
527 jack_params_add_parameter(controller_ptr
->params
, address
, true, &controller_ptr
->slave_drivers_vparam
);
529 controller_ptr
->dbus_descriptor
.context
= controller_ptr
;
530 controller_ptr
->dbus_descriptor
.interfaces
= g_jackcontroller_interfaces
;
532 if (!dbus_connection_register_object_path(
534 JACK_CONTROLLER_OBJECT_PATH
,
536 &controller_ptr
->dbus_descriptor
))
538 jack_error("Ran out of memory trying to register D-Bus object path");
539 goto fail_destroy_params
;
542 jack_controller_settings_load(controller_ptr
);
544 return controller_ptr
;
547 jack_params_destroy(controller_ptr
->params
);
550 jackctl_server_destroy(controller_ptr
->server
);
553 pthread_mutex_destroy(&controller_ptr
->lock
);
556 free(controller_ptr
);
563 jack_controller_add_slave_driver(
564 struct jack_controller
* controller_ptr
,
565 const char * driver_name
)
567 jackctl_driver_t
* driver
;
568 struct jack_controller_slave_driver
* driver_ptr
;
572 len_old
= strlen(controller_ptr
->slave_drivers_vparam_value
.str
);
573 len_new
= strlen(driver_name
);
574 if (len_old
+ len_new
+ 2 > sizeof(controller_ptr
->slave_drivers_vparam_value
.str
))
576 jack_error("No more space for slave drivers.");
580 driver
= jack_controller_find_driver(controller_ptr
->server
, driver_name
);
583 jack_error("Unknown driver \"%s\"", driver_name
);
587 if (jack_controller_check_slave_driver(controller_ptr
, driver_name
))
589 jack_info("Driver \"%s\" is already slave", driver_name
);
593 driver_ptr
= malloc(sizeof(struct jack_controller_slave_driver
));
594 if (driver_ptr
== NULL
)
596 jack_error("malloc() failed to allocate jack_controller_slave_driver struct");
600 driver_ptr
->name
= strdup(driver_name
);
601 if (driver_ptr
->name
== NULL
)
603 jack_error("strdup() failed for slave driver name \"%s\"", driver_name
);
608 driver_ptr
->handle
= driver
;
609 driver_ptr
->loaded
= false;
611 jack_info("driver \"%s\" set as slave", driver_name
);
613 list_add_tail(&driver_ptr
->siblings
, &controller_ptr
->slave_drivers
);
617 controller_ptr
->slave_drivers_vparam_value
.str
[len_old
++] = ',';
620 memcpy(controller_ptr
->slave_drivers_vparam_value
.str
+ len_old
, driver_name
, len_new
+ 1);
621 controller_ptr
->slave_drivers_set
= true;
627 jack_controller_remove_slave_driver(
628 struct jack_controller
* controller_ptr
,
629 const char * driver_name
)
631 struct list_head
* node_ptr
;
632 struct jack_controller_slave_driver
* driver_ptr
;
634 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
636 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
637 if (strcmp(driver_ptr
->name
, driver_name
) == 0)
639 list_del(&driver_ptr
->siblings
);
640 free(driver_ptr
->name
);
643 /* update the slave-drivers param value */
644 controller_ptr
->slave_drivers_vparam_value
.str
[0] = 0;
645 list_for_each(node_ptr
, &controller_ptr
->slave_drivers
)
647 driver_ptr
= list_entry(node_ptr
, struct jack_controller_slave_driver
, siblings
);
648 if (controller_ptr
->slave_drivers_vparam_value
.str
[0] != 0)
650 strcat(controller_ptr
->slave_drivers_vparam_value
.str
, ",");
653 strcat(controller_ptr
->slave_drivers_vparam_value
.str
, driver_ptr
->name
);
656 jack_info("driver \"%s\" is not slave anymore", driver_name
);
666 jack_controller_load_internal(
667 struct jack_controller
*controller_ptr
,
668 const char * internal_name
)
670 jackctl_internal_t
*internal
;
672 internal
= jack_controller_find_internal(controller_ptr
->server
, internal_name
);
673 if (internal
== NULL
)
678 jack_info("internal \"%s\" selected", internal_name
);
680 return jackctl_server_load_internal(controller_ptr
->server
, internal
);
684 jack_controller_unload_internal(
685 struct jack_controller
*controller_ptr
,
686 const char * internal_name
)
688 jackctl_internal_t
*internal
;
690 internal
= jack_controller_find_internal(controller_ptr
->server
, internal_name
);
691 if (internal
== NULL
)
696 jack_info("internal \"%s\" selected", internal_name
);
698 return jackctl_server_unload_internal(controller_ptr
->server
, internal
);
701 #define controller_ptr ((struct jack_controller *)context)
704 jack_controller_destroy(
707 if (controller_ptr
->started
)
709 while (!jack_controller_stop_server(controller_ptr
, NULL
))
711 jack_info("jack server failed to stop, retrying in 3 seconds...");
716 jack_controller_remove_slave_drivers(controller_ptr
);
717 jack_params_destroy(controller_ptr
->params
);
718 jackctl_server_destroy(controller_ptr
->server
);
719 pthread_mutex_destroy(&controller_ptr
->lock
);
720 free(controller_ptr
);
729 if (controller_ptr
->pending_save
== 0)
734 if (sysinfo(&si
) != 0)
736 jack_error("sysinfo() failed with %d", errno
);
738 else if (si
.uptime
< controller_ptr
->pending_save
+ 2) /* delay save by two seconds */
743 controller_ptr
->pending_save
= 0;
744 jack_controller_settings_save_auto(controller_ptr
);
747 #undef controller_ptr
750 jack_controller_pending_save(
751 struct jack_controller
* controller_ptr
)
755 if (sysinfo(&si
) != 0)
757 jack_error("sysinfo() failed with %d.", errno
);
758 controller_ptr
->pending_save
= 0;
759 jack_controller_settings_save_auto(controller_ptr
);
763 controller_ptr
->pending_save
= si
.uptime
;