comparison src/g23m-gprs/sm/sm_network_control.c @ 183:219afcfc6250

src/g23m-gprs: initial import from TCS3.2/LoCosto
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 13 Oct 2016 04:24:13 +0000
parents
children
comparison
equal deleted inserted replaced
182:f02d0a0e1849 183:219afcfc6250
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: Network Control 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_network_control.h"
28 #include "sm_context_control.h"
29
30 #include "sm_mm_output_handler.h"
31
32 #include "sm_qos.h"
33 #include "sm_tft.h"
34 #include "sm_timer_handler.h"
35
36 /*==== CONSTS ===============================================================*/
37
38 /*==== TYPES ================================================================*/
39
40 typedef void (*T_SM_NETWORK_CONTROL_TRANSITION_FUNC)(struct T_SM_CONTEXT_DATA *ptr_context_data, /*@null@*/ void *data);
41
42 typedef struct {
43 #ifdef DEBUG
44 T_SM_NETWORK_CONTROL_EVENT event;
45 #endif /* DEBUG */
46 T_SM_NETWORK_CONTROL_TRANSITION_FUNC func;
47 } T_SM_NETWORK_CONTROL_TRANSITION;
48
49 /*==== LOCALS ===============================================================*/
50
51 static void state_event_error(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
52 static void ignored (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
53 static void message_incompatible_with_state(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
54 static void message_for_invalid_ti(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
55
56 /* Handler functions for internal events */
57 static void handle_activate_primary(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
58 static void handle_activate_secondary(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
59 static void handle_request_activation_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
60 static void handle_modify_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
61 static void handle_deactivate_in_S0(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
62 static void handle_deactivate_during_activation(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
63 static void handle_deactivate_during_modification(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
64 static void handle_deactivate_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
65 static void handle_deactivate_local(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
66
67 /* Handler functions for incoming air interface messages */
68 static void handle_activate_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
69 static void handle_activate_pdp_context_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
70 static void handle_activate_secondary_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
71 static void handle_activate_secondary_pdp_context_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
72 static void handle_request_pdp_context_activation_in_S0(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
73 static void handle_request_pdp_context_activation_in_S1(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
74 static void handle_request_pdp_context_activation_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
75 static void handle_modify_pdp_context_request_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
76 static void handle_modify_pdp_context_request_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
77 static void handle_modify_pdp_context_request_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
78 static void handle_modify_pdp_context_request_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
79 static void handle_modify_pdp_context_accept_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
80 static void handle_modify_pdp_context_accept_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
81 static void handle_modify_pdp_context_accept_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
82 static void handle_modify_pdp_context_reject_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
83 static void handle_modify_pdp_context_reject_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
84 static void handle_modify_pdp_context_reject_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
85 static void handle_deactivate_pdp_context_request_while_active(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
86 static void handle_deactivate_pdp_context_request_while_deactivating(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
87 static void handle_deactivate_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
88 /* Handler functions for timer timeouts */
89 static void handle_T3380(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
90 static void handle_T3380_max (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
91 static void handle_T3381 (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
92 static void handle_T3381_max_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
93 static void handle_T3381_max_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
94 static void handle_T3381_max_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
95 static void handle_T3390 (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
96 static void handle_T3390_max (struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
97 /* Handler functions for incoming primitives */
98 static void handle_mmpm_suspend_ind(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
99 static void handle_mmpm_resume_ind(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data);
100
101 /***********************************************************************
102 * State/Transition Table
103 */
104 static const T_SM_NETWORK_CONTROL_TRANSITION
105 transition[SM_NETWORK_CONTROL_NUMBER_OF_STATES][SM_NETWORK_CONTROL_NUMBER_OF_EVENTS] =
106 {
107 { /* S0: SM NETWORK DEACTIVATED */
108 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_for_invalid_ti),
109 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_for_invalid_ti),
110 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_for_invalid_ti),
111 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_for_invalid_ti),
112 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, state_event_error),
113 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, state_event_error),
114 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, message_for_invalid_ti),
115 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_for_invalid_ti),
116 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_for_invalid_ti),
117 M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, handle_request_pdp_context_activation_in_S0),
118 M_TRANSITION(SM_M_SM_STATUS, state_event_error),
119 M_TRANSITION(SM_P_MMPM_RESUME_IND, ignored),
120 M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind),
121 M_TRANSITION(SM_T_T3380, state_event_error),
122 M_TRANSITION(SM_T_T3380_MAX, state_event_error),
123 M_TRANSITION(SM_T_T3381, state_event_error),
124 M_TRANSITION(SM_T_T3381_MAX, state_event_error),
125 M_TRANSITION(SM_T_T3390, state_event_error),
126 M_TRANSITION(SM_T_T3390_MAX, state_event_error),
127 M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, handle_activate_primary),
128 M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, handle_activate_secondary),
129 M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local),
130 M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error),
131 M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, handle_request_activation_reject),
132 M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_in_S0)
133 },
134 { /* S1: SM NETWORK ACTIVATING PRIMARY */
135 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, handle_activate_pdp_context_accept),
136 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, handle_activate_pdp_context_reject),
137 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
138 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
139 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active),
140 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
141 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, message_incompatible_with_state),
142 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
143 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
144 M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, handle_request_pdp_context_activation_in_S1),
145 M_TRANSITION(SM_M_SM_STATUS, state_event_error),
146 M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind),
147 M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind),
148 M_TRANSITION(SM_T_T3380, handle_T3380),
149 M_TRANSITION(SM_T_T3380_MAX, handle_T3380_max),
150 M_TRANSITION(SM_T_T3381, state_event_error),
151 M_TRANSITION(SM_T_T3381_MAX, state_event_error),
152 M_TRANSITION(SM_T_T3390, state_event_error),
153 M_TRANSITION(SM_T_T3390_MAX, state_event_error),
154 M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error),
155 M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error),
156 M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local),
157 M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error),
158 M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error),
159 M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_activation)
160 },
161 { /* S2: SM NETWORK ACTIVATING SECONDARY */
162 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
163 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state),
164 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, handle_activate_secondary_pdp_context_accept),
165 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, handle_activate_secondary_pdp_context_reject),
166 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active),
167 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
168 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, message_incompatible_with_state),
169 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
170 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
171 M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state),
172 M_TRANSITION(SM_M_SM_STATUS, state_event_error),
173 M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind),
174 M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind),
175 M_TRANSITION(SM_T_T3380, handle_T3380),
176 M_TRANSITION(SM_T_T3380_MAX, handle_T3380_max),
177 M_TRANSITION(SM_T_T3381, state_event_error),
178 M_TRANSITION(SM_T_T3381_MAX, state_event_error),
179 M_TRANSITION(SM_T_T3390, state_event_error),
180 M_TRANSITION(SM_T_T3390_MAX, state_event_error),
181 M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error),
182 M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error),
183 M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local),
184 M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error),
185 M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error),
186 M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_activation)
187 },
188 { /* S3: SM NETWORK ACTIVATING ADDING TFTS */
189 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
190 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state),
191 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
192 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
193 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active),
194 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
195 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, handle_modify_pdp_context_request_in_S3),
196 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, handle_modify_pdp_context_accept_in_S3),
197 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, handle_modify_pdp_context_reject_in_S3),
198 M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state),
199 M_TRANSITION(SM_M_SM_STATUS, state_event_error),
200 M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind),
201 M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind),
202 M_TRANSITION(SM_T_T3380, state_event_error),
203 M_TRANSITION(SM_T_T3380_MAX, state_event_error),
204 M_TRANSITION(SM_T_T3381, handle_T3381),
205 M_TRANSITION(SM_T_T3381_MAX, handle_T3381_max_in_S3),
206 M_TRANSITION(SM_T_T3390, state_event_error),
207 M_TRANSITION(SM_T_T3390_MAX, state_event_error),
208 M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error),
209 M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error),
210 M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local),
211 M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error),
212 M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error),
213 M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_modification)
214 },
215 { /* S4: SM NETWORK ACTIVATED */
216 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
217 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state),
218 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
219 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
220 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active),
221 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
222 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, handle_modify_pdp_context_request_in_S4),
223 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
224 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
225 M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, handle_request_pdp_context_activation_in_S4),
226 M_TRANSITION(SM_M_SM_STATUS, state_event_error),
227 M_TRANSITION(SM_P_MMPM_RESUME_IND, ignored),
228 M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind),
229 M_TRANSITION(SM_T_T3380, state_event_error),
230 M_TRANSITION(SM_T_T3380_MAX, state_event_error),
231 M_TRANSITION(SM_T_T3381, state_event_error),
232 M_TRANSITION(SM_T_T3381_MAX, state_event_error),
233 M_TRANSITION(SM_T_T3390, state_event_error),
234 M_TRANSITION(SM_T_T3390_MAX, state_event_error),
235 M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error),
236 M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error),
237 M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local),
238 M_TRANSITION(SM_I_NETWORK_MODIFY, handle_modify_in_S4),
239 M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error),
240 M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_in_S4)
241 },
242 { /* S5: SM NETWORK MODIFYING */
243 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
244 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state),
245 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
246 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
247 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active),
248 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
249 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, handle_modify_pdp_context_request_in_S5),
250 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, handle_modify_pdp_context_accept_in_S5),
251 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, handle_modify_pdp_context_reject_in_S5),
252 M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state),
253 M_TRANSITION(SM_M_SM_STATUS, state_event_error),
254 M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind),
255 M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind),
256 M_TRANSITION(SM_T_T3380, state_event_error),
257 M_TRANSITION(SM_T_T3380_MAX, state_event_error),
258 M_TRANSITION(SM_T_T3381, handle_T3381),
259 M_TRANSITION(SM_T_T3381_MAX, handle_T3381_max_in_S5),
260 M_TRANSITION(SM_T_T3390, state_event_error),
261 M_TRANSITION(SM_T_T3390_MAX, state_event_error),
262 M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error),
263 M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error),
264 M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local),
265 M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error),
266 M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error),
267 M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_modification)
268 },
269 { /* S6: SM NETWORK MODIFYING ADDITIONAL TFTS */
270 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
271 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state),
272 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
273 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
274 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_active),
275 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
276 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, handle_modify_pdp_context_request_in_S6),
277 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, handle_modify_pdp_context_accept_in_S6),
278 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, handle_modify_pdp_context_reject_in_S6),
279 M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state),
280 M_TRANSITION(SM_M_SM_STATUS, state_event_error),
281 M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind),
282 M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind),
283 M_TRANSITION(SM_T_T3380, state_event_error),
284 M_TRANSITION(SM_T_T3380_MAX, state_event_error),
285 M_TRANSITION(SM_T_T3381, handle_T3381),
286 M_TRANSITION(SM_T_T3381_MAX, handle_T3381_max_in_S6),
287 M_TRANSITION(SM_T_T3390, state_event_error),
288 M_TRANSITION(SM_T_T3390_MAX, state_event_error),
289 M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error),
290 M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error),
291 M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local),
292 M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error),
293 M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error),
294 M_TRANSITION(SM_I_NETWORK_DEACTIVATE, handle_deactivate_during_modification)
295 },
296 { /* S7: SM NETWORK DEACTIVATING */
297 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
298 M_TRANSITION(SM_M_ACTIVATE_PDP_CONTEXT_REJECT, message_incompatible_with_state),
299 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
300 M_TRANSITION(SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
301 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, handle_deactivate_pdp_context_request_while_deactivating),
302 M_TRANSITION(SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, handle_deactivate_pdp_context_accept),
303 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REQUEST, message_incompatible_with_state),
304 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_ACCEPT, message_incompatible_with_state),
305 M_TRANSITION(SM_M_MODIFY_PDP_CONTEXT_REJECT, message_incompatible_with_state),
306 M_TRANSITION(SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, message_incompatible_with_state),
307 M_TRANSITION(SM_M_SM_STATUS, state_event_error),
308 M_TRANSITION(SM_P_MMPM_RESUME_IND, handle_mmpm_resume_ind),
309 M_TRANSITION(SM_P_MMPM_SUSPEND_IND, handle_mmpm_suspend_ind),
310 M_TRANSITION(SM_T_T3380, state_event_error),
311 M_TRANSITION(SM_T_T3380_MAX, state_event_error),
312 M_TRANSITION(SM_T_T3381, state_event_error),
313 M_TRANSITION(SM_T_T3381_MAX, state_event_error),
314 M_TRANSITION(SM_T_T3390, handle_T3390),
315 M_TRANSITION(SM_T_T3390_MAX, handle_T3390_max),
316 M_TRANSITION(SM_I_NETWORK_ACTIVATE_PRIMARY, state_event_error),
317 M_TRANSITION(SM_I_NETWORK_ACTIVATE_SECONDARY, state_event_error),
318 M_TRANSITION(SM_I_NETWORK_DEACTIVATE_LOCAL, handle_deactivate_local),
319 M_TRANSITION(SM_I_NETWORK_MODIFY, state_event_error),
320 M_TRANSITION(SM_I_NETWORK_REQUEST_ACTIVATION_REJECT, state_event_error),
321 M_TRANSITION(SM_I_NETWORK_DEACTIVATE, ignored)
322 }
323 };
324
325 /*==== PRIVATE FUNCTIONS ====================================================*/
326
327 /*
328 +------------------------------------------------------------------------------
329 | Function : sm_nw_mark_context_active
330 +------------------------------------------------------------------------------
331 | Description : Mark context in network state ACTIVE
332 |
333 | Parameters : nsapi - context index
334 +------------------------------------------------------------------------------
335 */
336 static void sm_nw_mark_context_active(int /*@alt U8@*/ nsapi)
337 {
338 sm_data.sm_context_activation_status
339 = sm_add_nsapi_to_nsapi_set(nsapi, sm_data.sm_context_activation_status);
340 }
341
342 /*
343 +------------------------------------------------------------------------------
344 | Function : sm_nw_mark_context_inactive
345 +------------------------------------------------------------------------------
346 | Description : Mark context in network state INACTIVE
347 |
348 | Parameters : nsapi - context index
349 +------------------------------------------------------------------------------
350 */
351 static void sm_nw_mark_context_inactive(int /*@alt U8@*/ nsapi)
352 {
353 sm_data.sm_context_activation_status
354 = sm_remove_nsapi_from_nsapi_set(nsapi, sm_data.sm_context_activation_status);
355 }
356
357 /*
358 +------------------------------------------------------------------------------
359 | Function : sm_nw_mark_nsapi_set_inactive
360 +------------------------------------------------------------------------------
361 | Description : Mark a set of contexts in network state INACTIVE
362 |
363 | Parameters : nsapi_set - Set of NSAPIs to mark inactive
364 +------------------------------------------------------------------------------
365 */
366 static void sm_nw_mark_nsapi_set_inactive(U16 nsapi_set)
367 {
368 sm_data.sm_context_activation_status &= 0xffff ^ nsapi_set;
369 }
370
371 /*
372 +------------------------------------------------------------------------------
373 | Function : sm_nw_get_next_free_ti
374 +------------------------------------------------------------------------------
375 | Description : Traverse sm_context_array and find the lowest unused TI.
376 |
377 | Parameters : context - context that needs TI
378 +------------------------------------------------------------------------------
379 */
380 static U8 sm_nw_get_next_free_ti(struct T_SM_CONTEXT_DATA *context_to_get_ti)
381 {
382 int nsapi;
383 U16 ti_mask = (U16)0x07ff;
384
385 /* Iterate through sm_context_array and find the lowest available TI */
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 && context != context_to_get_ti
392 && (context->ti & (U8)SM_TI_FLAG) == (U8)0 )
393 {
394 ti_mask &= 0x7ff ^ (1 << context->ti);
395 }
396 }
397
398 if (ti_mask != 0)
399 {
400 int index;
401 for (index = 0;
402 index < SM_MAX_NSAPI_OFFSET && (ti_mask & (1UL << (U16)index)) == 0;
403 index++)
404 {};
405 return (U8)index;
406 } else {
407 /* No TIs available */
408 return (U8)0;
409 }
410 }
411
412 /*
413 +------------------------------------------------------------------------------
414 | Function : sm_nw_initiate_deactivation
415 +------------------------------------------------------------------------------
416 | Description : General function for aborting a procedure and deactivating
417 |
418 | Parameters : context - context data
419 +------------------------------------------------------------------------------
420 */
421 static void sm_nw_initiate_deactivation(struct T_SM_CONTEXT_DATA *context,
422 T_CAUSE_ps_cause *ps_cause)
423 {
424 /* Stop any active timer and start T3390 in stead */
425 sm_timer_stop(context);
426 sm_timer_start(context, SM_TIMER_T3390);
427
428 /* Send message DEACTIVATE PDP CONTEXT REQUEST */
429 send_msg_deactivate_pdp_context_request(context, ps_cause, FALSE);
430 }
431
432 /*
433 +------------------------------------------------------------------------------
434 | Function : sm_nw_store_mt_modify_parameters
435 +------------------------------------------------------------------------------
436 | Description : Examines a T_D_MODIFY_PDP_CONTEXT_REQUEST message and stores
437 | the parameters included. Returns flags which indicate the
438 | parameters that were updated.
439 |
440 | Parameters : context - context data
441 | msg - T_D_MODIFY_PDP_CONTEXT_REQUEST
442 +------------------------------------------------------------------------------
443 */
444 static T_SM_UPDATE_FLAGS
445 sm_nw_store_mt_modify_parameters(struct T_SM_CONTEXT_DATA *context,
446 T_D_MODIFY_PDP_CONTEXT_REQUEST *msg)
447 {
448 T_SM_UPDATE_FLAGS update_flags;
449 sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos);
450
451 update_flags = SM_UPDATE_QOS;
452
453 /* Store GSM RAT parameters, if present */
454 if (context->radio_prio != msg->radio_prio.radio_prio_val ||
455 context->sapi != msg->llc_sapi.sapi)
456 {
457 context->radio_prio = msg->radio_prio.radio_prio_val;
458 context->sapi = msg->llc_sapi.sapi;
459 update_flags |= SM_UPDATE_SAPI_RADIO_PRIO_PFI;
460 }
461
462 /* Store PFI, if present */
463 if (msg->v_pfi != (U8)FALSE && msg->pfi.pfi_val != context->pfi)
464 {
465 sm_set_pfi_included(context, TRUE);
466 context->pfi = msg->pfi.pfi_val;
467 update_flags |= SM_UPDATE_SAPI_RADIO_PRIO_PFI;
468 }
469
470 /* IP address "modified" (== assigned late)? Store, if so. */
471 if (msg->v_address != (U8)FALSE)
472 {
473 sm_nw_store_negotiated_address(context, &msg->address, msg->v_address);
474 update_flags |= SM_UPDATE_ADDRESS;
475 }
476
477 return update_flags;
478 }
479
480 /*
481 +------------------------------------------------------------------------------
482 | Function : sm_nw_store_modify_accept_parameters
483 +------------------------------------------------------------------------------
484 | Description : Examines a T_D_MODIFY_PDP_CONTEXT_ACCEPT message and stores
485 | the parameters included. Returns flags which indicate the
486 | parameters that were updated.
487 |
488 | Parameters : context - context data
489 | msg - T_D_MODIFY_PDP_CONTEXT_REQUEST
490 +------------------------------------------------------------------------------
491 */
492 static T_SM_UPDATE_FLAGS
493 sm_nw_store_modify_accept_parameters(struct T_SM_CONTEXT_DATA *context,
494 T_D_MODIFY_PDP_CONTEXT_ACCEPT *msg)
495 {
496 T_SM_UPDATE_FLAGS update_flags = (T_SM_UPDATE_FLAGS)0;
497
498 /* Store GSM RAT parameters, if present */
499 if (msg->v_llc_sapi != (U8)FALSE)
500 {
501 context->sapi = msg->llc_sapi.sapi;
502 update_flags = SM_UPDATE_SAPI_RADIO_PRIO_PFI;
503 }
504
505 if (msg->v_radio_prio != (U8)FALSE &&
506 msg->radio_prio.radio_prio_val != context->radio_prio)
507 {
508 context->radio_prio = msg->radio_prio.radio_prio_val;
509 update_flags = SM_UPDATE_SAPI_RADIO_PRIO_PFI;
510 }
511
512 /* Store PFI, if present */
513 if (msg->v_pfi != (U8)FALSE &&
514 msg->pfi.pfi_val != context->pfi)
515 {
516 sm_set_pfi_included(context, TRUE);
517 context->pfi = msg->pfi.pfi_val;
518 update_flags = SM_UPDATE_SAPI_RADIO_PRIO_PFI;
519 }
520
521 return update_flags;
522 }
523
524 /*
525 +------------------------------------------------------------------------------
526 | Function : state_event_error
527 +------------------------------------------------------------------------------
528 | Description : General function used to report state event errors.
529 |
530 | Parameters : context - Not used
531 | data - Not used
532 +------------------------------------------------------------------------------
533 */
534 static void state_event_error(/*@unused@*/ struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data)
535 {
536 (void)TRACE_ERROR("SM Network Control: STATE EVENT ERROR!");
537 }
538
539 /*
540 +------------------------------------------------------------------------------
541 | Function : ignored
542 +------------------------------------------------------------------------------
543 | Description : General function used for transitions that shall be ignored
544 |
545 | Parameters : context - Not used
546 | data - Not used
547 +------------------------------------------------------------------------------
548 */
549 static void ignored(/*@unused@*/ struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data)
550 {
551 (void)TRACE_FUNCTION("SM Network Control: Event ignored.");
552 }
553
554 /*
555 +------------------------------------------------------------------------------
556 | Function : message_incompatible_with_state
557 +------------------------------------------------------------------------------
558 | Description : General function used for reporting illegal air interface
559 | messages in the current state
560 |
561 | Parameters : context - Context data
562 | data - Not used
563 +------------------------------------------------------------------------------
564 */
565 static void message_incompatible_with_state(/*@unused@*/ struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data)
566 {
567 (void)TRACE_FUNCTION("message_incompatible_with_state");
568
569 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_MSG_TYPE_INCOMPATIBLE_WITH_STATE);
570 send_msg_sm_status(context->ti, sm_get_nw_cause(context));
571 }
572
573 /*
574 +------------------------------------------------------------------------------
575 | Function : message_for_invalid_ti
576 +------------------------------------------------------------------------------
577 | Description : General function used for replying to network messages
578 | received for a context in state S0 (invalid TI)
579 |
580 | Parameters : context - Context data
581 | data - Not used
582 +------------------------------------------------------------------------------
583 */
584 static void message_for_invalid_ti(/*@unused@*/ struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data)
585 {
586 (void)TRACE_FUNCTION("message_for_invalid_ti");
587
588 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_INVALID_TI);
589 send_msg_sm_status(context->ti, sm_get_nw_cause(context));
590 }
591
592 /*
593 +------------------------------------------------------------------------------
594 | Function : handle_activate_primary
595 +------------------------------------------------------------------------------
596 | Description : Handle event SM_I_NETWORK_ACTIVATE_PRIMARY in S0
597 |
598 | Parameters : context - Context data
599 | data - SMREG_PDP_ACTIVATE_REQ *
600 +------------------------------------------------------------------------------
601 */
602 static void handle_activate_primary(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
603 {
604 T_SMREG_PDP_ACTIVATE_REQ *prim = (T_SMREG_PDP_ACTIVATE_REQ *)data;
605
606 (void)TRACE_FUNCTION("handle_activate_primary");
607
608 if (prim != NULL)
609 {
610 memcpy(&context->comp_params, &prim->comp_params, sizeof(T_NAS_comp_params));
611
612 sm_qos_copy_to_sm(&context->requested_qos, &prim->qos, prim->ctrl_qos);
613 sm_qos_copy_to_sm(&context->minimum_qos, (T_PS_qos *)&prim->min_qos,
614 (T_PS_ctrl_qos)prim->ctrl_min_qos);
615
616 sm_nw_store_requested_address(context, prim->pdp_type,
617 prim->ctrl_ip_address, &prim->ip_address);
618
619 /* Free APN (necessary if this is a network requested activation) */
620 sm_nw_free_apn(context);
621
622 /* Store APN for negotiation, if present */
623 if (prim->apn.c_apn_buf > (U8)0)
624 {
625 sm_nw_allocate_and_copy_apn(context, prim->apn.c_apn_buf, prim->apn.apn_buf);
626 }
627
628 /* Store TFT for later addition, if present */
629 TRACE_ASSERT(context->requested_tft.ptr_tft_pf == NULL);
630 if (prim->v_tft != (U8)FALSE && prim->tft.c_tft_pf > (U8)0)
631 {
632 sm_nw_allocate_and_copy_requested_tft(context, &prim->tft);
633 } else {
634 context->requested_tft.c_tft_pf = (U8)0;
635 }
636
637 /* Store PCO for negotiation, if present */
638 sm_nw_free_requested_pco(context);
639 if (prim->sdu.l_buf > 0)
640 {
641 U16 pco_len = prim->sdu.l_buf >> 3;
642 sm_nw_allocate_and_copy_requested_pco(context, pco_len,
643 &prim->sdu.buf[(prim->sdu.o_buf >> 3)]);
644 }
645
646 /* Allocate TI for context unless this was a NW initiated activation */
647 if ((context->ti & SM_TI_FLAG) == (U8)0)
648 {
649 context->ti = sm_nw_get_next_free_ti(context);
650 }
651 } else {
652 /* No SMREG primitive: This is a re-activation. Use current parameters. */
653 /* The following function call can cause problems in reactivation cases
654 * where the first pdp context uses dynamic addressing. When the following
655 * function is called the 'reactivated' context uses address issued by the
656 * network for the first pdp activation. This will result in static addressing
657 * and may cause pdp activation reject from networks that doesn't support
658 * static addressing.
659 */
660 /*sm_nw_copy_negotiated_address_to_requested(context);*/
661 }
662
663 /* Mark context as active */
664 sm_nw_mark_context_active(context->nsapi);
665
666 /* Start timer T3380 for this NSAPI/context */
667 sm_timer_start(context, SM_TIMER_T3380);
668
669 /* Send ACTIVATE PDP CONTEXT REQUEST message */
670 send_msg_activate_pdp_context_request(context);
671
672 /* Go to state SM NETWORK ACTIVATING PRIMARY */
673 context->network_control_state = SM_NETWORK_ACTIVATING_PRIMARY;
674 }
675
676 /*
677 +------------------------------------------------------------------------------
678 | Function : handle_activate_secondary
679 +------------------------------------------------------------------------------
680 | Description : Handle event SM_I_NETWORK_ACTIVATE_SECONDARY in S0
681 |
682 | Parameters : context - Context data
683 | data - T_SMREG_PDP_ACTIVATE_SEC_REQ *
684 +------------------------------------------------------------------------------
685 */
686 static void handle_activate_secondary(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
687 {
688 T_SMREG_PDP_ACTIVATE_SEC_REQ *prim = (T_SMREG_PDP_ACTIVATE_SEC_REQ *)data;
689
690 (void)TRACE_FUNCTION("handle_activate_secondary");
691
692 if (prim != NULL)
693 {
694 memcpy(&context->comp_params, &prim->comp_params, sizeof(T_NAS_comp_params));
695
696 sm_qos_copy_to_sm(&context->requested_qos, &prim->qos, prim->ctrl_qos);
697 sm_qos_copy_to_sm(&context->minimum_qos, (T_PS_qos *)&prim->min_qos,
698 (T_PS_ctrl_qos)prim->ctrl_min_qos);
699
700 /* Store TFT for later addition, if present */
701 sm_nw_free_requested_tft(context);
702 if (prim->v_tft != (U8)FALSE && prim->tft.c_tft_pf > (U8)0)
703 {
704 sm_nw_allocate_and_copy_requested_tft(context, &prim->tft);
705 } else {
706 context->requested_tft.c_tft_pf = (U8)0;
707 }
708 /* Allocate TI for context */
709 context->ti = sm_nw_get_next_free_ti(context);
710 } else {
711 /* No SMREG primitive: This is a re-activation. Use current parameters. */
712 }
713
714 /* Mark context as active */
715 sm_nw_mark_context_active(context->nsapi);
716
717 /* Start timer T3380 for this NSAPI/context */
718 sm_timer_start(context, SM_TIMER_T3380);
719
720 /* Send ACTIVATE SECONDARY PDP CONTEXT REQUEST message */
721 send_msg_activate_secondary_pdp_context_request(context);
722
723 /* Go to state SM NETWORK ACTIVATING SECONDARY */
724 context->network_control_state = SM_NETWORK_ACTIVATING_SECONDARY;
725 }
726
727 /*
728 +------------------------------------------------------------------------------
729 | Function : handle_request_activation_reject
730 +------------------------------------------------------------------------------
731 | Description : Handle event SM_I_NETWORK_REQUEST_ACTIVATION_REJECT in S0
732 |
733 | Parameters : context - Context data
734 | data - Not used (cause set in context data)
735 +------------------------------------------------------------------------------
736 */
737 static void handle_request_activation_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data)
738 {
739 (void)TRACE_FUNCTION("handle_request_activation_reject");
740
741 /* Send REQUEST PDP CONTEXT ACTIVATION REJECT message */
742 send_msg_request_pdp_context_activation_reject(context, sm_get_nw_cause(context));
743 }
744
745 /*
746 +------------------------------------------------------------------------------
747 | Function : handle_modify_in_S4
748 +------------------------------------------------------------------------------
749 | Description : Handle event SM_I_NETWORK_MODIFY in S4
750 |
751 | Parameters : context - Context data
752 | data - T_SMREG_PDP_MODIFY_REQ *
753 +------------------------------------------------------------------------------
754 */
755 static void handle_modify_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
756 {
757 T_SMREG_PDP_MODIFY_REQ *prim = (T_SMREG_PDP_MODIFY_REQ *)data;
758 BOOL start_modification = FALSE;
759
760 (void)TRACE_FUNCTION("handle_modify_in_S4");
761
762 /* If prim == NULL this is a context upgrade (RAB re-establishment) */
763 if (prim != NULL)
764 {
765 if (prim->ctrl_qos != PS_is_qos_not_present)
766 {
767 sm_qos_copy_to_sm(&context->requested_qos, &prim->qos, prim->ctrl_qos);
768 start_modification = TRUE;
769 }
770
771 if (prim->ctrl_min_qos != PS_is_min_qos_not_present)
772 {
773 sm_qos_copy_to_sm(&context->minimum_qos, (T_PS_qos *)&prim->min_qos,
774 (T_PS_ctrl_qos)prim->ctrl_min_qos);
775 if (!sm_qos_is_minimum_satisfied_by_sm(context, &context->accepted_qos))
776 {
777 start_modification = TRUE;
778 }
779 }
780
781 /* Store TFT for later addition, if present */
782 if (prim->v_tft != (U8)FALSE)
783 {
784 if (prim->tft.c_tft_pf > (U8)0)
785 {
786 sm_nw_allocate_and_copy_requested_tft(context, &prim->tft);
787 } else {
788 context->requested_tft.c_tft_pf = (U8)0;
789 }
790 if (sm_tft_more_to_modify(context))
791 {
792 start_modification = TRUE;
793 }
794 }
795 } else {
796 /* Prim == NULL: context upgrade (RAB re-establishment) */
797 /* Start modification with originally requested parameters */
798 start_modification = TRUE;
799 }
800
801 if (start_modification)
802 {
803 /* Start timer T3381 for this NSAPI/context */
804 sm_timer_start(context, SM_TIMER_T3381);
805
806 /* Send MODIFY PDP CONTEXT REQUEST message */
807 send_msg_modify_pdp_context_request(context);
808
809 /* Go to state SM NETWORK MODIFYING */
810 context->network_control_state = SM_NETWORK_MODIFYING;
811 }
812 }
813
814 /*
815 +------------------------------------------------------------------------------
816 | Function : handle_deactivate_in_S0
817 +------------------------------------------------------------------------------
818 | Description : Handle event SM_I_NETWORK_DEACTIVATE in S0
819 |
820 | Parameters : context - Context data
821 | data - rel_ind flag
822 +------------------------------------------------------------------------------
823 */
824 static void handle_deactivate_in_S0(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
825 {
826 (void)TRACE_FUNCTION("handle_deactivate_in_S0");
827
828 /* Report success deactivation to Context Control (already inactive) */
829 sm_context_control(context, SM_I_NETWORK_DEACTIVATE_COMPLETED, data);
830 }
831
832 /*
833 +------------------------------------------------------------------------------
834 | Function : handle_deactivate_during_activation
835 +------------------------------------------------------------------------------
836 | Description : Handle event SM_I_NETWORK_DEACTIVATE in S1 or S2
837 |
838 | Parameters : context - Context data
839 | data - Cause (T_CAUSE_ps_cause *)
840 +------------------------------------------------------------------------------
841 */
842 static void handle_deactivate_during_activation(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
843 {
844 (void)TRACE_FUNCTION("handle_deactivate_during_activation");
845
846 TRACE_ASSERT(data != NULL);
847
848 /* Go to state SM NETWORK DEACTIVATING */
849 context->network_control_state = SM_NETWORK_DEACTIVATING;
850
851 /* Stop T3380, and start deactivation */
852 sm_nw_initiate_deactivation(context, (T_CAUSE_ps_cause *)data);
853 }
854
855 /*
856 +------------------------------------------------------------------------------
857 | Function : handle_deactivate_in_S4
858 +------------------------------------------------------------------------------
859 | Description : Handle event SM_I_NETWORK_DEACTIVATE in S4
860 |
861 | Parameters : context - Context data
862 | data - Cause (T_CAUSE_ps_cause *)
863 +------------------------------------------------------------------------------
864 */
865 static void handle_deactivate_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
866 {
867 (void)TRACE_FUNCTION("handle_deactivate_in_S4");
868
869 TRACE_ASSERT(data != NULL);
870
871 /* Go to state SM NETWORK DEACTIVATING */
872 context->network_control_state = SM_NETWORK_DEACTIVATING;
873
874 /* Initiate deactivation; data contains cause */
875 sm_nw_initiate_deactivation(context, (T_CAUSE_ps_cause *)data);
876 }
877
878 /*
879 +------------------------------------------------------------------------------
880 | Function : handle_deactivate_during_modification
881 +------------------------------------------------------------------------------
882 | Description : Handle event SM_I_NETWORK_DEACTIVATE in S3, S5, or S6
883 |
884 | Parameters : context - Context data
885 | data - Cause (T_CAUSE_ps_cause *)
886 +------------------------------------------------------------------------------
887 */
888 static void handle_deactivate_during_modification(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
889 {
890 (void)TRACE_FUNCTION("handle_deactivate_during_modification");
891
892 TRACE_ASSERT(data != NULL);
893
894 /* Go to state SM NETWORK DEACTIVATING */
895 context->network_control_state = SM_NETWORK_DEACTIVATING;
896
897 /* Initiate deactivation; data contains cause */
898 sm_nw_initiate_deactivation(context, (T_CAUSE_ps_cause *)data);
899 }
900
901 /*
902 +------------------------------------------------------------------------------
903 | Function : handle_deactivate_local
904 +------------------------------------------------------------------------------
905 | Description : Handle SM_I_NETWORK_DEACTIVATE_LOCAL
906 |
907 | Parameters : context - context data
908 | data - unused
909 +------------------------------------------------------------------------------
910 */
911 static void handle_deactivate_local(struct T_SM_CONTEXT_DATA *context, /*@unused@*/ /*@null@*/ void *data)
912 {
913 /* Remove active TFT - this is necessary in case of reactivations */
914 sm_nw_free_active_tft(context);
915
916 /* Free stored coded message - if any */
917 sm_free_coded_msg(context);
918
919 /* Mark context as inactive */
920 sm_nw_mark_context_inactive(context->nsapi);
921
922 context->network_control_state = SM_NETWORK_DEACTIVATED;
923 }
924
925 /*
926 +------------------------------------------------------------------------------
927 | Function : handle_activate_pdp_context_accept
928 +------------------------------------------------------------------------------
929 | Description : Handle event SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT in S1
930 |
931 | Parameters : context - Context data
932 | data - T_ACTIVATE_PDP_CONTEXT_ACCEPT *
933 +------------------------------------------------------------------------------
934 */
935 static void handle_activate_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
936 {
937 T_ACTIVATE_PDP_CONTEXT_ACCEPT *msg = (T_ACTIVATE_PDP_CONTEXT_ACCEPT *)data;
938 T_SM_UPDATE_FLAGS update_flags = (T_SM_UPDATE_FLAGS)0;
939 BOOL is_address_changed = FALSE;
940
941 (void)TRACE_FUNCTION("handle_activate_pdp_context_accept");
942
943 TRACE_ASSERT(msg != NULL);
944
945 if (msg EQ NULL)
946 return;
947
948 /* Free stored coded message */
949 sm_free_coded_msg(context);
950
951 /* Stop timer T3380 */
952 sm_timer_stop(context);
953
954 if (!sm_is_llc_sapi_valid(msg->llc_sapi.sapi, context->ti))
955 {
956 return;
957 }
958
959 is_address_changed = sm_is_address_changed_with_reactivation(context,
960 &msg->address, msg->v_address);
961 /* Check whether negotiated QoS satisfies minimum QoS */
962 if ( sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos) &&
963 !(is_address_changed) )
964 {
965 if (context->accepted_qos.ctrl_qos != PS_is_qos_not_present)
966 {
967 update_flags |= SM_UPDATE_QOS;
968 }
969
970 /* QoS >= minimum QoS: Store negotiated parameters */
971 sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos);
972
973 /* Store GSM RAT parameters */
974 context->radio_prio = msg->radio_prio.radio_prio_val;
975 context->sapi = msg->llc_sapi.sapi;
976
977 /* Store PFI, if present */
978 if (msg->v_pfi != (U8)FALSE)
979 {
980 sm_set_pfi_included(context, TRUE);
981 context->pfi = msg->pfi.pfi_val;
982 } else {
983 sm_set_pfi_included(context, FALSE);
984 }
985
986 /* Store negotiated IP address, if any */
987 sm_nw_store_negotiated_address(context, &msg->address, msg->v_address);
988
989 /* Store negotiated PCO, if any */
990 if (msg->v_pco != (U8)FALSE && msg->pco.c_pco_value > (U8)0)
991 {
992 sm_nw_allocate_and_copy_negotiated_pco(context, msg->pco.c_pco_value,
993 msg->pco.pco_value);
994 } else {
995 context->negotiated_pco = NULL;
996 }
997
998 /* Check whether to add TFT */
999 if (sm_tft_more_to_modify(context))
1000 {
1001 /* Start T3381 */
1002 sm_timer_start(context, SM_TIMER_T3381);
1003 /* Send MODIFY PDP CONTEXT REQUEST with remaining TFTs */
1004 send_msg_modify_pdp_context_request(context);
1005 /* Go to state SM NETWORK ACTIVATING ADDING TFTS */
1006 context->network_control_state = SM_NETWORK_ACTIVATING_ADDING_TFTS;
1007 } else {
1008 /* No TFT: go to state SM NETWORK ACTIVATED, and inform Context Control */
1009 context->network_control_state = SM_NETWORK_ACTIVATED;
1010
1011 sm_context_control(context, SM_I_NETWORK_ACTIVATE_COMPLETED,
1012 (void *)update_flags);
1013 }
1014 } else { /* if (sm_qos_is_minimum_satisfied_by_aim()) */
1015 /* Minimum QoS not satisfied - Start deactivation, T3390 */
1016 sm_timer_start(context, SM_TIMER_T3390);
1017
1018 /* Send DEACTIVATE PDP CONTEXT REQUEST message */
1019 if (is_address_changed) {
1020 sm_set_nw_cause(context, CAUSE_is_from_nwsm,
1021 (U16)CAUSE_NWSM_REGULAR_DEACTIVATION);
1022 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION);
1023 }
1024 else {
1025 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1026 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1027 }
1028 send_msg_deactivate_pdp_context_request(context, sm_get_nw_cause(context), FALSE);
1029
1030 /* Go to state SM NETWORK DEACTIVATING */
1031 context->network_control_state = SM_NETWORK_DEACTIVATING;
1032
1033 /* Report failed activation to Context Control (with network deactivation) */
1034
1035 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE);
1036 } /* if */
1037 }
1038
1039 /*
1040 +------------------------------------------------------------------------------
1041 | Function : handle_activate_pdp_context_reject
1042 +------------------------------------------------------------------------------
1043 | Description : Handle event SM_M_ACTIVATE_PDP_CONTEXT_REJECT in S1
1044 |
1045 | Parameters : context - Context data
1046 | data - T_ACTIVATE_PDP_CONTEXT_REJECT *
1047 +------------------------------------------------------------------------------
1048 */
1049 static void handle_activate_pdp_context_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1050 {
1051 T_ACTIVATE_PDP_CONTEXT_REJECT *msg = (T_ACTIVATE_PDP_CONTEXT_REJECT *)data;
1052 (void)TRACE_FUNCTION("handle_activate_pdp_context_reject");
1053
1054 TRACE_ASSERT(msg != NULL);
1055
1056 if (msg EQ NULL)
1057 return;
1058
1059 /* Free stored coded message */
1060 sm_free_coded_msg(context);
1061
1062 /* Store erroneous PCO, if any */
1063 if (msg->v_pco != (U8)FALSE && msg->pco.c_pco_value > (U8)0)
1064 {
1065 sm_nw_allocate_and_copy_negotiated_pco(context, msg->pco.c_pco_value,
1066 msg->pco.pco_value);
1067 } else {
1068 context->negotiated_pco = NULL;
1069 }
1070
1071 /* Stop timer T3380 */
1072 sm_timer_stop(context);
1073
1074 /* Go to state SM NETWORK DEACTIVATED */
1075 context->network_control_state = SM_NETWORK_DEACTIVATED;
1076
1077 /* Mark context as inactive */
1078 sm_nw_mark_context_inactive(context->nsapi);
1079
1080 /* Build cause structure */
1081 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val);
1082
1083 /* Re-synchronise MMs PDP context status */
1084 send_mmpm_pdp_context_status_req();
1085
1086 /* Report failed activation to Context Control (no network deactivation) */
1087 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)FALSE);
1088 }
1089
1090 /*
1091 +------------------------------------------------------------------------------
1092 | Function : handle_activate_secondary_pdp_context_accept
1093 +------------------------------------------------------------------------------
1094 | Description : Handle event SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT
1095 |
1096 | Parameters : context - Context data
1097 | data - T_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT *
1098 +------------------------------------------------------------------------------
1099 */
1100 static void handle_activate_secondary_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1101 {
1102 T_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT *msg = (T_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT *)data;
1103
1104 (void)TRACE_FUNCTION("handle_activate_secondary_pdp_context_accept");
1105
1106 TRACE_ASSERT(msg != NULL);
1107
1108 if (msg EQ NULL)
1109 return;
1110
1111 /* Free stored coded message */
1112 sm_free_coded_msg(context);
1113
1114 /* Stop timer T3380 */
1115 sm_timer_stop(context);
1116
1117 if (!sm_is_llc_sapi_valid(msg->llc_sapi.sapi, context->ti))
1118 {
1119 return;
1120 }
1121
1122 /* Check whether negotiated QoS satisfies minimum QoS */
1123 if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos))
1124 {
1125 /* QoS >= minimum QoS: Store negotiated parameters */
1126 sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos);
1127
1128 /* Store GSM RAT parameters */
1129 context->radio_prio = msg->radio_prio.radio_prio_val;
1130 context->sapi = msg->llc_sapi.sapi;
1131
1132 /* Store PFI, if present */
1133 if (msg->v_pfi != (U8)FALSE)
1134 {
1135 sm_set_pfi_included(context, TRUE);
1136 context->pfi = msg->pfi.pfi_val;
1137 } else {
1138 sm_set_pfi_included(context, FALSE);
1139 }
1140
1141 /* Check whether to add TFT */
1142 if (sm_tft_more_to_modify(context))
1143 {
1144 /* Start T3381 */
1145 sm_timer_start(context, SM_TIMER_T3381);
1146 /* Send MODIFY PDP CONTEXT REQUEST with remaining TFTs */
1147 send_msg_modify_pdp_context_request(context);
1148 /* Go to state SM NETWORK ACTIVATING ADDING TFTS */
1149 context->network_control_state = SM_NETWORK_ACTIVATING_ADDING_TFTS;
1150 } else {
1151 /* No TFT: go to state SM NETWORK ACTIVATED, and inform Context Control */
1152 context->network_control_state = SM_NETWORK_ACTIVATED;
1153
1154 sm_context_control(context, SM_I_NETWORK_ACTIVATE_COMPLETED, NULL);
1155 }
1156 } else { /* if (sm_qos_is_minimum_satisfied_by_aim()) */
1157 /* Minimum QoS not satisfied - go to state SM NETWORK DEACTIVATING */
1158 context->network_control_state = SM_NETWORK_DEACTIVATING;
1159
1160 /* Start deactivation, T3390 */
1161 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1162 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1163
1164 /* Report failed activation to Context Control (with network deactivation) */
1165 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1166 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE);
1167 } /* if */
1168 }
1169
1170 /*
1171 +------------------------------------------------------------------------------
1172 | Function : handle_activate_secondary_pdp_context_reject
1173 +------------------------------------------------------------------------------
1174 | Description : Handle event SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT
1175 |
1176 | Parameters : context - Context data
1177 | data - T_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT *
1178 +------------------------------------------------------------------------------
1179 */
1180 static void handle_activate_secondary_pdp_context_reject(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1181 {
1182 T_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT *msg = (T_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT *)data;
1183 (void)TRACE_FUNCTION("handle_activate_secondary_pdp_context_reject");
1184
1185 TRACE_ASSERT(msg != NULL);
1186
1187 if (msg EQ NULL)
1188 return;
1189
1190 /* Free stored coded message */
1191 sm_free_coded_msg(context);
1192
1193 /* Stop timer T3380 */
1194 sm_timer_stop(context);
1195
1196 /* Go to state SM NETWORK DEACTIVATED */
1197 context->network_control_state = SM_NETWORK_DEACTIVATED;
1198
1199 /* Mark context as inactive */
1200 sm_nw_mark_context_inactive(context->nsapi);
1201
1202 /* Build cause structure */
1203 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val);
1204
1205 /* Re-synchronise MMs PDP context status */
1206 send_mmpm_pdp_context_status_req();
1207
1208 /* Report failed activation to Context Control (no network deactivation) */
1209 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)FALSE);
1210 }
1211
1212 /*
1213 +------------------------------------------------------------------------------
1214 | Function : handle_request_pdp_context_activation_in_S0
1215 +------------------------------------------------------------------------------
1216 | Description : Handle event SM_M_REQUEST_PDP_CONTEXT_ACTIVATION in S0
1217 |
1218 | Parameters : context - Context data
1219 | data - T_REQUEST_PDP_CONTEXT_ACTIVATION *
1220 +------------------------------------------------------------------------------
1221 */
1222 static void handle_request_pdp_context_activation_in_S0(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1223 {
1224 T_REQUEST_PDP_CONTEXT_ACTIVATION *msg = (T_REQUEST_PDP_CONTEXT_ACTIVATION *)data;
1225
1226 (void)TRACE_FUNCTION("handle_request_pdp_context_activation_in_S0");
1227
1228 TRACE_ASSERT(msg != NULL);
1229
1230 if (msg EQ NULL)
1231 return;
1232
1233 context->pdp_type = msg->address.pdp_type_no;
1234
1235 sm_nw_store_negotiated_address(context, &msg->address, (U8)TRUE);
1236
1237 if (msg->v_apn != (U8)FALSE)
1238 {
1239 sm_nw_allocate_and_copy_apn(context, msg->apn.c_apn_value, msg->apn.apn_value);
1240 } else {
1241 context->apn = NULL;
1242 }
1243
1244 /* Inform Context Control of activation request */
1245 sm_context_control(context, SM_I_NETWORK_REQUEST_ACTIVATION, msg);
1246 }
1247
1248 /*
1249 +------------------------------------------------------------------------------
1250 | Function : handle_request_pdp_context_activation_in_S1
1251 +------------------------------------------------------------------------------
1252 | Description : Handle event SM_M_REQUEST_PDP_CONTEXT_ACTIVATION in S1
1253 |
1254 | Parameters : context - Context data
1255 | data - T_REQUEST_PDP_CONTEXT_ACTIVATION *
1256 +------------------------------------------------------------------------------
1257 */
1258 static void handle_request_pdp_context_activation_in_S1(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1259 {
1260 T_REQUEST_PDP_CONTEXT_ACTIVATION *msg = (T_REQUEST_PDP_CONTEXT_ACTIVATION *)data;
1261 (void)TRACE_FUNCTION("handle_request_pdp_context_activation_in_S1");
1262
1263 TRACE_ASSERT(msg != NULL);
1264
1265 if (msg EQ NULL)
1266 return;
1267
1268 /*lint !e613 (Warning -- Possible use of null pointer) */
1269 if (sm_nw_is_address_and_apn_equal(context, &context->requested_address,
1270 &msg->address, msg->v_apn, &msg->apn))
1271 {
1272 /* Do nothing */
1273 } else {
1274 /* Reject incoming context activation */
1275 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_INSUFFICIENT_RESOURCES);
1276
1277 send_msg_request_pdp_context_activation_reject(context,
1278 sm_get_nw_cause(context));
1279 } /* if */
1280 }
1281
1282 /*
1283 +------------------------------------------------------------------------------
1284 | Function : handle_request_pdp_context_activation_in_S4
1285 +------------------------------------------------------------------------------
1286 | Description : Handle event SM_M_REQUEST_PDP_CONTEXT_ACTIVATION in S4
1287 |
1288 | Parameters : context - Context data
1289 | data - T_REQUEST_PDP_CONTEXT_ACTIVATION *
1290 +------------------------------------------------------------------------------
1291 */
1292 static void handle_request_pdp_context_activation_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1293 {
1294 T_REQUEST_PDP_CONTEXT_ACTIVATION *msg = (T_REQUEST_PDP_CONTEXT_ACTIVATION *)data;
1295 (void)TRACE_FUNCTION("handle_request_pdp_context_activation_in_S4");
1296
1297 TRACE_ASSERT(msg != NULL);
1298
1299 if (msg EQ NULL)
1300 return;
1301
1302 if (sm_nw_is_address_and_apn_equal(context, &context->negotiated_address,
1303 &msg->address, msg->v_apn, &msg->apn))
1304 {
1305 /* Go to state SM NETWORK ACTIVATING PRIMARY */
1306 context->network_control_state = SM_NETWORK_ACTIVATING_PRIMARY;
1307
1308 /* Inform Context Control of the activation override
1309 * NOTE! Normally other state machines are informed last, but in this
1310 * case we need to update sm_data.sm_context_activation_status _before_
1311 * sending ACTIVATE PDP CONTEXT REQUEST through MM. */
1312 sm_context_control(context, SM_I_NETWORK_REQUEST_ACTIVATION_OVERRIDE, NULL);
1313
1314 /* Context activation override - start context activation procedure */
1315 sm_timer_start(context, SM_TIMER_T3380);
1316
1317 /* This is akin to a context reactivation: Use currently negotiated IP address */
1318 sm_nw_copy_negotiated_address_to_requested(context);
1319
1320 send_msg_activate_pdp_context_request(context);
1321 } else {
1322 /* Reject incoming context activation */
1323 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_INSUFFICIENT_RESOURCES);
1324 send_msg_request_pdp_context_activation_reject(context, sm_get_nw_cause(context));
1325 } /* if */
1326 }
1327
1328 /*
1329 +------------------------------------------------------------------------------
1330 | Function : handle_modify_pdp_context_request_in_S3
1331 +------------------------------------------------------------------------------
1332 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REQUEST in S3
1333 |
1334 | Parameters : context - Context data
1335 | data - T_MODIFY_PDP_CONTEXT_REQUEST * (unused)
1336 +------------------------------------------------------------------------------
1337 */
1338 static void handle_modify_pdp_context_request_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
1339 {
1340 (void)TRACE_FUNCTION("handle_modify_pdp_context_request_in_S3");
1341
1342 /* Free coded message */
1343 sm_free_coded_msg(context);
1344
1345 /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */
1346 sm_set_nw_cause(context, CAUSE_is_from_nwsm,
1347 (U16)CAUSE_NWSM_MSG_INCOMPATIBLE_WITH_STATE);
1348 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1349
1350 /* Go to state SM NETWORK DEACTIVATING */
1351 context->network_control_state = SM_NETWORK_DEACTIVATING;
1352
1353 /* Inform Context Control of the failed activation (with network deactivation) */
1354 sm_set_aci_cause(context, CAUSE_is_from_nwsm,
1355 (U16)CAUSE_NWSM_MSG_INCOMPATIBLE_WITH_STATE);
1356 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE);
1357 }
1358
1359 /*
1360 +------------------------------------------------------------------------------
1361 | Function : handle_modify_pdp_context_request_in_S4
1362 +------------------------------------------------------------------------------
1363 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REQUEST in S4
1364 |
1365 | Parameters : context - Context data
1366 | data - T_D_MODIFY_PDP_CONTEXT_REQUEST *
1367 +------------------------------------------------------------------------------
1368 */
1369 static void handle_modify_pdp_context_request_in_S4(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1370 {
1371 T_D_MODIFY_PDP_CONTEXT_REQUEST *msg = (T_D_MODIFY_PDP_CONTEXT_REQUEST *)data;
1372 T_SM_UPDATE_FLAGS update_flags;
1373
1374 (void)TRACE_FUNCTION("handle_modify_pdp_context_request_in_S4");
1375
1376 TRACE_ASSERT(msg != NULL);
1377
1378 if (msg EQ NULL)
1379 return;
1380
1381 if (!sm_is_llc_sapi_valid(msg->llc_sapi.sapi, context->ti))
1382 {
1383 return;
1384 }
1385
1386 if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos))
1387 {
1388 /* QoS >= minimum QoS: Store negotiated parameters */
1389 update_flags = sm_nw_store_mt_modify_parameters(context, msg);
1390
1391 /* Go to state SM NETWORK ACTIVATED */
1392 context->network_control_state = SM_NETWORK_ACTIVATED;
1393
1394 /* Reply to network: MODIFY PDP CONTEXT ACCEPT */
1395 send_msg_modify_pdp_context_accept(context);
1396
1397 /* Report successful NW initiated context modification */
1398 sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY,
1399 (void *)update_flags);
1400 } else {
1401 /* Minimum QoS not satisfied - go to state SM NETWORK DEACTIVATING */
1402 context->network_control_state = SM_NETWORK_DEACTIVATING;
1403
1404 /* Start deactivation, T3390 */
1405 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1406 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1407
1408 /* Report failed activation to Context Control */
1409 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1410 sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY_FAILED, NULL);
1411 } /* if (sm_qos_is_minimum_satisfied_by_aim()) */
1412 }
1413
1414 /*
1415 +------------------------------------------------------------------------------
1416 | Function : handle_modify_pdp_context_request_in_S5
1417 +------------------------------------------------------------------------------
1418 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REQUEST in S5
1419 |
1420 | Parameters : context - Context data
1421 | data - T_D_MODIFY_PDP_CONTEXT_REQUEST *
1422 +------------------------------------------------------------------------------
1423 */
1424 static void handle_modify_pdp_context_request_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1425 {
1426 T_D_MODIFY_PDP_CONTEXT_REQUEST *msg = (T_D_MODIFY_PDP_CONTEXT_REQUEST *)data;
1427 T_SM_UPDATE_FLAGS update_flags;
1428
1429 (void)TRACE_FUNCTION("handle_modify_pdp_context_request_in_S5");
1430
1431 TRACE_ASSERT(msg != NULL);
1432
1433 if (msg EQ NULL)
1434 return;
1435
1436 /* Free coded message */
1437 sm_free_coded_msg(context);
1438
1439 /* Reject currently active UE initiated modification */
1440 sm_set_aci_cause(context, CAUSE_is_from_sm, (U16)CAUSE_SM_MODIFY_COLLISION);
1441 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)FALSE);
1442
1443 if (!sm_is_llc_sapi_valid(msg->llc_sapi.sapi, context->ti))
1444 {
1445 return;
1446 }
1447
1448 if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos))
1449 {
1450 /* QoS >= minimum QoS: Store negotiated parameters */
1451 update_flags = sm_nw_store_mt_modify_parameters(context, msg);
1452
1453 /* Go to state SM NETWORK ACTIVATED */
1454 context->network_control_state = SM_NETWORK_ACTIVATED;
1455
1456 /* Reply to network: MODIFY PDP CONTEXT ACCEPT */
1457 send_msg_modify_pdp_context_accept(context);
1458
1459 /* Report successful NW initiated context modification */
1460 sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY,
1461 (void *)update_flags);
1462 } else {
1463 /* Minimum QoS not satisfied - go to state SM NETWORK DEACTIVATING */
1464 context->network_control_state = SM_NETWORK_DEACTIVATING;
1465
1466 /* Start deactivation, T3390 */
1467 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1468 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1469
1470 /* Report failed activation to Context Control */
1471 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1472 sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY_FAILED, NULL);
1473 } /* if (sm_qos_is_minimum_satisfied_by_aim()) */
1474 }
1475
1476 /*
1477 +------------------------------------------------------------------------------
1478 | Function : handle_modify_pdp_context_request_in_S6
1479 +------------------------------------------------------------------------------
1480 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REQUEST in S6
1481 |
1482 | Parameters : context - Context data
1483 | data - T_MODIFY_PDP_CONTEXT_REQUEST * (unused)
1484 +------------------------------------------------------------------------------
1485 */
1486 static void handle_modify_pdp_context_request_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data)
1487 {
1488 (void)TRACE_FUNCTION("handle_modify_pdp_context_request_in_S6");
1489
1490 /* Free coded message */
1491 sm_free_coded_msg(context);
1492
1493 /* Reject currently active UE initiated modification */
1494 sm_set_aci_cause(context, CAUSE_is_from_sm, (U16)CAUSE_SM_MODIFY_COLLISION);
1495 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)FALSE);
1496
1497 /* Go to state SM NETWORK DEACTIVATING */
1498 context->network_control_state = SM_NETWORK_DEACTIVATING;
1499
1500 /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */
1501 sm_set_nw_cause(context, CAUSE_is_from_nwsm,
1502 (U16)CAUSE_NWSM_MSG_INCOMPATIBLE_WITH_STATE);
1503 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1504
1505 /* Inform Context Control of the failed modification */
1506 sm_set_aci_cause(context, CAUSE_is_from_nwsm,
1507 (U16)CAUSE_NWSM_MSG_INCOMPATIBLE_WITH_STATE);
1508 sm_context_control(context, SM_I_NETWORK_REQUEST_MODIFY_FAILED, NULL);
1509 }
1510
1511 /*
1512 +------------------------------------------------------------------------------
1513 | Function : handle_modify_pdp_context_accept_in_S3
1514 +------------------------------------------------------------------------------
1515 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_ACCEPT in S3
1516 |
1517 | Parameters : context - Context data
1518 | data - T_D_MODIFY_PDP_CONTEXT_ACCEPT *
1519 +------------------------------------------------------------------------------
1520 */
1521 static void handle_modify_pdp_context_accept_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1522 {
1523 T_D_MODIFY_PDP_CONTEXT_ACCEPT *msg = (T_D_MODIFY_PDP_CONTEXT_ACCEPT *)data;
1524 T_SM_UPDATE_FLAGS update_flags;
1525 (void)TRACE_FUNCTION("handle_modify_pdp_context_accept_in_S3");
1526
1527 TRACE_ASSERT(msg != NULL);
1528
1529 if (msg EQ NULL)
1530 return;
1531
1532 /* Free stored coded message */
1533 sm_free_coded_msg(context);
1534
1535 /* Stop timer T3381 */
1536 sm_timer_stop(context);
1537
1538 /* Store GSM RAT parameters, if present */
1539 update_flags = sm_nw_store_modify_accept_parameters(context, msg);
1540
1541 if (msg->v_qos != (U8)FALSE)
1542 {
1543 update_flags |= SM_UPDATE_QOS;
1544 /* We requested no new QoS, but received one nontheless. */
1545 if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos))
1546 {
1547 /* QoS >= minimum QoS: Store negotiated parameters */
1548 sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos);
1549 } else {
1550 /* Minimum QoS no longer satisfied: Abort activation */
1551 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1552 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1553
1554 context->network_control_state = SM_NETWORK_DEACTIVATING;
1555
1556 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1557 /* Report failed activation to Context Control (with network deactivation) */
1558 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE);
1559 return;
1560 } /* if (sm_qos_is_minimum_satisfied_by_aim) */
1561 }
1562
1563 if (sm_tft_more_to_modify(context))
1564 {
1565 /* Start T3381 */
1566 sm_timer_start(context, SM_TIMER_T3381);
1567 /* Send MODIFY PDP CONTEXT REQUEST with remaining TFTs */
1568 send_msg_modify_pdp_context_request(context);
1569 } else {
1570 /* No more TFTs to add: go to state SM NETWORK ACTIVATED, and inform Context Control */
1571 context->network_control_state = SM_NETWORK_ACTIVATED;
1572
1573 sm_context_control(context, SM_I_NETWORK_ACTIVATE_COMPLETED,
1574 (void *)update_flags);
1575 }
1576 }
1577
1578 /*
1579 +------------------------------------------------------------------------------
1580 | Function : handle_modify_pdp_context_accept_in_S5
1581 +------------------------------------------------------------------------------
1582 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_ACCEPT in S5
1583 |
1584 | Parameters : context - Context data
1585 | data - T_D_MODIFY_PDP_CONTEXT_ACCEPT *
1586 +------------------------------------------------------------------------------
1587 */
1588 static void handle_modify_pdp_context_accept_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1589 {
1590 T_D_MODIFY_PDP_CONTEXT_ACCEPT *msg = (T_D_MODIFY_PDP_CONTEXT_ACCEPT *)data;
1591 T_SM_UPDATE_FLAGS update_flags = (T_SM_UPDATE_FLAGS)0;
1592 (void)TRACE_FUNCTION("handle_modify_pdp_context_accept_in_S5");
1593
1594 TRACE_ASSERT(msg != NULL);
1595
1596 if (msg EQ NULL)
1597 return;
1598
1599 /* Free stored coded message */
1600 sm_free_coded_msg(context);
1601
1602 /* Stop timer T3381 */
1603 sm_timer_stop(context);
1604
1605 /* Store GSM RAT parameters, if present */
1606 update_flags = sm_nw_store_modify_accept_parameters(context, msg);
1607
1608 if (msg->v_qos != (U8)FALSE)
1609 {
1610 /* QoS updated */
1611 if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos))
1612 {
1613 /* QoS >= minimum QoS: Store negotiated parameters */
1614 sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos);
1615 update_flags |= SM_UPDATE_QOS;
1616 } else {
1617 /* Minimum QoS no longer satisfied: Deactivate */
1618 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1619 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1620
1621 context->network_control_state = SM_NETWORK_DEACTIVATING;
1622
1623 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1624 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)FALSE);
1625 return;
1626 } /* if (sm_qos_is_minimum_satisfied_by_aim) */
1627 } else {
1628 /* Check that minimum QoS is still satisfied by current QoS */
1629 if (!sm_qos_is_minimum_satisfied_by_sm(context, &context->accepted_qos))
1630 {
1631 /* Minimum QoS no longer satisfied: Deactivate */
1632 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1633 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1634
1635 context->network_control_state = SM_NETWORK_DEACTIVATING;
1636
1637 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1638 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE);
1639
1640 return;
1641 }
1642 }
1643
1644 if (sm_tft_more_to_modify(context))
1645 {
1646 /* Start T3381 */
1647 sm_timer_start(context, SM_TIMER_T3381);
1648 /* Send MODIFY PDP CONTEXT REQUEST with more TFTs */
1649 send_msg_modify_pdp_context_request(context);
1650
1651 context->network_control_state = SM_NETWORK_MODIFYING_ADDITIONAL_TFTS;
1652 } else {
1653 /* No more TFTs to add: Modification completed. */
1654 /* Go to state SM NETWORK ACTIVATED, and inform Context Control */
1655 context->network_control_state = SM_NETWORK_ACTIVATED;
1656
1657 sm_context_control(context, SM_I_NETWORK_MODIFY_COMPLETED,
1658 (void *)update_flags);
1659 }
1660 }
1661
1662 /*
1663 +------------------------------------------------------------------------------
1664 | Function : handle_modify_pdp_context_accept_in_S6
1665 +------------------------------------------------------------------------------
1666 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_ACCEPT in S6
1667 |
1668 | Parameters : context - Context data
1669 | data - T_D_MODIFY_PDP_CONTEXT_ACCEPT *
1670 +------------------------------------------------------------------------------
1671 */
1672 static void handle_modify_pdp_context_accept_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1673 {
1674 T_D_MODIFY_PDP_CONTEXT_ACCEPT *msg = (T_D_MODIFY_PDP_CONTEXT_ACCEPT *)data;
1675 T_SM_UPDATE_FLAGS update_flags = (T_SM_UPDATE_FLAGS)0;
1676 (void)TRACE_FUNCTION("handle_modify_pdp_context_accept_in_S6");
1677
1678 TRACE_ASSERT(msg != NULL);
1679
1680 if (msg EQ NULL)
1681 return;
1682
1683 /* Free stored coded message */
1684 sm_free_coded_msg(context);
1685
1686 /* Stop timer T3381 */
1687 sm_timer_stop(context);
1688
1689 /* Store GSM RAT parameters, if present */
1690 update_flags = sm_nw_store_modify_accept_parameters(context, msg);
1691
1692 if (msg->v_qos != (U8)FALSE)
1693 {
1694 /* We requested no new QoS, but received one nontheless. */
1695 if (sm_qos_is_minimum_satisfied_by_aim(context, &msg->qos))
1696 {
1697 /* QoS >= minimum QoS: Store negotiated parameters */
1698 sm_qos_assign_from_aim(&context->accepted_qos, &msg->qos);
1699 update_flags |= SM_UPDATE_QOS;
1700 } else {
1701 /* Minimum QoS no longer satisfied: Deactivate */
1702 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1703 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1704
1705 context->network_control_state = SM_NETWORK_DEACTIVATING;
1706
1707 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_QOS_NOT_ACCEPTED);
1708 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE);
1709
1710 return;
1711 } /* if (sm_qos_is_minimum_satisfied_by_aim) */
1712 }
1713
1714 if (sm_tft_more_to_modify(context))
1715 {
1716 /* Start T3381 */
1717 sm_timer_start(context, SM_TIMER_T3381);
1718 /* Send MODIFY PDP CONTEXT REQUEST with remaining TFTs */
1719 send_msg_modify_pdp_context_request(context);
1720 } else {
1721 /* No more TFTs to add: Modification completed. */
1722 /* Go to state SM NETWORK ACTIVATED, and inform Context Control */
1723 context->network_control_state = SM_NETWORK_ACTIVATED;
1724
1725 sm_context_control(context, SM_I_NETWORK_MODIFY_COMPLETED,
1726 (void *)update_flags);
1727 }
1728 }
1729
1730 /*
1731 +------------------------------------------------------------------------------
1732 | Function : handle_modify_pdp_context_reject_in_S3
1733 +------------------------------------------------------------------------------
1734 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REJECT in S3
1735 |
1736 | Parameters : context - Context data
1737 | data - T_MODIFY_PDP_CONTEXT_REJECT *
1738 +------------------------------------------------------------------------------
1739 */
1740 static void handle_modify_pdp_context_reject_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1741 {
1742 T_MODIFY_PDP_CONTEXT_REJECT *msg = (T_MODIFY_PDP_CONTEXT_REJECT *)data;
1743 (void)TRACE_FUNCTION("handle_modify_pdp_context_reject_in_S3");
1744
1745 TRACE_ASSERT(msg != NULL);
1746
1747 if (msg EQ NULL)
1748 return;
1749
1750 /* Free stored coded message */
1751 sm_free_coded_msg(context);
1752
1753 /* Go to state SM NETWORK DEACTIVATING */
1754 context->network_control_state = SM_NETWORK_DEACTIVATING;
1755
1756 /* Save cause value for ACI */
1757 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val);
1758
1759 /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */
1760 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION);
1761 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1762
1763 /* Inform Context Control of the failed activation (with network deactivation) */
1764 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE);
1765 }
1766
1767 /*
1768 +------------------------------------------------------------------------------
1769 | Function : handle_modify_pdp_context_reject_in_S5
1770 +------------------------------------------------------------------------------
1771 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REJECT in S5
1772 |
1773 | Parameters : context - Context data
1774 | data - T_MODIFY_PDP_CONTEXT_REJECT *
1775 +------------------------------------------------------------------------------
1776 */
1777 static void handle_modify_pdp_context_reject_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1778 {
1779 T_MODIFY_PDP_CONTEXT_REJECT *msg = (T_MODIFY_PDP_CONTEXT_REJECT *)data;
1780 (void)TRACE_FUNCTION("handle_modify_pdp_context_reject_in_S5");
1781
1782 TRACE_ASSERT(msg != NULL);
1783
1784 if (msg EQ NULL)
1785 return;
1786
1787 /* Free stored coded message */
1788 sm_free_coded_msg(context);
1789
1790 /* Go to state SM NETWORK DEACTIVATING */
1791 context->network_control_state = SM_NETWORK_DEACTIVATING;
1792
1793 /* Save cause value for ACI */
1794 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val);
1795
1796 /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */
1797 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION);
1798 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1799
1800 /* Inform Context Control of the failed modification */
1801 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE);
1802 }
1803
1804 /*
1805 +------------------------------------------------------------------------------
1806 | Function : handle_modify_pdp_context_reject_in_S6
1807 +------------------------------------------------------------------------------
1808 | Description : Handle event SM_M_MODIFY_PDP_CONTEXT_REJECT in S6
1809 |
1810 | Parameters : context - Context data
1811 | data - T_MODIFY_PDP_CONTEXT_REJECT *
1812 +------------------------------------------------------------------------------
1813 */
1814 static void handle_modify_pdp_context_reject_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1815 {
1816 T_MODIFY_PDP_CONTEXT_REJECT *msg = (T_MODIFY_PDP_CONTEXT_REJECT *)data;
1817 (void)TRACE_FUNCTION("handle_modify_pdp_context_reject_in_S6");
1818
1819 TRACE_ASSERT(msg != NULL);
1820
1821 if (msg EQ NULL)
1822 return;
1823
1824 /* Free stored coded message */
1825 sm_free_coded_msg(context);
1826
1827 /* Go to state SM NETWORK DEACTIVATING */
1828 context->network_control_state = SM_NETWORK_DEACTIVATING;
1829
1830 /* Save cause value for ACI */
1831 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val);
1832
1833 /* Stop T3381, start T3390, and send DEACTIVATE PDP CONTEXT REQUEST message */
1834 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION);
1835 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
1836
1837 /* Inform Context Control of the failed modification */
1838 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE);
1839 }
1840
1841 /*
1842 +------------------------------------------------------------------------------
1843 | Function : handle_deactivate_pdp_context_request_while_active
1844 +------------------------------------------------------------------------------
1845 | Description : Handle event SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST in S1 - S6
1846 |
1847 | Parameters : context - Context data
1848 | data - T_DEACTIVATE_PDP_CONTEXT_REQUEST *
1849 +------------------------------------------------------------------------------
1850 */
1851 static void handle_deactivate_pdp_context_request_while_active(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1852 {
1853 BOOL tear_down;
1854 T_DEACTIVATE_PDP_CONTEXT_REQUEST *msg = (T_DEACTIVATE_PDP_CONTEXT_REQUEST *)data;
1855 (void)TRACE_FUNCTION("handle_deactivate_pdp_context_request_while_active");
1856
1857 TRACE_ASSERT(msg != NULL);
1858
1859 if (msg EQ NULL)
1860 return;
1861
1862 /* Stop any active timers */
1863 sm_timer_stop(context);
1864
1865 /* Free stored coded message - if any */
1866 sm_free_coded_msg(context);
1867
1868 if (msg->v_tear_down != (U8)FALSE && msg->tear_down.tear_down_flag == (U8)1)
1869 {
1870 tear_down = TRUE;
1871 /* Mark linked contexts as inactive */
1872 sm_nw_mark_nsapi_set_inactive(sm_linked_nsapis(context->ti));
1873 } else {
1874 tear_down = FALSE;
1875 };
1876
1877 /* Mark context as inactive */
1878 sm_nw_mark_context_inactive(context->nsapi);
1879
1880 /* Save cause for ACI */
1881 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val);
1882
1883 /* Send DEACTIVATE PDP CONTEXT ACCEPT message */
1884 send_msg_deactivate_pdp_context_accept(context);
1885
1886 /* Go to state SM NETWORK DEACTIVATED */
1887 context->network_control_state = SM_NETWORK_DEACTIVATED;
1888
1889 /* Report deactivation to Context Control */
1890 sm_context_control(context, SM_I_NETWORK_REQUEST_DEACTIVATE, (void *)tear_down);
1891 }
1892
1893 /*
1894 +------------------------------------------------------------------------------
1895 | Function : handle_deactivate_pdp_context_request_while_deactivating
1896 +------------------------------------------------------------------------------
1897 | Description : Handle event SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST in S7
1898 |
1899 | Parameters : context - Context data
1900 | data - T_DEACTIVATE_PDP_CONTEXT_REQUEST *
1901 +------------------------------------------------------------------------------
1902 */
1903 static void handle_deactivate_pdp_context_request_while_deactivating(struct T_SM_CONTEXT_DATA *context, /*@null@*/ void *data)
1904 {
1905 T_DEACTIVATE_PDP_CONTEXT_REQUEST *msg = (T_DEACTIVATE_PDP_CONTEXT_REQUEST *)data;
1906 (void)TRACE_FUNCTION("handle_deactivate_pdp_context_request_while_deactivating");
1907
1908 TRACE_ASSERT(msg != NULL);
1909
1910 if (msg EQ NULL)
1911 return;
1912
1913 /* Save cause for ACI */
1914 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)msg->sm_cause.sm_cause_val);
1915
1916 /* Send DEACTIVATE PDP CONTEXT ACCEPT message */
1917 send_msg_deactivate_pdp_context_accept(context);
1918
1919 /* Report deactivation to Context Control iff tear_down == TRUE */
1920 if (msg->v_tear_down != (U8)FALSE && msg->tear_down.tear_down_flag == (U8)1)
1921 {
1922 sm_context_control(context, SM_I_NETWORK_REQUEST_DEACTIVATE, (void *)TRUE);
1923 }
1924 }
1925
1926 /*
1927 +------------------------------------------------------------------------------
1928 | Function : handle_deactivate_pdp_context_accept
1929 +------------------------------------------------------------------------------
1930 | Description : Handle event SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT in S7
1931 |
1932 | Parameters : context - Context data
1933 | data - Not used
1934 +------------------------------------------------------------------------------
1935 */
1936 static void handle_deactivate_pdp_context_accept(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data)
1937 {
1938 (void)TRACE_FUNCTION("handle_deactivate_pdp_context_accept");
1939
1940 /* Free stored coded message */
1941 sm_free_coded_msg(context);
1942
1943 /* Stop T3390 */
1944 sm_timer_stop(context);
1945
1946 /* Go to state SM NETWORK DEACTIVATED */
1947 context->network_control_state = SM_NETWORK_DEACTIVATED;
1948
1949 /* Mark context as inactive */
1950 sm_nw_mark_context_inactive(context->nsapi);
1951
1952 /* Report deactivate complete to Context Control */
1953 sm_context_control(context, SM_I_NETWORK_DEACTIVATE_COMPLETED, NULL);
1954 }
1955
1956 /*
1957 +------------------------------------------------------------------------------
1958 | Function : handle_T3380
1959 +------------------------------------------------------------------------------
1960 | Description : Handle event SM_T_T3380
1961 |
1962 | Parameters : context - Context data
1963 | data - Not used
1964 +------------------------------------------------------------------------------
1965 */
1966 static void handle_T3380(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
1967 {
1968 (void)TRACE_FUNCTION("handle_T3380");
1969
1970 /* If SM is not suspended, resend ACTIVATE (SECONDARY) PDP CONTEXT REQUEST */
1971 resend_msg(context);
1972 }
1973
1974 /*
1975 +------------------------------------------------------------------------------
1976 | Function : handle_T3380_max
1977 +------------------------------------------------------------------------------
1978 | Description : Handle event SM_T_T3380_MAX
1979 |
1980 | Parameters : context - Context data
1981 | data - Not used
1982 +------------------------------------------------------------------------------
1983 */
1984 static void handle_T3380_max(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
1985 {
1986 (void)TRACE_FUNCTION("handle_T3380_max");
1987
1988 /* Free stored coded message */
1989 sm_free_coded_msg(context);
1990
1991 /* Go to state SM NETWORK DEACTIVATED */
1992 context->network_control_state = SM_NETWORK_DEACTIVATED;
1993
1994 /* Inform Context Control of the failed activation (no network deactivation) */
1995 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_NETWORK_FAILURE);
1996 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)FALSE);
1997 }
1998
1999 /*
2000 +------------------------------------------------------------------------------
2001 | Function : handle_T3381
2002 +------------------------------------------------------------------------------
2003 | Description : Handle event SM_T_T3381
2004 |
2005 | Parameters : context - Context data
2006 | data - Not used
2007 +------------------------------------------------------------------------------
2008 */
2009 static void handle_T3381(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
2010 {
2011 (void)TRACE_FUNCTION("handle_T3381");
2012
2013 /* If SM is not suspended, resend MODIFY PDP CONTEXT REQUEST */
2014 resend_msg(context);
2015 }
2016
2017 /*
2018 +------------------------------------------------------------------------------
2019 | Function : handle_T3381_max_in_S3
2020 +------------------------------------------------------------------------------
2021 | Description : Handle event SM_T_T3381_MAX in S3
2022 |
2023 | Parameters : context - Context data
2024 | data - Not used
2025 +------------------------------------------------------------------------------
2026 */
2027 static void handle_T3381_max_in_S3(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
2028 {
2029 (void)TRACE_FUNCTION("handle_T3381_max_in_S3");
2030
2031 /* Free stored coded message */
2032 sm_free_coded_msg(context);
2033
2034 /* Go to state SM NETWORK DEACTIVATING */
2035 context->network_control_state = SM_NETWORK_DEACTIVATING;
2036
2037 /* Initiate deactivation */
2038 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION);
2039 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
2040
2041 /* Inform Context Control of the failed activation */
2042 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_NETWORK_FAILURE);
2043 sm_context_control(context, SM_I_NETWORK_ACTIVATE_REJECTED, (void *)TRUE);
2044 }
2045
2046 /*
2047 +------------------------------------------------------------------------------
2048 | Function : handle_T3381_max_in_S5
2049 +------------------------------------------------------------------------------
2050 | Description : Handle event SM_T_T3381_MAX in S5
2051 |
2052 | Parameters : context - Context data
2053 | data - Not used
2054 +------------------------------------------------------------------------------
2055 */
2056 static void handle_T3381_max_in_S5(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
2057 {
2058 (void)TRACE_FUNCTION("handle_T3381_max_in_S5");
2059
2060 /* Free stored coded message */
2061 sm_free_coded_msg(context);
2062
2063 /* Modify procedure has failed, but the context remains active. */
2064 /* Go to state SM NETWORK ACTIVATED */
2065 context->network_control_state = SM_NETWORK_ACTIVATED;
2066
2067 /* Inform Context Control of the failed activation */
2068 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_NETWORK_FAILURE);
2069 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)FALSE);
2070 }
2071
2072 /*
2073 +------------------------------------------------------------------------------
2074 | Function : handle_T3381_max_in_S6
2075 +------------------------------------------------------------------------------
2076 | Description : Handle event SM_T_T3381_MAX in S6
2077 |
2078 | Parameters : context - Context data
2079 | data - Not used
2080 +------------------------------------------------------------------------------
2081 */
2082 static void handle_T3381_max_in_S6(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
2083 {
2084 (void)TRACE_FUNCTION("handle_T3381_max_in_S6");
2085
2086 /* Free stored coded message */
2087 sm_free_coded_msg(context);
2088
2089 /* Go to state SM NETWORK DEACTIVATING */
2090 context->network_control_state = SM_NETWORK_DEACTIVATING;
2091
2092 /* Initiate deactivation */
2093 sm_set_nw_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_REGULAR_DEACTIVATION);
2094 sm_nw_initiate_deactivation(context, sm_get_nw_cause(context));
2095
2096 /* Inform Context Control of the failed activation */
2097 sm_set_aci_cause(context, CAUSE_is_from_nwsm, (U16)CAUSE_NWSM_NETWORK_FAILURE);
2098 sm_context_control(context, SM_I_NETWORK_MODIFY_REJECTED, (void *)TRUE);
2099 }
2100
2101 /*
2102 +------------------------------------------------------------------------------
2103 | Function : handle_T3390
2104 +------------------------------------------------------------------------------
2105 | Description : Handle event SM_T_T3390
2106 |
2107 | Parameters : context - Context data
2108 | data - Not used
2109 +------------------------------------------------------------------------------
2110 */
2111 static void handle_T3390(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
2112 {
2113 (void)TRACE_FUNCTION("handle_T3390");
2114
2115 /* If SM is not suspended, resend DEACTIVATE PDP CONTEXT REQUEST */
2116 resend_msg(context);
2117 }
2118
2119 /*
2120 +------------------------------------------------------------------------------
2121 | Function : handle_T3390_max
2122 +------------------------------------------------------------------------------
2123 | Description : Handle event SM_T_T3390_MAX
2124 |
2125 | Parameters : context - Context data
2126 | data - Not used
2127 +------------------------------------------------------------------------------
2128 */
2129 static void handle_T3390_max(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/void *data)
2130 {
2131 (void)TRACE_FUNCTION("handle_T3390_max");
2132
2133 /* Free stored coded message */
2134 sm_free_coded_msg(context);
2135
2136 /* Go to state SM NETWORK DEACTIVATED */
2137 context->network_control_state = SM_NETWORK_DEACTIVATED;
2138
2139 /* Context is considered deactivated. Inform Context Control. */
2140 sm_context_control(context, SM_I_NETWORK_DEACTIVATE_COMPLETED, NULL);
2141 }
2142
2143 /*
2144 +------------------------------------------------------------------------------
2145 | Function : handle_mmpm_suspend_ind
2146 +------------------------------------------------------------------------------
2147 | Description : Handle incoming MMPM_SUSPEND_IND primitive
2148 |
2149 | Parameters : context - Context data
2150 | data - Unused
2151 +------------------------------------------------------------------------------
2152 */
2153 static void handle_mmpm_suspend_ind(/*@unused@*/struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data)
2154 {
2155 (void)TRACE_FUNCTION("handle_mmpm_suspend_ind");
2156 }
2157
2158 /*
2159 +------------------------------------------------------------------------------
2160 | Function : handle_mmpm_resume_ind
2161 +------------------------------------------------------------------------------
2162 | Description : Handle incoming MMPM_RESUME_IND primitive
2163 |
2164 | Parameters : context - Context data
2165 | data - Unused
2166 +------------------------------------------------------------------------------
2167 */
2168 static void handle_mmpm_resume_ind(struct T_SM_CONTEXT_DATA *context, /*@null@*/ /*@unused@*/ void *data)
2169 {
2170 (void)TRACE_FUNCTION("handle_mmpm_resume_ind");
2171
2172 if (sm_is_started_during_suspend(context))
2173 {
2174 resend_msg(context);
2175 sm_clear_started_during_suspend(context);
2176 }
2177 }
2178
2179 /*==== PUBLIC FUNCTIONS =====================================================*/
2180
2181 /*
2182 +------------------------------------------------------------------------------
2183 | Function : sm_network_control_init
2184 +------------------------------------------------------------------------------
2185 | Description : Network Control state machine initialization function
2186
2187 | Parameters : context - Context data
2188 +------------------------------------------------------------------------------
2189 */
2190 void sm_network_control_init(struct T_SM_CONTEXT_DATA *context)
2191 {
2192 (void)TRACE_FUNCTION("sm_network_control_init");
2193
2194 context->network_control_state = SM_NETWORK_DEACTIVATED;
2195 }
2196
2197 /*
2198 +------------------------------------------------------------------------------
2199 | Function : sm_network_control_exit
2200 +------------------------------------------------------------------------------
2201 | Description : Network Control state machine exit function
2202
2203 | Parameters : context - Context data
2204 +------------------------------------------------------------------------------
2205 */
2206 void sm_network_control_exit(struct T_SM_CONTEXT_DATA *context)
2207 {
2208 (void)TRACE_FUNCTION("sm_network_control_exit");
2209
2210 context->network_control_state = SM_NETWORK_DEACTIVATED;
2211
2212 /* Free any memory allocated to this context (fields managed by Network Control) */
2213 sm_free_coded_msg(context);
2214 sm_nw_free_apn(context);
2215 sm_nw_free_requested_tft(context);
2216 sm_nw_free_active_tft(context);
2217 sm_nw_free_requested_pco(context);
2218 sm_nw_free_negotiated_pco(context);
2219 }
2220
2221 /*
2222 +------------------------------------------------------------------------------
2223 | Function : sm_network_control_state
2224 +------------------------------------------------------------------------------
2225 | Description : Returns a read-only string with the name of the active state.
2226
2227 | Parameters : context - Context data
2228 +------------------------------------------------------------------------------
2229 */
2230 #ifdef DEBUG
2231 /*@observer@*/const char *
2232 sm_network_control_state(struct T_SM_CONTEXT_DATA *context)
2233 {
2234 /*@observer@*/
2235 static const char *state_name[SM_NETWORK_CONTROL_NUMBER_OF_STATES] = {
2236 "S0_SM_NETWORK_DEACTIVATED",
2237 "S1_SM_NETWORK_ACTIVATING_PRIMARY",
2238 "S2_SM_NETWORK_ACTIVATING_SECONDARY",
2239 "S3_SM_NETWORK_ACTIVATING_ADDING_TFTS",
2240 "S4_SM_NETWORK_ACTIVATED",
2241 "S5_SM_NETWORK_MODIFYING",
2242 "S6_SM_NETWORK_MODIFYING_ADDITIONAL_TFTS",
2243 "S7_SM_NETWORK_DEACTIVATING"
2244 };
2245
2246 TRACE_ASSERT(context->network_control_state < SM_NETWORK_CONTROL_NUMBER_OF_STATES);
2247
2248 return state_name[(U16)context->network_control_state];
2249 }
2250 #endif
2251 /*
2252 +------------------------------------------------------------------------------
2253 | Function : sm_network_control
2254 +------------------------------------------------------------------------------
2255 | Description : User Plane Control state machine
2256 |
2257 | Parameters : context - Context data
2258 | event - Internal event (see sm_network_control.h)
2259 | data - Event dependent parameter
2260 +------------------------------------------------------------------------------
2261 */
2262 void sm_network_control(struct T_SM_CONTEXT_DATA *context,
2263 T_SM_NETWORK_CONTROL_EVENT event,
2264 /*@null@*/ void *data)
2265 {
2266 #ifdef DEBUG
2267 const char *old_state_name, *new_state_name;
2268 T_SM_NETWORK_CONTROL_STATE old_state;
2269 /*@observer@*/
2270 static const char *event_name[SM_NETWORK_CONTROL_NUMBER_OF_EVENTS] = {
2271 "SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT",
2272 "SM_M_ACTIVATE_PDP_CONTEXT_REJECT",
2273 "SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT",
2274 "SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT",
2275 "SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST",
2276 "SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT",
2277 "SM_M_MODIFY_PDP_CONTEXT_REQUEST",
2278 "SM_M_MODIFY_PDP_CONTEXT_ACCEPT",
2279 "SM_M_MODIFY_PDP_CONTEXT_REJECT",
2280 "SM_M_REQUEST_PDP_CONTEXT_ACTIVATION",
2281 "SM_M_SM_STATUS",
2282 "SM_P_MMPM_RESUME_IND",
2283 "SM_P_MMPM_SUSPEND_IND",
2284 "SM_T_T3380",
2285 "SM_T_T3380_MAX",
2286 "SM_T_T3381",
2287 "SM_T_T3381_MAX",
2288 "SM_T_T3390",
2289 "SM_T_T3390_MAX",
2290 "SM_I_NETWORK_ACTIVATE_PRIMARY",
2291 "SM_I_NETWORK_ACTIVATE_SECONDARY",
2292 "SM_I_NETWORK_DEACTIVATE_LOCAL",
2293 "SM_I_NETWORK_MODIFY",
2294 "SM_I_NETWORK_REQUEST_ACTIVATION_REJECT",
2295 "SM_I_NETWORK_DEACTIVATE"
2296 };
2297
2298 TRACE_ASSERT(event < SM_NETWORK_CONTROL_NUMBER_OF_EVENTS);
2299
2300 old_state = context->network_control_state;
2301 old_state_name = sm_network_control_state(context);
2302
2303 if (transition[(U16)old_state][(U16)event].event != event)
2304 {
2305 (void)TRACE_ERROR("Event table error in sm_network_control!");
2306 }
2307 #endif /* DEBUG */
2308
2309 transition[(U16)context->network_control_state][(U16)event].func(context, data);
2310
2311 #ifdef DEBUG
2312 new_state_name = sm_network_control_state(context);
2313
2314 (void)TRACE_EVENT_P4("SM NETWORK #%d: %s => %s to %s", context->nsapi,
2315 event_name[(U16)event], old_state_name, new_state_name);
2316 #endif /* DEBUG */
2317 }
2318
2319 /*==== END OF FILE ==========================================================*/