NetworkManager r3782 - in trunk: . src



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]