Palm m505 & network sync



I have a palm m505 with a USB cradle. It works just fine with coldsync, and I can use "pi-csd" and pppd to allow network sync using pilot-xfer.

However, gpilotd did not reply to the palm's request on UDP port 14237, as it seems from pi-csd.c it should.

I have implemented the reply routine, and it seems, that gpilotd is able to hotsync with the palm now. The patch is available, attached to http://bugzilla.gnome.org/show_bug.cgi?id=66606 and is attached as gnome-pilot_fix_network.patch

There are other issues: The communication between the palm and pppd sometimes breaks down, causing pilot-link to wait infinately for input on a socket. That's patched by the attached pilot-link_hang_on_read_fix.patch, which will be sent to pilot-link, devel list.

Also, the pppd does not cope well with the ttyUSB stuff, so I hacked that around a little, and came up with pppd_fix_usb_stuff.patch.

It now ALMOST works! I can start a hotsync, at it goes on for a while, but then, after 40-50 secs. the palm apparently drops the network connection, this causes a KERNEL LOCKUP! Only resolution is to reboot.

--
Helge Jensen
? gnome-pilot_fix_network.patch
Index: gpilotd/gpilotd.c
===================================================================
RCS file: /cvs/gnome/gnome-pilot/gpilotd/gpilotd.c,v
retrieving revision 1.125
diff -u -r1.125 gpilotd.c
--- gpilotd/gpilotd.c	2001/12/03 11:00:31	1.125
+++ gpilotd/gpilotd.c	2001/12/11 07:19:52
@@ -36,6 +36,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <sys/wait.h>
 #include <sys/time.h>
 
@@ -726,6 +727,126 @@
 }
 
 #ifdef WITH_NETWORK
+
+static gchar *
+inet_ntoa_from_ip(guint32 ip) {
+	struct in_addr a;
+	a.s_addr = GUINT32_TO_BE(ip);
+	return g_strdup(inet_ntoa(a));
+}
+
+/** Generate reply when woken by palm m50x hotsync request */
+static gboolean
+network_device_reply_wake(GIOChannel *io_channel_req,
+			  const GPilotDevice *device) {
+	enum { BUFFER_LENGTH = 2048 };
+	gchar buf[BUFFER_LENGTH];
+	guint buf_read;
+	guint32 palm_addr;
+	guint32 palm_netmask;
+	/* I am unable to use the GIOChannel abstractions, since I
+           need the sender's address and we use UDP */
+	gint req_fd = g_io_channel_unix_get_fd(io_channel_req);
+	struct sockaddr req_addr;
+	socklen_t req_addr_length = sizeof(req_addr);
+	enum { 
+		PALM_MAGIC_INDEX = 0,
+		PALM_ADDR_INDEX = PALM_MAGIC_INDEX + 4,
+		PALM_NETMASK_INDEX = PALM_ADDR_INDEX + 4,
+		PALM_HOST_INDEX = PALM_NETMASK_INDEX + 4
+	};
+	gchar palm_magic[] = { 0xFA, 0xDE, 0x01 };
+	gchar *palm_host;
+
+	gboolean success = TRUE;
+	
+	/* Read the msg from the palm */
+	buf_read = recvfrom(req_fd, buf, BUFFER_LENGTH-1, MSG_NOSIGNAL,
+			    &req_addr, &req_addr_length);
+	
+	if ( buf_read == -1 ) {
+		g_warning("Unable to receive hotsync req: %s",
+			  strerror(errno));
+		goto error;
+	}
+	
+	/* Make sure we don't fall-through buf when reading string */
+	buf[buf_read] = 0;
+	
+	/* Message format:
+	   
+	   16-bit: 0xFADE
+	   8-bit: 0x01
+	   32-bit: IP-address of palm
+	   32-bit: Net-mask (from palm)
+	*/
+	/* Check for malformed message */
+	if ( buf_read < 12 )
+		goto error;
+		
+	/* @todo: perhaps we should return true instead of false since
+           i don't know the protocol used by other devices than
+           palm-m505 */
+	if ( memcmp(&buf[PALM_MAGIC_INDEX],
+		    &palm_magic[0],
+		    sizeof(palm_magic)) 
+	     != 0 )
+		goto error;
+	
+	{
+		guint32 *palm_addr_p = (guint32*) &buf[PALM_ADDR_INDEX];
+		palm_addr = GUINT32_FROM_BE(*palm_addr_p);
+	}
+	{
+		guint32 *palm_netmask_p = (guint32*) &buf[PALM_NETMASK_INDEX];
+		palm_netmask = GUINT32_FROM_BE(*palm_netmask_p);
+	}
+	palm_host = &buf[PALM_HOST_INDEX];
+
+	/* @todo: Maybe this should die? */
+	g_message("Received hotsync request to host :%s",
+		  palm_host);
+	
+	if ( strcmp(palm_host, device->host ) != 0 ) {
+		g_warning("Unwanted sync-request for host: %s, expected: %s",
+			  palm_host, device->host);
+		goto error;
+	}
+	if ( palm_addr != GUINT32_FROM_BE(inet_addr(device->ip)) ) {
+		gchar *palm_ip_conn = inet_ntoa_from_ip(palm_addr);
+		g_warning("Unwanted sync-request for host: %s, expected: %s",
+			  palm_ip_conn, device->host);
+		g_free(palm_ip_conn);
+		goto error;
+	}
+	
+	/* Generate reply */
+	/* Reply-format: RESEND Message, with 0x02 substituted for
+	   0x01 in the magic zone */
+	buf[2] = 0x02;
+
+	/* Send reply */
+	{
+		ssize_t sent;
+		
+		sent = sendto(req_fd,
+			      buf, buf_read, 
+			      MSG_NOSIGNAL,
+			      &req_addr,
+			      req_addr_length);
+		if ( sent != buf_read ) {
+			g_warning("Unable to send sync-req reply");
+			goto error;
+		}
+	}
+	goto ok;
+	
+ error:
+	success = FALSE;
+ ok:
+	return success;
+}
+
 gboolean 
 network_device_in (GIOChannel *io_channel,
 	  GIOCondition condition,
@@ -751,6 +872,11 @@
 		return FALSE; 
 	}	
 	g_message (_("Woke on %s"),device->name);
