Index: Makefile.am
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/Makefile.am,v
retrieving revision 1.59
diff --unified=5 -r1.59 Makefile.am
--- Makefile.am 1 Nov 2006 12:58:31 -0000 1.59
+++ Makefile.am 9 Nov 2006 01:11:23 -0000
@@ -23,11 +23,12 @@
dbus-hci.h dbus-hci.c dbus-common.c dbus-common.h \
dbus-error.c dbus-error.h dbus-manager.c dbus-manager.h \
dbus-adapter.c dbus-adapter.h \
dbus-device.c dbus-device.h dbus-service.c dbus-service.h \
dbus-security.c dbus-security.h dbus-test.c dbus-test.h \
- dbus-sdp.c dbus-sdp.h dbus-rfcomm.c dbus-rfcomm.h
+ dbus-sdp.c dbus-sdp.h dbus-rfcomm.c dbus-rfcomm.h \
+ sdp-xml.c sdp-xml.h
hcid_LDADD = @DBUS_LIBS@ @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a
passkey_agent_SOURCES = passkey-agent.c
Index: dbus-adapter.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-adapter.c,v
retrieving revision 1.135
diff --unified=5 -r1.135 dbus-adapter.c
--- dbus-adapter.c 7 Nov 2006 20:36:10 -0000 1.135
+++ dbus-adapter.c 9 Nov 2006 01:11:24 -0000
@@ -1059,28 +1059,17 @@
}
static DBusHandlerResult adapter_get_remote_svc(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- return get_remote_svc_rec(conn, msg, data);
+ return get_remote_svc_rec(conn, msg, data, SDP_FORMAT_BINARY);
}
static DBusHandlerResult adapter_get_remote_svc_xml(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- DBusMessage *reply;
- const char *result = ""
- "";
-
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &result,
- DBUS_TYPE_INVALID);
-
- return send_message_and_unref(conn, reply);
+ return get_remote_svc_rec(conn, msg, data, SDP_FORMAT_XML);
}
static DBusHandlerResult adapter_get_remote_svc_handles(DBusConnection *conn,
DBusMessage *msg,
void *data)
Index: dbus-sdp.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.c,v
retrieving revision 1.54
diff --unified=5 -r1.54 dbus-sdp.c
--- dbus-sdp.c 1 Nov 2006 12:58:31 -0000 1.54
+++ dbus-sdp.c 9 Nov 2006 01:11:25 -0000
@@ -55,10 +55,11 @@
#include "dbus-adapter.h"
#include "dbus-error.h"
#include "dbus-sdp.h"
#define MAX_IDENTIFIER_LEN 29 /* "XX:XX:XX:XX:XX:XX/0xYYYYYYYY\0" */
+#define DEFAULT_XML_BUFFER_SIZE 1024
struct service_provider {
char *owner; /* null for remote services or unique name if local */
char *prov; /* remote Bluetooth address that provides the service */
struct slist *lrec;
@@ -96,10 +97,37 @@
char *name;
uint16_t class;
char *info_name;
} sdp_service_t;
+typedef struct {
+ int size;
+ char *str;
+} string_t;
+
+static void append_and_grow_string(void *data, const char *str)
+{
+ string_t *string = (string_t *)data;
+ char *newbuf;
+
+ int oldlen = strlen(string->str);
+ int newlen = strlen(str);
+
+ if ((oldlen + newlen + 1) > string->size) {
+ newbuf = (char *) malloc(string->size * 2);
+ if (!newbuf)
+ return;
+
+ memcpy(newbuf, string->str, oldlen+1);
+ string->size *= 2;
+ free(string->str);
+ string->str = newbuf;
+ }
+
+ strcat(string->str, str);
+}
+
/* FIXME: move to a common file */
sdp_service_t sdp_service[] = {
{ "vcp", VIDEO_CONF_SVCLASS_ID, "Video Conference" },
{ "map", 0, NULL },
{ "pbap", PBAP_SVCLASS_ID, "Phone Book Access" },
@@ -608,10 +636,80 @@
send_message_and_unref(ctxt->conn, reply);
failed:
transaction_context_free(ctxt);
}
+static void remote_svc_rec_completed_xml_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata)
+{
+ struct transaction_context *ctxt = udata;
+ sdp_record_t *rec = NULL;
+ DBusMessage *reply;
+ const char *dst;
+ int scanned;
+ string_t result;
+
+ if (!ctxt)
+ return;
+
+ if (err == 0xffff) {
+ /* Check for protocol error or I/O error */
+ int sdp_err = sdp_get_error(ctxt->session);
+ if (sdp_err < 0) {
+ error("search failed: Invalid session!");
+ error_failed(ctxt->conn, ctxt->rq, EINVAL);
+ goto failed;
+ }
+
+ error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
+ error_failed(ctxt->conn, ctxt->rq, sdp_err);
+ goto failed;
+ }
+
+ if (type == SDP_ERROR_RSP) {
+ error_sdp_failed(ctxt->conn, ctxt->rq, err);
+ goto failed;
+ }
+
+ /* check response PDU ID */
+ if (type != SDP_SVC_ATTR_RSP) {
+ error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
+ error_failed(ctxt->conn, ctxt->rq, EPROTO);
+ goto failed;
+ }
+
+ dbus_message_get_args(ctxt->rq, NULL,
+ DBUS_TYPE_STRING, &dst,
+ DBUS_TYPE_INVALID);
+
+ reply = dbus_message_new_method_return(ctxt->rq);
+
+ result.str = 0;
+
+ rec = sdp_extract_pdu(rsp, &scanned);
+ if (rec == NULL) {
+ error("SVC REC is null");
+ goto done;
+ }
+
+ result.str = malloc(sizeof(char) * DEFAULT_XML_BUFFER_SIZE);
+ result.size = DEFAULT_XML_BUFFER_SIZE;
+
+ sdp_cache_append(NULL, dst, rec);
+
+ convert_sdp_record_to_xml(rec, &result, append_and_grow_string);
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_STRING, &result.str,
+ DBUS_TYPE_INVALID);
+
+done:
+ send_message_and_unref(ctxt->conn, reply);
+ free(result.str);
+failed:
+ transaction_context_free(ctxt);
+}
+
static void remote_svc_handles_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata)
{
struct transaction_context *ctxt = udata;
DBusMessage *reply;
DBusMessageIter iter, array_iter;
@@ -898,28 +996,65 @@
sdp_list_free(attrids, NULL);
return err;
}
-DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data)
+static int remote_svc_rec_conn_xml_cb(struct transaction_context *ctxt)
+{
+ sdp_list_t *attrids = NULL;
+ uint32_t range = 0x0000ffff;
+ const char *dst;
+ uint32_t handle;
+ int err = 0;
+
+ if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_xml_cb, ctxt) < 0) {
+ err = -EINVAL;
+ goto fail;
+ }
+
+ dbus_message_get_args(ctxt->rq, NULL,
+ DBUS_TYPE_STRING, &dst,
+ DBUS_TYPE_UINT32, &handle,
+ DBUS_TYPE_INVALID);
+
+ attrids = sdp_list_append(NULL, &range);
+ /* Create/send the search request and set the callback to indicate the request completion */
+ if (sdp_service_attr_async(ctxt->session, handle, SDP_ATTR_REQ_RANGE, attrids) < 0) {
+ err = -sdp_get_error(ctxt->session);
+ goto fail;
+ }
+
+fail:
+ if (attrids)
+ sdp_list_free(attrids, NULL);
+
+ return err;
+}
+
+DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data, sdp_format_t format)
{
struct adapter *adapter = data;
const char *dst;
uint32_t handle;
int err = 0;
+ connect_cb_t *cb;
if (!dbus_message_get_args(msg, NULL,
DBUS_TYPE_STRING, &dst,
DBUS_TYPE_UINT32, &handle,
DBUS_TYPE_INVALID))
return error_invalid_arguments(conn, msg);
if (find_pending_connect(dst))
return error_service_search_in_progress(conn, msg);
+ cb = remote_svc_rec_conn_cb;
+ if (format == SDP_FORMAT_XML)
+ cb = remote_svc_rec_conn_xml_cb;
+
if (!connect_request(conn, msg, adapter->dev_id,
- dst, remote_svc_rec_conn_cb, &err)) {
+ dst, cb, &err)) {
error("Search request failed: %s (%d)", strerror(err), err);
return error_failed(conn, msg, err);
}
return DBUS_HANDLER_RESULT_HANDLED;
Index: dbus-sdp.h
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.h,v
retrieving revision 1.1
diff --unified=5 -r1.1 dbus-sdp.h
--- dbus-sdp.h 30 Oct 2006 18:39:38 -0000 1.1
+++ dbus-sdp.h 9 Nov 2006 01:11:25 -0000
@@ -28,15 +28,20 @@
#include
#include
#define SDP_INTERFACE "org.bluez.SDP"
+typedef enum {
+ SDP_FORMAT_XML,
+ SDP_FORMAT_BINARY
+} sdp_format_t;
+
DBusHandlerResult handle_sdp_method(DBusConnection *conn, DBusMessage *msg, void *data);
DBusHandlerResult get_remote_svc_handles(DBusConnection *conn, DBusMessage *msg, void *data);
-DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data);
+DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data, sdp_format_t format);
uint16_t sdp_str2svclass(const char *str);
typedef void get_record_cb_t(sdp_record_t *rec, void *data, int err);
Index: service-record.dtd
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/service-record.dtd,v
retrieving revision 1.2
diff --unified=5 -r1.2 service-record.dtd
--- service-record.dtd 30 Oct 2006 14:11:16 -0000 1.2
+++ service-record.dtd 9 Nov 2006 01:11:25 -0000
@@ -1,16 +1,17 @@
-
+
-
+
-
+
+
@@ -29,10 +30,24 @@
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+