summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/avdtp.c3
-rw-r--r--audio/control.c3
-rw-r--r--audio/device.c5
-rw-r--r--audio/device.h2
-rw-r--r--audio/headset.c7
-rw-r--r--audio/manager.c6
-rw-r--r--audio/manager.h4
-rw-r--r--common/glib-helper.c142
-rw-r--r--common/glib-helper.h3
-rw-r--r--input/device.c9
-rw-r--r--input/manager.c7
-rw-r--r--network/connection.c3
-rw-r--r--serial/manager.c3
13 files changed, 151 insertions, 46 deletions
diff --git a/audio/avdtp.c b/audio/avdtp.c
index 300898e2..7290578b 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -1508,7 +1508,8 @@ failed:
return FALSE;
}
-static void l2cap_connect_cb(GIOChannel *chan, int err, gpointer user_data)
+static void l2cap_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data)
{
struct avdtp *session = user_data;
struct l2cap_options l2o;
diff --git a/audio/control.c b/audio/control.c
index 1777899e..6bf05bef 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -816,7 +816,8 @@ proceed:
return TRUE;
}
-static void avctp_connect_cb(GIOChannel *chan, int err, gpointer data)
+static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer data)
{
struct avctp *session = data;
struct l2cap_options l2o;
diff --git a/audio/device.c b/audio/device.c
index b240bdae..120d45f3 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -72,7 +72,8 @@ static DBusHandlerResult device_get_address(DBusConnection *conn,
return send_message_and_unref(conn, reply);
}
-static char *get_dev_name(DBusConnection *conn, bdaddr_t *src, bdaddr_t *bda)
+static char *get_dev_name(DBusConnection *conn, const bdaddr_t *src,
+ const bdaddr_t *bda)
{
char address[18], filename[PATH_MAX + 1];
@@ -191,7 +192,7 @@ static void device_unregister(DBusConnection *conn, void *data)
}
struct device *device_register(DBusConnection *conn,
- const char *path, bdaddr_t *bda)
+ const char *path, const bdaddr_t *bda)
{
struct device *dev;
bdaddr_t src;
diff --git a/audio/device.h b/audio/device.h
index c5907075..44515bf4 100644
--- a/audio/device.h
+++ b/audio/device.h
@@ -70,7 +70,7 @@ struct device {
};
struct device *device_register(DBusConnection *conn,
- const char *path, bdaddr_t *bda);
+ const char *path, const bdaddr_t *bda);
int device_store(struct device *device, gboolean is_default);
diff --git a/audio/headset.c b/audio/headset.c
index 247d02d4..40a8a0d3 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -288,8 +288,8 @@ static unsigned int connect_cb_new(struct headset *hs,
return cb->id;
}
-static void sco_connect_cb(GIOChannel *chan, int err,
- gpointer user_data)
+static void sco_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data)
{
int sk;
struct device *dev = user_data;
@@ -675,7 +675,8 @@ static gboolean sco_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;
}
-static void rfcomm_connect_cb(GIOChannel *chan, int err, gpointer user_data)
+static void rfcomm_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data)
{
struct device *dev = user_data;
struct headset *hs = dev->headset;
diff --git a/audio/manager.c b/audio/manager.c
index 15136b71..f09125f9 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -122,7 +122,7 @@ static struct enabled_interfaces enabled = {
static DBusHandlerResult get_records(uuid_t *uuid, struct audio_sdp_data *data);
-static struct device *create_device(bdaddr_t *bda)
+static struct device *create_device(const bdaddr_t *bda)
{
static int device_id = 0;
char path[128];
@@ -468,7 +468,7 @@ static DBusHandlerResult resolve_services(DBusMessage *msg,
return get_records(&uuid, sdp_data);
}
-struct device *manager_device_connected(bdaddr_t *bda, const char *uuid)
+struct device *manager_device_connected(const bdaddr_t *bda, const char *uuid)
{
struct device *device;
const char *path;
@@ -1726,7 +1726,7 @@ gboolean manager_authorize(bdaddr_t *dba, const char *uuid,
return TRUE;
}
-struct device *manager_find_device(bdaddr_t *bda, const char *interface,
+struct device *manager_find_device(const bdaddr_t *bda, const char *interface,
gboolean connected)
{
GSList *l;
diff --git a/audio/manager.h b/audio/manager.h
index c8f826ee..acc9c8e2 100644
--- a/audio/manager.h
+++ b/audio/manager.h
@@ -41,10 +41,10 @@ void audio_manager_exit(void);
gboolean server_is_enabled(uint16_t svc);
-struct device *manager_find_device(bdaddr_t *bda, const char *interface,
+struct device *manager_find_device(const bdaddr_t *bda, const char *interface,
gboolean connected);
-struct device *manager_device_connected(bdaddr_t *bda, const char *uuid);
+struct device *manager_device_connected(const bdaddr_t *bda, const char *uuid);
gboolean manager_create_device(bdaddr_t *bda, create_dev_cb_t cb,
void *user_data);
diff --git a/common/glib-helper.c b/common/glib-helper.c
index 93ef262c..69b23d4c 100644
--- a/common/glib-helper.c
+++ b/common/glib-helper.c
@@ -43,6 +43,8 @@
#include "glib-helper.h"
+typedef int (*resolver_t) (int fd, bdaddr_t *src, bdaddr_t *dst);
+
int set_nonblocking(int fd)
{
long arg;
@@ -66,6 +68,7 @@ struct io_context {
int fd;
GIOChannel *io;
bt_io_callback_t cb;
+ resolver_t resolver;
gpointer user_data;
};
@@ -366,18 +369,91 @@ GSList *bt_string2list(const gchar *str)
return l;
}
+static inline int resolve_names(int fd, struct sockaddr *host,
+ struct sockaddr *peer, socklen_t len)
+{
+ int err;
+ socklen_t namelen;
+
+ namelen = len;
+ err = getsockname(fd, host, &namelen);
+ if (err < 0)
+ return err;
+
+ namelen = len;
+ err = getpeername(fd, peer, &namelen);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int rfcomm_resolver(int fd, bdaddr_t *src, bdaddr_t *dst)
+{
+ struct sockaddr_rc host, peer;
+ socklen_t len;
+ int err;
+
+ len = sizeof(host);
+ err = resolve_names(fd, (struct sockaddr *) &host,
+ (struct sockaddr *) &peer, len);
+ if (err < 0)
+ return err;
+
+ bacpy(src, &host.rc_bdaddr);
+ bacpy(dst, &peer.rc_bdaddr);
+
+ return 0;
+}
+
+static int l2cap_resolver(int fd, bdaddr_t *src, bdaddr_t *dst)
+{
+ struct sockaddr_l2 host, peer;
+ socklen_t len;
+ int err;
+
+ len = sizeof(host);
+ err = resolve_names(fd, (struct sockaddr *) &host,
+ (struct sockaddr *) &peer, len);
+ if (err < 0)
+ return err;
+
+ bacpy(src, &host.l2_bdaddr);
+ bacpy(dst, &peer.l2_bdaddr);
+
+ return 0;
+}
+
+static int sco_resolver(int fd, bdaddr_t *src, bdaddr_t *dst)
+{
+ struct sockaddr_sco host, peer;
+ socklen_t len;
+ int err;
+
+ len = sizeof(host);
+ err = resolve_names(fd, (struct sockaddr *) &host,
+ (struct sockaddr *) &peer, len);
+ if (err < 0)
+ return err;
+
+ bacpy(src, &host.sco_bdaddr);
+ bacpy(dst, &peer.sco_bdaddr);
+
+ return 0;
+}
+
static gboolean listen_cb(GIOChannel *chan, GIOCondition cond,
struct io_context *io_ctxt)
{
- int srv_sk, cli_sk, err = 0, ret;
+ int fd, err = 0;
GIOChannel *io;
+ struct sockaddr addr;
socklen_t len;
- struct sockaddr_rc addr;
+ bdaddr_t src, dst;
if (cond & G_IO_NVAL)
return FALSE;
- len = sizeof(ret);
if (cond & (G_IO_HUP | G_IO_ERR)) {
g_io_channel_close(chan);
g_io_channel_unref(chan);
@@ -385,22 +461,31 @@ static gboolean listen_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;
}
- srv_sk = g_io_channel_unix_get_fd(chan);
+ len = sizeof(addr);
+ fd = accept(io_ctxt->fd, &addr, &len);
+ if (fd < 0)
+ goto drop;
- len = sizeof(struct sockaddr_rc);
- cli_sk = accept(srv_sk, (struct sockaddr *) &addr, &len);
- if (cli_sk < 0) {
- if (io_ctxt->cb)
- io_ctxt->cb(NULL, -errno, io_ctxt->user_data);
- return TRUE;
+ if (io_ctxt->resolver) {
+ err = io_ctxt->resolver(fd, &src, &dst);
+ if (err < 0) {
+ close(fd);
+ goto drop;
+ }
}
- io = g_io_channel_unix_new(cli_sk);
+ io = g_io_channel_unix_new(fd);
if (!io)
err = -ENOMEM;
if (io_ctxt->cb)
- io_ctxt->cb(io, err, io_ctxt->user_data);
+ io_ctxt->cb(io, err, &src, &dst, io_ctxt->user_data);
+
+ return TRUE;
+
+drop:
+ if (io_ctxt->cb)
+ io_ctxt->cb(NULL, -errno, NULL, NULL, io_ctxt->user_data);
return TRUE;
}
@@ -426,16 +511,15 @@ static int transport_listen(struct io_context *io_ctxt)
static gboolean connect_cb(GIOChannel *io, GIOCondition cond,
struct io_context *io_ctxt)
{
- int sk, err = 0, ret;
+ int err = 0, ret;
socklen_t len;
+ bdaddr_t src, dst;
if (cond & G_IO_NVAL)
return FALSE;
- sk = g_io_channel_unix_get_fd(io);
-
len = sizeof(ret);
- if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
+ if (getsockopt(io_ctxt->fd, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
err = -errno;
goto done;
}
@@ -445,11 +529,17 @@ static gboolean connect_cb(GIOChannel *io, GIOCondition cond,
goto done;
}
+ if (io_ctxt->resolver) {
+ err = io_ctxt->resolver(io_ctxt->fd, &src, &dst);
+ if (err < 0)
+ goto done;
+ }
+
io_ctxt->io = NULL;
done:
if (io_ctxt->cb)
- io_ctxt->cb(io, err, io_ctxt->user_data);
+ io_ctxt->cb(io, err, &src, &dst, io_ctxt->user_data);
if (io_ctxt->io) {
g_io_channel_close(io_ctxt->io);
g_io_channel_unref(io_ctxt->io);
@@ -682,14 +772,15 @@ static int rfcomm_connect(struct io_context *io_ctxt, const bdaddr_t *src,
return 0;
}
-static int create_io_context(struct io_context **io_ctxt, bt_io_callback_t cb,
- void *user_data)
+static int create_io_context(struct io_context **io_ctxt, gpointer cb,
+ gpointer resolver, gpointer user_data)
{
*io_ctxt = g_try_malloc0(sizeof(struct search_context));
if (!*io_ctxt)
return -ENOMEM;
(*io_ctxt)->cb = cb;
+ (*io_ctxt)->resolver = resolver;
(*io_ctxt)->user_data = user_data;
return 0;
@@ -710,7 +801,7 @@ GIOChannel *bt_rfcomm_listen(const bdaddr_t *src, uint8_t channel, uint32_t flag
struct io_context *io_ctxt;
int err;
- err = create_io_context(&io_ctxt, cb, user_data);
+ err = create_io_context(&io_ctxt, cb, rfcomm_resolver, user_data);
if (err < 0)
return NULL;
@@ -729,7 +820,7 @@ int bt_rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,
struct io_context *io_ctxt;
int err;
- err = create_io_context(&io_ctxt, cb, user_data);
+ err = create_io_context(&io_ctxt, cb, rfcomm_resolver, user_data);
if (err < 0)
return err;
@@ -748,7 +839,7 @@ GIOChannel *bt_l2cap_listen(const bdaddr_t *src, uint16_t psm, uint16_t mtu,
struct io_context *io_ctxt;
int err;
- err = create_io_context(&io_ctxt, cb, user_data);
+ err = create_io_context(&io_ctxt, cb, l2cap_resolver, user_data);
if (err < 0)
return NULL;
@@ -762,12 +853,13 @@ GIOChannel *bt_l2cap_listen(const bdaddr_t *src, uint16_t psm, uint16_t mtu,
}
int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst,
- uint16_t psm, uint16_t mtu, bt_io_callback_t cb, void *user_data)
+ uint16_t psm, uint16_t mtu, bt_io_callback_t cb,
+ void *user_data)
{
struct io_context *io_ctxt;
int err;
- err = create_io_context(&io_ctxt, cb, user_data);
+ err = create_io_context(&io_ctxt, cb, l2cap_resolver, user_data);
if (err < 0)
return err;
@@ -786,7 +878,7 @@ int bt_sco_connect(const bdaddr_t *src, const bdaddr_t *dst,
struct io_context *io_ctxt;
int err;
- err = create_io_context(&io_ctxt, cb, user_data);
+ err = create_io_context(&io_ctxt, cb, sco_resolver, user_data);
if (err < 0)
return err;
diff --git a/common/glib-helper.h b/common/glib-helper.h
index ddc57d4b..1db329ca 100644
--- a/common/glib-helper.h
+++ b/common/glib-helper.h
@@ -23,7 +23,8 @@
int set_nonblocking(int fd);
-typedef void (*bt_io_callback_t) (GIOChannel *io, int err, gpointer user_data);
+typedef void (*bt_io_callback_t) (GIOChannel *io, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data);
typedef void (*bt_callback_t) (sdp_list_t *recs, int err, gpointer user_data);
typedef void (*bt_destroy_t) (gpointer user_data);
diff --git a/input/device.c b/input/device.c
index 131e626d..04cabb0f 100644
--- a/input/device.c
+++ b/input/device.c
@@ -371,7 +371,8 @@ failed:
return FALSE;
}
-static void rfcomm_connect_cb(GIOChannel *chan, int err, gpointer user_data)
+static void rfcomm_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data)
{
struct device *idev = user_data;
struct fake_input *fake;
@@ -553,7 +554,8 @@ cleanup:
return err;
}
-static void interrupt_connect_cb(GIOChannel *chan, int err, gpointer user_data)
+static void interrupt_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data)
{
struct device *idev = user_data;
@@ -594,7 +596,8 @@ cleanup:
idev->pending_connect = NULL;
}
-static void control_connect_cb(GIOChannel *chan, int err, gpointer user_data)
+static void control_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data)
{
struct device *idev = user_data;
diff --git a/input/manager.c b/input/manager.c
index 13ca178d..9ed1f195 100644
--- a/input/manager.c
+++ b/input/manager.c
@@ -212,7 +212,9 @@ static void extract_pnp_record(sdp_record_t *rec, struct hidp_connadd_req *req)
req->version = pdlist ? pdlist->val.uint16 : 0x0000;
}
-static void interrupt_connect_cb(GIOChannel *chan, int err, gpointer user_data)
+static void interrupt_connect_cb(GIOChannel *chan, int err,
+ const bdaddr_t *src, const bdaddr_t *dst,
+ gpointer user_data)
{
struct pending_req *pr = user_data;
struct hidp_connadd_req hidp;
@@ -272,7 +274,8 @@ cleanup:
g_free(hidp.rd_data);
}
-static void control_connect_cb(GIOChannel *chan, int err, gpointer user_data)
+static void control_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data)
{
struct pending_req *pr = user_data;
diff --git a/network/connection.c b/network/connection.c
index e5ed6d9c..057fbba6 100644
--- a/network/connection.c
+++ b/network/connection.c
@@ -222,7 +222,8 @@ out:
return err;
}
-static void connect_cb(GIOChannel *chan, int err, gpointer data)
+static void connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer data)
{
struct network_conn *nc = data;
diff --git a/serial/manager.c b/serial/manager.c
index 2ad0655c..f67a6f89 100644
--- a/serial/manager.c
+++ b/serial/manager.c
@@ -337,7 +337,8 @@ static int rfcomm_bind(bdaddr_t *src, bdaddr_t *dst, int16_t dev_id, uint8_t ch)
return id;
}
-static void rfcomm_connect_cb(GIOChannel *chan, int err_cb, gpointer user_data)
+static void rfcomm_connect_cb(GIOChannel *chan, int err_cb, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer user_data)
{
struct pending_connect *pc = user_data;
struct rfcomm_dev_req req;