xref: /netbsd-src/sys/netbt/rfcomm.h (revision ce2c90c7c172d95d2402a5b3d96d8f8e6d138a21)
1 /*	$NetBSD: rfcomm.h,v 1.2 2006/10/01 06:08:08 plunky 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.2 2006/10/01 06:08:08 plunky 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_MIN		1
81 #define RFCOMM_CHANNEL_MAX		30
82 
83 /* RFCOMM frame types */
84 #define RFCOMM_FRAME_SABM		0x2f
85 #define RFCOMM_FRAME_DISC		0x43
86 #define RFCOMM_FRAME_UA			0x63
87 #define RFCOMM_FRAME_DM			0x0f
88 #define RFCOMM_FRAME_UIH		0xef
89 
90 /* RFCOMM MCC commands */
91 #define RFCOMM_MCC_TEST			0x08	/* Test */
92 #define RFCOMM_MCC_FCON			0x28	/* Flow Control on */
93 #define RFCOMM_MCC_FCOFF		0x18	/* Flow Control off */
94 #define RFCOMM_MCC_MSC			0x38	/* Modem Status Command */
95 #define RFCOMM_MCC_RPN			0x24	/* Remote Port Negotiation */
96 #define RFCOMM_MCC_RLS			0x14	/* Remote Line Status */
97 #define RFCOMM_MCC_PN			0x20	/* Port Negotiation */
98 #define RFCOMM_MCC_NSC			0x04	/* Non Supported Command */
99 
100 /* RFCOMM modem signals */
101 #define RFCOMM_MSC_FC			0x02	/* Flow Control asserted */
102 #define RFCOMM_MSC_RTC			0x04	/* Ready To Communicate */
103 #define RFCOMM_MSC_RTR			0x08	/* Ready To Receive */
104 #define RFCOMM_MSC_IC			0x40	/* Incomming Call (RING) */
105 #define RFCOMM_MSC_DV			0x80	/* Data Valid */
106 
107 /* RPN parameters - baud rate */
108 #define RFCOMM_RPN_BR_2400		0x0
109 #define RFCOMM_RPN_BR_4800		0x1
110 #define RFCOMM_RPN_BR_7200		0x2
111 #define RFCOMM_RPN_BR_9600		0x3
112 #define RFCOMM_RPN_BR_19200		0x4
113 #define RFCOMM_RPN_BR_38400		0x5
114 #define RFCOMM_RPN_BR_57600		0x6
115 #define RFCOMM_RPN_BR_115200		0x7
116 #define RFCOMM_RPN_BR_230400		0x8
117 
118 /* RPN parameters - data bits */
119 #define RFCOMM_RPN_DATA_5		0x0
120 #define RFCOMM_RPN_DATA_6		0x1
121 #define RFCOMM_RPN_DATA_7		0x2
122 #define RFCOMM_RPN_DATA_8		0x3
123 
124 /* RPN parameters - stop bit */
125 #define RFCOMM_RPN_STOP_1		0
126 #define RFCOMM_RPN_STOP_15		1
127 
128 /* RPN parameters - parity enable */
129 #define RFCOMM_RPN_PARITY_NONE		0x0
130 
131 /* RPN parameters - parity type */
132 #define RFCOMM_RPN_PARITY_ODD		0x0
133 #define RFCOMM_RPN_PARITY_EVEN		0x1
134 #define RFCOMM_RPN_PARITY_MARK		0x2
135 #define RFCOMM_RPN_PARITY_SPACE		0x3
136 
137 /* RPN parameters - default line_setting */
138 #define RFCOMM_RPN_8_N_1		0x03
139 
140 /* RPN parameters - flow control */
141 #define RFCOMM_RPN_XON_CHAR		0x11
142 #define RFCOMM_RPN_XOFF_CHAR		0x13
143 #define RFCOMM_RPN_FLOW_NONE		0x00
144 
145 /* RPN parameters - mask */
146 #define RFCOMM_RPN_PM_RATE		0x0001
147 #define RFCOMM_RPN_PM_DATA		0x0002
148 #define RFCOMM_RPN_PM_STOP		0x0004
149 #define RFCOMM_RPN_PM_PARITY		0x0008
150 #define RFCOMM_RPN_PM_PTYPE		0x0010
151 #define RFCOMM_RPN_PM_XON		0x0020
152 #define RFCOMM_RPN_PM_XOFF		0x0040
153 
154 #define RFCOMM_RPN_PM_FLOW		0x3f00
155 
156 #define RFCOMM_RPN_PM_ALL		0x3f7f
157 
158 /* RFCOMM command frame header */
159 struct rfcomm_cmd_hdr
160 {
161 	uint8_t		address;
162 	uint8_t		control;
163 	uint8_t		length;
164 	uint8_t		fcs;
165 } __attribute__ ((__packed__));
166 
167 /* RFCOMM MSC command */
168 struct rfcomm_mcc_msc
169 {
170 	uint8_t		address;
171 	uint8_t		modem;
172 	uint8_t		brk;
173 } __attribute__ ((__packed__));
174 
175 /* RFCOMM RPN command */
176 struct rfcomm_mcc_rpn
177 {
178 	uint8_t		dlci;
179 	uint8_t		bit_rate;
180 	uint8_t		line_settings;
181 	uint8_t		flow_control;
182 	uint8_t		xon_char;
183 	uint8_t		xoff_char;
184 	uint16_t	param_mask;
185 } __attribute__ ((__packed__));
186 
187 /* RFCOMM RLS command */
188 struct rfcomm_mcc_rls
189 {
190 	uint8_t		address;
191 	uint8_t		status;
192 } __attribute__ ((__packed__));
193 
194 /* RFCOMM PN command */
195 struct rfcomm_mcc_pn
196 {
197 	uint8_t		dlci;
198 	uint8_t		flow_control;
199 	uint8_t		priority;
200 	uint8_t		ack_timer;
201 	uint16_t	mtu;
202 	uint8_t		max_retrans;
203 	uint8_t		credits;
204 } __attribute__ ((__packed__));
205 
206 /* RFCOMM frame parsing macros */
207 #define RFCOMM_DLCI(b)			(((b) & 0xfc) >> 2)
208 #define RFCOMM_TYPE(b)			(((b) & 0xef))
209 
210 #define RFCOMM_EA(b)			(((b) & 0x01))
211 #define RFCOMM_CR(b)			(((b) & 0x02) >> 1)
212 #define RFCOMM_PF(b)			(((b) & 0x10) >> 4)
213 
214 #define RFCOMM_CHANNEL(dlci)		(((dlci) >> 1) & 0x2f)
215 #define RFCOMM_DIRECTION(dlci)		((dlci) & 0x1)
216 
217 #define RFCOMM_MKADDRESS(cr, dlci) \
218 	((((dlci) & 0x3f) << 2) | ((cr) << 1) | 0x01)
219 
220 #define RFCOMM_MKCONTROL(type, pf)	((((type) & 0xef) | ((pf) << 4)))
221 #define RFCOMM_MKDLCI(dir, channel)	((((channel) & 0x1f) << 1) | (dir))
222 
223 /* RFCOMM MCC macros */
224 #define RFCOMM_MCC_TYPE(b)		(((b) & 0xfc) >> 2)
225 #define RFCOMM_MCC_LENGTH(b)		(((b) & 0xfe) >> 1)
226 #define RFCOMM_MKMCC_TYPE(cr, type)	((((type) << 2) | ((cr) << 1) | 0x01))
227 
228 /* RPN macros */
229 #define RFCOMM_RPN_DATA_BITS(line)	((line) & 0x3)
230 #define RFCOMM_RPN_STOP_BITS(line)	(((line) >> 2) & 0x1)
231 #define RFCOMM_RPN_PARITY(line)		(((line) >> 3) & 0x1)
232 
233 /*************************************************************************
234  *************************************************************************
235  **			SOCK_STREAM RFCOMM sockets			**
236  *************************************************************************
237  *************************************************************************/
238 
239 #define SO_RFCOMM_MTU		1	/* mtu */
240 #define SO_RFCOMM_FC_INFO	2	/* flow control info (below) */
241 
242 /* Flow control information */
243 struct rfcomm_fc_info {
244 	uint8_t		lmodem;		/* modem signals (local) */
245 	uint8_t		rmodem;		/* modem signals (remote) */
246 	uint8_t		tx_cred;	/* TX credits */
247 	uint8_t		rx_cred;	/* RX credits */
248 	uint8_t		cfc;		/* credit flow control */
249 	uint8_t		reserved;
250 };
251 
252 #ifdef _KERNEL
253 
254 /* sysctl variables */
255 extern int rfcomm_sendspace;
256 extern int rfcomm_recvspace;
257 extern int rfcomm_mtu_default;
258 extern int rfcomm_ack_timeout;
259 extern int rfcomm_mcc_timeout;
260 
261 /*
262  * Bluetooth RFCOMM session data
263  * One L2CAP connection == one RFCOMM session
264  */
265 
266 /* Credit note */
267 struct rfcomm_credit {
268 	struct rfcomm_dlc		*rc_dlc;	/* owner */
269 	uint16_t			 rc_len;	/* length */
270 	SIMPLEQ_ENTRY(rfcomm_credit)	 rc_next;	/* next credit */
271 };
272 
273 /* RFCOMM session data (one L2CAP channel) */
274 struct rfcomm_session {
275 	struct l2cap_channel		*rs_l2cap;	/* L2CAP pointer */
276 	uint16_t			 rs_flags;	/* session flags */
277 	uint16_t			 rs_state;	/* session state */
278 	uint16_t			 rs_mtu;	/* default MTU */
279 
280 	SIMPLEQ_HEAD(,rfcomm_credit)	 rs_credits;	/* credit notes */
281 	LIST_HEAD(,rfcomm_dlc)		 rs_dlcs;	/* DLC list */
282 
283 	struct callout			 rs_timeout;	/* timeout */
284 
285 	LIST_ENTRY(rfcomm_session)	 rs_next;	/* next session */
286 };
287 
288 LIST_HEAD(rfcomm_session_list, rfcomm_session);
289 extern struct rfcomm_session_list rfcomm_session_active;
290 extern struct rfcomm_session_list rfcomm_session_listen;
291 
292 /* Session state */
293 #define RFCOMM_SESSION_CLOSED		0
294 #define RFCOMM_SESSION_WAIT_CONNECT	1
295 #define RFCOMM_SESSION_OPEN		2
296 #define RFCOMM_SESSION_WAIT_DISCONNECT	3
297 #define RFCOMM_SESSION_LISTEN		4
298 
299 /* Session flags */
300 #define RFCOMM_SESSION_INITIATOR	(1 << 0) /* we are initiator */
301 #define RFCOMM_SESSION_CFC		(1 << 1) /* credit flow control */
302 #define RFCOMM_SESSION_LFC		(1 << 2) /* local flow control */
303 #define RFCOMM_SESSION_RFC		(1 << 3) /* remote flow control */
304 #define RFCOMM_SESSION_FREE		(1 << 4) /* self lock out for free */
305 
306 #define IS_INITIATOR(rs)	((rs)->rs_flags & RFCOMM_SESSION_INITIATOR)
307 
308 /* Bluetooth RFCOMM DLC data (connection) */
309 struct rfcomm_dlc {
310 	struct rfcomm_session	*rd_session; /* RFCOMM session */
311 	uint8_t			 rd_dlci;    /* RFCOMM DLCI */
312 
313 	uint16_t		 rd_flags;   /* DLC flags */
314 	uint16_t		 rd_state;   /* DLC state */
315 	uint16_t		 rd_mtu;     /* MTU */
316 
317 	struct sockaddr_bt	 rd_laddr;   /* local address */
318 	struct sockaddr_bt	 rd_raddr;   /* remote address */
319 
320 	uint8_t			 rd_lmodem;  /* local modem signls */
321 	uint8_t			 rd_rmodem;  /* remote modem signals */
322 
323 	int			 rd_rxcred;  /* receive credits (sent) */
324 	size_t			 rd_rxsize;  /* receive buffer (bytes, avail) */
325 	int			 rd_txcred;  /* transmit credits (unused) */
326 	int			 rd_pending; /* packets sent but not complete */
327 
328 	struct callout		 rd_timeout; /* timeout */
329 	struct mbuf		*rd_txbuf;   /* transmit buffer */
330 
331 	const struct btproto	*rd_proto;   /* upper layer callbacks */
332 	void			*rd_upper;   /* upper layer argument */
333 
334 	LIST_ENTRY(rfcomm_dlc)	 rd_next;    /* next dlc on session */
335 };
336 
337 /*
338  * Credit Flow Control works in the following way.
339  *
340  * txcred is how many packets we can send. Received credit
341  * is added to this value, and it is decremented each time
342  * we send a packet.
343  *
344  * rxsize is the number of bytes that are available in the
345  * upstream receive buffer.
346  *
347  * rxcred is the number of credits that we have previously
348  * sent that are still unused. This value will be decreased
349  * for each packet we receive and we will add to it when we
350  * send credits. We calculate the amount of credits to send
351  * by the cunning formula "(space / mtu) - sent" so that if
352  * we get a bunch of small packets, we can continue sending
353  * credits without risking buffer overflow.
354  */
355 
356 /* DLC flags */
357 #define RFCOMM_DLC_DETACH		(1 << 0) /* DLC to be detached */
358 #define RFCOMM_DLC_SHUTDOWN		(1 << 1) /* DLC to be shutdown */
359 
360 /* DLC state */
361 #define RFCOMM_DLC_CLOSED		0	/* no session */
362 #define RFCOMM_DLC_WAIT_SESSION		1	/* waiting for session */
363 #define RFCOMM_DLC_WAIT_CONNECT		2	/* waiting for connect */
364 #define RFCOMM_DLC_OPEN			3	/* can send/receive */
365 #define RFCOMM_DLC_WAIT_DISCONNECT	4	/* waiting for disconnect */
366 #define RFCOMM_DLC_LISTEN		5	/* listening DLC */
367 
368 /*
369  * Bluetooth RFCOMM socket kernel prototypes
370  */
371 
372 struct socket;
373 
374 /* rfcomm_dlc.c */
375 struct rfcomm_dlc *rfcomm_dlc_lookup(struct rfcomm_session *, int);
376 struct rfcomm_dlc *rfcomm_dlc_newconn(struct rfcomm_session *, int);
377 void rfcomm_dlc_close(struct rfcomm_dlc *, int);
378 void rfcomm_dlc_timeout(void *);
379 int rfcomm_dlc_connect(struct rfcomm_dlc *);
380 void rfcomm_dlc_start(struct rfcomm_dlc *);
381 
382 /* rfcomm_session.c */
383 struct rfcomm_session *rfcomm_session_alloc(struct rfcomm_session_list *, struct sockaddr_bt *);
384 struct rfcomm_session *rfcomm_session_lookup(struct sockaddr_bt *, struct sockaddr_bt *);
385 void rfcomm_session_free(struct rfcomm_session *);
386 int rfcomm_session_send_frame(struct rfcomm_session *, int, int);
387 int rfcomm_session_send_uih(struct rfcomm_session *, struct rfcomm_dlc *, int, struct mbuf *);
388 int rfcomm_session_send_mcc(struct rfcomm_session *, int, uint8_t, void *, int);
389 
390 /* rfcomm_socket.c */
391 int rfcomm_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);
392 int rfcomm_ctloutput(int, struct socket *, int, int, struct mbuf **);
393 
394 /* rfcomm_upper.c */
395 int rfcomm_attach(struct rfcomm_dlc **, const struct btproto *, void *);
396 int rfcomm_bind(struct rfcomm_dlc *, struct sockaddr_bt *);
397 int rfcomm_sockaddr(struct rfcomm_dlc *, struct sockaddr_bt *);
398 int rfcomm_connect(struct rfcomm_dlc *, struct sockaddr_bt *);
399 int rfcomm_peeraddr(struct rfcomm_dlc *, struct sockaddr_bt *);
400 int rfcomm_disconnect(struct rfcomm_dlc *, int);
401 int rfcomm_detach(struct rfcomm_dlc **);
402 int rfcomm_listen(struct rfcomm_dlc *);
403 int rfcomm_send(struct rfcomm_dlc *, struct mbuf *);
404 int rfcomm_rcvd(struct rfcomm_dlc *, size_t);
405 int rfcomm_setopt(struct rfcomm_dlc *, int, void *);
406 int rfcomm_getopt(struct rfcomm_dlc *, int, void *);
407 
408 #endif /* _KERNEL */
409 
410 #endif /* _NETBT_RFCOMM_H_ */
411