From 7bf2dc97075a52b296112a0c069b1c202aca526d Mon Sep 17 00:00:00 2001 From: Pekka Pessi Date: Fri, 23 Apr 2010 18:17:16 +0300 Subject: [PATCH] Fix: transaction id usage in gisi/server.c --- gisi/server.c | 111 ++++++++++++++++++++++++++++------------------------------ 1 file changed, 54 insertions(+), 57 deletions(-) diff --git a/gisi/server.c b/gisi/server.c index ef2d5dd..9733908 100644 --- a/gisi/server.c +++ b/gisi/server.c @@ -44,7 +44,7 @@ struct _GIsiIncoming { struct sockaddr_pn spn; - uint8_t id; + uint8_t trans_id; }; struct _GIsiServer { @@ -61,8 +61,6 @@ struct _GIsiServer { GIsiRequestFunc func[256]; void *data[256]; - GIsiIncoming irq[1]; - /* Debugging */ GIsiDebugFunc debug_func; void *debug_data; @@ -87,7 +85,7 @@ GIsiServer *g_isi_server_create(GIsiModem *modem, uint8_t resource, abort(); self = ptr; - memset (self, 0, sizeof *self); + memset(self, 0, sizeof(*self)); self->resource = resource; self->version.major = major; self->version.minor = minor; @@ -174,9 +172,11 @@ g_isi_server_add_name(GIsiServer *self) 0, 0, }; - if (sendto(self->fd, req, sizeof(req), 0, (void *)&spn, - sizeof(spn)) != sizeof(spn)) - return; + if (sendto(self->fd, req, sizeof(req), 0, + (void *)&spn, sizeof(spn)) != sizeof(req)) { + g_warning("%s: %s", "sendto(PN_NAMESERVICE)", + strerror(errno)); + } } } @@ -236,7 +236,7 @@ int g_isi_vrespond(GIsiServer *self, const struct iovec *iov, size_t iovlen, return -1; } - _iov[0].iov_base = &irq->id; + _iov[0].iov_base = &irq->trans_id; _iov[0].iov_len = 1; for (i = 0, len = 1; i < iovlen; i++) { _iov[1 + i] = iov[i]; @@ -245,8 +245,7 @@ int g_isi_vrespond(GIsiServer *self, const struct iovec *iov, size_t iovlen, ret = sendmsg(self->fd, &msg, MSG_NOSIGNAL); - if (irq != self->irq) - g_free(irq); + g_free(irq); return ret; } @@ -285,65 +284,63 @@ void g_isi_server_unhandle(GIsiServer *self, uint8_t type) self->func[type] = NULL; } -/* Data callback */ -static gboolean g_isi_server_callback(GIOChannel *channel, GIOCondition cond, - gpointer opaque) -{ - GIsiServer *self = opaque; - int len; - GIsiIncoming *irq = self->irq; - struct sockaddr_pn *addr = &irq->spn; - socklen_t addrlen = sizeof(irq->spn); - if (cond & (G_IO_NVAL|G_IO_HUP)) { - g_warning("Unexpected event on Phonet channel %p", channel); - return FALSE; - } +static void generic_error_response(GIsiServer *self, + uint8_t trans_id, uint8_t error, uint8_t message_id, + void *addr, socklen_t addrlen) +{ + uint8_t common[] = { trans_id, 0xF0, error, message_id }; - len = phonet_peek_length(channel); - { - uint32_t buf[(len + 3) / 4]; - uint8_t *msg; - uint8_t id; - uint8_t failure; - len = recvfrom(self->fd, buf, len, MSG_DONTWAIT, - (void *)addr, &addrlen); + sendto(self->fd, common, sizeof(common), MSG_NOSIGNAL, addr, addrlen); +} - if (len < 2 || irq->spn.spn_resource != self->resource) - return TRUE; +static void process_message(GIsiServer *self, int len) +{ + uint8_t msg[len + 1]; + struct sockaddr_pn addr; + socklen_t addrlen = sizeof(addr); + uint8_t message_id; + GIsiRequestFunc func; + void *data; - msg = (uint8_t *)buf; + len = recvfrom(self->fd, msg, sizeof(msg), MSG_DONTWAIT, + (void *)&addr, &addrlen); - if (self->debug_func) - self->debug_func(msg + 1, len - 1, self->debug_data); + if (len < 2 || addr.spn_resource != self->resource) + return; - irq->id = id = msg[1]; + if (self->debug_func) + self->debug_func(msg + 1, len - 1, self->debug_data); - if (self->func[id]) { - irq = g_new0(GIsiIncoming, 1); + message_id = msg[1]; + func = self->func[message_id]; + data = self->data[message_id]; - if (irq) { - *irq = *self->irq; - self->func[id](self, msg + 1, len - 1, - irq, self->data[id]); - return TRUE; - } - g_free(irq); - failure = 0x14; + if (func) { + GIsiIncoming *irq = g_new0(GIsiIncoming, 1); - } else { + if (irq) { + irq->spn = addr; + irq->trans_id = msg[0]; + func(self, msg + 1, len - 1, irq, data); + return; + } + } - failure = 0x17; + /* Respond with COMMON MESSAGE COMM_SERVICE_NOT_AUTHENTICATED_RESP */ + generic_error_response(self, msg[0], 0x17, msg[1], &addr, addrlen); +} - { - uint8_t common[] = { - 0xF0, failure, msg[1] - }; - g_isi_respond(self, common, sizeof(common), - irq); - } - } +/* Data callback */ +static gboolean g_isi_server_callback(GIOChannel *channel, GIOCondition cond, + gpointer opaque) +{ + if (cond & (G_IO_NVAL|G_IO_HUP)) { + g_warning("Unexpected event on Phonet channel %p", channel); + return FALSE; } + process_message(opaque, phonet_peek_length(channel)); + return TRUE; } -- 2.7.4