comparison src/g23m-gsm/mm/mm_gmm.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_GMM.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 for the communication
18 | of MM with GMM. All communications from MM to GMM will
19 | be through this file.
20 +-----------------------------------------------------------------------------
21 */
22
23 #ifndef MM_GMM_C
24 #define MM_GMM_C
25
26 #define ENTITY_MM
27
28 /*==== INCLUDES ===================================================*/
29
30
31 #include <string.h>
32 #include "typedefs.h"
33 #include "pconst.cdg"
34 #include "message.h"
35 #include "ccdapi.h"
36 #include "vsi.h"
37 #include "custom.h"
38 #include "gsm.h"
39 #include "prim.h"
40 #include "cnf_mm.h"
41 #include "mon_mm.h"
42 #include "pei.h"
43 #include "tok.h"
44 #include "mm.h"
45
46 /*==== EXPORT =====================================================*/
47
48 /*==== TEST =====================================================*/
49
50 /*==== PRIVAT =====================================================*/
51
52 /*==== VARIABLES ==================================================*/
53
54 /*==== FUNCTIONS ==================================================*/
55
56 #if defined(GPRS)
57
58 /*
59 +--------------------------------------------------------------------+
60 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
61 | STATE : code ROUTINE : mm_send_mmgmm_reg_cnf |
62 +--------------------------------------------------------------------+
63
64 PURPOSE : sends the MMGMM_REG_CNF primitive
65
66 */
67
68 GLOBAL void mm_send_mmgmm_reg_cnf (UBYTE bootup_cause)
69 {
70 GET_INSTANCE_DATA;
71 TRACE_FUNCTION ("mm_send_mmgmm_reg_cnf()");
72
73 {
74 PALLOC (mmgmm_reg_cnf, MMGMM_REG_CNF); /* T_MMGMM_REG_CNF */
75 if (bootup_cause NEQ PWR_SCAN_START)
76 {
77 mmgmm_reg_cnf->plmn.v_plmn = V_PLMN_PRES;
78 memcpy (mmgmm_reg_cnf->plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC);
79 memcpy (mmgmm_reg_cnf->plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC);
80 }
81 else
82 {
83 mmgmm_reg_cnf->plmn.v_plmn = V_PLMN_NOT_PRES;
84 }
85 mmgmm_reg_cnf->lac = mm_data->mm.lai.lac;
86 mmgmm_reg_cnf->cid = mm_data->mm.cid;
87 mmgmm_reg_cnf->resumption = mm_data->gprs.resumption;
88 mmgmm_reg_cnf->gprs_indicator = mm_data->mm.gprs_indication;
89 mmgmm_reg_cnf->bootup_cause = bootup_cause;
90 PSENDX (GMM, mmgmm_reg_cnf);
91 }
92 }
93
94 /*
95 +--------------------------------------------------------------------+
96 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
97 | STATE : code ROUTINE : mm_mmgmm_reg_cnf |
98 +--------------------------------------------------------------------+
99
100 PURPOSE : This function indicates change in service or change in PLMN
101 to the GMREG SAP. This is suppressed if the
102 registration type is REG_CELL_SEARCH_ONLY, in this
103 case GMM is not interested in the MM service information.
104
105 */
106
107 GLOBAL void mm_mmgmm_reg_cnf (void)
108 {
109 GET_INSTANCE_DATA;
110 TRACE_FUNCTION ("mm_mmgmm_reg_cnf()");
111
112 if (GET_STATE (STATE_REG_TYPE) NEQ REG_CELL_SEARCH_ONLY)
113 {
114 /* Issue 20792 : Added condition mm_data->plmn_scan_mmi. If network search requested by user
115 is pending then after RR release MM should initiate network search and after getting
116 proper PLMN list it should inform GMM followed by successful Registration. Else there will be
117 collision in RR between network search and GPRS Attach resulting in abortion of network
118 search and hence empty list by RR will be returned.
119 */
120
121
122 if ( mm_data->plmn_scan_mmi )
123 {
124 mm_data->gprs.reg_cnf_on_idle_entry = TRUE;
125 }
126 else
127 {
128 if ((mm_data->reg.full_service_indicated EQ FALSE) OR
129 (mm_data->reg.new_cell_ind EQ TRUE))
130 {
131 /*
132 * Either no full service was indicated to the MMI,
133 * or the PLMN has changed from that what was indicated before.
134 */
135 mm_send_mmgmm_reg_cnf (REG_END);
136
137 mm_data->reg.full_service_indicated = TRUE;
138 mm_data->reg.new_cell_ind = FALSE;
139 }
140
141 mm_data->gprs.reg_cnf_on_idle_entry = FALSE;
142
143 /* Disallow establishment for own location updating and CM services */
144 if (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED)
145 {
146 SET_STATE (STATE_REG_TYPE, REG_CELL_SEARCH_ONLY);
147 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_IDLE);
148 }
149 } /* else */
150 }
151 }
152
153
154 /*
155 +--------------------------------------------------------------------+
156 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
157 | STATE : code ROUTINE : mm_send_mmgmm_nreg_ind |
158 +--------------------------------------------------------------------+
159
160 PURPOSE : This procedure builds ans sends the MMGMM_NREG_IND
161 primitive without having any side effects.
162
163 */
164
165 LOCAL void mm_send_mmgmm_nreg_ind (UBYTE service,
166 UBYTE search_running,
167 UBYTE forb_ind)
168 {
169 GET_INSTANCE_DATA;
170 PALLOC (mmgmm_nreg_ind, MMGMM_NREG_IND); /* T_MMGMM_NREG_IND */
171
172 TRACE_FUNCTION ("mm_send_mmgmm_nreg_ind()");
173
174 mmgmm_nreg_ind->service = service;
175 mmgmm_nreg_ind->search_running = search_running;
176
177 if (forb_ind EQ FORB_PLMN_INCLUDED)
178 {
179 mmgmm_nreg_ind->new_forb_plmn.v_plmn = V_PLMN_PRES;
180 memcpy (mmgmm_nreg_ind->new_forb_plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC);
181 memcpy (mmgmm_nreg_ind->new_forb_plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC);
182 }
183 else
184 {
185 mmgmm_nreg_ind->new_forb_plmn.v_plmn = V_PLMN_NOT_PRES;
186 memset (mmgmm_nreg_ind->new_forb_plmn.mcc, 0x0f, SIZE_MCC);
187 memset (mmgmm_nreg_ind->new_forb_plmn.mnc, 0x0f, SIZE_MNC);
188 }
189
190 mmgmm_nreg_ind->cause = mm_data->limited_cause;
191 /* No GPRS resumption field in MMGMM_NREG_IND as in MMGMM_REG_REJ */
192 PSENDX (GMM, mmgmm_nreg_ind);
193 }
194
195
196 /*
197 +--------------------------------------------------------------------+
198 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
199 | STATE : code ROUTINE : mm_send_mmgmm_reg_rej |
200 +--------------------------------------------------------------------+
201
202 PURPOSE : This procedure builds ans sends the MMGMM_REG_REJ
203 primitive without having any side effects.
204
205 */
206
207 LOCAL void mm_send_mmgmm_reg_rej (UBYTE service,
208 UBYTE search_running,
209 UBYTE forb_ind)
210 {
211 GET_INSTANCE_DATA;
212 PALLOC (mmgmm_reg_rej, MMGMM_REG_REJ); /* T_MMGMM_REG_REJ */
213
214 TRACE_FUNCTION ("mm_send_mmgmm_reg_rej()");
215
216 mmgmm_reg_rej->service = service;
217 mmgmm_reg_rej->search_running = search_running;
218
219 if (forb_ind EQ FORB_PLMN_INCLUDED)
220 {
221 mmgmm_reg_rej->new_forb_plmn.v_plmn = V_PLMN_PRES;
222 memcpy (mmgmm_reg_rej->new_forb_plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC);
223 memcpy (mmgmm_reg_rej->new_forb_plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC);
224 }
225 else
226 {
227 mmgmm_reg_rej->new_forb_plmn.v_plmn = V_PLMN_NOT_PRES;
228 memset (mmgmm_reg_rej->new_forb_plmn.mcc, 0x0f, SIZE_MCC);
229 memset (mmgmm_reg_rej->new_forb_plmn.mnc, 0x0f, SIZE_MNC);
230 }
231
232 mmgmm_reg_rej->cause = mm_data->limited_cause;
233 mmgmm_reg_rej->resumption = mm_data->gprs.resumption;
234 PSENDX (GMM, mmgmm_reg_rej);
235 }
236 /*
237 +--------------------------------------------------------------------+
238 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
239 | STATE : code ROUTINE : mm_mmgmm_nreg_ind |
240 +--------------------------------------------------------------------+
241
242 PURPOSE : This is the common procedure for MMGMM_NREG_IND and
243 MMGMM_REG_REJ. MMGMM_REG_REJ is sent if the procedure
244 war a remote controlled location updating procedure,
245 otherwise MMGMM_NREG_IND is sent.
246
247 */
248
249 GLOBAL void mm_mmgmm_nreg_ind (UBYTE service,
250 UBYTE search_running,
251 UBYTE forb_ind)
252 {
253 GET_INSTANCE_DATA;
254 TRACE_FUNCTION ("mm_mmgmm_nreg_ind()");
255
256 if (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED)
257 {
258 mm_send_mmgmm_reg_rej (service, search_running, forb_ind);
259 }
260 else
261 {
262 mm_send_mmgmm_nreg_ind (service, search_running, forb_ind);
263 }
264
265 #ifdef WIN32
266 TRACE_EVENT_P1 (" service=%d", service);
267 TRACE_EVENT_P1 (" search_running=%d", search_running);
268 TRACE_EVENT_P1 (" limited_cause=%d", mm_data->limited_cause);
269 TRACE_EVENT_P1 (" resumption=%d", mm_data->gprs.resumption);
270 #endif /* #ifdef WIN32 */
271
272 /*
273 * Delete the limited cause if it was not fatal, as
274 * on the next cell selection the reason may be another than
275 * the one now indicated.
276 */
277 if (mm_data->reg.op.sim_ins EQ SIM_INSRT)
278 mm_data->limited_cause = MMCS_INT_NOT_PRESENT;
279
280 mm_data->reg.full_service_indicated = FALSE;
281 mm_data->gprs.reg_cnf_on_idle_entry = FALSE;
282
283 /* Disallow establishment for own location updating and CM services */
284 if (GET_STATE (STATE_REG_TYPE) EQ REG_REMOTE_CONTROLLED)
285 {
286 SET_STATE (STATE_REG_TYPE, REG_CELL_SEARCH_ONLY);
287 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_IDLE);
288 }
289 }
290
291
292 /*
293 +--------------------------------------------------------------------+
294 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
295 | STATE : code ROUTINE : mm_mmgmm_nreg_cnf |
296 +--------------------------------------------------------------------+
297
298 PURPOSE : If GPRS is enabled, send MMGMM_NREG_CNF.
299 Otherwise send MMR_NREG_CNF.
300
301 */
302
303 GLOBAL void mm_mmgmm_nreg_cnf (UBYTE detach_cause)
304 {
305 GET_INSTANCE_DATA;
306 TRACE_FUNCTION ("mm_mmgmm_nreg_cnf()");
307
308 if (mm_data->nreg_request)
309 {
310 PALLOC (mmgmm_nreg_cnf, MMGMM_NREG_CNF); /* T_MMGMM_NREG_CNF */
311 mmgmm_nreg_cnf->detach_cause = detach_cause;
312
313 #ifdef WIN32
314 vsi_o_ttrace (VSI_CALLER TC_FUNC,
315 " detach_cause=%d", mmgmm_nreg_cnf->detach_cause);
316 #endif /* WIN32 */
317
318 PSENDX (GMM, mmgmm_nreg_cnf);
319
320 mm_data->nreg_request = FALSE;
321 }
322 }
323
324 /*
325 +--------------------------------------------------------------------+
326 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
327 | STATE : code ROUTINE : mm_mmgmm_plmn_ind |
328 +--------------------------------------------------------------------+
329
330 PURPOSE : If GPRS is enabled, send MMGMM_PLMN_IND.
331 Otherwise send MMR_PLMN_IND.
332
333 */
334
335 GLOBAL void mm_mmgmm_plmn_ind (USHORT cause,
336 const T_RR_ABORT_IND *rr_abort_ind)
337 {
338 GET_INSTANCE_DATA;
339 TRACE_FUNCTION ("mm_mmgmm_plmn_ind()");
340
341 if (mm_data->plmn_scan_mmi)
342 {
343 USHORT i;
344 PALLOC (mmgmm_plmn_ind, MMGMM_PLMN_IND); /* T_MMGMM_PLMN_IND */
345
346 /* Issue 20792 : If there was any network search request pending during specific
347 prorcedure then on getting RR_RELEASE_IND that would be processed first and
348 MMGMM_REG_CNF will be held till that is done. Once PLMN list is receieved by RR
349 MM should send MMGMM_PLMN_IND to GMM followed by MMGMM_REG_CNF .
350 */
351
352 if ( mm_data->gprs.reg_cnf_on_idle_entry )
353 {
354 mm_data->plmn_scan_mmi = FALSE;
355 mm_data->reg.full_service_indicated = FALSE;/* Force MMGMM_REG_CNF */
356 mm_mmgmm_reg_cnf();
357 }
358
359 /* Net Search Result */
360 mmgmm_plmn_ind->cause = cause;
361
362 // See comment for MMR_PLMN_IND!!!
363 memset (mmgmm_plmn_ind->plmn, NOT_PRESENT_8BIT,
364 sizeof (mmgmm_plmn_ind->plmn));
365
366 /* Make testcases happy, initialize all unused data */
367 memset (mmgmm_plmn_ind->forb_ind, FORB_PLMN_NOT_INCLUDED,
368 sizeof (mmgmm_plmn_ind->forb_ind));
369 memset (mmgmm_plmn_ind->rxlevel, 0x00,
370 sizeof (mmgmm_plmn_ind->rxlevel));
371 memset (mmgmm_plmn_ind->gprs_status, MMGMM_GPRS_GSM,
372 sizeof (mmgmm_plmn_ind->gprs_status));
373
374 if (cause EQ MMCS_SUCCESS)
375 {
376 /* Create the PLMN list for the MMI and sent it */
377 reg_create_plmn_list (rr_abort_ind, WITH_ALL_PLMNS);
378
379 for (i = 0; i < mm_data->reg.plmn_cnt; i++)
380 {
381 /* Copy the PLMN information itself from registration data
382 * This may be too complicated, one memcpy() may be sufficient */
383
384 reg_unpack_plmn (&mmgmm_plmn_ind->plmn[i], mm_data->reg.plmn, i);
385
386 /* Process forbidden PLMN information */
387 if (reg_plmn_in_list (mm_data->reg.forb_plmn,
388 MAX_FORB_PLMN_ID,
389 &mmgmm_plmn_ind->plmn[i]))
390 {
391 mmgmm_plmn_ind->forb_ind[i] = FORB_PLMN_INCLUDED;
392 }
393 else
394 {
395 /*
396 * PLMN not member of forbidden list (cause #11), if GPRS is
397 * active, consider GPRS forbidden list also (cause #14)
398 */
399 if (!mm_gsm_alone() AND
400 (mm_data->gprs.mobile_class EQ MMGMM_CLASS_CG) AND
401 reg_plmn_in_list (mm_data->reg.gprs_forb_plmn,
402 MAX_GPRS_FORB_PLMN_ID,
403 &mmgmm_plmn_ind->plmn[i]))
404 {
405 mmgmm_plmn_ind->forb_ind[i] = FORB_PLMN_INCLUDED;
406 }
407 else
408 {
409 mmgmm_plmn_ind->forb_ind[i] = FORB_PLMN_NOT_INCLUDED;
410 }
411 }
412
413 /* Copy the rx level from registration data */
414 mmgmm_plmn_ind->rxlevel[i] = mm_data->reg.plmn_rx [i];
415
416 mmgmm_plmn_ind->lac_list[i] = mm_data->reg.plmn_lac [i]; //LOL 02.01.2003: added for EONS support
417
418 /* Copy the GPRS capabilities from registration data */
419 mmgmm_plmn_ind->gprs_status[i] = mm_data->reg.gprs_status[i];
420 } /* for */
421
422 /* Do not consider the forbidden PLMNs for MM's internal operation */
423 reg_create_plmn_list (rr_abort_ind, WITH_OTHER_PLMNS);
424 } /* if */
425
426 PSENDX (GMM, mmgmm_plmn_ind);
427
428 }
429
430 reg_check_plmn_search (cause, rr_abort_ind);
431 }
432
433
434 /*
435 +--------------------------------------------------------------------+
436 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
437 | STATE : code ROUTINE : mm_mmgmm_auth_rej_ind |
438 +--------------------------------------------------------------------+
439
440 PURPOSE : If GPRS is enabled, send MMGMM_AUTH_REJ_IND.
441 Otherwise this is compiled to a dummy function and will
442 return without further action.
443 */
444
445 GLOBAL void mm_mmgmm_auth_rej_ind (void)
446 {
447 GET_INSTANCE_DATA;
448 TRACE_FUNCTION ("mm_mmgmm_auth_rej_ind()");
449
450 {
451 PALLOC (mmgmm_auth_rej_ind, MMGMM_AUTH_REJ_IND);
452 PSENDX (GMM, mmgmm_auth_rej_ind);
453 }
454
455 mm_data->reg.full_service_indicated = FALSE;
456 mm_data->gprs.reg_cnf_on_idle_entry = FALSE;
457 }
458
459
460 /*
461 +--------------------------------------------------------------------+
462 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
463 | STATE : code ROUTINE : mm_mmgmm_cm_establish_ind |
464 +--------------------------------------------------------------------+
465
466 PURPOSE : If GPRS is enabled, send MMGMM_CM_ESTABLISH_IND if
467 not already done. A GSM only protocol stack doesn't
468 need this function.
469 By the primitive MMGMM_CM_ESTABLISH_IND GMM is informed
470 that a circuit switched call has to be started.
471
472 */
473
474 GLOBAL void mm_mmgmm_cm_establish_ind (void)
475 {
476 GET_INSTANCE_DATA;
477 TRACE_FUNCTION ("mm_mmgmm_establish_ind()");
478
479 switch (GET_STATE (STATE_GPRS_CM_EST))
480 {
481 case CM_GPRS_EST_IDLE:
482 {
483 PALLOC (mmgmm_establish_ind, MMGMM_CM_ESTABLISH_IND);
484 PSENDX (GMM, mmgmm_establish_ind);
485 }
486 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_PEND);
487 break;
488
489 default: /* Maybe CM establishment is already allowed etc. */
490 break;
491 }
492 }
493
494
495 /*
496 +--------------------------------------------------------------------+
497 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
498 | STATE : code ROUTINE : mm_mmgmm_cm_emergency_ind |
499 +--------------------------------------------------------------------+
500
501 PURPOSE : If GPRS is enabled, send MMGMM_CM_EMERGENCY_IND.
502 Otherwise this is compiled to a dummy function and will
503 return without further action.
504 By this primitive GMM is informed that a circuit switched
505 emergency call has to be started.
506
507 */
508
509 GLOBAL void mm_mmgmm_cm_emergency_ind (void)
510 {
511 GET_INSTANCE_DATA;
512 TRACE_FUNCTION ("mm_mmgmm_emergency_ind()");
513
514 switch (GET_STATE (STATE_GPRS_CM_EST))
515 {
516 case CM_GPRS_EST_IDLE:
517 case CM_GPRS_EST_PEND:
518 {
519 PALLOC (mmgmm_emergency_ind, MMGMM_CM_EMERGENCY_IND);
520 PSENDX (GMM, mmgmm_emergency_ind);
521 }
522 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EMERGE_PEND);
523 break;
524
525 default: /* MMGMM_CM_EMERGENCY_IND has already been sent */
526 break;
527 }
528 }
529
530
531 /*
532 +--------------------------------------------------------------------+
533 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
534 | STATE : code ROUTINE : mm_mmgmm_cm_release_ind |
535 +--------------------------------------------------------------------+
536
537 PURPOSE : If GPRS is enabled, send MMGMM_CM_RELEASE_IND if the
538 conditions are met.
539 Otherwise this is compiled to a dummy function and will
540 return without further action.
541 */
542
543 GLOBAL void mm_mmgmm_cm_release_ind (UBYTE resumption)
544 {
545 GET_INSTANCE_DATA;
546 TRACE_FUNCTION ("mm_mmgmm_cm_release_ind()");
547
548 if (!mm_gsm_alone() AND
549 (GET_STATE (STATE_GPRS_CM_EST) NEQ CM_GPRS_EST_IDLE) AND
550 (mm_count_connections (CM_NOT_IDLE) EQ 0))
551 {
552 PALLOC (mmgmm_cm_release_ind, MMGMM_CM_RELEASE_IND);
553 mmgmm_cm_release_ind->resumption = resumption;
554
555 #ifdef WIN32
556 vsi_o_ttrace (VSI_CALLER TC_FUNC,
557 " resumption=%d", mmgmm_cm_release_ind->resumption);
558 #endif /* WIN32 */
559
560 PSENDX (GMM, mmgmm_cm_release_ind);
561
562 SET_STATE (STATE_GPRS_CM_EST, CM_GPRS_EST_IDLE);
563 }
564 }
565
566
567 /*
568 +--------------------------------------------------------------------+
569 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
570 | STATE : code ROUTINE : mm_mmgmm_activate_ind |
571 +--------------------------------------------------------------------+
572
573 PURPOSE : If GPRS is enabled, send MMGMM_ACTIVATE_IND.
574 Otherwise this is compiled to a dummy function and will
575 return without further action.
576 The t3212_val here is to be given in the same form as it
577 is to be received from the network, this means in steps of
578 6 minutes, it will be scaled to milliseconds for GMM here.
579 */
580
581 GLOBAL void mm_mmgmm_activate_ind (UBYTE status)
582 {
583 GET_INSTANCE_DATA;
584 TRACE_FUNCTION ("mm_mmgmm_activate_ind()");
585
586 if (!mm_gsm_alone())
587 {
588 PALLOC (mmgmm_activate_ind, MMGMM_ACTIVATE_IND); /* T_MMGMM_ACTIVATE_IND */
589 mmgmm_activate_ind->plmn.v_plmn = V_PLMN_PRES;
590 memcpy (mmgmm_activate_ind->plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC);
591 memcpy (mmgmm_activate_ind->plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC);
592 mmgmm_activate_ind->lac = mm_data->mm.lai.lac;
593 mmgmm_activate_ind->cid = mm_data->mm.cid;
594 if (mm_data->t3212_cfg_counter NEQ 0 AND
595 mm_data->mm.mm_info.t3212 NEQ 0)
596 mmgmm_activate_ind->t3212_val = mm_data->t3212_cfg_counter * 10000;
597 else
598 mmgmm_activate_ind->t3212_val = mm_data->mm.mm_info.t3212 * 360000;
599 mmgmm_activate_ind->status = status;
600 mmgmm_activate_ind->gprs_indicator = mm_data->mm.gprs_indication;
601
602 if (status NEQ MMGMM_LIMITED_SERVICE)
603 {
604 mm_data->reg.actual_plmn = mmgmm_activate_ind->plmn; /* Struct copy */
605 }
606
607 #ifdef WIN32
608 vsi_o_ttrace (VSI_CALLER TC_FUNC,
609 " MCC=%x%x%x MNC=%x%x%x LAC=%04x",
610 mmgmm_activate_ind->plmn.mcc[0],
611 mmgmm_activate_ind->plmn.mcc[1],
612 mmgmm_activate_ind->plmn.mcc[2],
613 mmgmm_activate_ind->plmn.mnc[0],
614 mmgmm_activate_ind->plmn.mnc[1],
615 mmgmm_activate_ind->plmn.mnc[2],
616 mmgmm_activate_ind->lac);
617
618 vsi_o_ttrace (VSI_CALLER TC_FUNC,
619 " t3212_val=%d",
620 mmgmm_activate_ind->t3212_val);
621
622 vsi_o_ttrace (VSI_CALLER TC_FUNC,
623 " status=%d",
624 mmgmm_activate_ind->status);
625
626 vsi_o_ttrace (VSI_CALLER TC_FUNC,
627 " gprs_indicator=%d",
628 mmgmm_activate_ind->gprs_indicator);
629 #endif /* #ifdef WIN32 */
630
631 PSENDX (GMM, mmgmm_activate_ind);
632 }
633 }
634
635
636 /*
637 +--------------------------------------------------------------------+
638 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
639 | STATE : code ROUTINE : mm_mmgmm_t3212_val_ind |
640 +--------------------------------------------------------------------+
641
642 PURPOSE : If GPRS is enabled, send MMGMM_T3212_VAL_IND always T3212
643 changes, but no cell selection by RR was performed.
644 For a GSM only protocol stack, this function doesn't exist.
645 The time to be sent to GMM is scaled in units of milliseconds.
646
647 */
648
649 GLOBAL void mm_mmgmm_t3212_val_ind (void)
650 {
651 GET_INSTANCE_DATA;
652 TRACE_FUNCTION ("mm_mmgmm_t3212_val_ind()");
653
654 {
655 /* T_MMGMM_T3212_VAL_IND */
656 PALLOC (mmgmm_t3212_val_ind, MMGMM_T3212_VAL_IND);
657
658 if (mm_data->t3212_cfg_counter NEQ 0 AND
659 mm_data->mm.mm_info.t3212 NEQ 0)
660 {
661 mmgmm_t3212_val_ind->t3212_val = mm_data->t3212_cfg_counter * 10000;
662 }
663 else
664 {
665 mmgmm_t3212_val_ind->t3212_val = mm_data->mm.mm_info.t3212 * 360000;
666 }
667
668 #ifdef WIN32
669 vsi_o_ttrace (VSI_CALLER TC_FUNC,
670 " t3212_val=%d", mmgmm_t3212_val_ind->t3212_val);
671 #endif /* WIN32 */
672
673 PSENDX (GMM, mmgmm_t3212_val_ind);
674 }
675 }
676
677
678 /*
679 +--------------------------------------------------------------------+
680 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
681 | STATE : code ROUTINE : mm_mmgmm_lup_accept_ind |
682 +--------------------------------------------------------------------+
683
684 PURPOSE : If GPRS is enabled, send MMGMM_LUP_ACCEPT_IND.
685 For a GSM only protocol stack, this function doesn't exist.
686 It is assumed that the networks sends a location updating
687 accept message for the location area of the current serving
688 cell here, this assumption should be true always.
689
690 */
691
692 GLOBAL void mm_mmgmm_lup_accept_ind (void)
693 {
694 GET_INSTANCE_DATA;
695 TRACE_FUNCTION ("mm_mmgmm_lup_accept_ind()");
696
697 if ((mm_data->reg.full_service_indicated EQ FALSE) OR
698 (mm_data->reg.new_cell_ind EQ TRUE))
699 {
700 /* T_MMGMM_LUP_ACCEPT_IND */
701 PALLOC (mmgmm_lup_accept_ind, MMGMM_LUP_ACCEPT_IND);
702 mmgmm_lup_accept_ind->plmn.v_plmn = V_PLMN_PRES;
703 memcpy (mmgmm_lup_accept_ind->plmn.mcc, mm_data->mm.lai.mcc, SIZE_MCC);
704 memcpy (mmgmm_lup_accept_ind->plmn.mnc, mm_data->mm.lai.mnc, SIZE_MNC);
705 mmgmm_lup_accept_ind->lac = mm_data->mm.lai.lac;
706 mmgmm_lup_accept_ind->cid = mm_data->mm.cid;
707
708 #ifdef WIN32
709 vsi_o_ttrace (VSI_CALLER TC_FUNC,
710 " MCC=%x%x%x MNC=%x%x%x LAC=%04x",
711 mmgmm_lup_accept_ind->plmn.mcc[0],
712 mmgmm_lup_accept_ind->plmn.mcc[1],
713 mmgmm_lup_accept_ind->plmn.mcc[2],
714 mmgmm_lup_accept_ind->plmn.mnc[0],
715 mmgmm_lup_accept_ind->plmn.mnc[1],
716 mmgmm_lup_accept_ind->plmn.mnc[2],
717 mmgmm_lup_accept_ind->lac);
718 #endif /* #ifdef WIN32 */
719
720 PSENDX (GMM, mmgmm_lup_accept_ind);
721
722 mm_data->reg.full_service_indicated = TRUE;
723 mm_data->reg.new_cell_ind = FALSE;
724 }
725 }
726
727
728 /*
729 +--------------------------------------------------------------------+
730 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
731 | STATE : code ROUTINE : mm_mmgmm_lup_needed_ind |
732 +--------------------------------------------------------------------+
733
734 PURPOSE : If GPRS is enabled, send MMGMM_LUP_NEEDED_IND.
735 For a GSM only protocol stack, this function doesn't exist.
736 This function is used if GMM has to be informed about the
737 fact that a location updating procedure is needed by MM,
738 eg. a CM SERVICE REJECT message with the cause "IMSI unknown
739 in VLR" has been received or simply T3212 has expired.
740 A cell selection was not the cause for the need to update.
741 If the location updating is neccessary due to an incoming
742 establish request by the CM entities in state
743 MM_IDLE_ATTEMPT_TO_UPDATE, this is indicated by
744 MMGMM_CM_ESTABLISH_IND and should cause a registration by GMM
745 as GMM should know that MM needs an update in this situation.
746
747 */
748
749 GLOBAL void mm_mmgmm_lup_needed_ind (UBYTE reason)
750 {
751 GET_INSTANCE_DATA;
752 TRACE_FUNCTION ("mm_mmgmm_lup_needed_ind()");
753
754 if (!mm_lup_allowed_by_gmm ())
755 {
756 /* T_MMGMM_LUP_NEEDED_IND */
757 PALLOC (mmgmm_lup_needed_ind, MMGMM_LUP_NEEDED_IND);
758 mmgmm_lup_needed_ind->reason = reason;
759
760 #ifdef WIN32
761 vsi_o_ttrace (VSI_CALLER TC_FUNC,
762 " reason=%d", mmgmm_lup_needed_ind->reason);
763 #endif /* WIN32 */
764
765 PSENDX (GMM, mmgmm_lup_needed_ind);
766 }
767 else
768 {
769 /* This is an internal MM error, harmless, but should be fixed if seen */
770 TRACE_ERROR ("MMGMM_LUP_NEEDED_IND suppressed");
771 }
772 }
773
774
775 /*
776 +--------------------------------------------------------------------+
777 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
778 | STATE : code ROUTINE : mm_mmgmm_tmsi_ind |
779 +--------------------------------------------------------------------+
780
781 PURPOSE : Send MMGMM_TMSI_IND with the new TMSI
782 whenever the TMSI changes after SIM insertion.
783
784 */
785
786 GLOBAL void mm_mmgmm_tmsi_ind (ULONG tmsi)
787 {
788 GET_INSTANCE_DATA;
789 TRACE_FUNCTION ("mm_mmgmm_tmsi_ind()");
790
791 if (tmsi NEQ mm_data->reg.indicated_tmsi)
792 {
793 PALLOC (mmgmm_tmsi_ind, MMGMM_TMSI_IND); /* T_MMGMM_TMSI_IND */
794 mmgmm_tmsi_ind->tmsi = tmsi;
795 PSENDX (GMM, mmgmm_tmsi_ind);
796
797 mm_data->reg.indicated_tmsi = tmsi;
798 }
799 }
800
801
802 /*
803 +--------------------------------------------------------------------+
804 | PROJECT : GSM-PS (6147) MODULE : MM_MM |
805 | STATE : code ROUTINE : mm_mmgmm_ahplmn_ind |
806 +--------------------------------------------------------------------+
807
808 PURPOSE : Send MMGMM_AHPLMN_IND with the new AHPLMN
809 at poweron if valid AHPLMN and whenever the
810 AHPLMN changes.
811 */
812
813 GLOBAL void mm_mmgmm_ahplmn_ind (T_plmn *acting_hplmn)
814 {
815
816 TRACE_FUNCTION ("mm_mmgmm_ahplmn_ind()");
817 {
818 PALLOC(mmgmm_ahplmn_ind, MMGMM_AHPLMN_IND); /*T_MMGMM_AHPLMN_IND*/
819
820 mmgmm_ahplmn_ind->ahplmn.v_plmn = acting_hplmn->v_plmn;
821 memcpy(mmgmm_ahplmn_ind->ahplmn.mcc, acting_hplmn->mcc, SIZE_MCC);
822 memcpy(mmgmm_ahplmn_ind->ahplmn.mnc, acting_hplmn->mnc, SIZE_MNC);
823
824
825
826 #ifdef WIN32
827 vsi_o_ttrace (VSI_CALLER TC_FUNC,
828 " MCC=%x%x%x MNC=%x%x%x v_plmn=%x",
829 mmgmm_ahplmn_ind->ahplmn.mcc[0],
830 mmgmm_ahplmn_ind->ahplmn.mcc[1],
831 mmgmm_ahplmn_ind->ahplmn.mcc[2],
832 mmgmm_ahplmn_ind->ahplmn.mnc[0],
833 mmgmm_ahplmn_ind->ahplmn.mnc[1],
834 mmgmm_ahplmn_ind->ahplmn.mnc[2],
835 mmgmm_ahplmn_ind->ahplmn.v_plmn);
836
837 #endif /* #ifdef WIN32 */
838
839 PSENDX(GMM, mmgmm_ahplmn_ind);
840 }
841
842 }
843
844 #endif /* defined(GPRS) */
845 #endif /* MM_GMM_C */