FreeCalypso > hg > fc-magnetite
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 ==========================================================*/ |
