summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2013-10-08 11:08:07 +0200
committerAleksander Morgado <aleksander@lanedo.com>2013-10-08 11:08:07 +0200
commitc34f8d2d02f3d43f448cb183fd53f061e1e80f98 (patch)
tree2cc3f4d35b0716b2d1aa750524a21c0546004c17
parent5b22dc7b242012f4d550b3c3c2b451f884409cea (diff)
downloadModemManager-aleksander/on-hardware-activation.tar.gz
wip: systemd on hardware activationaleksander/on-hardware-activation
NOTE: what to do with manual scans and devices only available in manual scans?
-rw-r--r--data/ModemManager.service.in2
-rw-r--r--src/80-mm-candidate.rules8
-rw-r--r--src/main.c43
-rw-r--r--src/mm-context.c8
-rw-r--r--src/mm-context.h1
-rw-r--r--src/mm-manager.c16
-rw-r--r--src/mm-manager.h4
7 files changed, 73 insertions, 9 deletions
diff --git a/data/ModemManager.service.in b/data/ModemManager.service.in
index 9fe3a3bce..02921caf8 100644
--- a/data/ModemManager.service.in
+++ b/data/ModemManager.service.in
@@ -10,5 +10,5 @@ StandardError=null
Restart=on-abort
[Install]
-WantedBy=multi-user.target
+WantedBy=modem.target
Alias=dbus-org.freedesktop.ModemManager1.service
diff --git a/src/80-mm-candidate.rules b/src/80-mm-candidate.rules
index 2e938d7a1..11b2c8d3d 100644
--- a/src/80-mm-candidate.rules
+++ b/src/80-mm-candidate.rules
@@ -9,9 +9,9 @@
ACTION!="add|change|move", GOTO="mm_candidate_end"
-SUBSYSTEM=="tty", ENV{ID_MM_CANDIDATE}="1"
-SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1"
-KERNEL=="cdc-wdm*", SUBSYSTEM=="usb", ENV{ID_MM_CANDIDATE}="1"
-KERNEL=="cdc-wdm*", SUBSYSTEM=="usbmisc", ENV{ID_MM_CANDIDATE}="1"
+SUBSYSTEM=="tty", ENV{ID_MM_CANDIDATE}="1", TAG+="systemd", ENV{SYSTEMD_WANTS}="modem.target"
+SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1", TAG+="systemd", ENV{SYSTEMD_WANTS}="modem.target"
+KERNEL=="cdc-wdm*", SUBSYSTEM=="usb", ENV{ID_MM_CANDIDATE}="1", TAG+="systemd", ENV{SYSTEMD_WANTS}="modem.target"
+KERNEL=="cdc-wdm*", SUBSYSTEM=="usbmisc", ENV{ID_MM_CANDIDATE}="1", TAG+="systemd", ENV{SYSTEMD_WANTS}="modem.target"
LABEL="mm_candidate_end"
diff --git a/src/main.c b/src/main.c
index 4841c3d73..7a930431c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -37,6 +37,10 @@
/* Maximum time to wait for all modems to get disabled and removed */
#define MAX_SHUTDOWN_TIME_SECS 20
+/* Maximum time to wait after last modem disappears */
+#define MAX_WAIT_AFTER_LAST_MODEM_SECS 10
+guint after_last_modem_timeout_id;
+
static GMainLoop *loop;
static MMManager *manager;
@@ -51,6 +55,34 @@ quit_cb (gpointer user_data)
return FALSE;
}
+static gboolean
+after_last_modem_stop_loop_cb (gpointer user_data)
+{
+ after_last_modem_timeout_id = 0;
+ mm_info ("No modems to manage, shutting down...");
+ if (loop)
+ g_idle_add ((GSourceFunc) g_main_loop_quit, loop);
+ return FALSE;
+}
+
+static void
+manager_num_modems_changed (MMManager *_manager)
+{
+ if (mm_manager_get_num_modems (manager) == 0) {
+ g_assert (after_last_modem_timeout_id == 0);
+ after_last_modem_timeout_id = g_timeout_add_seconds (MAX_WAIT_AFTER_LAST_MODEM_SECS,
+ (GSourceFunc)after_last_modem_stop_loop_cb,
+ NULL);
+ return;
+ }
+
+ /* At least one modem, remove timeout if any */
+ if (after_last_modem_timeout_id) {
+ g_source_remove (after_last_modem_timeout_id);
+ after_last_modem_timeout_id = 0;
+ }
+}
+
static void
bus_acquired_cb (GDBusConnection *connection,
const gchar *name,
@@ -69,6 +101,15 @@ bus_acquired_cb (GDBusConnection *connection,
g_main_loop_quit (loop);
return;
}
+
+ /* If exit requested when no modems available, set it up */
+ if (mm_context_get_exit_without_modems ()) {
+ manager_num_clients_changed (manager);
+ g_signal_connect (manager,
+ "notify::" MM_MANAGER_NUM_CLIENTS,
+ G_CALLBACK (manager_num_clients_changed),
+ NULL);
+ }
}
static void
@@ -155,7 +196,7 @@ main (int argc, char *argv[])
* forever: if disabling the modems takes longer than 20s, just
* shutdown anyway. */
timer = g_timer_new ();
- while (mm_manager_num_modems (manager) &&
+ while (mm_manager_get_num_modems (manager) &&
g_timer_elapsed (timer, NULL) < (gdouble)MAX_SHUTDOWN_TIME_SECS) {
GMainContext *ctx = g_main_loop_get_context (inner);
diff --git a/src/mm-context.c b/src/mm-context.c
index 4a44456a4..8d0dde521 100644
--- a/src/mm-context.c
+++ b/src/mm-context.c
@@ -23,6 +23,7 @@ static const gchar *log_level;
static const gchar *log_file;
static gboolean show_ts;
static gboolean rel_ts;
+static gboolean exit_without_modems;
static const GOptionEntry entries[] = {
{ "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Run with extended debugging capabilities", NULL },
@@ -30,6 +31,7 @@ static const GOptionEntry entries[] = {
{ "log-file", 0, 0, G_OPTION_ARG_STRING, &log_file, "Path to log file", NULL },
{ "timestamps", 0, 0, G_OPTION_ARG_NONE, &show_ts, "Show timestamps in log output", NULL },
{ "relative-timestamps", 0, 0, G_OPTION_ARG_NONE, &rel_ts, "Use relative timestamps (from MM start)", NULL },
+ { "exit-without-modems", 0, 0, G_OPTION_ARG_NONE, &exit_without_modems, "Exit if no modems found", NULL },
{ NULL }
};
@@ -63,6 +65,12 @@ mm_context_get_relative_timestamps (void)
return rel_ts;
}
+gboolean
+mm_context_get_exit_without_modems (void)
+{
+ return exit_without_modems;
+}
+
void
mm_context_init (gint argc,
gchar **argv)
diff --git a/src/mm-context.h b/src/mm-context.h
index 659a85bca..348bf5a96 100644
--- a/src/mm-context.h
+++ b/src/mm-context.h
@@ -26,5 +26,6 @@ const gchar *mm_context_get_log_level (void);
const gchar *mm_context_get_log_file (void);
gboolean mm_context_get_timestamps (void);
gboolean mm_context_get_relative_timestamps (void);
+gboolean mm_context_get_exit_without_modems (void);
#endif /* MM_CONTEXT_H */
diff --git a/src/mm-manager.c b/src/mm-manager.c
index 9fb6407e2..a1f1e4e0e 100644
--- a/src/mm-manager.c
+++ b/src/mm-manager.c
@@ -42,6 +42,7 @@ G_DEFINE_TYPE_EXTENDED (MMManager, mm_manager, MM_GDBUS_TYPE_ORG_FREEDESKTOP_MOD
enum {
PROP_0,
PROP_CONNECTION,
+ PROP_NUM_MODEMS,
LAST_PROP
};
@@ -546,7 +547,7 @@ mm_manager_shutdown (MMManager *self)
}
guint32
-mm_manager_num_modems (MMManager *self)
+mm_manager_get_num_modems (MMManager *self)
{
GHashTableIter iter;
gpointer key, value;
@@ -722,6 +723,9 @@ get_property (GObject *object,
case PROP_CONNECTION:
g_value_set_object (value, priv->connection);
break;
+ case PROP_NUM_MODEMS:
+ g_value_set_uint (value, mm_manager_get_num_modems (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -844,4 +848,14 @@ mm_manager_class_init (MMManagerClass *manager_class)
G_TYPE_DBUS_CONNECTION,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class, PROP_CONNECTION, properties[PROP_CONNECTION]);
+
+ properties[PROP_NUM_MODEMS] =
+ g_param_spec_uint (MM_MANAGER_NUM_MODEMS,
+ "Number of modems",
+ "Number of modems currently managed",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READABLE);
+ g_object_class_install_property (object_class, PROP_NUM_MODEMS, properties[PROP_NUM_MODEMS]);
}
diff --git a/src/mm-manager.h b/src/mm-manager.h
index 7f1a00ad1..1a40c2afd 100644
--- a/src/mm-manager.h
+++ b/src/mm-manager.h
@@ -31,6 +31,7 @@
#define MM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_MANAGER, MMManagerClass))
#define MM_MANAGER_CONNECTION "connection" /* Construct-only */
+#define MM_MANAGER_N_MODEMS "n-modems"
typedef struct _MMManagerPrivate MMManagerPrivate;
@@ -50,9 +51,8 @@ MMManager *mm_manager_new (GDBusConnection *bus,
void mm_manager_start (MMManager *manager,
gboolean manual_scan);
-
void mm_manager_shutdown (MMManager *manager);
-guint32 mm_manager_num_modems (MMManager *manager);
+guint32 mm_manager_get_num_modems (MMManager *manager);
#endif /* MM_MANAGER_H */