47 #include "../dbus-gmain/dbus-gmain.h"
49 #ifdef SAILFISH_ACCESS_CONTROL
50 # include <sailfishaccesscontrol.h>
57 #define INIT_DONE_OBJECT "/com/nokia/startup/signal"
58 #define INIT_DONE_INTERFACE "com.nokia.startup.signal"
59 #define INIT_DONE_SIGNAL "init_done"
60 #define INIT_DONE_MATCH "type='signal',interface='"INIT_DONE_INTERFACE"',member='"INIT_DONE_SIGNAL"'"
62 # define PID_UNKNOWN ((pid_t)-1)
91 #define ADD_METHOD(NAME, FUNC, ARGS) {\
92 .type = DBUS_MESSAGE_TYPE_METHOD_CALL,\
100 #define ADD_SIGNAL(NAME, ARGS) {\
101 .type = DBUS_MESSAGE_TYPE_SIGNAL,\
109 #define ADD_SENTINEL {\
110 .type = DBUS_MESSAGE_TYPE_INVALID,\
182 static void member_info_introspect(
const member_info_t *
self, FILE *file);
189 static void interface_info_introspect(
const interface_info_t *
self, FILE *file);
196 static void object_info_introspect (
const object_info_t *
self, FILE *file,
const char *interface);
197 static char *object_info_get_introspect_xml(
const object_info_t *
self,
const char *interface);
217 static void usb_moded_available_modes_for_user_cb(
umdbus_context_t *context);
233 static const object_info_t *umdbus_get_object_info (
const char *
object);
237 static DBusHandlerResult umdbus_msg_handler (DBusConnection *
const connection, DBusMessage *
const msg, gpointer
const user_data);
238 DBusConnection *umdbus_get_connection (
void);
241 static void umdbus_cleanup_service (
void);
243 static DBusMessage *umdbus_new_signal (
const char *signal_name);
244 static int umdbus_send_signal_ex (
const char *signal_name,
const char *content);
245 static void umdbus_send_legacy_signal (
const char *state_ind);
247 static bool umdbus_append_basic_entry (DBusMessageIter *iter,
const char *key,
int type,
const void *val);
248 static bool umdbus_append_int32_entry (DBusMessageIter *iter,
const char *key,
int val);
249 static bool umdbus_append_string_entry (DBusMessageIter *iter,
const char *key,
const char *val);
250 static bool umdbus_append_mode_details (DBusMessage *msg,
const char *mode_name);
251 static void umdbus_send_mode_details_signal (
const char *mode_name);
259 static void umdbus_get_name_owner_cb (DBusPendingCall *pc,
void *aptr);
261 static uid_t umdbus_get_sender_uid (
const char *name);
262 const char *umdbus_arg_type_repr (
int type);
263 const char *umdbus_arg_type_signature (
int type);
264 const char *umdbus_msg_type_repr (
int type);
265 bool umdbus_parser_init (DBusMessageIter *iter, DBusMessage *msg);
266 int umdbus_parser_at_type (DBusMessageIter *iter);
267 bool umdbus_parser_at_end (DBusMessageIter *iter);
268 bool umdbus_parser_require_type (DBusMessageIter *iter,
int type,
bool strict);
269 bool umdbus_parser_get_bool (DBusMessageIter *iter,
bool *pval);
270 bool umdbus_parser_get_int (DBusMessageIter *iter,
int *pval);
271 bool umdbus_parser_get_string (DBusMessageIter *iter,
const char **pval);
272 bool umdbus_parser_get_object (DBusMessageIter *iter,
const char **pval);
273 bool umdbus_parser_get_variant (DBusMessageIter *iter, DBusMessageIter *val);
274 bool umdbus_parser_get_array (DBusMessageIter *iter, DBusMessageIter *val);
275 bool umdbus_parser_get_struct (DBusMessageIter *iter, DBusMessageIter *val);
276 bool umdbus_parser_get_entry (DBusMessageIter *iter, DBusMessageIter *val);
277 bool umdbus_append_init (DBusMessageIter *iter, DBusMessage *msg);
278 bool umdbus_open_container (DBusMessageIter *iter, DBusMessageIter *sub,
int type,
const char *sign);
279 bool umdbus_close_container (DBusMessageIter *iter, DBusMessageIter *sub,
bool success);
280 bool umdbus_append_basic_value (DBusMessageIter *iter,
int type,
const DBusBasicValue *val);
281 bool umdbus_append_basic_variant (DBusMessageIter *iter,
int type,
const DBusBasicValue *val);
282 bool umdbus_append_bool (DBusMessageIter *iter,
bool val);
283 bool umdbus_append_int (DBusMessageIter *iter,
int val);
284 bool umdbus_append_string (DBusMessageIter *iter,
const char *val);
285 bool umdbus_append_bool_variant (DBusMessageIter *iter,
bool val);
286 bool umdbus_append_int_variant (DBusMessageIter *iter,
int val);
287 bool umdbus_append_string_variant (DBusMessageIter *iter,
const char *val);
288 bool umdbus_append_args_va (DBusMessageIter *iter,
int type, va_list va);
289 bool umdbus_append_args (DBusMessageIter *iter,
int arg_type, ...);
290 DBusMessage *umdbus_blocking_call (DBusConnection *con,
const char *dst,
const char *obj,
const char *iface,
const char *meth, DBusError *err,
int arg_type, ...);
291 bool umdbus_parse_reply (DBusMessage *rsp,
int arg_type, ...);
297 static DBusConnection *umdbus_connection = NULL;
298 static gboolean umdbus_service_name_acquired = FALSE;
305 member_info_introspect(
const member_info_t *
self, FILE *file)
307 LOG_REGISTER_CONTEXT;
309 switch( self->type ) {
310 case DBUS_MESSAGE_TYPE_METHOD_CALL:
313 fprintf(file,
" <method name=\"%s\">\n%s </method>\n", self->member, self->args);
315 fprintf(file,
" <method name=\"%s\"/>\n", self->member);
317 case DBUS_MESSAGE_TYPE_SIGNAL:
322 fprintf(file,
" <signal name=\"%s\">\n%s </signal>\n", self->member, self->args);
324 fprintf(file,
" <signal name=\"%s\"/>\n", self->member);
338 LOG_REGISTER_CONTEXT;
342 if( !
self || !member )
345 for(
size_t i = 0;
self->members[i].member; ++i ) {
346 if( strcmp(self->members[i].member, member) )
348 mem = &
self->members[i];
358 LOG_REGISTER_CONTEXT;
360 fprintf(file,
" <interface name=\"%s\">\n", self->interface);
361 for(
size_t i = 0;
self->members[i].member; ++i )
362 member_info_introspect(&self->members[i], file);
363 fprintf(file,
" </interface>\n");
371 object_info_get_interface(
const object_info_t *
self,
const char *interface)
373 LOG_REGISTER_CONTEXT;
377 if( !
self || !interface )
380 for(
size_t i = 0;
self->interfaces[i]; ++i ) {
381 if( strcmp(self->interfaces[i]->interface, interface) )
383 ifc =
self->interfaces[i];
391 object_info_introspect(
const object_info_t *
self, FILE *file,
const char *interface)
393 LOG_REGISTER_CONTEXT;
398 static const char dtd[] =
399 "<!DOCTYPE node PUBLIC\n"
400 " \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
401 " \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n";
403 fprintf(file,
"%s\n", dtd);
405 fprintf(file,
"<node name=\"%s\">\n", self->object);
406 for(
size_t i = 0;
self->interfaces[i]; ++i ) {
408 if( interface && strcmp(self->interfaces[i]->interface, interface) )
410 interface_info_introspect(self->interfaces[i], file);
416 const char *parent =
self->object;
417 if( !strcmp(parent,
"/") )
419 size_t n = strlen(parent);
421 const char *child = obj->object;
422 if( strncmp(parent, child, n) )
424 if( child[n] !=
'/' )
427 if( strchr(child,
'/' ) )
429 fprintf(file,
" <node name=\"%s\"/>\n", child);
432 fprintf(file,
"</node>\n");
438 object_info_get_introspect_xml(
const object_info_t *
self,
const char *interface)
440 LOG_REGISTER_CONTEXT;
446 FILE *file = open_memstream(&text, &size);
447 object_info_introspect(
self, file, interface);
461 LOG_REGISTER_CONTEXT;
463 char *text = object_info_get_introspect_xml(context->
object_info, 0);
464 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
465 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
472 introspectable_introspect_cb,
473 " <arg name=\"xml\" type=\"s\" direction=\"out\"/>\n"),
478 .
interface =
"org.freedesktop.DBus.Introspectable",
479 .members = introspectable_members
494 " <arg direction=\"out\" name=\"machine_uuid\" type=\"s\"/>\n"),
499 .
interface =
"org.freedesktop.DBus.Peer",
500 .members = peer_members
516 LOG_REGISTER_CONTEXT;
518 const char *mode = control_get_external_mode();
522 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
523 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID);
531 LOG_REGISTER_CONTEXT;
533 const char *mode = control_get_target_mode();
534 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
535 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID);
543 LOG_REGISTER_CONTEXT;
545 const char *mode = control_get_target_mode();
546 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
547 umdbus_append_mode_details(context->
rsp, mode);
557 LOG_REGISTER_CONTEXT;
559 const char *mode = control_get_external_mode();
561 DBusError err = DBUS_ERROR_INIT;
562 uid_t uid = umdbus_get_sender_uid(context->
sender);
564 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID) ) {
565 log_err(
"parse error: %s: %s", err.name, err.message);
566 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
568 else if( !usbmoded_is_mode_permitted(use, uid) ) {
570 log_warning(
"Mode '%s' is not allowed for uid %d", use, uid);
571 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_ACCESS_DENIED, context->
member);
575 log_warning(
"Mode '%s' requested while not connected to pc", use);
579 log_warning(
"Unknown mode '%s' requested", use);
583 log_warning(
"Mode '%s' requested while busy", use);
587 log_warning(
"Mode '%s' was rejected", use);
591 log_debug(
"Mode '%s' requested", use);
594 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
595 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID);
600 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_FAILED, context->
member);
602 dbus_error_free(&err);
614 LOG_REGISTER_CONTEXT;
617 DBusError err = DBUS_ERROR_INIT;
618 uid_t uid = umdbus_get_sender_uid(context->
sender);
620 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID) ) {
621 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
625 int ret = config_set_mode_setting(config, uid);
626 if( SET_CONFIG_OK(ret) ) {
627 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
628 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID);
631 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, config);
634 dbus_error_free(&err);
642 LOG_REGISTER_CONTEXT;
644 uid_t uid = umdbus_get_sender_uid(context->
sender);
645 char *config = config_get_mode_setting(uid);
647 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
648 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID);
661 LOG_REGISTER_CONTEXT;
665 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
666 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &mode_list, DBUS_TYPE_INVALID);
679 LOG_REGISTER_CONTEXT;
683 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
684 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &mode_list, DBUS_TYPE_INVALID);
693 LOG_REGISTER_CONTEXT;
695 uid_t uid = umdbus_get_sender_uid(context->
sender);
698 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
699 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &mode_list, DBUS_TYPE_INVALID);
712 LOG_REGISTER_CONTEXT;
715 DBusError err = DBUS_ERROR_INIT;
717 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID) ) {
718 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
720 #ifdef SAILFISH_ACCESS_CONTROL
722 else if( !sailfish_access_control_hasgroup(umdbus_get_sender_uid(context->
sender),
"sailfish-system") ) {
723 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_ACCESS_DENIED, context->
member);
728 int ret = config_set_hide_mode_setting(config);
729 if( SET_CONFIG_OK(ret) ) {
730 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
731 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID);
734 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, config);
737 dbus_error_free(&err);
745 LOG_REGISTER_CONTEXT;
748 DBusError err = DBUS_ERROR_INIT;
750 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID) ) {
751 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
753 #ifdef SAILFISH_ACCESS_CONTROL
755 else if( !sailfish_access_control_hasgroup(umdbus_get_sender_uid(context->
sender),
"sailfish-system") ) {
756 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_ACCESS_DENIED, context->
member);
761 int ret = config_set_unhide_mode_setting(config);
762 if( SET_CONFIG_OK(ret) ) {
763 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
764 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID);
767 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, config);
770 dbus_error_free(&err);
778 LOG_REGISTER_CONTEXT;
780 char *config = config_get_hidden_modes();
782 config = g_strdup(
"");
783 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
784 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID);
797 LOG_REGISTER_CONTEXT;
799 gchar *mode_list = config_get_mode_whitelist();
802 mode_list = g_strdup(
"");
804 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
805 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &mode_list, DBUS_TYPE_INVALID);
814 LOG_REGISTER_CONTEXT;
816 const char *whitelist = 0;
817 DBusError err = DBUS_ERROR_INIT;
819 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &whitelist, DBUS_TYPE_INVALID) ) {
820 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
823 int ret = config_set_mode_whitelist(whitelist);
824 if( SET_CONFIG_OK(ret) ) {
825 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
826 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &whitelist, DBUS_TYPE_INVALID);
829 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, whitelist);
831 dbus_error_free(&err);
839 LOG_REGISTER_CONTEXT;
841 dbus_uint32_t uid = 0;
842 DBusError err = DBUS_ERROR_INIT;
844 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID) ) {
845 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
849 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
850 else if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
851 dbus_message_append_args(context->
rsp, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID);
853 dbus_error_free(&err);
861 LOG_REGISTER_CONTEXT;
863 const char *mode = 0;
864 dbus_bool_t enabled = FALSE;
865 DBusError err = DBUS_ERROR_INIT;
867 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &mode, DBUS_TYPE_BOOLEAN, &enabled, DBUS_TYPE_INVALID) )
868 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
870 int ret = config_set_mode_in_whitelist(mode, enabled);
871 if( SET_CONFIG_OK(ret) )
872 context->
rsp = dbus_message_new_method_return(context->
msg);
874 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, mode);
876 dbus_error_free(&err);
888 LOG_REGISTER_CONTEXT;
892 DBusError err = DBUS_ERROR_INIT;
894 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_STRING, &setting, DBUS_TYPE_INVALID) ) {
895 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
899 int ret = config_set_network_setting(config, setting);
900 if( SET_CONFIG_OK(ret) ) {
901 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
902 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &config, DBUS_TYPE_STRING, &setting, DBUS_TYPE_INVALID);
906 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, config);
909 dbus_error_free(&err);
917 LOG_REGISTER_CONTEXT;
921 DBusError err = DBUS_ERROR_INIT;
923 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID) ) {
924 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
927 setting = config_get_network_setting(config);
929 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
930 dbus_message_append_args(context->
rsp, DBUS_TYPE_STRING, &config, DBUS_TYPE_STRING, &setting, DBUS_TYPE_INVALID);
934 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, config);
937 dbus_error_free(&err);
949 LOG_REGISTER_CONTEXT;
951 usbmoded_set_rescue_mode(
false);
952 log_debug(
"Rescue mode off\n ");
953 context->
rsp = dbus_message_new_method_return(context->
msg);
959 usb_moded_state_request_cb,
960 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
962 usb_moded_target_state_get_cb,
963 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
965 usb_moded_target_config_get_cb,
966 " <arg name=\"config\" type=\"a{sv}\" direction=\"out\"/>\n"
967 " <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QVariantMap\"/>\n"),
969 usb_moded_state_set_cb,
970 " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
971 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
973 usb_moded_config_set_cb,
974 " <arg name=\"config\" type=\"s\" direction=\"in\"/>\n"
975 " <arg name=\"config\" type=\"s\" direction=\"out\"/>\n"),
977 usb_moded_config_get_cb,
978 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
980 usb_moded_mode_list_cb,
981 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
983 usb_moded_available_modes_get_cb,
984 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
986 usb_moded_available_modes_for_user_cb,
987 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
989 usb_moded_mode_hide_cb,
990 " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
991 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
993 usb_moded_mode_unhide_cb,
994 " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
995 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
997 usb_moded_hidden_get_cb,
998 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
1000 usb_moded_whitelisted_modes_get_cb,
1001 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
1003 usb_moded_whitelisted_modes_set_cb,
1004 " <arg name=\"modes\" type=\"s\" direction=\"in\"/>\n"),
1006 usb_moded_whitelisted_set_cb,
1007 " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
1008 " <arg name=\"whitelisted\" type=\"b\" direction=\"in\"/>\n"),
1010 usb_moded_network_set_cb,
1011 " <arg name=\"key\" type=\"s\" direction=\"in\"/>\n"
1012 " <arg name=\"value\" type=\"s\" direction=\"in\"/>\n"
1013 " <arg name=\"key\" type=\"s\" direction=\"out\"/>\n"
1014 " <arg name=\"value\" type=\"s\" direction=\"out\"/>\n"),
1016 usb_moded_network_get_cb,
1017 " <arg name=\"key\" type=\"s\" direction=\"in\"/>\n"
1018 " <arg name=\"key\" type=\"s\" direction=\"out\"/>\n"
1019 " <arg name=\"value\" type=\"s\" direction=\"out\"/>\n"),
1021 usb_moded_rescue_off_cb,
1024 usb_moded_user_config_clear_cb,
1025 " <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"),
1027 " <arg name=\"mode_or_event\" type=\"s\"/>\n"),
1028 ADD_SIGNAL(USB_MODE_CURRENT_STATE_SIGNAL_NAME,
1029 " <arg name=\"mode\" type=\"s\"/>\n"),
1030 ADD_SIGNAL(USB_MODE_TARGET_STATE_SIGNAL_NAME,
1031 " <arg name=\"mode\" type=\"s\"/>\n"),
1032 ADD_SIGNAL(USB_MODE_TARGET_CONFIG_SIGNAL_NAME,
1033 " <arg name=\"config\" type=\"a{sv}\"/>\n"
1034 " <annotation name=\"org.qtproject.QtDBus.QtTypeName.In0\" value=\"QVariantMap\"/>\n"),
1036 " <arg name=\"event\" type=\"s\"/>\n"),
1038 " <arg name=\"section\" type=\"s\"/>\n"
1039 " <arg name=\"key\" type=\"s\"/>\n"
1040 " <arg name=\"value\" type=\"s\"/>\n"),
1041 ADD_SIGNAL(USB_MODE_SUPPORTED_MODES_SIGNAL_NAME,
1042 " <arg name=\"modes\" type=\"s\"/>\n"),
1043 ADD_SIGNAL(USB_MODE_AVAILABLE_MODES_SIGNAL_NAME,
1044 " <arg name=\"modes\" type=\"s\"/>\n"),
1045 ADD_SIGNAL(USB_MODE_HIDDEN_MODES_SIGNAL_NAME,
1046 " <arg name=\"modes\" type=\"s\"/>\n"),
1047 ADD_SIGNAL(USB_MODE_WHITELISTED_MODES_SIGNAL_NAME,
1048 " <arg name=\"modes\" type=\"s\"/>\n"),
1050 " <arg name=\"error\" type=\"s\"/>\n"),
1056 .members = usb_moded_members
1066 &introspectable_interface,
1074 &introspectable_interface,
1076 &usb_moded_interface,
1089 .interfaces = standard_interfaces,
1093 .interfaces = standard_interfaces,
1096 .object =
"/com/meego",
1097 .interfaces = standard_interfaces,
1100 .object = USB_MODE_OBJECT,
1101 .interfaces = usb_moded_interfaces,
1111 umdbus_get_object_info(
const char *
object)
1113 LOG_REGISTER_CONTEXT;
1120 for(
size_t i = 0; usb_moded_objects[i].
object; ++i ) {
1121 if( !strcmp(usb_moded_objects[i].
object,
object) ) {
1122 obj = &usb_moded_objects[i];
1138 LOG_REGISTER_CONTEXT;
1140 const object_info_t *object_info = umdbus_get_object_info(USB_MODE_OBJECT);
1141 char *xml = object_info_get_introspect_xml(object_info, USB_MODE_INTERFACE);
1142 fprintf(stdout,
"%s", xml ?:
"\n");
1153 LOG_REGISTER_CONTEXT;
1155 static const char dtd[] =
1156 "<!DOCTYPE busconfig PUBLIC\n"
1157 " \"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN\"\n"
1158 " \"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd\">\n";
1160 fprintf(stdout,
"%s\n", dtd);
1161 fprintf(stdout,
"<busconfig>\n");
1164 " <policy user=\"root\">\n"
1167 " send_interface=\"" USB_MODE_INTERFACE
"\"/>\n"
1171 " <policy context=\"default\">\n"
1174 " send_interface=\"" USB_MODE_INTERFACE
"\"/>\n"
1176 " send_interface=\"org.freedesktop.DBus.Introspectable\"/>\n");
1179 if( mem->
type != DBUS_MESSAGE_TYPE_METHOD_CALL )
1183 " send_interface=\"" USB_MODE_INTERFACE
"\"\n"
1184 " send_member=\"%s\"/>\n",
1187 fprintf(stdout,
" </policy>\n");
1188 fprintf(stdout,
"</busconfig>\n");
1196 LOG_REGISTER_CONTEXT;
1198 DBusMessage* msg = 0;
1200 if( !section || !key || !value ) {
1201 log_err(
"config notification with NULL %s",
1202 !section ?
"section" : !key ?
"key" : value);
1206 if( !umdbus_service_name_acquired ) {
1207 log_err(
"config notification without service: [%s] %s=%s",
1208 section, key, value);
1212 if( !umdbus_connection ) {
1213 log_err(
"config notification without connection: [%s] %s=%s",
1214 section, key, value);
1218 log_debug(
"broadcast signal %s(%s, %s, %s)\n", USB_MODE_CONFIG_SIGNAL_NAME, section, key, value);
1220 msg = dbus_message_new_signal(USB_MODE_OBJECT, USB_MODE_INTERFACE, USB_MODE_CONFIG_SIGNAL_NAME);
1224 dbus_message_append_args(msg, DBUS_TYPE_STRING, §ion,
1225 DBUS_TYPE_STRING, &key,
1226 DBUS_TYPE_STRING, &value,
1228 dbus_connection_send(umdbus_connection, msg, NULL);
1232 dbus_message_unref(msg);
1235 static DBusHandlerResult umdbus_msg_handler(DBusConnection *
const connection, DBusMessage *
const msg, gpointer
const user_data)
1239 LOG_REGISTER_CONTEXT;
1241 DBusHandlerResult status = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1246 switch( (context.
type = dbus_message_get_type(msg)) ) {
1247 case DBUS_MESSAGE_TYPE_SIGNAL:
1248 case DBUS_MESSAGE_TYPE_METHOD_CALL:
1255 if( !(context.
sender = dbus_message_get_sender(msg)) )
1258 if( !(context.
object = dbus_message_get_path(msg)) )
1261 if( !(context.
interface = dbus_message_get_interface(msg)) )
1264 if( !(context.
member = dbus_message_get_member(msg)) )
1267 log_debug(
"DBUS %s %s.%s from %s",
1268 dbus_message_type_to_string(context.
type),
1272 if( context.
type == DBUS_MESSAGE_TYPE_SIGNAL ) {
1273 if( !strcmp(context.
interface, INIT_DONE_INTERFACE) && !strcmp(context.
member, INIT_DONE_SIGNAL) ) {
1292 context.
rsp = dbus_message_new_error_printf(context.
msg,
1293 DBUS_ERROR_UNKNOWN_OBJECT,
1294 "Object '%s' does not exist",
1298 context.
rsp = dbus_message_new_error_printf(context.
msg,
1299 DBUS_ERROR_UNKNOWN_INTERFACE,
1300 "Interface '%s' does not exist",
1304 context.
rsp = dbus_message_new_error_printf(context.
msg,
1305 DBUS_ERROR_UNKNOWN_METHOD,
1306 "Method '%s.%s' does not exist",
1313 status = DBUS_HANDLER_RESULT_HANDLED;
1314 if( !dbus_message_get_no_reply(context.
msg) ) {
1315 if( !dbus_connection_send(connection, context.
rsp, 0) )
1316 log_debug(
"Failed sending reply. Out Of Memory!\n");
1318 dbus_message_unref(context.
rsp);
1324 DBusConnection *umdbus_get_connection(
void)
1326 LOG_REGISTER_CONTEXT;
1328 DBusConnection *connection = 0;
1329 if( umdbus_connection )
1330 connection = dbus_connection_ref(umdbus_connection);
1332 log_err(
"something asked for connection ref while unconnected");
1343 LOG_REGISTER_CONTEXT;
1345 gboolean status = FALSE;
1346 DBusError error = DBUS_ERROR_INIT;
1349 if ((umdbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) == NULL)
1351 log_debug(
"Failed to open connection to system message bus; %s\n", error.message);
1356 if (!dbus_connection_add_filter(umdbus_connection, umdbus_msg_handler, NULL, NULL))
1360 dbus_bus_add_match(umdbus_connection, INIT_DONE_MATCH, 0);
1366 dbus_gmain_set_up_connection(umdbus_connection, NULL);
1372 dbus_error_free(&error);
1383 LOG_REGISTER_CONTEXT;
1385 gboolean status = FALSE;
1386 DBusError error = DBUS_ERROR_INIT;
1389 if( !umdbus_connection ) {
1394 ret = dbus_bus_request_name(umdbus_connection,
USB_MODE_SERVICE, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1395 if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
1397 log_debug(
"failed claiming dbus name\n");
1398 if( dbus_error_is_set(&error) )
1399 log_debug(
"DBUS ERROR: %s, %s", error.name, error.message);
1403 umdbus_service_name_acquired = TRUE;
1408 dbus_error_free(&error);
1414 static void umdbus_cleanup_service(
void)
1416 LOG_REGISTER_CONTEXT;
1418 if( !umdbus_service_name_acquired )
1421 umdbus_service_name_acquired = FALSE;
1424 if( umdbus_connection &&
1425 dbus_connection_get_is_connected(umdbus_connection) )
1440 LOG_REGISTER_CONTEXT;
1443 if (umdbus_connection != NULL)
1445 umdbus_cleanup_service();
1447 dbus_connection_remove_filter(umdbus_connection, umdbus_msg_handler, NULL);
1449 dbus_connection_unref(umdbus_connection),
1450 umdbus_connection = NULL;
1461 umdbus_new_signal(
const char *signal_name)
1463 LOG_REGISTER_CONTEXT;
1465 DBusMessage *msg = 0;
1467 if( !umdbus_connection )
1469 log_err(
"sending signal %s without dbus connection", signal_name);
1472 if( !umdbus_service_name_acquired )
1474 log_err(
"sending signal %s before acquiring name", signal_name);
1478 msg = dbus_message_new_signal(USB_MODE_OBJECT, USB_MODE_INTERFACE,
1482 log_err(
"allocating signal %s failed", signal_name);
1499 umdbus_send_signal_ex(
const char *signal_name,
const char *content)
1501 LOG_REGISTER_CONTEXT;
1504 DBusMessage* msg = 0;
1511 log_debug(
"broadcast signal %s(%s)", signal_name, content);
1513 if( !(msg = umdbus_new_signal(signal_name)) )
1517 if( !dbus_message_append_args(msg,
1518 DBUS_TYPE_STRING, &content,
1519 DBUS_TYPE_INVALID) )
1521 log_err(
"appending arguments to signal %s failed", signal_name);
1526 if( !dbus_connection_send(umdbus_connection, msg, 0) )
1528 log_err(
"sending signal %s failed", signal_name);
1536 dbus_message_unref(msg);
1548 static void umdbus_send_legacy_signal(
const char *state_ind)
1550 LOG_REGISTER_CONTEXT;
1561 LOG_REGISTER_CONTEXT;
1563 umdbus_send_signal_ex(USB_MODE_CURRENT_STATE_SIGNAL_NAME,
1565 umdbus_send_legacy_signal(state_ind);
1578 umdbus_append_basic_entry(DBusMessageIter *iter,
const char *key,
1579 int type,
const void *val)
1581 LOG_REGISTER_CONTEXT;
1584 const char *signature = 0;
1586 case DBUS_TYPE_INT32: signature = DBUS_TYPE_INT32_AS_STRING;
break;
1587 case DBUS_TYPE_STRING: signature = DBUS_TYPE_STRING_AS_STRING;
break;
1591 log_err(
"unhandled D-Bus type: %d", type);
1592 goto bailout_message;
1595 DBusMessageIter entry, variant;
1597 if( !dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
1599 goto bailout_message;
1601 if( !dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key) )
1604 if( !dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
1605 signature, &variant) )
1608 if( !dbus_message_iter_append_basic(&variant, type, val) )
1609 goto bailout_variant;
1611 if( !dbus_message_iter_close_container(&entry, &variant) )
1612 goto bailout_variant;
1614 if( !dbus_message_iter_close_container(iter, &entry) )
1620 dbus_message_iter_abandon_container(&entry, &variant);
1623 dbus_message_iter_abandon_container(iter, &entry);
1638 umdbus_append_int32_entry(DBusMessageIter *iter,
const char *key,
int val)
1640 LOG_REGISTER_CONTEXT;
1642 dbus_int32_t arg = val;
1643 return umdbus_append_basic_entry(iter, key, DBUS_TYPE_INT32, &arg);
1655 umdbus_append_string_entry(DBusMessageIter *iter,
const char *key,
1658 LOG_REGISTER_CONTEXT;
1662 return umdbus_append_basic_entry(iter, key, DBUS_TYPE_STRING, &val);
1673 umdbus_append_mode_details(DBusMessage *msg,
const char *mode_name)
1675 LOG_REGISTER_CONTEXT;
1679 DBusMessageIter body, dict;
1681 dbus_message_iter_init_append(msg, &body);
1683 if( !dbus_message_iter_open_container(&body,
1685 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1686 DBUS_TYPE_STRING_AS_STRING
1687 DBUS_TYPE_VARIANT_AS_STRING
1688 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1690 goto bailout_message;
1695 if( !umdbus_append_string_entry(&dict,
"mode_name", mode_name) )
1702 #define ADD_STR(name) \
1703 if( !umdbus_append_string_entry(&dict, #name, data ? data->name : 0) )\
1705 #define ADD_INT(name) \
1706 if( !umdbus_append_int32_entry(&dict, #name, data ? data->name : 0) )\
1712 ADD_STR(network_interface);
1714 ADD_INT(dhcp_server);
1716 ADD_STR(connman_tethering);
1721 ADD_INT(mass_storage);
1722 ADD_STR(mode_module);
1723 ADD_STR(sysfs_path);
1724 ADD_STR(sysfs_value);
1725 ADD_STR(sysfs_reset_value);
1726 ADD_STR(android_extra_sysfs_path);
1727 ADD_STR(android_extra_sysfs_value);
1728 ADD_STR(android_extra_sysfs_path2);
1729 ADD_STR(android_extra_sysfs_value2);
1730 ADD_STR(android_extra_sysfs_path3);
1731 ADD_STR(android_extra_sysfs_value3);
1732 ADD_STR(android_extra_sysfs_path4);
1733 ADD_STR(android_extra_sysfs_value4);
1735 ADD_STR(idVendorOverride);
1741 if( !dbus_message_iter_close_container(&body, &dict) )
1747 dbus_message_iter_abandon_container(&body, &dict);
1758 umdbus_send_mode_details_signal(
const char *mode_name)
1760 DBusMessage* msg = 0;
1762 if( !(msg = umdbus_new_signal(USB_MODE_TARGET_CONFIG_SIGNAL_NAME)) )
1765 if( !umdbus_append_mode_details(msg, mode_name) )
1768 dbus_connection_send(umdbus_connection, msg, 0);
1772 dbus_message_unref(msg);
1781 LOG_REGISTER_CONTEXT;
1792 umdbus_send_mode_details_signal(state_ind);
1794 umdbus_send_signal_ex(USB_MODE_TARGET_STATE_SIGNAL_NAME,
1804 LOG_REGISTER_CONTEXT;
1806 umdbus_send_signal_ex(USB_MODE_EVENT_SIGNAL_NAME,
1808 umdbus_send_legacy_signal(state_ind);
1820 LOG_REGISTER_CONTEXT;
1822 return umdbus_send_signal_ex(USB_MODE_ERROR_SIGNAL_NAME, error);
1834 LOG_REGISTER_CONTEXT;
1836 return umdbus_send_signal_ex(USB_MODE_SUPPORTED_MODES_SIGNAL_NAME, supported_modes);
1848 LOG_REGISTER_CONTEXT;
1850 return umdbus_send_signal_ex(USB_MODE_AVAILABLE_MODES_SIGNAL_NAME, available_modes);
1862 LOG_REGISTER_CONTEXT;
1864 return umdbus_send_signal_ex(USB_MODE_HIDDEN_MODES_SIGNAL_NAME, hidden_modes);
1875 LOG_REGISTER_CONTEXT;
1877 return umdbus_send_signal_ex(USB_MODE_WHITELISTED_MODES_SIGNAL_NAME, whitelist);
1885 static void umdbus_get_name_owner_cb(DBusPendingCall *pc,
void *aptr)
1887 LOG_REGISTER_CONTEXT;
1889 usb_moded_get_name_owner_fn cb = aptr;
1891 DBusMessage *rsp = 0;
1892 const char *dta = 0;
1893 DBusError err = DBUS_ERROR_INIT;
1895 if( !(rsp = dbus_pending_call_steal_reply(pc)) ) {
1896 log_err(
"did not get reply");
1900 if( dbus_set_error_from_message(&err, rsp) )
1902 if( strcmp(err.name, DBUS_ERROR_NAME_HAS_NO_OWNER) )
1903 log_err(
"error reply: %s: %s", err.name, err.message);
1907 if( !dbus_message_get_args(rsp, &err,
1908 DBUS_TYPE_STRING, &dta,
1909 DBUS_TYPE_INVALID) )
1911 if( strcmp(err.name, DBUS_ERROR_NAME_HAS_NO_OWNER) )
1912 log_err(
"parse error: %s: %s", err.name, err.message);
1921 if( rsp ) dbus_message_unref(rsp);
1923 dbus_error_free(&err);
1935 usb_moded_get_name_owner_fn cb,
1936 DBusPendingCall **ppc)
1938 LOG_REGISTER_CONTEXT;
1940 gboolean ack = FALSE;
1941 DBusMessage *req = 0;
1942 DBusPendingCall *pc = 0;
1944 if(!umdbus_connection)
1947 req = dbus_message_new_method_call(DBUS_INTERFACE_DBUS,
1949 DBUS_INTERFACE_DBUS,
1952 log_err(
"could not create method call message");
1956 if( !dbus_message_append_args(req,
1957 DBUS_TYPE_STRING, &name,
1958 DBUS_TYPE_INVALID) ) {
1959 log_err(
"could not add method call parameters");
1963 if( !dbus_connection_send_with_reply(umdbus_connection, req, &pc, -1) )
1969 if( !dbus_pending_call_set_notify(pc, umdbus_get_name_owner_cb, cb, 0) )
1979 if( pc ) dbus_pending_call_unref(pc);
1980 if( req ) dbus_message_unref(req);
1992 umdbus_get_sender_uid(
const char *name)
1994 LOG_REGISTER_CONTEXT;
1996 pid_t pid = PID_UNKNOWN;
1997 uid_t uid = UID_UNKNOWN;
1998 DBusMessage *req = 0;
1999 DBusMessage *rsp = 0;
2000 DBusError err = DBUS_ERROR_INIT;
2004 if(!umdbus_connection)
2007 req = dbus_message_new_method_call(DBUS_INTERFACE_DBUS,
2009 DBUS_INTERFACE_DBUS,
2012 log_err(
"could not create method call message");
2016 if( !dbus_message_append_args(req,
2017 DBUS_TYPE_STRING, &name,
2018 DBUS_TYPE_INVALID) ) {
2019 log_err(
"could not add method call parameters");
2024 rsp = dbus_connection_send_with_reply_and_block(umdbus_connection, req, -1, &err);
2026 if( !rsp && dbus_error_is_set(&err) ) {
2027 log_err(
"could not get sender pid for %s: %s: %s", name, err.name, err.message);
2031 if( !dbus_message_get_args(rsp, &err,
2032 DBUS_TYPE_UINT32, &pid,
2033 DBUS_TYPE_INVALID) ) {
2034 log_err(
"parse error: %s: %s", err.name, err.message);
2038 snprintf(path,
sizeof path,
"/proc/%d", (
int)pid);
2039 memset(&st, 0,
sizeof st);
2040 if( stat(path, &st) != -1 ) {
2046 if( req ) dbus_message_unref(req);
2047 if( rsp ) dbus_message_unref(rsp);
2049 dbus_error_free(&err);
2055 umdbus_arg_type_repr(
int type)
2057 const char *repr =
"UNKNOWN";
2059 case DBUS_TYPE_INVALID: repr =
"INVALID";
break;
2060 case DBUS_TYPE_BYTE: repr =
"BYTE";
break;
2061 case DBUS_TYPE_BOOLEAN: repr =
"BOOLEAN";
break;
2062 case DBUS_TYPE_INT16: repr =
"INT16";
break;
2063 case DBUS_TYPE_UINT16: repr =
"UINT16";
break;
2064 case DBUS_TYPE_INT32: repr =
"INT32";
break;
2065 case DBUS_TYPE_UINT32: repr =
"UINT32";
break;
2066 case DBUS_TYPE_INT64: repr =
"INT64";
break;
2067 case DBUS_TYPE_UINT64: repr =
"UINT64";
break;
2068 case DBUS_TYPE_DOUBLE: repr =
"DOUBLE";
break;
2069 case DBUS_TYPE_STRING: repr =
"STRING";
break;
2070 case DBUS_TYPE_OBJECT_PATH: repr =
"OBJECT_PATH";
break;
2071 case DBUS_TYPE_SIGNATURE: repr =
"SIGNATURE";
break;
2072 case DBUS_TYPE_UNIX_FD: repr =
"UNIX_FD";
break;
2073 case DBUS_TYPE_ARRAY: repr =
"ARRAY";
break;
2074 case DBUS_TYPE_VARIANT: repr =
"VARIANT";
break;
2075 case DBUS_TYPE_STRUCT: repr =
"STRUCT";
break;
2076 case DBUS_TYPE_DICT_ENTRY: repr =
"DICT_ENTRY";
break;
2083 umdbus_arg_type_signature(
int type)
2085 const char *sign = 0;
2087 case DBUS_TYPE_INVALID: sign = DBUS_TYPE_INVALID_AS_STRING;
break;
2088 case DBUS_TYPE_BYTE: sign = DBUS_TYPE_BYTE_AS_STRING;
break;
2089 case DBUS_TYPE_BOOLEAN: sign = DBUS_TYPE_BOOLEAN_AS_STRING;
break;
2090 case DBUS_TYPE_INT16: sign = DBUS_TYPE_INT16_AS_STRING;
break;
2091 case DBUS_TYPE_UINT16: sign = DBUS_TYPE_UINT16_AS_STRING;
break;
2092 case DBUS_TYPE_INT32: sign = DBUS_TYPE_INT32_AS_STRING;
break;
2093 case DBUS_TYPE_UINT32: sign = DBUS_TYPE_UINT32_AS_STRING;
break;
2094 case DBUS_TYPE_INT64: sign = DBUS_TYPE_INT64_AS_STRING;
break;
2095 case DBUS_TYPE_UINT64: sign = DBUS_TYPE_UINT64_AS_STRING;
break;
2096 case DBUS_TYPE_DOUBLE: sign = DBUS_TYPE_DOUBLE_AS_STRING;
break;
2097 case DBUS_TYPE_STRING: sign = DBUS_TYPE_STRING_AS_STRING;
break;
2098 case DBUS_TYPE_OBJECT_PATH: sign = DBUS_TYPE_OBJECT_PATH_AS_STRING;
break;
2099 case DBUS_TYPE_SIGNATURE: sign = DBUS_TYPE_SIGNATURE_AS_STRING;
break;
2100 case DBUS_TYPE_UNIX_FD: sign = DBUS_TYPE_UNIX_FD_AS_STRING;
break;
2101 case DBUS_TYPE_ARRAY: sign = DBUS_TYPE_ARRAY_AS_STRING;
break;
2102 case DBUS_TYPE_VARIANT: sign = DBUS_TYPE_VARIANT_AS_STRING;
break;
2103 case DBUS_TYPE_STRUCT: sign = DBUS_TYPE_STRUCT_AS_STRING;
break;
2104 case DBUS_TYPE_DICT_ENTRY: sign = DBUS_TYPE_DICT_ENTRY_AS_STRING;
break;
2111 umdbus_msg_type_repr(
int type)
2113 return dbus_message_type_to_string(type);
2117 umdbus_parser_init(DBusMessageIter *iter, DBusMessage *msg)
2119 return iter && msg && dbus_message_iter_init(msg, iter);
2123 umdbus_parser_at_type(DBusMessageIter *iter)
2125 return iter ? dbus_message_iter_get_arg_type(iter) : DBUS_TYPE_INVALID;
2129 umdbus_parser_at_end(DBusMessageIter *iter)
2131 return umdbus_parser_at_type(iter) == DBUS_TYPE_INVALID;
2135 umdbus_parser_require_type(DBusMessageIter *iter,
int type,
bool strict)
2137 int have = umdbus_parser_at_type(iter);
2142 if( strict || have != DBUS_TYPE_INVALID )
2143 log_warning(
"expected %s, got %s",
2144 umdbus_arg_type_repr(type),
2145 umdbus_arg_type_repr(have));
2150 umdbus_parser_get_bool(DBusMessageIter *iter,
bool *pval)
2152 dbus_bool_t val = 0;
2153 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_BOOLEAN,
true);
2155 dbus_message_iter_get_basic(iter, &val);
2156 dbus_message_iter_next(iter);
2158 return *pval = val, ack;
2162 umdbus_parser_get_int(DBusMessageIter *iter,
int *pval)
2164 dbus_int32_t val = 0;
2165 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_INT32,
true);
2167 dbus_message_iter_get_basic(iter, &val);
2168 dbus_message_iter_next(iter);
2170 return *pval = (int)val, ack;
2174 umdbus_parser_get_string(DBusMessageIter *iter,
const char **pval)
2176 const char *val = 0;
2177 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_STRING,
true);
2179 dbus_message_iter_get_basic(iter, &val);
2180 dbus_message_iter_next(iter);
2182 return *pval = val, ack;
2186 umdbus_parser_get_object(DBusMessageIter *iter,
const char **pval)
2188 const char *val = 0;
2189 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_OBJECT_PATH,
true);
2191 dbus_message_iter_get_basic(iter, &val);
2192 dbus_message_iter_next(iter);
2194 return *pval = val, ack;
2198 umdbus_parser_get_variant(DBusMessageIter *iter, DBusMessageIter *val)
2200 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_VARIANT,
true);
2202 dbus_message_iter_recurse(iter, val);
2203 dbus_message_iter_next(iter);
2209 umdbus_parser_get_array(DBusMessageIter *iter, DBusMessageIter *val)
2211 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_ARRAY,
true);
2213 dbus_message_iter_recurse(iter, val);
2214 dbus_message_iter_next(iter);
2220 umdbus_parser_get_struct(DBusMessageIter *iter, DBusMessageIter *val)
2222 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_STRUCT,
false);
2224 dbus_message_iter_recurse(iter, val);
2225 dbus_message_iter_next(iter);
2231 umdbus_parser_get_entry(DBusMessageIter *iter, DBusMessageIter *val)
2233 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_DICT_ENTRY,
false);
2235 dbus_message_iter_recurse(iter, val);
2236 dbus_message_iter_next(iter);
2242 umdbus_append_init(DBusMessageIter *iter, DBusMessage *msg)
2244 bool ack = iter && msg && (dbus_message_iter_init_append(msg, iter),
true);
2249 umdbus_open_container(DBusMessageIter *iter, DBusMessageIter *sub,
int type,
const char *sign)
2251 bool ack = dbus_message_iter_open_container(iter, type, sign, sub);
2257 log_warning(
"failed to open %s container with signature: %s",
2258 umdbus_arg_type_repr(type), sign ?:
"");
2264 umdbus_close_container(DBusMessageIter *iter, DBusMessageIter *sub,
bool success)
2267 if( !(success = dbus_message_iter_close_container(iter, sub)) ) {
2268 log_warning(
"failed to close container");
2272 log_warning(
"abandoning container");
2273 dbus_message_iter_abandon_container(iter, sub);
2279 umdbus_append_basic_value(DBusMessageIter *iter,
int type,
const DBusBasicValue *val)
2281 if(
log_p(LOG_DEBUG) ) {
2283 const char *repr = buff;
2285 case DBUS_TYPE_BYTE:
2286 snprintf(buff,
sizeof buff,
"%u", val->byt);
2288 case DBUS_TYPE_BOOLEAN:
2289 repr = val->bool_val ?
"true" :
"false";
2291 case DBUS_TYPE_INT16:
2292 snprintf(buff,
sizeof buff,
"%d", val->i16);
2294 case DBUS_TYPE_UINT16:
2295 snprintf(buff,
sizeof buff,
"%u", val->u16);
2297 case DBUS_TYPE_INT32:
2298 snprintf(buff,
sizeof buff,
"%d", val->i32);
2300 case DBUS_TYPE_UINT32:
2301 snprintf(buff,
sizeof buff,
"%u", val->u32);
2303 case DBUS_TYPE_INT64:
2304 snprintf(buff,
sizeof buff,
"%lld", (
long long)val->i64);
2306 case DBUS_TYPE_UINT64:
2307 snprintf(buff,
sizeof buff,
"%llu", (
unsigned long long)val->u64);
2309 case DBUS_TYPE_DOUBLE:
2310 snprintf(buff,
sizeof buff,
"%g", val->dbl);
2312 case DBUS_TYPE_STRING:
2313 case DBUS_TYPE_OBJECT_PATH:
2314 case DBUS_TYPE_SIGNATURE:
2315 repr = (
const char *)val->str;
2317 case DBUS_TYPE_UNIX_FD:
2318 snprintf(buff,
sizeof buff,
"%d", val->fd);
2321 case DBUS_TYPE_INVALID:
2322 case DBUS_TYPE_ARRAY:
2323 case DBUS_TYPE_VARIANT:
2324 case DBUS_TYPE_STRUCT:
2325 case DBUS_TYPE_DICT_ENTRY:
2329 log_debug(
"append %s value %s", umdbus_arg_type_repr(type), repr);
2332 if (dbus_message_iter_append_basic(iter, type, val))
2335 log_warning(
"failed to append %s argument", umdbus_arg_type_repr(type));
2340 umdbus_append_basic_variant(DBusMessageIter *iter,
int type,
const DBusBasicValue *val)
2343 const char *sign = 0;
2345 log_debug(
"append %s variant", umdbus_arg_type_repr(type));
2347 if( !dbus_type_is_basic(type) )
2350 if( !(sign = umdbus_arg_type_signature(type)) )
2353 DBusMessageIter var;
2355 if( umdbus_open_container(iter, &var, DBUS_TYPE_VARIANT, sign) ) {
2356 ack = umdbus_append_basic_value(&var, DBUS_TYPE_BOOLEAN, val);
2357 ack = umdbus_close_container(iter, &var, ack);
2363 log_warning(
"failed to append %s variant", umdbus_arg_type_repr(type));
2369 umdbus_append_bool(DBusMessageIter *iter,
bool val)
2371 DBusBasicValue dta = { .bool_val = (dbus_bool_t)val };
2372 return umdbus_append_basic_value(iter, DBUS_TYPE_BOOLEAN, &dta);
2376 umdbus_append_int(DBusMessageIter *iter,
int val)
2378 DBusBasicValue dta = { .i32 = (dbus_int32_t)val };
2379 return umdbus_append_basic_value(iter, DBUS_TYPE_INT32, &dta);
2383 umdbus_append_string(DBusMessageIter *iter,
const char *val)
2385 DBusBasicValue dta = { .str = (
char *)val };
2386 return umdbus_append_basic_value(iter, DBUS_TYPE_STRING, &dta);
2390 umdbus_append_bool_variant(DBusMessageIter *iter,
bool val)
2392 DBusBasicValue dta = { .bool_val = val };
2393 return umdbus_append_basic_variant(iter, DBUS_TYPE_BOOLEAN, &dta);
2397 umdbus_append_int_variant(DBusMessageIter *iter,
int val)
2399 DBusBasicValue dta = { .i32 = val };
2400 return umdbus_append_basic_variant(iter, DBUS_TYPE_INT32, &dta);
2404 umdbus_append_string_variant(DBusMessageIter *iter,
const char *val)
2406 DBusBasicValue dta = { .str = (
char *)val };
2407 return umdbus_append_basic_variant(iter, DBUS_TYPE_STRING, &dta);
2411 umdbus_append_args_va(DBusMessageIter *iter,
int type, va_list va)
2415 DBusBasicValue *arg;
2417 while( type != DBUS_TYPE_INVALID ) {
2419 case DBUS_TYPE_VARIANT:
2420 type = va_arg(va,
int);
2421 if( !dbus_type_is_basic(type) ) {
2422 log_err(
"variant type %s is not supported",
2423 umdbus_arg_type_repr(type));
2426 arg = va_arg(va, DBusBasicValue *);
2427 if( !umdbus_append_basic_variant(iter, type, arg) )
2432 case DBUS_TYPE_ARRAY:
2433 case DBUS_TYPE_STRUCT:
2436 if( !dbus_type_is_basic(type) ) {
2437 log_err(
"value type %s is not supported",
2438 umdbus_arg_type_repr(type));
2441 arg = va_arg(va, DBusBasicValue *);
2442 if( !umdbus_append_basic_value(iter, type, arg) )
2446 type = va_arg(va,
int);
2454 umdbus_append_args(DBusMessageIter *iter,
int arg_type, ...)
2457 va_start(va, arg_type);
2458 bool ack = umdbus_append_args_va(iter, arg_type, va);
2464 umdbus_blocking_call(DBusConnection *con,
2472 DBusMessage *rsp = 0;
2473 DBusMessage *req = 0;
2476 va_start(va, arg_type);
2478 if( !(req = dbus_message_new_method_call(dst, obj, iface, meth)) )
2481 DBusMessageIter body;
2482 if( !umdbus_append_init(&body, req) )
2489 if( !umdbus_append_args_va(&body, arg_type, va) )
2492 if( !(rsp = dbus_connection_send_with_reply_and_block(con, req, -1, err)) ) {
2493 log_warning(
"no reply to %s.%s(): %s: %s",
2494 iface, meth, err->name, err->message);
2498 if( dbus_set_error_from_message(err, rsp) ) {
2499 log_warning(
"error reply to %s.%s(): %s: %s",
2500 iface, meth, err->name, err->message);
2501 dbus_message_unref(rsp), rsp = 0;
2505 log_debug(
"blocking %s.%s() call succeeded", iface, meth);
2509 dbus_message_unref(req);
2517 umdbus_parse_reply(DBusMessage *rsp,
int arg_type, ...)
2520 DBusError err = DBUS_ERROR_INIT;
2523 va_start(va, arg_type);
2532 if( !dbus_message_get_args_valist(rsp, &err, arg_type, va) ) {
2533 log_warning(
"parse error: %s: %s", err.name, err.message);
2540 dbus_error_free(&err);