xref: /dflybsd-src/sys/netgraph7/bluetooth/l2cap/ng_l2cap_cmds.h (revision b06ebda0110aaa466b4f7ba6cacac7a26b29f434)
1*b06ebda0SMatthew Dillon /*
2*b06ebda0SMatthew Dillon  * ng_l2cap_cmds.h
3*b06ebda0SMatthew Dillon  */
4*b06ebda0SMatthew Dillon 
5*b06ebda0SMatthew Dillon /*-
6*b06ebda0SMatthew Dillon  * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
7*b06ebda0SMatthew Dillon  * All rights reserved.
8*b06ebda0SMatthew Dillon  *
9*b06ebda0SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
10*b06ebda0SMatthew Dillon  * modification, are permitted provided that the following conditions
11*b06ebda0SMatthew Dillon  * are met:
12*b06ebda0SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
13*b06ebda0SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
14*b06ebda0SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
15*b06ebda0SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in the
16*b06ebda0SMatthew Dillon  *    documentation and/or other materials provided with the distribution.
17*b06ebda0SMatthew Dillon  *
18*b06ebda0SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19*b06ebda0SMatthew Dillon  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*b06ebda0SMatthew Dillon  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*b06ebda0SMatthew Dillon  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22*b06ebda0SMatthew Dillon  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23*b06ebda0SMatthew Dillon  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24*b06ebda0SMatthew Dillon  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25*b06ebda0SMatthew Dillon  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26*b06ebda0SMatthew Dillon  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27*b06ebda0SMatthew Dillon  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*b06ebda0SMatthew Dillon  * SUCH DAMAGE.
29*b06ebda0SMatthew Dillon  *
30*b06ebda0SMatthew Dillon  * $Id: ng_l2cap_cmds.h,v 1.4 2003/04/01 18:15:26 max Exp $
31*b06ebda0SMatthew Dillon  * $FreeBSD: src/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.h,v 1.5 2005/01/07 01:45:43 imp Exp $
32*b06ebda0SMatthew Dillon  */
33*b06ebda0SMatthew Dillon 
34*b06ebda0SMatthew Dillon #ifndef _NETGRAPH_L2CAP_CMDS_H_
35*b06ebda0SMatthew Dillon #define _NETGRAPH_L2CAP_CMDS_H_
36*b06ebda0SMatthew Dillon 
37*b06ebda0SMatthew Dillon /******************************************************************************
38*b06ebda0SMatthew Dillon  ******************************************************************************
39*b06ebda0SMatthew Dillon  **                L2CAP to L2CAP signaling command macros
40*b06ebda0SMatthew Dillon  ******************************************************************************
41*b06ebda0SMatthew Dillon  ******************************************************************************/
42*b06ebda0SMatthew Dillon 
43*b06ebda0SMatthew Dillon /*
44*b06ebda0SMatthew Dillon  * Note: All L2CAP implementations are required to support minimal signaling
45*b06ebda0SMatthew Dillon  *       MTU of 48 bytes. In order to simplify things we will send one command
46*b06ebda0SMatthew Dillon  *       per one L2CAP packet. Given evrything above we can assume that one
47*b06ebda0SMatthew Dillon  *       signaling packet will fit into single mbuf.
48*b06ebda0SMatthew Dillon  */
49*b06ebda0SMatthew Dillon 
50*b06ebda0SMatthew Dillon /* L2CAP_CommandRej */
51*b06ebda0SMatthew Dillon #define	_ng_l2cap_cmd_rej(_m, _ident, _reason, _mtu, _scid, _dcid)	\
52*b06ebda0SMatthew Dillon do {									\
53*b06ebda0SMatthew Dillon 	struct _cmd_rej {						\
54*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
55*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_rej_cp	 param;				\
56*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_rej_data_t	 data;				\
57*b06ebda0SMatthew Dillon 	} __attribute__ ((packed))	*c = NULL;			\
58*b06ebda0SMatthew Dillon 									\
59*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
60*b06ebda0SMatthew Dillon 	if ((_m) == NULL) 						\
61*b06ebda0SMatthew Dillon 		break;							\
62*b06ebda0SMatthew Dillon 									\
63*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _cmd_rej *);				\
64*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_CMD_REJ;					\
65*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
66*b06ebda0SMatthew Dillon 	c->hdr.length = sizeof(c->param);				\
67*b06ebda0SMatthew Dillon 									\
68*b06ebda0SMatthew Dillon 	c->param.reason = htole16((_reason));				\
69*b06ebda0SMatthew Dillon 									\
70*b06ebda0SMatthew Dillon 	if ((_reason) == NG_L2CAP_REJ_MTU_EXCEEDED) {			\
71*b06ebda0SMatthew Dillon 		c->data.mtu.mtu = htole16((_mtu));			\
72*b06ebda0SMatthew Dillon 		c->hdr.length += sizeof(c->data.mtu);			\
73*b06ebda0SMatthew Dillon 	} else if ((_reason) == NG_L2CAP_REJ_INVALID_CID) {		\
74*b06ebda0SMatthew Dillon 		c->data.cid.scid = htole16((_scid));			\
75*b06ebda0SMatthew Dillon 		c->data.cid.dcid = htole16((_dcid));			\
76*b06ebda0SMatthew Dillon 		c->hdr.length += sizeof(c->data.cid);			\
77*b06ebda0SMatthew Dillon 	}								\
78*b06ebda0SMatthew Dillon 									\
79*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + 		\
80*b06ebda0SMatthew Dillon 					c->hdr.length;			\
81*b06ebda0SMatthew Dillon 									\
82*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(c->hdr.length);				\
83*b06ebda0SMatthew Dillon } while (0)
84*b06ebda0SMatthew Dillon 
85*b06ebda0SMatthew Dillon /* L2CAP_ConnectReq */
86*b06ebda0SMatthew Dillon #define	_ng_l2cap_con_req(_m, _ident, _psm, _scid)			\
87*b06ebda0SMatthew Dillon do {									\
88*b06ebda0SMatthew Dillon 	struct _con_req {						\
89*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
90*b06ebda0SMatthew Dillon 		ng_l2cap_con_req_cp	 param;				\
91*b06ebda0SMatthew Dillon 	} __attribute__ ((packed)) 	*c = NULL;			\
92*b06ebda0SMatthew Dillon 									\
93*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
94*b06ebda0SMatthew Dillon 	if ((_m) == NULL) 						\
95*b06ebda0SMatthew Dillon 		break;							\
96*b06ebda0SMatthew Dillon 									\
97*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
98*b06ebda0SMatthew Dillon 									\
99*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _con_req *);				\
100*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_CON_REQ;					\
101*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
102*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(sizeof(c->param));			\
103*b06ebda0SMatthew Dillon 									\
104*b06ebda0SMatthew Dillon 	c->param.psm = htole16((_psm));					\
105*b06ebda0SMatthew Dillon 	c->param.scid = htole16((_scid));				\
106*b06ebda0SMatthew Dillon } while (0)
107*b06ebda0SMatthew Dillon 
108*b06ebda0SMatthew Dillon /* L2CAP_ConnectRsp */
109*b06ebda0SMatthew Dillon #define _ng_l2cap_con_rsp(_m, _ident, _dcid, _scid, _result, _status)	\
110*b06ebda0SMatthew Dillon do {									\
111*b06ebda0SMatthew Dillon 	struct _con_rsp {						\
112*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
113*b06ebda0SMatthew Dillon 		ng_l2cap_con_rsp_cp	 param;				\
114*b06ebda0SMatthew Dillon 	} __attribute__ ((packed))	*c = NULL;			\
115*b06ebda0SMatthew Dillon 									\
116*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
117*b06ebda0SMatthew Dillon 	if ((_m) == NULL) 						\
118*b06ebda0SMatthew Dillon 		break;							\
119*b06ebda0SMatthew Dillon 									\
120*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
121*b06ebda0SMatthew Dillon 									\
122*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _con_rsp *);				\
123*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_CON_RSP;					\
124*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
125*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(sizeof(c->param));			\
126*b06ebda0SMatthew Dillon 									\
127*b06ebda0SMatthew Dillon 	c->param.dcid = htole16((_dcid));				\
128*b06ebda0SMatthew Dillon 	c->param.scid = htole16((_scid));				\
129*b06ebda0SMatthew Dillon 	c->param.result = htole16((_result));				\
130*b06ebda0SMatthew Dillon 	c->param.status = htole16((_status));				\
131*b06ebda0SMatthew Dillon } while (0)
132*b06ebda0SMatthew Dillon 
133*b06ebda0SMatthew Dillon /* L2CAP_ConfigReq */
134*b06ebda0SMatthew Dillon #define	_ng_l2cap_cfg_req(_m, _ident, _dcid, _flags, _data)		\
135*b06ebda0SMatthew Dillon do {									\
136*b06ebda0SMatthew Dillon 	struct _cfg_req {						\
137*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
138*b06ebda0SMatthew Dillon 		ng_l2cap_cfg_req_cp	 param;				\
139*b06ebda0SMatthew Dillon 	} __attribute__ ((packed))	*c = NULL;			\
140*b06ebda0SMatthew Dillon 									\
141*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
142*b06ebda0SMatthew Dillon 	if ((_m) == NULL) { 						\
143*b06ebda0SMatthew Dillon 		NG_FREE_M((_data));					\
144*b06ebda0SMatthew Dillon 		break;							\
145*b06ebda0SMatthew Dillon 	}								\
146*b06ebda0SMatthew Dillon 									\
147*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
148*b06ebda0SMatthew Dillon 									\
149*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _cfg_req *);				\
150*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_CFG_REQ;					\
151*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
152*b06ebda0SMatthew Dillon 	c->hdr.length = sizeof(c->param);				\
153*b06ebda0SMatthew Dillon 									\
154*b06ebda0SMatthew Dillon 	c->param.dcid = htole16((_dcid));				\
155*b06ebda0SMatthew Dillon 	c->param.flags = htole16((_flags));				\
156*b06ebda0SMatthew Dillon 	if ((_data) != NULL) {						\
157*b06ebda0SMatthew Dillon 		int	l = (_data)->m_pkthdr.len;			\
158*b06ebda0SMatthew Dillon 									\
159*b06ebda0SMatthew Dillon 		m_cat((_m), (_data));					\
160*b06ebda0SMatthew Dillon 		c->hdr.length += l;					\
161*b06ebda0SMatthew Dillon 		(_m)->m_pkthdr.len += l;				\
162*b06ebda0SMatthew Dillon 	}								\
163*b06ebda0SMatthew Dillon 									\
164*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(c->hdr.length);				\
165*b06ebda0SMatthew Dillon } while (0)
166*b06ebda0SMatthew Dillon 
167*b06ebda0SMatthew Dillon /* L2CAP_ConfigRsp */
168*b06ebda0SMatthew Dillon #define _ng_l2cap_cfg_rsp(_m, _ident, _scid, _flags, _result, _data)	\
169*b06ebda0SMatthew Dillon do {									\
170*b06ebda0SMatthew Dillon 	struct _cfg_rsp {						\
171*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
172*b06ebda0SMatthew Dillon 		ng_l2cap_cfg_rsp_cp	 param;				\
173*b06ebda0SMatthew Dillon 	} __attribute__ ((packed))	*c = NULL;			\
174*b06ebda0SMatthew Dillon 									\
175*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
176*b06ebda0SMatthew Dillon 	if ((_m) == NULL) { 						\
177*b06ebda0SMatthew Dillon 		NG_FREE_M((_data));					\
178*b06ebda0SMatthew Dillon 		break;							\
179*b06ebda0SMatthew Dillon 	}								\
180*b06ebda0SMatthew Dillon 									\
181*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
182*b06ebda0SMatthew Dillon 									\
183*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _cfg_rsp *);				\
184*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_CFG_RSP;					\
185*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
186*b06ebda0SMatthew Dillon 	c->hdr.length = sizeof(c->param);				\
187*b06ebda0SMatthew Dillon 									\
188*b06ebda0SMatthew Dillon 	c->param.scid = htole16((_scid));				\
189*b06ebda0SMatthew Dillon 	c->param.flags = htole16((_flags));				\
190*b06ebda0SMatthew Dillon 	c->param.result = htole16((_result));				\
191*b06ebda0SMatthew Dillon 	if ((_data) != NULL) {						\
192*b06ebda0SMatthew Dillon 		int	l = (_data)->m_pkthdr.len;			\
193*b06ebda0SMatthew Dillon 									\
194*b06ebda0SMatthew Dillon 		m_cat((_m), (_data));					\
195*b06ebda0SMatthew Dillon 		c->hdr.length += l;					\
196*b06ebda0SMatthew Dillon 		(_m)->m_pkthdr.len += l;				\
197*b06ebda0SMatthew Dillon 	}								\
198*b06ebda0SMatthew Dillon 									\
199*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(c->hdr.length);				\
200*b06ebda0SMatthew Dillon } while (0)
201*b06ebda0SMatthew Dillon 
202*b06ebda0SMatthew Dillon /* Build configuration options */
203*b06ebda0SMatthew Dillon #define _ng_l2cap_build_cfg_options(_m, _mtu, _flush_timo, _flow)	\
204*b06ebda0SMatthew Dillon do {									\
205*b06ebda0SMatthew Dillon 	u_int8_t	*p = NULL;					\
206*b06ebda0SMatthew Dillon 									\
207*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
208*b06ebda0SMatthew Dillon 	if ((_m) == NULL)						\
209*b06ebda0SMatthew Dillon 		break;							\
210*b06ebda0SMatthew Dillon 									\
211*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = 0;				\
212*b06ebda0SMatthew Dillon 	p = mtod((_m), u_int8_t *);					\
213*b06ebda0SMatthew Dillon 									\
214*b06ebda0SMatthew Dillon 	if ((_mtu) != NULL) {						\
215*b06ebda0SMatthew Dillon 		struct _cfg_opt_mtu {					\
216*b06ebda0SMatthew Dillon 			ng_l2cap_cfg_opt_t	 hdr;			\
217*b06ebda0SMatthew Dillon 			u_int16_t		 val;			\
218*b06ebda0SMatthew Dillon 		} __attribute__ ((packed))	*o = NULL;		\
219*b06ebda0SMatthew Dillon 									\
220*b06ebda0SMatthew Dillon 		o = (struct _cfg_opt_mtu *) p;				\
221*b06ebda0SMatthew Dillon 		o->hdr.type = NG_L2CAP_OPT_MTU;				\
222*b06ebda0SMatthew Dillon 		o->hdr.length = sizeof(o->val);				\
223*b06ebda0SMatthew Dillon 		o->val = htole16(*(u_int16_t *)(_mtu));			\
224*b06ebda0SMatthew Dillon 									\
225*b06ebda0SMatthew Dillon 		(_m)->m_pkthdr.len += sizeof(*o);			\
226*b06ebda0SMatthew Dillon 		p += sizeof(*o);					\
227*b06ebda0SMatthew Dillon 	}								\
228*b06ebda0SMatthew Dillon 									\
229*b06ebda0SMatthew Dillon 	if ((_flush_timo) != NULL) {					\
230*b06ebda0SMatthew Dillon 		struct _cfg_opt_flush {					\
231*b06ebda0SMatthew Dillon 			ng_l2cap_cfg_opt_t	 hdr;			\
232*b06ebda0SMatthew Dillon 			u_int16_t		 val;			\
233*b06ebda0SMatthew Dillon 		} __attribute__ ((packed))	*o = NULL;		\
234*b06ebda0SMatthew Dillon 									\
235*b06ebda0SMatthew Dillon 		o = (struct _cfg_opt_flush *) p;			\
236*b06ebda0SMatthew Dillon 		o->hdr.type = NG_L2CAP_OPT_FLUSH_TIMO;			\
237*b06ebda0SMatthew Dillon 		o->hdr.length = sizeof(o->val);				\
238*b06ebda0SMatthew Dillon 		o->val = htole16(*(u_int16_t *)(_flush_timo));		\
239*b06ebda0SMatthew Dillon 									\
240*b06ebda0SMatthew Dillon 		(_m)->m_pkthdr.len += sizeof(*o);			\
241*b06ebda0SMatthew Dillon 		p += sizeof(*o);					\
242*b06ebda0SMatthew Dillon 	}								\
243*b06ebda0SMatthew Dillon 									\
244*b06ebda0SMatthew Dillon 	if ((_flow) != NULL) {						\
245*b06ebda0SMatthew Dillon 		struct _cfg_opt_flow {					\
246*b06ebda0SMatthew Dillon 			ng_l2cap_cfg_opt_t	 hdr;			\
247*b06ebda0SMatthew Dillon 			ng_l2cap_flow_t		 val;			\
248*b06ebda0SMatthew Dillon 		} __attribute__ ((packed))	*o = NULL;		\
249*b06ebda0SMatthew Dillon 									\
250*b06ebda0SMatthew Dillon 		o = (struct _cfg_opt_flow *) p;				\
251*b06ebda0SMatthew Dillon 		o->hdr.type = NG_L2CAP_OPT_QOS;				\
252*b06ebda0SMatthew Dillon 		o->hdr.length = sizeof(o->val);				\
253*b06ebda0SMatthew Dillon 		o->val.flags = ((ng_l2cap_flow_p)(_flow))->flags;	\
254*b06ebda0SMatthew Dillon 		o->val.service_type = ((ng_l2cap_flow_p)		\
255*b06ebda0SMatthew Dillon 				(_flow))->service_type;			\
256*b06ebda0SMatthew Dillon 		o->val.token_rate =					\
257*b06ebda0SMatthew Dillon 			htole32(((ng_l2cap_flow_p)(_flow))->token_rate);\
258*b06ebda0SMatthew Dillon 		o->val.token_bucket_size =				\
259*b06ebda0SMatthew Dillon 			htole32(((ng_l2cap_flow_p)			\
260*b06ebda0SMatthew Dillon 				(_flow))->token_bucket_size);		\
261*b06ebda0SMatthew Dillon 		o->val.peak_bandwidth = 				\
262*b06ebda0SMatthew Dillon 			htole32(((ng_l2cap_flow_p)			\
263*b06ebda0SMatthew Dillon 				(_flow))->peak_bandwidth);		\
264*b06ebda0SMatthew Dillon 		o->val.latency = htole32(((ng_l2cap_flow_p)		\
265*b06ebda0SMatthew Dillon 				(_flow))->latency);			\
266*b06ebda0SMatthew Dillon 		o->val.delay_variation = 				\
267*b06ebda0SMatthew Dillon 			htole32(((ng_l2cap_flow_p)			\
268*b06ebda0SMatthew Dillon 				(_flow))->delay_variation);		\
269*b06ebda0SMatthew Dillon 									\
270*b06ebda0SMatthew Dillon 		(_m)->m_pkthdr.len += sizeof(*o);			\
271*b06ebda0SMatthew Dillon 	}								\
272*b06ebda0SMatthew Dillon 									\
273*b06ebda0SMatthew Dillon 	(_m)->m_len = (_m)->m_pkthdr.len;				\
274*b06ebda0SMatthew Dillon } while (0)
275*b06ebda0SMatthew Dillon 
276*b06ebda0SMatthew Dillon /* L2CAP_DisconnectReq */
277*b06ebda0SMatthew Dillon #define	_ng_l2cap_discon_req(_m, _ident, _dcid, _scid)			\
278*b06ebda0SMatthew Dillon do {									\
279*b06ebda0SMatthew Dillon 	struct _discon_req {						\
280*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
281*b06ebda0SMatthew Dillon 		ng_l2cap_discon_req_cp	 param;				\
282*b06ebda0SMatthew Dillon 	} __attribute__ ((packed))	*c = NULL;			\
283*b06ebda0SMatthew Dillon 									\
284*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
285*b06ebda0SMatthew Dillon 	if ((_m) == NULL)						\
286*b06ebda0SMatthew Dillon 		break;							\
287*b06ebda0SMatthew Dillon 									\
288*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
289*b06ebda0SMatthew Dillon 									\
290*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _discon_req *);				\
291*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_DISCON_REQ;				\
292*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
293*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(sizeof(c->param));			\
294*b06ebda0SMatthew Dillon 									\
295*b06ebda0SMatthew Dillon 	c->param.dcid = htole16((_dcid));				\
296*b06ebda0SMatthew Dillon 	c->param.scid = htole16((_scid));				\
297*b06ebda0SMatthew Dillon } while (0)
298*b06ebda0SMatthew Dillon 
299*b06ebda0SMatthew Dillon /* L2CA_DisconnectRsp */
300*b06ebda0SMatthew Dillon #define	_ng_l2cap_discon_rsp(_m, _ident, _dcid, _scid)			\
301*b06ebda0SMatthew Dillon do {									\
302*b06ebda0SMatthew Dillon 	struct _discon_rsp {						\
303*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
304*b06ebda0SMatthew Dillon 		ng_l2cap_discon_rsp_cp	 param;				\
305*b06ebda0SMatthew Dillon 	} __attribute__ ((packed))	*c = NULL;			\
306*b06ebda0SMatthew Dillon 									\
307*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
308*b06ebda0SMatthew Dillon 	if ((_m) == NULL)						\
309*b06ebda0SMatthew Dillon 		break;							\
310*b06ebda0SMatthew Dillon 									\
311*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
312*b06ebda0SMatthew Dillon 									\
313*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _discon_rsp *);				\
314*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_DISCON_RSP;				\
315*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
316*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(sizeof(c->param));			\
317*b06ebda0SMatthew Dillon 									\
318*b06ebda0SMatthew Dillon 	c->param.dcid = htole16((_dcid));				\
319*b06ebda0SMatthew Dillon 	c->param.scid = htole16((_scid));				\
320*b06ebda0SMatthew Dillon } while (0)
321*b06ebda0SMatthew Dillon 
322*b06ebda0SMatthew Dillon /* L2CAP_EchoReq */
323*b06ebda0SMatthew Dillon #define	_ng_l2cap_echo_req(_m, _ident, _data, _size)			\
324*b06ebda0SMatthew Dillon do {									\
325*b06ebda0SMatthew Dillon 	ng_l2cap_cmd_hdr_t	*c = NULL;				\
326*b06ebda0SMatthew Dillon 									\
327*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
328*b06ebda0SMatthew Dillon 	if ((_m) == NULL) 						\
329*b06ebda0SMatthew Dillon 		break;							\
330*b06ebda0SMatthew Dillon 									\
331*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
332*b06ebda0SMatthew Dillon 									\
333*b06ebda0SMatthew Dillon 	c = mtod((_m), ng_l2cap_cmd_hdr_t *);				\
334*b06ebda0SMatthew Dillon 	c->code = NG_L2CAP_ECHO_REQ;					\
335*b06ebda0SMatthew Dillon 	c->ident = (_ident);						\
336*b06ebda0SMatthew Dillon 	c->length = 0;							\
337*b06ebda0SMatthew Dillon 									\
338*b06ebda0SMatthew Dillon 	if ((_data) != NULL) {						\
339*b06ebda0SMatthew Dillon 		m_copyback((_m), sizeof(*c), (_size), (_data));		\
340*b06ebda0SMatthew Dillon 		c->length += (_size);					\
341*b06ebda0SMatthew Dillon 	}								\
342*b06ebda0SMatthew Dillon 									\
343*b06ebda0SMatthew Dillon 	c->length = htole16(c->length);					\
344*b06ebda0SMatthew Dillon } while (0)
345*b06ebda0SMatthew Dillon 
346*b06ebda0SMatthew Dillon /* L2CAP_InfoReq */
347*b06ebda0SMatthew Dillon #define	_ng_l2cap_info_req(_m, _ident, _type)				\
348*b06ebda0SMatthew Dillon do {									\
349*b06ebda0SMatthew Dillon 	struct _info_req {						\
350*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
351*b06ebda0SMatthew Dillon 		ng_l2cap_info_req_cp	 param;				\
352*b06ebda0SMatthew Dillon 	} __attribute__ ((packed))	*c = NULL;			\
353*b06ebda0SMatthew Dillon 									\
354*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
355*b06ebda0SMatthew Dillon 	if ((_m) == NULL)						\
356*b06ebda0SMatthew Dillon 		break;							\
357*b06ebda0SMatthew Dillon 									\
358*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
359*b06ebda0SMatthew Dillon 									\
360*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _info_req *);				\
361*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_INFO_REQ;				\
362*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
363*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(sizeof(c->param));			\
364*b06ebda0SMatthew Dillon 									\
365*b06ebda0SMatthew Dillon 	c->param.type = htole16((_type));				\
366*b06ebda0SMatthew Dillon } while (0)
367*b06ebda0SMatthew Dillon 
368*b06ebda0SMatthew Dillon /* L2CAP_InfoRsp */
369*b06ebda0SMatthew Dillon #define	_ng_l2cap_info_rsp(_m, _ident, _type, _result, _mtu)		\
370*b06ebda0SMatthew Dillon do {									\
371*b06ebda0SMatthew Dillon 	struct _info_rsp {						\
372*b06ebda0SMatthew Dillon 		ng_l2cap_cmd_hdr_t	 hdr;				\
373*b06ebda0SMatthew Dillon 		ng_l2cap_info_rsp_cp	 param;				\
374*b06ebda0SMatthew Dillon 		ng_l2cap_info_rsp_data_t data;				\
375*b06ebda0SMatthew Dillon 	} __attribute__ ((packed))	*c = NULL;			\
376*b06ebda0SMatthew Dillon 									\
377*b06ebda0SMatthew Dillon 	MGETHDR((_m), M_DONTWAIT, MT_DATA);				\
378*b06ebda0SMatthew Dillon 	if ((_m) == NULL) 						\
379*b06ebda0SMatthew Dillon 		break;							\
380*b06ebda0SMatthew Dillon 									\
381*b06ebda0SMatthew Dillon 	c = mtod((_m), struct _info_rsp *);				\
382*b06ebda0SMatthew Dillon 	c->hdr.code = NG_L2CAP_INFO_REQ;				\
383*b06ebda0SMatthew Dillon 	c->hdr.ident = (_ident);					\
384*b06ebda0SMatthew Dillon 	c->hdr.length = sizeof(c->param);				\
385*b06ebda0SMatthew Dillon 									\
386*b06ebda0SMatthew Dillon 	c->param.type = htole16((_type));				\
387*b06ebda0SMatthew Dillon 	c->param.result = htole16((_result));				\
388*b06ebda0SMatthew Dillon 									\
389*b06ebda0SMatthew Dillon 	if ((_result) == NG_L2CAP_SUCCESS) {				\
390*b06ebda0SMatthew Dillon 		switch ((_type)) {					\
391*b06ebda0SMatthew Dillon 		case NG_L2CAP_CONNLESS_MTU:				\
392*b06ebda0SMatthew Dillon 			c->data.mtu.mtu = htole16((_mtu));		\
393*b06ebda0SMatthew Dillon 			c->hdr.length += sizeof((c->data.mtu.mtu));	\
394*b06ebda0SMatthew Dillon 			break;						\
395*b06ebda0SMatthew Dillon 		}							\
396*b06ebda0SMatthew Dillon 	}								\
397*b06ebda0SMatthew Dillon 									\
398*b06ebda0SMatthew Dillon 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) +		\
399*b06ebda0SMatthew Dillon 					c->hdr.length;			\
400*b06ebda0SMatthew Dillon 									\
401*b06ebda0SMatthew Dillon 	c->hdr.length = htole16(c->hdr.length);		 		\
402*b06ebda0SMatthew Dillon } while (0)
403*b06ebda0SMatthew Dillon 
404*b06ebda0SMatthew Dillon void ng_l2cap_con_wakeup              (ng_l2cap_con_p);
405*b06ebda0SMatthew Dillon void ng_l2cap_con_fail                (ng_l2cap_con_p, u_int16_t);
406*b06ebda0SMatthew Dillon void ng_l2cap_process_command_timeout (node_p, hook_p, void *, int);
407*b06ebda0SMatthew Dillon 
408*b06ebda0SMatthew Dillon #endif /* ndef _NETGRAPH_L2CAP_CMDS_H_ */
409*b06ebda0SMatthew Dillon 
410