diff options
Diffstat (limited to 'gobex')
-rw-r--r-- | gobex/gobex-transfer.c | 98 | ||||
-rw-r--r-- | gobex/gobex-transfer.h | 6 |
2 files changed, 102 insertions, 2 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; +} diff --git a/gobex/gobex-transfer.h b/gobex/gobex-transfer.h index 040d0e73b..fdc28781b 100644 --- a/gobex/gobex-transfer.h +++ b/gobex/gobex-transfer.h @@ -31,4 +31,8 @@ guint g_obex_put_req(GObex *obex, const char *type, const char *name, GObexDataProducer data_func, GObexFunc complete_func, gpointer user_data, GError **err); -#endif +guint g_obex_put_rsp(GObex *obex, GObexPacket *req, + GObexDataConsumer data_func, GObexFunc complete_func, + gpointer user_data, GError **err); + +#endif /* __GOBEX_TRANSFER_H_ */ |