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