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