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