aboutsummaryrefslogtreecommitdiffstats
path: root/src/tetra_llc_pdu.h
blob: e2ce6fd7c4ec8e271cf4ecfb1736ace815c95e4e (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
#ifndef TETRA_LLC_PDU_H
#define TETRA_LLC_PDU_H

#include <osmocom/core/linuxlist.h>

/* Table 21.1 */
enum tetra_llc_pdu_t {
	TLLC_PDUT_BL_ADATA		= 0,
	TLLC_PDUT_BL_DATA		= 1,
	TLLC_PDUT_BL_UDATA		= 2,
	TLLC_PDUT_BL_ACK		= 3,
	TLLC_PDUT_BL_ADATA_FCS		= 4,
	TLLC_PDUT_BL_DATA_FCS		= 5,
	TLLC_PDUT_BL_UDATA_FCS		= 6,
	TLLC_PDUT_BL_ACK_FCS		= 7,
	TLLC_PDUT_AL_SETUP		= 8,
	TLLC_PDUT_AL_DATA_FINAL		= 9,
	TLLC_PDUT_AL_UDATA_UFINAL	= 10,
	TLLC_PDUT_AL_ACK_RNR		= 11,
	TLLC_PDUT_AL_RECONNECT		= 12,
	TLLC_PDUT_SUPPL			= 13,
	TLLC_PDUT_L2SIG			= 14,
	TLLD_PDUT_AL_DISC		= 15
};
const char *tetra_get_llc_pdut_name(uint8_t pdut);

/* Table 21.2 */
enum tetra_llc_l2sig_pdu_t {
	TLLC_PDUT_L2_DATA_PRIO		= 0,
	TLLC_PDUT_L2_SCHEDULE_SYNC	= 1,
	TLLC_PDUT_L2_LINK_FB_CTRL	= 2,
	TLLC_PDUT_L2_LINK_FB_INFO	= 3,
	TLLC_PDUT_L2_LINK_FB_INFO_RD_PRIO = 4
};

/* Table 21.3 */
enum tetra_llc_suppl_pdu_t {
	TLLC_PDUT_SUPPL_ALX_DATA_FINAL	= 0,
	TLLC_PDUT_SUPPL_ALX_UDATA_UFINAL = 1,
	TLLC_PDUT_SUPPL_ALX_ACK_RNR	= 2
};

/* Decoded */

enum tllc_pdut_dec {
	TLLC_PDUT_DEC_UNKNOWN,
	TLLC_PDUT_DEC_BL_ADATA,
	TLLC_PDUT_DEC_BL_DATA,
	TLLC_PDUT_DEC_BL_UDATA,
	TLLC_PDUT_DEC_BL_ACK,
	TLLC_PDUT_DEC_AL_SETUP,
	TLLC_PDUT_DEC_AL_DATA,
	TLLC_PDUT_DEC_AL_FINAL,
	TLLC_PDUT_DEC_AL_UDATA,
	TLLC_PDUT_DEC_AL_UFINAL,
	TLLC_PDUT_DEC_AL_ACK,
	TLLC_PDUT_DEC_AL_RNR,
	TLLC_PDUT_DEC_AL_RECONNECT,
	TLLC_PDUT_DEC_AL_DISC,
	TLLC_PDUT_DEC_ALX_DATA,
	TLLC_PDUT_DEC_ALX_FINAL,
	TLLC_PDUT_DEC_ALX_UDATA,
	TLLC_PDUT_DEC_ALX_UFINAL,
	TLLC_PDUT_DEC_ALX_ACK,
	TLLC_PDUT_DEC_ALX_RNR,
};
const char *tetra_get_llc_pdut_dec_name(enum tllc_pdut_dec pdut);

/* decoded/parsed PDU with easier encoding */
struct tetra_llc_pdu {
	enum tllc_pdut_dec pdu_type;
	uint8_t nr;		/* N(R) PDU number (receive) */
	uint8_t ns;		/* N(S) PDU number (sent) */
	uint8_t ss;		/* S(S) Segment (sent) */
	uint32_t _fcs;
	uint32_t *fcs;
	uint8_t *tl_sdu;	/* pointer to bitbuf */
	uint8_t tl_sdu_len;	/* in bits */
};

/* parse a received LLC PDU and parse it into 'lpp' */
int tetra_llc_pdu_parse(struct tetra_llc_pdu *lpp, uint8_t *buf, int len);

/* TETRA LLC state */
struct tllc_state {
	struct llist_head list;

	struct {
		struct llist_head defrag_list;
	} rx;
};

/* entry in the defragmentation queue */
struct tllc_defrag_q_e {
	struct llist_head list;
	unsigned int ns;	/* current de-fragmenting */
	unsigned int last_ss;	/* last received S(S) */

	struct msgb *tl_sdu;
};
#endif /* TETRA_LLC_PDU_H */