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,\
182static void member_info_introspect(
const member_info_t *self, FILE *file);
189static void interface_info_introspect(
const interface_info_t *self, FILE *file);
196static void object_info_introspect (
const object_info_t *self, FILE *file,
const char *interface);
197static char *object_info_get_introspect_xml(
const object_info_t *self,
const char *interface);
217static void usb_moded_available_modes_for_user_cb(
umdbus_context_t *context);
233static const object_info_t *umdbus_get_object_info (
const char *
object);
237static DBusHandlerResult umdbus_msg_handler (DBusConnection *
const connection, DBusMessage *
const msg, gpointer
const user_data);
238DBusConnection *umdbus_get_connection (
void);
241static void umdbus_cleanup_service (
void);
243static DBusMessage *umdbus_new_signal (
const char *signal_name);
244static int umdbus_send_signal_ex (
const char *signal_name,
const char *content);
245static void umdbus_send_legacy_signal (
const char *state_ind);
247static bool umdbus_append_basic_entry (DBusMessageIter *iter,
const char *key,
int type,
const void *val);
248static bool umdbus_append_int32_entry (DBusMessageIter *iter,
const char *key,
int val);
249static bool umdbus_append_string_entry (DBusMessageIter *iter,
const char *key,
const char *val);
250static bool umdbus_append_mode_details (DBusMessage *msg,
const char *mode_name);
251static void umdbus_send_mode_details_signal (
const char *mode_name);
259static void umdbus_get_name_owner_cb (DBusPendingCall *pc,
void *aptr);
261static uid_t umdbus_get_sender_uid (
const char *name);
262const char *umdbus_arg_type_repr (
int type);
263const char *umdbus_arg_type_signature (
int type);
264const char *umdbus_msg_type_repr (
int type);
265bool umdbus_parser_init (DBusMessageIter *iter, DBusMessage *msg);
266int umdbus_parser_at_type (DBusMessageIter *iter);
267bool umdbus_parser_at_end (DBusMessageIter *iter);
268bool umdbus_parser_require_type (DBusMessageIter *iter,
int type,
bool strict);
269bool umdbus_parser_get_bool (DBusMessageIter *iter,
bool *pval);
270bool umdbus_parser_get_int (DBusMessageIter *iter,
int *pval);
271bool umdbus_parser_get_string (DBusMessageIter *iter,
const char **pval);
272bool umdbus_parser_get_object (DBusMessageIter *iter,
const char **pval);
273bool umdbus_parser_get_variant (DBusMessageIter *iter, DBusMessageIter *val);
274bool umdbus_parser_get_array (DBusMessageIter *iter, DBusMessageIter *val);
275bool umdbus_parser_get_struct (DBusMessageIter *iter, DBusMessageIter *val);
276bool umdbus_parser_get_entry (DBusMessageIter *iter, DBusMessageIter *val);
277bool umdbus_append_init (DBusMessageIter *iter, DBusMessage *msg);
278bool umdbus_open_container (DBusMessageIter *iter, DBusMessageIter *sub,
int type,
const char *sign);
279bool umdbus_close_container (DBusMessageIter *iter, DBusMessageIter *sub,
bool success);
280bool umdbus_append_basic_value (DBusMessageIter *iter,
int type,
const DBusBasicValue *val);
281bool umdbus_append_basic_variant (DBusMessageIter *iter,
int type,
const DBusBasicValue *val);
282bool umdbus_append_bool (DBusMessageIter *iter,
bool val);
283bool umdbus_append_int (DBusMessageIter *iter,
int val);
284bool umdbus_append_string (DBusMessageIter *iter,
const char *val);
285bool umdbus_append_bool_variant (DBusMessageIter *iter,
bool val);
286bool umdbus_append_int_variant (DBusMessageIter *iter,
int val);
287bool umdbus_append_string_variant (DBusMessageIter *iter,
const char *val);
288bool umdbus_append_args_va (DBusMessageIter *iter,
int type, va_list va);
289bool umdbus_append_args (DBusMessageIter *iter,
int arg_type, ...);
290DBusMessage *umdbus_blocking_call (DBusConnection *con,
const char *dst,
const char *obj,
const char *iface,
const char *meth, DBusError *err,
int arg_type, ...);
291bool umdbus_parse_reply (DBusMessage *rsp,
int arg_type, ...);
297static DBusConnection *umdbus_connection = NULL;
298static gboolean umdbus_service_name_acquired = FALSE;
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 )
358 LOG_REGISTER_CONTEXT;
360 fprintf(file,
" <interface name=\"%s\">\n", self->
interface);
362 member_info_introspect(&self->
members[i], file);
363 fprintf(file,
" </interface>\n");
371object_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 ) {
391object_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 ) {
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");
438object_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;
920 DBusError err = DBUS_ERROR_INIT;
922 if( !dbus_message_get_args(context->
msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID) ) {
923 context->
rsp = dbus_message_new_error(context->
msg, DBUS_ERROR_INVALID_ARGS, context->
member);
930 if( (context->
rsp = dbus_message_new_method_return(context->
msg)) )
931 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);
938 dbus_error_free(&err);
950 LOG_REGISTER_CONTEXT;
952 usbmoded_set_rescue_mode(
false);
953 log_debug(
"Rescue mode off\n ");
954 context->
rsp = dbus_message_new_method_return(context->
msg);
960 usb_moded_state_request_cb,
961 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
963 usb_moded_target_state_get_cb,
964 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
966 usb_moded_target_config_get_cb,
967 " <arg name=\"config\" type=\"a{sv}\" direction=\"out\"/>\n"
968 " <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QVariantMap\"/>\n"),
970 usb_moded_state_set_cb,
971 " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
972 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
974 usb_moded_config_set_cb,
975 " <arg name=\"config\" type=\"s\" direction=\"in\"/>\n"
976 " <arg name=\"config\" type=\"s\" direction=\"out\"/>\n"),
978 usb_moded_config_get_cb,
979 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
981 usb_moded_mode_list_cb,
982 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
984 usb_moded_available_modes_get_cb,
985 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
987 usb_moded_available_modes_for_user_cb,
988 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
990 usb_moded_mode_hide_cb,
991 " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
992 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
994 usb_moded_mode_unhide_cb,
995 " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
996 " <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"),
998 usb_moded_hidden_get_cb,
999 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
1001 usb_moded_whitelisted_modes_get_cb,
1002 " <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"),
1004 usb_moded_whitelisted_modes_set_cb,
1005 " <arg name=\"modes\" type=\"s\" direction=\"in\"/>\n"),
1007 usb_moded_whitelisted_set_cb,
1008 " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
1009 " <arg name=\"whitelisted\" type=\"b\" direction=\"in\"/>\n"),
1011 usb_moded_network_set_cb,
1012 " <arg name=\"key\" type=\"s\" direction=\"in\"/>\n"
1013 " <arg name=\"value\" type=\"s\" direction=\"in\"/>\n"
1014 " <arg name=\"key\" type=\"s\" direction=\"out\"/>\n"
1015 " <arg name=\"value\" type=\"s\" direction=\"out\"/>\n"),
1017 usb_moded_network_get_cb,
1018 " <arg name=\"key\" type=\"s\" direction=\"in\"/>\n"
1019 " <arg name=\"key\" type=\"s\" direction=\"out\"/>\n"
1020 " <arg name=\"value\" type=\"s\" direction=\"out\"/>\n"),
1022 usb_moded_rescue_off_cb,
1025 usb_moded_user_config_clear_cb,
1026 " <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"),
1028 " <arg name=\"mode_or_event\" type=\"s\"/>\n"),
1029 ADD_SIGNAL(USB_MODE_CURRENT_STATE_SIGNAL_NAME,
1030 " <arg name=\"mode\" type=\"s\"/>\n"),
1031 ADD_SIGNAL(USB_MODE_TARGET_STATE_SIGNAL_NAME,
1032 " <arg name=\"mode\" type=\"s\"/>\n"),
1033 ADD_SIGNAL(USB_MODE_TARGET_CONFIG_SIGNAL_NAME,
1034 " <arg name=\"config\" type=\"a{sv}\" direction=\"out\"/>\n"
1035 " <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QVariantMap\"/>\n"),
1037 " <arg name=\"event\" type=\"s\"/>\n"),
1039 " <arg name=\"section\" type=\"s\"/>\n"
1040 " <arg name=\"key\" type=\"s\"/>\n"
1041 " <arg name=\"value\" type=\"s\"/>\n"),
1042 ADD_SIGNAL(USB_MODE_SUPPORTED_MODES_SIGNAL_NAME,
1043 " <arg name=\"modes\" type=\"s\"/>\n"),
1044 ADD_SIGNAL(USB_MODE_AVAILABLE_MODES_SIGNAL_NAME,
1045 " <arg name=\"modes\" type=\"s\"/>\n"),
1046 ADD_SIGNAL(USB_MODE_HIDDEN_MODES_SIGNAL_NAME,
1047 " <arg name=\"modes\" type=\"s\"/>\n"),
1048 ADD_SIGNAL(USB_MODE_WHITELISTED_MODES_SIGNAL_NAME,
1049 " <arg name=\"modes\" type=\"s\"/>\n"),
1051 " <arg name=\"error\" type=\"s\"/>\n"),
1056 .interface = USB_MODE_INTERFACE,
1057 .members = usb_moded_members
1067 &introspectable_interface,
1075 &introspectable_interface,
1077 &usb_moded_interface,
1090 .interfaces = standard_interfaces,
1094 .interfaces = standard_interfaces,
1097 .object =
"/com/meego",
1098 .interfaces = standard_interfaces,
1101 .object = USB_MODE_OBJECT,
1102 .interfaces = usb_moded_interfaces,
1112umdbus_get_object_info(
const char *
object)
1114 LOG_REGISTER_CONTEXT;
1121 for(
size_t i = 0; usb_moded_objects[i].object; ++i ) {
1122 if( !strcmp(usb_moded_objects[i].
object,
object) ) {
1123 obj = &usb_moded_objects[i];
1139 LOG_REGISTER_CONTEXT;
1141 const object_info_t *object_info = umdbus_get_object_info(USB_MODE_OBJECT);
1142 char *xml = object_info_get_introspect_xml(object_info, USB_MODE_INTERFACE);
1143 fprintf(stdout,
"%s", xml ?:
"\n");
1154 LOG_REGISTER_CONTEXT;
1156 static const char dtd[] =
1157 "<!DOCTYPE busconfig PUBLIC\n"
1158 " \"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN\"\n"
1159 " \"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd\">\n";
1161 fprintf(stdout,
"%s\n", dtd);
1162 fprintf(stdout,
"<busconfig>\n");
1165 " <policy user=\"root\">\n"
1166 " <allow own=\"" USB_MODE_SERVICE
"\"/>\n"
1167 " <allow send_destination=\"" USB_MODE_SERVICE
"\"\n"
1168 " send_interface=\"" USB_MODE_INTERFACE
"\"/>\n"
1172 " <policy context=\"default\">\n"
1173 " <deny own=\"" USB_MODE_SERVICE
"\"/>\n"
1174 " <deny send_destination=\"" USB_MODE_SERVICE
"\"\n"
1175 " send_interface=\"" USB_MODE_INTERFACE
"\"/>\n"
1176 " <allow send_destination=\"" USB_MODE_SERVICE
"\"\n"
1177 " send_interface=\"org.freedesktop.DBus.Introspectable\"/>\n");
1180 if( mem->
type != DBUS_MESSAGE_TYPE_METHOD_CALL )
1183 " <allow send_destination=\"" USB_MODE_SERVICE
"\"\n"
1184 " send_interface=\"" USB_MODE_INTERFACE
"\"\n"
1185 " send_member=\"%s\"/>\n",
1188 fprintf(stdout,
" </policy>\n");
1189 fprintf(stdout,
"</busconfig>\n");
1197 LOG_REGISTER_CONTEXT;
1199 DBusMessage* msg = 0;
1201 if( !section || !key || !value ) {
1202 log_err(
"config notification with NULL %s",
1203 !section ?
"section" : !key ?
"key" : value);
1207 if( !umdbus_service_name_acquired ) {
1208 log_err(
"config notification without service: [%s] %s=%s",
1209 section, key, value);
1213 if( !umdbus_connection ) {
1214 log_err(
"config notification without connection: [%s] %s=%s",
1215 section, key, value);
1219 log_debug(
"broadcast signal %s(%s, %s, %s)\n", USB_MODE_CONFIG_SIGNAL_NAME, section, key, value);
1221 msg = dbus_message_new_signal(USB_MODE_OBJECT, USB_MODE_INTERFACE, USB_MODE_CONFIG_SIGNAL_NAME);
1225 dbus_message_append_args(msg, DBUS_TYPE_STRING, §ion,
1226 DBUS_TYPE_STRING, &key,
1227 DBUS_TYPE_STRING, &value,
1229 dbus_connection_send(umdbus_connection, msg, NULL);
1233 dbus_message_unref(msg);
1236static DBusHandlerResult umdbus_msg_handler(DBusConnection *
const connection, DBusMessage *
const msg, gpointer
const user_data)
1240 LOG_REGISTER_CONTEXT;
1242 DBusHandlerResult status = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1247 switch( (context.
type = dbus_message_get_type(msg)) ) {
1248 case DBUS_MESSAGE_TYPE_SIGNAL:
1249 case DBUS_MESSAGE_TYPE_METHOD_CALL:
1256 if( !(context.
sender = dbus_message_get_sender(msg)) )
1259 if( !(context.
object = dbus_message_get_path(msg)) )
1262 if( !(context.
interface = dbus_message_get_interface(msg)) )
1265 if( !(context.
member = dbus_message_get_member(msg)) )
1268 log_debug(
"DBUS %s %s.%s from %s",
1269 dbus_message_type_to_string(context.
type),
1273 if( context.
type == DBUS_MESSAGE_TYPE_SIGNAL ) {
1274 if( !strcmp(context.
interface, INIT_DONE_INTERFACE) && !strcmp(context.
member, INIT_DONE_SIGNAL) ) {
1293 context.
rsp = dbus_message_new_error_printf(context.
msg,
1294 DBUS_ERROR_UNKNOWN_OBJECT,
1295 "Object '%s' does not exist",
1299 context.
rsp = dbus_message_new_error_printf(context.
msg,
1300 DBUS_ERROR_UNKNOWN_INTERFACE,
1301 "Interface '%s' does not exist",
1305 context.
rsp = dbus_message_new_error_printf(context.
msg,
1306 DBUS_ERROR_UNKNOWN_METHOD,
1307 "Method '%s.%s' does not exist",
1314 status = DBUS_HANDLER_RESULT_HANDLED;
1315 if( !dbus_message_get_no_reply(context.
msg) ) {
1316 if( !dbus_connection_send(connection, context.
rsp, 0) )
1317 log_debug(
"Failed sending reply. Out Of Memory!\n");
1319 dbus_message_unref(context.
rsp);
1325DBusConnection *umdbus_get_connection(
void)
1327 LOG_REGISTER_CONTEXT;
1329 DBusConnection *connection = 0;
1330 if( umdbus_connection )
1331 connection = dbus_connection_ref(umdbus_connection);
1333 log_err(
"something asked for connection ref while unconnected");
1344 LOG_REGISTER_CONTEXT;
1346 gboolean status = FALSE;
1347 DBusError error = DBUS_ERROR_INIT;
1350 if ((umdbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) == NULL)
1352 log_debug(
"Failed to open connection to system message bus; %s\n", error.message);
1357 if (!dbus_connection_add_filter(umdbus_connection, umdbus_msg_handler, NULL, NULL))
1361 dbus_bus_add_match(umdbus_connection, INIT_DONE_MATCH, 0);
1367 dbus_gmain_set_up_connection(umdbus_connection, NULL);
1373 dbus_error_free(&error);
1384 LOG_REGISTER_CONTEXT;
1386 gboolean status = FALSE;
1387 DBusError error = DBUS_ERROR_INIT;
1390 if( !umdbus_connection ) {
1395 ret = dbus_bus_request_name(umdbus_connection, USB_MODE_SERVICE, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1396 if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
1398 log_debug(
"failed claiming dbus name\n");
1399 if( dbus_error_is_set(&error) )
1400 log_debug(
"DBUS ERROR: %s, %s", error.name, error.message);
1403 log_debug(
"claimed name %s", USB_MODE_SERVICE);
1404 umdbus_service_name_acquired = TRUE;
1409 dbus_error_free(&error);
1415static void umdbus_cleanup_service(
void)
1417 LOG_REGISTER_CONTEXT;
1419 if( !umdbus_service_name_acquired )
1422 umdbus_service_name_acquired = FALSE;
1423 log_debug(
"release name %s", USB_MODE_SERVICE);
1425 if( umdbus_connection &&
1426 dbus_connection_get_is_connected(umdbus_connection) )
1428 dbus_bus_release_name(umdbus_connection, USB_MODE_SERVICE, NULL);
1441 LOG_REGISTER_CONTEXT;
1444 if (umdbus_connection != NULL)
1446 umdbus_cleanup_service();
1448 dbus_connection_remove_filter(umdbus_connection, umdbus_msg_handler, NULL);
1450 dbus_connection_unref(umdbus_connection),
1451 umdbus_connection = NULL;
1462umdbus_new_signal(
const char *signal_name)
1464 LOG_REGISTER_CONTEXT;
1466 DBusMessage *msg = 0;
1468 if( !umdbus_connection )
1470 log_err(
"sending signal %s without dbus connection", signal_name);
1473 if( !umdbus_service_name_acquired )
1475 log_err(
"sending signal %s before acquiring name", signal_name);
1479 msg = dbus_message_new_signal(USB_MODE_OBJECT, USB_MODE_INTERFACE,
1483 log_err(
"allocating signal %s failed", signal_name);
1500umdbus_send_signal_ex(
const char *signal_name,
const char *content)
1502 LOG_REGISTER_CONTEXT;
1505 DBusMessage* msg = 0;
1512 log_debug(
"broadcast signal %s(%s)", signal_name, content);
1514 if( !(msg = umdbus_new_signal(signal_name)) )
1518 if( !dbus_message_append_args(msg,
1519 DBUS_TYPE_STRING, &content,
1520 DBUS_TYPE_INVALID) )
1522 log_err(
"appending arguments to signal %s failed", signal_name);
1527 if( !dbus_connection_send(umdbus_connection, msg, 0) )
1529 log_err(
"sending signal %s failed", signal_name);
1537 dbus_message_unref(msg);
1549static void umdbus_send_legacy_signal(
const char *state_ind)
1551 LOG_REGISTER_CONTEXT;
1562 LOG_REGISTER_CONTEXT;
1564 umdbus_send_signal_ex(USB_MODE_CURRENT_STATE_SIGNAL_NAME,
1566 umdbus_send_legacy_signal(state_ind);
1579umdbus_append_basic_entry(DBusMessageIter *iter,
const char *key,
1580 int type,
const void *val)
1582 LOG_REGISTER_CONTEXT;
1585 const char *signature = 0;
1587 case DBUS_TYPE_INT32: signature = DBUS_TYPE_INT32_AS_STRING;
break;
1588 case DBUS_TYPE_STRING: signature = DBUS_TYPE_STRING_AS_STRING;
break;
1592 log_err(
"unhandled D-Bus type: %d", type);
1593 goto bailout_message;
1596 DBusMessageIter entry, variant;
1598 if( !dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
1600 goto bailout_message;
1602 if( !dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key) )
1605 if( !dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
1606 signature, &variant) )
1609 if( !dbus_message_iter_append_basic(&variant, type, val) )
1610 goto bailout_variant;
1612 if( !dbus_message_iter_close_container(&entry, &variant) )
1613 goto bailout_variant;
1615 if( !dbus_message_iter_close_container(iter, &entry) )
1621 dbus_message_iter_abandon_container(&entry, &variant);
1624 dbus_message_iter_abandon_container(iter, &entry);
1639umdbus_append_int32_entry(DBusMessageIter *iter,
const char *key,
int val)
1641 LOG_REGISTER_CONTEXT;
1643 dbus_int32_t arg = val;
1644 return umdbus_append_basic_entry(iter, key, DBUS_TYPE_INT32, &arg);
1656umdbus_append_string_entry(DBusMessageIter *iter,
const char *key,
1659 LOG_REGISTER_CONTEXT;
1663 return umdbus_append_basic_entry(iter, key, DBUS_TYPE_STRING, &val);
1674umdbus_append_mode_details(DBusMessage *msg,
const char *mode_name)
1676 LOG_REGISTER_CONTEXT;
1680 DBusMessageIter body, dict;
1682 dbus_message_iter_init_append(msg, &body);
1684 if( !dbus_message_iter_open_container(&body,
1686 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1687 DBUS_TYPE_STRING_AS_STRING
1688 DBUS_TYPE_VARIANT_AS_STRING
1689 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1691 goto bailout_message;
1696 if( !umdbus_append_string_entry(&dict,
"mode_name", mode_name) )
1703#define ADD_STR_EX(name, memb) \
1704 if( !umdbus_append_string_entry(&dict, #name, data ? data->memb : 0) )\
1706#define ADD_STR(name) \
1707 if( !umdbus_append_string_entry(&dict, #name, data ? data->name : 0) )\
1709#define ADD_INT(name) \
1710 if( !umdbus_append_int32_entry(&dict, #name, data ? data->name : 0) )\
1716 ADD_STR_EX(network_interface, cached_interface);
1718 ADD_INT(dhcp_server);
1720 ADD_STR(connman_tethering);
1725 ADD_INT(mass_storage);
1726 ADD_STR(mode_module);
1727 ADD_STR(sysfs_path);
1728 ADD_STR(sysfs_value);
1729 ADD_STR(sysfs_reset_value);
1730 ADD_STR(android_extra_sysfs_path);
1731 ADD_STR(android_extra_sysfs_value);
1732 ADD_STR(android_extra_sysfs_path2);
1733 ADD_STR(android_extra_sysfs_value2);
1734 ADD_STR(android_extra_sysfs_path3);
1735 ADD_STR(android_extra_sysfs_value3);
1736 ADD_STR(android_extra_sysfs_path4);
1737 ADD_STR(android_extra_sysfs_value4);
1739 ADD_STR(idVendorOverride);
1745 if( !dbus_message_iter_close_container(&body, &dict) )
1751 dbus_message_iter_abandon_container(&body, &dict);
1762umdbus_send_mode_details_signal(
const char *mode_name)
1764 DBusMessage* msg = 0;
1766 if( !(msg = umdbus_new_signal(USB_MODE_TARGET_CONFIG_SIGNAL_NAME)) )
1769 if( !umdbus_append_mode_details(msg, mode_name) )
1772 dbus_connection_send(umdbus_connection, msg, 0);
1776 dbus_message_unref(msg);
1785 LOG_REGISTER_CONTEXT;
1796 umdbus_send_mode_details_signal(state_ind);
1798 umdbus_send_signal_ex(USB_MODE_TARGET_STATE_SIGNAL_NAME,
1808 LOG_REGISTER_CONTEXT;
1810 umdbus_send_signal_ex(USB_MODE_EVENT_SIGNAL_NAME,
1812 umdbus_send_legacy_signal(state_ind);
1824 LOG_REGISTER_CONTEXT;
1826 return umdbus_send_signal_ex(USB_MODE_ERROR_SIGNAL_NAME, error);
1838 LOG_REGISTER_CONTEXT;
1840 return umdbus_send_signal_ex(USB_MODE_SUPPORTED_MODES_SIGNAL_NAME, supported_modes);
1852 LOG_REGISTER_CONTEXT;
1854 return umdbus_send_signal_ex(USB_MODE_AVAILABLE_MODES_SIGNAL_NAME, available_modes);
1866 LOG_REGISTER_CONTEXT;
1868 return umdbus_send_signal_ex(USB_MODE_HIDDEN_MODES_SIGNAL_NAME, hidden_modes);
1879 LOG_REGISTER_CONTEXT;
1881 return umdbus_send_signal_ex(USB_MODE_WHITELISTED_MODES_SIGNAL_NAME, whitelist);
1889static void umdbus_get_name_owner_cb(DBusPendingCall *pc,
void *aptr)
1891 LOG_REGISTER_CONTEXT;
1893 usb_moded_get_name_owner_fn cb = aptr;
1895 DBusMessage *rsp = 0;
1896 const char *dta = 0;
1897 DBusError err = DBUS_ERROR_INIT;
1899 if( !(rsp = dbus_pending_call_steal_reply(pc)) ) {
1900 log_err(
"did not get reply");
1904 if( dbus_set_error_from_message(&err, rsp) )
1906 if( strcmp(err.name, DBUS_ERROR_NAME_HAS_NO_OWNER) )
1907 log_err(
"error reply: %s: %s", err.name, err.message);
1911 if( !dbus_message_get_args(rsp, &err,
1912 DBUS_TYPE_STRING, &dta,
1913 DBUS_TYPE_INVALID) )
1915 if( strcmp(err.name, DBUS_ERROR_NAME_HAS_NO_OWNER) )
1916 log_err(
"parse error: %s: %s", err.name, err.message);
1925 if( rsp ) dbus_message_unref(rsp);
1927 dbus_error_free(&err);
1939 usb_moded_get_name_owner_fn cb,
1940 DBusPendingCall **ppc)
1942 LOG_REGISTER_CONTEXT;
1944 gboolean ack = FALSE;
1945 DBusMessage *req = 0;
1946 DBusPendingCall *pc = 0;
1948 if(!umdbus_connection)
1951 req = dbus_message_new_method_call(DBUS_INTERFACE_DBUS,
1953 DBUS_INTERFACE_DBUS,
1956 log_err(
"could not create method call message");
1960 if( !dbus_message_append_args(req,
1961 DBUS_TYPE_STRING, &name,
1962 DBUS_TYPE_INVALID) ) {
1963 log_err(
"could not add method call parameters");
1967 if( !dbus_connection_send_with_reply(umdbus_connection, req, &pc, -1) )
1973 if( !dbus_pending_call_set_notify(pc, umdbus_get_name_owner_cb, cb, 0) )
1983 if( pc ) dbus_pending_call_unref(pc);
1984 if( req ) dbus_message_unref(req);
1996umdbus_get_sender_uid(
const char *name)
1998 LOG_REGISTER_CONTEXT;
2000 pid_t pid = PID_UNKNOWN;
2001 uid_t uid = UID_UNKNOWN;
2002 DBusMessage *req = 0;
2003 DBusMessage *rsp = 0;
2004 DBusError err = DBUS_ERROR_INIT;
2008 if(!umdbus_connection)
2011 req = dbus_message_new_method_call(DBUS_INTERFACE_DBUS,
2013 DBUS_INTERFACE_DBUS,
2016 log_err(
"could not create method call message");
2020 if( !dbus_message_append_args(req,
2021 DBUS_TYPE_STRING, &name,
2022 DBUS_TYPE_INVALID) ) {
2023 log_err(
"could not add method call parameters");
2028 rsp = dbus_connection_send_with_reply_and_block(umdbus_connection, req, -1, &err);
2030 if( !rsp && dbus_error_is_set(&err) ) {
2031 log_err(
"could not get sender pid for %s: %s: %s", name, err.name, err.message);
2035 if( !dbus_message_get_args(rsp, &err,
2036 DBUS_TYPE_UINT32, &pid,
2037 DBUS_TYPE_INVALID) ) {
2038 log_err(
"parse error: %s: %s", err.name, err.message);
2042 snprintf(path,
sizeof path,
"/proc/%d", (
int)pid);
2043 memset(&st, 0,
sizeof st);
2044 if( stat(path, &st) != -1 ) {
2050 if( req ) dbus_message_unref(req);
2051 if( rsp ) dbus_message_unref(rsp);
2053 dbus_error_free(&err);
2059umdbus_arg_type_repr(
int type)
2061 const char *repr =
"UNKNOWN";
2063 case DBUS_TYPE_INVALID: repr =
"INVALID";
break;
2064 case DBUS_TYPE_BYTE: repr =
"BYTE";
break;
2065 case DBUS_TYPE_BOOLEAN: repr =
"BOOLEAN";
break;
2066 case DBUS_TYPE_INT16: repr =
"INT16";
break;
2067 case DBUS_TYPE_UINT16: repr =
"UINT16";
break;
2068 case DBUS_TYPE_INT32: repr =
"INT32";
break;
2069 case DBUS_TYPE_UINT32: repr =
"UINT32";
break;
2070 case DBUS_TYPE_INT64: repr =
"INT64";
break;
2071 case DBUS_TYPE_UINT64: repr =
"UINT64";
break;
2072 case DBUS_TYPE_DOUBLE: repr =
"DOUBLE";
break;
2073 case DBUS_TYPE_STRING: repr =
"STRING";
break;
2074 case DBUS_TYPE_OBJECT_PATH: repr =
"OBJECT_PATH";
break;
2075 case DBUS_TYPE_SIGNATURE: repr =
"SIGNATURE";
break;
2076 case DBUS_TYPE_UNIX_FD: repr =
"UNIX_FD";
break;
2077 case DBUS_TYPE_ARRAY: repr =
"ARRAY";
break;
2078 case DBUS_TYPE_VARIANT: repr =
"VARIANT";
break;
2079 case DBUS_TYPE_STRUCT: repr =
"STRUCT";
break;
2080 case DBUS_TYPE_DICT_ENTRY: repr =
"DICT_ENTRY";
break;
2087umdbus_arg_type_signature(
int type)
2089 const char *sign = 0;
2091 case DBUS_TYPE_INVALID: sign = DBUS_TYPE_INVALID_AS_STRING;
break;
2092 case DBUS_TYPE_BYTE: sign = DBUS_TYPE_BYTE_AS_STRING;
break;
2093 case DBUS_TYPE_BOOLEAN: sign = DBUS_TYPE_BOOLEAN_AS_STRING;
break;
2094 case DBUS_TYPE_INT16: sign = DBUS_TYPE_INT16_AS_STRING;
break;
2095 case DBUS_TYPE_UINT16: sign = DBUS_TYPE_UINT16_AS_STRING;
break;
2096 case DBUS_TYPE_INT32: sign = DBUS_TYPE_INT32_AS_STRING;
break;
2097 case DBUS_TYPE_UINT32: sign = DBUS_TYPE_UINT32_AS_STRING;
break;
2098 case DBUS_TYPE_INT64: sign = DBUS_TYPE_INT64_AS_STRING;
break;
2099 case DBUS_TYPE_UINT64: sign = DBUS_TYPE_UINT64_AS_STRING;
break;
2100 case DBUS_TYPE_DOUBLE: sign = DBUS_TYPE_DOUBLE_AS_STRING;
break;
2101 case DBUS_TYPE_STRING: sign = DBUS_TYPE_STRING_AS_STRING;
break;
2102 case DBUS_TYPE_OBJECT_PATH: sign = DBUS_TYPE_OBJECT_PATH_AS_STRING;
break;
2103 case DBUS_TYPE_SIGNATURE: sign = DBUS_TYPE_SIGNATURE_AS_STRING;
break;
2104 case DBUS_TYPE_UNIX_FD: sign = DBUS_TYPE_UNIX_FD_AS_STRING;
break;
2105 case DBUS_TYPE_ARRAY: sign = DBUS_TYPE_ARRAY_AS_STRING;
break;
2106 case DBUS_TYPE_VARIANT: sign = DBUS_TYPE_VARIANT_AS_STRING;
break;
2107 case DBUS_TYPE_STRUCT: sign = DBUS_TYPE_STRUCT_AS_STRING;
break;
2108 case DBUS_TYPE_DICT_ENTRY: sign = DBUS_TYPE_DICT_ENTRY_AS_STRING;
break;
2115umdbus_msg_type_repr(
int type)
2117 return dbus_message_type_to_string(type);
2121umdbus_parser_init(DBusMessageIter *iter, DBusMessage *msg)
2123 return iter && msg && dbus_message_iter_init(msg, iter);
2127umdbus_parser_at_type(DBusMessageIter *iter)
2129 return iter ? dbus_message_iter_get_arg_type(iter) : DBUS_TYPE_INVALID;
2133umdbus_parser_at_end(DBusMessageIter *iter)
2135 return umdbus_parser_at_type(iter) == DBUS_TYPE_INVALID;
2139umdbus_parser_require_type(DBusMessageIter *iter,
int type,
bool strict)
2141 int have = umdbus_parser_at_type(iter);
2146 if( strict || have != DBUS_TYPE_INVALID )
2147 log_warning(
"expected %s, got %s",
2148 umdbus_arg_type_repr(type),
2149 umdbus_arg_type_repr(have));
2154umdbus_parser_get_bool(DBusMessageIter *iter,
bool *pval)
2156 dbus_bool_t val = 0;
2157 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_BOOLEAN,
true);
2159 dbus_message_iter_get_basic(iter, &val);
2160 dbus_message_iter_next(iter);
2162 return *pval = val, ack;
2166umdbus_parser_get_int(DBusMessageIter *iter,
int *pval)
2168 dbus_int32_t val = 0;
2169 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_INT32,
true);
2171 dbus_message_iter_get_basic(iter, &val);
2172 dbus_message_iter_next(iter);
2174 return *pval = (int)val, ack;
2178umdbus_parser_get_string(DBusMessageIter *iter,
const char **pval)
2180 const char *val = 0;
2181 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_STRING,
true);
2183 dbus_message_iter_get_basic(iter, &val);
2184 dbus_message_iter_next(iter);
2186 return *pval = val, ack;
2190umdbus_parser_get_object(DBusMessageIter *iter,
const char **pval)
2192 const char *val = 0;
2193 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_OBJECT_PATH,
true);
2195 dbus_message_iter_get_basic(iter, &val);
2196 dbus_message_iter_next(iter);
2198 return *pval = val, ack;
2202umdbus_parser_get_variant(DBusMessageIter *iter, DBusMessageIter *val)
2204 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_VARIANT,
true);
2206 dbus_message_iter_recurse(iter, val);
2207 dbus_message_iter_next(iter);
2213umdbus_parser_get_array(DBusMessageIter *iter, DBusMessageIter *val)
2215 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_ARRAY,
true);
2217 dbus_message_iter_recurse(iter, val);
2218 dbus_message_iter_next(iter);
2224umdbus_parser_get_struct(DBusMessageIter *iter, DBusMessageIter *val)
2226 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_STRUCT,
false);
2228 dbus_message_iter_recurse(iter, val);
2229 dbus_message_iter_next(iter);
2235umdbus_parser_get_entry(DBusMessageIter *iter, DBusMessageIter *val)
2237 bool ack = umdbus_parser_require_type(iter, DBUS_TYPE_DICT_ENTRY,
false);
2239 dbus_message_iter_recurse(iter, val);
2240 dbus_message_iter_next(iter);
2246umdbus_append_init(DBusMessageIter *iter, DBusMessage *msg)
2248 bool ack = iter && msg && (dbus_message_iter_init_append(msg, iter),
true);
2253umdbus_open_container(DBusMessageIter *iter, DBusMessageIter *sub,
int type,
const char *sign)
2255 bool ack = dbus_message_iter_open_container(iter, type, sign, sub);
2261 log_warning(
"failed to open %s container with signature: %s",
2262 umdbus_arg_type_repr(type), sign ?:
"");
2268umdbus_close_container(DBusMessageIter *iter, DBusMessageIter *sub,
bool success)
2271 if( !(success = dbus_message_iter_close_container(iter, sub)) ) {
2272 log_warning(
"failed to close container");
2276 log_warning(
"abandoning container");
2277 dbus_message_iter_abandon_container(iter, sub);
2283umdbus_append_basic_value(DBusMessageIter *iter,
int type,
const DBusBasicValue *val)
2285 if(
log_p(LOG_DEBUG) ) {
2287 const char *repr = buff;
2289 case DBUS_TYPE_BYTE:
2290 snprintf(buff,
sizeof buff,
"%u", val->byt);
2292 case DBUS_TYPE_BOOLEAN:
2293 repr = val->bool_val ?
"true" :
"false";
2295 case DBUS_TYPE_INT16:
2296 snprintf(buff,
sizeof buff,
"%d", val->i16);
2298 case DBUS_TYPE_UINT16:
2299 snprintf(buff,
sizeof buff,
"%u", val->u16);
2301 case DBUS_TYPE_INT32:
2302 snprintf(buff,
sizeof buff,
"%d", val->i32);
2304 case DBUS_TYPE_UINT32:
2305 snprintf(buff,
sizeof buff,
"%u", val->u32);
2307 case DBUS_TYPE_INT64:
2308 snprintf(buff,
sizeof buff,
"%lld", (
long long)val->i64);
2310 case DBUS_TYPE_UINT64:
2311 snprintf(buff,
sizeof buff,
"%llu", (
unsigned long long)val->u64);
2313 case DBUS_TYPE_DOUBLE:
2314 snprintf(buff,
sizeof buff,
"%g", val->dbl);
2316 case DBUS_TYPE_STRING:
2317 case DBUS_TYPE_OBJECT_PATH:
2318 case DBUS_TYPE_SIGNATURE:
2319 repr = (
const char *)val->str;
2321 case DBUS_TYPE_UNIX_FD:
2322 snprintf(buff,
sizeof buff,
"%d", val->fd);
2325 case DBUS_TYPE_INVALID:
2326 case DBUS_TYPE_ARRAY:
2327 case DBUS_TYPE_VARIANT:
2328 case DBUS_TYPE_STRUCT:
2329 case DBUS_TYPE_DICT_ENTRY:
2333 log_debug(
"append %s value %s", umdbus_arg_type_repr(type), repr);
2336 if (dbus_message_iter_append_basic(iter, type, val))
2339 log_warning(
"failed to append %s argument", umdbus_arg_type_repr(type));
2344umdbus_append_basic_variant(DBusMessageIter *iter,
int type,
const DBusBasicValue *val)
2347 const char *sign = 0;
2349 log_debug(
"append %s variant", umdbus_arg_type_repr(type));
2351 if( !dbus_type_is_basic(type) )
2354 if( !(sign = umdbus_arg_type_signature(type)) )
2357 DBusMessageIter var;
2359 if( umdbus_open_container(iter, &var, DBUS_TYPE_VARIANT, sign) ) {
2360 ack = umdbus_append_basic_value(&var, DBUS_TYPE_BOOLEAN, val);
2361 ack = umdbus_close_container(iter, &var, ack);
2367 log_warning(
"failed to append %s variant", umdbus_arg_type_repr(type));
2373umdbus_append_bool(DBusMessageIter *iter,
bool val)
2375 DBusBasicValue dta = { .bool_val = (dbus_bool_t)val };
2376 return umdbus_append_basic_value(iter, DBUS_TYPE_BOOLEAN, &dta);
2380umdbus_append_int(DBusMessageIter *iter,
int val)
2382 DBusBasicValue dta = { .i32 = (dbus_int32_t)val };
2383 return umdbus_append_basic_value(iter, DBUS_TYPE_INT32, &dta);
2387umdbus_append_string(DBusMessageIter *iter,
const char *val)
2389 DBusBasicValue dta = { .str = (
char *)val };
2390 return umdbus_append_basic_value(iter, DBUS_TYPE_STRING, &dta);
2394umdbus_append_bool_variant(DBusMessageIter *iter,
bool val)
2396 DBusBasicValue dta = { .bool_val = val };
2397 return umdbus_append_basic_variant(iter, DBUS_TYPE_BOOLEAN, &dta);
2401umdbus_append_int_variant(DBusMessageIter *iter,
int val)
2403 DBusBasicValue dta = { .i32 = val };
2404 return umdbus_append_basic_variant(iter, DBUS_TYPE_INT32, &dta);
2408umdbus_append_string_variant(DBusMessageIter *iter,
const char *val)
2410 DBusBasicValue dta = { .str = (
char *)val };
2411 return umdbus_append_basic_variant(iter, DBUS_TYPE_STRING, &dta);
2415umdbus_append_args_va(DBusMessageIter *iter,
int type, va_list va)
2419 DBusBasicValue *arg;
2421 while( type != DBUS_TYPE_INVALID ) {
2423 case DBUS_TYPE_VARIANT:
2424 type = va_arg(va,
int);
2425 if( !dbus_type_is_basic(type) ) {
2426 log_err(
"variant type %s is not supported",
2427 umdbus_arg_type_repr(type));
2430 arg = va_arg(va, DBusBasicValue *);
2431 if( !umdbus_append_basic_variant(iter, type, arg) )
2436 case DBUS_TYPE_ARRAY:
2437 case DBUS_TYPE_STRUCT:
2440 if( !dbus_type_is_basic(type) ) {
2441 log_err(
"value type %s is not supported",
2442 umdbus_arg_type_repr(type));
2445 arg = va_arg(va, DBusBasicValue *);
2446 if( !umdbus_append_basic_value(iter, type, arg) )
2450 type = va_arg(va,
int);
2458umdbus_append_args(DBusMessageIter *iter,
int arg_type, ...)
2461 va_start(va, arg_type);
2462 bool ack = umdbus_append_args_va(iter, arg_type, va);
2468umdbus_blocking_call(DBusConnection *con,
2476 DBusMessage *rsp = 0;
2477 DBusMessage *req = 0;
2480 va_start(va, arg_type);
2482 if( !(req = dbus_message_new_method_call(dst, obj, iface, meth)) )
2485 DBusMessageIter body;
2486 if( !umdbus_append_init(&body, req) )
2493 if( !umdbus_append_args_va(&body, arg_type, va) )
2496 if( !(rsp = dbus_connection_send_with_reply_and_block(con, req, -1, err)) ) {
2497 log_warning(
"no reply to %s.%s(): %s: %s",
2498 iface, meth, err->name, err->message);
2502 if( dbus_set_error_from_message(err, rsp) ) {
2503 log_warning(
"error reply to %s.%s(): %s: %s",
2504 iface, meth, err->name, err->message);
2505 dbus_message_unref(rsp), rsp = 0;
2509 log_debug(
"blocking %s.%s() call succeeded", iface, meth);
2513 dbus_message_unref(req);
2521umdbus_parse_reply(DBusMessage *rsp,
int arg_type, ...)
2524 DBusError err = DBUS_ERROR_INIT;
2527 va_start(va, arg_type);
2536 if( !dbus_message_get_args_valist(rsp, &err, arg_type, va) ) {
2537 log_warning(
"parse error: %s: %s", err.name, err.message);
2544 dbus_error_free(&err);
const member_info_t * members
void(* handler)(umdbus_context_t *)
const interface_info_t ** interfaces
const interface_info_t * interface_info
const object_info_t * object_info
const member_info_t * member_info
int common_valid_mode(const char *mode)
gchar * common_get_mode_list(mode_list_type_t type, uid_t uid)
bool config_user_clear(uid_t uid)
char * config_get_network_fallback(const char *config)
char * config_get_network_setting(const char *config)
bool control_select_mode(const char *mode)
cable_state_t control_get_cable_state(void)
#define DBUS_GET_CONNECTION_PID_REQ
#define DBUS_GET_NAME_OWNER_REQ
void umdbus_dump_introspect_xml(void)
int umdbus_send_hidden_modes_signal(const char *hidden_modes)
void umdbus_send_current_state_signal(const char *state_ind)
void umdbus_cleanup(void)
void umdbus_send_target_state_signal(const char *state_ind)
void umdbus_send_event_signal(const char *state_ind)
gboolean umdbus_init_service(void)
void umdbus_dump_busconfig_xml(void)
int umdbus_send_error_signal(const char *error)
gboolean umdbus_get_name_owner_async(const char *name, usb_moded_get_name_owner_fn cb, DBusPendingCall **ppc)
int umdbus_send_available_modes_signal(const char *available_modes)
void umdbus_send_config_signal(const char *section, const char *key, const char *value)
gboolean umdbus_init_connection(void)
int umdbus_send_supported_modes_signal(const char *supported_modes)
#define ADD_SIGNAL(NAME, ARGS)
#define ADD_METHOD(NAME, FUNC, ARGS)
int umdbus_send_whitelisted_modes_signal(const char *whitelist)
#define USB_MODE_SIGNAL_NAME
#define MODE_CHARGING_FALLBACK
void network_update(void)
void usbmoded_set_init_done(bool reached)
const modedata_t * usbmoded_get_modedata(const char *modename)
void usbmoded_probe_init_done(void)