|
@@ -105,13 +105,18 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
|
|
}
|
|
}
|
|
|
|
|
|
/* ---- Socket functions ---- */
|
|
/* ---- Socket functions ---- */
|
|
-static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
|
|
|
|
|
|
+static struct sock *__rfcomm_get_listen_sock_by_addr(u8 channel, bdaddr_t *src)
|
|
{
|
|
{
|
|
struct sock *sk = NULL;
|
|
struct sock *sk = NULL;
|
|
|
|
|
|
sk_for_each(sk, &rfcomm_sk_list.head) {
|
|
sk_for_each(sk, &rfcomm_sk_list.head) {
|
|
- if (rfcomm_pi(sk)->channel == channel &&
|
|
|
|
- !bacmp(&rfcomm_pi(sk)->src, src))
|
|
|
|
|
|
+ if (rfcomm_pi(sk)->channel != channel)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ if (bacmp(&rfcomm_pi(sk)->src, src))
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ if (sk->sk_state == BT_BOUND || sk->sk_state == BT_LISTEN)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -331,6 +336,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
|
|
{
|
|
{
|
|
struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
|
|
struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
|
|
struct sock *sk = sock->sk;
|
|
struct sock *sk = sock->sk;
|
|
|
|
+ int chan = sa->rc_channel;
|
|
int err = 0;
|
|
int err = 0;
|
|
|
|
|
|
BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr);
|
|
BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr);
|
|
@@ -352,12 +358,12 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
|
|
|
|
|
|
write_lock(&rfcomm_sk_list.lock);
|
|
write_lock(&rfcomm_sk_list.lock);
|
|
|
|
|
|
- if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
|
|
|
|
|
|
+ if (chan && __rfcomm_get_listen_sock_by_addr(chan, &sa->rc_bdaddr)) {
|
|
err = -EADDRINUSE;
|
|
err = -EADDRINUSE;
|
|
} else {
|
|
} else {
|
|
/* Save source address */
|
|
/* Save source address */
|
|
bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr);
|
|
bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr);
|
|
- rfcomm_pi(sk)->channel = sa->rc_channel;
|
|
|
|
|
|
+ rfcomm_pi(sk)->channel = chan;
|
|
sk->sk_state = BT_BOUND;
|
|
sk->sk_state = BT_BOUND;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -439,7 +445,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
|
|
write_lock(&rfcomm_sk_list.lock);
|
|
write_lock(&rfcomm_sk_list.lock);
|
|
|
|
|
|
for (channel = 1; channel < 31; channel++)
|
|
for (channel = 1; channel < 31; channel++)
|
|
- if (!__rfcomm_get_sock_by_addr(channel, src)) {
|
|
|
|
|
|
+ if (!__rfcomm_get_listen_sock_by_addr(channel, src)) {
|
|
rfcomm_pi(sk)->channel = channel;
|
|
rfcomm_pi(sk)->channel = channel;
|
|
err = 0;
|
|
err = 0;
|
|
break;
|
|
break;
|