Commit 0c076963 authored by spiiroin's avatar spiiroin

Merge branch 'jb41747_initial_state' into 'master'

Optionally force an USB function on bootup

See merge request !35
parents aaaa8494 6b38de2b
......@@ -23,6 +23,7 @@
#include <stdio.h>
#include <glib.h>
#include "usb_moded.h"
#include "usb_moded-android.h"
#include "usb_moded-log.h"
#include "usb_moded-modesetting.h"
......@@ -84,11 +85,17 @@ void android_init_values(void)
{
gchar *text;
/* If the directory is not there, no point emitting warnings
* about every file that is not going to be there either. */
if( access("/sys/class/android_usb/android0", F_OK) != 0 )
{
goto EXIT;
}
/* Disable */
write_to_file("/sys/class/android_usb/android0/enable", "0");
/* Configure */
if( (text = get_android_serial()) )
{
write_to_file("/sys/class/android_usb/android0/iSerial", text);
......@@ -128,8 +135,22 @@ void android_init_values(void)
/* For rndis to be discovered correctly in M$ Windows (vista and later) */
write_to_file("/sys/class/android_usb/f_rndis/wceis", "1");
/* Make sure android_usb does not stay disabled in case usb moded
* has crashed / been killed in inconvenient time. */
/* Some devices can have enumeration issues due to incomplete
* configuration on the 1st connect after bootup. Briefly setting
* up for example mass_storage function can be utilized as a
* workaround in such cases. */
if(!init_done_p()) {
const char *function = get_android_bootup_function();
if(function) {
write_to_file("/sys/class/android_usb/android0/functions", function);
write_to_file("/sys/class/android_usb/android0/enable", "1");
write_to_file("/sys/class/android_usb/android0/enable", "0");
}
}
/* Clear functions and enable */
write_to_file("/sys/class/android_usb/android0/functions", "none");
write_to_file("/sys/class/android_usb/android0/enable", "1");
EXIT:
......
......@@ -194,6 +194,9 @@ static DBusHandlerResult msg_handler(DBusConnection *const connection, DBusMessa
if( type == DBUS_MESSAGE_TYPE_SIGNAL )
{
if( !strcmp(interface, INIT_DONE_INTERFACE) && !strcmp(member, INIT_DONE_SIGNAL) ) {
/* Update the cached state value */
set_init_done(true);
/* Auto-disable rescue mode when bootup is finished */
if( rescue_mode ) {
rescue_mode = FALSE;
......@@ -598,6 +601,9 @@ gboolean usb_moded_dbus_init_connection(void)
/* Listen to init-done signals */
dbus_bus_add_match(dbus_connection_sys, INIT_DONE_MATCH, 0);
/* Re-check flag file after adding signal listener */
probe_init_done();
/* Connect D-Bus to the mainloop */
dbus_connection_setup_with_g_main(dbus_connection_sys, NULL);
......
......@@ -92,6 +92,30 @@ static gboolean android_ignore_next_udev_disconnect_event = FALSE;
static gboolean systemd_notify = FALSE;
#endif
/** Optional android usb function to setup during bootup */
static gchar *android_bootup_function = 0;
/** Get android usb function to setup during bootup
*
* @returns function name, or NULL if no function was requested
*/
const char *get_android_bootup_function(void)
{
return android_bootup_function;
}
/** Set android usb function to setup during bootup
*
* @param function usb function name, or NULL
*/
void set_android_bootup_function(const char *function)
{
char *value = function ? g_strdup(function) : 0;
g_free(android_bootup_function);
android_bootup_function = value;
}
/** Default allowed cable detection delay
*
* To comply with USB standards, the delay should be
......@@ -150,7 +174,6 @@ static gboolean set_disconnected_silent(gpointer data);
static void usb_moded_init(void);
static gboolean charging_fallback(gpointer data);
static void usage(void);
static bool init_done_p(void);
/* ============= Implementation starts here =========================================== */
/** set the usb connection status
......@@ -850,24 +873,41 @@ static void usage(void)
{
fprintf(stdout,
"Usage: usb_moded [OPTION]...\n"
"USB mode daemon\n"
"\n"
" -a, --android_usb_broken \tkeep gadget active on broken android kernels\n"
" -i, --android_usb_broken_udev_events \tignore incorrect disconnect events after mode setting\n"
" -f, --fallback \tassume always connected\n"
" -s, --force-syslog \t\tlog to syslog\n"
" -T, --force-stderr \t\tlog to stderr\n"
" -l, --log-line-info \t\tlog to stderr and show origin of logging\n"
" -D, --debug \t\tturn on debug printing\n"
" -d, --diag \t\tturn on diag mode\n"
" -h, --help \t\tdisplay this help and exit\n"
" -r, --rescue \t\trescue mode\n"
"USB mode daemon\n"
"\n"
" -a, --android_usb_broken\n"
" keep gadget active on broken android kernels\n"
" -i, --android_usb_broken_udev_events\n"
" ignore incorrect disconnect events after mode setting\n"
" -f, --fallback \n"
" assume always connected\n"
" -s, --force-syslog \n"
" log to syslog\n"
" -T, --force-stderr \n"
" log to stderr\n"
" -l, --log-line-info\n"
" log to stderr and show origin of logging\n"
" -D, --debug \n"
" turn on debug printing\n"
" -d, --diag \n"
" turn on diag mode\n"
" -h, --help \n"
" display this help and exit\n"
" -r, --rescue \n"
" rescue mode\n"
#ifdef SYSTEMD
" -n, --systemd \t\tnotify systemd when started up\n"
" -n, --systemd \n"
" notify systemd when started up\n"
#endif
" -v, --version \t\toutput version information and exit\n"
" -m, --max-cable-delay=<ms>\tmaximum delay before accepting cable connection\n"
"\n");
" -v, --version \n"
" output version information and exit\n"
" -m, --max-cable-delay=<ms>\n"
" maximum delay before accepting cable connection\n"
" -b, --android-bootup-function=<function>\n"
" Setup given function during bootup. Might be required\n"
" on some devices to make enumeration work on the 1st\n"
" cable connect.\n"
"\n");
}
void send_supported_modes_signal(void)
......@@ -1192,13 +1232,35 @@ void delay_suspend(void)
allow_suspend_cb, 0);
}
/** Path to init-done flag file */
static const char init_done_flagfile[] = "/run/systemd/boot-status/init-done";
/** cached init-done-reached state */
static bool init_done_reached = false;
/** Check if system has already been successfully booted up
*
* @return true if init-done has been reached, or false otherwise
*/
static bool init_done_p(void)
bool init_done_p(void)
{
return init_done_reached;
}
/** Update cached init-done-reached state */
void set_init_done(bool reached)
{
if( init_done_reached != reached ) {
init_done_reached = reached;
log_debug("init_done -> %s",
init_done_reached ? "reached" : "not reached");
}
}
/** Check whether init-done flag file exists */
void probe_init_done(void)
{
return access("/run/systemd/boot-status/init-done", F_OK) == 0;
set_init_done(access(init_done_flagfile, F_OK) == 0);
}
/** Request orderly exit from mainloop
......@@ -1298,6 +1360,7 @@ int main(int argc, char* argv[])
{ "systemd", no_argument, 0, 'n' },
{ "version", no_argument, 0, 'v' },
{ "max-cable-delay", required_argument, 0, 'm' },
{ "android-bootup-function", required_argument, 0, 'b' },
{ 0, 0, 0, 0 }
};
......@@ -1309,7 +1372,7 @@ int main(int argc, char* argv[])
* - - - - - - - - - - - - - - - - - - - */
/* Parse the command-line options */
while ((opt = getopt_long(argc, argv, "aifsTlDdhrnvm:", options, &opt_idx)) != -1)
while ((opt = getopt_long(argc, argv, "aifsTlDdhrnvm:b:", options, &opt_idx)) != -1)
{
switch (opt)
{
......@@ -1363,6 +1426,10 @@ int main(int argc, char* argv[])
set_cable_connection_delay(strtol(optarg, 0, 0));
break;
case 'b':
set_android_bootup_function(optarg);
break;
default:
usage();
exit(0);
......@@ -1394,6 +1461,9 @@ int main(int argc, char* argv[])
g_thread_init(NULL);
#endif
/* Check if we are in mid-bootup */
probe_init_done();
/* Must be the 1st libdbus call that is made */
dbus_threads_init_default();
......@@ -1565,6 +1635,8 @@ EXIT:
# endif
#endif
set_android_bootup_function(0);
/* Must be done just before exit to make sure no more wakelocks
* are taken and left behind on exit path */
allow_suspend();
......
......@@ -25,6 +25,7 @@
#define USB_MODED_H_
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
......@@ -103,4 +104,11 @@ void usb_moded_usleep_(const char *file, int line, const char *func, useconds_t
#define usb_moded_msleep(msec) usb_moded_usleep_(__FILE__,__LINE__,__FUNCTION__,(msec)*1000)
#define usb_moded_sleep(sec) usb_moded_usleep_(__FILE__,__LINE__,__FUNCTION__,(sec)*1000000)
bool init_done_p(void);
void set_init_done(bool reached);
void probe_init_done(void);
const char *get_android_bootup_function(void);
void set_android_bootup_function(const char *function);
#endif /* USB_MODED_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment