Commit | Line | Data |
---|---|---|
be21871f AE |
1 | /* |
2 | RFCOMM implementation for Linux Bluetooth stack (BlueZ) | |
1da177e4 LT |
3 | Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com> |
4 | Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org> | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License version 2 as | |
8 | published by the Free Software Foundation; | |
9 | ||
10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
11 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
12 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | |
13 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | |
be21871f AE |
14 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES |
15 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
16 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
1da177e4 LT |
17 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | ||
be21871f AE |
19 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, |
20 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | |
1da177e4 LT |
21 | SOFTWARE IS DISCLAIMED. |
22 | */ | |
23 | ||
dab6b5da ER |
24 | #include <linux/refcount.h> |
25 | ||
1da177e4 LT |
26 | #ifndef __RFCOMM_H |
27 | #define __RFCOMM_H | |
28 | ||
1da177e4 LT |
29 | #define RFCOMM_CONN_TIMEOUT (HZ * 30) |
30 | #define RFCOMM_DISC_TIMEOUT (HZ * 20) | |
31 | #define RFCOMM_AUTH_TIMEOUT (HZ * 25) | |
9e726b17 | 32 | #define RFCOMM_IDLE_TIMEOUT (HZ * 2) |
1da177e4 LT |
33 | |
34 | #define RFCOMM_DEFAULT_MTU 127 | |
35 | #define RFCOMM_DEFAULT_CREDITS 7 | |
36 | ||
1da177e4 LT |
37 | #define RFCOMM_MAX_CREDITS 40 |
38 | ||
39 | #define RFCOMM_SKB_HEAD_RESERVE 8 | |
40 | #define RFCOMM_SKB_TAIL_RESERVE 2 | |
41 | #define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE) | |
42 | ||
43 | #define RFCOMM_SABM 0x2f | |
44 | #define RFCOMM_DISC 0x43 | |
45 | #define RFCOMM_UA 0x63 | |
46 | #define RFCOMM_DM 0x0f | |
47 | #define RFCOMM_UIH 0xef | |
48 | ||
49 | #define RFCOMM_TEST 0x08 | |
50 | #define RFCOMM_FCON 0x28 | |
51 | #define RFCOMM_FCOFF 0x18 | |
52 | #define RFCOMM_MSC 0x38 | |
53 | #define RFCOMM_RPN 0x24 | |
54 | #define RFCOMM_RLS 0x14 | |
55 | #define RFCOMM_PN 0x20 | |
56 | #define RFCOMM_NSC 0x04 | |
57 | ||
58 | #define RFCOMM_V24_FC 0x02 | |
59 | #define RFCOMM_V24_RTC 0x04 | |
60 | #define RFCOMM_V24_RTR 0x08 | |
61 | #define RFCOMM_V24_IC 0x40 | |
62 | #define RFCOMM_V24_DV 0x80 | |
63 | ||
64 | #define RFCOMM_RPN_BR_2400 0x0 | |
65 | #define RFCOMM_RPN_BR_4800 0x1 | |
66 | #define RFCOMM_RPN_BR_7200 0x2 | |
67 | #define RFCOMM_RPN_BR_9600 0x3 | |
68 | #define RFCOMM_RPN_BR_19200 0x4 | |
69 | #define RFCOMM_RPN_BR_38400 0x5 | |
70 | #define RFCOMM_RPN_BR_57600 0x6 | |
71 | #define RFCOMM_RPN_BR_115200 0x7 | |
72 | #define RFCOMM_RPN_BR_230400 0x8 | |
73 | ||
74 | #define RFCOMM_RPN_DATA_5 0x0 | |
75 | #define RFCOMM_RPN_DATA_6 0x1 | |
76 | #define RFCOMM_RPN_DATA_7 0x2 | |
77 | #define RFCOMM_RPN_DATA_8 0x3 | |
78 | ||
79 | #define RFCOMM_RPN_STOP_1 0 | |
80 | #define RFCOMM_RPN_STOP_15 1 | |
81 | ||
82 | #define RFCOMM_RPN_PARITY_NONE 0x0 | |
3a5e903c S |
83 | #define RFCOMM_RPN_PARITY_ODD 0x1 |
84 | #define RFCOMM_RPN_PARITY_EVEN 0x3 | |
85 | #define RFCOMM_RPN_PARITY_MARK 0x5 | |
1da177e4 LT |
86 | #define RFCOMM_RPN_PARITY_SPACE 0x7 |
87 | ||
88 | #define RFCOMM_RPN_FLOW_NONE 0x00 | |
89 | ||
90 | #define RFCOMM_RPN_XON_CHAR 0x11 | |
91 | #define RFCOMM_RPN_XOFF_CHAR 0x13 | |
92 | ||
93 | #define RFCOMM_RPN_PM_BITRATE 0x0001 | |
94 | #define RFCOMM_RPN_PM_DATA 0x0002 | |
95 | #define RFCOMM_RPN_PM_STOP 0x0004 | |
96 | #define RFCOMM_RPN_PM_PARITY 0x0008 | |
97 | #define RFCOMM_RPN_PM_PARITY_TYPE 0x0010 | |
98 | #define RFCOMM_RPN_PM_XON 0x0020 | |
99 | #define RFCOMM_RPN_PM_XOFF 0x0040 | |
100 | #define RFCOMM_RPN_PM_FLOW 0x3F00 | |
101 | ||
102 | #define RFCOMM_RPN_PM_ALL 0x3F7F | |
103 | ||
104 | struct rfcomm_hdr { | |
105 | u8 addr; | |
106 | u8 ctrl; | |
285b4e90 | 107 | u8 len; /* Actual size can be 2 bytes */ |
66c853cc | 108 | } __packed; |
1da177e4 LT |
109 | |
110 | struct rfcomm_cmd { | |
111 | u8 addr; | |
112 | u8 ctrl; | |
113 | u8 len; | |
114 | u8 fcs; | |
66c853cc | 115 | } __packed; |
1da177e4 LT |
116 | |
117 | struct rfcomm_mcc { | |
118 | u8 type; | |
119 | u8 len; | |
66c853cc | 120 | } __packed; |
1da177e4 LT |
121 | |
122 | struct rfcomm_pn { | |
123 | u8 dlci; | |
124 | u8 flow_ctrl; | |
125 | u8 priority; | |
126 | u8 ack_timer; | |
6ba9c755 | 127 | __le16 mtu; |
1da177e4 LT |
128 | u8 max_retrans; |
129 | u8 credits; | |
66c853cc | 130 | } __packed; |
1da177e4 LT |
131 | |
132 | struct rfcomm_rpn { | |
133 | u8 dlci; | |
134 | u8 bit_rate; | |
135 | u8 line_settings; | |
136 | u8 flow_ctrl; | |
137 | u8 xon_char; | |
138 | u8 xoff_char; | |
6ba9c755 | 139 | __le16 param_mask; |
66c853cc | 140 | } __packed; |
1da177e4 LT |
141 | |
142 | struct rfcomm_rls { | |
143 | u8 dlci; | |
144 | u8 status; | |
66c853cc | 145 | } __packed; |
1da177e4 LT |
146 | |
147 | struct rfcomm_msc { | |
148 | u8 dlci; | |
149 | u8 v24_sig; | |
66c853cc | 150 | } __packed; |
1da177e4 LT |
151 | |
152 | /* ---- Core structures, flags etc ---- */ | |
153 | ||
154 | struct rfcomm_session { | |
155 | struct list_head list; | |
156 | struct socket *sock; | |
9e726b17 | 157 | struct timer_list timer; |
1da177e4 LT |
158 | unsigned long state; |
159 | unsigned long flags; | |
1da177e4 LT |
160 | int initiator; |
161 | ||
162 | /* Default DLC parameters */ | |
163 | int cfc; | |
164 | uint mtu; | |
165 | ||
166 | struct list_head dlcs; | |
167 | }; | |
168 | ||
169 | struct rfcomm_dlc { | |
170 | struct list_head list; | |
171 | struct rfcomm_session *session; | |
172 | struct sk_buff_head tx_queue; | |
173 | struct timer_list timer; | |
174 | ||
86aae6c7 | 175 | struct mutex lock; |
1da177e4 LT |
176 | unsigned long state; |
177 | unsigned long flags; | |
dab6b5da | 178 | refcount_t refcnt; |
1da177e4 LT |
179 | u8 dlci; |
180 | u8 addr; | |
181 | u8 priority; | |
182 | u8 v24_sig; | |
8b6b3da7 | 183 | u8 remote_v24_sig; |
1da177e4 | 184 | u8 mscex; |
77db1980 | 185 | u8 out; |
9f2c8a03 MH |
186 | u8 sec_level; |
187 | u8 role_switch; | |
bb23c0ab | 188 | u32 defer_setup; |
1da177e4 LT |
189 | |
190 | uint mtu; | |
191 | uint cfc; | |
192 | uint rx_credits; | |
193 | uint tx_credits; | |
194 | ||
195 | void *owner; | |
196 | ||
197 | void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb); | |
198 | void (*state_change)(struct rfcomm_dlc *d, int err); | |
199 | void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig); | |
200 | }; | |
201 | ||
202 | /* DLC and session flags */ | |
203 | #define RFCOMM_RX_THROTTLED 0 | |
204 | #define RFCOMM_TX_THROTTLED 1 | |
205 | #define RFCOMM_TIMED_OUT 2 | |
bb23c0ab | 206 | #define RFCOMM_MSC_PENDING 3 |
8c84b830 MH |
207 | #define RFCOMM_SEC_PENDING 4 |
208 | #define RFCOMM_AUTH_PENDING 5 | |
209 | #define RFCOMM_AUTH_ACCEPT 6 | |
210 | #define RFCOMM_AUTH_REJECT 7 | |
211 | #define RFCOMM_DEFER_SETUP 8 | |
88149db4 | 212 | #define RFCOMM_ENC_DROP 9 |
1da177e4 LT |
213 | |
214 | /* Scheduling flags and events */ | |
1da177e4 LT |
215 | #define RFCOMM_SCHED_WAKEUP 31 |
216 | ||
217 | /* MSC exchange flags */ | |
218 | #define RFCOMM_MSCEX_TX 1 | |
219 | #define RFCOMM_MSCEX_RX 2 | |
220 | #define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX) | |
221 | ||
222 | /* CFC states */ | |
223 | #define RFCOMM_CFC_UNKNOWN -1 | |
224 | #define RFCOMM_CFC_DISABLED 0 | |
225 | #define RFCOMM_CFC_ENABLED RFCOMM_MAX_CREDITS | |
226 | ||
3a5e903c S |
227 | /* ---- RFCOMM SEND RPN ---- */ |
228 | int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, | |
229 | u8 bit_rate, u8 data_bits, u8 stop_bits, | |
285b4e90 | 230 | u8 parity, u8 flow_ctrl_settings, |
3a5e903c S |
231 | u8 xon_char, u8 xoff_char, u16 param_mask); |
232 | ||
1da177e4 | 233 | /* ---- RFCOMM DLCs (channels) ---- */ |
dd0fc66f | 234 | struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio); |
1da177e4 | 235 | void rfcomm_dlc_free(struct rfcomm_dlc *d); |
5a9d0a3f WR |
236 | int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, |
237 | u8 channel); | |
1da177e4 LT |
238 | int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason); |
239 | int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb); | |
72e5108c | 240 | void rfcomm_dlc_send_noerror(struct rfcomm_dlc *d, struct sk_buff *skb); |
1da177e4 LT |
241 | int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig); |
242 | int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig); | |
bb23c0ab | 243 | void rfcomm_dlc_accept(struct rfcomm_dlc *d); |
c10a848c | 244 | struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel); |
1da177e4 | 245 | |
86aae6c7 LP |
246 | #define rfcomm_dlc_lock(d) mutex_lock(&d->lock) |
247 | #define rfcomm_dlc_unlock(d) mutex_unlock(&d->lock) | |
1da177e4 LT |
248 | |
249 | static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d) | |
250 | { | |
dab6b5da | 251 | refcount_inc(&d->refcnt); |
1da177e4 LT |
252 | } |
253 | ||
254 | static inline void rfcomm_dlc_put(struct rfcomm_dlc *d) | |
255 | { | |
dab6b5da | 256 | if (refcount_dec_and_test(&d->refcnt)) |
1da177e4 LT |
257 | rfcomm_dlc_free(d); |
258 | } | |
259 | ||
e74e58f8 JP |
260 | void __rfcomm_dlc_throttle(struct rfcomm_dlc *d); |
261 | void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d); | |
1da177e4 LT |
262 | |
263 | static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d) | |
264 | { | |
265 | if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags)) | |
266 | __rfcomm_dlc_throttle(d); | |
267 | } | |
268 | ||
269 | static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) | |
270 | { | |
271 | if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags)) | |
272 | __rfcomm_dlc_unthrottle(d); | |
273 | } | |
274 | ||
275 | /* ---- RFCOMM sessions ---- */ | |
5a9d0a3f WR |
276 | void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, |
277 | bdaddr_t *dst); | |
1da177e4 | 278 | |
1da177e4 LT |
279 | /* ---- RFCOMM sockets ---- */ |
280 | struct sockaddr_rc { | |
281 | sa_family_t rc_family; | |
282 | bdaddr_t rc_bdaddr; | |
283 | u8 rc_channel; | |
284 | }; | |
285 | ||
286 | #define RFCOMM_CONNINFO 0x02 | |
287 | struct rfcomm_conninfo { | |
288 | __u16 hci_handle; | |
289 | __u8 dev_class[3]; | |
290 | }; | |
291 | ||
292 | #define RFCOMM_LM 0x03 | |
293 | #define RFCOMM_LM_MASTER 0x0001 | |
294 | #define RFCOMM_LM_AUTH 0x0002 | |
295 | #define RFCOMM_LM_ENCRYPT 0x0004 | |
296 | #define RFCOMM_LM_TRUSTED 0x0008 | |
297 | #define RFCOMM_LM_RELIABLE 0x0010 | |
298 | #define RFCOMM_LM_SECURE 0x0020 | |
2c068e0b | 299 | #define RFCOMM_LM_FIPS 0x0040 |
1da177e4 LT |
300 | |
301 | #define rfcomm_pi(sk) ((struct rfcomm_pinfo *) sk) | |
302 | ||
303 | struct rfcomm_pinfo { | |
304 | struct bt_sock bt; | |
94a86df0 MH |
305 | bdaddr_t src; |
306 | bdaddr_t dst; | |
1da177e4 LT |
307 | struct rfcomm_dlc *dlc; |
308 | u8 channel; | |
9f2c8a03 MH |
309 | u8 sec_level; |
310 | u8 role_switch; | |
1da177e4 LT |
311 | }; |
312 | ||
313 | int rfcomm_init_sockets(void); | |
314 | void rfcomm_cleanup_sockets(void); | |
315 | ||
5a9d0a3f WR |
316 | int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, |
317 | struct rfcomm_dlc **d); | |
1da177e4 LT |
318 | |
319 | /* ---- RFCOMM TTY ---- */ | |
320 | #define RFCOMM_MAX_DEV 256 | |
321 | ||
322 | #define RFCOMMCREATEDEV _IOW('R', 200, int) | |
323 | #define RFCOMMRELEASEDEV _IOW('R', 201, int) | |
324 | #define RFCOMMGETDEVLIST _IOR('R', 210, int) | |
325 | #define RFCOMMGETDEVINFO _IOR('R', 211, int) | |
326 | #define RFCOMMSTEALDLC _IOW('R', 220, int) | |
327 | ||
1c64834e | 328 | /* rfcomm_dev.flags bit definitions */ |
1da177e4 LT |
329 | #define RFCOMM_REUSE_DLC 0 |
330 | #define RFCOMM_RELEASE_ONHUP 1 | |
331 | #define RFCOMM_HANGUP_NOW 2 | |
332 | #define RFCOMM_TTY_ATTACHED 3 | |
1c64834e PH |
333 | #define RFCOMM_DEFUNCT_BIT4 4 /* don't reuse this bit - userspace visible */ |
334 | ||
335 | /* rfcomm_dev.status bit definitions */ | |
336 | #define RFCOMM_DEV_RELEASED 0 | |
80ea7337 | 337 | #define RFCOMM_TTY_OWNED 1 |
1da177e4 LT |
338 | |
339 | struct rfcomm_dev_req { | |
340 | s16 dev_id; | |
341 | u32 flags; | |
342 | bdaddr_t src; | |
343 | bdaddr_t dst; | |
344 | u8 channel; | |
1da177e4 LT |
345 | }; |
346 | ||
347 | struct rfcomm_dev_info { | |
348 | s16 id; | |
349 | u32 flags; | |
350 | u16 state; | |
351 | bdaddr_t src; | |
352 | bdaddr_t dst; | |
353 | u8 channel; | |
354 | }; | |
355 | ||
356 | struct rfcomm_dev_list_req { | |
357 | u16 dev_num; | |
7d2c7ddb | 358 | struct rfcomm_dev_info dev_info[] __counted_by(dev_num); |
1da177e4 LT |
359 | }; |
360 | ||
361 | int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); | |
af0d3b10 DY |
362 | |
363 | #ifdef CONFIG_BT_RFCOMM_TTY | |
1da177e4 LT |
364 | int rfcomm_init_ttys(void); |
365 | void rfcomm_cleanup_ttys(void); | |
af0d3b10 DY |
366 | #else |
367 | static inline int rfcomm_init_ttys(void) | |
368 | { | |
369 | return 0; | |
370 | } | |
371 | static inline void rfcomm_cleanup_ttys(void) | |
372 | { | |
373 | } | |
374 | #endif | |
1da177e4 | 375 | #endif /* __RFCOMM_H */ |