summaryrefslogtreecommitdiffstats
path: root/common/sdp-xml.c
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2006-11-10 17:59:14 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2006-11-10 17:59:14 +0000
commite1046e6b02c2eef72ad63f2a61949e1ca606f63f (patch)
tree9ca8d4936a0baa5df7d420289c1c34c18ef61264 /common/sdp-xml.c
parent326cf15e58c699fb2fb62181fcdd47339ec60c15 (diff)
Added raw service record to xml conversion functions
Diffstat (limited to 'common/sdp-xml.c')
-rw-r--r--common/sdp-xml.c400
1 files changed, 400 insertions, 0 deletions
diff --git a/common/sdp-xml.c b/common/sdp-xml.c
new file mode 100644
index 00000000..5c6dd877
--- /dev/null
+++ b/common/sdp-xml.c
@@ -0,0 +1,400 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 "sdp-xml.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <bluetooth/sdp_lib.h>
+#include <malloc.h>
+#include <limits.h>
+
+#define STRBUFSIZE 256
+#define MAXINDENT 64
+
+static void convert_raw_data_to_xml(sdp_data_t *value, int indent_level,
+ void *data,
+ void (*appender) (void *, const char *))
+{
+ int i, hex;
+ char buf[STRBUFSIZE];
+ char indent[MAXINDENT];
+ char next_indent[MAXINDENT];
+
+ if (!value)
+ return;
+
+ if (indent_level >= MAXINDENT)
+ indent_level = MAXINDENT - 2;
+
+ for (i = 0; i < indent_level; i++) {
+ indent[i] = '\t';
+ next_indent[i] = '\t';
+ }
+
+ indent[i] = '\0';
+ next_indent[i] = '\t';
+ next_indent[i + 1] = '\0';
+
+ buf[STRBUFSIZE - 1] = '\0';
+
+ switch (value->dtd) {
+ case SDP_DATA_NIL:
+ appender(data, indent);
+ appender(data, "<nil/>\n");
+ break;
+ case SDP_BOOL:
+ appender(data, indent);
+ appender(data, "<boolean value=\"");
+ appender(data, value->val.uint8 ? "true" : "false");
+ appender(data, "\" />\n");
+ break;
+ case SDP_UINT8:
+ appender(data, indent);
+ appender(data, "<uint8 value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "0x%02x", value->val.uint8);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_UINT16:
+ appender(data, indent);
+ appender(data, "<uint16 value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "0x%04x", value->val.uint16);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_UINT32:
+ appender(data, indent);
+ appender(data, "<uint32 value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "0x%08x", value->val.uint32);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_UINT64:
+ appender(data, indent);
+ appender(data, "<uint64 value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "0x%016jx", value->val.uint64);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_UINT128:
+ appender(data, indent);
+ appender(data, "<uint128 value=\"");
+
+ for (i = 0; i < 16; i++) {
+ sprintf(&buf[i * 2], "%02x",
+ (unsigned char) value->val.uint128.data[i]);
+ }
+
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_INT8:
+ appender(data, indent);
+ appender(data, "<int8 value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int8);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_INT16:
+ appender(data, indent);
+ appender(data, "<int16 value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int16);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_INT32:
+ appender(data, indent);
+ appender(data, "<int32 value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int32);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_INT64:
+ appender(data, indent);
+ appender(data, "<int64 value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "%jd", value->val.int64);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_INT128:
+ appender(data, indent);
+ appender(data, "<int128 value=\"");
+
+ for (i = 0; i < 16; i++) {
+ sprintf(&buf[i * 2], "%02x",
+ (unsigned char) value->val.int128.data[i]);
+ }
+ appender(data, buf);
+
+ appender(data, "\" />\n");
+ break;
+ case SDP_UUID16:
+ appender(data, indent);
+ appender(data, "<uuid value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "0x%04x",
+ value->val.uuid.value.uuid16);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_UUID32:
+ appender(data, indent);
+ appender(data, "<uuid value=\"");
+ snprintf(buf, STRBUFSIZE - 1, "0x%08x",
+ value->val.uuid.value.uuid32);
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_UUID128:
+ appender(data, indent);
+ appender(data, "<uuid value=\"");
+
+ snprintf(buf, STRBUFSIZE - 1,
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[0],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[1],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[2],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[3],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[4],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[5],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[6],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[7],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[8],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[9],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[10],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[11],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[12],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[13],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[14],
+ (unsigned char) value->val.uuid.value.
+ uuid128.data[15]);
+
+ appender(data, buf);
+ appender(data, "\" />\n");
+ break;
+ case SDP_TEXT_STR8:
+ case SDP_TEXT_STR16:
+ case SDP_TEXT_STR32:
+ {
+ hex = 0;
+
+ int num_chars_to_escape = 0;
+
+ for (i = 0; i < value->unitSize; i++) {
+ if (i == (value->unitSize - 1)
+ && value->val.str[i] == '\0')
+ break;
+ if (!isprint(value->val.str[i])) {
+ hex = 1;
+ break;
+ }
+
+ /* XML is evil, must do this... */
+ if ((value->val.str[i] == '<') ||
+ (value->val.str[i] == '>') ||
+ (value->val.str[i] == '"') ||
+ (value->val.str[i] == '&'))
+ num_chars_to_escape++;
+
+ }
+
+ appender(data, indent);
+
+ appender(data, "<text ");
+
+ char *strBuf = 0;
+
+ if (hex) {
+ appender(data, "encoding=\"hex\" ");
+ strBuf = (char *) malloc(sizeof(char)
+ * (value->unitSize * 2 + 1));
+
+ /* Unit Size seems to include the size for dtd
+ It is thus off by 1
+ This is safe for Normal strings, but not
+ hex encoded data */
+ for (i = 0; i < (value->unitSize-1); i++)
+ sprintf(&strBuf[i * sizeof (char) * 2],
+ "%02x",
+ (unsigned char) value->val.str[i]);
+
+ strBuf[value->unitSize * 2] = '\0';
+ }
+ else {
+ int j;
+ /* escape the XML disallowed chars */
+ strBuf = (char *)
+ malloc(sizeof(char) *
+ (value->unitSize + 1 + num_chars_to_escape * 4));
+ for (i = 0, j = 0; i < value->unitSize; i++) {
+ if (value->val.str[i] == '&') {
+ strBuf[j++] = '&';
+ strBuf[j++] = 'a';
+ strBuf[j++] = 'm';
+ strBuf[j++] = 'p';
+ }
+ else if (value->val.str[i] == '<') {
+ strBuf[j++] = '&';
+ strBuf[j++] = 'l';
+ strBuf[j++] = 't';
+ }
+ else if (value->val.str[i] == '>') {
+ strBuf[j++] = '&';
+ strBuf[j++] = 'g';
+ strBuf[j++] = 't';
+ }
+ else if (value->val.str[i] == '"') {
+ strBuf[j++] = '&';
+ strBuf[j++] = 'q';
+ strBuf[j++] = 'u';
+ strBuf[j++] = 'o';
+ strBuf[j++] = 't';
+ }
+ else {
+ strBuf[j++] = value->val.str[i];
+ }
+ }
+
+ strBuf[j] = '\0';
+ }
+
+ appender(data, "value=\"");
+ appender(data, strBuf);
+ appender(data, "\" />\n");
+ free(strBuf);
+ break;
+ }
+ case SDP_URL_STR8:
+ case SDP_URL_STR16:
+ case SDP_URL_STR32:
+ appender(data, indent);
+ appender(data, "<url value=\"");
+ appender(data, value->val.str);
+ appender(data, "\" />\n");
+ break;
+ case SDP_SEQ8:
+ case SDP_SEQ16:
+ case SDP_SEQ32:
+ appender(data, indent);
+ appender(data, "<sequence>\n");
+
+ convert_raw_data_to_xml(value->val.dataseq,
+ indent_level + 1, data,
+ appender);
+
+ appender(data, indent);
+ appender(data, "</sequence>\n");
+
+ break;
+ case SDP_ALT8:
+ case SDP_ALT16:
+ case SDP_ALT32:
+ appender(data, indent);
+
+ appender(data, "<alternate>\n");
+
+ convert_raw_data_to_xml(value->val.dataseq,
+ indent_level + 1, data,
+ appender);
+ appender(data, indent);
+
+ appender(data, "</alternate>\n");
+
+ break;
+ default:
+ break;
+ }
+
+ convert_raw_data_to_xml(value->next, indent_level, data,
+ appender);
+}
+
+struct conversion_data
+{
+ void *data;
+ void (*appender) (void *data, const char *);
+};
+
+static void convert_raw_attr_to_xml_func(void *val, void *data)
+{
+ struct conversion_data *cd = (struct conversion_data *) data;
+ sdp_data_t *value = (sdp_data_t *) val;
+ char buf[STRBUFSIZE];
+
+ buf[STRBUFSIZE - 1] = '\0';
+ snprintf(buf, STRBUFSIZE - 1, "\t<attribute id=\"0x%04x\">\n",
+ value->attrId);
+ cd->appender(cd->data, buf);
+
+ if (data)
+ convert_raw_data_to_xml(value, 2, cd->data,
+ cd->appender);
+ else
+ cd->appender(cd->data, "\t\tNULL\n");
+
+ cd->appender(cd->data, "\t</attribute>\n");
+}
+
+/*
+ Will convert the sdp record to XML. The appender and data can be used
+ to control where to output the record (e.g. file or a data buffer). The
+ appender will be called repeatedly with data and the character buffer
+ (containing parts of the generated XML) to append.
+*/
+void convert_sdp_record_to_xml(sdp_record_t *rec,
+ void *data,
+ void (*appender) (void *, const char *))
+{
+ struct conversion_data cd;
+
+ cd.data = data;
+ cd.appender = appender;
+
+ if (rec && rec->attrlist) {
+ appender(data, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n");
+ appender(data, "<record>\n");
+ sdp_list_foreach(rec->attrlist,
+ convert_raw_attr_to_xml_func, &cd);
+ appender(data, "</record>\n");
+ }
+}
+