aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2012-08-09 13:32:25 +0300
committerJohan Hedberg <johan.hedberg@intel.com>2012-08-16 12:34:00 +0300
commit79db04845e1602dff291d365345c270c7a7a235d (patch)
treee952f70e9c0f72719115c21edc627e749eddd33e
parentf1a2dd4fba4cd20c9230f4622b84c7da2c3864f6 (diff)
downloadobexd-79db04845e1602dff291d365345c270c7a7a235d.tar.gz
gobex: Introduce GObexApparam API
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_*.
-rw-r--r--Makefile.am3
-rw-r--r--gobex/gobex-apparam.c314
-rw-r--r--gobex/gobex-apparam.h59
3 files changed, 375 insertions, 1 deletions
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 */