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 ==========================================================*/