GIOChannel *io;
guint io_source;
- gboolean (*read) (GObex *obex);
- gboolean (*write) (GObex *obex);
+ gboolean (*read) (GObex *obex, GError **err);
+ gboolean (*write) (GObex *obex, GError **err);
guint8 *rx_buf;
size_t rx_data;
GQueue *tx_queue;
- GObexRequestFunc req_func;
- gpointer req_func_data;
-
- GObexDisconnectFunc disconn_func;
- gpointer disconn_func_data;
+ GObexEventFunc ev_func;
+ gpointer ev_func_data;
struct pending_pkt *pending_req;
};
return FALSE;
}
-static gboolean write_stream(GObex *obex)
+static gboolean write_stream(GObex *obex, GError **err)
{
GIOStatus status;
gsize bytes_written;
buf = (gchar *) &obex->tx_buf[obex->tx_sent];
status = g_io_channel_write_chars(obex->io, buf, obex->tx_data,
- &bytes_written, NULL);
+ &bytes_written, err);
if (status != G_IO_STATUS_NORMAL)
return FALSE;
return TRUE;
}
-static gboolean write_packet(GObex *obex)
+static gboolean write_packet(GObex *obex, GError **err)
{
+ g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_FAILED,
+ "Packet based writing not implemented");
return FALSE;
}
obex->tx_sent = 0;
}
- if (!obex->write(obex))
+ if (!obex->write(obex, NULL))
goto done;
if (obex->tx_data > 0 || g_queue_get_length(obex->tx_queue) > 0)
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;
-}
-
-void g_obex_set_disconnect_function(GObex *obex, GObexDisconnectFunc func,
+void g_obex_set_event_function(GObex *obex, GObexEventFunc func,
gpointer user_data)
{
- obex->disconn_func = func;
- obex->disconn_func_data = user_data;
+ obex->ev_func = func;
+ obex->ev_func_data = user_data;
}
static void parse_connect_data(GObex *obex, GObexPacket *pkt)
static void handle_request(GObex *obex, GError *err, GObexPacket *req)
{
- if (g_obex_packet_get_operation(req, NULL) == G_OBEX_OP_CONNECT)
- parse_connect_data(obex, req);
+ if (req != NULL) {
+ guint8 op = g_obex_packet_get_operation(req, NULL);
+ if (op == G_OBEX_OP_CONNECT)
+ parse_connect_data(obex, req);
+ }
- if (obex->req_func)
- obex->req_func(obex, req, obex->req_func_data);
+ if (obex->ev_func)
+ obex->ev_func(obex, err, req, obex->ev_func_data);
}
static gboolean g_obex_handle_packet(GObex *obex, GError *err, GObexPacket *pkt)
{
if (obex->pending_req)
handle_response(obex, err, pkt);
- else if (pkt != NULL)
+ else
handle_request(obex, err, pkt);
/* FIXME: Application callback needed for err != NULL? */
return TRUE;
}
-static gboolean read_stream(GObex *obex)
+static gboolean read_stream(GObex *obex, GError **err)
{
GIOChannel *io = obex->io;
GIOStatus status;
return TRUE;
}
-static gboolean read_packet(GObex *obex)
+static gboolean read_packet(GObex *obex, GError **err)
{
+ g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_DISCONNECTED,
+ "Packet reading not implemented");
return FALSE;
}
if (cond & G_IO_NVAL)
return FALSE;
- if (cond & (G_IO_HUP | G_IO_ERR))
+ if (cond & (G_IO_HUP | G_IO_ERR)) {
+ err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_DISCONNECTED,
+ "Transport got disconnected");
goto failed;
+ }
- if (!obex->read(obex))
+ if (!obex->read(obex, &err))
goto failed;
if (obex->rx_data < 3 || obex->rx_data < obex->rx_pkt_len)
obex->io = NULL;
obex->io_source = 0;
- if (obex->disconn_func)
- obex->disconn_func(obex, obex->disconn_func_data);
+ if (obex->ev_func)
+ obex->ev_func(obex, err, NULL, obex->ev_func_data);
+
+ g_error_free(err);
return FALSE;
}
typedef struct _GObex GObex;
-typedef void (*GObexRequestFunc) (GObex *obex, GObexPacket *req,
+typedef void (*GObexEventFunc) (GObex *obex, GError *err, GObexPacket *req,
gpointer user_data);
typedef void (*GObexResponseFunc) (GObex *obex, GError *err, GObexPacket *rsp,
gpointer user_data);
-typedef void (*GObexDisconnectFunc) (GObex *obex, gpointer user_data);
gboolean g_obex_send(GObex *obex, GObexPacket *pkt, GError **err);
GError **err);
gboolean g_obex_cancel_req(GObex *obex, guint req_id);
-void g_obex_set_request_function(GObex *obex, GObexRequestFunc func,
- gpointer user_data);
-
-void g_obex_set_disconnect_function(GObex *obex, GObexDisconnectFunc func,
+void g_obex_set_event_function(GObex *obex, GObexEventFunc func,
gpointer user_data);
GObex *g_obex_new(GIOChannel *io, GObexTransportType transport_type);
g_assert_no_error(gerr);
}
-static void handle_connect_request(GObex *obex, GObexPacket *pkt,
+static void handle_connect_event(GObex *obex, GError *err, GObexPacket *pkt,
gpointer user_data)
{
- GError **err = user_data;
+ GError **test_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);
+
+ if (err != NULL) {
+ *test_err = g_error_copy(err);
+ return;
}
- g_main_loop_quit(mainloop);
+ if (g_obex_packet_get_operation(pkt, NULL) != G_OBEX_OP_CONNECT)
+ g_set_error(test_err, TEST_ERROR, TEST_ERROR_UNEXPECTED,
+ "Unexpected operation");
}
static void test_recv_connect_stream(void)
create_endpoints(&obex, &io, SOCK_STREAM);
- g_obex_set_request_function(obex, handle_connect_request, &gerr);
+ g_obex_set_event_function(obex, handle_connect_event, &gerr);
status = g_io_channel_write_chars(io, (gchar *) pkt_connect_req,
sizeof(pkt_connect_req),
g_assert_no_error(gerr);
}
-static void disconnected(GObex *obex, gpointer user_data)
+static void disconn_ev(GObex *obex, GError *err, GObexPacket *req,
+ gpointer user_data)
{
+ GError **test_err = user_data;
+
+ if (!g_error_matches(err, G_OBEX_ERROR, G_OBEX_ERROR_DISCONNECTED))
+ g_set_error(test_err, TEST_ERROR, TEST_ERROR_UNEXPECTED,
+ "Did not get expected disconnect error");
+
g_main_loop_quit(mainloop);
}
create_endpoints(&obex, &io, SOCK_STREAM);
- g_obex_set_disconnect_function(obex, disconnected, NULL);
+ g_obex_set_event_function(obex, disconn_ev, &gerr);
timer_id = g_timeout_add_seconds(1, test_timeout, &gerr);