summaryrefslogtreecommitdiff
path: root/gobex/gobex-packet.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2011-07-05 19:26:57 +0300
committerMarcel Holtmann <marcel@holtmann.org>2012-12-04 22:21:59 +0100
commit0a4824ddb1c8724a7032935c1e23d726666ac145 (patch)
treeed336007d49403ea29ff9101d8e92da4505811cd /gobex/gobex-packet.c
parent49514b2cc4e8cbb1a71b69c5f63fd59dc20bb46b (diff)
downloadbluez-0a4824ddb1c8724a7032935c1e23d726666ac145.tar.gz
gobex: Make on-demand body headers a GObexPacket feature
Diffstat (limited to 'gobex/gobex-packet.c')
-rw-r--r--gobex/gobex-packet.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/gobex/gobex-packet.c b/gobex/gobex-packet.c
index e5bf618ac..6051fc4c8 100644
--- a/gobex/gobex-packet.c
+++ b/gobex/gobex-packet.c
@@ -40,6 +40,9 @@ struct _GObexPacket {
gsize hlen; /* Length of all encoded headers */
GSList *headers;
+
+ GObexPacketDataFunc get_body;
+ gpointer get_body_data;
};
GObexHeader *g_obex_packet_get_header(GObexPacket *pkt, guint8 id)
@@ -94,6 +97,18 @@ gboolean g_obex_packet_add_header(GObexPacket *pkt, GObexHeader *header)
return TRUE;
}
+gboolean g_obex_packet_add_body(GObexPacket *pkt, GObexPacketDataFunc func,
+ gpointer user_data)
+{
+ if (pkt->get_body != NULL)
+ return FALSE;
+
+ pkt->get_body = func;
+ pkt->get_body_data = user_data;
+
+ return TRUE;
+}
+
const void *g_obex_packet_get_data(GObexPacket *pkt, gsize *len)
{
if (pkt->data_len == 0) {
@@ -257,8 +272,32 @@ failed:
return NULL;
}
+static gssize get_body(GObexPacket *pkt, guint8 *buf, gsize len)
+{
+ guint16 u16;
+ gssize ret;
+
+ if (len < 3)
+ return -ENOBUFS;
+
+ ret = pkt->get_body(pkt, buf + 3, len - 3, pkt->get_body_data);
+ if (ret < 0)
+ return ret;
+
+ if (ret > 0)
+ buf[0] = G_OBEX_HDR_ID_BODY;
+ else
+ buf[0] = G_OBEX_HDR_ID_BODY_END;
+
+ u16 = g_htons(ret + 3);
+ memcpy(&buf[1], &u16, sizeof(u16));
+
+ return ret;
+}
+
gssize g_obex_packet_encode(GObexPacket *pkt, guint8 *buf, gsize len)
{
+ gssize ret;
gsize count;
guint16 u16;
GSList *l;
@@ -281,7 +320,6 @@ gssize g_obex_packet_encode(GObexPacket *pkt, guint8 *buf, gsize len)
for (l = pkt->headers; l != NULL; l = g_slist_next(l)) {
GObexHeader *hdr = l->data;
- gssize ret;
if (count >= len)
return -ENOBUFS;
@@ -290,18 +328,18 @@ gssize g_obex_packet_encode(GObexPacket *pkt, guint8 *buf, gsize len)
if (ret < 0)
return ret;
- /* Fix-up on-demand body header type and final bit. This
- * breaks the layers of abstraction a bit but it's the
- * simplest way to avoid two consecutive empty packets */
- if (g_obex_header_get_id(hdr) == G_OBEX_HDR_ID_BODY &&
- ret == 3) {
- buf[0] |= FINAL_BIT;
- buf[count] = G_OBEX_HDR_ID_BODY_END;
- }
-
count += ret;
}
+ if (pkt->get_body) {
+ ret = get_body(pkt, buf + count, len - count);
+ if (ret < 0)
+ return ret;
+ if (ret == 0)
+ buf[0] |= FINAL_BIT;
+ count += ret + 3;
+ }
+
u16 = g_htons(count);
memcpy(&buf[1], &u16, sizeof(u16));