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