diff wh1080.c @ 3:dc5ff2a1ed81

Be smarter about retries. If the interrupt endpoint can't be read 100 times then retry the whole request.
author Daniel O'Connor <darius@dons.net.au>
date Wed, 10 Feb 2010 11:33:27 +1030
parents 9da35e705144
children b22a888eb975
line wrap: on
line diff
--- a/wh1080.c	Tue Feb 09 13:48:52 2010 +1030
+++ b/wh1080.c	Wed Feb 10 11:33:27 2010 +1030
@@ -230,7 +230,8 @@
  */
 int read_station (char *buf)
 {
-  int bytes_read;
+#define MAXTRIES 100
+  int bytes_read, i = 0;
 
   /* XXX Find out what all this means, and be cleverer about retries */
   do
@@ -239,23 +240,34 @@
                                           USB_ENDPOINT_IN | USB_RECIP_INTERFACE,
                                           buf,
                                           8,
-                                          10 )) == 8 )
+                                          10 )) == 8 ){
+      if (i > 5)
+        fprintf(stderr, "Read OK after %d tries\n", i + 1);
       return bytes_read;
+    }
+    
     if (errno == EAGAIN)
       usleep (10000);
+    i++;
   }
-  while (errno != EINTR);
-  fprintf (stderr,
-           "Can't read device: %s (%d)\n",
-           usb_strerror (),
-           errno );
+  while (errno != EINTR && i < MAXTRIES);
+  if (i == MAXTRIES) {
+#if 0
+    fprintf(stderr,
+	    "Can't read from device after %d attempts\n", MAXTRIES);
+#endif
+  } else
+    fprintf (stderr,
+	     "Can't read device: %s (%d)\n",
+	     usb_strerror (),
+	     errno );
   return 0;
 }
 
 /* Read a page (32 bytes) from the device. */
 int read_station_page (uint16_t page, char *buf)
 {
-  int bytes_read = 0;                           /* keep track of input */
+  int i, bytes_read, tries = 0;
   struct read_page_request
   {
     char command;                               /* XXX I'm guessing at this */
@@ -266,12 +278,30 @@
 #if BYTE_ORDER == LITTLE_ENDIAN
   page = htobe16 (page);                        /* in big-endian for the command */
 #endif
+  rerequest:
+  bytes_read = 0;
+  tries++;
+  if (tries > 10) {
+    fprintf(stderr, "Unable to read page after 10 tries\n");
+    exit(1);
+  }
+  
   request [0] = (struct read_page_request) {0xa1, page, 32};
   request [1] = request [0];
   if (write_station_control ((char *) request) == 0)
     exit (1);                                   /* XXX we've already complained */
-  while (bytes_read < 32)
-    bytes_read += read_station ((char *) &buf [bytes_read]);
+  
+  while (bytes_read < 32) {
+    if ((i = read_station ((char *) &buf [bytes_read])) == 0) {
+#if 0
+      fprintf(stderr, "Couldn't read from the device, rerequesting\n");
+#endif
+      goto rerequest;
+    }
+    
+    bytes_read += i;
+  }
+  
   return bytes_read;
 }
 
@@ -503,6 +533,7 @@
            readings->wind_direction_text,
            readings->rain - db_previous_rain );
   db_previous_rain = readings->rain;            /* update our current rainfall XXX fix this */
+#if 0
   if (update)                                   /* only if updates set */
   {
     if (mysql_query (mysql, mysql_querytext))
@@ -514,7 +545,7 @@
     }
   }
   else if (verbose)
-    puts (mysql_querytext);
+#endif
 }
 
 /*
@@ -630,3 +661,10 @@
   usb_release_interface (station, 0);
   return 0;
 }
+
+
+/*
+ *;;; Local Variables: ***
+ *;;; c-basic-offset:2 ***
+ *;;; End: ***
+ */