From cf3101fe1ccc075e8a66397043b6a17469b2cd8a Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Sun, 28 Oct 2007 12:21:55 +0200 Subject: [PATCH] Handle possible errors from g_io_channel_read_chars() --- src/gps-nmea-parse.c | 135 +++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 64 deletions(-) diff --git a/src/gps-nmea-parse.c b/src/gps-nmea-parse.c index 3bf75a6..b97a7ca 100644 --- a/src/gps-nmea-parse.c +++ b/src/gps-nmea-parse.c @@ -29,12 +29,11 @@ #include "gtkgps.h" #include "gtkcompass.h" - #define GPS_FILTER_MAX_SKIP (10) static gint track_drop_cnt=0; gboolean -channel_cb_error(GIOChannel * src, GIOCondition condition, gpointer data) +channel_cb_error(GIOChannel *src, GIOCondition condition, gpointer data) { /* An error has occurred - re-connect(). */ rcvr_disconnect(); @@ -46,7 +45,6 @@ if (_conn_state > RCVR_OFF) { gps_hide_text(); rcvr_connect_later(); } - return FALSE; } @@ -415,71 +413,80 @@ channel_parse_gsv(gchar * sentence) } gboolean -channel_cb_input(GIOChannel * src, GIOCondition condition, gpointer data) +channel_cb_input(GIOChannel *src, GIOCondition condition, gpointer data) { - gsize bytes_read; - vprintf("%s(%d)\n", __PRETTY_FUNCTION__, condition); - - if (G_IO_STATUS_NORMAL == g_io_channel_read_chars(_channel, - _gps_read_buf_curr, _gps_read_buf_last - _gps_read_buf_curr, - &bytes_read, NULL)) { - gchar *eol; - - _gps_read_buf_curr += bytes_read; - *_gps_read_buf_curr = '\0'; /* append a \0 so we can read as string */ - while ((eol = strchr(_gps_read_buf, '\n'))) { - gchar *sptr = _gps_read_buf + 1; /* Skip the $ */ - guint csum = 0; - if (*_gps_read_buf == '$') { - /* This is the beginning of a sentence; okay to parse. */ - *eol = '\0'; /* overwrite \n with \0 */ - while (*sptr && *sptr != '*') - csum ^= *sptr++; - - /* If we're at a \0 (meaning there is no checksum), or if the - * checksum is good, then parse the sentence. */ - if (!*sptr || csum == strtol(sptr + 1, NULL, 16)) { - if (*sptr) - *sptr = '\0'; /* take checksum out of the buffer. */ - if (!strncmp(_gps_read_buf + 3, "GSV", 3)) { - if (_conn_state == RCVR_UP) - channel_parse_gsv(_gps_read_buf + 7); - } else if (!strncmp(_gps_read_buf + 3, "RMC", 3)) - channel_parse_rmc(_gps_read_buf + 7); - else if (!strncmp(_gps_read_buf + 3, "GGA", 3)) - channel_parse_gga(_gps_read_buf + 7); - else if (!strncmp(_gps_read_buf + 3, "GSA", 3)) - channel_parse_gsa(_gps_read_buf + 7); - else g_print("Unknown NMEA: [%s]\n", _gps_read_buf); - - if (_gps_info) - gps_display_data(); - - if (_satdetails_on) - gps_display_details(); - } else { - /* There was a checksum, and it was bad. */ - g_printerr - ("%s: Bad checksum in NMEA sentence:\n%s\n", - __PRETTY_FUNCTION__, - _gps_read_buf); - } - } - - /* If eol is at or after (_gps_read_buf_curr - 1) */ - if (eol >= (_gps_read_buf_curr - 1)) { - /* Last read was a newline - reset read buffer */ - _gps_read_buf_curr = _gps_read_buf; - *_gps_read_buf_curr = '\0'; +gsize bytes_read; +GIOStatus status; +gchar *eol; + +vprintf("%s(%d)\n", __PRETTY_FUNCTION__, condition); + +status=g_io_channel_read_chars(_channel, _gps_read_buf_curr, _gps_read_buf_last - _gps_read_buf_curr, &bytes_read, NULL); + +switch (status) { + case G_IO_STATUS_NORMAL: + _gps_read_buf_curr += bytes_read; + *_gps_read_buf_curr = '\0'; /* append a \0 so we can read as string */ + while ((eol = strchr(_gps_read_buf, '\n'))) { + gchar *sptr = _gps_read_buf + 1; /* Skip the $ */ + guint csum = 0; + if (*_gps_read_buf == '$') { + /* This is the beginning of a sentence; okay to parse. */ + *eol = '\0'; /* overwrite \n with \0 */ + while (*sptr && *sptr != '*') + csum ^= *sptr++; + + /* If we're at a \0 (meaning there is no checksum), or if the + * checksum is good, then parse the sentence. */ + if (!*sptr || csum == strtol(sptr + 1, NULL, 16)) { + if (*sptr) + *sptr = '\0'; /* take checksum out of the buffer. */ + if (!strncmp(_gps_read_buf + 3, "GSV", 3)) { + if (_conn_state == RCVR_UP) + channel_parse_gsv(_gps_read_buf + 7); + } else if (!strncmp(_gps_read_buf + 3, "RMC", 3)) + channel_parse_rmc(_gps_read_buf + 7); + else if (!strncmp(_gps_read_buf + 3, "GGA", 3)) + channel_parse_gga(_gps_read_buf + 7); + else if (!strncmp(_gps_read_buf + 3, "GSA", 3)) + channel_parse_gsa(_gps_read_buf + 7); + else g_print("Unknown NMEA: [%s]\n", _gps_read_buf); + + if (_gps_info) + gps_display_data(); + + if (_satdetails_on) + gps_display_details(); } else { - /* Move the next line to the front of the buffer. */ - memmove(_gps_read_buf, eol + 1, _gps_read_buf_curr - eol); /* include terminating 0 */ - /* Subtract _curr so that it's pointing at the new \0. */ - _gps_read_buf_curr -= (eol - _gps_read_buf + 1); + /* There was a checksum, and it was bad. */ + g_printerr("%s: Bad checksum in NMEA sentence:\n%s\n", __PRETTY_FUNCTION__, _gps_read_buf); } } + + /* If eol is at or after (_gps_read_buf_curr - 1) */ + if (eol >= (_gps_read_buf_curr - 1)) { + /* Last read was a newline - reset read buffer */ + _gps_read_buf_curr = _gps_read_buf; + *_gps_read_buf_curr = '\0'; + } else { + /* Move the next line to the front of the buffer. */ + memmove(_gps_read_buf, eol + 1, _gps_read_buf_curr - eol); /* include terminating 0 */ + /* Subtract _curr so that it's pointing at the new \0. */ + _gps_read_buf_curr -= (eol - _gps_read_buf + 1); + } } + break; + case G_IO_STATUS_ERROR: + case G_IO_STATUS_EOF: + rcvr_disconnect(); + rcvr_connect_later(); + return FALSE; + break; + case G_IO_STATUS_AGAIN: + return TRUE; + break; +} - vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__); - return TRUE; +vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__); +return TRUE; } -- 2.39.5