2006/10/3, Armin M. Warda <[EMAIL PROTECTED]>:
  Hi Cezary,

Hi,

I merged your 'GPS-Info patch' for Maemo-Mapper 1.1
http://eko.one.pl/files/n770/maemo-mapper/gpsinfo/gpsinfo-20061002.diff
with my set of patches.

Is the original project dead, there have been no traffic in SVN the
last months or so. In a forom thread I also posted a patch (attached
because link is broken) that 'fixes' my bt jam (using the method in
one of the older versions of mapper, now when a certain time no data
arrived). Also i noticed that 'g_io_channel_read_line' is a real power
consumer when lines only arrive partial, it keeps generating input
events until the eol is arrived (ironically this increases the bt jam
occurrence).
One other thing I noticed that the screen blank protection didn't work
in fullscreen mode. (I always start an extra app that does that too).
Given that I have now used mapper over quite some distances, often
more than four hours drive, and mapper w/o these patch is jammed
within 10 minutes or so, I'm starting to believe that it's rather
stable for me.
Index: src/maemo-mapper.c
===================================================================
--- src/maemo-mapper.c	(revision 26)
+++ src/maemo-mapper.c	(working copy)
@@ -505,6 +505,12 @@
 
 /** The file descriptor of our connection with the GPS receiver. */
 static gint _fd = -1;
+/** Track how often we fail to read a line as an indication of a bluetooth jam*/
+static gint _fd_read_timeout_check;
+static gint _fd_read_failure;
+static gint _fd_read_timeout_timer;
+static gchar _gps_read_buf[256];
+static gchar _gps_read_buf_pos;
 
 /** The GIOChannel through which communication with the GPS receiver is
  * performed. */
@@ -1448,6 +1454,11 @@
         g_source_remove(_input_sid);
         _input_sid = 0;
     }
+    if (_fd_read_timeout_timer)
+    {
+        g_source_remove(_fd_read_timeout_timer);
+        _fd_read_timeout_timer = 0;
+    }
 
     /* Destroy the GIOChannel object. */
     if(_channel)
@@ -1468,6 +1479,7 @@
 }
 
 static void rcvr_connect_later(); /* Forward declaration. */
