From 14d2bde30d43c7d677f75530360231ea64f634e6 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Jul 2011 00:50:15 +0300 Subject: [PATCH] gobex: Add Get support to test-client and test-server --- tools/obex-client-tool.c | 64 +++++++++++++++++++++++----- tools/obex-server-tool.c | 91 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 141 insertions(+), 14 deletions(-) diff --git a/tools/obex-client-tool.c b/tools/obex-client-tool.c index a621ec241..f83edfa4d 100644 --- a/tools/obex-client-tool.c +++ b/tools/obex-client-tool.c @@ -115,18 +115,18 @@ static void cmd_connect(int argc, char **argv) g_obex_connect(obex, conn_complete, NULL, NULL, G_OBEX_HDR_INVALID); } -struct put_data { +struct transfer_data { int fd; }; -static void put_complete(GObex *obex, GError *err, gpointer user_data) +static void transfer_complete(GObex *obex, GError *err, gpointer user_data) { - struct put_data *data = user_data; + struct transfer_data *data = user_data; if (err != NULL) - g_printerr("put failed: %s\n", err->message); + g_printerr("failed: %s\n", err->message); else - g_print("put succeeded\n"); + g_print("transfer succeeded\n"); close(data->fd); g_free(data); @@ -134,14 +134,14 @@ static void put_complete(GObex *obex, GError *err, gpointer user_data) static gssize put_data_cb(void *buf, gsize len, gpointer user_data) { - struct put_data *data = user_data; + struct transfer_data *data = user_data; return read(data->fd, buf, len); } static void cmd_put(int argc, char **argv) { - struct put_data *data; + struct transfer_data *data; GError *err = NULL; int fd; @@ -152,14 +152,57 @@ static void cmd_put(int argc, char **argv) fd = open(argv[1], O_RDONLY | O_NOCTTY, 0); if (fd < 0) { - g_printerr("open: %s", strerror(errno)); + g_printerr("open: %s\n", strerror(errno)); + return; + } + + data = g_new0(struct transfer_data, 1); + data->fd = fd; + + g_obex_put_req(obex, put_data_cb, transfer_complete, data, &err, + G_OBEX_HDR_NAME, argv[1], + G_OBEX_HDR_INVALID); + if (err != NULL) { + g_printerr("put failed: %s\n", err->message); + g_error_free(err); + close(data->fd); + g_free(data); + } +} + +static gboolean get_data_cb(const void *buf, gsize len, gpointer user_data) +{ + struct transfer_data *data = user_data; + + if (write(data->fd, buf, len) < 0) { + g_printerr("write: %s\n", strerror(errno)); + return FALSE; + } + + return TRUE; +} + +static void cmd_get(int argc, char **argv) +{ + struct transfer_data *data; + GError *err = NULL; + int fd; + + if (argc < 2) { + g_printerr("Filename required\n"); + return; + } + + fd = open(argv[1], O_WRONLY | O_CREAT | O_NOCTTY, 0); + if (fd < 0) { + g_printerr("open: %s\n", strerror(errno)); return; } - data = g_new0(struct put_data, 1); + data = g_new0(struct transfer_data, 1); data->fd = fd; - g_obex_put_req(obex, put_data_cb, put_complete, data, &err, + g_obex_get_req(obex, get_data_cb, transfer_complete, data, &err, G_OBEX_HDR_NAME, argv[1], G_OBEX_HDR_INVALID); if (err != NULL) { @@ -188,6 +231,7 @@ static struct { { "quit", cmd_exit, "", "Exit application" }, { "connect", cmd_connect, "[target]", "OBEX Connect" }, { "put", cmd_put, "", "Send a file" }, + { "get", cmd_get, "", "Receive a file" }, { NULL }, }; diff --git a/tools/obex-server-tool.c b/tools/obex-server-tool.c index 39ec18a4a..fdf078ab8 100644 --- a/tools/obex-server-tool.c +++ b/tools/obex-server-tool.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -62,17 +63,34 @@ static void disconn_func(GObex *obex, GError *err, gpointer user_data) g_obex_unref(obex); } -static void put_complete(GObex *obex, GError *err, gpointer user_data) +struct transfer_data { + int fd; +}; + +static void transfer_complete(GObex *obex, GError *err, gpointer user_data) { + struct transfer_data *data = user_data; + if (err != NULL) - g_printerr("put failed: %s\n", err->message); + g_printerr("transfer failed: %s\n", err->message); else - g_print("put succeeded\n"); + g_print("transfer succeeded\n"); + + close(data->fd); + g_free(data); } static gboolean recv_data(const void *buf, gsize len, gpointer user_data) { + struct transfer_data *data = user_data; + g_print("received %zu bytes of data\n", len); + + if (write(data->fd, buf, len) < 0) { + g_printerr("write: %s\n", strerror(errno)); + return FALSE; + } + return TRUE; } @@ -81,6 +99,7 @@ static void handle_put(GObex *obex, GObexPacket *req, gpointer user_data) GError *err = NULL; GObexHeader *hdr; const char *type, *name; + struct transfer_data *data; gsize type_len; hdr = g_obex_packet_find_header(req, G_OBEX_HDR_TYPE); @@ -103,11 +122,74 @@ static void handle_put(GObex *obex, GObexPacket *req, gpointer user_data) g_print("put type \"%s\" name \"%s\"\n", type ? type : "", name ? name : ""); - g_obex_put_rsp(obex, req, recv_data, put_complete, NULL, &err, + data = g_new0(struct transfer_data, 1); + + data->fd = open(name, O_WRONLY | O_CREAT | O_NOCTTY, 0); + if (data->fd < 0) { + g_printerr("open(%s): %s\n", name, strerror(errno)); + g_free(data); + return; + } + + g_obex_put_rsp(obex, req, recv_data, transfer_complete, data, &err, + G_OBEX_HDR_INVALID); + if (err != NULL) { + g_printerr("Unable to send response: %s\n", err->message); + g_error_free(err); + g_free(data); + } +} + +static gssize send_data(void *buf, gsize len, gpointer user_data) +{ + struct transfer_data *data = user_data; + + return read(data->fd, buf, len); +} + +static void handle_get(GObex *obex, GObexPacket *req, gpointer user_data) +{ + GError *err = NULL; + struct transfer_data *data; + const char *type, *name; + GObexHeader *hdr; + gsize type_len; + + hdr = g_obex_packet_find_header(req, G_OBEX_HDR_TYPE); + if (hdr != NULL) { + g_obex_header_get_bytes(hdr, (const guint8 **) &type, + &type_len); + if (type[type_len - 1] != '\0') { + g_printerr("non-nul terminated type header\n"); + type = NULL; + } + } else + type = NULL; + + hdr = g_obex_packet_find_header(req, G_OBEX_HDR_NAME); + if (hdr != NULL) + g_obex_header_get_unicode(hdr, &name); + else + name = NULL; + + g_print("get type \"%s\" name \"%s\"\n", type ? type : "", + name ? name : ""); + + data = g_new0(struct transfer_data, 1); + + data->fd = open(name, O_RDONLY | O_NOCTTY, 0); + if (data->fd < 0) { + g_printerr("open(%s): %s", name, strerror(errno)); + g_free(data); + return; + } + + g_obex_get_rsp(obex, send_data, transfer_complete, data, &err, G_OBEX_HDR_INVALID); if (err != NULL) { g_printerr("Unable to send response: %s\n", err->message); g_error_free(err); + g_free(data); } } @@ -166,6 +248,7 @@ static gboolean unix_accept(GIOChannel *chan, GIOCondition cond, gpointer data) g_io_channel_unref(io); g_obex_set_disconnect_function(obex, disconn_func, NULL); g_obex_add_request_function(obex, G_OBEX_OP_PUT, handle_put, NULL); + g_obex_add_request_function(obex, G_OBEX_OP_GET, handle_get, NULL); g_obex_add_request_function(obex, G_OBEX_OP_CONNECT, handle_connect, NULL); clients = g_slist_append(clients, obex);; -- 2.47.3