66 #ifdef SAILFISH_ACCESS_CONTROL
67 # include <sailfishaccesscontrol.h>
71 # include <systemd/sd-daemon.h>
79 #ifndef VERBOSE_WAKELOCKING
80 # define VERBOSE_WAKELOCKING 0
90 #define CABLE_CONNECTION_DELAY_DEFAULT 0
102 #define CABLE_CONNECTION_DELAY_MAXIMUM 4000
117 bool usbmoded_get_rescue_mode (
void);
118 void usbmoded_set_rescue_mode (
bool rescue_mode);
119 bool usbmoded_get_diag_mode (
void);
120 void usbmoded_set_diag_mode (
bool diag_mode);
121 bool usbmoded_is_mode_permitted (
const char *modename, uid_t uid);
124 static gboolean usbmoded_allow_suspend_timer_cb (gpointer aptr);
135 void usbmoded_handle_signal (
int signum);
136 static bool usbmoded_init (
void);
137 static void usbmoded_cleanup (
void);
138 static void usbmoded_usage (
void);
139 static void usbmoded_parse_options (
int argc,
char *argv[]);
145 int main(
int argc,
char *argv[]);
151 static int usbmoded_exitcode = EXIT_FAILURE;
152 static GMainLoop *usbmoded_mainloop = NULL;
154 static bool usbmoded_hw_fallback =
false;
156 static bool usbmoded_systemd_notify =
false;
158 static bool usbmoded_auto_exit =
false;
160 static pthread_mutex_t usbmoded_mutex = PTHREAD_MUTEX_INITIALIZER;
162 #define USBMODED_LOCKED_ENTER do {\
163 if( pthread_mutex_lock(&usbmoded_mutex) != 0 ) { \
164 log_crit("USBMODED LOCK FAILED");\
165 _exit(EXIT_FAILURE);\
169 #define USBMODED_LOCKED_LEAVE do {\
170 if( pthread_mutex_unlock(&usbmoded_mutex) != 0 ) { \
171 log_crit("USBMODED UNLOCK FAILED");\
172 _exit(EXIT_FAILURE);\
188 static GList *usbmoded_modelist = 0;
199 LOG_REGISTER_CONTEXT;
201 return usbmoded_modelist;
211 LOG_REGISTER_CONTEXT;
213 USBMODED_LOCKED_ENTER;
215 if( !usbmoded_modelist ) {
216 log_notice(
"load modelist");
220 USBMODED_LOCKED_LEAVE;
230 LOG_REGISTER_CONTEXT;
232 USBMODED_LOCKED_ENTER;
234 if( usbmoded_modelist ) {
235 log_notice(
"free modelist");
237 usbmoded_modelist = 0;
240 USBMODED_LOCKED_LEAVE;
254 LOG_REGISTER_CONTEXT;
260 if( !g_strcmp0(data->
mode_name, modename) ) {
281 LOG_REGISTER_CONTEXT;
283 USBMODED_LOCKED_ENTER;
287 USBMODED_LOCKED_LEAVE;
302 static bool usbmoded_rescue_mode =
false;
304 bool usbmoded_get_rescue_mode(
void)
306 LOG_REGISTER_CONTEXT;
308 return usbmoded_rescue_mode;
311 void usbmoded_set_rescue_mode(
bool rescue_mode)
313 LOG_REGISTER_CONTEXT;
315 if( usbmoded_rescue_mode != rescue_mode ) {
316 log_info(
"rescue_mode: %d -> %d", usbmoded_rescue_mode, rescue_mode);
317 usbmoded_rescue_mode = rescue_mode;
330 static int usbmoded_diag_mode = -1;
332 bool usbmoded_get_diag_mode(
void)
334 LOG_REGISTER_CONTEXT;
336 if( usbmoded_diag_mode == -1 ) {
337 usbmoded_diag_mode =
false;
338 log_info(
"diag_mode: locked to %d", usbmoded_diag_mode);
341 return usbmoded_diag_mode;
344 void usbmoded_set_diag_mode(
bool diag_mode)
346 LOG_REGISTER_CONTEXT;
348 if( usbmoded_diag_mode != diag_mode ) {
349 if( usbmoded_diag_mode == -1 ) {
350 usbmoded_diag_mode = diag_mode;
351 log_info(
"diag_mode: set to %d", usbmoded_diag_mode);
354 log_err(
"dig_mode: already locked to %d", usbmoded_diag_mode);
363 bool usbmoded_is_mode_permitted(
const char *modename, uid_t uid)
365 #ifdef SAILFISH_ACCESS_CONTROL
366 LOG_REGISTER_CONTEXT;
377 if( uid == UID_UNKNOWN ) {
388 group = config_get_group_for_mode(modename);
389 allowed = sailfish_access_control_hasgroup(uid, group);
424 LOG_REGISTER_CONTEXT;
431 if( usbmoded_cable_connection_delay != delay_ms ) {
432 log_info(
"cable_connection_delay: %d -> %d",
433 usbmoded_cable_connection_delay,
435 usbmoded_cable_connection_delay = delay_ms;
444 LOG_REGISTER_CONTEXT;
446 return usbmoded_cable_connection_delay;
454 static bool usbmoded_blocking_suspend =
false;
457 static guint usbmoded_allow_suspend_timer_id = 0;
463 static gboolean usbmoded_allow_suspend_timer_cb(gpointer aptr)
465 LOG_REGISTER_CONTEXT;
469 usbmoded_allow_suspend_timer_id = 0;
483 LOG_REGISTER_CONTEXT;
485 if( usbmoded_allow_suspend_timer_id ) {
486 g_source_remove(usbmoded_allow_suspend_timer_id),
487 usbmoded_allow_suspend_timer_id = 0;
490 if( usbmoded_blocking_suspend ) {
491 usbmoded_blocking_suspend =
false;
508 LOG_REGISTER_CONTEXT;
514 usbmoded_blocking_suspend =
true;
516 if( usbmoded_allow_suspend_timer_id )
517 g_source_remove(usbmoded_allow_suspend_timer_id);
519 usbmoded_allow_suspend_timer_id =
521 usbmoded_allow_suspend_timer_cb, 0);
535 LOG_REGISTER_CONTEXT;
551 LOG_REGISTER_CONTEXT;
574 LOG_REGISTER_CONTEXT;
593 LOG_REGISTER_CONTEXT;
595 bool can_export =
true;
604 if( usbmoded_get_rescue_mode() )
616 static const char usbmoded_init_done_flagfile[] =
"/run/systemd/boot-status/init-done";
619 static bool usbmoded_init_done_reached =
false;
627 LOG_REGISTER_CONTEXT;
629 return usbmoded_init_done_reached;
635 LOG_REGISTER_CONTEXT;
637 if( usbmoded_init_done_reached != reached ) {
638 usbmoded_init_done_reached = reached;
639 log_warning(
"init_done -> %s",
640 usbmoded_init_done_reached ?
"reached" :
"not reached");
643 if( usbmoded_init_done_reached )
644 usbmoded_set_rescue_mode(
false);
653 LOG_REGISTER_CONTEXT;
666 LOG_REGISTER_CONTEXT;
670 if( usbmoded_exitcode < exitcode )
671 usbmoded_exitcode = exitcode;
674 if( !usbmoded_mainloop )
676 log_warning(
"exit requested outside mainloop; exit(%d) now",
678 exit(usbmoded_exitcode);
681 log_debug(
"stopping usb-moded mainloop");
682 g_main_loop_quit(usbmoded_mainloop);
685 void usbmoded_handle_signal(
int signum)
687 LOG_REGISTER_CONTEXT;
689 log_debug(
"handle signal: %s\n", strsignal(signum));
691 if( signum == SIGTERM )
696 else if( signum == SIGHUP )
704 log_debug(
"reloading dynamic mode configuration");
717 log_debug(
"reloading appsync configuration");
723 gchar *config = config_get_mode_setting(current_user);
726 log_warning(
"default mode '%s' is not valid, reset to '%s'",
728 config_set_mode_setting(
MODE_ASK, current_user);
731 log_debug(
"default mode '%s' is still valid", config);
740 const char *current = control_get_target_mode();
744 log_debug(
"current mode '%s' is internal", current);
749 log_warning(
"current mode '%s' is not valid, re-evaluating",
760 log_debug(
"current mode '%s' is still valid", current);
764 log_debug(
"broadcast mode availability lists");
775 static bool usbmoded_init(
void)
777 LOG_REGISTER_CONTEXT;
784 if( !worker_init() ) {
785 log_crit(
"worker thread init failed");
790 log_crit(
"signal handler init failed");
795 usbmoded_set_rescue_mode(
false);
796 log_warning(
"init done passed; rescue mode ignored");
801 log_crit(
"dbus systembus connection failed");
812 if( !dsme_start_listener() ) {
813 log_crit(
"dsme tracking could not be started");
821 if( !devicelock_start_listener() ) {
822 log_crit(
"devicelock tracking could not be started");
832 log_crit(
"Cannot create or find a valid configuration");
843 if(config_check_trigger())
847 if(access(
"/etc/modprobe.d/g_ether.conf", F_OK) != 0)
849 mac_generate_random_mac();
861 for(
int i = 10; ; ) {
873 log_crit(
"No supported usb control mechanisms found");
881 if( !systemd_control_start() ) {
882 log_crit(
"systemd control could not be started");
896 log_warning(
"usb-moded started after init-done; "
897 "forcing appsync stop");
906 log_crit(
"usb-moded dbus service init failed");
914 if( !umudev_init() && !usbmoded_hw_fallback ) {
915 log_crit(
"hwal init failed");
921 if ( !user_watch_init() ) {
922 log_crit(
"user watch init failed");
935 if( usbmoded_hw_fallback ) {
936 log_warning(
"Forcing USB state to connected always. ASK mode non functional!");
949 static void usbmoded_cleanup(
void)
951 LOG_REGISTER_CONTEXT;
974 systemd_control_stop();
978 devicelock_stop_listener();
983 dsme_stop_listener();
1006 worker_clear_kernel_module();
1007 worker_clear_hardware_mode();
1008 control_clear_cable_state();
1009 control_clear_internal_mode();
1010 control_clear_external_mode();
1011 control_clear_target_mode();
1019 # ifdef APP_SYNC_DBUS
1029 static const char usbmoded_usage_info[] =
1030 "Usage: usb_moded [OPTION]...\n"
1033 " -a, --android_usb_broken\n"
1034 " keep gadget active on broken android kernels\n"
1035 " -i, --android_usb_broken_udev_events\n"
1036 " ignore incorrect disconnect events after mode setting\n"
1038 " assume always connected\n"
1039 " -s, --force-syslog\n"
1041 " -T, --force-stderr\n"
1043 " -l, --log-line-info\n"
1044 " log to stderr and show origin of logging\n"
1046 " turn on debug printing\n"
1048 " turn on diag mode\n"
1050 " display this help and exit\n"
1055 " notify systemd when started up\n"
1058 " output version information and exit\n"
1059 " -m, --max-cable-delay=<ms>\n"
1060 " maximum delay before accepting cable connection\n"
1061 " -b, --android-bootup-function=<function>\n"
1062 " Setup given function during bootup. Might be required\n"
1063 " on some devices to make enumeration work on the 1st\n"
1065 " -I --dbus-introspect-xml\n"
1066 " Dump usb-moded D-Bus introspect data to stdout.\n"
1067 " -B --dbus-busconfig-xml\n"
1068 " Dump usb-moded D-Bus busconfig data to stdout.\n"
1071 static const struct option usbmoded_long_options[] =
1073 {
"android_usb_broken", no_argument, 0,
'a' },
1074 {
"android_usb_broken_udev_events", no_argument, 0,
'i' },
1075 {
"fallback", no_argument, 0,
'd' },
1076 {
"force-syslog", no_argument, 0,
's' },
1077 {
"force-stderr", no_argument, 0,
'T' },
1078 {
"log-line-info", no_argument, 0,
'l' },
1079 {
"debug", no_argument, 0,
'D' },
1080 {
"diag", no_argument, 0,
'd' },
1081 {
"help", no_argument, 0,
'h' },
1082 {
"rescue", no_argument, 0,
'r' },
1083 {
"systemd", no_argument, 0,
'n' },
1084 {
"version", no_argument, 0,
'v' },
1085 {
"max-cable-delay", required_argument, 0,
'm' },
1086 {
"android-bootup-function", required_argument, 0,
'b' },
1087 {
"auto-exit", no_argument, 0,
'Q' },
1088 {
"dbus-introspect-xml", no_argument, 0,
'I' },
1089 {
"dbus-busconfig-xml", no_argument, 0,
'B' },
1093 static const char usbmoded_short_options[] =
"aifsTlDdhrnvm:b:QIB";
1096 static void usbmoded_usage(
void)
1098 LOG_REGISTER_CONTEXT;
1100 fprintf(stdout,
"%s", usbmoded_usage_info);
1103 static void usbmoded_parse_options(
int argc,
char* argv[])
1105 LOG_REGISTER_CONTEXT;
1109 int opt = getopt_long(argc, argv,
1110 usbmoded_short_options,
1111 usbmoded_long_options,
1119 log_warning(
"Deprecated option: --android_usb_broken");
1122 log_warning(
"Deprecated option: --android_usb_broken_udev_events");
1125 usbmoded_hw_fallback =
true;
1128 log_set_type(LOG_TO_SYSLOG);
1132 log_set_type(LOG_TO_STDERR);
1140 log_set_type(LOG_TO_STDERR);
1145 usbmoded_set_diag_mode(
true);
1153 usbmoded_set_rescue_mode(
true);
1157 usbmoded_systemd_notify =
true;
1161 printf(
"USB mode daemon version: %s\n", VERSION);
1169 log_warning(
"Deprecated option: --android-bootup-function");
1173 usbmoded_auto_exit =
true;
1191 int main(
int argc,
char* argv[])
1193 LOG_REGISTER_CONTEXT;
1198 #if !GLIB_CHECK_VERSION(2, 36, 0)
1201 #if !GLIB_CHECK_VERSION(2, 31, 0)
1202 g_thread_init(NULL);
1204 dbus_threads_init_default();
1215 usbmoded_parse_options(argc, argv);
1217 fprintf(stderr,
"usb_moded %s starting\n", VERSION);
1223 if( !freopen(
"/dev/null",
"a", stdout) ) {
1224 log_err(
"can't redirect stdout: %m");
1226 if( !freopen(
"/dev/null",
"a", stderr) ) {
1227 log_err(
"can't redirect stderr: %m");
1235 if( !usbmoded_init() )
1244 if( usbmoded_systemd_notify ) {
1245 log_debug(
"notifying systemd");
1246 sd_notify(0,
"READY=1");
1251 usbmoded_exitcode = EXIT_SUCCESS;
1255 if( usbmoded_auto_exit )
1258 usbmoded_mainloop = g_main_loop_new(NULL, FALSE);
1260 log_debug(
"enter usb-moded mainloop");
1261 g_main_loop_run(usbmoded_mainloop);
1262 log_debug(
"leave usb-moded mainloop");
1264 g_main_loop_unref(usbmoded_mainloop),
1265 usbmoded_mainloop = 0;
1286 log_debug(
"usb-moded return from main, with exit code %d",
1288 return usbmoded_exitcode;