summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@indt.org.br>2008-07-03 17:21:46 -0300
committerLuiz Augusto von Dentz <luiz.dentz@indt.org.br>2008-07-28 10:33:07 -0300
commitc36942e998cd6187181df3033e53f1d624a5fd1a (patch)
tree63d19027d4dc0e779ede82eca74b0bcf80ecd881
parentc7b89988961e6c197c07fb1ba1f94bf27e457a51 (diff)
Remove dbus-sdp.c and dbus-sdp.h.
-rw-r--r--hcid/Makefile.am2
-rw-r--r--hcid/adapter.c1
-rw-r--r--hcid/dbus-common.c1
-rw-r--r--hcid/dbus-sdp.c1125
-rw-r--r--hcid/dbus-sdp.h42
-rw-r--r--hcid/device.c37
6 files changed, 37 insertions, 1171 deletions
diff --git a/hcid/Makefile.am b/hcid/Makefile.am
index d24c06af..9fdf75e5 100644
--- a/hcid/Makefile.am
+++ b/hcid/Makefile.am
@@ -21,7 +21,7 @@ libhciserver_a_SOURCES = hcid.h security.c storage.c \
adapter.h adapter.c device.h device.c plugin.h plugin.c \
dbus-common.c dbus-common.h dbus-error.c dbus-error.h \
dbus-database.c dbus-database.h dbus-service.c dbus-service.h \
- dbus-hci.h dbus-hci.c dbus-sdp.c dbus-sdp.h \
+ dbus-hci.h dbus-hci.c \
telephony.h telephony.c agent.h agent.c
sbin_PROGRAMS = hcid
diff --git a/hcid/adapter.c b/hcid/adapter.c
index 6a7a1700..6658f31a 100644
--- a/hcid/adapter.c
+++ b/hcid/adapter.c
@@ -57,7 +57,6 @@
#include "oui.h"
#include "dbus-common.h"
#include "dbus-hci.h"
-#include "dbus-sdp.h"
#include "dbus-database.h"
#include "dbus-error.h"
#include "error.h"
diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c
index eae6d3c5..a2b25588 100644
--- a/hcid/dbus-common.c
+++ b/hcid/dbus-common.c
@@ -49,7 +49,6 @@
#include "adapter.h"
#include "dbus-hci.h"
#include "dbus-database.h"
-#include "dbus-sdp.h"
#include "dbus-common.h"
#define BLUEZ_NAME "org.bluez"
diff --git a/hcid/dbus-sdp.c b/hcid/dbus-sdp.c
deleted file mode 100644
index 02f9e31c..00000000
--- a/hcid/dbus-sdp.c
+++ /dev/null
@@ -1,1125 +0,0 @@
-/*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2006-2007 Nokia Corporation
- * Copyright (C) 2004-2008 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 <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-#include <bluetooth/l2cap.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
-#include <netinet/in.h>
-
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <gdbus.h>
-
-#include "hcid.h"
-#include "textfile.h"
-#include "adapter.h"
-#include "dbus-hci.h"
-#include "dbus-common.h"
-#include "dbus-error.h"
-#include "error.h"
-#include "dbus-sdp.h"
-#include "sdp-xml.h"
-#include "glib-helper.h"
-
-#define SESSION_TIMEOUT 2000
-#define DEFAULT_XML_BUF_SIZE 1024
-
-struct transaction_context {
- char *src;
- char *dst;
- DBusConnection *conn;
- DBusMessage *rq;
- sdp_session_t *session;
- GIOChannel *io;
- guint io_id;
- uuid_t uuid;
- GSList *identifiers;
-};
-
-typedef int connect_cb_t(struct transaction_context *t);
-
-struct pending_connect {
- DBusConnection *conn;
- DBusMessage *rq;
- char *src;
- char *dst;
- sdp_session_t *session;
- connect_cb_t *conn_cb;
-};
-
-struct cached_session {
- sdp_session_t *session;
- guint timeout_id;
- guint io_id;
-};
-
-static GSList *cached_sessions = NULL;
-
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
-}
-
-static inline DBusMessage *in_progress(DBusMessage *msg, const char *str)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", str);
-}
-
-static inline DBusMessage *adapter_not_ready(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
- "Adapter is not ready");
-}
-
-static inline DBusMessage *failed_strerror(DBusMessage *msg, int err)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- strerror(err));
-}
-
-static gboolean session_timeout(gpointer user_data)
-{
- struct cached_session *s = user_data;
-
- debug("sdp session timed out. closing");
-
- cached_sessions = g_slist_remove(cached_sessions, s);
-
- g_source_remove(s->io_id);
- sdp_close(s->session);
- g_free(s);
-
- return FALSE;
-}
-
-gboolean idle_callback(GIOChannel *io, GIOCondition cond, gpointer user_data)
-{
- struct cached_session *s = user_data;
-
- if (cond & G_IO_NVAL)
- return FALSE;
-
- if (cond & (G_IO_ERR | G_IO_HUP))
- debug("idle_callback: session got disconnected");
-
- if (cond & G_IO_IN)
- debug("got unexpected input on idle SDP socket");
-
- cached_sessions = g_slist_remove(cached_sessions, s);
-
- g_source_remove(s->timeout_id);
- sdp_close(s->session);
- g_free(s);
-
- return FALSE;
-}
-
-static void cache_sdp_session(sdp_session_t *sess, GIOChannel *io)
-{
- struct cached_session *s;
-
- s = g_new0(struct cached_session, 1);
-
- s->session = sess;
- s->timeout_id = g_timeout_add(SESSION_TIMEOUT, session_timeout, s);
- s->io_id = g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- idle_callback, s);
-
- cached_sessions = g_slist_append(cached_sessions, s);
-
- debug("sdp session added to cache");
-}
-
-static int get_bdaddrs(int sock, bdaddr_t *sba, bdaddr_t *dba)
-{
- struct sockaddr_l2 a;
- socklen_t len;
-
- len = sizeof(a);
- if (getsockname(sock, (struct sockaddr *) &a, &len) < 0) {
- error("getsockname: %s (%d)", strerror(errno), errno);
- return -1;
- }
-
- bacpy(sba, &a.l2_bdaddr);
-
- len = sizeof(a);
- if (getpeername(sock, (struct sockaddr *) &a, &len) < 0) {
- error("getpeername: %s (%d)", strerror(errno), errno);
- return -1;
- }
-
- bacpy(dba, &a.l2_bdaddr);
-
- return 0;
-}
-
-static struct cached_session *get_cached_session(bdaddr_t *src, bdaddr_t *dst)
-{
- GSList *l;
-
- for (l = cached_sessions; l != NULL; l = l->next) {
- struct cached_session *s = l->data;
- int sock = sdp_get_socket(s->session);
- bdaddr_t sba, dba;
-
- if (get_bdaddrs(sock, &sba, &dba) < 0)
- continue;
-
- if (bacmp(&sba, src) || bacmp(&dba, dst))
- continue;
-
- debug("found matching session, removing from list");
-
- cached_sessions = g_slist_remove(cached_sessions, s);
-
- return s;
- }
-
- return NULL;
-}
-
-static sdp_session_t *get_sdp_session(bdaddr_t *src, bdaddr_t *dst)
-{
- struct cached_session *s;
- sdp_session_t *session;
-
- s = get_cached_session(src, dst);
- if (!s) {
- debug("no matching session found. creating a new one");
- return sdp_connect(src, dst, SDP_NON_BLOCKING);
- }
-
- session = s->session;
-
- g_source_remove(s->timeout_id);
- g_source_remove(s->io_id);
- g_free(s);
-
- return session;
-}
-
-void append_and_grow_string(void *data, const char *str)
-{
- sdp_buf_t *buff = data;
- int len;
-
- len = strlen(str);
-
- if (!buff->data) {
- buff->data = malloc(DEFAULT_XML_BUF_SIZE);
- if (!buff->data)
- return;
- buff->buf_size = DEFAULT_XML_BUF_SIZE;
- }
-
- /* Grow string */
- while (buff->buf_size < (buff->data_size + len + 1)) {
- void *tmp;
- uint32_t new_size;
-
- /* Grow buffer by a factor of 2 */
- new_size = (buff->buf_size << 1);
-
- tmp = realloc(buff->data, new_size);
- if (!tmp)
- return;
-
- buff->data = tmp;
- buff->buf_size = new_size;
- }
-
- /* Include the NULL character */
- memcpy(buff->data + buff->data_size, str, len + 1);
- buff->data_size += len;
-}
-
-/* list of remote and local service records */
-static GSList *pending_connects = NULL;
-
-static struct pending_connect *pending_connect_new(DBusConnection *conn,
- DBusMessage *msg, const char *src,
- const char *dst, connect_cb_t *cb)
-{
- struct pending_connect *c;
-
- if (!dst)
- return NULL;
-
- c = g_new0(struct pending_connect, 1);
- c->src = g_strdup(src);
- c->dst = g_strdup(dst);
- c->conn = dbus_connection_ref(conn);
- c->rq = dbus_message_ref(msg);
- c->conn_cb = cb;
-
- return c;
-}
-
-static void pending_connect_free(struct pending_connect *c)
-{
- if (!c)
- return;
-
- g_free(c->src);
- g_free(c->dst);
-
- if (c->rq)
- dbus_message_unref(c->rq);
-
- if (c->conn)
- dbus_connection_unref(c->conn);
-
- g_free(c);
-}
-
-static struct pending_connect *find_pending_connect(const char *dst)
-{
- GSList *l;
-
- for (l = pending_connects; l != NULL; l = l->next) {
- struct pending_connect *pending = l->data;
- if (!strcmp(dst, pending->dst))
- return pending;
- }
-
- return NULL;
-}
-
-static int sdp_store_record(const char *src, const char *dst, uint32_t handle, uint8_t *buf, size_t size)
-{
- char filename[PATH_MAX + 1], key[28], *value;
- int i, err;
-
- create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");
-
- create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
- snprintf(key, sizeof(key), "%17s#%08X", dst, handle);
-
- value = g_malloc0(size * 2 + 1);
-
- for (i = 0; i < size; i++)
- sprintf(value + (i * 2), "%02X", buf[i]);
-
- err = textfile_put(filename, key, value);
-
- g_free(value);
-
- return err;
-}
-
-static void transaction_context_free(void *udata, gboolean cache)
-{
- struct transaction_context *ctxt = udata;
-
- if (!ctxt)
- return;
-
- g_free(ctxt->src);
- g_free(ctxt->dst);
-
- if (ctxt->conn)
- dbus_connection_unref(ctxt->conn);
-
- if (ctxt->rq)
- dbus_message_unref(ctxt->rq);
-
- if (ctxt->session && !ctxt->io)
- sdp_close(ctxt->session);
-
- if (ctxt->session && ctxt->io) {
- g_source_remove(ctxt->io_id);
-
- if (cache)
- cache_sdp_session(ctxt->session, ctxt->io);
- else
- sdp_close(ctxt->session);
-
- g_io_channel_unref(ctxt->io);
- }
-
- if (ctxt->identifiers) {
- g_slist_foreach(ctxt->identifiers, (GFunc) g_free, NULL);
- g_slist_free(ctxt->identifiers);
- }
-
- g_free(ctxt);
-}
-
-static gboolean search_process_cb(GIOChannel *chan,
- GIOCondition cond, void *udata)
-{
- struct transaction_context *ctxt = udata;
- int err = 0;
-
- if (cond & G_IO_NVAL) {
- g_io_channel_unref(chan);
- return FALSE;
- }
-
- if (cond & (G_IO_ERR | G_IO_HUP)) {
- err = EIO;
- goto failed;
- }
-
- if (sdp_process(ctxt->session) < 0)
- goto failed;
-
- return TRUE;
-
-failed:
- if (err) {
- error_failed_errno(ctxt->conn, ctxt->rq, err);
- transaction_context_free(ctxt, FALSE);
- }
-
- return TRUE;
-}
-
-static void remote_svc_rec_completed_cb(uint8_t type, uint16_t err,
- uint8_t *rsp, size_t size, void *udata)
-{
- struct transaction_context *ctxt = udata;
- sdp_record_t *rec;
- DBusMessage *reply;
- DBusMessageIter iter, array_iter;
- int scanned;
-
- 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_errno(ctxt->conn, ctxt->rq, EINVAL);
- goto failed;
- }
-
- error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
- error_failed_errno(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_errno(ctxt->conn, ctxt->rq, EPROTO);
- goto failed;
- }
-
- reply = dbus_message_new_method_return(ctxt->rq);
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING, &array_iter);
-
- rec = sdp_extract_pdu_safe(rsp, size, &scanned);
- if (rec == NULL || size != scanned) {
- error("Invalid service record!");
- goto done;
- }
-
- sdp_store_record(ctxt->src, ctxt->dst, rec->handle, rsp, size);
-
- sdp_record_free(rec);
-
- dbus_message_iter_append_fixed_array(&array_iter,
- DBUS_TYPE_BYTE, &rsp, size);
-
-done:
- dbus_message_iter_close_container(&iter, &array_iter);
- dbus_connection_send(ctxt->conn, reply, NULL);
- dbus_message_unref(reply);
-
-failed:
- transaction_context_free(ctxt, TRUE);
-}
-
-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;
- DBusMessage *reply;
- int scanned;
- sdp_buf_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_errno(ctxt->conn, ctxt->rq, EINVAL);
- goto failed;
- }
-
- error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
- error_failed_errno(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_errno(ctxt->conn, ctxt->rq, EPROTO);
- goto failed;
- }
-
- reply = dbus_message_new_method_return(ctxt->rq);
-
- rec = sdp_extract_pdu_safe(rsp, size, &scanned);
- if (rec == NULL || size != scanned) {
- error("Invalid service record!");
- goto done;
- }
-
- sdp_store_record(ctxt->src, ctxt->dst, rec->handle, rsp, size);
-
- memset(&result, 0, sizeof(sdp_buf_t));
-
- convert_sdp_record_to_xml(rec, &result, append_and_grow_string);
-
- sdp_record_free(rec);
-
- if (result.data) {
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &result.data,
- DBUS_TYPE_INVALID);
-
- free(result.data);
- }
-done:
- dbus_connection_send(ctxt->conn, reply, NULL);
- dbus_message_unref(reply);
-
-failed:
- transaction_context_free(ctxt, TRUE);
-}
-
-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;
- uint8_t *pdata;
- int csrc, tsrc;
-
- 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_errno(ctxt->conn, ctxt->rq, EINVAL);
- goto failed;
- }
-
- error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
- error_failed_errno(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_SEARCH_RSP) {
- error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
- error_failed_errno(ctxt->conn, ctxt->rq, EPROTO);
- goto failed;
- }
-
- reply = dbus_message_new_method_return(ctxt->rq);
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_UINT32_AS_STRING, &array_iter);
-
- pdata = rsp;
-
- tsrc = ntohs(bt_get_unaligned((uint16_t *) pdata));
- if (tsrc <= 0)
- goto done;
-
- pdata += sizeof(uint16_t);
-
- csrc = ntohs(bt_get_unaligned((uint16_t *) pdata));
- if (csrc <= 0)
- goto done;
-
- pdata += sizeof(uint16_t);
-
- do {
- uint32_t handle = ntohl(bt_get_unaligned((uint32_t*)pdata));
- pdata += sizeof(uint32_t);
-
- dbus_message_iter_append_basic(&array_iter,
- DBUS_TYPE_UINT32, &handle);
- } while (--tsrc);
-
-
-done:
- dbus_message_iter_close_container(&iter, &array_iter);
- dbus_connection_send(ctxt->conn, reply, NULL);
- dbus_message_unref(reply);
-
-failed:
- transaction_context_free(ctxt, TRUE);
-}
-
-static const char *extract_service_class(sdp_data_t *d)
-{
- sdp_data_t *seq;
- uuid_t *uuid;
- static char uuid_str[37];
-
- /* Expected sequence of UUID16 */
- if (d->attrId != SDP_ATTR_SVCLASS_ID_LIST)
- return NULL;
-
- if (d->dtd != SDP_SEQ8 && d->dtd != SDP_SEQ16 && d->dtd != SDP_SEQ32)
- return NULL;
-
- if (!d->val.dataseq)
- return NULL;
-
- seq = d->val.dataseq;
- if (!SDP_IS_UUID(seq->dtd))
- return NULL;
-
- uuid = &seq->val.uuid;
- if (uuid->type != SDP_UUID16)
- return NULL;
-
- sprintf(uuid_str, "0000%04x-0000-1000-8000-00805f9b34fb",
- uuid->value.uuid16);
-
- return uuid_str;
-}
-
-static int service_search_attr(struct transaction_context *ctxt, uint16_t uuid)
-{
- sdp_list_t *attrids, *search;
- uint32_t range = 0x0000ffff;
- int ret = 0;
-
- sdp_uuid16_create(&ctxt->uuid, uuid);
-
- search = sdp_list_append(0, &ctxt->uuid);
- attrids = sdp_list_append(NULL, &range);
-
- /*
- * Create/send the search request and set the
- * callback to indicate the request completion
- */
- if (sdp_service_search_attr_async(ctxt->session, search,
- SDP_ATTR_REQ_RANGE, attrids) < 0)
- ret = -sdp_get_error(ctxt->session);
-
- sdp_list_free(search, NULL);
- sdp_list_free(attrids, NULL);
-
- return ret;
-}
-
-static void remote_svc_identifiers_completed_cb(uint8_t type, uint16_t err,
- uint8_t *rsp, size_t size, void *udata)
-{
- struct transaction_context *ctxt = udata;
- const char *puuid;
- const char *devid_uuid = "00001200-0000-1000-8000-00805f9b34fb";
- char **identifiers;
- DBusMessage *reply;
- GSList *l = NULL;
- int scanned, extracted = 0, len = 0, recsize = 0, bytesleft = size;
- uint8_t dtd = 0;
-
- 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_errno(ctxt->conn, ctxt->rq, EINVAL);
- goto failed;
- }
-
- error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
- error_failed_errno(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_SEARCH_ATTR_RSP) {
- error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
- error_failed_errno(ctxt->conn, ctxt->rq, EPROTO);
- goto failed;
- }
-
- scanned = sdp_extract_seqtype_safe(rsp, bytesleft, &dtd, &len);
- rsp += scanned;
- bytesleft -= scanned;
- for (; extracted < len; rsp += recsize, extracted += recsize, bytesleft -= recsize) {
- sdp_record_t *rec;
- sdp_data_t *d;
-
- recsize = 0;
- rec = sdp_extract_pdu_safe(rsp, bytesleft, &recsize);
- if (!rec)
- break;
-
- sdp_store_record(ctxt->src, ctxt->dst, rec->handle, rsp, recsize);
-
- d = sdp_data_get(rec, SDP_ATTR_SVCLASS_ID_LIST);
- if (!d) {
- sdp_record_free(rec);
- continue;
- }
-
- puuid = extract_service_class(d);
- sdp_record_free(rec);
- if (!puuid)
- continue;
-
- /* Ignore repeated identifiers */
- l = g_slist_find_custom(ctxt->identifiers,
- puuid, (GCompareFunc) strcmp);
- if (l)
- continue;
-
- ctxt->identifiers = g_slist_append(ctxt->identifiers,
- g_strdup(puuid));
- }
-
- /* If public browse response is empty: search for L2CAP */
- if (!ctxt->identifiers && ctxt->uuid.value.uuid16 == PUBLIC_BROWSE_GROUP)
- if (service_search_attr(ctxt, L2CAP_UUID) == 0)
- return; /* Wait the response */
-
- /* Request DeviceID if it was not returned previously */
- l = g_slist_find_custom(ctxt->identifiers,
- devid_uuid, (GCompareFunc) strcmp);
- if (!l && ctxt->uuid.value.uuid16 != PNP_INFO_SVCLASS_ID)
- if (service_search_attr(ctxt, PNP_INFO_SVCLASS_ID) == 0)
- return; /* Wait the response */
-
- reply = dbus_message_new_method_return(ctxt->rq);
-
- identifiers = g_new(char *, g_slist_length(ctxt->identifiers));
-
- for (l = ctxt->identifiers, len = 0; l; l = l->next, len++)
- identifiers[len] = l->data;
-
- dbus_message_append_args(reply,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
- &identifiers, len,
- DBUS_TYPE_INVALID);
-
- dbus_connection_send(ctxt->conn, reply, NULL);
- dbus_message_unref(reply);
-
- if (len)
- g_dbus_emit_signal(ctxt->conn,
- dbus_message_get_path(ctxt->rq),
- ADAPTER_INTERFACE,
- "RemoteIdentifiersUpdated",
- DBUS_TYPE_STRING, &ctxt->dst,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
- &identifiers, len,
- DBUS_TYPE_INVALID);
-
- if (identifiers)
- g_free(identifiers);
-
-failed:
- transaction_context_free(ctxt, TRUE);
-}
-
-static gboolean sdp_client_connect_cb(GIOChannel *chan,
- GIOCondition cond, void *udata)
-{
- struct pending_connect *c = udata;
- struct transaction_context *ctxt = NULL;
- int sdp_err, err = 0, sk;
- socklen_t len;
-
- sk = g_io_channel_unix_get_fd(chan);
-
- len = sizeof(err);
- if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
- error("getsockopt(): %s (%d)", strerror(errno), errno);
- err = errno;
- goto failed;
- }
- if (err != 0) {
- error("connect(): %s (%d)", strerror(err), err);
- goto failed;
- }
-
- ctxt = g_new0(struct transaction_context, 1);
- ctxt->src = g_strdup(c->src);
- ctxt->dst = g_strdup(c->dst);
- ctxt->conn = dbus_connection_ref(c->conn);
- ctxt->rq = dbus_message_ref(c->rq);
- ctxt->session = c->session;
-
- /* set the complete transaction callback and send the search request */
- sdp_err = c->conn_cb(ctxt);
- if (sdp_err < 0) {
- err = -sdp_err;
- error("search failed: %s (%d)", strerror(err), err);
- goto failed;
- }
-
- /* set the callback responsible for update the transaction data */
- ctxt->io_id = g_io_add_watch(chan,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- search_process_cb, ctxt);
- ctxt->io = g_io_channel_ref(chan);
-
- goto done;
-
-failed:
- error_connection_attempt_failed(c->conn, c->rq, err);
-
- if (ctxt)
- transaction_context_free(ctxt, FALSE);
- else
- sdp_close(c->session);
-
-done:
- pending_connects = g_slist_remove(pending_connects, c);
- pending_connect_free(c);
-
- return FALSE;
-}
-
-static struct pending_connect *connect_request(DBusConnection *conn,
- DBusMessage *msg,
- const char *src,
- const char *dst,
- connect_cb_t *cb, int *err)
-{
- struct pending_connect *c;
- bdaddr_t srcba, dstba;
- GIOChannel *chan;
-
- c = pending_connect_new(conn, msg, src, dst, cb);
- if (!c) {
- if (err)
- *err = ENOMEM;
- return NULL;
- }
-
- str2ba(src, &srcba);
- str2ba(dst, &dstba);
- c->session = get_sdp_session(&srcba, &dstba);
- if (!c->session) {
- if (err)
- *err = errno;
- error("sdp_connect() failed: %s (%d)", strerror(errno), errno);
- pending_connect_free(c);
- return NULL;
- }
-
- chan = g_io_channel_unix_new(sdp_get_socket(c->session));
- g_io_add_watch(chan, G_IO_OUT, sdp_client_connect_cb, c);
- g_io_channel_unref(chan);
- pending_connects = g_slist_append(pending_connects, c);
-
- return c;
-}
-
-static int remote_svc_rec_conn_cb(struct transaction_context *ctxt)
-{
- sdp_list_t *attrids;
- uint32_t range = 0x0000ffff;
- const char *dst;
- uint32_t handle;
-
- if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_cb, ctxt) < 0)
- return -EINVAL;
-
- 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) {
- sdp_list_free(attrids, NULL);
- return -sdp_get_error(ctxt->session);
- }
-
- sdp_list_free(attrids, NULL);
-
- return 0;
-}
-
-static int remote_svc_rec_conn_xml_cb(struct transaction_context *ctxt)
-{
- sdp_list_t *attrids;
- uint32_t range = 0x0000ffff;
- const char *dst;
- uint32_t handle;
-
- if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_xml_cb, ctxt) < 0)
- return -EINVAL;
-
- 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) {
- sdp_list_free(attrids, NULL);
- return -sdp_get_error(ctxt->session);
- }
-
- sdp_list_free(attrids, NULL);
-
- return 0;
-}
-
-DBusMessage *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;
- connect_cb_t *cb;
-
- if (!adapter->up)
- return adapter_not_ready(msg);
-
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &dst,
- DBUS_TYPE_UINT32, &handle,
- DBUS_TYPE_INVALID))
- return invalid_args(msg);
-
- if (find_pending_connect(dst))
- return in_progress(msg, "Service search in progress");
-
- cb = remote_svc_rec_conn_cb;
- if (format == SDP_FORMAT_XML)
- cb = remote_svc_rec_conn_xml_cb;
-
- if (!connect_request(conn, msg, adapter->address,
- dst, cb, &err)) {
- error("Search request failed: %s (%d)", strerror(err), err);
- return failed_strerror(msg, err);
- }
-
- return NULL;
-}
-
-static int remote_svc_handles_conn_cb(struct transaction_context *ctxt)
-{
- sdp_list_t *search = NULL;
- const char *dst, *svc;
-
- if (sdp_set_notify(ctxt->session, remote_svc_handles_completed_cb, ctxt) < 0)
- return -EINVAL;
-
- dbus_message_get_args(ctxt->rq, NULL,
- DBUS_TYPE_STRING, &dst,
- DBUS_TYPE_STRING, &svc,
- DBUS_TYPE_INVALID);
-
- if (strlen(svc) > 0)
- bt_string2uuid(&ctxt->uuid, svc);
- else
- sdp_uuid16_create(&ctxt->uuid, PUBLIC_BROWSE_GROUP);
-
- search = sdp_list_append(0, &ctxt->uuid);
-
- /* Create/send the search request and set the callback to indicate the request completion */
- if (sdp_service_search_async(ctxt->session, search, 64) < 0) {
- error("send request failed: %s (%d)", strerror(errno), errno);
- sdp_list_free(search, NULL);
- return -sdp_get_error(ctxt->session);
- }
-
- sdp_list_free(search, NULL);
-
- return 0;
-}
-
-static int remote_svc_identifiers_conn_cb(struct transaction_context *ctxt)
-{
- if (sdp_set_notify(ctxt->session,
- remote_svc_identifiers_completed_cb, ctxt) < 0)
- return -EINVAL;
-
- return service_search_attr(ctxt, PUBLIC_BROWSE_GROUP);
-}
-
-DBusMessage *get_remote_svc_handles(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct adapter *adapter = data;
- const char *dst, *svc;
- int err;
- uuid_t uuid;
-
- if (!adapter->up)
- return adapter_not_ready(msg);
-
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &dst,
- DBUS_TYPE_STRING, &svc,
- DBUS_TYPE_INVALID))
- return invalid_args(msg);
-
- if (strlen(svc) > 0) {
- /* Check if it is a service name string */
- if (bt_string2uuid(&uuid, svc) < 0) {
- error("Invalid service class name");
- return invalid_args(msg);
- }
- }
-
- if (find_pending_connect(dst))
- return in_progress(msg, "Service search in progress");
-
- if (!connect_request(conn, msg, adapter->address,
- dst, remote_svc_handles_conn_cb, &err)) {
- error("Search request failed: %s (%d)", strerror(err), err);
- return failed_strerror(msg, err);
- }
-
- return NULL;
-}
-
-DBusMessage *get_remote_svc_identifiers(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct adapter *adapter = data;
- const char *dst;
- int err;
-
- if (!adapter->up)
- return adapter_not_ready(msg);
-
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &dst,
- DBUS_TYPE_INVALID))
- return invalid_args(msg);
-
- if (find_pending_connect(dst))
- return in_progress(msg, "Service search in progress");
-
- if (!connect_request(conn, msg, adapter->address,
- dst, remote_svc_identifiers_conn_cb, &err)) {
- error("Search request failed: %s (%d)", strerror(err), err);
- return failed_strerror(msg, err);
- }
-
- return NULL;
-}
-
-DBusMessage *finish_remote_svc_transact(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct cached_session *s;
- const char *address;
- struct adapter *adapter = data;
- bdaddr_t sba, dba;
-
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &address,
- DBUS_TYPE_INVALID))
- return invalid_args(msg);
-
- str2ba(adapter->address, &sba);
- str2ba(address, &dba);
-
- while ((s = get_cached_session(&sba, &dba))) {
- sdp_close(s->session);
- g_source_remove(s->timeout_id);
- g_source_remove(s->io_id);
- g_free(s);
- }
-
- return dbus_message_new_method_return(msg);
-}
diff --git a/hcid/dbus-sdp.h b/hcid/dbus-sdp.h
deleted file mode 100644
index 06484bbc..00000000
--- a/hcid/dbus-sdp.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2006-2007 Nokia Corporation
- * Copyright (C) 2004-2008 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
- *
- */
-
-typedef enum {
- SDP_FORMAT_XML,
- SDP_FORMAT_BINARY
-} sdp_format_t;
-
-DBusMessage *get_remote_svc_handles(DBusConnection *conn,
- DBusMessage *msg, void *data);
-
-DBusMessage *get_remote_svc_identifiers(DBusConnection *conn,
- DBusMessage *msg, void *data);
-
-DBusMessage *get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg,
- void *data, sdp_format_t format);
-
-DBusMessage *finish_remote_svc_transact(DBusConnection *conn,
- DBusMessage *msg, void *data);
-
-void append_and_grow_string(void *data, const char *str);
diff --git a/hcid/device.c b/hcid/device.c
index a2b6ab9d..c9160d58 100644
--- a/hcid/device.c
+++ b/hcid/device.c
@@ -62,9 +62,9 @@
#include "error.h"
#include "glib-helper.h"
#include "agent.h"
-#include "dbus-sdp.h"
#include "sdp-xml.h"
+#define DEFAULT_XML_BUF_SIZE 1024
#define MAX_DEVICES 16
#define DISCONNECT_TIMER 2
@@ -1316,6 +1316,41 @@ static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
dbus_message_iter_close_container(dict, &entry);
}
+void append_and_grow_string(void *data, const char *str)
+{
+ sdp_buf_t *buff = data;
+ int len;
+
+ len = strlen(str);
+
+ if (!buff->data) {
+ buff->data = malloc(DEFAULT_XML_BUF_SIZE);
+ if (!buff->data)
+ return;
+ buff->buf_size = DEFAULT_XML_BUF_SIZE;
+ }
+
+ /* Grow string */
+ while (buff->buf_size < (buff->data_size + len + 1)) {
+ void *tmp;
+ uint32_t new_size;
+
+ /* Grow buffer by a factor of 2 */
+ new_size = (buff->buf_size << 1);
+
+ tmp = realloc(buff->data, new_size);
+ if (!tmp)
+ return;
+
+ buff->data = tmp;
+ buff->buf_size = new_size;
+ }
+
+ /* Include the NULL character */
+ memcpy(buff->data + buff->data_size, str, len + 1);
+ buff->data_size += len;
+}
+
static void discover_device_reply(struct browse_req *req, sdp_list_t *recs)
{
DBusMessage *reply;