1 | /* $NetBSD: rfcomm.h,v 1.18 2014/08/08 03:05:45 rtr Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2006 Itronix Inc. |
5 | * All rights reserved. |
6 | * |
7 | * Written by Iain Hibbert for Itronix Inc. |
8 | * |
9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions |
11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in the |
16 | * documentation and/or other materials provided with the distribution. |
17 | * 3. The name of Itronix Inc. may not be used to endorse |
18 | * or promote products derived from this software without specific |
19 | * prior written permission. |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY |
25 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
26 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
27 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
28 | * ON ANY THEORY OF LIABILITY, WHETHER IN |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 | * POSSIBILITY OF SUCH DAMAGE. |
32 | */ |
33 | /*- |
34 | * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> |
35 | * All rights reserved. |
36 | * |
37 | * Redistribution and use in source and binary forms, with or without |
38 | * modification, are permitted provided that the following conditions |
39 | * are met: |
40 | * 1. Redistributions of source code must retain the above copyright |
41 | * notice, this list of conditions and the following disclaimer. |
42 | * 2. Redistributions in binary form must reproduce the above copyright |
43 | * notice, this list of conditions and the following disclaimer in the |
44 | * documentation and/or other materials provided with the distribution. |
45 | * |
46 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
47 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
48 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
49 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
50 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
51 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
52 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
53 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
54 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
55 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
56 | * SUCH DAMAGE. |
57 | * |
58 | * $Id: rfcomm.h,v 1.18 2014/08/08 03:05:45 rtr Exp $ |
59 | * $FreeBSD: src/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h,v 1.4 2005/01/11 01:39:53 emax Exp $ |
60 | */ |
61 | |
62 | #ifndef _NETBT_RFCOMM_H_ |
63 | #define _NETBT_RFCOMM_H_ |
64 | |
65 | #include <sys/types.h> |
66 | |
67 | /************************************************************************* |
68 | ************************************************************************* |
69 | ** RFCOMM ** |
70 | ************************************************************************* |
71 | *************************************************************************/ |
72 | |
73 | #define RFCOMM_MTU_MAX 32767 |
74 | #define RFCOMM_MTU_MIN 23 |
75 | #define RFCOMM_MTU_DEFAULT 127 |
76 | |
77 | #define RFCOMM_CREDITS_MAX 255 /* in any single packet */ |
78 | #define RFCOMM_CREDITS_DEFAULT 7 /* default initial value */ |
79 | |
80 | #define RFCOMM_CHANNEL_ANY 0 |
81 | #define RFCOMM_CHANNEL_MIN 1 |
82 | #define RFCOMM_CHANNEL_MAX 30 |
83 | |
84 | /* RFCOMM frame types */ |
85 | #define RFCOMM_FRAME_SABM 0x2f |
86 | #define RFCOMM_FRAME_DISC 0x43 |
87 | #define RFCOMM_FRAME_UA 0x63 |
88 | #define RFCOMM_FRAME_DM 0x0f |
89 | #define RFCOMM_FRAME_UIH 0xef |
90 | |
91 | /* RFCOMM MCC commands */ |
92 | #define RFCOMM_MCC_TEST 0x08 /* Test */ |
93 | #define RFCOMM_MCC_FCON 0x28 /* Flow Control on */ |
94 | #define RFCOMM_MCC_FCOFF 0x18 /* Flow Control off */ |
95 | #define RFCOMM_MCC_MSC 0x38 /* Modem Status Command */ |
96 | #define RFCOMM_MCC_RPN 0x24 /* Remote Port Negotiation */ |
97 | #define RFCOMM_MCC_RLS 0x14 /* Remote Line Status */ |
98 | #define RFCOMM_MCC_PN 0x20 /* Port Negotiation */ |
99 | #define RFCOMM_MCC_NSC 0x04 /* Non Supported Command */ |
100 | |
101 | /* RFCOMM modem signals */ |
102 | #define RFCOMM_MSC_FC 0x02 /* Flow Control asserted */ |
103 | #define RFCOMM_MSC_RTC 0x04 /* Ready To Communicate */ |
104 | #define RFCOMM_MSC_RTR 0x08 /* Ready To Receive */ |
105 | #define RFCOMM_MSC_IC 0x40 /* Incomming Call (RING) */ |
106 | #define RFCOMM_MSC_DV 0x80 /* Data Valid */ |
107 | |
108 | /* RPN parameters - baud rate */ |
109 | #define RFCOMM_RPN_BR_2400 0x0 |
110 | #define RFCOMM_RPN_BR_4800 0x1 |
111 | #define RFCOMM_RPN_BR_7200 0x2 |
112 | #define RFCOMM_RPN_BR_9600 0x3 |
113 | #define RFCOMM_RPN_BR_19200 0x4 |
114 | #define RFCOMM_RPN_BR_38400 0x5 |
115 | #define RFCOMM_RPN_BR_57600 0x6 |
116 | #define RFCOMM_RPN_BR_115200 0x7 |
117 | #define RFCOMM_RPN_BR_230400 0x8 |
118 | |
119 | /* RPN parameters - data bits */ |
120 | #define RFCOMM_RPN_DATA_5 0x0 |
121 | #define RFCOMM_RPN_DATA_6 0x1 |
122 | #define RFCOMM_RPN_DATA_7 0x2 |
123 | #define RFCOMM_RPN_DATA_8 0x3 |
124 | |
125 | /* RPN parameters - stop bit */ |
126 | #define RFCOMM_RPN_STOP_1 0 |
127 | #define RFCOMM_RPN_STOP_15 1 |
128 | |
129 | /* RPN parameters - parity enable */ |
130 | #define RFCOMM_RPN_PARITY_NONE 0x0 |
131 | |
132 | /* RPN parameters - parity type */ |
133 | #define RFCOMM_RPN_PARITY_ODD 0x0 |
134 | #define RFCOMM_RPN_PARITY_EVEN 0x1 |
135 | #define RFCOMM_RPN_PARITY_MARK 0x2 |
136 | #define RFCOMM_RPN_PARITY_SPACE 0x3 |
137 | |
138 | /* RPN parameters - default line_setting */ |
139 | #define RFCOMM_RPN_8_N_1 0x03 |
140 | |
141 | /* RPN parameters - flow control */ |
142 | #define RFCOMM_RPN_XON_CHAR 0x11 |
143 | #define RFCOMM_RPN_XOFF_CHAR 0x13 |
144 | #define RFCOMM_RPN_FLOW_NONE 0x00 |
145 | |
146 | /* RPN parameters - mask */ |
147 | #define RFCOMM_RPN_PM_RATE 0x0001 |
148 | #define RFCOMM_RPN_PM_DATA 0x0002 |
149 | #define RFCOMM_RPN_PM_STOP 0x0004 |
150 | #define RFCOMM_RPN_PM_PARITY 0x0008 |
151 | #define RFCOMM_RPN_PM_PTYPE 0x0010 |
152 | #define RFCOMM_RPN_PM_XON 0x0020 |
153 | #define RFCOMM_RPN_PM_XOFF 0x0040 |
154 | |
155 | #define RFCOMM_RPN_PM_FLOW 0x3f00 |
156 | |
157 | #define RFCOMM_RPN_PM_ALL 0x3f7f |
158 | |
159 | /* RFCOMM command frame header */ |
160 | struct rfcomm_cmd_hdr |
161 | { |
162 | uint8_t address; |
163 | uint8_t control; |
164 | uint8_t length; |
165 | uint8_t fcs; |
166 | } __packed; |
167 | |
168 | /* RFCOMM MSC command */ |
169 | struct rfcomm_mcc_msc |
170 | { |
171 | uint8_t address; |
172 | uint8_t modem; |
173 | uint8_t brk; |
174 | } __packed; |
175 | |
176 | /* RFCOMM RPN command */ |
177 | struct rfcomm_mcc_rpn |
178 | { |
179 | uint8_t dlci; |
180 | uint8_t bit_rate; |
181 | uint8_t line_settings; |
182 | uint8_t flow_control; |
183 | uint8_t xon_char; |
184 | uint8_t xoff_char; |
185 | uint16_t param_mask; |
186 | } __packed; |
187 | |
188 | /* RFCOMM RLS command */ |
189 | struct rfcomm_mcc_rls |
190 | { |
191 | uint8_t address; |
192 | uint8_t status; |
193 | } __packed; |
194 | |
195 | /* RFCOMM PN command */ |
196 | struct rfcomm_mcc_pn |
197 | { |
198 | uint8_t dlci; |
199 | uint8_t flow_control; |
200 | uint8_t priority; |
201 | uint8_t ack_timer; |
202 | uint16_t mtu; |
203 | uint8_t max_retrans; |
204 | uint8_t credits; |
205 | } __packed; |
206 | |
207 | /* RFCOMM frame parsing macros */ |
208 | #define RFCOMM_DLCI(b) (((b) & 0xfc) >> 2) |
209 | #define RFCOMM_TYPE(b) (((b) & 0xef)) |
210 | |
211 | #define RFCOMM_EA(b) (((b) & 0x01)) |
212 | #define RFCOMM_CR(b) (((b) & 0x02) >> 1) |
213 | #define RFCOMM_PF(b) (((b) & 0x10) >> 4) |
214 | |
215 | #define RFCOMM_CHANNEL(dlci) (((dlci) >> 1) & 0x2f) |
216 | #define RFCOMM_DIRECTION(dlci) ((dlci) & 0x1) |
217 | |
218 | #define RFCOMM_MKADDRESS(cr, dlci) \ |
219 | ((((dlci) & 0x3f) << 2) | ((cr) << 1) | 0x01) |
220 | |
221 | #define RFCOMM_MKCONTROL(type, pf) ((((type) & 0xef) | ((pf) << 4))) |
222 | #define RFCOMM_MKDLCI(dir, channel) ((((channel) & 0x1f) << 1) | (dir)) |
223 | |
224 | /* RFCOMM MCC macros */ |
225 | #define RFCOMM_MCC_TYPE(b) (((b) & 0xfc) >> 2) |
226 | #define RFCOMM_MCC_LENGTH(b) (((b) & 0xfe) >> 1) |
227 | #define RFCOMM_MKMCC_TYPE(cr, type) ((((type) << 2) | ((cr) << 1) | 0x01)) |
228 | |
229 | /* RPN macros */ |
230 | #define RFCOMM_RPN_DATA_BITS(line) ((line) & 0x3) |
231 | #define RFCOMM_RPN_STOP_BITS(line) (((line) >> 2) & 0x1) |
232 | #define RFCOMM_RPN_PARITY(line) (((line) >> 3) & 0x1) |
233 | |
234 | /************************************************************************* |
235 | ************************************************************************* |
236 | ** SOCK_STREAM RFCOMM sockets ** |
237 | ************************************************************************* |
238 | *************************************************************************/ |
239 | |
240 | /* Socket options */ |
241 | #define SO_RFCOMM_MTU 1 /* mtu */ |
242 | #define SO_RFCOMM_FC_INFO 2 /* flow control info (below) */ |
243 | #define SO_RFCOMM_LM 3 /* link mode */ |
244 | |
245 | /* Flow control information */ |
246 | struct rfcomm_fc_info { |
247 | uint8_t lmodem; /* modem signals (local) */ |
248 | uint8_t rmodem; /* modem signals (remote) */ |
249 | uint8_t tx_cred; /* TX credits */ |
250 | uint8_t rx_cred; /* RX credits */ |
251 | uint8_t cfc; /* credit flow control */ |
252 | uint8_t reserved; |
253 | }; |
254 | |
255 | /* RFCOMM link mode flags */ |
256 | #define RFCOMM_LM_AUTH (1<<0) /* want authentication */ |
257 | #define RFCOMM_LM_ENCRYPT (1<<1) /* want encryption */ |
258 | #define RFCOMM_LM_SECURE (1<<2) /* want secured link */ |
259 | |
260 | #ifdef _KERNEL |
261 | |
262 | /* sysctl variables */ |
263 | extern int rfcomm_sendspace; |
264 | extern int rfcomm_recvspace; |
265 | extern int rfcomm_mtu_default; |
266 | extern int rfcomm_ack_timeout; |
267 | extern int rfcomm_mcc_timeout; |
268 | |
269 | /* |
270 | * Bluetooth RFCOMM session data |
271 | * One L2CAP connection == one RFCOMM session |
272 | */ |
273 | |
274 | /* Credit note */ |
275 | struct rfcomm_credit { |
276 | struct rfcomm_dlc *rc_dlc; /* owner */ |
277 | uint16_t rc_len; /* length */ |
278 | SIMPLEQ_ENTRY(rfcomm_credit) rc_next; /* next credit */ |
279 | }; |
280 | |
281 | /* RFCOMM session data (one L2CAP channel) */ |
282 | struct rfcomm_session { |
283 | struct l2cap_channel *rs_l2cap; /* L2CAP pointer */ |
284 | uint16_t rs_flags; /* session flags */ |
285 | uint16_t rs_state; /* session state */ |
286 | uint16_t rs_mtu; /* default MTU */ |
287 | |
288 | SIMPLEQ_HEAD(,rfcomm_credit) rs_credits; /* credit notes */ |
289 | LIST_HEAD(,rfcomm_dlc) rs_dlcs; /* DLC list */ |
290 | |
291 | callout_t rs_timeout; /* timeout */ |
292 | |
293 | LIST_ENTRY(rfcomm_session) rs_next; /* next session */ |
294 | }; |
295 | |
296 | LIST_HEAD(rfcomm_session_list, rfcomm_session); |
297 | extern struct rfcomm_session_list rfcomm_session_active; |
298 | extern struct rfcomm_session_list rfcomm_session_listen; |
299 | |
300 | /* Session state */ |
301 | #define RFCOMM_SESSION_CLOSED 0 |
302 | #define RFCOMM_SESSION_WAIT_CONNECT 1 |
303 | #define RFCOMM_SESSION_OPEN 2 |
304 | #define RFCOMM_SESSION_WAIT_DISCONNECT 3 |
305 | #define RFCOMM_SESSION_LISTEN 4 |
306 | |
307 | /* Session flags */ |
308 | #define RFCOMM_SESSION_INITIATOR (1 << 0) /* we are initiator */ |
309 | #define RFCOMM_SESSION_CFC (1 << 1) /* credit flow control */ |
310 | #define RFCOMM_SESSION_LFC (1 << 2) /* local flow control */ |
311 | #define RFCOMM_SESSION_RFC (1 << 3) /* remote flow control */ |
312 | #define RFCOMM_SESSION_FREE (1 << 4) /* self lock out for free */ |
313 | |
314 | #define IS_INITIATOR(rs) ((rs)->rs_flags & RFCOMM_SESSION_INITIATOR) |
315 | |
316 | /* Bluetooth RFCOMM DLC data (connection) */ |
317 | struct rfcomm_dlc { |
318 | struct rfcomm_session *rd_session; /* RFCOMM session */ |
319 | uint8_t rd_dlci; /* RFCOMM DLCI */ |
320 | |
321 | uint16_t rd_flags; /* DLC flags */ |
322 | uint16_t rd_state; /* DLC state */ |
323 | uint16_t rd_mtu; /* MTU */ |
324 | int rd_mode; /* link mode */ |
325 | |
326 | struct sockaddr_bt rd_laddr; /* local address */ |
327 | struct sockaddr_bt rd_raddr; /* remote address */ |
328 | |
329 | uint8_t rd_lmodem; /* local modem signls */ |
330 | uint8_t rd_rmodem; /* remote modem signals */ |
331 | |
332 | int rd_rxcred; /* receive credits (sent) */ |
333 | size_t rd_rxsize; /* receive buffer (bytes, avail) */ |
334 | int rd_txcred; /* transmit credits (unused) */ |
335 | int rd_pending; /* packets sent but not complete */ |
336 | |
337 | callout_t rd_timeout; /* timeout */ |
338 | struct mbuf *rd_txbuf; /* transmit buffer */ |
339 | |
340 | const struct btproto *rd_proto; /* upper layer callbacks */ |
341 | void *rd_upper; /* upper layer argument */ |
342 | |
343 | LIST_ENTRY(rfcomm_dlc) rd_next; /* next dlc on session */ |
344 | }; |
345 | |
346 | /* |
347 | * Credit Flow Control works in the following way. |
348 | * |
349 | * txcred is how many packets we can send. Received credit |
350 | * is added to this value, and it is decremented each time |
351 | * we send a packet. |
352 | * |
353 | * rxsize is the number of bytes that are available in the |
354 | * upstream receive buffer. |
355 | * |
356 | * rxcred is the number of credits that we have previously |
357 | * sent that are still unused. This value will be decreased |
358 | * for each packet we receive and we will add to it when we |
359 | * send credits. We calculate the amount of credits to send |
360 | * by the cunning formula "(space / mtu) - sent" so that if |
361 | * we get a bunch of small packets, we can continue sending |
362 | * credits without risking buffer overflow. |
363 | */ |
364 | |
365 | /* DLC flags */ |
366 | #define RFCOMM_DLC_DETACH (1 << 0) /* DLC to be detached */ |
367 | #define RFCOMM_DLC_SHUTDOWN (1 << 1) /* DLC to be shutdown */ |
368 | |
369 | /* DLC state */ |
370 | #define RFCOMM_DLC_CLOSED 0 /* no session */ |
371 | #define RFCOMM_DLC_WAIT_SESSION 1 /* waiting for session */ |
372 | #define RFCOMM_DLC_WAIT_CONNECT 2 /* waiting for connect */ |
373 | #define RFCOMM_DLC_WAIT_SEND_SABM 3 /* waiting to send SABM */ |
374 | #define RFCOMM_DLC_WAIT_SEND_UA 4 /* waiting to send UA */ |
375 | #define RFCOMM_DLC_WAIT_RECV_UA 5 /* waiting to receive UA */ |
376 | #define RFCOMM_DLC_OPEN 6 /* can send/receive */ |
377 | #define RFCOMM_DLC_WAIT_DISCONNECT 7 /* waiting for disconnect */ |
378 | #define RFCOMM_DLC_LISTEN 8 /* listening DLC */ |
379 | |
380 | /* |
381 | * Bluetooth RFCOMM socket kernel prototypes |
382 | */ |
383 | |
384 | struct socket; |
385 | struct sockopt; |
386 | |
387 | /* rfcomm_dlc.c */ |
388 | struct rfcomm_dlc *rfcomm_dlc_lookup(struct rfcomm_session *, int); |
389 | struct rfcomm_dlc *rfcomm_dlc_newconn(struct rfcomm_session *, int); |
390 | void rfcomm_dlc_close(struct rfcomm_dlc *, int); |
391 | void rfcomm_dlc_timeout(void *); |
392 | int rfcomm_dlc_setmode(struct rfcomm_dlc *); |
393 | int rfcomm_dlc_connect(struct rfcomm_dlc *); |
394 | int rfcomm_dlc_open(struct rfcomm_dlc *); |
395 | void rfcomm_dlc_start(struct rfcomm_dlc *); |
396 | |
397 | /* rfcomm_session.c */ |
398 | struct rfcomm_session *rfcomm_session_alloc(struct rfcomm_session_list *, struct sockaddr_bt *); |
399 | struct rfcomm_session *rfcomm_session_lookup(struct sockaddr_bt *, struct sockaddr_bt *); |
400 | void rfcomm_session_free(struct rfcomm_session *); |
401 | int rfcomm_session_send_frame(struct rfcomm_session *, int, int); |
402 | int rfcomm_session_send_uih(struct rfcomm_session *, struct rfcomm_dlc *, int, struct mbuf *); |
403 | int rfcomm_session_send_mcc(struct rfcomm_session *, int, uint8_t, void *, int); |
404 | void rfcomm_init(void); |
405 | |
406 | /* rfcomm_socket.c */ |
407 | int rfcomm_ctloutput(int, struct socket *, struct sockopt *); |
408 | |
409 | /* rfcomm_upper.c */ |
410 | int rfcomm_attach_pcb(struct rfcomm_dlc **, const struct btproto *, void *); |
411 | int rfcomm_bind_pcb(struct rfcomm_dlc *, struct sockaddr_bt *); |
412 | int rfcomm_sockaddr_pcb(struct rfcomm_dlc *, struct sockaddr_bt *); |
413 | int rfcomm_connect_pcb(struct rfcomm_dlc *, struct sockaddr_bt *); |
414 | int rfcomm_peeraddr_pcb(struct rfcomm_dlc *, struct sockaddr_bt *); |
415 | int rfcomm_disconnect_pcb(struct rfcomm_dlc *, int); |
416 | void rfcomm_detach_pcb(struct rfcomm_dlc **); |
417 | int rfcomm_listen_pcb(struct rfcomm_dlc *); |
418 | int rfcomm_send_pcb(struct rfcomm_dlc *, struct mbuf *); |
419 | int rfcomm_rcvd_pcb(struct rfcomm_dlc *, size_t); |
420 | int rfcomm_setopt(struct rfcomm_dlc *, const struct sockopt *); |
421 | int rfcomm_getopt(struct rfcomm_dlc *, struct sockopt *); |
422 | |
423 | #endif /* _KERNEL */ |
424 | |
425 | #endif /* _NETBT_RFCOMM_H_ */ |
426 | |