Bluetooth: Add chan->chan_type struct member
chan_type says if our chan is raw(direclty access to HCI), connection less or connection oriented. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
This commit is contained in:
parent
9a91a04a95
commit
715ec005cd
3 changed files with 38 additions and 26 deletions
|
@ -295,6 +295,7 @@ struct l2cap_chan {
|
||||||
__u16 omtu;
|
__u16 omtu;
|
||||||
__u16 flush_to;
|
__u16 flush_to;
|
||||||
__u8 mode;
|
__u8 mode;
|
||||||
|
__u8 chan_type;
|
||||||
|
|
||||||
__le16 sport;
|
__le16 sport;
|
||||||
|
|
||||||
|
@ -384,6 +385,10 @@ struct l2cap_conn {
|
||||||
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
|
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
|
||||||
#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
|
#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
|
||||||
|
|
||||||
|
#define L2CAP_CHAN_RAW 1
|
||||||
|
#define L2CAP_CHAN_CONN_LESS 2
|
||||||
|
#define L2CAP_CHAN_CONN_ORIENTED 3
|
||||||
|
|
||||||
/* ----- L2CAP socket info ----- */
|
/* ----- L2CAP socket info ----- */
|
||||||
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
|
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
|
||||||
|
|
||||||
chan->conn = conn;
|
chan->conn = conn;
|
||||||
|
|
||||||
if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
|
if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
|
||||||
if (conn->hcon->type == LE_LINK) {
|
if (conn->hcon->type == LE_LINK) {
|
||||||
/* LE connection */
|
/* LE connection */
|
||||||
chan->omtu = L2CAP_LE_DEFAULT_MTU;
|
chan->omtu = L2CAP_LE_DEFAULT_MTU;
|
||||||
|
@ -256,7 +256,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
|
||||||
chan->scid = l2cap_alloc_cid(conn);
|
chan->scid = l2cap_alloc_cid(conn);
|
||||||
chan->omtu = L2CAP_DEFAULT_MTU;
|
chan->omtu = L2CAP_DEFAULT_MTU;
|
||||||
}
|
}
|
||||||
} else if (sk->sk_type == SOCK_DGRAM) {
|
} else if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
|
||||||
/* Connectionless socket */
|
/* Connectionless socket */
|
||||||
chan->scid = L2CAP_CID_CONN_LESS;
|
chan->scid = L2CAP_CID_CONN_LESS;
|
||||||
chan->dcid = L2CAP_CID_CONN_LESS;
|
chan->dcid = L2CAP_CID_CONN_LESS;
|
||||||
|
@ -369,8 +369,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
|
||||||
|
|
||||||
case BT_CONNECTED:
|
case BT_CONNECTED:
|
||||||
case BT_CONFIG:
|
case BT_CONFIG:
|
||||||
if ((sk->sk_type == SOCK_SEQPACKET ||
|
if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
|
||||||
sk->sk_type == SOCK_STREAM) &&
|
|
||||||
conn->hcon->type == ACL_LINK) {
|
conn->hcon->type == ACL_LINK) {
|
||||||
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
|
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
|
||||||
l2cap_send_disconn_req(conn, chan, reason);
|
l2cap_send_disconn_req(conn, chan, reason);
|
||||||
|
@ -379,8 +378,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BT_CONNECT2:
|
case BT_CONNECT2:
|
||||||
if ((sk->sk_type == SOCK_SEQPACKET ||
|
if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
|
||||||
sk->sk_type == SOCK_STREAM) &&
|
|
||||||
conn->hcon->type == ACL_LINK) {
|
conn->hcon->type == ACL_LINK) {
|
||||||
struct l2cap_conn_rsp rsp;
|
struct l2cap_conn_rsp rsp;
|
||||||
__u16 result;
|
__u16 result;
|
||||||
|
@ -414,9 +412,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
|
||||||
|
|
||||||
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
|
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
|
||||||
{
|
{
|
||||||
struct sock *sk = chan->sk;
|
if (chan->chan_type == L2CAP_CHAN_RAW) {
|
||||||
|
|
||||||
if (sk->sk_type == SOCK_RAW) {
|
|
||||||
switch (chan->sec_level) {
|
switch (chan->sec_level) {
|
||||||
case BT_SECURITY_HIGH:
|
case BT_SECURITY_HIGH:
|
||||||
return HCI_AT_DEDICATED_BONDING_MITM;
|
return HCI_AT_DEDICATED_BONDING_MITM;
|
||||||
|
@ -657,8 +653,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
||||||
|
|
||||||
bh_lock_sock(sk);
|
bh_lock_sock(sk);
|
||||||
|
|
||||||
if (sk->sk_type != SOCK_SEQPACKET &&
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
|
||||||
sk->sk_type != SOCK_STREAM) {
|
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -852,8 +847,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
|
||||||
sk->sk_state_change(sk);
|
sk->sk_state_change(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sk->sk_type != SOCK_SEQPACKET &&
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
|
||||||
sk->sk_type != SOCK_STREAM) {
|
|
||||||
l2cap_sock_clear_timer(sk);
|
l2cap_sock_clear_timer(sk);
|
||||||
sk->sk_state = BT_CONNECTED;
|
sk->sk_state = BT_CONNECTED;
|
||||||
sk->sk_state_change(sk);
|
sk->sk_state_change(sk);
|
||||||
|
@ -1056,8 +1050,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan)
|
||||||
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
|
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
|
||||||
|
|
||||||
if (hcon->state == BT_CONNECTED) {
|
if (hcon->state == BT_CONNECTED) {
|
||||||
if (sk->sk_type != SOCK_SEQPACKET &&
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
|
||||||
sk->sk_type != SOCK_STREAM) {
|
|
||||||
l2cap_sock_clear_timer(sk);
|
l2cap_sock_clear_timer(sk);
|
||||||
if (l2cap_check_security(chan))
|
if (l2cap_check_security(chan))
|
||||||
sk->sk_state = BT_CONNECTED;
|
sk->sk_state = BT_CONNECTED;
|
||||||
|
@ -1537,13 +1530,12 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
|
||||||
|
|
||||||
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
|
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
|
||||||
{
|
{
|
||||||
struct sock *sk = chan->sk;
|
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
u16 control;
|
u16 control;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Connectionless channel */
|
/* Connectionless channel */
|
||||||
if (sk->sk_type == SOCK_DGRAM) {
|
if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
|
||||||
skb = l2cap_create_connless_pdu(chan, msg, len);
|
skb = l2cap_create_connless_pdu(chan, msg, len);
|
||||||
if (IS_ERR(skb))
|
if (IS_ERR(skb))
|
||||||
return PTR_ERR(skb);
|
return PTR_ERR(skb);
|
||||||
|
@ -1650,7 +1642,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||||
read_lock(&conn->chan_lock);
|
read_lock(&conn->chan_lock);
|
||||||
list_for_each_entry(chan, &conn->chan_l, list) {
|
list_for_each_entry(chan, &conn->chan_l, list) {
|
||||||
struct sock *sk = chan->sk;
|
struct sock *sk = chan->sk;
|
||||||
if (sk->sk_type != SOCK_RAW)
|
if (chan->chan_type != L2CAP_CHAN_RAW)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Don't send frame to the socket it came from */
|
/* Don't send frame to the socket it came from */
|
||||||
|
@ -4100,7 +4092,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
|
||||||
{
|
{
|
||||||
struct sock *sk = chan->sk;
|
struct sock *sk = chan->sk;
|
||||||
|
|
||||||
if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (encrypt == 0x00) {
|
if (encrypt == 0x00) {
|
||||||
|
|
|
@ -162,7 +162,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
||||||
if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
|
if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED
|
||||||
&& !(la.l2_psm || la.l2_cid)) {
|
&& !(la.l2_psm || la.l2_cid)) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -204,8 +204,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PSM must be odd and lsb of upper byte must be 0 */
|
/* PSM must be odd and lsb of upper byte must be 0 */
|
||||||
if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
|
if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && !la.l2_cid &&
|
||||||
sk->sk_type != SOCK_RAW && !la.l2_cid) {
|
chan->chan_type != L2CAP_CHAN_RAW) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -453,8 +453,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case BT_SECURITY:
|
case BT_SECURITY:
|
||||||
if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
|
||||||
&& sk->sk_type != SOCK_RAW) {
|
chan->chan_type != L2CAP_CHAN_RAW) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -599,8 +599,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case BT_SECURITY:
|
case BT_SECURITY:
|
||||||
if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
|
||||||
&& sk->sk_type != SOCK_RAW) {
|
chan->chan_type != L2CAP_CHAN_RAW) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -806,6 +806,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
|
||||||
sk->sk_type = parent->sk_type;
|
sk->sk_type = parent->sk_type;
|
||||||
bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
|
bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
|
||||||
|
|
||||||
|
chan->chan_type = pchan->chan_type;
|
||||||
chan->imtu = pchan->imtu;
|
chan->imtu = pchan->imtu;
|
||||||
chan->omtu = pchan->omtu;
|
chan->omtu = pchan->omtu;
|
||||||
chan->conf_state = pchan->conf_state;
|
chan->conf_state = pchan->conf_state;
|
||||||
|
@ -818,6 +819,20 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
|
||||||
chan->force_reliable = pchan->force_reliable;
|
chan->force_reliable = pchan->force_reliable;
|
||||||
chan->flushable = pchan->flushable;
|
chan->flushable = pchan->flushable;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
switch (sk->sk_type) {
|
||||||
|
case SOCK_RAW:
|
||||||
|
chan->chan_type = L2CAP_CHAN_RAW;
|
||||||
|
break;
|
||||||
|
case SOCK_DGRAM:
|
||||||
|
chan->chan_type = L2CAP_CHAN_CONN_LESS;
|
||||||
|
break;
|
||||||
|
case SOCK_SEQPACKET:
|
||||||
|
case SOCK_STREAM:
|
||||||
|
chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
chan->imtu = L2CAP_DEFAULT_MTU;
|
chan->imtu = L2CAP_DEFAULT_MTU;
|
||||||
chan->omtu = 0;
|
chan->omtu = 0;
|
||||||
if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
|
if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue