diff options
author | laforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2007-08-17 08:31:49 +0000 |
---|---|---|
committer | laforge <laforge@99fdad57-331a-0410-800a-d7fa5415bdb3> | 2007-08-17 08:31:49 +0000 |
commit | 34fbfd275b710d3662eb490f6a59f58285892f70 (patch) | |
tree | ba4573fc725a69878619d79b1277209e93fdec30 /src/libgsmd | |
parent | be174b78167bf9f2b77901b4b318606144a5ae58 (diff) |
From: Andrzej Zaborowski <balrog@zabor.org>
Date: Tue, 31 Jul 2007 22:28:28 +0200
Subject: [PATCH] Correctly split long usock reads into packets.
This is a patch for an unrelated to the above discussion timing issue in
libgsmd. In particular, when the modem responds fast enough, gsmd generates
usock packets fast enough for libgsmd to read multiple packets in a single read
and concatenate them thus discarding all packets but first. This happens on
Neo1973 when requesting for example the list of preferred operators or all
operators or, sometimes, list of short messages.
git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@2724 99fdad57-331a-0410-800a-d7fa5415bdb3
Diffstat (limited to 'src/libgsmd')
-rw-r--r-- | src/libgsmd/libgsmd.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c index 37a50e6..9906ea8 100644 --- a/src/libgsmd/libgsmd.c +++ b/src/libgsmd/libgsmd.c @@ -88,26 +88,32 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device) /* handle a packet that was received on the gsmd socket */ int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len) { - struct gsmd_msg_hdr *gmh = (struct gsmd_msg_hdr *)buf; + struct gsmd_msg_hdr *gmh; lgsm_msg_handler *handler; - - if (len < sizeof(*gmh)) - return -EINVAL; - - if (len - sizeof(*gmh) < gmh->len) - return -EINVAL; - - if (gmh->msg_type >= __NUM_GSMD_MSGS) - return -EINVAL; - - handler = lh->handler[gmh->msg_type]; - - if (handler) - return handler(lh, gmh); - else { - fprintf(stderr, "unable to handle packet type=%u\n", gmh->msg_type); - return 0; + int rc = 0; + + while (len) { + if (len < sizeof(*gmh)) + return -EINVAL; + gmh = (struct gsmd_msg_hdr *) buf; + + if (len - sizeof(*gmh) < gmh->len) + return -EINVAL; + len -= sizeof(*gmh) + gmh->len; + buf += sizeof(*gmh) + gmh->len; + + if (gmh->msg_type >= __NUM_GSMD_MSGS) + return -EINVAL; + + handler = lh->handler[gmh->msg_type]; + + if (handler) + rc |= handler(lh, gmh); + else + fprintf(stderr, "unable to handle packet type=%u\n", + gmh->msg_type); } + return rc; } int lgsm_register_handler(struct lgsm_handle *lh, int type, lgsm_msg_handler *handler) |