+static gboolean channel_cb_data_timeout(gpointer data);
 
 /**
  * Connect to the receiver.
@@ -1497,6 +1509,9 @@
             rcvr_connect_later();
         else
         {
+            _gps_read_buf_pos = 0;
+            _fd_read_timeout_check = TRUE;
+            _fd_read_timeout_timer = g_timeout_add(30000, channel_cb_data_timeout, NULL);
             _channel = g_io_channel_unix_new(_fd);
             g_io_channel_set_flags(_channel, G_IO_FLAG_NONBLOCK, NULL);
             _error_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
@@ -5116,6 +5131,42 @@
 }
 
 static gboolean
+hci_cb_reset(gpointer data)
+{
+    fprintf(stderr, "%s %d %d\n", __PRETTY_FUNCTION__, _fd_read_failure, _fd_read_timeout_check);
+
+    if (_fd_read_failure > 100 || _fd_read_timeout_check) /* recheck */
+    {
+        /* An bt jam - reset hci. */
+        rcvr_disconnect();
+        _fd_read_failure = 0;
+        system("/usr/bin/sudo -l | grep -q '/usr/sbin/hciconfig  *hci0  *reset'"
+                " && sudo /usr/sbin/hciconfig hci0 reset");
+        track_add(0, FALSE);
+
+        if(_conn_state > RCVR_OFF)
+        {
+            set_conn_state(RCVR_DOWN);
+            rcvr_connect_now();
+        }
+    }
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+static gboolean
+channel_cb_data_timeout(gpointer data)
+{
+    fprintf(stderr, "%s\n", __PRETTY_FUNCTION__);
+    if (_fd_read_timeout_check)
+        g_timeout_add(0, hci_cb_reset, NULL);
+    else
+        _fd_read_timeout_check = TRUE;
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;  /* keep alive */
+}
+
+static gboolean
 channel_cb_connect(GIOChannel *src, GIOCondition condition, gpointer data)
 {
     int error, size = sizeof(error);
@@ -5356,39 +5407,61 @@
 static gboolean
 channel_cb_input(GIOChannel *src, GIOCondition condition, gpointer data)
 {
-    gchar *sentence;
+    gchar *sentence = _gps_read_buf;
+    gsize bytes_read;
     vprintf("%s(%d)\n", __PRETTY_FUNCTION__, condition);
-    
-    while(G_IO_STATUS_NORMAL == g_io_channel_read_line(
+    _fd_read_failure++;
+   
+    if (G_IO_STATUS_NORMAL == g_io_channel_read_chars (
                 _channel,
-                &sentence,
-                NULL,
-                NULL,
-                NULL) && sentence)
+                _gps_read_buf + _gps_read_buf_pos,
+                sizeof(_gps_read_buf) - _gps_read_buf_pos -1,
+                &bytes_read,
+                NULL))
     {
-        gchar *sptr = sentence + 1;
-        guint csum = 0;
-        while(*sptr && *sptr != '*')
-            csum ^= *sptr++;
-        if (!*sptr || csum == strtol(sptr+1, NULL, 16))
+        char *eol;
+        _gps_read_buf_pos += bytes_read;
+        _gps_read_buf[_gps_read_buf_pos] = 0;
+        eol = strchr(_gps_read_buf, '\n');
+        _fd_read_timeout_check = FALSE;
+        while (eol)
         {
-            if(*sptr)
-                *sptr = '\0'; /* take checksum out of the sentence. */
-            if(!strncmp(sentence + 3, "RMC", 3))
-                channel_parse_rmc(sentence + 7);
-            else if(_conn_state == RCVR_UP
-                    && !strncmp(sentence + 3, "GSV", 3))
-                channel_parse_gsv(sentence + 7);
+            gchar *sptr = sentence + 1;
+            guint csum = 0;
+            int leftover = _gps_read_buf + _gps_read_buf_pos - eol - 1;
+            *eol = 0;
+            while(*sptr && *sptr != '*')
+                csum ^= *sptr++;
+            if (!*sptr || csum == strtol(sptr+1, NULL, 16))
+            {
+                _fd_read_failure = 0;
+                if(*sptr)
+                    *sptr = '\0'; /* take checksum out of the sentence. */
+                if(!strncmp(sentence + 3, "RMC", 3))
+                    channel_parse_rmc(sentence + 7);
+                else if(_conn_state == RCVR_UP
+                        && !strncmp(sentence + 3, "GSV", 3))
+                    channel_parse_gsv(sentence + 7);
+            }
+            else
+            {
+                fprintf(stderr, "%s: Bad checksum in NMEA sentence:\n%s\n",
+                        __PRETTY_FUNCTION__, sentence);
+            }
+            if (leftover <= 0) { /* last read was a newline */
+                _gps_read_buf_pos = 0;
+                eol = 0;
+            } else {
+                memmove(_gps_read_buf, eol+1, leftover+1); /* incl term. 0 */
+                _gps_read_buf_pos = leftover;
+                eol = strchr(_gps_read_buf, '\n');
+            }
         }
-        else
-        {
-            printf("%s: Bad checksum in NMEA sentence:\n%s\n",
-                    __PRETTY_FUNCTION__, sentence);
-        }
-        g_free(sentence);
     }
 
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    if (_fd_read_failure > 100)
+        g_timeout_add(0, hci_cb_reset, NULL);
+    vprintf("%s():status return TRUE\n", __PRETTY_FUNCTION__);
     return TRUE;
 }
 
_______________________________________________
maemo-developers mailing list
[email protected]
https://maemo.org/mailman/listinfo/maemo-developers

Reply via email to