Commit 5e9e4e44 authored by spiiroin's avatar spiiroin

Merge branch 'jb38422_serialno' into 'master'

Set usb serial number and watch out for unexpected changes

See merge request !26
parents f1a17e3c 0debddb6
......@@ -75,7 +75,7 @@ AM_CONDITIONAL([CONNMAN], [test x$connman = xtrue])
AC_ARG_ENABLE([systemd], AS_HELP_STRING([--enable-systemd], [Enable systemd notify interface @<:@default=false@:>@]),
[case "${enableval}" in
yes) systemd=true ; CFLAGS="-DSYSTEMD -lsystemd-daemon $CFLAGS" ;;
yes) systemd=true ; CFLAGS="-DSYSTEMD $CFLAGS" ;;
no) systemd=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-systemd]) ;;
esac],[systemd=false])
......@@ -98,6 +98,8 @@ PKG_CHECK_MODULES([USB_MODED], [
libudev
libkmod
ssu-sysinfo
libsystemd
dsme
])
AC_SUBST(USB_MODED_LIBS)
......
......@@ -14,8 +14,9 @@ BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(udev)
BuildRequires: pkgconfig(libkmod)
BuildRequires: doxygen
BuildRequires: pkgconfig(libsystemd-daemon)
BuildRequires: pkgconfig(libsystemd)
BuildRequires: pkgconfig(ssu-sysinfo)
BuildRequires: pkgconfig(dsme)
Requires: lsof
Requires: usb-moded-configs
......
......@@ -43,11 +43,65 @@ int android_settings(void)
return ret;
}
/** Read android serial number from kernel command line
*/
static gchar *get_android_serial(void)
{
static const char path[] = "/proc/cmdline";
static const char find[] = "androidboot.serialno=";
static const char pbrk[] = " \t\r\n,";
char *res = 0;
FILE *file = 0;
size_t size = 0;
char *data = 0;
if( !(file = fopen(path, "r")) ) {
log_warning("%s: %s: %m", path, "can't open");
goto EXIT;
}
if( getline(&data, &size, file) < 0 ) {
log_warning("%s: %s: %m", path, "can't read");
goto EXIT;
}
char *beg = strstr(data, find);
if( !beg ) {
log_warning("%s: no serial found", path);
goto EXIT;
}
beg += sizeof find - 1;
size_t len = strcspn(beg, pbrk);
if( len < 1 ) {
log_warning("%s: empty serial found", path);
goto EXIT;
}
res = g_strndup(beg, len);
EXIT:
free(data);
if( file )
fclose(file);
return res;
}
/** initialize the basic android values
*/
void android_init_values(void)
{
char *text;
gchar *text;
if( (text = get_android_serial()) )
{
write_to_file("/sys/class/android_usb/android0/iSerial", text);
g_free(text);
}
text = get_android_manufacturer();
if(text)
......
This diff is collapsed.
......@@ -47,10 +47,68 @@
#include "usb_moded-network.h"
#include "usb_moded-android.h"
static char *read_from_file(const char *path, size_t maxsize);
static GHashTable *tracked_values = 0;
static void usb_moded_mode_track_value(const char *path, const char *text)
{
if( !tracked_values || !path )
goto EXIT;
if( text )
g_hash_table_replace(tracked_values, g_strdup(path), g_strdup(text));
else
g_hash_table_remove(tracked_values, path);
EXIT:
return;
}
void usb_moded_mode_verify_values(void)
{
GHashTableIter iter;
gpointer key, value;
if( !tracked_values )
goto EXIT;
g_hash_table_iter_init(&iter, tracked_values);
while( g_hash_table_iter_next(&iter, &key, &value) )
{
const char *path = key;
const char *text = value;
char *curr = read_from_file(path, 0x1000);
if( g_strcmp0(text, curr) ) {
/* There might be case mismatch between hexadecimal
* values used in configuration files vs what we get
* back when reading from kernel interfaces. */
if( text && curr && !g_ascii_strcasecmp(text, curr) ) {
log_debug("unexpected change '%s' : '%s' -> '%s'", path,
text ?: "???",
curr ?: "???");
}
else {
log_warning("unexpected change '%s' : '%s' -> '%s'", path,
text ?: "???",
curr ?: "???");
}
usb_moded_mode_track_value(path, curr);
}
free(curr);
}
EXIT:
return;
}
static void report_mass_storage_blocker(const char *mountpoint, int try);
static guint delayed_network = 0;
#if LOG_ENABLE_DEBUG
static char *strip(char *str)
{
unsigned char *src = (unsigned char *)str;
......@@ -103,27 +161,38 @@ cleanup:
if(fd != -1) close(fd);
return text;
}
#endif /* LOG_ENABLE_DEBUG */
int write_to_file(const char *path, const char *text)
int write_to_file_real(const char *file, int line, const char *func,
const char *path, const char *text)
{
int err = -1;
int fd = -1;
size_t todo = 0;
char *prev = 0;
/* if either path or the text to be written are not there
we return an error */
if(!text || !path)
return err;
#if LOG_ENABLE_DEBUG
if(log_level >= LOG_DEBUG)
{
char *prev = read_from_file(path, 0x1000);
log_debug("WRITE '%s' : '%s' --> '%s'", path, prev ?: "???", text);
free(prev);
/* There are usb-moded configuration files and code that use
* "none" as a place-holder for no-function. Attempting to
* write that into sysfs leads to journal spamming due to
* EINVAL error return. Substituting "none" with an empty
* string avoids that. */
if( !strcmp(path, "/sys/class/android_usb/android0/functions") &&
!strcmp(text, "none") ) {
text = "";
}
#endif
/* If the file can be read, it also means we can later check that
* the file retains the value we are about to write here. */
if( (prev = read_from_file(path, 0x1000)) )
usb_moded_mode_track_value(path, text);
log_debug("%s:%d: %s(): WRITE '%s' : '%s' --> '%s'",
file, line, func,
path, prev ?: "???", text);
todo = strlen(text);
......@@ -152,6 +221,8 @@ cleanup:
if( fd != -1 ) TEMP_FAILURE_RETRY(close(fd));
free(prev);
return err;
}
......@@ -590,3 +661,21 @@ int usb_moded_mode_cleanup(const char *module)
return(0);
}
/** Allocate modesetting related dynamic resouces
*/
void usb_moded_mode_init(void)
{
if( !tracked_values ) {
tracked_values = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_free);
}
}
/** Release modesetting related dynamic resouces
*/
void usb_moded_mode_quit(void)
{
if( tracked_values ) {
g_hash_table_unref(tracked_values), tracked_values = 0;
}
}
......@@ -22,9 +22,16 @@
#include "usb_moded-dyn-config.h"
int write_to_file(const char *path, const char *text);
int write_to_file_real(const char *file, int line, const char *func, const char *path, const char *text);
#define write_to_file(path,text)\
write_to_file_real(__FILE__,__LINE__,__FUNCTION__,(path),(text))
int set_mtp_mode(void);
int set_dynamic_mode(void);
void unset_dynamic_mode(void);
/* clean up for the mode changes on disconnect */
int usb_moded_mode_cleanup(const char *module);
void usb_moded_mode_verify_values(void);
void usb_moded_mode_init(void);
void usb_moded_mode_quit(void);
......@@ -1279,7 +1279,7 @@ int main(int argc, char* argv[])
* - - - - - - - - - - - - - - - - - - - */
/* silence usb_moded_system() calls */
if(log_type != LOG_TO_STDERR || log_level != LOG_DEBUG )
if(log_type != LOG_TO_STDERR && log_level != LOG_DEBUG )
{
freopen("/dev/null", "a", stdout);
freopen("/dev/null", "a", stderr);
......@@ -1337,6 +1337,7 @@ int main(int argc, char* argv[])
#endif
/* Set daemon config/state data to sane state */
usb_moded_mode_init();
usb_moded_init();
/* Allos making systemd control ipc */
......@@ -1449,6 +1450,7 @@ EXIT:
/* Release dynamically allocated config/state data */
usb_moded_cleanup();
usb_moded_mode_quit();
/* Detach from SessionBus connection used for APP_SYNC_DBUS.
*
......
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