2008-05-26 12:56:22 +03:00
/* -*- Mode: C ; c-basic-offset: 4 -*- */
/*
2011-04-17 21:18:32 +03:00
Copyright ( C ) 2007 , 2008 , 2011 Nedko Arnaudov
2008-05-26 12:56:22 +03:00
Copyright ( C ) 2007 - 2008 Juuso Alasuutari
This program 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 .
This program 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 this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2008-06-02 23:46:33 +03:00
# if defined(HAVE_CONFIG_H)
# include "config.h"
# endif
2008-05-26 12:56:22 +03:00
# include <stdint.h>
# include <string.h>
# include <assert.h>
# include <dbus/dbus.h>
# include "jackdbus.h"
# include "controller_internal.h"
# include "xml.h"
unsigned char jack_controller_dbus_types [ JACK_PARAM_MAX ] =
{
[ JackParamInt ] = DBUS_TYPE_INT32 ,
[ JackParamUInt ] = DBUS_TYPE_UINT32 ,
[ JackParamChar ] = DBUS_TYPE_BYTE ,
[ JackParamString ] = DBUS_TYPE_STRING ,
[ JackParamBool ] = DBUS_TYPE_BOOLEAN ,
} ;
const char * jack_controller_dbus_type_signatures [ JACK_PARAM_MAX ] =
{
[ JackParamInt ] = DBUS_TYPE_INT32_AS_STRING ,
[ JackParamUInt ] = DBUS_TYPE_UINT32_AS_STRING ,
[ JackParamChar ] = DBUS_TYPE_BYTE_AS_STRING ,
[ JackParamString ] = DBUS_TYPE_STRING_AS_STRING ,
[ JackParamBool ] = DBUS_TYPE_BOOLEAN_AS_STRING ,
} ;
# define PARAM_TYPE_JACK_TO_DBUS(_) jack_controller_dbus_types[_]
# define PARAM_TYPE_JACK_TO_DBUS_SIGNATURE(_) jack_controller_dbus_type_signatures[_]
static
bool
jack_controller_jack_to_dbus_variant (
jackctl_param_type_t type ,
const union jackctl_parameter_value * value_ptr ,
message_arg_t * dbusv_ptr )
{
switch ( type )
{
case JackParamInt :
dbusv_ptr - > int32 = ( dbus_int32_t ) value_ptr - > i ;
return true ;
case JackParamUInt :
dbusv_ptr - > uint32 = ( dbus_uint32_t ) value_ptr - > ui ;
return true ;
case JackParamChar :
dbusv_ptr - > byte = value_ptr - > c ;
return true ;
case JackParamString :
dbusv_ptr - > string = value_ptr - > str ;
return true ;
case JackParamBool :
dbusv_ptr - > boolean = ( dbus_bool_t ) value_ptr - > b ;
return true ;
}
jack_error ( " Unknown JACK parameter type %i " , ( int ) type ) ;
assert ( 0 ) ;
return false ;
}
static
bool
jack_controller_dbus_to_jack_variant (
int type ,
const message_arg_t * dbusv_ptr ,
union jackctl_parameter_value * value_ptr )
{
size_t len ;
switch ( type )
{
case DBUS_TYPE_INT32 :
value_ptr - > i = dbusv_ptr - > int32 ;
return true ;
case DBUS_TYPE_UINT32 :
value_ptr - > ui = dbusv_ptr - > uint32 ;
return true ;
case DBUS_TYPE_BYTE :
value_ptr - > c = dbusv_ptr - > byte ;
return true ;
case DBUS_TYPE_STRING :
len = strlen ( dbusv_ptr - > string ) ;
if ( len > JACK_PARAM_STRING_MAX )
{
jack_error ( " Parameter string value is too long (%u) " , ( unsigned int ) len ) ;
return false ;
}
memcpy ( value_ptr - > str , dbusv_ptr - > string , len + 1 ) ;
return true ;
case DBUS_TYPE_BOOLEAN :
value_ptr - > b = dbusv_ptr - > boolean ;
return true ;
}
jack_error ( " Unknown D-Bus parameter type %i " , ( int ) type ) ;
return false ;
}
/*
* Construct a return message for a Get [ Driver | Engine ] ParameterValue method call .
*
* 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 - > reply will be set to NULL and handled in send_method_return ( ) .
*/
static void
jack_dbus_construct_method_return_parameter (
2008-10-19 23:46:35 +03:00
struct jack_dbus_method_call * call ,
2008-05-26 12:56:22 +03:00
dbus_bool_t is_set ,
int type ,
const char * signature ,
message_arg_t default_value ,
message_arg_t value )
{
DBusMessageIter iter ;
/* Create a new method return message. */
call - > reply = dbus_message_new_method_return ( call - > message ) ;
if ( ! call - > reply )
{
goto fail ;
}
dbus_message_iter_init_append ( call - > reply , & iter ) ;
/* Append the is_set argument. */
if ( ! dbus_message_iter_append_basic ( & iter , DBUS_TYPE_BOOLEAN , ( const void * ) & is_set ) )
{
goto fail_unref ;
}
/* Append the 'default' and 'value' arguments. */
if ( ! jack_dbus_message_append_variant ( & iter , type , signature , & default_value ) )
{
goto fail_unref ;
}
if ( ! jack_dbus_message_append_variant ( & iter , type , signature , & value ) )
{
goto fail_unref ;
}
return ;
fail_unref :
dbus_message_unref ( call - > reply ) ;
call - > reply = NULL ;
fail :
jack_error ( " Ran out of memory trying to construct method return " ) ;
}
2008-10-19 23:46:35 +03:00
static
bool
jack_controller_dbus_get_parameter_address_ex (
struct jack_dbus_method_call * call ,
DBusMessageIter * iter_ptr ,
const char * * address_array )
{
const char * signature ;
DBusMessageIter array_iter ;
int type ;
int index ;
if ( ! dbus_message_iter_init ( call - > message , iter_ptr ) )
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid arguments to method '%s'. No input arguments found. " ,
call - > method_name ) ;
return false ;
}
signature = dbus_message_iter_get_signature ( iter_ptr ) ;
if ( signature = = NULL )
{
jack_error ( " dbus_message_iter_get_signature() failed " ) ;
return false ;
}
if ( strcmp ( signature , " as " ) ! = 0 )
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid arguments to method '%s'. Input arguments signature '%s', must begin with 'as'. " ,
call - > method_name ,
signature ) ;
return false ;
}
dbus_message_iter_recurse ( iter_ptr , & array_iter ) ;
index = 0 ;
while ( ( type = dbus_message_iter_get_arg_type ( & array_iter ) ) ! = DBUS_TYPE_INVALID )
{
2011-04-17 21:18:32 +03:00
if ( index = = PARAM_ADDRESS_SIZE )
2008-10-19 23:46:35 +03:00
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
2011-04-17 21:18:32 +03:00
" Invalid arguments to method '%s'. Parameter address array must contain not more than %u elements. " ,
( unsigned int ) PARAM_ADDRESS_SIZE ,
2008-10-19 23:46:35 +03:00
call - > method_name ) ;
return false ;
}
;
if ( type ! = DBUS_TYPE_STRING )
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_FATAL ,
" Internal error when parsing parameter address of method '%s'. Address array element type '%c' is not string type. " ,
call - > method_name ,
type ) ;
return false ;
}
dbus_message_iter_get_basic ( & array_iter , address_array + index ) ;
//jack_info("address component: '%s'", address_array[index]);
dbus_message_iter_next ( & array_iter ) ;
index + + ;
}
2011-04-17 21:18:32 +03:00
while ( index < PARAM_ADDRESS_SIZE )
2008-10-19 23:46:35 +03:00
{
address_array [ index ] = NULL ;
index + + ;
}
return true ;
}
2008-05-26 12:56:22 +03:00
static
2008-10-19 23:46:35 +03:00
bool
jack_controller_dbus_get_parameter_address (
struct jack_dbus_method_call * call ,
const char * * address_array )
2008-05-26 12:56:22 +03:00
{
2008-10-19 23:46:35 +03:00
DBusMessageIter iter ;
bool ret ;
ret = jack_controller_dbus_get_parameter_address_ex ( call , & iter , address_array ) ;
if ( ret & & dbus_message_iter_has_next ( & iter ) )
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid arguments to method '%s'. Input arguments signature must be 'as'. " ,
call - > method_name ) ;
return false ;
}
return ret ;
2008-05-26 12:56:22 +03:00
}
2008-10-19 23:46:35 +03:00
# define controller_ptr ((struct jack_controller *)call->context)
2011-04-17 21:18:32 +03:00
static bool append_node_name ( void * context , const char * name )
2008-05-26 12:56:22 +03:00
{
2011-04-17 21:18:32 +03:00
return dbus_message_iter_append_basic ( context , DBUS_TYPE_STRING , & name ) ;
2008-05-26 12:56:22 +03:00
}
static
void
2008-10-19 23:46:35 +03:00
jack_controller_dbus_read_container (
struct jack_dbus_method_call * call )
2008-05-26 12:56:22 +03:00
{
2011-04-17 21:18:32 +03:00
const char * address [ PARAM_ADDRESS_SIZE ] ;
2008-10-19 23:46:35 +03:00
dbus_bool_t leaf ;
DBusMessageIter iter ;
DBusMessageIter array_iter ;
2008-05-26 12:56:22 +03:00
2008-10-19 23:46:35 +03:00
//jack_info("jack_controller_dbus_read_container() called");
if ( ! jack_controller_dbus_get_parameter_address ( call , address ) )
2008-05-26 12:56:22 +03:00
{
/* The method call had invalid arguments meaning that
2008-10-19 23:46:35 +03:00
* jack_controller_dbus_get_parameter_address ( ) has
* constructed an error for us . */
2008-05-26 12:56:22 +03:00
return ;
}
2008-10-19 23:46:35 +03:00
//jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
/* Create a new method return message. */
call - > reply = dbus_message_new_method_return ( call - > message ) ;
if ( ! call - > reply )
2008-05-26 12:56:22 +03:00
{
2008-10-19 23:46:35 +03:00
goto oom ;
}
dbus_message_iter_init_append ( call - > reply , & iter ) ;
2011-04-17 21:18:32 +03:00
if ( ! jack_params_check_address ( controller_ptr - > params , address , false ) )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid container address '%s':'%s':'%s' supplied to method '%s'. " ,
address [ 0 ] ,
address [ 1 ] ,
address [ 2 ] ,
call - > method_name ) ;
2008-05-26 12:56:22 +03:00
return ;
}
2011-04-17 21:18:32 +03:00
leaf = jack_params_is_leaf_container ( controller_ptr - > params , address ) ;
if ( ! dbus_message_iter_append_basic ( & iter , DBUS_TYPE_BOOLEAN , & leaf ) )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
goto oom_unref ;
2008-10-19 23:46:35 +03:00
}
2011-04-17 21:18:32 +03:00
if ( ! dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY , " s " , & array_iter ) )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
goto oom_unref ;
2008-10-19 23:46:35 +03:00
}
2011-04-17 21:18:32 +03:00
if ( ! jack_params_iterate_container ( controller_ptr - > params , address , append_node_name , & array_iter ) )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
goto oom_close_unref ;
2008-10-19 23:46:35 +03:00
}
2011-04-17 21:18:32 +03:00
dbus_message_iter_close_container ( & iter , & array_iter ) ;
2008-10-19 23:46:35 +03:00
return ;
oom_close_unref :
dbus_message_iter_close_container ( & iter , & array_iter ) ;
oom_unref :
dbus_message_unref ( call - > reply ) ;
call - > reply = NULL ;
oom :
jack_error ( " Ran out of memory trying to construct method return " ) ;
2008-05-26 12:56:22 +03:00
}
2011-04-17 21:18:32 +03:00
static bool append_parameter ( void * context , const struct jack_parameter * param_ptr )
2011-04-10 05:36:42 +03:00
{
DBusMessageIter struct_iter ;
unsigned char type ;
/* Open the struct. */
2011-04-17 21:18:32 +03:00
if ( ! dbus_message_iter_open_container ( context , DBUS_TYPE_STRUCT , NULL , & struct_iter ) )
2011-04-10 05:36:42 +03:00
{
goto fail ;
}
/* Append parameter type. */
2011-04-17 21:18:32 +03:00
type = PARAM_TYPE_JACK_TO_DBUS ( param_ptr - > type ) ;
2011-04-10 05:36:42 +03:00
if ( ! dbus_message_iter_append_basic ( & struct_iter , DBUS_TYPE_BYTE , & type ) )
{
goto fail_close ;
}
/* Append parameter name. */
2011-04-17 21:18:32 +03:00
if ( ! dbus_message_iter_append_basic ( & struct_iter , DBUS_TYPE_STRING , & param_ptr - > name ) )
2011-04-10 05:36:42 +03:00
{
goto fail_close ;
}
/* Append parameter short description. */
2011-04-17 21:18:32 +03:00
if ( ! dbus_message_iter_append_basic ( & struct_iter , DBUS_TYPE_STRING , & param_ptr - > short_decr ) )
2011-04-10 05:36:42 +03:00
{
goto fail_close ;
}
/* Append parameter long description. */
2011-04-17 21:18:32 +03:00
if ( ! dbus_message_iter_append_basic ( & struct_iter , DBUS_TYPE_STRING , & param_ptr - > long_descr ) )
2011-04-10 05:36:42 +03:00
{
goto fail_close ;
}
/* Close the struct. */
2011-04-17 21:18:32 +03:00
if ( ! dbus_message_iter_close_container ( context , & struct_iter ) )
2011-04-10 05:36:42 +03:00
{
goto fail ;
}
return true ;
fail_close :
2011-04-17 21:18:32 +03:00
dbus_message_iter_close_container ( context , & struct_iter ) ;
2011-04-10 05:36:42 +03:00
fail :
return false ;
}
2008-05-26 12:56:22 +03:00
static
void
2011-04-17 21:18:32 +03:00
jack_controller_dbus_get_parameters_info (
struct jack_dbus_method_call * call )
2008-05-26 12:56:22 +03:00
{
2011-04-17 21:18:32 +03:00
const char * address [ PARAM_ADDRESS_SIZE ] ;
2011-04-10 05:36:42 +03:00
DBusMessageIter iter , array_iter ;
2011-04-17 21:18:32 +03:00
//jack_info("jack_controller_dbus_get_parameters_info() called");
if ( ! jack_controller_dbus_get_parameter_address ( call , address ) )
{
/* The method call had invalid arguments meaning that
* jack_controller_dbus_get_parameter_address ( ) has
* constructed an error for us . */
return ;
}
//jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
if ( ! jack_params_check_address ( controller_ptr - > params , address , true ) )
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid container address '%s':'%s':'%s' supplied to method '%s'. " ,
address [ 0 ] ,
address [ 1 ] ,
address [ 2 ] ,
call - > method_name ) ;
return ;
}
2008-05-26 12:56:22 +03:00
call - > reply = dbus_message_new_method_return ( call - > message ) ;
if ( ! call - > reply )
{
goto fail ;
}
dbus_message_iter_init_append ( call - > reply , & iter ) ;
/* Open the array. */
if ( ! dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY , " (ysss) " , & array_iter ) )
{
goto fail_unref ;
}
2011-04-17 21:18:32 +03:00
if ( ! jack_params_iterate_params ( controller_ptr - > params , address , append_parameter , & array_iter ) )
2008-05-26 12:56:22 +03:00
{
2011-04-17 21:18:32 +03:00
goto fail_close_unref ;
2008-05-26 12:56:22 +03:00
}
/* Close the array. */
if ( ! dbus_message_iter_close_container ( & iter , & array_iter ) )
{
goto fail_unref ;
}
return ;
fail_close_unref :
dbus_message_iter_close_container ( & iter , & array_iter ) ;
fail_unref :
dbus_message_unref ( call - > reply ) ;
call - > reply = NULL ;
fail :
jack_error ( " Ran out of memory trying to construct method return " ) ;
}
static
void
2011-04-17 21:18:32 +03:00
jack_controller_dbus_get_parameter_info (
2008-10-19 23:46:35 +03:00
struct jack_dbus_method_call * call )
2008-05-26 12:56:22 +03:00
{
2011-04-17 21:18:32 +03:00
const char * address [ PARAM_ADDRESS_SIZE ] ;
const struct jack_parameter * param_ptr ;
DBusMessageIter iter ;
2008-05-26 12:56:22 +03:00
2011-04-17 21:18:32 +03:00
//jack_info("jack_controller_dbus_get_parameter_info() called");
2008-10-19 23:46:35 +03:00
if ( ! jack_controller_dbus_get_parameter_address ( call , address ) )
2008-05-26 12:56:22 +03:00
{
2008-10-19 23:46:35 +03:00
/* The method call had invalid arguments meaning that
* jack_controller_dbus_get_parameter_address ( ) has
* constructed an error for us . */
return ;
2008-05-26 12:56:22 +03:00
}
2008-10-19 23:46:35 +03:00
//jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
2008-05-26 12:56:22 +03:00
2011-04-17 21:18:32 +03:00
param_ptr = jack_params_get_parameter ( controller_ptr - > params , address ) ;
if ( param_ptr = = NULL )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
jack_dbus_error (
2008-10-19 23:46:35 +03:00
call ,
2011-04-17 21:18:32 +03:00
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid container address '%s':'%s':'%s' supplied to method '%s'. " ,
address [ 0 ] ,
address [ 1 ] ,
address [ 2 ] ,
call - > method_name ) ;
2008-10-19 23:46:35 +03:00
return ;
}
call - > reply = dbus_message_new_method_return ( call - > message ) ;
if ( ! call - > reply )
{
goto fail ;
}
dbus_message_iter_init_append ( call - > reply , & iter ) ;
2011-04-17 21:18:32 +03:00
if ( ! append_parameter ( & iter , param_ptr ) )
2008-05-26 12:56:22 +03:00
{
goto fail_unref ;
}
return ;
fail_unref :
2008-10-19 23:46:35 +03:00
dbus_message_unref ( call - > reply ) ;
2008-05-26 12:56:22 +03:00
call - > reply = NULL ;
fail :
2008-10-19 23:46:35 +03:00
jack_error ( " Ran out of memory trying to construct method return " ) ;
}
static
void
2011-04-17 21:18:32 +03:00
jack_controller_dbus_get_parameter_constraint (
2008-10-19 23:46:35 +03:00
struct jack_dbus_method_call * call )
{
2011-04-17 21:18:32 +03:00
const char * address [ PARAM_ADDRESS_SIZE ] ;
const struct jack_parameter * param_ptr ;
uint32_t index ;
DBusMessageIter iter , array_iter , struct_iter ;
const char * descr ;
message_arg_t value ;
2008-10-19 23:46:35 +03:00
2011-04-17 21:18:32 +03:00
//jack_info("jack_controller_dbus_get_parameter_constraint() called");
2008-10-19 23:46:35 +03:00
if ( ! jack_controller_dbus_get_parameter_address ( call , address ) )
{
/* The method call had invalid arguments meaning that
* jack_controller_dbus_get_parameter_address ( ) has
* constructed an error for us . */
return ;
}
//jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
2011-04-17 21:18:32 +03:00
param_ptr = jack_params_get_parameter ( controller_ptr - > params , address ) ;
if ( param_ptr = = NULL )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid container address '%s':'%s':'%s' supplied to method '%s'. " ,
address [ 0 ] ,
address [ 1 ] ,
address [ 2 ] ,
call - > method_name ) ;
2008-10-19 23:46:35 +03:00
return ;
}
2011-04-17 21:18:32 +03:00
call - > reply = dbus_message_new_method_return ( call - > message ) ;
if ( ! call - > reply )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
goto fail ;
}
2008-10-19 23:46:35 +03:00
2011-04-17 21:18:32 +03:00
dbus_message_iter_init_append ( call - > reply , & iter ) ;
2008-10-19 23:46:35 +03:00
2011-04-17 21:18:32 +03:00
if ( ( param_ptr - > constraint_flags & JACK_CONSTRAINT_FLAG_VALID ) ! = 0 )
{
value . boolean = param_ptr - > constraint_range ;
2008-10-19 23:46:35 +03:00
}
2011-04-17 21:18:32 +03:00
else
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
value . boolean = false ;
}
2008-10-19 23:46:35 +03:00
2011-04-17 21:18:32 +03:00
if ( ! dbus_message_iter_append_basic ( & iter , DBUS_TYPE_BOOLEAN , & value ) )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
goto fail_unref ;
2008-10-19 23:46:35 +03:00
}
2011-04-17 21:18:32 +03:00
if ( ( param_ptr - > constraint_flags & JACK_CONSTRAINT_FLAG_VALID ) ! = 0 )
2008-10-13 18:53:50 +03:00
{
2011-04-17 21:18:32 +03:00
value . boolean = ( param_ptr - > constraint_flags & JACK_CONSTRAINT_FLAG_STRICT ) ! = 0 ;
2008-10-13 18:53:50 +03:00
}
2008-10-13 18:54:10 +03:00
if ( ! dbus_message_iter_append_basic ( & iter , DBUS_TYPE_BOOLEAN , & value ) )
{
goto fail_unref ;
}
2008-10-13 18:53:50 +03:00
2011-04-17 21:18:32 +03:00
if ( ( param_ptr - > constraint_flags & JACK_CONSTRAINT_FLAG_VALID ) ! = 0 )
2008-10-13 18:54:10 +03:00
{
2011-04-17 21:18:32 +03:00
value . boolean = ( param_ptr - > constraint_flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE ) ! = 0 ;
2008-10-13 18:54:10 +03:00
}
2008-10-13 18:53:50 +03:00
if ( ! dbus_message_iter_append_basic ( & iter , DBUS_TYPE_BOOLEAN , & value ) )
{
goto fail_unref ;
}
2008-10-13 18:54:46 +03:00
/* Open the array. */
if ( ! dbus_message_iter_open_container ( & iter , DBUS_TYPE_ARRAY , " (vs) " , & array_iter ) )
{
goto fail_unref ;
}
2011-04-17 21:18:32 +03:00
if ( ( param_ptr - > constraint_flags & JACK_CONSTRAINT_FLAG_VALID ) = = 0 )
2008-10-13 18:53:50 +03:00
{
2011-04-17 21:18:32 +03:00
goto close ;
}
2008-10-13 18:53:50 +03:00
2011-04-17 21:18:32 +03:00
if ( param_ptr - > constraint_range )
{
2008-10-13 18:54:46 +03:00
/* Open the struct. */
if ( ! dbus_message_iter_open_container ( & array_iter , DBUS_TYPE_STRUCT , NULL , & struct_iter ) )
{
goto fail_close_unref ;
}
2008-10-13 18:53:50 +03:00
2011-04-17 21:18:32 +03:00
jack_controller_jack_to_dbus_variant ( param_ptr - > type , & param_ptr - > constraint . range . min , & value ) ;
2008-10-13 18:53:50 +03:00
2011-04-17 21:18:32 +03:00
if ( ! jack_dbus_message_append_variant (
& struct_iter ,
PARAM_TYPE_JACK_TO_DBUS ( param_ptr - > type ) ,
PARAM_TYPE_JACK_TO_DBUS_SIGNATURE ( param_ptr - > type ) ,
& value ) )
2008-10-13 18:54:46 +03:00
{
goto fail_close2_unref ;
}
2008-10-13 18:53:50 +03:00
2008-10-13 18:54:46 +03:00
descr = " min " ;
if ( ! dbus_message_iter_append_basic ( & struct_iter , DBUS_TYPE_STRING , & descr ) )
{
goto fail_close2_unref ;
}
/* Close the struct. */
if ( ! dbus_message_iter_close_container ( & array_iter , & struct_iter ) )
{
goto fail_close_unref ;
}
2008-10-13 18:53:50 +03:00
/* Open the struct. */
if ( ! dbus_message_iter_open_container ( & array_iter , DBUS_TYPE_STRUCT , NULL , & struct_iter ) )
{
goto fail_close_unref ;
}
2011-04-17 21:18:32 +03:00
jack_controller_jack_to_dbus_variant ( param_ptr - > type , & param_ptr - > constraint . range . max , & value ) ;
2008-10-13 18:54:46 +03:00
2011-04-17 21:18:32 +03:00
if ( ! jack_dbus_message_append_variant (
& struct_iter ,
PARAM_TYPE_JACK_TO_DBUS ( param_ptr - > type ) ,
PARAM_TYPE_JACK_TO_DBUS_SIGNATURE ( param_ptr - > type ) ,
& value ) )
2008-10-13 18:53:50 +03:00
{
goto fail_close2_unref ;
}
2008-10-13 18:54:46 +03:00
descr = " max " ;
2008-10-13 18:53:50 +03:00
if ( ! dbus_message_iter_append_basic ( & struct_iter , DBUS_TYPE_STRING , & descr ) )
{
goto fail_close2_unref ;
}
/* Close the struct. */
if ( ! dbus_message_iter_close_container ( & array_iter , & struct_iter ) )
{
goto fail_close_unref ;
}
}
2008-10-13 18:54:46 +03:00
else
{
/* Append enum values to the array. */
2011-04-17 21:18:32 +03:00
for ( index = 0 ; index < param_ptr - > constraint . enumeration . count ; index + + )
2008-10-13 18:54:46 +03:00
{
2011-04-17 21:18:32 +03:00
descr = param_ptr - > constraint . enumeration . possible_values_array [ index ] . short_desc ;
2008-10-13 18:54:46 +03:00
2011-04-17 21:18:32 +03:00
jack_controller_jack_to_dbus_variant ( param_ptr - > type , & param_ptr - > constraint . enumeration . possible_values_array [ index ] . value , & value ) ;
2008-10-13 18:54:46 +03:00
/* Open the struct. */
if ( ! dbus_message_iter_open_container ( & array_iter , DBUS_TYPE_STRUCT , NULL , & struct_iter ) )
{
goto fail_close_unref ;
}
2011-04-17 21:18:32 +03:00
if ( ! jack_dbus_message_append_variant (
& struct_iter ,
PARAM_TYPE_JACK_TO_DBUS ( param_ptr - > type ) ,
PARAM_TYPE_JACK_TO_DBUS_SIGNATURE ( param_ptr - > type ) ,
& value ) )
2008-10-13 18:54:46 +03:00
{
goto fail_close2_unref ;
}
if ( ! dbus_message_iter_append_basic ( & struct_iter , DBUS_TYPE_STRING , & descr ) )
{
goto fail_close2_unref ;
}
/* Close the struct. */
if ( ! dbus_message_iter_close_container ( & array_iter , & struct_iter ) )
{
goto fail_close_unref ;
}
}
}
2008-10-13 18:53:50 +03:00
2011-04-17 21:18:32 +03:00
close :
2008-10-13 18:53:50 +03:00
/* Close the array. */
if ( ! dbus_message_iter_close_container ( & iter , & array_iter ) )
{
goto fail_unref ;
}
return ;
fail_close2_unref :
dbus_message_iter_close_container ( & array_iter , & struct_iter ) ;
fail_close_unref :
dbus_message_iter_close_container ( & iter , & array_iter ) ;
fail_unref :
dbus_message_unref ( call - > reply ) ;
call - > reply = NULL ;
fail :
jack_error ( " Ran out of memory trying to construct method return " ) ;
}
2011-04-17 21:18:32 +03:00
static void
jack_controller_dbus_get_parameter_value (
2008-10-19 23:46:35 +03:00
struct jack_dbus_method_call * call )
2008-05-26 12:56:22 +03:00
{
2011-04-17 21:18:32 +03:00
const char * address [ PARAM_ADDRESS_SIZE ] ;
const struct jack_parameter * param_ptr ;
2008-05-26 12:56:22 +03:00
union jackctl_parameter_value jackctl_value ;
union jackctl_parameter_value jackctl_default_value ;
message_arg_t value ;
message_arg_t default_value ;
2008-10-19 23:46:35 +03:00
//jack_info("jack_controller_dbus_get_parameter_value() called");
if ( ! jack_controller_dbus_get_parameter_address ( call , address ) )
2008-05-26 12:56:22 +03:00
{
2008-10-19 23:46:35 +03:00
/* The method call had invalid arguments meaning that
* jack_controller_dbus_get_parameter_address ( ) has
* constructed an error for us . */
2008-05-26 12:56:22 +03:00
return ;
}
2008-10-19 23:46:35 +03:00
//jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
2008-05-26 12:56:22 +03:00
2011-04-17 21:18:32 +03:00
param_ptr = jack_params_get_parameter ( controller_ptr - > params , address ) ;
if ( param_ptr = = NULL )
2008-09-03 13:57:27 +03:00
{
2008-10-19 23:46:35 +03:00
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
2011-04-17 21:18:32 +03:00
" Invalid container address '%s':'%s':'%s' supplied to method '%s'. " ,
address [ 0 ] ,
address [ 1 ] ,
address [ 2 ] ,
call - > method_name ) ;
2008-09-03 13:57:27 +03:00
return ;
}
2011-04-17 21:18:32 +03:00
jackctl_default_value = param_ptr - > vtable . get_default_value ( param_ptr - > obj ) ;
jackctl_value = param_ptr - > vtable . get_value ( param_ptr - > obj ) ;
2008-09-03 13:57:27 +03:00
2011-04-17 21:18:32 +03:00
jack_controller_jack_to_dbus_variant ( param_ptr - > type , & jackctl_value , & value ) ;
jack_controller_jack_to_dbus_variant ( param_ptr - > type , & jackctl_default_value , & default_value ) ;
2008-09-03 13:57:27 +03:00
2011-04-17 21:18:32 +03:00
/* Construct the reply. */
jack_dbus_construct_method_return_parameter (
call ,
( dbus_bool_t ) ( param_ptr - > vtable . is_set ( param_ptr - > obj ) ? TRUE : FALSE ) ,
PARAM_TYPE_JACK_TO_DBUS ( param_ptr - > type ) ,
PARAM_TYPE_JACK_TO_DBUS_SIGNATURE ( param_ptr - > type ) ,
default_value ,
value ) ;
2008-09-03 13:57:27 +03:00
}
static
void
2008-10-19 23:46:35 +03:00
jack_controller_dbus_set_parameter_value (
struct jack_dbus_method_call * call )
2008-09-03 13:57:27 +03:00
{
2011-04-17 21:18:32 +03:00
const char * address [ PARAM_ADDRESS_SIZE ] ;
const struct jack_parameter * param_ptr ;
2008-10-19 23:46:35 +03:00
DBusMessageIter iter ;
DBusMessageIter variant_iter ;
2008-09-03 13:57:27 +03:00
message_arg_t arg ;
int arg_type ;
2011-04-17 21:18:32 +03:00
union jackctl_parameter_value value ;
2008-09-03 13:57:27 +03:00
2008-10-19 23:46:35 +03:00
//jack_info("jack_controller_dbus_set_parameter_value() called");
2008-09-03 13:57:27 +03:00
2008-10-19 23:46:35 +03:00
if ( ! jack_controller_dbus_get_parameter_address_ex ( call , & iter , address ) )
2008-09-03 13:57:27 +03:00
{
2008-10-19 23:46:35 +03:00
/* The method call had invalid arguments meaning that
* jack_controller_dbus_get_parameter_address ( ) has
* constructed an error for us . */
2008-09-03 13:57:27 +03:00
return ;
}
2008-10-19 23:46:35 +03:00
//jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
2008-09-03 13:57:27 +03:00
2011-04-17 21:18:32 +03:00
param_ptr = jack_params_get_parameter ( controller_ptr - > params , address ) ;
if ( param_ptr = = NULL )
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid container address '%s':'%s':'%s' supplied to method '%s'. " ,
address [ 0 ] ,
address [ 1 ] ,
address [ 2 ] ,
call - > method_name ) ;
return ;
}
2008-10-19 23:46:35 +03:00
dbus_message_iter_next ( & iter ) ;
2008-09-03 13:57:27 +03:00
2008-10-19 23:46:35 +03:00
if ( dbus_message_iter_has_next ( & iter ) )
2008-09-03 13:57:27 +03:00
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
2008-10-19 23:46:35 +03:00
" Invalid arguments to method '%s'. Too many arguments. " ,
call - > method_name ) ;
2008-09-03 13:57:27 +03:00
return ;
}
2008-10-19 23:46:35 +03:00
if ( dbus_message_iter_get_arg_type ( & iter ) ! = DBUS_TYPE_VARIANT )
2008-09-03 13:57:27 +03:00
{
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
2008-10-19 23:46:35 +03:00
" Invalid arguments to method '%s'. Value to set must be variant. " ,
call - > method_name ) ;
2008-09-03 13:57:27 +03:00
return ;
}
2008-10-19 23:46:35 +03:00
dbus_message_iter_recurse ( & iter , & variant_iter ) ;
dbus_message_iter_get_basic ( & variant_iter , & arg ) ;
arg_type = dbus_message_iter_get_arg_type ( & variant_iter ) ;
2008-09-03 13:57:27 +03:00
2008-10-19 23:46:35 +03:00
//jack_info("argument of type '%c'", arg_type);
2008-09-03 13:57:27 +03:00
2011-04-17 21:18:32 +03:00
if ( PARAM_TYPE_JACK_TO_DBUS ( param_ptr - > type ) ! = arg_type )
2008-10-19 23:46:35 +03:00
{
2011-04-17 21:18:32 +03:00
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Parameter value type mismatch: was expecting '%c', got '%c' " ,
( char ) PARAM_TYPE_JACK_TO_DBUS ( param_ptr - > type ) ,
( char ) arg_type ) ;
2008-10-19 23:46:35 +03:00
return ;
}
2011-04-17 21:18:32 +03:00
if ( ! jack_controller_dbus_to_jack_variant (
arg_type ,
& arg ,
& value ) )
2008-10-20 01:33:04 +03:00
{
jack_dbus_error (
call ,
2011-04-17 21:18:32 +03:00
JACK_DBUS_ERROR_INVALID_ARGS ,
" Cannot convert parameter value " ) ;
2008-10-20 01:33:04 +03:00
return ;
}
2011-04-17 21:18:32 +03:00
param_ptr - > vtable . set_value ( param_ptr - > obj , & value ) ;
2008-10-20 01:33:04 +03:00
2011-11-12 21:23:44 +02:00
jack_controller_pending_save ( controller_ptr ) ;
2008-10-20 01:33:04 +03:00
jack_dbus_construct_method_return_empty ( call ) ;
2011-04-17 21:18:32 +03:00
2008-10-20 01:33:04 +03:00
}
static
void
jack_controller_dbus_reset_parameter_value (
struct jack_dbus_method_call * call )
{
2011-04-17 21:18:32 +03:00
const char * address [ PARAM_ADDRESS_SIZE ] ;
const struct jack_parameter * param_ptr ;
2008-10-20 01:33:04 +03:00
//jack_info("jack_controller_dbus_reset_parameter_value() called");
if ( ! jack_controller_dbus_get_parameter_address ( call , address ) )
{
/* The method call had invalid arguments meaning that
* jack_controller_dbus_get_parameter_address ( ) has
* constructed an error for us . */
return ;
}
//jack_info("address is '%s':'%s':'%s'", address[0], address[1], address[2]);
2011-04-17 21:18:32 +03:00
param_ptr = jack_params_get_parameter ( controller_ptr - > params , address ) ;
if ( param_ptr = = NULL )
2008-10-20 01:33:04 +03:00
{
2011-04-17 21:18:32 +03:00
jack_dbus_error (
call ,
JACK_DBUS_ERROR_INVALID_ARGS ,
" Invalid container address '%s':'%s':'%s' supplied to method '%s'. " ,
address [ 0 ] ,
address [ 1 ] ,
address [ 2 ] ,
call - > method_name ) ;
2008-10-20 01:33:04 +03:00
return ;
}
2011-04-17 21:18:32 +03:00
param_ptr - > vtable . reset ( param_ptr - > obj ) ;
2008-10-20 01:33:04 +03:00
2011-11-12 21:23:44 +02:00
jack_controller_pending_save ( controller_ptr ) ;
2008-10-20 01:33:04 +03:00
2011-04-17 21:18:32 +03:00
jack_dbus_construct_method_return_empty ( call ) ;
2008-10-20 01:33:04 +03:00
}
2008-10-19 23:46:35 +03:00
# undef controller_ptr
2008-05-26 12:56:22 +03:00
2008-10-19 23:46:35 +03:00
JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX ( ReadContainer , " Get names of child parameters or containers " )
JACK_DBUS_METHOD_ARGUMENT_IN ( " parent " , " as " , " Address of parent container " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " leaf " , " b " , " Whether children are parameters (true) or containers (false) " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " children " , " as " , " Array of child names " )
2008-09-03 13:57:27 +03:00
JACK_DBUS_METHOD_ARGUMENTS_END
2008-10-19 23:46:35 +03:00
JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX ( GetParametersInfo , " Retrieve info about parameters " )
JACK_DBUS_METHOD_ARGUMENT_IN ( " parent " , " as " , " Address of parameters parent " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " parameter_info_array " , " a(ysss) " , " Array of parameter info structs. Each info struct contains: type char, name, short and long description " )
2008-09-03 13:57:27 +03:00
JACK_DBUS_METHOD_ARGUMENTS_END
2008-10-19 23:46:35 +03:00
JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX ( GetParameterInfo , " Retrieve info about parameter " )
JACK_DBUS_METHOD_ARGUMENT_IN ( " parameter " , " as " , " Address of parameter " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " parameter_info " , " (ysss) " , " Parameter info struct that contains: type char, name, short and long description " )
2008-09-03 13:57:27 +03:00
JACK_DBUS_METHOD_ARGUMENTS_END
2008-10-19 23:46:35 +03:00
JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX ( GetParameterConstraint , " Get constraint of parameter " )
JACK_DBUS_METHOD_ARGUMENT_IN ( " parameter " , " as " , " Address of parameter " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " is_range " , " b " , " Whether constrinat is a range. If so, values parameter will contain two values, min and max " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " is_strict " , " b " , " Whether enum constraint is strict. I.e. value not listed in values array will not work " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " is_fake_value " , " b " , " Whether enum values are fake. I.e. have no user meaningful meaning " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " values " , " a(vs) " , " Values. If there is no constraint, this array will be empty. For range constraint there will be two values, min and max. For enum constraint there will be 2 or more values. " )
2008-10-13 18:54:33 +03:00
JACK_DBUS_METHOD_ARGUMENTS_END
2008-10-19 23:46:35 +03:00
JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX ( GetParameterValue , " Get value of parameter " )
JACK_DBUS_METHOD_ARGUMENT_IN ( " parameter " , " as " , " Address of parameter " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " is_set " , " b " , " Whether parameter is set or its default value is used " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " default " , " v " , " Default value of parameter " )
JACK_DBUS_METHOD_ARGUMENT_OUT ( " value " , " v " , " Actual value of parameter " )
2008-09-03 13:57:27 +03:00
JACK_DBUS_METHOD_ARGUMENTS_END
2008-10-19 23:46:35 +03:00
JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX ( SetParameterValue , " Set value of parameter " )
JACK_DBUS_METHOD_ARGUMENT_IN ( " parameter " , " as " , " Address of parameter " )
JACK_DBUS_METHOD_ARGUMENT_IN ( " value " , " v " , " New value for parameter " )
2008-09-03 13:57:27 +03:00
JACK_DBUS_METHOD_ARGUMENTS_END
2008-10-20 01:33:04 +03:00
JACK_DBUS_METHOD_ARGUMENTS_BEGIN_EX ( ResetParameterValue , " Reset parameter to default value " )
JACK_DBUS_METHOD_ARGUMENT_IN ( " parameter " , " as " , " Address of parameter " )
JACK_DBUS_METHOD_ARGUMENTS_END
2008-05-26 12:56:22 +03:00
JACK_DBUS_METHODS_BEGIN
2008-10-19 23:46:35 +03:00
JACK_DBUS_METHOD_DESCRIBE ( ReadContainer , jack_controller_dbus_read_container )
JACK_DBUS_METHOD_DESCRIBE ( GetParametersInfo , jack_controller_dbus_get_parameters_info )
JACK_DBUS_METHOD_DESCRIBE ( GetParameterInfo , jack_controller_dbus_get_parameter_info )
JACK_DBUS_METHOD_DESCRIBE ( GetParameterConstraint , jack_controller_dbus_get_parameter_constraint )
JACK_DBUS_METHOD_DESCRIBE ( GetParameterValue , jack_controller_dbus_get_parameter_value )
JACK_DBUS_METHOD_DESCRIBE ( SetParameterValue , jack_controller_dbus_set_parameter_value )
2008-10-20 01:33:04 +03:00
JACK_DBUS_METHOD_DESCRIBE ( ResetParameterValue , jack_controller_dbus_reset_parameter_value )
2008-05-26 12:56:22 +03:00
JACK_DBUS_METHODS_END
2008-10-19 23:46:35 +03:00
/*
* Parameter addresses :
*
* " engine "
* " engine " , " driver "
* " engine " , " realtime "
* " engine " , . . . more engine parameters
*
* " driver " , " device "
* " driver " , . . . more driver parameters
*
* " drivers " , " alsa " , " device "
* " drivers " , " alsa " , . . . more alsa driver parameters
*
* " drivers " , . . . more drivers
*
* " internals " , " netmanager " , " multicast_ip "
* " internals " , " netmanager " , . . . more netmanager parameters
*
* " internals " , . . . more internals
*
*/
JACK_DBUS_IFACE_BEGIN ( g_jack_controller_iface_configure , " org.jackaudio.Configure " )
2008-05-26 12:56:22 +03:00
JACK_DBUS_IFACE_EXPOSE_METHODS
JACK_DBUS_IFACE_END