xref: /dragonfly/sys/netgraph7/bluetooth/l2cap/ng_l2cap_cmds.h (revision b5523eac31a95e6876e05e20e6fe836ec3a45202)
1 /*
2  * ng_l2cap_cmds.h
3  */
4 
5 /*-
6  * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $Id: ng_l2cap_cmds.h,v 1.4 2003/04/01 18:15:26 max Exp $
31  * $FreeBSD: src/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.h,v 1.5 2005/01/07 01:45:43 imp Exp $
32  */
33 
34 #ifndef _NETGRAPH_L2CAP_CMDS_H_
35 #define _NETGRAPH_L2CAP_CMDS_H_
36 
37 /******************************************************************************
38  ******************************************************************************
39  **                L2CAP to L2CAP signaling command macros
40  ******************************************************************************
41  ******************************************************************************/
42 
43 /*
44  * Note: All L2CAP implementations are required to support minimal signaling
45  *       MTU of 48 bytes. In order to simplify things we will send one command
46  *       per one L2CAP packet. Given evrything above we can assume that one
47  *       signaling packet will fit into single mbuf.
48  */
49 
50 /* L2CAP_CommandRej */
51 #define   _ng_l2cap_cmd_rej(_m, _ident, _reason, _mtu, _scid, _dcid)  \
52 do {                                                                                      \
53           struct _cmd_rej {                                                     \
54                     ng_l2cap_cmd_hdr_t   hdr;                                   \
55                     ng_l2cap_cmd_rej_cp  param;                                 \
56                     ng_l2cap_cmd_rej_data_t        data;                                  \
57           } __attribute__ ((packed))    *c = NULL;                              \
58                                                                                           \
59           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
60           if ((_m) == NULL)                                                     \
61                     break;                                                                \
62                                                                                           \
63           c = mtod((_m), struct _cmd_rej *);                                    \
64           c->hdr.code = NG_L2CAP_CMD_REJ;                                                 \
65           c->hdr.ident = (_ident);                                              \
66           c->hdr.length = sizeof(c->param);                                     \
67                                                                                           \
68           c->param.reason = htole16((_reason));                                 \
69                                                                                           \
70           if ((_reason) == NG_L2CAP_REJ_MTU_EXCEEDED) {                         \
71                     c->data.mtu.mtu = htole16((_mtu));                          \
72                     c->hdr.length += sizeof(c->data.mtu);                       \
73           } else if ((_reason) == NG_L2CAP_REJ_INVALID_CID) {                   \
74                     c->data.cid.scid = htole16((_scid));                        \
75                     c->data.cid.dcid = htole16((_dcid));                        \
76                     c->hdr.length += sizeof(c->data.cid);                       \
77           }                                                                               \
78                                                                                           \
79           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) +                   \
80                                                   c->hdr.length;                          \
81                                                                                           \
82           c->hdr.length = htole16(c->hdr.length);                               \
83 } while (0)
84 
85 /* L2CAP_ConnectReq */
86 #define   _ng_l2cap_con_req(_m, _ident, _psm, _scid)                            \
87 do {                                                                                      \
88           struct _con_req {                                                     \
89                     ng_l2cap_cmd_hdr_t   hdr;                                   \
90                     ng_l2cap_con_req_cp  param;                                 \
91           } __attribute__ ((packed))    *c = NULL;                              \
92                                                                                           \
93           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
94           if ((_m) == NULL)                                                     \
95                     break;                                                                \
96                                                                                           \
97           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);                        \
98                                                                                           \
99           c = mtod((_m), struct _con_req *);                                    \
100           c->hdr.code = NG_L2CAP_CON_REQ;                                                 \
101           c->hdr.ident = (_ident);                                              \
102           c->hdr.length = htole16(sizeof(c->param));                            \
103                                                                                           \
104           c->param.psm = htole16((_psm));                                                 \
105           c->param.scid = htole16((_scid));                                     \
106 } while (0)
107 
108 /* L2CAP_ConnectRsp */
109 #define _ng_l2cap_con_rsp(_m, _ident, _dcid, _scid, _result, _status) \
110 do {                                                                                      \
111           struct _con_rsp {                                                     \
112                     ng_l2cap_cmd_hdr_t   hdr;                                   \
113                     ng_l2cap_con_rsp_cp  param;                                 \
114           } __attribute__ ((packed))    *c = NULL;                              \
115                                                                                           \
116           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
117           if ((_m) == NULL)                                                     \
118                     break;                                                                \
119                                                                                           \
120           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);                        \
121                                                                                           \
122           c = mtod((_m), struct _con_rsp *);                                    \
123           c->hdr.code = NG_L2CAP_CON_RSP;                                                 \
124           c->hdr.ident = (_ident);                                              \
125           c->hdr.length = htole16(sizeof(c->param));                            \
126                                                                                           \
127           c->param.dcid = htole16((_dcid));                                     \
128           c->param.scid = htole16((_scid));                                     \
129           c->param.result = htole16((_result));                                 \
130           c->param.status = htole16((_status));                                 \
131 } while (0)
132 
133 /* L2CAP_ConfigReq */
134 #define   _ng_l2cap_cfg_req(_m, _ident, _dcid, _flags, _data)                   \
135 do {                                                                                      \
136           struct _cfg_req {                                                     \
137                     ng_l2cap_cmd_hdr_t   hdr;                                   \
138                     ng_l2cap_cfg_req_cp  param;                                 \
139           } __attribute__ ((packed))    *c = NULL;                              \
140                                                                                           \
141           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
142           if ((_m) == NULL) {                                                             \
143                     NG_FREE_M((_data));                                         \
144                     break;                                                                \
145           }                                                                               \
146                                                                                           \
147           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);                        \
148                                                                                           \
149           c = mtod((_m), struct _cfg_req *);                                    \
150           c->hdr.code = NG_L2CAP_CFG_REQ;                                                 \
151           c->hdr.ident = (_ident);                                              \
152           c->hdr.length = sizeof(c->param);                                     \
153                                                                                           \
154           c->param.dcid = htole16((_dcid));                                     \
155           c->param.flags = htole16((_flags));                                   \
156           if ((_data) != NULL) {                                                          \
157                     int       l = (_data)->m_pkthdr.len;                        \
158                                                                                           \
159                     m_cat((_m), (_data));                                                 \
160                     c->hdr.length += l;                                         \
161                     (_m)->m_pkthdr.len += l;                                    \
162           }                                                                               \
163                                                                                           \
164           c->hdr.length = htole16(c->hdr.length);                               \
165 } while (0)
166 
167 /* L2CAP_ConfigRsp */
168 #define _ng_l2cap_cfg_rsp(_m, _ident, _scid, _flags, _result, _data)  \
169 do {                                                                                      \
170           struct _cfg_rsp {                                                     \
171                     ng_l2cap_cmd_hdr_t   hdr;                                   \
172                     ng_l2cap_cfg_rsp_cp  param;                                 \
173           } __attribute__ ((packed))    *c = NULL;                              \
174                                                                                           \
175           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
176           if ((_m) == NULL) {                                                             \
177                     NG_FREE_M((_data));                                         \
178                     break;                                                                \
179           }                                                                               \
180                                                                                           \
181           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);                        \
182                                                                                           \
183           c = mtod((_m), struct _cfg_rsp *);                                    \
184           c->hdr.code = NG_L2CAP_CFG_RSP;                                                 \
185           c->hdr.ident = (_ident);                                              \
186           c->hdr.length = sizeof(c->param);                                     \
187                                                                                           \
188           c->param.scid = htole16((_scid));                                     \
189           c->param.flags = htole16((_flags));                                   \
190           c->param.result = htole16((_result));                                 \
191           if ((_data) != NULL) {                                                          \
192                     int       l = (_data)->m_pkthdr.len;                        \
193                                                                                           \
194                     m_cat((_m), (_data));                                                 \
195                     c->hdr.length += l;                                         \
196                     (_m)->m_pkthdr.len += l;                                    \
197           }                                                                               \
198                                                                                           \
199           c->hdr.length = htole16(c->hdr.length);                               \
200 } while (0)
201 
202 /* Build configuration options */
203 #define _ng_l2cap_build_cfg_options(_m, _mtu, _flush_timo, _flow)     \
204 do {                                                                                      \
205           u_int8_t  *p = NULL;                                                  \
206                                                                                           \
207           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
208           if ((_m) == NULL)                                                     \
209                     break;                                                                \
210                                                                                           \
211           (_m)->m_pkthdr.len = (_m)->m_len = 0;                                 \
212           p = mtod((_m), u_int8_t *);                                           \
213                                                                                           \
214           if ((_mtu) != NULL) {                                                           \
215                     struct _cfg_opt_mtu {                                                 \
216                               ng_l2cap_cfg_opt_t   hdr;                         \
217                               u_int16_t            val;                         \
218                     } __attribute__ ((packed))    *o = NULL;                    \
219                                                                                           \
220                     o = (struct _cfg_opt_mtu *) p;                                        \
221                     o->hdr.type = NG_L2CAP_OPT_MTU;                                       \
222                     o->hdr.length = sizeof(o->val);                                       \
223                     o->val = htole16(*(u_int16_t *)(_mtu));                     \
224                                                                                           \
225                     (_m)->m_pkthdr.len += sizeof(*o);                           \
226                     p += sizeof(*o);                                            \
227           }                                                                               \
228                                                                                           \
229           if ((_flush_timo) != NULL) {                                          \
230                     struct _cfg_opt_flush {                                               \
231                               ng_l2cap_cfg_opt_t   hdr;                         \
232                               u_int16_t            val;                         \
233                     } __attribute__ ((packed))    *o = NULL;                    \
234                                                                                           \
235                     o = (struct _cfg_opt_flush *) p;                            \
236                     o->hdr.type = NG_L2CAP_OPT_FLUSH_TIMO;                      \
237                     o->hdr.length = sizeof(o->val);                                       \
238                     o->val = htole16(*(u_int16_t *)(_flush_timo));              \
239                                                                                           \
240                     (_m)->m_pkthdr.len += sizeof(*o);                           \
241                     p += sizeof(*o);                                            \
242           }                                                                               \
243                                                                                           \
244           if ((_flow) != NULL) {                                                          \
245                     struct _cfg_opt_flow {                                                \
246                               ng_l2cap_cfg_opt_t   hdr;                         \
247                               ng_l2cap_flow_t                val;                         \
248                     } __attribute__ ((packed))    *o = NULL;                    \
249                                                                                           \
250                     o = (struct _cfg_opt_flow *) p;                                       \
251                     o->hdr.type = NG_L2CAP_OPT_QOS;                                       \
252                     o->hdr.length = sizeof(o->val);                                       \
253                     o->val.flags = ((ng_l2cap_flow_p)(_flow))->flags; \
254                     o->val.service_type = ((ng_l2cap_flow_p)                    \
255                                         (_flow))->service_type;                           \
256                     o->val.token_rate =                                         \
257                               htole32(((ng_l2cap_flow_p)(_flow))->token_rate);\
258                     o->val.token_bucket_size =                                  \
259                               htole32(((ng_l2cap_flow_p)                        \
260                                         (_flow))->token_bucket_size);           \
261                     o->val.peak_bandwidth =                                     \
262                               htole32(((ng_l2cap_flow_p)                        \
263                                         (_flow))->peak_bandwidth);              \
264                     o->val.latency = htole32(((ng_l2cap_flow_p)                 \
265                                         (_flow))->latency);                     \
266                     o->val.delay_variation =                                    \
267                               htole32(((ng_l2cap_flow_p)                        \
268                                         (_flow))->delay_variation);             \
269                                                                                           \
270                     (_m)->m_pkthdr.len += sizeof(*o);                           \
271           }                                                                               \
272                                                                                           \
273           (_m)->m_len = (_m)->m_pkthdr.len;                                     \
274 } while (0)
275 
276 /* L2CAP_DisconnectReq */
277 #define   _ng_l2cap_discon_req(_m, _ident, _dcid, _scid)                        \
278 do {                                                                                      \
279           struct _discon_req {                                                            \
280                     ng_l2cap_cmd_hdr_t   hdr;                                   \
281                     ng_l2cap_discon_req_cp         param;                                 \
282           } __attribute__ ((packed))    *c = NULL;                              \
283                                                                                           \
284           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
285           if ((_m) == NULL)                                                     \
286                     break;                                                                \
287                                                                                           \
288           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);                        \
289                                                                                           \
290           c = mtod((_m), struct _discon_req *);                                 \
291           c->hdr.code = NG_L2CAP_DISCON_REQ;                                    \
292           c->hdr.ident = (_ident);                                              \
293           c->hdr.length = htole16(sizeof(c->param));                            \
294                                                                                           \
295           c->param.dcid = htole16((_dcid));                                     \
296           c->param.scid = htole16((_scid));                                     \
297 } while (0)
298 
299 /* L2CA_DisconnectRsp */
300 #define   _ng_l2cap_discon_rsp(_m, _ident, _dcid, _scid)                        \
301 do {                                                                                      \
302           struct _discon_rsp {                                                            \
303                     ng_l2cap_cmd_hdr_t   hdr;                                   \
304                     ng_l2cap_discon_rsp_cp         param;                                 \
305           } __attribute__ ((packed))    *c = NULL;                              \
306                                                                                           \
307           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
308           if ((_m) == NULL)                                                     \
309                     break;                                                                \
310                                                                                           \
311           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);                        \
312                                                                                           \
313           c = mtod((_m), struct _discon_rsp *);                                 \
314           c->hdr.code = NG_L2CAP_DISCON_RSP;                                    \
315           c->hdr.ident = (_ident);                                              \
316           c->hdr.length = htole16(sizeof(c->param));                            \
317                                                                                           \
318           c->param.dcid = htole16((_dcid));                                     \
319           c->param.scid = htole16((_scid));                                     \
320 } while (0)
321 
322 /* L2CAP_EchoReq */
323 #define   _ng_l2cap_echo_req(_m, _ident, _data, _size)                          \
324 do {                                                                                      \
325           ng_l2cap_cmd_hdr_t  *c = NULL;                                        \
326                                                                                           \
327           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
328           if ((_m) == NULL)                                                     \
329                     break;                                                                \
330                                                                                           \
331           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);                        \
332                                                                                           \
333           c = mtod((_m), ng_l2cap_cmd_hdr_t *);                                 \
334           c->code = NG_L2CAP_ECHO_REQ;                                          \
335           c->ident = (_ident);                                                            \
336           c->length = 0;                                                                  \
337                                                                                           \
338           if ((_data) != NULL) {                                                          \
339                     m_copyback((_m), sizeof(*c), (_size), (_data));             \
340                     c->length += (_size);                                                 \
341           }                                                                               \
342                                                                                           \
343           c->length = htole16(c->length);                                                 \
344 } while (0)
345 
346 /* L2CAP_InfoReq */
347 #define   _ng_l2cap_info_req(_m, _ident, _type)                                 \
348 do {                                                                                      \
349           struct _info_req {                                                    \
350                     ng_l2cap_cmd_hdr_t   hdr;                                   \
351                     ng_l2cap_info_req_cp           param;                                 \
352           } __attribute__ ((packed))    *c = NULL;                              \
353                                                                                           \
354           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
355           if ((_m) == NULL)                                                     \
356                     break;                                                                \
357                                                                                           \
358           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(*c);                        \
359                                                                                           \
360           c = mtod((_m), struct _info_req *);                                   \
361           c->hdr.code = NG_L2CAP_INFO_REQ;                                      \
362           c->hdr.ident = (_ident);                                              \
363           c->hdr.length = htole16(sizeof(c->param));                            \
364                                                                                           \
365           c->param.type = htole16((_type));                                     \
366 } while (0)
367 
368 /* L2CAP_InfoRsp */
369 #define   _ng_l2cap_info_rsp(_m, _ident, _type, _result, _mtu)                  \
370 do {                                                                                      \
371           struct _info_rsp {                                                    \
372                     ng_l2cap_cmd_hdr_t   hdr;                                   \
373                     ng_l2cap_info_rsp_cp           param;                                 \
374                     ng_l2cap_info_rsp_data_t data;                                        \
375           } __attribute__ ((packed))    *c = NULL;                              \
376                                                                                           \
377           MGETHDR((_m), M_NOWAIT, MT_DATA);                                     \
378           if ((_m) == NULL)                                                     \
379                     break;                                                                \
380                                                                                           \
381           c = mtod((_m), struct _info_rsp *);                                   \
382           c->hdr.code = NG_L2CAP_INFO_REQ;                                      \
383           c->hdr.ident = (_ident);                                              \
384           c->hdr.length = sizeof(c->param);                                     \
385                                                                                           \
386           c->param.type = htole16((_type));                                     \
387           c->param.result = htole16((_result));                                 \
388                                                                                           \
389           if ((_result) == NG_L2CAP_SUCCESS) {                                  \
390                     switch ((_type)) {                                          \
391                     case NG_L2CAP_CONNLESS_MTU:                                 \
392                               c->data.mtu.mtu = htole16((_mtu));                \
393                               c->hdr.length += sizeof((c->data.mtu.mtu));       \
394                               break;                                                      \
395                     }                                                                     \
396           }                                                                               \
397                                                                                           \
398           (_m)->m_pkthdr.len = (_m)->m_len = sizeof(c->hdr) +                   \
399                                                   c->hdr.length;                          \
400                                                                                           \
401           c->hdr.length = htole16(c->hdr.length);                               \
402 } while (0)
403 
404 void ng_l2cap_con_wakeup              (ng_l2cap_con_p);
405 void ng_l2cap_con_fail                (ng_l2cap_con_p, u_int16_t);
406 void ng_l2cap_process_command_timeout (node_p, hook_p, void *, int);
407 
408 #endif /* ndef _NETGRAPH_L2CAP_CMDS_H_ */
409 
410