NetworkManager r3782 - in trunk: . src
- From: tambeti svn gnome org
- To: svn-commits-list gnome org
- Subject: NetworkManager r3782 - in trunk: . src
- Date: Mon, 30 Jun 2008 12:18:57 +0000 (UTC)
Author: tambeti
Date: Mon Jun 30 12:18:57 2008
New Revision: 3782
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3782&view=rev
Log:
2008-06-30 Tambet Ingo <tambet gmail com>
* src/nm-serial-device.c:
* src/nm-gsm-device.c:
* src/nm-cdma-device.c: Move the pending call handling to a common location
in serial device. Handle setting device state to failed in one place as well.
Modified:
trunk/ChangeLog
trunk/src/nm-cdma-device.c
trunk/src/nm-gsm-device.c
trunk/src/nm-serial-device.c
Modified: trunk/src/nm-cdma-device.c
==============================================================================
--- trunk/src/nm-cdma-device.c (original)
+++ trunk/src/nm-cdma-device.c Mon Jun 30 12:18:57 2008
@@ -19,7 +19,6 @@
char *monitor_iface;
NMSerialDevice *monitor_device;
- guint pending_id;
guint state_to_disconnected_id;
} NMCdmaDevicePrivate;
@@ -59,12 +58,6 @@
NULL);
}
-static inline void
-cdma_device_set_pending (NMCdmaDevice *device, guint pending_id)
-{
- NM_CDMA_DEVICE_GET_PRIVATE (device)->pending_id = pending_id;
-}
-
static NMSetting *
cdma_device_get_setting (NMCdmaDevice *device, GType setting_type)
{
@@ -90,8 +83,6 @@
{
gboolean success = FALSE;
- cdma_device_set_pending (NM_CDMA_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
nm_info ("Connected, Woo!");
@@ -125,25 +116,18 @@
{
NMSettingCdma *setting;
char *command;
- guint id;
+ guint id = 0;
char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL };
- gboolean success;
setting = NM_SETTING_CDMA (cdma_device_get_setting (NM_CDMA_DEVICE (device), NM_TYPE_SETTING_CDMA));
command = g_strconcat ("ATDT", setting->number, NULL);
- success = nm_serial_device_send_command_string (device, command);
+ if (nm_serial_device_send_command_string (device, command))
+ id = nm_serial_device_wait_for_reply (device, 60, responses, responses, dial_done, NULL);
g_free (command);
- if (success) {
- id = nm_serial_device_wait_for_reply (device, 60, responses, responses, dial_done, NULL);
- if (id)
- cdma_device_set_pending (NM_CDMA_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- } else {
+ if (id == 0)
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- }
}
static void
@@ -151,8 +135,6 @@
int reply_index,
gpointer user_data)
{
- cdma_device_set_pending (NM_CDMA_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
do_dial (device);
@@ -171,37 +153,31 @@
static void
init_modem (NMSerialDevice *device, gpointer user_data)
{
- guint id;
+ guint id = 0;
char *responses[] = { "OK", "ERROR", "ERR", NULL };
- if (!nm_serial_device_send_command_string (device, "ATZ E0")) {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- return;
- }
-
- id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL);
+ if (nm_serial_device_send_command_string (device, "ATZ E0"))
+ id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL);
- if (id)
- cdma_device_set_pending (NM_CDMA_DEVICE (device), id);
- else
+ if (id == 0)
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
}
static NMActStageReturn
real_act_stage1_prepare (NMDevice *device)
{
- NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (device);
NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device);
NMSettingSerial *setting;
+ guint id;
setting = NM_SETTING_SERIAL (cdma_device_get_setting (NM_CDMA_DEVICE (device), NM_TYPE_SETTING_SERIAL));
if (!nm_serial_device_open (serial_device, setting))
return NM_ACT_STAGE_RETURN_FAILURE;
- priv->pending_id = nm_serial_device_flash (serial_device, 100, init_modem, NULL);
+ id = nm_serial_device_flash (serial_device, 100, init_modem, NULL);
- return priv->pending_id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
+ return id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
}
static NMConnection *
@@ -267,19 +243,6 @@
nm_device_activate_schedule_stage1_device_prepare (dev);
}
-static void
-real_deactivate_quickly (NMDevice *device)
-{
- NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (device);
-
- if (priv->pending_id) {
- g_source_remove (priv->pending_id);
- priv->pending_id = 0;
- }
-
- NM_DEVICE_CLASS (nm_cdma_device_parent_class)->deactivate_quickly (device);
-}
-
/*****************************************************************************/
/* Monitor device handling */
@@ -496,7 +459,6 @@
device_class->get_generic_capabilities = real_get_generic_capabilities;
device_class->act_stage1_prepare = real_act_stage1_prepare;
device_class->connection_secrets_updated = real_connection_secrets_updated;
- device_class->deactivate_quickly = real_deactivate_quickly;
/* Properties */
g_object_class_install_property
Modified: trunk/src/nm-gsm-device.c
==============================================================================
--- trunk/src/nm-gsm-device.c (original)
+++ trunk/src/nm-gsm-device.c Mon Jun 30 12:18:57 2008
@@ -45,8 +45,8 @@
static guint signals[LAST_SIGNAL] = { 0 };
-static void enter_pin (NMSerialDevice *device, gboolean retry);
-static void automatic_registration (NMSerialDevice *device);
+static void enter_pin (NMGsmDevice *device, gboolean retry);
+static void automatic_registration (NMGsmDevice *device);
NMGsmDevice *
nm_gsm_device_new (const char *udi,
@@ -68,10 +68,39 @@
NULL);
}
-static inline void
-gsm_device_set_pending (NMGsmDevice *device, guint pending_id)
+static void
+modem_wait_for_reply (NMGsmDevice *self,
+ const char *command,
+ guint timeout,
+ char **responses,
+ char **terminators,
+ NMSerialWaitForReplyFn callback)
+{
+ NMSerialDevice *serial = NM_SERIAL_DEVICE (self);
+ guint id = 0;
+
+ if (nm_serial_device_send_command_string (serial, command))
+ id = nm_serial_device_wait_for_reply (serial, timeout, responses, terminators, callback, NULL);
+
+ if (id == 0)
+ nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED);
+}
+
+static void
+modem_get_reply (NMGsmDevice *self,
+ const char *command,
+ guint timeout,
+ const char *terminators,
+ NMSerialGetReplyFn callback)
{
- NM_GSM_DEVICE_GET_PRIVATE (device)->pending_id = pending_id;
+ NMSerialDevice *serial = NM_SERIAL_DEVICE (self);
+ guint id = 0;
+
+ if (nm_serial_device_send_command_string (serial, command))
+ id = nm_serial_device_get_reply (serial, timeout, terminators, callback, NULL);
+
+ if (id == 0)
+ nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED);
}
static NMSetting *
@@ -99,8 +128,6 @@
{
gboolean success = FALSE;
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
nm_info ("Connected, Woo!");
@@ -130,13 +157,11 @@
}
static void
-do_dial (NMSerialDevice *device, guint cid)
+do_dial (NMGsmDevice *device, guint cid)
{
NMSettingGsm *setting;
char *command;
- guint id;
char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL };
- gboolean success;
setting = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM));
@@ -154,18 +179,8 @@
} else
command = g_strconcat ("ATDT", setting->number, NULL);
- success = nm_serial_device_send_command_string (device, command);
+ modem_wait_for_reply (device, command, 60, responses, responses, dial_done);
g_free (command);
-
- if (success) {
- id = nm_serial_device_wait_for_reply (device, 60, responses, responses, dial_done, NULL);
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- } else {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- }
}
static void
@@ -173,13 +188,9 @@
int reply_index,
gpointer user_data)
{
- guint cid = GPOINTER_TO_UINT (user_data);
-
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
- do_dial (device, cid);
+ do_dial (NM_GSM_DEVICE (device), 1);
break;
default:
nm_warning ("Setting APN failed");
@@ -189,13 +200,11 @@
}
static void
-set_apn (NMSerialDevice *device)
+set_apn (NMGsmDevice *device)
{
NMSettingGsm *setting;
char *command;
char *responses[] = { "OK", "ERROR", NULL };
- gboolean success;
- guint id = 0;
guint cid = 1;
setting = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM));
@@ -207,16 +216,8 @@
}
command = g_strdup_printf ("AT+CGDCONT=%d, \"IP\", \"%s\"", cid, setting->apn);
- success = nm_serial_device_send_command_string (device, command);
+ modem_wait_for_reply (device, command, 3, responses, responses, set_apn_done);
g_free (command);
-
- if (success)
- id = nm_serial_device_wait_for_reply (device, 3, responses, responses, set_apn_done, GUINT_TO_POINTER (cid));
-
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
}
static void
@@ -224,11 +225,9 @@
int reply_index,
gpointer user_data)
{
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
- set_apn (device);
+ set_apn (NM_GSM_DEVICE (device));
break;
case -1:
nm_warning ("Manual registration timed out");
@@ -242,29 +241,17 @@
}
static void
-manual_registration (NMSerialDevice *device)
+manual_registration (NMGsmDevice *device)
{
NMSettingGsm *setting;
char *command;
- guint id;
char *responses[] = { "OK", "ERROR", "ERR", NULL };
- gboolean success;
- setting = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM));
+ setting = NM_SETTING_GSM (gsm_device_get_setting (device, NM_TYPE_SETTING_GSM));
command = g_strdup_printf ("AT+COPS=1,2,\"%s\"", setting->network_id);
- success = nm_serial_device_send_command_string (device, command);
+ modem_wait_for_reply (device, command, 30, responses, responses, manual_registration_done);
g_free (command);
-
- if (success) {
- id = nm_serial_device_wait_for_reply (device, 30, responses, responses, manual_registration_done, NULL);
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- } else {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- }
}
static void
@@ -272,38 +259,26 @@
const char *response,
gpointer user_data)
{
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
-
if (response)
nm_info ("Associated with network: %s", response);
else
nm_warning ("Couldn't read active network name");
- set_apn (device);
+ set_apn (NM_GSM_DEVICE (device));
}
static void
-automatic_registration_get_network (NMSerialDevice *device)
+automatic_registration_get_network (NMGsmDevice *device)
{
- guint id;
const char terminators[] = { '\r', '\n', '\0' };
- if (!nm_serial_device_send_command_string (device, "AT+COPS?")) {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- return;
- }
-
- id = nm_serial_device_get_reply (device, 10, terminators, get_network_done, NULL);
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+ modem_get_reply (device, "AT+COPS?", 10, terminators, get_network_done);
}
static gboolean
automatic_registration_again (gpointer data)
{
- automatic_registration (NM_SERIAL_DEVICE (data));
+ automatic_registration (NM_GSM_DEVICE (data));
return FALSE;
}
@@ -312,20 +287,17 @@
int reply_index,
gpointer user_data)
{
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
nm_info ("Registered on Home network");
- automatic_registration_get_network (device);
+ automatic_registration_get_network (NM_GSM_DEVICE (device));
break;
case 1:
nm_info ("Registered on Roaming network");
- automatic_registration_get_network (device);
+ automatic_registration_get_network (NM_GSM_DEVICE (device));
break;
case 2:
- gsm_device_set_pending (NM_GSM_DEVICE (device),
- g_timeout_add (1000, automatic_registration_again, device));
+ NM_GSM_DEVICE_GET_PRIVATE (device)->pending_id = g_timeout_add (1000, automatic_registration_again, device);
break;
case 3:
nm_warning ("Automatic registration failed: not registered and not searching.");
@@ -343,30 +315,20 @@
}
static void
-automatic_registration (NMSerialDevice *device)
+automatic_registration (NMGsmDevice *device)
{
- guint id;
char *responses[] = { "+CREG: 0,1", "+CREG: 0,5", "+CREG: 0,2", "+CREG: 0,0", NULL };
char *terminators[] = { "OK", "ERROR", "ERR", NULL };
- if (!nm_serial_device_send_command_string (device, "AT+CREG?")) {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- return;
- }
-
- id = nm_serial_device_wait_for_reply (device, 60, responses, terminators, automatic_registration_response, NULL);
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+ modem_wait_for_reply (device, "AT+CREG?", 60, responses, terminators, automatic_registration_response);
}
static void
-do_register (NMSerialDevice *device)
+do_register (NMGsmDevice *device)
{
NMSettingGsm *setting;
- setting = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM));
+ setting = NM_SETTING_GSM (gsm_device_get_setting (device, NM_TYPE_SETTING_GSM));
if (setting->network_id)
manual_registration (device);
@@ -379,11 +341,9 @@
int reply_index,
gpointer user_data)
{
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
- do_register (device);
+ do_register (NM_GSM_DEVICE (device));
break;
case -1:
nm_warning ("Modem second stage initialization timed out");
@@ -397,24 +357,11 @@
}
static void
-init_modem_full (NMSerialDevice *device)
+init_modem_full (NMGsmDevice *device)
{
- guint id;
char *responses[] = { "OK", "ERROR", "ERR", NULL };
- /* At this point we know that SIM has been unlocked, and we can safely
- * initialize the modem
- */
- if (!nm_serial_device_send_command_string (device, "ATZ")) {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- return;
- }
-
- id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_full_done, NULL);
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+ modem_wait_for_reply (device, "ATZ", 10, responses, responses, init_full_done);
}
static void
@@ -424,10 +371,9 @@
{
NMSettingGsm *setting;
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
switch (reply_index) {
case 0:
- init_modem_full (device);
+ init_modem_full (NM_GSM_DEVICE (device));
break;
case -1:
nm_warning ("Did not receive response for secret");
@@ -453,13 +399,13 @@
break;
}
- enter_pin (device, TRUE);
+ enter_pin (NM_GSM_DEVICE (device), TRUE);
break;
}
}
static void
-enter_pin (NMSerialDevice *device, gboolean retry)
+enter_pin (NMGsmDevice *device, gboolean retry)
{
NMSettingGsm *setting;
NMActRequest *req;
@@ -490,23 +436,11 @@
if (secret) {
char *command;
- guint id;
char *responses[] = { "OK", "ERROR", "ERR", NULL };
- gboolean success;
command = g_strdup_printf ("AT+CPIN=\"%s\"", secret);
- success = nm_serial_device_send_command_string (device, command);
+ modem_wait_for_reply (device, command, 3, responses, responses, enter_pin_done);
g_free (command);
-
- if (success) {
- id = nm_serial_device_wait_for_reply (device, 3, responses, responses, enter_pin_done, NULL);
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- } else {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- }
} else {
nm_info ("(%s): GSM %s secret required", nm_device_get_iface (NM_DEVICE (device)), secret_name);
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_NEED_AUTH);
@@ -519,19 +453,17 @@
int reply_index,
gpointer user_data)
{
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
- do_register (device);
+ do_register (NM_GSM_DEVICE (device));
break;
case 1:
NM_GSM_DEVICE_GET_PRIVATE (device)->need_secret = NM_GSM_SECRET_PIN;
- enter_pin (device, FALSE);
+ enter_pin (NM_GSM_DEVICE (device), FALSE);
break;
case 2:
NM_GSM_DEVICE_GET_PRIVATE (device)->need_secret = NM_GSM_SECRET_PUK;
- enter_pin (device, FALSE);
+ enter_pin (NM_GSM_DEVICE (device), FALSE);
break;
case -1:
nm_warning ("PIN checking timed out");
@@ -545,22 +477,12 @@
}
static void
-check_pin (NMSerialDevice *device)
+check_pin (NMGsmDevice *self)
{
- guint id;
char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL };
char *terminators[] = { "OK", "ERROR", "ERR", NULL };
- if (!nm_serial_device_send_command_string (device, "AT+CPIN?")) {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- return;
- }
-
- id = nm_serial_device_wait_for_reply (device, 3, responses, terminators, check_pin_done, NULL);
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+ modem_wait_for_reply (self, "AT+CPIN?", 3, responses, terminators, check_pin_done);
}
static void
@@ -568,11 +490,9 @@
int reply_index,
gpointer user_data)
{
- gsm_device_set_pending (NM_GSM_DEVICE (device), 0);
-
switch (reply_index) {
case 0:
- check_pin (device);
+ check_pin (NM_GSM_DEVICE (device));
break;
case -1:
nm_warning ("Modem initialization timed out");
@@ -588,18 +508,9 @@
static void
init_modem (NMSerialDevice *device, gpointer user_data)
{
- guint id;
char *responses[] = { "OK", "ERROR", "ERR", NULL };
- if (!nm_serial_device_send_command_string (device, "ATZ E0")) {
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
- return;
- }
- id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL);
- if (id)
- gsm_device_set_pending (NM_GSM_DEVICE (device), id);
- else
- nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
+ modem_wait_for_reply (NM_GSM_DEVICE (device), "AT E0", 10, responses, responses, init_done);
}
static NMActStageReturn
@@ -608,6 +519,7 @@
NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device);
NMSettingSerial *setting;
+ guint id;
priv->need_secret = NM_GSM_SECRET_NONE;
@@ -616,9 +528,9 @@
if (!nm_serial_device_open (serial_device, setting))
return NM_ACT_STAGE_RETURN_FAILURE;
- priv->pending_id = nm_serial_device_flash (serial_device, 100, init_modem, NULL);
+ id = nm_serial_device_flash (serial_device, 100, init_modem, NULL);
- return priv->pending_id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
+ return id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
}
static NMConnection *
Modified: trunk/src/nm-serial-device.c
==============================================================================
--- trunk/src/nm-serial-device.c (original)
+++ trunk/src/nm-serial-device.c Mon Jun 30 12:18:57 2008
@@ -36,6 +36,9 @@
NMIP4Config *pending_ip4_config;
struct termios old_t;
+ guint pending_id;
+ guint timeout_id;
+
/* PPP stats */
guint32 in_bytes;
guint32 out_bytes;
@@ -228,6 +231,98 @@
return setting;
}
+/* Timeout handling */
+
+static void
+nm_serial_device_timeout_removed (gpointer data)
+{
+ NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (data);
+
+ priv->timeout_id = 0;
+}
+
+static gboolean
+nm_serial_device_timed_out (gpointer data)
+{
+ NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (data);
+
+ /* Cancel data reading */
+ if (priv->pending_id)
+ g_source_remove (priv->pending_id);
+ else
+ nm_warning ("Timeout reached, but there's nothing to time out");
+
+ return FALSE;
+}
+
+static void
+nm_serial_device_add_timeout (NMSerialDevice *self, guint timeout)
+{
+ NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (self);
+
+ if (priv->pending_id == 0)
+ nm_warning ("Adding a time out while not waiting for any data");
+
+ if (priv->timeout_id) {
+ nm_warning ("Trying to add a new time out while the old one still exists");
+ g_source_remove (priv->timeout_id);
+ }
+
+ priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
+ timeout * 1000,
+ nm_serial_device_timed_out,
+ self,
+ nm_serial_device_timeout_removed);
+ if (G_UNLIKELY (priv->timeout_id == 0))
+ nm_warning ("Registering serial device time out failed.");
+}
+
+static void
+nm_serial_device_remove_timeout (NMSerialDevice *self)
+{
+ NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (self);
+
+ if (priv->timeout_id)
+ g_source_remove (priv->timeout_id);
+}
+
+/* Pending data reading */
+
+static guint
+nm_serial_device_set_pending (NMSerialDevice *device,
+ guint timeout,
+ GIOFunc callback,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
+
+ if (G_UNLIKELY (priv->pending_id)) {
+ /* FIXME: Probably should queue up pending calls instead? */
+ /* Multiple pending calls on the same GIOChannel doesn't work, so let's cancel the previous one. */
+ nm_warning ("Adding new pending call while previous one isn't finished.");
+ nm_warning ("Cancelling the previous pending call.");
+ g_source_remove (priv->pending_id);
+ }
+
+ priv->pending_id = g_io_add_watch_full (priv->channel,
+ G_PRIORITY_DEFAULT,
+ G_IO_IN | G_IO_ERR | G_IO_HUP,
+ callback, user_data, notify);
+
+ nm_serial_device_add_timeout (device, timeout);
+
+ return priv->pending_id;}
+
+static void
+nm_serial_device_pending_done (NMSerialDevice *self)
+{
+ NM_SERIAL_DEVICE_GET_PRIVATE (self)->pending_id = 0;
+ nm_serial_device_remove_timeout (self);
+}
+
+/****/
+
static gboolean
config_fd (NMSerialDevice *device, NMSettingSerial *setting)
{
@@ -315,6 +410,9 @@
priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
+ if (priv->pending_id)
+ g_source_remove (priv->pending_id);
+
if (priv->fd) {
nm_debug ("Closing device '%s'", nm_device_get_iface (NM_DEVICE (device)));
@@ -389,34 +487,23 @@
GString *result;
NMSerialGetReplyFn callback;
gpointer user_data;
- guint timeout_id;
- guint got_data_id;
} GetReplyInfo;
static void
-get_reply_info_destroy (gpointer data)
+get_reply_done (gpointer data)
{
GetReplyInfo *info = (GetReplyInfo *) data;
- if (info->got_data_id)
- g_source_remove (info->got_data_id);
+ nm_serial_device_pending_done (info->device);
- g_free (info->terminators);
-
- if (info->result)
- g_string_free (info->result, TRUE);
-
- g_free (info);
-}
-
-static gboolean
-get_reply_timeout (gpointer data)
-{
- GetReplyInfo *info = (GetReplyInfo *) data;
+ /* Call the callback */
+ info->callback (info->device, info->result->str, info->user_data);
- info->callback (info->device, NULL, info->user_data);
+ /* Free info */
+ g_free (info->terminators);
+ g_string_free (info->result, TRUE);
- return FALSE;
+ g_slice_free (GetReplyInfo, info);
}
static gboolean
@@ -431,8 +518,10 @@
gboolean done = FALSE;
int i;
- if (!(condition & G_IO_IN))
- goto done;
+ if (condition & G_IO_HUP || condition & G_IO_ERR) {
+ g_string_truncate (info->result, 0);
+ return FALSE;
+ }
do {
GError *err = NULL;
@@ -474,30 +563,11 @@
if (info->result->len > SERIAL_BUF_SIZE) {
g_warning ("%s (%s): response buffer filled before repsonse received",
__func__, nm_device_get_iface (NM_DEVICE (info->device)));
- g_string_free (info->result, TRUE);
- info->result = NULL;
+ g_string_truncate (info->result, 0);
done = TRUE;
}
} while (!done || bytes_read == SERIAL_BUF_SIZE || status == G_IO_STATUS_AGAIN);
-done:
- if (condition & G_IO_HUP || condition & G_IO_ERR) {
- g_string_free (info->result, TRUE);
- info->result = NULL;
- done = TRUE;
- }
-
- if (done) {
- char *result = info->result ? g_string_free (info->result, FALSE) : NULL;
- info->result = NULL;
- info->callback (info->device, result, info->user_data);
- g_free (result);
-
- /* Clear the id - returning FALSE already removes it */
- info->got_data_id = 0;
- g_source_remove (info->timeout_id);
- }
-
return !done;
}
@@ -514,25 +584,14 @@
g_return_val_if_fail (terminators != NULL, 0);
g_return_val_if_fail (callback != NULL, 0);
- info = g_new (GetReplyInfo, 1);
+ info = g_slice_new0 (GetReplyInfo);
info->device = device;
info->terminators = g_strdup (terminators);
info->result = g_string_new (NULL);
info->callback = callback;
info->user_data = user_data;
- info->got_data_id = g_io_add_watch (NM_SERIAL_DEVICE_GET_PRIVATE (device)->channel,
- G_IO_IN | G_IO_ERR | G_IO_HUP,
- get_reply_got_data,
- info);
-
- info->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
- timeout * 1000,
- get_reply_timeout,
- info,
- get_reply_info_destroy);
-
- return info->timeout_id;
+ return nm_serial_device_set_pending (device, timeout, get_reply_got_data, info, get_reply_done);
}
typedef struct {
@@ -542,36 +601,28 @@
GString *result;
NMSerialWaitForReplyFn callback;
gpointer user_data;
+ int reply_index;
guint timeout;
time_t start;
- guint timeout_id;
- guint got_data_id;
} WaitForReplyInfo;
static void
-wait_for_reply_info_destroy (gpointer data)
+wait_for_reply_done (gpointer data)
{
WaitForReplyInfo *info = (WaitForReplyInfo *) data;
- if (info->got_data_id)
- g_source_remove (info->got_data_id);
+ nm_serial_device_pending_done (info->device);
+ /* Call the callback */
+ info->callback (info->device, info->reply_index, info->user_data);
+
+ /* Free info */
if (info->result)
g_string_free (info->result, TRUE);
g_strfreev (info->str_needles);
g_strfreev (info->terminators);
- g_free (info);
-}
-
-static gboolean
-wait_for_reply_timeout (gpointer data)
-{
- WaitForReplyInfo *info = (WaitForReplyInfo *) data;
-
- info->callback (info->device, -1, info->user_data);
-
- return FALSE;
+ g_slice_free (WaitForReplyInfo, info);
}
static gboolean
@@ -614,10 +665,9 @@
GIOStatus status;
gboolean got_response = FALSE;
gboolean done = FALSE;
- int idx = -1;
- if (!(condition & G_IO_IN))
- goto done;
+ if (condition & G_IO_HUP || condition & G_IO_ERR)
+ return FALSE;
do {
GError *err = NULL;
@@ -663,8 +713,8 @@
tmp = g_strstrip (line);
if (tmp && strlen (tmp)) {
done = find_terminator (tmp, info->terminators);
- if (idx == -1)
- got_response = find_response (tmp, info->str_needles, &idx);
+ if (info->reply_index == -1)
+ got_response = find_response (tmp, info->str_needles, &(info->reply_index));
}
}
@@ -692,18 +742,6 @@
g_usleep (50);
} while (!done || bytes_read == SERIAL_BUF_SIZE || status == G_IO_STATUS_AGAIN);
-done:
- if (condition & G_IO_HUP || condition & G_IO_ERR)
- done = TRUE;
-
- if (done) {
- info->callback (info->device, idx, info->user_data);
-
- /* Clear the id - returning FALSE already removes it */
- info->got_data_id = 0;
- g_source_remove (info->timeout_id);
- }
-
return !done;
}
@@ -721,28 +759,18 @@
g_return_val_if_fail (responses != NULL, 0);
g_return_val_if_fail (callback != NULL, 0);
- info = g_new0 (WaitForReplyInfo, 1);
+ info = g_slice_new0 (WaitForReplyInfo);
info->device = device;
info->str_needles = g_strdupv (responses);
info->terminators = g_strdupv (terminators);
info->result = g_string_new (NULL);
info->callback = callback;
info->user_data = user_data;
-
- info->got_data_id = g_io_add_watch (NM_SERIAL_DEVICE_GET_PRIVATE (device)->channel,
- G_IO_IN | G_IO_ERR | G_IO_HUP,
- wait_for_reply_got_data,
- info);
-
+ info->reply_index = -1;
info->timeout = timeout * 1000;
info->start = time (NULL);
- info->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
- timeout * 1000,
- wait_for_reply_timeout,
- info,
- wait_for_reply_info_destroy);
- return info->timeout_id;
+ return nm_serial_device_set_pending (device, timeout, wait_for_reply_got_data, info, wait_for_reply_done);
}
#if 0
@@ -753,14 +781,18 @@
gpointer user_data;
} WaitQuietInfo;
-static gboolean
+static void
wait_quiet_done (gpointer data)
{
WaitQuietInfo *info = (WaitQuietInfo *) data;
+ nm_serial_device_pending_done (info->device);
+
+ /* Call the callback */
info->callback (info->device, info->timed_out, info->user_data);
- return FALSE;
+ /* Free info */
+ g_slice_free (WaitQuietInfo, info);
}
static gboolean
@@ -769,7 +801,7 @@
WaitQuietInfo *info = (WaitQuietInfo *) data;
info->timed_out = FALSE;
- wait_quiet_done (data);
+ g_source_remove (NM_SERIAL_DEVICE_GET_PRIVATE (info->device)->pending);
return FALSE;
}
@@ -784,6 +816,9 @@
char buf[4096];
GIOStatus status;
+ if (condition & G_IO_HUP || condition & G_IO_ERR)
+ return FALSE;
+
if (condition & G_IO_IN) {
do {
status = g_io_channel_read_chars (source, buf, 4096, &bytes_read, NULL);
@@ -796,11 +831,6 @@
} while (bytes_read == 4096 || status == G_IO_STATUS_AGAIN);
}
- if (condition & G_IO_HUP || condition & G_IO_ERR) {
- wait_quiet_done (data);
- return FALSE
- }
-
return TRUE;
}
@@ -816,27 +846,16 @@
g_return_if_fail (NM_IS_SERIAL_DEVICE (device));
g_return_if_fail (callback != NULL);
- info = g_new (WaitQuietInfo, 1);
-
+ info = g_slice_new0 (WaitQuietInfo);
info->device = device;
info->timed_out = TRUE;
info->callback = callback;
info->user_data = user_data;
-
- info->got_data_id = g_io_add_watch (NM_SERIAL_DEVICE_GET_PRIVATE (device)->channel,
- G_IO_IN | G_IO_ERR | G_IO_HUP,
- wait_quiet_got_data,
- info);
-
info->quiet_id = g_timeout_add (quiet_time,
wait_quiet_timeout,
info);
- info->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
- timeout,
- wait_quiet_timeout,
- info,
- wait_quiet_info_destroy);
+ return nm_serial_device_set_pending (device, timeout, wait_quiet_got_data, info, wait_quiet_done);
}
#endif
@@ -874,14 +893,25 @@
tcsetattr (fd, TCSANOW, &options);
}
-static gboolean
+static void
flash_done (gpointer data)
{
FlashInfo *info = (FlashInfo *) data;
- set_speed (info->device, info->current_speed);
+ NM_SERIAL_DEVICE_GET_PRIVATE (info->device)->pending_id = 0;
+
info->callback (info->device, info->user_data);
+ g_slice_free (FlashInfo, info);
+}
+
+static gboolean
+flash_do (gpointer data)
+{
+ FlashInfo *info = (FlashInfo *) data;
+
+ set_speed (info->device, info->current_speed);
+
return FALSE;
}
@@ -892,11 +922,12 @@
gpointer user_data)
{
FlashInfo *info;
+ guint id;
g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0);
g_return_val_if_fail (callback != NULL, 0);
- info = g_new (FlashInfo, 1);
+ info = g_slice_new0 (FlashInfo);
info->device = device;
info->current_speed = get_speed (device);
info->callback = callback;
@@ -904,11 +935,15 @@
set_speed (device, B0);
- return g_timeout_add_full (G_PRIORITY_DEFAULT,
- flash_time,
- flash_done,
- info,
- g_free);
+ id = g_timeout_add_full (G_PRIORITY_DEFAULT,
+ flash_time,
+ flash_do,
+ info,
+ flash_done);
+
+ NM_SERIAL_DEVICE_GET_PRIVATE (device)->pending_id = id;
+
+ return id;
}
GIOChannel *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]