summaryrefslogtreecommitdiff
path: root/tools/parser/rfcomm.h
blob: c3a1dfb22eea720cfcfabe6bfec262459c8fbe61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2001-2002  Wayne Lee <waynelee@qualcomm.com>
 *  Copyright (C) 2003-2011  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 */

#ifndef __RFCOMM_H
#define __RFCOMM_H

#include <endian.h>

#define RFCOMM_PSM 3

#define TRUE  1
#define FALSE 0

#define RFCOMM_MAX_CONN 10
#define BT_NBR_DATAPORTS RFCOMM_MAX_CONN

#define GET_BIT(pos,bitfield) ((bitfield[(pos)/32]) & (1 << ((pos) % 32)))
#define SET_BIT(pos,bitfield) ((bitfield[(pos)/32]) |= (1 << ((pos) % 32))) 
#define CLR_BIT(pos,bitfield) ((bitfield[(pos)/32]) &= ((1 << ((pos) % 32)) ^ (~0)))

/* Sets the P/F-bit in the control field */
#define SET_PF(ctr) ((ctr) | (1 << 4)) 
/* Clears the P/F-bit in the control field */
#define CLR_PF(ctr) ((ctr) & 0xef)
/* Returns the P/F-bit */
#define GET_PF(ctr) (((ctr) >> 4) & 0x1)

#define MIN(a, b) (((a) < (b)) ? (a) : (b))

/* Endian-swapping macros for structs */
#define swap_long_frame(x) ((x)->h.length.val = le16_to_cpu((x)->h.length.val))
#define swap_mcc_long_frame(x) (swap_long_frame(x))

/* Used for UIH packets */
#define SHORT_CRC_CHECK 2
/* Used for all packet exepts for the UIH packets */
#define LONG_CRC_CHECK 3
/* Short header for short UIH packets */
#define SHORT_HDR 2
/* Long header for long UIH packets */
#define LONG_HDR 3

/* FIXME: Should this one be defined here? */
#define SHORT_PAYLOAD_SIZE 127
/* Used for setting the EA field in different packets, really neccessary? */
#define EA 1
/* Yes the FCS size is only one byte */
#define FCS_SIZE 1

#define RFCOMM_MAX_HDR_SIZE 5

#define MAX_CREDITS   30
#define START_CREDITS 7
#define MIN_CREDITS   6

#define DEF_RFCOMM_MTU 127

/* The values in the control field when sending ordinary rfcomm packets */
#define SABM 0x2f	/* set asynchronous balanced mode */
#define UA   0x63	/* unnumbered acknolodgement */
#define DM   0x0f	/* disconnected mode */
#define DISC 0x43	/* disconnect */
#define UIH  0xef	/* unnumbered information with header check (only) */
#define UI   0x03	/* unnumbered information (with all data check) */

#define SABM_SIZE 4
#define UA_SIZE   4

/* The values in the type field in a multiplexer command packet */
#define PN    (0x80 >> 2)	/* parameter negotiation */
#define PSC   (0x40 >> 2)	/* power saving control */
#define CLD   (0xc0 >> 2)	/* close down */
#define TEST  (0x20 >> 2)	/* test */
#define FCON  (0xa0 >> 2)	/* flow control on */
#define FCOFF (0x60 >> 2)	/* flow control off */
#define MSC   (0xe0 >> 2)	/* modem status command */
#define NSC   (0x10 >> 2)	/* not supported command response */
#define RPN   (0x90 >> 2)	/* remote port negotiation */
#define RLS   (0x50 >> 2)	/* remote line status */
#define SNC   (0xd0 >> 2)	/* service negotiation command */

/* Define of some V.24 signals modem control signals in RFCOMM */
#define DV  0x80	/* data valid */
#define IC  0x40	/* incoming call */
#define RTR 0x08	/* ready to receive */
#define RTC 0x04	/* ready to communicate */
#define FC  0x02	/* flow control (unable to accept frames) */

#define CTRL_CHAN 0	/* The control channel is defined as DLCI 0 in rfcomm */
#define MCC_CMD 1	 /* Multiplexer command */
#define MCC_RSP 0	 /* Multiplexer response */

#if __BYTE_ORDER == __LITTLE_ENDIAN

typedef struct parameter_mask {
	uint8_t bit_rate:1;
	uint8_t data_bits:1;
	uint8_t stop_bit:1;
	uint8_t parity:1;
	uint8_t parity_type:1;
	uint8_t xon:1;
	uint8_t xoff:1;
	uint8_t res1:1;
	uint8_t xon_input:1;
	uint8_t xon_output:1;
	uint8_t rtr_input:1;
	uint8_t rtr_output:1;
	uint8_t rtc_input:1;
	uint8_t rtc_output:1;
	uint8_t res2:2;
} __attribute__ ((packed)) parameter_mask;

