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