[PATCH 1/7] sap: initial SIM access client support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Claudio Takahasi <claudio.takahasi@xxxxxxxxxxxxx>

Add Makefile changes to support SAP client plugin and initial skeleton
for D-Bus methods.
---
 Makefile.am   |    1 +
 sap/client.c  |  198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sap/client.h  |   29 ++++++++
 sap/manager.c |   76 ++++++++++++++++++++--
 sap/sap.h     |    2 +
 sap/server.c  |    1 -
 6 files changed, 300 insertions(+), 7 deletions(-)
 create mode 100644 sap/client.c
 create mode 100644 sap/client.h

diff --git a/Makefile.am b/Makefile.am
index 68380d9..95bd9eb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -156,6 +156,7 @@ builtin_modules += sap
 builtin_sources += sap/main.c \
 			sap/manager.h sap/manager.c \
 			sap/server.h sap/server.c \
+			sap/client.h sap/client.c \
 			sap/sap.h
 
 builtin_nodist += sap/sap.c
diff --git a/sap/client.c b/sap/client.c
new file mode 100644
index 0000000..231b4ef
--- /dev/null
+++ b/sap/client.c
@@ -0,0 +1,198 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2009  Marcel Holtmann <marcel@xxxxxxxxxxxx>
+ *
+ *
+ *  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 <bluetooth.h>
+
+#include <gdbus.h>
+
+#include "btio.h"
+#include "error.h"
+#include "dbus-common.h"
+#include "log.h"
+
+#include "client.h"
+
+#define SAP_INTERFACE	"org.bluez.SimAccessServer"
+
+static DBusConnection *connection;
+
+struct client {
+	bdaddr_t	sba;		/* Source Bluetooth address */
+	bdaddr_t	dba;		/* Destination Bluetooth address */
+	uint8_t		channel;	/* SAP RFCOMM channel */
+	char		*path;		/* Device path */
+	GIOChannel	*io;		/* BtIO Channel */
+	DBusMessage	*msg;
+};
+
+static void client_free(struct client *client)
+{
+	if (client->msg)
+		dbus_message_unref(client->msg);
+	if (client->io) {
+		g_io_channel_shutdown(client->io, TRUE, NULL);
+		g_io_channel_unref(client->io);
+	}
+
+	g_free(client->path);
+	g_free(client);
+}
+
+static void path_unregister(void *data)
+{
+	struct client *client = data;
+
+	info("Unregistered interface %s on path %s",
+			SAP_INTERFACE, client->path);
+
+	client_free(client);
+}
+
+static void rfcomm_connect_cb(GIOChannel *chan, GError *gerr, gpointer data)
+{
+	struct client *client = data;
+	DBusMessage *reply;
+
+	if (gerr) {
+		error("%s", gerr->message);
+		reply = btd_error_failed(client->msg, gerr->message);
+
+		g_io_channel_unref(client->io);
+		client->io = NULL;
+
+		goto failed;
+	}
+
+	g_io_channel_set_encoding(chan, NULL, NULL);
+
+	reply = dbus_message_new_method_return(client->msg);
+
+	/* TODO: Enable SAP messages forwarding */
+
+failed:
+	g_dbus_send_message(connection, reply);
+	dbus_message_unref(client->msg);
+	client->msg = NULL;
+}
+
+static DBusMessage *client_connect(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct client *client = data;
+	DBusMessage *reply;
+	GError *gerr = NULL;
+
+	if (client->io)
+		return btd_error_already_connected(msg);
+
+	client->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, client,
+			NULL, &gerr,
+			BT_IO_OPT_SOURCE_BDADDR, &client->sba,
+			BT_IO_OPT_DEST_BDADDR, &client->dba,
+			BT_IO_OPT_CHANNEL, client->channel,
+			BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
+			BT_IO_OPT_INVALID);
+
+	if (!client->io) {
+		reply = btd_error_failed(msg, gerr->message);
+		g_error_free(gerr);
+		return reply;
+	}
+
+	client->msg = dbus_message_ref(msg);
+
+	return NULL;
+}
+
+static DBusMessage *client_disconnect(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct client *client = data;
+
+	if (!client->io)
+		return btd_error_not_connected(msg);
+
+	if (client->msg)
+		return btd_error_in_progress(msg);
+
+	 /* TODO: exit from remote SIM mode */
+
+	return dbus_message_new_method_return(msg);
+}
+
+static GDBusMethodTable client_methods[] = {
+	{ "Connect",		"",	"",	client_connect,
+		G_DBUS_METHOD_FLAG_ASYNC },
+	{ "Disconnect",		"",	"",	client_disconnect,
+		G_DBUS_METHOD_FLAG_ASYNC },
+	{ NULL, NULL, NULL, NULL }
+};
+
+static GDBusSignalTable client_signals[] = {
+	{ "PropertyChanged",		"sv"		},
+	{ }
+};
+
+int sap_client_init(DBusConnection *conn)
+{
+	connection = dbus_connection_ref(conn);
+	return 0;
+}
+
+void sap_client_exit(void)
+{
+	dbus_connection_unref(connection);
+	connection = NULL;
+}
+
+int sap_client_register(const char *path,
+		const bdaddr_t *sba, const bdaddr_t *dba, uint8_t channel)
+{
+	struct client *client;
+
+	client = g_new0(struct client, 1);
+	bacpy(&client->sba, sba);
+	bacpy(&client->dba, dba);
+	client->channel = channel;
+	client->path = g_strdup(path);
+
+	if (!g_dbus_register_interface(connection, path,
+				SAP_INTERFACE, client_methods, client_signals, NULL,
+				client, path_unregister)) {
+		error("D-Bus failed to register %s interface",
+				SAP_INTERFACE);
+		client_free(client);
+		return -1;
+	}
+
+	return 0;
+}
+
+void sap_client_unregister(const char *path)
+{
+	g_dbus_unregister_interface(connection, path, SAP_INTERFACE);
+}
diff --git a/sap/client.h b/sap/client.h
new file mode 100644
index 0000000..2ef5668
--- /dev/null
+++ b/sap/client.h
@@ -0,0 +1,29 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2009  Marcel Holtmann <marcel@xxxxxxxxxxxx>
+ *
+ *
+ *  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
+ *
+ */
+
+int sap_client_init(DBusConnection *conn);
+void sap_client_exit(void);
+
+int sap_client_register(const char *path,
+		const bdaddr_t *sba, const bdaddr_t *dba, uint8_t channel);
+void sap_client_unregister(const char *path);
diff --git a/sap/manager.c b/sap/manager.c
index a97f434..386bf54 100644
--- a/sap/manager.c
+++ b/sap/manager.c
@@ -35,11 +35,61 @@
 #include "adapter.h"
 #include "device.h"
 
