comparison src/g23m-gprs/gmm/gmm_kernf.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 : GPRS (8441)
4 | Modul : gmm_kernf.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 modul is part of the entity GMM and implements all
18 | procedures and functions as described in the
19 | SDL-documentation (KERN-statemachine)
20 +-----------------------------------------------------------------------------
21 */
22
23
24 #ifndef GMM_KERNF_C
25 #define GMM_KERNF_C
26 #endif
27
28 #define ENTITY_GMM
29
30 /*==== INCLUDES =============================================================*/
31
32 #include "typedefs.h" /* to get Condat data types */
33 #include "vsi.h" /* to get a lot of macros */
34 #include "macdef.h"
35 #include "gprs.h"
36 #include "gsm.h" /* to get a lot of macros */
37 #include "ccdapi.h" /* to get CCD API */
38 #include "cnf_gmm.h" /* to get cnf-definitions */
39 #include "mon_gmm.h" /* to get mon-definitions */
40 #include "prim.h" /* to get the definitions of used SAP and directions */
41 #include "gmm.h" /* to get the global entity definitions */
42
43 #include "gmm_kernf.h" /* to get some local definitions */
44 #include "gmm_kernl.h" /* to get some local definitions */
45 #include "gmm_f.h"
46 #include <string.h> /* to get memset */
47 #include "pcm.h"
48 #include "gmm_rxf.h"
49 #include "gmm_rxs.h"
50 #include "gmm_txf.h"
51 #include "gmm_rdyf.h"
52 #include "gmm_syncs.h"
53 #include "gmm_kernp.h"
54 #include "gmm_rdys.h"
55 #include "gmm_syncf.h"
56 #include "gmm_em.h" /* To get Engineering Mode functions */
57
58 #ifdef _TARGET_
59 #include "ffs/ffs.h"
60 #endif
61
62 #include "cl_imei.h" /* IMEI common library */
63
64 #include <stdlib.h>
65
66 #include <stdio.h> /* for sprintf */
67
68 /*==== CONST ================================================================*/
69
70 /*==== LOCAL VARS ===========================================================*/
71
72 /*==== PRIVATE FUNCTIONS ====================================================*/
73
74 /*==== PUBLIC FUNCTIONS =====================================================*/
75 /*
76 +------------------------------------------------------------------------------
77 | Function : kern_gmmreg_info_ind
78 +------------------------------------------------------------------------------
79 | Description : The function kern_gmmreg_info_ind forwards the info comming
80 | from the net to the MMI entity
81 |
82 | Parameters : void
83 |
84 +------------------------------------------------------------------------------
85 */
86 GLOBAL void kern_gmmreg_info_ind ( void)
87 {
88 GMM_TRACE_FUNCTION( "kern_gmmreg_info_ind" );
89 {
90 MCAST(gmm_information, GMM_INFORMATION);
91 /* Agilent Issue OMAPS00148436 WA */
92 if (!gmm_information->v_full_network_name && !gmm_information->v_short_network_name
93 && !gmm_information->v_time_zone && !gmm_information->v_time_zone_and_time)
94 {
95 TRACE_EVENT ("GMM_INFORMATION message doesn't contain valid information");
96 GMM_RETURN;
97 }
98 {
99
100 PALLOC (gmmreg_info_ind, GMMREG_INFO_IND); /* T_GMMREG_INFO_IND */
101
102 /*
103 * Set PLMN, this will be used if network name is given
104 */
105 gmmreg_info_ind->plmn.v_plmn = TRUE;
106 memcpy (gmmreg_info_ind->plmn.mcc, gmm_data->kern.attach_cap.rai_accepted.mcc, SIZE_MCC);
107 memcpy (gmmreg_info_ind->plmn.mnc, gmm_data->kern.attach_cap.rai_accepted.mnc, SIZE_MNC);
108
109 /*
110 * Set full network name, if present
111 */
112
113 if (gmm_information->v_full_network_name)
114 {
115 gmmreg_info_ind->full_net_name_gmm.v_name = TRUE;
116 gmmreg_info_ind->full_net_name_gmm.dcs /* TCS 2.1 */
117 = gmm_information->full_network_name.code;
118 gmmreg_info_ind->full_net_name_gmm.add_ci
119 = gmm_information->full_network_name.add_ci;
120 gmmreg_info_ind->full_net_name_gmm.num_spare =
121 gmm_information->full_network_name.nr_sparebits;
122 memset(gmmreg_info_ind->full_net_name_gmm.text, 0, MMR_MAX_TEXT_LEN);
123 gmmreg_info_ind->full_net_name_gmm.c_text =
124 MINIMUM (MMR_MAX_TEXT_LEN, gmm_information->full_network_name.c_text_string);
125 memcpy (gmmreg_info_ind->full_net_name_gmm.text,
126 gmm_information->full_network_name.text_string,
127 gmmreg_info_ind->full_net_name_gmm.c_text);
128 }
129 else
130 {
131 gmmreg_info_ind->full_net_name_gmm.v_name = FALSE;
132 }
133 /* Set short network name, if present */
134 if (gmm_information->v_short_network_name)
135 {
136 gmmreg_info_ind->short_net_name_gmm.v_name = TRUE;
137 gmmreg_info_ind->short_net_name_gmm.dcs = gmm_information->short_network_name.code; /* TCS 2.1 */
138 gmmreg_info_ind->short_net_name_gmm.add_ci = gmm_information->short_network_name.add_ci;
139 gmmreg_info_ind->short_net_name_gmm.num_spare =
140 gmm_information->short_network_name.nr_sparebits;
141 memset(gmmreg_info_ind->short_net_name_gmm.text, 0, MMR_MAX_TEXT_LEN);
142 gmmreg_info_ind->short_net_name_gmm.c_text =
143 MINIMUM (MMR_MAX_TEXT_LEN, gmm_information->short_network_name.c_text_string);
144 memcpy (gmmreg_info_ind->short_net_name_gmm.text,
145 gmm_information->short_network_name.text_string,
146 gmmreg_info_ind->short_net_name_gmm.c_text);
147 }
148 else
149 {
150 gmmreg_info_ind->short_net_name_gmm.v_name = FALSE;
151 }
152 /* Set network time zone, if present */
153 if (gmm_information->v_time_zone)
154 {
155 gmmreg_info_ind->net_time_zone.v_time_zone = TRUE;
156 gmmreg_info_ind->net_time_zone.time_zone
157 = gmm_information->time_zone.time_zone_value;
158 }
159 else
160 {
161 gmmreg_info_ind->net_time_zone.v_time_zone = FALSE;
162 }
163 /* Set network time zone and time, if present */
164 if (gmm_information->v_time_zone_and_time)
165 {
166 gmmreg_info_ind->net_time_zone.v_time_zone = TRUE;
167 gmmreg_info_ind->net_time_zone.time_zone
168 = gmm_information->time_zone_and_time.time_zone_value;
169 gmmreg_info_ind->net_time.v_time = TRUE;
170
171 gmmreg_info_ind->net_time.year =
172 10 * gmm_information->time_zone_and_time.year[0] +
173 gmm_information->time_zone_and_time.year[1];
174 gmmreg_info_ind->net_time.month =
175 10 * gmm_information->time_zone_and_time.month[0] +
176 gmm_information->time_zone_and_time.month[1];
177 gmmreg_info_ind->net_time.day =
178 10 * gmm_information->time_zone_and_time.day[0] +
179 gmm_information->time_zone_and_time.day[1];
180 gmmreg_info_ind->net_time.hour =
181 10 * gmm_information->time_zone_and_time.hour[0] +
182 gmm_information->time_zone_and_time.hour[1];
183 gmmreg_info_ind->net_time.minute =
184 10 * gmm_information->time_zone_and_time.minute[0] +
185 gmm_information->time_zone_and_time.minute[1];
186 gmmreg_info_ind->net_time.second =
187 10 * gmm_information->time_zone_and_time.second[0] +
188 gmm_information->time_zone_and_time.second[1];
189 }
190 else
191 {
192 gmmreg_info_ind->net_time.v_time = FALSE;
193 }
194
195 #ifdef REL99
196 if (gmm_information->v_daylight_save_time) /* TCS 4.0 */
197 { /* TCS 4.0 */
198 gmmreg_info_ind->net_daylight_save_time = /* TCS 4.0 */
199 gmm_information->daylight_save_time.save_time_value; /* TCS 4.0 */
200 } /* TCS 4.0 */
201 else /* TCS 4.0 */
202 { /* TCS 4.0 */
203 gmmreg_info_ind->net_daylight_save_time = GMMREG_ADJ_NO; /* TCS 4.0 */
204 } /* TCS 4.0 */
205 #endif
206
207 PSEND ( hCommMMI, gmmreg_info_ind);
208 }
209 }
210 GMM_RETURN;
211 } /* kern_gmmreg_info_ind() */
212 /*
213 +------------------------------------------------------------------------------
214 | Function : kern_calculate_digits
215 +------------------------------------------------------------------------------
216 | Description : Derives tm mobile identiti for the AIR
217 |
218 | COPIED FROM : MM mm_mmf.c : mm_calculate_digits
219 |
220 | Parameters : mobile_identity - used in the AIR message
221 |
222 +------------------------------------------------------------------------------
223 */
224 LOCAL UBYTE kern_calculate_digits (UBYTE *digits)
225 {
226 UBYTE i = 0;
227
228 GMM_TRACE_FUNCTION ("kern_calculate_digits()");
229
230 while (digits[i] < 0x0A AND i < 16)
231 i++;
232
233 GMM_RETURN_ (i);
234 }
235 /*
236 +------------------------------------------------------------------------------
237 | Function : kern_mmgmmreg_attach_cnf
238 +------------------------------------------------------------------------------
239 | Description : This procedure sends the gmmreg_attach_cnf primitiv to ACI
240 |
241 | Parameters : attach_type - attach type
242 | mmgmm_reg_req - the primitiv
243 |
244 +------------------------------------------------------------------------------
245 */
246 GLOBAL void kern_mmgmmreg_attach_cnf ( UBYTE attach_type, UBYTE search_running,
247 T_MMGMM_REG_CNF * mmgmm_reg_cnf )
248 {
249 GMM_TRACE_FUNCTION( "kern_mmgmmreg_attach_cnf" );
250
251 TRACE_1_INFO ("Info: MM lac: %x", mmgmm_reg_cnf->lac);
252
253 switch (gmm_data->kern.sig_cell_info.gmm_status)
254 {
255 case GMMRR_SERVICE_LIMITED:
256 case GMMRR_SERVICE_NONE:
257 search_running=SEARCH_NOT_RUNNING;
258 break;
259 default:
260 case GMMRR_SERVICE_FULL:
261 break;
262 }
263
264
265 gmm_data->kern.mm_cell_env.cid = mmgmm_reg_cnf->cid;
266 gmm_data->kern.mm_cell_env.rai.lac = mmgmm_reg_cnf->lac;
267 gmm_data->kern.mm_cell_env.rai.plmn = mmgmm_reg_cnf->plmn;
268
269 GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_CID);
270
271 {
272 PALLOC ( gmmreg_attach_cnf, GMMREG_ATTACH_CNF );
273 gmmreg_attach_cnf->attach_type = attach_type;
274 /*
275 * gmmreg_attach_cnf->plmn = gmm_data->mm_plmn= mmgmm_reg_cnf->plmn;
276 */
277 gmmreg_attach_cnf->plmn = mmgmm_reg_cnf->plmn;
278 gmmreg_attach_cnf->search_running = search_running;
279 gmmreg_attach_cnf->lac = mmgmm_reg_cnf->lac;
280 gmmreg_attach_cnf->rac = gmm_data->kern.sig_cell_info.env.rai.rac;
281 //gmmreg_attach_cnf->cid = gmm_data->kern.sig_cell_info.env.cid; // #HM#
282 gmmreg_attach_cnf->cid = mmgmm_reg_cnf->cid; // #HM#
283 gmmreg_attach_cnf->gprs_indicator = gmm_data->kern.sig_cell_info.gmm_status;
284 gmmreg_attach_cnf->bootup_cause = REG_END;
285 #ifdef GMM_TCS4
286 gmmreg_attach_cnf->rt = gmm_data->kern.sig_cell_info.rt; // TCS 4.0
287 #endif
288 #ifdef TRACE_EVE
289 {
290 switch (attach_type)
291 {
292 case GMMREG_AT_COMB:
293 TRACE_EVENT ("MS is combined attached.");
294 break;
295 case GMMREG_AT_IMSI:
296 TRACE_EVENT ("MS is GSM-only attached.");
297 break;
298 case GMMREG_AT_GPRS:
299 TRACE_EVENT ("MS is GPRS-only attached.");
300 break;
301 default:
302 TRACE_ERROR ("MS is attached with wrong attach type.");
303 break;
304 }
305 TRACE_7_PARA("%x%x%x, %x%x%x, lac %x",
306 gmmreg_attach_cnf->plmn.mcc[0],
307 gmmreg_attach_cnf->plmn.mcc[1],
308 gmmreg_attach_cnf->plmn.mcc[2],
309 gmmreg_attach_cnf->plmn.mnc[0],
310 gmmreg_attach_cnf->plmn.mnc[1],
311 gmmreg_attach_cnf->plmn.mnc[2],
312 gmmreg_attach_cnf->lac);
313 }
314 #endif
315
316 PSEND ( hCommMMI, gmmreg_attach_cnf );
317
318 gmm_data->kern.attach_cap.gmmreg = FALSE;
319 }
320 GMM_RETURN;
321 } /* kern_mmgmmreg_attach_cnf () */
322 /*
323 +------------------------------------------------------------------------------
324 | Function : kern_gmmreg_attach_cnf
325 +------------------------------------------------------------------------------
326 | Description : This procedure sends the gmmreg_attach_cnf primitiv to ACI
327 |
328 | Parameters : attach_type - attach type
329 |
330 +------------------------------------------------------------------------------
331 */
332 GLOBAL void kern_gmmreg_attach_cnf ( UBYTE attach_type)
333 {
334 GMM_TRACE_FUNCTION( "kern_gmmreg_attach_cnf" );
335 kern_gmmreg_attach_cnf_sr(attach_type,SEARCH_NOT_RUNNING);
336 GMM_RETURN;
337 } /* kern_gmmreg_attach_cnf () */
338 /*
339 +------------------------------------------------------------------------------
340 | Function : kern_gmmreg_attach_cnf_sr
341 +------------------------------------------------------------------------------
342 | Description : This procedure sends the gmmreg_attach_cnf primitiv to ACI
343 |
344 | Parameters : attach_type - attach type
345 |
346 +------------------------------------------------------------------------------
347 */
348 GLOBAL void kern_gmmreg_attach_cnf_sr ( UBYTE attach_type, UBYTE search_running)
349 {
350 GMM_TRACE_FUNCTION( "kern_gmmreg_attach_cnf_sr" );
351 TRACE_2_OUT_PARA("%s, %s",
352 search_running==SEARCH_RUNNING? "searching":"finished",
353 attach_type==GMMREG_AT_COMB? "comb":
354 attach_type==GMMREG_AT_GPRS?"gprs":
355 attach_type==GMMREG_AT_IMSI?"gsm":
356 "unknown tpe"
357 );
358
359 {
360 PALLOC ( gmmreg_attach_cnf, GMMREG_ATTACH_CNF );
361 gmmreg_attach_cnf->attach_type = attach_type;
362 gmmreg_attach_cnf->plmn.v_plmn = TRUE;
363 gmmreg_attach_cnf->search_running= search_running;
364 memcpy ( gmmreg_attach_cnf->plmn.mcc, gmm_data->kern.sig_cell_info.env.rai.plmn.mcc, SIZE_MCC);
365 memcpy ( gmmreg_attach_cnf->plmn.mnc, gmm_data->kern.sig_cell_info.env.rai.plmn.mnc, SIZE_MNC);
366 gmmreg_attach_cnf->lac = gmm_data->kern.sig_cell_info.env.rai.lac;
367 gmmreg_attach_cnf->rac = gmm_data->kern.sig_cell_info.env.rai.rac;
368 gmmreg_attach_cnf->cid = gmm_data->kern.sig_cell_info.env.cid;
369 gmmreg_attach_cnf->gprs_indicator = gmm_data->kern.sig_cell_info.gmm_status;
370 gmmreg_attach_cnf->bootup_cause = REG_END;
371 #ifdef GMM_TCS4
372 gmmreg_attach_cnf->rt = gmm_data->kern.sig_cell_info.rt; /* TCS 4.0 */
373 #endif
374 PSEND ( hCommMMI, gmmreg_attach_cnf );
375
376 gmm_data->kern.attach_cap.gmmreg = FALSE;
377
378 /*
379 * ACI does not realize GSM detach if search running has been set
380 * in kern_mmgmm_nreg_cnf
381 */
382 if (GMMRR_NET_MODE_III==gmm_data->kern.sig_cell_info.net_mode
383 && GMMREG_CLASS_BG== gmm_data->kern.attach_cap.mobile_class
384 && GMMREG_AT_GPRS==attach_type)
385 {
386 kern_gmmreg_detach (GMMREG_DT_IMSI,
387 GMMCS_LIMITED_SERVICE, /* TCS 2.1 */
388 SEARCH_NOT_RUNNING,
389 GMMCS_LIMITED_SERVICE);
390 }
391 }
392 GMM_RETURN;
393 } /* kern_gmmreg_attach_cnf_sr () */
394 /*
395 +------------------------------------------------------------------------------
396 | Function : kern_gmmreg_detach
397 +------------------------------------------------------------------------------
398 | Description : This procedure sends the gmmreg_detach primitiv to ACI
399 |
400 | Parameters : detach_type - detach type
401 | cause - error cause
402 | search_running - cell search still running or not
403 |
404 +------------------------------------------------------------------------------
405 */
406 GLOBAL void kern_gmmreg_detach ( UBYTE detach_type,
407 USHORT service,
408 UBYTE search_running,
409 USHORT cause)
410 {
411 UBYTE mm_state;
412
413 GMM_TRACE_FUNCTION( "kern_gmmreg_detach" );
414
415 mm_state = GET_STATE(MM);
416
417 if (GMMREG_DT_GPRS==detach_type
418 && ( GMM_MM_DEREG==mm_state
419 || GMM_MM_REG_NO_CELL_AVAILABLE==mm_state
420 || GMM_MM_REG_INITATED_VIA_GPRS==mm_state
421 || MMGMM_LIMITED_SERVICE==gmm_data->kern.sig_cell_info.mm_status )
422 )
423 {
424 detach_type = GMMREG_DT_COMB;
425 }
426
427 TRACE_3_OUT_PARA("%s, cause: 0x%x, %s",
428 detach_type==GMMREG_DT_COMB? "comb":
429 detach_type==GMMREG_DT_IMSI? "gsm":
430 detach_type==GMMREG_DT_GPRS?"gprs":
431 detach_type==GMMREG_DT_POWER_OFF?"power off":
432 detach_type==GMMREG_DT_SIM_REMOVED?"sim removed":
433 detach_type==GMMREG_DT_LIMITED_SERVICE?"limited":
434 detach_type==GMMREG_DT_SOFT_OFF?"soft off":
435 "unknown type"
436 , cause,
437 (search_running==GMMREG_SEARCH_RUNNING?"searching":"finished"));
438
439 if ( gmm_data->kern.detach_cap.gmmreg )
440 {
441 PALLOC ( gmmreg_detach_cnf, GMMREG_DETACH_CNF );
442 gmmreg_detach_cnf->detach_type = gmm_data->kern.detach_cap.detach_type;
443 PSEND ( hCommMMI, gmmreg_detach_cnf );
444 }
445 else
446 {
447 if ( gmm_data->kern.attach_cap.gmmreg )
448 {
449 if (GMMREG_CLASS_CG==gmm_data->kern.attach_cap.mobile_class
450 && GMMREG_DT_IMSI==detach_type)
451 {
452 kern_gmmreg_attach_cnf_sr(GMMREG_AT_GPRS, search_running);
453 }
454 else
455 {
456 PALLOC ( gmmreg_attach_rej, GMMREG_ATTACH_REJ );
457 gmmreg_attach_rej->detach_type = detach_type;
458 gmmreg_attach_rej->cause = cause;
459 gmmreg_attach_rej->search_running = search_running;
460 gmmreg_attach_rej->service = service;
461 PSEND ( hCommMMI, gmmreg_attach_rej );
462 }
463 if (GMMREG_SEARCH_NOT_RUNNING==search_running)
464 {
465 gmm_data->kern.attach_cap.gmmreg=FALSE;
466 }
467
468 }
469 else /* if ! gmmreg */
470 {
471 /*
472 * If gmmsm == TRUE means, we are in GMM_REGISTERED_INITIATED state.
473 * That means, if ACI did not send an attach request ACI need not
474 * to be informed, otherwise we are attached in ACI has to be informed
475 */
476 #ifndef GMM_TCS4
477 if ( !gmm_data->kern.attach_cap.gmmsm )
478 #endif
479 {
480 PALLOC ( gmmreg_detach_ind, GMMREG_DETACH_IND );
481 gmmreg_detach_ind->detach_type = detach_type;
482 gmmreg_detach_ind->cause = cause;
483 gmmreg_detach_ind->search_running = search_running;
484 gmmreg_detach_ind->service = service;
485 PSEND ( hCommMMI, gmmreg_detach_ind );
486 }
487 }
488 }
489 gmm_data->kern.detach_cap.gmmreg=FALSE;
490 /*
491 * Clear data before Power Off
492 */
493 if (GMMREG_DT_POWER_OFF==detach_type)
494 {
495 /*
496 * every servce i reinitilized that the test sysem may run
497 * with out real power off
498 */
499 kern_init();
500 rxgmm_init();
501 txgmm_init();
502 rdy_init();
503 sync_gmm_init();
504
505 /*
506 * In kern_init the deep is set to 0 for MACRO GMM_RETURN
507 */
508 return;
509 }
510 GMM_RETURN;
511 } /* kern_gmmreg_detach () */
512
513 /*
514 +------------------------------------------------------------------------------
515 | Function : kern_llgmm_assign_tlli
516 +------------------------------------------------------------------------------
517 | Description : This procedure assigned the given TLLI parameter to LLC
518 |
519 | Parameters : new_tlli_type - type of new TLLI (random, local ,..)
520 | old_tlli_type - type of old TLLI
521 |
522 +------------------------------------------------------------------------------
523 */
524 GLOBAL void kern_llgmm_assign_tlli ( T_TLLI_TYPE new_tlli_type,
525 T_TLLI_TYPE old_tlli_type )
526 {
527 GMM_TRACE_FUNCTION( "kern_llgmm_assign_tlli" );
528
529 if( GMM_LLC_STATE_UNASSIGNED EQ gmm_data->kern.attach_cap.llc_state )
530 {
531 gmm_data->kern.attach_cap.llc_state = GMM_LLC_STATE_ASSIGNED;
532 }
533 {
534 PALLOC ( llgmm_assign_req, LLGMM_ASSIGN_REQ );
535 llgmm_assign_req->old_tlli = gmm_get_tlli ( old_tlli_type );
536 if ( GMMRR_TMSI_INVALID == gmm_data->ptmsi.current )
537 {
538 /*
539 * <R.GMM.TLLIUSE.M.005>
540 */
541 llgmm_assign_req->new_tlli = gmm_get_tlli ( RANDOM_TLLI );
542 }
543 else
544 {
545 llgmm_assign_req->new_tlli = gmm_get_tlli ( new_tlli_type );
546 }
547 if (NO_KEY== gmm_data->kern.auth_cap.cksn)
548 {
549 memset (llgmm_assign_req->llgmm_kc.key, 0x0, MAX_KC);
550 }
551 else
552 {
553 memcpy ( llgmm_assign_req->llgmm_kc.key, gmm_data->kern.auth_cap.kc, MAX_KC );
554 }
555 llgmm_assign_req->ciphering_algorithm = LLGMM_CIPHER_NA;
556
557 TRACE_2_OUT_PARA("TLLI old: 0x%X, new: 0x%X", llgmm_assign_req->old_tlli,llgmm_assign_req->new_tlli);
558
559 PSEND ( hCommLLC, llgmm_assign_req );
560 }
561 GMM_RETURN;
562 } /* kern_llgmm_assign_tlli() */
563 /*
564 +------------------------------------------------------------------------------
565 | Function : kern_llgmm_assign
566 +------------------------------------------------------------------------------
567 | Description : This procedure assigned the current TLLI parameter to LLC
568 |
569 | Parameters : void
570 |
571 +------------------------------------------------------------------------------
572 */
573 GLOBAL void kern_llgmm_assign ( void )
574 {
575 GMM_TRACE_FUNCTION( "kern_llgmm_assign" );
576 kern_llgmm_assign_tlli ( CURRENT_TLLI, OLD_TLLI );
577 GMM_RETURN;
578 } /* kern_llgmm_assign() */
579 /*
580 +------------------------------------------------------------------------------
581 | Function : kern_gmmsm_establish_rej
582 +------------------------------------------------------------------------------
583 | Description : This procedure informs SM that gprs is off.
584 |
585 | Parameters : void
586 |
587 +------------------------------------------------------------------------------
588 */
589 GLOBAL void kern_gmmsm_establich_rej ( void )
590 {
591 GMM_TRACE_FUNCTION( "kern_gmmsm_stablich_rej" );
592
593 #ifdef GMM_TCS4
594
595 {
596 PALLOC (mmpm_detach_ind, MMPM_DETACH_IND);
597 mmpm_detach_ind->ps_cause = kern_make_new_cause();
598 /*For reattach, overwrite the cause from kern_make_new_cause()*/
599 if (GMM_DT_RE_ATTACH == gmm_data->kern.detach_cap.detach_type) {
600 mmpm_detach_ind->ps_cause.ctrl_value = CAUSE_is_from_mm;
601 mmpm_detach_ind->ps_cause.value.mm_cause =
602 (U16)CAUSE_MM_DETACH_WITH_REATTACH;
603 }
604 PSEND ( hCommSM, mmpm_detach_ind);
605 }
606
607 #else /*New TI DK primitive should be sent*/
608 if ( gmm_data->kern.attach_cap.gmmsm )
609 {
610 PALLOC ( gmmsm_establish_rej, GMMSM_ESTABLISH_REJ );
611 gmmsm_establish_rej->sm_cause = gmm_data->kern.detach_cap.error_cause;
612 PSEND ( hCommSM, gmmsm_establish_rej );
613 }
614 else // if !gmmsm
615 {
616
617 // <R.GMM.PRELIND.M.001>
618
619 PALLOC ( gmmsm_release_ind, GMMSM_RELEASE_IND);
620 PSEND ( hCommSM, gmmsm_release_ind );
621 }
622
623 #endif
624
625
626
627 GMM_RETURN;
628 } /* kern_gmmsm_establish_rej() */
629
630
631 /*
632 +------------------------------------------------------------------------------
633 | Function : kern_llgmm_unassign
634 +------------------------------------------------------------------------------
635 | Description : This procedure unassigned all TLLIs in LLC
636 |
637 | Parameters : void
638 |
639 +------------------------------------------------------------------------------
640 */
641 GLOBAL void kern_llgmm_unassign ( void )
642 {
643 GMM_TRACE_FUNCTION( "kern_llgmm_unassign" );
644
645 switch (gmm_data->kern.attach_cap.llc_state)
646 {
647 case GMM_LLC_STATE_UNASSIGNED:
648 GMM_RETURN;
649 default:
650 case GMM_LLC_STATE_ASSIGNED:
651 case GMM_LLC_STATE_SUSPENED:
652 case GMM_LLC_STATE_SUSPENED_RAU:
653 gmm_data->kern.attach_cap.llc_state = GMM_LLC_STATE_UNASSIGNED;
654 break;
655 }
656
657
658
659 /*
660 * PTMSI is still valid for next attach
661 * gmm_data->ptmsi.current = GMMRR_TMSI_INVALID;
662 */
663 gmm_data->ptmsi.new_grr = GMMRR_TMSI_INVALID;
664
665 gmm_data->tlli.old=gmm_data->tlli.current;
666 gmm_data->tlli.current_type = INVALID_TLLI;
667 gmm_data->tlli.current=GMMRR_TMSI_INVALID;
668
669 TRACE_0_OUT_PARA("Unassign");
670 {
671 PALLOC ( gmmrr_assign_req, GMMRR_ASSIGN_REQ );
672 gmmrr_assign_req->old_tlli = GMMRR_TLLI_INVALID;
673 gmmrr_assign_req->new_tlli = GMMRR_TLLI_INVALID;
674 gmmrr_assign_req->old_ptmsi = GMMRR_TMSI_INVALID;
675 gmmrr_assign_req->new_ptmsi = GMMRR_TMSI_INVALID;
676 gmmrr_assign_req->imsi = gmm_data->imsi;
677 gmmrr_assign_req->rai.plmn.v_plmn=TRUE;
678 memcpy (gmmrr_assign_req->rai.plmn.mcc, gmm_data->kern.attach_cap.rai_accepted.mcc, SIZE_MCC);
679 memcpy (gmmrr_assign_req->rai.plmn.mnc, gmm_data->kern.attach_cap.rai_accepted.mnc, SIZE_MNC);
680 gmmrr_assign_req->rai.lac = gmm_data->kern.attach_cap.rai_accepted.lac;
681 gmmrr_assign_req->rai.rac = gmm_data->kern.attach_cap.rai_accepted.rac;
682 PSEND ( hCommGRR, gmmrr_assign_req );
683 }
684 {
685 PALLOC (llgmm_assign_req, LLGMM_ASSIGN_REQ);
686
687 /* gmm_data->tlli.current_type=INVALID_TLLI; */
688
689 llgmm_assign_req->old_tlli = LLGMM_TLLI_INVALID;
690 llgmm_assign_req->new_tlli = LLGMM_TLLI_INVALID;
691
692 memset (llgmm_assign_req->llgmm_kc.key,0, sizeof (llgmm_assign_req->llgmm_kc.key));
693
694 llgmm_assign_req->ciphering_algorithm = LLGMM_CIPHER_NO_ALGORITHM;
695 kern_reset_cipher ();
696
697 PSEND ( hCommLLC, llgmm_assign_req );
698 }
699
700 GMM_RETURN;
701 } /* kern_llgmm_unassign() */
702 /*
703 +------------------------------------------------------------------------------
704 | Function : kern_llgmm_suspend
705 +------------------------------------------------------------------------------
706 | Description : This procedure suspends LLC
707 |
708 | Parameters : susp_cause - cause off suspension
709 |
710 +------------------------------------------------------------------------------
711 */
712 GLOBAL void kern_llgmm_suspend ( UBYTE susp_cause)
713 {
714 U8 cell_state=GMMREG_CS_CALL;
715 #ifdef GMM_TCS4
716 U8 mm_cause = CAUSE_MM_DEDICATED_MODE;
717 #endif
718
719 GMM_TRACE_FUNCTION( "kern_llgmm_suspend" );
720 /*
721 * if LLC is in suspended RAU it means that GRR has opned the GMM queue
722 * so we have to remember.
723 */
724 switch (gmm_data->kern.attach_cap.llc_state)
725 {
726 case GMM_LLC_STATE_SUSPENED_RAU:
727 GMM_RETURN;
728 case GMM_LLC_STATE_UNASSIGNED:
729 TRACE_ERROR ("suspending of LLC in state unassigned ignored");
730 GMM_RETURN;
731 default:
732 case GMM_LLC_STATE_ASSIGNED:
733 case GMM_LLC_STATE_SUSPENED:
734 break;
735 }
736
737 switch (susp_cause)
738 {
739 case LLGMM_CALL:
740 TRACE_0_OUT_PARA("call");
741
742 cell_state=GMMREG_CS_CALL;
743 #ifdef GMM_TCS4
744 mm_cause = CAUSE_MM_DEDICATED_MODE;
745 #endif
746 break;
747
748 case LLGMM_LIMITED:
749 TRACE_0_OUT_PARA("limited");
750 cell_state=GMMREG_LIMITED_SERVICE;
751 #ifdef GMM_TCS4
752 mm_cause = CAUSE_MM_LIMITED_SERVICE;
753 #endif
754 break;
755
756 case LLGMM_NO_GPRS_SERVICE:
757 TRACE_0_OUT_PARA("no_service");
758 cell_state=GMMREG_GPRS_NOT_SUPPORTED;
759 #ifdef GMM_TCS4
760 mm_cause = CAUSE_MM_NO_SERVICE;
761 #endif
762 break;
763
764 case LLGMM_RAU:
765 cell_state=GMMREG_TRY_TO_UPDATE;
766 #ifdef GMM_TCS4
767 mm_cause = CAUSE_MM_TRY_TO_UPDATE;
768 #endif
769
770 if(GET_STATE(CU) EQ CU_CELL_RES_SENT
771 || GET_STATE(CU) EQ CU_REQUESTED_CELL_RES_SENT)
772 {
773 susp_cause= LLGMM_PERIODIC_RAU;
774 /* NO break; */
775 }
776 else
777 {
778 gmm_data->kern.attach_cap.llc_state=GMM_LLC_STATE_SUSPENED_RAU;
779 TRACE_0_OUT_PARA("rau");
780 break;
781 }
782 /* GS, how would you solve it with V8?*/
783 case LLGMM_PERIODIC_RAU:
784 if (GMM_LLC_STATE_SUSPENED==gmm_data->kern.attach_cap.llc_state)
785 {
786 GMM_RETURN;
787 }
788 else
789 {
790 TRACE_0_OUT_PARA("periodic rau");
791 cell_state=GMMREG_TRY_TO_UPDATE;
792 #ifdef GMM_TCS4
793 mm_cause = CAUSE_MM_TRY_TO_UPDATE;
794 #endif
795 }
796 break;
797 default:
798 TRACE_ERROR("llc_susp unexpected");
799 break;
800 }
801
802 if (GMM_LLC_STATE_SUSPENED_RAU!=gmm_data->kern.attach_cap.llc_state)
803 {
804 gmm_data->kern.attach_cap.llc_state= GMM_LLC_STATE_SUSPENED;
805 }
806
807 {
808 PALLOC (llgmm_suspend_req, LLGMM_SUSPEND_REQ);
809 llgmm_suspend_req->susp_cause = susp_cause;
810 PSEND ( hCommLLC, llgmm_suspend_req );
811 }
812
813 {
814 PALLOC(gmmreg_suspend_ind, GMMREG_SUSPEND_IND);
815 gmmreg_suspend_ind->cell_state= cell_state;
816 PSEND(hCommMMI,gmmreg_suspend_ind);
817 }
818 #ifdef GMM_TCS4
819 {
820 PALLOC(mmpm_suspend_ind, MMPM_SUSPEND_IND);
821 mmpm_suspend_ind->ps_cause.ctrl_value = CAUSE_is_from_mm;
822 mmpm_suspend_ind->ps_cause.value.mm_cause = mm_cause;
823 PSEND(hCommSM,mmpm_suspend_ind);
824 }
825 #endif
826 GMM_RETURN;
827 } /* kern_llgmm_suspend() */
828 /*
829 +------------------------------------------------------------------------------
830 | Function : kern_llgmm_resume
831 +------------------------------------------------------------------------------
832 | Description : This procedure resumes LLC
833 |
834 | Parameters : void
835 |
836 +------------------------------------------------------------------------------
837 */
838 GLOBAL void kern_llgmm_resume ( void )
839 {
840 GMM_TRACE_FUNCTION( "kern_llgmm_resume" );
841
842 switch(gmm_data->kern.attach_cap.llc_state)
843 {
844 case GMM_LLC_STATE_SUSPENED_RAU:
845 case GMM_LLC_STATE_SUSPENED:
846 {
847 PALLOC (llgmm_resume_req, LLGMM_RESUME_REQ);
848 gmm_data->kern.attach_cap.llc_state=GMM_LLC_STATE_ASSIGNED;
849 PSEND ( hCommLLC, llgmm_resume_req );
850 }
851 {
852 PALLOC (gmmreg_resume_ind, GMMREG_RESUME_IND);
853 PSEND ( hCommMMI, gmmreg_resume_ind );
854 }
855
856 #ifdef GMM_TCS4
857 {
858 PALLOC(mmpm_resume_ind, MMPM_RESUME_IND);
859 PSEND(hCommSM,mmpm_resume_ind);
860 }
861 #endif
862 break;
863 case GMM_LLC_STATE_ASSIGNED:
864 default:
865 break;
866 case GMM_LLC_STATE_UNASSIGNED:
867 TRACE_ERROR("resuming LLC in state unassigned");
868 kern_llgmm_assign();
869 break;
870 }
871 kern_gmmrr_stop_waiting_for_transmission();
872 GMM_RETURN;
873 } /* kern_llgmm_suspend() */
874
875
876 /*
877 +------------------------------------------------------------------------------
878 | Function : kern_gmmrr_enable
879 +------------------------------------------------------------------------------
880 | Description : The function kern_enable()
881 | disables GRR and activates MM to act as a class CC mobile.
882 |
883 | Parameters : void
884 |
885 +------------------------------------------------------------------------------
886 */
887 GLOBAL void kern_gmmrr_enable ( void )
888 {
889 GMM_TRACE_FUNCTION ("kern_gmmrr_enable()");
890 gmm_data->kern.attach_cap.mobile_class_changed = FALSE;
891 {
892 PALLOC ( gmmrr_enable_req, GMMRR_ENABLE_REQ );
893 TRACE_EVENT ("GRR is on");
894 gmm_data->kern.attach_cap.grr_state = GMM_GRR_STATE_ON;
895 gmmrr_enable_req->mobile_class = gmm_data->kern.attach_cap.mobile_class;
896 gmmrr_enable_req->acc_contr_class = gmm_data->acc_contr_class;
897 if (DRX_NOT_USED==gmm_data->drx_parameter.split_pg_cycle_code)
898 {
899 gmmrr_enable_req->split_pg_cycle = 704/* GMMREG_NO_DRX*/;
900 }
901 else if (gmm_data->drx_parameter.split_pg_cycle_code<65)
902 {
903 gmmrr_enable_req->split_pg_cycle
904 = gmm_data->drx_parameter.split_pg_cycle_code;
905 }
906 else if (gmm_data->drx_parameter.split_pg_cycle_code<=98)
907 {
908 const USHORT cycle_array[] =
909 {
910 71, 72, 74, 75, 77, 79, 80, 83, 86, 88, 90, 92, 96, 101, 103, 107,
911 112,116, 118, 128, 141, 144, 150, 160, 171, 176, 192, 214, 224, 235,
912 256, 288, 320, 352
913 };
914
915 gmmrr_enable_req->split_pg_cycle
916 = cycle_array[gmm_data->drx_parameter.split_pg_cycle_code-65];
917 }
918 else
919 {
920 gmmrr_enable_req->split_pg_cycle = 1;
921 }
922
923 if( gmm_data->drx_parameter.split_on_ccch EQ SPLIT_NO )
924 {
925 gmmrr_enable_req->spgc_ccch_supp = GMMRR_SPGC_CCCH_SUPP_NO;
926 }
927 else
928 {
929 gmmrr_enable_req->spgc_ccch_supp = GMMRR_SPGC_CCCH_SUPP_YES;
930 }
931
932 gmmrr_enable_req->gmmrr_non_drx_timer = gmm_data->drx_parameter.non_drx_timer;
933
934 PSEND ( hCommGRR, gmmrr_enable_req );
935 }
936 GMM_RETURN;
937 } /* kern_gmmrr_ensable () */
938
939 /*
940 +------------------------------------------------------------------------------
941 | Function : kern_gmmrr_disable
942 +------------------------------------------------------------------------------
943 | Description : The function kern_gmmrr_disable switches off GRR
944 |
945 | Parameters : cm_estasblish_res - OK or NOT to establish the CM
946 |
947 +------------------------------------------------------------------------------
948 */
949 GLOBAL void kern_gmmrr_disable ( void )
950 {
951 GMM_TRACE_FUNCTION ("kern_gmmrr_disable()");
952 TRACE_EVENT ("GRR is off");
953
954 /*gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_CC;*/
955 gmm_data->kern.attach_cap.attach_type &= ~GMMREG_AT_GPRS;
956
957 gmm_data->kern.attach_cap.grr_state = GMM_GRR_STATE_OFF;
958 gmm_data->kern.suspension_type &= ~GMM_SUSP_LOCAL_DETACH;
959
960 /* This code is applicable only for Release 99 */
961 #ifdef REL99
962 gmm_data->ptmsi_signature.available = FALSE;
963 gmm_data->ptmsi_signature.value = INVALID_PTMSI_SIGNATURE;
964 #endif
965
966 kern_llgmm_unassign();
967
968
969 {
970 PALLOC ( gmmrr_disable_req, GMMRR_DISABLE_REQ );
971 PSEND ( hCommGRR, gmmrr_disable_req );
972 }
973 /* kern_mm_activate_mm (); */
974 GMM_RETURN;
975 } /* kern_gmmrr_disable () */
976 /*
977 +------------------------------------------------------------------------------
978 | Function : kern_mm_cm_establish_res
979 +------------------------------------------------------------------------------
980 | Description : The function mm_cm_establish_res is a response whether a CS call
981 | is possible or not
982 |
983 | Parameters : cm_estasblish_res - OK or NOT to establish the CM
984 |
985 +------------------------------------------------------------------------------
986 */
987 GLOBAL void kern_mm_cm_establish_res ( UBYTE cm_establish_res )
988 {
989 GMM_TRACE_FUNCTION ("kern_mm_cm_establish_res ()");
990 {
991 PALLOC ( mmgmm_cm_establish_res, MMGMM_CM_ESTABLISH_RES);
992 mmgmm_cm_establish_res->cm_establish_res = cm_establish_res;
993 gmm_data->kern.suspension_type &= ~GMM_SUSP_CALL;
994 PSEND ( hCommMM, mmgmm_cm_establish_res );
995 }
996 GMM_RETURN;
997 } /* kern_mm_establish_res () */
998 /*
999 +------------------------------------------------------------------------------
1000 | Function : kern_mm_cm_emergency_res
1001 +------------------------------------------------------------------------------
1002 | Description : The function mm_cm_emrgency_res is a response whether a
1003 | emergnecy call is possible or not
1004 |
1005 | Parameters : cm_estasblish_res - OK or NOT to establish the CM
1006 |
1007 +------------------------------------------------------------------------------
1008 */
1009 GLOBAL void kern_mm_cm_emergency_res ( UBYTE cm_establish_res )
1010 {
1011 GMM_TRACE_FUNCTION ("kern_mm_cm_emergency_res ()");
1012 {
1013 PALLOC ( mmgmm_cm_emergency_res, MMGMM_CM_EMERGENCY_RES);
1014 mmgmm_cm_emergency_res->cm_establish_res = cm_establish_res;
1015 PSEND ( hCommMM, mmgmm_cm_emergency_res );
1016 gmm_data->kern.suspension_type &= ~GMM_SUSP_EM_CALL;
1017 }
1018 GMM_RETURN;
1019 } /* kern_mm_emergency_res () */
1020 /*
1021 +------------------------------------------------------------------------------
1022 | Function : kern_mm_net_req
1023 +------------------------------------------------------------------------------
1024 | Description : The function kern_mm_net_req sends the promitve to MM
1025 |
1026 | Parameters : void
1027 |
1028 +------------------------------------------------------------------------------
1029 */
1030 GLOBAL void kern_mm_net_req ( void )
1031 {
1032 GMM_TRACE_FUNCTION( "kern_mm_net_req" );
1033 {
1034 PALLOC ( mmgmm_net_req, MMGMM_NET_REQ );
1035 PSEND ( hCommMM, mmgmm_net_req);
1036 }
1037 GMM_RETURN;
1038 } /* kern_mm_net_req() */
1039 /*
1040 +------------------------------------------------------------------------------
1041 | Function : kern_mm_start_t3212
1042 +------------------------------------------------------------------------------
1043 | Description : This procedure is called: "If the detach type information
1044 | element value indicates "GPRS detach without switching off ?and
1045 | the MS is attached for GPRS and non-GPRS services and the
1046 | network operates in network operation mode I, then if in the MS
1047 | the timer T3212 is not already running, the timer T3212 shall be
1048 | set to its initial value and restarted after the DETACH REQUEST
1049 | message has been sent."
1050 |
1051 | <R.GMM.DINITM.M.007>
1052 |
1053 | Parameters : void
1054 |
1055 +------------------------------------------------------------------------------
1056 */
1057 GLOBAL void kern_mm_start_t3212 ( void )
1058 {
1059 GMM_TRACE_FUNCTION( "kern_mm_start_t3212" );
1060 {
1061 PALLOC ( mmgmm_start_t3212_req, MMGMM_START_T3212_REQ );
1062 PSEND ( hCommMM, mmgmm_start_t3212_req);
1063 }
1064 GMM_RETURN;
1065 } /* kern_mm_start_t3212() */
1066 /*
1067 +------------------------------------------------------------------------------
1068 | Function : kern_ssim_authentication_req
1069 +------------------------------------------------------------------------------
1070 | Description : The function kern_sim_authentication_req
1071 |
1072 | Parameters : void
1073 |
1074 +------------------------------------------------------------------------------
1075 */
1076 GLOBAL void kern_sim_authentication_req ( UBYTE *random, UBYTE cksn )
1077 {
1078 GMM_TRACE_FUNCTION( "kern_sim_authentication_req" );
1079 {
1080 PALLOC (sim_authentication_req, SIM_AUTHENTICATION_REQ);
1081 sim_authentication_req->source = SRC_GMM;
1082 #ifdef GMM_TCS4
1083 sim_authentication_req->req_id = gmm_data->kern.auth_cap.last_auth_req_id;
1084 #endif
1085 memcpy (
1086 sim_authentication_req->rand, random, MAX_RAND);
1087 sim_authentication_req->cksn = cksn;
1088 PSEND (hCommSIM, sim_authentication_req);
1089 }
1090 GMM_RETURN;
1091 } /* kern_mm_authentication_req() */
1092 /*
1093 +------------------------------------------------------------------------------
1094 | Function : kern_mm_attach_started
1095 +------------------------------------------------------------------------------
1096 | Description : The function kern_mm_attach_started sends the primitive
1097 | mmgmm_attach_started_req to MM
1098 |
1099 | Parameters : void
1100 |
1101 +------------------------------------------------------------------------------
1102 */
1103 GLOBAL void kern_mm_attach_started ( void )
1104 {
1105 GMM_TRACE_FUNCTION( "kern_mm_attach_started" );
1106
1107 SET_STATE ( MM, GMM_MM_REG_INITATED_VIA_GPRS);
1108 {
1109 PALLOC ( mmgmm_attach_started_req, MMGMM_ATTACH_STARTED_REQ );
1110 PSEND ( hCommMM, mmgmm_attach_started_req);
1111 }
1112 GMM_RETURN;
1113 } /* kern_mm_attach_started() */
1114 /*
1115 +------------------------------------------------------------------------------
1116 | Function : kern_mm_auth_rej
1117 +------------------------------------------------------------------------------
1118 | Description : The function kern_mm_atuth_rej sends the primitive
1119 | mmgmm_auth_req to MM
1120 |
1121 | Parameters :
1122 |
1123 +------------------------------------------------------------------------------
1124 */
1125 GLOBAL void kern_mm_auth_rej ( void )
1126 {
1127 GMM_TRACE_FUNCTION( "kern_mm_auth_rej" );
1128 {
1129 PALLOC ( mmgmm_auth_rej_req, MMGMM_AUTH_REJ_REQ );
1130 PSEND ( hCommMM, mmgmm_auth_rej_req);
1131 }
1132 GMM_RETURN;
1133 } /* kern_mm_attach_rej() */
1134 /*
1135 +------------------------------------------------------------------------------
1136 | Function : kern_mm_attach_rej
1137 +------------------------------------------------------------------------------
1138 | Description : The function kern_mm_attach_rej sends the primitive
1139 | mmgmm_attach_rej_req to MM. The primitive is always sent if
1140 | responce from MM is expected, .i.e no MMGMM_NREG_CNF
1141 |
1142 | Parameters : error_cause - the error cause given by the net or
1143 | MMGMM_AAC_OVER_5 if attach_attempt_counter is greater or equal
1144 | than 5
1145 |
1146 +------------------------------------------------------------------------------
1147 */
1148 GLOBAL void kern_mm_attach_rej ( USHORT error_cause )
1149 {
1150 GMM_TRACE_FUNCTION( "kern_mm_attach_rej" );
1151
1152 //if (GMM_MM_REG_INITATED_VIA_GPRS==gmm_data->mm_imsi_attached)
1153 {
1154 PALLOC ( mmgmm_attach_rej_req, MMGMM_ATTACH_REJ_REQ );
1155 /*
1156 * Anite B2 TC 44.2.1.2.8
1157 */
1158 SET_STATE ( MM, GMM_MM_DEREG);
1159
1160 mmgmm_attach_rej_req-> cause = error_cause; /* TCS 2.1 */
1161 PSEND ( hCommMM, mmgmm_attach_rej_req);
1162 }
1163 /*
1164 else
1165 {
1166 kern_mm_imsi_detach_ind ( error_cause, MMGMM_DETACH_DONE);
1167 }
1168 */
1169 GMM_RETURN;
1170 } /* kern_mm_attach_rej() */
1171
1172 /*
1173 +------------------------------------------------------------------------------
1174 | Function : kern_mm_attach_acc
1175 +------------------------------------------------------------------------------
1176 | Description : The function kern_mm_attach_acc sends the promitve to MM.
1177 |
1178 | Parameters : mobile_identity - TMSI given by the network
1179 |
1180 +------------------------------------------------------------------------------
1181 */
1182 GLOBAL void kern_mm_attach_acc ( BOOL v_mobile_identity, /* TCS 2.1 */
1183 T_mobile_identity * mobile_identity, /* TCS 2.1 */
1184 BOOL v_eqv_plmn_list, /* TCS 2.1 */
1185 T_eqv_plmn_list * eqv_plmn_list /* TCS 2.1 */
1186 ) /* TCS 2.1 */
1187 {
1188 GMM_TRACE_FUNCTION( "kern_mm_attach_acc" );
1189 /*
1190 * HM: This catches never...
1191 * Patch HM 07-Aug-01, make GMM2503 pass >>>
1192 * GMM thinks it performs a combined attach in network mode I,
1193 * but the truth is we came from network mode I and are now
1194 * performing the non-combined procedures in network mode II.
1195 */
1196 if ( GMM_MM_REG_INITATED_VIA_GPRS == GET_STATE(MM) )
1197 /* Patch HM 07-Aug-01, make GMM2503 pass <<< */
1198 {
1199 PALLOC ( mmgmm_attach_acc_req, MMGMM_ATTACH_ACC_REQ );
1200
1201 sig_kern_sync_set_mm_state ( MMGMM_FULL_SERVICE );
1202
1203 gmm_data->kern.mm_cell_env.rai.lac = gmm_data->kern.sig_cell_info.env.rai.lac;
1204 gmm_data->kern.mm_cell_env.rai.plmn = gmm_data->kern.sig_cell_info.env.rai.plmn;
1205 mmgmm_attach_acc_req->v_tmsi = v_mobile_identity;
1206 mmgmm_attach_acc_req->lac = gmm_data->kern.mm_cell_env.rai.lac;
1207 mmgmm_attach_acc_req->plmn.v_plmn = TRUE;
1208 memcpy(mmgmm_attach_acc_req->plmn.mnc,gmm_data->kern.mm_cell_env.rai.plmn.mnc,SIZE_MNC);
1209 memcpy (mmgmm_attach_acc_req->plmn.mcc, gmm_data->kern.mm_cell_env.rai.plmn.mcc,SIZE_MCC);
1210 mmgmm_attach_acc_req->tmsi =
1211 (v_mobile_identity?gmm_data->tmsi:MMGMM_TMSI_INVALID);
1212 mmgmm_attach_acc_req->v_equ_plmn_list = v_eqv_plmn_list; /* TCS 2.1 */
1213 if (v_eqv_plmn_list) /* TCS 2.1 */
1214 memcpy(&mmgmm_attach_acc_req->equ_plmn_list, eqv_plmn_list, sizeof(T_equ_plmn_list)); /* TCS 2.1 */
1215 PSEND ( hCommMM, mmgmm_attach_acc_req);
1216 }
1217 else
1218 {
1219 PALLOC ( mmgmm_allowed_req, MMGMM_ALLOWED_REQ );
1220 mmgmm_allowed_req->lac = gmm_data->kern.attach_cap.rai_accepted.lac;
1221 mmgmm_allowed_req->plmn.v_plmn = TRUE;
1222 memcpy(mmgmm_allowed_req->plmn.mnc,gmm_data->kern.attach_cap.rai_accepted.mnc,SIZE_MNC);
1223 memcpy (mmgmm_allowed_req->plmn.mcc, gmm_data->kern.attach_cap.rai_accepted.mcc,SIZE_MCC);
1224 mmgmm_allowed_req->v_equ_plmn_list = v_eqv_plmn_list; /* TCS 2.1 */
1225 if (v_eqv_plmn_list) /* TCS 2.1 */
1226 memcpy(&mmgmm_allowed_req->equ_plmn_list, eqv_plmn_list, sizeof(T_equ_plmn_list)); /* TCS 2.1 */
1227 PSEND ( hCommMM, mmgmm_allowed_req);
1228 }
1229 GMM_RETURN;
1230 } /* kern_mm_attach_acc() */
1231
1232 /*
1233 +------------------------------------------------------------------------------
1234 | Function : kern_mm_reg_req
1235 +------------------------------------------------------------------------------
1236 | Description : The function kern_mm_reg_req sends the primitive
1237 | MMGMM_REG_REQ to MM
1238 |
1239 | Parameters :
1240 |
1241 +------------------------------------------------------------------------------
1242 */
1243 GLOBAL void kern_mm_reg_req (U8 reg_type, U8 bootup_act)
1244 {
1245 GMM_TRACE_FUNCTION( "kern_mm_reg_req" );
1246 {
1247 PALLOC ( mmgmm_reg_req, MMGMM_REG_REQ ); /* T_MMGMM_REG_REQ */
1248 mmgmm_reg_req->reg_type = reg_type;
1249 mmgmm_reg_req->service_mode = gmm_data->kern.attach_cap.service_mode;
1250 mmgmm_reg_req->mobile_class = gmm_data->kern.attach_cap.mobile_class;
1251 mmgmm_reg_req->bootup_act = bootup_act;
1252 PSEND ( hCommMM, mmgmm_reg_req );
1253 }
1254 GMM_RETURN;
1255 } /* kern_mm_attach_rej() */
1256
1257 /*
1258 +------------------------------------------------------------------------------
1259 | Function : kern_mm_activate_rr
1260 +------------------------------------------------------------------------------
1261 | Description : The MMGMM_ACTIVATE_REQ is used to initiate GPRS Cell Selection
1262 | in RR. Cell selection for CS only is triggered implicitly be
1263 | activating MM (i.e. the MS is operates as a class CC mobile) by
1264 | sending the primitive discribed in function kern_mm_activate_mm
1265 | Parameters : void
1266 |
1267 +------------------------------------------------------------------------------
1268 */
1269 GLOBAL void kern_mm_activate_rr ( void )
1270 {
1271 GMM_TRACE_FUNCTION ("kern_mm_activate_rr()");
1272
1273 if (gmm_data->kern.attach_cap.network_selection_mode EQ MODE_AUTO)
1274 {
1275 kern_mm_reg_req (REG_CELL_SEARCH_ONLY, NORMAL_REG);
1276 }
1277 else
1278 {
1279 PALLOC ( mmgmm_plmn_res, MMGMM_PLMN_RES ); /* T_MMGMM_PLMN_RES */
1280 mmgmm_plmn_res->plmn = gmm_data->kern.attach_cap.plmn_requested;
1281 mmgmm_plmn_res->reg_type = REG_CELL_SEARCH_ONLY;
1282 mmgmm_plmn_res->mobile_class = gmm_data->kern.attach_cap.mobile_class;
1283 PSEND ( hCommMM, mmgmm_plmn_res );
1284 }
1285
1286 kern_gmmrr_enable();
1287 GMM_RETURN;
1288 } /* kern_mm_activate_rr () */
1289
1290 /*
1291 +------------------------------------------------------------------------------
1292 | Function : kern_mm_activate_mm
1293 +------------------------------------------------------------------------------
1294 | Description : The MM_ACTIVATE_MM_REQ is used to request MM to act as
1295 | an GSM-only mobile.
1296 |
1297 | Parameters : void
1298 |
1299 +------------------------------------------------------------------------------
1300 */
1301 GLOBAL void kern_mm_activate_mm ( void )
1302 {
1303 GMM_TRACE_FUNCTION ("kern_mm_activate_mm()");
1304
1305 if (GMMREG_CLASS_CG!=gmm_data->kern.attach_cap.mobile_class)
1306 {
1307 /*
1308 * remember lau initiated
1309 */
1310 gmm_data->kern.attach_cap.mm_lau_attempted = TRUE;
1311
1312 if (gmm_data->kern.attach_cap.network_selection_mode EQ MODE_AUTO)
1313 {
1314 kern_mm_reg_req (REG_GPRS_INACTIVE, NORMAL_REG);
1315 }
1316 else
1317 {
1318 PALLOC ( mmgmm_plmn_res, MMGMM_PLMN_RES ); /* T_MMGMM_PLMN_RES */
1319 mmgmm_plmn_res->plmn = gmm_data->kern.attach_cap.plmn_requested;
1320 mmgmm_plmn_res->reg_type = REG_GPRS_INACTIVE;
1321 mmgmm_plmn_res->mobile_class = gmm_data->kern.attach_cap.mobile_class;
1322 PSEND ( hCommMM, mmgmm_plmn_res );
1323 }
1324 }
1325 GMM_RETURN;
1326 } /* kern_mm_activate_rr () */
1327
1328 /*
1329 +------------------------------------------------------------------------------
1330 | Function : kern_local_detach_open_proc
1331 +------------------------------------------------------------------------------
1332 | Description : The function kern_local_detach_open_proc() calls all open
1333 | issues to be done upon receiving GMMRR_SUSPEND_CNF
1334 |
1335 | Parameters : void
1336 |
1337 +------------------------------------------------------------------------------
1338 */
1339 GLOBAL void kern_local_detach_open_proc (void )
1340 {
1341 GMM_TRACE_FUNCTION( "kern_local_detach_open_proc" );
1342
1343 TRACE_1_INFO ("open %d",gmm_data->kern.detach_cap.local_detach_open_proc);
1344
1345
1346 switch ( gmm_data->kern.detach_cap.local_detach_open_proc)
1347 {
1348 case GMM_LOCAL_DETACH_PROC_RESUME:
1349 kern_resume_grr_der();
1350 break;
1351 case GMM_LOCAL_DETACH_PROC_ENTER_NULL_IMSI:
1352 SET_STATE (KERN, KERN_GMM_NULL_IMSI);
1353 EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI);
1354 /* If GMM entered No Cell Available & after coming back to GSM only N/W, the user does a manual
1355 * detach, then it is necessary for GMM to disable GRR & enable GSM only mode through MM */
1356 kern_gmmrr_disable();
1357 kern_mm_activate_mm();
1358 break;
1359 case GMM_LOCAL_DETACH_PROC_ENTER_NULL_NO_IMSI:
1360 SET_STATE (KERN, KERN_GMM_NULL_NO_IMSI);
1361 EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI);
1362
1363 break;
1364 case GMM_LOCAL_DETACH_PROC_ENTER_NULL_IMSI_LIMITED_SERVICE_REQ:
1365 SET_STATE (KERN, KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ);
1366 EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ);
1367
1368 break;
1369 case GMM_LOCAL_DETACH_PROC_ENTER_REG_NORMAL:
1370 kern_enter_reg_normal();
1371 break;
1372 case GMM_LOCAL_DETACH_PROC_ENTER_DEREG:
1373 kern_enter_der();
1374 break;
1375 case GMM_LOCAL_DETACH_PROC_UNASSIGN:
1376 kern_llgmm_unassign();
1377 kern_resume_grr_der();
1378 break;
1379 case GMM_LOCAL_DETACH_PROC_SUSP_LAU:
1380 gmm_data->kern.suspension_type &= ~GMM_SUSP_LOCAL_DETACH;
1381 kern_mm_lau();
1382 break;
1383 case GMM_LOCAL_DETACH_PROC_RE_ATTACH:
1384
1385 TRACE_0_OUT_PARA("Unassign");
1386 gmm_data->tlli.old=gmm_data->tlli.current;
1387 gmm_data->tlli.current_type = INVALID_TLLI;
1388 gmm_data->tlli.current=GMMRR_TMSI_INVALID;
1389 gmm_data->kern.attach_cap.llc_state = GMM_LLC_STATE_UNASSIGNED;
1390 {
1391 PALLOC (llgmm_assign_req, LLGMM_ASSIGN_REQ);
1392
1393 gmm_data->tlli.current_type=INVALID_TLLI;
1394
1395 llgmm_assign_req->old_tlli = LLGMM_TLLI_INVALID;
1396 llgmm_assign_req->new_tlli = LLGMM_TLLI_INVALID;
1397
1398 memset (llgmm_assign_req->llgmm_kc.key,0, sizeof (llgmm_assign_req->llgmm_kc.key));
1399
1400 kern_reset_cipher ();
1401 llgmm_assign_req->ciphering_algorithm = LLGMM_CIPHER_NO_ALGORITHM;
1402
1403 PSEND ( hCommLLC, llgmm_assign_req );
1404 }
1405
1406 kern_resume_grr_der();
1407
1408 //kern_attach_reset();
1409 //kern_attach();
1410
1411 break;
1412 case GMM_LOCAL_DETACH_PROC_RAU:
1413 kern_rau();
1414 break;
1415 case GMM_LOCAL_DETACH_PROC_DISABLE:
1416 if (gmm_data->sim_gprs_invalid)
1417 {
1418 SET_STATE ( KERN, KERN_GMM_NULL_NO_IMSI);
1419 EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI);
1420
1421 }
1422 else
1423 {
1424 SET_STATE ( KERN, KERN_GMM_NULL_IMSI);
1425 EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI);
1426
1427 }
1428
1429 kern_gmmrr_disable();
1430 kern_mm_activate_mm ();
1431 break;
1432 case GMM_LOCAL_DETACH_PROC_COMB_DISABLE:
1433 SET_STATE ( KERN, KERN_GMM_NULL_NO_IMSI);
1434 EM_GMM_SET_STATE(KERN_GMM_NULL_NO_IMSI);
1435 gmm_data->kern.attach_cap.attach_type = GMMREG_AT_NOT_KNOWN;
1436 kern_gmmrr_disable();
1437 kern_mm_activate_mm ();
1438 break;
1439 case GMM_LOCAL_DETACH_PROC_AUTH_FAILED:
1440 SET_STATE ( KERN, KERN_GMM_DEREG_NO_IMSI);
1441 EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI);
1442 gmm_data->kern.attach_cap.attach_type = GMMREG_AT_NOT_KNOWN;
1443 kern_gmmrr_disable();
1444 kern_mm_imsi_detach_ind ( GMMCS_AUTHENTICATION_REJECTED, /* TCS 2.1 */
1445 GET_STATE(MM)==GMM_MM_DEREG?
1446 MMGMM_DETACH_DONE:
1447 MMGMM_PERFORM_DETACH,
1448 gmm_data->kern.detach_cap.detach_type );
1449 break;
1450 case GMM_LOCAL_DETACH_PROC_SIM_REMOVED:
1451 SET_STATE ( KERN, KERN_GMM_DEREG_NO_IMSI);
1452 EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI);
1453 gmm_data->kern.attach_cap.attach_type = GMMREG_AT_NOT_KNOWN;
1454 kern_gmmrr_disable();
1455 kern_mm_imsi_detach_ind ( GMMCS_SIM_REMOVED, /* TCS 2.1 */
1456 GET_STATE(MM)==GMM_MM_DEREG?
1457 MMGMM_DETACH_DONE:
1458 MMGMM_PERFORM_DETACH,
1459 gmm_data->kern.detach_cap.detach_type);
1460
1461 break;
1462 case GMM_LOCAL_DETACH_PROC_POWER_OFF:
1463 SET_STATE (KERN, KERN_GMM_DEREG_NO_IMSI);
1464 EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI);
1465 vsi_t_stop ( GMM_handle, kern_TPOWER_OFF);
1466 kern_gmmrr_disable();
1467 kern_mm_imsi_detach_ind ( GMMCS_POWER_OFF, /* TCS 2.1 */
1468 GET_STATE(MM)==GMM_MM_DEREG?
1469 MMGMM_DETACH_DONE:
1470 MMGMM_PERFORM_DETACH,
1471 gmm_data->kern.detach_cap.detach_type);
1472
1473 break;
1474 case GMM_LOCAL_DETACH_PROC_SOFT_OFF:
1475
1476 if (gmm_data->sim_gprs_invalid)
1477 {
1478 SET_STATE (KERN, KERN_GMM_DEREG_NO_IMSI);
1479 EM_GMM_SET_STATE(KERN_GMM_DEREG_NO_IMSI);
1480 }
1481 else
1482 {
1483 SET_STATE (KERN, KERN_GMM_NULL_IMSI);
1484 EM_GMM_SET_STATE(KERN_GMM_NULL_IMSI);
1485 }
1486 vsi_t_stop ( GMM_handle, kern_TPOWER_OFF);
1487 kern_gmmrr_disable();
1488 kern_mm_imsi_detach_ind ( GMMCS_POWER_OFF, /* TCS 2.1 */
1489 GET_STATE(MM)==GMM_MM_DEREG?
1490 MMGMM_DETACH_DONE:
1491 MMGMM_PERFORM_DETACH,
1492 gmm_data->kern.detach_cap.detach_type);
1493
1494 break;
1495
1496 case GMM_LOCAL_DETACH_PROC_NOT_CHANGED:
1497 case GMM_LOCAL_DETACH_PROC_NOTHING:
1498 default:
1499 if (GMM_GRR_STATE_SUSPENDED==gmm_data->kern.attach_cap.grr_state)
1500 {
1501 kern_resume_grr_der();
1502 }
1503 break;
1504 }
1505 gmm_data->kern.detach_cap.local_detach_open_proc=GMM_LOCAL_DETACH_PROC_NOTHING;
1506 GMM_RETURN;
1507 } /* kern_kern_local_detach_open_proc () */
1508
1509 /*
1510 +------------------------------------------------------------------------------
1511 | Function : kern_local_detach
1512 +------------------------------------------------------------------------------
1513 | Description : The function kern_local_detach() ....
1514 |
1515 | Parameters : error_cause - error cause
1516 |
1517 | gmm_data->kern.detach_cap.detach_type MUST be set !
1518 |
1519 +------------------------------------------------------------------------------
1520 */
1521 GLOBAL void kern_local_detach ( USHORT error_cause, BOOL det_acc_sent, T_LOCAL_DETACH_PROC local_detach_open_proc )
1522 {
1523 /*
1524 * compiler cl470.exe test: replace local variable detach_type with
1525 * gmm_data...detach_type
1526 * => you may get an assembler error (because switch condition
1527 * modified within case statement ??)
1528 */
1529 UBYTE detach_type = gmm_data->kern.detach_cap.detach_type;
1530 UBYTE kern_gmm_save_state = GET_STATE(KERN);
1531
1532 GMM_TRACE_FUNCTION( "kern_local_detach" );
1533
1534 if (GMM_LOCAL_DETACH_PROC_NOT_CHANGED!=local_detach_open_proc)
1535 {
1536 gmm_data->kern.detach_cap.local_detach_open_proc=local_detach_open_proc;
1537 }
1538 else
1539 {
1540 if(GMM_LOCAL_DETACH_PROC_NOTHING EQ gmm_data->kern.detach_cap.local_detach_open_proc)
1541 {
1542 TRACE_ERROR ("GMM_LOCAL_DETACH_PROC_NOTHING called");
1543 }
1544 }
1545
1546 if ( gmm_data->kern.local_detached)
1547 /*local_detach_done */
1548 {
1549 TRACE_0_INFO ("kern_local_detach() called already");
1550 gmm_data->kern.local_detached = FALSE;
1551 kern_local_detach_open_proc();
1552 GMM_RETURN;
1553 }
1554 gmm_data->kern.local_detached = TRUE;
1555
1556 switch (detach_type)
1557 {
1558 case GMMREG_DT_IMSI:
1559 break;
1560 case GMMREG_DT_POWER_OFF:
1561 SET_STATE ( KERN, KERN_GMM_DEREG_SUSPENDING );
1562 EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDING );
1563
1564 kern_gmmsm_establich_rej();
1565
1566 if (det_acc_sent)
1567 {
1568 gmm_data->kern.suspension_type |= GMM_SUSP_LOCAL_DETACH;
1569 sig_kern_rdy_start_timer_req( kern_TPOWER_OFF, TPOWER_OFF_VALUE);
1570 }
1571 else
1572 {
1573 vsi_t_start ( GMM_handle , kern_TPOWER_OFF, TPOWER_OFF_VALUE);
1574 kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LOCAL_DETACH);
1575 }
1576 break;
1577 default:
1578 SET_STATE ( KERN, KERN_GMM_DEREG_SUSPENDING );
1579 EM_GMM_SET_STATE(KERN_GMM_DEREG_SUSPENDING );
1580 kern_gmmsm_establich_rej();
1581
1582 if (det_acc_sent)
1583 {
1584 gmm_data->kern.suspension_type |= GMM_SUSP_LOCAL_DETACH;
1585 sig_kern_rdy_start_timer_req( kern_TLOCAL_DETACH, TLOCAL_DETACH_VALUE);
1586 }
1587 else
1588 {
1589 kern_gmmrr_suspend (GMMRR_NOT_SUSP_GPRS, GMMRR_NORMAL_RELEASE, GMM_SUSP_LOCAL_DETACH);
1590 }
1591 break;
1592 }
1593 /*
1594 * LABEL UNASSIGN_GMMREG
1595 */
1596
1597 vsi_t_stop ( GMM_handle , kern_T3321);
1598
1599 switch ( detach_type )
1600 {
1601 case GMM_DT_RE_ATTACH:
1602 GMM_RETURN;
1603 case GMMREG_DT_LIMITED_SERVICE:
1604 case GMMREG_DT_SIM_REMOVED:
1605 gmm_data->kern.detach_cap.local_detach_open_proc=
1606 (GMMCS_AUTHENTICATION_REJECTED== error_cause? /* TCS 2.1 */
1607 GMM_LOCAL_DETACH_PROC_AUTH_FAILED:
1608 GMM_LOCAL_DETACH_PROC_SIM_REMOVED);
1609 kern_gmmreg_detach (gmm_data->kern.detach_cap.detach_type, error_cause,
1610 GMMREG_SEARCH_NOT_RUNNING, error_cause);
1611
1612 break;
1613 case GMMREG_DT_POWER_OFF:
1614 case GMMREG_DT_SOFT_OFF:
1615 /* If GPRS is already suspended and power switch off is to be done,
1616 * kern_local_detach_open_proc() will not be called as GMM will not receive
1617 * GMMRR_SUSPEND_CNF from GRR, as GRR is already suspended */
1618 if (kern_gmm_save_state EQ KERN_GMM_REG_SUSPENDED)
1619 {
1620 gmm_data->kern.local_detached = FALSE;
1621 kern_local_detach_open_proc();
1622 }
1623 break;
1624 case GMMREG_DT_IMSI:
1625 kern_mm_attach_rej ( error_cause );
1626 kern_gmmreg_detach (gmm_data->kern.detach_cap.detach_type, error_cause,
1627 GMMREG_SEARCH_NOT_RUNNING, error_cause);
1628 gmm_data->kern.local_detached = FALSE;
1629 kern_local_detach_open_proc();
1630
1631 break;
1632 case GMMREG_DT_COMB:
1633 kern_mm_attach_rej ( error_cause );
1634 kern_gmmreg_detach (gmm_data->kern.detach_cap.detach_type, error_cause,
1635 GMMREG_SEARCH_NOT_RUNNING, error_cause);
1636 break;
1637 case GMMREG_DT_DISABLE_GPRS:
1638 gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_CC;
1639 gmm_data->kern.attach_cap.attach_type &= ~GMMREG_AT_GPRS;
1640 /* NO break; */
1641 case GMMREG_DT_GPRS:
1642 break;
1643 default:
1644 TRACE_ERROR ( "Unexpected detach_type in DETACH LABEL" );
1645 break;
1646 }
1647
1648 GMM_RETURN;
1649 } /* kern_local_detach() */
1650
1651
1652 /*
1653 +------------------------------------------------------------------------------
1654 | Function : kern_get_imeisv
1655 +------------------------------------------------------------------------------
1656 | Description : The function kern_get_imeisv
1657 | copied from MM: void csf_read_imei (T_imsi *imei)
1658 |
1659 | Parameters : void
1660 |
1661 +------------------------------------------------------------------------------
1662 */
1663 GLOBAL void kern_get_imeisv (T_gmobile_identity *imei)
1664 {
1665 UBYTE buf[CL_IMEI_SIZE];
1666
1667
1668 GMM_TRACE_FUNCTION( "kern_get_imeisv" );
1669 #ifdef TDSGEN
1670 imei->identity_digit[0] = 0x04;
1671 imei->identity_digit[1] = 0x04;
1672 imei->identity_digit[2] = 0x06;
1673 imei->identity_digit[3] = 0x00;
1674 imei->identity_digit[4] = 0x01;
1675 imei->identity_digit[5] = 0x09;
1676 imei->identity_digit[6] = 0x01;
1677 imei->identity_digit[7] = 0x09;
1678 imei->identity_digit[8] = 0x07;
1679 imei->identity_digit[9] = 0x05;
1680 imei->identity_digit[10] = 0x00;
1681 imei->identity_digit[11] = 0x07;
1682 imei->identity_digit[12] = 0x05;
1683 imei->identity_digit[13] = 0x09;
1684 imei->identity_digit[14] = 0x00;
1685 imei->identity_digit[15] = 0x00;/* Software Version Number */
1686
1687 #else /* TDSGEN */
1688 /*
1689 * Get IMEISV from IMEI common library
1690 */
1691 cl_get_imeisv(CL_IMEI_SIZE, buf, CL_IMEI_GET_SECURE_IMEI);
1692 imei->identity_digit[0] = (buf [0] >> 4) & 0x0F; /* TAC 8 byte */
1693 imei->identity_digit[1] = buf [0] & 0x0F;
1694 imei->identity_digit[2] = (buf [1] >> 4) & 0x0F;
1695 imei->identity_digit[3] = buf [1] & 0x0F;
1696 imei->identity_digit[4] = (buf [2] >> 4) & 0x0F;
1697 imei->identity_digit[5] = buf [2] & 0x0F;
1698 imei->identity_digit[6] = (buf [3] >> 4) & 0x0F;
1699 imei->identity_digit[7] = buf [3] & 0x0F;
1700 imei->identity_digit[8] = (buf [4] >> 4) & 0x0F; /* SNR 6 byte */
1701 imei->identity_digit[9] = buf [4] & 0x0F;
1702 imei->identity_digit[10] = (buf [5] >> 4) & 0x0F;
1703 imei->identity_digit[11] = buf [5] & 0x0F;
1704 imei->identity_digit[12] = (buf [6] >> 4) & 0x0F;
1705 imei->identity_digit[13] = buf [6] & 0x0F;
1706 imei->identity_digit[14] = (buf [7] >> 4) & 0x0F; /* SV 2 byte */
1707 imei->identity_digit[15] = buf [7] & 0x0F;
1708 TRACE_EVENT_P8("GMM INFO IMEI: TAC %1x%1x%1x%1x%1x%1x%1x%1x",
1709 imei->identity_digit[0], imei->identity_digit[1],
1710 imei->identity_digit[2], imei->identity_digit[3],
1711 imei->identity_digit[4], imei->identity_digit[5],
1712 imei->identity_digit[6], imei->identity_digit[7]);
1713 TRACE_EVENT_P6("GMM INFO IMEI: SNR %1x%1x%1x%1x%1x%1x",
1714 imei->identity_digit[8], imei->identity_digit[9],
1715 imei->identity_digit[10], imei->identity_digit[11],
1716 imei->identity_digit[12], imei->identity_digit[13]);
1717 TRACE_EVENT_P2("GMM INFO IMEI: SV %1x%1x", imei->identity_digit[14],
1718 imei->identity_digit[15]);
1719
1720 #endif /* not defined TDSGEN */
1721
1722 imei->v_identity_digit = TRUE;
1723 imei->c_identity_digit = 16;
1724
1725 imei->type_of_identity = ID_TYPE_IMEISV;
1726 imei->odd_even = 0;
1727
1728 GMM_RETURN;
1729 } /* kern_get_imeisv() */
1730 /*
1731 +------------------------------------------------------------------------------
1732 | Function : kern_get_imei
1733 +------------------------------------------------------------------------------
1734 | Description : The function kern_get_imei
1735 | copied from MM: void csf_read_imei (T_imsi *imei)
1736 |
1737 | Parameters : void
1738 |
1739 +------------------------------------------------------------------------------
1740 */
1741 GLOBAL void kern_get_imei (T_gmobile_identity *imei)
1742 {
1743 GMM_TRACE_FUNCTION( "kern_get_imei" );
1744 kern_get_imeisv(imei);
1745
1746 /*
1747 * get imeisv returns 16 digits, but imei has only 14 digits
1748 * thus clear last byte:
1749 */
1750 imei->identity_digit[14] = 0;
1751 imei->identity_digit[15] = 0;
1752 imei->v_identity_digit = TRUE;
1753 imei->c_identity_digit = 15;
1754
1755
1756 imei->type_of_identity = ID_TYPE_IMEI;
1757 imei->odd_even = 1;
1758 GMM_RETURN;
1759 } /* kern_get_imei() */
1760 /*
1761 +------------------------------------------------------------------------------
1762 | Function : kern_read_pcm
1763 +------------------------------------------------------------------------------
1764 | Description : The function kern_read_pcm
1765 |
1766 | Parameters : void
1767 |
1768 +------------------------------------------------------------------------------
1769 */
1770
1771 GLOBAL void kern_read_pcm ( void )
1772 {
1773 #ifdef _TARGET_
1774 T_GMM_FFS ffsBuffer;
1775 T_FFS_SIZE size = ffs_fread("/GPRS/gmm", &ffsBuffer, sizeof(ffsBuffer));
1776 TRACE_FUNCTION( "kern_read_pcm" );
1777
1778
1779 if ( size != sizeof(ffsBuffer) )
1780 {
1781 if ( size < 0 )
1782 {
1783 TRACE_EVENT_P1("FFS can not read \"/GPRS/gmm\" (%d)", size);
1784 }
1785 else
1786 {
1787 TRACE_EVENT_P2("FFS contains old file of \"/GPRS/gmm\": %dBytes long, but %dBytes expected",
1788 size, sizeof(ffsBuffer));
1789 }
1790 }
1791 else
1792 {
1793 gmm_data->config.cipher_on = ffsBuffer.cipher_on;
1794
1795 TRACE_1_INFO("GEA2=%d", (gmm_data->config.cipher_on & 0x02)>0);
1796 TRACE_1_INFO("GEA3=%d", (gmm_data->config.cipher_on & 0x04)>0);
1797 TRACE_1_INFO("GEA4=%d", (gmm_data->config.cipher_on & 0x08)>0);
1798 TRACE_1_INFO("GEA5=%d", (gmm_data->config.cipher_on & 0x10)>0);
1799 TRACE_1_INFO("GEA6=%d", (gmm_data->config.cipher_on & 0x20)>0);
1800 TRACE_1_INFO("GEA7=%d", (gmm_data->config.cipher_on & 0x40)>0);
1801
1802 }
1803 #endif /* NOT DEFINED _SIMULATION_ */
1804 return;
1805 }
1806
1807 /*
1808 +------------------------------------------------------------------------------
1809 | Function : kern_build_ms_network_capability
1810 +------------------------------------------------------------------------------
1811 | Description : The function kern_build_ms_network_capability() ....
1812 |
1813 | Parameters : void
1814 |
1815 +------------------------------------------------------------------------------
1816 */
1817 GLOBAL void kern_build_ms_network_capability (T_ms_network_capability *ms_network_capability)
1818 {
1819 T_mob_class_2 mob_class_2;
1820 EXTERN void rr_csf_get_classmark2 (T_mob_class_2 *mob_class_2);
1821
1822 GMM_TRACE_FUNCTION ("kern_build_ms_network_capability()");
1823
1824 rr_csf_get_classmark2 (&mob_class_2);
1825
1826 #ifdef REL99
1827 // HM 20-Jun-2003 Release 1999 >>>
1828 // Ensure these IEs are not accidently included in the uplink message
1829 // until Release 1999 is completely implemented in GMM
1830 memset (ms_network_capability, 0, sizeof (T_ms_network_capability));
1831 // HM 20-Jun-2003 Release 1999 <<<
1832 #endif
1833
1834 if (gmm_data->config.cipher_on)
1835 {
1836 ms_network_capability->gea_1 = GEA_1_YES;
1837 TRACE_EVENT ("ciphering on requested");
1838 }
1839 else
1840 {
1841 ms_network_capability->gea_1 = GEA_1_NO;
1842 TRACE_EVENT ("ciphering off requested");
1843 }
1844
1845 ms_network_capability->ss_screening_indicator = mob_class_2.ss_screen;
1846 ms_network_capability->sm_capabilities_gsm = mob_class_2.mt_pp_sms;
1847 ms_network_capability->sm_capabilities_gprs = SM_CAP_GPRS_YES;
1848 ms_network_capability->ucs2_support = UCS2_YES;
1849 /*
1850 * R99 definitions must be set to 0
1851 */
1852
1853 ms_network_capability->solsa_capability = NO;
1854 #ifdef REL99
1855 ms_network_capability->rev_level_ind = REV_LEVEL_IND_99_YES;
1856 ms_network_capability->pfc_feature_mode = YES;
1857 #else
1858 ms_network_capability->rev_level_ind = REV_LEVEL_IND_99_NO;
1859 ms_network_capability->pfc_feature_mode = NO;
1860 #endif
1861 /*
1862 * end of R99 definitions
1863 */
1864 ms_network_capability->ext_gea_bits.gea_2 = (gmm_data->config.cipher_on & 0x02)>0;
1865 ms_network_capability->ext_gea_bits.gea_3 = (gmm_data->config.cipher_on & 0x04)>0;
1866 ms_network_capability->ext_gea_bits.gea_4 = (gmm_data->config.cipher_on & 0x08)>0;
1867 ms_network_capability->ext_gea_bits.gea_5 = (gmm_data->config.cipher_on & 0x10)>0;
1868 ms_network_capability->ext_gea_bits.gea_6 = (gmm_data->config.cipher_on & 0x20)>0;
1869 ms_network_capability->ext_gea_bits.gea_7 = (gmm_data->config.cipher_on & 0x40)>0;
1870
1871 #ifdef TDSGEN
1872 ms_network_capability->sm_capabilities_gsm = SM_CAP_GSM_NO;
1873 ms_network_capability->ss_screening_indicator = 0;
1874 #endif
1875
1876 GMM_RETURN;
1877 } /* kern_build_ms_network_capability () */
1878
1879 /*
1880 +------------------------------------------------------------------------------
1881 | Function : kern_init
1882 +------------------------------------------------------------------------------
1883 | Description : The function kern_init() ....
1884 |
1885 | Parameters : void
1886 |
1887 +------------------------------------------------------------------------------
1888 */
1889 GLOBAL void kern_init ( void )
1890 {
1891 int i;
1892 TRACE_FUNCTION( "kern_init" );
1893
1894 /*gmm_data->gprs_enabled = TRUE;*/
1895 /*
1896 * Initialise service KERN with state KERN_READY.
1897 */
1898 INIT_STATE ( KERN, KERN_GMM_NULL_NO_IMSI );
1899
1900 #ifdef TRACE_FUNC
1901 #ifdef IDENTATION
1902 gmm_data->deep=0;
1903 #endif
1904 #endif
1905 gmm_data->anite = FALSE;
1906 gmm_data->tlli.current = LLGMM_TLLI_INVALID;
1907 gmm_data->tlli.old = LLGMM_TLLI_INVALID;
1908 gmm_data->kern.local_detached = FALSE;
1909 gmm_data->tlli.current_type = INVALID_TLLI;
1910 INIT_STATE ( MM, GMM_MM_DEREG);
1911 gmm_data->gu = GU3_ROAMING_NOT_ALLOWED;
1912 gmm_data->acc_contr_class = 0;
1913 gmm_data->kern.gprs_indicator = GMM_GPRS_SUPP_NO;
1914 #ifdef GMM_TCS4
1915 gmm_data->sync.sig_cell_info.rt = RT_GSM; /* TCS 4.0 */
1916 #endif
1917
1918 gmm_data->kern.attach_cap.attach_acc_after_po = FALSE;
1919 TRACE_EVENT ("GRR is off");
1920 gmm_data->kern.attach_cap.grr_state = GMM_GRR_STATE_OFF;
1921 /*
1922 * set all kc values to 0xff
1923 */
1924 memset (gmm_data->kern.auth_cap.kc, 0x00, MAX_KC);
1925
1926 gmm_data->kern.auth_cap.ciphering_algorithm = LLGMM_CIPHER_NO_ALGORITHM;
1927 /*
1928 * multiple outstanding SIM_AUTHENTICATION_REQ messages reset the counter
1929 */
1930 gmm_data->kern.auth_cap.last_auth_req_id = NOT_PRESENT_8BIT;
1931 gmm_data->config.cipher_on = 0x01;
1932 gmm_data->cipher = FALSE;
1933 gmm_data->config.preuse_off = FALSE;
1934
1935 gmm_data->ptmsi.new_grr = GMMRR_TMSI_INVALID;
1936 gmm_data->ptmsi.current = GMMRR_TMSI_INVALID;
1937 gmm_data->ptmsi.old = GMMRR_TMSI_INVALID;
1938 gmm_data->tmsi = GMMRR_TMSI_INVALID;
1939 gmm_data->config.nmo = 0xff;
1940 /*
1941 * set the dafault timer vlaues needed in service kern
1942 */
1943 gmm_data->kern.t3310_val = T3310_VALUE;
1944 gmm_data->kern.t3311_val = T3311_VALUE;
1945 gmm_data->kern.t3321_val = T3321_VALUE;
1946
1947 /*
1948 * T3302 is loaded with the same value which is used to load T3212.
1949 */
1950 gmm_data->kern.t3302_val = T3302_VALUE;
1951
1952 gmm_data->kern.timeout_t3312 = FALSE;
1953
1954 vsi_t_stop ( GMM_handle, kern_T3310);
1955 vsi_t_stop ( GMM_handle, kern_T3311);
1956 vsi_t_stop ( GMM_handle, kern_T3321);
1957 vsi_t_stop ( GMM_handle, kern_TPOWER_OFF);
1958 vsi_t_stop ( GMM_handle, kern_TLOCAL_DETACH);
1959
1960 /*
1961 * which kind of attach will be used is unknown this time
1962 * nobody requested an attach
1963 */
1964
1965 gmm_data->kern.attach_cap.mobile_class = GMMREG_CLASS_BG;
1966 gmm_data->kern.attach_cap.mobile_class_changed = FALSE;
1967 gmm_data->kern.attach_cap.attach_type = GMMREG_AT_NOT_KNOWN;
1968 gmm_data->kern.attach_cap.service_mode = SERVICE_MODE_LIMITED;
1969 gmm_data->kern.attach_cap.gmmreg = FALSE;
1970 #ifndef GMM_TCS4
1971 gmm_data->kern.attach_cap.gmmsm = FALSE;
1972 #endif
1973 gmm_data->kern.detach_cap.network = FALSE;
1974 gmm_data->kern.detach_cap.gmmreg = FALSE;
1975 gmm_data->kern.detach_cap.local_detach_open_proc=GMM_LOCAL_DETACH_PROC_NOTHING;
1976 gmm_data->kern.detach_cap.error_cause = GMMCS_INT_NOT_PRESENT; /* TCS 2.1 */
1977 gmm_data->kern.suspension_type = GMM_SUSP_NONE;
1978 /*
1979 * the DRX parameter are hardware dependend
1980 * TI is not supporting DRX
1981 * <R.GMM.AGINIT.M.006>
1982 */
1983
1984 #ifdef _SIMULATION_
1985 gmm_data->drx_parameter.split_pg_cycle_code = 92 /* 95 DRX_NOT_USED */;
1986 #ifdef TDSGEN
1987 gmm_data->drx_parameter.split_pg_cycle_code = 16;
1988 #endif
1989
1990 #else /* #ifdef _SIMULATION_ */
1991 gmm_data->drx_parameter.split_pg_cycle_code = 16 /* 95 DRX_NOT_USED */;
1992 #endif /* #ifdef _SIMULATION_ */
1993
1994 gmm_data->drx_parameter.split_on_ccch = SPLIT_NO;
1995 gmm_data->drx_parameter.non_drx_timer = DRX_2_SEC;
1996
1997
1998 /*
1999 * resets the attach and rau attempt counter
2000 */
2001 gmm_data->kern.aac = 0;
2002 gmm_data->kern.attach_cap.rau_initiated = GMM_NO_RAU;
2003 gmm_data->kern.attach_cap.enter_attempting_to_update_after_lau=FALSE;
2004
2005 gmm_data->kern.sig_cell_info.env.rai.rac = GMMREG_RA_INVALID;
2006 gmm_data->kern.sig_cell_info.env.rai.lac = GMMRR_LA_INVALID;
2007 gmm_data->kern.sig_cell_info.gmm_status = GMMRR_SERVICE_UNKNOWN ; /* Initalize gmm status value */
2008
2009 #ifdef _SIMULATION_
2010 gmm_data->kern.mm_cell_env.rai.rac = GMMREG_RA_INVALID;
2011 gmm_data->kern.mm_cell_env.rai.lac = GMMRR_LA_INVALID;
2012 gmm_data->kern.detach_cap.detach_type = VAL_DETACH_TYPE___DEF;
2013 #endif
2014
2015 /*
2016 * Cel ID
2017 */
2018 gmm_data->kern.cell_id.lac = (USHORT)GMMREG_LA_INVALID;
2019 gmm_data->kern.cell_id.rac = (UBYTE)GMMREG_RA_INVALID;
2020
2021
2022 INIT_STATE (CU,CU_CELL_RES_SENT);
2023 gmm_data->kern.attach_cap.llc_state=GMM_LLC_STATE_UNASSIGNED;
2024 gmm_data->kern.gmmrr_resume_sent = FALSE;
2025 gmm_data->kern.attach_cap.grr_via_llc_suspended=FALSE;
2026 gmm_data->kern.attach_cap.mm_lau_attempted=FALSE;
2027
2028 for(i=0; i<MAX_LIST_OF_FORBIDDEN_PLMNS_FOR_GPRS_SERVICE; i++)
2029 {
2030 memset(gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[i].mcc, 0xFF, SIZE_MCC);
2031 memset(gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[i].mnc, 0xFF, SIZE_MNC);
2032 }
2033 kern_read_pcm();
2034
2035 #ifdef REL99
2036 /* Used to indicate to LLC if it should use NULL frame for
2037 * performing cell updates. Cell notification is disabled by
2038 * default. This field is changed only if the SGSN indicates
2039 * that it supports cell notification
2040 */
2041 gmm_data->cell_notification = NO_CELL_NOTIFY; /* TCS 4.0 */
2042 /* Initialise all the pdp context status to invalid untill GMM gets a valid status from SM */
2043 gmm_data->kern.attach_cap.pdp_context_status = INVALID_PDP_CONTEXT_STATUS; /* TCS 4.0 */
2044 #endif
2045
2046 return;
2047 } /* kern_init() */
2048
2049
2050 /*
2051 +------------------------------------------------------------------------------
2052 | Function : kern_attach_reset
2053 +------------------------------------------------------------------------------
2054 | Description : This procedure is called in cell updatingn procedure, if RA
2055 | was changed an the ATTACH procedurehas to re-initialized.
2056 |
2057 | Parameters : void
2058 |
2059 +------------------------------------------------------------------------------
2060 */
2061 GLOBAL void kern_attach_reset ( void )
2062 {
2063 GMM_TRACE_FUNCTION( "kern_attach_reset" );
2064
2065 /*
2066 * resets the counter for TIMER t3310
2067 */
2068 gmm_data->kern.ct3310 = 0;
2069
2070 /*
2071 * I reuse timer T3310 also for T3330
2072 */
2073 vsi_t_stop ( GMM_handle, kern_T3310);
2074 vsi_t_stop ( GMM_handle, kern_T3311);
2075
2076
2077 gmm_data->kern.aac = 0;
2078 gmm_data->kern.detach_cap.network = FALSE;
2079 GMM_RETURN;
2080 } /* kern_attach_reset() */
2081
2082 /*
2083 +------------------------------------------------------------------------------
2084 | Function : kern_mm_detach_started
2085 +------------------------------------------------------------------------------
2086 | Description : The function kern_mm_detach_started indicates MM that the
2087 | GSM detach procedure is started by GMM. MM has to enter state
2088 | MM-IMSI-DETACH-PENDING.
2089 |
2090 | Parameters : void
2091 |
2092 +------------------------------------------------------------------------------
2093 */
2094 GLOBAL void kern_mm_detach_started ( void )
2095 {
2096 GMM_TRACE_FUNCTION( "kern_mm_detach_started" );
2097
2098 switch( gmm_data->kern.detach_cap.detach_type)
2099 {
2100 case GMMREG_DT_SIM_REMOVED :
2101 if (GMM_MM_DEREG == GET_STATE(MM))
2102 {
2103 break;
2104 }
2105 /* NO break;*/
2106 case GMMREG_DT_IMSI:
2107 case GMMREG_DT_COMB:
2108 if (GMMRR_NET_MODE_I==gmm_data->kern.sig_cell_info.net_mode)
2109 {
2110 PALLOC ( mmgmm_detach_started_req, MMGMM_DETACH_STARTED_REQ);
2111 PSEND ( hCommMM, mmgmm_detach_started_req );
2112 }
2113 break;
2114 default:
2115 break;
2116 }
2117 GMM_RETURN;
2118 } /* kern_detach_started() */
2119
2120 /*
2121 +------------------------------------------------------------------------------
2122 | Function : kern_mm_imsi_detach_ind
2123 +------------------------------------------------------------------------------
2124 | Description : The function kern_mm_imsi_detach()handles the IMSI detach.
2125 |
2126 | Parameters : detach_done - indicates whether GMM has already done the IMSI
2127 | detach or not.
2128 |
2129 +------------------------------------------------------------------------------
2130 */
2131 GLOBAL void kern_mm_imsi_detach_ind ( USHORT error_cause, BOOL detach_done, UBYTE detach_type )
2132 {
2133 GMM_TRACE_FUNCTION( "kern_mm_imsi_detach_ind" );
2134
2135 {
2136 PALLOC ( mmgmm_nreg_req, MMGMM_NREG_REQ); /* T_MMGMM_NREG_REQ */
2137 mmgmm_nreg_req->cause = error_cause; /* TCS 2.1 */
2138 mmgmm_nreg_req->detach_done = detach_done;
2139 SET_STATE ( MM, GMM_MM_DEREG );
2140
2141 TRACE_1_OUT_PARA("detach_done %d",detach_done);
2142
2143 switch ( detach_type )
2144 {
2145 case GMMREG_DT_SIM_REMOVED:
2146 mmgmm_nreg_req->detach_cause = CS_SIM_REM; /* TCS 2.1 */
2147 break;
2148 case GMMREG_DT_POWER_OFF:
2149 mmgmm_nreg_req->detach_cause = CS_POW_OFF; /* TCS 2.1 */
2150 break;
2151 case GMMREG_DT_SOFT_OFF:
2152 mmgmm_nreg_req->detach_cause = CS_SOFT_OFF; /* TCS 2.1 */
2153 break;
2154 default:
2155 mmgmm_nreg_req->detach_cause = CS_DISABLE; /* TCS 2.1 */
2156 break;
2157 }
2158 gmm_data->kern.suspension_type &= ~GMM_SUSP_IMSI_DETACH;
2159 PSEND ( hCommMM, mmgmm_nreg_req );
2160 }
2161 GMM_RETURN;
2162 } /* kern_imsi_detach_ind () */
2163 /*
2164 +------------------------------------------------------------------------------
2165 | Function : kern_mm_imsi_detach
2166 +------------------------------------------------------------------------------
2167 | Description : The function kern_mm_imsi_detach()handles the IMSI detach.
2168 |
2169 | Parameters : detach_done - indicates whether GMM has already done the IMSI
2170 | detach or not.
2171 |
2172 +------------------------------------------------------------------------------
2173 */
2174 GLOBAL void kern_mm_imsi_detach ( void )
2175 {
2176 GMM_TRACE_FUNCTION( "kern_mm_imsi_detach" );
2177 kern_mm_imsi_detach_ind (GMMCS_INT_NOT_PRESENT, MMGMM_PERFORM_DETACH,
2178 gmm_data->kern.detach_cap.detach_type); /* TCS 2.1 */
2179 GMM_RETURN;
2180 } /* kern_imsi_detach() */
2181
2182
2183 /*
2184 +------------------------------------------------------------------------------
2185 | Function : kern_mm_lau
2186 +------------------------------------------------------------------------------
2187 | Description : This procedure start the LAU procedure in entity MM
2188 |
2189 | Parameters : void
2190 |
2191 +------------------------------------------------------------------------------
2192 */
2193 GLOBAL void kern_mm_lau ( void )
2194 {
2195 GMM_TRACE_FUNCTION( "kern_mm_lau" );
2196
2197 gmm_data->kern.attach_cap.mm_lau_attempted=TRUE;
2198 gmm_data->kern.suspension_type &= ~GMM_SUSP_LAU;
2199
2200 if (gmm_data->kern.attach_cap.network_selection_mode EQ MODE_AUTO)
2201 {
2202 kern_mm_reg_req (REG_REMOTE_CONTROLLED, NORMAL_REG);
2203 }
2204 else
2205 {
2206 PALLOC ( mmgmm_plmn_res, MMGMM_PLMN_RES ); /* T_MMGMM_PLMN_RES */
2207 mmgmm_plmn_res->plmn = gmm_data->kern.attach_cap.plmn_requested;
2208 mmgmm_plmn_res->reg_type = REG_REMOTE_CONTROLLED;
2209 mmgmm_plmn_res->mobile_class = gmm_data->kern.attach_cap.mobile_class;
2210 PSEND ( hCommMM, mmgmm_plmn_res );
2211 }
2212
2213 GMM_RETURN;
2214 } /* kern_mm_lau() */
2215
2216 /*
2217 +------------------------------------------------------------------------------
2218 | Function : kern_gmmrr_assign
2219 +------------------------------------------------------------------------------
2220 | Description : The function kern_gmmrr_assign()
2221 |
2222 | This procedure assigned the current TLLI parameter to GRR
2223 | entities
2224 |
2225 | Parameters : void
2226 |
2227 |
2228 +------------------------------------------------------------------------------
2229 */
2230 GLOBAL void kern_gmmrr_assign ( void )
2231 {
2232 GMM_TRACE_FUNCTION( "kern_gmmrr_assign" );
2233
2234 {
2235 PALLOC ( gmmrr_assign_req, GMMRR_ASSIGN_REQ );
2236 gmmrr_assign_req->new_tlli = gmm_get_tlli ( CURRENT_TLLI );
2237 gmmrr_assign_req->old_tlli = gmm_get_tlli ( OLD_TLLI );
2238
2239 if (GMMRR_TLLI_INVALID==gmmrr_assign_req->new_tlli)
2240 {
2241 gmmrr_assign_req->old_ptmsi = GMMRR_TMSI_INVALID;
2242 gmmrr_assign_req->new_ptmsi = GMMRR_TMSI_INVALID;
2243 }
2244 else
2245 {
2246 gmmrr_assign_req->old_ptmsi = gmm_data->ptmsi.old;
2247 gmmrr_assign_req->new_ptmsi = gmm_data->ptmsi.new_grr;
2248
2249 }
2250 gmmrr_assign_req->imsi = gmm_data->imsi;
2251 gmmrr_assign_req->rai.plmn.v_plmn=TRUE;
2252 memcpy (gmmrr_assign_req->rai.plmn.mcc, gmm_data->kern.attach_cap.rai_accepted.mcc, SIZE_MCC);
2253 memcpy (gmmrr_assign_req->rai.plmn.mnc, gmm_data->kern.attach_cap.rai_accepted.mnc, SIZE_MNC);
2254 gmmrr_assign_req->rai.lac = gmm_data->kern.attach_cap.rai_accepted.lac;
2255 gmmrr_assign_req->rai.rac = gmm_data->kern.attach_cap.rai_accepted.rac;
2256
2257 TRACE_3_OUT_PARA("PTMSI old: 0x%X new: 0x%X,curent:0x%X ",gmmrr_assign_req->old_ptmsi,
2258 gmmrr_assign_req->new_ptmsi, gmm_data->ptmsi.current);
2259 PSEND ( hCommGRR, gmmrr_assign_req );
2260 }
2261 GMM_RETURN;
2262 } /* kern_gmmrr_assign() */
2263
2264 /*
2265 +------------------------------------------------------------------------------
2266 | Function : kern_local_atach
2267 +------------------------------------------------------------------------------
2268 | Description : The function kern_local_attach()
2269 |
2270 | This procedure assigned the given TLLI parameter to the other
2271 | entities
2272 |
2273 | Parameters : new_tlli_type - type of new TLLI (random, local ,..)
2274 | old_tlli_type - type of old TLLI
2275 |
2276 +------------------------------------------------------------------------------
2277 */
2278 GLOBAL void kern_local_attach ( T_TLLI_TYPE new_tlli_type, T_TLLI_TYPE old_tlli_type )
2279 {
2280 GMM_TRACE_FUNCTION( "kern_local_attach" );
2281
2282 kern_llgmm_assign_tlli ( new_tlli_type, old_tlli_type );
2283 kern_gmmrr_assign();
2284 GMM_RETURN;
2285 } /* kern_local_attach() */
2286
2287 /*
2288 +------------------------------------------------------------------------------
2289 | Function : kern_ptmsi_negotiated
2290 +------------------------------------------------------------------------------
2291 | Description : This procedure is called if an AIR message is received which
2292 | contains an optional PTMSI IE. i.e. in the ATTACH_ACCEPT or
2293 | RAU_ACCEPT message. It stores the P-TMSI and the
2294 | P-TMSI Signature, if available into the SIM and changes the
2295 | update state to GU1 UPDATED and triggers the cell update
2296 | procedure by calling LLGMM_TRIGGER_REQ, if needed. Otherwise,
2297 | if P-TMSI was negotiated CU is triggered outside of this
2298 | procedure by transmitting CONFIRM message. At the end of this
2299 | procedure the new genereted TLLI is passed to the other layers
2300 |
2301 | Parameters : v_mobile_identity - flag from AIR if ptmsi is available
2302 | mobile_identity - ptmsi from AIR
2303 | v_ptmsi_signature - flag from AIR if psignature is available
2304 | ptmsi_signature - ptmsi signature from AIR
2305 |
2306 +------------------------------------------------------------------------------
2307 */
2308 GLOBAL void kern_tmsi_negotiated ( BOOL v_tmsi,
2309 T_mobile_identity *tmsi,
2310 BOOL v_ptmsi,
2311 T_gmobile_identity *ptmsi,
2312 BOOL v_ptmsi_signature,
2313 T_p_tmsi_signature *p_tmsi_signature
2314 )
2315 {
2316 GMM_TRACE_FUNCTION ("kern_tmsi_negotiated()");
2317
2318 /*
2319 * save the available flags
2320 */
2321 gmm_data->ptmsi_signature.available = v_ptmsi_signature;
2322 if ( v_ptmsi )
2323 {
2324 if ( !ptmsi->v_tmsi )
2325 {
2326 TRACE_ERROR ( "PTMSI IE received from air without ptmsi value, perhaps IMSI reseived" );
2327 sig_kern_rx_gmm_status(ERRCS_IE_INVALID);
2328 }
2329 else
2330 {
2331 /*
2332 * store the given PTMSI
2333 */
2334 gmm_data->ptmsi.old = gmm_data->ptmsi.current,
2335
2336 gmm_data->ptmsi.new_grr
2337 = gmm_data->ptmsi.current = kern_get_tmsi ((T_mobile_identity *)ptmsi );
2338
2339 }
2340 }
2341 if ( v_tmsi )
2342 {
2343 if ( !tmsi->v_tmsi )
2344 {
2345 TRACE_EVENT ( "TMSI IE received from air without ptmsi value, perhaps IMSI reseived" );
2346 /*
2347 * <R.GMM.ACSUBOTH.M.011>
2348 * If the message contains an IMSI (i.e. the MS is not allocated any TMSI)
2349 * than the MS shall delete any TMSI.
2350 */
2351 gmm_data->tmsi =MMGMM_TMSI_INVALID;
2352
2353 }
2354 else
2355 {
2356 /*
2357 * store the given TMSI
2358 */
2359 gmm_data->tmsi = kern_get_tmsi ((T_mobile_identity *)tmsi );
2360 }
2361 }
2362 /*
2363 * After the rocedure the local TLLI have to be used
2364 *
2365 * set all TLLIs and saves the current TLLI as old TLLI
2366 */
2367 gmm_set_current_tlli ( LOCAL_TLLI ) ;
2368
2369
2370 if ( v_ptmsi_signature )
2371 {
2372 /*
2373 * <R.GMM.AGACCEPT.M.020>, <R.GMM.AGACCEPT.M.021>,
2374 * <R.GMM.AGACCEPT.M.022>, <R.GMM.RNACCEPT.M.014>
2375 */
2376 gmm_data->ptmsi_signature.value
2377 = p_tmsi_signature->p_tmsi_signature_value;
2378 }
2379 /*
2380 * <R.GMM.AGACCEPT.M017>, <R.GMM.AGACCEPT.M019>,
2381 * <R.GMM.AGACCEPT.M022>,<R.GMM.AGACCEPT.M023>
2382 */
2383 gmm_data->gu = GU1_UPDATED;
2384
2385 kern_sim_gmm_update();
2386 vsi_o_ttrace(VSI_CALLER TC_EVENT,"Info: GU: %i", gmm_data->gu+1);
2387
2388
2389 if (
2390 GMM_PERIODIC_RAU != gmm_data->kern.attach_cap.rau_initiated
2391 || ptmsi->v_tmsi
2392 || tmsi->v_tmsi
2393 )
2394 {
2395 /*
2396 * in attach and RAU the TLLI as to change from foreign to local tlli
2397 */
2398 kern_local_attach ( CURRENT_TLLI, OLD_TLLI );
2399 }
2400 else
2401 {
2402 /*
2403 * AniteB2 44.2.3.1.5
2404 * RR has to transmit the last assigned RAI with GPRS resumption
2405 */
2406 kern_gmmrr_assign();
2407 }
2408 GMM_RETURN;
2409
2410 } /* kern_ptmsi_negotiated */
2411
2412 /*
2413 +------------------------------------------------------------------------------
2414 | Function : kern_sim_del_locigprs
2415 +------------------------------------------------------------------------------
2416 | Description : This procedure resets all location infos on sim
2417 |
2418 | Parameters : void
2419 |
2420 +------------------------------------------------------------------------------
2421 */
2422 GLOBAL void kern_sim_del_locigprs ( void )
2423 {
2424 GMM_TRACE_FUNCTION ("kern_sim_del_locigprs()");
2425
2426 gmm_data->ptmsi.current = GMMRR_TMSI_INVALID;
2427 gmm_data->ptmsi.new_grr = GMMRR_TMSI_INVALID;
2428 gmm_data->ptmsi.old = GMMRR_TMSI_INVALID;
2429 gmm_data->ptmsi_signature.available = FALSE;
2430 gmm_data->ptmsi_signature.value = INVALID_PTMSI_SIGNATURE;
2431
2432 gmm_data->kern.attach_cap.rai_accepted.lac = 0xfffe; /* INVALID */
2433 gmm_data->kern.attach_cap.rai_accepted.rac = 0xff; /* INVALID */
2434 memset (gmm_data->kern.auth_cap.kc, 0xFF, MAX_KC);
2435 gmm_data->kern.auth_cap.cksn = NO_KEY;
2436 GMM_RETURN;
2437 } /* kern_sim_del_locigprs */
2438
2439 /*
2440 +------------------------------------------------------------------------------
2441 | Function : kern_sim_gmm_update
2442 +------------------------------------------------------------------------------
2443 | Description : This procedure sends the primitive SIM_GU_UPDATE_REQ to SIM.
2444 | The primitive is allocated within this function and the
2445 | parameters of the primitive are filled in with the actually
2446 | set global variables of GMM.
2447 |
2448 | Parameters : void
2449 |
2450 +------------------------------------------------------------------------------
2451 */
2452 GLOBAL void kern_sim_gmm_update ()
2453 {
2454 GMM_TRACE_FUNCTION ("kern_sim_gmm_update()");
2455 {
2456 PALLOC ( sim_gmm_update_req, SIM_GMM_UPDATE_REQ );
2457 kern_set_loc_info (sim_gmm_update_req);
2458 kern_set_kc_cksn (sim_gmm_update_req);
2459 sim_gmm_update_req->att_status
2460 = gmm_data->kern.attach_cap.attach_acc_after_po;
2461 PSEND ( hCommSIM, sim_gmm_update_req );
2462 }
2463 GMM_RETURN;
2464 } /* kern_sim_gmm_update */
2465
2466 /*
2467 +------------------------------------------------------------------------------
2468 | Function : kern_read_imsi
2469 +------------------------------------------------------------------------------
2470 | Description : This procedure reads the imsi from primitive
2471 | sim_gmm_insert_ind
2472 |
2473 | copied from mm_regF.c in MM
2474 |
2475 | Parameters : sim_gmm_insert_ind - primitiv pointer
2476 |
2477 +------------------------------------------------------------------------------
2478 */
2479 GLOBAL void kern_read_imsi (T_SIM_GMM_INSERT_IND *sim_gmm_insert_ind)
2480 {
2481 USHORT i;
2482 UBYTE digit;
2483 UBYTE length;
2484 ULONG init_value=25;
2485 #ifdef NEW_FRAME
2486 T_TIME time_val;
2487 #else /* NEW_FRAME */
2488 T_VSI_TVALUE time_val;
2489 #endif /* NEW_FRAME */
2490
2491 GMM_TRACE_FUNCTION ("kern_read_imsi ()");
2492
2493
2494 gmm_data->imsi.v_mid = TRUE;
2495 gmm_data->imsi.id_type = TYPE_IMSI;
2496 gmm_data->imsi.tmsi_dig = 0;
2497
2498
2499 length = (sim_gmm_insert_ind->imsi_field.c_field-1)*2;
2500 if (sim_gmm_insert_ind->imsi_field.field[0] & 0x08)
2501 {
2502 length++;
2503 }
2504
2505 for (i = 0; i < length; i++)
2506 {
2507 digit = (i & 1) ?
2508 sim_gmm_insert_ind->imsi_field.field[(i + 1) / 2] & 0x0f :
2509 (sim_gmm_insert_ind->imsi_field.field[(i + 1) / 2] & 0xf0) >> 4;
2510 gmm_data->imsi.id[i] = digit;
2511 init_value += digit*digit;
2512 }
2513 gmm_data->imsi.id[i] = 0xff;
2514
2515 vsi_t_time (VSI_CALLER &time_val);
2516 srand ((USHORT)(init_value*time_val));
2517 GMM_RETURN;
2518 } /*kern_read_imsi*/
2519 /*
2520 +------------------------------------------------------------------------------
2521 | Function : kern_get_tmsi
2522 +------------------------------------------------------------------------------
2523 | Description : This procedure translate the timer value given by ACI to
2524 | an air message struct
2525 |
2526 |
2527 | Parameters : mobile_identity - PTMSI received from AIR
2528 |
2529 +------------------------------------------------------------------------------
2530 */
2531
2532 GLOBAL ULONG kern_get_tmsi (T_mobile_identity * mobile_identity )
2533 {
2534 ULONG ptmsi;
2535 GMM_TRACE_FUNCTION( "kern_get_tmsi" );
2536
2537 ptmsi = (mobile_identity->tmsi.b_tmsi[0] << 24)+
2538 (mobile_identity->tmsi.b_tmsi[1] << 16)+
2539 (mobile_identity->tmsi.b_tmsi[2] << 8)+
2540 mobile_identity->tmsi.b_tmsi[3];
2541 GMM_RETURN_ (ptmsi);
2542
2543 } /* kern_get_tmsi */
2544
2545 /*
2546 +------------------------------------------------------------------------------
2547 | Function : kern_get_mobile_identity
2548 +------------------------------------------------------------------------------
2549 | Description : Derives the mobile identiti for the AIR
2550 |
2551 | COPIED FROM : MM mm_mmf.c : mm_fill_identity
2552 |
2553 | Parameters : type_of_identity - tpe of identity
2554 | gmobile_identity - used in the AIR message
2555 |
2556 +------------------------------------------------------------------------------
2557 */
2558
2559 GLOBAL void kern_get_mobile_identity (
2560 UBYTE type_of_identity,
2561 T_gmobile_identity* gmobile_identity )
2562 {
2563 GMM_TRACE_FUNCTION ("kern_get_mobile_identity()");
2564
2565 memset (gmobile_identity, 0, sizeof (T_mobile_identity));
2566
2567 switch (type_of_identity)
2568 {
2569 case ID_TYPE_IMEISV:
2570 kern_get_imeisv ( gmobile_identity);
2571 break;
2572 case ID_TYPE_IMEI:
2573 kern_get_imei ( gmobile_identity);
2574 break;
2575 case ID_TYPE_TMSI:
2576 kern_ulong2mobile_identity (gmm_data->ptmsi.current, gmobile_identity);
2577 break;
2578 default:
2579 TRACE_ERROR ("undefined type of Identity");
2580 /*
2581 * NO break;
2582 */
2583 case ID_TYPE_IMSI:
2584 gmobile_identity->v_tmsi = FALSE;
2585 gmobile_identity->type_of_identity = ID_TYPE_IMSI;
2586 gmobile_identity->v_identity_digit = TRUE;
2587 gmobile_identity->c_identity_digit
2588 = kern_calculate_digits (gmm_data->imsi.id);
2589 gmobile_identity->odd_even = gmobile_identity->c_identity_digit & 1;
2590 memcpy (gmobile_identity->identity_digit, gmm_data->imsi.id, 16);
2591 break;
2592 }
2593 GMM_RETURN;
2594 } /* kern_get_mobile_identity() */
2595 /*
2596 +------------------------------------------------------------------------------
2597 | Function : kern_read_kc_cksn
2598 +------------------------------------------------------------------------------
2599 | Description : Reads the location information delivered by the SIM card
2600 | into the registration memory structures.
2601 |
2602 | COPIED FROM : MM mm_regf.c : reg_read_kc_cksn
2603 |
2604 | Parameters : T_loc_info - the the loc_inf field from sim_gmm_inserted_ind
2605 |
2606 +------------------------------------------------------------------------------
2607 */
2608 GLOBAL void kern_read_kc_cksn (T_SIM_GMM_INSERT_IND *sim_gmm_insert_ind)
2609 {
2610 GMM_TRACE_FUNCTION ("kern_read_kc_cksn ()");
2611
2612 switch (gmm_data->gu)
2613 {
2614 case GU2_NOT_UPDATED:
2615 /*
2616 * GSM: 04.08, Ch.4.1.3.2 GPRS update status
2617 *
2618 * GU2: NOT UPDATED
2619 * The last GPRS attach or routing area updating attempt failed procedurally,
2620 * i.e. no response was received from the network. This includes the cases of
2621 * failures or congestion inside the network.
2622 * In this case, the SIM may contain the RAI of the routing area (RA) to which
2623 * the subscriber was attached, and possibly also a valid P-TMSI,
2624 * GPRS GSM ciphering key, GPRS UMTS ciphering key, GPRS UMTS integrity key
2625 * and GPRS ciphering key sequence number. For compatibility reasons, all these
2626 * fields shall be set to the "deleted" value if the RAI is deleted. However, the
2627 * presence of other values shall not be considered an error by the MS.
2628 */
2629 if ( GMMRR_LA_INVALID != gmm_data->kern.attach_cap.rai_accepted.lac)
2630 {
2631 break;
2632 }
2633 /* NO break */
2634 case GU3_ROAMING_NOT_ALLOWED:
2635 case GU3_PLMN_NOT_ALLOWED:
2636 /*
2637 * GSM: 04.08, Ch.4.3.2.4:
2638 * "When the deletion of the sequence number is described this also means
2639 * that the associated key shall be considered as invalid."
2640 * GSM: 04.08, Ch.4.7.7.4:
2641 * "If the sequence number is deleted,
2642 * the associated key shall be considered as invalid."
2643 */
2644
2645 gmm_data->kern.auth_cap.cksn = NO_KEY;
2646 memset (gmm_data->kern.auth_cap.kc, 0xFF, MAX_KC);
2647 break;
2648 default:
2649 gmm_data->kern.auth_cap.cksn = sim_gmm_insert_ind->kc_n.kc[MAX_KC];
2650 if (NO_KEY == gmm_data->kern.auth_cap.cksn)
2651 {
2652 memset (gmm_data->kern.auth_cap.kc, 0xFF, MAX_KC);
2653 }
2654 else
2655 {
2656 /*
2657 * copy parameter from SIM card
2658 */
2659 memcpy (gmm_data->kern.auth_cap.kc, sim_gmm_insert_ind->kc_n.kc, MAX_KC);
2660 }
2661 break;
2662 }
2663 GMM_RETURN;
2664 }
2665 /*
2666 +------------------------------------------------------------------------------
2667 | Function : kern_set_kc_cksn
2668 +------------------------------------------------------------------------------
2669 | Description : sets the kc and cksn delivered by the SIM card
2670 | into the registration memory structures.
2671 |
2672 | COPIED FROM : MM mm_regf.c : reg_read_kc_cksn
2673 |
2674 | Parameters : T_loc_info - the the loc_inf field from sim_gmm_inserted_ind
2675 |
2676 +------------------------------------------------------------------------------
2677 */
2678 GLOBAL void kern_set_kc_cksn (T_SIM_GMM_UPDATE_REQ *sim_gmm_update_req)
2679 {
2680 GMM_TRACE_FUNCTION ("kern_set_kc_cksn ()");
2681
2682 sim_gmm_update_req->cksn = gmm_data->kern.auth_cap.cksn;
2683 memcpy (sim_gmm_update_req->kc, gmm_data->kern.auth_cap.kc, MAX_KC);
2684 GMM_RETURN;
2685 }
2686
2687 /*
2688 +------------------------------------------------------------------------------
2689 | Function : kern_read_log_info
2690 +------------------------------------------------------------------------------
2691 | Description : Reads the location information delivered by the SIM card
2692 | into the registration memory structures.
2693 |
2694 | COPIED FROM : MM mm_regf.c : reg_read_log_info
2695 |
2696 | Parameters : T_loc_info - the the loc_inf field from sim_gmm_inserted_ind
2697 |
2698 +------------------------------------------------------------------------------
2699 */
2700 GLOBAL void kern_read_loc_info (T_SIM_GMM_INSERT_IND *sim_gmm_insert_ind)
2701 {
2702 GMM_TRACE_FUNCTION ("kern_read_loc_info ()");
2703
2704 gmm_data->tmsi = (sim_gmm_insert_ind->loc_info.loc[0] << 24) +
2705 (sim_gmm_insert_ind->loc_info.loc[1] << 16) +
2706 (sim_gmm_insert_ind->loc_info.loc[2] << 8) +
2707 sim_gmm_insert_ind->loc_info.loc[3];
2708
2709 gmm_data->ptmsi.new_grr =
2710 gmm_data->ptmsi.current = (sim_gmm_insert_ind->gprs_loc_info.loc[0] << 24) +
2711 (sim_gmm_insert_ind->gprs_loc_info.loc[1] << 16) +
2712 (sim_gmm_insert_ind->gprs_loc_info.loc[2] << 8) +
2713 sim_gmm_insert_ind->gprs_loc_info.loc[3];
2714
2715
2716 gmm_data->ptmsi_signature.value =
2717 (sim_gmm_insert_ind->gprs_loc_info.loc[4] << 16) +
2718 (sim_gmm_insert_ind->gprs_loc_info.loc[5] << 8) +
2719 sim_gmm_insert_ind->gprs_loc_info.loc[6];
2720 gmm_data->ptmsi_signature.available = TRUE;
2721
2722 gmm_data->kern.attach_cap.rai_accepted.mcc[0] = sim_gmm_insert_ind->gprs_loc_info.loc[7] & 0x0f;
2723 gmm_data->kern.attach_cap.rai_accepted.mcc[1] = sim_gmm_insert_ind->gprs_loc_info.loc[7] >> 4;
2724 gmm_data->kern.attach_cap.rai_accepted.mcc[2] = sim_gmm_insert_ind->gprs_loc_info.loc[8] & 0x0f;
2725 gmm_data->kern.attach_cap.rai_accepted.mnc[2] = sim_gmm_insert_ind->gprs_loc_info.loc[8] >> 4;
2726 gmm_data->kern.attach_cap.rai_accepted.mnc[0] = sim_gmm_insert_ind->gprs_loc_info.loc[9] & 0x0f;
2727 gmm_data->kern.attach_cap.rai_accepted.mnc[1] = sim_gmm_insert_ind->gprs_loc_info.loc[9] >> 4;
2728 gmm_data->kern.attach_cap.rai_accepted.lac = sim_gmm_insert_ind->gprs_loc_info.loc[10] * 256 +
2729 sim_gmm_insert_ind->gprs_loc_info.loc[11];
2730 gmm_data->kern.attach_cap.rai_accepted.rac = sim_gmm_insert_ind->gprs_loc_info.loc[12];
2731
2732 gmm_data->gu = sim_gmm_insert_ind->gprs_loc_info.loc[13];
2733
2734 if ( GMMRR_LA_INVALID == gmm_data->kern.attach_cap.rai_accepted.lac)
2735 {
2736 kern_sim_del_locigprs ();
2737 }
2738 TRACE_9_PARA("TMSI %x, PTMSI %x, lac %x, rac %x, MCC: %x%x%x, MNC: %x%x",
2739 gmm_data->tmsi,
2740 gmm_data->ptmsi.current,
2741 gmm_data->kern.attach_cap.rai_accepted.lac,
2742 gmm_data->kern.attach_cap.rai_accepted.rac,
2743 gmm_data->kern.attach_cap.rai_accepted.mcc[0],
2744 gmm_data->kern.attach_cap.rai_accepted.mcc[1],
2745 gmm_data->kern.attach_cap.rai_accepted.mcc[2],
2746 gmm_data->kern.attach_cap.rai_accepted.mnc[0],
2747 gmm_data->kern.attach_cap.rai_accepted.mnc[1]
2748 );
2749
2750 if (gmm_data->gu > GU3_ROAMING_NOT_ALLOWED)
2751 {
2752 gmm_data->gu = GU2_NOT_UPDATED;
2753 }
2754 GMM_RETURN;
2755 }
2756
2757 /*
2758 +------------------------------------------------------------------------------
2759 | Function : kern_set_loc_info
2760 +------------------------------------------------------------------------------
2761 | Description : derives the log_info field for for sim inserted
2762 |
2763 | COPIED FROM : MM mm_regf.c : reg_set_log_info
2764 |
2765 | Parameters : sim_gmm_update_req - the primitive
2766 |
2767 +------------------------------------------------------------------------------
2768 */
2769 GLOBAL void kern_set_loc_info (T_SIM_GMM_UPDATE_REQ *sim_gmm_update_req)
2770 {
2771
2772 GMM_TRACE_FUNCTION ("kern_set_loc_info ()");
2773 sim_gmm_update_req->gprs_loc_info.c_loc = MAX_LOCIGPRS;
2774
2775 sim_gmm_update_req->gprs_loc_info.loc[0] = (UBYTE)(gmm_data->ptmsi.current >> 24);
2776 sim_gmm_update_req->gprs_loc_info.loc[1] = (UBYTE)(gmm_data->ptmsi.current >> 16);
2777 sim_gmm_update_req->gprs_loc_info.loc[2] = (UBYTE)(gmm_data->ptmsi.current >> 8);
2778 sim_gmm_update_req->gprs_loc_info.loc[3] = (UBYTE)gmm_data->ptmsi.current;
2779
2780 sim_gmm_update_req->gprs_loc_info.loc[4] = (UBYTE)(gmm_data->ptmsi_signature.value >> 16);
2781 sim_gmm_update_req->gprs_loc_info.loc[5] = (UBYTE)(gmm_data->ptmsi_signature.value >> 8);
2782 sim_gmm_update_req->gprs_loc_info.loc[6] = (UBYTE)gmm_data->ptmsi_signature.value;
2783
2784 sim_gmm_update_req->gprs_loc_info.loc[7] = gmm_data->kern.attach_cap.rai_accepted.mcc[1] << 4;
2785 sim_gmm_update_req->gprs_loc_info.loc[7] += gmm_data->kern.attach_cap.rai_accepted.mcc[0];
2786
2787 sim_gmm_update_req->gprs_loc_info.loc[8] = gmm_data->kern.attach_cap.rai_accepted.mnc[2] << 4;
2788 sim_gmm_update_req->gprs_loc_info.loc[8] += gmm_data->kern.attach_cap.rai_accepted.mcc[2];
2789
2790 sim_gmm_update_req->gprs_loc_info.loc[9] = gmm_data->kern.attach_cap.rai_accepted.mnc[1] << 4;
2791 sim_gmm_update_req->gprs_loc_info.loc[9] += gmm_data->kern.attach_cap.rai_accepted.mnc[0];
2792 sim_gmm_update_req->gprs_loc_info.loc[10] = gmm_data->kern.attach_cap.rai_accepted.lac >> 8;
2793 sim_gmm_update_req->gprs_loc_info.loc[11] = gmm_data->kern.attach_cap.rai_accepted.lac & 0xff;
2794 sim_gmm_update_req->gprs_loc_info.loc[12] = gmm_data->kern.attach_cap.rai_accepted.rac;
2795
2796 sim_gmm_update_req->gprs_loc_info.loc[13] = gmm_data->gu;
2797 GMM_RETURN;
2798 }
2799 /*
2800 +------------------------------------------------------------------------------
2801 | Function : kern_ulong2mobile_identity
2802 +------------------------------------------------------------------------------
2803 | Description : Derives tm mobile identiti for the AIR
2804 |
2805 | COPIED FROM : MM mm_mmf.c : mm_fill_identity
2806 |
2807 | Parameters : mobile_identity - used in the AIR message
2808 |
2809 +------------------------------------------------------------------------------
2810 */
2811
2812 GLOBAL void kern_ulong2mobile_identity ( ULONG ptmsi, T_gmobile_identity* gmobile_identity )
2813 {
2814 GMM_TRACE_FUNCTION ("kern_ulong2mobile_identity()");
2815
2816 memset (gmobile_identity, 0, sizeof (T_mobile_identity));
2817
2818
2819
2820 if ( GMMRR_TMSI_INVALID == gmm_data->ptmsi.current )
2821 {
2822 /*
2823 * IMSI
2824 * <R.GMM.AGINIT.M.005>
2825 */
2826 gmobile_identity->v_tmsi = FALSE;
2827
2828 kern_get_mobile_identity ( ID_TYPE_IMSI, gmobile_identity );
2829 }
2830 else /* !ptmsi.available */
2831 {
2832 /*
2833 * PTMSI
2834 * <R.GMM.AGINIT.M.002>
2835 */
2836 gmobile_identity->odd_even = EVEN;
2837 gmobile_identity->v_tmsi = TRUE;
2838 gmobile_identity->type_of_identity = ID_TYPE_TMSI;
2839 gmobile_identity->v_identity_digit = FALSE;
2840 gmobile_identity->tmsi.l_tmsi = 32;
2841
2842
2843 ccd_codeByte (gmobile_identity->tmsi.b_tmsi, 0, 8, (UBYTE)(ptmsi >> 24));
2844 ccd_codeByte (gmobile_identity->tmsi.b_tmsi, 8, 8, (UBYTE)(ptmsi >> 16));
2845 ccd_codeByte (gmobile_identity->tmsi.b_tmsi, 16, 8, (UBYTE)(ptmsi >> 8));
2846 ccd_codeByte (gmobile_identity->tmsi.b_tmsi, 24, 8, (UBYTE) ptmsi);
2847 }
2848 GMM_RETURN;
2849
2850 } /* kern_ulong2mobile_identity() */
2851 /*
2852 +------------------------------------------------------------------------------
2853 | Function : kern_kern_cell_changed
2854 +------------------------------------------------------------------------------
2855 | Description : Returns TRUE if cell was changed.
2856 |
2857 | Parameters : void
2858 |
2859 +------------------------------------------------------------------------------
2860 */
2861
2862 GLOBAL BOOL kern_cell_changed ( void )
2863 {
2864 GMM_TRACE_FUNCTION ("kern_cell_changed()");
2865
2866 if ( gmm_data->kern.sig_cell_info.env.cid != gmm_data->kern.old_sig_cell_info.env.cid)
2867 {
2868 TRACE_EVENT("Info: cid changed");
2869 GMM_RETURN_ (TRUE);
2870 }
2871 else
2872 {
2873 GMM_RETURN_ (kern_ra_crossed());
2874 }
2875 } /* kern_lai_changed() */
2876
2877 /*
2878 +------------------------------------------------------------------------------
2879 | Function : kern_kern_lai_changed
2880 +------------------------------------------------------------------------------
2881 | Description : Returns TRUE if LA was changed.
2882 |
2883 | Parameters : void
2884 |
2885 +------------------------------------------------------------------------------
2886 */
2887
2888 GLOBAL BOOL kern_lai_changed ( void )
2889 {
2890 GMM_TRACE_FUNCTION ("kern_lai_changed()");
2891
2892 if ( gmm_data->kern.attach_cap.rai_accepted.lac != gmm_data->kern.sig_cell_info.env.rai.lac)
2893 {
2894 TRACE_3_INFO ("Info: LAI changed: changed lac: %x (%x) -> %x",
2895 gmm_data->kern.attach_cap.rai_accepted.lac,
2896 gmm_data->kern.old_sig_cell_info.env.rai.lac,
2897 gmm_data->kern.sig_cell_info.env.rai.lac);
2898 GMM_RETURN_ (TRUE);
2899 }
2900 else
2901 {
2902 if (kern_plmn_changed())
2903 {
2904 GMM_RETURN_ (TRUE);
2905 }
2906 }
2907
2908 GMM_RETURN_ (FALSE);
2909 } /* kern_lai_changed() */
2910
2911 /*
2912 +------------------------------------------------------------------------------
2913 | Function : kern_kern_lau_needed
2914 +------------------------------------------------------------------------------
2915 | Description : Returns TRUE if LAU is needed
2916 |
2917 | Parameters : void
2918 |
2919 +------------------------------------------------------------------------------
2920 */
2921
2922 GLOBAL BOOL kern_lau_needed ( void )
2923 {
2924 UBYTE mm_state;
2925
2926 GMM_TRACE_FUNCTION ("kern_lau_needed()");
2927
2928 mm_state = GET_STATE(MM);
2929
2930 TRACE_1_PARA ("sig_cell_info.mm_status %d", gmm_data->kern.sig_cell_info.mm_status);
2931
2932 switch (gmm_data->kern.attach_cap.attach_type)
2933 {
2934 case GMMREG_AT_IMSI:
2935 case GMMREG_AT_COMB:
2936 GMM_RETURN_ (
2937 ( GMM_MM_DEREG == mm_state
2938 || GMM_MM_REG_UPDATE_NEEDED == mm_state
2939 || MMGMM_WAIT_FOR_UPDATE == gmm_data->kern.sig_cell_info.mm_status
2940
2941 || gmm_data->kern.sig_cell_info.env.rai.lac != gmm_data->kern.mm_cell_env.rai.lac
2942 || (memcmp (gmm_data->kern.sig_cell_info.env.rai.plmn.mnc,
2943 gmm_data->kern.mm_cell_env.rai.plmn.mnc, SIZE_MNC) != 0)
2944 || (memcmp (gmm_data->kern.sig_cell_info.env.rai.plmn.mcc,
2945 gmm_data->kern.mm_cell_env.rai.plmn.mcc, SIZE_MCC) != 0)
2946 )
2947
2948 && ( MMGMM_LIMITED_SERVICE != gmm_data->kern.sig_cell_info.mm_status)
2949 );
2950 /* break; */
2951 default:
2952 GMM_RETURN_ (FALSE);
2953 /* break; */
2954 }
2955 } /* kern_lau_needed() */
2956
2957
2958 /*
2959 +------------------------------------------------------------------------------
2960 | Function : kern_ra_crossed
2961 +------------------------------------------------------------------------------
2962 | Description : Returns TRUE if RA was crossed.
2963 |
2964 | Parameters : void
2965 |
2966 +------------------------------------------------------------------------------
2967 */
2968
2969 GLOBAL BOOL kern_ra_crossed ( void )
2970 {
2971 GMM_TRACE_FUNCTION ("kern_ra_crossed?");
2972
2973 if (gmm_data->kern.sig_cell_info.env.rai.rac != gmm_data->kern.old_sig_cell_info.env.rai.rac
2974 || gmm_data->kern.sig_cell_info.env.rai.lac != gmm_data->kern.old_sig_cell_info.env.rai.lac )
2975 {
2976 TRACE_EVENT("Info: RA crossed");
2977 GMM_RETURN_ (TRUE);
2978 }
2979 GMM_RETURN_(FALSE);
2980 } /* kern_rai_changed() */
2981
2982 /*
2983 +------------------------------------------------------------------------------
2984 | Function : kern_rai_changed
2985 +------------------------------------------------------------------------------
2986 | Description : Returns TRUE if RA was changed.
2987 |
2988 | Parameters : void
2989 |
2990 +------------------------------------------------------------------------------
2991 */
2992
2993 GLOBAL BOOL kern_rai_changed ( void )
2994 {
2995 GMM_TRACE_FUNCTION ("kern_rai_changed()");
2996
2997 if ( gmm_data->kern.sig_cell_info.env.rai.rac != gmm_data->kern.attach_cap.rai_accepted.rac )
2998 {
2999 TRACE_0_INFO("RAI changed");
3000 GMM_RETURN_ (TRUE);
3001 }
3002 GMM_RETURN_ (kern_lai_changed());
3003 } /* kern_rai_changed() */
3004
3005 /*
3006 +------------------------------------------------------------------------------
3007 | Function : kern_plmn_changed
3008 +------------------------------------------------------------------------------
3009 | Description : Returns TRUE if PLMN was changed.
3010 |
3011 | Parameters : void
3012 |
3013 +------------------------------------------------------------------------------
3014 */
3015
3016 GLOBAL BOOL kern_plmn_changed ( void )
3017 {
3018 GMM_TRACE_FUNCTION ("kern_plmn_changed()");
3019
3020 if ( (memcmp (gmm_data->kern.sig_cell_info.env.rai.plmn.mnc, gmm_data->kern.attach_cap.rai_accepted.mnc, SIZE_MNC) != 0)
3021 || (memcmp (gmm_data->kern.sig_cell_info.env.rai.plmn.mcc, gmm_data->kern.attach_cap.rai_accepted.mcc, SIZE_MCC) != 0)
3022 )
3023 {
3024 TRACE_0_INFO ("PLMN changed");
3025 GMM_RETURN_ (TRUE);
3026 }
3027 else
3028 {
3029 GMM_RETURN_ (FALSE);
3030 }
3031 } /* kern_plmn_changed() */
3032 /*
3033 +------------------------------------------------------------------------------
3034 | Function : kern_set_rai
3035 +------------------------------------------------------------------------------
3036 | Description : This Procedure sets the old rai and the new rai.
3037 |
3038 | Parameters : rai
3039 |
3040 +------------------------------------------------------------------------------
3041 */
3042
3043 GLOBAL void kern_set_rai ( T_routing_area_identification * rai)
3044 {
3045 GMM_TRACE_FUNCTION ("kern_set_rai()");
3046
3047 /*
3048 * gmm_data->kern.attach_cap.rai_accepted has to be always the last valid assigned RAI
3049 * gmm_data->rai includes the last updated lac and or rac depending
3050 * on the net mode and the oroiginator:
3051 * net modeII: lac may only chaged by MM so that we know
3052 * whether we have to update LA or not either upon cell_ind(lac) or
3053 * activate_ind(lac) dependinig on what receives first. .
3054 * That means gmm_data->rai MUST NOT sent to the network it
3055 * can be wrong, i.e. new LAC but old RAC! Use always gmm_data->kern.attach_cap.rai_accepted
3056 * for transmission o the AIR.
3057 */
3058 gmm_data->kern.attach_cap.rai_accepted = *rai;
3059
3060 if (GMMRR_NET_MODE_I==gmm_data->kern.sig_cell_info.net_mode)
3061 {
3062 memcpy (gmm_data->kern.mm_cell_env.rai.plmn.mcc, rai->mcc, SIZE_MCC);
3063 memcpy (gmm_data->kern.mm_cell_env.rai.plmn.mnc, rai->mnc, SIZE_MNC);
3064
3065 gmm_data->kern.mm_cell_env.rai.lac = rai->lac;
3066 gmm_data->kern.mm_cell_env.rai.rac = rai->rac;
3067 gmm_data->kern.mm_cell_env.cid = gmm_data->kern.sig_cell_info.env.cid;
3068 }
3069 GMM_RETURN;
3070 } /* kern_set_rai() */
3071
3072 /*
3073 +------------------------------------------------------------------------------
3074 | Function : kern_gmmrr_suspend
3075 +------------------------------------------------------------------------------
3076 | Description : The function kern_gmmrr_suspend()
3077 |
3078 | This procedure suspends GRR
3079 |
3080 | Parameters : void
3081 |
3082 +------------------------------------------------------------------------------
3083 */
3084 GLOBAL void kern_gmmrr_suspend ( UBYTE susp_gprs, UBYTE gmmrr_susp_cause, UBYTE susp_type)
3085 {
3086 GMM_TRACE_FUNCTION( "kern_gmmrr_suspend" );
3087
3088 gmm_data->kern.suspension_type |= susp_type;
3089 TRACE_1_OUT_PARA ("susp_type: %x", gmm_data->kern.suspension_type);
3090
3091 if (GMM_GRR_STATE_CR==gmm_data->kern.attach_cap.grr_state)
3092 {
3093 TRACE_0_INFO("suspension delayed untill cell_ind is received");
3094 }
3095 else
3096 {
3097 PALLOC ( gmmrr_suspend_req, GMMRR_SUSPEND_REQ);
3098 gmmrr_suspend_req->susp_gprs = susp_gprs;
3099 gmmrr_suspend_req->gmmrr_susp_cause= gmmrr_susp_cause;
3100 /* START PATCH UBUOB ISSUE 8379 */
3101 gmm_data->kern.gmmrr_resume_sent = FALSE;
3102 gmm_data->kern.attach_cap.grr_state = GMM_GRR_STATE_SUSPENDING;
3103 /* END PATCH UBUOB ISSUE 8379 */
3104 PSEND ( hCommGRR, gmmrr_suspend_req );
3105 }
3106
3107 GMM_RETURN;
3108 } /* kern_gmmrr_suspend() */
3109 /*
3110 +------------------------------------------------------------------------------
3111 | Function : kern_gmmrr_stop_waiting_for_transmission
3112 +------------------------------------------------------------------------------
3113 | Description : The function kern_gmmrr_stop_waiting_for_transmission()
3114 |
3115 | Is sent after gmmrr_cell_ind if no RAU is needed.
3116 |
3117 | Parameters : void
3118 |
3119 +------------------------------------------------------------------------------
3120 */
3121 GLOBAL void kern_gmmrr_stop_waiting_for_transmission (void)
3122 {
3123 GMM_TRACE_FUNCTION( "kern_gmmrr_stop_waiting_for_transmission" );
3124 switch(GET_STATE(CU))
3125 {
3126 case CU_NOT_REQUESTED:
3127 {
3128 PALLOC (gmmrr_cell_res, GMMRR_CELL_RES);
3129 gmmrr_cell_res->cu_cause=GMMRR_RA_DEFAULT;
3130 SET_STATE (CU, CU_CELL_RES_SENT);
3131 PSEND (hCommGRR, gmmrr_cell_res);
3132 }
3133 break;
3134 case CU_REQUESTED:
3135 {
3136 PALLOC (gmmrr_cell_res, GMMRR_CELL_RES);
3137 gmmrr_cell_res->cu_cause=GMMRR_RA_CU;
3138 PSEND (hCommGRR, gmmrr_cell_res);
3139 }
3140 /* NO break; */
3141 case CU_REQUESTED_CELL_RES_SENT:
3142 SET_STATE (CU, CU_CELL_RES_SENT);
3143 kern_send_llgmm_trigger_req();
3144 break;
3145 default:
3146 case CU_CELL_RES_SENT:
3147 break;
3148 }
3149 GMM_RETURN;
3150 } /* kern_gmmrr_suspend() */
3151
3152 /*
3153 +------------------------------------------------------------------------------
3154 | Function : kern_gmmrr_attach_started
3155 +------------------------------------------------------------------------------
3156 | Description : The function kern_attach_started()
3157 | |
3158 | Parameters : void
3159 |
3160 +------------------------------------------------------------------------------
3161 */
3162 /*
3163 * GMMRR_ATTACH_STARTED_REQ is used to inform GRR that routing area upodate or
3164 * attach procedure is started. This time span is closed with
3165 * GMMRR_ATTACH_FINISHED_REQ
3166 * GSM 04.60, ch. 5.5.1.5 Discontinuous reception (DRX):
3167 * "When initiating the MM procedures for GPRS attach and routeing area update
3168 * defined in 3GPP TS 04.08, the mobile station shall enter the MM non- DRX mode
3169 * period. This period ends when either of the messages GPRS ATTACH ACCEPT,
3170 * GPRS ATTACH REJECT, ROUTING AREA UPDATE ACCEPT or ROUTING AREA UPDATE REJECT
3171 * is received by the mobile station. This period also ends after timeout
3172 * waiting for any of these messages."
3173 */
3174
3175 GLOBAL void kern_gmmrr_attach_started (void)
3176 {
3177 GMM_TRACE_FUNCTION( "kern_gmmrr_attach_started" );
3178 {
3179 PALLOC (gmmrr_attach_started_req, GMMRR_ATTACH_STARTED_REQ);
3180 gmm_data->kern.attach_cap.gmmrr_attach_finished_sent=FALSE;
3181 PSEND (hCommGRR, gmmrr_attach_started_req);
3182 }
3183 GMM_RETURN;
3184 } /* kern_gmmrr_attach_finished() */
3185
3186 /*
3187 +------------------------------------------------------------------------------
3188 | Function : kern_gmmrr_attach_finished
3189 +------------------------------------------------------------------------------
3190 | Description : The function kern_attach_finished()
3191 |
3192 | Parameters : void
3193 |
3194 +------------------------------------------------------------------------------
3195 */
3196 GLOBAL void kern_gmmrr_attach_finished (void)
3197 {
3198 GMM_TRACE_FUNCTION( "kern_gmmrr_attach_finished" );
3199 if(!gmm_data->kern.attach_cap.gmmrr_attach_finished_sent )
3200 {
3201 PALLOC (gmmrr_attach_finished_req, GMMRR_ATTACH_FINISHED_REQ);
3202 gmm_data->kern.attach_cap.gmmrr_attach_finished_sent=TRUE;
3203 PSEND (hCommGRR, gmmrr_attach_finished_req);
3204 }
3205 GMM_RETURN;
3206 } /* kern_gmmrr_attach_finished() */
3207
3208 /*
3209 +------------------------------------------------------------------------------
3210 | Function : kern_is_cell_forbidden
3211 +------------------------------------------------------------------------------
3212 | Description : The function kern_is_cell_forbidden checks whether cell is
3213 | forbidden for GPRS or not
3214 |
3215 | Parameters : void
3216 |
3217 +------------------------------------------------------------------------------
3218 */
3219 GLOBAL BOOL kern_is_cell_forbidden (void)
3220 {
3221 BOOL forbidden = (GMMRR_SERVICE_LIMITED== gmm_data->kern.sig_cell_info.gmm_status);
3222
3223 int i;
3224 GMM_TRACE_FUNCTION( "kern_is_cell_forbidden" );
3225
3226 if (MMGMM_LIMITED_SERVICE == gmm_data->kern.sig_cell_info.mm_status)
3227 {
3228 TRACE_0_INFO ("mm is in limited");
3229 GMM_RETURN_ (TRUE);
3230 }
3231
3232
3233
3234 if(MODE_AUTO EQ gmm_data->kern.attach_cap.network_selection_mode
3235 /* START PATCH UBUOB ISSUE 8781 */
3236 || !gmm_data->kern.attach_cap.gmmreg)
3237 /* END PATCH UBUOB ISSUE 8781 */
3238 {
3239 for(i=0;!forbidden && (i<MAX_LIST_OF_FORBIDDEN_PLMNS_FOR_GPRS_SERVICE); i++)
3240 {
3241 forbidden =
3242 forbidden
3243 ||
3244 (
3245 (memcmp
3246 (gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[i].mcc,
3247 gmm_data->kern.sig_cell_info.env.rai.plmn.mcc, SIZE_MCC)
3248 == 0
3249 )
3250 &&
3251 (memcmp
3252 (gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[i].mnc,
3253 gmm_data->kern.sig_cell_info.env.rai.plmn.mnc, SIZE_MNC)
3254 == 0
3255 )
3256 );
3257 }
3258 }
3259 TRACE_1_INFO ("cell %s",forbidden?"forbidden":"allowed");
3260
3261 GMM_RETURN_(forbidden);
3262
3263
3264 } /* kern_gmmrr_attach_finished() */
3265
3266 /*
3267 +------------------------------------------------------------------------------
3268 | Function : kern_remove_plmn_from_forbidden_list
3269 +------------------------------------------------------------------------------
3270 | Description : The function kern_remove_plmn_from_forbidden_list
3271 |
3272 | Parameters : void
3273 |
3274 +------------------------------------------------------------------------------
3275 */
3276 GLOBAL void kern_remove_plmn_from_forbidden_list (T_plmn plmn)
3277 {
3278 int i;
3279 GMM_TRACE_FUNCTION( "kern_remove_plmn_from_forbidden_list" );
3280
3281 for(i=0; i<MAX_LIST_OF_FORBIDDEN_PLMNS_FOR_GPRS_SERVICE; i++)
3282 {
3283 BOOL forbidden =
3284 ((memcmp
3285 (gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[i].mcc,
3286 plmn.mcc, SIZE_MCC)
3287 == 0
3288 )
3289 &&
3290 (memcmp
3291 (gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[i].mnc,
3292 plmn.mnc, SIZE_MNC)
3293 == 0
3294 )
3295 );
3296 if (forbidden)
3297 {
3298 memset(gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[i].mcc, 0xFF, SIZE_MCC);
3299 memset(gmm_data->kern.attach_cap.list_of_forbidden_plmns_for_gprs_service[i].mnc, 0xFF, SIZE_MNC);
3300 }
3301 }
3302
3303 GMM_RETURN;
3304
3305
3306 } /* kern_gmmrr_attach_finished() */
3307
3308 /*
3309 +------------------------------------------------------------------------------
3310 | Function : kern_send_gmmreg_cell_ind
3311 +------------------------------------------------------------------------------
3312 | Description : The function kern_send_gmmreg_cell_ind informs MMI
3313 | that cell has changed or that we GSM is in full service again
3314 |
3315 | Parameters : void
3316 |
3317 +------------------------------------------------------------------------------
3318 */
3319 GLOBAL void kern_send_gmmreg_cell_ind (void)
3320 {
3321 BOOL attach_cnf_to_be_sent;
3322 GMM_TRACE_FUNCTION( "kern_send_gmmreg_cell_ind" );
3323
3324 attach_cnf_to_be_sent = (MMGMM_FULL_SERVICE == gmm_data->kern.sig_cell_info.mm_status
3325 && (
3326 (
3327 (
3328 kern_cell_changed()
3329 || gmm_data->kern.attach_cap.gmmreg
3330 )
3331 &&
3332 (
3333 GMMRR_SERVICE_NONE != gmm_data->kern.sig_cell_info.gmm_status
3334 || GMMRR_SERVICE_NONE == gmm_data->kern.old_sig_cell_info.gmm_status
3335 )
3336 )
3337 /* OLD !!! */
3338 || MMGMM_FULL_SERVICE != gmm_data->kern.old_sig_cell_info.mm_status
3339 )
3340 );
3341
3342 switch( GET_STATE( KERN ) )
3343 {
3344 case KERN_GMM_NULL_NO_IMSI:
3345 case KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ:
3346 case KERN_GMM_NULL_IMSI:
3347 case KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ:
3348 case KERN_GMM_NULL_PLMN_SEARCH:
3349
3350 case KERN_GMM_DEREG_NO_IMSI:
3351 case KERN_GMM_DEREG_PLMN_SEARCH:
3352 case KERN_GMM_DEREG_NO_CELL_AVAILABLE:
3353 case KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH:
3354 case KERN_GMM_DEREG_LIMITED_SERVICE:
3355 case KERN_GMM_DEREG_RESUMING:
3356 case KERN_GMM_DEREG_SUSPENDING:
3357 case KERN_GMM_DEREG_SUSPENDED:
3358
3359 if (attach_cnf_to_be_sent)
3360 {
3361 if ( GMMRR_NET_MODE_III==gmm_data->kern.sig_cell_info.net_mode
3362 && GMMREG_CLASS_BC== gmm_data->kern.attach_cap.mobile_class
3363 && !kern_lau_needed())
3364 {
3365 kern_gmmreg_attach_cnf_sr(GMMREG_AT_IMSI,
3366 SEARCH_NOT_RUNNING);
3367 }
3368 else
3369 {
3370 switch (gmm_data->kern.sig_cell_info.gmm_status)
3371 {
3372 case GMMRR_SERVICE_LIMITED:
3373 case GMMRR_SERVICE_NONE:
3374 kern_gmmreg_attach_cnf_sr(GMMREG_AT_IMSI,
3375 SEARCH_NOT_RUNNING);
3376 break;
3377 default:
3378 case GMMRR_SERVICE_FULL:
3379 kern_gmmreg_attach_cnf_sr(GMMREG_AT_IMSI,
3380 (UBYTE)(gmm_data->sim_gprs_invalid?
3381 SEARCH_NOT_RUNNING:SEARCH_RUNNING));
3382 break;
3383 }
3384 }
3385 }
3386 break;
3387
3388 case KERN_GMM_DEREG_INITIATED:
3389 break;
3390 case KERN_GMM_REG_INITIATED:
3391 if (attach_cnf_to_be_sent)
3392 {
3393 kern_gmmreg_attach_cnf_sr(GMMREG_AT_IMSI,SEARCH_RUNNING);
3394 }
3395 break;
3396 default:
3397 TRACE_ERROR ("Unexpexcted state");
3398 /* NO break */
3399 case KERN_GMM_REG_ATTEMPTING_TO_UPDATE:
3400 case KERN_GMM_REG_NO_CELL_AVAILABLE:
3401 case KERN_GMM_REG_LIMITED_SERVICE:
3402 case KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM:
3403 case KERN_GMM_REG_RESUMING:
3404 case KERN_GMM_REG_SUSPENDED:
3405 case KERN_GMM_REG_SUSPENDING:
3406 case KERN_GMM_REG_IMSI_DETACH_INITIATED:
3407
3408 case KERN_GMM_REG_TEST_MODE_NO_IMSI:
3409 case KERN_GMM_REG_TEST_MODE:
3410 case KERN_GMM_RAU_INITIATED:
3411 case KERN_GMM_RAU_WAIT_FOR_NPDU_LIST:
3412
3413 if (attach_cnf_to_be_sent)
3414 {
3415 kern_gmmreg_attach_cnf(GMMREG_AT_COMB);
3416 }
3417 break;
3418 case KERN_GMM_REG_NORMAL_SERVICE:
3419 if (attach_cnf_to_be_sent)
3420 {
3421 kern_gmmreg_attach_cnf(GMMREG_AT_COMB);
3422
3423 #ifdef REL99
3424 if (gmm_data->kern.sig_cell_info.sgsnr_flag!= gmm_data->kern.old_sig_cell_info.sgsnr_flag)
3425 {
3426 PALLOC (mmpm_attach_ind, MMPM_ATTACH_IND);
3427 PSEND ( hCommSM, mmpm_attach_ind );
3428 }
3429 #endif
3430
3431 break;
3432 }
3433 }
3434 GMM_RETURN;
3435 } /* kern_gmmreg_cell_ind */
3436 /*
3437 +------------------------------------------------------------------------------
3438 | Function : kern_send_llgmm_trigger_req
3439 +------------------------------------------------------------------------------
3440 | Description : Sends trigger request with the correct cause value
3441 |
3442 | Parameters : None
3443 |
3444 +------------------------------------------------------------------------------
3445 */
3446 GLOBAL void kern_send_llgmm_trigger_req(void)
3447 {
3448
3449 GMM_TRACE_FUNCTION ("kern_send_llgmm_trigger_req()");
3450 {
3451 PALLOC (llgmm_trigger_req, LLGMM_TRIGGER_REQ);
3452
3453 #ifdef REL99
3454 /*
3455 * If SGSN supports cell notification indicate that LLC
3456 * can use NULL frame for performing cell updates.
3457 * The first cell notification shouldn't use LLC NULL
3458 * frame. The following logic takes care of it.
3459 */
3460 switch (gmm_data->cell_notification) /* TCS 4.0 */
3461 { /* TCS 4.0 */
3462 case FIRST_CELL_NOTIFY: /* TCS 4.0 */
3463 /*
3464 * Next cell update can use LLC NULL frame
3465 */
3466 gmm_data->cell_notification = NOT_FIRST_CELL_NOTIFY; /* TCS 4.0 */
3467 /*
3468 * This cell update should not use LLC NULL frame
3469 */
3470 llgmm_trigger_req->trigger_cause = LLGMM_TRICS_CELL_UPDATE;
3471 break; /* TCS 4.0 */
3472 case NOT_FIRST_CELL_NOTIFY: /* TCS 4.0 */
3473 /*
3474 * Cell notification supported and this is not the first cell update.
3475 * So LLC NULL frame can be used
3476 */
3477 llgmm_trigger_req->trigger_cause = LLGMM_TRICS_CELL_UPDATE_NULL_FRAME; /* TCS 4.0 */
3478 break; /* TCS 4.0 */
3479 default: /* TCS 4.0 */
3480 /*
3481 * cell notification not supported by SGSN
3482 */
3483 llgmm_trigger_req->trigger_cause = LLGMM_TRICS_CELL_UPDATE; /* TCS 4.0 */
3484 } /* TCS 4.0 */
3485 #else
3486 llgmm_trigger_req->trigger_cause = LLGMM_TRICS_CELL_UPDATE; /* TCS 4.0 */
3487 #endif
3488
3489 PSEND ( hCommLLC, llgmm_trigger_req );
3490 }
3491 GMM_RETURN;
3492 } /* kern_send_llgmm_trigger_req */
3493 /*
3494 +------------------------------------------------------------------------------
3495 | Function : kern_attach_rau_init
3496 +------------------------------------------------------------------------------
3497 | Description : The function kern_attach_rau_init initilize RAU and attach procedure
3498 |
3499 | Parameters : void
3500 |
3501 +------------------------------------------------------------------------------
3502 */
3503 GLOBAL void kern_attach_rau_init (void)
3504 {
3505 GMM_TRACE_FUNCTION( "kern_attach_rau_init" );
3506 /*
3507 * PATCH UBUOB 22.7.07: multiple outstanding SIM_AUTHENTICATION_REQ messages
3508 * for safety reset the counter whenever a new attachment is started
3509 */
3510
3511 gmm_data->kern.auth_cap.last_auth_req_id = NOT_PRESENT_8BIT;
3512
3513
3514 /* START PATCH UBUOB ISSUE 8284 */
3515 gmm_data->kern.detach_cap.error_cause = GMMCS_INT_NOT_PRESENT; /* TCS 2.1 */
3516 /* END PATCH UBUOB ISSUE 8284 */
3517
3518 gmm_data->kern.attach_cap.t3310_value=0;
3519 vsi_t_stop ( GMM_handle , kern_T3310);
3520
3521 /* #5899 */
3522 /*
3523 * PATCH UBUOB 25.3.02: Stop timer T3302 when you are trying to ATTACH again
3524 * otherwise it may timeout in the middle of the procedure. Also this ATTACH
3525 * procedure may be successful and then T3302 also needs to be stopped.
3526 */
3527 vsi_t_stop ( GMM_handle , kern_T3302);
3528 /* end patch */
3529
3530 /*
3531 * PATCH UBUOB 25.10.02: there are cases where T3311 also needs to be stopped:
3532 * GMM receives CGRLC_STATUS_IND(access not allowed due to cell change), starts T3311 (TCS 2.1)
3533 * GMMRR_CELL_IND(cell changed), RAU restarted, but forgot to stop T3311
3534 * trace 25a_night_cell_change_no_patch
3535 */
3536 vsi_t_stop ( GMM_handle , kern_T3311);
3537 /* end patch ubuob 25.10.02 */
3538 sig_kern_rdy_stop_t3302_req();
3539
3540 /*
3541 * patch ubuob 23.10.02: flag needs to be cleared when initiating RAU or ATTACH
3542 * and not at end
3543 */
3544 SET_STATE (GU,GU_UPDATE_NOT_NEEDED);
3545 /* end patch ubuob */
3546
3547 GMM_RETURN;
3548
3549
3550 } /* kern_attach_rau_init */
3551
3552 /*
3553 +------------------------------------------------------------------------------
3554 | Function : kern_make_cause
3555 +------------------------------------------------------------------------------
3556 | Description : The function kern_make_cause()
3557 |
3558 | An internal 16 bit cause is generated from the cause received
3559 | from the network. The reject causes indicating a retry in a new
3560 | cell are translated to a single value. In case no cause was sent
3561 | by the network a special internal value is returned to handle this.
3562 |
3563 | Parameters : valid flag, network cause value
3564 |
3565 +------------------------------------------------------------------------------
3566 */
3567 GLOBAL USHORT kern_make_cause (BOOL cause_valid, UBYTE network_cause)
3568 {
3569 GMM_TRACE_FUNCTION ("kern_make_cause");
3570
3571 if (cause_valid)
3572 {
3573 if (network_cause >= 0x30 AND /* TCS 2.1 */
3574 network_cause <= 0x3F) /* TCS 2.1 */
3575 { /* TCS 2.1 */
3576 GMM_RETURN_ (GMMCS_RETRY_IN_NEW_CELL); /* TCS 2.1 */
3577 } /* TCS 2.1 */
3578 else /* TCS 2.1 */
3579 { /* TCS 2.1 */
3580 GMM_RETURN_ (CAUSE_MAKE (DEFBY_STD, /* TCS 2.1 */
3581 ORIGSIDE_NET, /* TCS 2.1 */
3582 GMM_ORIGINATING_ENTITY, /* TCS 2.1 */
3583 network_cause)); /* TCS 2.1 */
3584 } /* TCS 2.1 */
3585 }
3586 else
3587 {
3588 GMM_RETURN_ (GMMCS_NET_CAUSE_NOT_PRESENT);
3589 }
3590 }
3591 #ifdef GMM_TCS4
3592 /*
3593 +------------------------------------------------------------------------------
3594 | Function : kern_make_new_cause
3595 +------------------------------------------------------------------------------
3596 | Description : The function kern_make_new_cause()
3597 |
3598 | An internal 16 bit cause is generated from the cause received
3599 | from the network. The reject causes indicating a retry in a new
3600 | cell are translated to a single value. In case no cause was sent
3601 | by the network a special internal value is returned to handle this.
3602 |
3603 | Parameters : valid flag, network cause value
3604 |
3605 +------------------------------------------------------------------------------
3606 */
3607 GLOBAL T_CAUSE_ps_cause kern_make_new_cause ( void )
3608 {
3609 T_CAUSE_ps_cause ps_cause;
3610 GMM_TRACE_FUNCTION ("kern_make_cause");
3611 ps_cause.ctrl_value = CAUSE_is_from_mm;
3612
3613 switch (gmm_data->kern.detach_cap.error_cause)
3614 {
3615 case GMMCS_INT_NOT_PRESENT:
3616 case GMMCS_NET_CAUSE_NOT_PRESENT :
3617 case MMCS_INT_NOT_PRESENT:
3618 ps_cause.value.mm_cause = CAUSE_MM_NO_ERROR;
3619 break;
3620 default:
3621 ps_cause.ctrl_value = CAUSE_is_from_nwmm;
3622 ps_cause.value.nwmm_cause = gmm_data->kern.detach_cap.error_cause&0xff; /* TCS 4.0 */
3623 break;
3624 case MMCS_UNSPECIFIED:
3625 case GMMCS_INT_PROTOCOL_ERROR:
3626 ps_cause.value.mm_cause = CAUSE_MM_PROTOCOL_ERROR;
3627 break;
3628 case GMMCS_SUCCESS:
3629 ps_cause.value.mm_cause = CAUSE_MM_SUCCESS;
3630 break;
3631 case GMMCS_AAC_UNDER_5:
3632 case GMMCS_AAC_OVER_5:
3633 ps_cause.value.mm_cause = CAUSE_MM_TRY_TO_UPDATE;
3634 break;
3635 case MMCS_AUTHENTICATION_REJECTED:
3636 case GMMCS_AUTHENTICATION_REJECTED:
3637 ps_cause.value.mm_cause = CAUSE_MM_AUTHENTICATION_REJECTED;
3638 break;
3639 case MMCS_SIM_REMOVED:
3640 case GMMCS_SIM_REMOVED:
3641 ps_cause.value.mm_cause = CAUSE_MM_SIM_REMOVED;
3642 break;
3643 case GMMCS_POWER_OFF:
3644 ps_cause.value.mm_cause = CAUSE_MM_POWER_OFF;
3645 break;
3646 case GMMCS_LIMITED_SERVICE:
3647 ps_cause.value.mm_cause = CAUSE_MM_LIMITED_SERVICE;
3648 break;
3649 case MMCS_SUCCESS:
3650 ps_cause.value.mm_cause = CAUSE_MM_SUCCESS;
3651 break;
3652 case MMCS_NO_REGISTRATION:
3653 ps_cause.value.mm_cause = CAUSE_MM_NO_REGISTRATION;
3654 break;
3655 case MMCS_TIMER_RECOVERY:
3656 ps_cause.value.mm_cause = CAUSE_MM_TIMER_RECOVERY;
3657 break;
3658 case MMCS_NO_REESTABLISH:
3659 ps_cause.value.mm_cause = CAUSE_MM_NO_REESTABLISH;
3660 break;
3661 case MMCS_INT_PREEM:
3662 ps_cause.value.mm_cause = CAUSE_MM_INT_PREEM;
3663 break;
3664 case MMCS_PLMN_NOT_IDLE_MODE:
3665 ps_cause.value.mm_cause = CAUSE_MM_PLMN_NOT_IDLE_MODE;
3666 break;
3667
3668
3669 }
3670 GMM_RETURN_ (ps_cause);
3671 }
3672 #endif
3673
3674 /*
3675 +------------------------------------------------------------------------------
3676 | Function : kern_call_undone_mm_proc_der
3677 +------------------------------------------------------------------------------
3678 | Description : This function starts all undone MM procedures after finishing the last
3679 | MM procedure
3680 |
3681 | Parameters : void
3682 |
3683 +------------------------------------------------------------------------------
3684 */
3685 GLOBAL void kern_call_undone_mm_proc_der ( void )
3686 {
3687 GMM_TRACE_FUNCTION( "kern_call_undone_mm_proc_der" );
3688 if (!gmm_data->kern.suspension_type)
3689 /*
3690 * default branch
3691 */
3692 {
3693 kern_resume_grr_der();
3694 GMM_RETURN;
3695 }
3696
3697
3698 if (GMM_SUSP_EM_CALL & gmm_data->kern.suspension_type)
3699 {
3700 kern_mm_cm_emergency_res(MMGMM_ESTABLISH_OK);
3701 }
3702 else if (GMM_SUSP_LAU & gmm_data->kern.suspension_type)
3703 {
3704 kern_mm_lau();
3705 }
3706 else if (GMM_SUSP_CALL & gmm_data->kern.suspension_type)
3707 {
3708 kern_mm_cm_establish_res(MMGMM_ESTABLISH_OK);
3709 }
3710 else if (GMM_SUSP_IMSI_DETACH & gmm_data->kern.suspension_type)
3711 {
3712 kern_mm_imsi_detach();
3713 }
3714 else if (GMM_SUSP_LOCAL_DETACH & gmm_data->kern.suspension_type)
3715 {
3716 kern_local_detach ( GMMCS_INT_NOT_PRESENT, FALSE, GMM_LOCAL_DETACH_PROC_NOT_CHANGED); /* TCS 2.1 */
3717
3718 }
3719 GMM_RETURN;
3720 }
3721 /*
3722 +------------------------------------------------------------------------------
3723 | Function : kern_call_undone_mm_proc_reg
3724 +------------------------------------------------------------------------------
3725 | Description : This function starts all undone MM procedures after finishing the last
3726 | MM procedure
3727 |
3728 | Parameters : void
3729 |
3730 +------------------------------------------------------------------------------
3731 */
3732 GLOBAL void kern_call_undone_mm_proc_reg ( void )
3733 {
3734 GMM_TRACE_FUNCTION( "kern_call_undone_mm_proc_reg" );
3735 if (GMM_SUSP_NONE == gmm_data->kern.suspension_type)
3736 /*
3737 * default branch
3738 */
3739 {
3740 kern_resume_grr_reg();
3741 GMM_RETURN;
3742 }
3743
3744
3745 if (GMM_SUSP_EM_CALL & gmm_data->kern.suspension_type)
3746 {
3747 kern_mm_cm_emergency_res(MMGMM_ESTABLISH_OK);
3748 }
3749 else if (GMM_SUSP_LAU & gmm_data->kern.suspension_type)
3750 {
3751 kern_mm_lau();
3752 }
3753 else if (GMM_SUSP_CALL & gmm_data->kern.suspension_type)
3754 {
3755 kern_mm_cm_establish_res(MMGMM_ESTABLISH_OK);
3756 }
3757 else if (GMM_SUSP_IMSI_DETACH & gmm_data->kern.suspension_type)
3758 {
3759 kern_mm_imsi_detach();
3760 }
3761 else if (GMM_SUSP_LOCAL_DETACH & gmm_data->kern.suspension_type)
3762 {
3763 kern_local_detach ( GMMCS_INT_NOT_PRESENT, FALSE, GMM_LOCAL_DETACH_PROC_NOT_CHANGED); /* TCS 2.1 */
3764 }
3765 GMM_RETURN;
3766 }
3767
3768 /*
3769 +------------------------------------------------------------------------------
3770 | Function : kern_reset_cipher
3771 +------------------------------------------------------------------------------
3772 | Description : This function deletes the ciphering parameters
3773 |
3774 | Parameters : void
3775 |
3776 +------------------------------------------------------------------------------
3777 */
3778 GLOBAL void kern_reset_cipher ( void )
3779 {
3780 GMM_TRACE_FUNCTION( "kern_reset_cipher" );
3781
3782 /*
3783 * 3GPP,24.008:
3784 * 4.7.7.2 Authentication and ciphering response by the MS
3785 *
3786 * The RAND and RES values stored in the mobile station shall be deleted:
3787 * - if the mobile station enters the GMM states GMM-DEREGISTERED or GMM-NULL.
3788 */
3789 /*
3790 * 3GPP,24.008:
3791 * 4.7.7.4 GPRS ciphering key sequence number
3792 *
3793 * If the GPRS ciphering key sequence number is deleted, the associated GPRS GSM
3794 * ciphering key , GPRS UMTS ciphering key and GPRS UMTS integrity key shall be deleted
3795 * (i.e. the established GSM security context or the UMTS security context is no longer
3796 * valid).
3797 */
3798 TRACE_EVENT ("ciphering OFF");
3799 gmm_data->cipher = FALSE;
3800
3801 GMM_RETURN;
3802 }
3803