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
117bool usbmoded_get_rescue_mode (
void);
118void usbmoded_set_rescue_mode (
bool rescue_mode);
119bool usbmoded_get_diag_mode (
void);
120void usbmoded_set_diag_mode (
bool diag_mode);
121bool usbmoded_is_mode_permitted (
const char *modename, uid_t uid);
124static gboolean usbmoded_allow_suspend_timer_cb (gpointer aptr);
135void usbmoded_handle_signal (
int signum);
136static bool usbmoded_init (
void);
137static void usbmoded_cleanup (
void);
138static void usbmoded_usage (
void);
139static void usbmoded_parse_options (
int argc,
char *argv[]);
145int main(
int argc,
char *argv[]);
151static int usbmoded_exitcode = EXIT_FAILURE;
152static GMainLoop *usbmoded_mainloop = NULL;
154static bool usbmoded_hw_fallback =
false;
156static bool usbmoded_systemd_notify =
false;
158static bool usbmoded_auto_exit =
false;
160static 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);\
188static 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;
302static bool usbmoded_rescue_mode =
false;
304bool usbmoded_get_rescue_mode(
void)
306 LOG_REGISTER_CONTEXT;
308 return usbmoded_rescue_mode;
311void 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;
330static int usbmoded_diag_mode = -1;
332bool 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;
344void 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);
363bool 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;
454static bool usbmoded_blocking_suspend =
false;
457static guint usbmoded_allow_suspend_timer_id = 0;
463static 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() )
616static const char usbmoded_init_done_flagfile[] =
"/run/systemd/boot-status/init-done";
619static 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);
685void 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");
775static 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!");
949static 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
1029static 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"
1071static 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' },
1093static const char usbmoded_short_options[] =
"aifsTlDdhrnvm:b:QIB";
1096static void usbmoded_usage(
void)
1098 LOG_REGISTER_CONTEXT;
1100 fprintf(stdout,
"%s", usbmoded_usage_info);
1103static 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;
1191int 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;
void dbusappsync_cleanup(void)
void appsync_free_configuration(void)
void appsync_deactivate_all(bool force)
void appsync_load_configuration(void)
void common_release_wakelock(const char *wakelock_name)
int common_valid_mode(const char *mode)
void common_send_available_modes_signal(void)
void common_send_whitelisted_modes_signal(void)
void common_send_hidden_modes_signal(void)
bool common_modename_is_internal(const char *modename)
void common_acquire_wakelock(const char *wakelock_name)
void common_send_supported_modes_signal(void)
void control_settings_changed(void)
void control_set_cable_state(cable_state_t cable_state)
void control_init_done_changed(void)
void control_set_enabled(bool enable)
void umdbus_dump_introspect_xml(void)
void umdbus_cleanup(void)
gboolean umdbus_init_service(void)
void umdbus_dump_busconfig_xml(void)
gboolean umdbus_init_connection(void)
bool devicelock_have_export_permission(void)
bool dsme_state_is_user(void)
bool dsme_state_is_shutdown(void)
void modelist_free(GList *modelist)
void modedata_free(modedata_t *self)
modedata_t * modedata_copy(const modedata_t *that)
GList * modelist_load(bool diag)
void log_set_level(int lev)
void log_set_name(const char *name)
void log_set_lineinfo(bool lineinfo)
void modesetting_init(void)
void modesetting_quit(void)
uid_t user_get_current_user(void)
void usbmoded_set_cable_connection_delay(int delay_ms)
void usbmoded_exit_mainloop(int exitcode)
bool usbmoded_in_usermode(void)
#define CABLE_CONNECTION_DELAY_DEFAULT
#define CABLE_CONNECTION_DELAY_MAXIMUM
void usbmoded_set_init_done(bool reached)
const modedata_t * usbmoded_get_modedata(const char *modename)
GList * usbmoded_get_modelist(void)
bool usbmoded_init_done_p(void)
void usbmoded_delay_suspend(void)
int usbmoded_get_cable_connection_delay(void)
bool usbmoded_in_shutdown(void)
void usbmoded_load_modelist(void)
modedata_t * usbmoded_dup_modedata(const char *modename)
bool usbmoded_can_export(void)
void usbmoded_allow_suspend(void)
void usbmoded_probe_init_done(void)
uid_t usbmoded_get_current_user(void)
void usbmoded_free_modelist(void)
#define USB_MODED_SUSPEND_DELAY_DEFAULT_MS
#define USB_MODED_WAKELOCK_STATE_CHANGE