OSDN Git Service

gobex: Add va-args based packet creation support
authorJohan Hedberg <johan.hedberg@intel.com>
Sun, 10 Jul 2011 18:36:47 +0000 (21:36 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 4 Dec 2012 21:22:01 +0000 (22:22 +0100)
gobex/gobex-header.c
gobex/gobex-header.h
gobex/gobex-packet.c
gobex/gobex-packet.h
gobex/gobex-transfer.c
gobex/gobex-transfer.h
gobex/gobex.c
tools/obex-server-tool.c
unit/test-gobex-packet.c
unit/test-gobex-transfer.c
unit/test-gobex.c

index 1e5e534..bf7dc9d 100644 (file)
@@ -397,3 +397,48 @@ guint16 g_obex_header_get_length(GObexHeader *header)
 {
        return header->hlen;
 }
+
+GSList *g_obex_header_create_list(guint8 first_hdr_id, va_list args,
+                                                       gsize *total_len)
+{
+       unsigned int id = first_hdr_id;
+       GSList *l = NULL;
+
+       *total_len = 0;
+
+       while (id != G_OBEX_HDR_ID_INVALID) {
+               GObexHeader *hdr;
+               const char *str;
+               const void *bytes;
+               unsigned int val;
+               gsize len;
+
+               switch (G_OBEX_HDR_TYPE(id)) {
+               case G_OBEX_HDR_TYPE_UNICODE:
+                       str = va_arg(args, const char *);
+                       hdr = g_obex_header_new_unicode(id, str);
+                       break;
+               case G_OBEX_HDR_TYPE_BYTES:
+                       bytes = va_arg(args, void *);
+                       len = va_arg(args, gsize);
+                       hdr = g_obex_header_new_bytes(id, bytes, len);
+                       break;
+               case G_OBEX_HDR_TYPE_UINT8:
+                       val = va_arg(args, unsigned int);
+                       hdr = g_obex_header_new_uint8(id, val);
+                       break;
+               case G_OBEX_HDR_TYPE_UINT32:
+                       val = va_arg(args, unsigned int);
+                       hdr = g_obex_header_new_uint32(id, val);
+                       break;
+               default:
+                       g_assert_not_reached();
+               }
+
+               l = g_slist_append(l, hdr);
+               *total_len += hdr->hlen;
+               id = va_arg(args, int);
+       }
+
+       return l;
+}
index 721fc36..0a8ff33 100644 (file)
@@ -27,6 +27,8 @@
 #include <gobex/gobex-defs.h>
 
 /* Header ID's */
+#define G_OBEX_HDR_ID_INVALID          0x00
+
 #define G_OBEX_HDR_ID_COUNT            0xc0
 #define G_OBEX_HDR_ID_NAME             0x01
 #define G_OBEX_HDR_ID_TYPE             0x42
@@ -66,6 +68,9 @@ GObexHeader *g_obex_header_new_bytes(guint8 id, const void *data, gsize len);
 GObexHeader *g_obex_header_new_uint8(guint8 id, guint8 val);
 GObexHeader *g_obex_header_new_uint32(guint8 id, guint32 val);
 
+GSList *g_obex_header_create_list(guint8 first_hdr_id, va_list args,
+                                                       gsize *total_len);
+
 guint8 g_obex_header_get_id(GObexHeader *header);
 guint16 g_obex_header_get_length(GObexHeader *header);
 
index 0e6528e..10c1cf7 100644 (file)
@@ -154,7 +154,8 @@ gboolean g_obex_packet_set_data(GObexPacket *pkt, const void *data, gsize len,
        return TRUE;
 }
 
-GObexPacket *g_obex_packet_new(guint8 opcode, gboolean final, GSList *headers)
+GObexPacket *g_obex_packet_new_valist(guint8 opcode, gboolean final,
+                                       guint8 first_hdr_id, va_list args)
 {
        GObexPacket *pkt;
 
@@ -162,13 +163,26 @@ GObexPacket *g_obex_packet_new(guint8 opcode, gboolean final, GSList *headers)
 
        pkt->opcode = opcode;
        pkt->final = final;
-       pkt->headers = headers;
-
+       pkt->headers = g_obex_header_create_list(first_hdr_id, args,
+                                                               &pkt->hlen);
        pkt->data_policy = G_OBEX_DATA_COPY;
 
        return pkt;
 }
 
+GObexPacket *g_obex_packet_new(guint8 opcode, gboolean final,
+                                               guint8 first_hdr_id, ...)
+{
+       GObexPacket *pkt;
+       va_list args;
+
+       va_start(args, first_hdr_id);
+       pkt = g_obex_packet_new_valist(opcode, final, first_hdr_id, args);
+       va_end(args);
+
+       return pkt;
+}
+
 void g_obex_packet_free(GObexPacket *pkt)
 {
        switch (pkt->data_policy) {
@@ -253,7 +267,7 @@ GObexPacket *g_obex_packet_decode(const void *data, gsize len,
        final = (opcode & FINAL_BIT) ? TRUE : FALSE;
        opcode &= ~FINAL_BIT;
 
-       pkt = g_obex_packet_new(opcode, final, NULL);
+       pkt = g_obex_packet_new(opcode, final, G_OBEX_HDR_ID_INVALID);
 
        if (header_offset == 0)
                goto headers;
index 669cabf..ea61d99 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef __GOBEX_PACKET_H
 #define __GOBEX_PACKET_H
 
+#include <stdarg.h>
 #include <glib.h>
 
 #include <gobex/gobex-defs.h>
@@ -90,7 +91,10 @@ gboolean g_obex_packet_add_body(GObexPacket *pkt, GObexDataProducer func,
 gboolean g_obex_packet_set_data(GObexPacket *pkt, const void *data, gsize len,
                                                GObexDataPolicy data_policy);
 const void *g_obex_packet_get_data(GObexPacket *pkt, gsize *len);
-GObexPacket *g_obex_packet_new(guint8 opcode, gboolean final, GSList *headers);
+GObexPacket *g_obex_packet_new(guint8 opcode, gboolean final,
+                                               guint8 first_hdr_id, ...);
+GObexPacket *g_obex_packet_new_valist(guint8 opcode, gboolean final,
+                                       guint8 first_hdr_id, va_list args);
 void g_obex_packet_free(GObexPacket *pkt);
 
 GObexPacket *g_obex_packet_decode(const void *data, gsize len,
index bdef980..75fa50e 100644 (file)
@@ -32,8 +32,6 @@ struct transfer {
 
        GObex *obex;
 
-       GSList *hdrs;
-
        guint req_id;
 
        gint put_id;
@@ -102,7 +100,7 @@ static gssize put_get_data(void *buf, gsize len, gpointer user_data)
        if (ret >= 0)
                return ret;
 
-       req = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, G_OBEX_HDR_ID_INVALID);
        transfer->req_id = g_obex_send_req(transfer->obex, req, -1,
                                                transfer_abort_response,
                                                transfer, &err);
@@ -161,7 +159,7 @@ static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp,
                return;
        }
 
-       req = g_obex_packet_new(transfer->opcode, TRUE, NULL);
+       req = g_obex_packet_new(transfer->opcode, TRUE, G_OBEX_HDR_ID_INVALID);
 
        if (transfer->opcode == G_OBEX_OP_PUT)
                g_obex_packet_add_body(req, put_get_data, transfer);
@@ -203,7 +201,7 @@ guint g_obex_put_req(GObex *obex, const char *type, const char *name,
        transfer = transfer_new(obex, G_OBEX_OP_PUT, complete_func, user_data);
        transfer->data_producer = data_func;
 
-       req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, G_OBEX_HDR_ID_INVALID);
 
        if (type) {
                hdr = g_obex_header_new_bytes(G_OBEX_HDR_ID_TYPE,
@@ -252,7 +250,7 @@ static void transfer_put_req(GObex *obex, GObexPacket *req, gpointer user_data)
                        transfer->data_consumer(buf, len, transfer->user_data);
        }
 
-       rsp = g_obex_packet_new(rspcode, TRUE, NULL);
+       rsp = g_obex_packet_new(rspcode, TRUE, G_OBEX_HDR_ID_INVALID);
        if (!g_obex_send(obex, rsp, &err)) {
                transfer_complete(transfer, err);
                g_error_free(err);
@@ -270,7 +268,8 @@ static void transfer_abort_req(GObex *obex, GObexPacket *req, gpointer user_data
 
        err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
                                                "Request was aborted");
-       rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE, NULL);
+       rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE,
+                                               G_OBEX_HDR_ID_INVALID);
        g_obex_send(obex, rsp, NULL);
 
        transfer_complete(transfer, err);
@@ -313,7 +312,7 @@ guint g_obex_get_req(GObex *obex, const char *type, const char *name,
        transfer = transfer_new(obex, G_OBEX_OP_GET, complete_func, user_data);
        transfer->data_consumer = data_func;
 
-       req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_ID_INVALID);
 
        if (type) {
                hdr = g_obex_header_new_bytes(G_OBEX_HDR_ID_TYPE,
@@ -352,7 +351,8 @@ static gssize get_get_data(void *buf, gsize len, gpointer user_data)
                return ret;
        }
 
-       req = g_obex_packet_new(G_OBEX_RSP_INTERNAL_SERVER_ERROR, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_RSP_INTERNAL_SERVER_ERROR, TRUE,
+                                                       G_OBEX_HDR_ID_INVALID);
        g_obex_send(transfer->obex, req, NULL);
 
        err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
@@ -363,14 +363,30 @@ static gssize get_get_data(void *buf, gsize len, gpointer user_data)
        return ret;
 }
 
+static void transfer_get_req_first(struct transfer *transfer,
+                                       guint8 first_hdr_id, va_list args)
+{
+       GError *err = NULL;
+       GObexPacket *rsp;
+
+       rsp = g_obex_packet_new_valist(G_OBEX_RSP_CONTINUE, TRUE,
+                                                       first_hdr_id, args);
+       g_obex_packet_add_body(rsp, get_get_data, transfer);
+
+       if (!g_obex_send(transfer->obex, rsp, &err)) {
+               transfer_complete(transfer, err);
+               g_error_free(err);
+       }
+}
+
 static void transfer_get_req(GObex *obex, GObexPacket *req, gpointer user_data)
 {
        struct transfer *transfer = user_data;
        GError *err = NULL;
        GObexPacket *rsp;
 
-       rsp = g_obex_packet_new(G_OBEX_RSP_CONTINUE, TRUE, transfer->hdrs);
-       transfer->hdrs = NULL;
+       rsp = g_obex_packet_new(G_OBEX_RSP_CONTINUE, TRUE,
+                                               G_OBEX_HDR_ID_INVALID);
        g_obex_packet_add_body(rsp, get_get_data, transfer);
 
        if (!g_obex_send(obex, rsp, &err)) {
@@ -379,18 +395,21 @@ static void transfer_get_req(GObex *obex, GObexPacket *req, gpointer user_data)
        }
 }
 
-guint g_obex_get_rsp(GObex *obex, GSList *hdrs, GObexDataProducer data_func,
+guint g_obex_get_rsp(GObex *obex, GObexDataProducer data_func,
                        GObexFunc complete_func, gpointer user_data,
-                       GError **err)
+                       GError **err, guint8 first_hdr_id, ...)
 {
        struct transfer *transfer;
+       va_list args;
        gint id;
 
        transfer = transfer_new(obex, G_OBEX_OP_GET, complete_func, user_data);
        transfer->data_producer = data_func;
-       transfer->hdrs = hdrs;
 
-       transfer_get_req(obex, NULL, transfer);
+       va_start(args, first_hdr_id);
+       transfer_get_req_first(transfer, first_hdr_id, args);
+       va_end(args);
+
        if (!g_slist_find(transfers, transfer))
                return 0;
 
index 21e14c8..2dff42e 100644 (file)
@@ -39,9 +39,9 @@ guint g_obex_put_rsp(GObex *obex, GObexPacket *req,
                        GObexDataConsumer data_func, GObexFunc complete_func,
                        gpointer user_data, GError **err);
 
-guint g_obex_get_rsp(GObex *obex, GSList *hdrs, GObexDataProducer data_func,
+guint g_obex_get_rsp(GObex *obex, GObexDataProducer data_func,
                        GObexFunc complete_func, gpointer user_data,
-                       GError **err);
+                       GError **err, guint8 first_hdr_id, ...);
 
 gboolean g_obex_cancel_transfer(guint id);
 
index 9ac5c95..b0d21ea 100644 (file)
@@ -422,7 +422,7 @@ static gboolean pending_req_abort(GObex *obex, GError **err)
 
        obex->pending_req->cancelled = TRUE;
 
-       pkt = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, NULL);
+       pkt = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, G_OBEX_HDR_ID_INVALID);
 
        return g_obex_send(obex, pkt, err);
 }
@@ -624,7 +624,8 @@ static void handle_request(GObex *obex, GObexPacket *req)
                return;
        }
 
-       rsp = g_obex_packet_new(G_OBEX_RSP_NOT_IMPLEMENTED, TRUE, NULL);
+       rsp = g_obex_packet_new(G_OBEX_RSP_NOT_IMPLEMENTED, TRUE,
+                                                       G_OBEX_HDR_ID_INVALID);
        g_obex_send(obex, rsp, NULL);
 }
 
@@ -913,7 +914,8 @@ guint g_obex_connect(GObex *obex, void *target, gsize target_len,
        GObexPacket *req;
        struct connect_data data;
 
-       req = g_obex_packet_new(G_OBEX_OP_CONNECT, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_CONNECT, TRUE,
+                                               G_OBEX_HDR_ID_INVALID);
 
        init_connect_data(obex, &data);
        g_obex_packet_set_data(req, &data, sizeof(data), G_OBEX_DATA_COPY);
@@ -934,7 +936,7 @@ guint g_obex_setpath(GObex *obex, const char *path, GObexResponseFunc func,
        GObexPacket *req;
        struct setpath_data data;
 
-       req = g_obex_packet_new(G_OBEX_OP_SETPATH, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_SETPATH, TRUE, G_OBEX_HDR_ID_INVALID);
 
        memset(&data, 0, sizeof(data));
 
@@ -959,7 +961,8 @@ guint g_obex_mkdir(GObex *obex, const char *path, GObexResponseFunc func,
        GObexHeader *hdr;
        struct setpath_data data;
 
-       req = g_obex_packet_new(G_OBEX_OP_SETPATH, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_SETPATH, TRUE,
+                                               G_OBEX_HDR_ID_INVALID);
 
        memset(&data, 0, sizeof(data));
        hdr = g_obex_header_new_unicode(G_OBEX_HDR_ID_NAME, path);
@@ -976,7 +979,7 @@ guint g_obex_delete(GObex *obex, const char *name, GObexResponseFunc func,
        GObexPacket *req;
        GObexHeader *hdr;
 
-       req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, G_OBEX_HDR_ID_INVALID);
 
        hdr = g_obex_header_new_unicode(G_OBEX_HDR_ID_NAME, name);
        g_obex_packet_add_header(req, hdr);
index 1432203..bfb6877 100644 (file)
@@ -116,7 +116,8 @@ static void handle_connect(GObex *obex, GObexPacket *req, gpointer user_data)
 
        g_print("connect\n");
 
-       rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE, NULL);
+       rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE,
+                                               G_OBEX_HDR_ID_INVALID);
        g_obex_send(obex, rsp, NULL);
 }
 
index aa9054d..d3e4825 100644 (file)
@@ -39,11 +39,21 @@ static uint8_t pkt_put[] = { G_OBEX_OP_PUT, 0x00, 0x03 };
 
 static uint8_t pkt_nval_len[] = { G_OBEX_OP_PUT, 0xab, 0xcd, 0x12 };
 
+static guint8 pkt_put_long[] = { G_OBEX_OP_PUT, 0x00, 0x32,
+       G_OBEX_HDR_ID_CONNECTION, 0x01, 0x02, 0x03, 0x04,
+       G_OBEX_HDR_ID_TYPE, 0x00, 0x0b,
+       'f', 'o', 'o', '/', 'b', 'a', 'r', '\0',
+       G_OBEX_HDR_ID_NAME, 0x00, 0x15,
+       0, 'f', 0, 'i', 0, 'l', 0, 'e', 0, '.', 0, 't', 0, 'x', 0, 't', 0, 0,
+       G_OBEX_HDR_ID_ACTION, 0xab,
+       G_OBEX_HDR_ID_BODY, 0x00, 0x08,
+       0, 1, 2, 3, 4 };
+
 static void test_pkt(void)
 {
        GObexPacket *pkt;
 
-       pkt = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, NULL);
+       pkt = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, G_OBEX_HDR_ID_INVALID);
 
        g_assert(pkt != NULL);
 
