smsc_at.c problem and patch

Yulianto Z <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi,

I found a problem when I use iTegno WM1080A with Kannel. Finally I got
the bug and solve it.. So these are the description of bug, and attached
the diff to current HEAD version of gw/smsc/smsc_at.c

- What:
  - write(fd, buf, len) function did not write all data in buf. Return
value of this function, show how much data in buf has been written.
  - This bug will result that only 19 chars of SMS, can be sent. Because
write only eat 64 char at one time (in my system, others my vary), which
is equivalent with 19 chars of SMS in my system.

- How to produce the bug:
  - I am using RH8, Linux kernel 2.4.22, glibc 2.3.2, libxml2 2.5.11,
Kannel 1.3.1 (and cvs version as well), iTegno WM1080A/3000.



-- 
cogito ergo sum

GPG fingerprint:
 E2BC 9029 F3FB 90C7 2FAB 9E42 421E F015 119E 0D5D
smsc_at.c_patch.diff (text/x-patch, 2.9 KB)
Index: gw/smsc/smsc_at.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_at.c,v
retrieving revision 1.8
diff -u -r1.8 smsc_at.c
--- gw/smsc/smsc_at.c	17 Oct 2003 14:11:47 -0000	1.8
+++ gw/smsc/smsc_at.c	12 Nov 2003 13:10:42 -0000
@@ -236,19 +236,29 @@
     int count;
     int s = 0;
     int write_count = 0;
+    char *data;
+    int data_written = 0;
     Octstr *linestr = NULL;
 
     linestr = octstr_format("%s\r", line);
 
     debug("bb.smsc.at2", 0, "AT2[%s]: --> %s^M", octstr_get_cstr(privdata->name), line);
 
+    /*
+     * yulianto: Not all data eaten by 'write' function, it might eat data
+     * partially. This why we need loop.
+     * */
+    data = octstr_get_cstr(linestr);
     count = octstr_len(linestr);
     while (1) {
 	errno = 0;
-	s = write(privdata->fd, octstr_get_cstr(linestr), count);
+	s = write(privdata->fd, data + data_written, count - data_written);
 	if (s < 0 && errno == EAGAIN && write_count < RETRY_SEND) {
 	    gwthread_sleep(1);
 	    ++write_count;
+  } else if (data_written < count) {
+    data_written += s;
+    write_count = 0;
 	} else
 	    break;
     };
@@ -256,6 +266,7 @@
     if (s < 0) {
         debug("bb.smsc.at2", 0, "AT2[%s]: write failed with errno %d", 
               octstr_get_cstr(privdata->name), errno);
+        tcflush(privdata->fd, TCOFLUSH);
         return s;
     }
     tcdrain(privdata->fd);
@@ -284,6 +295,7 @@
     if (s < 0) {
         debug("bb.smsc.at2", 0, "AT2[%s]: write failed with errno %d", 
               octstr_get_cstr(privdata->name), errno);
+        tcflush(privdata->fd, TCOFLUSH);
         return s;
     }
     tcdrain(privdata->fd);
@@ -296,11 +308,38 @@
 {
     int count;
     int s;
+    int write_count = 0;
+    char *data = line;
+    int data_written = 0;
 
     count = strlen(line);
     debug("bb.smsc.at2", 0, "AT2[%s]: --> %s", octstr_get_cstr(privdata->name), line);
-    s = write(privdata->fd, line, count);
+    debug("bb.smsc.at2", 0, "AT2[%s]: --> %s", octstr_get_cstr(privdata->name), line);
+    /*
+     * yulianto: Not all data eaten by 'write' function, it might eat data
+     * partially. This why we need loop.
+     * */
+    while (1) {
+	errno = 0;
+	s = write(privdata->fd, data + data_written, count - data_written);
+	if (s < 0 && errno == EAGAIN && write_count < RETRY_SEND) {
+	    gwthread_sleep(1);
+	    ++write_count;
+  } else if (data_written < count) {
+      data_written += s;
+      write_count = 0;
+	} else
+	    break;
+    };
+    if (s < 0) {
+        debug("bb.smsc.at2", 0, "AT2[%s]: write failed with errno %d", 
+              octstr_get_cstr(privdata->name), errno);
+        tcflush(privdata->fd, TCOFLUSH);
+        return s;
+    }
     tcdrain(privdata->fd);
+    gwthread_sleep((double) (privdata->modem == NULL ? 
+        100 : privdata->modem->sendline_sleep) / 1000);
     return s;
 }
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQA/sjPUQh7wFRGeDV0RAlUbAKCTD5xuUoMOIPnwOtS74wObMOJgRQCgi4m2
Tq07i7Kxc4c+3OVH4DMGHGU=
=YXp1
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.