From 2e94a60c2097c8eeffce011e45bac883fd283ef3 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 27 Jun 2011 11:06:48 +0300 Subject: [PATCH] gobex: Add basic request callback support --- gobex/gobex.c | 13 ++++++++ gobex/gobex.h | 8 ++++- unit/test-gobex.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/gobex/gobex.c b/gobex/gobex.c index 2f0018530..d41f85909 100644 --- a/gobex/gobex.c +++ b/gobex/gobex.c @@ -79,6 +79,9 @@ struct _GObex { guint16 tx_mtu; GQueue *req_queue; + + GObexRequestFunc req_func; + gpointer req_func_data; }; struct connect_data { @@ -541,8 +544,18 @@ gboolean g_obex_send(GObex *obex, GObexPacket *pkt) return TRUE; } +void g_obex_set_request_function(GObex *obex, GObexRequestFunc func, + gpointer user_data) +{ + obex->req_func = func; + obex->req_func_data = user_data; +} + static gboolean g_obex_handle_packet(GObex *obex, GObexPacket *pkt) { + if (obex->req_func) + obex->req_func(obex, pkt, obex->req_func_data); + return TRUE; } diff --git a/gobex/gobex.h b/gobex/gobex.h index 3ff84ad94..69a28f61a 100644 --- a/gobex/gobex.h +++ b/gobex/gobex.h @@ -72,6 +72,9 @@ typedef struct _GObex GObex; typedef struct _GObexPacket GObexPacket; typedef struct _GObexHeader GObexHeader; +typedef void (*GObexRequestFunc) (GObex *obex, GObexPacket *req, + gpointer user_data); + GObexHeader *g_obex_header_unicode(guint8 id, const char *str); GObexHeader *g_obex_header_bytes(guint8 id, void *data, size_t len, GObexDataPolicy data_policy); @@ -93,7 +96,10 @@ void g_obex_packet_free(GObexPacket *req); GObexPacket *g_obex_packet_decode(const void *data, size_t len, GObexDataPolicy data_policy); -gboolean g_obex_send(GObex *obex, GObexPacket *req); +gboolean g_obex_send(GObex *obex, GObexPacket *pkt); + +void g_obex_set_request_function(GObex *obex, GObexRequestFunc func, + gpointer user_data); GObex *g_obex_new(GIOChannel *io); diff --git a/unit/test-gobex.c b/unit/test-gobex.c index d7964fb10..cd0451eee 100644 --- a/unit/test-gobex.c +++ b/unit/test-gobex.c @@ -19,11 +19,20 @@ * */ +#include +#include +#include +#include #include #include #include +static GMainLoop *mainloop = NULL; + +static uint8_t pkt_connect_req[] = { G_OBEX_OP_CONNECT | G_OBEX_FINAL, + 0x00, 0x07, 0x01, 0x00, 0x10, 0x00 }; + static uint8_t hdr_connid[] = { G_OBEX_HDR_ID_CONNECTION, 1, 2, 3, 4 }; static uint8_t hdr_name_ascii[] = { G_OBEX_HDR_ID_NAME, 0x00, 0x0b, 0x00, 'f', 0x00, 'o', 0x00, 'o', @@ -34,6 +43,17 @@ static uint8_t hdr_name_umlaut[] = { G_OBEX_HDR_ID_NAME, 0x00, 0x0b, static uint8_t hdr_body[] = { G_OBEX_HDR_ID_BODY, 0x00, 0x07, 1, 2, 3, 4 }; static uint8_t hdr_actionid[] = { G_OBEX_HDR_ID_ACTION, 0x00 }; +enum { + TEST_ERROR_TIMEOUT, + TEST_ERROR_UNEXPECTED, +}; + +static GQuark test_error_quark(void) +{ + return g_quark_from_static_string("test-error-quark"); +} +#define TEST_ERROR test_error_quark() + static GObex *create_gobex(int fd) { GIOChannel *io; @@ -67,6 +87,65 @@ static void assert_memequal(void *mem1, size_t len1, void *mem2, size_t len2) g_assert(0); } +static gboolean test_timeout(gpointer user_data) +{ + GError **err = user_data; + + if (!g_main_loop_is_running(mainloop)) + return FALSE; + + g_set_error(err, TEST_ERROR, TEST_ERROR_TIMEOUT, "Timed out"); + + g_main_loop_quit(mainloop); + + return FALSE; +} + +static void handle_request(GObex *obex, GObexPacket *pkt, gpointer user_data) +{ + GError **err = user_data; + + switch (g_obex_packet_get_operation(pkt, NULL)) { + case G_OBEX_OP_CONNECT: + break; + default: + g_set_error(err, TEST_ERROR, TEST_ERROR_UNEXPECTED, + "Unexpected operation"); + break; + } + + g_main_loop_quit(mainloop); +} + +static void test_connect_stream(void) +{ + GError *gerr = NULL; + GObex *obex; + ssize_t err; + int sv[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sv) < 0) { + g_printerr("socketpair: %s", strerror(errno)); + abort(); + } + + obex = create_gobex(sv[0]); + g_assert(obex != NULL); + + g_obex_set_request_function(obex, handle_request, &gerr); + + err = write(sv[1], pkt_connect_req, sizeof(pkt_connect_req)); + g_assert_cmpint(err, ==, sizeof(pkt_connect_req)); + + mainloop = g_main_loop_new(NULL, FALSE); + + g_timeout_add_seconds(1, test_timeout, &gerr); + + g_main_loop_run(mainloop); + + g_assert_no_error(gerr); +} + static void test_header_name_ascii(void) { GObexHeader *header; @@ -426,6 +505,8 @@ int main(int argc, char *argv[]) g_test_add_func("/gobex/test_decode_pkt", test_decode_pkt); + g_test_add_func("/gobex/test_connect_stream", test_connect_stream); + g_test_run(); return 0;