typedef struct rpn_values {
	uint8_t bit_rate;
	uint8_t data_bits:2;
	uint8_t stop_bit:1;
	uint8_t parity:1;
	uint8_t parity_type:2;
	uint8_t res1:2;
	uint8_t xon_input:1;
	uint8_t xon_output:1;
	uint8_t rtr_input:1;
	uint8_t rtr_output:1;
	uint8_t rtc_input:1;
	uint8_t rtc_output:1;
	uint8_t res2:2;
	uint8_t xon;
	uint8_t xoff;
	uint16_t pm;
	//parameter_mask pm;
} __attribute__ ((packed)) rpn_values;

#elif __BYTE_ORDER == __BIG_ENDIAN

typedef struct parameter_mask {
	uint8_t res1:1;
	uint8_t xoff:1;
	uint8_t xon:1;
	uint8_t parity_type:1;
	uint8_t parity:1;
	uint8_t stop_bit:1;
	uint8_t data_bits:1;
	uint8_t bit_rate:1;
	uint8_t res2:2;
	uint8_t rtc_output:1;
	uint8_t rtc_input:1;
	uint8_t rtr_output:1;
	uint8_t rtr_input:1;
	uint8_t xon_output:1;
	uint8_t xon_input:1;

} __attribute__ ((packed)) parameter_mask;

typedef struct rpn_values {
	uint8_t bit_rate;
	uint8_t res1:2;
	uint8_t parity_type:2;
	uint8_t parity:1;
	uint8_t stop_bit:1;
	uint8_t data_bits:2;
	uint8_t res2:2;
	uint8_t rtc_output:1;
	uint8_t rtc_input:1;
	uint8_t rtr_output:1;
	uint8_t rtr_input:1;
	uint8_t xon_output:1;
	uint8_t xon_input:1;
	uint8_t xon;
	uint8_t xoff;
	uint16_t pm;
	//parameter_mask pm;
} __attribute__ ((packed)) rpn_values;

#else
#error "Unknown byte order"
#endif

/* Typedefinitions of stuctures used for creating and parsing packets, for a
 * further description of the structures please se the bluetooth core
 * specification part F:1 and the ETSI TS 07.10 specification  */

#if __BYTE_ORDER == __LITTLE_ENDIAN

typedef struct address_field {
	uint8_t ea:1;
	uint8_t cr:1;
	uint8_t d:1;
	uint8_t server_chn:5;
} __attribute__ ((packed)) address_field;

typedef struct short_length {
	uint8_t ea:1;
	uint8_t len:7;
} __attribute__ ((packed)) short_length;

typedef union long_length {
	struct bits {
		uint8_t ea:1;
		unsigned short len:15;
	} __attribute__ ((packed)) bits ;
	uint16_t val ;
} __attribute__ ((packed)) long_length;

typedef struct short_frame_head {
	address_field addr;
	uint8_t control;
	short_length length;
} __attribute__ ((packed)) short_frame_head;

typedef struct short_frame {
	short_frame_head h;
	uint8_t data[0]; 
} __attribute__ ((packed)) short_frame;

typedef struct long_frame_head {
	address_field addr;
	uint8_t control;
	long_length length;
	uint8_t data[0];
} __attribute__ ((packed)) long_frame_head;

typedef struct long_frame {
	long_frame_head h;
	uint8_t data[0];
} __attribute__ ((packed)) long_frame;

/* Typedefinitions for structures used for the multiplexer commands */
typedef struct mcc_type {
	uint8_t ea:1;
	uint8_t cr:1;
	uint8_t type:6;
} __attribute__ ((packed)) mcc_type;

typedef struct mcc_short_frame_head {
	mcc_type type;
	short_length length;
	uint8_t value[0];
} __attribute__ ((packed)) mcc_short_frame_head;

typedef struct mcc_short_frame {
	mcc_short_frame_head h;
	uint8_t value[0];
} __attribute__ ((packed)) mcc_short_frame;

typedef struct mcc_long_frame_head {
	mcc_type type;
	long_length length;
	uint8_t value[0];
} __attribute__ ((packed)) mcc_long_frame_head;

typedef struct mcc_long_frame {
	mcc_long_frame_head h;
	uint8_t value[0];
} __attribute__ ((packed)) mcc_long_frame;

/* MSC-command */
typedef struct v24_signals {
	uint8_t ea:1;
	uint8_t fc:1;
	uint8_t rtc:1;
	uint8_t rtr:1;
	uint8_t reserved:2;
	uint8_t ic:1;
	uint8_t dv:1;
} __attribute__ ((packed)) v24_signals;

typedef struct break_signals {
	uint8_t ea:1;
	uint8_t b1:1;
	uint8_t b2:1;
	uint8_t b3:1;
	uint8_t len:4;
} __attribute__ ((packed)) break_signals;

typedef struct msc_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	address_field dlci;
	v24_signals v24_sigs;
	//break_signals break_sigs;
	uint8_t fcs;
} __attribute__ ((packed)) msc_msg;

