ng_l2cap_cmds.h revision 114878
1107120Sjulian/* 2107120Sjulian * ng_l2cap_cmds.h 3107120Sjulian * 4107120Sjulian * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com> 5107120Sjulian * All rights reserved. 6107120Sjulian * 7107120Sjulian * Redistribution and use in source and binary forms, with or without 8107120Sjulian * modification, are permitted provided that the following conditions 9107120Sjulian * are met: 10107120Sjulian * 1. Redistributions of source code must retain the above copyright 11107120Sjulian * notice, this list of conditions and the following disclaimer. 12107120Sjulian * 2. Redistributions in binary form must reproduce the above copyright 13107120Sjulian * notice, this list of conditions and the following disclaimer in the 14107120Sjulian * documentation and/or other materials provided with the distribution. 15107120Sjulian * 16107120Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17107120Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18107120Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19107120Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20107120Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21107120Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22107120Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23107120Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24107120Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25107120Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26107120Sjulian * SUCH DAMAGE. 27107120Sjulian * 28114878Sjulian * $Id: ng_l2cap_cmds.h,v 1.4 2003/04/01 18:15:26 max Exp $ 29107120Sjulian * $FreeBSD: head/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.h 114878 2003-05-10 21:44:42Z julian $ 30107120Sjulian */ 31107120Sjulian 32107120Sjulian#ifndef _NETGRAPH_L2CAP_CMDS_H_ 33107120Sjulian#define _NETGRAPH_L2CAP_CMDS_H_ 34107120Sjulian 35107120Sjulian/****************************************************************************** 36107120Sjulian ****************************************************************************** 37107120Sjulian ** L2CAP to L2CAP signaling command macros 38107120Sjulian ****************************************************************************** 39107120Sjulian ******************************************************************************/ 40107120Sjulian 41107120Sjulian/* 42107120Sjulian * Note: All L2CAP implementations are required to support minimal signaling 43107120Sjulian * MTU of 48 bytes. In order to simplify things we will send one command 44107120Sjulian * per one L2CAP packet. Given evrything above we can assume that one 45107120Sjulian * signaling packet will fit into single mbuf. 46107120Sjulian */ 47107120Sjulian 48107120Sjulian/* L2CAP_CommandRej */ 49107120Sjulian#define _ng_l2cap_cmd_rej(_m, _ident, _reason, _mtu, _scid, _dcid) \ 50107120Sjuliando { \ 51107120Sjulian struct _cmd_rej { \ 52107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 53107120Sjulian ng_l2cap_cmd_rej_cp param; \ 54107120Sjulian ng_l2cap_cmd_rej_data_t data; \ 55107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 56107120Sjulian \ 57111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 58107120Sjulian if ((_m) == NULL) \ 59107120Sjulian break; \ 60107120Sjulian \ 61107120Sjulian c = mtod((_m), struct _cmd_rej *); \ 62107120Sjulian c->hdr.code = NG_L2CAP_CMD_REJ; \ 63107120Sjulian c->hdr.ident = (_ident); \ 64107120Sjulian c->hdr.length = sizeof(c->param); \ 65107120Sjulian \ 66107120Sjulian c->param.reason = htole16((_reason)); \ 67107120Sjulian \ 68107120Sjulian if ((_reason) == NG_L2CAP_REJ_MTU_EXCEEDED) { \ 69107120Sjulian c->data.mtu.mtu = htole16((_mtu)); \ 70107120Sjulian c->hdr.length += sizeof(c->data.mtu); \ 71107120Sjulian } else if ((_reason) == NG_L2CAP_REJ_INVALID_CID) { \ 72107120Sjulian c->data.cid.scid = htole16((_scid)); \ 73107120Sjulian c->data.cid.dcid = htole16((_dcid)); \ 74107120Sjulian c->hdr.length += sizeof(c->data.cid); \ 75107120Sjulian } \ 76107120Sjulian \ 77107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + \ 78107120Sjulian c->hdr.length; \ 79107120Sjulian \ 80107120Sjulian c->hdr.length = htole16(c->hdr.length); \ 81107120Sjulian} while (0) 82107120Sjulian 83107120Sjulian/* L2CAP_ConnectReq */ 84107120Sjulian#define _ng_l2cap_con_req(_m, _ident, _psm, _scid) \ 85107120Sjuliando { \ 86107120Sjulian struct _con_req { \ 87107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 88107120Sjulian ng_l2cap_con_req_cp param; \ 89107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 90107120Sjulian \ 91111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 92107120Sjulian if ((_m) == NULL) \ 93107120Sjulian break; \ 94107120Sjulian \ 95107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 96107120Sjulian \ 97107120Sjulian c = mtod((_m), struct _con_req *); \ 98107120Sjulian c->hdr.code = NG_L2CAP_CON_REQ; \ 99107120Sjulian c->hdr.ident = (_ident); \ 100107120Sjulian c->hdr.length = htole16(sizeof(c->param)); \ 101107120Sjulian \ 102107120Sjulian c->param.psm = htole16((_psm)); \ 103107120Sjulian c->param.scid = htole16((_scid)); \ 104107120Sjulian} while (0) 105107120Sjulian 106107120Sjulian/* L2CAP_ConnectRsp */ 107107120Sjulian#define _ng_l2cap_con_rsp(_m, _ident, _dcid, _scid, _result, _status) \ 108107120Sjuliando { \ 109107120Sjulian struct _con_rsp { \ 110107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 111107120Sjulian ng_l2cap_con_rsp_cp param; \ 112107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 113107120Sjulian \ 114111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 115107120Sjulian if ((_m) == NULL) \ 116107120Sjulian break; \ 117107120Sjulian \ 118107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 119107120Sjulian \ 120107120Sjulian c = mtod((_m), struct _con_rsp *); \ 121107120Sjulian c->hdr.code = NG_L2CAP_CON_RSP; \ 122107120Sjulian c->hdr.ident = (_ident); \ 123107120Sjulian c->hdr.length = htole16(sizeof(c->param)); \ 124107120Sjulian \ 125107120Sjulian c->param.dcid = htole16((_dcid)); \ 126107120Sjulian c->param.scid = htole16((_scid)); \ 127107120Sjulian c->param.result = htole16((_result)); \ 128107120Sjulian c->param.status = htole16((_status)); \ 129107120Sjulian} while (0) 130107120Sjulian 131107120Sjulian/* L2CAP_ConfigReq */ 132107120Sjulian#define _ng_l2cap_cfg_req(_m, _ident, _dcid, _flags, _data) \ 133107120Sjuliando { \ 134107120Sjulian struct _cfg_req { \ 135107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 136107120Sjulian ng_l2cap_cfg_req_cp param; \ 137107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 138107120Sjulian \ 139111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 140107120Sjulian if ((_m) == NULL) { \ 141107120Sjulian NG_FREE_M((_data)); \ 142107120Sjulian break; \ 143107120Sjulian } \ 144107120Sjulian \ 145107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 146107120Sjulian \ 147107120Sjulian c = mtod((_m), struct _cfg_req *); \ 148107120Sjulian c->hdr.code = NG_L2CAP_CFG_REQ; \ 149107120Sjulian c->hdr.ident = (_ident); \ 150107120Sjulian c->hdr.length = sizeof(c->param); \ 151107120Sjulian \ 152107120Sjulian c->param.dcid = htole16((_dcid)); \ 153107120Sjulian c->param.flags = htole16((_flags)); \ 154107120Sjulian if ((_data) != NULL) { \ 155114878Sjulian int l = (_data)->m_pkthdr.len; \ 156114878Sjulian \ 157107120Sjulian m_cat((_m), (_data)); \ 158114878Sjulian c->hdr.length += l; \ 159114878Sjulian (_m)->m_pkthdr.len += l; \ 160107120Sjulian } \ 161107120Sjulian \ 162107120Sjulian c->hdr.length = htole16(c->hdr.length); \ 163107120Sjulian} while (0) 164107120Sjulian 165107120Sjulian/* L2CAP_ConfigRsp */ 166107120Sjulian#define _ng_l2cap_cfg_rsp(_m, _ident, _scid, _flags, _result, _data) \ 167107120Sjuliando { \ 168107120Sjulian struct _cfg_rsp { \ 169107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 170107120Sjulian ng_l2cap_cfg_rsp_cp param; \ 171107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 172107120Sjulian \ 173111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 174107120Sjulian if ((_m) == NULL) { \ 175107120Sjulian NG_FREE_M((_data)); \ 176107120Sjulian break; \ 177107120Sjulian } \ 178107120Sjulian \ 179107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 180107120Sjulian \ 181107120Sjulian c = mtod((_m), struct _cfg_rsp *); \ 182107120Sjulian c->hdr.code = NG_L2CAP_CFG_RSP; \ 183107120Sjulian c->hdr.ident = (_ident); \ 184107120Sjulian c->hdr.length = sizeof(c->param); \ 185107120Sjulian \ 186107120Sjulian c->param.scid = htole16((_scid)); \ 187107120Sjulian c->param.flags = htole16((_flags)); \ 188107120Sjulian c->param.result = htole16((_result)); \ 189107120Sjulian if ((_data) != NULL) { \ 190114878Sjulian int l = (_data)->m_pkthdr.len; \ 191114878Sjulian \ 192107120Sjulian m_cat((_m), (_data)); \ 193114878Sjulian c->hdr.length += l; \ 194114878Sjulian (_m)->m_pkthdr.len += l; \ 195107120Sjulian } \ 196107120Sjulian \ 197107120Sjulian c->hdr.length = htole16(c->hdr.length); \ 198107120Sjulian} while (0) 199107120Sjulian 200107120Sjulian/* Build configuration options */ 201107120Sjulian#define _ng_l2cap_build_cfg_options(_m, _mtu, _flush_timo, _flow) \ 202107120Sjuliando { \ 203107120Sjulian u_int8_t *p = NULL; \ 204107120Sjulian \ 205111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 206107120Sjulian if ((_m) == NULL) \ 207107120Sjulian break; \ 208107120Sjulian \ 209107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = 0; \ 210107120Sjulian p = mtod((_m), u_int8_t *); \ 211107120Sjulian \ 212107120Sjulian if ((_mtu) != NULL) { \ 213107120Sjulian struct _cfg_opt_mtu { \ 214107120Sjulian ng_l2cap_cfg_opt_t hdr; \ 215107120Sjulian u_int16_t val; \ 216107120Sjulian } __attribute__ ((packed)) *o = NULL; \ 217107120Sjulian \ 218107120Sjulian o = (struct _cfg_opt_mtu *) p; \ 219107120Sjulian o->hdr.type = NG_L2CAP_OPT_MTU; \ 220107120Sjulian o->hdr.length = sizeof(o->val); \ 221107120Sjulian o->val = htole16(*(u_int16_t *)(_mtu)); \ 222107120Sjulian \ 223107120Sjulian (_m)->m_pkthdr.len += sizeof(*o); \ 224107120Sjulian p += sizeof(*o); \ 225107120Sjulian } \ 226107120Sjulian \ 227107120Sjulian if ((_flush_timo) != NULL) { \ 228107120Sjulian struct _cfg_opt_flush { \ 229107120Sjulian ng_l2cap_cfg_opt_t hdr; \ 230107120Sjulian u_int16_t val; \ 231107120Sjulian } __attribute__ ((packed)) *o = NULL; \ 232107120Sjulian \ 233107120Sjulian o = (struct _cfg_opt_flush *) p; \ 234107120Sjulian o->hdr.type = NG_L2CAP_OPT_FLUSH_TIMO; \ 235107120Sjulian o->hdr.length = sizeof(o->val); \ 236107120Sjulian o->val = htole16(*(u_int16_t *)(_flush_timo)); \ 237107120Sjulian \ 238107120Sjulian (_m)->m_pkthdr.len += sizeof(*o); \ 239107120Sjulian p += sizeof(*o); \ 240107120Sjulian } \ 241107120Sjulian \ 242107120Sjulian if ((_flow) != NULL) { \ 243107120Sjulian struct _cfg_opt_flow { \ 244107120Sjulian ng_l2cap_cfg_opt_t hdr; \ 245107120Sjulian ng_l2cap_flow_t val; \ 246107120Sjulian } __attribute__ ((packed)) *o = NULL; \ 247107120Sjulian \ 248107120Sjulian o = (struct _cfg_opt_flow *) p; \ 249107120Sjulian o->hdr.type = NG_L2CAP_OPT_QOS; \ 250107120Sjulian o->hdr.length = sizeof(o->val); \ 251107120Sjulian o->val.flags = ((ng_l2cap_flow_p)(_flow))->flags; \ 252107120Sjulian o->val.service_type = ((ng_l2cap_flow_p) \ 253107120Sjulian (_flow))->service_type; \ 254107120Sjulian o->val.token_rate = \ 255107120Sjulian htole32(((ng_l2cap_flow_p)(_flow))->token_rate);\ 256107120Sjulian o->val.token_bucket_size = \ 257107120Sjulian htole32(((ng_l2cap_flow_p) \ 258107120Sjulian (_flow))->token_bucket_size); \ 259107120Sjulian o->val.peak_bandwidth = \ 260107120Sjulian htole32(((ng_l2cap_flow_p) \ 261107120Sjulian (_flow))->peak_bandwidth); \ 262107120Sjulian o->val.latency = htole32(((ng_l2cap_flow_p) \ 263107120Sjulian (_flow))->latency); \ 264107120Sjulian o->val.delay_variation = \ 265107120Sjulian htole32(((ng_l2cap_flow_p) \ 266107120Sjulian (_flow))->delay_variation); \ 267107120Sjulian \ 268107120Sjulian (_m)->m_pkthdr.len += sizeof(*o); \ 269107120Sjulian } \ 270107120Sjulian \ 271107120Sjulian (_m)->m_len = (_m)->m_pkthdr.len; \ 272107120Sjulian} while (0) 273107120Sjulian 274107120Sjulian/* L2CAP_DisconnectReq */ 275107120Sjulian#define _ng_l2cap_discon_req(_m, _ident, _dcid, _scid) \ 276107120Sjuliando { \ 277107120Sjulian struct _discon_req { \ 278107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 279107120Sjulian ng_l2cap_discon_req_cp param; \ 280107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 281107120Sjulian \ 282111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 283107120Sjulian if ((_m) == NULL) \ 284107120Sjulian break; \ 285107120Sjulian \ 286107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 287107120Sjulian \ 288107120Sjulian c = mtod((_m), struct _discon_req *); \ 289107120Sjulian c->hdr.code = NG_L2CAP_DISCON_REQ; \ 290107120Sjulian c->hdr.ident = (_ident); \ 291107120Sjulian c->hdr.length = htole16(sizeof(c->param)); \ 292107120Sjulian \ 293107120Sjulian c->param.dcid = htole16((_dcid)); \ 294107120Sjulian c->param.scid = htole16((_scid)); \ 295107120Sjulian} while (0) 296107120Sjulian 297107120Sjulian/* L2CA_DisconnectRsp */ 298107120Sjulian#define _ng_l2cap_discon_rsp(_m, _ident, _dcid, _scid) \ 299107120Sjuliando { \ 300107120Sjulian struct _discon_rsp { \ 301107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 302107120Sjulian ng_l2cap_discon_rsp_cp param; \ 303107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 304107120Sjulian \ 305111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 306107120Sjulian if ((_m) == NULL) \ 307107120Sjulian break; \ 308107120Sjulian \ 309107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 310107120Sjulian \ 311107120Sjulian c = mtod((_m), struct _discon_rsp *); \ 312107120Sjulian c->hdr.code = NG_L2CAP_DISCON_RSP; \ 313107120Sjulian c->hdr.ident = (_ident); \ 314107120Sjulian c->hdr.length = htole16(sizeof(c->param)); \ 315107120Sjulian \ 316107120Sjulian c->param.dcid = htole16((_dcid)); \ 317107120Sjulian c->param.scid = htole16((_scid)); \ 318107120Sjulian} while (0) 319107120Sjulian 320107120Sjulian/* L2CAP_EchoReq */ 321107120Sjulian#define _ng_l2cap_echo_req(_m, _ident, _data, _size) \ 322107120Sjuliando { \ 323107120Sjulian ng_l2cap_cmd_hdr_t *c = NULL; \ 324107120Sjulian \ 325111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 326107120Sjulian if ((_m) == NULL) \ 327107120Sjulian break; \ 328107120Sjulian \ 329107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 330107120Sjulian \ 331107120Sjulian c = mtod((_m), ng_l2cap_cmd_hdr_t *); \ 332107120Sjulian c->code = NG_L2CAP_ECHO_REQ; \ 333107120Sjulian c->ident = (_ident); \ 334107120Sjulian c->length = 0; \ 335107120Sjulian \ 336107120Sjulian if ((_data) != NULL) { \ 337107120Sjulian m_copyback((_m), sizeof(*c), (_size), (_data)); \ 338107120Sjulian c->length += (_size); \ 339107120Sjulian } \ 340107120Sjulian \ 341107120Sjulian c->length = htole16(c->length); \ 342107120Sjulian} while (0) 343107120Sjulian 344107120Sjulian/* L2CAP_InfoReq */ 345107120Sjulian#define _ng_l2cap_info_req(_m, _ident, _type) \ 346107120Sjuliando { \ 347107120Sjulian struct _info_req { \ 348107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 349107120Sjulian ng_l2cap_info_req_cp param; \ 350107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 351107120Sjulian \ 352111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 353107120Sjulian if ((_m) == NULL) \ 354107120Sjulian break; \ 355107120Sjulian \ 356107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 357107120Sjulian \ 358107120Sjulian c = mtod((_m), struct _info_req *); \ 359107120Sjulian c->hdr.code = NG_L2CAP_INFO_REQ; \ 360107120Sjulian c->hdr.ident = (_ident); \ 361107120Sjulian c->hdr.length = htole16(sizeof(c->param)); \ 362107120Sjulian \ 363107120Sjulian c->param.type = htole16((_type)); \ 364107120Sjulian} while (0) 365107120Sjulian 366107120Sjulian/* L2CAP_InfoRsp */ 367107120Sjulian#define _ng_l2cap_info_rsp(_m, _ident, _type, _result, _mtu) \ 368107120Sjuliando { \ 369107120Sjulian struct _info_rsp { \ 370107120Sjulian ng_l2cap_cmd_hdr_t hdr; \ 371107120Sjulian ng_l2cap_info_rsp_cp param; \ 372107120Sjulian ng_l2cap_info_rsp_data_t data; \ 373107120Sjulian } __attribute__ ((packed)) *c = NULL; \ 374107120Sjulian \ 375111119Simp MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 376107120Sjulian if ((_m) == NULL) \ 377107120Sjulian break; \ 378107120Sjulian \ 379107120Sjulian c = mtod((_m), struct _info_rsp *); \ 380107120Sjulian c->hdr.code = NG_L2CAP_INFO_REQ; \ 381107120Sjulian c->hdr.ident = (_ident); \ 382107120Sjulian c->hdr.length = sizeof(c->param); \ 383107120Sjulian \ 384107120Sjulian c->param.type = htole16((_type)); \ 385107120Sjulian c->param.result = htole16((_result)); \ 386107120Sjulian \ 387107120Sjulian if ((_result) == NG_L2CAP_SUCCESS) { \ 388107120Sjulian switch ((_type)) { \ 389107120Sjulian case NG_L2CAP_CONNLESS_MTU: \ 390107120Sjulian c->data.mtu.mtu = htole16((_mtu)); \ 391107120Sjulian c->hdr.length += sizeof((c->data.mtu.mtu)); \ 392107120Sjulian break; \ 393107120Sjulian } \ 394107120Sjulian } \ 395107120Sjulian \ 396107120Sjulian (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + \ 397107120Sjulian c->hdr.length; \ 398107120Sjulian \ 399107120Sjulian c->hdr.length = htole16(c->hdr.length); \ 400107120Sjulian} while (0) 401107120Sjulian 402107120Sjulianvoid ng_l2cap_con_wakeup (ng_l2cap_con_p); 403107120Sjulianvoid ng_l2cap_con_fail (ng_l2cap_con_p, u_int16_t); 404107120Sjulianvoid ng_l2cap_process_command_timeout (node_p, hook_p, void *, int); 405107120Sjulian 406107120Sjulian#endif /* ndef _NETGRAPH_L2CAP_CMDS_H_ */ 407107120Sjulian 408