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