@@ -159,7 +169,7 @@ static void test_encode_on_demand(void)
        uint8_t buf[255];
        gssize len;
 
-       pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, NULL);
+       pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_ID_INVALID);
        g_obex_packet_add_body(pkt, get_body_data, NULL);
 
        len = g_obex_packet_encode(pkt, buf, sizeof(buf));
@@ -184,7 +194,7 @@ static void test_encode_on_demand_fail(void)
        uint8_t buf[255];
        gssize len;
 
-       pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, NULL);
+       pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_ID_INVALID);
        g_obex_packet_add_body(pkt, get_body_data_fail, NULL);
 
        len = g_obex_packet_encode(pkt, buf, sizeof(buf));
@@ -194,6 +204,30 @@ static void test_encode_on_demand_fail(void)
        g_obex_packet_free(pkt);
 }
 
+static void test_create_args(void)
+{
+       GObexPacket *pkt;
+       guint8 buf[255], body[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
+       gssize len;
+
+       pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE,
+                       G_OBEX_HDR_ID_CONNECTION, 0x01020304,
+                       G_OBEX_HDR_ID_TYPE, "foo/bar", strlen("foo/bar") + 1,
+                       G_OBEX_HDR_ID_NAME, "file.txt",
+                       G_OBEX_HDR_ID_ACTION, 0xab,
+                       G_OBEX_HDR_ID_BODY, body, sizeof(body),
+                       G_OBEX_HDR_ID_INVALID);
+
+       g_assert(pkt != NULL);
+
+       len = g_obex_packet_encode(pkt, buf, sizeof(buf));
+       g_assert(len > 0);
+
+       assert_memequal(pkt_put_long, sizeof(pkt_put_long), buf, len);
+
+       g_obex_packet_free(pkt);
+}
+
 int main(int argc, char *argv[])
 {
        g_test_init(&argc, &argv, NULL);
@@ -213,6 +247,8 @@ int main(int argc, char *argv[])
        g_test_add_func("/gobex/test_encode_on_demand_fail",
                                                test_encode_on_demand_fail);
 
+       g_test_add_func("/gobex/test_create_args", test_create_args);
+
        g_test_run();
 
        return 0;
index 68c6a51..cf391f0 100644 (file)
@@ -273,8 +273,8 @@ static void handle_get(GObex *obex, GObexPacket *req, gpointer user_data)
                return;
        }
 
-       id = g_obex_get_rsp(obex, NULL, provide_data, transfer_complete,
-                                                               d, &d->err);
+       id = g_obex_get_rsp(obex, provide_data, transfer_complete, d, &d->err,
+                                                       G_OBEX_HDR_ID_INVALID);
        if (id == 0)
                g_main_loop_quit(d->mainloop);
 }
index 6d14b51..ce40bf6 100644 (file)
@@ -252,7 +252,8 @@ static void send_connect(GObexResponseFunc rsp_func, GIOFunc send_rsp_func,
        GObexPacket *req;
        guint8 connect_data[] = { 0x10, 0x00, 0x10, 0x00 };
 
-       req = g_obex_packet_new(G_OBEX_OP_CONNECT, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_CONNECT, TRUE,
+                                               G_OBEX_HDR_ID_INVALID);
        g_assert(req != NULL);
 
        g_obex_packet_set_data(req, connect_data, sizeof(connect_data),
@@ -326,7 +327,7 @@ static void test_cancel_req_immediate(void)
 
        r.err = NULL;
 
-       req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, G_OBEX_HDR_ID_INVALID);
        r.id = g_obex_send_req(r.obex, req, -1, req_done, &r, &r.err);
        g_assert_no_error(r.err);
        g_assert(r.id != 0);
@@ -407,7 +408,7 @@ static void test_cancel_req_delay(int transport_type)
 
        r.err = NULL;
 
-       req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, G_OBEX_HDR_ID_INVALID);
        r.id = g_obex_send_req(r.obex, req, -1, req_done, &r, &r.err);
        g_assert_no_error(r.err);
        g_assert(r.id != 0);
