These patches are a result of my attempts to make openobex 1.3 work with my Sony Ericsson K300 phone, connected with an USB-to-serial adapter (DCU-11 or so). These patches apply against the public tarball downloaded from openobex.triq.net

openobex-01-fix-custom-transport.patch

This patch fixes a (IMHO) serious bug in the custom transport. If the custom transport read an insufficient (but still nonzero) number of bytes at a time, the read routine at lib/obex_main.c can enter a situation in which the first instance of /* Check if we are still connected */ consumes all the available bytes, and the second instance sees an empty buffer, which it (incorrectly) interprets as an EOF, thus triggering OBEX_EV_LINKERR. This bug prevents obex_test from correctly sending or receiving objects when using the custom (serial) transport when the custom transport fails to feed big enough chunks.

openobex-02-apps-setpath-nocreate.patch

This patch fixes the setpath_client procedure of obex_test, so that the SETPATH operation includes the don't-create flag (integer 2). The previous value indicated creation-then-chdir of the specified path

openobex-03-apps-target-filebrowsing.patch

This patch adds the filebrowsing profile GUID to the headers of the connection request in obex_test. Without this, no useful test can be done (at least on a Sony Ericsson K300), and file operations might even hang the phone.

openobex-04-debug-stderr-redirect.patch

Convenience patch to send debugging to stderr, not stdout, so that it is easier to capture to a file for later study.

openobex-05-iconv-for-unicode.patch

This patch replaces the OBEX_CharToUnicode implementation with a more functional version which uses iconv for charset conversion. The previous implementation is not useful for non-English locales, because it "converts" characters to Unicode by tacking a null byte to form a 16-bit big-endian value. My phone has an images directory called "Imágenes" (that is, a string with U+00E1 LATIN SMALL LETTER A WITH ACUTE). In my case, I was lucky because the low byte of the codepoint happens to match the same symbol in the ISO-8859-1, so some trickery with the iconv command-line tool was enough. Now imagine somebody in Japan with a directory name written in Kanji... Although my patch hardcodes an assumption that the user is working in UTF-8 (with only one fallback to ISO-8859-1), I think it is a better assumption than pure ASCII.

Please comment on these patches.

Alex Villacís Lasso

--
perl -e '$x = 2.4; print sprintf("%.0f + %.0f = %.0f\n", $x, $x, $x + $x);'

diff -ur openobex-1.3-orig/lib/obex_main.c openobex-1.3/lib/obex_main.c
--- openobex-1.3-orig/lib/obex_main.c	2006-05-04 06:24:21.000000000 -0500
+++ openobex-1.3/lib/obex_main.c	2007-02-18 14:33:29.000000000 -0500
@@ -250,7 +250,7 @@
 		DEBUG(4, "Got %d bytes\n", actual);
 
 		/* Check if we are still connected */
-		if (actual <= 0)	{
+		if (buf == NULL && buflen == 0 && actual <= 0)	{
 			obex_deliver_event(self, OBEX_EV_LINKERR, 0, 0, TRUE);
 			return actual;
 		}
@@ -270,7 +270,7 @@
 				buflen);
 
 			/* Check if we are still connected */
-			if (actual <= 0)	{
+			if (buf == NULL && buflen == 0 && actual <= 0)	{
 				obex_deliver_event(self, OBEX_EV_LINKERR, 0, 0, TRUE);
 				return actual;
 			}
diff -ur openobex-1.3-orig/apps/obex_test_client.c openobex-1.3-patch/apps/obex_test_client.c
--- openobex-1.3-orig/apps/obex_test_client.c	2006-05-16 08:26:15.000000000 -0500
+++ openobex-1.3-patch/apps/obex_test_client.c	2007-02-18 19:51:14.000000000 -0500
@@ -404,7 +404,7 @@
 //
 void setpath_client(obex_t *handle)
 {
-	uint8_t setpath_data[2] = { 0, 0 };
+	uint8_t setpath_data[2] = { 2, 0 };
 	obex_object_t *object;
 	char path[200];
 	int path_size;
diff -ur openobex-1.3-orig/apps/obex_test_client.c openobex-1.3-patch/apps/obex_test_client.c
--- openobex-1.3-orig/apps/obex_test_client.c	2007-02-18 19:52:13.000000000 -0500
+++ openobex-1.3-patch/apps/obex_test_client.c	2007-02-18 19:53:27.000000000 -0500
@@ -116,6 +116,7 @@
 {
 	obex_object_t *object;
 	obex_headerdata_t hd;
+	static unsigned char fsBrowser[]={ 0xf9, 0xec, 0x7b, 0xc4, 0x95, 0x3c, 0x11, 0xd2, 0x98, 0x4e, 0x52, 0x54, 0x00, 0xdc, 0x9e, 0x09, 0x00};
 
 	if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_CONNECT)))	{
 		printf("Error\n");
@@ -129,6 +130,15 @@
 		OBEX_ObjectDelete(handle, object);
 		return;
 	}
