xref: /freebsd/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.h (revision 2ff63af9b88c7413b7d71715b5532625752a248e)
1878ed226SJulian Elischer /*
2878ed226SJulian Elischer  * ng_l2cap_cmds.h
3c398230bSWarner Losh  */
4c398230bSWarner Losh 
5c398230bSWarner Losh /*-
6*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
7fe267a55SPedro F. Giffuni  *
8878ed226SJulian Elischer  * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
9878ed226SJulian Elischer  * All rights reserved.
10878ed226SJulian Elischer  *
11878ed226SJulian Elischer  * Redistribution and use in source and binary forms, with or without
12878ed226SJulian Elischer  * modification, are permitted provided that the following conditions
13878ed226SJulian Elischer  * are met:
14878ed226SJulian Elischer  * 1. Redistributions of source code must retain the above copyright
15878ed226SJulian Elischer  *    notice, this list of conditions and the following disclaimer.
16878ed226SJulian Elischer  * 2. Redistributions in binary form must reproduce the above copyright
17878ed226SJulian Elischer  *    notice, this list of conditions and the following disclaimer in the
18878ed226SJulian Elischer  *    documentation and/or other materials provided with the distribution.
19878ed226SJulian Elischer  *
20878ed226SJulian Elischer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21878ed226SJulian Elischer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22878ed226SJulian Elischer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23878ed226SJulian Elischer  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24878ed226SJulian Elischer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25878ed226SJulian Elischer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26878ed226SJulian Elischer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27878ed226SJulian Elischer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28878ed226SJulian Elischer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29878ed226SJulian Elischer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30878ed226SJulian Elischer  * SUCH DAMAGE.
31878ed226SJulian Elischer  *
32f2bb1caeSJulian Elischer  * $Id: ng_l2cap_cmds.h,v 1.4 2003/04/01 18:15:26 max Exp $
33878ed226SJulian Elischer  */
34878ed226SJulian Elischer 
35878ed226SJulian Elischer #ifndef _NETGRAPH_L2CAP_CMDS_H_
36878ed226SJulian Elischer #define _NETGRAPH_L2CAP_CMDS_H_
37878ed226SJulian Elischer 
38878ed226SJulian Elischer /******************************************************************************
39878ed226SJulian Elischer  ******************************************************************************
40878ed226SJulian Elischer  **                L2CAP to L2CAP signaling command macros
41878ed226SJulian Elischer  ******************************************************************************
42878ed226SJulian Elischer  ******************************************************************************/
43878ed226SJulian Elischer 
44878ed226SJulian Elischer /*
45878ed226SJulian Elischer  * Note: All L2CAP implementations are required to support minimal signaling
46878ed226SJulian Elischer  *       MTU of 48 bytes. In order to simplify things we will send one command
47878ed226SJulian Elischer  *       per one L2CAP packet. Given evrything above we can assume that one
48878ed226SJulian Elischer  *       signaling packet will fit into single mbuf.
49878ed226SJulian Elischer  */
50878ed226SJulian Elischer 
51878ed226SJulian Elischer /* L2CAP_CommandRej */
52878ed226SJulian Elischer #define	_ng_l2cap_cmd_rej(_m, _ident, _reason, _mtu, _scid, _dcid)	\
53878ed226SJulian Elischer do {									\
54878ed226SJulian Elischer 	struct _cmd_rej {						\
55878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
56878ed226SJulian Elischer 		ng_l2cap_cmd_rej_cp	 param;				\
57878ed226SJulian Elischer 		ng_l2cap_cmd_rej_data_t	 data;				\
58878ed226SJulian Elischer 	} __attribute__ ((packed))	*c = NULL;			\
59878ed226SJulian Elischer 									\
60eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
61878ed226SJulian Elischer 	if ((_m) == NULL) 						\
62878ed226SJulian Elischer 		break;							\
63878ed226SJulian Elischer 									\
64878ed226SJulian Elischer 	c = mtod((_m), struct _cmd_rej *);				\
65878ed226SJulian Elischer 	c->hdr.code = NG_L2CAP_CMD_REJ;					\
66878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
67878ed226SJulian Elischer 	c->hdr.length = sizeof(c->param);				\
68878ed226SJulian Elischer 									\
69878ed226SJulian Elischer 	c->param.reason = htole16((_reason));				\
70878ed226SJulian Elischer 									\
71878ed226SJulian Elischer 	if ((_reason) == NG_L2CAP_REJ_MTU_EXCEEDED) {			\
72878ed226SJulian Elischer 		c->data.mtu.mtu = htole16((_mtu));			\
73878ed226SJulian Elischer 		c->hdr.length += sizeof(c->data.mtu);			\
74878ed226SJulian Elischer 	} else if ((_reason) == NG_L2CAP_REJ_INVALID_CID) {		\
75878ed226SJulian Elischer 		c->data.cid.scid = htole16((_scid));			\
76878ed226SJulian Elischer 		c->data.cid.dcid = htole16((_dcid));			\
77878ed226SJulian Elischer 		c->hdr.length += sizeof(c->data.cid);			\
78878ed226SJulian Elischer 	}								\
79878ed226SJulian Elischer 									\
80878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + 		\
81878ed226SJulian Elischer 					c->hdr.length;			\
82878ed226SJulian Elischer 									\
83878ed226SJulian Elischer 	c->hdr.length = htole16(c->hdr.length);				\
84878ed226SJulian Elischer } while (0)
85878ed226SJulian Elischer 
86878ed226SJulian Elischer /* L2CAP_ConnectReq */
87878ed226SJulian Elischer #define	_ng_l2cap_con_req(_m, _ident, _psm, _scid)			\
88878ed226SJulian Elischer do {									\
89878ed226SJulian Elischer 	struct _con_req {						\
90878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
91878ed226SJulian Elischer 		ng_l2cap_con_req_cp	 param;				\
92878ed226SJulian Elischer 	} __attribute__ ((packed)) 	*c = NULL;			\
93878ed226SJulian Elischer 									\
94eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
95878ed226SJulian Elischer 	if ((_m) == NULL) 						\
96878ed226SJulian Elischer 		break;							\
97878ed226SJulian Elischer 									\
98878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
99878ed226SJulian Elischer 									\
100878ed226SJulian Elischer 	c = mtod((_m), struct _con_req *);				\
101878ed226SJulian Elischer 	c->hdr.code = NG_L2CAP_CON_REQ;					\
102878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
103878ed226SJulian Elischer 	c->hdr.length = htole16(sizeof(c->param));			\
104878ed226SJulian Elischer 									\
105878ed226SJulian Elischer 	c->param.psm = htole16((_psm));					\
106878ed226SJulian Elischer 	c->param.scid = htole16((_scid));				\
107878ed226SJulian Elischer } while (0)
108878ed226SJulian Elischer 
109878ed226SJulian Elischer /* L2CAP_ConnectRsp */
110878ed226SJulian Elischer #define _ng_l2cap_con_rsp(_m, _ident, _dcid, _scid, _result, _status)	\
111878ed226SJulian Elischer do {									\
112878ed226SJulian Elischer 	struct _con_rsp {						\
113878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
114878ed226SJulian Elischer 		ng_l2cap_con_rsp_cp	 param;				\
115878ed226SJulian Elischer 	} __attribute__ ((packed))	*c = NULL;			\
116878ed226SJulian Elischer 									\
117eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
118878ed226SJulian Elischer 	if ((_m) == NULL) 						\
119878ed226SJulian Elischer 		break;							\
120878ed226SJulian Elischer 									\
121878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
122878ed226SJulian Elischer 									\
123878ed226SJulian Elischer 	c = mtod((_m), struct _con_rsp *);				\
124878ed226SJulian Elischer 	c->hdr.code = NG_L2CAP_CON_RSP;					\
125878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
126878ed226SJulian Elischer 	c->hdr.length = htole16(sizeof(c->param));			\
127878ed226SJulian Elischer 									\
128878ed226SJulian Elischer 	c->param.dcid = htole16((_dcid));				\
129878ed226SJulian Elischer 	c->param.scid = htole16((_scid));				\
130878ed226SJulian Elischer 	c->param.result = htole16((_result));				\
131878ed226SJulian Elischer 	c->param.status = htole16((_status));				\
132878ed226SJulian Elischer } while (0)
133878ed226SJulian Elischer 
134878ed226SJulian Elischer /* L2CAP_ConfigReq */
135878ed226SJulian Elischer #define	_ng_l2cap_cfg_req(_m, _ident, _dcid, _flags, _data)		\
136878ed226SJulian Elischer do {									\
137878ed226SJulian Elischer 	struct _cfg_req {						\
138878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
139878ed226SJulian Elischer 		ng_l2cap_cfg_req_cp	 param;				\
140878ed226SJulian Elischer 	} __attribute__ ((packed))	*c = NULL;			\
141878ed226SJulian Elischer 									\
142eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
143878ed226SJulian Elischer 	if ((_m) == NULL) { 						\
144878ed226SJulian Elischer 		NG_FREE_M((_data));					\
145878ed226SJulian Elischer 		break;							\
146878ed226SJulian Elischer 	}								\
147878ed226SJulian Elischer 									\
148878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
149878ed226SJulian Elischer 									\
150878ed226SJulian Elischer 	c = mtod((_m), struct _cfg_req *);				\
151878ed226SJulian Elischer 	c->hdr.code = NG_L2CAP_CFG_REQ;					\
152878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
153878ed226SJulian Elischer 	c->hdr.length = sizeof(c->param);				\
154878ed226SJulian Elischer 									\
155878ed226SJulian Elischer 	c->param.dcid = htole16((_dcid));				\
156878ed226SJulian Elischer 	c->param.flags = htole16((_flags));				\
157878ed226SJulian Elischer 	if ((_data) != NULL) {						\
158f2bb1caeSJulian Elischer 		int	l = (_data)->m_pkthdr.len;			\
159f2bb1caeSJulian Elischer 									\
160878ed226SJulian Elischer 		m_cat((_m), (_data));					\
161f2bb1caeSJulian Elischer 		c->hdr.length += l;					\
162f2bb1caeSJulian Elischer 		(_m)->m_pkthdr.len += l;				\
163878ed226SJulian Elischer 	}								\
164878ed226SJulian Elischer 									\
165878ed226SJulian Elischer 	c->hdr.length = htole16(c->hdr.length);				\
166878ed226SJulian Elischer } while (0)
167878ed226SJulian Elischer 
168878ed226SJulian Elischer /* L2CAP_ConfigRsp */
169878ed226SJulian Elischer #define _ng_l2cap_cfg_rsp(_m, _ident, _scid, _flags, _result, _data)	\
170878ed226SJulian Elischer do {									\
171878ed226SJulian Elischer 	struct _cfg_rsp {						\
172878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
173878ed226SJulian Elischer 		ng_l2cap_cfg_rsp_cp	 param;				\
174878ed226SJulian Elischer 	} __attribute__ ((packed))	*c = NULL;			\
175878ed226SJulian Elischer 									\
176eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
177878ed226SJulian Elischer 	if ((_m) == NULL) { 						\
178878ed226SJulian Elischer 		NG_FREE_M((_data));					\
179878ed226SJulian Elischer 		break;							\
180878ed226SJulian Elischer 	}								\
181878ed226SJulian Elischer 									\
182878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
183878ed226SJulian Elischer 									\
184878ed226SJulian Elischer 	c = mtod((_m), struct _cfg_rsp *);				\
185878ed226SJulian Elischer 	c->hdr.code = NG_L2CAP_CFG_RSP;					\
186878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
187878ed226SJulian Elischer 	c->hdr.length = sizeof(c->param);				\
188878ed226SJulian Elischer 									\
189878ed226SJulian Elischer 	c->param.scid = htole16((_scid));				\
190878ed226SJulian Elischer 	c->param.flags = htole16((_flags));				\
191878ed226SJulian Elischer 	c->param.result = htole16((_result));				\
192878ed226SJulian Elischer 	if ((_data) != NULL) {						\
193f2bb1caeSJulian Elischer 		int	l = (_data)->m_pkthdr.len;			\
194f2bb1caeSJulian Elischer 									\
195878ed226SJulian Elischer 		m_cat((_m), (_data));					\
196f2bb1caeSJulian Elischer 		c->hdr.length += l;					\
197f2bb1caeSJulian Elischer 		(_m)->m_pkthdr.len += l;				\
198878ed226SJulian Elischer 	}								\
199878ed226SJulian Elischer 									\
200878ed226SJulian Elischer 	c->hdr.length = htole16(c->hdr.length);				\
201878ed226SJulian Elischer } while (0)
202878ed226SJulian Elischer 
203fbc48c2bSTakanori Watanabe #define _ng_l2cap_cmd_urs(_m, _ident, _result)	\
204fbc48c2bSTakanori Watanabe do {									\
205fbc48c2bSTakanori Watanabe 	struct  _cmd_urs{						\
206fbc48c2bSTakanori Watanabe 		ng_l2cap_cmd_hdr_t	 hdr;				\
207fbc48c2bSTakanori Watanabe 		uint16_t	 result;				\
208fbc48c2bSTakanori Watanabe 	} __attribute__ ((packed))	*c = NULL;			\
209fbc48c2bSTakanori Watanabe 									\
210fbc48c2bSTakanori Watanabe 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
211fbc48c2bSTakanori Watanabe 									\
212fbc48c2bSTakanori Watanabe 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
213fbc48c2bSTakanori Watanabe 									\
214fbc48c2bSTakanori Watanabe 	c = mtod((_m), struct _cmd_urs *);				\
215fbc48c2bSTakanori Watanabe 	c->hdr.code = NG_L2CAP_CMD_PARAM_UPDATE_RESPONSE;		\
216fbc48c2bSTakanori Watanabe 	c->hdr.ident = (_ident);					\
217fbc48c2bSTakanori Watanabe 	c->hdr.length = sizeof(c->result);				\
218fbc48c2bSTakanori Watanabe 									\
219fbc48c2bSTakanori Watanabe 	c->result = htole16((_result));				\
220fbc48c2bSTakanori Watanabe } while (0)
221fbc48c2bSTakanori Watanabe 
222878ed226SJulian Elischer /* Build configuration options */
223878ed226SJulian Elischer #define _ng_l2cap_build_cfg_options(_m, _mtu, _flush_timo, _flow)	\
224878ed226SJulian Elischer do {									\
225878ed226SJulian Elischer 	u_int8_t	*p = NULL;					\
226878ed226SJulian Elischer 									\
227eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
228878ed226SJulian Elischer 	if ((_m) == NULL)						\
229878ed226SJulian Elischer 		break;							\
230878ed226SJulian Elischer 									\
231878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = 0;				\
232878ed226SJulian Elischer 	p = mtod((_m), u_int8_t *);					\
233878ed226SJulian Elischer 									\
234878ed226SJulian Elischer 	if ((_mtu) != NULL) {						\
235878ed226SJulian Elischer 		struct _cfg_opt_mtu {					\
236878ed226SJulian Elischer 			ng_l2cap_cfg_opt_t	 hdr;			\
237878ed226SJulian Elischer 			u_int16_t		 val;			\
238878ed226SJulian Elischer 		} __attribute__ ((packed))	*o = NULL;		\
239878ed226SJulian Elischer 									\
240878ed226SJulian Elischer 		o = (struct _cfg_opt_mtu *) p;				\
241878ed226SJulian Elischer 		o->hdr.type = NG_L2CAP_OPT_MTU;				\
242878ed226SJulian Elischer 		o->hdr.length = sizeof(o->val);				\
243878ed226SJulian Elischer 		o->val = htole16(*(u_int16_t *)(_mtu));			\
244878ed226SJulian Elischer 									\
245878ed226SJulian Elischer 		(_m)->m_pkthdr.len += sizeof(*o);			\
246878ed226SJulian Elischer 		p += sizeof(*o);					\
247878ed226SJulian Elischer 	}								\
248878ed226SJulian Elischer 									\
249878ed226SJulian Elischer 	if ((_flush_timo) != NULL) {					\
250878ed226SJulian Elischer 		struct _cfg_opt_flush {					\
251878ed226SJulian Elischer 			ng_l2cap_cfg_opt_t	 hdr;			\
252878ed226SJulian Elischer 			u_int16_t		 val;			\
253878ed226SJulian Elischer 		} __attribute__ ((packed))	*o = NULL;		\
254878ed226SJulian Elischer 									\
255878ed226SJulian Elischer 		o = (struct _cfg_opt_flush *) p;			\
256878ed226SJulian Elischer 		o->hdr.type = NG_L2CAP_OPT_FLUSH_TIMO;			\
257878ed226SJulian Elischer 		o->hdr.length = sizeof(o->val);				\
258878ed226SJulian Elischer 		o->val = htole16(*(u_int16_t *)(_flush_timo));		\
259878ed226SJulian Elischer 									\
260878ed226SJulian Elischer 		(_m)->m_pkthdr.len += sizeof(*o);			\
261878ed226SJulian Elischer 		p += sizeof(*o);					\
262878ed226SJulian Elischer 	}								\
263878ed226SJulian Elischer 									\
264878ed226SJulian Elischer 	if ((_flow) != NULL) {						\
265878ed226SJulian Elischer 		struct _cfg_opt_flow {					\
266878ed226SJulian Elischer 			ng_l2cap_cfg_opt_t	 hdr;			\
267878ed226SJulian Elischer 			ng_l2cap_flow_t		 val;			\
268878ed226SJulian Elischer 		} __attribute__ ((packed))	*o = NULL;		\
269878ed226SJulian Elischer 									\
270878ed226SJulian Elischer 		o = (struct _cfg_opt_flow *) p;				\
271878ed226SJulian Elischer 		o->hdr.type = NG_L2CAP_OPT_QOS;				\
272878ed226SJulian Elischer 		o->hdr.length = sizeof(o->val);				\
273878ed226SJulian Elischer 		o->val.flags = ((ng_l2cap_flow_p)(_flow))->flags;	\
274878ed226SJulian Elischer 		o->val.service_type = ((ng_l2cap_flow_p)		\
275878ed226SJulian Elischer 				(_flow))->service_type;			\
276878ed226SJulian Elischer 		o->val.token_rate =					\
277878ed226SJulian Elischer 			htole32(((ng_l2cap_flow_p)(_flow))->token_rate);\
278878ed226SJulian Elischer 		o->val.token_bucket_size =				\
279878ed226SJulian Elischer 			htole32(((ng_l2cap_flow_p)			\
280878ed226SJulian Elischer 				(_flow))->token_bucket_size);		\
281878ed226SJulian Elischer 		o->val.peak_bandwidth = 				\
282878ed226SJulian Elischer 			htole32(((ng_l2cap_flow_p)			\
283878ed226SJulian Elischer 				(_flow))->peak_bandwidth);		\
284878ed226SJulian Elischer 		o->val.latency = htole32(((ng_l2cap_flow_p)		\
285878ed226SJulian Elischer 				(_flow))->latency);			\
286878ed226SJulian Elischer 		o->val.delay_variation = 				\
287878ed226SJulian Elischer 			htole32(((ng_l2cap_flow_p)			\
288878ed226SJulian Elischer 				(_flow))->delay_variation);		\
289878ed226SJulian Elischer 									\
290878ed226SJulian Elischer 		(_m)->m_pkthdr.len += sizeof(*o);			\
291878ed226SJulian Elischer 	}								\
292878ed226SJulian Elischer 									\
293878ed226SJulian Elischer 	(_m)->m_len = (_m)->m_pkthdr.len;				\
294878ed226SJulian Elischer } while (0)
295878ed226SJulian Elischer 
296878ed226SJulian Elischer /* L2CAP_DisconnectReq */
297878ed226SJulian Elischer #define	_ng_l2cap_discon_req(_m, _ident, _dcid, _scid)			\
298878ed226SJulian Elischer do {									\
299878ed226SJulian Elischer 	struct _discon_req {						\
300878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
301878ed226SJulian Elischer 		ng_l2cap_discon_req_cp	 param;				\
302878ed226SJulian Elischer 	} __attribute__ ((packed))	*c = NULL;			\
303878ed226SJulian Elischer 									\
304eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
305878ed226SJulian Elischer 	if ((_m) == NULL)						\
306878ed226SJulian Elischer 		break;							\
307878ed226SJulian Elischer 									\
308878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
309878ed226SJulian Elischer 									\
310878ed226SJulian Elischer 	c = mtod((_m), struct _discon_req *);				\
311878ed226SJulian Elischer 	c->hdr.code = NG_L2CAP_DISCON_REQ;				\
312878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
313878ed226SJulian Elischer 	c->hdr.length = htole16(sizeof(c->param));			\
314878ed226SJulian Elischer 									\
315878ed226SJulian Elischer 	c->param.dcid = htole16((_dcid));				\
316878ed226SJulian Elischer 	c->param.scid = htole16((_scid));				\
317878ed226SJulian Elischer } while (0)
318878ed226SJulian Elischer 
319878ed226SJulian Elischer /* L2CA_DisconnectRsp */
320878ed226SJulian Elischer #define	_ng_l2cap_discon_rsp(_m, _ident, _dcid, _scid)			\
321878ed226SJulian Elischer do {									\
322878ed226SJulian Elischer 	struct _discon_rsp {						\
323878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
324878ed226SJulian Elischer 		ng_l2cap_discon_rsp_cp	 param;				\
325878ed226SJulian Elischer 	} __attribute__ ((packed))	*c = NULL;			\
326878ed226SJulian Elischer 									\
327eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
328878ed226SJulian Elischer 	if ((_m) == NULL)						\
329878ed226SJulian Elischer 		break;							\
330878ed226SJulian Elischer 									\
331878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
332878ed226SJulian Elischer 									\
333878ed226SJulian Elischer 	c = mtod((_m), struct _discon_rsp *);				\
334878ed226SJulian Elischer 	c->hdr.code = NG_L2CAP_DISCON_RSP;				\
335878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
336878ed226SJulian Elischer 	c->hdr.length = htole16(sizeof(c->param));			\
337878ed226SJulian Elischer 									\
338878ed226SJulian Elischer 	c->param.dcid = htole16((_dcid));				\
339878ed226SJulian Elischer 	c->param.scid = htole16((_scid));				\
340878ed226SJulian Elischer } while (0)
341878ed226SJulian Elischer 
342878ed226SJulian Elischer /* L2CAP_EchoReq */
343878ed226SJulian Elischer #define	_ng_l2cap_echo_req(_m, _ident, _data, _size)			\
344878ed226SJulian Elischer do {									\
345878ed226SJulian Elischer 	ng_l2cap_cmd_hdr_t	*c = NULL;				\
346878ed226SJulian Elischer 									\
347eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
348878ed226SJulian Elischer 	if ((_m) == NULL) 						\
349878ed226SJulian Elischer 		break;							\
350878ed226SJulian Elischer 									\
351878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
352878ed226SJulian Elischer 									\
353878ed226SJulian Elischer 	c = mtod((_m), ng_l2cap_cmd_hdr_t *);				\
354878ed226SJulian Elischer 	c->code = NG_L2CAP_ECHO_REQ;					\
355878ed226SJulian Elischer 	c->ident = (_ident);						\
356878ed226SJulian Elischer 	c->length = 0;							\
357878ed226SJulian Elischer 									\
358878ed226SJulian Elischer 	if ((_data) != NULL) {						\
359878ed226SJulian Elischer 		m_copyback((_m), sizeof(*c), (_size), (_data));		\
360878ed226SJulian Elischer 		c->length += (_size);					\
361878ed226SJulian Elischer 	}								\
362878ed226SJulian Elischer 									\
363878ed226SJulian Elischer 	c->length = htole16(c->length);					\
364878ed226SJulian Elischer } while (0)
365878ed226SJulian Elischer 
366878ed226SJulian Elischer /* L2CAP_InfoReq */
367878ed226SJulian Elischer #define	_ng_l2cap_info_req(_m, _ident, _type)				\
368878ed226SJulian Elischer do {									\
369878ed226SJulian Elischer 	struct _info_req {						\
370878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
371878ed226SJulian Elischer 		ng_l2cap_info_req_cp	 param;				\
372878ed226SJulian Elischer 	} __attribute__ ((packed))	*c = NULL;			\
373878ed226SJulian Elischer 									\
374eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
375878ed226SJulian Elischer 	if ((_m) == NULL)						\
376878ed226SJulian Elischer 		break;							\
377878ed226SJulian Elischer 									\
378878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);			\
379878ed226SJulian Elischer 									\
380878ed226SJulian Elischer 	c = mtod((_m), struct _info_req *);				\
381878ed226SJulian Elischer 	c->hdr.code = NG_L2CAP_INFO_REQ;				\
382878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
383878ed226SJulian Elischer 	c->hdr.length = htole16(sizeof(c->param));			\
384878ed226SJulian Elischer 									\
385878ed226SJulian Elischer 	c->param.type = htole16((_type));				\
386878ed226SJulian Elischer } while (0)
387878ed226SJulian Elischer 
388878ed226SJulian Elischer /* L2CAP_InfoRsp */
389878ed226SJulian Elischer #define	_ng_l2cap_info_rsp(_m, _ident, _type, _result, _mtu)		\
390878ed226SJulian Elischer do {									\
391878ed226SJulian Elischer 	struct _info_rsp {						\
392878ed226SJulian Elischer 		ng_l2cap_cmd_hdr_t	 hdr;				\
393878ed226SJulian Elischer 		ng_l2cap_info_rsp_cp	 param;				\
394878ed226SJulian Elischer 		ng_l2cap_info_rsp_data_t data;				\
395878ed226SJulian Elischer 	} __attribute__ ((packed))	*c = NULL;			\
396878ed226SJulian Elischer 									\
397eb1b1807SGleb Smirnoff 	MGETHDR((_m), M_NOWAIT, MT_DATA);				\
398878ed226SJulian Elischer 	if ((_m) == NULL) 						\
399878ed226SJulian Elischer 		break;							\
400878ed226SJulian Elischer 									\
401878ed226SJulian Elischer 	c = mtod((_m), struct _info_rsp *);				\
402fae16029SMaksim Yevmenkin 	c->hdr.code = NG_L2CAP_INFO_RSP;				\
403878ed226SJulian Elischer 	c->hdr.ident = (_ident);					\
404878ed226SJulian Elischer 	c->hdr.length = sizeof(c->param);				\
405878ed226SJulian Elischer 									\
406878ed226SJulian Elischer 	c->param.type = htole16((_type));				\
407878ed226SJulian Elischer 	c->param.result = htole16((_result));				\
408878ed226SJulian Elischer 									\
409878ed226SJulian Elischer 	if ((_result) == NG_L2CAP_SUCCESS) {				\
410878ed226SJulian Elischer 		switch ((_type)) {					\
411878ed226SJulian Elischer 		case NG_L2CAP_CONNLESS_MTU:				\
412878ed226SJulian Elischer 			c->data.mtu.mtu = htole16((_mtu));		\
413878ed226SJulian Elischer 			c->hdr.length += sizeof((c->data.mtu.mtu));	\
414878ed226SJulian Elischer 			break;						\
415878ed226SJulian Elischer 		}							\
416878ed226SJulian Elischer 	}								\
417878ed226SJulian Elischer 									\
418878ed226SJulian Elischer 	(_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) +		\
419878ed226SJulian Elischer 					c->hdr.length;			\
420878ed226SJulian Elischer 									\
421878ed226SJulian Elischer 	c->hdr.length = htole16(c->hdr.length);		 		\
422878ed226SJulian Elischer } while (0)
423878ed226SJulian Elischer 
424878ed226SJulian Elischer void ng_l2cap_con_wakeup              (ng_l2cap_con_p);
425878ed226SJulian Elischer void ng_l2cap_con_fail                (ng_l2cap_con_p, u_int16_t);
426878ed226SJulian Elischer void ng_l2cap_process_command_timeout (node_p, hook_p, void *, int);
427878ed226SJulian Elischer 
428878ed226SJulian Elischer #endif /* ndef _NETGRAPH_L2CAP_CMDS_H_ */
429