1/*
2 * ng_btsocket_rfcomm.h
3 */
4
5/*-
6 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7 *
8 * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id: ng_btsocket_rfcomm.h,v 1.10 2003/03/29 22:27:42 max Exp $
33 * $FreeBSD$
34 */
35
36#ifndef _NETGRAPH_BTSOCKET_RFCOMM_H_
37#define _NETGRAPH_BTSOCKET_RFCOMM_H_
38
39/*****************************************************************************
40 *****************************************************************************
41 **                              RFCOMM                                     **
42 *****************************************************************************
43 *****************************************************************************/
44
45/* XXX FIXME this does not belong here */
46
47#define RFCOMM_DEFAULT_MTU		667
48#define RFCOMM_MAX_MTU			1024
49
50#define RFCOMM_DEFAULT_CREDITS		7
51#define RFCOMM_MAX_CREDITS		40
52
53/* RFCOMM frame types */
54#define RFCOMM_FRAME_SABM		0x2f
55#define RFCOMM_FRAME_DISC		0x43
56#define RFCOMM_FRAME_UA			0x63
57#define RFCOMM_FRAME_DM			0x0f
58#define RFCOMM_FRAME_UIH		0xef
59
60/* RFCOMM MCC commands */
61#define RFCOMM_MCC_TEST			0x08 /* Test */
62#define RFCOMM_MCC_FCON			0x28 /* Flow Control on */
63#define RFCOMM_MCC_FCOFF		0x18 /* Flow Control off */
64#define RFCOMM_MCC_MSC			0x38 /* Modem Status Command */
65#define RFCOMM_MCC_RPN			0x24 /* Remote Port Negotiation */
66#define RFCOMM_MCC_RLS			0x14 /* Remote Line Status */
67#define RFCOMM_MCC_PN			0x20 /* Port Negotiation */
68#define RFCOMM_MCC_NSC			0x04 /* Non Supported Command */
69
70/* RFCOMM modem signals */
71#define RFCOMM_MODEM_FC			0x02 /* Flow Control asserted */
72#define RFCOMM_MODEM_RTC		0x04 /* Ready To Communicate */
73#define RFCOMM_MODEM_RTR		0x08 /* Ready To Receive */
74#define	RFCOMM_MODEM_IC			0x40 /* Incoming Call */
75#define RFCOMM_MODEM_DV			0x80 /* Data Valid */
76
77/* RPN parameters - baud rate */
78#define RFCOMM_RPN_BR_2400		0x0
79#define RFCOMM_RPN_BR_4800		0x1
80#define RFCOMM_RPN_BR_7200		0x2
81#define RFCOMM_RPN_BR_9600		0x3
82#define RFCOMM_RPN_BR_19200		0x4
83#define RFCOMM_RPN_BR_38400		0x5
84#define RFCOMM_RPN_BR_57600		0x6
85#define RFCOMM_RPN_BR_115200		0x7
86#define RFCOMM_RPN_BR_230400		0x8
87
88/* RPN parameters - data bits */
89#define RFCOMM_RPN_DATA_5		0x0
90#define RFCOMM_RPN_DATA_6		0x2
91#define RFCOMM_RPN_DATA_7		0x1
92#define RFCOMM_RPN_DATA_8		0x3
93
94/* RPN parameters - stop bit */
95#define RFCOMM_RPN_STOP_1		0
96#define RFCOMM_RPN_STOP_15		1
97
98/* RPN parameters - parity */
99#define RFCOMM_RPN_PARITY_NONE		0x0
100#define RFCOMM_RPN_PARITY_ODD		0x4
101#define RFCOMM_RPN_PARITY_EVEN		0x5
102#define RFCOMM_RPN_PARITY_MARK		0x6
103#define RFCOMM_RPN_PARITY_SPACE		0x7
104
105/* RPN parameters - flow control */
106#define RFCOMM_RPN_FLOW_NONE		0x00
107#define RFCOMM_RPN_XON_CHAR		0x11
108#define RFCOMM_RPN_XOFF_CHAR		0x13
109
110/* RPN parameters - mask */
111#define RFCOMM_RPN_PM_BITRATE		0x0001
112#define RFCOMM_RPN_PM_DATA		0x0002
113#define RFCOMM_RPN_PM_STOP		0x0004
114#define RFCOMM_RPN_PM_PARITY		0x0008
115#define RFCOMM_RPN_PM_PARITY_TYPE	0x0010
116#define RFCOMM_RPN_PM_XON		0x0020
117#define RFCOMM_RPN_PM_XOFF		0x0040
118#define RFCOMM_RPN_PM_FLOW		0x3F00
119#define RFCOMM_RPN_PM_ALL		0x3F7F
120
121/* RFCOMM frame header */
122struct rfcomm_frame_hdr
123{
124	u_int8_t	address;
125	u_int8_t	control;
126	u_int8_t	length;	/* Actual size could be 2 bytes */
127} __attribute__ ((packed));
128
129/* RFCOMM command frame header */
130struct rfcomm_cmd_hdr
131{
132	u_int8_t	address;
133	u_int8_t	control;
134	u_int8_t	length;
135	u_int8_t	fcs;
136} __attribute__ ((packed));
137
138/* RFCOMM MCC command header */
139struct rfcomm_mcc_hdr
140{
141	u_int8_t	type;
142	u_int8_t	length; /* XXX FIXME Can actual size be 2 bytes?? */
143} __attribute__ ((packed));
144
145/* RFCOMM MSC command */
146struct rfcomm_mcc_msc
147{
148	u_int8_t	address;
149	u_int8_t	modem;
150} __attribute__ ((packed));
151
152/* RFCOMM RPN command */
153struct rfcomm_mcc_rpn
154{
155	u_int8_t	dlci;
156	u_int8_t	bit_rate;
157	u_int8_t	line_settings;
158	u_int8_t	flow_control;
159	u_int8_t	xon_char;
160	u_int8_t	xoff_char;
161	u_int16_t	param_mask;
162} __attribute__ ((packed));
163
164/* RFCOMM RLS command */
165struct rfcomm_mcc_rls
166{
167	u_int8_t	address;
168	u_int8_t	status;
169} __attribute__ ((packed));
170
171/* RFCOMM PN command */
172struct rfcomm_mcc_pn
173{
174	u_int8_t	dlci;
175	u_int8_t	flow_control;
176	u_int8_t	priority;
177	u_int8_t	ack_timer;
178	u_int16_t	mtu;
179	u_int8_t	max_retrans;
180	u_int8_t	credits;
181} __attribute__ ((packed));
182
183/* RFCOMM frame parsing macros */
184#define RFCOMM_DLCI(b)			(((b) & 0xfc) >> 2)
185#define RFCOMM_CHANNEL(b)		(((b) & 0xf8) >> 3)
186#define RFCOMM_DIRECTION(b)		(((b) & 0x04) >> 2)
187#define RFCOMM_TYPE(b)			(((b) & 0xef))
188
189#define RFCOMM_EA(b)			(((b) & 0x01))
190#define RFCOMM_CR(b)			(((b) & 0x02) >> 1)
191#define RFCOMM_PF(b)			(((b) & 0x10) >> 4)
192
193#define RFCOMM_SRVCHANNEL(dlci)		((dlci) >> 1)
194
195#define RFCOMM_MKADDRESS(cr, dlci) \
196	((((dlci) & 0x3f) << 2) | ((cr) << 1) | 0x01)
197
198#define RFCOMM_MKCONTROL(type, pf)	((((type) & 0xef) | ((pf) << 4)))
199#define RFCOMM_MKDLCI(dir, channel)	((((channel) & 0x1f) << 1) | (dir))
200
201#define RFCOMM_MKLEN8(len)		(((len) << 1) | 1)
202#define RFCOMM_MKLEN16(len)		((len) << 1)
203
204/* RFCOMM MCC macros */
205#define RFCOMM_MCC_TYPE(b)		(((b) & 0xfc) >> 2)
206#define RFCOMM_MCC_LENGTH(b)		(((b) & 0xfe) >> 1)
207#define RFCOMM_MKMCC_TYPE(cr, type)	((((type) << 2) | ((cr) << 1) | 0x01))
208
209/* RPN macros */
210#define RFCOMM_RPN_DATA_BITS(line)	((line) & 0x3)
211#define RFCOMM_RPN_STOP_BITS(line)	(((line) >> 2) & 0x1)
212#define RFCOMM_RPN_PARITY(line)		(((line) >> 3) & 0x3)
213#define RFCOMM_MKRPN_LINE_SETTINGS(data, stop, parity) \
214	(((data) & 0x3) | (((stop) & 0x1) << 2) | (((parity) & 0x3) << 3))
215
216/*****************************************************************************
217 *****************************************************************************
218 **                      SOCK_STREAM RFCOMM sockets                         **
219 *****************************************************************************
220 *****************************************************************************/
221
222#define NG_BTSOCKET_RFCOMM_SENDSPACE \
223	(RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 2)
224#define NG_BTSOCKET_RFCOMM_RECVSPACE \
225	(RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 2)
226
227/*
228 * Bluetooth RFCOMM session. One L2CAP connection == one RFCOMM session
229 */
230
231struct ng_btsocket_rfcomm_pcb;
232struct ng_btsocket_rfcomm_session;
233
234struct ng_btsocket_rfcomm_session {
235	struct socket				*l2so;	 /* L2CAP socket */
236
237	u_int16_t				 state;  /* session state */
238#define NG_BTSOCKET_RFCOMM_SESSION_CLOSED	 0
239#define NG_BTSOCKET_RFCOMM_SESSION_LISTENING	 1
240#define NG_BTSOCKET_RFCOMM_SESSION_CONNECTING	 2
241#define NG_BTSOCKET_RFCOMM_SESSION_CONNECTED	 3
242#define NG_BTSOCKET_RFCOMM_SESSION_OPEN		 4
243#define NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING 5
244
245	u_int16_t				 flags;  /* session flags */
246#define NG_BTSOCKET_RFCOMM_SESSION_INITIATOR	(1 << 0) /* initiator */
247#define NG_BTSOCKET_RFCOMM_SESSION_LFC		(1 << 1) /* local flow */
248#define NG_BTSOCKET_RFCOMM_SESSION_RFC		(1 << 2) /* remote flow */
249
250#define INITIATOR(s) \
251	(((s)->flags & NG_BTSOCKET_RFCOMM_SESSION_INITIATOR)? 1 : 0)
252
253	u_int16_t				 mtu;    /* default MTU */
254	struct ng_bt_mbufq			 outq;   /* outgoing queue */
255
256	struct mtx				 session_mtx; /* session lock */
257	LIST_HEAD(, ng_btsocket_rfcomm_pcb)	 dlcs;	 /* active DLC */
258
259	LIST_ENTRY(ng_btsocket_rfcomm_session)	 next;	 /* link to next */
260};
261typedef struct ng_btsocket_rfcomm_session	ng_btsocket_rfcomm_session_t;
262typedef struct ng_btsocket_rfcomm_session *	ng_btsocket_rfcomm_session_p;
263
264/*
265 * Bluetooth RFCOMM socket PCB (DLC)
266 */
267
268struct ng_btsocket_rfcomm_pcb {
269	struct socket				*so;	  /* RFCOMM socket */
270	struct ng_btsocket_rfcomm_session	*session; /* RFCOMM session */
271
272	u_int16_t				 flags;   /* DLC flags */
273#define NG_BTSOCKET_RFCOMM_DLC_TIMO		(1 << 0)  /* timeout pending */
274#define NG_BTSOCKET_RFCOMM_DLC_CFC		(1 << 1)  /* credit flow ctrl */
275#define	NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT		(1 << 2)  /* timeout happened */
276#define NG_BTSOCKET_RFCOMM_DLC_DETACHED		(1 << 3)  /* DLC detached */
277#define NG_BTSOCKET_RFCOMM_DLC_SENDING		(1 << 4)  /* send pending */
278
279	u_int16_t				 state;   /* DLC state */
280#define NG_BTSOCKET_RFCOMM_DLC_CLOSED		0
281#define NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT	1
282#define NG_BTSOCKET_RFCOMM_DLC_CONFIGURING	2
283#define NG_BTSOCKET_RFCOMM_DLC_CONNECTING	3
284#define NG_BTSOCKET_RFCOMM_DLC_CONNECTED	4
285#define NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING	5
286
287	bdaddr_t				 src;     /* source address */
288	bdaddr_t				 dst;     /* dest. address */
289
290	u_int8_t				 channel; /* RFCOMM channel */
291	u_int8_t				 dlci;    /* RFCOMM DLCI */
292
293	u_int8_t				 lmodem;  /* local mdm signls */
294	u_int8_t				 rmodem;  /* remote -/- */
295
296	u_int16_t				 mtu;	  /* MTU */
297	int16_t					 rx_cred; /* RX credits */
298	int16_t					 tx_cred; /* TX credits */
299
300	struct mtx				 pcb_mtx; /* PCB lock */
301	struct callout				 timo;    /* timeout */
302
303	LIST_ENTRY(ng_btsocket_rfcomm_pcb)	 session_next;/* link to next */
304	LIST_ENTRY(ng_btsocket_rfcomm_pcb)	 next;	  /* link to next */
305};
306typedef struct ng_btsocket_rfcomm_pcb	ng_btsocket_rfcomm_pcb_t;
307typedef struct ng_btsocket_rfcomm_pcb *	ng_btsocket_rfcomm_pcb_p;
308
309#define	so2rfcomm_pcb(so) \
310	((struct ng_btsocket_rfcomm_pcb *)((so)->so_pcb))
311
312/*
313 * Bluetooth RFCOMM socket methods
314 */
315
316#ifdef _KERNEL
317
318void ng_btsocket_rfcomm_init       (void);
319void ng_btsocket_rfcomm_abort      (struct socket *);
320void ng_btsocket_rfcomm_close      (struct socket *);
321int  ng_btsocket_rfcomm_accept     (struct socket *, struct sockaddr **);
322int  ng_btsocket_rfcomm_attach     (struct socket *, int, struct thread *);
323int  ng_btsocket_rfcomm_bind       (struct socket *, struct sockaddr *,
324                                    struct thread *);
325int  ng_btsocket_rfcomm_connect    (struct socket *, struct sockaddr *,
326                                    struct thread *);
327int  ng_btsocket_rfcomm_control    (struct socket *, u_long, caddr_t,
328                                    struct ifnet *, struct thread *);
329int  ng_btsocket_rfcomm_ctloutput  (struct socket *, struct sockopt *);
330void ng_btsocket_rfcomm_detach     (struct socket *);
331int  ng_btsocket_rfcomm_disconnect (struct socket *);
332int  ng_btsocket_rfcomm_listen     (struct socket *, int, struct thread *);
333int  ng_btsocket_rfcomm_peeraddr   (struct socket *, struct sockaddr **);
334int  ng_btsocket_rfcomm_send       (struct socket *, int, struct mbuf *,
335                                    struct sockaddr *, struct mbuf *,
336                                    struct thread *);
337int  ng_btsocket_rfcomm_sockaddr   (struct socket *, struct sockaddr **);
338
339#endif /* _KERNEL */
340
341#endif /* _NETGRAPH_BTSOCKET_RFCOMM_H_ */
342