ng_l2cap_cmds.h revision 267654
176479Swpaul/* 276479Swpaul * ng_l2cap_cmds.h 376479Swpaul */ 476479Swpaul 576479Swpaul/*- 676479Swpaul * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com> 776479Swpaul * All rights reserved. 876479Swpaul * 976479Swpaul * Redistribution and use in source and binary forms, with or without 1076479Swpaul * modification, are permitted provided that the following conditions 1176479Swpaul * are met: 1276479Swpaul * 1. Redistributions of source code must retain the above copyright 1376479Swpaul * notice, this list of conditions and the following disclaimer. 1476479Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1576479Swpaul * notice, this list of conditions and the following disclaimer in the 1676479Swpaul * documentation and/or other materials provided with the distribution. 1776479Swpaul * 1876479Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1976479Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2076479Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2176479Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2276479Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2376479Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2476479Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2576479Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2676479Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2776479Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2876479Swpaul * SUCH DAMAGE. 2976479Swpaul * 3076479Swpaul * $Id: ng_l2cap_cmds.h,v 1.4 2003/04/01 18:15:26 max Exp $ 3176479Swpaul * $FreeBSD: releng/9.3/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.h 210783 2010-08-02 22:26:08Z emax $ 3276479Swpaul */ 3376479Swpaul 3476479Swpaul#ifndef _NETGRAPH_L2CAP_CMDS_H_ 3576479Swpaul#define _NETGRAPH_L2CAP_CMDS_H_ 3676479Swpaul 3776479Swpaul/****************************************************************************** 3876479Swpaul ****************************************************************************** 3976479Swpaul ** L2CAP to L2CAP signaling command macros 4076479Swpaul ****************************************************************************** 4176479Swpaul ******************************************************************************/ 4276479Swpaul 4376479Swpaul/* 4476479Swpaul * Note: All L2CAP implementations are required to support minimal signaling 4576479Swpaul * MTU of 48 bytes. In order to simplify things we will send one command 4676479Swpaul * per one L2CAP packet. Given evrything above we can assume that one 4776479Swpaul * signaling packet will fit into single mbuf. 4876479Swpaul */ 4976479Swpaul 5076479Swpaul/* L2CAP_CommandRej */ 5176479Swpaul#define _ng_l2cap_cmd_rej(_m, _ident, _reason, _mtu, _scid, _dcid) \ 5276479Swpauldo { \ 5376479Swpaul struct _cmd_rej { \ 5476479Swpaul ng_l2cap_cmd_hdr_t hdr; \ 5576479Swpaul ng_l2cap_cmd_rej_cp param; \ 5676479Swpaul ng_l2cap_cmd_rej_data_t data; \ 5776479Swpaul } __attribute__ ((packed)) *c = NULL; \ 5876479Swpaul \ 5976479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 6076479Swpaul if ((_m) == NULL) \ 6176479Swpaul break; \ 6276479Swpaul \ 6376479Swpaul c = mtod((_m), struct _cmd_rej *); \ 6476479Swpaul c->hdr.code = NG_L2CAP_CMD_REJ; \ 6576479Swpaul c->hdr.ident = (_ident); \ 6676479Swpaul c->hdr.length = sizeof(c->param); \ 6776479Swpaul \ 6876479Swpaul c->param.reason = htole16((_reason)); \ 6976479Swpaul \ 7078323Swpaul if ((_reason) == NG_L2CAP_REJ_MTU_EXCEEDED) { \ 7178323Swpaul c->data.mtu.mtu = htole16((_mtu)); \ 7278323Swpaul c->hdr.length += sizeof(c->data.mtu); \ 7378323Swpaul } else if ((_reason) == NG_L2CAP_REJ_INVALID_CID) { \ 7478323Swpaul c->data.cid.scid = htole16((_scid)); \ 7578323Swpaul c->data.cid.dcid = htole16((_dcid)); \ 7678323Swpaul c->hdr.length += sizeof(c->data.cid); \ 7778323Swpaul } \ 7878323Swpaul \ 7978323Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + \ 8078323Swpaul c->hdr.length; \ 8178323Swpaul \ 8278323Swpaul c->hdr.length = htole16(c->hdr.length); \ 8378323Swpaul} while (0) 8478323Swpaul 8578323Swpaul/* L2CAP_ConnectReq */ 8676479Swpaul#define _ng_l2cap_con_req(_m, _ident, _psm, _scid) \ 8776479Swpauldo { \ 88113038Sobrien struct _con_req { \ 89113038Sobrien ng_l2cap_cmd_hdr_t hdr; \ 90113038Sobrien ng_l2cap_con_req_cp param; \ 9176479Swpaul } __attribute__ ((packed)) *c = NULL; \ 9276479Swpaul \ 9376479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 9476479Swpaul if ((_m) == NULL) \ 9576479Swpaul break; \ 9676479Swpaul \ 9776479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 9876479Swpaul \ 9976479Swpaul c = mtod((_m), struct _con_req *); \ 10076479Swpaul c->hdr.code = NG_L2CAP_CON_REQ; \ 10176479Swpaul c->hdr.ident = (_ident); \ 10276479Swpaul c->hdr.length = htole16(sizeof(c->param)); \ 10376479Swpaul \ 10476479Swpaul c->param.psm = htole16((_psm)); \ 10576479Swpaul c->param.scid = htole16((_scid)); \ 10676479Swpaul} while (0) 10776479Swpaul 10876479Swpaul/* L2CAP_ConnectRsp */ 10976479Swpaul#define _ng_l2cap_con_rsp(_m, _ident, _dcid, _scid, _result, _status) \ 11076479Swpauldo { \ 11176479Swpaul struct _con_rsp { \ 11276479Swpaul ng_l2cap_cmd_hdr_t hdr; \ 11376479Swpaul ng_l2cap_con_rsp_cp param; \ 11476479Swpaul } __attribute__ ((packed)) *c = NULL; \ 11576479Swpaul \ 11676479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 11776479Swpaul if ((_m) == NULL) \ 11876479Swpaul break; \ 11976479Swpaul \ 12076479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 12176479Swpaul \ 12276479Swpaul c = mtod((_m), struct _con_rsp *); \ 12376479Swpaul c->hdr.code = NG_L2CAP_CON_RSP; \ 12476479Swpaul c->hdr.ident = (_ident); \ 12576479Swpaul c->hdr.length = htole16(sizeof(c->param)); \ 12676479Swpaul \ 12776522Swpaul c->param.dcid = htole16((_dcid)); \ 12876479Swpaul c->param.scid = htole16((_scid)); \ 129113506Smdodd c->param.result = htole16((_result)); \ 130113506Smdodd c->param.status = htole16((_status)); \ 13176479Swpaul} while (0) 13276479Swpaul 13376479Swpaul/* L2CAP_ConfigReq */ 13476479Swpaul#define _ng_l2cap_cfg_req(_m, _ident, _dcid, _flags, _data) \ 13576479Swpauldo { \ 13676479Swpaul struct _cfg_req { \ 13776479Swpaul ng_l2cap_cmd_hdr_t hdr; \ 13876479Swpaul ng_l2cap_cfg_req_cp param; \ 13976479Swpaul } __attribute__ ((packed)) *c = NULL; \ 14076479Swpaul \ 14176479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 14276479Swpaul if ((_m) == NULL) { \ 14376479Swpaul NG_FREE_M((_data)); \ 14476479Swpaul break; \ 14576479Swpaul } \ 14676479Swpaul \ 14799497Salfred (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 14899497Salfred \ 14999497Salfred c = mtod((_m), struct _cfg_req *); \ 15076479Swpaul c->hdr.code = NG_L2CAP_CFG_REQ; \ 15199497Salfred c->hdr.ident = (_ident); \ 15299497Salfred c->hdr.length = sizeof(c->param); \ 15399497Salfred \ 15499497Salfred c->param.dcid = htole16((_dcid)); \ 15576479Swpaul c->param.flags = htole16((_flags)); \ 15699497Salfred if ((_data) != NULL) { \ 15799497Salfred int l = (_data)->m_pkthdr.len; \ 15899497Salfred \ 15999497Salfred m_cat((_m), (_data)); \ 16099497Salfred c->hdr.length += l; \ 16199497Salfred (_m)->m_pkthdr.len += l; \ 16299497Salfred } \ 16399497Salfred \ 16499497Salfred c->hdr.length = htole16(c->hdr.length); \ 16599497Salfred} while (0) 16699497Salfred 16799497Salfred/* L2CAP_ConfigRsp */ 16899497Salfred#define _ng_l2cap_cfg_rsp(_m, _ident, _scid, _flags, _result, _data) \ 16999497Salfreddo { \ 17076479Swpaul struct _cfg_rsp { \ 17199497Salfred ng_l2cap_cmd_hdr_t hdr; \ 17299497Salfred ng_l2cap_cfg_rsp_cp param; \ 17399497Salfred } __attribute__ ((packed)) *c = NULL; \ 17499497Salfred \ 17599497Salfred MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 17676479Swpaul if ((_m) == NULL) { \ 17799497Salfred NG_FREE_M((_data)); \ 17899497Salfred break; \ 17999497Salfred } \ 18099497Salfred \ 18176479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 18299497Salfred \ 18399497Salfred c = mtod((_m), struct _cfg_rsp *); \ 18499497Salfred c->hdr.code = NG_L2CAP_CFG_RSP; \ 18576479Swpaul c->hdr.ident = (_ident); \ 18699497Salfred c->hdr.length = sizeof(c->param); \ 18799497Salfred \ 18899497Salfred c->param.scid = htole16((_scid)); \ 18999497Salfred c->param.flags = htole16((_flags)); \ 19099497Salfred c->param.result = htole16((_result)); \ 19176479Swpaul if ((_data) != NULL) { \ 19276479Swpaul int l = (_data)->m_pkthdr.len; \ 19376479Swpaul \ 19476479Swpaul m_cat((_m), (_data)); \ 19576479Swpaul c->hdr.length += l; \ 19676479Swpaul (_m)->m_pkthdr.len += l; \ 19776479Swpaul } \ 19876479Swpaul \ 19976479Swpaul c->hdr.length = htole16(c->hdr.length); \ 20076479Swpaul} while (0) 20176479Swpaul 20276479Swpaul/* Build configuration options */ 20376479Swpaul#define _ng_l2cap_build_cfg_options(_m, _mtu, _flush_timo, _flow) \ 20476479Swpauldo { \ 20576479Swpaul u_int8_t *p = NULL; \ 20676479Swpaul \ 20776479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 20876479Swpaul if ((_m) == NULL) \ 20976479Swpaul break; \ 21076479Swpaul \ 21176479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = 0; \ 21276479Swpaul p = mtod((_m), u_int8_t *); \ 21376479Swpaul \ 21476479Swpaul if ((_mtu) != NULL) { \ 21576479Swpaul struct _cfg_opt_mtu { \ 21676479Swpaul ng_l2cap_cfg_opt_t hdr; \ 21776479Swpaul u_int16_t val; \ 21876479Swpaul } __attribute__ ((packed)) *o = NULL; \ 21976479Swpaul \ 22076479Swpaul o = (struct _cfg_opt_mtu *) p; \ 22176479Swpaul o->hdr.type = NG_L2CAP_OPT_MTU; \ 22276479Swpaul o->hdr.length = sizeof(o->val); \ 22376479Swpaul o->val = htole16(*(u_int16_t *)(_mtu)); \ 22476479Swpaul \ 22576479Swpaul (_m)->m_pkthdr.len += sizeof(*o); \ 22676479Swpaul p += sizeof(*o); \ 227113506Smdodd } \ 22876479Swpaul \ 22976479Swpaul if ((_flush_timo) != NULL) { \ 23076479Swpaul struct _cfg_opt_flush { \ 23176479Swpaul ng_l2cap_cfg_opt_t hdr; \ 23276479Swpaul u_int16_t val; \ 23376479Swpaul } __attribute__ ((packed)) *o = NULL; \ 23476479Swpaul \ 23576479Swpaul o = (struct _cfg_opt_flush *) p; \ 23676479Swpaul o->hdr.type = NG_L2CAP_OPT_FLUSH_TIMO; \ 23776479Swpaul o->hdr.length = sizeof(o->val); \ 23876479Swpaul o->val = htole16(*(u_int16_t *)(_flush_timo)); \ 239106696Salfred \ 24076479Swpaul (_m)->m_pkthdr.len += sizeof(*o); \ 24176479Swpaul p += sizeof(*o); \ 242106696Salfred } \ 24376479Swpaul \ 24499497Salfred if ((_flow) != NULL) { \ 24599497Salfred struct _cfg_opt_flow { \ 24676479Swpaul ng_l2cap_cfg_opt_t hdr; \ 24776479Swpaul ng_l2cap_flow_t val; \ 24876479Swpaul } __attribute__ ((packed)) *o = NULL; \ 24976479Swpaul \ 25076479Swpaul o = (struct _cfg_opt_flow *) p; \ 25176479Swpaul o->hdr.type = NG_L2CAP_OPT_QOS; \ 25276479Swpaul o->hdr.length = sizeof(o->val); \ 25376479Swpaul o->val.flags = ((ng_l2cap_flow_p)(_flow))->flags; \ 25476479Swpaul o->val.service_type = ((ng_l2cap_flow_p) \ 25576479Swpaul (_flow))->service_type; \ 25699497Salfred o->val.token_rate = \ 25799497Salfred htole32(((ng_l2cap_flow_p)(_flow))->token_rate);\ 25876479Swpaul o->val.token_bucket_size = \ 25976479Swpaul htole32(((ng_l2cap_flow_p) \ 26076479Swpaul (_flow))->token_bucket_size); \ 26176479Swpaul o->val.peak_bandwidth = \ 26276479Swpaul htole32(((ng_l2cap_flow_p) \ 26376479Swpaul (_flow))->peak_bandwidth); \ 26476479Swpaul o->val.latency = htole32(((ng_l2cap_flow_p) \ 26576479Swpaul (_flow))->latency); \ 26676479Swpaul o->val.delay_variation = \ 26776479Swpaul htole32(((ng_l2cap_flow_p) \ 26876479Swpaul (_flow))->delay_variation); \ 26976479Swpaul \ 27076479Swpaul (_m)->m_pkthdr.len += sizeof(*o); \ 27176479Swpaul } \ 27276479Swpaul \ 27376479Swpaul (_m)->m_len = (_m)->m_pkthdr.len; \ 27476479Swpaul} while (0) 27576479Swpaul 27676479Swpaul/* L2CAP_DisconnectReq */ 27776479Swpaul#define _ng_l2cap_discon_req(_m, _ident, _dcid, _scid) \ 27876479Swpauldo { \ 27976479Swpaul struct _discon_req { \ 28076479Swpaul ng_l2cap_cmd_hdr_t hdr; \ 28176479Swpaul ng_l2cap_discon_req_cp param; \ 28276479Swpaul } __attribute__ ((packed)) *c = NULL; \ 28376479Swpaul \ 28476479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 28576479Swpaul if ((_m) == NULL) \ 28699497Salfred break; \ 28799497Salfred \ 28876479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 28976479Swpaul \ 29076479Swpaul c = mtod((_m), struct _discon_req *); \ 29176479Swpaul c->hdr.code = NG_L2CAP_DISCON_REQ; \ 29276479Swpaul c->hdr.ident = (_ident); \ 29376479Swpaul c->hdr.length = htole16(sizeof(c->param)); \ 29476479Swpaul \ 29576479Swpaul c->param.dcid = htole16((_dcid)); \ 29676479Swpaul c->param.scid = htole16((_scid)); \ 29776479Swpaul} while (0) 29876479Swpaul 29976479Swpaul/* L2CA_DisconnectRsp */ 30076479Swpaul#define _ng_l2cap_discon_rsp(_m, _ident, _dcid, _scid) \ 30176479Swpauldo { \ 30276479Swpaul struct _discon_rsp { \ 30376479Swpaul ng_l2cap_cmd_hdr_t hdr; \ 30476479Swpaul ng_l2cap_discon_rsp_cp param; \ 30576479Swpaul } __attribute__ ((packed)) *c = NULL; \ 30676479Swpaul \ 30776479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 30876479Swpaul if ((_m) == NULL) \ 30976479Swpaul break; \ 31076479Swpaul \ 31176479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 31276479Swpaul \ 31376479Swpaul c = mtod((_m), struct _discon_rsp *); \ 31476479Swpaul c->hdr.code = NG_L2CAP_DISCON_RSP; \ 31576479Swpaul c->hdr.ident = (_ident); \ 31676479Swpaul c->hdr.length = htole16(sizeof(c->param)); \ 31799497Salfred \ 31899497Salfred c->param.dcid = htole16((_dcid)); \ 31976479Swpaul c->param.scid = htole16((_scid)); \ 32076479Swpaul} while (0) 32176479Swpaul 32276479Swpaul/* L2CAP_EchoReq */ 32376479Swpaul#define _ng_l2cap_echo_req(_m, _ident, _data, _size) \ 32476479Swpauldo { \ 32576479Swpaul ng_l2cap_cmd_hdr_t *c = NULL; \ 32676479Swpaul \ 32776479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 32876479Swpaul if ((_m) == NULL) \ 32976479Swpaul break; \ 33076479Swpaul \ 33176479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 33276479Swpaul \ 33376479Swpaul c = mtod((_m), ng_l2cap_cmd_hdr_t *); \ 33476479Swpaul c->code = NG_L2CAP_ECHO_REQ; \ 33576479Swpaul c->ident = (_ident); \ 33676479Swpaul c->length = 0; \ 33776479Swpaul \ 33876479Swpaul if ((_data) != NULL) { \ 33976479Swpaul m_copyback((_m), sizeof(*c), (_size), (_data)); \ 34076479Swpaul c->length += (_size); \ 34176479Swpaul } \ 34276479Swpaul \ 34376479Swpaul c->length = htole16(c->length); \ 34476479Swpaul} while (0) 34576479Swpaul 34676479Swpaul/* L2CAP_InfoReq */ 34776479Swpaul#define _ng_l2cap_info_req(_m, _ident, _type) \ 34876479Swpauldo { \ 34976479Swpaul struct _info_req { \ 35076479Swpaul ng_l2cap_cmd_hdr_t hdr; \ 35176479Swpaul ng_l2cap_info_req_cp param; \ 35276479Swpaul } __attribute__ ((packed)) *c = NULL; \ 35376479Swpaul \ 35476479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 35576479Swpaul if ((_m) == NULL) \ 35676479Swpaul break; \ 35776479Swpaul \ 35876479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c); \ 35976479Swpaul \ 36076479Swpaul c = mtod((_m), struct _info_req *); \ 36176479Swpaul c->hdr.code = NG_L2CAP_INFO_REQ; \ 36276479Swpaul c->hdr.ident = (_ident); \ 36376479Swpaul c->hdr.length = htole16(sizeof(c->param)); \ 36476479Swpaul \ 36599497Salfred c->param.type = htole16((_type)); \ 36699497Salfred} while (0) 36776479Swpaul 36876479Swpaul/* L2CAP_InfoRsp */ 36976479Swpaul#define _ng_l2cap_info_rsp(_m, _ident, _type, _result, _mtu) \ 37076479Swpauldo { \ 37176479Swpaul struct _info_rsp { \ 37276479Swpaul ng_l2cap_cmd_hdr_t hdr; \ 37376479Swpaul ng_l2cap_info_rsp_cp param; \ 37476479Swpaul ng_l2cap_info_rsp_data_t data; \ 37576479Swpaul } __attribute__ ((packed)) *c = NULL; \ 37676479Swpaul \ 37776479Swpaul MGETHDR((_m), M_DONTWAIT, MT_DATA); \ 37876479Swpaul if ((_m) == NULL) \ 37976479Swpaul break; \ 38076479Swpaul \ 38176479Swpaul c = mtod((_m), struct _info_rsp *); \ 38276479Swpaul c->hdr.code = NG_L2CAP_INFO_RSP; \ 38376479Swpaul c->hdr.ident = (_ident); \ 38476479Swpaul c->hdr.length = sizeof(c->param); \ 38576479Swpaul \ 38676479Swpaul c->param.type = htole16((_type)); \ 38776479Swpaul c->param.result = htole16((_result)); \ 38876479Swpaul \ 38976479Swpaul if ((_result) == NG_L2CAP_SUCCESS) { \ 39076479Swpaul switch ((_type)) { \ 39199497Salfred case NG_L2CAP_CONNLESS_MTU: \ 39299497Salfred c->data.mtu.mtu = htole16((_mtu)); \ 39376479Swpaul c->hdr.length += sizeof((c->data.mtu.mtu)); \ 39476479Swpaul break; \ 39576479Swpaul } \ 39676479Swpaul } \ 39776479Swpaul \ 39876479Swpaul (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) + \ 39976479Swpaul c->hdr.length; \ 40076479Swpaul \ 40176479Swpaul c->hdr.length = htole16(c->hdr.length); \ 40276479Swpaul} while (0) 40376479Swpaul 40476479Swpaulvoid ng_l2cap_con_wakeup (ng_l2cap_con_p); 40576479Swpaulvoid ng_l2cap_con_fail (ng_l2cap_con_p, u_int16_t); 40676479Swpaulvoid ng_l2cap_process_command_timeout (node_p, hook_p, void *, int); 40776479Swpaul 40876479Swpaul#endif /* ndef _NETGRAPH_L2CAP_CMDS_H_ */ 40976479Swpaul 41076479Swpaul