summaryrefslogtreecommitdiffstats
path: root/serial/manager.c
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-05-09 21:00:02 +0000
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-05-09 21:00:02 +0000
commit8cf2f361bf51ee608db71057843cd9dbdf66ff70 (patch)
tree3517c6f66db96858c76eba4a34997b3ac70bbf2d /serial/manager.c
parenta59f82bd8a01e83bd7724beccfe2a0383982650c (diff)
Cleanup and removal of dbus internal calls.
Diffstat (limited to 'serial/manager.c')
-rw-r--r--serial/manager.c629
1 files changed, 218 insertions, 411 deletions
diff --git a/serial/manager.c b/serial/manager.c
index aa05b8f3..2ad0655c 100644
--- a/serial/manager.c
+++ b/serial/manager.c
@@ -70,10 +70,9 @@
struct pending_connect {
DBusConnection *conn;
DBusMessage *msg;
- char *bda; /* Destination address */
- char *adapter_path; /* Adapter D-Bus path */
+ char *adapter; /* Adapter address */
+ char *address; /* Destination address */
char *pattern; /* Connection request pattern */
- bdaddr_t src;
uint8_t channel;
char *dev; /* tty device name */
int id; /* RFCOMM device id */
@@ -143,12 +142,12 @@ static void pending_connect_free(struct pending_connect *pc)
dbus_connection_unref(pc->conn);
if (pc->msg)
dbus_message_unref(pc->msg);
- if (pc->bda)
- g_free(pc->bda);
+ if (pc->adapter)
+ g_free(pc->adapter);
+ if (pc->address)
+ g_free(pc->address);
if (pc->pattern)
g_free(pc->pattern);
- if (pc->adapter_path)
- g_free(pc->adapter_path);
if (pc->dev)
g_free(pc->dev);
g_free(pc);
@@ -162,7 +161,7 @@ static struct pending_connect *find_pending_connect_by_pattern(const char *bda,
/* Pattern can be friendly name, uuid128, record handle or channel */
for (l = pending_connects; l != NULL; l = l->next) {
struct pending_connect *pending = l->data;
- if (!strcasecmp(pending->bda, bda) &&
+ if (!strcasecmp(pending->address, bda) &&
!strcasecmp(pending->pattern, pattern))
return pending;
}
@@ -234,7 +233,7 @@ static void open_notify(int fd, int err, struct pending_connect *pc)
DBUS_TYPE_STRING, &pc->dev,
DBUS_TYPE_INVALID);
- str2ba(pc->bda, &dst);
+ str2ba(pc->address, &dst);
/* Add the RFCOMM connection listener */
port_add_listener(pc->conn, pc->id, &dst, fd,
@@ -364,8 +363,8 @@ static void rfcomm_connect_cb(GIOChannel *chan, int err_cb, gpointer user_data)
memset(&req, 0, sizeof(req));
req.dev_id = -1;
req.flags = (1 << RFCOMM_REUSE_DLC);
- bacpy(&req.src, &pc->src);
- str2ba(pc->bda, &req.dst);
+ str2ba(pc->adapter, &req.src);
+ str2ba(pc->address, &req.dst);
req.channel = pc->channel;
sk = g_io_channel_unix_get_fd(chan);
@@ -392,22 +391,87 @@ fail:
pending_connect_remove(pc);
}
-static void record_reply(DBusPendingCall *call, void *data)
+static DBusHandlerResult create_channel_port(DBusConnection *conn,
+ DBusMessage *msg, const char *adapter,
+ const char *address, const char *name,
+ long channel, void *data)
+{
+ char path[MAX_PATH_LENGTH], port_name[16];
+ const char *ppath = path;
+ DBusMessage *reply;
+ int err;
+ bdaddr_t src, dst;
+
+ if (channel < 1 || channel > 30)
+ return error_invalid_arguments(conn, msg,
+ "invalid RFCOMM channel");
+
+ str2ba(adapter, &src);
+ str2ba(address, &dst);
+ err = rfcomm_bind(&src, &dst, -1, channel);
+ if (err < 0)
+ return error_failed_errno(conn, msg, -err);
+
+ snprintf(port_name, sizeof(port_name), "/dev/rfcomm%d", err);
+ port_store(&src, &dst, err, channel, name);
+ port_register(conn, err, &src, &dst, port_name, path, name);
+ ports_paths = g_slist_append(ports_paths, g_strdup(path));
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_STRING, &ppath,
+ DBUS_TYPE_INVALID);
+ send_message_and_unref(conn, reply);
+
+ dbus_connection_emit_signal(conn, SERIAL_MANAGER_PATH,
+ SERIAL_MANAGER_INTERFACE, "PortCreated" ,
+ DBUS_TYPE_STRING, &ppath,
+ DBUS_TYPE_INVALID);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult connect_pending(DBusConnection *conn, DBusMessage *msg,
+ struct pending_connect *pc)
+{
+ int err;
+ bdaddr_t src, dst;
+
+ if (!g_slist_find(pending_connects, pc)) {
+ pending_connects = g_slist_append(pending_connects, pc);
+ name_listener_add(conn, dbus_message_get_sender(msg),
+ (name_cb_t) transaction_owner_exited, NULL);
+ }
+
+ str2ba(pc->adapter, &src);
+ str2ba(pc->address, &dst);
+
+ err = bt_rfcomm_connect(&src, &dst, pc->channel, rfcomm_connect_cb, pc);
+ if (err < 0) {
+ const char *strerr = strerror(-err);
+ error("RFCOMM connect failed: %s(%d)", strerr, -err);
+ pending_connects = g_slist_remove(pending_connects, pc);
+ pending_connect_free(pc);
+ return error_connection_attempt_failed(conn, msg, -err);
+ }
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void record_cb(sdp_list_t *recs, int err, gpointer data)
{
struct pending_connect *pc;
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
sdp_record_t *rec = NULL;
- const uint8_t *rec_bin;
sdp_list_t *protos;
- DBusError derr;
- int len, scanned, ch, err;
+ int ch;
bdaddr_t dst;
/* Owner exited? */
- if (!g_slist_find(pending_connects, data)) {
- dbus_message_unref(reply);
+ if (!g_slist_find(pending_connects, data))
return;
- }
pc = data;
if (pc->canceled) {
@@ -415,45 +479,19 @@ static void record_reply(DBusPendingCall *call, void *data)
goto fail;
}
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- /* FIXME : forward error as is */
- if (dbus_error_has_name(&derr,
- "org.bluez.Error.ConnectionAttemptFailed"))
- error_connection_attempt_failed(pc->conn, pc->msg,
- EIO);
- else
- error_not_supported(pc->conn, pc->msg);
-
- error("GetRemoteServiceRecord: %s(%s)",
- derr.name, derr.message);
- dbus_error_free(&derr);
- goto fail;
- }
-
- if (!dbus_message_get_args(reply, &derr,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len,
- DBUS_TYPE_INVALID)) {
- error_not_supported(pc->conn, pc->msg);
- error("%s: %s", derr.name, derr.message);
- dbus_error_free(&derr);
+ if (err < 0) {
+ error_connection_attempt_failed(pc->conn, pc->msg, -err);
goto fail;
}
- if (len == 0) {
+ if (!recs || !recs->data) {
error_not_supported(pc->conn, pc->msg);
error("Invalid service record length");
goto fail;
}
- rec = sdp_extract_pdu(rec_bin, &scanned);
- if (!rec) {
- error("Can't extract SDP record.");
- error_not_supported(pc->conn, pc->msg);
- goto fail;
- }
-
- if (len != scanned || (sdp_get_access_protos(rec, &protos) < 0)) {
+ rec = recs->data;
+ if (sdp_get_access_protos(rec, &protos) < 0) {
error_not_supported(pc->conn, pc->msg);
goto fail;
}
@@ -468,21 +506,11 @@ static void record_reply(DBusPendingCall *call, void *data)
goto fail;
}
- str2ba(pc->bda, &dst);
+ str2ba(pc->address, &dst);
if (dbus_message_has_member(pc->msg, "CreatePort")) {
- char path[MAX_PATH_LENGTH], port_name[16];
- const char *ppath = path;
sdp_data_t *d;
char *svcname = NULL;
- DBusMessage *reply;
-
- err = rfcomm_bind(&pc->src, &dst, -1, ch);
- if (err < 0) {
- error_failed_errno(pc->conn, pc->msg, -err);
- goto fail;
- }
- snprintf(port_name, sizeof(port_name), "/dev/rfcomm%d", err);
d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
if (d) {
@@ -491,36 +519,16 @@ static void record_reply(DBusPendingCall *call, void *data)
d->unitSize, d->val.str);
}
- port_store(&pc->src, &dst, err, ch, svcname);
+ create_channel_port(pc->conn, pc->msg, pc->adapter,
+ pc->address, svcname, ch, data);
- port_register(pc->conn, err, &pc->src, &dst, port_name,
- path, svcname);
if (svcname)
g_free(svcname);
-
- ports_paths = g_slist_append(ports_paths, g_strdup(path));
-
- reply = dbus_message_new_method_return(pc->msg);
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &ppath,
- DBUS_TYPE_INVALID);
- send_message_and_unref(pc->conn, reply);
-
- dbus_connection_emit_signal(pc->conn, SERIAL_MANAGER_PATH,
- SERIAL_MANAGER_INTERFACE, "PortCreated" ,
- DBUS_TYPE_STRING, &ppath,
- DBUS_TYPE_INVALID);
} else {
/* ConnectService */
pc->channel = ch;
- err = bt_rfcomm_connect(&pc->src, &dst, ch, rfcomm_connect_cb, pc);
- if (err < 0) {
- error("RFCOMM connection failed");
- error_connection_attempt_failed(pc->conn,
- pc->msg, -err);
- goto fail;
- }
+ connect_pending(pc->conn, pc->msg, pc);
/* Wait the connect callback */
goto done;
@@ -529,132 +537,47 @@ static void record_reply(DBusPendingCall *call, void *data)
fail:
pending_connect_remove(pc);
done:
- if (rec)
- sdp_record_free(rec);
- dbus_message_unref(reply);
+ if (recs)
+ sdp_list_free(recs, (sdp_free_func_t) sdp_record_free);
}
-static int get_record(struct pending_connect *pc, uint32_t handle,
- DBusPendingCallNotifyFunction cb)
-{
- DBusMessage *msg;
- DBusPendingCall *call;
-
- msg = dbus_message_new_method_call("org.bluez", pc->adapter_path,
- "org.bluez.Adapter", "GetRemoteServiceRecord");
- if (!msg)
- return -1;
-
- dbus_message_append_args(msg,
- DBUS_TYPE_STRING, &pc->bda,
- DBUS_TYPE_UINT32, &handle,
- DBUS_TYPE_INVALID);
-
- if (!dbus_connection_send_with_reply(pc->conn, msg, &call, -1)) {
- error("Can't send D-Bus message.");
- dbus_message_unref(msg);
- return -1;
- }
-
- dbus_pending_call_set_notify(call, cb, pc, NULL);
- dbus_pending_call_unref(call);
- dbus_message_unref(msg);
-
- return 0;
-}
-
-static void handles_reply(DBusPendingCall *call, void *data)
+static int str2uuid(uuid_t *uuid, const char *string)
{
- struct pending_connect *pc;
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
- DBusError derr;
- uint32_t *phandle;
- int len;
-
- /* Owner exited? */
- if (!g_slist_find(pending_connects, data)) {
- dbus_message_unref(reply);
- return;
- }
-
- pc = data;
- if (pc->canceled) {
- error_canceled(pc->conn, pc->msg, "Connection canceled");
- goto fail;
- }
-
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- /* FIXME : forward error as is */
- if (dbus_error_has_name(&derr,
- "org.bluez.Error.ConnectionAttemptFailed"))
- error_connection_attempt_failed(pc->conn,
- pc->msg, EIO);
- else
- error_not_supported(pc->conn, pc->msg);
-
- error("GetRemoteServiceHandles: %s(%s)",
- derr.name, derr.message);
- dbus_error_free(&derr);
- goto fail;
- }
-
- if (!dbus_message_get_args(reply, &derr,
- DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle,
- &len, DBUS_TYPE_INVALID)) {
- error_not_supported(pc->conn, pc->msg);
- error("%s: %s", derr.name, derr.message);
- dbus_error_free(&derr);
- goto fail;
- }
-
- if (len == 0) {
- error_not_supported(pc->conn, pc->msg);
- goto fail;
- }
-
- if (get_record(pc, *phandle, record_reply) < 0) {
- error_not_supported(pc->conn, pc->msg);
- goto fail;
- }
+ uint16_t data1, data2, data3, data5;
+ uint32_t data0, data4;
- dbus_message_unref(reply);
- return;
-fail:
- dbus_message_unref(reply);
- pending_connect_remove(pc);
-}
+ if (strlen(string) == 36 &&
+ string[8] == '-' &&
+ string[13] == '-' &&
+ string[18] == '-' &&
+ string[23] == '-' &&
+ sscanf(string, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+ &data0, &data1, &data2, &data3, &data4, &data5) == 6) {
+ uint8_t val[16];
-static int get_handles(struct pending_connect *pc, const char *uuid,
- DBusPendingCallNotifyFunction cb)
-{
- DBusMessage *msg;
- DBusPendingCall *call;
+ data0 = htonl(data0);
+ data1 = htons(data1);
+ data2 = htons(data2);
+ data3 = htons(data3);
+ data4 = htonl(data4);
+ data5 = htons(data5);
- msg = dbus_message_new_method_call("org.bluez", pc->adapter_path,
- "org.bluez.Adapter", "GetRemoteServiceHandles");
- if (!msg)
- return -1;
+ memcpy(&val[0], &data0, 4);
+ memcpy(&val[4], &data1, 2);
+ memcpy(&val[6], &data2, 2);
+ memcpy(&val[8], &data3, 2);
+ memcpy(&val[10], &data4, 4);
+ memcpy(&val[14], &data5, 2);
- dbus_message_append_args(msg,
- DBUS_TYPE_STRING, &pc->bda,
- DBUS_TYPE_STRING, &uuid,
- DBUS_TYPE_INVALID);
+ sdp_uuid128_create(uuid, val);
- if (!dbus_connection_send_with_reply(pc->conn, msg, &call, -1)) {
- error("Can't send D-Bus message.");
- dbus_message_unref(msg);
- return -1;
+ return 0;
}
- dbus_pending_call_set_notify(call, cb, pc, NULL);
- dbus_pending_call_unref(call);
- dbus_message_unref(msg);
-
- return 0;
+ return -1;
}
-static int pattern2uuid128(const char *pattern, char *uuid, size_t size)
+static int pattern2uuid(const char *pattern, uuid_t *uuid)
{
uint16_t cls;
int i;
@@ -662,11 +585,7 @@ static int pattern2uuid128(const char *pattern, char *uuid, size_t size)
/* Friendly name */
cls = str2class(pattern);
if (cls) {
- uuid_t uuid16, uuid128;
-
- sdp_uuid16_create(&uuid16, cls);
- sdp_uuid16_to_uuid128(&uuid128, &uuid16);
- sdp_uuid2strn(&uuid128, uuid, size);
+ sdp_uuid16_create(uuid, cls);
return 0;
}
@@ -683,7 +602,7 @@ static int pattern2uuid128(const char *pattern, char *uuid, size_t size)
return -EINVAL;
}
- strncpy(uuid, pattern, size);
+ str2uuid(uuid, pattern);
return 0;
}
@@ -704,21 +623,53 @@ static int pattern2long(const char *pattern, long *pval)
return 0;
}
+static DBusHandlerResult search_uuid(DBusConnection *conn, DBusMessage *msg,
+ const char *adapter, const char *address,
+ const char *pattern, uuid_t *uuid, void *data)
+{
+ struct pending_connect *pc;
+ int err;
+ bdaddr_t src, dst;
+
+ pc = g_new0(struct pending_connect, 1);
+ pc->conn = dbus_connection_ref(conn);
+ pc->msg = dbus_message_ref(msg);
+ pc->adapter = g_strdup(adapter);
+ pc->address = g_strdup(address);
+ pc->id = -1;
+ pc->pattern = g_strdup(pattern);
+
+ str2ba(adapter, &src);
+ str2ba(address, &dst);
+
+ err = bt_search_service(&src, &dst, uuid, record_cb, pc, NULL);
+ if (err < 0) {
+ pending_connect_free(pc);
+ return error_not_supported(conn, msg);
+ }
+
+ pending_connects = g_slist_append(pending_connects, pc);
+ name_listener_add(conn, dbus_message_get_sender(msg),
+ (name_cb_t) transaction_owner_exited, NULL);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
static DBusHandlerResult create_port(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- char path[MAX_PATH_LENGTH], port_name[16], uuid[MAX_LEN_UUID_STR];
- const char *bda, *pattern, *ppath = path;
- struct pending_connect *pending, *pc;
- DBusMessage *reply;
+ const char *address, *pattern;
+ struct pending_connect *pending;
DBusError derr;
- bdaddr_t src, dst;
long val;
- int dev_id, err;
+ uuid_t uuid;
+ char adp[18];
+ int dev_id;
+ bdaddr_t src;
dbus_error_init(&derr);
if (!dbus_message_get_args(msg, &derr,
- DBUS_TYPE_STRING, &bda,
+ DBUS_TYPE_STRING, &address,
DBUS_TYPE_STRING, &pattern,
DBUS_TYPE_INVALID)) {
error_invalid_arguments(conn, msg, derr.message);
@@ -726,92 +677,27 @@ static DBusHandlerResult create_port(DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
}
- pending = find_pending_connect_by_pattern(bda, pattern);
- if (pending)
- return error_in_progress(conn, msg, "Connection in progress");
-
dev_id = hci_get_route(NULL);
- if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0))
+ if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0))
return error_failed(conn, msg, "Adapter not available");
- pc = g_new0(struct pending_connect, 1);
- bacpy(&pc->src, &src);
- pc->conn = dbus_connection_ref(conn);
- pc->msg = dbus_message_ref(msg);
- pc->bda = g_strdup(bda);
- pc->id = -1;
- pc->pattern = g_strdup(pattern);
- pc->adapter_path = g_malloc0(16);
- snprintf(pc->adapter_path, 16, "/org/bluez/hci%d", dev_id);
+ pending = find_pending_connect_by_pattern(address, pattern);
+ if (pending)
+ return error_in_progress(conn, msg, "Connection in progress");
- memset(uuid, 0, sizeof(uuid));
+ ba2str(&src, adp);
/* Friendly name or uuid128 */
- if (pattern2uuid128(pattern, uuid, sizeof(uuid)) == 0) {
- if (get_handles(pc, uuid, handles_reply) < 0) {
- pending_connect_free(pc);
- return error_not_supported(conn, msg);
- }
- pending_connects = g_slist_append(pending_connects, pc);
- name_listener_add(conn, dbus_message_get_sender(msg),
- (name_cb_t) transaction_owner_exited, NULL);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
+ if (pattern2uuid(pattern, &uuid) == 0)
+ return search_uuid(conn, msg, adp, address, pattern, &uuid,
+ data);
- /* Record handle or channel */
- err = pattern2long(pattern, &val);
- if (err < 0) {
- pending_connect_free(pc);
- return error_invalid_arguments(conn, msg, "invalid pattern");
- }
-
- /* Record handle: starts at 0x10000 */
- if (strncasecmp("0x", pattern, 2) == 0) {
- if (val < 0x10000) {
- pending_connect_free(pc);
- return error_invalid_arguments(conn, msg,
- "invalid record handle");
- }
+ /* RFCOMM Channel */
+ if (pattern2long(pattern, &val) == 0)
+ return create_channel_port(conn, msg, adp, address, pattern,
+ val, data);
- if (get_record(pc, val, record_reply) < 0) {
- pending_connect_free(pc);
- return error_not_supported(conn, msg);
- }
- pending_connects = g_slist_append(pending_connects, pc);
- name_listener_add(conn, dbus_message_get_sender(msg),
- (name_cb_t) transaction_owner_exited, NULL);
- return DBUS_HANDLER_RESULT_HANDLED;
- }
-
- pending_connect_free(pc);
- /* RFCOMM Channel range: 1 - 30 */
- if (val < 1 || val > 30)
- return error_invalid_arguments(conn, msg,
- "invalid RFCOMM channel");
-
- str2ba(bda, &dst);
- err = rfcomm_bind(&src, &dst, -1, val);
- if (err < 0)
- return error_failed_errno(conn, msg, -err);
-
- snprintf(port_name, sizeof(port_name), "/dev/rfcomm%d", err);
- port_store(&src, &dst, err, val, NULL);
- port_register(conn, err, &src, &dst, port_name, path, NULL);
- ports_paths = g_slist_append(ports_paths, g_strdup(path));
-
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &ppath,
- DBUS_TYPE_INVALID);
- send_message_and_unref(conn, reply);
-
- dbus_connection_emit_signal(conn, SERIAL_MANAGER_PATH,
- SERIAL_MANAGER_INTERFACE, "PortCreated" ,
- DBUS_TYPE_STRING, &ppath,
- DBUS_TYPE_INVALID);
- return DBUS_HANDLER_RESULT_HANDLED;
+ return error_invalid_arguments(conn, msg, "invalid pattern");
}
static void message_append_paths(DBusMessage *msg, const GSList *list)
@@ -951,42 +837,6 @@ static void add_lang_attr(sdp_record_t *r)
sdp_list_free(langs, 0);
}
-static int str2uuid(uuid_t *uuid, const char *string)
-{
- uint16_t data1, data2, data3, data5;
- uint32_t data0, data4;
-
- if (strlen(string) == 36 &&
- string[8] == '-' &&
- string[13] == '-' &&
- string[18] == '-' &&
- string[23] == '-' &&
- sscanf(string, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
- &data0, &data1, &data2, &data3, &data4, &data5) == 6) {
- uint8_t val[16];
-
- data0 = htonl(data0);
- data1 = htons(data1);
- data2 = htons(data2);
- data3 = htons(data3);
- data4 = htonl(data4);
- data5 = htons(data5);
-
- memcpy(&val[0], &data0, 4);
- memcpy(&val[4], &data1, 2);
- memcpy(&val[6], &data2, 2);
- memcpy(&val[8], &data3, 2);
- memcpy(&val[10], &data4, 4);
- memcpy(&val[14], &data5, 2);
-
- sdp_uuid128_create(uuid, val);
-
- return 0;
- }
-
- return -1;
-}
-
static sdp_record_t *proxy_record_new(const char *uuid128, uint8_t channel)
{
sdp_list_t *apseq, *aproto, *profiles, *proto[2], *root, *svclass_id;
@@ -1847,108 +1697,70 @@ static DBusHandlerResult remove_proxy(DBusConnection *conn,
dbus_message_new_method_return(msg));
}
-static DBusHandlerResult connect_service_from_devid(DBusConnection *conn,
- DBusMessage *msg, void *data, int dev_id,
- const char *bda, const char *pattern)
+static DBusHandlerResult connect_channel(DBusConnection *conn, DBusMessage *msg,
+ const char *adapter, const char *address,
+ const char *pattern, long channel, void *data)
{
- struct pending_connect *pending, *pc;
- bdaddr_t src, dst;
- long val;
- int err;
- char uuid[MAX_LEN_UUID_STR];
-
- pending = find_pending_connect_by_pattern(bda, pattern);
- if (pending)
- return error_in_progress(conn, msg, "Connection in progress");
+ struct pending_connect *pc;
- if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0))
- return error_failed(conn, msg, "Adapter not available");
+ if (channel < 1 || channel > 30)
+ return error_invalid_arguments(conn, msg,
+ "invalid RFCOMM channel");
pc = g_new0(struct pending_connect, 1);
- bacpy(&pc->src, &src);
pc->conn = dbus_connection_ref(conn);
pc->msg = dbus_message_ref(msg);
- pc->bda = g_strdup(bda);
+ pc->adapter = g_strdup(adapter);
+ pc->address = g_strdup(address);
pc->id = -1;
pc->pattern = g_strdup(pattern);
- pc->adapter_path = g_malloc0(16);
- snprintf(pc->adapter_path, 16, "/org/bluez/hci%d", dev_id);
-
- memset(uuid, 0, sizeof(uuid));
-
- /* Friendly name or uuid128 */
- if (pattern2uuid128(pattern, uuid, sizeof(uuid)) == 0) {
- if (get_handles(pc, uuid, handles_reply) < 0) {
- pending_connect_free(pc);
- return error_not_supported(conn, msg);
- }
- pending_connects = g_slist_append(pending_connects, pc);
- goto done;
- }
-
- /* Record handle or channel */
- err = pattern2long(pattern, &val);
- if (err < 0) {
- pending_connect_free(pc);
- return error_invalid_arguments(conn, msg, "invalid pattern");
- }
+ pc->channel = channel;
- /* Record handle: starts at 0x10000 */
- if (strncasecmp("0x", pattern, 2) == 0) {
- if (val < 0x10000) {
- pending_connect_free(pc);
- return error_invalid_arguments(conn, msg,
- "invalid record handle");
- }
-
- if (get_record(pc, val, record_reply) < 0) {
- pending_connect_free(pc);
- return error_not_supported(conn, msg);
- }
- pending_connects = g_slist_append(pending_connects, pc);
- goto done;
- }
+ return connect_pending(conn, msg, pc);
+}
- /* RFCOMM Channel range: 1 - 30 */
- if (val < 1 || val > 30) {
- pending_connect_free(pc);
- return error_invalid_arguments(conn, msg,
- "invalid RFCOMM channel");
- }
+static DBusHandlerResult service_connect(DBusConnection *conn, DBusMessage *msg,
+ const char *adapter, const char *address,
+ const char *pattern, void *data)
+{
+ int dev_id;
+ bdaddr_t src;
+ char adp[18];
+ uuid_t uuid;
+ long val;
- /* Add here since connect() in the first try can happen */
- pending_connects = g_slist_append(pending_connects, pc);
+ if (!adapter)
+ dev_id = hci_get_route(NULL);
+ else
+ dev_id = hci_devid(adapter);
- pc->channel = val;
+ if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0))
+ return error_failed(conn, msg, "Adapter not available");
- str2ba(pc->bda, &dst);
+ ba2str(&src, adp);
- err = bt_rfcomm_connect(&pc->src, &dst, val, rfcomm_connect_cb, pc);
+ /* Friendly name or uuid128 */
+ if (pattern2uuid(pattern, &uuid) == 0)
+ return search_uuid(conn, msg, adp, address, pattern, &uuid,
+ data);
- if (err < 0) {
- const char *strerr = strerror(-err);
- error("RFCOMM connect failed: %s(%d)", strerr, -err);
- pending_connects = g_slist_remove(pending_connects, pc);
- pending_connect_free(pc);
- return error_connection_attempt_failed(conn, msg, -err);
- }
-done:
- name_listener_add(conn, dbus_message_get_sender(msg),
- (name_cb_t) transaction_owner_exited, NULL);
+ /* RFCOMM Channel */
+ if (pattern2long(pattern, &val) == 0)
+ return connect_channel(conn, msg, adp, address, pattern,
+ val, data);
- return DBUS_HANDLER_RESULT_HANDLED;
+ return error_invalid_arguments(conn, msg, "invalid pattern");
}
static DBusHandlerResult connect_service(DBusConnection *conn,
DBusMessage *msg, void *data)
{
DBusError derr;
- const char *bda, *pattern;
- int devid;
+ const char *address, *pattern;
dbus_error_init(&derr);
if (!dbus_message_get_args(msg, &derr,
- DBUS_TYPE_STRING, &bda,
+ DBUS_TYPE_STRING, &address,
DBUS_TYPE_STRING, &pattern,
DBUS_TYPE_INVALID)) {
error_invalid_arguments(conn, msg, derr.message);
@@ -1956,22 +1768,19 @@ static DBusHandlerResult connect_service(DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
}
- devid = hci_get_route(NULL);
-
- return connect_service_from_devid(conn, msg, data, devid, bda, pattern);
+ return service_connect(conn, msg, NULL, address, pattern, data);
}
static DBusHandlerResult connect_service_from_adapter(DBusConnection *conn,
DBusMessage *msg, void *data)
{
DBusError derr;
- const char *adapter, *bda, *pattern;
- int devid;
+ const char *adapter, *address, *pattern;
dbus_error_init(&derr);
if (!dbus_message_get_args(msg, &derr,
DBUS_TYPE_STRING, &adapter,
- DBUS_TYPE_STRING, &bda,
+ DBUS_TYPE_STRING, &address,
DBUS_TYPE_STRING, &pattern,
DBUS_TYPE_INVALID)) {
error_invalid_arguments(conn, msg, derr.message);
@@ -1979,9 +1788,7 @@ static DBusHandlerResult connect_service_from_adapter(DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
}
- devid = hci_devid(adapter);
-
- return connect_service_from_devid(conn, msg, data, devid, bda, pattern);
+ return service_connect(conn, msg, adapter, address, pattern, data);
}
static DBusHandlerResult disconnect_service(DBusConnection *conn,