From b76d71e5b21ee1e6197ffd5fe14d6f098385a99b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 27 Jun 2011 16:54:59 +0300 Subject: [PATCH] gobex: Refactor reading/writing to allow packet based transport --- gobex/gobex.c | 58 +++++++++++++++++++++++++++++++++++++---------- gobex/gobex.h | 7 +++++- unit/test-gobex.c | 19 +++++++++++----- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/gobex/gobex.c b/gobex/gobex.c index 3e06d86f8..1235d7af2 100644 --- a/gobex/gobex.c +++ b/gobex/gobex.c @@ -78,6 +78,9 @@ struct _GObex { GIOChannel *io; guint io_source; + gboolean (*read) (GObex *obex); + gboolean (*write) (GObex *obex); + guint8 *rx_buf; size_t rx_data; guint16 rx_pkt_len; @@ -638,14 +641,34 @@ static struct pending_req *pending_req_new(GObexPacket *pkt) return req; } -static gboolean write_data(GIOChannel *io, GIOCondition cond, - gpointer user_data) +static gboolean write_stream(GObex *obex) { - GObex *obex = user_data; GIOStatus status; gsize bytes_written; gchar *buf; + buf = (gchar *) &obex->tx_buf[obex->tx_sent]; + status = g_io_channel_write_chars(obex->io, buf, obex->tx_data, + &bytes_written, NULL); + if (status != G_IO_STATUS_NORMAL) + return FALSE; + + obex->tx_sent += bytes_written; + obex->tx_data -= bytes_written; + + return TRUE; +} + +static gboolean write_packet(GObex *obex) +{ + return FALSE; +} + +static gboolean write_data(GIOChannel *io, GIOCondition cond, + gpointer user_data) +{ + GObex *obex = user_data; + if (cond & G_IO_NVAL) return FALSE; @@ -678,15 +701,9 @@ static gboolean write_data(GIOChannel *io, GIOCondition cond, obex->tx_sent = 0; } - buf = (gchar *) &obex->tx_buf[obex->tx_sent]; - status = g_io_channel_write_chars(io, buf, obex->tx_data, - &bytes_written, NULL); - if (status != G_IO_STATUS_NORMAL) + if (!obex->write(obex)) goto done; - obex->tx_sent += bytes_written; - obex->tx_data -= bytes_written; - if (obex->tx_data > 0 || g_queue_get_length(obex->req_queue) > 0) return TRUE; @@ -810,6 +827,11 @@ read_body: return TRUE; } +static gboolean read_packet(GObex *obex) +{ + return FALSE; +} + static gboolean incoming_data(GIOChannel *io, GIOCondition cond, gpointer user_data) { @@ -823,7 +845,8 @@ static gboolean incoming_data(GIOChannel *io, GIOCondition cond, if (cond & (G_IO_HUP | G_IO_ERR)) goto failed; - read_stream(obex); + if (!obex->read(obex)) + goto failed; if (obex->rx_data < 3 || obex->rx_data < obex->rx_pkt_len) return TRUE; @@ -858,7 +881,7 @@ failed: return FALSE; } -GObex *g_obex_new(GIOChannel *io) +GObex *g_obex_new(GIOChannel *io, GObexTransportType transport_type) { GObex *obex; GIOCondition cond; @@ -876,6 +899,17 @@ GObex *g_obex_new(GIOChannel *io) obex->rx_buf = g_malloc(obex->rx_mtu); obex->tx_buf = g_malloc(obex->tx_mtu); + switch (transport_type) { + case G_OBEX_TRANSPORT_STREAM: + obex->read = read_stream; + obex->write = write_stream; + break; + case G_OBEX_TRANSPORT_PACKET: + obex->read = read_packet; + obex->write = write_packet; + break; + } + g_io_channel_set_encoding(io, NULL, NULL); g_io_channel_set_buffered(io, FALSE); cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL; diff --git a/gobex/gobex.h b/gobex/gobex.h index cc56cdf22..3d0163615 100644 --- a/gobex/gobex.h +++ b/gobex/gobex.h @@ -67,6 +67,11 @@ typedef enum { G_OBEX_DATA_REF, } GObexDataPolicy; +typedef enum { + G_OBEX_TRANSPORT_STREAM, + G_OBEX_TRANSPORT_PACKET, +} GObexTransportType; + typedef struct _GObex GObex; typedef struct _GObexPacket GObexPacket; typedef struct _GObexHeader GObexHeader; @@ -110,7 +115,7 @@ gboolean g_obex_cancel_req(GObex *obex, guint req_id); void g_obex_set_request_function(GObex *obex, GObexRequestFunc func, gpointer user_data); -GObex *g_obex_new(GIOChannel *io); +GObex *g_obex_new(GIOChannel *io, GObexTransportType transport_type); GObex *g_obex_ref(GObex *obex); void g_obex_unref(GObex *obex); diff --git a/unit/test-gobex.c b/unit/test-gobex.c index 54257d529..668e52e84 100644 --- a/unit/test-gobex.c +++ b/unit/test-gobex.c @@ -58,7 +58,8 @@ static GQuark test_error_quark(void) } #define TEST_ERROR test_error_quark() -static GObex *create_gobex(int fd, gboolean close_on_unref) +static GObex *create_gobex(int fd, GObexTransportType transport_type, + gboolean close_on_unref) { GIOChannel *io; @@ -67,7 +68,7 @@ static GObex *create_gobex(int fd, gboolean close_on_unref) g_io_channel_set_close_on_unref(io, close_on_unref); - return g_obex_new(io); + return g_obex_new(io, transport_type); } static void dump_bytes(uint8_t *buf, size_t buf_len) @@ -157,6 +158,7 @@ done: static void create_endpoints(GObex **obex, GIOChannel **io, int sock_type) { + GObexTransportType transport_type; int sv[2]; if (socketpair(AF_UNIX, sock_type | SOCK_NONBLOCK, 0, sv) < 0) { @@ -164,7 +166,12 @@ static void create_endpoints(GObex **obex, GIOChannel **io, int sock_type) abort(); } - *obex = create_gobex(sv[0], TRUE); + if (sock_type == SOCK_STREAM) + transport_type = G_OBEX_TRANSPORT_STREAM; + else + transport_type = G_OBEX_TRANSPORT_PACKET; + + *obex = create_gobex(sv[0], transport_type, TRUE); g_assert(*obex != NULL); *io = g_io_channel_unix_new(sv[1]); @@ -650,7 +657,7 @@ static void test_ref_unref(void) { GObex *obex; - obex = create_gobex(STDIN_FILENO, FALSE); + obex = create_gobex(STDIN_FILENO, G_OBEX_TRANSPORT_STREAM, FALSE); g_assert(obex != NULL); @@ -664,7 +671,7 @@ static void test_basic(void) { GObex *obex; - obex = create_gobex(STDIN_FILENO, FALSE); + obex = create_gobex(STDIN_FILENO, G_OBEX_TRANSPORT_STREAM, FALSE); g_assert(obex != NULL); @@ -675,7 +682,7 @@ static void test_null_io(void) { GObex *obex; - obex = g_obex_new(NULL); + obex = g_obex_new(NULL, 0); g_assert(obex == NULL); } -- 2.47.3