comparison src/g23m-gprs/gmm/gmm_pei.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +0000
parents
children
comparison
equal deleted inserted replaced
0:4e78acac3d88 1:fa8dc04885d8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GPRS (8441)
4 | Modul : gmm_pei.c
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This module implements the process body interface
18 | for the entity GPRS Mobility Management (GMM)
19 |
20 | Exported functions:
21 |
22 | pei_create - Create the Protocol Stack Entity
23 | pei_init - Initialize Protocol Stack Entity
24 | pei_primitive - Process Primitive
25 | pei_timeout - Process Timeout
26 | pei_exit - Close resources and terminate
27 | pei_run - Process Primitive
28 | pei_config - Dynamic Configuration
29 | pei_monitor - Monitoring of physical Parameters
30 +-----------------------------------------------------------------------------
31 */
32
33
34 #define GMM_PEI_C
35
36 #define ENTITY_GMM
37
38 /*==== INCLUDES =============================================================*/
39
40 #include <stddef.h> /* to get definition of offsetof(), for MAK_FUNC_S */
41 #include <stdlib.h> /* to get atoi for tokenizer in pei_init */
42 #include "typedefs.h" /* to get Condat data types */
43 #include "vsi.h" /* to get a lot of macros */
44 #include "macdef.h"
45 #include "gprs.h"
46 #include "gsm.h" /* to get a lot of macros */
47 #include "cnf_gmm.h" /* to get cnf-definitions */
48 #include "mon_gmm.h" /* to get mon-definitions */
49 #include "prim.h" /* to get the definitions of used SAP and directions */
50 #include "pei.h" /* to get PEI interface */
51 #include "gmm.h" /* to get the global entity definitions */
52 #include "gmm_f.h" /* to get the debug print function */
53
54 #include "gmm_kernp.h" /* to get primitive interface to KERN */
55 #include "gmm_txp.h" /* to get primitive interface to TX */
56 #include "gmm_rxp.h" /* to get primitive interface to RX */
57 #include "gmm_rdyp.h" /* to get primitive interface to RDY */
58 #include "gmm_syncp.h" /* to get primitive interface to SYNC */
59
60 #include "gmm_kernf.h" /* to get functions from KERN */
61 #include "gmm_txf.h" /* to get functions from TX */
62 #include "gmm_rxf.h" /* to get functions from RX */
63 #include "gmm_rdyf.h" /* to get functions from RDY */
64 #include "gmm_syncf.h" /* to get functions from SYNC */
65
66
67 #include "ccdapi.h" /* to get ccd stuff */
68 #include "tok.h" /* to get tokenizer */
69 #include <string.h> /* to get memcpy */
70
71 #include "gmm_em.h" /*to get definitions of the Engineering Mode*/
72 /*==== DEFINITIONS ==========================================================*/
73
74 /*==== TYPES ================================================================*/
75
76 /*==== GLOBAL VARS ==========================================================*/
77
78 /*==== LOCAL VARS ===========================================================*/
79
80 static BOOL first_access = TRUE;
81 static T_MONITOR gmm_mon;
82
83 /*
84 * Jumptables to primitive handler functions. One table per SAP.
85 *
86 * Use MAK_FUNC_0 for primitives which contains no SDU.
87 * Use MAK_FUNC_S for primitives which contains a SDU.
88 */
89
90 /*******************************************************
91 * SAVE prim
92 *******************************************************/
93
94 #define PEI_SIGNAL_NOT_SAVED FALSE
95 #define PEI_SIGNAL_SAVED TRUE
96 #define PEI_END_SAVETAB 0xFF
97
98 #define GMM_MAX_SIGNALS_SAVED 5 /* value adjusted to GMM requirements */
99
100 typedef struct SAVE_QUEUE
101 {
102 void* prim;
103 T_VOID_FUNC func;
104 struct SAVE_QUEUE* next;
105 } T_SAVE_QUEUE;
106
107 void gmm_pei_delete_queue( T_SAVE_QUEUE** queue );
108
109 typedef struct
110 {
111 USHORT state;
112 USHORT signal[GMM_MAX_SIGNALS_SAVED];
113 } T_SAVE_TAB;
114
115 /*==== LOCAL PROTOTYPES =====================================================*/
116 LOCAL void gmm_pei_handle_prim( T_VOID_FUNC func, void* prim );
117 LOCAL BOOL gmm_pei_handle_save( void* prim, T_SAVE_QUEUE** queue,
118 const T_SAVE_TAB* table, T_VOID_FUNC func);
119 LOCAL void gmm_pei_handle_queue( T_SAVE_QUEUE** queue,
120 const T_SAVE_TAB* table);
121
122 /*==== VAR LOCAL ============================================================*/
123
124 LOCAL T_SAVE_QUEUE* save_queue; /* SAVE queue hangers */
125
126 LOCAL const T_SAVE_TAB save_tab[] = {
127
128 { KERN_GMM_REG_INITIATED,
129 {MMGMM_LUP_NEEDED_IND,
130 GMMREG_NET_REQ,
131 GMMREG_PLMN_RES,
132 0, 0 }
133 },
134
135 { KERN_GMM_RAU_INITIATED,
136 {MMGMM_LUP_NEEDED_IND,
137 GMMREG_DETACH_REQ,
138 GMMREG_NET_REQ,
139 GMMREG_PLMN_RES,
140 0 }
141 },
142
143 {KERN_GMM_RAU_WAIT_FOR_NPDU_LIST ,
144 {GMMRR_CELL_IND,
145 0, 0, 0, 0 }
146 },
147 { KERN_GMM_DEREG_SUSPENDING,
148 {GMMREG_NET_REQ,
149 GMMREG_PLMN_RES,
150 GMMRR_CS_PAGE_IND,
151 MMGMM_CM_ESTABLISH_IND,
152 MMGMM_CM_EMERGENCY_IND }
153 },
154 { KERN_GMM_REG_SUSPENDING,
155 {GMMREG_NET_REQ,
156 GMMREG_PLMN_RES,
157 GMMRR_CS_PAGE_IND,
158 MMGMM_CM_ESTABLISH_IND,
159 MMGMM_CM_EMERGENCY_IND }
160 },
161 { KERN_GMM_REG_RESUMING,
162 {GMMREG_DETACH_REQ,
163 GMMRR_CS_PAGE_IND,
164 MMGMM_CM_ESTABLISH_IND,
165 MMGMM_CM_EMERGENCY_IND,
166 GMMREG_ATTACH_REQ }
167 },
168 { KERN_GMM_DEREG_RESUMING,
169 {GMMREG_DETACH_REQ,
170 GMMRR_CS_PAGE_IND,
171 MMGMM_CM_ESTABLISH_IND,
172 MMGMM_CM_EMERGENCY_IND,
173 GMMREG_ATTACH_REQ}
174 },
175 { PEI_END_SAVETAB,
176 { 0, 0, 0, 0, 0 }
177 }
178 };
179 /*******************************************************
180 * End SAVE prim
181 *******************************************************/
182
183
184 /*
185 * Function is needed for grr_table[]. This declaration can be removed
186 * as soon as this function is no more called (i.e. all primitives are
187 * handled).
188 */
189 LOCAL void primitive_not_supported (void *data);
190
191 static const T_FUNC gmmreg_table[] =
192 {
193 MAK_FUNC_0(kern_gmmreg_attach_req, GMMREG_ATTACH_REQ),
194 MAK_FUNC_0(kern_gmmreg_detach_req, GMMREG_DETACH_REQ),
195 MAK_FUNC_0(kern_gmmreg_net_req, GMMREG_NET_REQ),
196 MAK_FUNC_0(kern_gmmreg_plmn_res, GMMREG_PLMN_RES),
197 MAK_FUNC_0(kern_gmmreg_plmn_mode_req, GMMREG_PLMN_MODE_REQ),
198 MAK_FUNC_0(kern_gmmreg_config_req, GMMREG_CONFIG_REQ),
199 };
200
201 #ifdef FF_EM_MODE
202 static const T_FUNC em_ul_table[] =
203 {
204 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x00 */
205 /*EM_SC_GPRS_INFO_REQ cannot be sent directly from ACI to GRR, because no SAP is defined.
206 So it have to be passed via GMM.*/
207 MAK_FUNC_0(em_gmm_sc_gprs_info_req, EM_SC_GPRS_INFO_REQ ), /* 0x01 */
208 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x02 */
209 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x03 */
210 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x04 */
211 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x05 */
212 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x06 */
213 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x07 */
214 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x08 */
215 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x09 */
216 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0A */
217 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0B */
218 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0C */
219 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0D */
220 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0E */
221 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0F */
222 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x10 */
223 MAK_FUNC_0(em_gmm_pco_trace_req , EM_PCO_TRACE_REQ ), /* 0x11*/ /*PCO output*/
224 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x12 */
225 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x13 */
226 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x14 */
227 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x15 */
228 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x16 */
229 MAK_FUNC_0(em_gmm_info_req, EM_GMM_INFO_REQ ), /* 0x17 */
230 /*EM_GRLC_INFO_REQ cannot be sent directly from ACI to GRLC, so it is passed via GMM*/
231 MAK_FUNC_0(em_gmm_grlc_info_req, EM_GRLC_INFO_REQ ), /* 0x18 */
232 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x19 */
233 MAK_FUNC_0(em_gmm_grr_event_req, EM_GRR_EVENT_REQ ), /* 0x1A */
234 MAK_FUNC_0(em_gmm_event_req, EM_GMM_EVENT_REQ ), /* 0x1B */
235 MAK_FUNC_0(em_gmm_grlc_event_req, EM_GRLC_EVENT_REQ ), /* 0x1C */
236 MAK_FUNC_0(em_gmm_throughput_info_req, EM_THROUGHPUT_INFO_REQ ) /* 0x1D */
237 };
238
239 static const T_FUNC em_dl_table[] =
240 {
241 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x00 */
242 /*EM_SC_GPRS_INFO_CNF cannot be sent directly from GRR to ACI, so it is passed via GMM*/
243 MAK_FUNC_0(em_gmm_sc_gprs_info_cnf, EM_SC_GPRS_INFO_CNF ), /* 0x01 */
244 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x02 */
245 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x03 */
246 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x04 */
247 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x05 */
248 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x06 */
249 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x07 */
250 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x08 */
251 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x09 */
252 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0A */
253 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0B */
254 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0C */
255 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0D */
256 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0E */
257 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x0F */
258 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x10 */
259 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x11 */
260 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x12 */
261 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x13 */
262 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x14 */
263 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x15 */
264 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x16 */
265 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x17 */
266 /*EM_GRLC_INFO_CNF cannot be sent directly from ACI to GRLC, so it is passed via GMM*/
267 MAK_FUNC_0(em_gmm_grlc_info_cnf, EM_GRLC_INFO_CNF ), /* 0x18 */
268 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x19 */
269 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x1A */
270 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x1B */
271 MAK_FUNC_N(primitive_not_supported, 0 ), /* 0x1C */
272 MAK_FUNC_0(em_gmm_throughput_info_cnf, EM_THROUGHPUT_INFO_CNF ) /* 0x1D */
273 };
274 #endif /* FF_EM_MODE */
275
276
277 static const T_FUNC gmmrr_table[] =
278 {
279 MAK_FUNC_0(sync_gmmrr_cell_ind, GMMRR_CELL_IND),
280 MAK_FUNC_N(primitive_not_supported, 0 ),
281 MAK_FUNC_0(kern_gmmrr_page_ind, GMMRR_PAGE_IND),
282 MAK_FUNC_0(kern_gmmrr_cs_page_ind, GMMRR_CS_PAGE_IND),
283 MAK_FUNC_0(kern_gmmrr_suspend_cnf, GMMRR_SUSPEND_CNF),
284 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
285 MAK_FUNC_N(primitive_not_supported, 0 ),/* TCS 2.1 */
286 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
287 MAK_FUNC_0(kern_gmmrr_cr_ind, GMMRR_CR_IND),
288 };
289
290
291 static const T_FUNC cgrlc_table[] = /* TCS 2.1 */
292 { /* TCS 2.1 */
293 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
294 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
295 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
296 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
297 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
298 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
299 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
300 MAK_FUNC_N(primitive_not_supported, 0 ), /* TCS 2.1 */
301 MAK_FUNC_0(kern_cgrlc_status_ind, CGRLC_STATUS_IND ), /* TCS 2.1 */
302 MAK_FUNC_0(kern_cgrlc_test_mode_cnf, CGRLC_TEST_MODE_CNF ), /* TCS 2.1 */
303 MAK_FUNC_0(rdy_cgrlc_trigger_ind, CGRLC_TRIGGER_IND ), /* TCS 2.1 */
304 MAK_FUNC_0(rdy_cgrlc_standby_state_ind, CGRLC_STANDBY_STATE_IND ), /* TCS 2.1 */
305 MAK_FUNC_0(rdy_cgrlc_ready_state_ind, CGRLC_READY_STATE_IND ), /* TCS 2.1 */
306 }; /* TCS 2.1 */
307
308
309 #ifndef GMM_TCS4
310 static const T_FUNC gmmsm_table[] =
311 {
312 MAK_FUNC_0(kern_gmmsm_establish_req, GMMSM_ESTABLISH_REQ),
313 MAK_FUNC_S(tx_gmmsm_unitdata_req, GMMSM_UNITDATA_REQ),
314 MAK_FUNC_0(kern_gmmsm_sequence_res, GMMSM_SEQUENCE_RES),
315 };
316 #else
317 static const T_FUNC mmpm_table[] =
318 {
319 #ifdef REL99
320 MAK_FUNC_0(kern_gmmsm_pdp_status_req, MMPM_PDP_CONTEXT_STATUS_REQ),
321 #else
322 MAK_FUNC_0(primitive_not_supported, MMPM_PDP_CONTEXT_STATUS_REQ),
323 #endif
324 MAK_FUNC_N(primitive_not_supported, 0),
325 MAK_FUNC_N(primitive_not_supported, 0),
326 MAK_FUNC_0(kern_gmmsm_sequence_res, MMPM_SEQUENCE_RES),
327 MAK_FUNC_S(tx_gmmsm_unitdata_req, MMPM_UNITDATA_REQ),
328 };
329
330 #endif /* #ifndef GMM_TCS4 */
331
332 static const T_FUNC gmmsms_table[] =
333 {
334 MAK_FUNC_0(kern_gmmsms_reg_state_req, GMMSMS_REG_STATE_REQ)
335 };
336
337 LOCAL const T_FUNC sim_table[] = {
338 MAK_FUNC_0 (primitive_not_supported , SIM_READ_CNF ), /* 0x00 */
339 MAK_FUNC_0 (primitive_not_supported , SIM_UPDATE_CNF ),
340 MAK_FUNC_0 (primitive_not_supported , SIM_READ_RECORD_CNF ),
341 MAK_FUNC_N (primitive_not_supported , 0 ),
342 MAK_FUNC_0 (primitive_not_supported , SIM_UPDATE_RECORD_CNF ),
343 MAK_FUNC_N (primitive_not_supported , 0 ),
344 MAK_FUNC_N (primitive_not_supported , 0 ),
345 MAK_FUNC_N (primitive_not_supported , 0 ),
346 MAK_FUNC_0 (primitive_not_supported , SIM_INCREMENT_CNF ),
347 MAK_FUNC_0 (primitive_not_supported , SIM_VERIFY_PIN_CNF ),
348 MAK_FUNC_0 (primitive_not_supported , SIM_CHANGE_PIN_CNF ),
349 MAK_FUNC_0 (primitive_not_supported , SIM_DISABLE_PIN_CNF ),
350 MAK_FUNC_0 (primitive_not_supported , SIM_ENABLE_PIN_CNF ),
351 MAK_FUNC_0 (primitive_not_supported , SIM_UNBLOCK_CNF ),
352 MAK_FUNC_0 (kern_sim_authentication_cnf , SIM_AUTHENTICATION_CNF ),
353 MAK_FUNC_0 (primitive_not_supported , SIM_MMI_INSERT_IND ),
354 MAK_FUNC_0 (primitive_not_supported , SIM_MM_INSERT_IND ),
355 MAK_FUNC_0 (kern_sim_remove_ind , SIM_REMOVE_IND ),
356 MAK_FUNC_0 (primitive_not_supported , SIM_SYNC_CNF ),
357 MAK_FUNC_0 (primitive_not_supported , SIM_ACTIVATE_CNF ),
358 MAK_FUNC_0 (primitive_not_supported , SIM_SMS_INSERT_IND ), /* 0x14 */
359 MAK_FUNC_0 (primitive_not_supported , SIM_TOOLKIT_IND ), /* 0x15 */
360 MAK_FUNC_0 (primitive_not_supported , SIM_TOOLKIT_CNF ), /* 0x16 */
361 MAK_FUNC_0 (primitive_not_supported , SIM_ACTIVATE_IND ), /* 0x17 */
362 MAK_FUNC_0 (primitive_not_supported , SIM_MM_INFO_IND ), /* 0x18 GMM GlumPs*/
363 MAK_FUNC_0 (primitive_not_supported , SIM_ACCESS_CNF ), /* 0x19 */
364 MAK_FUNC_0 (primitive_not_supported , SIM_FILE_UPDATE_IND ), /* 0x1a */
365 MAK_FUNC_0 (kern_sim_gmm_insert_ind , SIM_GMM_INSERT_IND ), /* 0x1b */
366 };
367
368 static const T_FUNC ll_table[] =
369 {
370 MAK_FUNC_0(primitive_not_supported, LL_RESET_IND),
371 MAK_FUNC_S(primitive_not_supported, LL_ESTABLISH_CNF),
372 MAK_FUNC_S(primitive_not_supported, LL_ESTABLISH_IND),
373 MAK_FUNC_0(primitive_not_supported, LL_RELEASE_CNF),
374 MAK_FUNC_0(primitive_not_supported, LL_RELEASE_IND),
375 MAK_FUNC_S(primitive_not_supported, LL_XID_CNF),
376 MAK_FUNC_S(primitive_not_supported, LL_XID_IND),
377 MAK_FUNC_0(primitive_not_supported, LL_READY_IND),
378 MAK_FUNC_0(primitive_not_supported, LL_UNITREADY_IND),
379 MAK_FUNC_0(primitive_not_supported, LL_DATA_CNF),
380 MAK_FUNC_S(primitive_not_supported, LL_DATA_IND),
381 MAK_FUNC_S(rx_ll_unitdata_ind, LL_UNITDATA_IND)
382 };
383
384 static const T_FUNC llgmm_table[] =
385 {
386 MAK_FUNC_0(kern_llgmm_status_ind, LLGMM_STATUS_IND),
387 MAK_FUNC_0(kern_llgmm_tlli_ind, LLGMM_TLLI_IND)
388 };
389
390 static const T_FUNC mmgmm_table[] =
391 {
392 MAK_FUNC_0(sync_mmgmm_reg_cnf, MMGMM_REG_CNF),
393 MAK_FUNC_0(sync_mmgmm_reg_rej, MMGMM_REG_REJ),
394 MAK_FUNC_0(sync_mmgmm_nreg_ind, MMGMM_NREG_IND),
395 MAK_FUNC_0(kern_mmgmm_nreg_cnf, MMGMM_NREG_CNF),
396 MAK_FUNC_0(kern_mmgmm_plmn_ind, MMGMM_PLMN_IND),
397 MAK_FUNC_0(kern_mmgmm_auth_rej_ind, MMGMM_AUTH_REJ_IND),
398 MAK_FUNC_0(kern_mmgmm_cm_establish_ind, MMGMM_CM_ESTABLISH_IND),
399 MAK_FUNC_0(kern_mmgmm_cm_release_ind, MMGMM_CM_RELEASE_IND),
400 MAK_FUNC_0(sync_mmgmm_activate_ind, MMGMM_ACTIVATE_IND),
401 MAK_FUNC_0(kern_mmgmm_t3212_val_ind, MMGMM_T3212_VAL_IND),
402 MAK_FUNC_0(kern_mmgmm_info_ind, MMGMM_INFO_IND),
403 MAK_FUNC_0(kern_mmgmm_cm_emergency_ind, MMGMM_CM_EMERGENCY_IND),
404 MAK_FUNC_0(kern_mmgmm_lup_accept_ind, MMGMM_LUP_ACCEPT_IND),
405 MAK_FUNC_0(kern_mmgmm_lup_needed_ind, MMGMM_LUP_NEEDED_IND),
406 MAK_FUNC_0(kern_mmgmm_ciphering_ind, MMGMM_CIPHERING_IND),
407 MAK_FUNC_0(kern_mmgmm_tmsi_ind, MMGMM_TMSI_IND),
408 MAK_FUNC_0(kern_mmgmm_ahplmn_ind, MMGMM_AHPLMN_IND)
409 };
410
411
412 /*==== PRIVATE FUNCTIONS ====================================================*/
413
414 /*
415 +------------------------------------------------------------------------------
416 | Function : primitive_not_supported
417 +------------------------------------------------------------------------------
418 | Description : This function handles unsupported primitives.
419 |
420 | Parameters : -
421 |
422 | Return : -
423 |
424 +------------------------------------------------------------------------------
425 */
426 LOCAL void primitive_not_supported (void *data)
427 {
428 TRACE_FUNCTION ("primitive_not_supported");
429
430 PFREE (data);
431 }
432
433
434 /*==== PUBLIC FUNCTIONS =====================================================*/
435
436 /*
437 +------------------------------------------------------------------------------
438 | Function : pei_primitive
439 +------------------------------------------------------------------------------
440 | Description : This function is called by the frame when a primitive is
441 | received and needs to be processed.
442 |
443 | |
444 | GMMREG
445 | | | | |
446 | GMMSM | GMMSM GMMAA UPLINK
447 | | | | |
448 | +---v-----v-----v-----v----+
449 | | |
450 | MMGMM ----> GMM |
451 | | |
452 | +---^--------^--------^----+
453 | | | |
454 | | | LLGMM DOWNLINK
455 | | GMMRR |
456 | | |
457 | SIM
458 | |
459 |
460 |
461 | Parameters : prim - Pointer to the received primitive
462 |
463 | Return : PEI_OK - function succeeded
464 | PEI_ERROR - function failed
465 |
466 +------------------------------------------------------------------------------
467 */
468 LOCAL SHORT pei_primitive (void * primptr)
469 {
470 TRACE_FUNCTION ("pei_primitive");
471 #ifdef TRACE_FUNC
472 #ifdef IDENTATION
473 gmm_data->deep=0;
474 #endif
475 #endif
476
477 if (primptr NEQ NULL)
478 {
479 T_PRIM *prim = (T_PRIM *)primptr;
480 ULONG opc = prim->custom.opc;
481 USHORT n;
482 const T_FUNC *table;
483
484 /*
485 * This must be called for Partition Pool supervision. Will be replaced
486 * by another macro some time.
487 */
488 VSI_PPM_REC (&prim->custom, __FILE__, __LINE__);
489
490 GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_STATE);
491 PTRACE_IN (opc);
492
493 switch (SAP_NR(opc))
494 {
495 case GMMREG_UL:
496 table = gmmreg_table;
497 n = TAB_SIZE (gmmreg_table);
498 break;
499 case GMMRR_DL:
500 table = gmmrr_table;
501 n = TAB_SIZE (gmmrr_table);
502 break;
503 case SAP_NR(CGRLC_DL): /* TCS 2.1 */
504 table = cgrlc_table; /* TCS 2.1 */
505 n = TAB_SIZE (cgrlc_table); /* TCS 2.1 */
506 break; /* TCS 2.1 */
507 #ifndef GMM_TCS4
508 case GMMSM_UL:
509 table = gmmsm_table;
510 n = TAB_SIZE (gmmsm_table);
511 break;
512 #else
513 case SAP_NR(MMPM_UL):
514 table = mmpm_table;
515 n = TAB_SIZE (mmpm_table);
516 break;
517 #endif
518 case GMMSMS_UL:
519 table = gmmsms_table;
520 n = TAB_SIZE (gmmsms_table);
521 break;
522 case SAP_NR(SIM_UL):/*lint !e778 (Info -- Constant expression evaluates to 0 in operation '&') */
523 table = sim_table;
524 n = TAB_SIZE (sim_table);
525 break;
526 case LL_DL:
527 table = ll_table;
528 n = TAB_SIZE (ll_table);
529 break;
530 case LLGMM_DL:
531 table = llgmm_table;
532 n = TAB_SIZE (llgmm_table);
533 break;
534 case MMGMM_DL:
535 table = mmgmm_table;
536 n = TAB_SIZE (mmgmm_table);
537 break;
538 #ifdef FF_EM_MODE
539 case EM_Ul:
540 table = em_ul_table;
541 n = TAB_SIZE (em_ul_table);
542 break;
543 case EM_Dl:
544 table = em_dl_table;
545 n = TAB_SIZE (em_dl_table);
546 break;
547 #endif /* FF_EM_MODE */
548 default:
549 TRACE_ERROR("pei_primitive. Unknown SAP");
550 table = NULL;
551 n = 0;
552 break;
553 }
554
555 if (table != NULL)
556 {
557 if (PRIM_NR(opc) < n)
558 {
559 table += PRIM_NR(opc);
560 #ifdef PALLOC_TRANSITION
561 P_SDU(prim) = table->soff ? (T_sdu*) (((char*)&prim->data) + table->soff) : 0;
562 #ifndef NO_COPY_ROUTING
563 P_LEN(prim) = table->size + sizeof (T_PRIM_HEADER);
564 #endif /* NO_COPY_ROUTING */
565 #endif /* PALLOC_TRANSITION */
566
567 /*******************************************************
568 * SAVE prim
569 *******************************************************/
570
571 if( gmm_pei_handle_save( prim, &save_queue, save_tab, table->func )
572 == PEI_SIGNAL_NOT_SAVED )
573 {
574 UBYTE old_kern_state = gmm_data->kern.state;
575 /*******************************************************
576 * SAVE prim
577 *******************************************************/
578
579 JUMP (table->func) (P2D(prim));
580
581 /*******************************************************
582 * SAVE prim
583 *******************************************************/
584 if( gmm_data->kern.state != old_kern_state )
585 {
586 gmm_pei_handle_queue(&save_queue, save_tab);
587 }
588 }
589 else
590 {
591 TRACE_2_INFO ("S:%2d SAVE of Primitive 0x%x", gmm_data->kern.state, opc );
592 }
593
594
595
596 /*******************************************************
597 * End SAVE prim
598 *******************************************************/
599
600 }
601 else
602 {
603 primitive_not_supported (P2D(prim));
604 }
605 return PEI_OK;
606 }
607
608 /*
609 * primitive is not a GSM primitive - forward it to the environment
610 */
611 if (opc & SYS_MASK)
612 vsi_c_primitive (VSI_CALLER prim);
613 else
614 {
615 PFREE (P2D(prim));
616 return PEI_ERROR;
617 }
618 }
619 return PEI_OK;
620 }
621
622
623 /*
624 +------------------------------------------------------------------------------
625 | Function : pei_init
626 +------------------------------------------------------------------------------
627 | Description : This function is called by the frame. It is used to initialise
628 | the entitiy.
629 |
630 | Parameters : handle - task handle
631 |
632 | Return : PEI_OK - entity initialised
633 | PEI_ERROR - entity not (yet) initialised
634 |
635 +------------------------------------------------------------------------------
636 */
637 LOCAL SHORT pei_init (T_HANDLE handle)
638 {
639 TRACE_FUNCTION ("pei_init");
640
641 /*
642 * Initialize task handle
643 */
644 GMM_handle = handle;
645
646 /*
647 * Open communication channels
648 */
649 if (hCommSMS < VSI_OK)
650 {
651 if ((hCommSMS = vsi_c_open (VSI_CALLER SMS_NAME)) < VSI_OK)
652 return PEI_ERROR;
653 }
654 if (hCommSM < VSI_OK)
655 {
656 if ((hCommSM = vsi_c_open (VSI_CALLER SM_NAME)) < VSI_OK)
657 return PEI_ERROR;
658 }
659 if (hCommGRLC < VSI_OK) /* TCS 2.1 */
660 { /* TCS 2.1 */
661 if ((hCommGRLC = vsi_c_open (VSI_CALLER GRLC_NAME)) < VSI_OK) /* TCS 2.1 */
662 return PEI_ERROR; /* TCS 2.1 */
663 } /* TCS 2.1 */
664
665 if (hCommGRR < VSI_OK)
666 {
667 if ((hCommGRR = vsi_c_open (VSI_CALLER GRR_NAME)) < VSI_OK)
668 return PEI_ERROR;
669 }
670 if (hCommLLC < VSI_OK)
671 {
672 if ((hCommLLC = vsi_c_open (VSI_CALLER LLC_NAME)) < VSI_OK)
673 return PEI_ERROR;
674 }
675 if (hCommSIM < VSI_OK)
676 {
677 if ((hCommSIM = vsi_c_open (VSI_CALLER SIM_NAME)) < VSI_OK)
678 return PEI_ERROR;
679 }
680 if (hCommMM < VSI_OK)
681 {
682 if ((hCommMM = vsi_c_open (VSI_CALLER MM_NAME)) < VSI_OK)
683 return PEI_ERROR;
684 }
685 if (hCommMMI < VSI_OK)
686 {
687 if ((hCommMMI = vsi_c_open (VSI_CALLER ACI_NAME)) < VSI_OK) /* TCS 2.1 */
688 return PEI_ERROR;
689 }
690 if (hCommGMM < VSI_OK)
691 {
692 if ((hCommGMM = vsi_c_open (VSI_CALLER GMM_NAME)) < VSI_OK)
693 return PEI_ERROR;
694 }
695 #ifdef GMM_TCS4
696 if (hCommUPM < VSI_OK)
697 {
698 if ((hCommUPM = vsi_c_open (VSI_CALLER UPM_NAME)) < VSI_OK)
699 return PEI_ERROR;
700 }
701 #endif
702
703
704 /*
705 * Initialize global pointer llc_data. This is required to access all
706 * entity data.
707 */
708 gmm_data = &gmm_data_base;
709
710 /*
711 * Initialite ccd
712 */
713 ccd_init ();
714
715 #ifdef FF_EM_MODE
716 em_init_gmm_event_trace();
717 #endif /* FF_EM_MODE */
718
719
720 /*
721 * Initialize entity data (call init function of every service)
722 */
723
724 kern_init();
725 rxgmm_init();
726 txgmm_init();
727 rdy_init();
728 sync_gmm_init();
729
730 GMM_TRACE_GMM_DATA(GMM_DEBUG_PRINT_MASK_FULL);
731
732 return (PEI_OK);
733 }
734
735 /*
736 +------------------------------------------------------------------------------
737 | Function : pei_timeout
738 +------------------------------------------------------------------------------
739 | Description : This function is called by the frame when a timer has expired.
740 |
741 | Parameters : index - timer index
742 |
743 | Return : PEI_OK - timeout processed
744 | PEI_ERROR - timeout not processed
745 |
746 +------------------------------------------------------------------------------
747 */
748 LOCAL SHORT pei_timeout (USHORT index)
749 {
750 UBYTE old_kern_state;
751 TRACE_FUNCTION ("pei_timeout");
752
753 old_kern_state = gmm_data->kern.state;
754 /*
755 * Process timeout
756 */
757 switch (index)
758 {
759 case kern_T3302:
760 /*
761 * T3302 expired.
762 */
763 kern_t3302 ();
764 break;
765 case kern_T3310:
766 /*
767 * T3310 expired.
768 */
769 kern_t3310 ();
770 break;
771 case kern_T3311:
772 /*
773 * T3311 expired.
774 */
775 kern_t3311 ();
776 break;
777 case kern_T3321:
778 /*
779 * T3321 expired.
780 */
781 kern_t3321 ();
782 break;
783 case rdy_T3312:
784 /*
785 * T3312 expired.
786 */
787 kern_t3312 ();
788 break;
789 case kern_TPOWER_OFF:
790 kern_tpower_off();
791 break;
792 case kern_TLOCAL_DETACH:
793 kern_tlocal_detach();
794 break;
795 case sync_TSYNC:
796 sync_tsync();
797 break;
798 default:
799 TRACE_ERROR("Unknown Timeout");
800 return PEI_ERROR;
801 }
802
803 if( gmm_data->kern.state != old_kern_state )
804 {
805 gmm_pei_handle_queue( &save_queue, save_tab);
806 }
807 return PEI_OK;
808 }
809
810 /*
811 +------------------------------------------------------------------------------
812 | Function : pei_signal
813 +------------------------------------------------------------------------------
814 | Description : This function is called by the frame when a signal has been
815 | received.
816 |
817 | Parameters : opc - signal operation code
818 | *data - pointer to primitive
819 |
820 | Return : PEI_OK - signal processed
821 | PEI_ERROR - signal not processed
822 |
823 +------------------------------------------------------------------------------
824 */
825 LOCAL SHORT pei_signal (ULONG opc, void *data)
826 {
827 TRACE_FUNCTION ("pei_signal");
828
829 /*
830 * Process signal
831 */
832 switch (opc)
833 {
834 default:
835 TRACE_ERROR("Unknown Signal OPC");
836 break;
837 }/*lint !e764 (Info -- switch statement does not have a case) */
838
839 return PEI_OK;
840 }
841
842 /*
843 +------------------------------------------------------------------------------
844 | Function : pei_exit
845 +------------------------------------------------------------------------------
846 | Description : This function is called by the frame when the entity is
847 | terminated. All open resources are freed.
848 |
849 | Parameters : -
850 |
851 | Return : PEI_OK - exit sucessful
852 | PEI_ERROR - exit not sueccessful
853 |
854 +------------------------------------------------------------------------------
855 */
856 LOCAL SHORT pei_exit (void)
857 {
858 TRACE_FUNCTION ("pei_exit");
859
860 /*
861 * Close communication channels
862 */
863 vsi_c_close (VSI_CALLER hCommSMS);
864 hCommSMS = VSI_ERROR;
865
866 vsi_c_close (VSI_CALLER hCommSM);
867 hCommSM = VSI_ERROR;
868
869 vsi_c_close (VSI_CALLER hCommGRLC); /* TCS 2.1 */
870 hCommGRLC = VSI_ERROR; /* TCS 2.1 */
871
872 vsi_c_close (VSI_CALLER hCommGRR);
873 hCommGRR = VSI_ERROR;
874
875 vsi_c_close (VSI_CALLER hCommLLC);
876 hCommLLC = VSI_ERROR;
877
878 vsi_c_close (VSI_CALLER hCommSIM);
879 hCommSIM = VSI_ERROR;
880
881 vsi_c_close (VSI_CALLER hCommMM);
882 hCommMM = VSI_ERROR;
883
884 vsi_c_close (VSI_CALLER hCommMMI);
885 hCommMMI = VSI_ERROR;
886
887 vsi_c_close (VSI_CALLER hCommGMM);
888 hCommGMM = VSI_ERROR;
889
890 /*
891 * delete queues
892 */
893 gmm_pei_delete_queue(&save_queue);
894
895 /*
896 * close ccd
897 */
898 ccd_exit ();
899
900 return PEI_OK;
901 }
902
903 /*
904 +------------------------------------------------------------------------------
905 | Function : pei_run
906 +------------------------------------------------------------------------------
907 | Description : This function is called by the frame when entering the main
908 | loop. This fucntion is only required in the active variant.
909 |
910 | This function is not used.
911 |
912 | Parameters : handle - Communication handle
913 |
914 | Return : PEI_OK - sucessful
915 | PEI_ERROR - not successful
916 |
917 +------------------------------------------------------------------------------
918 */
919 LOCAL SHORT pei_run (T_HANDLE TaskHandle, T_HANDLE ComHandle )
920 {
921 return PEI_OK;
922 }
923
924
925 /*
926 +------------------------------------------------------------------------------
927 | Function : gmm_tok_key
928 +------------------------------------------------------------------------------
929 | Description : This function is used by pei_config in windows test
930 | environment for string tokenizing for CHECK STATE command, e.g.
931 | COMMAND("GMM CONFIG CHECK_STATE=<REG_NORMAL_SERVICE>");
932 |
933 |
934 | Parameters :
935 |
936 | Return :
937 |
938 |
939 +------------------------------------------------------------------------------
940 */
941 #ifndef _TARGET_
942 typedef struct KW_STATE_DATA
943 {
944 char keyword[60];
945 SHORT code;
946 } KW_STATE_DATA;
947
948 LOCAL SHORT gmm_tok_key (KW_STATE_DATA * keytab, char * keyword)
949 {
950 /*
951 * Empty string terminates
952 */
953 while (keytab->keyword[0])
954 {
955 if (strcmp (keytab->keyword, keyword ) == 0)
956 return (keytab->code);
957 keytab++;
958 }
959
960 return (TOK_NOT_FOUND);
961 }
962 #endif
963
964 /*
965 +------------------------------------------------------------------------------
966 | Function : pei_config
967 +------------------------------------------------------------------------------
968 | Description : This function is called by the frame when a primitive is
969 | received indicating dynamic configuration.
970 |
971 | This function is not used in this entity.
972 |
973 | Parameters : handle - Communication handle
974 |
975 | Return : PEI_OK - sucessful
976 | PEI_ERROR - not successful
977 |
978 +------------------------------------------------------------------------------
979 */
980 LOCAL SHORT pei_config (char *inString)
981 {
982 TRACE_FUNCTION ("pei_config");
983 TRACE_FUNCTION (inString);
984
985 #ifndef NCONFIG
986 /*
987 * Parse next keyword and number of variables
988 */
989 if(!strcmp(inString,"PERIODIC_LAU"))
990 {
991 PALLOC (mmgmm_lup_needed_ind, MMGMM_LUP_NEEDED_IND);
992 mmgmm_lup_needed_ind->reason = MMGMM_T3212; /* TCS 2.1 */
993 TRACE_EVENT( "Info: Periodic LAU requested by MM");
994 PSEND (hCommGMM, mmgmm_lup_needed_ind);
995 }
996 else if(!strcmp(inString,"PERIODIC_RAU"))
997 {
998 kern_t3312();
999 }
1000 else if(!strcmp(inString,"REATTACH"))
1001 {
1002 PALLOC (gmmrr_page_ind, GMMRR_PAGE_IND);
1003 gmmrr_page_ind->page_id=GMMRR_IMSI;
1004 PSEND (hCommGMM, gmmrr_page_ind);
1005 }
1006 else if(!strcmp(inString,"CELL"))
1007 {
1008 PALLOC (gmmrr_cell_ind, GMMRR_CELL_IND);
1009 gmmrr_cell_ind->cell_info.service_state=GMMRR_SERVICE_FULL;
1010 gmmrr_cell_ind->cell_info.cell_env.rai.lac=0x2506;
1011 gmmrr_cell_ind->cell_info.cell_env.rai.rac=0x71;
1012 gmmrr_cell_ind->cell_info.net_mode=gmm_data->config.nmo;
1013 PSEND (hCommGMM, gmmrr_cell_ind);
1014 }
1015 else if(!strcmp(inString,"NMO_I"))
1016 {
1017 gmm_data->config.nmo = GMMRR_NET_MODE_I;
1018 }
1019 else if(!strcmp(inString,"NMO_II"))
1020 {
1021 gmm_data->config.nmo = GMMRR_NET_MODE_II;
1022 }
1023 else if(!strcmp(inString,"NMO_III"))
1024 {
1025 gmm_data->config.nmo = GMMRR_NET_MODE_III;
1026 }
1027 else if(!strcmp(inString,"GMM_INFO"))
1028 {
1029 PALLOC (gmmreg_info_ind, GMMREG_INFO_IND);
1030 PSEND (hCommMMI, gmmreg_info_ind);
1031 }
1032
1033 else if(!strcmp(inString,"RESET_SIM"))
1034 {
1035 gmm_data->sim_gprs_invalid = TRUE;
1036 kern_sim_del_locigprs ();
1037 kern_sim_gmm_update();
1038 kern_mm_auth_rej();
1039 {
1040 PALLOC (sim_update_req, SIM_UPDATE_REQ);
1041
1042 sim_update_req->source = SRC_GMM;
1043 /* req_id is not filled since response is not handled */
1044
1045 sim_update_req->v_path_info = FALSE;
1046
1047 sim_update_req->datafield = SIM_FPLMN;
1048 sim_update_req->length = 12;
1049 memset (sim_update_req->trans_data,0xff,12);
1050 sim_update_req->offset = 0;
1051
1052 PSEND (hCommSIM, sim_update_req);
1053 }
1054 {
1055 PALLOC (sim_update_req, SIM_UPDATE_REQ);
1056
1057 sim_update_req->source = SRC_GMM;
1058
1059 /* req_id is not filled since response is not handled */
1060 sim_update_req->v_path_info = FALSE;
1061
1062 sim_update_req->datafield = SIM_LOCI;
1063 sim_update_req->length = 11;
1064 memset (sim_update_req->trans_data,0xff,8);
1065 sim_update_req->trans_data[8]=0xfe;
1066 sim_update_req->trans_data[9]=0x0;
1067 sim_update_req->trans_data[10]=GU2_NOT_UPDATED;
1068 sim_update_req->offset = 0;
1069
1070 PSEND (hCommSIM, sim_update_req);
1071 }
1072 }
1073 else if(!strcmp(inString,"ANITE"))
1074 {
1075 gmm_data->anite = TRUE;
1076 }
1077 else if(!strcmp(inString,"CIPHER_OFF"))
1078 {
1079 gmm_data->config.cipher_on = 0x00;
1080 TRACE_EVENT ("ciphering switched OFF");
1081 }
1082 else if(!strcmp(inString,"CIPHER_ON"))
1083 {
1084 gmm_data->config.cipher_on |= 0x01;
1085 }
1086 else if(!strcmp(inString,"PREUSE_OFF"))
1087 {
1088 gmm_data->config.preuse_off = TRUE;
1089 }
1090
1091 #ifdef REL99
1092 else if(!strcmp(inString,"CL_SGSN_REL_98_OR_OLDER")) /* TCS 4.0 */
1093 { /* TCS 4.0 */
1094 /*gmm_data->config.sgsnr_flag = R_98NW; */
1095 cl_nwrl_set_sgsn_release(PS_SGSN_98_OLDER); /*CL function*/ /* TCS 4.0 */
1096 } /* TCS 4.0 */
1097 else if(!strcmp(inString,"CL_SGSN_REL_99_ONWARDS")) /* TCS 4.0 */
1098 { /* TCS 4.0 */
1099 /* gmm_data->config.sgsnr_flag = R_99NW; */
1100 cl_nwrl_set_sgsn_release(PS_SGSN_99_ONWARDS); /*CL function*/ /* TCS 4.0 */
1101 } /* TCS 4.0 */
1102 else if (!strcmp(inString,"CELL_NOTIFY_ON")) /* TCS 4.0 */
1103 { /* TCS 4.0 */
1104 gmm_data->config.cell_notification = FIRST_CELL_NOTIFY; /* TCS 4.0 */
1105 } /* TCS 4.0 */
1106 else if (!strcmp(inString, "CELL_NOTIFY_OFF")) /* TCS 4.0 */
1107 { /* TCS 4.0 */
1108 gmm_data->config.cell_notification = NO_CELL_NOTIFY; /* TCS 4.0 */
1109 } /* TCS 4.0 */
1110 #endif
1111
1112 #ifdef _SIMULATION_
1113 else if(!strcmp(inString, "NEXT_TIMEOUT"))
1114 {
1115 T_TIME old_value = 0;
1116 T_TIME new_value = 0;
1117 USHORT timer;
1118 USHORT timeout = TIMER_MAX;
1119
1120 /* Find next timer to timeout */
1121
1122 for(timer = 0; timer < TIMER_MAX; timer++)
1123 {
1124 if ( VSI_OK == vsi_t_status ( GMM_handle ,timer, &new_value ))
1125 {
1126 if (new_value >0 )
1127 {
1128 if((old_value==0)||
1129 (new_value < old_value))
1130 {
1131 old_value = new_value;
1132 timeout = timer;
1133 }
1134 }
1135 }
1136 }
1137
1138
1139 /* Force timeout */
1140 if(TIMER_MAX != timeout )
1141 {
1142 TRACE_1_INFO("gmm_pei_config - forcing timeout:%d", timeout);
1143
1144 vsi_t_stop ( GMM_handle, timeout);
1145
1146 for(timer = 0; timer < TIMER_MAX ; timer++)
1147 {
1148 if ( VSI_OK == vsi_t_status ( GMM_handle ,timer, &new_value ))
1149 {
1150 if (timer!=timeout )
1151 {
1152 if (new_value>0 && new_value-old_value >0 )
1153 {
1154 vsi_t_start ( GMM_handle , timer, new_value-old_value );
1155 }
1156 }
1157 }
1158 }
1159
1160 pei_timeout(timeout);
1161 }
1162 }
1163 #endif
1164
1165 #define GMM_CONFIG_DRX 1
1166 #define GMM_CONFIG_GEA 2
1167
1168 #ifndef _TARGET_
1169 #define GMM_CONFIG_CHECK_STATE 3
1170 #endif
1171
1172 #define GMM_DRX "DRX"
1173 #define GMM_GEA "GEA"
1174
1175 #ifndef _TARGET_
1176 #define GMM_CHECK_STATE "CHECK_STATE"
1177
1178 #define GMM_NULL_NO_IMSI "NULL_NO_IMSI"
1179 #define GMM_NULL_IMSI "NULL_IMSI"
1180 #define GMM_DEREG_INITIATED "DEREG_INITIATED"
1181 #define GMM_DEREG_ATTEMPTING_TO_ATTACH "DEREG_ATTEMPTING_TO_ATTACH"
1182 #define GMM_DEREG_NO_CELL_AVAILABLE "DEREG_NO_CELL_AVAILABLE"
1183 #define GMM_DEREG_LIMITED_SERVICE "DEREG_LIMITED_SERVICE"
1184 #define GMM_DEREG_NO_IMSI "DEREG_NO_IMSI"
1185 #define GMM_DEREG_PLMN_SEARCH "DEREG_PLMN_SEARCH"
1186 #define GMM_DEREG_SUSPENDED "DEREG_SUSPENDED"
1187
1188 #define GMM_REG_INITIATED "REG_INITIATED"
1189
1190 #define GMM_REG_NO_CELL_AVAILABLE "REG_NO_CELL_AVAILABLE"
1191 #define GMM_REG_LIMITED_SERVICE "REG_LIMITED_SERVICE"
1192 #define GMM_REG_ATTEMPTING_TO_UPDATE_MM "REG_ATTEMPTING_TO_UPDATE_MM "
1193 #define GMM_REG_ATTEMPTING_TO_UPDATE "REG_ATTEMPTING_TO_UPDATE"
1194 #define GMM_REG_RESUMING "REG_RESUMING"
1195 #define GMM_REG_SUSPENDED "REG_SUSPENDED"
1196 #define GMM_REG_NORMAL_SERVICE "REG_NORMAL_SERVICE"
1197
1198 #define GMM_RAU_INITIATED "RAU_INITIATED"
1199
1200 #define GMM_RAU_WAIT_FOR_NPDU_LIST "RAU_WAIT_FOR_NPDU_LIST"
1201
1202 #define GMM_REG_IMSI_DETACH_INITIATED "REG_IMSI_DETACH_INITIATED"
1203
1204 #define GMM_DEREG_SUSPENDING "DEREG_SUSPENDING"
1205 #define GMM_DEREG_RESUMING "DEREG_RESUMING"
1206
1207 #define GMM_REG_SUSPENDING "REG_SUSPENDING"
1208 #define GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ "NULL_NO_IMSI_LIMITED_SERVICE_REQ"
1209 #define GMM_NULL_IMSI_LIMITED_SERVICE_REQ "NULL_IMSI_LIMITED_SERVICE_REQ"
1210 #define GMM_REG_TEST_MODE "REG_TEST_MODE"
1211 #define GMM_NULL_PLMN_SEARCH "NULL_PLMN_SEARCH"
1212 #define GMM_REG_TEST_MODE_NO_IMSI "REG_TEST_MODE_NO_IMSI "
1213
1214 #endif
1215
1216 {
1217 LOCAL KW_DATA kwtab[] =
1218 {
1219 GMM_DRX, GMM_CONFIG_DRX,
1220 GMM_GEA, GMM_CONFIG_GEA,
1221 #ifndef _TARGET_
1222 GMM_CHECK_STATE, GMM_CONFIG_CHECK_STATE,
1223 #endif
1224 "", 0
1225 };
1226 #ifndef _TARGET_
1227 LOCAL KW_STATE_DATA kw_state_tab[] =
1228 {
1229 GMM_NULL_NO_IMSI ,KERN_GMM_NULL_NO_IMSI,
1230 GMM_NULL_IMSI ,KERN_GMM_NULL_IMSI,
1231 GMM_DEREG_INITIATED ,KERN_GMM_DEREG_INITIATED,
1232 GMM_DEREG_ATTEMPTING_TO_ATTACH ,KERN_GMM_DEREG_ATTEMPTING_TO_ATTACH,
1233 GMM_DEREG_NO_CELL_AVAILABLE ,KERN_GMM_DEREG_NO_CELL_AVAILABLE,
1234 GMM_DEREG_LIMITED_SERVICE ,KERN_GMM_DEREG_LIMITED_SERVICE,
1235 GMM_DEREG_NO_IMSI ,KERN_GMM_DEREG_NO_IMSI,
1236 GMM_DEREG_PLMN_SEARCH ,KERN_GMM_DEREG_PLMN_SEARCH,
1237 GMM_DEREG_SUSPENDED ,KERN_GMM_DEREG_SUSPENDED,
1238
1239 GMM_REG_INITIATED ,KERN_GMM_REG_INITIATED,
1240
1241 GMM_REG_NO_CELL_AVAILABLE ,KERN_GMM_REG_NO_CELL_AVAILABLE,
1242 GMM_REG_LIMITED_SERVICE ,KERN_GMM_REG_LIMITED_SERVICE,
1243 GMM_REG_ATTEMPTING_TO_UPDATE_MM ,KERN_GMM_REG_ATTEMPTING_TO_UPDATE_MM ,
1244 GMM_REG_ATTEMPTING_TO_UPDATE ,KERN_GMM_REG_ATTEMPTING_TO_UPDATE,
1245 GMM_REG_RESUMING ,KERN_GMM_REG_RESUMING,
1246 GMM_REG_SUSPENDED ,KERN_GMM_REG_SUSPENDED,
1247 GMM_REG_NORMAL_SERVICE ,KERN_GMM_REG_NORMAL_SERVICE,
1248
1249 GMM_RAU_INITIATED ,KERN_GMM_RAU_INITIATED,
1250
1251 GMM_RAU_WAIT_FOR_NPDU_LIST ,KERN_GMM_RAU_WAIT_FOR_NPDU_LIST,
1252
1253 GMM_REG_IMSI_DETACH_INITIATED ,KERN_GMM_REG_IMSI_DETACH_INITIATED,
1254
1255 GMM_DEREG_SUSPENDING ,KERN_GMM_DEREG_SUSPENDING,
1256 GMM_DEREG_RESUMING ,KERN_GMM_DEREG_RESUMING,
1257 GMM_REG_SUSPENDING ,KERN_GMM_REG_SUSPENDING,
1258
1259 GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ ,KERN_GMM_NULL_NO_IMSI_LIMITED_SERVICE_REQ,
1260 GMM_NULL_IMSI_LIMITED_SERVICE_REQ ,KERN_GMM_NULL_IMSI_LIMITED_SERVICE_REQ,
1261 GMM_REG_TEST_MODE ,KERN_GMM_REG_TEST_MODE,
1262 GMM_NULL_PLMN_SEARCH ,KERN_GMM_NULL_PLMN_SEARCH,
1263 GMM_REG_TEST_MODE_NO_IMSI ,KERN_GMM_REG_TEST_MODE_NO_IMSI ,
1264 "", 0
1265 };
1266
1267 #endif
1268 SHORT valno;
1269 char *keyw;
1270 char *val[10];
1271
1272 tok_init (inString);
1273
1274 while((valno = tok_next(&keyw,val)) NEQ TOK_EOCS)
1275 {
1276 switch ((tok_key((KW_DATA *)kwtab, keyw)))
1277 {
1278 case GMM_CONFIG_DRX:
1279 if (3==valno)
1280 {
1281 TRACE_EVENT ("use of DRX <split_pg_cycle_code,split_on_ccch,non_drx_timer>");
1282 gmm_data->drx_parameter.split_pg_cycle_code = atoi (val[0]);
1283 gmm_data->drx_parameter.split_on_ccch = atoi (val[1]);
1284 gmm_data->drx_parameter.non_drx_timer = atoi (val[2]);
1285 }
1286 else
1287 {
1288 TRACE_ERROR("[PEI_CONFIG]: use CONFIG DRX <1,2,3>");
1289 }
1290 break;
1291 case GMM_CONFIG_GEA:
1292 if (1==valno)
1293 {
1294 TRACE_EVENT ("GEA=<bit_field of wanted GEA in dec>");
1295
1296 gmm_data->config.cipher_on |= atoi (val[0]);
1297 TRACE_1_INFO("GEA2=%d", (gmm_data->config.cipher_on & 0x02)>0);
1298 TRACE_1_INFO("GEA3=%d", (gmm_data->config.cipher_on & 0x04)>0);
1299 TRACE_1_INFO("GEA4=%d", (gmm_data->config.cipher_on & 0x08)>0);
1300 TRACE_1_INFO("GEA5=%d", (gmm_data->config.cipher_on & 0x10)>0);
1301 TRACE_1_INFO("GEA6=%d", (gmm_data->config.cipher_on & 0x20)>0);
1302 TRACE_1_INFO("GEA7=%d", (gmm_data->config.cipher_on & 0x40)>0);
1303 }
1304 else
1305 {
1306 TRACE_ERROR("[PEI_CONFIG]: use CONFIG GEA=<0-255>//255 means all GEA wanted");
1307 }
1308 break;
1309 #ifndef _TARGET_
1310 case GMM_CONFIG_CHECK_STATE:
1311 if(1==valno)
1312 {
1313 if (gmm_tok_key ((KW_STATE_DATA *)kw_state_tab, val[0])!=GET_STATE(KERN))
1314 {
1315 PALLOC ( cgrlc_status_ind, CGRLC_STATUS_IND ); /* TCS 2.1 */
1316 PSEND ( hCommGMM, cgrlc_status_ind ); /* TCS 2.1 */
1317 TRACE_1_OUT_PARA( "neq %s", val[0]);
1318 TRACE_ERROR("state wrong");
1319 }
1320 else
1321 {
1322 TRACE_1_INFO("state %s ok",val[0]);
1323 }
1324 }
1325 else
1326 {
1327 TRACE_ERROR("[PEI_CONFIG]: USE CONFIG CHECK_STATE <state>");
1328 }
1329 break;
1330 #endif
1331 default:
1332 break;
1333 }
1334 }
1335 }
1336 #endif
1337 return PEI_OK;
1338 }
1339
1340 /*
1341 +------------------------------------------------------------------------------
1342 | Function : pei_monitor
1343 +------------------------------------------------------------------------------
1344 | Description : This function is called by the frame in case sudden entity
1345 | specific data is requested (e.g. entity Version).
1346 |
1347 | Parameters : out_monitor - return the address of the data to be
1348 | monitoredCommunication handle
1349 |
1350 | Return : PEI_OK - sucessful (address in out_monitor is valid)
1351 | PEI_ERROR - not successful
1352 |
1353 +------------------------------------------------------------------------------
1354 */
1355 LOCAL SHORT pei_monitor (void ** out_monitor)
1356 {
1357 TRACE_FUNCTION ("pei_monitor");
1358
1359 /*
1360 * Version = "0.S" (S = Step).
1361 */
1362 gmm_mon.version = "GMM 0.1";
1363 *out_monitor = &gmm_mon;
1364
1365 return PEI_OK;
1366 }
1367
1368 /*
1369 +------------------------------------------------------------------------------
1370 | Function : pei_create
1371 +------------------------------------------------------------------------------
1372 | Description : This function is called by the frame when the process is
1373 | created.
1374 |
1375 | Parameters : out_name - Pointer to the buffer in which to locate
1376 | the name of this entity
1377 |
1378 | Return : PEI_OK - entity created successfuly
1379 | PEI_ERROR - entity could not be created
1380 |
1381 +------------------------------------------------------------------------------
1382 */
1383 GLOBAL SHORT pei_create (T_PEI_INFO **info)
1384 {
1385 static T_PEI_INFO pei_info =
1386 {
1387 "GMM", /* name */
1388 { /* pei-table */
1389 pei_init,
1390 pei_exit,
1391 pei_primitive,
1392 pei_timeout,
1393 pei_signal,
1394 pei_run,
1395 pei_config,
1396 pei_monitor
1397 },
1398 2048, /* stack size */
1399 25, /* queue entries */
1400 190, /* priority (1->low, 255->high) */
1401 TIMER_MAX, /* number of timers */
1402 0x03|PRIM_NO_SUSPEND /* flags: bit 0 active(0) body/passive(1) */
1403 }; /* bit 1 com by copy(0)/reference(1) */
1404
1405
1406 TRACE_FUNCTION ("pei_create");
1407
1408 /*
1409 * Close Resources if open
1410 */
1411 if (first_access)
1412 first_access = FALSE;
1413 else
1414 pei_exit();
1415
1416 /*
1417 * Export startup configuration data
1418 */
1419 *info = &pei_info;
1420
1421 return (PEI_OK);
1422 }
1423
1424 /*
1425 +------------------------------------------------------------------------------
1426 | Function : gmm_pei_handle_queue
1427 +------------------------------------------------------------------------------
1428 | Description : This function searches for the first stored primitive, which
1429 | must not be saved further in current state.
1430 |
1431 | Parameters : state - current state of the instance
1432 | queue - PtrPtr to the hanger of the instance save queue
1433 | table - Ptr to the state/signals-to-save table
1434 | inst_data - Ptr to instance data
1435 +------------------------------------------------------------------------------
1436 */
1437 LOCAL void gmm_pei_handle_queue( T_SAVE_QUEUE** queue,
1438 const T_SAVE_TAB* table)
1439 {
1440 /* search for a T_SAVE_TAB entry which fits to current state */
1441 if( *queue )
1442 while( table->state != PEI_END_SAVETAB && table->state != gmm_data->kern.state )
1443 table++;
1444
1445 while( *queue )
1446 {
1447 T_SAVE_QUEUE* current = *queue;
1448 ULONG opc = ((T_PRIM_HEADER*)current->prim)->opc;
1449 USHORT n = 0;
1450
1451 if( table->state != PEI_END_SAVETAB )
1452 {
1453 /* search for this signals in savelist of this state */
1454 while( n < GMM_MAX_SIGNALS_SAVED && table->signal[n] &&
1455 table->signal[n] != opc )
1456 n++;
1457 }
1458
1459 if( table->signal[n] != opc )
1460 {
1461 TRACE_1_INFO ("Pimitive 0x%x send from SAVE queue",
1462 ((T_PRIM_HEADER*)current->prim)->opc );
1463 /* this signal must not further be stored -> handle it now */
1464 /* first remove it from save queue, because of recursion!! */
1465 *queue = current->next;
1466 gmm_pei_handle_prim(current->func, current->prim );
1467 /* and free memory after last use */
1468 MFREE( current );
1469
1470 /* recursion! handle at maximum one prim at once -> job done */
1471 return;
1472 }
1473
1474 /* goto next queued signal */
1475 queue = &((*queue)->next);
1476 }
1477 }
1478 /*
1479 +------------------------------------------------------------------------------
1480 | Function : gmm_pei_delete_queue
1481 +------------------------------------------------------------------------------
1482 | Description : This function removes all stored primitives from the queue and
1483 | frees the memory.
1484 |
1485 | Parameters : queue - PtrPtr to the hanger of the instance save queue
1486 +------------------------------------------------------------------------------
1487 */
1488 GLOBAL void gmm_pei_delete_queue( T_SAVE_QUEUE** queue )
1489 {
1490 while( *queue )
1491 {
1492 T_SAVE_QUEUE* current = *queue;
1493
1494
1495 TRACE_1_INFO( "Pimitive 0x%x deleted from SAVE queue",
1496 ((T_PRIM_HEADER*)current->prim)->opc );
1497
1498 *queue = current->next;
1499 PFREE( P2D(current->prim) );
1500 MFREE( current );
1501 }
1502 }
1503 /*
1504 +------------------------------------------------------------------------------
1505 | Function : gmm_pei_handle_prim
1506 +------------------------------------------------------------------------------
1507 | Description : This function calls the handle function of the signal
1508 |
1509 | Parameters : func - Function, which should handle the signal
1510 | inst_data - Ptr to instance data
1511 | *prim - Ptr to primitive
1512 +------------------------------------------------------------------------------
1513 */
1514 LOCAL void gmm_pei_handle_prim( T_VOID_FUNC func, void* prim )
1515 {
1516 JUMP(func)( P2D(prim));
1517
1518 gmm_pei_handle_queue( &save_queue, save_tab);
1519 }
1520 /*
1521 +------------------------------------------------------------------------------
1522 | Function : gmm_pei_handle_save
1523 +------------------------------------------------------------------------------
1524 | Description : This function saves the prim pointer to the save queue, if
1525 | this is necessary in current state.
1526 |
1527 | Parameters : *prim - Ptr to primitive
1528 | state - Current state of the instance
1529 | queue - PtrPtr to the hanger of the instance save queue
1530 | table - Ptr to the state/signals-to-save table
1531 | func - Function, which should handle the signal
1532 |
1533 | Returns : PEI_SIGNAL_SAVED - if signal is stored to save queue
1534 | PEI_SIGNAL_NOT_SAVED - else
1535 +------------------------------------------------------------------------------
1536 */
1537 LOCAL BOOL gmm_pei_handle_save( void* prim, T_SAVE_QUEUE** queue,
1538 const T_SAVE_TAB* table, T_VOID_FUNC func )
1539 {
1540 ULONG opc = ((T_PRIM_HEADER*)prim)->opc;
1541
1542 while( table->state != PEI_END_SAVETAB )
1543 {
1544 if( table->state == gmm_data->kern.state )
1545 {
1546 UBYTE n = 0;
1547
1548 /* check for signals to save */
1549 while( n < GMM_MAX_SIGNALS_SAVED && table->signal[n] )
1550 {
1551 if( table->signal[n] == opc )
1552 {
1553 /* store signal to end of save queue */
1554 while( *queue )
1555 queue = &((*queue)->next);
1556
1557 MALLOC( *queue, sizeof(T_SAVE_QUEUE) );
1558
1559 if( *queue )
1560 {
1561 (*queue)->prim = prim;
1562 (*queue)->func = func;
1563 (*queue)->next = NULL;
1564 }
1565 else
1566 {
1567 TRACE_ERROR( "Out of memory in mm_pei_handle_save()" );
1568 return PEI_SIGNAL_NOT_SAVED;
1569 }
1570
1571 return PEI_SIGNAL_SAVED;
1572 }
1573
1574 /* goto next signal */
1575 n++;
1576 }
1577
1578 break;
1579 }
1580
1581 /* gote next entry */
1582 table++;
1583 }
1584
1585 return PEI_SIGNAL_NOT_SAVED;
1586 }
1587
1588 /*==== END OF FILE ==========================================================*/