I have made the following changes intended for : CE:UX:MTF / usb-moded Please review and accept or decline. BOSS has already run some checks on this request. See the "Messages from BOSS" section below.
https://build.pub.meego.com//request/show/7414 Thank You, philippedeswert [This message was auto-generated] --- Request # 7414: Messages from BOSS: State: review at 2012-11-19T14:06:08 by bossbot Reviews: accepted by bossbot : Prechecks succeeded. new for CE-maintainers : Please replace this text with a review and approve/reject the review (not the SR). BOSS will take care of the rest Changes: submit: home:philippedeswert:branches:CE:UX:MTF / usb-moded -> CE:UX:MTF / usb-moded changes files: -------------- --- usb-moded.changes +++ usb-moded.changes @@ -0,0 +1,6 @@ +* Mon Nov 19 2012 Philippe De Swert <[email protected]> - 0.54 +- Instead of spawning shells with system() use libkmod +- Make config file optional as defaults work for most devices +- Add dbus method to set network configuration +- Basic rescue mode + old: ---- usb-moded-0.53.tar.bz2 new: ---- usb-moded-0.54.tar.bz2 spec files: ----------- --- usb-moded.spec +++ usb-moded.spec @@ -1,5 +1,5 @@ Name: usb-moded -Version: 0.53 +Version: 0.54 Release: 0 Summary: USB mode controller Group: System/System Control @@ -15,12 +15,13 @@ BuildRequires: pkgconfig(gconf-2.0) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(udev) +BuildRequires: pkgconfig(libkmod) BuildRequires: doxygen BuildRequires: GConf2 Provides: nokia-usb-networking Requires: dbus-x11 -Requires: lsof, usb-moded-config +Requires: lsof Requires(post): GConf2 Requires(pre): GConf2 Requires(preun): GConf2 other changes: -------------- ++++++ usb-moded-0.53.tar.bz2 -> usb-moded-0.54.tar.bz2 --- configure.ac +++ configure.ac @@ -1,4 +1,4 @@ -AC_INIT([usb_moded], [0.53]) +AC_INIT([usb_moded], [0.54]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AM_CONFIG_HEADER([config.h]) @@ -119,6 +119,7 @@ dbus-glib-1 >= 0.78 gobject-2.0 >= 2.16.6 gio-2.0 + libkmod ]) AC_SUBST(USB_MODED_LIBS) --- dbus-send-test.txt +++ dbus-send-test.txt @@ -2,6 +2,7 @@ dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.set_mode string:'ovi_suite' dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.set_config string:'ovi_suite' dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.set_mode string:'mass_storage' +dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.net_config string:'ip' string:'192.168.2.15' security extra: aegis-exec -a usb-moded::USBControl --- debian/changelog +++ debian/changelog @@ -1,3 +1,11 @@ +usb-moded (0.54) unstable; urgency=low + + * Instead of spawning shells with system() use libkmod + * Make config file optional as defaults work for most + * Add dbus method to set network configuration + + -- Philippe De Swert <[email protected]> Tue. 13 Nov 2012 18:56:23 +0300 + usb-moded (0.53) unstable; urgency=low * Un-nokia to make usb_moded more generic --- docs/usb_moded-doc.txt +++ docs/usb_moded-doc.txt @@ -101,6 +101,14 @@ By default usb0 will be used, so no need to fill it in if not needed. The gateway setting is also optional and will not be set if there is no value filled in. +If the ip is set to dhcp, usb_moded will try to use dhcp to configure the network (requires dhclient atm) + +The network configuration can also be set with dbus method calls via the net_config method. +This requires two strings as arguments. Supported are: ip, interface and gateway + +for exmaple: + +dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.net_config string:'ip' string:'192.168.2.15' Functional overview -------------------- --- src/usb_moded-config-private.h +++ src/usb_moded-config-private.h @@ -25,3 +25,4 @@ const char * get_mode_setting(void); int set_mode_setting(const char *mode); +int set_network_setting(const char *config, const char *setting); --- src/usb_moded-config.c +++ src/usb_moded-config.c @@ -33,6 +33,7 @@ #include "usb_moded-config.h" #include "usb_moded-config-private.h" #include "usb_moded-log.h" +#include "usb_moded-modes.h" static int get_conf_int(const gchar *entry, const gchar *key); static const char * get_conf_string(const gchar *entry, const gchar *key); @@ -128,6 +129,20 @@ return(get_conf_string(NETWORK_ENTRY, NETWORK_GATEWAY_KEY)); } +/* create basic conffile with sensible defaults */ +static void create_conf_file(void) +{ + GKeyFile *settingsfile; + gchar *keyfile; + + settingsfile = g_key_file_new(); + + g_key_file_set_string(settingsfile, MODE_SETTING_ENTRY, MODE_SETTING_KEY, MODE_DEVELOPER ); + keyfile = g_key_file_to_data (settingsfile, NULL, NULL); + if(g_file_set_contents(FS_MOUNT_CONFIG_FILE, keyfile, -1, NULL) == 0) + log_debug("conffile creation failed. Continuing without configuration!\n"); +} + static int get_conf_int(const gchar *entry, const gchar *key) { GKeyFile *settingsfile; @@ -139,9 +154,8 @@ test = g_key_file_load_from_file(settingsfile, FS_MOUNT_CONFIG_FILE, G_KEY_FILE_NONE, NULL); if(!test) { - log_debug("no conffile\n"); - g_key_file_free(settingsfile); - return(ret); + log_debug("no conffile, Creating\n"); + create_conf_file(); } keys = g_key_file_get_keys (settingsfile, entry, NULL, NULL); if(keys == NULL) @@ -170,9 +184,8 @@ test = g_key_file_load_from_file(settingsfile, FS_MOUNT_CONFIG_FILE, G_KEY_FILE_NONE, NULL); if(!test) { - log_debug("No conffile.\n"); - g_key_file_free(settingsfile); - return(ret); + log_debug("No conffile. Creating\n"); + create_conf_file(); } keys = g_key_file_get_keys (settingsfile, entry, NULL, NULL); if(keys == NULL) @@ -211,9 +224,8 @@ test = g_key_file_load_from_file(settingsfile, FS_MOUNT_CONFIG_FILE, G_KEY_FILE_NONE, NULL); if(!test) { - log_debug("No conffile.\n"); - g_key_file_free(settingsfile); - return(1); + log_debug("No conffile. Creating.\n"); + create_conf_file(); } g_key_file_set_string(settingsfile, MODE_SETTING_ENTRY, MODE_SETTING_KEY, mode); @@ -227,5 +239,40 @@ /* g_file_set_contents returns 1 on succes, since set_mode_settings returns 0 on succes we return the ! value */ return(!ret); } + +int set_network_setting(const char *config, const char *setting) +{ + GKeyFile *settingsfile; + gboolean test = FALSE; + int ret = 0; + gchar *keyfile; + + settingsfile = g_key_file_new(); + test = g_key_file_load_from_file(settingsfile, FS_MOUNT_CONFIG_FILE, G_KEY_FILE_NONE, NULL); + if(!test) + { + log_debug("No conffile. Creating.\n"); + create_conf_file(); + } + + if(!strcmp(config, NETWORK_IP_KEY) || !strcmp(config, NETWORK_INTERFACE_KEY) || !strcmp(config, NETWORK_GATEWAY_KEY)) + { + g_key_file_set_string(settingsfile, NETWORK_ENTRY, config, setting); + keyfile = g_key_file_to_data (settingsfile, NULL, NULL); + /* free the settingsfile before writing things out to be sure + the contents will be correctly written to file afterwards. + Just a precaution. */ + g_key_file_free(settingsfile); + ret = g_file_set_contents(FS_MOUNT_CONFIG_FILE, keyfile, -1, NULL); + } + else + { + g_key_file_free(settingsfile); + return(1); + } + /* g_file_set_contents returns 1 on succes, since set_mode_settings returns 0 on succes we return the ! value */ + return(!ret); +} + #endif --- src/usb_moded-dbus.c +++ src/usb_moded-dbus.c @@ -126,6 +126,26 @@ } dbus_error_free(&err); } + else if(!strcmp(member, USB_MODE_NETWORK_SET)) + { + char *config = 0, *setting = 0; + DBusError err = DBUS_ERROR_INIT; + + if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_STRING, &setting, DBUS_TYPE_INVALID)) + reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member); + else + { + /* error checking is done when setting the GConf key */ + if(!set_network_setting(config, setting)) + { + if((reply = dbus_message_new_method_return(msg))) + dbus_message_append_args (reply, DBUS_TYPE_STRING, &config, DBUS_TYPE_STRING, &setting, DBUS_TYPE_INVALID); + } + else + reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, config); + } + dbus_error_free(&err); + } else { /*unknown methods are handled here */ --- src/usb_moded-dbus.h +++ src/usb_moded-dbus.h @@ -35,10 +35,12 @@ **/ #define USB_MODE_STATE_SET "set_mode" #define USB_MODE_CONFIG_SET "set_config" +#define USB_MODE_NETWORK_SET "net_config" /* state definitions for signals and method parameters */ #define USB_CONNECTED "USB connected" #define USB_DISCONNECTED "USB disconnected" +#define USB_REALLY_DISCONNECT "USB mode change in progress" #define DATA_IN_USE "data_in_use" #define USB_CONNECTED_DIALOG_SHOW "mode_requested_show_dialog" #define USB_PRE_UNMOUNT "pre-unmount" --- src/usb_moded-modesetting.c +++ src/usb_moded-modesetting.c @@ -259,8 +259,12 @@ write_to_file("/sys/devices/platform/musb_hdrc/gadget/softconnect", "1"); #endif /* APP_SYNC */ /* bring network interface up in case no other network is up */ - /* system("ifdown usb0 ; ifup usb0"); */ +#ifdef DEBIAN + system("ifdown usb0 ; ifup usb0"); +#else + usb_network_down(); usb_network_up(); +#endif /* DEBIAN */ #ifdef NOKIA /* timeout for exporting CDROM image */ @@ -282,8 +286,13 @@ activate_sync(data->mode_name); if(data->network) { +#ifdef DEBIAN g_snprintf(command, 256, "ifdown %s ; ifup %s", data->network_interface, data->network_interface); system(command); +#else + usb_network_down(); + usb_network_up(); +#endif /* DEBIAN */ } return(0); @@ -337,6 +346,10 @@ if(!strcmp(module, MODULE_MASS_STORAGE)|| !strcmp(module, MODULE_FILE_STORAGE)) { + /* no clean-up needs to be done when we come from charging mode. We need + to check since we use fake mass-storage for charging */ + if(!strcmp(MODE_CHARGING, get_usb_mode())) + return 0; mount = find_mounts(); if(mount) { --- src/usb_moded-modesetting.h +++ src/usb_moded-modesetting.h @@ -30,6 +30,7 @@ int set_ovi_suite_mode(void); int set_mtp_mode(void); int set_dynamic_mode(struct mode_list_elem *data); +/* clean up for the mode changes on disconnect */ int usb_moded_mode_cleanup(const char *module); #ifdef NOKIA gboolean export_cdrom (gpointer data); --- src/usb_moded-modules.c +++ src/usb_moded-modules.c @@ -27,6 +27,8 @@ #include <glib.h> +#include <libkmod.h> + #include "usb_moded.h" #include "usb_moded-modules.h" #include "usb_moded-log.h" @@ -39,6 +41,9 @@ #include "usb_moded-modes.h" #endif +/* kmod context - initialized at start in usb_moded_init */ +struct kmod_ctx *ctx; + /** load module * * @param module Name of the module to load @@ -47,8 +52,9 @@ */ int usb_moded_load_module(const char *module) { - gchar *command; int ret = 0; +#ifdef NO_KMOD + gchar *command; command = g_strconcat("modprobe ", module, NULL); ret = system(command); @@ -63,6 +69,30 @@ ret = system(command); } g_free(command); +#else + const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST; + struct kmod_module *mod; + const char *charging_args = NULL; + + ret = kmod_module_new_from_name(ctx, module, &mod); + if(!strcmp(module, MODULE_MASS_STORAGE) && (ret != 0)) + { + ret = kmod_module_new_from_name(ctx, MODULE_FILE_STORAGE, &mod); + } + if(!strcmp(module, MODULE_CHARGING) && (ret != 0)) + { + /* split the string in module name and arguments, if it still fails do the same + for MODULE_CHARGE_FALLBACK */ + } + + if(!charging_args) + ret = kmod_module_probe_insert_module(mod, probe_flags, NULL, NULL, NULL, NULL); + else + ret = kmod_module_probe_insert_module(mod, probe_flags, charging_args, NULL, NULL, NULL); + + kmod_module_unref(mod); +#endif /* NO_KMOD */ + if( ret == 0) log_info("Module %s loaded successfully\n", module); return(ret); @@ -76,22 +106,51 @@ */ int usb_moded_unload_module(const char *module) { - gchar *command; int ret = 0; +#ifdef NO_KMOD + gchar *command; + command = g_strconcat("rmmod ", module, NULL); ret = system(command); g_free(command); +#else + struct kmod_module *mod; + + kmod_module_new_from_name(ctx, module, &mod); + ret = kmod_module_remove_module(mod, KMOD_REMOVE_NOWAIT); + kmod_module_unref(mod); + +#endif /* NO_KMOD */ return(ret); } +/** Check which state a module is in + * + * @return 1 if loaded, 0 when not loaded + */ +static int module_state_check(const char *module) +{ + int ret = 0; + struct kmod_module *mod; + + kmod_module_new_from_name(ctx, module, &mod); + ret = kmod_module_get_initstate(mod); + kmod_module_unref(mod); + if( ret == KMOD_MODULE_LIVE) + return(1); + else + return(0); +} + /** find which module is loaded * * @return The name of the loaded module, or NULL if no modules are loaded. */ const char * usb_moded_find_module(void) { +#ifdef NO_KMOD FILE *stream = 0; const char *result = 0; @@ -141,8 +200,26 @@ } pclose(stream); } + +return result; +#endif /* NO_KMOD */ - return result; + if(module_state_check("g_nokia")) + return(MODULE_NETWORK); + else if(module_state_check("g_ether")) + return(MODULE_WINDOWS_NET); + else if(module_state_check("g_ncm")) + return("g_ncm"); + else if(module_state_check("g_ffs")) + return(MODULE_MTP); + else if(module_state_check("g_mass_storage")) + return(MODULE_MASS_STORAGE); + else if(module_state_check("g_file_storage")) + return(MODULE_FILE_STORAGE); + else if(module_state_check(get_usb_module())) + return(get_usb_module()); + /* no module loaded */ + return(0); } /** clean up for modules when usb gets disconnected @@ -165,13 +242,19 @@ */ failure = usb_moded_unload_module(module); + + /* if we have MODULE_MASS_STORAGE it might be MODULE_FILE_STORAGE might + be loaded. So check and unload that one if unloading fails first time */ + if(failure && !strcmp(MODULE_MASS_STORAGE, module)) + failure = usb_moded_unload_module(module); + while(failure) { // SP: up to 2 second sleep -> worth a warning log? /* module did not get unloaded. We will wait a bit and try again */ sleep(1); - /* send another disconnect message */ - usb_moded_send_signal(USB_DISCONNECTED); + /* send the REALLY disconnect message */ + usb_moded_send_signal(USB_REALLY_DISCONNECT); failure = usb_moded_unload_module(module); log_debug("unloading failure = %d\n", failure); if(!failure) @@ -190,7 +273,7 @@ lets go for more extreme measures lsof, then various options of kill */ - log_info("DIE DIE DIE! Free USB-illy!\n"); + log_info("Oh noes the platform is on fire!\n"); kill: /* DIRTY DESPERATE WORKAROUND */ /*system("for i in `lsof -t /dev/ttyGS*`; do cat /proc/$i/cmdline | sed 's/|//g' | sed "s/\x00/ /g" | awk '{ print $1 }' | xargs kill; done"); --- src/usb_moded-modules.h +++ src/usb_moded-modules.h @@ -43,9 +43,6 @@ /* find which module is loaded */ const char * usb_moded_find_module(void); -/* clean up for the mode changes on disconnect */ -int usb_moded_mode_cleanup(const char *module); - /* clean up modules when usb gets disconnected */ int usb_moded_module_cleanup(const char *module); --- src/usb_moded-network.c +++ src/usb_moded-network.c @@ -23,6 +23,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "usb_moded-network.h" #include "usb_moded-config.h" @@ -79,18 +80,26 @@ system("ifconfig usb0 192.168.2.15"); return(0); } + if(!strcmp(ip, "dhcp")) + { + if(interface == NULL) + sprintf(command, "dhclient -d usb0\n"); + else + sprintf(command, "dhclient -d %s\n", interface); + } if(interface == NULL) sprintf(command, "ifconfig usb0 %s\n", ip); else sprintf(command, "ifconfig %s %s\n", interface, ip); system(command); + /* TODO: Check first if there is a gateway set */ if(gateway) { sprintf(command, "route add default gw %s\n", gateway); system(command); } - + return(0); #endif /* CONNMAN */ } --- src/usb_moded.c +++ src/usb_moded.c @@ -29,6 +29,8 @@ #include <string.h> #endif +#include <libkmod.h> + #include "usb_moded.h" #include "usb_moded-modes.h" #include "usb_moded-dbus.h" @@ -52,7 +54,10 @@ extern int log_level; extern int log_type; +gboolean rescue_mode; + gboolean runlevel_ignore = FALSE; +gboolean hw_fallback = FALSE; struct usb_mode current_mode; guint charging_timeout = 0; #ifdef NOKIA @@ -125,6 +130,8 @@ static gboolean set_disconnected(gpointer data) { + /* let usb settle */ + sleep(1); /* only disconnect for real if we are actually still disconnected */ if(!get_usb_connection_state()) { @@ -138,7 +145,7 @@ /* unload modules and general cleanup */ if(strcmp(get_usb_mode(), MODE_CHARGING)) usb_moded_mode_cleanup(get_usb_module()); - /* No else as we do not need to do anything for cleaning up charging mode */ + /* Nothing else as we do not need to do anything for cleaning up charging mode */ usb_moded_module_cleanup(get_usb_module()); set_usb_mode(MODE_UNDEFINED); #endif /* NOKIA */ @@ -165,6 +172,8 @@ #ifdef MEEGOLOCK /* check if we are allowed to export system contents 0 is unlocked */ export = usb_moded_get_export_permission(); + if(rescue_mode) + export = 1; #endif #ifdef MEEGOLOCK int act_dead = 0; @@ -406,6 +415,7 @@ char readbuf[MAX_READ_BUF]; FILE *proc_fd; #endif /* NOKIA_NSU */ + extern struct kmod_ctx *ctx; current_mode.connected = FALSE; current_mode.mounted = FALSE; @@ -436,6 +446,11 @@ if(check_trigger()) trigger_init(); #endif /* UDEV */ + + /* kmod init */ + ctx = kmod_new(NULL, NULL); + kmod_load_resources(ctx); + /* TODO: add more start-up clean-up and init here if needed */ } @@ -482,11 +497,12 @@ GMainLoop *mainloop = NULL; struct option const options[] = { - { "daemon", no_argument, 0, 'd' }, + { "fallback", no_argument, 0, 'd' }, { "force-syslog", no_argument, 0, 's' }, { "force-stderr", no_argument, 0, 'T' }, { "debug", no_argument, 0, 'D' }, { "help", no_argument, 0, 'h' }, + { "rescue", no_argument, 0, 'r' }, { "version", no_argument, 0, 'v' }, { 0, 0, 0, 0 } }; @@ -494,10 +510,13 @@ log_name = basename(*argv); /* Parse the command-line options */ - while ((opt = getopt_long(argc, argv, "sTDhvw", options, &opt_idx)) != -1) + while ((opt = getopt_long(argc, argv, "fsTDhrvw", options, &opt_idx)) != -1) { switch (opt) { + case 'f': + hw_fallback = TRUE; + break; case 's': log_type = LOG_TO_SYSLOG; break; @@ -514,6 +533,10 @@ usage(); exit(0); + case 'r': + rescue_mode = TRUE; + break; + case 'v': printf("USB mode daemon version: %s\n", VERSION); exit(0); @@ -551,7 +574,14 @@ if( !hwal_init() ) { log_crit("hwal init failed\n"); - goto EXIT; + if(hw_fallback) + { + log_warning("Forcing USB state to connected always. ASK mode non functional!\n"); + /* Since there will be no disconnect signals coming from hw the state should not change */ + set_usb_connected(TRUE); + } + else + goto EXIT; } #ifdef MEEGOLOCK start_devicelock_listener();
