summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h
blob: 6e9c197c0f39f5bb065426af83738e58acb0b424 (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
#ifndef _GSM48_MM_H
#define _GSM48_MM_H

/* GSM 04.07 9.2.2 */
#define GSM48_MMXX_MASK			0xf00
#define GSM48_MMCC_CLASS		0x100
#define GSM48_MMSS_CLASS		0x200
#define GSM48_MMSMS_CLASS		0x300
#define GSM48_MMCC_EST_REQ		0x110
#define GSM48_MMCC_EST_IND		0x112
#define GSM48_MMCC_EST_CNF		0x111
#define GSM48_MMCC_REL_REQ		0x120
#define GSM48_MMCC_REL_IND		0x122
#define GSM48_MMCC_DATA_REQ		0x130
#define GSM48_MMCC_DATA_IND		0x132
#define GSM48_MMCC_UNIT_DATA_REQ	0x140
#define GSM48_MMCC_UNIT_DATA_IND	0x142
#define GSM48_MMCC_SYNC_IND		0x152
#define GSM48_MMCC_REEST_REQ		0x160
#define GSM48_MMCC_REEST_CNF		0x161
#define GSM48_MMCC_ERR_IND		0x172
#define GSM48_MMCC_PROMPT_IND		0x182
#define GSM48_MMCC_PROMPT_REJ		0x184
#define GSM48_MMSS_EST_REQ		0x210
#define GSM48_MMSS_EST_IND		0x212
#define GSM48_MMSS_EST_CNF		0x211
#define GSM48_MMSS_REL_REQ		0x220
#define GSM48_MMSS_REL_IND		0x222
#define GSM48_MMSS_DATA_REQ		0x230
#define GSM48_MMSS_DATA_IND		0x232
#define GSM48_MMSS_UNIT_DATA_REQ	0x240
#define GSM48_MMSS_UNIT_DATA_IND	0x242
#define GSM48_MMSS_REEST_REQ		0x260
#define GSM48_MMSS_REEST_CNF		0x261
#define GSM48_MMSS_ERR_IND		0x272
#define GSM48_MMSS_PROMPT_IND		0x282
#define GSM48_MMSS_PROMPT_REJ		0x284
#define GSM48_MMSMS_EST_REQ		0x310
#define GSM48_MMSMS_EST_IND		0x312
#define GSM48_MMSMS_EST_CNF		0x311
#define GSM48_MMSMS_REL_REQ		0x320
#define GSM48_MMSMS_REL_IND		0x322
#define GSM48_MMSMS_DATA_REQ		0x330
#define GSM48_MMSMS_DATA_IND		0x332
#define GSM48_MMSMS_UNIT_DATA_REQ	0x340
#define GSM48_MMSMS_UNIT_DATA_IND	0x342
#define GSM48_MMSMS_REEST_REQ		0x360
#define GSM48_MMSMS_REEST_CNF		0x361
#define GSM48_MMSMS_ERR_IND		0x372
#define GSM48_MMSMS_PROMPT_IND		0x382
#define GSM48_MMSMS_PROMPT_REJ		0x384

#define MMXX_ALLOC_SIZE			256
#define MMXX_ALLOC_HEADROOM		64

/* MMxx-SAP header */
struct gsm48_mmxx_hdr {
	int		msg_type; /* MMxx_* primitive */
	uint32_t	ref; /* reference to transaction */
	uint32_t	transaction_id; /* transaction identifier */
	uint8_t		sapi; /* sapi */
	uint8_t		emergency; /* emergency type of call */
	uint8_t		cause; /* cause used for release */
};

/* GSM 6.1.2 */
#define	GSM48_MMR_REG_REQ		0x01
#define	GSM48_MMR_REG_CNF		0x02
#define	GSM48_MMR_NREG_REQ		0x03
#define	GSM48_MMR_NREG_IND		0x04

/* MMR-SAP header */
struct gsm48_mmr {
	int		msg_type;

	uint8_t		cause;
};

/* GSM 04.07 9.2.1 */
#define GSM48_MMXX_ST_IDLE		0
#define GSM48_MMXX_ST_CONN_PEND		1
#define GSM48_MMXX_ST_DEDICATED		2
#define GSM48_MMXX_ST_CONN_SUSP		3
#define GSM48_MMXX_ST_REESTPEND		4

/* GSM 04.08 4.1.2.1 */
#define	GSM48_MM_ST_NULL		0
#define GSM48_MM_ST_LOC_UPD_INIT	3
#define GSM48_MM_ST_WAIT_OUT_MM_CONN	5
#define GSM48_MM_ST_MM_CONN_ACTIVE	6
#define GSM48_MM_ST_IMSI_DETACH_INIT	7
#define GSM48_MM_ST_PROCESS_CM_SERV_P	8
#define GSM48_MM_ST_WAIT_NETWORK_CMD	9
#define GSM48_MM_ST_LOC_UPD_REJ		10
#define GSM48_MM_ST_WAIT_RR_CONN_LUPD	13
#define GSM48_MM_ST_WAIT_RR_CONN_MM_CON	14
#define GSM48_MM_ST_WAIT_RR_CONN_IMSI_D	15
#define GSM48_MM_ST_WAIT_REEST		17
#define GSM48_MM_ST_WAIT_RR_ACTIVE	18
#define GSM48_MM_ST_MM_IDLE		19
#define GSM48_MM_ST_WAIT_ADD_OUT_MM_CON	20
#define GSM48_MM_ST_MM_CONN_ACTIVE_VGCS	21
#define GSM48_MM_ST_WAIT_RR_CONN_VGCS	22
#define GSM48_MM_ST_LOC_UPD_PEND	23
#define GSM48_MM_ST_IMSI_DETACH_PEND	24
#define GSM48_MM_ST_RR_CONN_RELEASE_NA	25

/* GSM 04.08 4.1.2.1 */
#define GSM48_MM_SST_NORMAL_SERVICE	1
#define GSM48_MM_SST_ATTEMPT_UPDATE	2
#define GSM48_MM_SST_LIMITED_SERVICE	3
#define GSM48_MM_SST_NO_IMSI		4
#define GSM48_MM_SST_NO_CELL_AVAIL	5
#define GSM48_MM_SST_LOC_UPD_NEEDED	6
#define GSM48_MM_SST_PLMN_SEARCH	7
#define GSM48_MM_SST_PLMN_SEARCH_NORMAL	8
#define GSM48_MM_SST_RX_VGCS_NORMAL	9
#define GSM48_MM_SST_RX_VGCS_LIMITED	10

/* MM events */
#define GSM48_MM_EVENT_CELL_SELECTED	1
#define GSM48_MM_EVENT_NO_CELL_FOUND	2
#define GSM48_MM_EVENT_TIMEOUT_T3210	3
#define GSM48_MM_EVENT_TIMEOUT_T3211	4
#define GSM48_MM_EVENT_TIMEOUT_T3212	5
#define GSM48_MM_EVENT_TIMEOUT_T3213	6
#define GSM48_MM_EVENT_TIMEOUT_T3220	7
#define GSM48_MM_EVENT_TIMEOUT_T3230	8
#define GSM48_MM_EVENT_TIMEOUT_T3240	9
#define GSM48_MM_EVENT_IMSI_DETACH	10
#define GSM48_MM_EVENT_POWER_OFF	11
#define GSM48_MM_EVENT_PAGING		12
#define GSM48_MM_EVENT_AUTH_RESPONSE	13
#define GSM48_MM_EVENT_SYSINFO		14
#define GSM48_MM_EVENT_USER_PLMN_SEL	15
#define GSM48_MM_EVENT_LOST_COVERAGE	16

/* message for MM events */
struct gsm48_mm_event {
	uint32_t	msg_type;

	uint8_t		sres[4];
};

/* GSM 04.08 MM timers */
#define GSM_T3210_MS    20, 0
#define GSM_T3211_MS    15, 0
/* T3212 is given by SYSTEM INFORMATION */
#define GSM_T3213_MS    4, 0
#define GSM_T3220_MS    5, 0
#define GSM_T3230_MS    15, 0
#define GSM_T3240_MS    10, 0
#define GSM_T3241_MS    300, 0

/* MM sublayer instance */
struct gsm48_mmlayer {
	struct osmocom_ms	*ms;
	int			state;
	int			substate;

	/* queue for RR-SAP, MMxx-SAP, MMR-SAP, events message upwards */
	struct llist_head       rr_upqueue;
	struct llist_head       mmxx_upqueue;
	struct llist_head       mmr_downqueue;
	struct llist_head       event_queue;

	/* timers */
	struct osmo_timer_list	t3210, t3211, t3212, t3213;
	struct osmo_timer_list	t3220, t3230, t3240;
	int			t3212_value;
	int			start_t3211; /* remember to start timer */

	/* list of MM connections */
	struct llist_head	mm_conn;

	/* network name */
	char			name_short[32];
	char			name_long[32];

	/* location update */
	uint8_t			lupd_pending;	/* current pending loc. upd. */
	uint8_t			lupd_type;	/* current coded type */
	uint8_t			lupd_attempt;	/* attempt counter */
	uint8_t			lupd_ra_failure;/* random access failed */
	uint8_t			lupd_rej_cause;	/* cause of last reject */
	uint8_t			lupd_periodic;	/* periodic update pending */
	uint8_t			lupd_retry;	/* pending T3211/T3213 to */
	uint16_t		lupd_mcc, lupd_mnc, lupd_lac;

	/* imsi detach */
	uint8_t			delay_detach;	/* do detach when possible */

	/* other */
	uint8_t			est_cause; /* cause of establishment msg */
	int			mr_substate;	/* rem most recent substate */
	uint8_t			power_off_idle; /* waits for IDLE before po */

	/* sapi 3 */
	int			sapi3_link;
};

/* MM connection entry */
struct gsm48_mm_conn {
	struct llist_head	list;
	struct gsm48_mmlayer	*mm;

	/* ref and type form a unique tupple */
	uint32_t		ref; /* reference to trans */
	uint8_t			protocol;
	uint8_t			transaction_id;
	uint8_t			sapi;

	int			state;
};

uint8_t gsm48_current_pwr_lev(struct gsm_settings *set, uint16_t arfcn);
int gsm48_mm_init(struct osmocom_ms *ms);
int gsm48_mm_exit(struct osmocom_ms *ms);
struct msgb *gsm48_mmr_msgb_alloc(int msg_type);
struct msgb *gsm48_mmevent_msgb_alloc(int msg_type);
int gsm48_mmevent_msg(struct osmocom_ms *ms, struct msgb *msg);
int gsm48_mmr_downmsg(struct osmocom_ms *ms, struct msgb *msg);
int gsm48_rr_dequeue(struct osmocom_ms *ms);
int gsm48_mmxx_dequeue(struct osmocom_ms *ms);
int gsm48_mmr_dequeue(struct osmocom_ms *ms);
int gsm48_mmevent_dequeue(struct osmocom_ms *ms);
int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg);
struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
	uint8_t transaction_id, uint8_t sapi);
const char *get_mmr_name(int value);
const char *get_mm_name(int value);
const char *get_mmxx_name(int value);
extern const char *gsm48_mm_state_names[];
extern const char *gsm48_mm_substate_names[];

#endif /* _GSM48_MM_H */