typedef struct rpn_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	address_field dlci;
	rpn_values rpn_val;
	uint8_t fcs;
} __attribute__ ((packed)) rpn_msg;

/* RLS-command */  
typedef struct rls_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	address_field dlci;
	uint8_t error:4;
	uint8_t res:4;
	uint8_t fcs;
} __attribute__ ((packed)) rls_msg;

/* PN-command */
typedef struct pn_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
/* The res1, res2 and res3 values have to be set to 0 by the sender */
	uint8_t dlci:6;
	uint8_t res1:2;
	uint8_t frame_type:4;
	uint8_t credit_flow:4;
	uint8_t prior:6;
	uint8_t res2:2;
	uint8_t ack_timer;
	uint16_t frame_size:16;
	uint8_t max_nbrof_retrans;
	uint8_t credits;
	uint8_t fcs;
} __attribute__ ((packed)) pn_msg;

/* NSC-command */
typedef struct nsc_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	mcc_type command_type;
	uint8_t fcs;
} __attribute__ ((packed)) nsc_msg;

#elif __BYTE_ORDER == __BIG_ENDIAN

typedef struct address_field {
	uint8_t server_chn:5;
	uint8_t d:1;
	uint8_t cr:1;
	uint8_t ea:1;
} __attribute__ ((packed)) address_field;

typedef struct short_length {
	uint8_t len:7;
	uint8_t ea:1;
} __attribute__ ((packed)) short_length;

typedef union long_length {
	struct bits {
		unsigned short len:15;
		uint8_t ea:1;
	} __attribute__ ((packed)) bits;
	uint16_t val;
} __attribute__ ((packed)) long_length;

typedef struct short_frame_head {
	address_field addr;
	uint8_t control;
	short_length length;
} __attribute__ ((packed)) short_frame_head;

typedef struct short_frame {
	short_frame_head h;
	uint8_t data[0];
} __attribute__ ((packed)) short_frame;

typedef struct long_frame_head {
	address_field addr;
	uint8_t control;
	long_length length;
	uint8_t data[0];
} __attribute__ ((packed)) long_frame_head;

typedef struct long_frame {
	long_frame_head h;
	uint8_t data[0];
} __attribute__ ((packed)) long_frame;

typedef struct mcc_type {
	uint8_t type:6;
	uint8_t cr:1;
	uint8_t ea:1;
} __attribute__ ((packed)) mcc_type;

typedef struct mcc_short_frame_head {
	mcc_type type;
	short_length length;
	uint8_t value[0];
} __attribute__ ((packed)) mcc_short_frame_head;

typedef struct mcc_short_frame {
	mcc_short_frame_head h;
	uint8_t value[0];
} __attribute__ ((packed)) mcc_short_frame;

typedef struct mcc_long_frame_head {
	mcc_type type;
	long_length length;
	uint8_t value[0];
} __attribute__ ((packed)) mcc_long_frame_head;

typedef struct mcc_long_frame {
	mcc_long_frame_head h;
	uint8_t value[0];
} __attribute__ ((packed)) mcc_long_frame;

typedef struct v24_signals {
	uint8_t dv:1;
	uint8_t ic:1;
	uint8_t reserved:2;
	uint8_t rtr:1;
	uint8_t rtc:1;
	uint8_t fc:1;
	uint8_t ea:1;
} __attribute__ ((packed)) v24_signals;

typedef struct break_signals {
	uint8_t len:4;
	uint8_t b3:1;
	uint8_t b2:1;
	uint8_t b1:1;
	uint8_t ea:1;
} __attribute__ ((packed)) break_signals;

typedef struct msc_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	address_field dlci;
	v24_signals v24_sigs;
	//break_signals break_sigs;
	uint8_t fcs;
} __attribute__ ((packed)) msc_msg;

typedef struct rpn_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	address_field dlci;
	rpn_values rpn_val;
	uint8_t fcs;
} __attribute__ ((packed)) rpn_msg;

typedef struct rls_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	address_field dlci;
	uint8_t res:4;
	uint8_t error:4;
	uint8_t fcs;
} __attribute__ ((packed)) rls_msg;

typedef struct pn_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	uint8_t res1:2;
	uint8_t dlci:6;
	uint8_t credit_flow:4;
	uint8_t frame_type:4;
	uint8_t res2:2;
	uint8_t prior:6;
	uint8_t ack_timer;
	uint16_t frame_size:16;
	uint8_t max_nbrof_retrans;
	uint8_t credits;
	uint8_t fcs;
} __attribute__ ((packed)) pn_msg;

typedef struct nsc_msg {
	short_frame_head s_head;
	mcc_short_frame_head mcc_s_head;
	mcc_type command_type;
	uint8_t fcs;
} __attribute__ ((packed)) nsc_msg;

#else
#error "Unknown byte order"
#error Processor endianness unknown!
#endif

#endif /* __RFCOMM_H */