aboutsummaryrefslogtreecommitdiffstats
path: root/src/tetra_mac_pdu.h
blob: 74608a6168aec73c37376e6238dc0e2590b638f6 (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
#ifndef TETRA_MAC_PDU
#define TETRA_MAC_PDU

enum tetra_mac_pdu_types {
	TETRA_PDU_T_MAC_RESOURCE = 0,
	TETRA_PDU_T_MAC_FRAG_END = 1,
	TETRA_PDU_T_BROADCAST = 2,
	TETRA_PDU_T_MAC_SUPPL = 3,
};

enum tetra_mac_frage_pdu_types {
	TETRA_MAC_FRAGE_FRAG = 0,
	TETRA_MAC_FRAGE_END = 1,
};

enum tetra_mac_bcast_pdu_types {
	TETRA_MAC_BC_SYSINFO = 0,
	TETRA_MAC_BC_ACCESS_DEFINE = 1,
};

enum tetra_mac_supp_pdu_types {
	TETRA_MAC_SUPP_D_BLCK = 0,
};

enum tetra_bs_serv_details {
	BS_SERVDET_REG_RQD	= (1 << 11),
	BS_SERVDET_DEREG_RQD	= (1 << 10),
	BS_SERVDET_PRIO_CELL	= (1 << 9),
	BS_SERVDET_MIN_MODE	= (1 << 8),
	BS_SERVDET_MIGRATION	= (1 << 7),
	BS_SERVDET_SYS_W_SERV	= (1 << 6),
	BS_SERVDET_VOICE_SERV	= (1 << 5),
	BS_SERVDET_CSD_SERV	= (1 << 4),
	BS_SERVDET_SNDCP_SERV	= (1 << 2),
	BS_SERVDET_AIR_ENCR	= (1 << 1),
	BS_SERVDET_ADV_LINK	= (1 << 0),
};

const char *tetra_get_bs_serv_det_name(uint32_t pdu_type);

struct tetra_mle_si_decoded {
	uint16_t la;
	uint16_t subscr_class;
	uint16_t bs_service_details;
};

struct tetra_si_decoded {
	uint16_t main_carrier;
	uint8_t freq_band;
	uint8_t freq_offset;
	uint8_t duplex_spacing;
	uint8_t reverse_operation;
	uint8_t num_of_csch;
	uint8_t ms_txpwr_max_cell;
	uint8_t rxlev_access_min;
	uint8_t access_parameter;
	uint8_t radio_dl_timeout;
	int cck_valid_no_hf;
	union {
		uint16_t cck_id;
		uint16_t hyperframe_number;
	};
	struct tetra_mle_si_decoded mle_si;
};

const char *tetra_get_macpdu_name(uint8_t pdu_type);

void macpdu_decode_sysinfo(struct tetra_si_decoded *sid, const uint8_t *si_bits);


/* Section 21.4.7.2 ACCESS-ASSIGN PDU */
enum tetra_acc_ass_hdr {
	TETRA_ACC_ASS_DLCC_ULCO,
	TETRA_ACC_ASS_DLF1_ULCA,
	TETRA_ACC_ASS_DLF1_ULAO,
	TETRA_ACC_ASS_DLF1_ULF1,
};

enum tetra_acc_ass_hdr_f18 {
	TETRA_ACC_ASS_ULCO,
	TETRA_ACC_ASS_ULCA,
	TETRA_ACC_ASS_ULAO,
	TETRA_ACC_ASS_ULCA2,
};

enum tetra_dl_usage {
	TETRA_DL_US_UNALLOC	= 0,
	TETRA_DL_US_ASS_CTRL	= 1,
	TETRA_DL_US_COM_CTRL	= 2,
	TETRA_DL_US_RESERVED	= 3,
	TETRA_DL_US_TRAFFIC,
};

enum tetra_ul_usage {
	TETRA_UL_US_UNALLOC	= 0,
	TETRA_UL_US_TRAFFIC,
};

/* Section 21.5.1 */
enum tetra_access_field_bf_len {
	TETRA_ACC_BFL_RES_SUBS	= 0,
	TETRA_ACC_BFL_CLCH_SUBS	= 1,
	TETRA_ACC_BFL_ONGOING	= 2,
	TETRA_ACC_BFL_1		= 3,
	TETRA_ACC_BFL_2		= 4,
	TETRA_ACC_BFL_3		= 5,
	TETRA_ACC_BFL_4		= 7,
	TETRA_ACC_BFL_5		= 6,
	TETRA_ACC_BFL_6		= 8,
	TETRA_ACC_BFL_8		= 9,
	TETRA_ACC_BFL_10	= 0xa,
	TETRA_ACC_BFL_12	= 0xb,
	TETRA_ACC_BFL_16	= 0xc,
	TETRA_ACC_BFL_20	= 0xd,
	TETRA_ACC_BFL_24	= 0xe,
	TETRA_ACC_BFL_32	= 0xf,
};

struct tetra_access_field {
	uint8_t access_code;
	enum tetra_access_field_bf_len base_frame_len;
};

enum tetra_acc_ass_pres {
	TETRA_ACC_ASS_PRES_ACCESS1	= (1 << 0),
	TETRA_ACC_ASS_PRES_ACCESS2	= (1 << 1),
	TETRA_ACC_ASS_PRES_DL_USAGE	= (1 << 2),
	TETRA_ACC_ASS_PRES_UL_USAGE	= (1 << 3),
};

struct tetra_acc_ass_decoded {
	uint8_t hdr;
	uint32_t pres;	/* which of the fields below are present */

	enum tetra_ul_usage ul_usage;
	enum tetra_dl_usage dl_usage;
	struct tetra_access_field access[2];
};

void macpdu_decode_access_assign(struct tetra_acc_ass_decoded *aad, const uint8_t *bits, int f18);
const char *tetra_get_dl_usage_name(uint8_t num);
const char *tetra_get_ul_usage_name(uint8_t num);

enum tetra_mac_res_addr_type {
	ADDR_TYPE_NULL	= 0,
	ADDR_TYPE_SSI	= 1,
	ADDR_TYPE_EVENT_LABEL 	= 2,
	ADDR_TYPE_USSI		= 3,
	ADDR_TYPE_SMI		= 4,
	ADDR_TYPE_SSI_EVENT	= 5,
	ADDR_TYPE_SSI_USAGE	= 6,
	ADDR_TYPE_SMI_EVENT	= 7,
};
const char *tetra_get_addr_t_name(uint8_t addrt);

enum tetra_mac_alloc_type {
	TMAC_ALLOC_T_REPLACE	= 0,
	TMAC_ALLOC_T_ADDITIONAL	= 1,
	TMAC_ALLOC_T_QUIT_GO	= 2,
	TMAC_ALLOC_T_REPL_SLOT1	= 3,
};
const char *tetra_get_alloc_t_name(uint8_t alloct);

struct tetra_chan_alloc_decoded {
	uint8_t type;
	uint8_t timeslot;
	uint8_t ul_dl;
	uint8_t clch_perm;
	uint8_t cell_chg_f;
	uint16_t carrier_nr;
	uint8_t ext_carr_pres;
	struct {
		uint8_t freq_band;
		uint8_t freq_offset;
		uint8_t duplex_spc;
		uint8_t reverse_oper;
	} ext_carr;
	uint8_t monit_pattern;
	uint8_t monit_patt_f18;
	struct {
		uint8_t ul_dl_ass;
		uint8_t bandwidth;
		uint8_t modulation;
		uint8_t max_ul_qam;
		uint8_t conf_chan_stat;
		uint8_t bs_imbalance;
		uint8_t bs_tx_rel;
		uint8_t napping_sts;
	} aug;
};

struct tetra_addr {
	uint8_t type;
	uint16_t mcc;
	uint16_t mnc;
	uint32_t ssi;

	uint16_t event_label;
	uint8_t usage_marker;
};

struct tetra_resrc_decoded {
	uint8_t encryption_mode;
	uint8_t rand_acc_flag;
	int macpdu_length;
	struct tetra_addr addr;

	uint8_t power_control_pres;

	struct {
		uint8_t nr_slots;
		uint8_t delay;
		uint8_t pres;
	} slot_granting;

	uint8_t chan_alloc_pres;
	struct tetra_chan_alloc_decoded cad;
};
int macpdu_decode_resource(struct tetra_resrc_decoded *rsd, const uint8_t *bits);

const char *tetra_addr_dump(const struct tetra_addr *addr);

const char *tetra_get_ul_dl_name(uint8_t ul_dl);

#endif