Hi, On 07/04/2008, Paulius Zaleckas <[EMAIL PROTECTED]> wrote: > lgsm_handle doesn't have members you are using...
Yes, this was not the complete patch. I rebased the complete change on current SVN and attached to this mail. > > P.S. Is your tree available to the outside world? The tree is at http://folks.o-hand.com/andrew/gsmd.git , unfortunately it's severely outdated now. Regards
diff --git a/include/libgsmd/libgsmd.h b/include/libgsmd/libgsmd.h index f260ae2..2ea7382 100644 --- a/include/libgsmd/libgsmd.h +++ b/include/libgsmd/libgsmd.h @@ -65,7 +65,8 @@ extern int lgsm_subscriptions(struct lgsm_handle *lh, u_int32_t subscriptions); extern struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len); extern int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh); -extern int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len); +extern int lgsm_handle_packet(struct lgsm_handle *lh, + const char *buf, int len); extern int lgsm_blocking_wait_packet(struct lgsm_handle *lh, u_int16_t id, struct gsmd_msg_hdr *gmh, int rlen); diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index aa2c7b5..a495472 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -1646,23 +1646,29 @@ static int gsmd_usock_user_cb(int fd, unsigned int what, void *data) struct gsmd_ucmd *ucmd, *uctmp; llist_for_each_entry_safe(ucmd, uctmp, &gu->finished_ucmds, list) { - int rc; - - rc = write(fd, &ucmd->hdr, sizeof(ucmd->hdr) + ucmd->hdr.len); - if (rc < 0) { - DEBUGP("write return %d\n", rc); - return rc; - } - if (rc == 0) { - DEBUGP("write returns zero!!\n"); - break; + const void *pos = &ucmd->hdr; + size_t len = sizeof(ucmd->hdr) + ucmd->hdr.len; + + while (len) { + ssize_t rc; + + rc = write(fd, pos, len); + if (rc < 0 && errno != EINTR) { + DEBUGP("write returned %s\n", + strerror(errno)); + return rc; + } + if (rc == 0 && pos == &ucmd->hdr) { + DEBUGP("write returns zero!!\n"); + return 0; + } + if (rc > 0) { + len -= rc; + pos += rc; + } } - if (rc != sizeof(ucmd->hdr) + ucmd->hdr.len) { - DEBUGP("short write\n"); - break; - } - - DEBUGP("successfully sent cmd %p to user %p, freeing\n", ucmd, gu); + DEBUGP("successfully sent cmd %p to user %p, " + "freeing\n", ucmd, gu); llist_del(&ucmd->list); talloc_free(ucmd); } diff --git a/src/libgsmd/lgsm_internals.h b/src/libgsmd/lgsm_internals.h index c826723..c2000f0 100644 --- a/src/libgsmd/lgsm_internals.h +++ b/src/libgsmd/lgsm_internals.h @@ -8,6 +8,8 @@ struct lgsm_handle { int fd; lgsm_msg_handler *handler[__NUM_GSMD_MSGS]; enum lgsm_netreg_state netreg_state; + char usock_fifo[4096]; + int usock_len; }; int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh); diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c index 50bd719..2900ccd 100644 --- a/src/libgsmd/libgsmd.c +++ b/src/libgsmd/libgsmd.c @@ -89,34 +89,37 @@ 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) +int lgsm_handle_packet(struct lgsm_handle *lh, const char *buf, int len) { struct gsmd_msg_hdr *gmh; lgsm_msg_handler *handler; 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 (lh->usock_len + len > sizeof(lh->usock_fifo)) + return -ENOMEM; - if (handler) + memcpy(lh->usock_fifo + lh->usock_len, buf, len); + lh->usock_len += len; + gmh = (struct gsmd_msg_hdr *) lh->usock_fifo; + while (lh->usock_len >= sizeof(*gmh) && + lh->usock_len >= sizeof(*gmh) + gmh->len) { + if (gmh->msg_type < __NUM_GSMD_MSGS && + (handler = lh->handler[gmh->msg_type])) rc |= handler(lh, gmh); - else - fprintf(stderr, "unable to handle packet type=%u\n", - gmh->msg_type); + else { + fprintf(stderr, "unable to handle packet " + "type=%u id=%u\n", + gmh->msg_type, gmh->id); + rc |= EINVAL; + } + + lh->usock_len -= gmh->len + sizeof(*gmh); + memmove(lh->usock_fifo, + lh->usock_fifo + gmh->len + sizeof(*gmh), + lh->usock_len); } - return rc; + + return -rc; } int lgsm_register_handler(struct lgsm_handle *lh, int type, lgsm_msg_handler *handler) @@ -196,8 +199,21 @@ static u_int16_t next_msg_id; int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) { + ssize_t rc; + size_t len = sizeof(*gmh) + gmh->len; + const void *pos = gmh; + gmh->id = next_msg_id++; - return send(lh->fd, (char *) gmh, sizeof(*gmh) + gmh->len, 0); + while (len) { + rc = send(lh->fd, pos, len, 0); + if (rc < 0 && errno != EINTR) + return -errno; + if (rc > 0) { + len -= rc; + pos += rc; + } + } + return sizeof(*gmh) + gmh->len; } struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len)