struct profile_req {
struct btd_device *device;
struct btd_profile *profile;
- btd_profile_cb cb;
};
static GKeyFile *config = NULL;
}
static struct profile_req *new_profile_request(struct btd_device *dev,
- struct btd_profile *profile,
- btd_profile_cb cb)
+ struct btd_profile *profile)
{
struct profile_req *req;
req = g_new0(struct profile_req, 1);
req->device = dev;
req->profile = profile;
- req->cb = cb;
return req;
}
-static void profile_cb(struct audio_device *dev, int err, void *data)
+static void connect_cb(struct audio_device *dev, int err, void *data)
+{
+ struct profile_req *req = data;
+
+ device_profile_connected(req->device, req->profile, err);
+
+ g_free(req);
+}
+
+static void disconnect_cb(struct audio_device *dev, int err, void *data)
{
struct profile_req *req = data;
- if (req->cb)
- req->cb(req->device, req->profile, err);
+ device_profile_disconnected(req->device, req->profile, err);
g_free(req);
}
return -1;
}
- req = new_profile_request(dev, profile, device_profile_connected);
+ req = new_profile_request(dev, profile);
- err = source_connect(audio_dev, profile_cb, req);
+ err = source_connect(audio_dev, connect_cb, req);
if (err < 0) {
g_free(req);
return err;
return -1;
}
- req = new_profile_request(dev, profile, device_profile_disconnected);
+ req = new_profile_request(dev, profile);
- err = source_disconnect(audio_dev, FALSE, profile_cb, req);
+ err = source_disconnect(audio_dev, FALSE, disconnect_cb, req);
if (err < 0) {
g_free(req);
return err;
return -1;
}
- req = new_profile_request(dev, profile, device_profile_connected);
+ req = new_profile_request(dev, profile);
- err = sink_connect(audio_dev, profile_cb, req);
+ err = sink_connect(audio_dev, connect_cb, req);
if (err < 0) {
g_free(req);
return err;
return -1;
}
- req = new_profile_request(dev, profile, device_profile_disconnected);
+ req = new_profile_request(dev, profile);
- err = sink_disconnect(audio_dev, FALSE, profile_cb, req);
+ err = sink_disconnect(audio_dev, FALSE, disconnect_cb, req);
if (err < 0) {
g_free(req);
return err;
return -1;
}
- req = new_profile_request(dev, profile, device_profile_connected);
+ req = new_profile_request(dev, profile);
- err = control_connect(audio_dev, profile_cb, req);
+ err = control_connect(audio_dev, connect_cb, req);
if (err < 0) {
g_free(req);
return err;
return -1;
}
- req = new_profile_request(dev, profile, device_profile_disconnected);
+ req = new_profile_request(dev, profile);
- err = control_disconnect(audio_dev, profile_cb, req);
+ err = control_disconnect(audio_dev, disconnect_cb, req);
if (err < 0) {
g_free(req);
return err;
struct pending_connect {
struct btd_profile *profile;
- btd_profile_cb cb;
};
struct input_device {
if (err_msg)
error("%s", err_msg);
- pending->cb(idev->device, pending->profile, err);
+ device_profile_connected(idev->device, pending->profile, err);
g_free(pending);
}
idev->pending = g_new0(struct pending_connect, 1);
idev->pending->profile = profile;
- idev->pending->cb = device_profile_connected;
return dev_connect(idev);
}
static gboolean conf_security = TRUE;
-struct connect_req {
- struct btd_profile *profile;
- btd_profile_cb cb;
-};
-
static void read_config(const char *file)
{
GKeyFile *keyfile;
static void connect_profile_cb(struct btd_device *device, int err,
const char *pdev, void *data)
{
- struct connect_req *req = data;
-
- req->cb(device, req->profile, err);
+ struct btd_profile *profile = data;
- g_free(req);
+ device_profile_connected(device, profile, err);
}
static int connect_profile(struct btd_device *dev, struct btd_profile *profile,
- uint16_t id, btd_profile_cb cb)
+ uint16_t id)
{
- struct connect_req *req;
- int err;
-
DBG("path %s id %u", device_get_path(dev), id);
- req = g_new0(struct connect_req, 1);
- req->profile = profile;
- req->cb = cb;
-
- err = connection_connect(dev, id, NULL, connect_profile_cb, req);
- if (err < 0) {
- g_free(req);
- return err;
- }
-
- return 0;
+ return connection_connect(dev, id, NULL, connect_profile_cb, profile);
}
static int disconnect_profile(struct btd_device *dev,
struct btd_profile *profile,
- uint16_t id, btd_profile_cb cb)
+ uint16_t id)
{
int err;
if (err < 0)
return err;
- if (cb)
- cb(dev, profile, 0);
+ device_profile_disconnected(dev, profile, 0);
return 0;
}
static int panu_connect(struct btd_device *dev, struct btd_profile *profile)
{
- return connect_profile(dev, profile, BNEP_SVC_PANU,
- device_profile_connected);
+ return connect_profile(dev, profile, BNEP_SVC_PANU);
}
static int panu_disconnect(struct btd_device *dev, struct btd_profile *profile)
{
- return disconnect_profile(dev, profile, BNEP_SVC_PANU,
- device_profile_disconnected);
+ return disconnect_profile(dev, profile, BNEP_SVC_PANU);
}
static int panu_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
static int gn_connect(struct btd_device *dev, struct btd_profile *profile)
{
- return connect_profile(dev, profile, BNEP_SVC_GN,
- device_profile_connected);
+ return connect_profile(dev, profile, BNEP_SVC_GN);
}
static int gn_disconnect(struct btd_device *dev, struct btd_profile *profile)
{
- return disconnect_profile(dev, profile, BNEP_SVC_GN,
- device_profile_disconnected);
+ return disconnect_profile(dev, profile, BNEP_SVC_GN);
}
static int gn_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
static int nap_connect(struct btd_device *dev, struct btd_profile *profile)
{
- return connect_profile(dev, profile, BNEP_SVC_NAP,
- device_profile_connected);
+ return connect_profile(dev, profile, BNEP_SVC_NAP);
}
static int nap_disconnect(struct btd_device *dev, struct btd_profile *profile)
{
- return disconnect_profile(dev, profile, BNEP_SVC_NAP,
- device_profile_disconnected);
+ return disconnect_profile(dev, profile, BNEP_SVC_NAP);
}
static int nap_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
bool resolving;
bool connected;
- btd_profile_cb cb;
uint16_t version;
uint16_t features;
return FALSE;
}
-static void pending_reply(DBusPendingCall *call, void *user_data)
+static void new_conn_reply(DBusPendingCall *call, void *user_data)
{
struct ext_io *conn = user_data;
struct ext_profile *ext = conn->ext;
conn->pending = NULL;
if (!dbus_error_is_set(&err)) {
- if (conn->cb) {
- conn->cb(conn->device, &ext->p, 0);
- conn->cb = NULL;
- }
-
- if (conn->connected)
- goto disconnect;
-
+ device_profile_connected(conn->device, &ext->p, 0);
conn->connected = true;
return;
}
error("%s replied with an error: %s, %s", ext->name,
err.name, err.message);
- if (conn->cb) {
- conn->cb(conn->device, &ext->p, -ECONNREFUSED);
- conn->cb = NULL;
+ device_profile_connected(conn->device, &ext->p, -ECONNREFUSED);
+
+ if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY))
+ ext_cancel(ext);
+
+ dbus_error_free(&err);
+
+ ext->conns = g_slist_remove(ext->conns, conn);
+ ext_io_destroy(conn);
+}
+
+static void disconn_reply(DBusPendingCall *call, void *user_data)
+{
+ struct ext_io *conn = user_data;
+ struct ext_profile *ext = conn->ext;
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ DBusError err;
+
+ dbus_error_init(&err);
+ dbus_set_error_from_message(&err, reply);
+
+ dbus_message_unref(reply);
+
+ dbus_pending_call_unref(conn->pending);
+ conn->pending = NULL;
+
+ if (!dbus_error_is_set(&err)) {
+ device_profile_disconnected(conn->device, &ext->p, 0);
+ goto disconnect;
}
+ error("%s replied with an error: %s, %s", ext->name,
+ err.name, err.message);
+
+ device_profile_disconnected(conn->device, &ext->p, -ECONNREFUSED);
+
if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY))
ext_cancel(ext);
dbus_message_unref(msg);
- dbus_pending_call_set_notify(conn->pending, pending_reply, conn, NULL);
+ dbus_pending_call_set_notify(conn->pending, new_conn_reply, conn, NULL);
return true;
}
return;
drop:
- if (conn->cb) {
- conn->cb(conn->device, &ext->p, err ? -err->code : -EIO);
- conn->cb = NULL;
- }
+ device_profile_connected(conn->device, &ext->p,
+ err ? -err->code : -EIO);
if (io_err)
g_error_free(io_err);
ext->conns = g_slist_remove(ext->conns, conn);
return;
failed:
- conn->cb(conn->device, &ext->p, err);
+ device_profile_connected(conn->device, &ext->p, err);
ext->conns = g_slist_remove(ext->conns, conn);
ext_io_destroy(conn);
}
conn->adapter = btd_adapter_ref(adapter);
conn->device = btd_device_ref(dev);
- conn->cb = device_profile_connected;
ext->conns = g_slist_append(ext->conns, conn);
dbus_message_unref(msg);
- dbus_pending_call_set_notify(conn->pending, pending_reply, conn, NULL);
+ dbus_pending_call_set_notify(conn->pending, disconn_reply, conn, NULL);
return 0;
}
if (!conn || !conn->connected)
return -ENOTCONN;
- if (conn->cb)
+ if (conn->pending)
return -EBUSY;
err = send_disconn_req(ext, conn);
if (err < 0)
return err;
- conn->cb = device_profile_disconnected;
-
return 0;
}
#define BTD_PROFILE_PRIORITY_MEDIUM 1
#define BTD_PROFILE_PRIORITY_HIGH 2
-struct btd_profile;
-
-typedef void (*btd_profile_cb)(struct btd_device *device,
- struct btd_profile *profile, int err);
-
struct btd_profile {
const char *name;
int priority;