+	if ( (result = network_device_reply_wake(io_channel, device))
+	     != TRUE ) {
+		g_warning("Unable to reply to connect from %s", device->name);
+		return result;
+	}
 	result = sync_device (device,context);
 
 	return result;
? pilot-link_hang_on_read_fix.patch
Index: libsock/inet.c
===================================================================
RCS file: /cvs/pilot-link/pilot-link_src/libsock/inet.c,v
retrieving revision 1.11
diff -u -r1.11 inet.c
--- libsock/inet.c	6 Jun 2001 08:16:56 -0000	1.11
+++ libsock/inet.c	11 Dec 2001 07:01:59 -0000
@@ -54,6 +54,68 @@
 
 extern int dlp_trace;
 
+static const struct timeval default_timeout = { 1, 0 };
+
+static ssize_t read_w_timeout(int fd, void *buf, size_t count) {
+  struct timeval timeout = default_timeout;
+  int sel;
+  fd_set read_set;
+  fd_set err_set;
+
+  FD_ZERO(&read_set);
+  FD_ZERO(&err_set);
+  FD_SET(fd, &read_set);
+  FD_SET(fd, &err_set);
+  
+  {
+    sel = select(fd+1, &read_set, NULL, &err_set, &timeout);
+    
+    if ( sel == 0 )
+      return 0;  /* Timeout */
+    
+    if ( sel < 0 
+         || FD_ISSET(fd, &err_set) )
+      return -1; /* Error */
+  }
+  
+  if ( !FD_ISSET(fd, &read_set) ) {
+    /* hmmm, we expected input, that must be an error */
+    return -1;
+  }
+  
+  return read(fd, buf, count);
+}
+
+static ssize_t write_w_timeout(int fd, const void *buf, size_t count) {
+  struct timeval timeout = default_timeout;
+  int sel;
+  fd_set write_set;
+  fd_set err_set;
+
+  FD_ZERO(&write_set);
+  FD_ZERO(&err_set);
+  FD_SET(fd, &write_set);
+  FD_SET(fd, &err_set);
+  
+  {
+    sel = select(fd+1, NULL, &write_set, &err_set, &timeout);
+    
+    if ( sel == 0 )
+      return 0;  /* Timeout */
+    
+    if ( sel < 0 
+         || FD_ISSET(fd, &err_set) )
+      return -1; /* Error */
+  }
+  
+  if ( !FD_ISSET(fd, &write_set) ) {
+    /* hmmm, we expected to be allowed output, that must be an error */
+    return -1;
+  }
+  
+  return write(fd, buf, count);
+}
+
 /***********************************************************************
  *
  * Function:    pi_inet_connect
@@ -157,7 +219,7 @@
 		    open(ps->debuglog, O_WRONLY | O_CREAT | O_APPEND,
 			 0666);
 		/* This sequence is magic used by my trace analyzer - kja */
-		write(ps->debugfd, "\0\2\0\0\0\0\0\0\0\0", 10);
+		write_w_timeout(ps->debugfd, "\0\2\0\0\0\0\0\0\0\0", 10);
 	}
 #endif
 
@@ -258,7 +320,7 @@
 		    open(ps->debuglog, O_WRONLY | O_CREAT | O_APPEND,
 			 0666);
 		/* This sequence is magic used by my trace analyzer - kja */
-		write(ps->debugfd, "\0\2\0\0\0\0\0\0\0\0", 10);
+		write_w_timeout(ps->debugfd, "\0\2\0\0\0\0\0\0\0\0", 10);
 	}
 #endif
 
@@ -322,6 +384,7 @@
 	a = malloc(sizeof(struct pi_socket));
 	memcpy(a, ps, sizeof(struct pi_socket));
 
