Loading include/net/bluetooth/bluetooth.h +18 −0 Original line number Diff line number Diff line Loading @@ -161,12 +161,30 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l { struct sk_buff *skb; release_sock(sk); if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { skb_reserve(skb, BT_SKB_RESERVE); bt_cb(skb)->incoming = 0; } lock_sock(sk); if (!skb && *err) return NULL; *err = sock_error(sk); if (*err) goto out; if (sk->sk_shutdown) { *err = -ECONNRESET; goto out; } return skb; out: kfree_skb(skb); return NULL; } int bt_err(__u16 code); Loading net/bluetooth/l2cap.c +29 −33 Original line number Diff line number Diff line Loading @@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) static void l2cap_streaming_send(struct sock *sk) { struct sk_buff *skb, *tx_skb; struct sk_buff *skb; struct l2cap_pinfo *pi = l2cap_pi(sk); u16 control, fcs; while ((skb = sk->sk_send_head)) { tx_skb = skb_clone(skb, GFP_ATOMIC); control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); while ((skb = skb_dequeue(TX_QUEUE(sk)))) { control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); if (pi->fcs == L2CAP_FCS_CRC16) { fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); fcs = crc16(0, (u8 *)skb->data, skb->len - 2); put_unaligned_le16(fcs, skb->data + skb->len - 2); } l2cap_do_send(sk, tx_skb); l2cap_do_send(sk, skb); pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; if (skb_queue_is_last(TX_QUEUE(sk), skb)) sk->sk_send_head = NULL; else sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); skb = skb_dequeue(TX_QUEUE(sk)); kfree_skb(skb); } } Loading Loading @@ -1960,6 +1950,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us switch (optname) { case L2CAP_OPTIONS: if (sk->sk_state == BT_CONNECTED) { err = -EINVAL; break; } opts.imtu = l2cap_pi(sk)->imtu; opts.omtu = l2cap_pi(sk)->omtu; opts.flush_to = l2cap_pi(sk)->flush_to; Loading Loading @@ -2771,10 +2766,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, case L2CAP_CONF_MTU: if (val < L2CAP_DEFAULT_MIN_MTU) { *result = L2CAP_CONF_UNACCEPT; pi->omtu = L2CAP_DEFAULT_MIN_MTU; pi->imtu = L2CAP_DEFAULT_MIN_MTU; } else pi->omtu = val; l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); pi->imtu = val; l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); break; case L2CAP_CONF_FLUSH_TO: Loading Loading @@ -3071,6 +3066,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd return 0; } static inline void set_default_fcs(struct l2cap_pinfo *pi) { /* FCS is enabled only in ERTM or streaming mode, if one or both * sides request it. */ if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING) pi->fcs = L2CAP_FCS_NONE; else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV)) pi->fcs = L2CAP_FCS_CRC16; } static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; Loading @@ -3088,14 +3094,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!sk) return -ENOENT; if (sk->sk_state != BT_CONFIG) { struct l2cap_cmd_rej rej; rej.reason = cpu_to_le16(0x0002); l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); if (sk->sk_state == BT_DISCONN) goto unlock; } /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); Loading Loading @@ -3135,9 +3135,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr goto unlock; if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; Loading Loading @@ -3225,9 +3223,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; l2cap_pi(sk)->next_tx_seq = 0; Loading net/bluetooth/rfcomm/sock.c +4 −0 Original line number Diff line number Diff line Loading @@ -82,11 +82,14 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb) static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) { struct sock *sk = d->owner, *parent; unsigned long flags; if (!sk) return; BT_DBG("dlc %p state %ld err %d", d, d->state, err); local_irq_save(flags); bh_lock_sock(sk); if (err) Loading @@ -108,6 +111,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) } bh_unlock_sock(sk); local_irq_restore(flags); if (parent && sock_flag(sk, SOCK_ZAPPED)) { /* We have to drop DLC lock here, otherwise Loading Loading
include/net/bluetooth/bluetooth.h +18 −0 Original line number Diff line number Diff line Loading @@ -161,12 +161,30 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l { struct sk_buff *skb; release_sock(sk); if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { skb_reserve(skb, BT_SKB_RESERVE); bt_cb(skb)->incoming = 0; } lock_sock(sk); if (!skb && *err) return NULL; *err = sock_error(sk); if (*err) goto out; if (sk->sk_shutdown) { *err = -ECONNRESET; goto out; } return skb; out: kfree_skb(skb); return NULL; } int bt_err(__u16 code); Loading
net/bluetooth/l2cap.c +29 −33 Original line number Diff line number Diff line Loading @@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) static void l2cap_streaming_send(struct sock *sk) { struct sk_buff *skb, *tx_skb; struct sk_buff *skb; struct l2cap_pinfo *pi = l2cap_pi(sk); u16 control, fcs; while ((skb = sk->sk_send_head)) { tx_skb = skb_clone(skb, GFP_ATOMIC); control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); while ((skb = skb_dequeue(TX_QUEUE(sk)))) { control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); if (pi->fcs == L2CAP_FCS_CRC16) { fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); fcs = crc16(0, (u8 *)skb->data, skb->len - 2); put_unaligned_le16(fcs, skb->data + skb->len - 2); } l2cap_do_send(sk, tx_skb); l2cap_do_send(sk, skb); pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; if (skb_queue_is_last(TX_QUEUE(sk), skb)) sk->sk_send_head = NULL; else sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); skb = skb_dequeue(TX_QUEUE(sk)); kfree_skb(skb); } } Loading Loading @@ -1960,6 +1950,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us switch (optname) { case L2CAP_OPTIONS: if (sk->sk_state == BT_CONNECTED) { err = -EINVAL; break; } opts.imtu = l2cap_pi(sk)->imtu; opts.omtu = l2cap_pi(sk)->omtu; opts.flush_to = l2cap_pi(sk)->flush_to; Loading Loading @@ -2771,10 +2766,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, case L2CAP_CONF_MTU: if (val < L2CAP_DEFAULT_MIN_MTU) { *result = L2CAP_CONF_UNACCEPT; pi->omtu = L2CAP_DEFAULT_MIN_MTU; pi->imtu = L2CAP_DEFAULT_MIN_MTU; } else pi->omtu = val; l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); pi->imtu = val; l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); break; case L2CAP_CONF_FLUSH_TO: Loading Loading @@ -3071,6 +3066,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd return 0; } static inline void set_default_fcs(struct l2cap_pinfo *pi) { /* FCS is enabled only in ERTM or streaming mode, if one or both * sides request it. */ if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING) pi->fcs = L2CAP_FCS_NONE; else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV)) pi->fcs = L2CAP_FCS_CRC16; } static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; Loading @@ -3088,14 +3094,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!sk) return -ENOENT; if (sk->sk_state != BT_CONFIG) { struct l2cap_cmd_rej rej; rej.reason = cpu_to_le16(0x0002); l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); if (sk->sk_state == BT_DISCONN) goto unlock; } /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); Loading Loading @@ -3135,9 +3135,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr goto unlock; if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; Loading Loading @@ -3225,9 +3223,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; l2cap_pi(sk)->next_tx_seq = 0; Loading
net/bluetooth/rfcomm/sock.c +4 −0 Original line number Diff line number Diff line Loading @@ -82,11 +82,14 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb) static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) { struct sock *sk = d->owner, *parent; unsigned long flags; if (!sk) return; BT_DBG("dlc %p state %ld err %d", d, d->state, err); local_irq_save(flags); bh_lock_sock(sk); if (err) Loading @@ -108,6 +111,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) } bh_unlock_sock(sk); local_irq_restore(flags); if (parent && sock_flag(sk, SOCK_ZAPPED)) { /* We have to drop DLC lock here, otherwise Loading