@@ -502,7 +503,8 @@ static void test_send_connect(int transport_type)
        r.buf = pkt_connect_req;
        r.len = sizeof(pkt_connect_req);
 
-       req = g_obex_packet_new(G_OBEX_OP_CONNECT, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_CONNECT, TRUE,
+                                               G_OBEX_HDR_ID_INVALID);
        g_assert(req != NULL);
 
        g_obex_packet_set_data(req, connect_data, sizeof(connect_data),
@@ -565,7 +567,8 @@ static void test_recv_unexpected(void)
 
        g_obex_set_disconnect_function(obex, unexpected_disconn, &err);
 
-       req = g_obex_packet_new(G_OBEX_RSP_CONTINUE, TRUE, NULL);
+       req = g_obex_packet_new(G_OBEX_RSP_CONTINUE, TRUE,
+                                               G_OBEX_HDR_ID_INVALID);
        len = g_obex_packet_encode(req, buf, sizeof(buf));
        g_assert_cmpint(len, >=, 0);
 
@@ -618,7 +621,7 @@ static void test_send_on_demand(int transport_type, GObexDataProducer func)
        r.buf = pkt_put_body;
        r.len = sizeof(pkt_put_body);
 
-       req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, NULL);
+       req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_ID_INVALID);
        g_obex_packet_add_body(req, func, &r);
 
        g_obex_send(obex, req, &r.err);