5 #define GSM48_MMXX_MASK 0xf00
6 #define GSM48_MMCC_CLASS 0x100
7 #define GSM48_MMSS_CLASS 0x200
8 #define GSM48_MMSMS_CLASS 0x300
9 #define GSM48_MMCC_EST_REQ 0x110
10 #define GSM48_MMCC_EST_IND 0x112
11 #define GSM48_MMCC_EST_CNF 0x111
12 #define GSM48_MMCC_REL_REQ 0x120
13 #define GSM48_MMCC_REL_IND 0x122
14 #define GSM48_MMCC_DATA_REQ 0x130
15 #define GSM48_MMCC_DATA_IND 0x132
16 #define GSM48_MMCC_UNIT_DATA_REQ 0x140
17 #define GSM48_MMCC_UNIT_DATA_IND 0x142
18 #define GSM48_MMCC_SYNC_IND 0x152
19 #define GSM48_MMCC_REEST_REQ 0x160
20 #define GSM48_MMCC_REEST_CNF 0x161
21 #define GSM48_MMCC_ERR_IND 0x172
22 #define GSM48_MMCC_PROMPT_IND 0x182
23 #define GSM48_MMCC_PROMPT_REJ 0x184
24 #define GSM48_MMSS_EST_REQ 0x210
25 #define GSM48_MMSS_EST_IND 0x212
26 #define GSM48_MMSS_EST_CNF 0x211
27 #define GSM48_MMSS_REL_REQ 0x220
28 #define GSM48_MMSS_REL_IND 0x222
29 #define GSM48_MMSS_DATA_REQ 0x230
30 #define GSM48_MMSS_DATA_IND 0x232
31 #define GSM48_MMSS_UNIT_DATA_REQ 0x240
32 #define GSM48_MMSS_UNIT_DATA_IND 0x242
33 #define GSM48_MMSS_REEST_REQ 0x260
34 #define GSM48_MMSS_REEST_CNF 0x261
35 #define GSM48_MMSS_ERR_IND 0x272
36 #define GSM48_MMSS_PROMPT_IND 0x282
37 #define GSM48_MMSS_PROMPT_REJ 0x284
38 #define GSM48_MMSMS_EST_REQ 0x310
39 #define GSM48_MMSMS_EST_IND 0x312
40 #define GSM48_MMSMS_EST_CNF 0x311
41 #define GSM48_MMSMS_REL_REQ 0x320
42 #define GSM48_MMSMS_REL_IND 0x322
43 #define GSM48_MMSMS_DATA_REQ 0x330
44 #define GSM48_MMSMS_DATA_IND 0x332
45 #define GSM48_MMSMS_UNIT_DATA_REQ 0x340
46 #define GSM48_MMSMS_UNIT_DATA_IND 0x342
47 #define GSM48_MMSMS_REEST_REQ 0x360
48 #define GSM48_MMSMS_REEST_CNF 0x361
49 #define GSM48_MMSMS_ERR_IND 0x372
50 #define GSM48_MMSMS_PROMPT_IND 0x382
51 #define GSM48_MMSMS_PROMPT_REJ 0x384
53 #define MMXX_ALLOC_SIZE 256
54 #define MMXX_ALLOC_HEADROOM 64
57 struct gsm48_mmxx_hdr {
58 int msg_type; /* MMxx_* primitive */
59 uint32_t ref; /* reference to transaction */
60 uint32_t transaction_id; /* transaction identifier */
61 uint8_t emergency; /* emergency type of call */
62 uint8_t cause; /* cause used for release */
66 #define GSM48_MMR_REG_REQ 0x01
67 #define GSM48_MMR_REG_CNF 0x02
68 #define GSM48_MMR_NREG_REQ 0x03
69 #define GSM48_MMR_NREG_IND 0x04
79 #define GSM48_MMXX_ST_IDLE 0
80 #define GSM48_MMXX_ST_CONN_PEND 1
81 #define GSM48_MMXX_ST_DEDICATED 2
82 #define GSM48_MMXX_ST_CONN_SUSP 3
83 #define GSM48_MMXX_ST_REESTPEND 4
85 /* GSM 04.08 4.1.2.1 */
86 #define GSM48_MM_ST_NULL 0
87 #define GSM48_MM_ST_LOC_UPD_INIT 3
88 #define GSM48_MM_ST_WAIT_OUT_MM_CONN 5
89 #define GSM48_MM_ST_MM_CONN_ACTIVE 6
90 #define GSM48_MM_ST_IMSI_DETACH_INIT 7
91 #define GSM48_MM_ST_PROCESS_CM_SERV_P 8
92 #define GSM48_MM_ST_WAIT_NETWORK_CMD 9
93 #define GSM48_MM_ST_LOC_UPD_REJ 10
94 #define GSM48_MM_ST_WAIT_RR_CONN_LUPD 13
95 #define GSM48_MM_ST_WAIT_RR_CONN_MM_CON 14
96 #define GSM48_MM_ST_WAIT_RR_CONN_IMSI_D 15
97 #define GSM48_MM_ST_WAIT_REEST 17
98 #define GSM48_MM_ST_WAIT_RR_ACTIVE 18
99 #define GSM48_MM_ST_MM_IDLE 19
100 #define GSM48_MM_ST_WAIT_ADD_OUT_MM_CON 20
101 #define GSM48_MM_ST_MM_CONN_ACTIVE_VGCS 21
102 #define GSM48_MM_ST_WAIT_RR_CONN_VGCS 22
103 #define GSM48_MM_ST_LOC_UPD_PEND 23
104 #define GSM48_MM_ST_IMSI_DETACH_PEND 24
105 #define GSM48_MM_ST_RR_CONN_RELEASE_NA 25
107 /* GSM 04.08 4.1.2.1 */
108 #define GSM48_MM_SST_NORMAL_SERVICE 1
109 #define GSM48_MM_SST_ATTEMPT_UPDATE 2
110 #define GSM48_MM_SST_LIMITED_SERVICE 3
111 #define GSM48_MM_SST_NO_IMSI 4
112 #define GSM48_MM_SST_NO_CELL_AVAIL 5
113 #define GSM48_MM_SST_LOC_UPD_NEEDED 6
114 #define GSM48_MM_SST_PLMN_SEARCH 7
115 #define GSM48_MM_SST_PLMN_SEARCH_NORMAL 8
116 #define GSM48_MM_SST_RX_VGCS_NORMAL 9
117 #define GSM48_MM_SST_RX_VGCS_LIMITED 10
120 #define GSM48_MM_EVENT_CELL_SELECTED 1
121 #define GSM48_MM_EVENT_NO_CELL_FOUND 2
122 #define GSM48_MM_EVENT_TIMEOUT_T3210 3
123 #define GSM48_MM_EVENT_TIMEOUT_T3211 4
124 #define GSM48_MM_EVENT_TIMEOUT_T3212 5
125 #define GSM48_MM_EVENT_TIMEOUT_T3213 6
126 #define GSM48_MM_EVENT_TIMEOUT_T3220 7
127 #define GSM48_MM_EVENT_TIMEOUT_T3230 8
128 #define GSM48_MM_EVENT_TIMEOUT_T3240 9
129 #define GSM48_MM_EVENT_IMSI_DETACH 10
130 #define GSM48_MM_EVENT_POWER_OFF 11
131 #define GSM48_MM_EVENT_PAGING 12
132 #define GSM48_MM_EVENT_AUTH_RESPONSE 13
133 #define GSM48_MM_EVENT_SYSINFO 14
134 #define GSM48_MM_EVENT_USER_PLMN_SEL 15
136 /* message for MM events */
137 struct gsm48_mm_event {
143 /* GSM 04.08 MM timers */
144 #define GSM_T3210_MS 20, 0
145 #define GSM_T3211_MS 15, 0
146 /* T3212 is given by SYSTEM INFORMATION */
147 #define GSM_T3213_MS 4, 0
148 #define GSM_T3220_MS 5, 0
149 #define GSM_T3230_MS 15, 0
150 #define GSM_T3240_MS 10, 0
151 #define GSM_T3241_MS 300, 0
153 /* MM sublayer instance */
154 struct gsm48_mmlayer {
155 struct osmocom_ms *ms;
159 /* queue for RR-SAP, MMxx-SAP, MMR-SAP, events message upwards */
160 struct llist_head rr_upqueue;
161 struct llist_head mmxx_upqueue;
162 struct llist_head mmr_downqueue;
163 struct llist_head event_queue;
166 struct timer_list t3210, t3211, t3212, t3213;
167 struct timer_list t3220, t3230, t3240;
169 int start_t3211; /* remember to start timer */
171 /* list of MM connections */
172 struct llist_head mm_conn;
178 /* location update */
179 uint8_t lupd_pending; /* current pending loc. upd. */
180 uint8_t lupd_type; /* current coded type */
181 uint8_t lupd_attempt; /* attempt counter */
182 uint8_t lupd_ra_failure;/* random access failed */
183 uint8_t lupd_rej_cause; /* cause of last reject */
184 uint8_t lupd_periodic; /* periodic update pending */
185 uint8_t lupd_retry; /* pending T3211/T3213 to */
186 uint16_t lupd_mcc, lupd_mnc, lupd_lac;
189 uint8_t delay_detach; /* do detach when possible */
192 uint8_t est_cause; /* cause of establishment msg */
193 int mr_substate; /* rem most recent substate */
194 uint8_t power_off; /* set, if power off after detach */
195 uint8_t power_off_idle; /* waits for IDLE before po */
198 /* MM connection entry */
199 struct gsm48_mm_conn {
200 struct llist_head list;
201 struct gsm48_mmlayer *mm;
203 /* ref and type form a unique tupple */
204 uint32_t ref; /* reference to trans */
206 uint8_t transaction_id;
211 int gsm48_mm_init(struct osmocom_ms *ms);
212 int gsm48_mm_exit(struct osmocom_ms *ms);
213 struct msgb *gsm48_mmr_msgb_alloc(int msg_type);
214 struct msgb *gsm48_mmevent_msgb_alloc(int msg_type);
215 int gsm48_mmevent_msg(struct osmocom_ms *ms, struct msgb *msg);
216 int gsm48_mmr_downmsg(struct osmocom_ms *ms, struct msgb *msg);
217 int gsm48_rr_dequeue(struct osmocom_ms *ms);
218 int gsm48_mmxx_dequeue(struct osmocom_ms *ms);
219 int gsm48_mmr_dequeue(struct osmocom_ms *ms);
220 int gsm48_mmevent_dequeue(struct osmocom_ms *ms);
221 int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg);
222 struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
223 uint8_t transaction_id);
224 const char *get_mmr_name(int value);
225 const char *get_mmxx_name(int value);
226 extern const char *gsm48_mm_state_names[];
227 extern const char *gsm48_mm_substate_names[];
229 #endif /* _GSM48_MM_H */