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

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