FreeCalypso > hg > fc-tourmaline
comparison src/g23m-gprs/sm/sm_sequencer.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 | Project : 3G PS | |
3 | Module : SM | |
4 +----------------------------------------------------------------------------- | |
5 | Copyright 2003 Texas Instruments. | |
6 | All rights reserved. | |
7 | | |
8 | This file is confidential and a trade secret of Texas | |
9 | Instruments. | |
10 | The receipt of or possession of this file does not convey | |
11 | any rights to reproduce or disclose its contents or to | |
12 | manufacture, use, or sell anything it may describe, in | |
13 | whole, or in part, without the specific written consent of | |
14 | Texas Instruments. | |
15 +----------------------------------------------------------------------------- | |
16 | Purpose: Sequencer state machine implementation in the SM entity. | |
17 | For design details, see: | |
18 | 8010.908 SM Detailed Specification | |
19 +---------------------------------------------------------------------------*/ | |
20 | |
21 /*==== DECLARATION CONTROL =================================================*/ | |
22 | |
23 /*==== INCLUDES =============================================================*/ | |
24 | |
25 #include "sm.h" | |
26 | |
27 #include "sm_sequencer.h" | |
28 #include "sm_context_control.h" | |
29 | |
30 #include "sm_aci_output_handler.h" | |
31 #include "sm_mm_output_handler.h" | |
32 #include "sm_qos.h" | |
33 | |
34 /*==== CONSTS ===============================================================*/ | |
35 | |
36 /*==== TYPES ================================================================*/ | |
37 | |
38 typedef void (*T_SM_SEQUENCER_TRANSITION_FUNC)(void *data); | |
39 | |
40 typedef struct { | |
41 #ifdef DEBUG | |
42 T_SM_SEQUENCER_EVENT event; | |
43 #endif /* DEBUG */ | |
44 T_SM_SEQUENCER_TRANSITION_FUNC func; | |
45 } T_SM_SEQUENCER_TRANSITION; | |
46 | |
47 /*==== LOCALS ===============================================================*/ | |
48 | |
49 static void handle_mmpm_attach_ind(void *data); | |
50 static void handle_mmpm_detach_ind(void *data); | |
51 static void handle_smreg_pdp_deactivate_req(void *data); | |
52 static void handle_sm_status_req(void *data); | |
53 static void handle_context_activation_override(void *data); | |
54 static void handle_context_deactivate_completed(void *data); | |
55 static void handle_context_tear_down_deactivate(void *data); | |
56 static void handle_context_reactivate_completed(void *data); | |
57 | |
58 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
59 | |
60 static const | |
61 T_SM_SEQUENCER_TRANSITION transition[SM_SEQUENCER_NUMBER_OF_EVENTS] = | |
62 { | |
63 M_TRANSITION(SM_P_MMPM_ATTACH_IND, handle_mmpm_attach_ind), | |
64 M_TRANSITION(SM_P_MMPM_DETACH_IND, handle_mmpm_detach_ind), | |
65 M_TRANSITION(SM_P_SMREG_PDP_DEACTIVATE_REQ, handle_smreg_pdp_deactivate_req), | |
66 M_TRANSITION(SM_P_SM_STATUS_REQ, handle_sm_status_req), | |
67 M_TRANSITION(SM_I_CONTEXT_ACTIVATION_OVERRIDE, handle_context_activation_override), | |
68 M_TRANSITION(SM_I_CONTEXT_DEACTIVATE_COMPLETED, handle_context_deactivate_completed), | |
69 M_TRANSITION(SM_I_CONTEXT_TEAR_DOWN_DEACTIVATE, handle_context_tear_down_deactivate), | |
70 M_TRANSITION(SM_I_CONTEXT_REACTIVATE_COMPLETED, handle_context_reactivate_completed) | |
71 }; | |
72 | |
73 static void sm_seq_clear_nsapis_to_deactivate(void) | |
74 { | |
75 sm_data.sm_nsapis_requested_deactivated = 0; | |
76 sm_data.sm_nsapis_being_deactivated = 0; | |
77 } | |
78 | |
79 static void sm_seq_set_nsapis_to_deactivate(U16 nsapi_set) | |
80 { | |
81 sm_data.sm_nsapis_requested_deactivated |= nsapi_set; | |
82 } | |
83 | |
84 static U16 sm_seq_get_nsapis_to_deactivate(void) | |
85 { | |
86 return (sm_data.sm_nsapis_requested_deactivated); | |
87 } | |
88 | |
89 static BOOL sm_seq_is_nsapi_requested_deactivated(int /*@alt U8@*/ nsapi) | |
90 { | |
91 return sm_is_nsapi_in_nsapi_set(nsapi, sm_data.sm_nsapis_requested_deactivated); | |
92 } | |
93 | |
94 static void sm_seq_nsapi_started_deactivation(int /*@alt U8@*/ nsapi) | |
95 { | |
96 sm_data.sm_nsapis_being_deactivated | |
97 = sm_add_nsapi_to_nsapi_set(nsapi, sm_data.sm_nsapis_being_deactivated); | |
98 } | |
99 | |
100 static void sm_seq_nsapi_completed_deactivation(int /*@alt U8@*/ nsapi) | |
101 { | |
102 sm_data.sm_nsapis_being_deactivated | |
103 = sm_remove_nsapi_from_nsapi_set(nsapi, sm_data.sm_nsapis_being_deactivated); | |
104 } | |
105 | |
106 static BOOL sm_seq_is_nsapi_set_completed(void) | |
107 { | |
108 return (sm_data.sm_nsapis_being_deactivated == 0); | |
109 } | |
110 | |
111 /* | |
112 +------------------------------------------------------------------------------ | |
113 | Function : handle_mmpm_attach_ind | |
114 +------------------------------------------------------------------------------ | |
115 | Description : Handle incoming MMPM_ATTACH_IND | |
116 | | |
117 | Parameters : data - T_MMPM_ATTACH_IND * | |
118 +------------------------------------------------------------------------------ | |
119 */ | |
120 | |
121 #ifndef TI_PS_OP_SM_RETAIN_BEST_CONTEXT | |
122 /*Old method. Secondary contexts deactivated after a R99 to R97 RAU*/ | |
123 static void handle_mmpm_attach_ind(void *data) | |
124 { | |
125 int nsapi; | |
126 T_PS_sgsn_rel sgsn_rel; | |
127 T_MMPM_ATTACH_IND *prim = (T_MMPM_ATTACH_IND *)data; | |
128 #ifdef DEBUG | |
129 /*@observer@*/ | |
130 static const char *sgsn_rel_name[3] = { | |
131 "PS_SGSN_UNKNOWN", | |
132 "PS_SGSN_98_OLDER", | |
133 "PS_SGSN_99_ONWARDS" | |
134 }; | |
135 #endif | |
136 | |
137 (void)TRACE_FUNCTION("handle_mmpm_attach_ind"); | |
138 | |
139 sgsn_rel = (T_PS_sgsn_rel)cl_nwrl_get_sgsn_release(); | |
140 | |
141 (void)TRACE_EVENT_P1("SGSN release given by CL is (1->R97, 2->R99) >>> %d", | |
142 cl_nwrl_get_sgsn_release()); | |
143 | |
144 #ifdef DEBUG | |
145 (void)TRACE_EVENT_P2("Got SGSN release value 0x%02x: %s", | |
146 sgsn_rel, | |
147 (sgsn_rel <= PS_SGSN_99_ONWARDS | |
148 ? sgsn_rel_name[(U16)sgsn_rel] | |
149 : "BAD VALUE!")); | |
150 #endif | |
151 | |
152 /* Check whether the UE has moved from R99 to R97/R98 network. */ | |
153 if (sm_get_current_nw_release() == PS_SGSN_99_ONWARDS && | |
154 sgsn_rel == PS_SGSN_98_OLDER) { | |
155 /* We have moved from R99 network to pre-R99: | |
156 * check for secondary contexts, or contexts with TI > 6; | |
157 * These must be locally deactivated. */ | |
158 U16 nsapis_to_deactivate = 0; | |
159 | |
160 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
161 { | |
162 struct T_SM_CONTEXT_DATA *context; | |
163 | |
164 context = sm_get_context_data_from_nsapi(nsapi); | |
165 if (context != NULL && | |
166 (context->ti > (U8)SM_MAX_NON_EXT_TI || sm_is_secondary(context))) | |
167 { | |
168 nsapis_to_deactivate = sm_add_nsapi_to_nsapi_set(nsapi, nsapis_to_deactivate); | |
169 /* Make sure to clear the pending reactivation flag */ | |
170 sm_set_context_pending_reactivation(context, FALSE); | |
171 /* Order context deactivation */ | |
172 sm_context_control(context, SM_I_CONTEXT_LOCAL_DEACTIVATE, (void *)TRUE); | |
173 } | |
174 } | |
175 | |
176 /* If any contexts were deactivated, inform ACI and MM */ | |
177 if (nsapis_to_deactivate != 0) | |
178 { | |
179 T_CAUSE_ps_cause cause; | |
180 cause.ctrl_value = CAUSE_is_from_sm; | |
181 cause.value.sm_cause = (U16)CAUSE_SM_PRE_R99_NETWORK_ENTERED; | |
182 | |
183 send_smreg_pdp_deactivate_ind(nsapis_to_deactivate, &cause); | |
184 send_mmpm_pdp_context_status_req(); | |
185 } | |
186 } | |
187 | |
188 /* Check whether any (primary) contexts are pending reactivation: | |
189 * If so, start reactivation now. */ | |
190 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
191 { | |
192 struct T_SM_CONTEXT_DATA *context; | |
193 | |
194 context = sm_get_context_data_from_nsapi(nsapi); | |
195 if (context != NULL && !sm_is_secondary(context) | |
196 && sm_is_context_pending_reactivation(context)) | |
197 { | |
198 /* Clear the pending reactivation flag. Will be done in | |
199 sm_is_address_changed_with_reactivation */ | |
200 /*sm_set_context_pending_reactivation(context, FALSE);*/ | |
201 | |
202 /* Order context reactivation */ | |
203 sm_context_control(context, SM_I_CONTEXT_REACTIVATE, NULL); | |
204 } | |
205 } | |
206 | |
207 /* Set current RAT and core network release */ | |
208 sm_set_current_rat ((T_PS_rat)prim->rat); | |
209 sm_set_current_nw_release(sgsn_rel); | |
210 | |
211 /* | |
212 * The following line is useful if we try a PDP activation after a | |
213 * GPRS detach | |
214 */ | |
215 sm_data.sm_suspended = FALSE; | |
216 sm_data.sm_suspend_cause = CAUSE_MM_SUCCESS; | |
217 } | |
218 | |
219 #else /*#ifndef TI_PS_OP_SM_RETAIN_BEST_CONTEXT*/ | |
220 /*New method. The best context remain after a R99 to R97 RAU*/ | |
221 | |
222 static void handle_mmpm_attach_ind(void *data) | |
223 { | |
224 int nsapi; | |
225 T_PS_sgsn_rel sgsn_rel; | |
226 T_MMPM_ATTACH_IND *prim = (T_MMPM_ATTACH_IND *)data; | |
227 U16 nsapis_to_deactivate = 0; | |
228 U16 nsapis_deactivated = 0; | |
229 | |
230 #ifdef DEBUG | |
231 /*@observer@*/ | |
232 static const char *sgsn_rel_name[3] = { | |
233 "PS_SGSN_UNKNOWN", | |
234 "PS_SGSN_98_OLDER", | |
235 "PS_SGSN_99_ONWARDS" | |
236 }; | |
237 #endif | |
238 | |
239 (void)TRACE_FUNCTION("handle_mmpm_attach_ind"); | |
240 | |
241 sgsn_rel = cl_nwrl_get_sgsn_release(); | |
242 | |
243 (void)TRACE_EVENT_P1("SGSN release given by CL is (1->R97, 2->R99) >>> %d", | |
244 cl_nwrl_get_sgsn_release()); | |
245 | |
246 #ifdef DEBUG | |
247 (void)TRACE_EVENT_P2("Got SGSN release value 0x%02x: %s", | |
248 sgsn_rel, | |
249 (sgsn_rel <= PS_SGSN_99_ONWARDS | |
250 ? sgsn_rel_name[(U16)sgsn_rel] | |
251 : "BAD VALUE!")); | |
252 #endif | |
253 | |
254 /* Check whether the UE has moved from R99 to R97/R98 network. */ | |
255 if (sm_get_current_nw_release() == PS_SGSN_99_ONWARDS && | |
256 sgsn_rel == PS_SGSN_98_OLDER) { | |
257 /* We have moved from R99 network to pre-R99: | |
258 * First round of elimination. Check for contexts with TI > 6; | |
259 * These must be locally deactivated. | |
260 */ | |
261 | |
262 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
263 { | |
264 struct T_SM_CONTEXT_DATA *context; | |
265 | |
266 context = sm_get_context_data_from_nsapi(nsapi); | |
267 if (context != NULL && (context->ti > (U8)SM_MAX_NON_EXT_TI )) | |
268 { | |
269 nsapis_to_deactivate = sm_add_nsapi_to_nsapi_set(nsapi, | |
270 nsapis_to_deactivate); | |
271 /* Make sure to clear the pending reactivation flag */ | |
272 sm_set_context_pending_reactivation(context, FALSE); | |
273 /* Order context deactivation */ | |
274 sm_context_control(context, SM_I_CONTEXT_LOCAL_DEACTIVATE, (void *)TRUE); | |
275 } | |
276 } | |
277 | |
278 /* Second round of elimination. Rank contexts based on Traffic class and | |
279 * traffic handling priority. Locally deactivate all but the best ranking | |
280 * context(s). Ref 23.107 Annex C | |
281 */ | |
282 nsapis_deactivated = sm_rank_del_contexts_based_on_tc(); | |
283 nsapis_to_deactivate = (nsapis_to_deactivate | nsapis_deactivated); | |
284 | |
285 /* Third round of elimination. Context(s) with highest values of max bitrate | |
286 * for uplink or downlink remain. Ref 23.107 Annex C | |
287 */ | |
288 nsapis_deactivated = sm_retain_cntxt_wth_best_bitrate(); | |
289 nsapis_to_deactivate = (nsapis_to_deactivate | nsapis_deactivated); | |
290 | |
291 /* Final round of elimination. Context with smallest nsapi remain. | |
292 * Ref 23.107 Annex C | |
293 */ | |
294 nsapis_deactivated = sm_retain_cntxt_with_least_nsapi(); | |
295 nsapis_to_deactivate = (nsapis_to_deactivate | nsapis_deactivated); | |
296 | |
297 /* If any contexts were deactivated, inform ACI and MM */ | |
298 if (nsapis_to_deactivate != 0) | |
299 { | |
300 T_CAUSE_ps_cause cause; | |
301 cause.ctrl_value = CAUSE_is_from_sm; | |
302 cause.value.sm_cause = (U16)CAUSE_SM_PRE_R99_NETWORK_ENTERED; | |
303 | |
304 send_smreg_pdp_deactivate_ind(nsapis_to_deactivate, &cause); | |
305 send_mmpm_pdp_context_status_req(); | |
306 } | |
307 | |
308 /* Now all the remaining contexts should be primary. Clear the | |
309 * secondary context flag if it is set in any of the remaining | |
310 * active context(s). | |
311 */ | |
312 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
313 { | |
314 struct T_SM_CONTEXT_DATA *context; | |
315 | |
316 context = sm_get_context_data_from_nsapi(nsapi); | |
317 if ( (context != NULL) && (context->context_control_state | |
318 != SM_CONTEXT_DEACTIVATED) && sm_is_secondary(context)) | |
319 { /* Clear the secondary context flag */ | |
320 context->flags &= 0xff^(U8)SM_CONTEXT_FLAG_SECONDARY_CONTEXT; | |
321 } | |
322 } | |
323 } | |
324 | |
325 /* Check whether any (primary) contexts are pending reactivation: | |
326 * If so, start reactivation now. | |
327 */ | |
328 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
329 { | |
330 struct T_SM_CONTEXT_DATA *context; | |
331 | |
332 context = sm_get_context_data_from_nsapi(nsapi); | |
333 if (context != NULL && !sm_is_secondary(context) | |
334 && sm_is_context_pending_reactivation(context)) | |
335 { | |
336 /* Clear the pending reactivation flag. Will be done in | |
337 sm_is_address_changed_with_reactivation */ | |
338 //sm_set_context_pending_reactivation(context, FALSE); | |
339 | |
340 /* Order context reactivation */ | |
341 sm_context_control(context, SM_I_CONTEXT_REACTIVATE, NULL); | |
342 } | |
343 } | |
344 | |
345 /* Set current RAT and core network release */ | |
346 sm_set_current_rat ((T_PS_rat)prim->rat); | |
347 sm_set_current_nw_release(sgsn_rel); | |
348 | |
349 /* | |
350 * The following line is useful if we try a PDP activation after a | |
351 * GPRS detach | |
352 */ | |
353 sm_data.sm_suspended = FALSE; | |
354 sm_data.sm_suspend_cause = CAUSE_MM_SUCCESS; | |
355 } | |
356 #endif /*#ifndef TI_PS_OP_SM_RETAIN_BEST_CONTEXT*/ | |
357 | |
358 /* | |
359 +------------------------------------------------------------------------------ | |
360 | Function : handle_mmpm_detach_ind | |
361 +------------------------------------------------------------------------------ | |
362 | Description : Handle incoming MMPM_DETACH_IND primitive | |
363 | | |
364 | Parameters : data - T_MMPM_DETACH_IND * | |
365 +------------------------------------------------------------------------------ | |
366 */ | |
367 static void handle_mmpm_detach_ind(void *data) | |
368 { | |
369 T_MMPM_DETACH_IND *prim = data; | |
370 int nsapi; | |
371 U16 nsapis_to_deactivate = 0; | |
372 BOOL cause_reattach; | |
373 | |
374 (void)TRACE_FUNCTION("handle_mmpm_detach_ind"); | |
375 | |
376 TRACE_ASSERT (data != NULL); | |
377 | |
378 if (prim->ps_cause.ctrl_value == CAUSE_is_from_mm && | |
379 prim->ps_cause.value.mm_cause == (U16)CAUSE_MM_DETACH_WITH_REATTACH) | |
380 { | |
381 cause_reattach = TRUE; | |
382 } else { | |
383 cause_reattach = FALSE; | |
384 } | |
385 | |
386 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
387 { | |
388 struct T_SM_CONTEXT_DATA *context; | |
389 | |
390 context = sm_get_context_data_from_nsapi(nsapi); | |
391 if (context != NULL) | |
392 { | |
393 if (cause_reattach) | |
394 { | |
395 sm_set_context_pending_reactivation(context, TRUE); | |
396 } else { | |
397 sm_set_context_pending_reactivation(context, FALSE); | |
398 nsapis_to_deactivate = sm_add_nsapi_to_nsapi_set(nsapi, nsapis_to_deactivate); | |
399 } | |
400 | |
401 sm_context_control(context, SM_I_CONTEXT_LOCAL_DEACTIVATE, (void *)TRUE); | |
402 } | |
403 } | |
404 | |
405 /* Inform ACI that the contexts are gone. */ | |
406 if (nsapis_to_deactivate != 0) | |
407 { | |
408 send_smreg_pdp_deactivate_ind(nsapis_to_deactivate, &prim->ps_cause); | |
409 } | |
410 } | |
411 | |
412 /* | |
413 +------------------------------------------------------------------------------ | |
414 | Function : handle_smreg_pdp_deactivate_req | |
415 +------------------------------------------------------------------------------ | |
416 | Description : Handle incoming SMREG_PDP_DEACTIVATE_REQ | |
417 | | |
418 | Parameters : data - T_SMREG_PDP_DEACTIVATE_REQ * | |
419 +------------------------------------------------------------------------------ | |
420 */ | |
421 static void handle_smreg_pdp_deactivate_req(void *data) | |
422 { | |
423 int nsapi; | |
424 U16 nsapis_deactivated = 0; | |
425 T_SMREG_PDP_DEACTIVATE_REQ *prim = (T_SMREG_PDP_DEACTIVATE_REQ *)data; | |
426 (void)TRACE_FUNCTION("handle_smreg_pdp_deactivate_req"); | |
427 | |
428 TRACE_ASSERT(prim != NULL); | |
429 | |
430 if (prim EQ NULL) | |
431 return; | |
432 | |
433 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
434 { | |
435 if (sm_is_nsapi_in_nsapi_set(nsapi, prim->nsapi_set)) | |
436 { | |
437 struct T_SM_CONTEXT_DATA *context; | |
438 | |
439 context = sm_get_context_data_from_nsapi(nsapi); | |
440 if (context != NULL) | |
441 { | |
442 nsapis_deactivated = sm_add_nsapi_to_nsapi_set(nsapi, nsapis_deactivated); | |
443 | |
444 /* Set SM_CONTEXT_FLAG_STARTED_DURING_SUSPEND flag according to suspend status */ | |
445 sm_set_started_during_suspend(context); | |
446 | |
447 /* Clear pending reactivation flag */ | |
448 sm_set_context_pending_reactivation(context, FALSE); | |
449 | |
450 /* Mark requested nsapi for deactivation */ | |
451 sm_seq_set_nsapis_to_deactivate(sm_nsapi2nsapi_set(nsapi)); | |
452 | |
453 /* Mark NSAPI "deactivation in progress" */ | |
454 sm_seq_nsapi_started_deactivation(nsapi); | |
455 | |
456 if (prim->rel_ind == (U8)PS_REL_IND_YES) | |
457 { | |
458 /* Local deactivation */ | |
459 sm_context_control(context, SM_I_CONTEXT_LOCAL_DEACTIVATE, (void *)TRUE); | |
460 } else { | |
461 /* Deactivation with network signalling */ | |
462 sm_context_control(context, SM_I_CONTEXT_DEACTIVATE, | |
463 (void *)SM_I_DEACTIVATE_NETWORK_AND_USER_PLANE); | |
464 } /* if */ | |
465 } /* if */ | |
466 } /* if */ | |
467 } /* for */ | |
468 | |
469 if (nsapis_deactivated != 0) { | |
470 if (prim->rel_ind == (U8)PS_REL_IND_YES) { | |
471 /* For local deactivations, inform MM if any contexts were deactivated */ | |
472 send_mmpm_pdp_context_status_req(); | |
473 /* Inform ACI of the deactivated contexts */ | |
474 send_smreg_pdp_deactivate_cnf(prim->nsapi_set); | |
475 } | |
476 } else { | |
477 /* Contexts must already be deactivated - inform ACI */ | |
478 send_smreg_pdp_deactivate_cnf(prim->nsapi_set); | |
479 } | |
480 } | |
481 | |
482 /* | |
483 +------------------------------------------------------------------------------ | |
484 | Function : handle_sm_status_req | |
485 +------------------------------------------------------------------------------ | |
486 | Description : Handle incoming SM_STATUS_REQ | |
487 | | |
488 | Parameters : data - T_SM_STATUS_REQ * | |
489 +------------------------------------------------------------------------------ | |
490 */ | |
491 static void handle_sm_status_req(void *data) | |
492 { | |
493 int nsapi; | |
494 T_SM_STATUS_REQ *prim = (T_SM_STATUS_REQ *)data; | |
495 T_SM_CONTEXT_CONTROL_EVENT event; | |
496 void *edata; | |
497 (void)TRACE_FUNCTION("handle_sm_status_req"); | |
498 | |
499 if (prim->ps_cause.ctrl_value == CAUSE_is_from_llc) { | |
500 switch (prim->ps_cause.value.llc_cause) { | |
501 case CAUSE_LLC_NO_PEER_RES: | |
502 /* Do nothing */ | |
503 return; | |
504 case CAUSE_LLC_NORMAL_REL: /* Normal deactivation */ | |
505 default: /* Unknown user plane error: Deactivate contexts */ | |
506 /* Deactivate with network signalling */ | |
507 event = SM_I_CONTEXT_USER_PLANE_ERROR; | |
508 edata = NULL; | |
509 break; | |
510 } /* switch */ | |
511 } else if (prim->ps_cause.ctrl_value == CAUSE_is_from_upm) { | |
512 switch (prim->ps_cause.value.upm_cause) { | |
513 case CAUSE_UPM_RT_QOS_RELEASE: | |
514 /* Inform ACI of QoS downgrade */ | |
515 send_smreg_pdp_modify_ind_multiple(prim->nsapi_set, | |
516 SM_UPDATE_QOS_DOWNGRADE); | |
517 return; | |
518 case CAUSE_UPM_REEST_NEEDED: | |
519 event = SM_I_CONTEXT_UPGRADE; | |
520 edata = NULL; | |
521 break; | |
522 case CAUSE_UPM_REEST_REJECT: | |
523 /* FIXME: How to handle reactivation reject? */ | |
524 return; | |
525 case CAUSE_UPM_NORMAL_RELEASE: | |
526 event = SM_I_CONTEXT_USER_PLANE_ERROR; | |
527 edata = NULL; | |
528 break; | |
529 default: /* Unknown user plane error: Deactivate contexts */ | |
530 event = SM_I_CONTEXT_DEACTIVATE; | |
531 edata = (void *)SM_I_DEACTIVATE_NETWORK_AND_USER_PLANE; | |
532 break; | |
533 } /* switch */ | |
534 } else { | |
535 /* Unknown user plane error: Assume user plane down and deactivate contexts */ | |
536 event = SM_I_CONTEXT_USER_PLANE_ERROR; | |
537 edata = NULL; | |
538 } | |
539 | |
540 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
541 { | |
542 if (sm_is_nsapi_in_nsapi_set(nsapi, prim->nsapi_set)) | |
543 { | |
544 struct T_SM_CONTEXT_DATA *context; | |
545 | |
546 context = sm_get_context_data_from_nsapi(nsapi); | |
547 if (context != NULL) { | |
548 sm_set_aci_cause(context, prim->ps_cause.ctrl_value, | |
549 prim->ps_cause.value.nwsm_cause); | |
550 sm_context_control(context, event, edata); | |
551 } /* if */ | |
552 } /* if */ | |
553 } /* for */ | |
554 } | |
555 | |
556 /* | |
557 +------------------------------------------------------------------------------ | |
558 | Function : handle_context_activation_override | |
559 +------------------------------------------------------------------------------ | |
560 | Description : Handle SM_I_CONTEXT_ACTIVATION_OVERRIDE | |
561 | | |
562 | Parameters : data - ti | |
563 +------------------------------------------------------------------------------ | |
564 */ | |
565 static void handle_context_activation_override(void *data) | |
566 { | |
567 int nsapi, ti = (int)data; | |
568 U16 nsapis_to_deactivate = 0; | |
569 (void)TRACE_FUNCTION("handle_context_activation_override"); | |
570 | |
571 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
572 { | |
573 struct T_SM_CONTEXT_DATA *context; | |
574 | |
575 context = sm_get_context_data_from_nsapi(nsapi); | |
576 if (context != NULL && context->ti != (U8)ti && | |
577 sm_is_secondary(context) && context->linked_ti == (U8)ti) | |
578 { | |
579 /* Locally deactivate contexts linked to ti of input context */ | |
580 nsapis_to_deactivate = sm_add_nsapi_to_nsapi_set(nsapi, nsapis_to_deactivate); | |
581 } /* if */ | |
582 } /* for */ | |
583 | |
584 if (nsapis_to_deactivate != 0) | |
585 { | |
586 T_CAUSE_ps_cause cause; | |
587 | |
588 /* Found contexts to deactivate: inform ACI */ | |
589 cause.ctrl_value = CAUSE_is_from_sm; | |
590 cause.value.sm_cause = (U16)CAUSE_SM_ACTIVATION_OVERRIDE; | |
591 | |
592 send_smreg_pdp_deactivate_ind(nsapis_to_deactivate, &cause); | |
593 | |
594 /* Perform local deactivation */ | |
595 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
596 { | |
597 if (sm_is_nsapi_in_nsapi_set(nsapi, nsapis_to_deactivate)) | |
598 { | |
599 struct T_SM_CONTEXT_DATA *context; | |
600 | |
601 context = sm_get_context_data_from_nsapi(nsapi); | |
602 sm_context_control(context, SM_I_CONTEXT_LOCAL_DEACTIVATE, (void *)TRUE); | |
603 } /* if */ | |
604 } /* for */ | |
605 } /* if */ | |
606 } | |
607 | |
608 /* | |
609 +------------------------------------------------------------------------------ | |
610 | Function : handle_context_deactivate_completed | |
611 +------------------------------------------------------------------------------ | |
612 | Description : Handle SM_I_CONTEXT_DEACTIVATE_COMPLETED | |
613 | | |
614 | Parameters : data - NSAPI | |
615 +------------------------------------------------------------------------------ | |
616 */ | |
617 static void handle_context_deactivate_completed(void *data) | |
618 { | |
619 int nsapi = (int)data; | |
620 (void)TRACE_FUNCTION("handle_context_deactivate_completed"); | |
621 | |
622 /* Mark nsapi as deactivated */ | |
623 sm_seq_nsapi_completed_deactivation(nsapi); | |
624 | |
625 /* Check that this NSAPI is part of the requested NSAPIs being deactivated. | |
626 * Could also be due to SMREG_CONFIGURE_REQ etc. */ | |
627 if (sm_seq_is_nsapi_requested_deactivated(nsapi)) { | |
628 /* Yes, NSAPI is in set. Check whether deactivation completes with this NSAPI */ | |
629 if (sm_seq_is_nsapi_set_completed()) { | |
630 /* Done. Confirm deactivation towards ACI */ | |
631 send_smreg_pdp_deactivate_cnf(sm_seq_get_nsapis_to_deactivate()); | |
632 | |
633 /* Reset requested deactivation nsapi_set. */ | |
634 sm_seq_clear_nsapis_to_deactivate(); | |
635 } | |
636 } else { | |
637 /* No. NSAPI was deactivated for reasons other than deactivation from ACI */ | |
638 } | |
639 } | |
640 | |
641 /* | |
642 +------------------------------------------------------------------------------ | |
643 | Function : handle_context_reactivate_completed | |
644 +------------------------------------------------------------------------------ | |
645 | Description : Handle SM_I_CONTEXT_REACTIVATE_COMPLETED | |
646 | | |
647 | Parameters : data - TI (of primary context) | |
648 +------------------------------------------------------------------------------ | |
649 */ | |
650 static void handle_context_reactivate_completed(void *data) | |
651 { | |
652 int ti = (int)data; | |
653 int nsapi; | |
654 | |
655 (void)TRACE_FUNCTION("handle_context_reactivate_completed"); | |
656 | |
657 /* Check whether any secondary contexts are pending reactivation with | |
658 * linked_ti == ti of the primary context just reactivated. | |
659 * If so, start reactivation now. */ | |
660 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
661 { | |
662 struct T_SM_CONTEXT_DATA *context; | |
663 | |
664 context = sm_get_context_data_from_nsapi(nsapi); | |
665 if (context != NULL && sm_is_secondary(context) | |
666 && context->linked_ti == (U8)ti) | |
667 { | |
668 /* Clear the pending reactivation flag */ | |
669 sm_set_context_pending_reactivation(context, FALSE); | |
670 | |
671 /* Order context reactivation */ | |
672 sm_context_control(context, SM_I_CONTEXT_REACTIVATE, NULL); | |
673 } | |
674 } | |
675 } | |
676 | |
677 /* | |
678 +------------------------------------------------------------------------------ | |
679 | Function : handle_context_tear_down_deactivate | |
680 +------------------------------------------------------------------------------ | |
681 | Description : Handle SM_I_CONTEXT_TEAR_DOWN_DEACTIVATE | |
682 | | |
683 | Parameters : data - TI | |
684 +------------------------------------------------------------------------------ | |
685 */ | |
686 static void handle_context_tear_down_deactivate(void *data) | |
687 { | |
688 int nsapi, ti = (int)data; | |
689 U16 nsapis_to_deactivate = 0; | |
690 (void)TRACE_FUNCTION("handle_context_tear_down_deactivate"); | |
691 | |
692 nsapis_to_deactivate = sm_linked_nsapis((U8)ti); | |
693 | |
694 if (nsapis_to_deactivate != 0) { | |
695 /* Perform local deactivation */ | |
696 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
697 { | |
698 if (sm_is_nsapi_in_nsapi_set(nsapi, nsapis_to_deactivate)) | |
699 { | |
700 struct T_SM_CONTEXT_DATA *context; | |
701 | |
702 context = sm_get_context_data_from_nsapi(nsapi); | |
703 sm_context_control(context, SM_I_CONTEXT_LOCAL_DEACTIVATE, (void *)TRUE); | |
704 } /* if */ | |
705 } /* for */ | |
706 } /* if */ | |
707 } | |
708 | |
709 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
710 | |
711 /* | |
712 +------------------------------------------------------------------------------ | |
713 | Function : sm_sequencer_init | |
714 +------------------------------------------------------------------------------ | |
715 | Description : Sequencer state machine initialization function | |
716 | | |
717 | Parameters : None | |
718 +------------------------------------------------------------------------------ | |
719 */ | |
720 void sm_sequencer_init(void) | |
721 { | |
722 (void)TRACE_FUNCTION("sm_sequencer_init"); | |
723 | |
724 | |
725 sm_data.sm_attached = FALSE; | |
726 sm_data.sm_suspended = FALSE; | |
727 sm_data.sm_suspend_cause = CAUSE_MM_SUCCESS; | |
728 | |
729 | |
730 sm_seq_clear_nsapis_to_deactivate(); | |
731 } | |
732 | |
733 /* | |
734 +------------------------------------------------------------------------------ | |
735 | Function : sm_sequencer_exit | |
736 +------------------------------------------------------------------------------ | |
737 | Description : Sequencer state machine exit function | |
738 | |
739 | Parameters : None | |
740 +------------------------------------------------------------------------------ | |
741 */ | |
742 void sm_sequencer_exit(void) | |
743 { | |
744 (void)TRACE_FUNCTION("sm_sequencer_exit"); | |
745 | |
746 sm_data.sm_attached = FALSE; | |
747 sm_seq_clear_nsapis_to_deactivate(); | |
748 } | |
749 | |
750 /* | |
751 +------------------------------------------------------------------------------ | |
752 | Function : sm_sequencer | |
753 +------------------------------------------------------------------------------ | |
754 | Description : Sequencer state machine | |
755 | | |
756 | Parameters : event - Internal event (see sm_sequencer.h) | |
757 | data - Event dependent parameter | |
758 +------------------------------------------------------------------------------ | |
759 */ | |
760 void sm_sequencer(T_SM_SEQUENCER_EVENT event, | |
761 void *data) | |
762 { | |
763 #ifdef DEBUG | |
764 /*@observer@*/ | |
765 static const char *event_name[SM_SEQUENCER_NUMBER_OF_EVENTS] = { | |
766 "SM_P_MMPM_ATTACH_IND", | |
767 "SM_P_MMPM_DETACH_IND", | |
768 "SM_P_SMREG_PDP_DEACTIVATE_REQ", | |
769 "SM_P_SM_STATUS_REQ", | |
770 "SM_I_CONTEXT_ACTIVATION_OVERRIDE", | |
771 "SM_I_CONTEXT_DEACTIVATE_COMPLETED", | |
772 "SM_I_CONTEXT_TEAR_DOWN_DEACTIVATE", | |
773 "SM_I_CONTEXT_REACTIVATE_COMPLETED" | |
774 }; | |
775 char state_array[SM_MAX_NSAPI_OFFSET + 1]; | |
776 | |
777 TRACE_ASSERT(event < SM_SEQUENCER_NUMBER_OF_EVENTS); | |
778 | |
779 if (transition[(U16)event].event != event) { | |
780 (void)TRACE_ERROR("Event table error in sm_sequencer!"); | |
781 } | |
782 #endif /* DEBUG */ | |
783 | |
784 transition[(U16)event].func(data); | |
785 | |
786 #ifdef DEBUG | |
787 (void)TRACE_EVENT_P2("SM SEQUENCER : %s => %s", | |
788 event_name[(U16)event], | |
789 sm_context_bitfield(state_array, sm_data.sm_context_activation_status)); | |
790 #endif /* DEBUG */ | |
791 } | |
792 | |
793 /*==== END OF FILE ==========================================================*/ |