comparison src/g23m-gprs/sm/sm_dispatch_message.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: This module implements the process dispatcher for incoming
17 | air interface messages in the Session Management (SM) entity.
18 | For design details, see:
19 | 8010.908 SM Detailed Specification
20 +---------------------------------------------------------------------------*/
21
22 /*==== DECLARATION CONTROL =================================================*/
23
24 /*==== INCLUDES =============================================================*/
25
26 #include "sm.h"
27 #include "ccdapi.h"
28
29 #include "sm_network_control.h"
30 #include "sm_aci_output_handler.h"
31 #include "sm_mm_output_handler.h"
32
33 /*==== CONSTS ===============================================================*/
34
35 /*==== TYPES ================================================================*/
36
37 /*==== LOCALS ===============================================================*/
38
39 /*==== PRIVATE FUNCTIONS ====================================================*/
40
41 /*==== PUBLIC FUNCTIONS =====================================================*/
42
43 /*
44 +------------------------------------------------------------------------------
45 | Function : sm_disp_mmpm_unitdata_ind
46 +------------------------------------------------------------------------------
47 | Description : Dispatch MMPM_UNITDATA_IND
48 |
49 | Parameters : prim - received primitive
50 +------------------------------------------------------------------------------
51 */
52 void sm_disp_mmpm_unitdata_ind(T_MMPM_UNITDATA_IND *prim)
53 {
54 U8 ti, ti_flag, msg_type, *msg, ccdResult;
55 U16 offset;
56 struct T_SM_CONTEXT_DATA *context;
57 T_CAUSE_ps_cause cause;
58
59 (void)TRACE_FUNCTION("sm_disp_mmpm_unitdata_ind");
60
61 offset = (U16)(prim->sdu.o_buf + 7) >> 3; /* Offset in octets/bytes in message buffer */
62 msg = &prim->sdu.buf[offset];
63
64 /* Read L3 header: First TI/PD octet */
65 ti_flag = (msg[0] & SM_TI_FLAG) == (U8)0 ? (U8)SM_TI_FLAG : (U8)0;
66 ti = (msg[0] >> 4) & SM_TI_NON_EXT_MASK;
67
68 /* Check for extended TI: If TI == 7, read next octet for real TI */
69 if (ti == (U8)SM_TI_EXTEND_VALUE) {
70 ti = msg[1]; /* Read real TI from next octet in message */
71
72 if ((ti & (U8)SM_TI_FLAG) == (U8)0) {
73 /* Messages with TI EXT bit = 0 shall be ignored: [3G 24.008, 8.3.2] */
74 (void)TRACE_ERROR("Warning: TI EXT bit = 0 in message - message ignored!");
75 return;
76 } else {
77 ti &= SM_TI_MASK;
78 }
79 offset = (U16)16; /* # bits to advance message pointer to reach message type */
80 msg_type = msg[2]; /* Get message type octet after TI */
81 (void)TRACE_EVENT_P1(" Extended TI found: 0x%02x", ti);
82 } else {
83 offset = (U16)8; /* # bits to advance message pointer to reach message type */
84 (void)TRACE_EVENT_P1(" Non-extended TI found: 0x%02x", ti);
85 msg_type = msg[1]; /* Get message type octet after TI */
86 }
87 /* Set highest bit iff the direction flag bit was set above */
88 ti |= ti_flag;
89 /* Advance message pointer past TI/PD octet(s) */
90 prim->sdu.l_buf -= offset;
91 prim->sdu.o_buf += offset;
92
93 /* Check for message too short: [3G 24.008, 8.2] */
94 if (prim->sdu.l_buf < (U16)8) {
95 (void)TRACE_ERROR("Warning! Message too short - discarded...");
96 return;
97 }
98
99 /* Find context with TI = ti, if already active/being activated */
100 context = sm_get_context_data_from_ti(ti);
101
102 switch (msg_type) {
103 case ACTIVATE_PDP_CONTEXT_ACCEPT:
104 case ACTIVATE_PDP_CONTEXT_REJECT:
105 case ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT:
106 case ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT:
107 case D_MODIFY_PDP_CONTEXT_REQUEST:
108 case D_MODIFY_PDP_CONTEXT_ACCEPT:
109 case MODIFY_PDP_CONTEXT_REJECT:
110 case DEACTIVATE_PDP_CONTEXT_REQUEST:
111 case DEACTIVATE_PDP_CONTEXT_ACCEPT:
112 if (context == NULL) {
113 /* Message received on TI not relating to an active context, or context
114 * being activated/deactivated: [3G 24.008, 8.3.2 b)]*/
115 (void)TRACE_ERROR("Message received on TI not relating to an active context, or context being activated/deactivated");
116 cause.ctrl_value = CAUSE_is_from_nwsm;
117 cause.value.nwsm_cause = (U16)CAUSE_NWSM_INVALID_TI;
118 send_msg_sm_status(ti, &cause);
119 return;
120 }
121 break;
122 case REQUEST_PDP_CONTEXT_ACTIVATION:
123 if (ti_flag == (U8)0) {
124 /* Ignore REQUEST PDP CONTEXT ACTIVATION msg with TI flag = 1 [3G 24.008, 8.3.2 c)] */
125 /* Note: flag bit is inverted above! */
126 (void)TRACE_EVENT("REQUEST PDP CONTEXT ACTIVATION msg with TI flag = 1 ignored...");
127 return;
128 }
129 if (context == NULL) {
130 /* If no context exists for the TI, create one. */
131 context = sm_insert_mt_context_data(ti);
132 }
133 break;
134 case SM_STATUS:
135 if (context == NULL) {
136 /* Silently ignore message */
137 return;
138 }
139 break;
140 case ACTIVATE_PDP_CONTEXT_REQUEST: /* FALL-THROUGH */
141 case ACTIVATE_SECONDARY_PDP_CONTEXT_REQUEST: /* FALL-THROUGH */
142 case REQUEST_PDP_CONTEXT_ACTIVATION_REJECT: /* FALL-THROUGH */
143 case U_MODIFY_PDP_CONTEXT_REQUEST: /* FALL-THROUGH */
144 case U_MODIFY_PDP_CONTEXT_ACCEPT: /* FALL-THROUGH */
145 default:
146 /* Message type not defined for the PD in the given direction: [3G 24.008, 8.4] */
147 (void)TRACE_ERROR("Message type not defined for the PD in the given direction");
148 cause.ctrl_value = CAUSE_is_from_nwsm;
149 cause.value.nwsm_cause = (U16)CAUSE_NWSM_MSG_TYPE_NOT_IMPLEMENTED;
150 send_msg_sm_status(ti, &cause);
151 return;
152 } /* switch */
153
154 TRACE_ASSERT(context != NULL);
155
156 /* Decode message */
157 ccdResult = ccd_decodeMsg((U8)CCDENT_SM,
158 (U8)DOWNLINK,
159 (T_MSGBUF *)&prim->sdu,
160 (UBYTE *) _decodedMsg,
161 (U8)NOT_PRESENT_8BIT);
162
163 if (ccdResult != (U8)ccdOK) {
164 /* Error Handling */
165 U16 parlist[6];
166 U8 first_err;
167 U8 ccd_err;
168
169 /* clear parlist */
170 memset (parlist, 0, sizeof (parlist));
171 first_err = ccd_getFirstError((U8)CCDENT_SM, parlist);
172
173 ccd_err = first_err;
174 /* Loop over errors in parlist. Fix inherited from TI Berlin. */
175 do
176 {
177 /* Error Handling */
178 switch (ccd_err) {
179 case ERR_COMPREH_REQUIRED: /* Comprehension required */
180 case ERR_MAND_ELEM_MISS: { /* Mandatory elements missing */
181 (void)TRACE_ERROR("CCD ERROR: Mandatory elements missing");
182 if (msg_type == (U8)DEACTIVATE_PDP_CONTEXT_REQUEST) {
183 /* [3G 24.008, 8.5.5]: If msg_type is DEACTIVATE PDP CONTEXT REQUEST,
184 * respond with DEACTIVATE PDP CONTEXT ACCEPT and release context. */
185 send_msg_deactivate_pdp_context_accept(context);
186 } else if (msg_type == (U8)REQUEST_PDP_CONTEXT_ACTIVATION) {
187 /* [3G 24.008, 8.5.5]: If msg_type is REQUEST PDP CONTEXT ACTIVATION,
188 * respond with SM STATUS, cause #96 "invalid mandatory information". */
189 cause.ctrl_value = CAUSE_is_from_nwsm;
190 cause.value.nwsm_cause = (U16)CAUSE_NWSM_INVALID_MANDATORY_ELEMENT;
191 send_msg_sm_status(ti, &cause);
192 return;
193 } else {
194 cause.ctrl_value = CAUSE_is_from_nwsm;
195 cause.value.nwsm_cause = (U16)CAUSE_NWSM_INVALID_MANDATORY_ELEMENT;
196 send_msg_sm_status(ti, &cause);
197 return;
198 }
199 /*@switchbreak@*/
200 break;
201 }
202 } /* switch */
203 ccd_err = ccd_getNextError ((U8)CCDENT_SM, parlist);
204 } while (ccd_err != (U8)ERR_NO_MORE_ERROR);
205 } /* if (ccdResult...) */
206
207 switch (msg_type) {
208 case ACTIVATE_PDP_CONTEXT_ACCEPT:
209 /* Forward to Network Control */
210 sm_network_control(context, SM_M_ACTIVATE_PDP_CONTEXT_ACCEPT, _decodedMsg);
211 break;
212 case ACTIVATE_PDP_CONTEXT_REJECT:
213 /* Forward to Network Control */
214 sm_network_control(context, SM_M_ACTIVATE_PDP_CONTEXT_REJECT, _decodedMsg);
215 break;
216 case ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT:
217 /* Forward to Network Control */
218 sm_network_control(context, SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_ACCEPT, _decodedMsg);
219 break;
220 case ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT:
221 /* Forward to Network Control */
222 sm_network_control(context, SM_M_ACTIVATE_SECONDARY_PDP_CONTEXT_REJECT, _decodedMsg);
223 break;
224 case REQUEST_PDP_CONTEXT_ACTIVATION:
225 /* Forward to Network Control */
226 sm_network_control(context, SM_M_REQUEST_PDP_CONTEXT_ACTIVATION, _decodedMsg);
227 break;
228 case D_MODIFY_PDP_CONTEXT_REQUEST:
229 /* Forward to Network Control */
230 sm_network_control(context, SM_M_MODIFY_PDP_CONTEXT_REQUEST, _decodedMsg);
231 break;
232 case D_MODIFY_PDP_CONTEXT_ACCEPT:
233 /* Forward to Network Control */
234 sm_network_control(context, SM_M_MODIFY_PDP_CONTEXT_ACCEPT, _decodedMsg);
235 break;
236 case MODIFY_PDP_CONTEXT_REJECT:
237 /* Forward to Network Control */
238 sm_network_control(context, SM_M_MODIFY_PDP_CONTEXT_REJECT, _decodedMsg);
239 break;
240 case DEACTIVATE_PDP_CONTEXT_REQUEST:
241 /* Forward to Network Control */
242 sm_network_control(context, SM_M_DEACTIVATE_PDP_CONTEXT_REQUEST, _decodedMsg);
243 break;
244 case DEACTIVATE_PDP_CONTEXT_ACCEPT:
245 /* Forward to Network Control */
246 sm_network_control(context, SM_M_DEACTIVATE_PDP_CONTEXT_ACCEPT, _decodedMsg);
247 break;
248 case SM_STATUS:
249 /* Forward to Network Control */
250 sm_network_control(context, SM_M_SM_STATUS, _decodedMsg);
251 break;
252 } /* switch */
253
254 /* Deallocate context if it was marked for deactivation by the above operation */
255 /*lint -e613 (Possible use of null pointer 'context' in left argument to operator '->') */
256 if (sm_is_context_pending_deallocation(context)) {
257 sm_free_context_data_by_nsapi(context->nsapi);
258 }
259 }
260
261 /*==== END OF FILE ==========================================================*/