diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2007-08-15 22:33:48 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2007-08-15 22:33:48 +0000 | 
| commit | 3da5850c5f114a0f96e2b8a2f5e3866531ae9268 (patch) | |
| tree | ab88556f0f1db1d96244259f54f9494d6229baef | |
| parent | 3b320a0355706a98f824f4d0abf2d14f820bbd81 (diff) | |
Remove old RFCOMM API files
| -rw-r--r-- | hcid/dbus-rfcomm.c | 1056 | ||||
| -rw-r--r-- | hcid/dbus-rfcomm.h | 31 | ||||
| -rw-r--r-- | hcid/rfcomm-api.txt | 58 | 
3 files changed, 0 insertions, 1145 deletions
diff --git a/hcid/dbus-rfcomm.c b/hcid/dbus-rfcomm.c deleted file mode 100644 index f12f6ade..00000000 --- a/hcid/dbus-rfcomm.c +++ /dev/null @@ -1,1056 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2004-2007  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/ioctl.h> -#include <sys/socket.h> -#include <arpa/inet.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/rfcomm.h> -#include <bluetooth/hci.h> -#include <bluetooth/hci_lib.h> -#include <bluetooth/sdp.h> -#include <bluetooth/sdp_lib.h> - -#include <glib.h> - -#include <dbus/dbus.h> - -#include "dbus.h" -#include "dbus-helper.h" -#include "hcid.h" -#include "dbus-common.h" -#include "dbus-hci.h" -#include "dbus-adapter.h" -#include "dbus-error.h" -#include "dbus-sdp.h" -#include "dbus-rfcomm.h" - -/* Waiting for udev to create the device node */ -#define MAX_OPEN_TRIES	5 -#define OPEN_WAIT	300  /* ms */ - -static int rfcomm_ctl = -1; - -struct rfcomm_node { -	int16_t		id;		/* Device id */ -	char		name[16];       /* Node filename */ - -	DBusConnection	*conn;		/* for name listener handling */ - -	/* The following members are only valid for connected nodes */ -	GIOChannel	*io;		/* IO Channel for the connection */ -	guint		io_id;		/* ID for IO channel */ -	char		*owner;		/* D-Bus name that created the node */ -}; - -struct pending_connect { -	DBusConnection		*conn; -	DBusMessage		*msg; -	GIOChannel		*io; -	char 			*svc; -	int			canceled; -	struct sockaddr_rc	laddr; -	struct sockaddr_rc	raddr; - -	/* Used only when we wait for udev to create the device node */ -	struct rfcomm_node	*node; -	int			ntries; -}; - -static GSList *pending_connects = NULL; -static GSList *connected_nodes = NULL; -static GSList *bound_nodes = NULL; - -static char *rfcomm_node_name_from_id(int16_t id, char *dev, size_t len) -{ -	snprintf(dev, len, "/dev/rfcomm%d", id); -	return dev; -} - -static void rfcomm_node_free(struct rfcomm_node *node) -{ -	g_free(node->owner); -	if (node->io) { -		g_source_remove(node->io_id); -		g_io_channel_unref(node->io); -	} -	if (node->conn) -		dbus_connection_unref(node->conn); -	g_free(node); -} - -static struct rfcomm_node *find_node_by_name(GSList *nodes, const char *name) -{ -	GSList *l; - -	for (l = nodes; l != NULL; l = l->next) { -		struct rfcomm_node *node = l->data; -		if (!strcmp(node->name, name)) -			return node; -	} - -	return NULL; -} - -static struct pending_connect *find_pending_connect_by_channel(const char *bda, -								uint8_t ch) -{ -	GSList *l; -	bdaddr_t dba; - -	str2ba(bda, &dba); - -	for (l = pending_connects; l != NULL; l = l->next) { -		struct pending_connect *pending = l->data; -		if (!bacmp(&dba, &pending->raddr.rc_bdaddr) && -			pending->raddr.rc_channel == ch) -			return pending; -	} - -	return NULL; -} - -static struct pending_connect *find_pending_connect_by_service(const char *bda, -								const char *svc) -{ -	GSList *l; -	bdaddr_t dba; - -	str2ba(bda, &dba); - -	for (l = pending_connects; l != NULL; l = l->next) { -		struct pending_connect *pending = l->data; -		if (!bacmp(&dba, &pending->raddr.rc_bdaddr) && -			!strcmp(pending->svc, svc)) -			return pending; -	} - -	return NULL; -} - -static void pending_connect_free(struct pending_connect *c) -{ -	g_free(c->svc); -	if (c->io) -		g_io_channel_unref(c->io); -	if (c->msg) -		dbus_message_unref(c->msg); -	if (c->conn) -		dbus_connection_unref(c->conn); -	g_free(c); -} - -static int rfcomm_release(struct rfcomm_node *node, int *err) -{ -	struct rfcomm_dev_req req; - -	debug("rfcomm_release(%s)", node->name); - -	memset(&req, 0, sizeof(req)); -	req.dev_id = node->id; - -#if 0 -	/* -	 * We are hitting a kernel bug inside RFCOMM code when -	 * RFCOMM_HANGUP_NOW bit is set on request's flags passed to -	 * ioctl(RFCOMMRELEASEDEV)! -	 */ -	req.flags = (1 << RFCOMM_HANGUP_NOW); -#endif - -	if (ioctl(rfcomm_ctl, RFCOMMRELEASEDEV, &req) < 0) { -		if (err) -			*err = errno; -		error("Can't release device %d: %s (%d)", node->id, -				strerror(errno), errno); -		return -1; -	} - -	return 0; -} - -static void rfcomm_connect_req_exit(const char *name, void *data) -{ -	struct rfcomm_node *node = data; -	debug("Connect requestor %s exited. Releasing %s node", -		name, node->name); -	rfcomm_release(node, NULL); -	connected_nodes = g_slist_remove(connected_nodes, node); -	rfcomm_node_free(node); -} - -static gboolean rfcomm_disconnect_cb(GIOChannel *io, GIOCondition cond, -					struct rfcomm_node *node) -{ -	debug("RFCOMM node %s was disconnected", node->name); -	name_listener_remove(node->conn, node->owner, -				rfcomm_connect_req_exit, node); -	connected_nodes = g_slist_remove(connected_nodes, node); -	rfcomm_node_free(node); -	return FALSE; -} - -static void rfcomm_connect_cb_devnode_opened(int fd, struct pending_connect *c, -						struct rfcomm_node *node) -{ -	DBusMessage *reply = NULL; -	char *ptr; - -	reply = dbus_message_new_method_return(c->msg); -	if (!reply) { -		error_failed(c->conn, c->msg, ENOMEM); -		goto failed; -	} - -	ptr = node->name; -	if (!dbus_message_append_args(reply, -					DBUS_TYPE_STRING, &ptr, -					DBUS_TYPE_INVALID)) { -		error_failed(c->conn, c->msg, ENOMEM); -		goto failed; -	} - -	node->owner = g_strdup(dbus_message_get_sender(c->msg)); - -	/* Check if the caller is still present */ -	if (!dbus_bus_name_has_owner(c->conn, node->owner, NULL)) { -		error("RFCOMM.Connect requestor %s exited", node->owner); -		goto failed; -	} - -	node->io = g_io_channel_unix_new(fd); -	g_io_channel_set_close_on_unref(node->io, TRUE); -	node->io_id = g_io_add_watch(node->io, G_IO_ERR | G_IO_HUP, -					(GIOFunc) rfcomm_disconnect_cb, node); - -	send_message_and_unref(c->conn, reply); - -	connected_nodes = g_slist_append(connected_nodes, node); - -	node->conn = dbus_connection_ref(c->conn); -	name_listener_add(node->conn, node->owner, -			  rfcomm_connect_req_exit, node); - -	goto done; - -failed: -	close(fd); -	rfcomm_release(node, NULL); -	rfcomm_node_free(node); -	if (reply) -		dbus_message_unref(reply); -done: -	pending_connects = g_slist_remove(pending_connects, c); -	pending_connect_free(c); -} - -static gboolean rfcomm_connect_cb_continue(void *data) -{ -	struct pending_connect *c = data; -	struct rfcomm_node *node = c->node; -	int fd; - -	if (c->canceled) { -		error_connect_canceled(c->conn, c->msg); -		goto failed; -	} - -	fd = open(node->name, O_RDONLY | O_NOCTTY); -	if (fd < 0) { -		if (++c->ntries >= MAX_OPEN_TRIES) { -			int err = errno; -			error("Could not open %s: %s (%d)", -					node->name, strerror(err), err); -			error_connection_attempt_failed(c->conn, c->msg, err); -			goto failed; -		} -		return TRUE; -	} - -	rfcomm_connect_cb_devnode_opened(fd, c, node); - -	return FALSE; - -failed: -	rfcomm_release(node, NULL); -	rfcomm_node_free(node); - -	pending_connects = g_slist_remove(pending_connects, c); -	pending_connect_free(c); - -	return FALSE; -} - -static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond, -					struct pending_connect *c) -{ -	struct rfcomm_node *node = NULL; -	struct rfcomm_dev_req req; -	int sk, ret, err, fd = -1; -	socklen_t len; - -	if (c->canceled) { -		error_connect_canceled(c->conn, c->msg); -		goto failed; -	} - -	sk = g_io_channel_unix_get_fd(chan); - -	len = sizeof(ret); -	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { -		err = errno; -		error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err); -		error_failed(c->conn, c->msg, err); -		goto failed; -	} -	if (ret != 0) { -		error("connect(): %s (%d)", strerror(ret), ret); -		error_connection_attempt_failed(c->conn, c->msg, ret); -		goto failed; -	} - -	debug("rfcomm_connect_cb: connected"); - -	len = sizeof(c->laddr); -	if (getsockname(sk, (struct sockaddr *) &c->laddr, &len) < 0) { -		err = errno; -		error_failed(c->conn, c->msg, err); -		error("getsockname: %s (%d)", strerror(err), err); -		goto failed; -	} - -	node = g_new0(struct rfcomm_node, 1); - -	/* Create the rfcomm device node */ -	memset(&req, 0, sizeof(req)); - -	req.dev_id = -1; -	req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); - -	bacpy(&req.src, &c->laddr.rc_bdaddr); -	bacpy(&req.dst, &c->raddr.rc_bdaddr); -	req.channel = c->raddr.rc_channel; - -	node->id = ioctl(sk, RFCOMMCREATEDEV, &req); -	if (node->id < 0) { -		err = errno; -		error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(errno), err); -		error_failed(c->conn, c->msg, err); -		goto failed; -	} - -	rfcomm_node_name_from_id(node->id, node->name, sizeof(node->name)); - -	fd = open(node->name, O_RDONLY | O_NOCTTY); -	if (fd < 0) { -		c->node = node; -		c->ntries = 0; -		g_timeout_add(OPEN_WAIT, rfcomm_connect_cb_continue, c); -		return FALSE; -	} - -	rfcomm_connect_cb_devnode_opened(fd, c, node); - -	return FALSE; - -failed: -	if (node) -		rfcomm_node_free(node); - -	pending_connects = g_slist_remove(pending_connects, c); -	pending_connect_free(c); - -	return FALSE; -} - -static int rfcomm_connect(DBusConnection *conn, DBusMessage *msg, bdaddr_t *src, -			const char *bda, const char *svc, uint8_t ch, int *err) -{ -	int sk = -1; -	struct pending_connect *c = NULL; - -	c = g_new0(struct pending_connect, 1); - -	if (svc) -		c->svc = g_strdup(svc); - -	c->laddr.rc_family = AF_BLUETOOTH; -	bacpy(&c->laddr.rc_bdaddr, src); -	c->laddr.rc_channel = 0; - -	c->raddr.rc_family = AF_BLUETOOTH; -	str2ba(bda, &c->raddr.rc_bdaddr); -	c->raddr.rc_channel = ch; - -	sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); -	if (sk < 0) { -		if (err) -			*err = errno; -		goto failed; -	} - -	if (bind(sk, (struct sockaddr *) &c->laddr, sizeof(c->laddr)) < 0) { -		if (err) -			*err = errno; -		goto failed; -	} - -	if (set_nonblocking(sk) < 0) { -		*err = errno; -		goto failed; -	} - -	/* So we can reply to the message later */ -	c->msg = dbus_message_ref(msg); -	c->conn = dbus_connection_ref(conn); - -	c->io = g_io_channel_unix_new(sk); -	g_io_channel_set_close_on_unref(c->io, TRUE); - -	if (connect(sk, (struct sockaddr *) &c->raddr, sizeof(c->raddr)) < 0) { -		/* BlueZ returns EAGAIN eventhough it should return EINPROGRESS */ -		if (!(errno == EAGAIN || errno == EINPROGRESS)) { -			if (err) -				*err = errno; -			error("connect() failed: %s (%d)", strerror(errno), errno); -			goto failed; -		} - -		debug("Connect in progress"); -		g_io_add_watch(c->io, G_IO_OUT, (GIOFunc) rfcomm_connect_cb, c); -		pending_connects = g_slist_append(pending_connects, c); -	} else { -		debug("Connect succeeded with first try"); -		(void) rfcomm_connect_cb(c->io, G_IO_OUT, c); -	} - -	return 0; - -failed: -	if (c) -		pending_connect_free(c); -	if (sk >= 0) -		close(sk); -	return -1; -} - -static void rfcomm_bind_req_exit(const char *name, void *data) -{ -	struct rfcomm_node *node = data; -	debug("Bind requestor %s exited. Releasing %s node", name, node->name); -	rfcomm_release(node, NULL); -	bound_nodes = g_slist_remove(bound_nodes, node); -	rfcomm_node_free(node); -} - -static struct rfcomm_node *rfcomm_bind(bdaddr_t *src, const char *bda, -		uint8_t ch, DBusConnection *conn, const char *owner, int *err) -{ -	struct rfcomm_dev_req req; -	struct rfcomm_node *node; - -	debug("rfcomm_bind(%s, %d)", bda, ch); - -	memset(&req, 0, sizeof(req)); -	req.dev_id = -1; -	req.flags = 0; -	bacpy(&req.src, src); - -	str2ba(bda, &req.dst); -	req.channel = ch; - -	node = g_new0(struct rfcomm_node, 1); - -	node->owner = g_strdup(owner); - -	node->id = ioctl(rfcomm_ctl, RFCOMMCREATEDEV, &req); -	if (node->id < 0) { -		if (err) -			*err = errno; -		error("RFCOMMCREATEDEV failed: %s (%d)", strerror(errno), errno); -		rfcomm_node_free(node); -		return NULL; -	} - -	rfcomm_node_name_from_id(node->id, node->name, sizeof(node->name)); -	bound_nodes = g_slist_append(bound_nodes, node); - -	node->conn = dbus_connection_ref(conn); -	name_listener_add(node->conn, node->owner, rfcomm_bind_req_exit, node); - -	return node; -} - -typedef struct { -	DBusConnection *conn; -	DBusMessage *msg; -	char *dst; -	char *svc; -	struct adapter *adapter; -} rfcomm_continue_data_t; - -static rfcomm_continue_data_t *rfcomm_continue_data_new(DBusConnection *conn, -							DBusMessage *msg, -							const char *dst, -							const char *svc, -							struct adapter *adapter) -{ -	rfcomm_continue_data_t *new; - -	new = g_new(rfcomm_continue_data_t, 1); - -	new->dst = g_strdup(dst); -	if (!new->dst) { -		g_free(new); -		return NULL; -	} - -	new->svc = g_strdup(svc); -	new->conn = dbus_connection_ref(conn); -	new->msg = dbus_message_ref(msg); -	new->adapter = adapter; - -	return new; -} - -static void rfcomm_continue_data_free(rfcomm_continue_data_t *d) -{ -	dbus_connection_unref(d->conn); -	dbus_message_unref(d->msg); -	g_free(d->svc); -	g_free(d->dst); -	g_free(d); -} - -static void rfcomm_conn_req_continue(sdp_record_t *rec, void *data, int err) -{ -	rfcomm_continue_data_t *cdata = data; -	int ch = -1, conn_err; -	sdp_list_t *protos; -	bdaddr_t bdaddr; - -	if (err || !rec) { -		error_record_does_not_exist(cdata->conn, cdata->msg); -		goto failed; -	} - -	if (!sdp_get_access_protos(rec, &protos)) { -		ch = sdp_get_proto_port(protos, RFCOMM_UUID); -		sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); -		sdp_list_free(protos, NULL); -	} -	if (ch == -1) { -		error_record_does_not_exist(cdata->conn, cdata->msg); -		goto failed; -	} - -	if (find_pending_connect_by_channel(cdata->dst, ch)) { -		error_connect_in_progress(cdata->conn, cdata->msg); -		goto failed; -	} - -	hci_devba(cdata->adapter->dev_id, &bdaddr); -	if (rfcomm_connect(cdata->conn, cdata->msg, &bdaddr, -				cdata->dst, cdata->svc, ch, &conn_err) < 0) -		error_failed(cdata->conn, cdata->msg, conn_err); - -failed: -	rfcomm_continue_data_free(cdata); -} - -static DBusHandlerResult rfcomm_connect_req(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	struct adapter *adapter = data; -	rfcomm_continue_data_t *cdata; -	uint32_t handle; -	uuid_t uuid; -	const char *string; -	const char *dst; -	int err; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &dst, -				DBUS_TYPE_STRING, &string, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	cdata = rfcomm_continue_data_new(conn, msg, dst, string, adapter); -	if (!cdata) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	if (str2uuid(&uuid, string) == 0) -		err = get_record_with_uuid(conn, msg, adapter->dev_id, dst, -					&uuid, rfcomm_conn_req_continue, cdata); -	else if ((handle = strtol(string, NULL, 0))) -		err = get_record_with_handle(conn, msg, adapter->dev_id, dst, -					handle, rfcomm_conn_req_continue, cdata); -	else { -		rfcomm_continue_data_free(cdata); -		return error_invalid_arguments(conn, msg); -	} - -	if (!err) -		return DBUS_HANDLER_RESULT_HANDLED; - -	rfcomm_continue_data_free(cdata); - -	if (err == -ENOMEM) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	return error_failed(conn, msg, err); -} - -static DBusHandlerResult rfcomm_cancel_connect_req(DBusConnection *conn, -						DBusMessage *msg, -						void *data) -{ -	struct pending_connect *pending; -	DBusMessage *reply; -	const char *string; -	const char *dst; -	struct adapter *adapter = data; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &dst, -				DBUS_TYPE_STRING, &string, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	pending = find_pending_connect_by_service(dst, string); -	if (!pending) -		return error_connect_not_in_progress(conn, msg); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	pending->canceled = 1; - -	return send_message_and_unref(conn, reply); -} - -static DBusHandlerResult rfcomm_connect_by_ch_req(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	bdaddr_t bdaddr; -	const char *dst; -	uint8_t ch; -	int err; -	struct adapter *adapter = data; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	hci_devba(adapter->dev_id, &bdaddr); - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &dst, -				DBUS_TYPE_BYTE, &ch, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	if (find_pending_connect_by_channel(dst, ch)) -		return error_connect_in_progress(conn, msg); - -	if (rfcomm_connect(conn, msg, &bdaddr, dst, NULL, ch, &err) < 0) -		return error_failed(conn, msg, err); - -	return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult rfcomm_cancel_connect_by_ch_req(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	const char *dst; -	uint8_t ch; -	DBusMessage *reply; -	struct pending_connect *pending; -	struct adapter *adapter = data; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &dst, -				DBUS_TYPE_BYTE, &ch, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	pending = find_pending_connect_by_channel(dst, ch); -	if (!pending) -		return error_connect_not_in_progress(conn, msg); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	pending->canceled = 1; - -	return send_message_and_unref(conn, reply); -} - -static DBusHandlerResult rfcomm_disconnect_req(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	struct rfcomm_node *node; -	DBusMessage *reply; -	const char *name; -	int err; -	struct adapter *adapter = data; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &name, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	node = find_node_by_name(connected_nodes, name); -	if (!node) -		return error_not_connected(conn, msg); - -	if (strcmp(node->owner, dbus_message_get_sender(msg))) -		return error_not_authorized(conn, msg); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	if (rfcomm_release(node, &err) < 0) { -		dbus_message_unref(reply); -		return error_failed(conn, msg, err); -	} - -	name_listener_remove(node->conn, node->owner, -			     rfcomm_connect_req_exit, node); -	connected_nodes = g_slist_remove(connected_nodes, node); -	rfcomm_node_free(node); - -	return send_message_and_unref(conn, reply); -} - -static void rfcomm_bind_req_continue(sdp_record_t *rec, void *data, int err) -{ -	rfcomm_continue_data_t *cdata = data; -	struct rfcomm_node *node = NULL; -	DBusMessage *reply = NULL; -	int ch = -1, bind_err; -	sdp_list_t *protos; -	const char *name; -	bdaddr_t bdaddr; - -	if (err || !rec) { -		error_record_does_not_exist(cdata->conn, cdata->msg); -		goto failed; -	} - -	if (!sdp_get_access_protos(rec, &protos)) { -		ch = sdp_get_proto_port(protos, RFCOMM_UUID); -		sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); -		sdp_list_free(protos, NULL); -	} -	if (ch == -1) { -		error_record_does_not_exist(cdata->conn, cdata->msg); -		goto failed; -	} - -	hci_devba(cdata->adapter->dev_id, &bdaddr); - -	node = rfcomm_bind(&bdaddr, cdata->dst, ch, cdata->conn, -			dbus_message_get_sender(cdata->msg), &bind_err); -	if (!node) { -		error_failed(cdata->conn, cdata->msg, bind_err); -		goto failed; -	} - -	reply = dbus_message_new_method_return(cdata->msg); -	if (!reply) { -		error_failed(cdata->conn, cdata->msg, ENOMEM); -		goto failed; -	} - -	name = node->name; -	if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &name, -					DBUS_TYPE_INVALID)) { -		error_failed(cdata->conn, cdata->msg, ENOMEM); -		goto failed; -	} - -	send_message_and_unref(cdata->conn, reply); - -	rfcomm_continue_data_free(cdata); - -	return; - -failed: -	if (reply) -		dbus_message_unref(reply); -	if (node) { -		bound_nodes = g_slist_remove(bound_nodes, node); -		rfcomm_release(node, NULL); -		rfcomm_node_free(node); -	} - -	rfcomm_continue_data_free(cdata); -} - -static DBusHandlerResult rfcomm_bind_req(DBusConnection *conn, -					DBusMessage *msg, void *data) -{ -	struct adapter *adapter = data; -	rfcomm_continue_data_t *cdata; -	uint32_t handle; -	uuid_t uuid; -	const char *string; -	const char *dst; -	int err; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &dst, -				DBUS_TYPE_STRING, &string, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	cdata = rfcomm_continue_data_new(conn, msg, dst, string, adapter); -	if (!cdata) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	if (str2uuid(&uuid, string) == 0) -		err = get_record_with_uuid(conn, msg, adapter->dev_id, dst, -					&uuid, rfcomm_bind_req_continue, cdata); -	else if ((handle = strtol(string, NULL, 0))) -		err = get_record_with_handle(conn, msg, adapter->dev_id, dst, -					handle, rfcomm_bind_req_continue, cdata); -	else { -		rfcomm_continue_data_free(cdata); -		return error_invalid_arguments(conn, msg); -	} - -	if (!err) -		return DBUS_HANDLER_RESULT_HANDLED; - -	rfcomm_continue_data_free(cdata); - -	if (err == -ENOMEM) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	return error_failed(conn, msg, err); -} - -static DBusHandlerResult rfcomm_bind_by_ch_req(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	bdaddr_t bdaddr; -	DBusMessage *reply = NULL; -	uint8_t ch; -	int err; -	const char *dst, *name; -	struct adapter *adapter = data; -	struct rfcomm_node *node = NULL; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	hci_devba(adapter->dev_id, &bdaddr); - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &dst, -				DBUS_TYPE_BYTE, &ch, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	node = rfcomm_bind(&bdaddr, dst, ch, conn, -			dbus_message_get_sender(msg), &err); -	if (!node) -		return error_failed(conn, msg, err); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		goto need_memory; - -	name = node->name; -	if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &name, -					DBUS_TYPE_INVALID)) -		goto need_memory; - -	return send_message_and_unref(conn, reply); - -need_memory: -	if (reply) -		dbus_message_unref(reply); -	if (node) { -		bound_nodes = g_slist_remove(bound_nodes, node); -		rfcomm_release(node, NULL); -		rfcomm_node_free(node); -	} -	return DBUS_HANDLER_RESULT_NEED_MEMORY; -} - -static DBusHandlerResult rfcomm_release_req(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	DBusMessage *reply; -	const char *name; -	struct rfcomm_node *node; -	int err; -	struct adapter *adapter = data; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &name, -				DBUS_TYPE_INVALID)) -		return error_invalid_arguments(conn, msg); - -	node = find_node_by_name(bound_nodes, name); -	if (!node) -		return error_binding_does_not_exist(conn, msg); - -	if (strcmp(node->owner, dbus_message_get_sender(msg))) -		return error_not_authorized(conn, msg); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	if (rfcomm_release(node, &err) < 0) { -		dbus_message_unref(reply); -		return error_failed(conn, msg, err); -	} - -	name_listener_remove(node->conn, node->owner, -				rfcomm_bind_req_exit, node); -	bound_nodes = g_slist_remove(bound_nodes, node); -	rfcomm_node_free(node); - -	return send_message_and_unref(conn, reply); -} - -static DBusHandlerResult rfcomm_list_bindings_req(DBusConnection *conn, -						DBusMessage *msg, void *data) -{ -	bdaddr_t bdaddr; -	DBusMessage *reply; -	DBusMessageIter iter, sub; -	struct adapter *adapter = data; -	GSList *l; - -	if (!adapter->up) -		return error_not_ready(conn, msg); - -	hci_devba(adapter->dev_id, &bdaddr); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	dbus_message_iter_init_append(reply, &iter); - -	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) { -		dbus_message_unref(reply); -		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	} - -	for (l = bound_nodes; l != NULL; l = l->next) { -		struct rfcomm_node *node = l->data; -		struct rfcomm_dev_info di = { id: node->id }; -		char *name = node->name; - -		if (ioctl(rfcomm_ctl, RFCOMMGETDEVINFO, &di) < 0) { -			error("RFCOMMGETDEVINFO(%d): %s (%d)", -					node->id, strerror(errno), errno); -			continue; -		} - -		/* Ignore nodes not specific to this adapter */ -		if (bacmp(&di.src, &bdaddr)) -			continue; - -		dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name); -	} - -	if (!dbus_message_iter_close_container(&iter, &sub)) { -		dbus_message_unref(reply); -		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	} - -	return send_message_and_unref(conn, reply); -} - -static DBusMethodVTable rfcomm_methods[] = { -	{ "Connect",			rfcomm_connect_req, -		"ss",	"s"	}, -	{ "CancelConnect",		rfcomm_cancel_connect_req, -		"ss",	""	}, -	{ "ConnectByChannel",		rfcomm_connect_by_ch_req, -		"sy",	"s"	}, -	{ "CancelConnectByChannel",	rfcomm_cancel_connect_by_ch_req, -		"sy",	""	}, -	{ "Disconnect",			rfcomm_disconnect_req, -		"s",	""	}, -	{ "Bind",			rfcomm_bind_req, -		"ss",	"s"	}, -	{ "BindByChannel",		rfcomm_bind_by_ch_req, -		"sy",	"s"	}, -	{ "Release",			rfcomm_release_req, -		"s",	""	}, -	{ "ListBindings",		rfcomm_list_bindings_req, -		"",	"as"	}, -	{ NULL,	NULL, NULL, NULL } -}; - -dbus_bool_t rfcomm_init(DBusConnection *conn, const char *path) -{ -	if (rfcomm_ctl < 0) { -		rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM); -		if (rfcomm_ctl < 0) -			return FALSE; -	} - -	return dbus_connection_register_interface(conn, path, RFCOMM_INTERFACE, -							rfcomm_methods, -							NULL, NULL); -} diff --git a/hcid/dbus-rfcomm.h b/hcid/dbus-rfcomm.h deleted file mode 100644 index f7705ef8..00000000 --- a/hcid/dbus-rfcomm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2004-2007  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 - * - */ - -#ifndef __BLUEZ_DBUS_RFCOMM_H -#define __BLUEZ_DBUS_RFCOMM_H - -#define RFCOMM_INTERFACE	"org.bluez.RFCOMM" - -dbus_bool_t rfcomm_init(DBusConnection *conn, const char *path); - -#endif /* __BLUEZ_DBUS_RFCOMM_H */ diff --git a/hcid/rfcomm-api.txt b/hcid/rfcomm-api.txt deleted file mode 100644 index 827fde5a..00000000 --- a/hcid/rfcomm-api.txt +++ /dev/null @@ -1,58 +0,0 @@ -RFCOMM hierarchy (experimental) -=============================== - -Service		org.bluez -Interface	org.bluez.RFCOMM -Object path	/org/bluez/{hci0,hci1,...} - -Methods		string Connect(string address, string service) - -			This creates a connection to a remote RFCOMM based -			service. The service string can either be a UUID-128, -			a service abbreviation or a record handle. - -			The return value will be the path of the newly -			created RFCOMM TTY device (for example /dev/rfcomm0). - -			If the application disconnects from the D-Bus this -			connection will be terminated. - -			Valid service values: "vcp", "map", "pbap", "sap", -			                      "ftp", "bpp", "bip", "synch", -			                      "dun", "opp", "fax", "spp" - -		void CancelConnect(string address, string service) - -			This method cancels a previous Connect method call. - -		string ConnectByChannel(string address, byte channel) - -			This creates a connection to a remote RFCOMM based -			service. In contrast to Connect a channel number is -			needed. - -			The return value will be the path of the newly -			creates RFCOMM TTY device (for example /dev/rfcomm0). - -			If the application disconnects from the D-Bus this -			connection will be terminated. - -		void CancelConnectByChannel(string address, byte channel) - -			This method cancels a previous ConnectByChannel -			method call. - -		void Disconnect(string device) - -			This will disconnect a previously connected RFCOMM -			service. The device parameter must be the return value -			from a previous Connect or ConnectByChannel method -			call (for example /dev/rfcomm0). - -		string Bind(string address, string service) - -		string BindByChannel(string address, byte channel) - -		void Release(string device) - -		array{string} ListBindings()  | 
