#define G_OBEX_MINIMUM_MTU 255
#define G_OBEX_MAXIMUM_MTU 65535
+#define G_OBEX_DEFAULT_TIMEOUT 5
+
#define FINAL_BIT 0x80
struct _GObex {
struct pending_pkt {
guint id;
GObexPacket *pkt;
+ guint timeout;
+ guint timeout_id;
GObexResponseFunc rsp_func;
gpointer rsp_data;
};
g_free(p);
}
+static gboolean req_timeout(gpointer user_data)
+{
+ GObex *obex = user_data;
+ struct pending_pkt *p = obex->pending_req;
+
+ g_assert(p != NULL);
+
+ obex->pending_req = NULL;
+
+ if (p->rsp_func) {
+ GError *err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_TIMEOUT,
+ "Timed out waiting for response");
+ p->rsp_func(obex, err, NULL, p->rsp_data);
+ g_error_free(err);
+ }
+
+ pending_pkt_free(p);
+
+ return FALSE;
+}
+
static gboolean write_stream(GObex *obex)
{
GIOStatus status;
goto done;
}
- if (p->id > 0)
+ if (p->id > 0) {
obex->pending_req = p;
- else
+ p->timeout_id = g_timeout_add_seconds(p->timeout,
+ req_timeout, obex);
+ } else
pending_pkt_free(p);
obex->tx_data = len;
return ret;
}
-guint g_obex_send_req(GObex *obex, GObexPacket *req, GObexResponseFunc func,
- gpointer user_data, GError **err)
+guint g_obex_send_req(GObex *obex, GObexPacket *req, gint timeout,
+ GObexResponseFunc func, gpointer user_data,
+ GError **err)
{
struct pending_pkt *p;
static guint id = 1;
p->rsp_func = func;
p->rsp_data = user_data;
+ if (timeout < 0)
+ p->timeout = G_OBEX_DEFAULT_TIMEOUT;
+ else
+ p->timeout = timeout;
+
if (!g_obex_send_internal(obex, p, err)) {
pending_pkt_free(p);
return 0;
gboolean g_obex_send(GObex *obex, GObexPacket *pkt, GError **err);
-guint g_obex_send_req(GObex *obex, GObexPacket *req, GObexResponseFunc func,
- gpointer user_data, GError **err);
+guint g_obex_send_req(GObex *obex, GObexPacket *req, gint timeout,
+ GObexResponseFunc func, gpointer user_data,
+ GError **err);
gboolean g_obex_cancel_req(GObex *obex, guint req_id);
void g_obex_set_request_function(GObex *obex, GObexRequestFunc func,
g_main_loop_quit(mainloop);
}
+static void timeout_rsp(GObex *obex, GError *err, GObexPacket *rsp,
+ gpointer user_data)
+{
+ GError **test_err = user_data;
+
+ if (!g_error_matches(err, G_OBEX_ERROR, G_OBEX_ERROR_TIMEOUT))
+ g_set_error(test_err, TEST_ERROR, TEST_ERROR_UNEXPECTED,
+ "Did not get expected timeout error");
+
+ g_main_loop_quit(mainloop);
+}
+
static gboolean recv_and_send(GIOChannel *io, void *data, gsize len,
GError **err)
{
return FALSE;
}
+ if (data == NULL)
+ return TRUE;
+
g_io_channel_write_chars(io, data, len, &bytes_written, NULL);
if (bytes_written != len) {
g_set_error(err, TEST_ERROR, TEST_ERROR_UNEXPECTED,
return FALSE;
}
-static void send_connect(GObexResponseFunc rsp_func, GIOFunc send_rsp_func)
+static gboolean send_nothing(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ GError **err = user_data;
+
+ if (!recv_and_send(io, NULL, 0, err))
+ g_main_loop_quit(mainloop);
+
+ return FALSE;
+}
+
+static void send_connect(GObexResponseFunc rsp_func, GIOFunc send_rsp_func,
+ gint req_timeout)
{
guint8 connect_data[] = { 0x10, 0x00, 0x10, 0x00 };
GError *gerr = NULL;
GIOChannel *io;
GIOCondition cond;
GObexPacket *req;
- guint io_id, timer_id;
+ guint io_id, timer_id, test_time;
GObex *obex;
create_endpoints(&obex, &io, SOCK_STREAM);
g_obex_packet_set_data(req, connect_data, sizeof(connect_data),
G_OBEX_DATA_REF);
- g_obex_send_req(obex, req, rsp_func, &gerr, &gerr);
+ g_obex_send_req(obex, req, req_timeout, rsp_func, &gerr, &gerr);
g_assert_no_error(gerr);
cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
mainloop = g_main_loop_new(NULL, FALSE);
- timer_id = g_timeout_add_seconds(1, test_timeout, &gerr);
+ if (req_timeout > 0)
+ test_time = req_timeout + 1;
+ else
+ test_time = 1;
+
+ timer_id = g_timeout_add_seconds(test_time, test_timeout, &gerr);
g_main_loop_run(mainloop);
static void test_send_connect_req_stream(void)
{
- send_connect(connect_rsp, send_connect_rsp);
+ send_connect(connect_rsp, send_connect_rsp, -1);
}
static void test_send_nval_connect_req_stream(void)
{
- send_connect(nval_connect_rsp, send_nval_connect_rsp);
+ send_connect(nval_connect_rsp, send_nval_connect_rsp, -1);
+}
+
+static void test_send_connect_req_timeout_stream(void)
+{
+ send_connect(timeout_rsp, send_nothing, 1);
}
static void test_send_connect_stream(void)
test_send_connect_req_stream);
g_test_add_func("/gobex/test_send_nval_connect_req_stream",
test_send_nval_connect_req_stream);
+ g_test_add_func("/gobex/test_send_connect_req_timeout_stream",
+ test_send_connect_req_timeout_stream);
g_test_run();