comparison g23m-gsm/mm/mm_mmp.c @ 0:75a11d740a02

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