1114878Sjulian/*
2114878Sjulian * ng_btsocket_rfcomm.h
3139823Simp */
4139823Simp
5139823Simp/*-
6114878Sjulian * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7114878Sjulian * All rights reserved.
8114878Sjulian *
9114878Sjulian * Redistribution and use in source and binary forms, with or without
10114878Sjulian * modification, are permitted provided that the following conditions
11114878Sjulian * are met:
12114878Sjulian * 1. Redistributions of source code must retain the above copyright
13114878Sjulian *    notice, this list of conditions and the following disclaimer.
14114878Sjulian * 2. Redistributions in binary form must reproduce the above copyright
15114878Sjulian *    notice, this list of conditions and the following disclaimer in the
16114878Sjulian *    documentation and/or other materials provided with the distribution.
17114878Sjulian *
18114878Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19114878Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20114878Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21114878Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22114878Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23114878Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24114878Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25114878Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26114878Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27114878Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28114878Sjulian * SUCH DAMAGE.
29114878Sjulian *
30114878Sjulian * $Id: ng_btsocket_rfcomm.h,v 1.10 2003/03/29 22:27:42 max Exp $
31114878Sjulian * $FreeBSD$
32114878Sjulian */
33114878Sjulian
34114878Sjulian#ifndef _NETGRAPH_BTSOCKET_RFCOMM_H_
35122634Semax#define _NETGRAPH_BTSOCKET_RFCOMM_H_
36114878Sjulian
37114878Sjulian/*****************************************************************************
38114878Sjulian *****************************************************************************
39114878Sjulian **                              RFCOMM                                     **
40114878Sjulian *****************************************************************************
41114878Sjulian *****************************************************************************/
42114878Sjulian
43114878Sjulian/* XXX FIXME this does not belong here */
44114878Sjulian
45140027Semax#define RFCOMM_DEFAULT_MTU		667
46114878Sjulian#define RFCOMM_MAX_MTU			1024
47114878Sjulian
48114878Sjulian#define RFCOMM_DEFAULT_CREDITS		7
49114878Sjulian#define RFCOMM_MAX_CREDITS		40
50114878Sjulian
51114878Sjulian/* RFCOMM frame types */
52114878Sjulian#define RFCOMM_FRAME_SABM		0x2f
53114878Sjulian#define RFCOMM_FRAME_DISC		0x43
54114878Sjulian#define RFCOMM_FRAME_UA			0x63
55114878Sjulian#define RFCOMM_FRAME_DM			0x0f
56114878Sjulian#define RFCOMM_FRAME_UIH		0xef
57114878Sjulian
58114878Sjulian/* RFCOMM MCC commands */
59114878Sjulian#define RFCOMM_MCC_TEST			0x08 /* Test */
60114878Sjulian#define RFCOMM_MCC_FCON			0x28 /* Flow Control on */
61114878Sjulian#define RFCOMM_MCC_FCOFF		0x18 /* Flow Control off */
62114878Sjulian#define RFCOMM_MCC_MSC			0x38 /* Modem Status Command */
63114878Sjulian#define RFCOMM_MCC_RPN			0x24 /* Remote Port Negotiation */
64114878Sjulian#define RFCOMM_MCC_RLS			0x14 /* Remote Line Status */
65114878Sjulian#define RFCOMM_MCC_PN			0x20 /* Port Negotiation */
66114878Sjulian#define RFCOMM_MCC_NSC			0x04 /* Non Supported Command */
67114878Sjulian
68114878Sjulian/* RFCOMM modem signals */
69114878Sjulian#define RFCOMM_MODEM_FC			0x02 /* Flow Control asserted */
70114878Sjulian#define RFCOMM_MODEM_RTC		0x04 /* Ready To Communicate */
71114878Sjulian#define RFCOMM_MODEM_RTR		0x08 /* Ready To Receive */
72114878Sjulian#define RFCOMM_MODEM_IC			0x40 /* Incomming Call */
73114878Sjulian#define RFCOMM_MODEM_DV			0x80 /* Data Valid */
74114878Sjulian
75114878Sjulian/* RPN parameters - baud rate */
76114878Sjulian#define RFCOMM_RPN_BR_2400		0x0
77114878Sjulian#define RFCOMM_RPN_BR_4800		0x1
78114878Sjulian#define RFCOMM_RPN_BR_7200		0x2
79114878Sjulian#define RFCOMM_RPN_BR_9600		0x3
80114878Sjulian#define RFCOMM_RPN_BR_19200		0x4
81114878Sjulian#define RFCOMM_RPN_BR_38400		0x5
82114878Sjulian#define RFCOMM_RPN_BR_57600		0x6
83114878Sjulian#define RFCOMM_RPN_BR_115200		0x7
84114878Sjulian#define RFCOMM_RPN_BR_230400		0x8
85114878Sjulian
86114878Sjulian/* RPN parameters - data bits */
87114878Sjulian#define RFCOMM_RPN_DATA_5		0x0
88197083Semax#define RFCOMM_RPN_DATA_6		0x2
89197083Semax#define RFCOMM_RPN_DATA_7		0x1
90114878Sjulian#define RFCOMM_RPN_DATA_8		0x3
91114878Sjulian
92114878Sjulian/* RPN parameters - stop bit */
93114878Sjulian#define RFCOMM_RPN_STOP_1		0
94114878Sjulian#define RFCOMM_RPN_STOP_15		1
95114878Sjulian
96114878Sjulian/* RPN parameters - parity */
97114878Sjulian#define RFCOMM_RPN_PARITY_NONE		0x0
98114878Sjulian#define RFCOMM_RPN_PARITY_ODD		0x4
99114878Sjulian#define RFCOMM_RPN_PARITY_EVEN		0x5
100114878Sjulian#define RFCOMM_RPN_PARITY_MARK		0x6
101114878Sjulian#define RFCOMM_RPN_PARITY_SPACE		0x7
102114878Sjulian
103114878Sjulian/* RPN parameters - flow control */
104114878Sjulian#define RFCOMM_RPN_FLOW_NONE		0x00
105114878Sjulian#define RFCOMM_RPN_XON_CHAR		0x11
106114878Sjulian#define RFCOMM_RPN_XOFF_CHAR		0x13
107114878Sjulian
108114878Sjulian/* RPN parameters - mask */
109114878Sjulian#define RFCOMM_RPN_PM_BITRATE		0x0001
110114878Sjulian#define RFCOMM_RPN_PM_DATA		0x0002
111114878Sjulian#define RFCOMM_RPN_PM_STOP		0x0004
112114878Sjulian#define RFCOMM_RPN_PM_PARITY		0x0008
113114878Sjulian#define RFCOMM_RPN_PM_PARITY_TYPE	0x0010
114114878Sjulian#define RFCOMM_RPN_PM_XON		0x0020
115114878Sjulian#define RFCOMM_RPN_PM_XOFF		0x0040
116114878Sjulian#define RFCOMM_RPN_PM_FLOW		0x3F00
117114878Sjulian#define RFCOMM_RPN_PM_ALL		0x3F7F
118114878Sjulian
119114878Sjulian/* RFCOMM frame header */
120114878Sjulianstruct rfcomm_frame_hdr
121114878Sjulian{
122114878Sjulian	u_int8_t	address;
123114878Sjulian	u_int8_t	control;
124114878Sjulian	u_int8_t	length;	/* Actual size could be 2 bytes */
125114878Sjulian} __attribute__ ((packed));
126114878Sjulian
127114878Sjulian/* RFCOMM command frame header */
128114878Sjulianstruct rfcomm_cmd_hdr
129114878Sjulian{
130114878Sjulian	u_int8_t	address;
131114878Sjulian	u_int8_t	control;
132114878Sjulian	u_int8_t	length;
133114878Sjulian	u_int8_t	fcs;
134114878Sjulian} __attribute__ ((packed));
135114878Sjulian
136114878Sjulian/* RFCOMM MCC command header */
137114878Sjulianstruct rfcomm_mcc_hdr
138114878Sjulian{
139114878Sjulian	u_int8_t	type;
140114878Sjulian	u_int8_t	length; /* XXX FIXME Can actual size be 2 bytes?? */
141114878Sjulian} __attribute__ ((packed));
142114878Sjulian
143114878Sjulian/* RFCOMM MSC command */
144114878Sjulianstruct rfcomm_mcc_msc
145114878Sjulian{
146114878Sjulian	u_int8_t	address;
147114878Sjulian	u_int8_t	modem;
148114878Sjulian} __attribute__ ((packed));
149114878Sjulian
150114878Sjulian/* RFCOMM RPN command */
151114878Sjulianstruct rfcomm_mcc_rpn
152114878Sjulian{
153114878Sjulian	u_int8_t	dlci;
154114878Sjulian	u_int8_t	bit_rate;
155114878Sjulian	u_int8_t	line_settings;
156114878Sjulian	u_int8_t	flow_control;
157114878Sjulian	u_int8_t	xon_char;
158114878Sjulian	u_int8_t	xoff_char;
159114878Sjulian	u_int16_t	param_mask;
160114878Sjulian} __attribute__ ((packed));
161114878Sjulian
162114878Sjulian/* RFCOMM RLS command */
163114878Sjulianstruct rfcomm_mcc_rls
164114878Sjulian{
165114878Sjulian	u_int8_t	address;
166114878Sjulian	u_int8_t	status;
167114878Sjulian} __attribute__ ((packed));
168114878Sjulian
169114878Sjulian/* RFCOMM PN command */
170114878Sjulianstruct rfcomm_mcc_pn
171114878Sjulian{
172114878Sjulian	u_int8_t	dlci;
173114878Sjulian	u_int8_t	flow_control;
174114878Sjulian	u_int8_t	priority;
175114878Sjulian	u_int8_t	ack_timer;
176114878Sjulian	u_int16_t	mtu;
177114878Sjulian	u_int8_t	max_retrans;
178114878Sjulian	u_int8_t	credits;
179114878Sjulian} __attribute__ ((packed));
180114878Sjulian
181114878Sjulian/* RFCOMM frame parsing macros */
182114878Sjulian#define RFCOMM_DLCI(b)			(((b) & 0xfc) >> 2)
183114878Sjulian#define RFCOMM_CHANNEL(b)		(((b) & 0xf8) >> 3)
184114878Sjulian#define RFCOMM_DIRECTION(b)		(((b) & 0x04) >> 2)
185114878Sjulian#define RFCOMM_TYPE(b)			(((b) & 0xef))
186114878Sjulian
187114878Sjulian#define RFCOMM_EA(b)			(((b) & 0x01))
188114878Sjulian#define RFCOMM_CR(b)			(((b) & 0x02) >> 1)
189114878Sjulian#define RFCOMM_PF(b)			(((b) & 0x10) >> 4)
190114878Sjulian
191114878Sjulian#define RFCOMM_SRVCHANNEL(dlci)		((dlci) >> 1)
192114878Sjulian
193114878Sjulian#define RFCOMM_MKADDRESS(cr, dlci) \
194114878Sjulian	((((dlci) & 0x3f) << 2) | ((cr) << 1) | 0x01)
195114878Sjulian
196114878Sjulian#define RFCOMM_MKCONTROL(type, pf)	((((type) & 0xef) | ((pf) << 4)))
197114878Sjulian#define RFCOMM_MKDLCI(dir, channel)	((((channel) & 0x1f) << 1) | (dir))
198114878Sjulian
199114878Sjulian#define RFCOMM_MKLEN8(len)		(((len) << 1) | 1)
200114878Sjulian#define RFCOMM_MKLEN16(len)		((len) << 1)
201114878Sjulian
202114878Sjulian/* RFCOMM MCC macros */
203114878Sjulian#define RFCOMM_MCC_TYPE(b)		(((b) & 0xfc) >> 2)
204114878Sjulian#define RFCOMM_MCC_LENGTH(b)		(((b) & 0xfe) >> 1)
205114878Sjulian#define RFCOMM_MKMCC_TYPE(cr, type)	((((type) << 2) | ((cr) << 1) | 0x01))
206114878Sjulian
207114878Sjulian/* RPN macros */
208114878Sjulian#define RFCOMM_RPN_DATA_BITS(line)	((line) & 0x3)
209114878Sjulian#define RFCOMM_RPN_STOP_BITS(line)	(((line) >> 2) & 0x1)
210114878Sjulian#define RFCOMM_RPN_PARITY(line)		(((line) >> 3) & 0x3)
211114878Sjulian#define RFCOMM_MKRPN_LINE_SETTINGS(data, stop, parity) \
212114878Sjulian	(((data) & 0x3) | (((stop) & 0x1) << 2) | (((parity) & 0x3) << 3))
213114878Sjulian
214114878Sjulian/*****************************************************************************
215114878Sjulian *****************************************************************************
216114878Sjulian **                      SOCK_STREAM RFCOMM sockets                         **
217114878Sjulian *****************************************************************************
218114878Sjulian *****************************************************************************/
219114878Sjulian
220114878Sjulian#define NG_BTSOCKET_RFCOMM_SENDSPACE \
221140027Semax	(RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 2)
222114878Sjulian#define NG_BTSOCKET_RFCOMM_RECVSPACE \
223140027Semax	(RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 2)
224114878Sjulian
225114878Sjulian/*
226114878Sjulian * Bluetooth RFCOMM session. One L2CAP connection == one RFCOMM session
227114878Sjulian */
228114878Sjulian
229114878Sjulianstruct ng_btsocket_rfcomm_pcb;
230114878Sjulianstruct ng_btsocket_rfcomm_session;
231114878Sjulian
232114878Sjulianstruct ng_btsocket_rfcomm_session {
233114878Sjulian	struct socket				*l2so;	 /* L2CAP socket */
234114878Sjulian
235114878Sjulian	u_int16_t				 state;  /* session state */
236114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_CLOSED	 0
237114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_LISTENING	 1
238114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_CONNECTING	 2
239114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_CONNECTED	 3
240114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_OPEN		 4
241114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING 5
242114878Sjulian
243114878Sjulian	u_int16_t				 flags;  /* session flags */
244114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_INITIATOR	(1 << 0) /* initiator */
245114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_LFC		(1 << 1) /* local flow */
246114878Sjulian#define NG_BTSOCKET_RFCOMM_SESSION_RFC		(1 << 2) /* remote flow */
247114878Sjulian
248114878Sjulian#define INITIATOR(s) \
249114878Sjulian	(((s)->flags & NG_BTSOCKET_RFCOMM_SESSION_INITIATOR)? 1 : 0)
250114878Sjulian
251114878Sjulian	u_int16_t				 mtu;    /* default MTU */
252114878Sjulian	struct ng_bt_mbufq			 outq;   /* outgoing queue */
253114878Sjulian
254114878Sjulian	struct mtx				 session_mtx; /* session lock */
255114878Sjulian	LIST_HEAD(, ng_btsocket_rfcomm_pcb)	 dlcs;	 /* active DLC */
256114878Sjulian
257114878Sjulian	LIST_ENTRY(ng_btsocket_rfcomm_session)	 next;	 /* link to next */
258114878Sjulian};
259114878Sjuliantypedef struct ng_btsocket_rfcomm_session	ng_btsocket_rfcomm_session_t;
260114878Sjuliantypedef struct ng_btsocket_rfcomm_session *	ng_btsocket_rfcomm_session_p;
261114878Sjulian
262114878Sjulian/*
263114878Sjulian * Bluetooth RFCOMM socket PCB (DLC)
264114878Sjulian */
265114878Sjulian
266114878Sjulianstruct ng_btsocket_rfcomm_pcb {
267114878Sjulian	struct socket				*so;	  /* RFCOMM socket */
268114878Sjulian	struct ng_btsocket_rfcomm_session	*session; /* RFCOMM session */
269114878Sjulian
270114878Sjulian	u_int16_t				 flags;   /* DLC flags */
271114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_TIMO		(1 << 0)  /* timeout pending */
272114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_CFC		(1 << 1)  /* credit flow ctrl */
273114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT		(1 << 2)  /* timeout happend */
274114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_DETACHED		(1 << 3)  /* DLC detached */
275114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_SENDING		(1 << 4)  /* send pending */
276114878Sjulian
277114878Sjulian	u_int16_t				 state;   /* DLC state */
278114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_CLOSED		0
279114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT	1
280114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_CONFIGURING	2
281114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_CONNECTING	3
282114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_CONNECTED	4
283114878Sjulian#define NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING	5
284114878Sjulian
285114878Sjulian	bdaddr_t				 src;     /* source address */
286114878Sjulian	bdaddr_t				 dst;     /* dest. address */
287114878Sjulian
288114878Sjulian	u_int8_t				 channel; /* RFCOMM channel */
289114878Sjulian	u_int8_t				 dlci;    /* RFCOMM DLCI */
290114878Sjulian
291114878Sjulian	u_int8_t				 lmodem;  /* local mdm signls */
292114878Sjulian	u_int8_t				 rmodem;  /* remote -/- */
293114878Sjulian
294114878Sjulian	u_int16_t				 mtu;	  /* MTU */
295114878Sjulian	int16_t					 rx_cred; /* RX credits */
296114878Sjulian	int16_t					 tx_cred; /* TX credits */
297114878Sjulian
298114878Sjulian	struct mtx				 pcb_mtx; /* PCB lock */
299114878Sjulian	struct callout_handle			 timo;    /* timeout */
300114878Sjulian
301114878Sjulian	LIST_ENTRY(ng_btsocket_rfcomm_pcb)	 session_next;/* link to next */
302114878Sjulian	LIST_ENTRY(ng_btsocket_rfcomm_pcb)	 next;	  /* link to next */
303114878Sjulian};
304114878Sjuliantypedef struct ng_btsocket_rfcomm_pcb	ng_btsocket_rfcomm_pcb_t;
305114878Sjuliantypedef struct ng_btsocket_rfcomm_pcb *	ng_btsocket_rfcomm_pcb_p;
306114878Sjulian
307114878Sjulian#define	so2rfcomm_pcb(so) \
308114878Sjulian	((struct ng_btsocket_rfcomm_pcb *)((so)->so_pcb))
309114878Sjulian
310114878Sjulian/*
311114878Sjulian * Bluetooth RFCOMM socket methods
312114878Sjulian */
313114878Sjulian
314114878Sjulian#ifdef _KERNEL
315114878Sjulian
316114878Sjulianvoid ng_btsocket_rfcomm_init       (void);
317157366Srwatsonvoid ng_btsocket_rfcomm_abort      (struct socket *);
318160549Srwatsonvoid ng_btsocket_rfcomm_close      (struct socket *);
319114878Sjulianint  ng_btsocket_rfcomm_accept     (struct socket *, struct sockaddr **);
320114878Sjulianint  ng_btsocket_rfcomm_attach     (struct socket *, int, struct thread *);
321114878Sjulianint  ng_btsocket_rfcomm_bind       (struct socket *, struct sockaddr *,
322114878Sjulian                                    struct thread *);
323114878Sjulianint  ng_btsocket_rfcomm_connect    (struct socket *, struct sockaddr *,
324114878Sjulian                                    struct thread *);
325114878Sjulianint  ng_btsocket_rfcomm_control    (struct socket *, u_long, caddr_t,
326114878Sjulian                                    struct ifnet *, struct thread *);
327114878Sjulianint  ng_btsocket_rfcomm_ctloutput  (struct socket *, struct sockopt *);
328157370Srwatsonvoid ng_btsocket_rfcomm_detach     (struct socket *);
329114878Sjulianint  ng_btsocket_rfcomm_disconnect (struct socket *);
330151888Srwatsonint  ng_btsocket_rfcomm_listen     (struct socket *, int, struct thread *);
331114878Sjulianint  ng_btsocket_rfcomm_peeraddr   (struct socket *, struct sockaddr **);
332114878Sjulianint  ng_btsocket_rfcomm_send       (struct socket *, int, struct mbuf *,
333114878Sjulian                                    struct sockaddr *, struct mbuf *,
334114878Sjulian                                    struct thread *);
335114878Sjulianint  ng_btsocket_rfcomm_sockaddr   (struct socket *, struct sockaddr **);
336114878Sjulian
337114878Sjulian#endif /* _KERNEL */
338114878Sjulian
339114878Sjulian#endif /* _NETGRAPH_BTSOCKET_RFCOMM_H_ */
340114878Sjulian
341