master
  1/*	$NetBSD: rfcomm.h,v 1.19 2022/05/28 21:14:57 andvar 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.19 2022/05/28 21:14:57 andvar 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	/* Incoming 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 */
160struct 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 */
169struct rfcomm_mcc_msc
170{
171	uint8_t		address;
172	uint8_t		modem;
173	uint8_t		brk;
174} __packed;
175
176/* RFCOMM RPN command */
177struct 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 */
189struct rfcomm_mcc_rls
190{
191	uint8_t		address;
192	uint8_t		status;
193} __packed;
194
195/* RFCOMM PN command */
196struct 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 */
246struct 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 */
263extern int rfcomm_sendspace;
264extern int rfcomm_recvspace;
265extern int rfcomm_mtu_default;
266extern int rfcomm_ack_timeout;
267extern int rfcomm_mcc_timeout;
268
269/*
270 * Bluetooth RFCOMM session data
271 * One L2CAP connection == one RFCOMM session
272 */
273
274/* Credit note */
275struct 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) */
282struct 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
296LIST_HEAD(rfcomm_session_list, rfcomm_session);
297extern struct rfcomm_session_list rfcomm_session_active;
298extern 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) */
317struct 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
384struct socket;
385struct sockopt;
386
387/* rfcomm_dlc.c */
388struct rfcomm_dlc *rfcomm_dlc_lookup(struct rfcomm_session *, int);
389struct rfcomm_dlc *rfcomm_dlc_newconn(struct rfcomm_session *, int);
390void rfcomm_dlc_close(struct rfcomm_dlc *, int);
391void rfcomm_dlc_timeout(void *);
392int rfcomm_dlc_setmode(struct rfcomm_dlc *);
393int rfcomm_dlc_connect(struct rfcomm_dlc *);
394int rfcomm_dlc_open(struct rfcomm_dlc *);
395void rfcomm_dlc_start(struct rfcomm_dlc *);
396
397/* rfcomm_session.c */
398struct rfcomm_session *rfcomm_session_alloc(struct rfcomm_session_list *, struct sockaddr_bt *);
399struct rfcomm_session *rfcomm_session_lookup(struct sockaddr_bt *, struct sockaddr_bt *);
400void rfcomm_session_free(struct rfcomm_session *);
401int rfcomm_session_send_frame(struct rfcomm_session *, int, int);
402int rfcomm_session_send_uih(struct rfcomm_session *, struct rfcomm_dlc *, int, struct mbuf *);
403int rfcomm_session_send_mcc(struct rfcomm_session *, int, uint8_t, void *, int);
404void rfcomm_init(void);
405
406/* rfcomm_socket.c */
407int rfcomm_ctloutput(int, struct socket *, struct sockopt *);
408
409/* rfcomm_upper.c */
410int rfcomm_attach_pcb(struct rfcomm_dlc **, const struct btproto *, void *);
411int rfcomm_bind_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
412int rfcomm_sockaddr_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
413int rfcomm_connect_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
414int rfcomm_peeraddr_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
415int rfcomm_disconnect_pcb(struct rfcomm_dlc *, int);
416void rfcomm_detach_pcb(struct rfcomm_dlc **);
417int rfcomm_listen_pcb(struct rfcomm_dlc *);
418int rfcomm_send_pcb(struct rfcomm_dlc *, struct mbuf *);
419int rfcomm_rcvd_pcb(struct rfcomm_dlc *, size_t);
420int rfcomm_setopt(struct rfcomm_dlc *, const struct sockopt *);
421int rfcomm_getopt(struct rfcomm_dlc *, struct sockopt *);
422
423#endif /* _KERNEL */
424
425#endif /* _NETBT_RFCOMM_H_ */