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