{
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;
+}
#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
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);
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;
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) {
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;
#ifndef __GOBEX_PACKET_H
#define __GOBEX_PACKET_H
+#include <stdarg.h>
#include <glib.h>
#include <gobex/gobex-defs.h>
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,
GObex *obex;
- GSList *hdrs;
-
guint req_id;
gint put_id;
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);
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);
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,
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);
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);
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,
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,
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)) {
}
}
-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;
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);
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);
}
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);
}
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);
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));
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);
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);
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);
}
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);
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));
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));
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);
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;
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);
}
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),
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);
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);
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),
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);
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);