[PATCH obexd 1/9] gobex: Introduce GObexApparam API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

GObexApparam abstract the handling of application parameter tags, it
can be used to read/parse application parameter header data using
g_obex_apparam_get_* functions or to generate the data using
g_obex_apparam_set_*.
---
 Makefile.am           |   3 +-
 gobex/gobex-apparam.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gobex/gobex-apparam.h |  59 ++++++++++
 3 files changed, 375 insertions(+), 1 deletion(-)
 create mode 100644 gobex/gobex-apparam.c
 create mode 100644 gobex/gobex-apparam.h

diff --git a/Makefile.am b/Makefile.am
index 97a1553..a1b4da0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,7 +20,8 @@ gobex_sources = gobex/gobex.h gobex/gobex.c \
 			gobex/gobex-defs.h gobex/gobex-defs.c \
 			gobex/gobex-packet.c gobex/gobex-packet.h \
 			gobex/gobex-header.c gobex/gobex-header.h \
-			gobex/gobex-transfer.c gobex/gobex-debug.h
+			gobex/gobex-transfer.c gobex/gobex-debug.h \
+			gobex/gobex-apparam.h gobex/gobex-apparam.c
 
 noinst_PROGRAMS =
 libexec_PROGRAMS =
diff --git a/gobex/gobex-apparam.c b/gobex/gobex-apparam.c
new file mode 100644
index 0000000..09bf034
--- /dev/null
+++ b/gobex/gobex-apparam.c
@@ -0,0 +1,314 @@
+/*
+ *
+ *  OBEX library with GLib integration
+ *
+ *  Copyright (C) 2012  Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "gobex-apparam.h"
+
+struct _GObexApparam {
+	GHashTable *tags;
+};
+
+struct apparam_tag {
+	guint8 id;
+	guint8 len;
+	union {
+		/* Data is stored in network order */
+		char string[0];
+		guint8 data[0];
+		guint8 u8;
+		guint16 u16;
+		guint32 u32;
+		guint64 u64;
+	} value;
+} __attribute__ ((packed));
+
+static struct apparam_tag *tag_new(guint8 id, guint8 len, const void *data)
+{
+	struct apparam_tag *tag;
+
+	tag = g_malloc0(2 + len);
+	tag->id = id;
+	tag->len = len;
+	memcpy(tag->value.data, data, len);
+
+	return tag;
+}
+
+static GObexApparam *g_obex_apparam_new(void)
+{
+	GObexApparam *apparam;
+
+	apparam = g_new0(GObexApparam, 1);
+	apparam->tags = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+							NULL, g_free);
+
+	return apparam;
+}
+
+static struct apparam_tag *apparam_tag_decode(const void *data, gsize size,
+							gsize *parsed)
+{
+	struct apparam_tag *tag;
+	const guint8 *ptr = data;
+	guint8 id;
+	guint8 len;
+
+	if (size < 2)
+		return NULL;
+
+	id = ptr[0];
+	len = ptr[1];
+
+	if (len > size - 2)
+		return NULL;
+
+	tag = tag_new(id, len, ptr + 2);
+	if (tag == NULL)
+		return NULL;
+
+	*parsed = 2 + tag->len;
+
+	return tag;
+}
+
+GObexApparam *g_obex_apparam_decode(const void *data, gsize size)
+{
+	GObexApparam *apparam;
+	GHashTable *tags;
+	gsize count = 0;
+
+	if (size < 2)
+		return NULL;
+
+	apparam = g_obex_apparam_new();
+
+	tags = apparam->tags;
+	while (count < size) {
+		struct apparam_tag *tag;
+		gsize parsed;
+
+		tag = apparam_tag_decode(data + count, size - count, &parsed);
+		if (tag == NULL)
+			break;
+
+		g_hash_table_insert(tags, GUINT_TO_POINTER(tag->id), tag);
+
+		count += parsed;
+	}
+
+	if (count != size) {
+		g_obex_apparam_free(apparam);
+		return NULL;
+	}
+
+	return apparam;
+}
+
+static gssize tag_encode(struct apparam_tag *tag, void *buf, gsize len)
+{
+	gsize count = 2 + tag->len;
+
+	if (len < count)
+		return -ENOBUFS;
+
+	memcpy(buf, tag, count);
+
+	return count;
+}
+
+gssize g_obex_apparam_encode(GObexApparam *apparam, void *buf, gsize len)
+{
+	gsize count = 0;
+	gssize ret;
+	GHashTableIter iter;
+	gpointer key, value;
+
+	g_hash_table_iter_init(&iter, apparam->tags);
+	while (g_hash_table_iter_next(&iter, &key, &value)) {
+		struct apparam_tag *tag = value;
+
+		ret = tag_encode(tag, buf + count, len - count);
+		if (ret < 0)
+			return ret;
+
+		count += ret;
+	}
+
+	return count;
+}
+
+GObexApparam *g_obex_apparam_set_bytes(GObexApparam *apparam, guint8 id,
+						const void *value, gsize len)
+{
+	struct apparam_tag *tag;
+
+	if (apparam == NULL)
+		apparam = g_obex_apparam_new();
+
+	tag = tag_new(id, len, value);
+	g_hash_table_replace(apparam->tags, GUINT_TO_POINTER(id), tag);
+
+	return apparam;
+}
+
+GObexApparam *g_obex_apparam_set_uint8(GObexApparam *apparam, guint8 id,
+							guint8 value)
+{
+	return g_obex_apparam_set_bytes(apparam, id, &value, 1);
+}
+
+GObexApparam *g_obex_apparam_set_uint16(GObexApparam *apparam, guint8 id,
+							guint16 value)
+{
+	guint16 num = g_htons(value);
+
+	return g_obex_apparam_set_bytes(apparam, id, &num, 2);
+}
+
+GObexApparam *g_obex_apparam_set_uint32(GObexApparam *apparam, guint8 id,
+							guint32 value)
+{
+	guint32 num = g_htonl(value);
+
+	return g_obex_apparam_set_bytes(apparam, id, &num, 4);
+}
+
+GObexApparam *g_obex_apparam_set_uint64(GObexApparam *apparam, guint8 id,
+							guint64 value)
+{
+	guint64 num = GUINT64_TO_BE(value);
+
+	return g_obex_apparam_set_bytes(apparam, id, &num, 8);
+}
+
+GObexApparam *g_obex_apparam_set_string(GObexApparam *apparam, guint8 id,
+							const char *value)
+{
+	gsize len;
+
+	len = strlen(value) + 1;
+	if (len > G_MAXUINT8) {
+		((char *) value)[G_MAXUINT8 - 1] = '\0';
+		len = G_MAXUINT8;
+	}
+
+	return g_obex_apparam_set_bytes(apparam, id, value, len);
+}
+
+gboolean g_obex_apparam_get_uint8(GObexApparam *apparam, guint8 id,
+							guint8 *dest)
+{
+	struct apparam_tag *tag;
+
+	tag = g_hash_table_lookup(apparam->tags, GUINT_TO_POINTER(id));
+	if (tag == NULL)
+		return FALSE;
+
+	*dest = tag->value.u8;
+	return TRUE;
+}
+
+gboolean g_obex_apparam_get_uint16(GObexApparam *apparam, guint8 id,
+							guint16 *dest)
+{
+	struct apparam_tag *tag;
+
+	tag = g_hash_table_lookup(apparam->tags, GUINT_TO_POINTER(id));
+	if (tag == NULL)
+		return FALSE;
+
+	if (tag->len < sizeof(*dest))
+		return FALSE;
+
+	*dest = g_ntohs(tag->value.u16);
+	return TRUE;
+}
+
+gboolean g_obex_apparam_get_uint32(GObexApparam *apparam, guint8 id,
+							guint32 *dest)
+{
+	struct apparam_tag *tag;
+
+	tag = g_hash_table_lookup(apparam->tags, GUINT_TO_POINTER(id));
+	if (tag == NULL)
+		return FALSE;
+
+	if (tag->len < sizeof(*dest))
+		return FALSE;
+
+	*dest = g_ntohl(tag->value.u32);
+	return TRUE;
+}
+
+gboolean g_obex_apparam_get_uint64(GObexApparam *apparam, guint8 id,
+							guint64 *dest)
+{
+	struct apparam_tag *tag;
+
+	tag = g_hash_table_lookup(apparam->tags, GUINT_TO_POINTER(id));
+	if (tag == NULL)
+		return FALSE;
+
+	if (tag->len < sizeof(*dest))
+		return FALSE;
+
+	*dest = GUINT64_FROM_BE(tag->value.u64);
+	return TRUE;
+}
+
+char *g_obex_apparam_get_string(GObexApparam *apparam, guint8 id)
+{
+	struct apparam_tag *tag;
+
+	tag = g_hash_table_lookup(apparam->tags, GUINT_TO_POINTER(id));
+	if (tag == NULL)
+		return NULL;
+
+	return g_strndup(tag->value.string, tag->len);
+}
+
+gboolean g_obex_apparam_get_bytes(GObexApparam *apparam, guint8 id,
+					const guint8 **val, gsize *len)
+{
+	struct apparam_tag *tag;
+
+	tag = g_hash_table_lookup(apparam->tags, GUINT_TO_POINTER(id));
+	if (tag == NULL)
+		return FALSE;
+
+	*len = tag->len;
+	*val = tag->value.data;
+
+	return TRUE;
+}
+
+void g_obex_apparam_free(GObexApparam *apparam)
+{
+	g_hash_table_unref(apparam->tags);
+	g_free(apparam);
+}
diff --git a/gobex/gobex-apparam.h b/gobex/gobex-apparam.h
new file mode 100644
index 0000000..46e20d2
--- /dev/null
+++ b/gobex/gobex-apparam.h
@@ -0,0 +1,59 @@
+/*
+ *
+ *  OBEX library with GLib integration
+ *
+ *  Copyright (C) 2012  Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __GOBEX_APPARAM_H
+#define __GOBEX_APPARAM_H
+
+#include <glib.h>
+
+typedef struct _GObexApparam GObexApparam;
+
+GObexApparam *g_obex_apparam_decode(const void *data, gsize size);
+gssize g_obex_apparam_encode(GObexApparam *apparam, void *buf, gsize size);
+
+GObexApparam *g_obex_apparam_set_bytes(GObexApparam *apparam, guint8 id,
+						const void *value, gsize size);
+GObexApparam *g_obex_apparam_set_uint8(GObexApparam *apparam, guint8 id,
+							guint8 value);
+GObexApparam *g_obex_apparam_set_uint16(GObexApparam *apparam, guint8 id,
+							guint16 value);
+GObexApparam *g_obex_apparam_set_uint32(GObexApparam *apparam, guint8 id,
+							guint32 value);
+GObexApparam *g_obex_apparam_set_uint64(GObexApparam *apparam, guint8 id,
+							guint64 value);
+GObexApparam *g_obex_apparam_set_string(GObexApparam *apparam, guint8 id,
+							const char *value);
+
+gboolean g_obex_apparam_get_bytes(GObexApparam *apparam, guint8 id,
+					const guint8 **val, gsize *len);
+gboolean g_obex_apparam_get_uint8(GObexApparam *apparam, guint8 id,
+							guint8 *value);
+gboolean g_obex_apparam_get_uint16(GObexApparam *apparam, guint8 id,
+							guint16 *value);
+gboolean g_obex_apparam_get_uint32(GObexApparam *apparam, guint8 id,
+							guint32 *value);
+gboolean g_obex_apparam_get_uint64(GObexApparam *apparam, guint8 id,
+							guint64 *value);
+char *g_obex_apparam_get_string(GObexApparam *apparam, guint8 id);
+
+void g_obex_apparam_free(GObexApparam *apparam);
+
+#endif /* __GOBEX_APPARAM_H */
-- 
1.7.11.2

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux