FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/g23m-gsm/mm/mm_gmm.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 |
comparison
equal
deleted
inserted
replaced
672:0dc6f9e8e980 | 673:2f7df7a314f8 |
---|---|
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 */ |