comparison src/g23m-gsm/mm/mm_gprs.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS (8410)
4 | Modul : MM_GPRS.C
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 module defines the functions which are necessary
18 | to process requests from GMM in MM.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef MM_GMM_C
23 #define MM_GMM_C
24
25 #define ENTITY_MM
26
27 /*==== INCLUDES ===================================================*/
28
29 #include <string.h>
30 #include "typedefs.h"
31 #include "pconst.cdg"
32 #include "message.h"
33 #include "ccdapi.h"
34 #include "vsi.h"
35 #include "custom.h"
36 #include "gsm.h"
37 #include "prim.h"
38 #include "cnf_mm.h"
39 #include "mon_mm.h"
40 #include "pei.h"
41 #include "tok.h"
42 #include "mm.h"
43
44 #ifdef GPRS
45
46 /*==== EXPORT ==============================================================*/
47
48 /*==== TEST ================================================================*/
49
50 /*==== PRIVAT ==============================================================*/
51
52 /*==== VARIABLES ===========================================================*/
53
54 /*==== FUNCTIONS ===========================================================*/
55
56 /*
57 +----------------------------------------------------------------------------+
58 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
59 | STATE : code ROUTINE : mm_gprs_update_req |
60 +----------------------------------------------------------------------------+
61
62 PURPOSE : This function performs an remote controlled, by GMM initiatiated
63 location update
64
65 */
66
67 GLOBAL void mm_gprs_update_req (void)
68 {
69 GET_INSTANCE_DATA;
70 restart_function:
71
72 TRACE_FUNCTION ("mm_gprs_update_req()");
73
74 mm_data->gprs.resumption = MMGMM_RESUMPTION_FAILURE;
75
76 switch (GET_STATE (STATE_MM))
77 {
78 case MM_WAIT_FOR_OUTG_MM_CONN:
79 case MM_WAIT_FOR_RR_CONN_MM:
80 case MM_WAIT_FOR_RR_ACTIVE:
81 mm_data->attempt_cnt = 0; /* Just to be safe */
82 /* Save the event as outstanding periodic update */
83 mm_data->t3212_timeout = TRUE;
84 break;
85
86 case MM_IDLE_NORMAL_SERVICE: /* 19.1 */
87 case MM_LOCATION_UPDATING_PENDING:
88 case MM_IMSI_DETACH_PENDING:
89 /*
90 * As MM had no knowledge that a LOCATION UPDATING is necessary,
91 * it can only be a periodic location updating or an unnecessary
92 * trigger for an IMSI attach location updating.
93 */
94 if (mm_data->first_attach)
95 {
96 assert (mm_data->mm.mm_info.att EQ ATT_NOT_ALLOW);
97
98 /*
99 * Start BCCH with broadcasted value. It could be discussed
100 * it the better time would have been after RR_ACTIVATE_IND.
101 */
102 mm_start_t3212_bcch();
103
104 mm_data->first_attach_mem = mm_data->first_attach;
105 mm_data->first_attach = FALSE;
106
107 mm_mmgmm_reg_cnf ();
108 }
109 else
110 {
111 /*
112 * GMM should not trigger a periodic location updating
113 * if this is not announced by the cell, but anyway, it does not
114 * do any harm to check this condition here.
115 */
116 if (mm_data->mm.mm_info.t3212 NEQ T3212_NO_PRD_UPDAT)
117 {
118 mm_data->attempt_cnt = 0; /* Just to be safe */
119 mm_periodic_loc_upd ();
120 }
121 else
122 {
123 mm_mmgmm_reg_cnf ();
124 }
125 }
126 break;
127
128 case MM_IDLE_ATTEMPT_TO_UPDATE: /* 19.2 */
129 mm_data->attempt_cnt = 0; // Patch HM 14-Feb-02, GSM 11.10 44.2.1.2.8
130 mm_normal_loc_upd ();
131 break;
132
133 case MM_IDLE_LIMITED_SERVICE: /* 19.3 */
134 if (mm_data->reg.op.m EQ M_MAN)
135 {
136 mm_data->attempt_cnt = 0;
137 mm_normal_loc_upd ();
138 }
139 else
140 {
141 TRACE_EVENT ("GMM triggered invalid update, not done.");
142 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
143 SEARCH_NOT_RUNNING,
144 FORB_PLMN_NOT_INCLUDED);
145 }
146 break;
147
148 case MM_IDLE_NO_IMSI: /* 19.4 */
149 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
150 SEARCH_NOT_RUNNING,
151 FORB_PLMN_NOT_INCLUDED);
152 break;
153
154 case MM_IDLE_NO_CELL_AVAILABLE: /* 19.5 */
155 mm_mmgmm_nreg_ind (NREG_NO_SERVICE,
156 SEARCH_NOT_RUNNING,
157 FORB_PLMN_NOT_INCLUDED);
158 break;
159
160 case MM_IDLE_LUP_NEEDED: /* 19.6 */
161 /*
162 * Start location update procedure in remote controlled form,
163 * the type of location update may be NORMAL_LUP or IMSI_ATTACH_LUP.
164 * MM already knows from the state that it needs a remote controlled
165 * location updating.
166 */
167 if (!mm_normal_upd_needed ())
168 {
169 /* Send fake MMGMM_LUP_ACCEPT_IND to indicate the full service
170 * condition already (which is a fact if only IMSI ATTACH needed). */
171 mm_mmgmm_lup_accept_ind ();
172
173 mm_data->attempt_cnt = 0; /* Power on, SIM inserted */
174 mm_attach_loc_upd ();
175 }
176 else
177 {
178 mm_data->attempt_cnt = 0; /* Change of LA detected */
179 mm_normal_loc_upd ();
180 }
181 break;
182
183 case MM_IDLE_PLMN_SEARCH: /* 19.7 */
184 if (mm_data->idle_substate EQ MM_IDLE_NO_CELL_AVAILABLE)
185 {
186 mm_mmgmm_nreg_ind (NREG_NO_SERVICE,
187 SEARCH_NOT_RUNNING,
188 FORB_PLMN_NOT_INCLUDED);
189 break;
190 }
191 /*FALLTHROUGH*/
192 //lint -fallthrough
193 case MM_PLMN_SEARCH_NORMAL_SERVICE: /* 19.8 */
194 /* Scan aborted, notify MMI */
195 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
196
197 /* Back to previous, non-searching IDLE substate */
198 SET_STATE (STATE_MM, mm_data->idle_substate);
199
200 /* Restart the function in new state, avoid recursion, stack usage */
201 goto restart_function;
202
203 default:
204 TRACE_EVENT (UNEXPECTED_IN_STATE);
205 break;
206 }
207 }
208
209
210 /*
211 +----------------------------------------------------------------------------+
212 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
213 | STATE : code ROUTINE : mm_func_mmgmm_auth_rej_req |
214 +----------------------------------------------------------------------------+
215
216 PURPOSE : This function handles the MMGMM_AUTH_REJ_REQ primitive.
217 MMGMM_AUTH_REJ_REQ indicates MM that the authentication procedure
218 performed by GMM is rejected by the network. For further details,
219 see GSM 04.08 subclause 4.3.2.5.
220
221 */
222
223 GLOBAL void mm_func_mmgmm_auth_rej_req (void)
224 {
225 GET_INSTANCE_DATA;
226 TRACE_FUNCTION ("mm_func_mmgmm_auth_rej_req()");
227
228 switch (GET_STATE (STATE_MM))
229 {
230 case MM_IDLE_NORMAL_SERVICE:
231 case MM_IDLE_ATTEMPT_TO_UPDATE:
232 case MM_IDLE_LIMITED_SERVICE:
233 case MM_IDLE_NO_IMSI:
234 case MM_IDLE_NO_CELL_AVAILABLE:
235 case MM_IDLE_LUP_NEEDED:
236 case MM_IDLE_PLMN_SEARCH:
237 case MM_PLMN_SEARCH_NORMAL_SERVICE:
238 case MM_LOCATION_UPDATING_PENDING:
239 case MM_IMSI_DETACH_PENDING:
240 /* Release all calls, can only be stored calls */
241 mm_mmxx_rel_ind (MMCS_NO_REGISTRATION, CM_NOT_IDLE);
242
243 /*
244 * Upon receipt of an AUTHENTICATION REJECT message, the mobile station
245 * shall set the update status in the SIM to U2 ROAMING NOT ALLOWED,
246 * delete from the SIM the stored TMSI, LAI and ciphering key sequence
247 * number. [GSM 04.08 subclause 4.3.2.5]
248 */
249 #ifdef REL99
250 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED, FALSE);
251 #else
252 reg_invalidate_upd_state (MS_LA_NOT_ALLOWED);
253 #endif
254
255 /* Delete IMSI - consider SIM as invalid */
256 mm_clear_mob_ident (&mm_data->reg.imsi_struct);
257 mm_clear_reg_data ();
258
259 /* Inform RR about invalidation */
260 mm_build_rr_sync_req_cause (SYNCCS_TMSI_CKSN_KC_INVAL_NO_PAG);
261
262 /* Set new MM main state */
263 SET_STATE (STATE_MM, MM_IDLE_NO_IMSI);
264 break;
265
266 default: /* No IDLE state */
267 /*
268 * This means: Either this is an internal protocol error or we are
269 * performing circuit switched and packed switched operations in
270 * parallel. MM does not handle this. As it seems so that
271 * the networks will never support this it makes no sense to handle it.
272 */
273 TRACE_ERROR (UNEXPECTED_IN_STATE);
274 break;
275 }
276 }
277
278
279 /*
280 +----------------------------------------------------------------------------+
281 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
282 | STATE : code ROUTINE : mm_func_mmgmm_cm_establish_res |
283 +----------------------------------------------------------------------------+
284
285 PURPOSE : This function handles the MMGMM_CM_ESTABLISH_RES primitive.
286 MMGMM_CM_ESTABLISH_RES confirms the establish request.
287
288 */
289
290 GLOBAL void mm_func_mmgmm_cm_establish_res (UBYTE cm_establish_res)
291 {
292 GET_INSTANCE_DATA;
293 TRACE_FUNCTION ("mm_func_mmgmm_cm_establish_res()");
294
295 switch (GET_STATE (STATE_GPRS_CM_EST))
296 {
297 case CM_GPRS_EST_PEND: /* Normal case */
298 break;
299
300 case CM_GPRS_EST_OK: /* Clash MO/MT, special case */
301 TRACE_EVENT ("MO/MT clash");
302 return;
303
304 default:
305 TRACE_ERROR ("Unexpected STATE_GPRS_CM_EST");
306 break;
307 }
308
309 if (cm_establish_res EQ MMGMM_ESTABLISH_OK)
310 {
311 mm_data->gprs.resumption = MMGMM_RESUMPTION_FAILURE;
312
313 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK);
314
315 if (mm_count_connections (CM_NOT_IDLE) EQ 0)
316 {
317 /*
318 * In the meantime, all the stored connections have been cleared
319 * Worst case assumption: MMGMM_RESUMPTION_FAILURE.
320 */
321 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
322 }
323 else
324 {
325 /*
326 * Now all the stored establish requests may be performed
327 */
328 USE_STORED_ENTRIES();
329 }
330 }
331 else /* cm_establish_res EQ MMGMM_ESTABLISH_REJECT */
332 {
333 /* Clear outstanding MMGMM_CM_ESTABLISH_IND */
334 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_IDLE);
335
336 /* Release all connections, there can only be stored connections */
337 mm_mmxx_rel_ind (MMCS_INT_NOT_PRESENT, CM_NOT_IDLE);
338 }
339 }
340
341
342 /*
343 +----------------------------------------------------------------------------+
344 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
345 | STATE : code ROUTINE : mm_func_mmgmm_cm_emergency_res |
346 +----------------------------------------------------------------------------+
347
348 PURPOSE : This function handles the MMGMM_CM_EMERGENCY_RES primitive.
349 MMGMM_CM_EMERGENCY_RES confirms the establish request.
350
351 */
352
353 GLOBAL void mm_func_mmgmm_cm_emergency_res (UBYTE cm_establish_res)
354 {
355 GET_INSTANCE_DATA;
356 TRACE_FUNCTION ("mm_func_mmgmm_cm_emergency_res()");
357
358 switch (GET_STATE (STATE_GPRS_CM_EST))
359 {
360 case CM_GPRS_EST_PEND: /* Normal case */
361 case CM_GPRS_EMERGE_PEND:
362 break;
363
364 case CM_GPRS_EST_OK: /* Clash MO/MT, special case */
365 TRACE_EVENT ("MO/MT clash");
366 return;
367
368 default:
369 TRACE_ERROR ("Unexpected STATE_GPRS_CM_EST");
370 break;
371 }
372
373 if (cm_establish_res EQ MMGMM_ESTABLISH_OK)
374 {
375 mm_data->gprs.resumption = MMGMM_RESUMPTION_FAILURE;
376
377 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_OK);
378
379 if (mm_count_connections (CM_NOT_IDLE) EQ 0)
380 {
381 /*
382 * In the meantime, all the stored connections have been cleared
383 * Worst case assumption: MMGMM_RESUMPTION_FAILURE.
384 */
385 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
386 }
387 else
388 {
389 /*
390 * Now all the stored establish requests can be performed
391 */
392 USE_STORED_ENTRIES();
393 }
394 }
395 else /* cm_establish_res EQ MMGMM_EMERGENCY_REJECT */
396 {
397 /* Clear outstanding MMGMM_CM_ESTABLISH_IND */
398 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_IDLE);
399
400 /* Release all connections, there can only be stored connections */
401 mm_mmxx_rel_ind (MMCS_INT_NOT_PRESENT, CM_NOT_IDLE);
402 }
403 }
404
405
406 /*
407 +----------------------------------------------------------------------------+
408 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
409 | STATE : code ROUTINE : mm_func_attach_started_req |
410 +----------------------------------------------------------------------------+
411
412 PURPOSE : This function handles the MMGMM_ATTACH_STARTED_REQ primitive.
413 GMM indicates MM that GMM starts the combined attach procedure.
414 This implies also network mode I.
415
416 */
417
418 GLOBAL void mm_func_mmgmm_attach_started_req (void)
419 {
420 GET_INSTANCE_DATA;
421 TRACE_FUNCTION ("mm_func_mmgmm_attach_started_req()");
422
423 switch (GET_STATE (STATE_MM))
424 {
425 case MM_IDLE_LUP_NEEDED:
426 assert (GET_STATE (STATE_REG_TYPE) EQ REG_CELL_SEARCH_ONLY);
427 /*FALLTHROUGH*/
428 //lint -fallthrough
429 case MM_IDLE_NORMAL_SERVICE:
430 case MM_IDLE_ATTEMPT_TO_UPDATE:
431 case MM_IDLE_LIMITED_SERVICE:
432 case MM_PLMN_SEARCH_NORMAL_SERVICE:
433 case MM_LOCATION_UPDATING_PENDING:
434 case MM_IMSI_DETACH_PENDING:
435
436 /* IMSI present physically */
437 assert (mm_data->reg.imsi_struct.v_mid EQ V_MID_PRES AND
438 !mm_data->gprs.sim_physically_removed);
439
440 /* Revalidate SIM data */
441 mm_data->reg.op.sim_ins = SIM_INSRT;
442
443 /* Prevent MM specific procedures (location updating/detach) */
444 SET_STATE (STATE_REG_TYPE, REG_CELL_SEARCH_ONLY);
445
446 /*
447 * A GPRS MS operating in mode A or B in a network that operates in
448 * mode I should not use any MM timers relating to MM specific
449 * procedures, (e.g T3210, T3211, T3212, T3213) except in some error
450 * and abnormal cases. If the MM timers are already running, the MS
451 * should not react on the expiration of the timers.
452 *
453 * NOTE 2: Whenever GMM performs a combined GMM procedure,
454 * a GPRS MS enters the MM state MM LOCATION UPDATING PENDING in order
455 * to prevent the MM to perform a location update procedure.
456 *
457 * [GSM 04.08 subclause 4.1.1.2.1,
458 * GPRS MS operating in mode A or B in a network that operates in mode I]
459 */
460
461 /*
462 * As GMM sends the primitive MMGMM_ATTACH_STARTED_REQ if it begins a combined
463 * attach procedure, MM is cautious not to stop any timer here already.
464 * This is left up to the reception of MMGMM_ATTACH_ACC_REQ.
465 */
466
467 /*
468 * LOCATION UPDATING PENDING
469 *
470 * A location updating has been started using the combined
471 * GPRS routing area updating procedure.
472 *
473 * [GSM 04.08 subclause 4.1.2.1.1, Main states]
474 */
475
476 /* Remember service state */
477 mm_data->idle_substate = mm_get_service_state ();
478
479 //
480 // MM_LOCATION_UPDATING_PENDING is a superflous state.
481 // Don't enter it.
482 //
483 //SET_STATE (STATE_MM, MM_LOCATION_UPDATING_PENDING);
484 break;
485
486 default:
487 TRACE_ERROR (UNEXPECTED_IN_STATE);
488 break;
489 }
490 }
491
492
493 /*
494 +----------------------------------------------------------------------------+
495 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
496 | STATE : code ROUTINE : mm_attach_acc |
497 +----------------------------------------------------------------------------+
498
499 PURPOSE : This function handles the MMGMM_ATTACH_ACC_REQ primitive.
500 GMM informs MM about the successfull combined attach procedure
501 and sends the new TMSI, if available, to MM.
502 This implies also network mode I.
503
504 */
505
506 LOCAL void mm_attach_acc (const T_plmn *plmn,
507 USHORT lac,
508 UBYTE v_mobile_identity,
509 ULONG mobile_identity,
510 UBYTE v_equ_plmn_list,
511 const T_equ_plmn_list *equ_plmn_list)
512 {
513 GET_INSTANCE_DATA;
514 BOOL eplmn_changed;
515
516 TRACE_FUNCTION ("mm_attach_acc()");
517
518 /* All other conditions are an internal protocol failure here */
519 assert (GET_STATE (STATE_REG_TYPE) EQ REG_CELL_SEARCH_ONLY);
520
521 /* It is not specified that MM has to confirm a MMGMM_ATTACH_ACC_REQ,
522 * GMM is informed about full service condition */
523 mm_data->reg.full_service_indicated = TRUE;
524
525 /* Remember IMSI ATTACH has been done. */
526 if (mm_data->first_attach)
527 {
528 mm_data->first_attach_mem = mm_data->first_attach;
529 mm_data->first_attach = FALSE;
530 }
531
532 /* Remember MM was attached by combined attach/detach procedures */
533 mm_data->gprs.combined_procedures = TRUE;
534 mm_data->reg.update_stat = MS_UPDATED;
535 mm_data->rej_cause = 0;
536 mm_data->attempt_cnt = 0;
537 mm_data->loc_upd_type.lut = NOT_RUNNING;
538
539 if (memcmp(mm_data->reg.lai.mnc, plmn->mnc, SIZE_MNC) OR memcmp (mm_data->reg.lai.mcc, plmn->mcc, SIZE_MCC) OR (mm_data->reg.lai.lac NEQ lac))
540 {
541 /* EF LOCI value has changed, hence write it on SIM */
542 /* EF Indicator for EF LOCI - bit 1 - changed value from Attach Accept msg*/
543 mm_data->ef_indicator|=0x01;
544 }
545 /* Copy PLMN and LAC into registration data */
546 memcpy (mm_data->reg.lai.mnc, plmn->mnc, SIZE_MNC);
547 memcpy (mm_data->reg.lai.mcc, plmn->mcc, SIZE_MCC);
548 mm_data->reg.lai.lac = lac;
549
550 if (v_mobile_identity EQ MMGMM_TMSI_USED)
551 {
552 /* Remember GMM's TMSI to avoid unnecessary synchronization */
553 mm_data->reg.indicated_tmsi = mobile_identity;
554
555 if (mobile_identity NEQ mm_data->reg.tmsi)
556 {
557 /* EF LOCI value has changed, hence write it on SIM */
558 /* EF Indicator for EF LOCI - bit 1 - changed value from Attach Accept msg*/
559 mm_data->ef_indicator|=0x01;
560 }
561 if (mobile_identity NEQ MMGMM_TMSI_INVALID)
562 {
563 mm_data->reg.tmsi = mobile_identity;
564
565 /* Inform RR about changed TMSI */
566 mm_build_rr_sync_req_tmsi ();
567 }
568 else
569 {
570 mm_data->reg.tmsi = TMSI_INVALID_VALUE;
571
572 /* Inform RR about invalidation of TMSI */
573 mm_build_rr_sync_req_cause (SYNCCS_TMSI_INVAL);
574 }
575 }
576
577 /* Remove the PLMN from the "forbidden PLMN" list */
578 reg_plmn_bad_del (mm_data->reg.forb_plmn, MAX_FORB_PLMN_ID, plmn);
579
580 /* Remove the PLMN from the "forbidden PLMNs for GPRS service" list */
581 reg_plmn_bad_del (mm_data->reg.gprs_forb_plmn, MAX_GPRS_FORB_PLMN_ID, plmn);
582
583 /* Send RR_SYNC_REQ (Location Area allowed) */
584 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW);
585
586 /* This is a nasty hack to process 'equ_plmn_list'. The function 'reg_store_eqv_plmns'
587 * can only take a 'T_eqv_plmn_list' Currently 'T_equ_plmn_list' is identical to 'T_eqv_plmn_list'
588 * in all but name hence making the casting OK, **for now**. This problem needs to be adressed
589 * in the air interface document.
590 */
591 if (v_equ_plmn_list)
592 eplmn_changed = reg_store_eqv_plmns((T_eqv_plmn_list *)equ_plmn_list, (T_plmn *)plmn);
593 else
594 eplmn_changed = reg_clear_plmn_list (mm_data->reg.eqv_plmns.eqv_plmn_list, EPLMNLIST_SIZE);
595
596 /* Send RR_SYNC_REQ (equivalent plmn list changed) */
597 if(eplmn_changed)
598 mm_build_rr_sync_req_cause (SYNCCS_EPLMN_LIST);
599
600 /* Inform SIM */
601 reg_build_sim_update ();
602
603 /*
604 * We assume the network has updated us for the currently selected cell,
605 * otherwise we will run into trouble.
606 */
607 assert (mm_check_lai (&mm_data->reg.lai, &mm_data->mm.lai));
608
609 /* Stop all timers used for MM specific procedures */
610 TIMERSTOP (T3210);
611 TIMERSTOP (T3211);
612 TIMERSTOP (T3212);
613 mm_data->t3212_timeout = FALSE;
614
615 TIMERSTOP (T3213);
616 mm_data->t3213_restart = 0;
617 }
618
619
620
621 /*
622 +----------------------------------------------------------------------------+
623 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
624 | STATE : code ROUTINE : mm_func_attach_acc_req |
625 +----------------------------------------------------------------------------+
626
627 PURPOSE : This function handles the MMGMM_ATTACH_ACC_REQ primitive.
628 GMM informs MM about the successfull combined attach procedure
629 and sends the new TMSI, if available, to MM.
630 This implies also network mode I.
631
632 */
633
634 GLOBAL void mm_func_mmgmm_attach_acc_req (const T_plmn *plmn,
635 USHORT lac,
636 UBYTE v_mobile_identity,
637 ULONG mobile_identity,
638 UBYTE v_equ_plmn_list,
639 const T_equ_plmn_list *equ_plmn_list)
640 {
641 GET_INSTANCE_DATA;
642 TRACE_FUNCTION ("mm_func_mmgmm_attach_acc_req()");
643
644 switch (GET_STATE (STATE_MM))
645 {
646 case MM_IDLE_NORMAL_SERVICE: /* 19.1 */
647 case MM_IDLE_ATTEMPT_TO_UPDATE: /* 19.2 */
648 case MM_IDLE_LIMITED_SERVICE: /* 19.3 */
649 case MM_IDLE_LUP_NEEDED: /* 19.6 */
650 case MM_LOCATION_UPDATING_PENDING:
651 case MM_IMSI_DETACH_PENDING:
652 mm_attach_acc (plmn, lac, v_mobile_identity, mobile_identity, v_equ_plmn_list, equ_plmn_list);
653
654 SET_STATE (STATE_MM, MM_IDLE_NORMAL_SERVICE);
655 USE_STORED_ENTRIES();
656 break;
657
658 case MM_IDLE_PLMN_SEARCH: /* 19.7 */
659 mm_attach_acc (plmn, lac, v_mobile_identity, mobile_identity, v_equ_plmn_list, equ_plmn_list);
660
661 SET_STATE (STATE_MM, MM_PLMN_SEARCH_NORMAL_SERVICE);
662 USE_STORED_ENTRIES();
663 break;
664
665 case MM_PLMN_SEARCH_NORMAL_SERVICE: /* 19.8 */
666 mm_attach_acc (plmn, lac, v_mobile_identity, mobile_identity, v_equ_plmn_list, equ_plmn_list);
667 break;
668
669 default:
670 TRACE_ERROR (UNEXPECTED_IN_STATE);
671 break;
672 }
673
674 /* Check HPLMN timer state */
675 reg_check_hplmn_tim (mm_data->reg.thplmn);
676
677 }
678
679
680 /*
681 +----------------------------------------------------------------------------+
682 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
683 | STATE : code ROUTINE : mm_func_mmgmm_allowed_req |
684 +----------------------------------------------------------------------------+
685
686 PURPOSE : This function handles the MMGMM_ALLOWED_REQ primitive.
687 GMM informs MM that the attach procedure was accepted by the
688 network, but for GPRS services only. MM doesn't perform a state
689 change (especially GSM does not become idle updated on the cell
690 by receiving this event), but the location area is removed from
691 all forbidden lists.
692
693 */
694
695 GLOBAL void mm_func_mmgmm_allowed_req (UBYTE v_equ_plmn_list, const T_equ_plmn_list *equ_plmn_list)
696 {
697 GET_INSTANCE_DATA;
698 T_plmn plmn;
699 BOOL eplmn_changed;
700
701 TRACE_FUNCTION ("mm_mmgmm_allowed_req()");
702
703 /* Fill up the PLMN structure from the camped cell data */
704 plmn.v_plmn = V_PLMN_PRES;
705 memcpy (plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC);
706 memcpy (plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC);
707
708 /* Remove the PLMN from the "forbidden PLMN" list */
709 reg_plmn_bad_del (mm_data->reg.forb_plmn, MAX_FORB_PLMN_ID, &plmn);
710
711 /* Remove the PLMN from the "forbidden PLMNs for GPRS service" list */
712 reg_plmn_bad_del (mm_data->reg.gprs_forb_plmn, MAX_GPRS_FORB_PLMN_ID, &plmn);
713
714 /* Send RR_SYNC_REQ (Location Area allowed) */
715 mm_build_rr_sync_req_cause (SYNCCS_LAI_ALLOW);
716
717 /* This is a nasty hack to process 'equ_plmn_list'. The function 'reg_store_eqv_plmns'
718 * can only take a 'T_eqv_plmn_list' Currently 'T_equ_plmn_list' is identical to 'T_eqv_plmn_list'
719 * in all but name hence making the casting OK, for now. This problem needs to be adressed
720 * in the air interface document.
721 */
722 if (v_equ_plmn_list)
723 eplmn_changed = reg_store_eqv_plmns((T_eqv_plmn_list *)equ_plmn_list, (T_plmn *)&plmn);
724 else
725 eplmn_changed = reg_clear_plmn_list (mm_data->reg.eqv_plmns.eqv_plmn_list, EPLMNLIST_SIZE);
726
727 /* Send RR_SYNC_REQ (equivalent plmn list changed) */
728 if(eplmn_changed)
729 mm_build_rr_sync_req_cause (SYNCCS_EPLMN_LIST);
730
731 /* Update SIM */
732 reg_build_sim_update ();
733
734 /* Check HPLMN timer state */
735 reg_check_hplmn_tim (mm_data->reg.thplmn);
736 }
737
738
739 /*
740 +----------------------------------------------------------------------------+
741 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
742 | STATE : code ROUTINE : mm_func_mmgmm_attach_rej_req |
743 +----------------------------------------------------------------------------+
744
745 PURPOSE : This function handles the MMGMM_ATTACH_REJ_REQ primitive.
746 GMM informs MM that the attach procedure was rejected by the
747 network with the given reject cause. According to the given
748 cause action in MM is taken. For further details, see
749 GSM 04.08 subclause 4.7.3.1.4
750
751 See also the GSM functions mm_lup_rej() and mm_loc_upd_rej().
752
753 This does *not* imply network mode I here, also other network
754 modes are possible here. MM need not have received the
755 MMGMM_ATTACH_STARTED_REQ message.
756
757 */
758
759 GLOBAL void mm_func_mmgmm_attach_rej_req (USHORT cs) /* T_MMGMM_ATTACH_REJ_REQ */
760 {
761 GET_INSTANCE_DATA;
762 TRACE_FUNCTION ("mm_func_mmgmm_attach_rej_req()");
763
764 TRACE_EVENT_P1 (" cs = %d", cs);
765
766 /* All other conditions is an internal protocol failure here */
767 assert (GET_STATE (STATE_REG_TYPE) EQ REG_CELL_SEARCH_ONLY);
768
769 /* Check for correct originating entity */
770 assert (GET_CAUSE_ORIGIN_ENTITY (cs) EQ
771 GMM_ORIGINATING_ENTITY);
772
773 if (cs EQ GMMCS_GPRS_NOT_ALLOWED)
774 {
775 /* List of forbidden PLMNs for GPRS services has no meaning anymore */
776 reg_clear_plmn_list (mm_data->reg.gprs_forb_plmn, MAX_GPRS_FORB_PLMN_ID);
777
778 return; /* No further impact on GSM side */
779 }
780
781 switch (GET_STATE (STATE_MM))
782 {
783 case MM_NULL: /* MM is off, do nothing */
784 break;
785
786 case MM_LUP_INITIATED:
787 case MM_WAIT_FOR_OUTG_MM_CONN:
788 case MM_CONN_ACTIVE:
789 case MM_IMSI_DETACH_INIT:
790 case MM_PROCESS_PROMPT:
791 case MM_WAIT_FOR_NW_CMD:
792 #ifdef REL99
793 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
794 #endif
795 case MM_LUP_REJECTED:
796 case MM_WAIT_FOR_RR_CONN_LUP:
797 case MM_WAIT_FOR_RR_CONN_MM:
798 case MM_WAIT_FOR_RR_CONN_DETACH:
799 case MM_WAIT_FOR_REESTABLISH:
800 /* Abort to RR */
801 mm_abort_connection (ABCS_NORM);
802 /*FALLTHROUGH*/
803 //lint -fallthrough
804 default: /* These states have no existing or requested RR connection */
805 /* Release all connections to CM */
806 mm_mmxx_rel_ind (cs, CM_NOT_IDLE);
807
808 /* CM control back to GMM */
809 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_OK);
810
811 mm_data->rej_cause = cs;
812
813 /*
814 * Set the attempt counter to the maximal possible value. This will
815 * ensure no own location updating attempt will be scheduled and MM
816 * will enter the state MM_IDLE_ATTEMPT_TO_UPDATE if an unspecified
817 * cause has been received by the network.
818 * An exception is GMMCS_GPRS_NOT_ALLOWED_IN_PLMN which shall
819 * not have any influence for GSM (except that the PLMN in question
820 * has to be added to the forbidden list for GPRS services).
821 */
822 if (mm_data->rej_cause NEQ GMMCS_GPRS_NOT_ALLOWED_IN_PLMN)
823 mm_data->attempt_cnt = 4;
824
825 mm_loc_upd_rej ();
826 break;
827 }
828 }
829
830
831 /*
832 +----------------------------------------------------------------------------+
833 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
834 | STATE : code ROUTINE : mm_func_mmgmm_detach_started_req |
835 +----------------------------------------------------------------------------+
836
837 PURPOSE : This function handles the MMGMM_DETACH_STARTED_REQ primitive.
838 GMM indicates MM that GMM starts the detach procedure for GSM.
839 MM has to enter state MM_IMSI_DETACH_PENDING.
840 See GSM 04.08 subclause 4.7.4.1.
841 The reception of this primitive is only possible if network mode I,
842 this means, combined procedures are performed.
843
844 */
845
846 GLOBAL void mm_func_mmgmm_detach_started_req (void)
847 {
848 GET_INSTANCE_DATA;
849 TRACE_FUNCTION ("mm_func_mmgmm_detach_started_req()");
850
851 /* Reception of this primitive is a protocol failure if GSM is alone. */
852 assert (!mm_gsm_alone());
853
854 /* Remember combinded detach */
855 mm_data->gprs.combined_procedures = TRUE;
856
857 switch (GET_STATE (STATE_MM))
858 {
859 case MM_NULL: /* MM is off, do nothing */
860 case MM_IMSI_DETACH_PENDING: /* State already entered, do nothing */
861 break;
862
863 case MM_LUP_INITIATED:
864 case MM_WAIT_FOR_OUTG_MM_CONN:
865 case MM_CONN_ACTIVE:
866 case MM_IMSI_DETACH_INIT:
867 case MM_PROCESS_PROMPT:
868 case MM_WAIT_FOR_NW_CMD:
869 #ifdef REL99
870 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
871 #endif
872 case MM_LUP_REJECTED:
873 case MM_WAIT_FOR_RR_CONN_LUP:
874 case MM_WAIT_FOR_RR_CONN_MM:
875 case MM_WAIT_FOR_RR_CONN_DETACH:
876 case MM_WAIT_FOR_REESTABLISH:
877 /* Abort to RR */
878 mm_abort_connection (ABCS_NORM);
879 /*FALLTHROUGH*/
880 //lint -fallthrough
881 default: /* These states have no existing or requested RR connection */
882 /* Release all connections to CM */
883 mm_mmxx_rel_ind (MMCS_NO_REGISTRATION, CM_NOT_IDLE);
884
885 /* Prevent MM specific procedures (location updating/detach) */
886 SET_STATE (STATE_REG_TYPE, REG_CELL_SEARCH_ONLY);
887
888 /* Stop all possibly running MM timers */
889 TIMERSTOP (T3210);
890 TIMERSTOP (T3211);
891 TIMERSTOP (T3212);
892 mm_data->t3212_timeout = FALSE;
893 TIMERSTOP (T3213);
894 mm_data->t3213_restart = 0;
895 TIMERSTOP (T3220);
896 TIMERSTOP (T3230);
897 TIMERSTOP (T3240);
898
899 /* Remember service state */
900 mm_data->idle_substate = mm_get_service_state ();
901
902 /* Enter state MM_IMSI_DETACH_PENDING */
903 //
904 // MM_IMSI_DETACH_PENDING is a superflous state. Don't enter it.
905 //
906 //SET_STATE (STATE_MM, MM_IMSI_DETACH_PENDING);
907 break;
908 }
909 }
910
911
912 /*
913 +----------------------------------------------------------------------------+
914 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
915 | STATE : code ROUTINE : mm_func_mmgmm_start_t3212_req |
916 +----------------------------------------------------------------------------+
917
918 PURPOSE : This function handles the MMGMM_START_T3212_REQ primitive.
919 MMGMM_START_T3212_REQ indicates that GPRS is now detached after
920 combined attach state in network mode I.
921 MM has to start its own timer T3212 with the broadcasted value.
922
923 */
924
925 GLOBAL void mm_func_mmgmm_start_t3212_req (void)
926 {
927 GET_INSTANCE_DATA;
928 T_TIME t3212_time;
929
930 TRACE_FUNCTION ("mm_func_mmgmm_start_t3212_req()");
931
932 /* Reception of this primitive is a protocol failure if GSM is alone. */
933 assert (!mm_gsm_alone());
934
935 /*
936 * If the detach type information element value indicates "GPRS detach
937 * without switching off" and the MS is attached for GPRS and non-GPRS
938 * services and the network operates in network operation mode I, then
939 * if in the MS the timer T3212 is not already running, the timer T3212
940 * shall be set to its initial value and restarted after the
941 * DETACH REQUEST message has been sent.
942 * [GSM 04.08 subclause 4.7.4.1.1,
943 * MS initiated detach procedure initiation]
944 */
945
946 /*
947 * If the detach type information element value indicates "re-attach
948 * required" or "re-attach not required" and the MS is attached for GPRS
949 * and non-GPRS services and the network operates in network operation
950 * mode I, then if in the MS the timer T3212 is not already running,
951 * the timer T3212 shall be set to its initial value and restarted.
952 * [GSM 04.08 subclause 4.7.4.2.2,
953 * Network initiated GPRS detach procedure completion by the MS]
954 */
955
956 /*
957 * One thing is for sure: MM is not (anymore) attached by combined
958 * procedures if its own T3212 is running. On the other hand, GSM
959 * is not alone, but still performs its operation with GMM.
960 */
961 mm_data->gprs.combined_procedures = FALSE;
962
963 /*
964 * Start timer T3212 with broadcasted value.
965 */
966 if (mm_data->t3212_cfg_counter NEQ 0 AND
967 mm_data->mm.mm_info.t3212 NEQ 0)
968 t3212_time = mm_data->t3212_cfg_counter;
969 else
970 t3212_time = mm_data->mm.mm_info.t3212 * 36;
971
972 if (t3212_time NEQ 0)
973 {
974 TIMERSTART (T3212, t3212_time * T_T3212_TIC_VALUE);
975 }
976 else
977 {
978 TIMERSTOP (T3212); /* No periodic update timer */
979 }
980 }
981
982 #if 0
983 /*
984 +----------------------------------------------------------------------------+
985 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
986 | STATE : code ROUTINE : mm_func_mmgmm_trigger_req |
987 +----------------------------------------------------------------------------+
988
989 PURPOSE : Goal of this function is to ensure that the remaining
990 time before expiracy of the T_HPLMN timer is long enough.
991 Used to prevent from aborting a data transfer because of
992 a PLMN reselection.
993
994 */
995
996 GLOBAL void mm_func_mmgmm_trigger_req (void)
997 {
998 TRACE_FUNCTION ("mm_func_mmgmm_trigger_req()");
999
1000 /* Check if running first */
1001 if (TIMERACTIVE(T_HPLMN))
1002 {
1003 T_TIME remaining_time;
1004
1005 vsi_t_status (VSI_CALLER T_HPLMN, &remaining_time);
1006
1007 /* Check if THPLMN is close from expiracy */
1008 if (remaining_time <= TICS_PER_DECIHOURS)
1009 {
1010 TRACE_EVENT("Kick HPLMN timer");
1011 reg_stop_hplmn_tim(); /* Not restarted if already running */
1012 /* if (mm_full_service_pplmn_scan())
1013 */
1014 reg_check_hplmn_tim (1); /* Expiry not before 6 minutes */
1015 }
1016 }
1017 }
1018 #endif
1019
1020 /*
1021 +----------------------------------------------------------------------------+
1022 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1023 | STATE : code ROUTINE : mm_network_initiated_detach |
1024 +----------------------------------------------------------------------------+
1025
1026 PURPOSE : This function handles the network initiated detach received
1027 by GMM and signalled to MM by using the MMGMM_NREG_REQ primitive
1028 with cs EQ CS_DISABLE.
1029
1030 */
1031
1032 void mm_network_initiated_detach (USHORT cs)
1033 {
1034 GET_INSTANCE_DATA;
1035 TRACE_FUNCTION ("mm_network_initiated_detach()");
1036
1037 switch (GET_STATE (STATE_MM))
1038 {
1039 case MM_NULL:
1040 /* No further action required */
1041 mm_mmgmm_nreg_cnf (mm_data->nreg_cause);
1042 break;
1043
1044 case MM_LUP_INITIATED:
1045 case MM_CONN_ACTIVE:
1046 case MM_IMSI_DETACH_INIT:
1047 case MM_PROCESS_PROMPT:
1048 case MM_WAIT_FOR_NW_CMD:
1049 #ifdef REL99
1050 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1051 #endif
1052 case MM_LUP_REJECTED:
1053 /*
1054 * States where the mobile has a layer 2 connection
1055 */
1056
1057 /*
1058 * The problem with that all is the following:
1059 * If we read GSM 04.08, subclause 4.7.4.2, it is not described
1060 * what to do with a dedicated layer 2 connection.
1061 * Entering state MM_WAIT_FOR_NW_CMD and wait for either CHANNEL RELEASE
1062 * message in RR or for T3240 expiry in MM is not possible as it violates
1063 * the standard, entering MM_IDLE state is requested.
1064 * So the only way to get rid of an MM connection is a local release
1065 * before entering MM_IDLE state.
1066 * This is not described in GSM 04.08, subclause 4.7.4.2.
1067 * Also is not described what to do with (pending) CM connections, compare
1068 * this with the stardadization of the abort procedure (GSM 04.08, 4.3.5).
1069 * The conclusion of this all is: It is either not foreseen or
1070 * not yet standardized. So it still cannot be implemented in a
1071 * standard conformant way. Class A is for further study in MM, really.
1072 */
1073
1074 /*FALLTHROUGH*/
1075 case MM_WAIT_FOR_OUTG_MM_CONN:
1076 case MM_WAIT_FOR_RR_CONN_LUP:
1077 case MM_WAIT_FOR_RR_CONN_MM:
1078 case MM_WAIT_FOR_RR_CONN_DETACH:
1079 case MM_WAIT_FOR_REESTABLISH:
1080 case MM_WAIT_FOR_RR_ACTIVE:
1081 /*
1082 * States where the mobile has a layer 2 connection requested
1083 */
1084 TRACE_ERROR (UNEXPECTED_IN_STATE);
1085 break;
1086
1087 case MM_IDLE_NORMAL_SERVICE:
1088 case MM_LOCATION_UPDATING_PENDING:
1089 case MM_IMSI_DETACH_PENDING:
1090 case MM_IDLE_ATTEMPT_TO_UPDATE:
1091 case MM_IDLE_LIMITED_SERVICE:
1092 case MM_IDLE_NO_IMSI:
1093 case MM_IDLE_NO_CELL_AVAILABLE:
1094 case MM_IDLE_LUP_NEEDED:
1095 case MM_IDLE_PLMN_SEARCH:
1096 case MM_PLMN_SEARCH_NORMAL_SERVICE:
1097 /* Release all connections with appropriate cause to CM */
1098 mm_mmxx_rel_ind (cs, CM_NOT_IDLE);
1099
1100 /* Inform GMM */
1101 mm_mmgmm_cm_release_ind (MMGMM_RESUMPTION_FAILURE);
1102
1103 /* Handle the request of GMM like an location updating reject */
1104 mm_data->rej_cause = cs;
1105 mm_loc_upd_rej ();
1106 break;
1107
1108 default:
1109 /* All states caught, this means trouble */
1110 TRACE_ERROR (UNEXPECTED_DEFAULT);
1111 break;
1112 }
1113 }
1114
1115
1116 /*
1117 +----------------------------------------------------------------------------+
1118 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
1119 | STATE : code ROUTINE : mm_sim_removed_gprs_active |
1120 +----------------------------------------------------------------------------+
1121
1122 PURPOSE : This function handles the case that the SIM is removed when GPRS
1123 is active. An IMSI DETACH cannot be done immediately as MM has no
1124 knowledge about the network mode in the current design (which is
1125 regarded as a disadvantage for this case). All calls are thrown
1126 out and all update activities are to be stopped.
1127
1128 */
1129
1130 GLOBAL void mm_sim_removed_gprs_active (void)
1131 {
1132 GET_INSTANCE_DATA;
1133 TRACE_FUNCTION ("mm_sim_removed_gprs_active()");
1134
1135 /* Remember the cause for limited service */
1136 mm_data->limited_cause = MMCS_SIM_REMOVED;
1137
1138 /* Release all CM connections to upper layers */
1139 mm_mmxx_rel_ind (MMCS_NO_REGISTRATION, CM_NOT_IDLE);
1140
1141 /* Stop all running update timers and running attempts */
1142 TIMERSTOP (T_REGISTRATION);
1143 TIMERSTOP (T3210);
1144 TIMERSTOP (T3211);
1145 TIMERSTOP (T3212);
1146 TIMERSTOP (T3213);
1147 mm_data->t3213_restart = 0;
1148 mm_data->loc_upd_type.lut = NOT_RUNNING;
1149 mm_data->idle_entry = RRCS_INT_NOT_PRESENT;
1150
1151 switch (GET_STATE (STATE_MM))
1152 {
1153 /* Dedicated or dedicated requested states */
1154 case MM_LUP_INITIATED:
1155 case MM_WAIT_FOR_OUTG_MM_CONN:
1156 case MM_CONN_ACTIVE:
1157 case MM_IMSI_DETACH_INIT:
1158 case MM_PROCESS_PROMPT:
1159 case MM_WAIT_FOR_NW_CMD:
1160 #ifdef REL99
1161 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
1162 #endif
1163 case MM_LUP_REJECTED:
1164 case MM_WAIT_FOR_RR_CONN_LUP:
1165 case MM_WAIT_FOR_RR_CONN_MM:
1166 case MM_WAIT_FOR_RR_CONN_DETACH:
1167 /* Abort RR connection */
1168 mm_abort_connection (ABCS_NORM);
1169
1170 /* No state change, wait for RR_RELEASE_IND in old state */
1171 break;
1172
1173 default: /* All other states, especially IDLE states */
1174 if (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED)
1175 {
1176 /* Indicate end of RC update to GMM */
1177 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
1178 SEARCH_NOT_RUNNING,
1179 FORB_PLMN_NOT_INCLUDED);
1180 }
1181 break;
1182 }
1183 }
1184
1185 #endif /* GPRS */
1186
1187 #endif /* MM_GPRS_C */