+
+	hd.bs = (uint8_t *)fsBrowser;
+	if(OBEX_ObjectAddHeader(handle, object, OBEX_HDR_TARGET, hd, 16,
+				OBEX_FL_FIT_ONE_PACKET) < 0)	{
+		printf("Error adding header 2\n");
+		OBEX_ObjectDelete(handle, object);
+		return;
+	}
+
 	OBEX_Request(handle, object);
 	syncwait(handle);
 }
diff -ur openobex-1.3-orig/apps/obex_test_cable.c openobex-1.3-patch/apps/obex_test_cable.c
--- openobex-1.3-orig/apps/obex_test_cable.c	2006-01-18 08:02:14.000000000 -0500
+++ openobex-1.3-patch/apps/obex_test_cable.c	2007-02-18 19:55:55.000000000 -0500
@@ -181,34 +181,34 @@
 
 	// Set up R320s phone in OBEX mode.
 	if(cobex_do_at_cmd(gt, "ATZ\r", rspbuf, sizeof(rspbuf), 1) < 0)	{
-		printf("Comm-error sending ATZ\n");
+		fprintf(stderr, "Comm-error sending ATZ\n");
 		goto err;
 	}
 
 #ifdef TTBT
 	/* Special BT-mode */
 	if(cobex_do_at_cmd(gt, TTBT, rspbuf, sizeof(rspbuf), 10) < 0) {
-		printf("Comm-error sending AT*TTBT\n");
+		fprintf(stderr, "Comm-error sending AT*TTBT\n");
 		goto err;
 	}
 
 	if(strcasecmp("OK", rspbuf) != 0)       {
-		printf("Error doing AT*TTBT (%s)\n", rspbuf);
+		fprintf(stderr, "Error doing AT*TTBT (%s)\n", rspbuf);
 		goto err;
 	}
 #endif
 	
 	if(strcasecmp("OK", rspbuf) != 0)	{
-		printf("Error doing ATZ (%s)\n", rspbuf);
+		fprintf(stderr, "Error doing ATZ (%s)\n", rspbuf);
 		goto err;
 	}
 
 	if(cobex_do_at_cmd(gt, "AT*EOBEX\r", rspbuf, sizeof(rspbuf), 1) < 0)	{
-		printf("Comm-error sending AT*EOBEX\n");
+		fprintf(stderr, "Comm-error sending AT*EOBEX\n");
 		goto err;
 	}
 	if(strcasecmp("CONNECT", rspbuf) != 0)	{
-		printf("Error doing AT*EOBEX (%s)\n", rspbuf);
+		fprintf(stderr, "Error doing AT*EOBEX (%s)\n", rspbuf);
 		goto err;
 	}
 		return 1;
@@ -231,7 +231,7 @@
 #else
 		if(tcsendbreak(gt->ttyfd, 0) < 0) {
 #endif /* TCSBRKP */
-			printf("Unable to send break!\n");
+			fprintf(stderr, "Unable to send break!\n");
 		}
 	}
 	close(gt->ttyfd);
