Hi,
Hendrik Sattler schrieb:
> As alread mentioned in the last post, the BFB transfer does not fully work.
I experienced problems with serial port usb adapters and fast machines.
It seems the main problem is that the current code doesn't work well
with incomplete reads. Some initial backoff (sleep for a second or so)
will help.
That is a bad workaround though. I've ported some off my ongoing
multicobex rewrite for a quick fix. The attached patch fixes:
- at-command reads to expect a final result code of "OK" or "ERROR"
(considering some timeout)
- initial bfb reads to wait for a complete frame (again with timeout).
Let me know if this works as expected.
If the BFB mode get operations still fail, try disabling the SETPATH
(-S) and remove the first (root) slash from filenames. E.g. obexftp -t
/dev/ttyUSB0 -U S45 -S -g Bitmap/smiley.bmp
regards,
Christian
Index: bfb/bfb_io.c
===================================================================
--- bfb/bfb_io.c (Revision 199)
+++ bfb/bfb_io.c (Arbeitskopie)
@@ -124,8 +124,9 @@
{
int actual;
int tries=3;
- bfb_frame_t *frame;
+ bfb_frame_t *frame = NULL;
uint8_t rspbuf[200];
+ int rsplen;
uint8_t init_magic = BFB_CONNECT_HELLO;
uint8_t init_magic2 = BFB_CONNECT_HELLO_ACK;
@@ -140,7 +141,7 @@
return_val_if_fail (fd > 0, FALSE);
#endif
- while (tries-- > 0) {
+ while (!frame && tries-- > 0) {
actual = bfb_write_packets (fd, BFB_FRAME_CONNECT, &init_magic,
sizeof(init_magic));
DEBUG(2, "%s() Wrote %d packets\n", __func__, actual);
@@ -149,19 +150,23 @@
return FALSE;
}
- actual = bfb_io_read(fd, rspbuf, sizeof(rspbuf), 1);
- DEBUG(2, "%s() Read %d bytes\n", __func__, actual);
+ rsplen = 0;
+ while (!frame && actual > 0) {
+ actual = bfb_io_read(fd, &rspbuf[rsplen],
sizeof(rspbuf)-rsplen, 2);
+ DEBUG(2, "%s() Read %d bytes\n", __func__, actual);
- if (actual < 1) {
- DEBUG(1, "BFB read error\n");
- return FALSE;
+ if (actual < 0) {
+ DEBUG(1, "BFB read error\n");
+ return FALSE;
+ }
+ if (actual == 0) {
+ DEBUG(1, "BFB read timeout\n");
+ }
+
+ rsplen += actual;
+ frame = bfb_read_packets(rspbuf, &rsplen);
+ DEBUG(2, "%s() Unstuffed, %d bytes remaining\n",
__func__, rsplen);
}
-
- frame = bfb_read_packets(rspbuf, &actual);
- DEBUG(2, "%s() Unstuffed, %d bytes remaining\n", __func__,
actual);
-
- if (frame != NULL)
- break;
}
if (frame == NULL) {
@@ -183,8 +188,13 @@
return FALSE;
}
-/* Send an AT-command an expect 1 line back as answer */
-/* Ericsson may choose to answer one line, blank one line and then send OK */
+/**
+ Send an AT-command and expect an answer of one or more lines.
+
+ \note The expected lines are the the echo,
+ one optional information response and
+ a final result code of "OK" or "ERROR"
+ */
int do_at_cmd(fd_t fd, const char *cmd, char *rspbuf, int rspbuflen)
{
#ifdef _WIN32
@@ -194,7 +204,6 @@
#endif
char *answer = NULL;
- char *answer_end = NULL;
int answer_size;
char tmpbuf[100] = {0,};
@@ -210,52 +219,53 @@
DEBUG(3, "%s() Sending %d: %s\n", __func__, cmdlen, cmd);
/* Write command */
- if(bfb_io_write(fd, cmd, cmdlen) < cmdlen)
+ if (bfb_io_write(fd, cmd, cmdlen) < cmdlen)
return -1;
- while(!done) {
+ while (!done) {
actual = bfb_io_read(fd, &tmpbuf[total], sizeof(tmpbuf) -
total, 2);
/* error checking */
- if(actual < 0)
+ if (actual < 0)
return actual;
-
- if(actual == 0)
- /* Anser didn't come in time. Cancel */
- return -1;
+ if (actual == 0)
+ /* Answer didn't come in time. Cancel */
+ done = 1;
total += actual;
+ tmpbuf[total] = '\0'; /* terminate the string, always */
DEBUG(3, "%s() tmpbuf=%d: %s\n", __func__, total,
tmpbuf);
/* Answer not found within 100 bytes. Cancel */
- if(total == sizeof(tmpbuf))
+ if (total >= sizeof(tmpbuf))
return -1;
- if( (answer = strchr(tmpbuf, '\n')) ) {
- while((*answer == '\r') || (*answer == '\n'))
+ /* Remove first line (echo), then search final result code */
+ for (answer = strchr(tmpbuf, '\r'); answer ; answer =
strchr(answer, '\r')) {
+ while ((*answer == '\r') || (*answer == '\n'))
answer++;
- /* Remove first line (echo) */
- if( (answer_end = strchr(answer+1, '\n')) )
{
- /* Found end of answer */
+ if (!strncmp(answer, "OK\r", 3) ||
!strncmp(answer, "ERROR\r", 6)) {
done = 1;
}
}
}
- /* try hard to discard remaing lines */
- actual = bfb_io_read(fd, &tmpbuf[total], sizeof(tmpbuf) - total, 2);
+ /* try hard to discard remaing CR/LF */
+ if (total > 0 && tmpbuf[total-1] != '\n')
+ actual = bfb_io_read(fd, &tmpbuf[total], sizeof(tmpbuf) -
total, 2);
-/* DEBUG(3, "%s() buf:%08lx answer:%08lx end:%08lx\n", __func__, tmpbuf,
answer, answer_end); */
+ /* Remove echo and trailing CRs */
+ answer = strchr(tmpbuf, '\r');
+ if (!answer) /* no echo found */
+ return -1;
- DEBUG(3, "%s() Answer: %s\n", __func__, answer);
+ while (*answer == '\r' || *answer == '\n')
+ answer++;
+ answer_size = 0;
+ while (answer[answer_size] != '\0' &&
+ answer[answer_size] != '\r' && answer[answer_size] != '\n')
+ answer_size++;
- /* Remove heading and trailing \r */
- while((*answer_end == '\r') || (*answer_end == '\n'))
- answer_end--;
- DEBUG(3, "%s() Answer: %s\n", __func__, answer);
-
- answer_size = (answer_end) - answer +1;
-
- DEBUG(2, "%s() Answer size=%d\n", __func__, answer_size);
+ DEBUG(3, "%s() Answer (size=%d): %s\n", __func__, answer_size, answer);
if( (answer_size) >= rspbuflen )
return -1;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Openobex-users mailing list
[email protected]
http://lists.sourceforge.net/lists/listinfo/openobex-users