FreeCalypso > hg > freecalypso-citrine
comparison g23m-gsm/mm/mm_mms.c @ 0:75a11d740a02
initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 09 Jun 2016 00:02:41 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:75a11d740a02 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : GSM-PS (8410) | |
4 | Modul : MM_FORP | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : This Modul defines the functions for the mob. management | |
18 | capability of the module Mobility Managemant. | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #ifndef MM_MMS_C | |
23 #define MM_MMS_C | |
24 | |
25 #include "config.h" | |
26 #include "fixedconf.h" | |
27 #include "condat-features.h" | |
28 | |
29 #define ENTITY_MM | |
30 | |
31 /*==== INCLUDES ===================================================*/ | |
32 #if defined (NEW_FRAME) | |
33 | |
34 #include <string.h> | |
35 #include <stdlib.h> | |
36 #include <stddef.h> | |
37 #include "typedefs.h" | |
38 #include "pcm.h" | |
39 #include "pconst.cdg" | |
40 #include "mconst.cdg" | |
41 #include "message.h" | |
42 #include "ccdapi.h" | |
43 #include "vsi.h" | |
44 #include "custom.h" | |
45 #include "gsm.h" | |
46 #include "prim.h" | |
47 #include "cnf_mm.h" | |
48 #include "mon_mm.h" | |
49 #include "pei.h" | |
50 #include "tok.h" | |
51 #include "mm.h" | |
52 #include "mm_em.h" | |
53 | |
54 #else | |
55 | |
56 #include <string.h> | |
57 #include <stdlib.h> | |
58 #include <stddef.h> | |
59 #include "stddefs.h" | |
60 #include "pcm.h" | |
61 #include "pconst.cdg" | |
62 #include "mconst.cdg" | |
63 #include "message.h" | |
64 #include "ccdapi.h" | |
65 #include "custom.h" | |
66 #include "gsm.h" | |
67 #include "prim.h" | |
68 #include "cnf_mm.h" | |
69 #include "mon_mm.h" | |
70 #include "vsi.h" | |
71 #include "pei.h" | |
72 #include "tok.h" | |
73 #include "mm.h" | |
74 #include "mm_em.h" | |
75 | |
76 #endif | |
77 | |
78 /*==== EXPORT =====================================================*/ | |
79 | |
80 /*==== PRIVAT =====================================================*/ | |
81 | |
82 /*==== TEST =====================================================*/ | |
83 | |
84 /*==== VARIABLES ==================================================*/ | |
85 /* added by TISH 0418 to write simloci to FFS */ | |
86 extern T_loc_info loc_info_ffs; | |
87 extern T_imsi_struct imsi_in_ffs; | |
88 /* added by TISH 0418 to write simloci to FFS */ | |
89 | |
90 /*==== FUNCTIONS ==================================================*/ | |
91 | |
92 LOCAL void mm_send_rr_data_ind (T_RR_DATA_IND *rr_data_ind, | |
93 UBYTE comp, | |
94 T_PRIM_TYPE snd_prim_type); | |
95 LOCAL void mm_cpy_net_name (T_full_net_name *net_name, | |
96 T_full_name *name, | |
97 UBYTE v_net_name); | |
98 | |
99 /* | |
100 * ------------------------------------------------------------------- | |
101 * SIGNAL Processing functions | |
102 * ------------------------------------------------------------------- | |
103 */ | |
104 | |
105 /* | |
106 +--------------------------------------------------------------------+ | |
107 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
108 | STATE : code ROUTINE : mm_store_tmsi | | |
109 +--------------------------------------------------------------------+ | |
110 | |
111 PURPOSE : Convert the mobile identity to the internal TMSI | |
112 representation. | |
113 | |
114 */ | |
115 | |
116 LOCAL void mm_store_tmsi (const T_mob_id *moi) | |
117 { | |
118 GET_INSTANCE_DATA; | |
119 TRACE_FUNCTION ("mm_store_tmsi()"); | |
120 | |
121 mm_data->reg.tmsi = | |
122 (((ULONG)moi->tmsi.b_tmsi[0]) << 24) + | |
123 (((ULONG)moi->tmsi.b_tmsi[1]) << 16) + | |
124 (((ULONG)moi->tmsi.b_tmsi[2]) << 8) + | |
125 (ULONG)moi->tmsi.b_tmsi[3]; | |
126 } | |
127 | |
128 /* | |
129 +--------------------------------------------------------------------+ | |
130 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
131 | STATE : code ROUTINE : mm_abort | | |
132 +--------------------------------------------------------------------+ | |
133 | |
134 PURPOSE : Process the signal ABORT. | |
135 The abort procedure may be invoked by the network to abort any | |
136 on-going MM connection establishment or already established MM | |
137 connection. The mobile station shall treat ABORT message as | |
138 compatible with current protocol state only if it is received | |
139 when at least one MM connection exists or an MM connection is | |
140 being established. [GSM 04.08 clause 4.3.5] | |
141 | |
142 */ | |
143 | |
144 GLOBAL void mm_abort (T_D_ABORT *d_abort) | |
145 { | |
146 GET_INSTANCE_DATA; | |
147 TRACE_FUNCTION ("mm_abort()"); | |
148 | |
149 switch (GET_STATE (STATE_MM)) | |
150 { | |
151 case MM_WAIT_FOR_OUTG_MM_CONN: | |
152 case MM_CONN_ACTIVE: | |
153 case MM_PROCESS_PROMPT: | |
154 TIMERSTOP (T3230); | |
155 /*FALLTHROUGH*/ | |
156 //lint -fallthrough | |
157 case MM_WAIT_FOR_NW_CMD: | |
158 | |
159 mm_data->rej_cause = CAUSE_MAKE (DEFBY_STD, | |
160 ORIGSIDE_NET, | |
161 MM_CAUSE, | |
162 d_abort->rej_cause); | |
163 | |
164 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE) | |
165 { | |
166 /* | |
167 * T3212 is stopped if the first MM message is received, or | |
168 * ciphering mode setting is completed in the case of MM | |
169 * connection establishment, except when the most recent service | |
170 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2] | |
171 */ | |
172 TIMERSTOP (T3212); | |
173 mm_data->t3212_timeout = FALSE; | |
174 } | |
175 | |
176 switch (mm_data->rej_cause) | |
177 { | |
178 case MMCS_NETWORK_FAILURE: | |
179 mm_mmxx_rel_ind (RC_NETWORK_FAILURE, CM_NOT_IDLE); | |
180 break; | |
181 case MMCS_ILLEGAL_ME: | |
182 /* | |
183 * "At the receipt of the ABORT message the mobile station shall | |
184 * abort any MM connection establishment or call re-establishment | |
185 * procedure and release all MM connections (if any). | |
186 * If cause value #6 is received the mobile station shall | |
187 * delete any TMSI, LAI and ciphering key sequence number stored | |
188 * in the SIM, set the update status to ROAMING NOT ALLOWED (and | |
189 * store it in the SIM according to section 4.1.2.2) and consider | |
190 * the SIM invalid until switch off or the SIM is removed. | |
191 * As a consequence the mobile station enters state MM IDLE, | |
192 * substate NO IMSI after the release of the RR connection. | |
193 * The mobile station shall then wait for the network to release | |
194 * the RR connection - see section 4.5.3.1." [GSM 04.08 4.3.5] | |
195 */ | |
196 /* Release all connections with appropriate cause */ | |
197 mm_mmxx_rel_ind (mm_data->rej_cause, CM_NOT_IDLE); | |
198 /* Inform RR about loss of registration until power cycle */ | |
199 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL_NO_PAG); | |
200 /* Delete registration data and update SIM */ | |
201 #ifdef REL99 | |
202 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED, FALSE); | |
203 #else | |
204 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED); | |
205 #endif | |
206 /* Delete IMSI - consider SIM as invalid */ | |
207 mm_clear_mob_ident (&mm_data->reg.imsi_struct); | |
208 mm_clear_reg_data (); | |
209 /* Remember limited service cause for MMI information */ | |
210 mm_data->limited_cause = mm_data->rej_cause; | |
211 // Debug patch >>> | |
212 if (mm_data->mm_idle_no_imsi_marker EQ 0) | |
213 mm_data->mm_idle_no_imsi_marker = 23; | |
214 // Debug patch <<< | |
215 | |
216 break; | |
217 default: | |
218 break; | |
219 } | |
220 TIMERSTART (T3240, T_3240_VALUE); | |
221 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD); | |
222 break; | |
223 | |
224 case MM_LUP_REJECTED: | |
225 case MM_LUP_INITIATED: | |
226 #ifdef REL99 | |
227 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
228 #endif | |
229 mm_for_set_error (RC_MESSAGE_INCOMPAT); | |
230 break; | |
231 | |
232 default: | |
233 break; | |
234 } | |
235 } | |
236 | |
237 /* | |
238 +--------------------------------------------------------------------+ | |
239 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
240 | STATE : code ROUTINE : mm_auth_rej | | |
241 +--------------------------------------------------------------------+ | |
242 | |
243 PURPOSE : Process the signal AUTH_REJ. | |
244 | |
245 */ | |
246 | |
247 GLOBAL void mm_auth_rej (void) | |
248 { | |
249 GET_INSTANCE_DATA; | |
250 TRACE_FUNCTION ("mm_auth_rej()"); | |
251 | |
252 switch (GET_STATE (STATE_MM)) | |
253 { | |
254 case MM_LUP_INITIATED: | |
255 case MM_WAIT_FOR_OUTG_MM_CONN: | |
256 case MM_CONN_ACTIVE: | |
257 case MM_PROCESS_PROMPT: | |
258 case MM_WAIT_FOR_NW_CMD: | |
259 #ifdef REL99 | |
260 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
261 #endif | |
262 /* | |
263 * Upon receipt of an AUTHENTICATION REJECT message, | |
264 * the mobile station shall set the update status in the SIM to | |
265 * U2 ROAMING NOT ALLOWED, delete from the SIM the stored TMSI, | |
266 * LAI and ciphering key sequence number. | |
267 * The SIM shall be considered as invalid until switching off | |
268 * or the SIM is removed. | |
269 * If the AUTHENTICATION REJECT message is received in the state | |
270 * IMSI DETACH INITIATED the mobile station shall follow | |
271 * section 4.3.4.3. [Means: Ignore it]. | |
272 * If the AUTHENTICATION REJECT message is received in any other | |
273 * state the mobile station shall abort any MM specific, MM connection | |
274 * establishment or call re-establishment procedure, stop any of the | |
275 * timers T3210 or T3230 (if running), release all MM connections | |
276 * (if any), start timer T3240 and enter the state WAIT FOR NETWORK | |
277 * COMMAND, expecting the release of the RR connection. If the RR | |
278 * connection is not released within a given time controlled by the | |
279 * timer T3240, the mobile station shall abort the RR connection. | |
280 * In both cases, either after a RR connection release triggered from | |
281 * the network side or after a RR connection abort requested by the | |
282 * MS-side, the MS enters state MM IDLE, substate NO IMSI. | |
283 * [GSM 04.08 subclause 4.3.2.5] | |
284 */ | |
285 | |
286 mm_mmxx_rel_ind (MMCS_AUTHENTICATION_REJECTED, CM_NOT_IDLE); | |
287 | |
288 /* | |
289 * T3212 is stopped if an AUTHENTICATION REJECT message | |
290 * is received [GSM 04.08 subclause 4.4.2] | |
291 */ | |
292 TIMERSTOP (T3212); | |
293 mm_data->t3212_timeout = FALSE; | |
294 | |
295 TIMERSTOP (T3210); | |
296 TIMERSTOP (T3211); | |
297 TIMERSTOP (T3230); | |
298 | |
299 // As this will set later MM_IDLE_NO_IMSI_STATE, we will remember | |
300 mm_data->mm_idle_no_imsi_marker = 129; | |
301 | |
302 /* | |
303 * Upon receipt of an AUTHENTICATION REJECT message, the mobile station | |
304 * shall set the update status in the SIM to U2 ROAMING NOT ALLOWED, | |
305 * delete from the SIM the stored TMSI, LAI and ciphering key sequence | |
306 * number. [GSM 04.08 subclause 4.3.2.5] | |
307 */ | |
308 | |
309 /* Inform RR about the invalidation of the SIM */ | |
310 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL_NO_PAG); | |
311 | |
312 /* Invalidate the SIM in MM until switch off and inform the SIM */ | |
313 #ifdef REL99 | |
314 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED, FALSE); | |
315 #else | |
316 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED); | |
317 #endif | |
318 | |
319 /* Invalidate SIM data after indirect call to reg_build_sim_update() */ | |
320 mm_clear_mob_ident (&mm_data->reg.imsi_struct); | |
321 mm_clear_reg_data (); | |
322 | |
323 /* Remember limited service reason for MMI information */ | |
324 mm_data->limited_cause = MMCS_AUTHENTICATION_REJECTED; | |
325 | |
326 /* Delete EPLMN list */ | |
327 if (reg_clear_plmn_list (mm_data->reg.eqv_plmns.eqv_plmn_list, EPLMNLIST_SIZE)) | |
328 mm_build_rr_sync_req_cause (SYNCCS_EPLMN_LIST); | |
329 | |
330 #ifdef GPRS | |
331 /* | |
332 * Notify GMM about the AUTHENTICATION REJECT, not regarding whether | |
333 * it is active or not. For details, see GSM 04.08 subclause 4.1.1.2. | |
334 */ | |
335 mm_mmgmm_auth_rej_ind (); | |
336 #endif | |
337 #ifdef REL99 | |
338 /*Stop timer t3241 if it is ruuning. | |
339 *As per the spec 24.008, Timer T3241 is stopped and reset (but not started) | |
340 *when the MM state RR CONNECTION RELEASE NOT ALLOWED is left. | |
341 */ | |
342 TIMERSTOP(T3241); | |
343 #endif | |
344 /* Enter state MM_WAIT_FOR_NW_CMD */ | |
345 TIMERSTART (T3240, T_3240_VALUE); | |
346 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD); | |
347 | |
348 EM_AUTHENTICATION(EM_REJECT); | |
349 | |
350 break; | |
351 | |
352 case MM_LUP_REJECTED: | |
353 { | |
354 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
355 } | |
356 break; | |
357 | |
358 default: | |
359 break; | |
360 } | |
361 } | |
362 | |
363 /* | |
364 +--------------------------------------------------------------------+ | |
365 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
366 | STATE : code ROUTINE : mm_auth_req | | |
367 +--------------------------------------------------------------------+ | |
368 | |
369 PURPOSE : Process the signal AUTH_REQ. | |
370 | |
371 */ | |
372 | |
373 GLOBAL void mm_auth_req (T_D_AUTH_REQ *auth_req) | |
374 { | |
375 GET_INSTANCE_DATA; | |
376 TRACE_FUNCTION ("mm_auth_req()"); | |
377 | |
378 switch (GET_STATE (STATE_MM)) | |
379 { | |
380 | |
381 case MM_WAIT_FOR_OUTG_MM_CONN: | |
382 case MM_CONN_ACTIVE: | |
383 case MM_WAIT_FOR_NW_CMD: | |
384 { | |
385 if ( mm_data->idle_substate EQ MM_IDLE_NO_IMSI ) | |
386 { | |
387 mm_for_set_error( RC_MESSAGE_TYPE_INCOMPAT ); | |
388 break; | |
389 } | |
390 | |
391 } | |
392 /*Fall Through*/ | |
393 | |
394 case MM_LUP_INITIATED: | |
395 case MM_PROCESS_PROMPT: | |
396 #ifdef REL99 | |
397 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
398 #endif | |
399 { | |
400 PALLOC (sim_auth_req, SIM_AUTHENTICATION_REQ); | |
401 TIMERSTOP (T3211); | |
402 | |
403 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE) | |
404 { | |
405 /* | |
406 * T3212 is stopped if the first MM message is received, or | |
407 * ciphering mode setting is completed in the case of MM | |
408 * connection establishment, except when the most recent service | |
409 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2] | |
410 */ | |
411 TIMERSTOP (T3212); | |
412 mm_data->t3212_timeout = FALSE; | |
413 } | |
414 | |
415 TIMERSTOP (T3213); | |
416 mm_data->t3213_restart = 0; | |
417 mm_data->reg.cksn = auth_req->ciph_key_num.key_seq; | |
418 memcpy (sim_auth_req, auth_req, | |
419 sizeof (T_SIM_AUTHENTICATION_REQ)); | |
420 reg_mmr_auth_ind (sim_auth_req); | |
421 if (TIMERACTIVE(T3240)) | |
422 { | |
423 TIMERSTOP (T3240); | |
424 TIMERSTART (T3240, T_3240_VALUE); | |
425 } | |
426 | |
427 EM_AUTHENTICATION(EM_REQUEST); | |
428 | |
429 } | |
430 break; | |
431 | |
432 case MM_LUP_REJECTED: | |
433 { | |
434 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
435 break; | |
436 } | |
437 default: | |
438 break; | |
439 } | |
440 } | |
441 | |
442 /* | |
443 +--------------------------------------------------------------------+ | |
444 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
445 | STATE : code ROUTINE : mm_cm_message | | |
446 +--------------------------------------------------------------------+ | |
447 | |
448 PURPOSE : Process the signal CM_MESSAGE. Normally, this means | |
449 that a L3 message which is for one of the CM entities | |
450 is forwarded to the appropriate CM entity, either as | |
451 MMXX_ESTABLISH_IND or MMXX_DATA_IND. | |
452 The following can be assumed to be true: | |
453 PD is either PD_CC, PD_SS or PD_SMS. | |
454 The ti has already been transformed by the formatter into | |
455 the range 0..6 for mobile originated transactions and | |
456 the range 8..14 for mobile terminated transactions. | |
457 | |
458 */ | |
459 | |
460 GLOBAL void mm_cm_message (UBYTE pd, | |
461 UBYTE ti, | |
462 T_RR_DATA_IND *rr_data_ind) | |
463 { | |
464 GET_INSTANCE_DATA; | |
465 UBYTE comp; | |
466 | |
467 TRACE_FUNCTION ("mm_cm_message()"); | |
468 | |
469 switch (pd) | |
470 { | |
471 case PD_CC: | |
472 comp = CC_COMP; | |
473 break; | |
474 case PD_SS: | |
475 comp = SS_COMP; | |
476 break; | |
477 case PD_SMS: | |
478 comp = SMS_COMP; | |
479 break; | |
480 default: | |
481 PFREE (rr_data_ind); | |
482 return; | |
483 } | |
484 | |
485 switch (GET_STATE (STATE_MM)) | |
486 { | |
487 case MM_WAIT_FOR_OUTG_MM_CONN: | |
488 case MM_CONN_ACTIVE: | |
489 case MM_PROCESS_PROMPT: | |
490 case MM_WAIT_FOR_NW_CMD: | |
491 #ifdef REL99 | |
492 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
493 #endif | |
494 switch (CM_GET_STATE (comp, ti)) | |
495 { | |
496 case CM_IDLE: | |
497 CM_SET_STATE (comp, ti, CM_ACTIVE); | |
498 mm_send_rr_data_ind(rr_data_ind, comp, PRIM_EST_IND); | |
499 | |
500 TIMERSTOP (T3211); | |
501 TIMERSTOP (T3213); | |
502 mm_data->t3213_restart = 0; | |
503 TIMERSTOP (T3240); | |
504 #ifdef REL99 | |
505 /*Stop timer t3241 if it is ruuning. | |
506 *As per the spec 24.008, Timer T3241 is stopped and reset (but not started) | |
507 *when the MM state RR CONNECTION RELEASE NOT ALLOWED is left. | |
508 */ | |
509 TIMERSTOP(T3241); | |
510 #endif | |
511 | |
512 /* | |
513 * T3212 is stopped if the mobile station has responded to paging | |
514 * and thereafter has received the first correct layer 3 message | |
515 * except RR message. [GSM 04.08 subclause 4.4.2] | |
516 */ | |
517 TIMERSTOP (T3212); | |
518 mm_data->t3212_timeout = FALSE; | |
519 | |
520 SET_STATE (STATE_MM, MM_CONN_ACTIVE); | |
521 USE_STORED_ENTRIES(); | |
522 break; | |
523 | |
524 case CM_PENDING: | |
525 /* | |
526 * The connection is pending, and instead of MMXX_ESTABLISH_CNF | |
527 * the CM entity receives MMXX_ESTABLISH_IND. No state change | |
528 * in the connection table is performed. | |
529 * The special problem which was intended to solve here | |
530 * was to pass multilayer testcase MCC 100. | |
531 * Problem: From which GSM 11.10 testcase is MCC 100 derived? | |
532 * A transaction which is mobile originated has assigned ti=0..6 | |
533 * here, a transactions which is mobile terminated has assigned | |
534 * ti=8..14 here. | |
535 * => It is impossible to have a MMXX_ESTABLISH_IND for a pending | |
536 * connection with a correctly working network. | |
537 */ | |
538 TIMERSTOP (T3213); | |
539 mm_data->t3213_restart = 0; | |
540 TIMERSTOP (T3240); | |
541 mm_send_rr_data_ind(rr_data_ind, comp, PRIM_EST_IND); | |
542 | |
543 /* | |
544 * T3212 is stopped if the mobile station has responded to paging | |
545 * and thereafter has received the first correct layer 3 message | |
546 * except RR message. [GSM 04.08 subclause 4.4.2] | |
547 */ | |
548 TIMERSTOP (T3212); | |
549 mm_data->t3212_timeout = FALSE; | |
550 break; /* case CM_PENDING */ | |
551 | |
552 case CM_ACTIVE: | |
553 TIMERSTOP (T3213); | |
554 mm_data->t3213_restart = 0; | |
555 TIMERSTOP (T3240); | |
556 mm_send_rr_data_ind(rr_data_ind, comp, PRIM_DATA_IND); | |
557 break; /* case CM_ACTIVE */ | |
558 | |
559 default: | |
560 { | |
561 /* Implements Measure 29 and streamline encoding */ | |
562 mm_send_status(RC_IDENTIFIY); | |
563 } | |
564 PFREE (rr_data_ind); | |
565 break; | |
566 } | |
567 break; | |
568 | |
569 case MM_LUP_REJECTED: | |
570 case MM_LUP_INITIATED: | |
571 { | |
572 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
573 } | |
574 PFREE (rr_data_ind); | |
575 break; | |
576 | |
577 default: | |
578 PFREE (rr_data_ind); | |
579 break; | |
580 } | |
581 } | |
582 | |
583 /* | |
584 +--------------------------------------------------------------------+ | |
585 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
586 | STATE : code ROUTINE : mm_cm_serv_accept | | |
587 +--------------------------------------------------------------------+ | |
588 | |
589 PURPOSE : Process the signal CM_SERV_ACCEPT. | |
590 | |
591 */ | |
592 | |
593 GLOBAL void mm_cm_serv_accept (void) | |
594 { | |
595 GET_INSTANCE_DATA; | |
596 TRACE_FUNCTION ("mm_cm_serv_accept()"); | |
597 | |
598 switch (GET_STATE (STATE_MM)) | |
599 { | |
600 case MM_WAIT_FOR_REESTABLISH: | |
601 case MM_LUP_INITIATED: | |
602 case MM_WAIT_FOR_OUTG_MM_CONN: | |
603 case MM_CONN_ACTIVE: | |
604 case MM_WAIT_FOR_NW_CMD: | |
605 if (mm_data->wait_for_accept) | |
606 { | |
607 mm_mmxx_est_cnf (); | |
608 | |
609 /* | |
610 * Ensure we are not fooled by a forgotten reset of the location | |
611 * updating type, so check also the service state. Should not | |
612 * be necessary for a perfect world. | |
613 */ | |
614 if (mm_data->idle_substate NEQ MM_IDLE_LIMITED_SERVICE AND | |
615 mm_data->idle_substate NEQ MM_IDLE_NO_IMSI AND | |
616 (mm_data->loc_upd_type.lut EQ PERIODIC_LUP OR | |
617 mm_data->loc_upd_type.lut EQ IMSI_ATTACH_LUP)) | |
618 { | |
619 /* | |
620 * Implicit location updating accept for periodic or | |
621 * IMSI attach location updating request. | |
622 * This cannot be found in GSM 04.08, | |
623 * but otherwise GSM 11.10 26.7.4.3.4 would fail. | |
624 * For details, see GSM 11.10 subclause 26.7.4.3.4.1 | |
625 * 1.) and 2.) | |
626 */ | |
627 mm_data->loc_upd_type.lut = NOT_RUNNING; | |
628 | |
629 if (mm_data->first_attach) | |
630 { | |
631 mm_data->first_attach_mem = mm_data->first_attach; | |
632 mm_data->first_attach = FALSE; | |
633 } | |
634 #ifdef GPRS | |
635 if (!mm_gsm_alone()) | |
636 mm_data->gprs.reg_cnf_on_idle_entry = TRUE; | |
637 #endif /* GPRS */ | |
638 reg_mm_success (FULL_SERVICE); | |
639 } | |
640 | |
641 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE) | |
642 { | |
643 /* | |
644 * T3212 is stopped if the first MM message is received, or | |
645 * ciphering mode setting is completed in the case of MM | |
646 * connection establishment, except when the most recent service | |
647 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2] | |
648 */ | |
649 TIMERSTOP (T3212); | |
650 mm_data->t3212_timeout = FALSE; | |
651 } | |
652 | |
653 TIMERSTOP (T3211); | |
654 TIMERSTOP (T3213); | |
655 mm_data->t3213_restart = 0; | |
656 TIMERSTOP (T3230); | |
657 mm_data->wait_for_accept = FALSE; | |
658 SET_STATE (STATE_MM, MM_CONN_ACTIVE); | |
659 | |
660 EM_CM_SERVICE_ACCEPTED(EM_CIPHERING); | |
661 | |
662 USE_STORED_ENTRIES(); | |
663 } | |
664 else | |
665 { | |
666 /* CM_SERV_ACCEPT not expected, send MM_STATUS */ | |
667 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
668 } | |
669 break; | |
670 | |
671 case MM_PROCESS_PROMPT: | |
672 case MM_LUP_REJECTED: | |
673 #ifdef REL99 | |
674 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
675 #endif | |
676 /* CM_SERV_ACCEPT not expected, send MM_STATUS */ | |
677 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
678 break; | |
679 | |
680 default: | |
681 break; | |
682 } | |
683 } | |
684 | |
685 /* | |
686 +--------------------------------------------------------------------+ | |
687 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
688 | STATE : code ROUTINE : mm_cm_serv_rej | | |
689 +--------------------------------------------------------------------+ | |
690 | |
691 PURPOSE : Process the signal CM_SERV_REJ. | |
692 | |
693 */ | |
694 | |
695 GLOBAL void mm_cm_serv_rej (T_D_CM_SERV_REJ *cm_serv_rej) | |
696 { | |
697 GET_INSTANCE_DATA; | |
698 TRACE_FUNCTION ("mm_cm_serv_rej()"); | |
699 | |
700 /* Semantical checks and preprocessing */ | |
701 cm_serv_rej->rej_cause = for_check_reject_cause (cm_serv_rej->rej_cause); | |
702 | |
703 TRACE_EVENT_P1 ("CM_SERV_REJ cause = %d", cm_serv_rej->rej_cause); | |
704 | |
705 /* | |
706 * The behaviour is described in GSM 04.08 subclause 4.5.1.1 | |
707 * For further details, see this recommendation. | |
708 */ | |
709 switch (GET_STATE (STATE_MM)) | |
710 { | |
711 case MM_WAIT_FOR_REESTABLISH: | |
712 case MM_WAIT_FOR_OUTG_MM_CONN: | |
713 case MM_CONN_ACTIVE: | |
714 case MM_PROCESS_PROMPT: | |
715 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE) | |
716 { | |
717 /* | |
718 * T3212 is stopped if the first MM message is received, or | |
719 * ciphering mode setting is completed in the case of MM | |
720 * connection establishment, except when the most recent service | |
721 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2] | |
722 */ | |
723 TIMERSTOP (T3212); | |
724 mm_data->t3212_timeout = FALSE; | |
725 } | |
726 | |
727 TIMERSTOP (T3211); | |
728 TIMERSTOP (T3213); | |
729 mm_data->t3213_restart = 0; | |
730 | |
731 /* T3230 stopped on reception of CM_SERV_REJ or CM_SERV_ACC */ | |
732 TIMERSTOP (T3230); | |
733 | |
734 mm_data->rej_cause = CAUSE_MAKE (DEFBY_STD, | |
735 ORIGSIDE_NET, | |
736 MM_CAUSE, | |
737 cm_serv_rej->rej_cause); | |
738 switch (mm_data->rej_cause) | |
739 { | |
740 case MMCS_IMSI_IN_VLR: | |
741 /* | |
742 * CM SERVICE REJECT by the network, cause #4: For some | |
743 * reason the IMSI is not attached in the VLR. This may happen | |
744 * if there was a failure in the VLR's database. | |
745 * This is expected to happen seldom. | |
746 * GSM 11.10 subclause 26.7.5.5 doesn't expect that a call is saved | |
747 * and established is performed later in this condition. | |
748 * Choosing this | |
749 * implementation option complicates the protocol here too much. | |
750 * (danger of introducing bugs, especially if GPRS is also present) | |
751 * The next thing to do is a NORMAL UPDATE. | |
752 */ | |
753 | |
754 /* | |
755 * If cause value #4 is received, the mobile station aborts any | |
756 * MM connection, deletes any TMSI, LAI and ciphering key | |
757 * sequence number in the SIM, changes the update status to | |
758 * NOT UPDATED (and stores it in the SIM according to section | |
759 * 4.1.2.2), and enters the MM sublayer state WAIT FOR NETWORK | |
760 * COMMAND. If subsequently the RR connection is released or | |
761 * aborted, this will force the mobile station to initiate a | |
762 * normal location updating). Whether the CM request shall be | |
763 * memorized during the location updating procedure, is a | |
764 * choice of implementation. | |
765 * [GSM 04.08 subclause 4.5.1.1] | |
766 */ | |
767 | |
768 /* Indicate connection release to CM */ | |
769 mm_mmxx_rel_ind (mm_data->rej_cause, CM_NOT_IDLE); | |
770 | |
771 /* Invalidate update state and synchronize SIM */ | |
772 #ifdef REL99 | |
773 reg_invalidate_upd_state (MS_NOT_UPDATED, FALSE); | |
774 #else | |
775 reg_invalidate_upd_state (MS_NOT_UPDATED); | |
776 #endif | |
777 | |
778 /* Invalidate TMSI in RR and lower layers */ | |
779 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL); | |
780 | |
781 /* | |
782 * Ensure that the conditions are set in a way that after release | |
783 * of the RR connection a normal update will be performed. | |
784 */ | |
785 mm_data->attempt_cnt = 0; | |
786 mm_data->loc_upd_type.lut = NORMAL_LUP; | |
787 | |
788 /* Await network release in state MM_WAIT_FOR_NW_CMD */ | |
789 TIMERSTART (T3240, T_3240_VALUE); | |
790 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD); | |
791 break; | |
792 | |
793 case MMCS_ILLEGAL_ME: | |
794 /* | |
795 * If cause value #6 is received, the mobile station aborts any | |
796 * MM connection, deletes any TMSI, LAI and ciphering key sequence | |
797 * number in the SIM, changes the update status to ROAMING NOT | |
798 * ALLOWED (and stores it in the SIM according to section | |
799 * 4.1.2.2), and enters the MM sublayer state WAIT FOR NETWORK | |
800 * COMMAND. The mobile station shall consider the SIM as invalid | |
801 * until switch-off or the SIM is removed. | |
802 * [GSM 04.08 subclause 4.5.1.1] | |
803 */ | |
804 | |
805 /* Indicate connection release to CM */ | |
806 mm_mmxx_rel_ind (mm_data->rej_cause, CM_PENDING); | |
807 | |
808 /* Invalidate update state and synchronize SIM */ | |
809 #ifdef REL99 | |
810 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED, FALSE); | |
811 #else | |
812 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED); | |
813 #endif | |
814 | |
815 /* Delete IMSI - consider SIM as invalid */ | |
816 mm_clear_mob_ident (&mm_data->reg.imsi_struct); | |
817 mm_clear_reg_data (); | |
818 | |
819 /* Inform RR about loss of registration until power cycle */ | |
820 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL_NO_PAG); | |
821 | |
822 /* Remember limited service cause for MMI information */ | |
823 mm_data->limited_cause = mm_data->rej_cause; | |
824 | |
825 // Debug patch >>> | |
826 if (mm_data->mm_idle_no_imsi_marker EQ 0) | |
827 mm_data->mm_idle_no_imsi_marker = 6; | |
828 // Debug patch <<< | |
829 | |
830 TIMERSTART (T3240, T_3240_VALUE); | |
831 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD); | |
832 break; | |
833 | |
834 default: | |
835 /* | |
836 * Pending connections are only expected | |
837 * in state MM_CONN_ACTIVE if mm_data->wait_for_accept. | |
838 */ | |
839 mm_data->wait_for_accept = FALSE; | |
840 if ((GET_STATE (STATE_MM) EQ MM_CONN_ACTIVE) AND | |
841 (mm_count_connections (CM_ACTIVE) EQ 0)) | |
842 { | |
843 /* | |
844 * Special clash case. | |
845 * Seen in field for the SMS protocol when test engineers are | |
846 * sending SMS like crazy to themselfes, using scripts. | |
847 * For the CC protocol the following scenario is probably to | |
848 * happen, for SMS this must be something analogous: | |
849 * The MS sent the RELEASE message via the air interface to | |
850 * the network. The MSC receives this RELEASE message and | |
851 * sends the RELEASE_COMPLETE to the MS via the BSS and the | |
852 * CLEAR COMMAND message to the BSC in one single transaction. | |
853 * Now we have a pending clearance of the assigned radio | |
854 * resources. For details see "GSM Signalisierung", page 246. | |
855 * If there is in this situation a CM SERVICE REQUEST is | |
856 * received at the MSC this cannot be accepted as the | |
857 * clearance of the assigned radio resources are underway, | |
858 * so the MSC answers with a CM_SERVICE_REJECT. | |
859 * The only thing which can be done here is to repeat the | |
860 * CM_SERVICE_REQ besides the specification after entering | |
861 * IDLE stateto make the protocol bullet proof. | |
862 */ | |
863 TRACE_EVENT ("CM_SERV_REQ clashed with CLR_CMD"); | |
864 mm_write_entry (mm_data->pend_conn.comp, | |
865 mm_data->pend_conn.ti, | |
866 mm_data->pend_conn.cause, | |
867 EVENT_ENTRY, | |
868 NULL, | |
869 UNSPEC); | |
870 #if defined (FF_EOTD) AND defined (REL99) | |
871 /* | |
872 * If there is no MM connection & rrlp is started, start the | |
873 * timer3241 and move MM to state MM_RR_CONN_RELEASE_NOT_ALLOWED | |
874 */ | |
875 if(mm_data->rrlp_lcs_started EQ TRUE) | |
876 { | |
877 TIMERSTART(T3241,T_3241_VALUE); | |
878 SET_STATE(STATE_MM, MM_RR_CONN_RELEASE_NOT_ALLOWED); | |
879 } | |
880 else | |
881 #endif /* (FF_EOTD) AND defined (REL99) */ | |
882 { | |
883 TIMERSTART (T3240, T_3240_VALUE); | |
884 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD); | |
885 } | |
886 } | |
887 else | |
888 { | |
889 /* | |
890 * Handle the CM_SERVICE_REJECT as specified in | |
891 * [GSM 04.08 subclause 4.5.1.1] | |
892 */ | |
893 mm_mmxx_rel_ind (mm_data->rej_cause, CM_PENDING); | |
894 if (mm_count_connections (CM_ACTIVE) EQ 0) | |
895 { | |
896 #if defined (FF_EOTD) AND defined (REL99) | |
897 /* | |
898 * If there is no MM connection & rrlp is started, start the | |
899 * timer3241 and move MM to state MM_RR_CONN_RELEASE_NOT_ALLOWED | |
900 */ | |
901 if(mm_data->rrlp_lcs_started EQ TRUE) | |
902 { | |
903 TIMERSTART(T3241,T_3241_VALUE); | |
904 SET_STATE(STATE_MM, MM_RR_CONN_RELEASE_NOT_ALLOWED); | |
905 } | |
906 else | |
907 #endif /* (FF_EOTD) AND defined (REL99) */ | |
908 { | |
909 TIMERSTART (T3240, T_3240_VALUE); | |
910 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD); | |
911 } | |
912 } | |
913 USE_STORED_ENTRIES(); | |
914 } | |
915 break; | |
916 } | |
917 | |
918 EM_CM_SERVICE_REJECT; | |
919 | |
920 break; | |
921 | |
922 case MM_LUP_REJECTED: | |
923 #ifdef REL99 | |
924 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
925 #endif | |
926 case MM_LUP_INITIATED: | |
927 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
928 break; | |
929 | |
930 default: | |
931 break; | |
932 } | |
933 } | |
934 | |
935 /* | |
936 +--------------------------------------------------------------------+ | |
937 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
938 | STATE : code ROUTINE : mm_ident_req | | |
939 +--------------------------------------------------------------------+ | |
940 | |
941 PURPOSE : Process the signal IDENT_REQ. | |
942 | |
943 */ | |
944 | |
945 GLOBAL void mm_ident_req (T_D_IDENT_REQ *ident_req) | |
946 { | |
947 GET_INSTANCE_DATA; | |
948 TRACE_FUNCTION ("mm_ident_req()"); | |
949 | |
950 /* Message processing starts with semantical checks now */ | |
951 if (!for_check_identity_type (MSG(D_IDENT_REQ)->ident.ident_type)) | |
952 { | |
953 mm_for_set_error (RC_INVALID_MAND_MESSAGE); | |
954 return; | |
955 } | |
956 | |
957 | |
958 switch (GET_STATE (STATE_MM)) | |
959 { | |
960 case MM_LUP_INITIATED: | |
961 case MM_WAIT_FOR_OUTG_MM_CONN: | |
962 case MM_CONN_ACTIVE: | |
963 case MM_PROCESS_PROMPT: | |
964 case MM_WAIT_FOR_NW_CMD: | |
965 #ifdef REL99 | |
966 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
967 #endif | |
968 { | |
969 MCAST (ident_res, U_IDENT_RES); /* T_U_IDENT_RES */ | |
970 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE) | |
971 { | |
972 /* | |
973 * T3212 is stopped if the first MM message is received, or | |
974 * ciphering mode setting is completed in the case of MM | |
975 * connection establishment, except when the most recent service | |
976 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2] | |
977 */ | |
978 TIMERSTOP (T3212); | |
979 mm_data->t3212_timeout = FALSE; | |
980 } | |
981 | |
982 TIMERSTOP (T3211); | |
983 TIMERSTOP (T3213); | |
984 mm_data->t3213_restart = 0; | |
985 mm_build_ident_res (ident_req->ident.ident_type, ident_res); | |
986 for_data_req (BSIZE_U_IDENT_RES); | |
987 | |
988 EM_IDENTITY_REQUEST_RESPONSE; | |
989 | |
990 if (TIMERACTIVE(T3240)) | |
991 { | |
992 TIMERSTOP (T3240); | |
993 TIMERSTART (T3240, T_3240_VALUE); | |
994 } | |
995 } | |
996 break; | |
997 | |
998 case MM_LUP_REJECTED: | |
999 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
1000 break; | |
1001 | |
1002 default: | |
1003 | |
1004 break; | |
1005 } | |
1006 } | |
1007 | |
1008 /* | |
1009 +--------------------------------------------------------------------+ | |
1010 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
1011 | STATE : code ROUTINE : mm_loc_upd_acc | | |
1012 +--------------------------------------------------------------------+ | |
1013 | |
1014 PURPOSE : Process the signal LOC_UPD_ACC. | |
1015 | |
1016 */ | |
1017 | |
1018 GLOBAL void mm_loc_upd_acc (T_D_LOC_UPD_ACCEPT *loc_upd_accept) | |
1019 { | |
1020 GET_INSTANCE_DATA; | |
1021 TRACE_FUNCTION ("mm_loc_upd_acc()"); | |
1022 | |
1023 /* Semantical checks and preprocessing */ | |
1024 if (loc_upd_accept->loc_area_ident.c_mnc EQ 2) | |
1025 { | |
1026 loc_upd_accept->loc_area_ident.mnc[2] = 0xf; | |
1027 } | |
1028 | |
1029 switch (GET_STATE (STATE_MM)) | |
1030 { | |
1031 case MM_LUP_INITIATED: | |
1032 TRACE_EVENT ("*** LUP ACCEPTED ***"); | |
1033 | |
1034 #ifdef WIN32 | |
1035 | |
1036 /* | |
1037 * Check whether the simulation testcases send the | |
1038 * LOCATION UPDATING ACCEPT message for the location area | |
1039 * of the cell where the mobile currently is camped on. | |
1040 * Receiving a non appropritate location area in the LOCATION | |
1041 * UPDATING ACCEPT message in the simulation environment | |
1042 * is probably a bug in the simulation testcase. | |
1043 */ | |
1044 vsi_o_ttrace (VSI_CALLER TC_FUNC, | |
1045 " ACC: MCC=%x%x%x MNC=%x%x%x LAC=%04x", | |
1046 loc_upd_accept->loc_area_ident.mcc[0], | |
1047 loc_upd_accept->loc_area_ident.mcc[1], | |
1048 loc_upd_accept->loc_area_ident.mcc[2], | |
1049 loc_upd_accept->loc_area_ident.mnc[0], | |
1050 loc_upd_accept->loc_area_ident.mnc[1], | |
1051 loc_upd_accept->loc_area_ident.mnc[2], | |
1052 loc_upd_accept->loc_area_ident.lac); | |
1053 | |
1054 assert (mm_check_lai (&loc_upd_accept->loc_area_ident, | |
1055 &mm_data->mm.lai)); | |
1056 | |
1057 #endif /* #ifdef WIN32 */ | |
1058 | |
1059 /* | |
1060 * T3212 is stopped if a LOCATION UPDATING ACCEPT or | |
1061 * LOCATION UPDATING REJECT message is received. | |
1062 * [GSM 04.08 subclause 4.4.2] | |
1063 */ | |
1064 TIMERSTOP (T3212); | |
1065 mm_data->t3212_timeout = FALSE; | |
1066 | |
1067 TIMERSTOP (T3210); | |
1068 mm_data->reg.update_stat = MS_UPDATED; | |
1069 mm_data->rej_cause = 0; | |
1070 mm_data->attempt_cnt = 0; | |
1071 if (loc_upd_accept->v_mob_id NEQ 0) | |
1072 { | |
1073 switch (loc_upd_accept->mob_id.ident_type) | |
1074 { | |
1075 case TYPE_TMSI: | |
1076 { | |
1077 MCAST (tmsi_realloc_comp, U_TMSI_REALLOC_COMP); | |
1078 | |
1079 /* No IMSI ATTACH neccessary anymore */ | |
1080 if (mm_data->first_attach) | |
1081 { | |
1082 mm_data->first_attach_mem = mm_data->first_attach; | |
1083 mm_data->first_attach = FALSE; | |
1084 } | |
1085 | |
1086 /* No running location updating procedure anymore */ | |
1087 mm_data->loc_upd_type.lut = NOT_RUNNING; | |
1088 | |
1089 /* Save TMSI in MM registration data */ | |
1090 mm_store_tmsi (&loc_upd_accept->mob_id); | |
1091 | |
1092 /* Send RR_DATA_REQ (TMSI_REALLOC_COMPLETE) */ | |
1093 tmsi_realloc_comp->msg_type = U_TMSI_REALLOC_COMP; | |
1094 for_data_req (BSIZE_U_TMSI_REALLOC_COMP); | |
1095 | |
1096 EM_LOCATION_UPDATING; | |
1097 | |
1098 /* Structure copy */ | |
1099 mm_data->reg.lai = loc_upd_accept->loc_area_ident; | |
1100 | |
1101 /* | |
1102 * We assume the network has updated us for the currently | |
1103 * selected cell, otherwise we will run into trouble. | |
1104 */ | |
1105 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai)); | |
1106 | |
1107 /* Send RR_SYNC_REQ */ | |
1108 mm_build_rr_sync_req_tmsi (); | |
1109 | |
1110 /* Send RR_SYNC_REQ (Location Area allowed) */ | |
1111 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW); | |
1112 | |
1113 EM_TMSI_REALLOCATION_COMPLETE; | |
1114 | |
1115 break; | |
1116 } | |
1117 case TYPE_IMSI: | |
1118 { | |
1119 /* No IMSI ATTACH neccessary anymore */ | |
1120 if (mm_data->first_attach) | |
1121 { | |
1122 mm_data->first_attach_mem = mm_data->first_attach; | |
1123 mm_data->first_attach = FALSE; | |
1124 } | |
1125 | |
1126 /* No running location updating procedure anymore */ | |
1127 mm_data->loc_upd_type.lut = NOT_RUNNING; | |
1128 | |
1129 mm_data->reg.tmsi = TMSI_INVALID_VALUE; | |
1130 mm_build_rr_sync_req_cause (SYNCCS_TMSI_INVAL); | |
1131 | |
1132 /* Structure copy */ | |
1133 mm_data->reg.lai = loc_upd_accept->loc_area_ident; | |
1134 | |
1135 /* | |
1136 * We assume the network has updated us for the currently | |
1137 * selected cell, otherwise we will run into trouble. | |
1138 */ | |
1139 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai)); | |
1140 | |
1141 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW); | |
1142 | |
1143 EM_LOCATION_UPDATING; | |
1144 | |
1145 break; | |
1146 } | |
1147 case 2: /*TYPE_IMEI:*/ | |
1148 { | |
1149 /* Implements Measure 29 and streamline encoding */ | |
1150 mm_send_status(RC_INCORRECT_MESSAGE); | |
1151 /* Implementation problem: This should be handled like | |
1152 LOCATION UPDATING REJECT received with cause NETWORK FAILURE. | |
1153 The same may be true for all negative asserts in the field | |
1154 in the whole function */ | |
1155 break; | |
1156 } | |
1157 default: | |
1158 /* No IMSI ATTACH neccessary anymore */ | |
1159 if (mm_data->first_attach) | |
1160 { | |
1161 mm_data->first_attach_mem = mm_data->first_attach; | |
1162 mm_data->first_attach = FALSE; | |
1163 } | |
1164 | |
1165 /* No running location updating procedure anymore */ | |
1166 mm_data->loc_upd_type.lut = NOT_RUNNING; | |
1167 | |
1168 /* Structure copy */ | |
1169 mm_data->reg.lai = loc_upd_accept->loc_area_ident; | |
1170 | |
1171 /* | |
1172 * We assume the network has updated us for the currently | |
1173 * selected cell, otherwise we will run into trouble. | |
1174 */ | |
1175 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai)); | |
1176 | |
1177 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW); | |
1178 break; | |
1179 } | |
1180 } | |
1181 else | |
1182 { | |
1183 /* | |
1184 * Location updating accept without mobile ID, keep old TMSI | |
1185 * stored in MM data structures. | |
1186 */ | |
1187 | |
1188 /* No IMSI ATTACH neccessary anymore */ | |
1189 if (mm_data->first_attach) | |
1190 { | |
1191 mm_data->first_attach_mem = mm_data->first_attach; | |
1192 mm_data->first_attach = FALSE; | |
1193 } | |
1194 | |
1195 /* No running location updating procedure anymore */ | |
1196 mm_data->loc_upd_type.lut = NOT_RUNNING; | |
1197 | |
1198 /* Structure copy */ | |
1199 mm_data->reg.lai = loc_upd_accept->loc_area_ident; | |
1200 | |
1201 /* | |
1202 * We assume the network has updated us for the currently | |
1203 * selected cell, otherwise we will run into trouble. | |
1204 */ | |
1205 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai)); | |
1206 | |
1207 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW); | |
1208 } | |
1209 | |
1210 /* remove from forbidden PLMN list if stored */ | |
1211 reg_plmn_bad_del (mm_data->reg.forb_plmn, | |
1212 MAX_FORB_PLMN_ID, | |
1213 &mm_data->reg.actual_plmn); | |
1214 | |
1215 | |
1216 /* Store equivalent PLMNs (if received) */ | |
1217 if (loc_upd_accept->v_eqv_plmn_list NEQ 0) | |
1218 { | |
1219 if(reg_store_eqv_plmns(&loc_upd_accept->eqv_plmn_list, &mm_data->reg.actual_plmn)) | |
1220 mm_build_rr_sync_req_cause (SYNCCS_EPLMN_LIST); | |
1221 } | |
1222 | |
1223 /* Copy actual BCCH data before SIM update */ | |
1224 memcpy (mm_data->reg.bcch, mm_data->mm.bcch, SIZE_BCCH); | |
1225 | |
1226 /* Indicate successfull end of registration to GMM/MMI */ | |
1227 #ifdef GPRS | |
1228 if (!mm_gsm_alone()) | |
1229 mm_data->gprs.reg_cnf_on_idle_entry = TRUE; | |
1230 #endif | |
1231 /* Inform MMI about full service condition (with side effects) */ | |
1232 reg_mm_success (FULL_SERVICE); | |
1233 | |
1234 /* Update all EFs on SIM */ | |
1235 mm_data->ef_indicator = 0xFF; | |
1236 /* Update SIM */ | |
1237 reg_build_sim_update (); | |
1238 /* added by TISH 0418 to write simloci to FFS */ | |
1239 mm_write_simloci_to_ffs(); | |
1240 mm_write_imsi_to_ffs(); | |
1241 /* added by TISH 0418 to write simloci to FFS */ | |
1242 | |
1243 #if defined (WIN32) | |
1244 { | |
1245 TRACE_EVENT_P1 ("Follow On decoded = %d", loc_upd_accept->v_follow_proceed); | |
1246 } | |
1247 #endif /* #if defined (WIN32) */ | |
1248 | |
1249 | |
1250 if (loc_upd_accept->v_follow_proceed NEQ 0 AND | |
1251 mm_set_follow_on_request()) | |
1252 { | |
1253 SET_STATE (STATE_MM, MM_CONN_ACTIVE); | |
1254 mm_data->loc_upd_type.follow = FOR_PENDING_NO; | |
1255 mm_data->wait_for_accept = FALSE; | |
1256 TIMERSTART (T3230, T_3230_VALUE); | |
1257 TRACE_FUNCTION ("mm_loc_upd_acc () follow on - use_entry"); | |
1258 USE_STORED_ENTRIES(); | |
1259 } | |
1260 else | |
1261 { | |
1262 mm_data->loc_upd_type.follow = FOR_PENDING_NO; | |
1263 /* PATCH LE 02.12.99 | |
1264 * | |
1265 * Don't stop connection if not follow on proceed | |
1266 * | |
1267 * mm_mmxx_rel_ind (RELCS_UNSPECIFIED, CM_PENDING); | |
1268 * mm_mmxx_rel_ind (RELCS_UNSPECIFIED, CM_NOT_IDLE); | |
1269 * | |
1270 * END PATCH LE 02.12.99 | |
1271 */ | |
1272 TIMERSTART (T3240, T_3240_VALUE); | |
1273 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD); | |
1274 } | |
1275 break; | |
1276 case MM_WAIT_FOR_OUTG_MM_CONN: | |
1277 case MM_CONN_ACTIVE: | |
1278 case MM_PROCESS_PROMPT: | |
1279 case MM_WAIT_FOR_NW_CMD: | |
1280 case MM_LUP_REJECTED: | |
1281 #ifdef REL99 | |
1282 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
1283 #endif | |
1284 { | |
1285 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
1286 break; | |
1287 } | |
1288 default: | |
1289 break; | |
1290 } | |
1291 } | |
1292 | |
1293 /* | |
1294 +--------------------------------------------------------------------+ | |
1295 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
1296 | STATE : code ROUTINE : mm_lup_rej | | |
1297 +--------------------------------------------------------------------+ | |
1298 | |
1299 PURPOSE : Process the signal LUP_REJ. Here the reject cause is a well | |
1300 defined MM cause and no garbage. Even if the network sent | |
1301 garbage, here this has already been corrected. | |
1302 | |
1303 */ | |
1304 | |
1305 GLOBAL void mm_lup_rej (T_D_LOC_UPD_REJ *loc_upd_rej) | |
1306 { | |
1307 GET_INSTANCE_DATA; | |
1308 TRACE_FUNCTION ("mm_lup_rej()"); | |
1309 | |
1310 /* Semantical checks and preprocessing */ | |
1311 loc_upd_rej->rej_cause = for_check_reject_cause (loc_upd_rej->rej_cause); | |
1312 | |
1313 // Variable solely used for debugging purposes | |
1314 mm_data->debug_last_rej_cause = loc_upd_rej->rej_cause; | |
1315 | |
1316 /* Remember cause value for MMI information */ | |
1317 mm_data->limited_cause = CAUSE_MAKE (DEFBY_STD, | |
1318 ORIGSIDE_NET, | |
1319 MM_CAUSE, | |
1320 loc_upd_rej->rej_cause); | |
1321 | |
1322 EM_LOCATION_UPDATING_REJECT; | |
1323 | |
1324 switch (GET_STATE (STATE_MM)) | |
1325 { | |
1326 case MM_LUP_INITIATED: | |
1327 /* | |
1328 * T3212 is stopped if a LOCATION UPDATING ACCEPT or | |
1329 * LOCATION UPDATING REJECT message is received. | |
1330 * [GSM 04.08 subclause 4.4.2] | |
1331 */ | |
1332 TIMERSTOP (T3212); | |
1333 mm_data->t3212_timeout = FALSE; | |
1334 | |
1335 TIMERSTOP (T3210); | |
1336 | |
1337 mm_data->rej_cause = CAUSE_MAKE (DEFBY_STD, | |
1338 ORIGSIDE_NET, | |
1339 MM_CAUSE, | |
1340 loc_upd_rej->rej_cause); | |
1341 | |
1342 TIMERSTART (T3240, T_3240_VALUE); | |
1343 SET_STATE (STATE_MM, MM_LUP_REJECTED); | |
1344 break; | |
1345 | |
1346 case MM_WAIT_FOR_OUTG_MM_CONN: | |
1347 case MM_CONN_ACTIVE: | |
1348 case MM_PROCESS_PROMPT: | |
1349 case MM_WAIT_FOR_NW_CMD: | |
1350 case MM_LUP_REJECTED: | |
1351 #ifdef REL99 | |
1352 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
1353 #endif | |
1354 { | |
1355 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
1356 break; | |
1357 } | |
1358 default: | |
1359 break; | |
1360 } | |
1361 } | |
1362 | |
1363 /* | |
1364 +--------------------------------------------------------------------+ | |
1365 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
1366 | STATE : code ROUTINE : mm_mm_status | | |
1367 +--------------------------------------------------------------------+ | |
1368 | |
1369 PURPOSE : Process the signal MM_STATUS. | |
1370 | |
1371 */ | |
1372 | |
1373 GLOBAL void mm_mm_status (void) | |
1374 { | |
1375 GET_INSTANCE_DATA; | |
1376 TRACE_FUNCTION ("mm_mm_status()"); | |
1377 /* Semantical checks and preprocessing */ | |
1378 /* MSG(B_MM_STATUS)->rej_cause = for_check_reject_cause (MSG(B_MM_STATUS)->rej_cause); nobody cares */ | |
1379 | |
1380 switch (GET_STATE (STATE_MM)) | |
1381 { | |
1382 case MM_LUP_INITIATED: | |
1383 case MM_WAIT_FOR_OUTG_MM_CONN: | |
1384 case MM_CONN_ACTIVE: | |
1385 case MM_PROCESS_PROMPT: | |
1386 case MM_WAIT_FOR_NW_CMD: | |
1387 case MM_LUP_REJECTED: | |
1388 #ifdef REL99 | |
1389 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
1390 #endif | |
1391 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE) | |
1392 { | |
1393 /* | |
1394 * T3212 is stopped if the first MM message is received, or | |
1395 * ciphering mode setting is completed in the case of MM | |
1396 * connection establishment, except when the most recent service | |
1397 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2] | |
1398 */ | |
1399 TIMERSTOP (T3212); | |
1400 mm_data->t3212_timeout = FALSE; | |
1401 } | |
1402 | |
1403 if (TIMERACTIVE(T3240)) | |
1404 { | |
1405 TIMERSTOP (T3240); | |
1406 TIMERSTART (T3240, T_3240_VALUE); | |
1407 } | |
1408 break; | |
1409 | |
1410 default: | |
1411 break; | |
1412 } | |
1413 } | |
1414 | |
1415 /* | |
1416 +--------------------------------------------------------------------+ | |
1417 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
1418 | STATE : code ROUTINE : mm_mmr_auth_cnf | | |
1419 +--------------------------------------------------------------------+ | |
1420 | |
1421 PURPOSE : Process the signal MMR_AUTH_CNF. | |
1422 | |
1423 */ | |
1424 | |
1425 GLOBAL void mm_mmr_auth_cnf (T_SIM_AUTHENTICATION_CNF *sim_auth_cnf) | |
1426 { | |
1427 GET_INSTANCE_DATA; | |
1428 TRACE_FUNCTION ("mm_mmr_auth_cnf()"); | |
1429 | |
1430 /* Handle the response only if it is for the last sent SIM_AUTHENTICATION_REQ */ | |
1431 if (mm_data->last_auth_req_id EQ sim_auth_cnf->req_id) | |
1432 { | |
1433 switch (GET_STATE (STATE_MM)) | |
1434 { | |
1435 case MM_LUP_INITIATED: | |
1436 case MM_WAIT_FOR_OUTG_MM_CONN: | |
1437 case MM_CONN_ACTIVE: | |
1438 case MM_PROCESS_PROMPT: | |
1439 case MM_WAIT_FOR_NW_CMD: | |
1440 #ifdef REL99 | |
1441 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
1442 #endif | |
1443 { | |
1444 MCAST (auth_res, U_AUTH_RES); | |
1445 if(memcmp(mm_data->reg.kc, sim_auth_cnf->kc, MAX_KC)) | |
1446 { | |
1447 /* Set bit 4 in ef_indicator to indicate kc change to SIM for next SIM_MM_UPDATE_REQ */ | |
1448 mm_data->ef_indicator|=(0x01 << 3); | |
1449 } | |
1450 memcpy (mm_data->reg.kc, sim_auth_cnf->kc, MAX_KC); | |
1451 mm_build_auth_res (sim_auth_cnf, auth_res); | |
1452 for_data_req (BSIZE_U_AUTH_RES); | |
1453 mm_build_rr_sync_req(MSG_MM_CIPH); | |
1454 if (TIMERACTIVE(T3240)) | |
1455 { | |
1456 TIMERSTOP (T3240); | |
1457 TIMERSTART (T3240, T_3240_VALUE); | |
1458 } | |
1459 | |
1460 EM_AUTHENTICATION(EM_RESPONSE); | |
1461 | |
1462 } | |
1463 break; | |
1464 | |
1465 default: | |
1466 break; | |
1467 } | |
1468 /* Reset the variable since there are no more auth_rsp expected from SIM */ | |
1469 mm_data->last_auth_req_id = NOT_PRESENT_8BIT; | |
1470 } | |
1471 PFREE (sim_auth_cnf); | |
1472 } | |
1473 | |
1474 | |
1475 /* | |
1476 +--------------------------------------------------------------------+ | |
1477 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
1478 | STATE : code ROUTINE : mm_mmr_nreg_req | | |
1479 +--------------------------------------------------------------------+ | |
1480 | |
1481 PURPOSE : Process the signal MMR_NREG_REQ. | |
1482 The cause for the deregistration attempt may be | |
1483 CS_SIM_REM, CS_POW_OFF or CS_SOFT_OFF. | |
1484 | |
1485 */ | |
1486 | |
1487 GLOBAL void mm_mmr_nreg_req (UBYTE nreg_cause, | |
1488 UBYTE detach_done) | |
1489 { | |
1490 GET_INSTANCE_DATA; | |
1491 TRACE_FUNCTION ("mm_mmr_nreg_req()"); | |
1492 | |
1493 switch (GET_STATE (STATE_MM)) | |
1494 { | |
1495 case MM_NULL: | |
1496 /* No DL is active */ | |
1497 switch (nreg_cause) | |
1498 { | |
1499 case CS_POW_OFF: | |
1500 case CS_SOFT_OFF: | |
1501 mm_write_eplmn_to_ffs(); | |
1502 reg_end_of_deregistration (nreg_cause, NO_SERVICE); | |
1503 break; | |
1504 | |
1505 case CS_SIM_REM: | |
1506 mm_write_eplmn_to_ffs(); | |
1507 mm_clear_reg_data (); | |
1508 reg_end_of_deregistration (nreg_cause, NO_SERVICE); | |
1509 break; | |
1510 | |
1511 #ifdef GPRS | |
1512 case CS_DISABLE: /* Remote controlled IMSI DETACH */ | |
1513 mm_mmgmm_nreg_cnf (nreg_cause); | |
1514 break; | |
1515 #endif /* GPRS */ | |
1516 | |
1517 default: | |
1518 TRACE_ERROR (UNEXPECTED_PARAMETER); | |
1519 break; | |
1520 } | |
1521 break; | |
1522 | |
1523 case MM_LUP_INITIATED: | |
1524 case MM_LUP_REJECTED: | |
1525 /* | |
1526 * We do not know the answer to the running location updating procedure. | |
1527 * Therefore the update state is set to MS_NOT_UPDATED here, | |
1528 * so MM is on the safe side if assuming it is not updated anymore. | |
1529 * This also leads to the situation that in this | |
1530 * states an IMSI DETACH will not be performed, but this is ok | |
1531 * according to GSM 04.08 subclause 4.3.4.1: | |
1532 * "The IMSI detach procedure may not be started if a MM specific | |
1533 * procedure is active. If possible, the IMSI detach procedure is | |
1534 * then delayed until the MM specific procedure is finished, else | |
1535 * the IMSI detach is omitted." | |
1536 */ | |
1537 mm_build_rr_sync_req_cause (SYNCCS_TMSI_INVAL); | |
1538 #ifdef REL99 | |
1539 reg_invalidate_upd_state (MS_NOT_UPDATED, FALSE); | |
1540 #else | |
1541 reg_invalidate_upd_state (MS_NOT_UPDATED); | |
1542 #endif | |
1543 /*FALLTHROUGH*/ | |
1544 //lint -fallthrough | |
1545 case MM_WAIT_FOR_OUTG_MM_CONN: | |
1546 case MM_CONN_ACTIVE: | |
1547 case MM_PROCESS_PROMPT: | |
1548 case MM_WAIT_FOR_NW_CMD: | |
1549 #ifdef REL99 | |
1550 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
1551 #endif | |
1552 if (mm_data->mm.mm_info.att EQ ATT_ALLOW AND | |
1553 mm_data->reg.update_stat EQ MS_UPDATED AND | |
1554 detach_done EQ MMGMM_PERFORM_DETACH) | |
1555 { | |
1556 mm_mmxx_rel_ind (MMCS_NO_REGISTRATION, CM_NOT_IDLE); | |
1557 | |
1558 TIMERSTOP (T3210); | |
1559 TIMERSTOP (T3211); | |
1560 | |
1561 /* | |
1562 * The timer T3212 is stopped if the mobile station is deactivated | |
1563 * (i.e. equipment powered down or SIM removed. | |
1564 */ | |
1565 TIMERSTOP (T3212); | |
1566 mm_data->t3212_timeout = FALSE; | |
1567 | |
1568 TIMERSTOP (T3213); | |
1569 mm_data->t3213_restart = 0; | |
1570 TIMERSTOP (T3230); | |
1571 TIMERSTOP (T3240); | |
1572 #ifdef REL99 | |
1573 TIMERSTOP (T3241); | |
1574 #endif | |
1575 | |
1576 /* | |
1577 * Start IMSI Detach procedure | |
1578 */ | |
1579 if (mm_normal_upd_needed() OR | |
1580 mm_data->idle_substate EQ MM_IDLE_LIMITED_SERVICE) | |
1581 { | |
1582 TRACE_EVENT ("IMSI DETACH questionable"); | |
1583 } | |
1584 mm_data->nreg_cause = nreg_cause; | |
1585 mm_create_imsi_detach_message (); | |
1586 for_data_req (BSIZE_U_IMSI_DETACH_IND); | |
1587 TIMERSTART (T3220, T_3220_VALUE); | |
1588 SET_STATE (STATE_MM, MM_IMSI_DETACH_INIT); | |
1589 break; | |
1590 } | |
1591 /*FALLTHROUGH*/ | |
1592 //lint -fallthrough | |
1593 case MM_WAIT_FOR_RR_CONN_LUP: | |
1594 case MM_WAIT_FOR_RR_CONN_MM: | |
1595 case MM_WAIT_FOR_REESTABLISH: | |
1596 /* | |
1597 * No IMSI Detach procedure. | |
1598 * See also comment for state MM_WAIT_FOR_RR_ACTIVE. | |
1599 */ | |
1600 mm_mmxx_rel_ind (MMCS_NO_REGISTRATION, CM_NOT_IDLE); | |
1601 | |
1602 TIMERSTOP (T3210); | |
1603 TIMERSTOP (T3211); | |
1604 | |
1605 /* | |
1606 * The timer T3212 is stopped if the mobile station is deactivated | |
1607 * (i.e. equipment powered down or SIM removed. | |
1608 */ | |
1609 TIMERSTOP (T3212); | |
1610 mm_data->t3212_timeout = FALSE; | |
1611 | |
1612 TIMERSTOP (T3213); | |
1613 mm_data->t3213_restart = 0; | |
1614 TIMERSTOP (T3230); | |
1615 TIMERSTOP (T3240); | |
1616 | |
1617 switch (nreg_cause) | |
1618 { | |
1619 case CS_POW_OFF: | |
1620 case CS_SOFT_OFF: | |
1621 #ifdef GPRS | |
1622 case CS_DISABLE: /* Remote controlled IMSI DETACH */ | |
1623 #endif /* GPRS */ | |
1624 mm_data->nreg_cause = nreg_cause; | |
1625 mm_abort_connection (ABCS_NORM); | |
1626 | |
1627 /* | |
1628 * Entering state MM_IMSI_DETACH_INIT is a trick. | |
1629 * We know RR will confirm the RR_ABORT_REQ by RR_RELEASE_IND, | |
1630 * and in this state the appropriate actions will be taken then. | |
1631 */ | |
1632 SET_STATE (STATE_MM, MM_IMSI_DETACH_INIT); | |
1633 break; | |
1634 | |
1635 case CS_SIM_REM: | |
1636 mm_data->nreg_cause = nreg_cause; | |
1637 mm_abort_connection (ABCS_SIM_REM); | |
1638 SET_STATE (STATE_MM, MM_IMSI_DETACH_INIT); | |
1639 break; | |
1640 | |
1641 default: | |
1642 TRACE_ERROR (UNEXPECTED_DEFAULT); | |
1643 break; | |
1644 } | |
1645 break; | |
1646 | |
1647 case MM_IMSI_DETACH_INIT: | |
1648 case MM_WAIT_FOR_RR_CONN_DETACH: | |
1649 mm_data->nreg_cause = nreg_cause; | |
1650 break; | |
1651 | |
1652 case MM_WAIT_FOR_RR_ACTIVE: /* RR is searching for a cell */ | |
1653 /* | |
1654 * GSM 04.08 subclause 4.3.4.1 requires the following: | |
1655 * "If no RR connection exists, the MM sublayer within the mobile | |
1656 * station will request the RR sublayer to establish a RR | |
1657 * connection. If establishment of the RR connection is not possible | |
1658 * because a suitable cell is not (or not yet) available then, the | |
1659 * mobile station shall try for a period of at least 5 seconds and for | |
1660 * not more than a period of 20 seconds to find a suitable cell. If a | |
1661 * suitable cell is found during this time then, the mobile station shall | |
1662 * request the RR sublayer to establish an RR connection, otherwise the | |
1663 * IMSI detach is aborted. | |
1664 * [Here the situation is that RR is searching for a cell and no cell is | |
1665 * yet available, but one may be found in a period lesser than 20 seconds | |
1666 * and according to the standard an IMSI DETACH shall be performed. | |
1667 * This MM implementation is more simple here, if still searching for a | |
1668 * cell. the IMSI detach is not done. This may not cause any harm to the | |
1669 * mobile user, however, it is a minor violation of GSM 04.08.] | |
1670 */ | |
1671 switch (nreg_cause) | |
1672 { | |
1673 case CS_POW_OFF: /* switch off mobile */ | |
1674 case CS_SOFT_OFF: | |
1675 mm_mdl_rel_req (); | |
1676 mm_power_off (); /* deactivate lower layer */ | |
1677 reg_end_of_deregistration (nreg_cause, NO_SERVICE); | |
1678 break; | |
1679 | |
1680 case CS_SIM_REM: | |
1681 mm_abort_connection (ABCS_SIM_REM); | |
1682 mm_clear_reg_data (); | |
1683 reg_end_of_deregistration (nreg_cause, NO_SERVICE); | |
1684 break; | |
1685 | |
1686 #ifdef GPRS | |
1687 case CS_DISABLE: | |
1688 /* Remember MM may have to IMSI ATTACH if reactivated */ | |
1689 mm_data->first_attach = TRUE; | |
1690 | |
1691 /* Confirm the GMM requested deregistration */ | |
1692 mm_mmgmm_nreg_cnf (nreg_cause); | |
1693 | |
1694 /* No state change */ | |
1695 break; | |
1696 #endif /* GPRS */ | |
1697 | |
1698 default: | |
1699 TRACE_ERROR (UNEXPECTED_DEFAULT); | |
1700 break; | |
1701 } | |
1702 break; | |
1703 | |
1704 #ifdef GPRS | |
1705 case MM_LOCATION_UPDATING_PENDING: | |
1706 case MM_IMSI_DETACH_PENDING: | |
1707 case MM_IDLE_LUP_NEEDED: | |
1708 #endif /* GPRS */ | |
1709 case MM_IDLE_NORMAL_SERVICE: | |
1710 case MM_IDLE_ATTEMPT_TO_UPDATE: | |
1711 TIMERSTOP (T3211); | |
1712 | |
1713 /* | |
1714 * The timer T3212 is stopped if the mobile station is deactivated | |
1715 * (i.e. equipment powered down or SIM removed. | |
1716 */ | |
1717 TIMERSTOP (T3212); | |
1718 mm_data->t3212_timeout = FALSE; | |
1719 | |
1720 TIMERSTOP (T3213); | |
1721 mm_data->t3213_restart = 0; | |
1722 | |
1723 if (mm_data->mm.mm_info.att EQ ATT_ALLOW AND | |
1724 mm_data->reg.update_stat EQ MS_UPDATED AND | |
1725 detach_done EQ MMGMM_PERFORM_DETACH) | |
1726 { | |
1727 /* Start IMSI Detach procedure */ | |
1728 | |
1729 if (mm_normal_upd_needed()) | |
1730 { | |
1731 TRACE_EVENT ("IMSI DETACH questionable"); | |
1732 } | |
1733 mm_data->nreg_cause = nreg_cause; | |
1734 mm_create_imsi_detach_message (); | |
1735 for_est_req (ESTCS_MOB_ORIG_CAL_BY_SS_SMS, BSIZE_U_IMSI_DETACH_IND); | |
1736 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_CONN_DETACH); | |
1737 break; | |
1738 } | |
1739 /* | |
1740 * No IMSI DETACH procedure | |
1741 */ | |
1742 /*FALLTHROUGH*/ | |
1743 //lint -fallthrough | |
1744 case MM_IDLE_LIMITED_SERVICE: | |
1745 case MM_IDLE_NO_IMSI: | |
1746 TIMERSTOP (T3211); | |
1747 | |
1748 /* | |
1749 * The timer T3212 is stopped if the mobile station is deactivated | |
1750 * (i.e. equipment powered down or SIM removed. | |
1751 */ | |
1752 TIMERSTOP (T3212); | |
1753 mm_data->t3212_timeout = FALSE; | |
1754 | |
1755 TIMERSTOP (T3213); | |
1756 mm_data->t3213_restart = 0; | |
1757 switch (nreg_cause) | |
1758 { | |
1759 case CS_POW_OFF: | |
1760 case CS_SOFT_OFF: | |
1761 mm_mdl_rel_req (); | |
1762 mm_power_off (); | |
1763 reg_end_of_deregistration (nreg_cause, NO_SERVICE); | |
1764 break; | |
1765 | |
1766 case CS_SIM_REM: | |
1767 mm_mdl_rel_req(); | |
1768 mm_abort_connection (ABCS_SIM_REM); | |
1769 mm_clear_reg_data (); | |
1770 // Debugging patch >>> | |
1771 if (mm_data->mm_idle_no_imsi_marker EQ 0) | |
1772 mm_data->mm_idle_no_imsi_marker = 17; | |
1773 // Debugging patch <<< | |
1774 SET_STATE (STATE_MM, MM_IDLE_NO_IMSI); | |
1775 reg_end_of_deregistration (nreg_cause, LIMITED_SERVICE); | |
1776 break; | |
1777 | |
1778 #ifdef GPRS | |
1779 case CS_DISABLE: | |
1780 /* Remember MM may have to IMSI ATTACH if reactivated */ | |
1781 mm_data->first_attach = TRUE; | |
1782 | |
1783 /* Confirm the GMM requested deregistration */ | |
1784 mm_mmgmm_nreg_cnf (nreg_cause); | |
1785 | |
1786 /* No state change */ | |
1787 break; | |
1788 #endif /* GPRS */ | |
1789 | |
1790 default: /* Not expected */ | |
1791 TRACE_ERROR (UNEXPECTED_PARAMETER); | |
1792 break; | |
1793 } | |
1794 break; | |
1795 | |
1796 case MM_IDLE_NO_CELL_AVAILABLE: | |
1797 switch (nreg_cause) | |
1798 { | |
1799 case CS_POW_OFF: | |
1800 case CS_SOFT_OFF: | |
1801 mm_mdl_rel_req (); | |
1802 mm_power_off (); | |
1803 reg_end_of_deregistration (nreg_cause, NO_SERVICE); | |
1804 break; | |
1805 | |
1806 case CS_SIM_REM: | |
1807 mm_mdl_rel_req(); | |
1808 mm_abort_connection (ABCS_SIM_REM); | |
1809 mm_clear_reg_data (); | |
1810 reg_end_of_deregistration (nreg_cause, NO_SERVICE); | |
1811 /* No state transition to MM_IDLE_NO_IMSI here, | |
1812 * as state MM_IDLE_NO_CELL_AVAILABLE has precedence. */ | |
1813 break; | |
1814 | |
1815 #ifdef GPRS | |
1816 case CS_DISABLE: | |
1817 /* Remember MM may have to IMSI ATTACH if reactivated */ | |
1818 mm_data->first_attach = TRUE; | |
1819 | |
1820 /* Confirm the GMM requested deregistration */ | |
1821 mm_mmgmm_nreg_cnf (nreg_cause); | |
1822 | |
1823 /* No state transition to MM_IDLE_NO_IMSI here, | |
1824 * as state MM_IDLE_NO_CELL_AVAILABLE has precedence. */ | |
1825 break; | |
1826 #endif /* GPRS */ | |
1827 | |
1828 default: /* Not expected */ | |
1829 TRACE_ERROR (UNEXPECTED_PARAMETER); | |
1830 break; | |
1831 } | |
1832 break; | |
1833 | |
1834 case MM_IDLE_PLMN_SEARCH: | |
1835 case MM_PLMN_SEARCH_NORMAL_SERVICE: | |
1836 /* Back to IDLE state before network search was started, | |
1837 * as deregistration will stop network search in RR. */ | |
1838 SET_STATE (STATE_MM, mm_data->idle_substate); | |
1839 | |
1840 /* Repeat the deregistration attempt in new MM state */ | |
1841 mm_mmr_nreg_req (nreg_cause, detach_done); | |
1842 return; | |
1843 | |
1844 default: /* Not expected as all states are handled implicitely */ | |
1845 TRACE_ERROR (UNEXPECTED_DEFAULT); | |
1846 break; | |
1847 } | |
1848 } | |
1849 | |
1850 /* | |
1851 +--------------------------------------------------------------------+ | |
1852 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
1853 | STATE : code ROUTINE : mm_mmr_reg_req | | |
1854 +--------------------------------------------------------------------+ | |
1855 | |
1856 PURPOSE : Process the signal MMR_REG_REQ. | |
1857 | |
1858 */ | |
1859 | |
1860 GLOBAL void mm_mmr_reg_req (UBYTE func) | |
1861 { | |
1862 GET_INSTANCE_DATA; | |
1863 TRACE_EVENT ("mm_mmr_reg_req()"); | |
1864 | |
1865 /* Check input parameter */ | |
1866 assert (func EQ FUNC_LIM_SERV_ST_SRCH OR | |
1867 func EQ FUNC_PLMN_SRCH OR | |
1868 func EQ FUNC_NET_SRCH_BY_MMI); | |
1869 | |
1870 mm_data->reg.op.v_op = V_OP_PRES; | |
1871 mm_data->reg.op.func = func; | |
1872 | |
1873 /* (Re)Start MM's watchdog timer, next state is different from MM_NULL. */ | |
1874 TIMERSTART (T_REGISTRATION, T_REG_VALUE); | |
1875 | |
1876 switch (GET_STATE (STATE_MM)) | |
1877 { | |
1878 case MM_NULL: | |
1879 case MM_IDLE_NORMAL_SERVICE: | |
1880 case MM_IDLE_ATTEMPT_TO_UPDATE: | |
1881 case MM_IDLE_LIMITED_SERVICE: | |
1882 case MM_IDLE_NO_IMSI: | |
1883 case MM_IDLE_NO_CELL_AVAILABLE: | |
1884 #ifdef GPRS | |
1885 case MM_IDLE_LUP_NEEDED: | |
1886 case MM_LOCATION_UPDATING_PENDING: | |
1887 case MM_IMSI_DETACH_PENDING: | |
1888 #endif /* GPRS */ | |
1889 if (func EQ FUNC_NET_SRCH_BY_MMI) | |
1890 mm_start_net_req (); | |
1891 else | |
1892 { | |
1893 mm_rr_act_req (); | |
1894 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_ACTIVE); | |
1895 } | |
1896 break; | |
1897 | |
1898 case MM_IDLE_PLMN_SEARCH: | |
1899 case MM_PLMN_SEARCH_NORMAL_SERVICE: | |
1900 if (func NEQ FUNC_NET_SRCH_BY_MMI) | |
1901 { | |
1902 /* Network search aborted by GMM. Inform MMI */ | |
1903 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL); | |
1904 | |
1905 mm_rr_act_req (); | |
1906 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_ACTIVE); | |
1907 } | |
1908 break; | |
1909 | |
1910 case MM_LUP_INITIATED: | |
1911 case MM_IMSI_DETACH_INIT: | |
1912 case MM_PROCESS_PROMPT: | |
1913 case MM_WAIT_FOR_NW_CMD: | |
1914 #ifdef REL99 | |
1915 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
1916 #endif | |
1917 case MM_LUP_REJECTED: | |
1918 case MM_WAIT_FOR_RR_CONN_LUP: | |
1919 case MM_WAIT_FOR_RR_CONN_DETACH: | |
1920 if (func EQ FUNC_NET_SRCH_BY_MMI) | |
1921 { | |
1922 /* | |
1923 * If the MM state is not IDLE and this is caused by an MM specific | |
1924 * procedure, we store MMI's net request until MM becomes IDLE again. | |
1925 */ | |
1926 mm_write_entry (REG_COMP, 0, 0, EVENT_ENTRY, NULL, UNSPEC); | |
1927 break; | |
1928 } | |
1929 /*FALLTHROUGH*/ | |
1930 //lint -fallthrough | |
1931 case MM_WAIT_FOR_OUTG_MM_CONN: | |
1932 case MM_CONN_ACTIVE: | |
1933 case MM_WAIT_FOR_RR_CONN_MM: | |
1934 case MM_WAIT_FOR_REESTABLISH: | |
1935 if (func EQ FUNC_NET_SRCH_BY_MMI) | |
1936 { | |
1937 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL); | |
1938 } | |
1939 else | |
1940 { | |
1941 /* func is either FUNC_LIM_SERV_ST_SRCH or FUNC_PLMN_SRCH */ | |
1942 mm_mmxx_rel_ind (MMCS_INT_NOT_PRESENT, CM_NOT_IDLE); | |
1943 mm_abort_connection (ABCS_NORM); | |
1944 if (mm_data->reg.op.sim_ins EQ SIM_INSRT) | |
1945 { | |
1946 mm_rr_act_req (); | |
1947 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_ACTIVE); | |
1948 } | |
1949 } | |
1950 break; | |
1951 | |
1952 case MM_WAIT_FOR_RR_ACTIVE: | |
1953 if (func EQ FUNC_NET_SRCH_BY_MMI) | |
1954 mm_start_net_req (); | |
1955 else | |
1956 { | |
1957 mm_rr_act_req (); | |
1958 /* State remains */ | |
1959 } | |
1960 break; | |
1961 | |
1962 default: | |
1963 /* As all states are already handled by case, this must not happen */ | |
1964 TRACE_ERROR (UNEXPECTED_DEFAULT); | |
1965 break; | |
1966 } | |
1967 } | |
1968 | |
1969 /* | |
1970 +--------------------------------------------------------------------+ | |
1971 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
1972 | STATE : code ROUTINE : mm_tmsi_realloc_cmd | | |
1973 +--------------------------------------------------------------------+ | |
1974 | |
1975 PURPOSE : Process the signal TMSI_REALLOC_CMD. | |
1976 | |
1977 */ | |
1978 | |
1979 GLOBAL void mm_tmsi_realloc_cmd (T_D_TMSI_REALLOC_CMD *tmsi_realloc_cmd) | |
1980 { | |
1981 GET_INSTANCE_DATA; | |
1982 TRACE_FUNCTION ("mm_tmsi_realloc_cmd()"); | |
1983 | |
1984 /* semantical checks and preprocessing*/ | |
1985 if (!for_check_mobile_identity (&MSG(D_TMSI_REALLOC_CMD)->mob_id)) | |
1986 { | |
1987 mm_for_set_error (RC_INVALID_MAND_MESSAGE); | |
1988 return; | |
1989 } | |
1990 | |
1991 if (tmsi_realloc_cmd->loc_area_ident.c_mnc EQ 2) | |
1992 { | |
1993 tmsi_realloc_cmd->loc_area_ident.mnc[2] = 0xf; | |
1994 } | |
1995 | |
1996 { | |
1997 MCAST (tmsi_realloc_comp, U_TMSI_REALLOC_COMP); | |
1998 switch (tmsi_realloc_cmd->mob_id.ident_type) | |
1999 { | |
2000 case TYPE_TMSI: | |
2001 mm_store_tmsi (&tmsi_realloc_cmd->mob_id); | |
2002 mm_build_rr_sync_req_tmsi (); | |
2003 /* EF LOCI value has changed, hence write it on SIM */ | |
2004 /* EF Indicator for EF LOCI - bit 1 - changed value from Attach Accept msg*/ | |
2005 mm_data->ef_indicator|=0x01; | |
2006 break; | |
2007 case TYPE_IMSI: | |
2008 mm_data->reg.tmsi = TMSI_INVALID_VALUE; | |
2009 mm_build_rr_sync_req_cause (SYNCCS_TMSI_INVAL); | |
2010 /* EF LOCI value has changed, hence write it on SIM */ | |
2011 /* EF Indicator for EF LOCI - bit 1 - changed value from Attach Accept msg*/ | |
2012 mm_data->ef_indicator|=0x01; | |
2013 break; | |
2014 default: | |
2015 TRACE_EVENT ("Unexpected mobile id"); | |
2016 break; | |
2017 } | |
2018 | |
2019 /* | |
2020 * The mobile station shall consider the new TMSI and new LAI, | |
2021 * if any, as valid and the old TMSI and old LAI as deleted as | |
2022 * soon as a TMSI REALLOCATION COMMAND or another message | |
2023 * containing a new TMSI (e.g. LOCATION UPDATING ACCEPT) is | |
2024 * correctly received." [GSM 04.08 clause 4.3.1.4]. | |
2025 * It can *not* be assumed the new update state is U1 "UPDATED", | |
2026 * even if the description of the update state in GSM 04.08 4.1.2.2 | |
2027 * says a TMSI can only exists in "UPDATED". GSM 04.08 4.1.2.2 says | |
2028 * that normally a TMSI etc. only exists in updated, but first the | |
2029 * presence of other values shall not be considered as an error and | |
2030 * second this subclause states clearly that the update status shall | |
2031 * only be changed by LUP ACCEPT and some other explicitly mentioned | |
2032 * procedures, TMSI REALLOCATION COMMAND not beeing one of them. | |
2033 */ | |
2034 if (memcmp(mm_data->reg.lai.mnc, tmsi_realloc_cmd->loc_area_ident.mnc, SIZE_MNC) | |
2035 OR memcmp (mm_data->reg.lai.mcc, tmsi_realloc_cmd->loc_area_ident.mcc, SIZE_MCC) | |
2036 OR (mm_data->reg.lai.lac NEQ tmsi_realloc_cmd->loc_area_ident.lac)) | |
2037 { | |
2038 /* EF LOCI value has changed, hence write it on SIM */ | |
2039 /* EF Indicator for EF LOCI - bit 1 */ | |
2040 mm_data->ef_indicator|=0x01; | |
2041 } | |
2042 mm_data->reg.lai = tmsi_realloc_cmd->loc_area_ident; /* Struct copy */ | |
2043 tmsi_realloc_comp->msg_type = U_TMSI_REALLOC_COMP; | |
2044 for_data_req (BSIZE_U_TMSI_REALLOC_COMP); | |
2045 | |
2046 EM_TMSI_REALLOCATION_COMPLETE; | |
2047 | |
2048 TIMERSTOP (T3212); | |
2049 mm_data->t3212_timeout = FALSE; | |
2050 | |
2051 if (TIMERACTIVE(T3240)) | |
2052 { | |
2053 TIMERSTOP (T3240); | |
2054 TIMERSTART (T3240, T_3240_VALUE); | |
2055 } | |
2056 reg_build_sim_update (); | |
2057 } | |
2058 } | |
2059 | |
2060 /* | |
2061 +--------------------------------------------------------------------+ | |
2062 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
2063 | STATE : code ROUTINE : mm_cm_service_prompt | | |
2064 +--------------------------------------------------------------------+ | |
2065 | |
2066 PURPOSE : Process the signal CM_SERVICE_PROMPT. Only called from | |
2067 for_rr_data_ind if cmsp in classmark 2 is set. | |
2068 | |
2069 */ | |
2070 | |
2071 GLOBAL void mm_cm_service_prompt (T_D_CM_SERVICE_PROMPT *cm_service_prompt) | |
2072 { | |
2073 GET_INSTANCE_DATA; | |
2074 TRACE_FUNCTION ("mm_cm_service_prompt()"); | |
2075 | |
2076 switch (GET_STATE (STATE_MM)) | |
2077 { | |
2078 case MM_LUP_INITIATED: /* MM specific procedure, reject */ | |
2079 case MM_LUP_REJECTED: /* MM specific procedure, reject */ | |
2080 case MM_PROCESS_PROMPT: | |
2081 case MM_WAIT_FOR_OUTG_MM_CONN: | |
2082 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
2083 break; | |
2084 | |
2085 case MM_CONN_ACTIVE: | |
2086 if (mm_data->wait_for_accept) | |
2087 { | |
2088 /* This is state WAIT_FOR_ADD_OUTGOING_MM_CONN */ | |
2089 mm_for_set_error(RC_MESSAGE_INCOMPAT); | |
2090 } | |
2091 else | |
2092 { | |
2093 /* This is really MM_CONN_ACTIVE */ | |
2094 if ((cm_service_prompt->pd_and_sapi.pd EQ PD_CC) AND | |
2095 (cm_service_prompt->pd_and_sapi.sapi EQ SAPI_0)) | |
2096 { | |
2097 /* Send MMCM_PROMPT_IND to CC */ | |
2098 PALLOC (prompt_ind, MMCM_PROMPT_IND); | |
2099 PSENDX (CC, prompt_ind); | |
2100 SET_STATE (STATE_MM, MM_PROCESS_PROMPT); | |
2101 } | |
2102 else | |
2103 { | |
2104 /* Send MM_STATUS until CCBS fully supported by ACI and MMI */ | |
2105 mm_for_set_error(RC_SERVICE_NOT_SUPPORTED); | |
2106 } | |
2107 } | |
2108 break; | |
2109 | |
2110 case MM_WAIT_FOR_NW_CMD: | |
2111 #ifdef REL99 | |
2112 case MM_RR_CONN_RELEASE_NOT_ALLOWED: | |
2113 #endif | |
2114 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE) | |
2115 { | |
2116 /* | |
2117 * T3212 is stopped if the first MM message is received, or | |
2118 * ciphering mode setting is completed in the case of MM | |
2119 * connection establishment, except when the most recent service | |
2120 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2] | |
2121 */ | |
2122 TIMERSTOP (T3212); | |
2123 mm_data->t3212_timeout = FALSE; | |
2124 } | |
2125 | |
2126 if ((cm_service_prompt->pd_and_sapi.pd EQ PD_CC) AND | |
2127 (cm_service_prompt->pd_and_sapi.sapi EQ SAPI_0)) | |
2128 { | |
2129 #ifdef REL99 | |
2130 /* if timer T3240 is active, Restart T3240 */ | |
2131 if(TIMERACTIVE(T3240)) | |
2132 #endif | |
2133 { | |
2134 TIMERSTART (T3240, T_3240_VALUE); | |
2135 } | |
2136 /* Send MMCM_PROMPT_IND to CC */ | |
2137 { | |
2138 PALLOC (prompt_ind, MMCM_PROMPT_IND); /* T_MMCM_PROMPT_IND */ | |
2139 PSENDX (CC, prompt_ind); | |
2140 } | |
2141 #ifdef REL99 | |
2142 /* | |
2143 * Stop timer t3241 if it is running. *As per the spec 24.008, Timer | |
2144 * T3241 is stopped and reset (but not started) when the MM state | |
2145 * RR CONNECTION RELEASE NOT ALLOWED is left. | |
2146 */ | |
2147 TIMERSTOP(T3241); | |
2148 #endif | |
2149 | |
2150 SET_STATE (STATE_MM, MM_PROCESS_PROMPT); | |
2151 } | |
2152 else | |
2153 { | |
2154 /* Send MM_STATUS message, only CC and SAPI=0 supported */ | |
2155 mm_for_set_error(RC_SERVICE_NOT_SUPPORTED); | |
2156 } | |
2157 break; | |
2158 | |
2159 default: /* States without RR connection */ | |
2160 break; | |
2161 } | |
2162 } | |
2163 | |
2164 | |
2165 /* | |
2166 +--------------------------------------------------------------------+ | |
2167 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
2168 | STATE : code ROUTINE : mm_mm_information | | |
2169 +--------------------------------------------------------------------+ | |
2170 | |
2171 PURPOSE : Process the signal MM_INFORMATION. This signal may be | |
2172 received any time a RR connection to the network exists | |
2173 and is always been considered as compatible with the | |
2174 protocol state. | |
2175 */ | |
2176 | |
2177 GLOBAL void mm_mm_information (T_D_MM_INFORMATION *mm_information) | |
2178 { | |
2179 GET_INSTANCE_DATA; | |
2180 | |
2181 #ifdef GPRS | |
2182 PALLOC (mmr_info_ind,MMGMM_INFO_IND); | |
2183 #else | |
2184 PALLOC (mmr_info_ind,MMR_INFO_IND); | |
2185 #endif /* GPRS */ | |
2186 | |
2187 TRACE_FUNCTION ("mm_mm_information()"); | |
2188 | |
2189 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE) | |
2190 { | |
2191 /* | |
2192 * T3212 is stopped if the first MM message is received, or | |
2193 * ciphering mode setting is completed in the case of MM | |
2194 * connection establishment, except when the most recent service | |
2195 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2] | |
2196 */ | |
2197 TIMERSTOP (T3212); | |
2198 mm_data->t3212_timeout = FALSE; | |
2199 } | |
2200 | |
2201 /* Set PLMN, this will be used if network name is given */ | |
2202 mmr_info_ind->plmn.v_plmn = TRUE; | |
2203 memcpy (mmr_info_ind->plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC); | |
2204 memcpy (mmr_info_ind->plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC); | |
2205 | |
2206 /* Set full network name, if present */ | |
2207 mm_cpy_net_name(&mm_information->full_net_name, &mmr_info_ind->full_name, | |
2208 mm_information->v_full_net_name); | |
2209 | |
2210 /* Set short network name, if present */ | |
2211 mm_cpy_net_name(&mm_information->short_net_name, &mmr_info_ind->short_name, | |
2212 mm_information->v_short_net_name); | |
2213 | |
2214 /* Set network time zone, if present */ | |
2215 if (mm_information->v_net_tz NEQ 0) | |
2216 { | |
2217 mmr_info_ind->ntz.v_tz = TRUE; | |
2218 mmr_info_ind->ntz.tz = mm_information->net_tz.tz; | |
2219 } | |
2220 else | |
2221 mmr_info_ind->ntz.v_tz = FALSE; | |
2222 | |
2223 /* Set network time zone and time, if present */ | |
2224 if (mm_information->v_net_tz_and_time NEQ 0) | |
2225 { | |
2226 mmr_info_ind->ntz.v_tz = TRUE; | |
2227 mmr_info_ind->ntz.tz = mm_information->net_tz_and_time.tz; | |
2228 mmr_info_ind->time.v_time = TRUE; | |
2229 mmr_info_ind->time.year = | |
2230 10 * mm_information->net_tz_and_time.year[0] + | |
2231 mm_information->net_tz_and_time.year[1]; | |
2232 mmr_info_ind->time.month = | |
2233 10 * mm_information->net_tz_and_time.month[0] + | |
2234 mm_information->net_tz_and_time.month[1]; | |
2235 mmr_info_ind->time.day = | |
2236 10 * mm_information->net_tz_and_time.day[0] + | |
2237 mm_information->net_tz_and_time.day[1]; | |
2238 mmr_info_ind->time.hour = | |
2239 10 * mm_information->net_tz_and_time.hour[0] + | |
2240 mm_information->net_tz_and_time.hour[1]; | |
2241 mmr_info_ind->time.minute = | |
2242 10 * mm_information->net_tz_and_time.minute[0] + | |
2243 mm_information->net_tz_and_time.minute[1]; | |
2244 mmr_info_ind->time.second = | |
2245 10 * mm_information->net_tz_and_time.second[0] + | |
2246 mm_information->net_tz_and_time.second[1]; | |
2247 } | |
2248 else | |
2249 { | |
2250 mmr_info_ind->time.v_time = FALSE; | |
2251 } | |
2252 #ifdef REL99 | |
2253 if (mm_information->v_daylight_save_time) | |
2254 { | |
2255 mmr_info_ind->daylight_save_time = | |
2256 mm_information->daylight_save_time.save_time_value; | |
2257 } | |
2258 else | |
2259 { | |
2260 mmr_info_ind->daylight_save_time = MMR_ADJ_NO; | |
2261 } | |
2262 #endif | |
2263 #ifdef GPRS | |
2264 PSENDX (GMM, mmr_info_ind); | |
2265 #else | |
2266 PSENDX (MMI, mmr_info_ind); | |
2267 #endif | |
2268 } | |
2269 | |
2270 /* | |
2271 +--------------------------------------------------------------------+ | |
2272 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
2273 | STATE : code ROUTINE : mm_send_rr_data_ind | | |
2274 +--------------------------------------------------------------------+ | |
2275 | |
2276 PURPOSE : The function passes the RR_DATA_IND depending on the parameters | |
2277 'comp' and 'snd_prim_type' to the respective entity. | |
2278 'comp' gives either CC or SS or SMS entity | |
2279 'snd_prim_type' gives either ESTABLISH_IND or DATA_IND | |
2280 */ | |
2281 | |
2282 LOCAL void mm_send_rr_data_ind (T_RR_DATA_IND *rr_data_ind, | |
2283 UBYTE comp, | |
2284 T_PRIM_TYPE snd_prim_type) | |
2285 { | |
2286 TRACE_FUNCTION ("mm_send_rr_data_ind()"); | |
2287 | |
2288 switch (comp) | |
2289 { | |
2290 case CC_COMP: | |
2291 { | |
2292 if(snd_prim_type EQ PRIM_EST_IND) | |
2293 { | |
2294 PPASS (rr_data_ind, est, MMCM_ESTABLISH_IND); | |
2295 PSENDX (CC, est); | |
2296 } | |
2297 else | |
2298 { | |
2299 PPASS (rr_data_ind, data, MMCM_DATA_IND); | |
2300 PSENDX (CC, data); | |
2301 } | |
2302 } | |
2303 break; | |
2304 | |
2305 case SS_COMP: | |
2306 { | |
2307 if(snd_prim_type EQ PRIM_EST_IND) | |
2308 { | |
2309 PPASS (rr_data_ind, est, MMSS_ESTABLISH_IND); | |
2310 PSENDX (SS, est); | |
2311 } | |
2312 else | |
2313 { | |
2314 PPASS (rr_data_ind, data, MMSS_DATA_IND); | |
2315 PSENDX (SS, data); | |
2316 } | |
2317 } | |
2318 break; | |
2319 | |
2320 case SMS_COMP: | |
2321 { | |
2322 if(snd_prim_type EQ PRIM_EST_IND) | |
2323 { | |
2324 PPASS (rr_data_ind, est, MMSMS_ESTABLISH_IND); | |
2325 PSENDX (SMS, est); | |
2326 } | |
2327 else | |
2328 { | |
2329 PPASS (rr_data_ind, data, MMSMS_DATA_IND); | |
2330 PSENDX (SMS, data); | |
2331 } | |
2332 } | |
2333 break; | |
2334 | |
2335 default: | |
2336 PFREE (rr_data_ind); | |
2337 return; | |
2338 } /* switch (comp) */ | |
2339 } | |
2340 | |
2341 /* | |
2342 +--------------------------------------------------------------------+ | |
2343 | PROJECT : GSM-PS (6147) MODULE : MM_MM | | |
2344 | STATE : code ROUTINE : mm_cpy_net_name | | |
2345 +--------------------------------------------------------------------+ | |
2346 | |
2347 PURPOSE : The function sets the network name. | |
2348 */ | |
2349 | |
2350 LOCAL void mm_cpy_net_name (T_full_net_name *net_name, | |
2351 T_full_name *name, | |
2352 UBYTE v_net_name) | |
2353 { | |
2354 TRACE_FUNCTION ("mm_cpy_net_name()"); | |
2355 if (v_net_name NEQ 0) | |
2356 { | |
2357 name->v_name = TRUE; | |
2358 name->dcs = net_name->cs; | |
2359 name->add_ci = net_name->add_ci; | |
2360 name->num_spare = net_name->num_spare; | |
2361 memset(name->text, 0, MMR_MAX_TEXT_LEN); | |
2362 name->c_text = MINIMUM (MMR_MAX_TEXT_LEN, net_name->c_text); | |
2363 memcpy (name->text, net_name->text,name->c_text); | |
2364 } | |
2365 else | |
2366 name->v_name = FALSE; | |
2367 } | |
2368 | |
2369 #endif |