summaryrefslogtreecommitdiff
path: root/gobex/gobex-transfer.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2011-07-06 01:55:43 +0300
committerMarcel Holtmann <marcel@holtmann.org>2012-12-04 22:21:59 +0100
commitd070d17059b7f2d43b39858a20806de347ef8e74 (patch)
treef5de46b9c092afdc5ea386df9b5bdba985bbe274 /gobex/gobex-transfer.c
parentf25c695d2216a9991df5f271b3515e1d9761874a (diff)
downloadbluez-d070d17059b7f2d43b39858a20806de347ef8e74.tar.gz
gobex: Add basic server-side put transfer support
Diffstat (limited to 'gobex/gobex-transfer.c')
-rw-r--r--gobex/gobex-transfer.c98
1 files changed, 97 insertions, 1 deletions
diff --git a/gobex/gobex-transfer.c b/gobex/gobex-transfer.c
index d65d0164c..9b2fac862 100644
--- a/gobex/gobex-transfer.c
+++ b/gobex/gobex-transfer.c
@@ -34,6 +34,10 @@ struct transfer {
guint req_id;
+ gint put_id;
+ gint get_id;
+ gint abort_id;
+
GObexDataProducer data_producer;
GObexDataConsumer data_consumer;
GObexFunc complete_func;
@@ -44,6 +48,22 @@ struct transfer {
static void transfer_free(struct transfer *transfer)
{
transfers = g_slist_remove(transfers, transfer);
+
+ if (transfer->req_id > 0)
+ g_obex_cancel_req(transfer->obex, transfer->req_id, TRUE);
+
+ if (transfer->put_id)
+ g_obex_remove_request_function(transfer->obex,
+ transfer->put_id);
+
+ if (transfer->get_id)
+ g_obex_remove_request_function(transfer->obex,
+ transfer->req_id);
+
+ if (transfer->abort_id)
+ g_obex_remove_request_function(transfer->obex,
+ transfer->abort_id);
+
g_obex_unref(transfer->obex);
g_free(transfer);
}
@@ -59,6 +79,8 @@ static void transfer_abort_response(GObex *obex, GError *err, GObexPacket *rsp,
{
struct transfer *transfer = user_data;
+ transfer->req_id = 0;
+
/* Intentionally override error */
err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
"Operation was aborted");
@@ -97,13 +119,14 @@ static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp,
GObexPacket *req;
gboolean rspcode, final;
+ transfer->req_id = 0;
+
if (err != NULL) {
transfer_complete(transfer, err);
return;
}
rspcode = g_obex_packet_get_operation(rsp, &final);
-
if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
GError *rsp_err;
rsp_err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_FAILED,
@@ -183,3 +206,76 @@ guint g_obex_put_req(GObex *obex, const char *type, const char *name,
return transfer->id;
}
+
+static void transfer_put_req(GObex *obex, GObexPacket *req, gpointer user_data)
+{
+ struct transfer *transfer = user_data;
+ guint8 rspcode = G_OBEX_RSP_CONTINUE;
+ GError *err = NULL;
+ GObexPacket *rsp;
+ GObexHeader *body;
+
+ body = g_obex_packet_get_header(req, G_OBEX_HDR_ID_BODY);
+ if (body == NULL) {
+ body = g_obex_packet_get_header(req, G_OBEX_HDR_ID_BODY_END);
+ rspcode = G_OBEX_RSP_SUCCESS;
+ }
+
+ if (body != NULL) {
+ const guint8 *buf;
+ gsize len;
+
+ g_obex_header_get_bytes(body, &buf, &len);
+
+ transfer->data_consumer(buf, len, transfer->user_data);
+ }
+
+ rsp = g_obex_packet_new(rspcode, TRUE, NULL);
+ if (!g_obex_send(obex, rsp, &err)) {
+ transfer_complete(transfer, err);
+ g_error_free(err);
+ }
+
+ if (rspcode == G_OBEX_RSP_SUCCESS)
+ transfer_complete(transfer, NULL);
+}
+
+static void transfer_abort_req(GObex *obex, GObexPacket *req, gpointer user_data)
+{
+ struct transfer *transfer = user_data;
+ GObexPacket *rsp;
+ GError *err;
+
+ err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
+ "Request was aborted");
+ transfer_complete(transfer, err);
+ g_error_free(err);
+
+ rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE, NULL);
+ g_obex_send(obex, rsp, NULL);
+}
+
+guint g_obex_put_rsp(GObex *obex, GObexPacket *req,
+ GObexDataConsumer data_func, GObexFunc complete_func,
+ gpointer user_data, GError **err)
+{
+ struct transfer *transfer;
+ gint id;
+
+ transfer = transfer_new(obex, G_OBEX_OP_PUT, complete_func, user_data);
+ transfer->data_consumer = data_func;
+
+ transfer_put_req(obex, req, transfer);
+ if (!g_slist_find(transfers, transfer))
+ return 0;
+
+ id = g_obex_add_request_function(obex, G_OBEX_OP_PUT, transfer_put_req,
+ transfer);
+ transfer->put_id = id;
+
+ id = g_obex_add_request_function(obex, G_OBEX_OP_ABORT,
+ transfer_abort_req, transfer);
+ transfer->abort_id = id;
+
+ return transfer->id;
+}