+        /** @todo: could we "select" first? */
 	a->sd = accept(ps->sd, addr, addrlen);
 	if (a->sd < 0)
 		goto fail;
@@ -365,7 +428,7 @@
 
 	l = 0;
 	while (l < 6) {
-		n = write(ps->sd, buf + l, 6 - l);
+		n = write_w_timeout(ps->sd, buf + l, 6 - l);
 		if (n > 0)
 			l += n;
 		if (n < 0)
@@ -374,7 +437,7 @@
 
 	l = 0;
 	while (l < len) {
-		n = write(ps->sd, (char *) msg + l, len - l);
+		n = write_w_timeout(ps->sd, (char *) msg + l, len - l);
 		if (n > 0)
 			l += n;
 		if (n < 0)
@@ -386,8 +449,8 @@
 		buf[0] = 4;
 		buf[1] = 0;
 		set_long(buf + 2, len);
-		write(ps->debugfd, buf, 6);
-		write(ps->debugfd, msg, len);
+		write_w_timeout(ps->debugfd, buf, 6);
+		write_w_timeout(ps->debugfd, msg, len);
 	}
 #endif
 
@@ -414,7 +477,7 @@
 
 	l = 0;
 	while (l < 6) {
-		n = read(ps->sd, buf + l, 6 - l);
+		n = read_w_timeout(ps->sd, buf + l, 6 - l);
 		if (n > 0)
 			l += n;
 		if (n <= 0)
@@ -428,7 +491,7 @@
 
 	l = 0;
 	while (l < len) {
-		n = read(ps->sd, (char *) msg + l, len - l);
+		n = read_w_timeout(ps->sd, (char *) msg + l, len - l);
 		if (n > 0)
 			l += n;
 		if (n < 0)
@@ -443,7 +506,7 @@
 		char discard;
 
 		while (l < rlen) {
-			n = read(ps->sd, &discard, 1);
+			n = read_w_timeout(ps->sd, &discard, 1);
 			if (n > 0)
 				l += n;
 			if (n < 0)
@@ -466,8 +529,8 @@
 		buf[0] = 3;
 		buf[1] = 0;
 		set_long(buf + 2, len);
-		write(ps->debugfd, buf, 6);
-		write(ps->debugfd, msg, len);
+		write_w_timeout(ps->debugfd, buf, 6);
+		write_w_timeout(ps->debugfd, msg, len);
 	}
 #endif
 
? ppp_fix_usb.patch
? pppd/plugins/pppoe/pppoed
Index: pppd/sys-linux.c
===================================================================
RCS file: /cvsroot/ppp/pppd/sys-linux.c,v
retrieving revision 1.92
diff -u -r1.92 sys-linux.c
--- pppd/sys-linux.c	23 May 2001 03:39:13 -0000	1.92
+++ pppd/sys-linux.c	11 Dec 2001 07:26:07 -0000
@@ -515,9 +515,13 @@
     if (!hungup) {
 /*
  * Flush the tty output buffer so that the TIOCSETD doesn't hang.
+ *
+ * tty_fd may be invalid, if it points to a ttyUSB device. they jump
+ * up and down as it suits them.
  */
-	if (tcflush(tty_fd, TCIOFLUSH) < 0)
-	    warn("tcflush failed: %m");
+      if (tcflush(tty_fd, TCIOFLUSH) < 0) {
+        warn("tcflush failed: %m");
+      } else {
 /*
  * Restore the previous line discipline
  */
@@ -530,12 +534,12 @@
 	    if ( ! ok_error (errno))
 		warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
 	}
-
-	/* Reset non-blocking mode on fd. */
-	if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
-	    if ( ! ok_error (errno))
-		warn("Couldn't restore device fd flags: %m");
-	}
+      }
+      /* Reset non-blocking mode on fd. */
+      if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
+        if ( ! ok_error (errno))
+          warn("Couldn't restore device fd flags: %m");
+      }
     }
     initfdflags = -1;
 
Index: pppd/tty.c
===================================================================
RCS file: /cvsroot/ppp/pppd/tty.c,v
retrieving revision 1.6
diff -u -r1.6 tty.c
--- pppd/tty.c	12 Mar 2001 22:59:01 -0000	1.6
+++ pppd/tty.c	11 Dec 2001 07:26:08 -0000
@@ -399,9 +399,14 @@
 		option_error("connect script is required for demand-dialling\n");
 		exit(EXIT_OPTION_ERROR);
 	}
+#if USE_BUGGY_HOLDOFF_DEFAULTS
+       /* jensen slog dk, 2001-11-28: holdoff_specified is NEVER set
+           to any value, so this code does not make any sense at
+           all. */
 	/* default holdoff to 0 if no connect script has been given */
 	if (connect_script == 0 && !holdoff_specified)
 		holdoff = 0;
+#endif /* USE_BUGGY_HOLDOFF_DEFAULTS */
 
 	if (using_pty) {
 		if (!default_device) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]