@@ -302,16 +302,16 @@
 	if(gt->r320) {
 		CDEBUG("R320!!!\n");
 		if(cobex_do_at_cmd(gt, NULL, rspbuf, sizeof(rspbuf), 1) < 0)
-			printf("Comm-error waiting for OK after disconnect\n");
+			fprintf(stderr, "Comm-error waiting for OK after disconnect\n");
 		else if(strcasecmp(rspbuf, "OK") != 0)
-			printf("Excpected OK after OBEX diconnect got %s\n", rspbuf);
+			fprintf(stderr, "Expected OK after OBEX diconnect got %s\n", rspbuf);
 	
 #ifdef TTBT
 		sleep(2);
 		if(cobex_do_at_cmd(gt, "---", rspbuf, sizeof(rspbuf), 5) < 0)
-			printf("Comm-error Sending ---\n");
+			fprintf(stderr, "Comm-error Sending ---\n");
 		else if(strcasecmp(rspbuf, "DISCONNECT") != 0)
-			 printf("Error waiting for DISCONNECT (%s)\n", rspbuf);
+			 fprintf(stderr, "Error waiting for DISCONNECT (%s)\n", rspbuf);
 		sleep(2);
 #endif
 
@@ -353,7 +353,7 @@
 	
 	/* Return if no fd */
 	if(gt->ttyfd < 0) {
-		CDEBUG("No fd!");
+		CDEBUG("No fd!\n");
 		return -1;
 	}
 
@@ -367,8 +367,10 @@
 	
 	/* Check if this is a timeout (0) or error (-1) */
 	if (ret < 1) {
+		if (ret == 0) 
+			CDEBUG("Timeout on select() call\n");
+		else CDEBUG("Error (%d) on select call - (%d) %s\n", ret, errno, strerror(errno));
 		return ret;
-		CDEBUG("Timeout or error (%d)\n", ret);
 	}
 	actual = read(gt->ttyfd, &gt->inputbuf, sizeof(gt->inputbuf));
 	if(actual <= 0)
@@ -378,13 +380,13 @@
 	{
 		int i = 0;
 		for(i=0;i<actual;i++) {
-			printf("[%0X",gt->inputbuf[i]);
+			fprintf(stderr, "[%02X",(unsigned char)(gt->inputbuf[i]));
 			if(gt->inputbuf[i] >= 32) {
-				printf(",%c",gt->inputbuf[i]);
+				fprintf(stderr, ",%c",gt->inputbuf[i]);
 			}
-			printf("]");
+			fprintf(stderr, "]");
 		}
-		printf("\n");
+		fprintf(stderr, "\n");
 	}
 #endif
 	OBEX_CustomDataFeed(handle, (uint8_t *) gt->inputbuf, actual);
diff -ur openobex-1.3-orig/apps/obex_test_cable.h openobex-1.3-patch/apps/obex_test_cable.h
--- openobex-1.3-orig/apps/obex_test_cable.h	2005-12-24 22:39:40.000000000 -0500
+++ openobex-1.3-patch/apps/obex_test_cable.h	2007-02-18 19:55:55.000000000 -0500
@@ -37,7 +37,7 @@
 #include <termios.h>
 
 #ifdef CABLE_DEBUG
-#define CDEBUG(format, args...) printf("%s(): " format, __FUNCTION__ , ##args)
+#define CDEBUG(format, args...) fprintf(stderr, "%s(): " format, __FUNCTION__ , ##args)
 #else
 #define CDEBUG(args...)
 #endif
diff -ur openobex-1.3-orig/lib/obex.c openobex-1.3/lib/obex.c
--- openobex-1.3-orig/lib/obex.c	2006-05-25 13:09:41.000000000 -0500
+++ openobex-1.3/lib/obex.c	2007-02-19 21:29:01.000000000 -0500
@@ -65,6 +65,8 @@
 typedef char *bdaddr_t;
 #endif
 
+#include <iconv.h>
+
 void OBEX_FreeInterfaces(obex_t *self);
 
 /**
@@ -828,21 +830,9 @@
 	return 0;
 }
 
-/**
- * OBEX_CharToUnicode - Simple char to unicode function.
- * @uc: Destination (unicode)
- * @c: Source (char)
- * @size: Length of destination buffer, at least twice the size of source
- *
- * Buffers may not overlap. Returns -1 on error.
- */
-int OBEX_CharToUnicode(uint8_t *uc, const uint8_t *c, int size)
+static int obex_ascii_to_unicode(uint8_t *uc, const uint8_t *c, int size)
 {
 	int len, n;
-	DEBUG(4, "\n");
-
-	obex_return_val_if_fail(uc != NULL, -1);
-	obex_return_val_if_fail(c != NULL, -1);
 
 	len = n = strlen((char *) c);
 	obex_return_val_if_fail(n*2+2 <= size, -1);
@@ -858,6 +848,53 @@
 	return (len*2)+2 ;
 }
 
+static int obex_char_to_unicode(const char * iconv_encoding, uint8_t *uc, const uint8_t *c, int size)
+{
+	iconv_t hConv;
+	int len = -1;
+	
+	if ((iconv_t)-1 != (hConv = iconv_open("UCS-2BE", iconv_encoding))) {
+		char * inBuffer = (char *)c;
+		char * outBuffer = (char *)uc;
+		size_t inBytes = strlen(inBuffer);
+		size_t outBytes = size;
+		
+		if ((size_t)-1 != iconv(hConv, &inBuffer, &inBytes, &outBuffer, &outBytes)) {
+			len = size - outBytes;
+			uc[len] = 0;
+			uc[len + 1] = 0;
+			len += 2;
+		}
+
+		iconv_close(hConv);
+	}
+	return len;
+}
+
+/**
+ * OBEX_CharToUnicode - Simple char to unicode function.
+ * @uc: Destination (unicode)
+ * @c: Source (char)
+ * @size: Length of destination buffer, at least twice the size of source
+ *
+ * Buffers may not overlap. Returns -1 on error.
+ */
+int OBEX_CharToUnicode(uint8_t *uc, const uint8_t *c, int size)
+{
+	DEBUG(4, "\n");
+	int len;
+
+	obex_return_val_if_fail(uc != NULL, -1);
+	obex_return_val_if_fail(c != NULL, -1);
+	
+	/* FIXME: if system encoding is not UTF-8, guess real encoding, instead
+	   of assuming ISO-8859-1
+	 */
+	if ((len = obex_char_to_unicode("UTF-8", uc, c, size)) >= 0) return len;
+	if ((len = obex_char_to_unicode("ISO-8859-1", uc, c, size)) >= 0) return len;
+	return obex_ascii_to_unicode(uc, c, size);
+}
+
 /**
  * OBEX_ResponseToString - Return a human understandable string from a response-code.
  * @rsp: Response code.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Openobex-users mailing list
Openobex-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/openobex-users

Reply via email to