comparison gsm-fw/g23m-gsm/mm/mm_regs.c @ 673:2f7df7a314f8

gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 23:20:04 +0000
parents
children 832e5506c598
comparison
equal deleted inserted replaced
672:0dc6f9e8e980 673:2f7df7a314f8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS (8410)
4 | Modul : MM_REGS
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 registration
18 | capability of the module Mobility Managemant.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef MM_REGS_C
23 #define MM_REGS_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
49 #else
50
51 #include <string.h>
52 #include <stdlib.h>
53 #include <stddef.h>
54 #include "stddefs.h"
55 #include "pcm.h"
56 #include "pconst.cdg"
57 #include "mconst.cdg"
58 #include "message.h"
59 #include "ccdapi.h"
60 #include "custom.h"
61 #include "gsm.h"
62 #include "prim.h"
63 #include "cnf_mm.h"
64 #include "mon_mm.h"
65 #include "vsi.h"
66 #include "pei.h"
67 #include "tok.h"
68 #include "mm.h"
69
70 #endif
71 /*==== EXPORT =====================================================*/
72
73 /*==== PRIVAT =====================================================*/
74
75 /*==== VARIABLES ==================================================*/
76
77 /*==== FUNCTIONS ==================================================*/
78
79 /*==== TEST =====================================================*/
80
81 /*
82 * -------------------------------------------------------------------
83 * SIGNAL Processing functions
84 * -------------------------------------------------------------------
85 */
86
87 /*
88 +--------------------------------------------------------------------+
89 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
90 | STATE : code ROUTINE : reg_mmr_auth_ind |
91 +--------------------------------------------------------------------+
92
93 PURPOSE : Process the signal MMR_AUTH_IND.
94
95 */
96
97 GLOBAL void reg_mmr_auth_ind (T_SIM_AUTHENTICATION_REQ *sim_auth_req)
98 {
99 GET_INSTANCE_DATA;
100 MCAST (auth_req, D_AUTH_REQ);
101 TRACE_FUNCTION ("reg_mmr_auth_ind()");
102
103 if(mm_data->last_auth_req_id != NOT_PRESENT_8BIT)
104 {
105 mm_data->last_auth_req_id++;
106 }
107 else
108 {
109 mm_data->last_auth_req_id = 0;
110 }
111
112 sim_auth_req->source = SRC_MM;
113 sim_auth_req->req_id = mm_data->last_auth_req_id;
114 sim_auth_req->cksn = auth_req->ciph_key_num.key_seq;
115 memcpy (sim_auth_req->rand, auth_req->auth_rand.rand,
116 sizeof (sim_auth_req->rand));
117 PSENDX (SIM, sim_auth_req);
118 if (mm_data->last_auth_req_id != 0)
119 {
120 /* problem occurred!!!! */
121 #ifdef WIN32
122 vsi_o_ttrace (VSI_CALLER TC_FUNC,
123 "Authentication problem occurred %d", mm_data->last_auth_req_id);
124 #endif /* WIN32 */
125 }
126
127 }
128
129
130 /*
131 +--------------------------------------------------------------------+
132 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
133 | STATE : code ROUTINE : reg_net_list |
134 +--------------------------------------------------------------------+
135
136 PURPOSE : Build a list of available PLMNs for the MMI.
137 Use the information received from RR to update MM's
138 internal PLMN list used for MM's own operation.
139
140 */
141
142 #if 0 // The old code
143 GLOBAL void reg_net_list (const T_RR_ABORT_IND *rr_abort_ind)
144 {
145 TRACE_FUNCTION ("reg_net_list()");
146
147 /* Create the PLMN list for the MMI and send it */
148 reg_create_plmn_list (rr_abort_ind, WITH_ALL_PLMNS);
149
150 if (mm_data->reg.plmn_cnt EQ 0)
151 {
152 if ((rr_abort_ind->op.service NEQ NO_SERVICE) AND
153 (rr_abort_ind->cause EQ RRCS_ABORT_CEL_SEL_FAIL))
154 {
155 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE);
156 }
157 else
158 {
159 mm_mmgmm_plmn_ind (MMCS_SUCCESS);
160 }
161 }
162 else
163 {
164 mm_mmgmm_plmn_ind (MMCS_SUCCESS);
165 }
166
167 /* Do not consider the forbidden PLMN's for MM's internal operation */
168 reg_create_plmn_list (rr_abort_ind, WITH_OTHER_PLMNS);
169
170 switch (rr_abort_ind->op.service)
171 {
172 case NO_SERVICE:
173 mm_mmgmm_nreg_ind (NREG_NO_SERVICE,
174 SEARCH_NOT_RUNNING,
175 FORB_PLMN_NOT_INCLUDED);
176 break;
177
178 case LIMITED_SERVICE:
179 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
180 SEARCH_NOT_RUNNING,
181 FORB_PLMN_NOT_INCLUDED);
182 break;
183
184 case FULL_SERVICE:
185 break;
186
187 default: /* All possible values caught, this is garbage */
188 TRACE_ERROR (UNEXPECTED_DEFAULT);
189 break;
190 }
191 }
192 #else // The new code
193 GLOBAL void reg_net_list (const T_RR_ABORT_IND *rr_abort_ind)
194 {
195 GET_INSTANCE_DATA;
196 TRACE_FUNCTION ("reg_net_list()");
197
198 if (rr_abort_ind->plmn_avail EQ 0)
199 {
200 /*
201 * Distinguish between "no PLMN found" and search aborted
202 * due to eg. paging in RR. In the future, we may introduce
203 * a proper cause in the RR_ABORT_IND to distinguish this,
204 * this here should work but is ugly.
205 */
206 if ((rr_abort_ind->op.service NEQ NO_SERVICE) AND
207 (rr_abort_ind->cause EQ RRCS_ABORT_CEL_SEL_FAIL))
208 {
209 mm_mmgmm_plmn_ind (MMCS_PLMN_NOT_IDLE_MODE, NULL);
210 }
211 else
212 {
213 mm_mmgmm_plmn_ind (MMCS_SUCCESS, rr_abort_ind);
214 }
215 mm_data->reg.plmn_cnt = 0;
216 }
217 else
218 {
219 mm_mmgmm_plmn_ind (MMCS_SUCCESS, rr_abort_ind);
220 }
221
222 switch (rr_abort_ind->op.service)
223 {
224 case NO_SERVICE:
225 mm_mmgmm_nreg_ind (NREG_NO_SERVICE,
226 SEARCH_NOT_RUNNING,
227 FORB_PLMN_NOT_INCLUDED);
228 break;
229
230 case LIMITED_SERVICE:
231 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
232 SEARCH_NOT_RUNNING,
233 FORB_PLMN_NOT_INCLUDED);
234 break;
235
236 case FULL_SERVICE:
237 break;
238
239 default: /* All possible values caught, this is garbage */
240 TRACE_ERROR (UNEXPECTED_DEFAULT);
241 break;
242 }
243 }
244 #endif
245
246 /*
247 +--------------------------------------------------------------------+
248 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
249 | STATE : code ROUTINE : reg_rr_failure |
250 +--------------------------------------------------------------------+
251
252 PURPOSE : Indication from MM/RR about unsuccessfull cell selection.
253 The new service and the found PLMN indications are for-
254 warded to MM.
255
256 */
257
258 GLOBAL void reg_rr_failure (T_RR_ABORT_IND *rr_abort_ind)
259 {
260 GET_INSTANCE_DATA;
261 unsigned i;
262 BOOL actual_plmn_found;
263
264 TRACE_FUNCTION ("reg_rr_failure()");
265
266 #if defined (WIN32)
267 {
268 TRACE_EVENT_P1 ("PLMN_AVAIL = %d", rr_abort_ind->plmn_avail);
269
270 for (i = 0 ;i < rr_abort_ind->plmn_avail; i++)
271 {
272 TRACE_EVENT_P6 ("MCC=%x%x%x MNC=%x%x%x",
273 rr_abort_ind->plmn[i].mcc[0],
274 rr_abort_ind->plmn[i].mcc[1],
275 rr_abort_ind->plmn[i].mcc[2],
276 rr_abort_ind->plmn[i].mnc[0],
277 rr_abort_ind->plmn[i].mnc[1],
278 rr_abort_ind->plmn[i].mnc[2]);
279 }
280 }
281 #endif /* #if defined (WIN32) */
282
283 if (rr_abort_ind->plmn_avail EQ 0 OR
284 mm_data->reg.op.sim_ins EQ SIM_NO_INSRT)
285 {
286 /*
287 * No PLMN delivered by RR to build a PLMN list or no SIM present
288 */
289 switch (rr_abort_ind->op.service)
290 {
291 case NO_SERVICE:
292 mm_mmgmm_nreg_ind (NREG_NO_SERVICE,
293 SEARCH_NOT_RUNNING,
294 FORB_PLMN_NOT_INCLUDED);
295 break;
296
297 case LIMITED_SERVICE:
298 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
299 SEARCH_NOT_RUNNING,
300 FORB_PLMN_NOT_INCLUDED);
301 break;
302
303 default: /* eg. FULL_SERVICE and reg_rr_failure => nonsense */
304 TRACE_ERROR (UNEXPECTED_DEFAULT);
305 break;
306 }
307
308 /* Delete the PLMN list, currently no PLMN available */
309 mm_data->reg.plmn_cnt = 0;
310
311 /*
312 // First make sure to understand completely the underlying problem...
313 // Patch HM 11.06.01, clear PLMN list in ACI and MM >>>
314 mm_mmgmm_plmn_ind (MMCS_SUCCESS, rr_abort_ind);
315 // Patch HM 11.06.01, clear PLMN list in ACI and MM <<<
316 */
317
318 }
319 else
320 {
321 /*
322 * At least one PLMN found and SIM present, create PLMN list.
323 * Depending on the selected mode (automatic or manual),
324 * either select the next available PLMN or present the
325 * list of PLMNs possibly providing full service to the user.
326 */
327 switch (mm_data->reg.op.m)
328 {
329 case MODE_AUTO:
330 // Note: There are better algorithms to decide whether an update
331 // of the PLMN list is necessary or not, but for these we need the
332 // information from RR whether a found PLMN/location area is
333 // forbidden. This becomes especially TRUE for an exhausted PLMN
334 // list as we waste a lot of battery here if there is no location
335 // area suitable for full service available, but a lot of location
336 // areas on VPLMNs which are forbidden for roaming. In this case we
337 // run in a loop senseless activating VPLMN which don't provide
338 // full service at all.
339 /*
340 * Don't update the PLMN list if the actual PLMN is a member
341 * of the PLMN list delivered by RR and the current list is
342 * non-exhaused.
343 */
344 actual_plmn_found = FALSE;
345
346 if (mm_data->reg.plmn_cnt > mm_data->reg.plmn_index)
347 {
348 /*
349 * There is a non-exhausted list present in MM.
350 * Check whether the actual PLMN is a member.
351 */
352 for (i = 0; i < rr_abort_ind->plmn_avail; i++)
353 {
354 if (reg_plmn_equal_sim (&rr_abort_ind->plmn[i],
355 &mm_data->reg.actual_plmn))
356 {
357 actual_plmn_found = TRUE;
358 break;
359 }
360 }
361 if (!actual_plmn_found)
362 {
363 /* The requested PLMN was not found. Update outdated list. */
364 reg_create_plmn_list (rr_abort_ind, WITH_OTHER_PLMNS);
365 }
366 else
367 {
368 TRACE_EVENT ("PLMN list ignored");
369 }
370 }
371 else
372 {
373 /* No non-exhaused list present in MM. Take the new list from RR */
374 reg_create_plmn_list (rr_abort_ind, WITH_OTHER_PLMNS);
375 }
376
377 /*
378 * Select the next PLMN if available
379 * else indicate LIMITED SERVICE to MMI
380 */
381 reg_plmn_select (FORB_PLMN_NOT_INCLUDED);
382 break;
383
384 case MODE_MAN:
385 reg_create_plmn_list (rr_abort_ind, WITH_ALL_PLMNS);
386
387 /*
388 * Forward the PLMN list to MMI for selection
389 */
390 switch (rr_abort_ind->op.service)
391 {
392 case NO_SERVICE:
393 mm_mmgmm_nreg_ind (NREG_NO_SERVICE,
394 SEARCH_NOT_RUNNING,
395 FORB_PLMN_NOT_INCLUDED);
396 break;
397
398 case LIMITED_SERVICE:
399 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
400 SEARCH_NOT_RUNNING,
401 FORB_PLMN_NOT_INCLUDED);
402 break;
403
404 default: /* eg. FULL_SERVICE and reg_rr_failure => nonsense */
405 TRACE_ERROR (UNEXPECTED_DEFAULT);
406 break;
407 }
408 mm_data->plmn_scan_mmi = TRUE;
409 mm_mmgmm_plmn_ind (MMCS_SUCCESS, rr_abort_ind);
410 break;
411
412 default: /* No mode left */
413 TRACE_ERROR (UNEXPECTED_DEFAULT);
414 break;
415 }
416 }
417 }
418
419
420 /*
421 +--------------------------------------------------------------------+
422 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
423 | STATE : code ROUTINE : reg_mm_success |
424 +--------------------------------------------------------------------+
425
426 PURPOSE : MM indicates successfull registration.
427
428 */
429
430 GLOBAL void reg_mm_success (UBYTE service)
431 {
432 GET_INSTANCE_DATA;
433 TRACE_FUNCTION ("reg_mm_success()");
434
435 if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT)
436 {
437 /*
438 * No SIM is inserted
439 */
440 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
441 SEARCH_NOT_RUNNING,
442 FORB_PLMN_NOT_INCLUDED);
443 }
444 else
445 {
446 /*
447 * SIM is inserted
448 */
449 if (service EQ LIMITED_SERVICE)
450 {
451 mm_mmgmm_nreg_ind (NREG_LIMITED_SERVICE,
452 SEARCH_NOT_RUNNING,
453 FORB_PLMN_NOT_INCLUDED);
454 }
455 else
456 {
457 /*
458 * Send new PLMN identification to MMI or GMM.
459 * In case we compile for a GPRS protocol stack,
460 * we will not indicate end of procedure (entering IDLE state)
461 * by MMGMM_REG_CNF, but sending an intermediate result (full service)
462 * by MMGMM_LUP_ACCEPT_IND.
463 */
464 #ifdef GPRS
465 if (mm_data->gprs.reg_cnf_on_idle_entry)
466 {
467 mm_mmgmm_lup_accept_ind ();
468 }
469 else
470 #endif
471 {
472 mm_mmgmm_reg_cnf ();
473 }
474
475 /* Check HPLMN timer state */
476 reg_check_hplmn_tim (mm_data->reg.thplmn);
477
478 }
479 }
480 }
481
482
483 /*
484 +--------------------------------------------------------------------+
485 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
486 | STATE : code ROUTINE : reg_mm_cell_selected |
487 +--------------------------------------------------------------------+
488
489 PURPOSE : MM indicates successfull cell selection.
490
491 */
492
493 GLOBAL void reg_mm_cell_selected (void)
494 {
495 GET_INSTANCE_DATA;
496 TRACE_FUNCTION ("reg_mm_cell_selected()");
497
498 if (mm_gsm_alone() AND
499 mm_data->reg.op.sim_ins EQ SIM_INSRT)
500 {
501 /*
502 * GPRS is inactive (GSM only mobile or GPRS deactivated) AND
503 * a valid SIM is inserted. These are the prerequisites to indicate
504 * full service to the MMI after cell selection.
505 */
506 if (!mm_normal_upd_needed())
507 {
508 /*
509 * If no normal update is needed, the next service state
510 * is "normal service" regardless of the need of an IMSI
511 * ATTACH. Normal calls are possible, so we have to indicate
512 * full service to the MMI.
513 */
514 mm_mmgmm_reg_cnf ();
515 }
516 }
517 }
518
519 /*
520 +--------------------------------------------------------------------+
521 | PROJECT : GSM-PS (6147) MODULE : MM_REG |
522 | STATE : code ROUTINE : reg_mm_failure |
523 +--------------------------------------------------------------------+
524
525 PURPOSE : MM indicates an internal failure during location updating.
526
527 */
528
529 GLOBAL void reg_mm_failure (UBYTE forb_ind)
530 {
531 GET_INSTANCE_DATA;
532 TRACE_FUNCTION ("reg_mm_failure()");
533
534 if (!mm_lup_allowed_by_gmm())
535 {
536 /*
537 * Call of function caused by MMGMM_ATTACH_REJ_REQ
538 * and not by own failed LOCATION UPDATING ATTEMPT - or -
539 * by MMGMM_NREG_REQ with (cs EQ CS_DISABLE).
540 */
541
542 // This means, in automatic mode we wait for a
543 // GMM decision to try a location update in automatic
544 // mode if there are further networks present.
545 // We have to discuss this item for network mode I!
546
547 /*
548 * Check whether the MM failure was caused by MMGMM_NREG_REQ.
549 */
550 if (mm_data->nreg_request)
551 mm_mmgmm_nreg_cnf (mm_data->nreg_cause);
552 return;
553 }
554
555 /*
556 * The MM failure was caused by MM's own location updating procedure,
557 * LOCATION UPDATING REJECT message has been received.
558 */
559
560 /*
561 * In automatic mode with valid SIM, select the next PLMN if available
562 */
563 reg_plmn_select (forb_ind);
564 }
565
566 #endif