diff --git a/doc/serial-api.txt b/doc/serial-api.txt
index 841b21b..ad496d2 100644
--- a/doc/serial-api.txt
+++ b/doc/serial-api.txt
org.bluez.Error.ConnectionAttemptFailed
org.bluez.Error.NotSupported
+Methods fd ConnectFD(string pattern) [experimental]
+
+ Connects to a specific RFCOMM based service on a
+ remote device and returns a file descriptor to talk
+ with this device.
+
+ Possible patterns: UUID 128 bit as string
+ Profile short names, e.g: spp, dun
+ RFCOMM channel as string, 1-30
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.InProgress
+ org.bluez.Error.ConnectionAttemptFailed
+ org.bluez.Error.NotSupported
+
+
void Disconnect(string device)
Disconnect a RFCOMM TTY device that has been
diff --git a/serial/port.c b/serial/port.c
index a931ebd..7f5fce1 100644
--- a/serial/port.c
+++ b/serial/port.c
#define MAX_OPEN_TRIES 5
#define OPEN_WAIT 300 /* ms. udev node creation retry wait */
+#ifndef DBUS_TYPE_UNIX_FD
+#define DBUS_TYPE_UNIX_FD -1
+#endif
+
struct serial_device {
DBusConnection *conn; /* for name listener handling */
bdaddr_t src; /* Source (local) address */
goto fail;
}
+ sk = g_io_channel_unix_get_fd(chan);
+
+ if (dbus_message_has_member(port->msg, "ConnectFD")) {
+ reply = g_dbus_create_reply(port->msg, DBUS_TYPE_UNIX_FD, &sk,
+ DBUS_TYPE_INVALID);
+ g_dbus_send_message(device->conn, reply);
+
+ close(sk);
+
+ g_dbus_remove_watch(device->conn, port->listener_id);
+ port->listener_id = 0;
+
+ return;
+ }
+
memset(&req, 0, sizeof(req));
req.dev_id = -1;
req.flags = (1 << RFCOMM_REUSE_DLC);
g_io_channel_unref(port->io);
port->io = NULL;
- sk = g_io_channel_unix_get_fd(chan);
port->id = ioctl(sk, RFCOMMCREATEDEV, &req);
if (port->id < 0) {
int err = -errno;
const char *pattern;
int err;
+ if (dbus_message_has_member(msg, "ConnectFD") && DBUS_TYPE_UNIX_FD < 0)
+ return btd_error_not_supported(msg);
+
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
DBUS_TYPE_INVALID) == FALSE)
return NULL;
dbus_message_get_sender(msg),
port_owner_exited, port,
NULL);
+
port->msg = dbus_message_ref(msg);
err = connect_port(port);
static GDBusMethodTable port_methods[] = {
{ "Connect", "s", "s", port_connect, G_DBUS_METHOD_FLAG_ASYNC },
+ { "ConnectFD", "s", "h", port_connect, G_DBUS_METHOD_FLAG_ASYNC },
{ "Disconnect", "s", "", port_disconnect },
{ }
};