Commit 9e4425fff9e0a0fb6a8c705777ed861f991f8747

Authored by Gustavo F. Padovan
1 parent 7cbc9bd995

Bluetooth: Add l2cap_add_psm() and l2cap_add_scid()

The intention is to get rid of the l2cap_sk_list usage inside
l2cap_core.c. l2cap_sk_list will soon be replaced by a list that does not
depend on socket usage.

Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>

Showing 3 changed files with 59 additions and 33 deletions Side-by-side Diff

include/net/bluetooth/l2cap.h
... ... @@ -458,6 +458,10 @@
458 458 void l2cap_streaming_send(struct l2cap_chan *chan);
459 459 int l2cap_ertm_send(struct l2cap_chan *chan);
460 460  
  461 +struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src);
  462 +int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
  463 +int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
  464 +
461 465 void l2cap_sock_set_timer(struct sock *sk, long timeout);
462 466 void l2cap_sock_clear_timer(struct sock *sk);
463 467 void __l2cap_sock_close(struct sock *sk, int reason);
net/bluetooth/l2cap_core.c
... ... @@ -135,6 +135,50 @@
135 135 return c;
136 136 }
137 137  
  138 +struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
  139 +{
  140 + struct sock *sk;
  141 + struct hlist_node *node;
  142 + sk_for_each(sk, node, &l2cap_sk_list.head) {
  143 + struct l2cap_chan *chan = l2cap_pi(sk)->chan;
  144 +
  145 + if (chan->sport == psm && !bacmp(&bt_sk(sk)->src, src))
  146 + goto found;
  147 + }
  148 +
  149 + sk = NULL;
  150 +found:
  151 + return sk;
  152 +}
  153 +
  154 +int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
  155 +{
  156 + write_lock_bh(&l2cap_sk_list.lock);
  157 +
  158 + if (__l2cap_get_sock_by_addr(psm, src)) {
  159 + write_unlock_bh(&l2cap_sk_list.lock);
  160 + return -EADDRINUSE;
  161 + }
  162 +
  163 + chan->psm = psm;
  164 + chan->sport = psm;
  165 +
  166 + write_unlock_bh(&l2cap_sk_list.lock);
  167 +
  168 + return 0;
  169 +}
  170 +
  171 +int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
  172 +{
  173 + write_lock_bh(&l2cap_sk_list.lock);
  174 +
  175 + chan->scid = scid;
  176 +
  177 + write_unlock_bh(&l2cap_sk_list.lock);
  178 +
  179 + return 0;
  180 +}
  181 +
138 182 static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
139 183 {
140 184 u16 cid = L2CAP_CID_DYN_START;
net/bluetooth/l2cap_sock.c
... ... @@ -78,22 +78,6 @@
78 78 sk_stop_timer(sk, &sk->sk_timer);
79 79 }
80 80  
81   -static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
82   -{
83   - struct sock *sk;
84   - struct hlist_node *node;
85   - sk_for_each(sk, node, &l2cap_sk_list.head) {
86   - struct l2cap_chan *chan = l2cap_pi(sk)->chan;
87   -
88   - if (chan->sport == psm && !bacmp(&bt_sk(sk)->src, src))
89   - goto found;
90   - }
91   -
92   - sk = NULL;
93   -found:
94   - return sk;
95   -}
96   -
97 81 static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
98 82 {
99 83 struct sock *sk = sock->sk;
100 84  
101 85  
102 86  
... ... @@ -136,26 +120,20 @@
136 120 }
137 121 }
138 122  
139   - write_lock_bh(&l2cap_sk_list.lock);
  123 + if (la.l2_cid)
  124 + err = l2cap_add_scid(chan, la.l2_cid);
  125 + else
  126 + err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
140 127  
141   - if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
142   - err = -EADDRINUSE;
143   - } else {
144   - /* Save source address */
145   - bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
146   - chan->psm = la.l2_psm;
147   - chan->sport = la.l2_psm;
148   - sk->sk_state = BT_BOUND;
  128 + if (err < 0)
  129 + goto done;
149 130  
150   - if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
151   - __le16_to_cpu(la.l2_psm) == 0x0003)
152   - chan->sec_level = BT_SECURITY_SDP;
153   - }
  131 + if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
  132 + __le16_to_cpu(la.l2_psm) == 0x0003)
  133 + chan->sec_level = BT_SECURITY_SDP;
154 134  
155   - if (la.l2_cid)
156   - chan->scid = la.l2_cid;
157   -
158   - write_unlock_bh(&l2cap_sk_list.lock);
  135 + bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
  136 + sk->sk_state = BT_BOUND;
159 137  
160 138 done:
161 139 release_sock(sk);