Commit 7896a728 authored by spiiroin's avatar spiiroin

[android] Use wrapper function for all sysfs writes. JB#41748

Writing empty string gets ignored. This causes problems for example
when switching from mass-storage mode to charging only as the
lua/file attribute does not get cleared.

Use a wrapper function to append a linefeed to strings written to sysfs.
This avoids zero length writes and makes behavior similar to how
redirected echo from command line works.

Also tweak unexpected-sysfs-content-change tracker so that it ignores
changes in whitespace.
Signed-off-by: spiiroin's avatarSimo Piiroinen <simo.piiroinen@jollamobile.com>
parent e659901c
......@@ -50,6 +50,7 @@ bool android_set_charging_mode(void);
bool android_set_function (const char *function);
bool android_set_productid (const char *id);
bool android_set_vendorid (const char *id);
bool android_set_attr (const char *function, const char *attr, const char *value);
/* ========================================================================= *
* Data
......@@ -61,6 +62,29 @@ static int android_probed = -1;
* Functions
* ========================================================================= */
static bool
android_write_file(const char *path, const char *text)
{
bool ack = false;
if( !path || !text )
goto EXIT;
log_debug("WRITE %s '%s'", path, text);
char buff[64];
snprintf(buff, sizeof buff, "%s\n", text);
if( write_to_file(path, buff) == -1 )
goto EXIT;
ack = true;
EXIT:
return ack;
}
bool
android_in_use(void)
{
......@@ -146,14 +170,14 @@ android_init_values(void)
/* Configure */
if( (text = android_get_serial()) )
{
write_to_file(ANDROID0_SERIAL, text);
android_write_file(ANDROID0_SERIAL, text);
g_free(text);
}
text = config_get_android_manufacturer();
if(text)
{
write_to_file(ANDROID0_MANUFACTURER, text);
android_write_file(ANDROID0_MANUFACTURER, text);
g_free(text);
}
text = config_get_android_vendor_id();
......@@ -165,7 +189,7 @@ android_init_values(void)
text = config_get_android_product();
if(text)
{
write_to_file(ANDROID0_PRODUCT, text);
android_write_file(ANDROID0_PRODUCT, text);
g_free(text);
}
text = config_get_android_product_id();
......@@ -177,11 +201,16 @@ android_init_values(void)
text = mac_read_mac();
if(text)
{
write_to_file("/sys/class/android_usb/f_rndis/ethaddr", text);
android_set_attr("f_rndis", "ethaddr", text);
g_free(text);
}
/* For rndis to be discovered correctly in M$ Windows (vista and later) */
write_to_file("/sys/class/android_usb/f_rndis/wceis", "1");
android_set_attr("f_rndis", "wceis", "1");
/* Make sure remnants off mass-storage mode do not cause
* issues for charging_fallback & co */
android_set_attr("f_mass_storage", "lun/nofua", "0");
android_set_attr("f_mass_storage", "lun/file", "");
EXIT:
return android_in_use();
......@@ -193,7 +222,7 @@ android_set_enabled(bool enable)
bool ack = false;
if( android_in_use() ) {
const char *val = enable ? "1" : "0";
ack = write_to_file(ANDROID0_ENABLE, val) != -1;
ack = android_write_file(ANDROID0_ENABLE, val) != -1;
}
log_debug("ANDROID %s(%d) -> %d", __func__, enable, ack);
return ack;
......@@ -246,7 +275,7 @@ android_set_function(const char *function)
if( !android_set_enabled(false) )
goto EXIT;
if( write_to_file(ANDROID0_FUNCTIONS, function) == -1 )
if( android_write_file(ANDROID0_FUNCTIONS, function) == -1 )
goto EXIT;
/* Leave disabled, so that caller can adjust attributes
......@@ -276,7 +305,7 @@ android_set_productid(const char *id)
snprintf(str, sizeof str, "%04x", num);
id = str;
}
ack = write_to_file(ANDROID0_ID_PRODUCT, id) != -1;
ack = android_write_file(ANDROID0_ID_PRODUCT, id) != -1;
}
log_debug("ANDROID %s(%s) -> %d", __func__, id, ack);
return ack;
......@@ -298,8 +327,28 @@ android_set_vendorid(const char *id)
snprintf(str, sizeof str, "%04x", num);
id = str;
}
ack = write_to_file(ANDROID0_ID_VENDOR, id) != -1;
ack = android_write_file(ANDROID0_ID_VENDOR, id) != -1;
}
log_debug("ANDROID %s(%s) -> %d", __func__, id, ack);
return ack;
}
/** Set function attribute
*
* @return true if successful, false on failure
*/
bool
android_set_attr(const char *function, const char *attr, const char *value)
{
bool ack = false;
if( function && attr && value && android_in_use() ) {
char path[256];
snprintf(path, sizeof path, "%s/%s/%s",
ANDROID0_DIRECTORY, function, attr);
ack = android_write_file(path, value);
}
log_debug("ANDROID %s(%s, %s, %s) -> %d", __func__,
function, attr, value, ack);
return ack;
}
......@@ -53,5 +53,6 @@ bool android_set_charging_mode(void);
bool android_set_function (const char *function);
bool android_set_productid (const char *id);
bool android_set_vendorid (const char *id);
bool android_set_attr (const char *function, const char *attr, const char *value);
#endif /* USB_MODED_ANDROID_H_ */
......@@ -201,11 +201,12 @@ int modesetting_write_to_file_real(const char *file, int line, const char *func,
size_t todo = 0;
char *prev = 0;
bool clear = false;
gchar *repr = 0;
/* if either path or the text to be written are not there
* we return an error */
if(!text || !path)
return err;
goto cleanup;
/* When attempting to clear ffs function list, writing an
* empty string is ignored and accomplishes nothing - while
......@@ -225,14 +226,17 @@ int modesetting_write_to_file_real(const char *file, int line, const char *func,
}
}
repr = g_strdup(text);
modesetting_strip(repr);
/* 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 = modesetting_read_from_file(path, 0x1000)) )
modesetting_track_value(path, clear ? "" : text);
modesetting_track_value(path, clear ? "" : repr);
log_debug("%s:%d: %s(): WRITE '%s' : '%s' --> '%s'",
file, line, func,
path, prev ?: "???", text);
path, prev ?: "???", repr);
todo = strlen(text);
......@@ -265,6 +269,7 @@ cleanup:
if( fd != -1 ) TEMP_FAILURE_RETRY(close(fd));
free(prev);
free(repr);
return err;
}
......@@ -470,9 +475,8 @@ static bool modesetting_enter_mass_storage_mode(struct mode_list_elem *data)
const gchar *mountdev = info[0].si_mountdevice;
android_set_enabled(false);
android_set_function("mass_storage");
write_to_file("/sys/class/android_usb/f_mass_storage/lun/nofua",
nofua ? "1" : "0");
write_to_file("/sys/class/android_usb/f_mass_storage/lun/file", mountdev);
android_set_attr("f_mass_storage", "lun/nofua", nofua ? "1" : "0");
android_set_attr("f_mass_storage", "lun/file", mountdev);
android_set_enabled(true);
}
else if( configfs_in_use() ) {
......@@ -553,7 +557,7 @@ static int modesetting_leave_mass_storage_mode(struct mode_list_elem *data)
if( android_in_use() ) {
log_debug("Disable android mass storage\n");
android_set_enabled(false);
write_to_file("/sys/class/android_usb/f_mass_storage/lun/file", "");
android_set_attr("f_mass_storage", "lun/file", "");
}
else if( configfs_in_use() ) {
// TODO
......
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