1/*
2 * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3 * All rights reserved. Distributed under the terms of the MIT License.
4 *
5 */
6
7/*-
8 * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19*/
20
21
22/**************************************************************************
23 **************************************************************************
24 **                   Common defines and types (L2CAP)
25 **************************************************************************
26 **************************************************************************/
27
28#ifndef _L2CAP_
29#define _L2CAP_
30
31#include <bluetooth/bluetooth.h>
32
33// TODO: from BSD compatibility layer
34#define htole16(x) (x)
35#define le16toh(x) (x)
36#define le32toh(x) (x)
37#define htole32(x) (x)
38
39#define HZ	1000000 // us per second TODO: move somewhere more generic
40#define bluetooth_l2cap_ertx_timeout (60 * HZ)
41#define bluetooth_l2cap_rtx_timeout  (300 * HZ)
42
43/*
44 * Channel IDs are assigned relative to the instance of L2CAP node, i.e.
45 * relative to the unit. So the total number of channels that unit can have
46 * open at the same time is 0xffff - 0x0040 = 0xffbf (65471). This number
47 * does not depend on number of connections.
48 */
49#define L2CAP_NULL_CID		0x0000	/* DO NOT USE THIS CID */
50#define L2CAP_SIGNAL_CID	0x0001	/* signaling channel ID */
51#define L2CAP_CLT_CID		0x0002	/* connectionless channel ID */
52/* 0x0003 - 0x003f Reserved */
53#define L2CAP_FIRST_CID		0x0040	/* dynamically alloc. (start) */
54#define L2CAP_LAST_CID		0xffff	/* dynamically alloc. (end) */
55
56
57/*
58 * L2CAP signaling command ident's are assigned relative to the connection,
59 * because there is only one signaling channel (cid == 0x01) for every
60 * connection. So up to 254 (0xff - 0x01) L2CAP commands can be pending at the
61 * same time for the same connection.
62 */
63#define L2CAP_NULL_IDENT		0x00	/* DO NOT USE THIS IDENT */
64#define L2CAP_FIRST_IDENT		0x01	/* dynamically alloc. (start) */
65#define L2CAP_LAST_IDENT		0xff	/* dynamically alloc. (end) */
66
67
68/* L2CAP MTU */
69#define L2CAP_MTU_MINIMUM		48
70#define L2CAP_MTU_DEFAULT		672
71#define L2CAP_MTU_MAXIMUM		0xffff
72
73/* L2CAP flush and link timeouts */
74#define L2CAP_FLUSH_TIMO_DEFAULT	0xffff /* always retransmit */
75#define L2CAP_LINK_TIMO_DEFAULT		0xffff
76
77/* L2CAP Command Reject reasons */
78#define L2CAP_REJ_NOT_UNDERSTOOD	0x0000
79#define L2CAP_REJ_MTU_EXCEEDED		0x0001
80#define L2CAP_REJ_INVALID_CID		0x0002
81/* 0x0003 - 0xffff - reserved for future use */
82
83/* Protocol/Service Multioplexor (PSM) values */
84#define L2CAP_PSM_ANY		0x0000	/* Any/Invalid PSM */
85#define L2CAP_PSM_SDP		0x0001	/* Service Discovery Protocol */
86#define L2CAP_PSM_RFCOMM	0x0003	/* RFCOMM protocol */
87#define L2CAP_PSM_TCP		0x0005	/* Telephony Control Protocol */
88#define L2CAP_PSM_TCS		0x0007	/* TCS cordless */
89#define L2CAP_PSM_BNEP		0x000F	/* BNEP */
90#define L2CAP_PSM_HID_CTRL	0x0011	/* HID Control */
91#define L2CAP_PSM_HID_INT	0x0013	/* HID Interrupt */
92#define L2CAP_PSM_UPnP		0x0015	/* UPnP (ESDP) */
93#define L2CAP_PSM_AVCTP		0x0017	/* AVCTP */
94#define L2CAP_PSM_AVDTP		0x0019	/* AVDTP */
95/*  < 0x1000 - reserved for future use */
96/*  0x1001 < x < 0xFFFF dinamically assigned */
97
98/* L2CAP Connection response command result codes */
99#define L2CAP_SUCCESS		0x0000
100#define L2CAP_PENDING		0x0001
101#define L2CAP_PSM_NOT_SUPPORTED	0x0002
102#define L2CAP_SEQUIRY_BLOCK	0x0003
103#define L2CAP_NO_RESOURCES	0x0004
104#define L2CAP_TIMEOUT		0xeeee
105#define L2CAP_UNKNOWN		0xffff
106/* 0x0005 - 0xffff - reserved for future use */
107
108/* L2CAP Connection response status codes */
109#define L2CAP_NO_INFO		0x0000
110#define L2CAP_AUTH_PENDING		0x0001
111#define L2CAP_AUTZ_PENDING		0x0002
112/* 0x0003 - 0xffff - reserved for future use */
113
114/* L2CAP Configuration response result codes */
115#define L2CAP_UNACCEPTABLE_PARAMS	0x0001
116#define L2CAP_REJECT			0x0002
117#define L2CAP_UNKNOWN_OPTION		0x0003
118/* 0x0003 - 0xffff - reserved for future use */
119
120/* L2CAP Configuration options */
121#define L2CAP_OPT_CFLAG_BIT		0x0001
122#define L2CAP_OPT_CFLAG(flags)		((flags) & L2CAP_OPT_CFLAG_BIT)
123#define L2CAP_OPT_HINT_BIT		0x80
124#define L2CAP_OPT_HINT(type)		((type) & L2CAP_OPT_HINT_BIT)
125#define L2CAP_OPT_HINT_MASK		0x7f
126#define L2CAP_OPT_MTU			0x01
127#define L2CAP_OPT_MTU_SIZE		sizeof(uint16)
128#define L2CAP_OPT_FLUSH_TIMO		0x02
129#define L2CAP_OPT_FLUSH_TIMO_SIZE	sizeof(uint16)
130#define L2CAP_OPT_QOS			0x03
131#define L2CAP_OPT_QOS_SIZE		sizeof(l2cap_flow_t)
132/* 0x4 - 0xff - reserved for future use */
133
134#define	L2CAP_CFG_IN	(1 << 0)	/* incoming path done */
135#define	L2CAP_CFG_OUT	(1 << 1)	/* outgoing path done */
136#define	L2CAP_CFG_BOTH  (L2CAP_CFG_IN | L2CAP_CFG_OUT)
137#define	L2CAP_CFG_IN_SENT	(1 << 2)	/* L2CAP ConfigReq sent */
138#define	L2CAP_CFG_OUT_SENT	(1 << 3)	/* ---/--- */
139
140/* L2CAP Information request type codes */
141#define L2CAP_CONNLESS_MTU		0x0001
142#define L2CAP_EXTENDED_MASK	0x0002
143/* 0x0003 - 0xffff - reserved for future use */
144
145/* L2CAP Information response codes */
146#define L2CAP_NOT_SUPPORTED		0x0001
147/* 0x0002 - 0xffff - reserved for future use */
148
149/* L2CAP flow (QoS) */
150typedef struct {
151	uint8	flags;             /* reserved for future use */
152	uint8	service_type;      /* service type */
153	uint32	token_rate;        /* bytes per second */
154	uint32	token_bucket_size; /* bytes */
155	uint32	peak_bandwidth;    /* bytes per second */
156	uint32	latency;           /* microseconds */
157	uint32	delay_variation;   /* microseconds */
158} __attribute__ ((packed)) l2cap_flow_t;
159
160
161/**************************************************************************
162 **************************************************************************
163 **                 Link level defines, headers and types
164 **************************************************************************
165 **************************************************************************/
166
167/* L2CAP header */
168typedef struct {
169	uint16	length;	/* payload size */
170	uint16	dcid;	/* destination channel ID */
171} __attribute__ ((packed)) l2cap_hdr_t;
172
173
174/* L2CAP ConnectionLess Traffic (CLT) (if destination cid == 0x2) */
175typedef struct {
176	uint16	psm; /* Protocol/Service Multiplexor */
177} __attribute__ ((packed)) l2cap_clt_hdr_t;
178
179#define L2CAP_CLT_MTU_MAXIMUM (L2CAP_MTU_MAXIMUM - sizeof(l2cap_clt_hdr_t))
180
181/* L2CAP command header */
182typedef struct {
183	uint8	code;   /* command OpCode */
184	uint8	ident;  /* identifier to match request and response */
185	uint16	length; /* command parameters length */
186} __attribute__ ((packed)) l2cap_cmd_hdr_t;
187
188
189/* L2CAP Command Reject */
190#define L2CAP_CMD_REJ	0x01
191typedef struct {
192	uint16	reason; /* reason to reject command */
193/*	uint8	data[]; -- optional data (depends on reason) */
194} __attribute__ ((packed)) l2cap_cmd_rej_cp;
195
196/* CommandReject data */
197typedef union {
198 	/* L2CAP_REJ_MTU_EXCEEDED */
199	struct {
200		uint16	mtu; /* actual signaling MTU */
201	} __attribute__ ((packed)) mtu;
202	/* L2CAP_REJ_INVALID_CID */
203	struct {
204		uint16	scid; /* local CID */
205		uint16	dcid; /* remote CID */
206	} __attribute__ ((packed)) cid;
207} l2cap_cmd_rej_data_t;
208typedef l2cap_cmd_rej_data_t * l2cap_cmd_rej_data_p;
209
210/* L2CAP Connection Request */
211#define L2CAP_CON_REQ	0x02
212typedef struct {
213	uint16	psm;  /* Protocol/Service Multiplexor (PSM) */
214	uint16	scid; /* source channel ID */
215} __attribute__ ((packed)) l2cap_con_req_cp;
216
217/* L2CAP Connection Response */
218#define L2CAP_CON_RSP	0x03
219typedef struct {
220	uint16	dcid;   /* destination channel ID */
221	uint16	scid;   /* source channel ID */
222	uint16	result; /* 0x00 - success */
223	uint16	status; /* more info if result != 0x00 */
224} __attribute__ ((packed)) l2cap_con_rsp_cp;
225
226/* L2CAP Configuration Request */
227#define L2CAP_CFG_REQ	0x04
228typedef struct {
229	uint16	dcid;  /* destination channel ID */
230	uint16	flags; /* flags */
231/*	uint8	options[] --  options */
232} __attribute__ ((packed)) l2cap_cfg_req_cp;
233
234/* L2CAP Configuration Response */
235#define L2CAP_CFG_RSP	0x05
236typedef struct {
237	uint16	scid;   /* source channel ID */
238	uint16	flags;  /* flags */
239	uint16	result; /* 0x00 - success */
240/*	uint8	options[] -- options */
241} __attribute__ ((packed)) l2cap_cfg_rsp_cp;
242
243/* L2CAP configuration option */
244typedef struct {
245	uint8	type;
246	uint8	length;
247/*	uint8	value[] -- option value (depends on type) */
248} __attribute__ ((packed)) l2cap_cfg_opt_t;
249typedef l2cap_cfg_opt_t * l2cap_cfg_opt_p;
250
251/* L2CAP configuration option value */
252typedef union {
253	uint16		mtu;		/* L2CAP_OPT_MTU */
254	uint16		flush_timo;	/* L2CAP_OPT_FLUSH_TIMO */
255	l2cap_flow_t	flow;		/* L2CAP_OPT_QOS */
256} l2cap_cfg_opt_val_t;
257typedef l2cap_cfg_opt_val_t * l2cap_cfg_opt_val_p;
258
259/* L2CAP Disconnect Request */
260#define L2CAP_DISCON_REQ	0x06
261typedef struct {
262	uint16	dcid; /* destination channel ID */
263	uint16	scid; /* source channel ID */
264} __attribute__ ((packed)) l2cap_discon_req_cp;
265
266/* L2CAP Disconnect Response */
267#define L2CAP_DISCON_RSP	0x07
268typedef l2cap_discon_req_cp	l2cap_discon_rsp_cp;
269
270/* L2CAP Echo Request */
271#define L2CAP_ECHO_REQ	0x08
272/* No command parameters, only optional data */
273
274/* L2CAP Echo Response */
275#define L2CAP_ECHO_RSP	0x09
276#define L2CAP_MAX_ECHO_SIZE \
277	(L2CAP_MTU_MAXIMUM - sizeof(l2cap_cmd_hdr_t))
278/* No command parameters, only optional data */
279
280/* L2CAP Information Request */
281#define L2CAP_INFO_REQ	0x0a
282typedef struct {
283	uint16	type; /* requested information type */
284} __attribute__ ((packed)) l2cap_info_req_cp;
285
286/* L2CAP Information Response */
287#define L2CAP_INFO_RSP	0x0b
288typedef struct {
289	uint16	type;   /* requested information type */
290	uint16	result; /* 0x00 - success */
291/*	uint8	info[]  -- info data (depends on type)
292 *
293 * L2CAP_CONNLESS_MTU - 2 bytes connectionless MTU
294 */
295} __attribute__ ((packed)) l2cap_info_rsp_cp;
296
297#define IS_SIGNAL_REQ(code) ((code & 1) == 0)
298#define IS_SIGNAL_RSP(code) ((code & 1) == 1)
299
300
301typedef union {
302 	/* L2CAP_CONNLESS_MTU */
303	struct {
304		uint16	mtu;
305	} __attribute__ ((packed)) mtu;
306} l2cap_info_rsp_data_t;
307typedef l2cap_info_rsp_data_t *	l2cap_info_rsp_data_p;
308
309
310#endif
311
312