comparison src/g23m-gsm/mm/mm_mmp.c @ 104:27a4235405c6

src/g23m-gsm: import from LoCosto source
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 04 Oct 2016 18:24:05 +0000
parents
children
comparison
equal deleted inserted replaced
103:76d139c7a25e 104:27a4235405c6
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS (8410)
4 | Modul : MM_MMP
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 Management.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef MM_MMP_C
23 #define MM_MMP_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
82 /*==== FUNCTIONS ==================================================*/
83
84
85 LOCAL void mm_rr_abort_cell_sel_fail (T_RR_ABORT_IND *rr_abort_ind);
86 LOCAL void mm_mmcm_ss_sms_data_req (T_VOID_STRUCT *mm_data_req);
87 LOCAL void mm_sim_insert_state (void);
88
89 /*
90 +--------------------------------------------------------------------+
91 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
92 | STATE : code ROUTINE : mm_est_rr_for_cm |
93 +--------------------------------------------------------------------+
94
95 PURPOSE : Establish a RR connection for any CM entity. If this is
96 possible, e.g. GPRS is not active/delivered or
97 CM establishment is allowed by GPRS,
98 the RR_ESTABLISH_REQ is sent and state MM_WAIT_FOR_RR_CONN_MM
99 is entered. Otherwise GMM is informed about the CM connection
100 request and the primitive is saved for later usage, but no state
101 change is done.
102
103 */
104
105 LOCAL void mm_est_rr_for_cm (UBYTE comp, UBYTE ti, USHORT estcs)
106 {
107 GET_INSTANCE_DATA;
108 UBYTE service;
109
110 TRACE_FUNCTION ("mm_est_rr_for_cm()");
111
112 #ifdef WIN32
113 TRACE_EVENT_P3 (" comp = %d, ti = %d, estcs = %x",
114 comp,
115 ti,
116 estcs);
117 #endif /* #ifdef WIN32 */
118
119 switch (comp)
120 {
121 case CC_COMP:
122 if (estcs EQ MMCM_ESTCS_EMERGE)
123 service = EMERGENCY_SERVICE;
124 else
125 service = CALL_SERVICE;
126 break;
127
128 case SS_COMP:
129 estcs = ESTCS_MOB_ORIG_CAL_BY_SS_SMS; /* Override estcs */
130 service = SS_SERVICE;
131 break;
132
133 case SMS_COMP:
134 estcs = ESTCS_MOB_ORIG_CAL_BY_SS_SMS; /* Override estcs */
135 service = SMS_SERVICE;
136 break;
137
138 default:
139 TRACE_ERROR (UNEXPECTED_PARAMETER);
140 return;
141 }
142
143 mm_data->act_retrans = INTERNAL_REDIAL;
144
145 if (estcs EQ MMCM_ESTCS_EMERGE)
146 {
147 /*
148 * Establish RR connection for emergency call
149 */
150 #ifdef GPRS
151 if (mm_cm_est_allowed())
152 {
153 #endif
154 mm_data->idle_substate = GET_STATE (STATE_MM);
155 mm_rr_est_req (estcs, service, ti);
156 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_CONN_MM);
157 #ifdef GPRS
158 }
159 else
160 {
161 mm_mmgmm_cm_emergency_ind ();
162 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, UNSPEC);
163 }
164 #endif
165 }
166 else
167 {
168 /*
169 * Establish RR connection for normal call, SS or SMS
170 */
171 #ifdef GPRS
172 if (mm_cm_est_allowed())
173 {
174 #endif
175 mm_data->idle_substate = GET_STATE (STATE_MM);
176 mm_rr_est_req (estcs, service, ti);
177 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_CONN_MM);
178 #ifdef GPRS
179 }
180 else
181 {
182 mm_mmgmm_cm_establish_ind ();
183 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, UNSPEC);
184 }
185 #endif
186 }
187 }
188
189
190 /*
191 +--------------------------------------------------------------------+
192 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
193 | STATE : code ROUTINE : mm_mmxx_release_req |
194 +--------------------------------------------------------------------+
195
196 PURPOSE : Process the primitives
197 MMCM_RELEASE_REQ, MMSS_RELEASE_REQ and MMSMS_RELEASE_REQ.
198
199 */
200
201 LOCAL void mm_mmxx_release_req (UBYTE comp, UBYTE ti)
202 {
203 GET_INSTANCE_DATA;
204 TRACE_FUNCTION ("mm_mmxx_release_req()");
205
206 switch (GET_STATE (STATE_MM))
207 {
208 case MM_LUP_INITIATED:
209 case MM_IMSI_DETACH_INIT:
210 case MM_WAIT_FOR_NW_CMD:
211 case MM_LUP_REJECTED:
212 case MM_WAIT_FOR_RR_CONN_LUP:
213 case MM_WAIT_FOR_RR_CONN_DETACH:
214 /*
215 * RR connection requested/established. Only delete the request from CM,
216 * but do not inform GMM now until connection released.
217 */
218 mm_delete_entry (comp, ti);
219 break;
220
221 case MM_WAIT_FOR_RR_ACTIVE:
222 case MM_IDLE_NORMAL_SERVICE: /* 19.1 */
223 case MM_IDLE_ATTEMPT_TO_UPDATE: /* 19.2 */
224 case MM_IDLE_LIMITED_SERVICE: /* 19.3 */
225 case MM_IDLE_NO_IMSI: /* 19.4 */
226 case MM_IDLE_NO_CELL_AVAILABLE: /* 19.5 */
227 case MM_IDLE_PLMN_SEARCH: /* 19.7 */
228 case MM_PLMN_SEARCH_NORMAL_SERVICE: /* 19.8 */
229 #ifdef GPRS
230 case MM_IDLE_LUP_NEEDED: /* 19.6 */
231 case MM_LOCATION_UPDATING_PENDING:
232 case MM_IMSI_DETACH_PENDING:
233 #endif /* GPRS */
234 mm_delete_entry (comp, ti);
235 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_OK);
236 break;
237
238 case MM_WAIT_FOR_OUTG_MM_CONN:
239 if ((mm_data->pend_conn.comp EQ comp) AND
240 (mm_data->pend_conn.ti EQ ti))
241 {
242 MCAST (cm_serv_abort, U_CM_SERV_ABORT);
243 CM_SET_STATE (comp, mm_data->pend_conn.ti, CM_IDLE);
244 cm_serv_abort->msg_type = U_CM_SERV_ABORT;
245 for_data_req (BSIZE_U_CM_SERV_ABORT);
246
247 EM_SERVICE_ABORTED;
248 TIMERSTOP (T3230);
249
250 #if defined (FF_EOTD) AND defined (REL99)
251 /*
252 * check the flag rrlp_lcs_started value. True if rrlp is running, False
253 * if no rrlp is runnig.
254 */
255 if(mm_data->rrlp_lcs_started EQ TRUE)
256 {
257 /*
258 * Enter state MM_RR_CONN_RELEASE_NOT_ALLOWED only if the last
259 * active MM connection has been released by the CM layer
260 * and there is rrlp service on going.
261 */
262 TIMERSTART (T3241, T_3241_VALUE);
263 SET_STATE (STATE_MM, MM_RR_CONN_RELEASE_NOT_ALLOWED);
264 }
265 else
266 #endif /* (FF_EOTD) AND defined (REL99) */
267 {
268 TIMERSTART (T3240, T_3240_VALUE);
269 mm_data->wait_for_accept = FALSE;
270 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
271 }
272 }
273 else
274 {
275 mm_delete_entry (comp, ti);
276 }
277 break;
278
279 case MM_CONN_ACTIVE:
280 switch (CM_GET_STATE (comp, ti))
281 {
282 case CM_STORE:
283 mm_delete_entry (comp, ti);
284 break;
285
286 case CM_PENDING:
287 mm_data->wait_for_accept = FALSE;
288 CM_SET_STATE (comp, ti, CM_IDLE);
289 break;
290
291 case CM_ACTIVE:
292 CM_SET_STATE (comp, ti, CM_IDLE);
293 if ((mm_count_connections (CM_ACTIVE) EQ 0) AND
294 !TIMERACTIVE (T3230))
295 {
296 #if defined (FF_EOTD) AND defined (REL99)
297 /*check the flag rrlp_lcs_started value. True if rrlp is running, False if no rrlp is runnig.*/
298 if(mm_data->rrlp_lcs_started EQ TRUE)
299 {
300 /*
301 * Enter state MM_RR_CONN_RELEASE_NOT_ALLOWED only if the last
302 * active MM connection has been released by the CM layer
303 * and there is rrlp service on going.
304 */
305 TIMERSTART (T3241, T_3241_VALUE);
306 SET_STATE (STATE_MM, MM_RR_CONN_RELEASE_NOT_ALLOWED);
307 }
308 else
309 #endif /* (FF_EOTD) AND defined (REL99) */
310 {
311 /*
312 * Enter state MM_WAIT_FOR_NW_CMD only if the last
313 * active MM connection has been released by the CM layer
314 * and there is no pending connection. Otherwise keep state.
315 */
316 TIMERSTART (T3240, T_3240_VALUE);
317 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
318 }
319 }
320 break;
321
322 default:
323 break;
324 }
325 break;
326
327 case MM_PROCESS_PROMPT:
328 switch (CM_GET_STATE (comp, ti))
329 {
330 case CM_STORE:
331 mm_delete_entry (comp, ti);
332 break;
333
334 case CM_PENDING:
335 /*
336 * In state MM_PROCESS_PROMPT there are never pending connections,
337 * so these need not be handled here
338 */
339 TRACE_ERROR ("CM_PENDING?");
340 break;
341
342 case CM_ACTIVE:
343 CM_SET_STATE (comp, ti, CM_IDLE);
344 if (mm_count_connections (CM_ACTIVE) EQ 0)
345 {
346 /*
347 * Last active connection released, but
348 * PROMPT remains present. Only START T3240
349 */
350 TIMERSTART (T3240, T_3240_VALUE);
351 }
352 break;
353
354 default:
355 break;
356 }
357 break;
358
359 case MM_WAIT_FOR_RR_CONN_MM:
360 if (mm_data->pend_conn.comp EQ comp AND
361 mm_data->pend_conn.ti EQ ti)
362 {
363 CM_SET_STATE (comp, mm_data->pend_conn.ti, CM_IDLE);
364 mm_abort_connection (ABCS_NORM);
365 TIMERSTOP (T3230);
366 /* After RR_ABORT_REQ here, RR_RELEASE_IND is guaranteed by RR */
367 }
368 else
369 {
370 mm_delete_entry (comp, ti);
371 }
372 break;
373
374 case MM_WAIT_FOR_REESTABLISH:
375 switch (CM_GET_STATE (comp, ti))
376 {
377 case CM_IDLE:
378 case CM_PENDING:
379 break;
380 case CM_STORE:
381 mm_delete_entry (comp, ti);
382 break;
383 case CM_ACTIVE:
384 /* CC will not start call reestablishment,
385 * then clear connection status
386 */
387 CM_SET_STATE (comp, ti, CM_IDLE);
388 /* this was the last answer from MM */
389 if (mm_count_connections (CM_ACTIVE) EQ 0)
390 {
391 /* there was no connection requesting call reestablishment */
392 if ( mm_count_connections (CM_REEST_PENDING) EQ 0)
393 {
394 /* Find IDLE state after MM connection */
395 mm_release_rr_connection (MMGMM_RESUMPTION_FAILURE);
396 }
397 else
398 {
399 /*
400 * RR has already signalled a cell which is
401 * suitable for call reestablishment
402 * This could be explained to me. Why is in the release
403 * routine reestablishment performed. I never understood
404 * the problem which was solved here. Implementation problem? ...
405 */
406 if (mm_data->reest_cell_avail)
407 mm_reest (mm_data->reest_ti);
408 }
409 }
410 break;
411 }
412 break;
413
414 default:
415 break;
416 }
417 }
418
419 /*==== VARIABLES ==================================================*/
420 GLOBAL UBYTE _decodedMsg [MAX_MSTRUCT_LEN_MM];
421
422 /*==== FUNCTIONS ==================================================*/
423
424 /*
425 * -------------------------------------------------------------------
426 * PRIMITIVE Processing functions
427 * -------------------------------------------------------------------
428 */
429
430 /*
431 +--------------------------------------------------------------------+
432 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
433 | STATE : code ROUTINE : mm_init_mm_data |
434 +--------------------------------------------------------------------+
435
436 PURPOSE : Initialize the MM data for the module mob. management.
437
438 */
439
440 GLOBAL void mm_init_mm_data (void)
441 {
442 GET_INSTANCE_DATA;
443 USHORT i;
444
445 TRACE_FUNCTION ("mm_init_mm_data()");
446
447 #if defined (NEW_FRAME)
448 for (i = 0; i < NUM_OF_MM_TIMERS; i++)
449 mm_data->t_running[i] = FALSE;
450 #else
451 for (i = 0; i < NUM_OF_MM_TIMERS; i++)
452 mm_data->t_handle[i] = VSI_ERROR;
453 #endif
454
455 mm_init ();
456 reg_clear_plmn_list (mm_data->reg.eqv_plmns.eqv_plmn_list, EPLMNLIST_SIZE);
457 mm_data->state[STATE_MM] = MM_NULL;
458 #ifdef GPRS
459 mm_data->state[STATE_REG_TYPE] = REG_GPRS_INACTIVE;
460 mm_data->state[STATE_GPRS_CM_EST] = CM_GPRS_EST_OK;
461 #endif /* GPRS */
462 }
463
464 /*
465 +--------------------------------------------------------------------+
466 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
467 | STATE : code ROUTINE : mm_mdl_error_ind |
468 +--------------------------------------------------------------------+
469
470 PURPOSE : Process the primitive MDL_ERROR_IND.
471
472 */
473
474 GLOBAL void mm_mdl_error_ind (T_MDL_ERROR_IND *mdl_error_ind)
475 {
476 TRACE_FUNCTION ("mm_mdl_error_ind()");
477
478 #if 0
479 /*
480 * No MDL_RELEASE_REQ is needed in DL for fatal reasons,
481 * as DL already automatically releases the DL connection if such
482 * a fatal reason occurs. The opposite is true: This function
483 * will disturb DL operation if it sends a MDL_RELEASE_REQ
484 * after receiving MDL_ERROR_IND with cause CS_T200_EXP in case
485 * of a switch back to the old channel on handover failure.
486 *
487 * The communication path between DL and MM may have been a
488 * general misdecision in design, this has still to be discussed.
489 */
490 switch (GET_STATE (STATE_MM))
491 {
492 case MM_NULL:
493 case MM_IDLE_NO_CELL_AVAILABLE:
494 /*
495 * no DL is active
496 */
497 break;
498
499 default:
500 /*
501 * Handling depending on the error cause
502 */
503 switch (mdl_error_ind->cs)
504 {
505 case CS_T200_EXP:
506 case CS_UNSOL_DM_RESP:
507 case CS_UNSOL_DM_RESP_MULT_FRM:
508 case CS_NR_SEQ_ERR:
509 switch (mdl_error_ind->sapi)
510 {
511 case SAPI_0:
512 mm_mdl_rel_req ();
513 break;
514 case SAPI_3:
515 mm_mdl_rel_req_sapi_3 ();
516 break;
517 }
518 break;
519 }
520 break;
521 }
522 #endif
523
524 PFREE (mdl_error_ind);
525 }
526
527 /*
528 +--------------------------------------------------------------------+
529 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
530 | STATE : code ROUTINE : mm_mmcm_data_req |
531 +--------------------------------------------------------------------+
532
533 PURPOSE : Process the primitive MMCM_DATA_REQ.
534
535 */
536
537 GLOBAL void mm_mmcm_data_req (T_MMCM_DATA_REQ *mmcm_data_req)
538 {
539 TRACE_FUNCTION ("mm_mmcm_data_req()");
540
541 mm_mmcm_ss_sms_data_req ( (T_VOID_STRUCT*)mmcm_data_req);
542 }
543
544
545 /*
546 +--------------------------------------------------------------------+
547 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
548 | STATE : code ROUTINE : mm_mmxx_establish_req |
549 +--------------------------------------------------------------------+
550
551 PURPOSE : Process MMCM_ESTABLISH_REQ, MMSS_ESTABLISH_REQ and
552 MMSMS_ESTABLISH_REQ finally. This is a generic function
553 which handles the establishment for all CM entities.
554
555 */
556
557 GLOBAL void mm_mmxx_establish_req (UBYTE comp,
558 UBYTE ti,
559 USHORT estcs,
560 U8 info)
561
562 {
563 GET_INSTANCE_DATA;
564 UBYTE service;
565
566 restart_function:
567 TRACE_FUNCTION ("mm_mmxx_establish_req()");
568
569 switch (comp)
570 {
571 case CC_COMP:
572 if (estcs EQ MMCM_ESTCS_EMERGE)
573 service = EMERGENCY_SERVICE;
574 else
575 service = CALL_SERVICE;
576 break;
577
578 case SS_COMP:
579 service = SS_SERVICE;
580 break;
581
582 case SMS_COMP:
583 service = SMS_SERVICE;
584 break;
585
586 default:
587 TRACE_ERROR (UNEXPECTED_DEFAULT); /* Cannot happen */
588 return; /* No action which makes sense possible here */
589 }
590
591 #ifdef GPRS
592 if ((mm_data->gprs.mobile_class EQ MMGMM_CLASS_CG) OR
593 (mm_data->gprs.sim_physically_removed AND
594 (service NEQ EMERGENCY_SERVICE)))
595 {
596 /*
597 * 1.) No CS services with a PS only mobile,
598 * for MMGMM_CLASS_BG MM has to ask
599 * 2.) SIM removal, GMM detaching and call request requiring SIM
600 * => release the call
601 */
602 mm_mmxx_release_ind (comp, ti, MMCS_NO_REGISTRATION);
603 return;
604 }
605 #endif /* #ifdef GPRS */
606
607 switch (GET_STATE (STATE_MM))
608 {
609 case MM_NULL:
610 case MM_IDLE_NO_CELL_AVAILABLE:
611 /*
612 * without coverage no calls !
613 */
614 mm_mmxx_release_ind (comp, ti, MMCS_NO_REGISTRATION);
615 break;
616
617 case MM_LUP_INITIATED:
618 case MM_WAIT_FOR_OUTG_MM_CONN:
619 case MM_PROCESS_PROMPT:
620 case MM_WAIT_FOR_NW_CMD:
621 case MM_LUP_REJECTED:
622 case MM_WAIT_FOR_RR_CONN_LUP:
623 case MM_WAIT_FOR_RR_CONN_MM:
624 case MM_WAIT_FOR_REESTABLISH:
625 case MM_WAIT_FOR_RR_ACTIVE:
626 #ifdef GPRS
627 case MM_LOCATION_UPDATING_PENDING:
628 #endif /* GPRS */
629 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, UNSPEC);
630 break;
631 #ifdef REL99
632 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
633 /*Upon reception of CM establishment request, MM will stop the timer 3241 &
634 *shall send mm_rr_data_request. Upon reception of cm service accept from
635 *network MM enter in MM_CONN_ACTIVE state.
636 */
637 TIMERSTOP (T3241);
638 mm_rr_data_req (estcs, service, ti);
639 TIMERSTART (T3230, T_3230_VALUE);
640 SET_STATE (STATE_MM, MM_WAIT_FOR_OUTG_MM_CONN);
641 break;
642 #endif
643
644 case MM_CONN_ACTIVE:
645 if (mm_data->wait_for_accept)
646 {
647 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, UNSPEC);
648 }
649 else
650 {
651 /*
652 * There is a rare, unhandled case:
653 * MM_CONN_ACTIVE and the service state is not full service,
654 * we have an ongoing emergency call. In this case MM should
655 * reject the establish request, but this is not critical here.
656 */
657 mm_rr_data_req (estcs, service, ti);
658 TIMERSTART (T3230, T_3230_VALUE);
659 }
660 break;
661
662 case MM_IMSI_DETACH_INIT:
663 case MM_WAIT_FOR_RR_CONN_DETACH:
664 #ifdef GPRS
665 case MM_IMSI_DETACH_PENDING:
666 #endif /* GPRS */
667 if (mm_data->nreg_cause EQ CS_SIM_REM AND
668 estcs EQ MMCM_ESTCS_EMERGE)
669 {
670 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, UNSPEC);
671 }
672 else
673 {
674 mm_mmxx_release_ind (comp, ti, MMCS_NO_REGISTRATION);
675 }
676 break;
677
678 case MM_IDLE_NORMAL_SERVICE:
679 mm_est_rr_for_cm (comp, ti, estcs);
680 break;
681
682 #ifdef GPRS
683 case MM_IDLE_LUP_NEEDED:
684 /*
685 * Inform GMM about the wish to establish a RR connection
686 * for CM. Either GMM will accept this and bring MM into
687 * IDLE updated state or GMM will refuse this.
688 * The final decision is left to GMM here.
689 */
690 if (estcs EQ MMCM_ESTCS_EMERGE)
691 {
692 /*
693 * Emergency call
694 */
695 mm_mmxx_rel_ind (MMCS_INT_PREEM, CM_NOT_IDLE);
696 mm_est_rr_for_cm (comp, ti, estcs);
697 }
698 else
699 {
700 /*
701 * Normal call
702 */
703 if (mm_cm_est_allowed())
704 {
705 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, CM_LUP_TRIGGER);
706 if (info EQ UNSPEC)
707 {
708 SET_STATE (STATE_REG_TYPE, REG_REMOTE_CONTROLLED);
709 mm_normal_loc_upd ();
710 }
711 }
712 else
713 {
714 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, UNSPEC);
715 mm_mmgmm_cm_establish_ind ();
716 }
717 }
718 break;
719 #endif /* GPRS */
720
721 case MM_IDLE_ATTEMPT_TO_UPDATE:
722 if (info NEQ CM_LUP_TRIGGER)
723 mm_data->attempt_cnt = 0;
724 if (estcs EQ MMCM_ESTCS_EMERGE)
725 {
726 /*
727 * Emergency call
728 */
729 mm_mmxx_rel_ind (MMCS_INT_PREEM, CM_NOT_IDLE);
730 mm_est_rr_for_cm (comp, ti, estcs);
731 }
732 else
733 {
734 /*
735 * 'info' is used to check to see where this function was called.
736 * If this function was called from 'mm_mmcm_establish_req()' then
737 * this is the first pass for this function and 'mm_normal_loc_upd()'
738 * must be called according to the Recs.
739 * If the function was called from 'mm_use_entry()', then it means
740 * an existing CM request is stored in the MM local stack and the current
741 * MM procedure is running for that entry. Subsequent calls of 'mm_use_entry()'
742 * must be ignored i.e. mm_normal_loc_upd()' must *not* be called.
743 */
744 /*
745 * Normal call
746 */
747 if (mm_cm_est_allowed())
748 {
749 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, CM_LUP_TRIGGER);
750 if (info EQ UNSPEC)
751 {
752 #ifdef GPRS
753 if (!mm_lup_allowed_by_gmm())
754 {
755 SET_STATE (STATE_REG_TYPE, REG_REMOTE_CONTROLLED);
756 }
757 #endif
758 mm_normal_loc_upd ();
759 }
760 }
761 else
762 {
763 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, UNSPEC);
764 mm_mmgmm_cm_establish_ind ();
765 }
766 }
767 break;
768
769 case MM_IDLE_LIMITED_SERVICE:
770 case MM_IDLE_NO_IMSI:
771 if (estcs EQ MMCM_ESTCS_EMERGE)
772 {
773 mm_est_rr_for_cm (comp, ti, estcs);
774 }
775 else
776 {
777 mm_mmxx_release_ind (comp, ti, MMCS_NO_REGISTRATION);
778 }
779 break;
780
781 case MM_IDLE_PLMN_SEARCH:
782 mm_write_entry (comp, ti, estcs, EVENT_ENTRY, NULL, UNSPEC);
783 if (estcs EQ MMCM_ESTCS_EMERGE)
784 {
785 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
786 mm_rr_act_req ();
787 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_ACTIVE);
788 }
789 break;
790
791 case MM_PLMN_SEARCH_NORMAL_SERVICE:
792 /* Indicate stop of search to the MMI */
793 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
794
795 /* Back to IDLE state before network search was started,
796 * as establishment will stop network search in RR */
797 SET_STATE (STATE_MM, mm_data->idle_substate);
798
799 /* Repeat the establish attempt in new MM state */
800 /* -- mm_mmxx_establish_req (comp, ti, estcs,info); -- */
801 /* -- return; -- */
802 /* avoid recursion, stack usage, therefore the goto. */
803 goto restart_function; /*lint !e801 goto*/
804
805 default:
806 TRACE_ERROR (UNEXPECTED_DEFAULT); /* All states caught */
807 break;
808 }
809 } /* mm_mmxx_establish_req() */
810
811
812 /*
813 +--------------------------------------------------------------------+
814 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
815 | STATE : code ROUTINE : mm_mmcm_establish_req |
816 +--------------------------------------------------------------------+
817
818 PURPOSE : Process the primitive MMCM_ESTABLISH_REQ.
819
820 */
821
822 GLOBAL void mm_mmcm_establish_req (T_MMCM_ESTABLISH_REQ *mmcm_establish_req)
823 {
824 TRACE_FUNCTION ("mm_mmcm_establish_req()");
825
826 /*
827 * And from this point MM is not interested in prio anymore.
828 * To distinguish emergency calls from normal calls estcs is used.
829 */
830
831 switch (mmcm_establish_req->org_entity)
832 {
833 case MMCM_ORG_ENTITY_CC:
834
835 mm_mmxx_establish_req (CC_COMP,
836 mmcm_establish_req->ti,
837 mmcm_establish_req->estcs,
838 UNSPEC);
839 break;
840
841 case MMCM_ORG_ENTITY_SS:
842 mm_mmxx_establish_req (SS_COMP, mmcm_establish_req->ti, 0,UNSPEC);
843 break;
844
845 case MMCM_ORG_ENTITY_SMS:
846 mm_mmxx_establish_req (SMS_COMP, mmcm_establish_req->ti, 0,UNSPEC);
847 break;
848
849 default:
850 TRACE_ERROR ("org_entity trashed");
851 break;
852 }
853
854 PFREE (mmcm_establish_req);
855 }
856
857 /*
858 +--------------------------------------------------------------------+
859 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
860 | STATE : code ROUTINE : mmcm_reestablish_req |
861 +--------------------------------------------------------------------+
862
863 PURPOSE : Process the primitive MMCM_REESTABLISH_REQ.
864
865 */
866
867 GLOBAL void mm_mmcm_reestablish_req (T_MMCM_REESTABLISH_REQ *mmcm_reestablish_req)
868 {
869
870 GET_INSTANCE_DATA;
871 TRACE_FUNCTION ("mm_mmcm_reestablish_req()");
872
873 switch (GET_STATE (STATE_MM))
874 {
875 case MM_WAIT_FOR_REESTABLISH:
876 /* set re-establishment transaction identifier if not already set */
877 if (mm_data->reest_ti EQ NOT_PRESENT_8BIT)
878 mm_data->reest_ti = mmcm_reestablish_req->ti;
879
880 /* set connection type to reestablishment pending */
881 CM_SET_STATE (CC_COMP, mmcm_reestablish_req->ti, CM_REEST_PENDING);
882
883 /* all CM connection have answered and
884 * RR has signalled a suitable cell for call reestablishment */
885 if (mm_count_connections (CM_ACTIVE) EQ 0 AND mm_data->reest_cell_avail)
886 mm_reest (mm_data->reest_ti);
887 break;
888
889 default:
890 break;
891 }
892 PFREE (mmcm_reestablish_req);
893 }
894
895
896 /*
897 +--------------------------------------------------------------------+
898 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
899 | STATE : code ROUTINE : mm_mmcm_release_req |
900 +--------------------------------------------------------------------+
901
902 PURPOSE : Process the primitive MMCM_RELEASE_REQ.
903
904 */
905
906 GLOBAL void mm_mmcm_release_req (T_MMCM_RELEASE_REQ *mmcm_release_req)
907 {
908 TRACE_FUNCTION ("mm_mmcm_release_req()");
909
910 mm_mmxx_release_req (CC_COMP, mmcm_release_req->ti);
911
912 PFREE (mmcm_release_req);
913 }
914
915 /*
916 +--------------------------------------------------------------------+
917 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
918 | STATE : code ROUTINE : mm_mmss_data_req |
919 +--------------------------------------------------------------------+
920
921 PURPOSE : Process the primitive MMSS_DATA_REQ.
922
923 */
924
925 GLOBAL void mm_mmss_data_req (T_MMSS_DATA_REQ *mmss_data_req)
926 {
927 TRACE_FUNCTION ("mm_mmss_data_req()");
928
929 mm_mmcm_ss_sms_data_req ( (T_VOID_STRUCT*)mmss_data_req);
930 }
931
932 /*
933 +--------------------------------------------------------------------+
934 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
935 | STATE : code ROUTINE : mm_mmss_establish_req |
936 +--------------------------------------------------------------------+
937
938 PURPOSE : Process the primitive MMSS_ESTABLISH_REQ.
939
940 */
941
942 GLOBAL void mm_mmss_establish_req (T_MMSS_ESTABLISH_REQ *mmss_establish_req)
943 {
944 TRACE_FUNCTION ("mm_mmss_establish_req()");
945
946 mm_mmxx_establish_req (SS_COMP, mmss_establish_req->ti, 0, UNSPEC);
947
948 PFREE (mmss_establish_req);
949 }
950
951
952 /*
953 +--------------------------------------------------------------------+
954 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
955 | STATE : code ROUTINE : mm_mmss_release_req |
956 +--------------------------------------------------------------------+
957
958 PURPOSE : Process the primitive MMSS_RELEASE_REQ.
959
960 */
961
962 GLOBAL void mm_mmss_release_req (T_MMSS_RELEASE_REQ *mmss_release_req)
963 {
964 TRACE_FUNCTION ("mm_mmss_release_req()");
965
966 mm_mmxx_release_req (SS_COMP, mmss_release_req->ti);
967
968 PFREE (mmss_release_req);
969 }
970
971 /*
972 +--------------------------------------------------------------------+
973 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
974 | STATE : code ROUTINE : mm_mmsms_data_req |
975 +--------------------------------------------------------------------+
976
977 PURPOSE : Process the primitive MMSMS_DATA_REQ.
978
979 */
980
981 GLOBAL void mm_mmsms_data_req (T_MMSMS_DATA_REQ *mmsms_data_req)
982 {
983 TRACE_FUNCTION ("mm_mmsms_data_req()");
984
985 mm_mmcm_ss_sms_data_req ( (T_VOID_STRUCT*)mmsms_data_req);
986 }
987
988 /*
989 +--------------------------------------------------------------------+
990 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
991 | STATE : code ROUTINE : mm_mmsms_establish_req |
992 +--------------------------------------------------------------------+
993
994 PURPOSE : Process the primitive MMSMS_ESTABLISH_REQ.
995
996 */
997
998 GLOBAL void mm_mmsms_establish_req (T_MMSMS_ESTABLISH_REQ *mmsms_establish_req)
999 {
1000 TRACE_FUNCTION ("mm_mmsms_establish_req()");
1001
1002 mm_mmxx_establish_req (SMS_COMP, mmsms_establish_req->ti, 0, UNSPEC);
1003
1004 PFREE (mmsms_establish_req);
1005 }
1006
1007 /*
1008 +--------------------------------------------------------------------+
1009 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1010 | STATE : code ROUTINE : mm_mmsms_release_req |
1011 +--------------------------------------------------------------------+
1012
1013 PURPOSE : Process the primitive MMSMS_RELEASE_REQ.
1014
1015 */
1016
1017 GLOBAL void mm_mmsms_release_req (T_MMSMS_RELEASE_REQ *mmsms_release_req)
1018 {
1019 TRACE_FUNCTION ("mm_mmsms_release_req()");
1020
1021 mm_mmxx_release_req (SMS_COMP, mmsms_release_req->ti);
1022
1023 PFREE (mmsms_release_req);
1024 }
1025
1026 /*
1027 +--------------------------------------------------------------------+
1028 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1029 | STATE : code ROUTINE : mm_rr_abort_ind |
1030 +--------------------------------------------------------------------+
1031
1032 PURPOSE : Process the primitive RR_ABORT_IND.
1033
1034 */
1035
1036 GLOBAL void mm_rr_abort_ind (T_RR_ABORT_IND *rr_abort_ind)
1037 {
1038 GET_INSTANCE_DATA;
1039 TRACE_FUNCTION ("mm_rr_abort_ind()");
1040 mm_data->t3213_restart = MAX_REST_T3213;
1041
1042 /*
1043 * If MM is reading sim and waiting for the SIM_READ_CNF for the EF PLMNsel
1044 * /EF EFPLMNwAcT/EFOPLMNwAcT which are used to prepare pref_plmn list.
1045 * rr_abort_ind will be stored if plmn_avail is indicated and will be used
1046 * once sim_read_cnf is received.
1047 */
1048 if (mm_data->reg.sim_read_in_progress AND rr_abort_ind->plmn_avail >0)
1049 {
1050 mm_write_entry(NO_ENTRY,NO_ENTRY,NO_ENTRY,PRIMITIVE_ENTRY,rr_abort_ind, UNSPEC);
1051 return;
1052 }
1053
1054 #ifdef WIN32
1055 /* Check for correct cause value */
1056 switch (rr_abort_ind->cause)
1057 {
1058 case RRCS_ABORT_CEL_SEL_FAIL:
1059 case RRCS_ABORT_RAD_LNK_FAIL:
1060 case RRCS_DATA_LINK_FAIL:
1061 case RRCS_ABORT_PTM:
1062 break;
1063
1064 default:
1065 TRACE_ERROR("Unexpected cause value");
1066 assert (0); /* Stop the simulation */
1067 break;
1068 }
1069 #endif /* #ifdef WIN32 */
1070
1071 EM_RESULT_PLMN_LIST;
1072
1073 TRACE_EVENT_P1 ("SERVICE = %d", rr_abort_ind->op.service);
1074
1075 /* This switch statement is used to catch the case where the RR_ABORT_IND sent in state */
1076 /* MM_LUP_INITIATED triggers a second RR_ABORT_IND received in state MM_IDLE_NORMAL_SERVICE */
1077 /* caused by a TABORT timeout. The second RR_ABORT_IND (containing zero plmns) is subsequently */
1078 /* ignored. This situation occurs when running TC 26.7.4.3.4 */
1079
1080 switch(GET_STATE (STATE_MM))
1081 {
1082 case MM_LUP_INITIATED:
1083 mm_data->rr_abort_prior_to_tabort = TRUE;
1084 break;
1085
1086 case MM_IDLE_NORMAL_SERVICE:
1087 break;
1088
1089 default:
1090 mm_data->rr_abort_prior_to_tabort = FALSE;
1091 break;
1092 }
1093
1094
1095
1096
1097 if (rr_abort_ind->op.service EQ LIMITED_SERVICE)
1098 mm_data->rf_power = rr_abort_ind->power;
1099
1100 switch (GET_STATE (STATE_MM))
1101 {
1102 case MM_NULL:
1103 break;
1104
1105 case MM_LUP_INITIATED:
1106 TIMERSTOP (T3210);
1107 mm_mdl_rel_req ();
1108 mm_lup_restart ();
1109 break;
1110
1111 case MM_WAIT_FOR_OUTG_MM_CONN:
1112 case MM_CONN_ACTIVE:
1113 case MM_PROCESS_PROMPT:
1114 case MM_WAIT_FOR_NW_CMD:
1115 #ifdef REL99
1116 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1117 #endif
1118 mm_mdl_rel_req ();
1119 TIMERSTOP (T3230);
1120 TIMERSTOP (T3240);
1121 #ifdef REL99
1122 TIMERSTOP (T3241);
1123 #endif
1124 mm_mmxx_rel_ind (rr_abort_ind->cause, CM_PENDING);
1125
1126 if (mm_mmxx_err_ind (rr_abort_ind->cause) NEQ 0)
1127 {
1128 /*
1129 * Active connections exist (CM_ACTIVE), remember that
1130 * CC has not yet signalled a valid ti for call re-establishment and
1131 * RR has not yet indicated a cell which is able to process call
1132 * re-establishment. Enter MM state MM_WAIT_FOR_REESTABLISH.
1133 */
1134 mm_data->reest_ti = NOT_PRESENT_8BIT;
1135 mm_data->reest_cell_avail = FALSE;
1136 SET_STATE (STATE_MM, MM_WAIT_FOR_REESTABLISH);
1137 }
1138 else
1139 {
1140 /* No active CM connection. Find IDLE state after MM connection. */
1141 mm_release_rr_connection (MMGMM_RESUMPTION_FAILURE);
1142 }
1143 break;
1144
1145 case MM_IMSI_DETACH_INIT:
1146 case MM_WAIT_FOR_RR_CONN_DETACH:
1147 mm_mdl_rel_req ();
1148 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
1149 mm_end_of_detach ();
1150 break;
1151
1152 case MM_LUP_REJECTED:
1153 mm_mdl_rel_req ();
1154 TIMERSTOP (T3240);
1155 mm_loc_upd_rej ();
1156 break;
1157
1158 case MM_WAIT_FOR_RR_CONN_LUP:
1159 if (rr_abort_ind->op.func EQ FUNC_NET_SRCH_BY_MMI)
1160 {
1161 /*
1162 * A running parallel search has been interrupted by a
1163 * location updating procedure. The sequence is
1164 * RR_ACTIVATE_REQ (MMI SEARCH) / RR_ACTIVATE_IND (new LA)
1165 * RR_ESTABLISH_REQ (LUP request) / RR_ABORT_IND (MMI SEARCH)
1166 * In this case we abort the pending search to the upper layers
1167 * and continue with our location updating procedure.
1168 */
1169 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
1170 }
1171 else
1172 {
1173 /*
1174 * The RR_ABORT_IND is not indicating the end of a search for
1175 * available networks.
1176 */
1177 TIMERSTOP (T3210);
1178 mm_mdl_rel_req ();
1179 if (rr_abort_ind->cause EQ RRCS_ABORT_CEL_SEL_FAIL)
1180 {
1181 TIMERSTOP (T3211);
1182 TIMERSTOP (T3213);
1183 mm_data->t3213_restart = 0;
1184 mm_mmxx_rel_ind (rr_abort_ind->cause, CM_NOT_IDLE);
1185 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
1186 switch (rr_abort_ind->op.service)
1187 {
1188 case NO_SERVICE:
1189 SET_STATE (STATE_MM, MM_IDLE_NO_CELL_AVAILABLE);
1190 break;
1191
1192 case LIMITED_SERVICE:
1193 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
1194 break;
1195
1196 default: /* eg. FULL_SERVICE and reg_rr_failure => nonsense */
1197 TRACE_ERROR (UNEXPECTED_DEFAULT);
1198 break;
1199 }
1200 reg_rr_failure (rr_abort_ind);
1201 }
1202 else
1203 {
1204 mm_lup_restart ();
1205 }
1206 }
1207 break;
1208
1209 case MM_WAIT_FOR_RR_CONN_MM:
1210 if (rr_abort_ind->op.func EQ FUNC_NET_SRCH_BY_MMI)
1211 {
1212 /*
1213 * Handle MMXXX_NET_REQ followed by MMGXXX_PLMN_RES during network
1214 * running search. MMXXX_NET_REQ is leading to establishment for MM's
1215 * location updating, this aborts the network search in RR.
1216 * Don't send probably partial or empty list to the MMI and avoid
1217 * MMXXX_NREG_IND in this situation, as this could be interpreted
1218 * by GMM as end of the procedure (which it is not).
1219 * Instead, send simply MMXXX_PLMN_IND (MMCS_PLMN_NOT_IDLE_MODE).
1220 */
1221 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
1222 }
1223 else
1224 {
1225 mm_mdl_rel_req ();
1226 if (rr_abort_ind->cause EQ RRCS_ABORT_CEL_SEL_FAIL)
1227 {
1228 TIMERSTOP (T3211);
1229 TIMERSTOP (T3213);
1230 mm_data->t3213_restart = 0;
1231 if (rr_abort_ind->op.service EQ NO_SERVICE)
1232 {
1233 mm_mmxx_rel_ind (rr_abort_ind->cause, CM_NOT_IDLE);
1234 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
1235 SET_STATE (STATE_MM, MM_IDLE_NO_CELL_AVAILABLE);
1236 reg_rr_failure (rr_abort_ind);
1237 }
1238 else
1239 {
1240 if (mm_data->pend_conn.cause EQ MMCM_ESTCS_EMERGE)
1241 {
1242 /*
1243 * Clash RR_ESTABLISH_REQ (emergency call) /
1244 * RR_ABORT_IND (limited service).
1245 * RR dropped the RR_ESTABLISH_REQ.
1246 * Repeat the emergency call attempt.
1247 */
1248 mm_rr_est_req (mm_data->pend_conn.cause,
1249 mm_data->pend_conn.service,
1250 mm_data->pend_conn.ti);
1251 /* Remain in state MM_WAIT_FOR_RR_CONN_MM */
1252 }
1253 else
1254 {
1255 mm_mmxx_rel_ind (rr_abort_ind->cause, CM_NOT_IDLE);
1256 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
1257 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
1258 reg_rr_failure (rr_abort_ind);
1259 }
1260 }
1261 }
1262 else
1263 {
1264 /*
1265 * Is data link failure possible here? Release pending connection.
1266 */
1267 mm_mmxx_rel_ind (rr_abort_ind->cause, CM_PENDING);
1268 mm_release_rr_connection (MMGMM_RESUMPTION_FAILURE);
1269 }
1270 }
1271 break;
1272
1273 case MM_WAIT_FOR_REESTABLISH:
1274 case MM_IDLE_ATTEMPT_TO_UPDATE:
1275 case MM_IDLE_LIMITED_SERVICE:
1276 mm_mdl_rel_req ();
1277 mm_rr_abort_cell_sel_fail( rr_abort_ind);
1278 break;
1279
1280 case MM_IDLE_NO_IMSI:
1281 /*
1282 * During limited service without SIM card
1283 * the no service condition is signalled by RR.
1284 */
1285 mm_mdl_rel_req ();
1286 if (rr_abort_ind->cause EQ RRCS_ABORT_CEL_SEL_FAIL AND
1287 rr_abort_ind->op.service EQ NO_SERVICE)
1288 {
1289 TIMERSTOP (T3211);
1290 TIMERSTOP (T3213);
1291 mm_data->t3213_restart = 0;
1292 mm_mmxx_rel_ind (rr_abort_ind->cause, CM_NOT_IDLE);
1293 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
1294 SET_STATE (STATE_MM, MM_IDLE_NO_CELL_AVAILABLE);
1295 reg_rr_failure (rr_abort_ind);
1296 }
1297 break;
1298
1299 case MM_IDLE_NORMAL_SERVICE:
1300 TIMERSTOP (T3213);
1301 mm_data->t3213_restart = 0;
1302 /*Check to see if this RR_ABORT_IND is caused by a RR TABORT timeout...*/
1303 if((mm_data->rr_abort_prior_to_tabort EQ TRUE) && (rr_abort_ind->plmn_avail EQ 0))
1304 {
1305 mm_data->rr_abort_prior_to_tabort = FALSE;
1306 PFREE (rr_abort_ind);
1307 return;
1308 }
1309
1310 /*lint -fallthrough */
1311 #ifdef GPRS
1312 case MM_IDLE_LUP_NEEDED:
1313 #endif /* GPRS */
1314
1315 mm_mdl_rel_req ();
1316 mm_rr_abort_cell_sel_fail( rr_abort_ind);
1317 break;
1318
1319 case MM_IDLE_NO_CELL_AVAILABLE:
1320 if (rr_abort_ind->op.service NEQ NO_SERVICE)
1321 {
1322 mm_data->reg.bcch_encode = FALSE;
1323 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
1324 reg_rr_failure (rr_abort_ind);
1325 }
1326 break;
1327
1328 case MM_WAIT_FOR_RR_ACTIVE:
1329 if (mm_data->reg.op.func EQ rr_abort_ind->op.func)
1330 {
1331 /*
1332 * answer to the request of MM
1333 */
1334 mm_mdl_rel_req ();
1335 mm_data->reg.bcch_encode = FALSE;
1336 if (rr_abort_ind->op.service EQ NO_SERVICE)
1337 {
1338 SET_STATE (STATE_MM, MM_IDLE_NO_CELL_AVAILABLE);
1339 }
1340 else
1341 {
1342 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
1343 }
1344 reg_rr_failure (rr_abort_ind);
1345 USE_STORED_ENTRIES();
1346 }
1347 #ifndef NTRACE
1348 else
1349 {
1350 /* This RR_ABORT_IND is to be ignored here, trace the func */
1351 switch (rr_abort_ind->op.func)
1352 {
1353 case FUNC_LIM_SERV_ST_SRCH:
1354 TRACE_EVENT ("RR_ABORT_IND (FUNC_LIM_SERV_ST_SRCH)");
1355 break;
1356
1357 case FUNC_PLMN_SRCH:
1358 TRACE_EVENT ("RR_ABORT_IND (FUNC_PLMN_SRCH)");
1359 break;
1360
1361 case FUNC_NET_SRCH_BY_MMI:
1362 TRACE_EVENT ("RR_ABORT_IND (FUNC_NET_SRCH_BY_MMI)");
1363 break;
1364
1365 default:
1366 TRACE_ERROR (UNEXPECTED_PARAMETER);
1367 break;
1368 }
1369 }
1370 #endif /* of #ifndef NTRACE */
1371 break;
1372
1373 case MM_IDLE_PLMN_SEARCH:
1374 /* Find new MM IDLE state, not searching */
1375 switch (rr_abort_ind->op.service)
1376 {
1377 case NO_SERVICE:
1378 SET_STATE (STATE_MM, MM_IDLE_NO_CELL_AVAILABLE);
1379 break;
1380
1381 case LIMITED_SERVICE:
1382 mm_sim_insert_state();
1383 break;
1384 case FULL_SERVICE:
1385 /* MM has to wait with full service in MM state machine
1386 * until it is known which cell was selected by RR. */
1387 mm_sim_insert_state();
1388 break;
1389
1390 default:
1391 TRACE_ERROR (UNEXPECTED_DEFAULT); /* Something has been garbled */
1392 break;
1393 }
1394 /* Build and send the list */
1395 reg_net_list (rr_abort_ind);
1396
1397 /* State change has occurred => use stored primitives */
1398 USE_STORED_ENTRIES();
1399 break;
1400
1401 case MM_PLMN_SEARCH_NORMAL_SERVICE:
1402 /* This state implies that a SIM is present */
1403
1404 /* Find new MM IDLE state, not searching */
1405 switch (rr_abort_ind->op.service)
1406 {
1407 case NO_SERVICE:
1408 SET_STATE (STATE_MM, MM_IDLE_NO_CELL_AVAILABLE);
1409 reg_net_list (rr_abort_ind); /* Build and send the list */
1410 USE_STORED_ENTRIES();
1411 break;
1412
1413 case LIMITED_SERVICE:
1414 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
1415 reg_net_list (rr_abort_ind); /* Build and send the list */
1416 USE_STORED_ENTRIES();
1417 break;
1418
1419 case FULL_SERVICE:
1420 /*
1421 * Back to old full service IDLE state, maybe either
1422 * MM_IDLE_NORMAL_SERVICE, MM_IDLE_ATTEMPT_TO_UPDATE,
1423 * or MM_IDLE_LUP_NEEDED.
1424 */
1425
1426 SET_STATE(STATE_MM,mm_data->idle_substate);
1427
1428 if (rr_abort_ind->cause EQ RRCS_ABORT_PTM)
1429 {
1430 if(mm_data->net_search_count < 2)
1431 {
1432 /* Since GPRS is in PTM there seems to be no need to inform
1433 * ACI of the Network list
1434 * Also,MM should start with 10 secs timer and on the expiry of
1435 * this timer should initiate the plmn scan search again
1436 */
1437 TIMERSTART(T_HPLMN,10000);
1438 mm_data->net_search_count++;
1439 }
1440 else
1441 {
1442 /* The user initiated network search should be repeated only twice
1443 * and empty PLMN list should be returned. But if the search was
1444 * other than user initiated network scan allow repetions till PLMN
1445 * search is a success. This should be tried every 2 mins.
1446 */
1447 if ( mm_data->plmn_scan_mmi )
1448 reg_net_list (rr_abort_ind);
1449 else
1450 TIMERSTART(T_HPLMN,120000);
1451 }
1452 }
1453 else
1454 {
1455 mm_data->net_search_count = 0;/*Network Scan successful,reset couter*/
1456 reg_net_list (rr_abort_ind); /* Build and send the list */
1457 }
1458
1459
1460 if (GET_STATE (STATE_MM) NEQ MM_WAIT_FOR_RR_ACTIVE)
1461 {
1462 /*
1463 * reg_net_list () didn't select a different PLMN.
1464 * Check whether MM needs a location update procedure.
1465 */
1466 if (mm_data->t3212_timeout AND
1467 mm_data->loc_upd_type.lut EQ NOT_RUNNING)
1468 {
1469 /*
1470 * T3212 expired during MM_PLMN_SEARCH_NORMAL_SERVICE.
1471 * Repeat the timeout event now as we are back to IDLE.
1472 */
1473 mm_data->t3212_timeout = FALSE;
1474 tim_t3212 ();
1475 }
1476 else
1477 {
1478 /*
1479 * Check whether T3211 and T3213 are inactive, if so,
1480 * continue an already running update now (if any).
1481 */
1482 if (!TIMERACTIVE (T3211) AND !TIMERACTIVE (T3213))
1483 {
1484 mm_continue_running_update ();
1485 }
1486 }
1487 }
1488 break;
1489
1490 default:
1491 TRACE_ERROR (UNEXPECTED_DEFAULT); /* Something has been garbled */
1492 break;
1493 }
1494 break;
1495
1496 #ifdef GPRS
1497 case MM_LOCATION_UPDATING_PENDING:
1498 case MM_IMSI_DETACH_PENDING:
1499 /*
1500 * This state transitions here should be discussed with ANS,
1501 * maybe MM is doing the wrong thing here.
1502 */
1503 if (rr_abort_ind->op.func NEQ FUNC_NET_SRCH_BY_MMI)
1504 {
1505 mm_mdl_rel_req ();
1506
1507 /* Throw out all pending connections */
1508 mm_mmxx_rel_ind (rr_abort_ind->cause, CM_NOT_IDLE);
1509 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
1510
1511 TRACE_EVENT ("State transition may be subject of discussion");
1512
1513 /* Enter the appropriate IDLE state for the offered service */
1514 if (rr_abort_ind->op.service EQ NO_SERVICE)
1515 {
1516 SET_STATE (STATE_MM, MM_IDLE_NO_CELL_AVAILABLE);
1517 }
1518 else
1519 {
1520 mm_sim_insert_state();
1521 }
1522 reg_rr_failure (rr_abort_ind);
1523 }
1524 break;
1525 #endif /* GPRS */
1526
1527 default:
1528 /* All states caught by case statements, this is impossible */
1529 TRACE_ERROR (UNEXPECTED_DEFAULT);
1530 break;
1531 }
1532 PFREE (rr_abort_ind);
1533 }
1534
1535
1536 /*
1537 +--------------------------------------------------------------------+
1538 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1539 | STATE : code ROUTINE : mm_limited_from_rr |
1540 +--------------------------------------------------------------------+
1541
1542 PURPOSE : This function takes the appropriate actions if a limited
1543 service cell is offered by RR.
1544
1545 */
1546
1547 LOCAL void mm_limited_from_rr (T_RR_ACTIVATE_CNF *rr_activate_cnf)
1548 {
1549 TRACE_FUNCTION ("mm_limited_from_rr()");
1550
1551 mm_copy_rr_act_cnf_data (rr_activate_cnf);
1552
1553 reg_mm_success (LIMITED_SERVICE);
1554
1555 /* Inform GPRS about selected cell */
1556 mm_mmgmm_activate_ind (MMGMM_LIMITED_SERVICE);
1557
1558 mm_sim_insert_state();
1559 }
1560
1561
1562 /*
1563 +----------------------------------------------------------------------------+
1564 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1565 | STATE : code ROUTINE : mm_rr_activate_cnf |
1566 +----------------------------------------------------------------------------+
1567
1568 PURPOSE : Process the primitive RR_ACTIVATE_CNF.
1569
1570 */
1571
1572 GLOBAL void mm_rr_activate_cnf (T_RR_ACTIVATE_CNF *rr_activate_cnf)
1573 {
1574 GET_INSTANCE_DATA;
1575 TRACE_FUNCTION ("mm_rr_activate_cnf()");
1576
1577 #ifdef WIN32
1578 vsi_o_ttrace (VSI_CALLER TC_FUNC,
1579 " MCC=%x%x%x MNC=%x%x%x LAC=%04X CID=%04X POW=%d",
1580 rr_activate_cnf->plmn.mcc[0],
1581 rr_activate_cnf->plmn.mcc[1],
1582 rr_activate_cnf->plmn.mcc[2],
1583 rr_activate_cnf->plmn.mnc[0],
1584 rr_activate_cnf->plmn.mnc[1],
1585 rr_activate_cnf->plmn.mnc[2],
1586 rr_activate_cnf->lac,
1587 rr_activate_cnf->cid,
1588 rr_activate_cnf->power);
1589 #endif /* #ifdef WIN32 */
1590 /* Changes for Boot Time Speedup. MM will get RR_ACTIVATE_CNF with op.func = FUNC_ST_PWR_SCAN.
1591 * No need to process it as this is response to dummy request.
1592 * MM need to send REG_CNF indicating PWR_SCAN_START
1593 */
1594 if (mm_data->reg.op.func EQ FUNC_ST_PWR_SCAN)
1595 {
1596 if (rr_activate_cnf->op.func EQ FUNC_ST_PWR_SCAN)
1597 {
1598 mm_send_mmgmm_reg_cnf (PWR_SCAN_START);
1599 }
1600 else
1601 {
1602 TRACE_EVENT_P1 ("Expected function FUNC_ST_PWR_SCAN but received %x", rr_activate_cnf->op.func);
1603 }
1604 return ;
1605 }
1606 mm_data->rf_power = rr_activate_cnf->power;
1607 mm_data->reg.new_cell_ind = TRUE;
1608
1609 if (reg_plmn_equal_eqv (&rr_activate_cnf->plmn, &mm_data->reg.actual_plmn))
1610 {
1611 mm_data->reg.actual_plmn = rr_activate_cnf->plmn; /* Struct copy */
1612 }
1613
1614 switch (GET_STATE (STATE_MM))
1615 {
1616 case MM_WAIT_FOR_RR_ACTIVE:
1617 if (mm_data->reg.op.func EQ rr_activate_cnf->op.func)
1618 {
1619 /*
1620 * this is the answer to the request of MM
1621 */
1622 switch (rr_activate_cnf->op.service)
1623 {
1624 case LIMITED_SERVICE:
1625 mm_limited_from_rr (rr_activate_cnf);
1626 USE_STORED_ENTRIES();
1627 break;
1628
1629 case FULL_SERVICE:
1630 /*
1631 * full service is indicated by RR.
1632 */
1633 mm_copy_rr_act_cnf_data (rr_activate_cnf);
1634
1635 if (!mm_normal_upd_needed() AND
1636 !mm_attach_upd_needed() AND
1637 !mm_periodic_upd_needed())
1638 {
1639 /*
1640 * No location updating needed
1641 */
1642 TIMERSTOP (T3213);
1643 mm_data->t3213_restart = 0;
1644
1645 /* Track possible change of T3212 */
1646 mm_change_t3212 ();
1647
1648 reg_mm_success (FULL_SERVICE);
1649 reg_build_sim_update (); /* Update cell id */
1650 mm_mmgmm_activate_ind (MMGMM_FULL_SERVICE);
1651
1652 /* Back to MM_IDLE_NORMAL_SERVICE */
1653 mm_data->idle_entry = RRCS_INT_NOT_PRESENT;
1654 /* Remember MM doesn't need any IMSI ATTACH anymore */
1655 if (mm_lup_allowed_by_gmm() AND mm_data->first_attach )
1656 {
1657 mm_data->first_attach_mem = mm_data->first_attach;
1658 mm_data->first_attach = FALSE;
1659 }
1660
1661 mm_data->t3212_timeout = FALSE;
1662 mm_data->loc_upd_type.lut = NOT_RUNNING;
1663 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
1664 /* Check HPLMN timer state */
1665 reg_check_hplmn_tim (mm_data->reg.thplmn);
1666 USE_STORED_ENTRIES();
1667 }
1668 else
1669 {
1670 /*
1671 * Location updating needed
1672 */
1673 reg_mm_cell_selected ();
1674
1675 mm_data->attempt_cnt = 0;
1676
1677 if (mm_normal_upd_needed())
1678 {
1679 /*
1680 * If updating is allowed by GMM, start procedure,
1681 * otherwise enter state MM_IDLE_LUP_NEEDED.
1682 */
1683 mm_normal_loc_upd ();
1684 }
1685 else if (mm_attach_upd_needed())
1686 {
1687 /*
1688 * If updating is allowed by GMM, start procedure,
1689 * otherwise enter state MM_IDLE_LUP_NEEDED.
1690 */
1691 mm_attach_loc_upd ();
1692 }
1693 else
1694 {
1695 /*
1696 * It must be a periodic location updating procedure.
1697 * If updating is allowed, start procedure,
1698 * otherwise enter state MM_IDLE_NORMAL_SERVICE.
1699 * Compare this with GSM 04.08 subclause 4.2.3
1700 */
1701 if (mm_lup_allowed_by_gmm()) /*lint !e774*/
1702 {
1703 mm_periodic_loc_upd ();
1704 }
1705 else
1706 {
1707 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
1708 }
1709 }
1710
1711 /*
1712 * If GPRS is active, GMM will be informed about the
1713 * cell selection. In this case, MM has not tried
1714 * to establish a RR connection for location updating
1715 * and the state MM_IDLE_LUP_NEEDED has already been entered.
1716 */
1717 mm_mmgmm_activate_ind (MMGMM_WAIT_FOR_UPDATE);
1718 }
1719 break; /* case FULL_SERVICE */
1720
1721 default: /* NO_SERVICE or other garbage */
1722 TRACE_ERROR (UNEXPECTED_DEFAULT);
1723 break;
1724 } /* switch() */
1725 }
1726 break;
1727
1728 default:
1729 /*
1730 * Normally MM should not receive an unsolicited RR_ACTIVATE_CNF,
1731 * but if it happens, we keep MM up to date using considering the
1732 * RR_ACTIVATE_CNF as RR_ACTIVATE_IND.
1733 * It is theoretically possible that a clash
1734 * RR_ACTIVATE_REQ -> RR_ABORT_IND -> RR_ACTIVATE_CNF
1735 * happens, but in most of the cases the reception of RR_ACTIVATE_CNF
1736 * in another state than MM_WAIT_FOR_RR_ACTIVE is a strong hint that
1737 * something went wrong in RR which should be observed carefully.
1738 */
1739 TRACE_ERROR ("RR_ACTIVATE_CNF => RR_ACTIVATE_IND");
1740 mm_rr_activate_ind ((T_RR_ACTIVATE_IND*)rr_activate_cnf);
1741 return; /* Don't free primitive twice */
1742 }
1743 PFREE (rr_activate_cnf);
1744 }
1745
1746 /*
1747 +--------------------------------------------------------------------+
1748 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1749 | STATE : code ROUTINE : mm_handled_forb_plmn_cell |
1750 +--------------------------------------------------------------------+
1751
1752 PURPOSE : This function checks whether RR selected a full service
1753 cell which is part of the forbidden PLMN list.
1754 If the cell is a member of a forbidden list, the
1755 appropriate actions are taken, but no change
1756 of the MM main state is performed.
1757
1758 */
1759
1760 LOCAL BOOL mm_handled_forb_plmn_cell (T_RR_ACTIVATE_IND *rr_activate_ind)
1761 {
1762 GET_INSTANCE_DATA;
1763 TRACE_FUNCTION ("mm_handled_forb_plmn_cell()");
1764
1765 if (reg_plmn_in_list (mm_data->reg.forb_plmn,
1766 MAX_FORB_PLMN_ID,
1767 &rr_activate_ind->plmn))
1768 {
1769 TRACE_EVENT ("RR selected forbidden PLMN");
1770
1771 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF *)rr_activate_ind);
1772
1773 reg_mm_success (LIMITED_SERVICE);
1774
1775 mm_build_rr_sync_req_cause (SYNCCS_LIMITED_SERVICE);
1776
1777 /*
1778 * GSM 04.08 subclause 4.4.4.7 doesn't say that a forbidden PLMN
1779 * for GSM shall also be considered as a forbidden PLMN for GPRS.
1780 * This means, we could have the situation that GSM has limited
1781 * service only, but GPRS has full network access.
1782 */
1783 mm_mmgmm_activate_ind (MMGMM_LIMITED_SERVICE);
1784
1785 return TRUE; /* Cell is in forbidden list */
1786 }
1787
1788 if (rr_activate_ind->mm_info.la EQ LA_IN_FRBD_LST_INCL)
1789 {
1790 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF *)rr_activate_ind);
1791
1792 reg_mm_success (LIMITED_SERVICE);
1793
1794 mm_mmgmm_activate_ind (MMGMM_LIMITED_SERVICE);
1795
1796 return TRUE; /* Cell is in forbidden list */
1797 }
1798 return FALSE; /* Cell is not in forbidden list */
1799 }
1800
1801
1802 /*
1803 +--------------------------------------------------------------------+
1804 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1805 | STATE : code ROUTINE : mm_full_from_rr |
1806 +--------------------------------------------------------------------+
1807
1808 PURPOSE : This function takes the appropriate actions if a full
1809 service cell is offered by RR in some MM states.
1810
1811 */
1812
1813 LOCAL void mm_full_from_rr (T_RR_ACTIVATE_IND *rr_activate_ind)
1814 {
1815 GET_INSTANCE_DATA;
1816 BOOL rr_changed_lai;
1817
1818 TRACE_FUNCTION ("mm_full_from_rr()");
1819
1820 rr_changed_lai = !mm_check_lai_from_RR (&mm_data->mm.lai,
1821 &rr_activate_ind->plmn,
1822 rr_activate_ind->lac);
1823
1824 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF *)rr_activate_ind);
1825
1826 mm_data->idle_entry = RRCS_INT_NOT_PRESENT;
1827
1828 if (mm_normal_upd_needed())
1829 mm_data->loc_upd_type.lut = NORMAL_LUP;
1830 else if (mm_attach_upd_needed())
1831 mm_data->loc_upd_type.lut = IMSI_ATTACH_LUP;
1832 else if (mm_periodic_upd_needed())
1833 mm_data->loc_upd_type.lut = PERIODIC_LUP;
1834 else
1835 {
1836 if (memcmp(mm_data->reg.lai.mcc, mm_data->mm.lai.mcc, SIZE_MCC)
1837 OR memcmp(mm_data->reg.lai.mnc, mm_data->mm.lai.mnc, SIZE_MNC)
1838 OR (mm_data->reg.lai.lac NEQ mm_data->mm.lai.lac))
1839 {
1840 /* EF LOCI value has changed, hence write it on SIM */
1841 /* EF Indicator for EF LOCI - bit 1*/
1842 mm_data->ef_indicator|=0x01;
1843 }
1844 mm_data->loc_upd_type.lut = NOT_RUNNING;
1845 }
1846
1847 #ifdef GPRS
1848 if (rr_changed_lai AND
1849 (mm_data->loc_upd_type.lut NEQ NOT_RUNNING) AND
1850 (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED))
1851 {
1852 /*
1853 * MM is in remote controlled operation with GPRS present and
1854 * the location area identifier has changed, MM has to set
1855 * its reg_type auxiliary state variable. The network mode
1856 * may have changed to network mode I.
1857 * Beware not to suppress an outstanding MMGMM_REG_CNF if
1858 * no update needed anymore for whatever reason.
1859 */
1860 SET_STATE (STATE_REG_TYPE, REG_CELL_SEARCH_ONLY);
1861 }
1862 #endif /* GPRS */
1863
1864 switch (mm_data->loc_upd_type.lut)
1865 {
1866 case NOT_RUNNING:
1867 /*
1868 * No location updating needed
1869 */
1870
1871 /* Track possible change of T3212 */
1872 mm_change_t3212 ();
1873
1874 TIMERSTOP (T3211);
1875 TIMERSTOP (T3213);
1876 mm_data->t3213_restart = 0;
1877
1878 mm_mmgmm_activate_ind (MMGMM_FULL_SERVICE);
1879 reg_mm_success (FULL_SERVICE);
1880 reg_build_sim_update ();
1881
1882 /* Remember MM doesn't need any IMSI ATTACH anymore */
1883 if (mm_lup_allowed_by_gmm() AND mm_data->first_attach)
1884 {
1885 mm_data->first_attach_mem = mm_data->first_attach;
1886 mm_data->first_attach = FALSE;
1887 }
1888 mm_data->t3212_timeout = FALSE;
1889
1890 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
1891 USE_STORED_ENTRIES();
1892 break;
1893
1894 case NORMAL_LUP:
1895 /*
1896 * If updating is allowed by GMM, start procedure,
1897 * otherwise enter appropriate IDLE state.
1898 */
1899 if (mm_lup_allowed_by_gmm()) /*lint !e774*/
1900 {
1901 mm_mmgmm_activate_ind (MMGMM_CELL_SELECTED);
1902 if (rr_changed_lai OR (!TIMERACTIVE (T3211) AND !TIMERACTIVE (T3213)))
1903 {
1904 mm_normal_loc_upd ();
1905 }
1906 else
1907 {
1908 /* Await timer expiry in appropriate IDLE state */
1909 if (mm_data->reg.update_stat EQ MS_UPDATED)
1910 {
1911 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
1912 }
1913 else
1914 {
1915 SET_STATE (STATE_MM, MM_IDLE_ATTEMPT_TO_UPDATE);
1916 }
1917 }
1918 }
1919 else
1920 {
1921 mm_mmgmm_activate_ind (MMGMM_WAIT_FOR_UPDATE);
1922 SET_STATE (STATE_MM, MM_IDLE_LUP_NEEDED);
1923 }
1924 break;
1925
1926 case IMSI_ATTACH_LUP:
1927 /*
1928 * If updating is allowed, start procedure,
1929 * otherwise enter state MM_IDLE_LUP_NEEDED.
1930 */
1931 if (mm_lup_allowed_by_gmm()) /*lint !e774*/
1932 {
1933 mm_mmgmm_activate_ind (MMGMM_CELL_SELECTED);
1934
1935 if (mm_gsm_alone ())
1936 {
1937 mm_mmgmm_reg_cnf (); /* Early indication of full service */
1938 }
1939
1940 if (!TIMERACTIVE (T3211) AND !TIMERACTIVE (T3213))
1941 {
1942 mm_attach_loc_upd ();
1943 }
1944 else
1945 {
1946 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
1947 }
1948 }
1949 else
1950 {
1951 mm_mmgmm_activate_ind (MMGMM_WAIT_FOR_UPDATE);
1952 SET_STATE (STATE_MM, MM_IDLE_LUP_NEEDED);
1953 }
1954 break;
1955
1956 case PERIODIC_LUP:
1957 /*
1958 * It is a periodic location updating procedure.
1959 * If updating is allowed, start procedure,
1960 * otherwise enter state MM_IDLE_NORMAL_SERVICE.
1961 * Compare this with GSM 04.08 subclause 4.2.3
1962 */
1963 if (mm_lup_allowed_by_gmm()) /*lint !e774*/
1964 {
1965 mm_mmgmm_activate_ind (MMGMM_CELL_SELECTED);
1966
1967 if (mm_gsm_alone ())
1968 {
1969 mm_mmgmm_reg_cnf (); /* Early indication of full service */
1970 }
1971
1972 if (!TIMERACTIVE (T3211) AND !TIMERACTIVE (T3213))
1973 {
1974 mm_periodic_loc_upd ();
1975 }
1976 else
1977 {
1978 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
1979 }
1980 }
1981 else
1982 {
1983 mm_mmgmm_activate_ind (MMGMM_WAIT_FOR_UPDATE);
1984 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
1985 }
1986 break;
1987
1988 default: /* Cannot happen */
1989 break;
1990 }
1991 }
1992
1993
1994 /*
1995 +--------------------------------------------------------------------+
1996 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1997 | STATE : code ROUTINE : mm_rr_activate_ind |
1998 +--------------------------------------------------------------------+
1999
2000 PURPOSE : Process the primitive RR_ACTIVATE_IND. MM is informed
2001 by RR about a cell selection without prior request
2002 by RR_ACTIVATE_REQ.
2003
2004 */
2005
2006 GLOBAL void mm_rr_activate_ind (T_RR_ACTIVATE_IND *rr_activate_ind)
2007 {
2008 GET_INSTANCE_DATA;
2009
2010 mm_data->t3213_restart = MAX_REST_T3213;
2011 restart_function:
2012 TRACE_FUNCTION ("mm_rr_activate_ind()");
2013
2014 #ifdef WIN32
2015 vsi_o_ttrace (VSI_CALLER TC_FUNC,
2016 " MCC=%x%x%x MNC=%x%x%x LAC=%04X CID=%04X POW=%d",
2017 rr_activate_ind->plmn.mcc[0],
2018 rr_activate_ind->plmn.mcc[1],
2019 rr_activate_ind->plmn.mcc[2],
2020 rr_activate_ind->plmn.mnc[0],
2021 rr_activate_ind->plmn.mnc[1],
2022 rr_activate_ind->plmn.mnc[2],
2023 rr_activate_ind->lac,
2024 rr_activate_ind->cid,
2025 rr_activate_ind->power);
2026 #endif /* #ifdef WIN32 */
2027
2028 mm_data->rf_power = rr_activate_ind->power;
2029 mm_data->reg.new_cell_ind = TRUE;
2030
2031 if(reg_plmn_equal_eqv (&rr_activate_ind->plmn, &mm_data->reg.actual_plmn))
2032 {
2033 mm_data->reg.actual_plmn = rr_activate_ind->plmn; /* Struct copy */
2034 }
2035
2036 switch (GET_STATE (STATE_MM))
2037 {
2038 case MM_WAIT_FOR_RR_CONN_MM:
2039 /*
2040 * If the unexpected incoming RR_ACTIVATE_IND in this state indicates
2041 * a new location area the rr_activation_indication is stored and a
2042 * rr_abort_req is sent. This should be answered by RR with a
2043 * RR_RELEASE_IND message triggering the MM to change the state to
2044 * MM_IDLE and to handle the outstanding RR_ACTIVATE_IND there.
2045 */
2046 {
2047 T_loc_area_ident local_lai;
2048
2049 memcpy (local_lai.mcc, rr_activate_ind->plmn.mcc, SIZE_MCC);
2050 memcpy (local_lai.mnc, rr_activate_ind->plmn.mnc, SIZE_MNC);
2051 local_lai.lac = rr_activate_ind->lac;
2052
2053 if (!mm_check_lai (&mm_data->mm.lai, &local_lai))
2054 {
2055 mm_write_entry(NO_ENTRY, NO_ENTRY, NO_ENTRY, PRIMITIVE_ENTRY, rr_activate_ind, UNSPEC);
2056 if (mm_data->pend_conn.cause NEQ ESTCS_EMRG_CAL)
2057 {
2058 TRACE_EVENT_P1 ("pend_conn.cause= %x", mm_data->pend_conn.cause);
2059 mm_abort_connection(ABCS_NORM);
2060 }
2061 return;
2062 }
2063 }
2064 /* FALLTHROUGH */
2065 /*lint -fallthrough */
2066 case MM_WAIT_FOR_RR_CONN_LUP:
2067 /*
2068 * case MM_WAIT_FOR_RR_CONN_MM:
2069 */
2070 case MM_WAIT_FOR_RR_CONN_DETACH:
2071 /*
2072 * A dedicated connection to the network
2073 * has been requested, but has not yet been established.
2074 * As we are storing the cell data here only,
2075 * it may become necessary to perform a location
2076 * updating procedure if coming back to IDLE.
2077 */
2078
2079 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF*) rr_activate_ind);
2080
2081 /* Inform GPRS about selected cell */
2082 mm_mmgmm_activate_ind (MMGMM_CELL_SELECTED);
2083
2084 if (mm_check_lai (&mm_data->mm.lai, &mm_data->reg.lai))
2085 reg_build_sim_update (); /* Update cell id */
2086 break;
2087
2088 case MM_WAIT_FOR_REESTABLISH:
2089 /* RR indicates a suitable cell for call reestablishment */
2090 if (rr_activate_ind->mm_info.re EQ 0)
2091 {
2092 /* What if call reestablishment and after call release of
2093 reestablished call in other LA LUP is necessary?
2094
2095 The following line was obviously missing here (HM, 01.02.01)
2096 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF *) rr_activate_ind);
2097
2098 Inform GPRS about selected cell
2099 mm_mmgmm_activate_ind (MMGMM_CELL_SELECTED);
2100 */
2101 mm_data->reest_cell_avail = TRUE;
2102 /*at least one connection has requested call reestablishment */
2103 if (mm_data->reest_ti NEQ NOT_PRESENT_8BIT)
2104 mm_reest (mm_data->reest_ti);
2105 /*if (mm_normal_upd_needed())
2106 { */
2107 mm_write_entry(NO_ENTRY, NO_ENTRY, NO_ENTRY, PRIMITIVE_ENTRY, rr_activate_ind, UNSPEC);
2108 return;
2109 /*} */
2110 }
2111 else
2112 {
2113 /*
2114 * No support of call reestablishment
2115 */
2116
2117 mm_mmxx_rel_ind (MMCS_NO_REESTABLISH, CM_NOT_IDLE);
2118
2119 /* Find IDLE state after MM connection */
2120 mm_release_rr_connection (MMGMM_RESUMPTION_FAILURE);
2121
2122 /* Restart the function in new state to perform location updating
2123 * if needed, avoid recursion for stack usage, therefore the goto */
2124 goto restart_function; /*lint !e801 goto*/
2125 }
2126 /* break is removed ,as case is returning before break so it is not needed */
2127 case MM_WAIT_FOR_RR_ACTIVE:
2128 /*
2129 * Clash case. While MM required to perform a network selection in RR,
2130 * RR performed a cell selection. This maybe ignored, as RR stored the
2131 * RR_ACTIVATE_REQ primitive in this case and a RR_ACTIVATE_CNF or
2132 * RR_ABORT_IND primitive will follow within short time.
2133 */
2134 break;
2135
2136 #ifdef GPRS
2137 case MM_LOCATION_UPDATING_PENDING:
2138 case MM_IMSI_DETACH_PENDING:
2139 /*
2140 *What to do here?...
2141 */
2142 assert (GET_STATE (STATE_REG_TYPE) EQ REG_CELL_SEARCH_ONLY);
2143 TRACE_EVENT ("This needs still discussion");
2144 /*FALLTHROUGH*/
2145 /* lint -fallthrough */
2146 #endif /* GPRS */
2147 case MM_IDLE_NORMAL_SERVICE: /* 19.1 */
2148 switch (rr_activate_ind->op.service)
2149 {
2150 case LIMITED_SERVICE:
2151 mm_limited_from_rr ((T_RR_ACTIVATE_CNF*)rr_activate_ind);
2152 break;
2153
2154 case FULL_SERVICE:
2155 if (mm_handled_forb_plmn_cell (rr_activate_ind))
2156 {
2157 /*
2158 * The cell is a member of a forbidden list.
2159 */
2160 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
2161 USE_STORED_ENTRIES();
2162 }
2163 else
2164 {
2165 mm_full_from_rr (rr_activate_ind);
2166 }
2167 break;
2168
2169 default: /* Either NO_SERVICE or other garbage */
2170 TRACE_ERROR (UNEXPECTED_DEFAULT);
2171 break;
2172 }
2173 break;
2174
2175 case MM_IDLE_ATTEMPT_TO_UPDATE: /* 19.2 */
2176 if (mm_handled_forb_plmn_cell (rr_activate_ind))
2177 {
2178 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
2179 }
2180 else
2181 {
2182 /*
2183 * RR selected a cell which may serve for full service. Behaviour
2184 * here is described in GSM 04.08 subclause 4.2.2.2, "Service State,
2185 * ATTEMPTING TO UPDATE". The idea behind this subclause for the
2186 * case "cell in old location area selected" seems to be very simple:
2187 * If the location updating problem has been caused by the BSS or the
2188 * cell itself, perform an updating attempt as soon as a new cell
2189 * has been selected by RR and don't consider the timers T3211 and
2190 * T3213. In case the location updating problem has been caused by the
2191 * NSS (core network), e.g. there was a "network failure", updating
2192 * if a new cell is entered makes no sense as the problem was under
2193 * no circumstances related to the previously selected cell.
2194 */
2195 if (mm_check_lai_from_RR (&mm_data->mm.lai,
2196 &rr_activate_ind->plmn,
2197 rr_activate_ind->lac))
2198 {
2199 /*
2200 * RR selected a cell which belongs to a location
2201 * area identical with the previously selected cell.
2202 * Don't reset the attempt counter.
2203 * Compare this with GSM 04.08 subclause 4.4.4.5.
2204 */
2205 BOOL perform_lup;
2206
2207 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF*) rr_activate_ind);
2208
2209 /* Track possible change of T3212 */
2210 mm_change_t3212 ();
2211
2212 /*
2213 * Check reject cause category according to GSM 04.08 s
2214 * subclause 4.2.2.2 and decide whether a location updating
2215 * procedure shall be performed.
2216 */
2217 switch (mm_data->rej_cause)
2218 {
2219 case RRCS_MM_ABORTED: /* GSM 04.08 4.4.4.9 e), T3210 */
2220 case RRCS_ABNORM_UNSPEC: /* GSM 04.08 4.4.4.9 f), ABNORM */
2221 /*
2222 * don´t start normal location updating if the state
2223 * has been entered after T3210 timeout or the network
2224 * released the RR connection with RR cause RRCS_ABNORM_UNSPEC.
2225 */
2226 perform_lup = FALSE;
2227 break;
2228
2229 case MMCS_RETRY_IN_NEW_CELL: /* GSM 04.08 4.4.4.8 g), RETRY */
2230 perform_lup = TRUE;
2231 break;
2232
2233 case RRCS_RND_ACC_FAIL: /* GSM 04.08 4.4.4.9 c) */
2234 case RRCS_DL_EST_FAIL: /* GSM 04.08 4.4.4.9 d) */
2235 perform_lup = (mm_data->attempt_cnt < 4);
2236 break;
2237
2238 default:
2239 /*
2240 * Treated here: GSM 04.08 4.4.4.9 f) with causes different
2241 * from "abnormal release, unspecified and g) with causes
2242 * different from "retry upon entry into a new cell".
2243 */
2244 perform_lup =
2245 GET_CAUSE_ORIGIN_ENTITY (mm_data->rej_cause) EQ RR_ORIGINATING_ENTITY;
2246 break;
2247 } /* switch (mm_data->rej_cause) */
2248
2249 if (perform_lup)
2250 {
2251 /*
2252 * Normal location update is necessary
2253 */
2254 mm_normal_loc_upd ();
2255
2256 /* Inform GPRS about selected cell */
2257 if (mm_lup_allowed_by_gmm()) /*lint !e774*/
2258 {
2259 mm_mmgmm_activate_ind (MMGMM_CELL_SELECTED);
2260 }
2261 else
2262 {
2263 mm_mmgmm_activate_ind (MMGMM_WAIT_FOR_UPDATE);
2264 }
2265 }
2266 else
2267 {
2268 /*
2269 * RR performed a cell selection which doesn't lead to a
2270 * location updating procedure in this state
2271 */
2272 mm_mmgmm_activate_ind (MMGMM_CELL_SELECTED);
2273 }
2274 }
2275 else
2276 {
2277 /*
2278 * RR selected a cell which belongs to a location
2279 * area not identical with the previously selected cell.
2280 * See GSM 04.08, subclause 4.2.2.2, "Service State,
2281 * ATTEMPTING TO UPDATE".
2282 */
2283 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF*) rr_activate_ind);
2284
2285 /* Track possible change of T3212 */
2286 mm_change_t3212 ();
2287
2288 mm_data->attempt_cnt = 0; /* GSM 04.08 subclause 4.4.4.5 */
2289
2290 #ifdef GPRS
2291 TIMERSTOP (T3211);
2292 TIMERSTOP (T3213);
2293 mm_data->t3213_restart = 0;
2294
2295 if (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED)
2296 {
2297 SET_STATE (STATE_REG_TYPE, REG_CELL_SEARCH_ONLY);
2298 }
2299 #endif /* GPRS */
2300
2301 mm_normal_loc_upd ();
2302 mm_mmgmm_activate_ind (MMGMM_WAIT_FOR_UPDATE);
2303 }
2304 } /* cell which may offer full service */
2305 break;
2306
2307 case MM_IDLE_LIMITED_SERVICE: /* 19.3 */
2308 case MM_IDLE_NO_CELL_AVAILABLE: /* 19.5 */
2309 switch (rr_activate_ind->op.service)
2310 {
2311 case LIMITED_SERVICE:
2312 mm_limited_from_rr ((T_RR_ACTIVATE_CNF*)rr_activate_ind);
2313 break;
2314
2315 case FULL_SERVICE:
2316 if (mm_handled_forb_plmn_cell (rr_activate_ind))
2317 {
2318 /*
2319 * The cell is a member of a forbidden list.
2320 */
2321 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
2322 mm_use_entry ();
2323 }
2324 else
2325 {
2326 mm_full_from_rr (rr_activate_ind);
2327 }
2328 break;
2329
2330 default: /* Either NO_SERVICE or other garbage */
2331 TRACE_ERROR (UNEXPECTED_DEFAULT);
2332 break;
2333 }
2334 break;
2335
2336 case MM_IDLE_PLMN_SEARCH: /* 19.7 */
2337 if (!mm_handled_forb_plmn_cell (rr_activate_ind))
2338 {
2339 /*
2340 * Cell is not in forbidden list, offering full service.
2341 */
2342 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF*) rr_activate_ind);
2343
2344 // Is it really for sure that an ACTIVATE IND in this state
2345 // cannot serve for more than limited service? Why?...
2346
2347 /* Inform GPRS about selected cell */
2348 mm_mmgmm_activate_ind (MMGMM_LIMITED_SERVICE);
2349
2350 if (mm_check_lai (&mm_data->mm.lai, &mm_data->reg.lai))
2351 reg_build_sim_update ();
2352
2353 switch (mm_data->reg.op.func)
2354 {
2355 case FUNC_LIM_SERV_ST_SRCH:
2356 reg_mm_success (LIMITED_SERVICE);
2357 mm_sim_set_imsi_marker( MSG_RR_ACT);
2358 break;
2359 }
2360 }
2361 break;
2362
2363 #ifdef GPRS
2364 case MM_IDLE_LUP_NEEDED: /* 19.6 */
2365 if (mm_handled_forb_plmn_cell (rr_activate_ind))
2366 {
2367 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
2368 }
2369 else
2370 {
2371 mm_copy_rr_act_cnf_data ((T_RR_ACTIVATE_CNF*) rr_activate_ind);
2372 /*
2373 * Cell maybe ok for full service, not forbidden PLMN
2374 */
2375 if (!mm_normal_upd_needed() AND !mm_attach_upd_needed())
2376 {
2377 /*
2378 * Back to old updated area, no IMSI ATTACH needed
2379 */
2380 mm_mmgmm_activate_ind (MMGMM_FULL_SERVICE);
2381 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
2382 }
2383 else
2384 {
2385 /*
2386 * Location updating procedure needed
2387 */
2388 mm_mmgmm_activate_ind (MMGMM_WAIT_FOR_UPDATE);
2389
2390 /* Remain in MM state MM_IDLE_LUP_NEEDED */
2391 }
2392 }
2393 break;
2394 #endif /* GPRS */
2395
2396 case MM_IDLE_NO_IMSI: /* 19.4 */
2397 /*
2398 * The mobile has no SIM and a cell change is indicated.
2399 * Service cannot be better than LIMITED_SERVICE without IMSI (SIM).
2400 */
2401 mm_limited_from_rr ((T_RR_ACTIVATE_CNF*)rr_activate_ind);
2402 break;
2403
2404 case MM_PLMN_SEARCH_NORMAL_SERVICE: /* 19.8 */
2405 /*
2406 * RR_ACTIVATE_REQ -> RR_ACTIVATE_IND -> RR_ABORT_IND (search result)
2407 * Best thing (which is not perfect anyway) here is to abort the
2408 * search requested by the MMI and to handle this in the previous state.
2409 * The user may get an empty list, but the RR_ACTIVATE_IND maybe
2410 * more important.
2411 */
2412
2413 /* Abort the search for the MMI */
2414 mm_data->reg.plmn_cnt = 0;
2415 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
2416
2417 /* Back to previous IDLE state */
2418 SET_STATE (STATE_MM, mm_data->idle_substate);
2419
2420 /* Restart the function in new state, avoid recursion, stack usage,
2421 * therefore the goto. */
2422 goto restart_function; /*lint !e801 goto*/
2423
2424 /*
2425 * Rare case: rr_activate_ind was received during call establishment for
2426 * emergency call and stored.
2427 * Stored rr_activate_ind shall remain stored until end of emergency call.
2428 */
2429 case MM_CONN_ACTIVE:
2430 /*
2431 * Rare case: 16868 rr_activate indication follows to RR_ABORT during a call.
2432 * Reestablishment was rejected because of unknown TI.
2433 * Should trigger an LUP after RR connection release if a new LAI is contained.
2434 * Stored rr_activate_ind shall remain stored.
2435 */
2436 case MM_WAIT_FOR_NW_CMD:
2437 mm_write_entry(NO_ENTRY, NO_ENTRY, NO_ENTRY, PRIMITIVE_ENTRY, rr_activate_ind, UNSPEC);
2438 return;
2439
2440 default:
2441 /*
2442 * MM_LUP_INITIATED, MM_WAIT_FOR_OUTG_MM_CONN,
2443 * MM_IMSI_DETACH_INIT, MM_PROCESS_PROMPT,
2444 * MM_LUP_REJECTED => Not expected cell selection in dedicated mode
2445 */
2446 TRACE_ERROR (UNEXPECTED_DEFAULT);
2447 break;
2448 }
2449 PFREE (rr_activate_ind);
2450 }
2451
2452 /*
2453 +--------------------------------------------------------------------+
2454 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
2455 | STATE : code ROUTINE : mm_rr_establish_cnf |
2456 +--------------------------------------------------------------------+
2457
2458 PURPOSE : Process the primitive RR_ESTABLISH_CNF.
2459
2460 */
2461
2462 GLOBAL void mm_rr_establish_cnf (T_RR_ESTABLISH_CNF *rr_establish_cnf)
2463 {
2464 GET_INSTANCE_DATA;
2465 TRACE_FUNCTION ("mmrr_establish_cnf()");
2466
2467 switch (GET_STATE (STATE_MM))
2468 {
2469 case MM_WAIT_FOR_RR_CONN_LUP:
2470 TIMERSTART (T3210, T_3210_VALUE);
2471 mm_data->ciphering_on = FALSE;
2472 SET_STATE (STATE_MM, MM_LUP_INITIATED);
2473 break;
2474
2475 case MM_WAIT_FOR_RR_CONN_MM:
2476 mm_data->ciphering_on = FALSE;
2477 mm_data->wait_for_accept = TRUE;
2478 SET_STATE (STATE_MM, MM_WAIT_FOR_OUTG_MM_CONN);
2479 TIMERSTART (T3230, T_3230_VALUE);
2480 break;
2481
2482 case MM_WAIT_FOR_REESTABLISH:
2483 mm_data->ciphering_on = FALSE;
2484 mm_data->wait_for_accept = TRUE;
2485 TIMERSTART (T3230, T_3230_VALUE);
2486 break;
2487
2488 case MM_WAIT_FOR_RR_CONN_DETACH:
2489 /*
2490 * RR connection for IMSI Detach has been established
2491 */
2492 TIMERSTART (T3220, T_3220_VALUE);
2493 /*
2494 * Wait for release by the infrastructure or timeout T3220
2495 * if the SIM card is removed.
2496 */
2497 SET_STATE (STATE_MM, MM_IMSI_DETACH_INIT);
2498 break;
2499
2500 default:
2501 /*
2502 * A RR_ESTABLISH_CNF is somewhat unexpected here, but we can try to
2503 * handle it by aborting the RR connection. But it is at least also
2504 * worth a TRACE.
2505 */
2506 mm_abort_connection (ABCS_NORM);
2507 TRACE_EVENT (UNEXPECTED_IN_STATE);
2508 break;
2509 }
2510 EM_RR_CONECTION_ESTABLISHED;
2511
2512 PFREE (rr_establish_cnf);
2513 }
2514
2515 /*
2516 +--------------------------------------------------------------------+
2517 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
2518 | STATE : code ROUTINE : mm_rr_establish_ind |
2519 +--------------------------------------------------------------------+
2520
2521 PURPOSE : Process the primitive RR_ESTABLISH_IND.
2522
2523 */
2524
2525 GLOBAL void mm_rr_establish_ind (T_RR_ESTABLISH_IND *rr_establish_ind)
2526 {
2527 GET_INSTANCE_DATA;
2528 TRACE_FUNCTION ("mm_rr_establish_ind()");
2529
2530 TIMERSTOP (T3240);
2531
2532 switch (GET_STATE (STATE_MM))
2533 {
2534 case MM_IDLE_PLMN_SEARCH:
2535 case MM_PLMN_SEARCH_NORMAL_SERVICE:
2536 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
2537 /*FALLTHROUGH*/
2538 //lint -fallthrough
2539 case MM_WAIT_FOR_RR_CONN_LUP:
2540 case MM_IDLE_NORMAL_SERVICE:
2541 case MM_IDLE_ATTEMPT_TO_UPDATE:
2542 case MM_IDLE_LIMITED_SERVICE:
2543 #ifdef GPRS
2544 case MM_IDLE_LUP_NEEDED:
2545 case MM_LOCATION_UPDATING_PENDING:
2546 mm_data->gprs.resumption = MMGMM_RESUMPTION_FAILURE;
2547 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK);
2548 #endif /* GPRS */
2549
2550 mm_data->idle_substate = mm_get_service_state ();
2551 mm_data->ciphering_on = FALSE;
2552 mm_data->rej_cause = 0;
2553 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
2554 break;
2555
2556 case MM_WAIT_FOR_RR_CONN_MM:
2557 /*
2558 * Clash. RR_ESTABLISH_IND was underway, in the
2559 * same moment RR_ESTABLISH_REQ was sent.
2560 * The RR_ESTABLISH_REQ is cancelled, the MT
2561 * establishment has the right of way.
2562 */
2563 #ifdef GPRS
2564 mm_data->gprs.resumption = MMGMM_RESUMPTION_FAILURE;
2565 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK);
2566 #endif /* GPRS */
2567
2568 if (mm_data->pend_conn.comp EQ SMS_COMP)
2569 {
2570 /*
2571 * In the clash a pending MO SMS is involved. Do not release the SMS
2572 * but store it until it can established again.
2573 * Note: This special treatment makes only sense for SMS.
2574 */
2575 TRACE_EVENT ("MO SMS clashed with MT");
2576 mm_write_entry (mm_data->pend_conn.comp,
2577 mm_data->pend_conn.ti,
2578 mm_data->pend_conn.cause,
2579 EVENT_ENTRY,
2580 NULL,
2581 UNSPEC);
2582 }
2583 else
2584 {
2585 /* Release all pending connections */
2586 mm_mmxx_rel_ind (MMCS_INT_PREEM, CM_PENDING);
2587 }
2588 mm_data->idle_substate = mm_get_service_state ();
2589 mm_data->ciphering_on = FALSE;
2590 mm_data->rej_cause = 0;
2591 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
2592 break;
2593
2594 /*
2595 case MM_WAIT_FOR_RR_CONN_MM:
2596 mm_abort_connection (ABCS_NORM);
2597 switch (mm_data->pend_conn.comp)
2598 {
2599 case CC_COMP:
2600 if (mm_data->pend_conn.prio EQ PRIO_NORM_CALL)
2601 {
2602 switch (mm_data->pend_conn.cause)
2603 {
2604 case ESTCS_MOB_ORIG_SPCH:
2605 case ESTCS_MOB_ORIG_DATA:
2606 case ESTCS_MOB_ORIG_DATA_HR_SUFF:
2607 mm_rr_est_req (mm_data->pend_conn.cause,
2608 CALL_SERVICE,
2609 mm_data->pend_conn.ti);
2610 break;
2611 }
2612 }
2613 else
2614 mm_rr_est_req (ESTCS_EMERGE, CALL_SERVICE,
2615 mm_data->pend_conn.ti);
2616 break;
2617 case SS_COMP:
2618 mm_rr_est_req (ESTCS_MOB_ORIG_CAL_BY_SS_SMS, SS_SERVICE,
2619 mm_data->pend_conn.ti);
2620 break;
2621 case SMS_COMP:
2622 mm_rr_est_req (ESTCS_MOB_ORIG_CAL_BY_SS_SMS, SMS_SERVICE,
2623 mm_data->pend_conn.ti);
2624 break;
2625 }
2626 break;
2627 */
2628
2629 case MM_WAIT_FOR_REESTABLISH:
2630 /*
2631 * Lost RR connection by a radio link failure and next thing which
2632 * happens is MT call establishment, just before the internal
2633 * communication after the radio link failure was completed.
2634 * This is not expected to happen, but if so, the MT call
2635 * has to be aborted. Maybe the incoming call ti is identical to a ti
2636 * for a call which has to be reestablished, this would lead to failure.
2637 */
2638 mm_abort_connection (ABCS_NORM);
2639 break;
2640
2641 default:
2642 break;
2643 }
2644 EM_RR_CONECTION_ESTABLISHED;
2645
2646 PFREE (rr_establish_ind);
2647 }
2648
2649 /*
2650 +--------------------------------------------------------------------+
2651 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
2652 | STATE : code ROUTINE : mm_rr_release_ind |
2653 +--------------------------------------------------------------------+
2654
2655 PURPOSE : Process the primitive RR_RELEASE_IND.
2656
2657 */
2658
2659 GLOBAL void mm_rr_release_ind (T_RR_RELEASE_IND *rr_release_ind)
2660 {
2661 GET_INSTANCE_DATA;
2662 TRACE_FUNCTION ("mm_rr_release_ind()");
2663
2664 /* Check for correct cause value */
2665 assert (GET_CAUSE_ORIGIN_ENTITY (rr_release_ind->cause) EQ
2666 RR_ORIGINATING_ENTITY);
2667
2668 #ifdef GPRS
2669 mm_data->gprs.resumption = rr_release_ind->gprs_resumption;
2670 #endif /* #ifdef GPRS */
2671
2672 switch (GET_STATE (STATE_MM))
2673 {
2674 case MM_LUP_INITIATED:
2675 if (mm_data->rej_cause EQ 0)
2676 mm_data->rej_cause = rr_release_ind->cause;
2677 TIMERSTOP (T3210);
2678 mm_mdl_rel_req ();
2679 mm_lup_restart ();
2680 break;
2681
2682 case MM_WAIT_FOR_OUTG_MM_CONN:
2683 case MM_WAIT_FOR_NW_CMD:
2684 #ifdef REL99
2685 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
2686 #endif
2687 case MM_WAIT_FOR_RR_CONN_MM:
2688
2689 EM_RR_CONNECTION_ESTABLISHED_2;
2690
2691 /*FALLTHROUGH*/
2692 //lint -fallthrough
2693 case MM_WAIT_FOR_REESTABLISH:
2694 if (rr_release_ind->cause NEQ RRCS_MO_MT_COLL)
2695 mm_mdl_rel_req ();
2696
2697 TIMERSTOP (T3230);
2698 TIMERSTOP (T3240);
2699 #ifdef REL99
2700 /*Stop timer t3241 if it is ruuning.
2701 *As per the spec 24.008, Timer T3241 is stopped and reset (but not started)
2702 *when the MM state RR CONNECTION RELEASE NOT ALLOWED is left.
2703 */
2704 TIMERSTOP(T3241);
2705 #endif
2706
2707 if (rr_release_ind->cause EQ RRCS_RND_ACC_FAIL AND
2708 mm_data->reg.op.sim_ins EQ SIM_INSRT AND
2709 mm_data->reg.op.ts EQ TS_NO_AVAIL AND
2710 mm_data->act_retrans NEQ 0 AND
2711 (mm_count_connections (CM_PENDING) NEQ 0 OR
2712 mm_count_connections (CM_REEST_PENDING) NEQ 0))
2713 {
2714 /*
2715 * start internal redial, if
2716 * - no TEST SIM
2717 * - SIM
2718 * - Cause <> random access failure
2719 * - retransmission counter <> 0
2720 * - at least one CM connection is pending
2721 */
2722 mm_data->act_retrans--;
2723 mm_rr_est_req (mm_data->pend_conn.cause,
2724 mm_data->pend_conn.service,
2725 mm_data->pend_conn.ti);
2726 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_CONN_MM);
2727 }
2728 else
2729 {
2730 /*
2731 * other cases: no internal redial
2732 */
2733 if (rr_release_ind->cause EQ RRCS_MO_MT_COLL)
2734 {
2735 if (mm_data->pend_conn.comp EQ SMS_COMP)
2736 {
2737 /*
2738 * Clash MO/MT, a pending MO SMS is involved. Do not release
2739 * the SMS but store it until it can be established again.
2740 * Note: This special treatment makes only sense for SMS.
2741 */
2742 TRACE_EVENT ("MO SMS clashed with MT");
2743 mm_write_entry (mm_data->pend_conn.comp,
2744 mm_data->pend_conn.ti,
2745 mm_data->pend_conn.cause,
2746 EVENT_ENTRY,
2747 NULL,
2748 UNSPEC);
2749 }
2750 else
2751 {
2752 /*
2753 * Clash MO/MT, no pending MO SMS is involved. Inform CM
2754 * about the release of the pending connection
2755 */
2756 mm_mmxx_rel_ind (rr_release_ind->cause, CM_PENDING);
2757 mm_mmxx_rel_ind (rr_release_ind->cause, CM_REEST_PENDING);
2758 }
2759
2760 /* Back to old Idle state without informing GMM about CM release */
2761 SET_STATE (STATE_MM, mm_data->idle_substate);
2762 }
2763 else /* if release_ind->cause */
2764 {
2765
2766 /* Commenting the OMAPS00048777 changes as it was a incomplete workaround.
2767 Refer the analysis section of the defect 71208 for details */
2768
2769 /*#ifdef GPRS
2770 if (mm_data->gprs.sim_physically_removed)
2771 {
2772 mm_data->nreg_cause = CS_SIM_REM;
2773 mm_create_imsi_detach_message ();
2774 for_est_req (ESTCS_MOB_ORIG_CAL_BY_SS_SMS, BSIZE_U_IMSI_DETACH_IND);
2775 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_CONN_DETACH);
2776 }
2777 else
2778 #endif
2779 {*/
2780 /*
2781 * No MO/MT clash. Inform CM and also GMM about release.
2782 * Release all connections except the stored connections.
2783 */
2784 mm_mmxx_rel_ind (rr_release_ind->cause, CM_PENDING);
2785 mm_mmxx_rel_ind (rr_release_ind->cause, CM_ACTIVE);
2786 mm_mmxx_rel_ind (rr_release_ind->cause, CM_REEST_PENDING);
2787
2788 /* Find IDLE state */
2789 mm_release_rr_connection (rr_release_ind->gprs_resumption);
2790 /* }*/
2791 } /* release cause <> collision */
2792 }
2793 break;
2794
2795 case MM_CONN_ACTIVE:
2796 case MM_PROCESS_PROMPT:
2797 {
2798 if (rr_release_ind->sapi NEQ SAPI_3)
2799 {
2800 /*
2801 * Release of main signalling link, release all.
2802 */
2803
2804 /* Manager DL release, kill layer 2 */
2805 mm_mdl_rel_req ();
2806
2807 TIMERSTOP (T3230);
2808 TIMERSTOP (T3240);
2809
2810 if ((rr_release_ind->cause EQ RRCS_NORM) AND
2811 (mm_count_connections (CM_PENDING) NEQ 0))
2812 {
2813 /*
2814 * This is state MM WAIT FOR ADD OUTG MM CONN.
2815 * MM_PROCESS_PROMPT is incompatible with the requestion of a new
2816 * MM connection, so we are not in this state here.
2817 * The RR connection was released by the network normally.
2818 * Assume a clash case and repeat the CM_SERVICE_REQUEST message
2819 * for the pending connection.
2820 */
2821 mm_mmxx_rel_ind (rr_release_ind->cause, CM_ACTIVE);
2822 mm_mmxx_rel_ind (rr_release_ind->cause, CM_REEST_PENDING);
2823
2824 mm_rr_est_req (mm_data->pend_conn.cause,
2825 mm_data->pend_conn.service,
2826 mm_data->pend_conn.ti);
2827 SET_STATE (STATE_MM, MM_WAIT_FOR_RR_CONN_MM);
2828 }
2829 else
2830 {
2831 /*
2832 * Inform CM about release.
2833 */
2834 mm_mmxx_rel_ind (rr_release_ind->cause, CM_PENDING);
2835 mm_mmxx_rel_ind (rr_release_ind->cause, CM_ACTIVE);
2836 mm_mmxx_rel_ind (rr_release_ind->cause, CM_REEST_PENDING);
2837
2838 /* Find IDLE state after MM connection */
2839 mm_release_rr_connection (rr_release_ind->gprs_resumption);
2840 }
2841 }
2842 else
2843 {
2844 /*
2845 * Only release of RR connection for SAPI = 3,
2846 * main signalling link not released.
2847 */
2848
2849 /*
2850 * Inform CM entity SMS about release. All SAPI 3 connections
2851 * are to be released to SMS (except the stored ones).
2852 */
2853 mm_mmsms_rel_ind (rr_release_ind->cause, CM_PENDING);
2854 mm_mmsms_rel_ind (rr_release_ind->cause, CM_ACTIVE);
2855 mm_mmsms_rel_ind (rr_release_ind->cause, CM_REEST_PENDING);
2856
2857 if (mm_count_connections (CM_ACTIVE) NEQ 0 OR
2858 mm_count_connections (CM_PENDING) NEQ 0)
2859 {
2860 /*
2861 * Some active or pending connections remaining for
2862 * SAPI NEQ 3, kill layer 2 only for SAPI = 3
2863 */
2864 mm_mdl_rel_req_sapi_3 ();
2865 }
2866 else
2867 {
2868 /*
2869 * No active or pending connections
2870 * remaining, manager release of layer 2.
2871 */
2872 mm_mdl_rel_req ();
2873
2874 TIMERSTOP (T3230);
2875 TIMERSTOP (T3240);
2876
2877 /* Find IDLE state after MM connection */
2878 mm_release_rr_connection (rr_release_ind->gprs_resumption);
2879 }
2880 }
2881 break;
2882 }
2883
2884 case MM_IMSI_DETACH_INIT:
2885 case MM_WAIT_FOR_RR_CONN_DETACH:
2886 mm_mdl_rel_req ();
2887 mm_mmgmm_cm_release_ind (rr_release_ind->gprs_resumption);
2888 mm_end_of_detach ();
2889 break;
2890
2891 case MM_LUP_REJECTED:
2892 mm_mdl_rel_req ();
2893 TIMERSTOP (T3240);
2894 mm_loc_upd_rej ();
2895 break;
2896
2897 case MM_WAIT_FOR_RR_CONN_LUP:
2898 mm_data->rej_cause = rr_release_ind->cause;
2899 mm_mdl_rel_req ();
2900 TIMERSTOP (T3210);
2901 switch (rr_release_ind->cause)
2902 {
2903 case RRCS_DL_EST_FAIL:
2904 /*
2905 * GSM 04.08 subclause 4.4.4.9 case d)
2906 * RR connection failure.
2907 */
2908 mm_data->rej_cause = RRCS_DL_EST_FAIL;
2909 mm_lup_restart ();
2910 break;
2911
2912 case RRCS_RND_ACC_FAIL:
2913 /*
2914 * GSM 04.08 subclause 4.4.4.9 case c)
2915 * Random access failure.
2916 */
2917 mm_data->rej_cause = RRCS_RND_ACC_FAIL;
2918 mm_data->idle_entry = RRCS_INT_NOT_PRESENT;
2919
2920 #ifdef WIN32
2921 TRACE_EVENT_P1 ("Last Rej Cause = %x", mm_data->last_rej_cause);
2922 #endif /* #ifdef WIN32 */
2923
2924 if (mm_data->last_rej_cause EQ RRCS_RND_ACC_FAIL)
2925 {
2926 mm_lup_restart ();
2927 }
2928 else
2929 {
2930 mm_data->last_rej_cause = RRCS_RND_ACC_FAIL;
2931 TIMERSTART (T3213, T_3213_VALUE);
2932 mm_data->t3213_restart = 0;
2933
2934 /*
2935 * It can be safely assumed that idle_substate here is either
2936 * MM_IDLE_NORMAL_SERVICE or MM_IDLE_ATTEMPT_TO_UPDATE
2937 */
2938 SET_STATE (STATE_MM, mm_data->idle_substate);
2939 }
2940 break;
2941
2942 case RRCS_ACCESS_BARRED:
2943 case RRCS_RND_ACC_DELAY:
2944 /*
2945 * GSM 04.08 subclause 4.4.4.9 case a)
2946 * Access barred because of access class control.
2947 * GSM 04.08 subclause 4.4.4.9 case b)
2948 * The answer to random access is an
2949 * IMMEDIATE ASSIGNMENT REJECT message.
2950 */
2951 mm_data->idle_entry = rr_release_ind->cause;
2952
2953 /*
2954 * It can be safely assumed that idle_substate here is either
2955 * MM_IDLE_NORMAL_SERVICE or MM_IDLE_ATTEMPT_TO_UPDATE
2956 */
2957 SET_STATE (STATE_MM, mm_data->idle_substate);
2958 break;
2959
2960 default: /* eg. RRCS_ABNORM_UNSPEC, RRCS_INT_NOT_PRESENT */
2961 mm_lup_restart ();
2962 break;
2963 }
2964 break;
2965
2966 default:
2967 /*
2968 * 19.x, MM_LOCATION_UPDATING_PENDING, MM_IMSI_DETACH_PENDING,
2969 * and all remaining MM states.
2970 */
2971
2972 /* Local end release of layer 2 */
2973 mm_mdl_rel_req ();
2974
2975 #ifdef GPRS
2976 /* Assume GMM sent GMMRR_CS_PAGE_RES (GMMRR_CS_PAGE_CNF).
2977 * This means CS services are (were) allowed. */
2978 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK);
2979
2980 /* Give CM control back to GMM */
2981 mm_mmgmm_cm_release_ind (rr_release_ind->gprs_resumption);
2982 #endif /* #ifdef GPRS */
2983
2984 USE_STORED_ENTRIES();
2985 break;
2986 }
2987
2988 #ifdef GPRS
2989 mm_data->gprs.resumption = MMGMM_RESUMPTION_FAILURE;
2990 #endif /* #ifdef GPRS */
2991
2992 PFREE (rr_release_ind);
2993 }
2994
2995
2996 /*
2997 +--------------------------------------------------------------------+
2998 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
2999 | STATE : code ROUTINE : mm_rr_sync_ind |
3000 +--------------------------------------------------------------------+
3001
3002 PURPOSE : Process the primitive RR_SYNC_IND.
3003
3004 */
3005
3006 GLOBAL void mm_rr_sync_ind (T_RR_SYNC_IND *rr_sync_ind)
3007 {
3008 GET_INSTANCE_DATA;
3009 BOOL t3212_changed;
3010
3011 TRACE_FUNCTION ("mm_rr_sync_ind()");
3012
3013 /* prevent the T3213 from restarting when it runs first time, but don't forget, that it is restarted if so */
3014 if (mm_data->t3213_restart EQ 0)
3015 {
3016 mm_data->t3213_restart = MAX_REST_T3213;
3017 }
3018
3019 /* Remember wheter a change in broadcasted value for T3212 was detected */
3020 t3212_changed = (rr_sync_ind->mm_info.valid EQ MM_INFO_PRES AND
3021 mm_data->mm.mm_info.t3212 NEQ rr_sync_ind->mm_info.t3212);
3022
3023 /*
3024 * Forward new BCCH information to the SIM application
3025 */
3026 if (rr_sync_ind->bcch_info.v_bcch EQ V_BCCH_PRES)
3027 {
3028 // Patch HM 14.03.01 >>>
3029 // memcpy (&mm_data->mm.bcch, &rr_sync_ind->bcch_info, SIZE_BCCH);
3030 memcpy (mm_data->mm.bcch, rr_sync_ind->bcch_info.bcch, SIZE_BCCH);
3031 // Patch HM 14.03.01 <<<
3032 if (memcmp(rr_sync_ind->bcch_info.bcch,mm_data->reg.bcch,SIZE_BCCH))
3033 {
3034 /* Set bit 2 in ef_indicator to indicate bcch_info change to SIM */
3035 mm_data->ef_indicator|=(0x01 << 1);
3036 }
3037 reg_build_sim_update ();
3038 PFREE (rr_sync_ind); //
3039 return; //
3040 }
3041
3042 /*
3043 * forwarding of ciphering indicator
3044 */
3045 if (rr_sync_ind->ciph NEQ CIPH_NOT_PRES)
3046 {
3047 if (rr_sync_ind->ciph NEQ mm_data->ciphering_on)
3048 {
3049 #ifdef GPRS /* GPRS supported, forward ciphering info for indicator to GMM */
3050 PALLOC (ciphering_ind,MMGMM_CIPHERING_IND);
3051 ciphering_ind->ciph = rr_sync_ind->ciph;
3052 PSENDX (GMM, ciphering_ind);
3053 #else /* GSM only case, forward ciphering info for indicator to ACI directly */
3054 PALLOC (ciphering_ind,MMR_CIPHERING_IND);
3055 ciphering_ind->ciph = rr_sync_ind->ciph;
3056 PSENDX (MMI, ciphering_ind);
3057 #endif /* GPRS */
3058 }
3059 }
3060
3061 switch (GET_STATE (STATE_MM))
3062 {
3063 case MM_LUP_INITIATED:
3064 if (rr_sync_ind->ciph NEQ CIPH_NOT_PRES)
3065 {
3066 mm_data->ciphering_on = rr_sync_ind->ciph;
3067 }
3068 break;
3069
3070 case MM_WAIT_FOR_OUTG_MM_CONN:
3071 if (rr_sync_ind->ciph NEQ CIPH_NOT_PRES)
3072 {
3073 mm_data->ciphering_on = rr_sync_ind->ciph;
3074 mm_data->error = FALSE;
3075 mm_cm_serv_accept ();
3076 }
3077
3078 if (rr_sync_ind->chm.ch_mode NEQ NOT_PRESENT_8BIT)
3079 {
3080 PALLOC (mmcm_sync_ind, MMCM_SYNC_IND); /* T_MMCM_SYNC_IND */
3081 mmcm_sync_ind->ti = 0;
3082 mmcm_sync_ind->sync_info.ch_info.ch_type = rr_sync_ind->chm.ch_type;
3083 mmcm_sync_ind->sync_info.ch_info.ch_mode = rr_sync_ind->chm.ch_mode;
3084 PSENDX (CC, mmcm_sync_ind);
3085
3086 }
3087 break;
3088
3089 case MM_CONN_ACTIVE:
3090 if (rr_sync_ind->chm.ch_mode NEQ NOT_PRESENT_8BIT)
3091 {
3092 PALLOC (mmcm_sync_ind, MMCM_SYNC_IND); /* T_MMCM_SYNC_IND */
3093 mmcm_sync_ind->ti = 0;
3094 mmcm_sync_ind->sync_info.ch_info.ch_type = rr_sync_ind->chm.ch_type;
3095 mmcm_sync_ind->sync_info.ch_info.ch_mode = rr_sync_ind->chm.ch_mode;
3096 PSENDX (CC, mmcm_sync_ind);
3097 }
3098 if (rr_sync_ind->ciph NEQ NOT_PRESENT_8BIT)
3099 {
3100 mm_data->ciphering_on = rr_sync_ind->ciph;
3101 if (mm_data->wait_for_accept)
3102 {
3103 mm_mmxx_est_cnf ();
3104 TIMERSTOP (T3230);
3105 mm_data->wait_for_accept = FALSE;
3106
3107 EM_CM_SERVICE_ACCEPTED(EM_COMMAND);
3108
3109 USE_STORED_ENTRIES();
3110 }
3111 }
3112 break;
3113
3114 case MM_PROCESS_PROMPT:
3115 if (rr_sync_ind->chm.ch_mode NEQ NOT_PRESENT_8BIT)
3116 {
3117 /* Channel mode modification, MMCM_SYNC_IND to CC */
3118 PALLOC (mmcm_sync_ind, MMCM_SYNC_IND); /* T_MMCM_SYNC_IND */
3119 mmcm_sync_ind->ti = 0;
3120 mmcm_sync_ind->sync_info.ch_info.ch_type = rr_sync_ind->chm.ch_type;
3121 mmcm_sync_ind->sync_info.ch_info.ch_mode = rr_sync_ind->chm.ch_mode;
3122 PSENDX (CC, mmcm_sync_ind);
3123
3124 }
3125
3126 if (rr_sync_ind->ciph NEQ NOT_PRESENT_8BIT)
3127 {
3128 /* Ciphering changed, remember this is MM data */
3129 mm_data->ciphering_on = rr_sync_ind->ciph;
3130 if (mm_count_connections (CM_ACTIVE) NEQ 0)
3131 {
3132 /*
3133 * In state MM_PROCESS PROMPT we cannot have
3134 * pending connections which are waiting
3135 * for CM SERVICE ACCEPT. This means, do nothing here.
3136 */
3137 }
3138 else
3139 {
3140 /*
3141 * No connection exists, behaviour like in state
3142 * of MM_WAIT_FOR_NW_CMD, restart T3240
3143 */
3144 TIMERSTART (T3240, T_3240_VALUE);
3145 }
3146 }
3147 break;
3148
3149 case MM_WAIT_FOR_NW_CMD:
3150 #ifdef REL99
3151 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
3152 #endif
3153 if (rr_sync_ind->chm.ch_mode NEQ NOT_PRESENT_8BIT)
3154 {
3155 PALLOC (mmcm_sync_ind, MMCM_SYNC_IND); /* T_MMCM_SYNC_IND */
3156 mmcm_sync_ind->ti = 0;
3157 mmcm_sync_ind->sync_info.ch_info.ch_type = rr_sync_ind->chm.ch_type;
3158 mmcm_sync_ind->sync_info.ch_info.ch_mode = rr_sync_ind->chm.ch_mode;
3159 PSENDX (CC, mmcm_sync_ind);
3160
3161 }
3162
3163 if (rr_sync_ind->ciph NEQ NOT_PRESENT_8BIT)
3164 {
3165 mm_data->ciphering_on = rr_sync_ind->ciph;
3166
3167 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
3168 {
3169 /*
3170 * T3212 is stopped if the first MM message is received, or
3171 * ciphering mode setting is completed in the case of MM
3172 * connection establishment, except when the most recent service
3173 * state is LIMITED SERVICE. [GSM 04.08 subclause 4.4.2]
3174 */
3175 TIMERSTOP (T3212);
3176 mm_data->t3212_timeout = FALSE;
3177 }
3178 #ifdef REL99
3179 if(TIMERACTIVE(T3241))
3180 {
3181 /*Do nothing*/
3182 }
3183 else
3184 #endif
3185 {
3186 /*restart timer T3240*/
3187 TIMERSTART (T3240, T_3240_VALUE);
3188 }
3189
3190 }
3191 break;
3192
3193 case MM_IDLE_NO_IMSI:
3194 /*
3195 * Add traces to see last reject cause for location updating reject and
3196 * the place where MM entered the MM_IDLE_NO_IMSI state.
3197 */
3198 TRACE_EVENT_P1 ("Last lup rej cause: %04x",
3199 mm_data->debug_last_rej_cause);
3200 TRACE_EVENT_P1 ("Entered state at %d",
3201 mm_data->mm_idle_no_imsi_marker);
3202 /*FALLTHROUGH*/
3203 //lint -fallthrough
3204 case MM_WAIT_FOR_RR_CONN_LUP:
3205 case MM_WAIT_FOR_RR_CONN_MM:
3206 case MM_WAIT_FOR_RR_CONN_DETACH:
3207 case MM_IDLE_LIMITED_SERVICE:
3208 if ((rr_sync_ind->mm_info.valid EQ MM_INFO_PRES) AND
3209 (mm_data->reg.lai.lac NEQ LAC_INVALID_VALUE))
3210 {
3211 mm_data->mm.mm_info = rr_sync_ind->mm_info; /* Structure copy */
3212
3213 if (t3212_changed)
3214 {
3215 // Maybe GMM is not interested either in T3212 if service state
3216 // is LIMITED SERVICE only, this should be checked...
3217 mm_mmgmm_t3212_val_ind ();
3218 }
3219 }
3220 break;
3221
3222 case MM_IDLE_NORMAL_SERVICE: /* 19.1 */
3223 if (rr_sync_ind->mm_info.valid EQ MM_INFO_PRES)
3224 {
3225 mm_data->mm.mm_info = rr_sync_ind->mm_info; /* Structure copy */
3226
3227 if (t3212_changed)
3228 {
3229 mm_mmgmm_t3212_val_ind ();
3230 mm_change_t3212 ();
3231 }
3232
3233 }
3234
3235 if ((rr_sync_ind->synccs EQ SYNCCS_ACC_CLS_CHA AND
3236 mm_data->idle_entry EQ RRCS_ACCESS_BARRED) OR
3237 (rr_sync_ind->synccs EQ SYNCCS_T3122_TIM_OUT AND
3238 mm_data->idle_entry EQ RRCS_RND_ACC_DELAY) OR
3239 (mm_data->t3213_restart > 0 AND
3240 mm_data->rej_cause EQ RRCS_RND_ACC_FAIL))
3241
3242 {
3243 mm_continue_running_update ();
3244 }
3245 break;
3246
3247 case MM_IDLE_ATTEMPT_TO_UPDATE:
3248 if (rr_sync_ind->mm_info.valid EQ MM_INFO_PRES)
3249 {
3250 mm_data->mm.mm_info = rr_sync_ind->mm_info; /* Structure copy */
3251
3252 if (t3212_changed)
3253 {
3254 mm_mmgmm_t3212_val_ind ();
3255 mm_change_t3212 ();
3256 }
3257
3258 }
3259
3260 if ((rr_sync_ind->synccs EQ SYNCCS_ACC_CLS_CHA AND
3261 mm_data->idle_entry EQ RRCS_ACCESS_BARRED) OR
3262 (rr_sync_ind->synccs EQ SYNCCS_T3122_TIM_OUT AND
3263 mm_data->idle_entry EQ RRCS_RND_ACC_DELAY) OR
3264 (mm_data->t3213_restart > 0 AND
3265 mm_data->rej_cause EQ RRCS_RND_ACC_FAIL))
3266 {
3267 mm_continue_running_update ();
3268 break;
3269 }
3270
3271 #if 0 /* This code causes failure on ALCATEL test cases */
3272 /* This registration attempt does not check the attempt counter*/
3273 /* and so can cause the MS to attempt more than 4 LUs to the network */
3274 if (rr_sync_ind->synccs EQ SYNCCS_LUP_RETRY)
3275 {
3276 if (mm_data->reg.op.sim_ins EQ SIM_INSRT AND
3277 mm_data->reg.op.ts EQ TS_NO_AVAIL)
3278 {
3279 /*
3280 * A SIM is inserted and it is no test SIM
3281 */
3282 if (mm_lup_allowed_by_gmm()) /*lint !e774*/
3283 {
3284 mm_normal_loc_upd ();
3285 }
3286 else
3287 {
3288 mm_mmgmm_lup_needed_ind (MMGMM_RXLEV_JUMP);
3289 /* No state change, MM remains in MM_IDLE_ATTEMPT_TO_UPDATE */
3290 }
3291 }
3292 }
3293 #endif
3294 break;
3295
3296 case MM_WAIT_FOR_REESTABLISH:
3297 if (rr_sync_ind->mm_info.re EQ RE_ALLOW)
3298 {
3299 /*
3300 * RR indicates a suitable cell for call reestablishment
3301 */
3302
3303 mm_data->reest_cell_avail = TRUE;
3304 // at least one connection has requested call reestablishment
3305 if (mm_data->reest_ti NEQ NOT_PRESENT_8BIT)
3306 mm_reest (mm_data->reest_ti);
3307 }
3308 else
3309 {
3310 /*
3311 * No support of call reestablishment
3312 */
3313
3314 mm_mmxx_rel_ind (MMCS_NO_REESTABLISH, CM_NOT_IDLE);
3315
3316 /* Find IDLE state after MM connection */
3317 mm_release_rr_connection(MMGMM_RESUMPTION_FAILURE);
3318 }
3319 break;
3320
3321 #ifdef GPRS
3322 case MM_IDLE_LUP_NEEDED: /* 19.6 */
3323 case MM_LOCATION_UPDATING_PENDING: /* 23 */
3324 case MM_IMSI_DETACH_PENDING: /* 24 */
3325 if (rr_sync_ind->mm_info.valid EQ MM_INFO_PRES)
3326 {
3327 mm_data->mm.mm_info = rr_sync_ind->mm_info; /* Structure copy */
3328
3329 if (t3212_changed)
3330 {
3331 mm_mmgmm_t3212_val_ind ();
3332 if (mm_get_service_state () NEQ MM_IDLE_LIMITED_SERVICE)
3333 mm_change_t3212 ();
3334 }
3335
3336 }
3337 break;
3338 #endif /* GPRS */
3339
3340 default:
3341 TRACE_EVENT (PRIMITIVE_IGNORED);
3342 break;
3343 }
3344 PFREE (rr_sync_ind);
3345 }
3346
3347 #if defined (FF_EOTD) AND defined (REL99)
3348
3349 /*
3350 +--------------------------------------------------------------------+
3351 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
3352 | STATE : code ROUTINE : mm_rr_rrlp_start_ind |
3353 +--------------------------------------------------------------------+
3354
3355 PURPOSE : Process the primitive mm_rr_rrlp_start_ind.
3356
3357 */
3358
3359 GLOBAL void mm_rr_rrlp_start_ind (T_RR_RRLP_START_IND *rr_rrlp_start_ind)
3360 {
3361 GET_INSTANCE_DATA;
3362 TRACE_FUNCTION ("mm_rr_rrlp_start_ind()");
3363 /*
3364 *set rrlp_lcs_started flag to true
3365 */
3366 mm_data->rrlp_lcs_started = TRUE;
3367 switch (GET_STATE (STATE_MM))
3368 {
3369 case MM_WAIT_FOR_NW_CMD:
3370 TIMERSTOP(T3240);
3371 TIMERSTART(T3241, T_3241_VALUE);
3372 SET_STATE (STATE_MM, MM_RR_CONN_RELEASE_NOT_ALLOWED);
3373 break;
3374
3375 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
3376 TIMERSTOP(T3241);
3377 TIMERSTART(T3241, T_3241_VALUE);
3378 break;
3379
3380 default :
3381 break;
3382 }
3383 PFREE (rr_rrlp_start_ind);
3384 }
3385
3386
3387 /*
3388 +--------------------------------------------------------------------+
3389 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
3390 | STATE : code ROUTINE : mm_rr_rrlp_stop_ind |
3391 +--------------------------------------------------------------------+
3392
3393 PURPOSE : Process the primitive mm_rr_rrlp_stop_ind.
3394
3395 */
3396
3397 GLOBAL void mm_rr_rrlp_stop_ind (T_RR_RRLP_STOP_IND *rr_rrlp_stop_ind)
3398 {
3399 GET_INSTANCE_DATA;
3400 TRACE_FUNCTION ("mm_rr_rrlp_stop_ind()");
3401 /*
3402 *set rrlp_lcs_started flag to false
3403 */
3404 mm_data->rrlp_lcs_started = FALSE;
3405 switch (GET_STATE (STATE_MM))
3406 {
3407 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
3408 TIMERSTOP(T3241);
3409 TIMERSTART(T3240, T_3240_VALUE);
3410 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
3411 break;
3412
3413 default :
3414 break;
3415 }
3416 PFREE (rr_rrlp_stop_ind);
3417 }
3418
3419 #endif /* (FF_EOTD) AND defined (REL99) */
3420 /*
3421 +--------------------------------------------------------------------+
3422 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
3423 | STATE : code ROUTINE : mm_mmcm_prompt_rej |
3424 +--------------------------------------------------------------------+
3425
3426 PURPOSE : Process the primitive MMCM_PROMPT_REJ.
3427
3428 */
3429
3430 GLOBAL void mm_mmcm_prompt_rej (T_MMCM_PROMPT_REJ *prompt_rej)
3431 {
3432 GET_INSTANCE_DATA;
3433 TRACE_FUNCTION ("mm_mmcm_prompt_rej()");
3434
3435 switch (GET_STATE (STATE_MM))
3436 {
3437 case MM_PROCESS_PROMPT:
3438 /* Send MM STATUS with cause #34 */
3439 {
3440 /* Implements Measure 29 and streamline encoding */
3441 mm_send_status(RC_SERVICE_ORDER);
3442 }
3443
3444 if ((mm_count_connections (CM_ACTIVE) NEQ 0) OR
3445 (mm_count_connections (CM_PENDING) NEQ 0))
3446 {
3447 /* This is not standardized in GSM 4.08, but
3448 without returning to state MM_CONN_ACTIVE
3449 some MSCs in GSM 04.93 don't make sense. */
3450 SET_STATE (STATE_MM, MM_CONN_ACTIVE);
3451 }
3452 else
3453 {
3454 #if defined (FF_EOTD) AND defined (REL99)
3455 if(mm_data->rrlp_lcs_started EQ TRUE)
3456 {
3457 TIMERSTART(T3241,T_3241_VALUE);
3458 SET_STATE(STATE_MM, MM_RR_CONN_RELEASE_NOT_ALLOWED);
3459 }
3460 else
3461 #endif /* (FF_EOTD) AND defined (REL99) */
3462 {
3463 TIMERSTART (T3240, T_3240_VALUE);
3464 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
3465 }
3466 }
3467 break;
3468
3469 default:
3470 break;
3471 }
3472 PFREE (prompt_rej);
3473 }
3474
3475 /*
3476 +--------------------------------------------------------------------+
3477 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
3478 | STATE : code ROUTINE : mm_mmcm_prompt_res |
3479 +--------------------------------------------------------------------+
3480
3481 PURPOSE : Process the primitive MMCM_PROMPT_RES.
3482
3483 */
3484
3485 GLOBAL void mm_mmcm_prompt_res (T_MMCM_PROMPT_RES *prompt_res)
3486 {
3487 GET_INSTANCE_DATA;
3488 TRACE_FUNCTION ("mm_mmcm_prompt_res()");
3489
3490 switch (GET_STATE (STATE_MM))
3491 {
3492 case MM_PROCESS_PROMPT:
3493 TIMERSTOP (T3240);
3494 CM_SET_STATE (CC_COMP, prompt_res->ti, CM_ACTIVE);
3495 SET_STATE (STATE_MM, MM_CONN_ACTIVE);
3496 break;
3497 default:
3498 /* MM cannot do anything (anymore) with the ti, send MMCM_RELEASE_IND */
3499 mm_mmxx_release_ind (CC_COMP, prompt_res->ti, MMCS_INT_NOT_PRESENT);
3500 break;
3501 }
3502 PFREE (prompt_res);
3503 }
3504
3505 /*
3506 +--------------------------------------------------------------------+
3507 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
3508 | STATE : code ROUTINE : mm_mmcm_ss_sms_data_req |
3509 +--------------------------------------------------------------------+
3510
3511 PURPOSE : This function unifies mm_mmcm_data_req(), mm_mmss_data_req()
3512 and mm_mmsms_data_req().
3513 */
3514
3515 LOCAL void mm_mmcm_ss_sms_data_req (T_VOID_STRUCT *mm_data_req)
3516 {
3517 GET_INSTANCE_DATA;
3518 TRACE_FUNCTION ("mm_mmcm_ss_sms_data_req()");
3519 switch (GET_STATE (STATE_MM))
3520 {
3521 case MM_WAIT_FOR_OUTG_MM_CONN:
3522 case MM_CONN_ACTIVE:
3523 case MM_PROCESS_PROMPT:
3524 case MM_WAIT_FOR_NW_CMD:
3525 {
3526 PPASS (mm_data_req, rr_data_req, RR_DATA_REQ);
3527 for_cm_message (rr_data_req);
3528 break;
3529 }
3530 default:
3531 PFREE (mm_data_req);
3532 break;
3533 }
3534 }
3535
3536 /*
3537 +--------------------------------------------------------------------+
3538 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
3539 | STATE : code ROUTINE : mm_sim_insrt_state |
3540 +--------------------------------------------------------------------+
3541
3542 PURPOSE : This function sets the parameter mm_idle_no_imsi_marker
3543 depending on the selector imsi_marker.
3544
3545 */
3546 GLOBAL void mm_sim_set_imsi_marker (T_MSG_TYPE imsi_marker)
3547 {
3548 GET_INSTANCE_DATA;
3549 TRACE_FUNCTION ("mm_sim_set_imsi_marker()");
3550 if (mm_data->reg.op.sim_ins EQ SIM_INSRT)
3551 {
3552 /* Valid SIM inserted */
3553 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
3554 }
3555 else
3556 {
3557 /* Find original place where MM entered MM_IDLE_NO_IMSI state >>> */
3558 if (mm_data->mm_idle_no_imsi_marker EQ 0)
3559 {
3560 if ( imsi_marker EQ MSG_RR_ACT)
3561 mm_data->mm_idle_no_imsi_marker = 13;
3562 else
3563 mm_data->mm_idle_no_imsi_marker = 3;
3564 }
3565 /* End of debugging patch <<< */
3566 /* Invalid SIM inserted */
3567 SET_STATE (STATE_MM, MM_IDLE_NO_IMSI);
3568 }
3569 }
3570
3571 /*
3572 +--------------------------------------------------------------------+
3573 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
3574 | STATE : code ROUTINE : mm_sim_insrt_state |
3575 +--------------------------------------------------------------------+
3576
3577 PURPOSE : This function sets the MM state depending on the SIM INSERT
3578 status.
3579
3580 */
3581 LOCAL void mm_sim_insert_state (void)
3582 {
3583 GET_INSTANCE_DATA;
3584 TRACE_FUNCTION ("mm_sim_insert_state()");
3585 if (mm_data->reg.op.sim_ins EQ SIM_INSRT)
3586 {
3587 /* SIM present */
3588 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
3589 }
3590 else
3591 {
3592 /* SIM not present */
3593 SET_STATE (STATE_MM, MM_IDLE_NO_IMSI);
3594 }
3595 }
3596
3597 /*
3598 +--------------------------------------------------------------------+
3599 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
3600 | STATE : code ROUTINE : mm_rr_abort_cell_sel_fail |
3601 +--------------------------------------------------------------------+
3602
3603 PURPOSE : This function processes RR_ABORT_IND
3604
3605 */
3606 LOCAL void mm_rr_abort_cell_sel_fail (T_RR_ABORT_IND *rr_abort_ind)
3607 {
3608 GET_INSTANCE_DATA;
3609 TRACE_FUNCTION ("mm_rr_abort_cell_sel_fail()");
3610 if (rr_abort_ind->cause EQ RRCS_ABORT_CEL_SEL_FAIL)
3611 {
3612 TIMERSTOP (T3211);
3613 TIMERSTOP (T3213);
3614 mm_data->t3213_restart = 0;
3615 mm_mmxx_rel_ind (rr_abort_ind->cause, CM_NOT_IDLE);
3616 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
3617 if (rr_abort_ind->op.service EQ NO_SERVICE)
3618 {
3619 SET_STATE (STATE_MM, MM_IDLE_NO_CELL_AVAILABLE);
3620 }
3621 else
3622 {
3623 SET_STATE (STATE_MM, MM_IDLE_LIMITED_SERVICE);
3624 }
3625 reg_rr_failure (rr_abort_ind);
3626 }
3627 }
3628
3629
3630 #endif