+#include "sap.h"
 #include "manager.h"
 #include "server.h"
+#include "client.h"
 
 static DBusConnection *connection = NULL;
 
+static int sap_client_probe(struct btd_device *device, GSList *uuids)
+{
+	struct btd_adapter *adapter = device_get_adapter(device);
+	const gchar *path = device_get_path(device);
+	const sdp_record_t *rec;
+	sdp_list_t *protos;
+	bdaddr_t sba, dba;
+	const char *uuid;
+	uint8_t channel;
+
+	adapter_get_address(adapter, &sba);
+	device_get_address(device, &dba);
+
+
+	while (uuids) {
+		uuid = uuids->data;
+		DBG("UUID: %s", uuid);
+		rec = btd_device_get_record(device, uuid);
+		if (!rec)
+			return -EINVAL;
+
+		if (sdp_get_access_protos(rec, &protos) < 0)
+			return -EINVAL;
+
+		channel = 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 (channel < 1 || channel > 30) {
+			error("Channel out of range: %d", channel);
+			return -EINVAL;
+		}
+
+		sap_client_register(path, &sba, &dba, channel);
+		uuids = uuids->next;
+	}
+
+	return 0;
+}
+
+static void sap_client_remove(struct btd_device *device)
+{
+	const gchar *path = device_get_path(device);
+
+	DBG("path %s", path);
+	sap_client_unregister(path);
+}
+
 static int sap_server_probe(struct btd_adapter *adapter)
 {
 	const char *path = adapter_get_path(adapter);
@@ -61,6 +111,13 @@ static void sap_server_remove(struct btd_adapter *adapter)
 	sap_server_unregister(path);
 }
 
+static struct btd_device_driver sap_client_driver = {
+	.name	= "sap-client",
+	.uuids	= BTD_UUIDS(SAP_UUID),
+	.probe	= sap_client_probe,
+	.remove	= sap_client_remove,
+};
+
 static struct btd_adapter_driver sap_server_driver = {
 	.name	= "sap-server",
 	.probe	= sap_server_probe,
@@ -69,25 +126,32 @@ static struct btd_adapter_driver sap_server_driver = {
 
 int sap_manager_init(DBusConnection *conn)
 {
-	connection = dbus_connection_ref(conn);
-
-	if (sap_server_init(connection) < 0) {
+	if (sap_server_init(conn) < 0) {
 		error("Can't init SAP server");
-		dbus_connection_unref(conn);
 		return -1;
 	}
 
 	btd_register_adapter_driver(&sap_server_driver);
 
+	sap_client_init(conn);
+
+	btd_register_device_driver(&sap_client_driver);
+
+	connection = dbus_connection_ref(conn);
+
 	return 0;
 }
 
 void sap_manager_exit(void)
 {
+	sap_server_exit();
+
+	btd_unregister_device_driver(&sap_client_driver);
+
+	sap_client_exit();
+
 	btd_unregister_adapter_driver(&sap_server_driver);
 
 	dbus_connection_unref(connection);
 	connection = NULL;
-
-	sap_server_exit();
 }
diff --git a/sap/sap.h b/sap/sap.h
index 1dbb235..99fde0a 100644
--- a/sap/sap.h
+++ b/sap/sap.h
@@ -28,6 +28,8 @@
 
 #define SAP_VERSION 0x0101
 
+#define SAP_UUID	"0000112D-0000-1000-8000-00805F9B34FB"
+
 /* Connection Status - SAP v1.1 section 5.2.2 */
 enum sap_status {
 	SAP_STATUS_OK				= 0x00,
diff --git a/sap/server.c b/sap/server.c
index 8bd8fe1..a44f7d7 100644
--- a/sap/server.c
+++ b/sap/server.c
@@ -46,7 +46,6 @@
 #include "server.h"
 
 #define SAP_SERVER_INTERFACE	"org.bluez.SimAccess"
-#define SAP_UUID		"0000112D-0000-1000-8000-00805F9B34FB"
 #define SAP_SERVER_CHANNEL	8
 
 #define PADDING4(x) ((4 - (x & 0x03)) & 0x03)
-- 
1.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux