aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/gprs/rlcmac/rlcmac_prim.h
blob: d6f733eb55394f6fa24b11c3766b9a7c608445f3 (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
#pragma once

/* GPRS Radio Resource SAP as per:
 * 3GPP TS 44.060 4.3
 * 3GPP TS 24.007 9.3
 * 3GPP TS 44.064 7.2.3
 */

#include <osmocom/core/prim.h>
#include <osmocom/core/utils.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gprs/rlcmac/rlcmac.h>

/* TS 24.007 Section 9.3 */
enum osmo_gprs_rlcmac_prim_sap {
	OSMO_GPRS_RLCMAC_SAP_GRR,
	OSMO_GPRS_RLCMAC_SAP_GMMRR,
	OSMO_GPRS_RLCMAC_SAP_L1CTL,
};

extern const struct value_string osmo_gprs_rlcmac_prim_sap_names[];
static inline const char *osmo_gprs_rlcmac_prim_sap_name(enum osmo_gprs_rlcmac_prim_sap val)
{
	return get_value_string(osmo_gprs_rlcmac_prim_sap_names, val);
}

/* TS 24.007 Section 9.3.1 "Service primitives for GRR-SAP (GSM only)"
 * TS 04.64 Section 7.2.3 "LLE - RLC/MAC primitives" (MS side) */
enum osmo_gprs_rlcmac_grr_prim_type {
	OSMO_GPRS_RLCMAC_GRR_DATA,	/* Req/Ind: TLLI, LL-PDU, SAPI, Cause, QoS, Radio Prio */
	OSMO_GPRS_RLCMAC_GRR_UNITDATA,	/* Req/Ind: TLLI, LL-PDU, SAPI, QoS, Radio Prio */
};

extern const struct value_string osmo_gprs_rlcmac_grr_prim_type_names[];
static inline const char *osmo_gprs_rlcmac_grr_prim_type_name(enum osmo_gprs_rlcmac_grr_prim_type val)
{
	return get_value_string(osmo_gprs_rlcmac_grr_prim_type_names, val);
}

/* Parameters for OSMO_GPRS_RLCMAC_GRR_* prims */
struct osmo_gprs_rlcmac_grr_prim {
	/* Common fields */
	uint32_t tlli;
	uint8_t *ll_pdu;
	size_t ll_pdu_len;
	/* Specific fields */
	union {
		/* OSMO_GPRS_RLCMAC_GRR_DATA | Req */
		struct {
			uint8_t sapi;
			uint8_t radio_prio;
			struct {
				uint8_t peak_throughput;
			} qos_params; /* 3GPP TS 44.064 7.2.3.1 */
		} data_req;
		/* OSMO_GPRS_RLCMAC_GRR_UNITDATA | Req */
		struct {
			uint8_t sapi;
			uint8_t radio_prio;
			struct {
				uint8_t peak_throughput;
			} qos_params; /* 3GPP TS 44.064 7.2.3.2 */
			uint8_t cause;
		} unitdata_req;
	};
};

/* TS 24.007 Section 9.3.2 "Service primitives for GMMRR-SAP (GSM only)"
 * OSMO_GPRS_RLCMAC_GMMRR_LLC_TRANSMITTED: addition implementing TS 24.008 4.7.2.1.1
 * Same as enum osmo_gprs_gmm_gmmrr_prim_type.
 */
enum osmo_gprs_rlcmac_gmmrr_prim_type {
	OSMO_GPRS_RLCMAC_GMMRR_ASSIGN,	/* Req: newTLLI  */
	OSMO_GPRS_RLCMAC_GMMRR_PAGE,	/* Ind: TLLI */
	OSMO_GPRS_RLCMAC_GMMRR_LLC_TRANSMITTED, /* Ind: TLLI */
};

extern const struct value_string osmo_gprs_rlcmac_gmmrr_prim_type_names[];
static inline const char *osmo_gprs_rlcmac_gmmrr_prim_type_name(enum osmo_gprs_rlcmac_gmmrr_prim_type val)
{
	return get_value_string(osmo_gprs_rlcmac_gmmrr_prim_type_names, val);
}

/* Parameters for OSMO_GPRS_RLCMAC_GRR_* prims.
 * Same as struct osmo_gprs_gmm_gmmrr_prim.
 */
struct osmo_gprs_rlcmac_gmmrr_prim {
	/* Common fields */
	uint32_t tlli;
	union {
		/* OSMO_GPRS_RLCMAC_GMMRR_ASSIGN | Req */
		struct {
			uint32_t new_tlli;
			uint32_t ptmsi;
			char imsi[OSMO_IMSI_BUF_SIZE];
		} assign_req;
		/* OSMO_GPRS_RLCMAC_GMMRR_PAGE | Ind */
		struct {
		} page_ind;
		/* OSMO_GPRS_RLCMAC_GMMRR_LLC_TRANSMITTED | Ind */
		struct {
		} llc_transmitted_ind;
	};
};

/* From/Towards lower layers */
enum osmo_gprs_rlcmac_l1ctl_prim_type {
	OSMO_GPRS_RLCMAC_L1CTL_RACH,
	OSMO_GPRS_RLCMAC_L1CTL_CCCH_DATA,
	OSMO_GPRS_RLCMAC_L1CTL_PDCH_DATA,
	OSMO_GPRS_RLCMAC_L1CTL_PDCH_RTS,
	OSMO_GPRS_RLCMAC_L1CTL_CFG_UL_TBF,
	OSMO_GPRS_RLCMAC_L1CTL_CFG_DL_TBF,
	OSMO_GPRS_RLCMAC_L1CTL_PDCH_ESTABLISH,
	OSMO_GPRS_RLCMAC_L1CTL_PDCH_RELEASE,
	OSMO_GPRS_RLCMAC_L1CTL_CCCH_READY,
};

extern const struct value_string osmo_gprs_rlcmac_l1ctl_prim_type_names[];
static inline const char *osmo_gprs_rlcmac_l1ctl_prim_type_name(enum osmo_gprs_rlcmac_l1ctl_prim_type val)
{
	return get_value_string(osmo_gprs_rlcmac_l1ctl_prim_type_names, val);
}

/* Parameters for OSMO_GPRS_RLCMAC_L1CTL_* prims */
struct osmo_gprs_rlcmac_l1ctl_prim {
	/* Common fields (none) */
	union {
		/* OSMO_GPRS_RLCMAC_L1CTL_RACH | Req */
		struct {
			bool is_11bit;
			union {
				uint8_t ra;
				struct {
					uint16_t ra11;
					uint8_t synch_seq;
				};
			};
		} rach_req;
		/* OSMO_GPRS_RLCMAC_L1CTL_CCCH_DATA | Ind */
		struct {
			uint32_t fn;
			uint8_t *data; /* data_len = GSM_MACBLOCK_LEN */
		} ccch_data_ind;
		/* OSMO_GPRS_RLCMAC_L1CTL_PDCH_DATA | Req */
		struct {
			uint32_t fn;
			uint8_t ts_nr;
			uint8_t data_len;
			uint8_t *data;
		} pdch_data_req;
		/* OSMO_GPRS_RLCMAC_L1CTL_PDCH_DATA | Ind */
		struct {
			uint32_t fn;
			uint8_t ts_nr;
			uint8_t rx_lev;
			uint16_t ber10k;
			int16_t ci_cb;
			uint8_t data_len; /* data_len = 0 if decoding fails or filtered by lower layer based on DL TFI */
			uint8_t *data;
		} pdch_data_ind;
		/* OSMO_GPRS_RLCMAC_L1CTL_PDCH_RTS | Ind */
		struct {
			uint32_t fn;
			uint8_t ts_nr;
			uint8_t usf;
		} pdch_rts_ind;
		/* OSMO_GPRS_RLCMAC_L1CTL_CFG_UL_TBF | Req */
		struct {
			uint8_t ul_tbf_nr;
			uint8_t ul_slotmask;
			uint32_t start_fn; /* TBF starting time (absolute Fn), UINT32_MAX = Invalid */
			uint8_t ul_usf[8]; /* USF for each PDCH indicated in the slotmask */
		} cfg_ul_tbf_req;
		/* OSMO_GPRS_RLCMAC_L1CTL_CFG_DL_TBF | Req */
		struct {
			uint8_t dl_tbf_nr;
			uint8_t dl_slotmask;
			uint32_t start_fn; /* TBF starting time (absolute Fn), UINT32_MAX = Invalid */
			uint8_t dl_tfi; /* DL TFI for all PDCHs indicated in the slotmask */
		} cfg_dl_tbf_req;
		/* OSMO_GPRS_RLCMAC_L1CTL_PDCH_ESTABLISH | Req */
		struct {
			uint8_t ts_nr;	/* Timeslot Number */
			uint8_t tsc;	/* Training Sequence Code */
			uint8_t ta;	/* Timing Advance */
			bool fh;	/* Frequency Hopping */
			union {
				uint16_t arfcn;
				struct {
					uint8_t hsn;
					uint8_t maio;
					uint8_t ma_len;
					uint8_t ma[8];
				} fhp; /* fh == true */
			};
		} pdch_est_req;
		/* OSMO_GPRS_RLCMAC_L1CTL_CCCH_READY | Ind */
		struct {
		} ccch_ready;
	};
};

struct osmo_gprs_rlcmac_prim {
	struct osmo_prim_hdr oph;
	union {
		struct osmo_gprs_rlcmac_grr_prim grr;
		struct osmo_gprs_rlcmac_gmmrr_prim gmmrr;
		struct osmo_gprs_rlcmac_l1ctl_prim l1ctl;
	};
};

typedef int (*osmo_gprs_rlcmac_prim_up_cb)(struct osmo_gprs_rlcmac_prim *rlcmac_prim, void *up_user_data);
void osmo_gprs_rlcmac_prim_set_up_cb(osmo_gprs_rlcmac_prim_up_cb up_cb, void *up_user_data);

typedef int (*osmo_gprs_rlcmac_prim_down_cb)(struct osmo_gprs_rlcmac_prim *rlcmac_prim, void *down_user_data);
void osmo_gprs_rlcmac_prim_set_down_cb(osmo_gprs_rlcmac_prim_down_cb down_cb, void *down_user_data);

int osmo_gprs_rlcmac_prim_upper_down(struct osmo_gprs_rlcmac_prim *rlcmac_prim);
int osmo_gprs_rlcmac_prim_lower_up(struct osmo_gprs_rlcmac_prim *rlcmac_prim);

const char *osmo_gprs_rlcmac_prim_name(const struct osmo_gprs_rlcmac_prim *rlcmac_prim);

/* Alloc primitive for GRR SAP: */
struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_grr_unitdata_req(
				uint32_t tlli, uint8_t *ll_pdu, size_t ll_pdu_len);

/* Alloc primitive for GMMRR SAP: */
struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(
				uint32_t old_tlli, uint32_t new_tlli);

/* Alloc primitive for L1CTL SAP: */
struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_l1ctl_ccch_data_ind(uint32_t fn, uint8_t *data);
struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_data_ind(uint8_t ts_nr, uint32_t fn,
				uint8_t rx_lev, uint16_t ber10k, int16_t ci_cb,
				uint8_t *data, uint8_t data_len);
struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_l1ctl_pdch_rts_ind(uint8_t ts_nr, uint32_t fn, uint8_t usf);
struct osmo_gprs_rlcmac_prim *gprs_rlcmac_prim_alloc_l1ctl_pdch_est_req(uint8_t ts_nr, uint8_t tsc, uint8_t ta);
struct osmo_gprs_rlcmac_prim *gprs_rlcmac_prim_alloc_l1ctl_pdch_rel_req(void);
struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_l1ctl_ccch_ready_ind(void);