diff options
Diffstat (limited to 'serial/main.c')
| -rw-r--r-- | serial/main.c | 150 | 
1 files changed, 150 insertions, 0 deletions
diff --git a/serial/main.c b/serial/main.c new file mode 100644 index 00000000..20aea93a --- /dev/null +++ b/serial/main.c @@ -0,0 +1,150 @@ +/* + * + *  BlueZ - Bluetooth protocol stack for Linux + * + *  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 <errno.h> +#include <sys/types.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/sdp.h> + +#include <gdbus.h> + +#include "plugin.h" +#include "device.h" +#include "adapter.h" +#include "logging.h" +#include "manager.h" +#include "port.h" + +#define SERIAL_PORT_UUID	"00001101-0000-1000-8000-00805F9B34FB" +#define DIALUP_NET_UUID		"00001103-0000-1000-8000-00805F9B34FB" + +#define SERIAL_INTERFACE     "org.bluez.Serial" +#define ERROR_INVALID_ARGS   "org.bluez.Error.InvalidArguments" +#define ERROR_DOES_NOT_EXIST "org.bluez.Error.DoesNotExist" + +static DBusMessage *serial_connect(DBusConnection *conn, +					DBusMessage *msg, void *user_data) +{ +	struct btd_device *device = user_data; +	const char *target; +	char src[18], dst[18]; + +	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &target, +						DBUS_TYPE_INVALID) == FALSE) +		return NULL; + +	ba2str(&device->src, src); +	ba2str(&device->dst, dst); + +	service_connect(conn, msg, src, dst, target); + +	return NULL; +} + +static DBusMessage *serial_disconnect(DBusConnection *conn, +					DBusMessage *msg, void *user_data) +{ +	const char *device, *sender; +	int err, id; + +	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &device, +						DBUS_TYPE_INVALID) == FALSE) +		return NULL; + +	sender = dbus_message_get_sender(msg); + +	if (sscanf(device, "/dev/rfcomm%d", &id) != 1) +		return g_dbus_create_error(msg, ERROR_INVALID_ARGS, NULL); + +	err = port_remove_listener(sender, device); +	if (err < 0) +		return g_dbus_create_error(msg, ERROR_DOES_NOT_EXIST, NULL); + +	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); +} + +static GDBusMethodTable serial_methods[] = { +	{ "Connect",    "s", "s", serial_connect, G_DBUS_METHOD_FLAG_ASYNC }, +	{ "Disconnect", "s", "",  serial_disconnect }, +	{ } +}; + +static DBusConnection *conn; + +static int serial_probe(struct btd_device *device) +{ +	DBG("path %s", device->path); + +	if (g_dbus_register_interface(conn, device->path, SERIAL_INTERFACE, +						serial_methods, NULL, NULL, +							device, NULL) == FALSE) +		return -1; + +	return 0; +} + +static void serial_remove(struct btd_device *device) +{ +	DBG("path %s", device->path); + +	g_dbus_unregister_interface(conn, device->path, SERIAL_INTERFACE); +} + +static struct btd_device_driver serial_driver = { +	.name	= "serial", +	.uuids	= BTD_UUIDS(SERIAL_PORT_UUID, DIALUP_NET_UUID), +	.probe	= serial_probe, +	.remove	= serial_remove, +}; + +static int serial_init(void) +{ +	conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); +	if (conn == NULL) +		return -EIO; + +	if (serial_manager_init(conn) < 0) { +		dbus_connection_unref(conn); +		return -EIO; +	} + +	btd_register_device_driver(&serial_driver); + +	return 0; +} + +static void serial_exit(void) +{ +	btd_unregister_device_driver(&serial_driver); + +	serial_manager_exit(); + +	dbus_connection_unref(conn); +} + +BLUETOOTH_PLUGIN_DEFINE("serial", serial_init, serial_exit)  | 
