mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-06 05:38:15 +02:00
2008-04-17 Dan Williams <dcbw@redhat.com>
* src/nm-serial-device.c src/nm-serial-device.h - (wait_for_reply_got_data): break input into lines, and search each line for responses _and_ terminator strings; also make sure that the read loop doesn't continue after the timeout is supposed to fire - (nm_serial_device_wait_for_reply): take an array of terminators too * src/nm-gsm-device.c src/nm-cdma-device.c - Send terminators to nm_serial_device_wait_for_reply() git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3570 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
parent
48971a4e85
commit
bcbf96cf7f
5 changed files with 110 additions and 28 deletions
13
ChangeLog
13
ChangeLog
|
|
@ -1,3 +1,16 @@
|
||||||
|
2008-04-17 Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
|
* src/nm-serial-device.c
|
||||||
|
src/nm-serial-device.h
|
||||||
|
- (wait_for_reply_got_data): break input into lines, and search each
|
||||||
|
line for responses _and_ terminator strings; also make sure that
|
||||||
|
the read loop doesn't continue after the timeout is supposed to fire
|
||||||
|
- (nm_serial_device_wait_for_reply): take an array of terminators too
|
||||||
|
|
||||||
|
* src/nm-gsm-device.c
|
||||||
|
src/nm-cdma-device.c
|
||||||
|
- Send terminators to nm_serial_device_wait_for_reply()
|
||||||
|
|
||||||
2008-04-16 Dan Williams <dcbw@redhat.com>
|
2008-04-16 Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
Patch from 陈鑫 <znscnchen@gmail.com>
|
Patch from 陈鑫 <znscnchen@gmail.com>
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ do_dial (NMSerialDevice *device)
|
||||||
g_free (command);
|
g_free (command);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
id = nm_serial_device_wait_for_reply (device, 60, responses, dial_done, NULL);
|
id = nm_serial_device_wait_for_reply (device, 60, responses, responses, dial_done, NULL);
|
||||||
if (id)
|
if (id)
|
||||||
cdma_device_set_pending (NM_CDMA_DEVICE (device), id);
|
cdma_device_set_pending (NM_CDMA_DEVICE (device), id);
|
||||||
else
|
else
|
||||||
|
|
@ -171,14 +171,14 @@ static void
|
||||||
init_modem (NMSerialDevice *device, gpointer user_data)
|
init_modem (NMSerialDevice *device, gpointer user_data)
|
||||||
{
|
{
|
||||||
guint id;
|
guint id;
|
||||||
char *responses[] = { "OK", "ERR", NULL };
|
char *responses[] = { "OK", "ERROR", "ERR", NULL };
|
||||||
|
|
||||||
if (!nm_serial_device_send_command_string (device, "ATZ E0")) {
|
if (!nm_serial_device_send_command_string (device, "ATZ E0")) {
|
||||||
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
|
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = nm_serial_device_wait_for_reply (device, 10, responses, init_done, NULL);
|
id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL);
|
||||||
|
|
||||||
if (id)
|
if (id)
|
||||||
cdma_device_set_pending (NM_CDMA_DEVICE (device), id);
|
cdma_device_set_pending (NM_CDMA_DEVICE (device), id);
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ do_dial (NMSerialDevice *device)
|
||||||
g_free (command);
|
g_free (command);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
id = nm_serial_device_wait_for_reply (device, 60, responses, dial_done, NULL);
|
id = nm_serial_device_wait_for_reply (device, 60, responses, responses, dial_done, NULL);
|
||||||
if (id)
|
if (id)
|
||||||
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
||||||
else
|
else
|
||||||
|
|
@ -192,7 +192,7 @@ manual_registration (NMSerialDevice *device)
|
||||||
g_free (command);
|
g_free (command);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
id = nm_serial_device_wait_for_reply (device, 30, responses, manual_registration_done, NULL);
|
id = nm_serial_device_wait_for_reply (device, 30, responses, responses, manual_registration_done, NULL);
|
||||||
if (id)
|
if (id)
|
||||||
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
||||||
else
|
else
|
||||||
|
|
@ -282,13 +282,14 @@ automatic_registration (NMSerialDevice *device)
|
||||||
{
|
{
|
||||||
guint id;
|
guint id;
|
||||||
char *responses[] = { "+CREG: 0,1", "+CREG: 0,5", "+CREG: 0,2", "+CREG: 0,0", NULL };
|
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?")) {
|
if (!nm_serial_device_send_command_string (device, "AT+CREG?")) {
|
||||||
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
|
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = nm_serial_device_wait_for_reply (device, 60, responses, automatic_registration_response, NULL);
|
id = nm_serial_device_wait_for_reply (device, 60, responses, terminators, automatic_registration_response, NULL);
|
||||||
if (id)
|
if (id)
|
||||||
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
||||||
else
|
else
|
||||||
|
|
@ -391,7 +392,7 @@ enter_pin (NMSerialDevice *device, gboolean retry)
|
||||||
g_free (command);
|
g_free (command);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
id = nm_serial_device_wait_for_reply (device, 3, responses, enter_pin_done, NULL);
|
id = nm_serial_device_wait_for_reply (device, 3, responses, responses, enter_pin_done, NULL);
|
||||||
if (id)
|
if (id)
|
||||||
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
||||||
else
|
else
|
||||||
|
|
@ -441,13 +442,14 @@ check_pin (NMSerialDevice *device)
|
||||||
{
|
{
|
||||||
guint id;
|
guint id;
|
||||||
char *responses[] = { "READY", "SIM PIN", "SIM PUK", "ERROR", "ERR", NULL };
|
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?")) {
|
if (!nm_serial_device_send_command_string (device, "AT+CPIN?")) {
|
||||||
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
|
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = nm_serial_device_wait_for_reply (device, 3, responses, check_pin_done, NULL);
|
id = nm_serial_device_wait_for_reply (device, 3, responses, terminators, check_pin_done, NULL);
|
||||||
if (id)
|
if (id)
|
||||||
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
||||||
else
|
else
|
||||||
|
|
@ -480,14 +482,14 @@ static void
|
||||||
init_modem (NMSerialDevice *device, gpointer user_data)
|
init_modem (NMSerialDevice *device, gpointer user_data)
|
||||||
{
|
{
|
||||||
guint id;
|
guint id;
|
||||||
char *responses[] = { "OK", "ERR", NULL };
|
char *responses[] = { "OK", "ERROR", "ERR", NULL };
|
||||||
|
|
||||||
if (!nm_serial_device_send_command_string (device, "ATZ E0")) {
|
if (!nm_serial_device_send_command_string (device, "ATZ E0")) {
|
||||||
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
|
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = nm_serial_device_wait_for_reply (device, 10, responses, init_done, NULL);
|
id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL);
|
||||||
if (id)
|
if (id)
|
||||||
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
gsm_device_set_pending (NM_GSM_DEVICE (device), id);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -524,9 +524,12 @@ nm_serial_device_get_reply (NMSerialDevice *device,
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMSerialDevice *device;
|
NMSerialDevice *device;
|
||||||
char **str_needles;
|
char **str_needles;
|
||||||
|
char **terminators;
|
||||||
GString *result;
|
GString *result;
|
||||||
NMSerialWaitForReplyFn callback;
|
NMSerialWaitForReplyFn callback;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
|
guint timeout;
|
||||||
|
time_t start;
|
||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
guint got_data_id;
|
guint got_data_id;
|
||||||
} WaitForReplyInfo;
|
} WaitForReplyInfo;
|
||||||
|
|
@ -543,6 +546,7 @@ wait_for_reply_info_destroy (gpointer data)
|
||||||
g_string_free (info->result, TRUE);
|
g_string_free (info->result, TRUE);
|
||||||
|
|
||||||
g_strfreev (info->str_needles);
|
g_strfreev (info->str_needles);
|
||||||
|
g_strfreev (info->terminators);
|
||||||
g_free (info);
|
g_free (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -556,6 +560,35 @@ wait_for_reply_timeout (gpointer data)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
find_terminator (const char *line, char **terminators)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; terminators[i]; i++) {
|
||||||
|
if (!strcasecmp (line, terminators[i]))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
find_response (const char *line, char **responses, gint *idx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Don't look for a result again if we got one previously */
|
||||||
|
for (i = 0; responses[i]; i++) {
|
||||||
|
if (strcasestr (line, responses[i])) {
|
||||||
|
*idx = i;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RESPONSE_LINE_MAX 128
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
wait_for_reply_got_data (GIOChannel *source,
|
wait_for_reply_got_data (GIOChannel *source,
|
||||||
GIOCondition condition,
|
GIOCondition condition,
|
||||||
|
|
@ -565,9 +598,9 @@ wait_for_reply_got_data (GIOChannel *source,
|
||||||
gchar buf[SERIAL_BUF_SIZE + 1];
|
gchar buf[SERIAL_BUF_SIZE + 1];
|
||||||
gsize bytes_read;
|
gsize bytes_read;
|
||||||
GIOStatus status;
|
GIOStatus status;
|
||||||
|
gboolean got_response = FALSE;
|
||||||
gboolean done = FALSE;
|
gboolean done = FALSE;
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!(condition & G_IO_IN))
|
if (!(condition & G_IO_IN))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -587,14 +620,42 @@ wait_for_reply_got_data (GIOChannel *source,
|
||||||
g_string_append (info->result, buf);
|
g_string_append (info->result, buf);
|
||||||
|
|
||||||
serial_debug ("Got:", info->result->str, info->result->len);
|
serial_debug ("Got:", info->result->str, info->result->len);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; info->str_needles[i]; i++) {
|
/* Look for needles and terminators */
|
||||||
if ( info->result->str
|
if ((bytes_read > 0) && info->result->str) {
|
||||||
&& strcasestr (info->result->str, info->str_needles[i])) {
|
char *p = info->result->str;
|
||||||
idx = i;
|
|
||||||
done = TRUE;
|
/* Break the response up into lines and process each one */
|
||||||
|
while ( (p < info->result->str + strlen (info->result->str))
|
||||||
|
&& !(done && got_response)) {
|
||||||
|
char line[RESPONSE_LINE_MAX] = { '\0', };
|
||||||
|
char *tmp;
|
||||||
|
int i;
|
||||||
|
gboolean got_something = FALSE;
|
||||||
|
|
||||||
|
for (i = 0; *p && (i < RESPONSE_LINE_MAX - 1); p++) {
|
||||||
|
/* Ignore front CR/LF */
|
||||||
|
if ((*p == '\n') || (*p == '\r')) {
|
||||||
|
if (got_something)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
line[i++] = *p;
|
||||||
|
got_something = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line[i] = '\0';
|
||||||
|
|
||||||
|
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 (done && got_response)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Limit the size of the buffer */
|
/* Limit the size of the buffer */
|
||||||
|
|
@ -602,7 +663,19 @@ wait_for_reply_got_data (GIOChannel *source,
|
||||||
g_warning ("%s (%s): response buffer filled before repsonse received",
|
g_warning ("%s (%s): response buffer filled before repsonse received",
|
||||||
__func__, nm_device_get_iface (NM_DEVICE (info->device)));
|
__func__, nm_device_get_iface (NM_DEVICE (info->device)));
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure we don't go over the timeout, in addition to the timeout
|
||||||
|
* handler that's been scheduled. If for some reason this loop doesn't
|
||||||
|
* terminate (terminator not found, whatever) then this should make
|
||||||
|
* sure that NM doesn't spin the CPU forever.
|
||||||
|
*/
|
||||||
|
if (time (NULL) - info->start > info->timeout + 1) {
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
g_usleep (50);
|
||||||
} 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:
|
||||||
|
|
@ -624,29 +697,20 @@ guint
|
||||||
nm_serial_device_wait_for_reply (NMSerialDevice *device,
|
nm_serial_device_wait_for_reply (NMSerialDevice *device,
|
||||||
guint timeout,
|
guint timeout,
|
||||||
char **responses,
|
char **responses,
|
||||||
|
char **terminators,
|
||||||
NMSerialWaitForReplyFn callback,
|
NMSerialWaitForReplyFn callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
WaitForReplyInfo *info;
|
WaitForReplyInfo *info;
|
||||||
char **str_array;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0);
|
g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0);
|
||||||
g_return_val_if_fail (responses != NULL, 0);
|
g_return_val_if_fail (responses != NULL, 0);
|
||||||
g_return_val_if_fail (callback != NULL, 0);
|
g_return_val_if_fail (callback != NULL, 0);
|
||||||
|
|
||||||
/* Copy the array */
|
|
||||||
str_array = g_new (char*, g_strv_length (responses) + 1);
|
|
||||||
i = 0;
|
|
||||||
while (responses[i]) {
|
|
||||||
str_array[i] = g_strdup (responses[i]);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
str_array[i] = NULL;
|
|
||||||
|
|
||||||
info = g_new0 (WaitForReplyInfo, 1);
|
info = g_new0 (WaitForReplyInfo, 1);
|
||||||
info->device = device;
|
info->device = device;
|
||||||
info->str_needles = str_array;
|
info->str_needles = g_strdupv (responses);
|
||||||
|
info->terminators = g_strdupv (terminators);
|
||||||
info->result = g_string_new (NULL);
|
info->result = g_string_new (NULL);
|
||||||
info->callback = callback;
|
info->callback = callback;
|
||||||
info->user_data = user_data;
|
info->user_data = user_data;
|
||||||
|
|
@ -656,6 +720,8 @@ nm_serial_device_wait_for_reply (NMSerialDevice *device,
|
||||||
wait_for_reply_got_data,
|
wait_for_reply_got_data,
|
||||||
info);
|
info);
|
||||||
|
|
||||||
|
info->timeout = timeout * 1000;
|
||||||
|
info->start = time (NULL);
|
||||||
info->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
|
info->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
|
||||||
timeout * 1000,
|
timeout * 1000,
|
||||||
wait_for_reply_timeout,
|
wait_for_reply_timeout,
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ guint nm_serial_device_get_reply (NMSerialDevice *device,
|
||||||
guint nm_serial_device_wait_for_reply (NMSerialDevice *device,
|
guint nm_serial_device_wait_for_reply (NMSerialDevice *device,
|
||||||
guint timeout,
|
guint timeout,
|
||||||
char **responses,
|
char **responses,
|
||||||
|
char **terminators,
|
||||||
NMSerialWaitForReplyFn callback,
|
NMSerialWaitForReplyFn callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue