Diff between 696e89cfdcf325ea083257b54cc4f1eb6ac5abf4 and 2e94a60c2097c8eeffce011e45bac883fd283ef3

Changed Files

File Additions Deletions Status
gobex/gobex.c +13 -0 modified
gobex/gobex.h +7 -1 modified
unit/test-gobex.c +81 -0 modified

Full Patch

diff --git a/gobex/gobex.c b/gobex/gobex.c
index 2f00185..d41f859 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 3ff84ad..69a28f6 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 d7964fb..cd0451e 100644
--- a/unit/test-gobex.c
+++ b/unit/test-gobex.c
@@ -19,11 +19,20 @@
  *
  */
 
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
 #include <unistd.h>
 #include <string.h>
 
 #include <gobex/gobex.h>
 
+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;