2008-03-10 Dan Williams <dcbw@redhat.com>

* src/nm-serial-device.c
		- (nm_serial_device_send_command): report errno on error
		- (get_reply_got_data): limit the size of the overall buffer
		- (wait_for_reply_info_destroy): destroy result string
		- (wait_for_reply_got_data): append received data to an overall buffer
			until timeout, filled buffer, or error instead of keeping a per-call
			buffer.  Some devices send data slowly enough that this function
			gets called multiple times for the same command stream.
		- (nm_serial_device_wait_for_reply): initialize overall buffer for
			wait_for_reply_got_data() here



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3415 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2008-03-10 21:34:42 +00:00
parent e4bbf230d2
commit bf104fbc78
2 changed files with 40 additions and 10 deletions

View file

@ -1,3 +1,16 @@
2008-03-10 Dan Williams <dcbw@redhat.com>
* src/nm-serial-device.c
- (nm_serial_device_send_command): report errno on error
- (get_reply_got_data): limit the size of the overall buffer
- (wait_for_reply_info_destroy): destroy result string
- (wait_for_reply_got_data): append received data to an overall buffer
until timeout, filled buffer, or error instead of keeping a per-call
buffer. Some devices send data slowly enough that this function
gets called multiple times for the same command stream.
- (nm_serial_device_wait_for_reply): initialize overall buffer for
wait_for_reply_got_data() here
2008-03-10 Dan Williams <dcbw@redhat.com> 2008-03-10 Dan Williams <dcbw@redhat.com>
* src/nm-cdma-device.c * src/nm-cdma-device.c

View file

@ -336,7 +336,7 @@ nm_serial_device_send_command (NMSerialDevice *device, GByteArray *command)
if (errno == EAGAIN) if (errno == EAGAIN)
goto again; goto again;
g_warning ("Error in writing"); g_warning ("Error in writing (errno %d)", errno);
return FALSE; return FALSE;
} }
@ -421,7 +421,6 @@ get_reply_got_data (GIOChannel *source,
GError *err = NULL; GError *err = NULL;
status = g_io_channel_read_chars (source, buf, SERIAL_BUF_SIZE, &bytes_read, &err); status = g_io_channel_read_chars (source, buf, SERIAL_BUF_SIZE, &bytes_read, &err);
if (status == G_IO_STATUS_ERROR) { if (status == G_IO_STATUS_ERROR) {
g_warning ("%s", err->message); g_warning ("%s", err->message);
g_error_free (err); g_error_free (err);
@ -453,6 +452,15 @@ get_reply_got_data (GIOChannel *source,
g_string_append_c (info->result, *p); g_string_append_c (info->result, *p);
} }
} }
/* Limit the size of the buffer */
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;
done = TRUE;
}
} while (!done || bytes_read == SERIAL_BUF_SIZE || status == G_IO_STATUS_AGAIN); } while (!done || bytes_read == SERIAL_BUF_SIZE || status == G_IO_STATUS_AGAIN);
done: done:
@ -513,6 +521,7 @@ nm_serial_device_get_reply (NMSerialDevice *device,
typedef struct { typedef struct {
NMSerialDevice *device; NMSerialDevice *device;
char **str_needles; char **str_needles;
GString *result;
NMSerialWaitForReplyFn callback; NMSerialWaitForReplyFn callback;
gpointer user_data; gpointer user_data;
guint timeout_id; guint timeout_id;
@ -527,6 +536,9 @@ wait_for_reply_info_destroy (gpointer data)
if (info->got_data_id) if (info->got_data_id)
g_source_remove (info->got_data_id); g_source_remove (info->got_data_id);
if (info->result)
g_string_free (info->result, TRUE);
g_strfreev (info->str_needles); g_strfreev (info->str_needles);
g_free (info); g_free (info);
} }
@ -547,7 +559,6 @@ wait_for_reply_got_data (GIOChannel *source,
gpointer data) gpointer data)
{ {
WaitForReplyInfo *info = (WaitForReplyInfo *) data; WaitForReplyInfo *info = (WaitForReplyInfo *) data;
GString *response = NULL;
gchar buf[SERIAL_BUF_SIZE + 1]; gchar buf[SERIAL_BUF_SIZE + 1];
gsize bytes_read; gsize bytes_read;
GIOStatus status; GIOStatus status;
@ -558,7 +569,6 @@ wait_for_reply_got_data (GIOChannel *source,
if (!(condition & G_IO_IN)) if (!(condition & G_IO_IN))
goto done; goto done;
response = g_string_new (NULL);
do { do {
GError *err = NULL; GError *err = NULL;
@ -571,20 +581,26 @@ wait_for_reply_got_data (GIOChannel *source,
if (bytes_read > 0) { if (bytes_read > 0) {
buf[bytes_read] = 0; buf[bytes_read] = 0;
g_string_append (response, buf); g_string_append (info->result, buf);
serial_debug ("Got:", response->str, response->len); serial_debug ("Got:", info->result->str, info->result->len);
for (i = 0; info->str_needles[i]; i++) { for (i = 0; info->str_needles[i]; i++) {
if (strcasestr (response->str, info->str_needles[i])) { if ( info->result->str
&& strcasestr (info->result->str, info->str_needles[i])) {
idx = i; idx = i;
done = TRUE; done = TRUE;
} }
} }
} }
} while (bytes_read == SERIAL_BUF_SIZE || status == G_IO_STATUS_AGAIN);
g_string_free (response, TRUE); /* Limit the size of the buffer */
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)));
done = TRUE;
}
} while (!done || bytes_read == SERIAL_BUF_SIZE || status == G_IO_STATUS_AGAIN);
done: done:
if (condition & G_IO_HUP || condition & G_IO_ERR) if (condition & G_IO_HUP || condition & G_IO_ERR)
@ -625,9 +641,10 @@ nm_serial_device_wait_for_reply (NMSerialDevice *device,
} }
str_array[i] = NULL; str_array[i] = NULL;
info = g_new (WaitForReplyInfo, 1); info = g_new0 (WaitForReplyInfo, 1);
info->device = device; info->device = device;
info->str_needles = str_array; info->str_needles = str_array;
info->result = g_string_new (NULL);
info->callback = callback; info->callback = callback;
info->user_data = user_data; info->user_data = user_data;