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