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
115static modedata_t *usbmoded_lookup_modedata (
const char *modename);
119bool usbmoded_get_rescue_mode (
void);
120void usbmoded_set_rescue_mode (
bool rescue_mode);
121bool usbmoded_get_diag_mode (
void);
122void usbmoded_set_diag_mode (
bool diag_mode);
123bool usbmoded_is_mode_permitted (
const char *modename, uid_t uid);
126static gboolean usbmoded_allow_suspend_timer_cb (gpointer aptr);
137void usbmoded_handle_signal (
int signum);
138static bool usbmoded_init (
void);
139static void usbmoded_cleanup (
void);
140static void usbmoded_usage (
void);
141static void usbmoded_parse_options (
int argc,
char *argv[]);
147int main(
int argc,
char *argv[]);
153static int usbmoded_exitcode = EXIT_FAILURE;
154static GMainLoop *usbmoded_mainloop = NULL;
156static bool usbmoded_hw_fallback =
false;
158static bool usbmoded_systemd_notify =
false;
160static bool usbmoded_auto_exit =
false;
162static pthread_mutex_t usbmoded_mutex = PTHREAD_MUTEX_INITIALIZER;
164#define USBMODED_LOCKED_ENTER do {\
165 if( pthread_mutex_lock(&usbmoded_mutex) != 0 ) { \
166 log_crit("USBMODED LOCK FAILED");\
167 _exit(EXIT_FAILURE);\
171#define USBMODED_LOCKED_LEAVE do {\
172 if( pthread_mutex_unlock(&usbmoded_mutex) != 0 ) { \
173 log_crit("USBMODED UNLOCK FAILED");\
174 _exit(EXIT_FAILURE);\
190static GList *usbmoded_modelist = 0;
201 LOG_REGISTER_CONTEXT;
203 return usbmoded_modelist;
213 LOG_REGISTER_CONTEXT;
215 USBMODED_LOCKED_ENTER;
217 if( !usbmoded_modelist ) {
218 log_notice(
"load modelist");
222 USBMODED_LOCKED_LEAVE;
232 LOG_REGISTER_CONTEXT;
234 USBMODED_LOCKED_ENTER;
236 if( usbmoded_modelist ) {
237 log_notice(
"free modelist");
239 usbmoded_modelist = 0;
242 USBMODED_LOCKED_LEAVE;
254usbmoded_lookup_modedata(
const char *modename)
256 LOG_REGISTER_CONTEXT;
262 if( !g_strcmp0(data->
mode_name, modename) ) {
281 LOG_REGISTER_CONTEXT;
283 return usbmoded_lookup_modedata(modename);
297 LOG_REGISTER_CONTEXT;
299 modedata_t *modedata = usbmoded_lookup_modedata(modename);
301 modedata_cache_settings(modedata);
317 LOG_REGISTER_CONTEXT;
319 USBMODED_LOCKED_ENTER;
323 USBMODED_LOCKED_LEAVE;
338static bool usbmoded_rescue_mode =
false;
340bool usbmoded_get_rescue_mode(
void)
342 LOG_REGISTER_CONTEXT;
344 return usbmoded_rescue_mode;
347void usbmoded_set_rescue_mode(
bool rescue_mode)
349 LOG_REGISTER_CONTEXT;
351 if( usbmoded_rescue_mode != rescue_mode ) {
352 log_info(
"rescue_mode: %d -> %d", usbmoded_rescue_mode, rescue_mode);
353 usbmoded_rescue_mode = rescue_mode;
366static int usbmoded_diag_mode = -1;
368bool usbmoded_get_diag_mode(
void)
370 LOG_REGISTER_CONTEXT;
372 if( usbmoded_diag_mode == -1 ) {
373 usbmoded_diag_mode =
false;
374 log_info(
"diag_mode: locked to %d", usbmoded_diag_mode);
377 return usbmoded_diag_mode;
380void usbmoded_set_diag_mode(
bool diag_mode)
382 LOG_REGISTER_CONTEXT;
384 if( usbmoded_diag_mode != diag_mode ) {
385 if( usbmoded_diag_mode == -1 ) {
386 usbmoded_diag_mode = diag_mode;
387 log_info(
"diag_mode: set to %d", usbmoded_diag_mode);
390 log_err(
"dig_mode: already locked to %d", usbmoded_diag_mode);
399bool usbmoded_is_mode_permitted(
const char *modename, uid_t uid)
401#ifdef SAILFISH_ACCESS_CONTROL
402 LOG_REGISTER_CONTEXT;
413 if( uid == UID_UNKNOWN ) {
424 group = config_get_group_for_mode(modename);
425 allowed = sailfish_access_control_hasgroup(uid, group);
460 LOG_REGISTER_CONTEXT;
467 if( usbmoded_cable_connection_delay != delay_ms ) {
468 log_info(
"cable_connection_delay: %d -> %d",
469 usbmoded_cable_connection_delay,
471 usbmoded_cable_connection_delay = delay_ms;
480 LOG_REGISTER_CONTEXT;
482 return usbmoded_cable_connection_delay;
490static bool usbmoded_blocking_suspend =
false;
493static guint usbmoded_allow_suspend_timer_id = 0;
499static gboolean usbmoded_allow_suspend_timer_cb(gpointer aptr)
501 LOG_REGISTER_CONTEXT;
505 usbmoded_allow_suspend_timer_id = 0;
519 LOG_REGISTER_CONTEXT;
521 if( usbmoded_allow_suspend_timer_id ) {
522 g_source_remove(usbmoded_allow_suspend_timer_id),
523 usbmoded_allow_suspend_timer_id = 0;
526 if( usbmoded_blocking_suspend ) {
527 usbmoded_blocking_suspend =
false;
544 LOG_REGISTER_CONTEXT;
550 usbmoded_blocking_suspend =
true;
552 if( usbmoded_allow_suspend_timer_id )
553 g_source_remove(usbmoded_allow_suspend_timer_id);
555 usbmoded_allow_suspend_timer_id =
557 usbmoded_allow_suspend_timer_cb, 0);
571 LOG_REGISTER_CONTEXT;
587 LOG_REGISTER_CONTEXT;
610 LOG_REGISTER_CONTEXT;
629 LOG_REGISTER_CONTEXT;
631 bool can_export =
true;
640 if( usbmoded_get_rescue_mode() )
652static const char usbmoded_init_done_flagfile[] =
"/run/systemd/boot-status/init-done";
655static bool usbmoded_init_done_reached =
false;
663 LOG_REGISTER_CONTEXT;
665 return usbmoded_init_done_reached;
671 LOG_REGISTER_CONTEXT;
673 if( usbmoded_init_done_reached != reached ) {
674 usbmoded_init_done_reached = reached;
675 log_warning(
"init_done -> %s",
676 usbmoded_init_done_reached ?
"reached" :
"not reached");
679 if( usbmoded_init_done_reached )
680 usbmoded_set_rescue_mode(
false);
689 LOG_REGISTER_CONTEXT;
702 LOG_REGISTER_CONTEXT;
706 if( usbmoded_exitcode < exitcode )
707 usbmoded_exitcode = exitcode;
710 if( !usbmoded_mainloop )
712 log_warning(
"exit requested outside mainloop; exit(%d) now",
714 exit(usbmoded_exitcode);
717 log_debug(
"stopping usb-moded mainloop");
718 g_main_loop_quit(usbmoded_mainloop);
721void usbmoded_handle_signal(
int signum)
723 LOG_REGISTER_CONTEXT;
725 log_debug(
"handle signal: %s\n", strsignal(signum));
727 if( signum == SIGTERM )
732 else if( signum == SIGHUP )
740 log_debug(
"reloading dynamic mode configuration");
753 log_debug(
"reloading appsync configuration");
759 gchar *config = config_get_mode_setting(current_user);
762 log_warning(
"default mode '%s' is not valid, reset to '%s'",
764 config_set_mode_setting(
MODE_ASK, current_user);
767 log_debug(
"default mode '%s' is still valid", config);
776 const char *current = control_get_target_mode();
780 log_debug(
"current mode '%s' is internal", current);
785 log_warning(
"current mode '%s' is not valid, re-evaluating",
796 log_debug(
"current mode '%s' is still valid", current);
800 log_debug(
"broadcast mode availability lists");
811static bool usbmoded_init(
void)
813 LOG_REGISTER_CONTEXT;
820 if( !worker_init() ) {
821 log_crit(
"worker thread init failed");
826 log_crit(
"signal handler init failed");
831 usbmoded_set_rescue_mode(
false);
832 log_warning(
"init done passed; rescue mode ignored");
837 log_crit(
"dbus systembus connection failed");
848 if( !dsme_start_listener() ) {
849 log_crit(
"dsme tracking could not be started");
857 if( !devicelock_start_listener() ) {
858 log_crit(
"devicelock tracking could not be started");
868 log_crit(
"Cannot create or find a valid configuration");
879 if(config_check_trigger())
883 if(access(
"/etc/modprobe.d/g_ether.conf", F_OK) != 0)
885 mac_generate_random_mac();
897 for(
int i = 10; ; ) {
909 log_crit(
"No supported usb control mechanisms found");
917 if( !systemd_control_start() ) {
918 log_crit(
"systemd control could not be started");
932 log_warning(
"usb-moded started after init-done; "
933 "forcing appsync stop");
942 log_crit(
"usb-moded dbus service init failed");
950 if( !umudev_init() && !usbmoded_hw_fallback ) {
951 log_crit(
"hwal init failed");
957 if ( !user_watch_init() ) {
958 log_crit(
"user watch init failed");
971 if( usbmoded_hw_fallback ) {
972 log_warning(
"Forcing USB state to connected always. ASK mode non functional!");
985static void usbmoded_cleanup(
void)
987 LOG_REGISTER_CONTEXT;
1010 systemd_control_stop();
1014 devicelock_stop_listener();
1019 dsme_stop_listener();
1042 worker_clear_kernel_module();
1043 worker_clear_hardware_mode();
1044 control_clear_cable_state();
1045 control_clear_internal_mode();
1046 control_clear_external_mode();
1047 control_clear_target_mode();
1055# ifdef APP_SYNC_DBUS
1065static const char usbmoded_usage_info[] =
1066"Usage: usb_moded [OPTION]...\n"
1069" -a, --android_usb_broken\n"
1070" keep gadget active on broken android kernels\n"
1071" -i, --android_usb_broken_udev_events\n"
1072" ignore incorrect disconnect events after mode setting\n"
1074" assume always connected\n"
1075" -s, --force-syslog\n"
1077" -T, --force-stderr\n"
1079" -l, --log-line-info\n"
1080" log to stderr and show origin of logging\n"
1082" turn on debug printing\n"
1084" turn on diag mode\n"
1086" display this help and exit\n"
1091" notify systemd when started up\n"
1094" output version information and exit\n"
1095" -m, --max-cable-delay=<ms>\n"
1096" maximum delay before accepting cable connection\n"
1097" -b, --android-bootup-function=<function>\n"
1098" Setup given function during bootup. Might be required\n"
1099" on some devices to make enumeration work on the 1st\n"
1101" -I --dbus-introspect-xml\n"
1102" Dump usb-moded D-Bus introspect data to stdout.\n"
1103" -B --dbus-busconfig-xml\n"
1104" Dump usb-moded D-Bus busconfig data to stdout.\n"
1107static const struct option usbmoded_long_options[] =
1109 {
"android_usb_broken", no_argument, 0,
'a' },
1110 {
"android_usb_broken_udev_events", no_argument, 0,
'i' },
1111 {
"fallback", no_argument, 0,
'd' },
1112 {
"force-syslog", no_argument, 0,
's' },
1113 {
"force-stderr", no_argument, 0,
'T' },
1114 {
"log-line-info", no_argument, 0,
'l' },
1115 {
"debug", no_argument, 0,
'D' },
1116 {
"diag", no_argument, 0,
'd' },
1117 {
"help", no_argument, 0,
'h' },
1118 {
"rescue", no_argument, 0,
'r' },
1119 {
"systemd", no_argument, 0,
'n' },
1120 {
"version", no_argument, 0,
'v' },
1121 {
"max-cable-delay", required_argument, 0,
'm' },
1122 {
"android-bootup-function", required_argument, 0,
'b' },
1123 {
"auto-exit", no_argument, 0,
'Q' },
1124 {
"dbus-introspect-xml", no_argument, 0,
'I' },
1125 {
"dbus-busconfig-xml", no_argument, 0,
'B' },
1129static const char usbmoded_short_options[] =
"aifsTlDdhrnvm:b:QIB";
1132static void usbmoded_usage(
void)
1134 LOG_REGISTER_CONTEXT;
1136 fprintf(stdout,
"%s", usbmoded_usage_info);
1139static void usbmoded_parse_options(
int argc,
char* argv[])
1141 LOG_REGISTER_CONTEXT;
1145 int opt = getopt_long(argc, argv,
1146 usbmoded_short_options,
1147 usbmoded_long_options,
1155 log_warning(
"Deprecated option: --android_usb_broken");
1158 log_warning(
"Deprecated option: --android_usb_broken_udev_events");
1161 usbmoded_hw_fallback =
true;
1164 log_set_type(LOG_TO_SYSLOG);
1168 log_set_type(LOG_TO_STDERR);
1176 log_set_type(LOG_TO_STDERR);
1181 usbmoded_set_diag_mode(
true);
1189 usbmoded_set_rescue_mode(
true);
1193 usbmoded_systemd_notify =
true;
1197 printf(
"USB mode daemon version: %s\n", VERSION);
1205 log_warning(
"Deprecated option: --android-bootup-function");
1209 usbmoded_auto_exit =
true;
1227int main(
int argc,
char* argv[])
1229 LOG_REGISTER_CONTEXT;
1234#if !GLIB_CHECK_VERSION(2, 36, 0)
1237#if !GLIB_CHECK_VERSION(2, 31, 0)
1238 g_thread_init(NULL);
1240 dbus_threads_init_default();
1251 usbmoded_parse_options(argc, argv);
1253 fprintf(stderr,
"usb_moded %s starting\n", VERSION);
1259 if( !freopen(
"/dev/null",
"a", stdout) ) {
1260 log_err(
"can't redirect stdout: %m");
1262 if( !freopen(
"/dev/null",
"a", stderr) ) {
1263 log_err(
"can't redirect stderr: %m");
1271 if( !usbmoded_init() )
1280 if( usbmoded_systemd_notify ) {
1281 log_debug(
"notifying systemd");
1282 sd_notify(0,
"READY=1");
1287 usbmoded_exitcode = EXIT_SUCCESS;
1291 if( usbmoded_auto_exit )
1294 usbmoded_mainloop = g_main_loop_new(NULL, FALSE);
1296 log_debug(
"enter usb-moded mainloop");
1297 g_main_loop_run(usbmoded_mainloop);
1298 log_debug(
"leave usb-moded mainloop");
1300 g_main_loop_unref(usbmoded_mainloop),
1301 usbmoded_mainloop = 0;
1322 log_debug(
"usb-moded return from main, with exit code %d",
1324 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)
void usbmoded_refresh_modedata(const char *modename)
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