FreeCalypso > hg > freecalypso-citrine
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 |