FreeCalypso > hg > fc-selenite
comparison src/g23m-gprs/sm/sm_memory_handler.c @ 1:d393cd9bb723
src/g23m-*: initial import from Magnetite
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Sun, 15 Jul 2018 04:40:46 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:b6a5e36de839 | 1:d393cd9bb723 |
|---|---|
| 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: Memory allocation function definition for 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 #include "sm_tft.h" | |
| 27 | |
| 28 /*==== CONSTS ===============================================================*/ | |
| 29 | |
| 30 /*==== TYPES ================================================================*/ | |
| 31 | |
| 32 /*==== LOCALS ===============================================================*/ | |
| 33 | |
| 34 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
| 35 | |
| 36 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
| 37 | |
| 38 /* | |
| 39 +------------------------------------------------------------------------------ | |
| 40 | Function : sm_pfree | |
| 41 +------------------------------------------------------------------------------ | |
| 42 | Description : PFREE macro replacement | |
| 43 | | |
| 44 | Parameters : data - memory to free | |
| 45 +------------------------------------------------------------------------------ | |
| 46 */ | |
| 47 void sm_pfree(/*@only@*/ /*@null@*/ /*@out@*/ void *data) | |
| 48 { | |
| 49 if (data != NULL) | |
| 50 { | |
| 51 vsi_c_pfree((T_VOID_STRUCT **)&data FILE_LINE_MACRO); | |
| 52 } | |
| 53 } | |
| 54 | |
| 55 /* | |
| 56 +------------------------------------------------------------------------------ | |
| 57 | Function : sm_mfree | |
| 58 +------------------------------------------------------------------------------ | |
| 59 | Description : Wrapper for MFREE macro | |
| 60 | | |
| 61 | Parameters : data - memory to free | |
| 62 +------------------------------------------------------------------------------ | |
| 63 */ | |
| 64 static void sm_mfree(/*@only@*/ /*@out@*/ /*@null@*/ void *data) | |
| 65 { | |
| 66 if (data != NULL) { | |
| 67 MFREE(data); | |
| 68 } | |
| 69 } | |
| 70 | |
| 71 /* | |
| 72 +------------------------------------------------------------------------------ | |
| 73 | Function : sm_allocate_context_data | |
| 74 +------------------------------------------------------------------------------ | |
| 75 | Description : Allocate an instance of SM_CONTEXT_DATA | |
| 76 | | |
| 77 | Parameters : None | |
| 78 +------------------------------------------------------------------------------ | |
| 79 */ | |
| 80 struct T_SM_CONTEXT_DATA *sm_allocate_context_data(void) | |
| 81 { | |
| 82 struct T_SM_CONTEXT_DATA *context; | |
| 83 | |
| 84 context = (struct T_SM_CONTEXT_DATA *) | |
| 85 M_ALLOC((U32)sizeof(struct T_SM_CONTEXT_DATA)); | |
| 86 | |
| 87 return context; | |
| 88 } | |
| 89 | |
| 90 /* | |
| 91 +------------------------------------------------------------------------------ | |
| 92 | Function : sm_assign_context_data_to_nsapi | |
| 93 +------------------------------------------------------------------------------ | |
| 94 | Description : Assign a non-zero context data structure to an NSAPI index in | |
| 95 | sm_context_array. | |
| 96 | | |
| 97 | Parameters : context - Context data | |
| 98 | nsapi - Index at which to insert data | |
| 99 +------------------------------------------------------------------------------ | |
| 100 */ | |
| 101 void | |
| 102 sm_assign_context_data_to_nsapi(/*@only@*/struct T_SM_CONTEXT_DATA *context, | |
| 103 int /*@alt U8@*/ nsapi) | |
| 104 { | |
| 105 TRACE_ASSERT(context != NULL); | |
| 106 TRACE_ASSERT(sm_data.sm_context_array[nsapi - (int)NAS_NSAPI_5] == NULL); | |
| 107 | |
| 108 sm_data.sm_context_array[nsapi - (int)NAS_NSAPI_5] = context; | |
| 109 } | |
| 110 | |
| 111 /* | |
| 112 +------------------------------------------------------------------------------ | |
| 113 | Function : sm_get_context_data_from_nsapi | |
| 114 +------------------------------------------------------------------------------ | |
| 115 | Description : Returns a context data structure for the given NSAPI index. | |
| 116 | Returns NULL, if the context is inactive. | |
| 117 | | |
| 118 | Parameters : nsapi - Index at which to fetch data | |
| 119 +------------------------------------------------------------------------------ | |
| 120 */ | |
| 121 struct T_SM_CONTEXT_DATA * | |
| 122 sm_get_context_data_from_nsapi(int /*@alt U8@*/ nsapi) | |
| 123 { | |
| 124 TRACE_ASSERT((T_NAS_nsapi)nsapi >= NAS_NSAPI_5 && nsapi <= NAS_NSAPI_15); | |
| 125 | |
| 126 /*lint -e{661} sm_context_array causes out of bounds access, it does not! */ | |
| 127 return sm_data.sm_context_array[nsapi - (int)NAS_NSAPI_5]; | |
| 128 } | |
| 129 | |
| 130 /* | |
| 131 +------------------------------------------------------------------------------ | |
| 132 | Function : sm_assign_context_data_to_nsapi | |
| 133 +------------------------------------------------------------------------------ | |
| 134 | Description : Returns a context data structure for the given TI value. | |
| 135 | Returns NULL, if the context is inactive. | |
| 136 | | |
| 137 | Parameters : ti - TI value identifying the context | |
| 138 +------------------------------------------------------------------------------ | |
| 139 */ | |
| 140 /*@null@*/struct T_SM_CONTEXT_DATA * | |
| 141 sm_get_context_data_from_ti(int /*@alt U8@*/ ti) | |
| 142 { | |
| 143 int index; | |
| 144 | |
| 145 /* First, search sm_context_array: */ | |
| 146 for (index = 0; index < SM_MAX_NSAPI_OFFSET; index++) { | |
| 147 if (sm_data.sm_context_array[index] != NULL && | |
| 148 (sm_data.sm_context_array[index]->ti & SM_TI_MASK) == (ti & SM_TI_MASK)) | |
| 149 { | |
| 150 return sm_data.sm_context_array[index]; | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 /* Next, try in sm_pending_mt_array: */ | |
| 155 for (index = 0; index < SM_MAX_NSAPI_OFFSET; index++) { | |
| 156 if (sm_data.sm_pending_mt_array[index] != NULL && | |
| 157 sm_data.sm_pending_mt_array[index]->ti == ti) | |
| 158 { | |
| 159 return sm_data.sm_pending_mt_array[index]; | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 /* None found: return NULL */ | |
| 164 return NULL; | |
| 165 } | |
| 166 | |
| 167 /* | |
| 168 +------------------------------------------------------------------------------ | |
| 169 | Function : sm_free_context_data | |
| 170 +------------------------------------------------------------------------------ | |
| 171 | Description : Free context data memory. Calls de-initialization functions | |
| 172 | in state machines. | |
| 173 | | |
| 174 | Parameters : context - Context data | |
| 175 +------------------------------------------------------------------------------ | |
| 176 */ | |
| 177 void sm_free_context_data(/*@only@*/struct T_SM_CONTEXT_DATA *context) | |
| 178 { | |
| 179 if (context != NULL) { | |
| 180 sm_user_plane_control_exit (context); | |
| 181 sm_network_control_exit (context); | |
| 182 sm_context_deactivate_control_exit(context); | |
| 183 sm_context_control_exit (context); | |
| 184 | |
| 185 TRACE_ASSERT(context->apn == NULL); | |
| 186 TRACE_ASSERT(context->requested_pco == NULL); | |
| 187 TRACE_ASSERT(context->negotiated_pco == NULL); | |
| 188 TRACE_ASSERT(context->requested_tft.ptr_tft_pf == NULL); | |
| 189 TRACE_ASSERT(context->active_tft.ptr_tft_pf == NULL); | |
| 190 TRACE_ASSERT(context->coded_msg == NULL); | |
| 191 | |
| 192 sm_mfree(context); | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 /* | |
| 197 +------------------------------------------------------------------------------ | |
| 198 | Function : sm_free_context_data_by_nsapi | |
| 199 +------------------------------------------------------------------------------ | |
| 200 | Description : Frees context identified by NSAPI. Uses sm_free_context_data() | |
| 201 | | |
| 202 | Parameters : nsapi - NSAPI | |
| 203 +------------------------------------------------------------------------------ | |
| 204 */ | |
| 205 void sm_free_context_data_by_nsapi(int /*@alt U8@*/ nsapi) | |
| 206 { | |
| 207 U16 index; | |
| 208 TRACE_ASSERT((T_NAS_nsapi)nsapi >= NAS_NSAPI_5 && nsapi <= NAS_NSAPI_15); | |
| 209 | |
| 210 index = sm_nsapi_to_index((U16)nsapi); | |
| 211 sm_free_context_data(sm_data.sm_context_array[index]); | |
| 212 sm_data.sm_context_array[index] = NULL; | |
| 213 } | |
| 214 | |
| 215 /* | |
| 216 +------------------------------------------------------------------------------ | |
| 217 | Function : sm_insert_mt_context_data | |
| 218 +------------------------------------------------------------------------------ | |
| 219 | Description : Allocates and inserts context data structure in | |
| 220 | sm_pending_mt_array. | |
| 221 | | |
| 222 | Parameters : ti - TI value identifying context | |
| 223 +------------------------------------------------------------------------------ | |
| 224 */ | |
| 225 /*@observer@*/ /*@null@*/ struct T_SM_CONTEXT_DATA * | |
| 226 sm_insert_mt_context_data(int /*@alt U8@*/ ti) | |
| 227 { | |
| 228 int index, insert_index = -1; | |
| 229 struct T_SM_CONTEXT_DATA *context; | |
| 230 | |
| 231 for (index = 0; index < SM_MAX_NSAPI_OFFSET; index++) { | |
| 232 if (insert_index < 0 && sm_data.sm_pending_mt_array[index] == NULL) { | |
| 233 insert_index = index; | |
| 234 } | |
| 235 if (sm_data.sm_pending_mt_array[index] != NULL && | |
| 236 sm_data.sm_pending_mt_array[index]->ti == ti) { | |
| 237 (void)TRACE_EVENT_P1("ERROR: Tried to overwrite MT context data for TI=%d!", ti); | |
| 238 return sm_data.sm_pending_mt_array[index]; | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 context = sm_allocate_context_data(); | |
| 243 | |
| 244 if (context != NULL && insert_index >= 0) { | |
| 245 memset(context, 0, sizeof(struct T_SM_CONTEXT_DATA)); | |
| 246 | |
| 247 context->ti = (U8)ti; | |
| 248 | |
| 249 sm_data.sm_pending_mt_array[insert_index] = context; | |
| 250 } else if (insert_index < 0) { | |
| 251 (void)TRACE_ERROR("ERROR: No free entries in MT context data array!"); | |
| 252 } else { | |
| 253 (void)TRACE_ERROR("ERROR: Unable to allocate memory for context data array!"); | |
| 254 } | |
| 255 | |
| 256 return context; | |
| 257 } | |
| 258 | |
| 259 /* | |
| 260 +------------------------------------------------------------------------------ | |
| 261 | Function : sm_extract_mt_context_data | |
| 262 +------------------------------------------------------------------------------ | |
| 263 | Description : Searches sm_pending_mt_array for the input TI. Returns the | |
| 264 | address of the data structure found, if any; otherwise NULL. | |
| 265 | If found, the entry in sm_pending_mt_array is reset to NULL. | |
| 266 | | |
| 267 | Parameters : ti - TI value identifying context | |
| 268 +------------------------------------------------------------------------------ | |
| 269 */ | |
| 270 /*@null@*/ /*@only@*/struct T_SM_CONTEXT_DATA * | |
| 271 sm_extract_mt_context_data(int /*@alt U8@*/ ti) | |
| 272 { | |
| 273 int index; | |
| 274 | |
| 275 for (index = 0; index < SM_MAX_NSAPI_OFFSET; index++) | |
| 276 { | |
| 277 if (sm_data.sm_pending_mt_array[index] != NULL && | |
| 278 sm_data.sm_pending_mt_array[index]->ti == ti) | |
| 279 { | |
| 280 struct T_SM_CONTEXT_DATA *context; | |
| 281 context = sm_data.sm_pending_mt_array[index]; | |
| 282 sm_data.sm_pending_mt_array[index] = NULL; | |
| 283 | |
| 284 return context; | |
| 285 } /* if */ | |
| 286 } /* for */ | |
| 287 return NULL; | |
| 288 } | |
| 289 | |
| 290 /* | |
| 291 +------------------------------------------------------------------------------ | |
| 292 | Function : sm_free_pending_mt_context_by_index | |
| 293 +------------------------------------------------------------------------------ | |
| 294 | Description : Frees context in sm_pending_mt_array indentified by index | |
| 295 | | |
| 296 | Parameters : index - index in sm_pending_mt_array[] | |
| 297 +------------------------------------------------------------------------------ | |
| 298 */ | |
| 299 void sm_free_pending_mt_context_by_index(U16 index) | |
| 300 { | |
| 301 TRACE_ASSERT(index < (U16)SM_MAX_NSAPI_OFFSET); | |
| 302 | |
| 303 /*lint -e{661} sm_context_array causes out of bounds access, it does not! */ | |
| 304 sm_free_context_data(sm_data.sm_pending_mt_array[index]); | |
| 305 /*lint -e{661} sm_context_array causes out of bounds access, it does not! */ | |
| 306 sm_data.sm_pending_mt_array[index] = NULL; | |
| 307 } | |
| 308 | |
| 309 /* | |
| 310 +------------------------------------------------------------------------------ | |
| 311 | Function : sm_linked_nsapis | |
| 312 +------------------------------------------------------------------------------ | |
| 313 | Description : Returns the nsapi_set of secondary contexts linked to this | |
| 314 | context. | |
| 315 | | |
| 316 | Parameters : context - context data | |
| 317 +------------------------------------------------------------------------------ | |
| 318 */ | |
| 319 U16 sm_linked_nsapis(U8 ti) | |
| 320 { | |
| 321 struct T_SM_CONTEXT_DATA *context; | |
| 322 int nsapi; | |
| 323 U16 linked_nsapis = 0; | |
| 324 U8 linked_ti; | |
| 325 | |
| 326 context = sm_get_context_data_from_ti(ti); | |
| 327 | |
| 328 TRACE_ASSERT(context != NULL); | |
| 329 | |
| 330 if (context EQ NULL) | |
| 331 return linked_nsapis; | |
| 332 | |
| 333 if (sm_is_secondary(context)) | |
| 334 { | |
| 335 linked_ti = context->linked_ti; | |
| 336 } else { | |
| 337 linked_ti = ti; | |
| 338 } | |
| 339 | |
| 340 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++) | |
| 341 { | |
| 342 context = sm_get_context_data_from_nsapi(nsapi); | |
| 343 if (context != NULL && context->ti != (U8)ti && context->ti != linked_ti && | |
| 344 sm_is_secondary(context) && context->linked_ti == (U8)ti) | |
| 345 { | |
| 346 linked_nsapis = sm_add_nsapi_to_nsapi_set(nsapi, linked_nsapis); | |
| 347 } /* if */ | |
| 348 } /* for */ | |
| 349 | |
| 350 return linked_nsapis; | |
| 351 } | |
| 352 | |
| 353 /* | |
| 354 +------------------------------------------------------------------------------ | |
| 355 | Function : sm_free_coded_msg | |
| 356 +------------------------------------------------------------------------------ | |
| 357 | Description : Stores a coded message in context data. | |
| 358 | Used for retransmissions (i.e. in case of time-outs, resume | |
| 359 | after suspension). | |
| 360 | | |
| 361 | Parameters : context - context data | |
| 362 | msg - coded message | |
| 363 +------------------------------------------------------------------------------ | |
| 364 */ | |
| 365 void sm_allocate_and_copy_coded_msg(struct T_SM_CONTEXT_DATA *context, | |
| 366 U8 est_cause, | |
| 367 /*@in@*/ T_sdu *msg) | |
| 368 { | |
| 369 U32 msg_len; | |
| 370 #ifdef DEBUG_VERBOSE | |
| 371 (void)TRACE_FUNCTION("sm_allocate_and_copy_coded_msg"); | |
| 372 #endif | |
| 373 | |
| 374 msg_len = (U32)(msg->l_buf >> 3); | |
| 375 | |
| 376 if (context->coded_msg != NULL) | |
| 377 { | |
| 378 sm_free_coded_msg(context); | |
| 379 } | |
| 380 | |
| 381 TRACE_ASSERT(context->coded_msg == NULL); | |
| 382 /* Allocate space for T_sdu (l_buf and o_buf) + air interface message octets */ | |
| 383 context->coded_msg = (T_sdu *)M_ALLOC(msg_len + (U32)offsetof(T_sdu, buf)); | |
| 384 | |
| 385 if (context->coded_msg == NULL) | |
| 386 { | |
| 387 return; | |
| 388 } | |
| 389 | |
| 390 /* coded_msg->o_buf is always 0. So we store the only external parameter | |
| 391 * in there (est_cause). */ | |
| 392 context->coded_msg->l_buf = msg->l_buf; | |
| 393 context->coded_msg->o_buf = (U16)est_cause; | |
| 394 memcpy(context->coded_msg->buf, &msg->buf[(msg->o_buf >> 3)], (size_t)msg_len); | |
| 395 } | |
| 396 | |
| 397 /* | |
| 398 +------------------------------------------------------------------------------ | |
| 399 | Function : sm_free_coded_msg | |
| 400 +------------------------------------------------------------------------------ | |
| 401 | Description : Frees the coded message stored for this NSAPI, if any. | |
| 402 | | |
| 403 | Parameters : context - context data | |
| 404 +------------------------------------------------------------------------------ | |
| 405 */ | |
| 406 void sm_free_coded_msg(struct T_SM_CONTEXT_DATA *context) | |
| 407 { | |
| 408 #ifdef DEBUG_VERBOSE | |
| 409 (void)TRACE_FUNCTION("sm_free_coded_msg"); | |
| 410 #endif | |
| 411 | |
| 412 if (context->coded_msg != NULL) { | |
| 413 sm_mfree(context->coded_msg); | |
| 414 } | |
| 415 context->coded_msg = NULL; | |
| 416 } | |
| 417 | |
| 418 | |
| 419 /*====================================================================== | |
| 420 * Network Control Memory Handler Functions | |
| 421 *======================================================================*/ | |
| 422 | |
| 423 /* | |
| 424 +------------------------------------------------------------------------------ | |
| 425 | Function : sm_nw_allocate_and_copy_*_pco | |
| 426 +------------------------------------------------------------------------------ | |
| 427 | Description : Allocate and copy requested or negotiated PCO data structure. | |
| 428 | | |
| 429 | Parameters : context - context data | |
| 430 | pco_len - PCO data length | |
| 431 | pco - PCO data | |
| 432 +------------------------------------------------------------------------------ | |
| 433 */ | |
| 434 void sm_nw_allocate_and_copy_requested_pco(/*@special@*/ | |
| 435 struct T_SM_CONTEXT_DATA *context, | |
| 436 size_t /*@alt U8,U16@*/ pco_len, | |
| 437 /*@unique@*/ U8 *pco) | |
| 438 { | |
| 439 TRACE_ASSERT(context->requested_pco == NULL); | |
| 440 context->requested_pco = (T_SM_pco *)M_ALLOC((U32)(pco_len + 1)); | |
| 441 TRACE_ASSERT(context->requested_pco != NULL); | |
| 442 | |
| 443 context->requested_pco->c_pco_value = (U8)pco_len; | |
| 444 memcpy(context->requested_pco->pco_value, pco, (size_t)pco_len); | |
| 445 } | |
| 446 | |
| 447 void sm_nw_allocate_and_copy_negotiated_pco(/*@special@*/ | |
| 448 struct T_SM_CONTEXT_DATA *context, | |
| 449 size_t /*@alt U8@*/ pco_len, | |
| 450 /*@unique@*/ U8 *pco) | |
| 451 { | |
| 452 TRACE_ASSERT(context->negotiated_pco == NULL); | |
| 453 context->negotiated_pco = (T_SM_pco *)M_ALLOC((U32)(pco_len + 1)); | |
| 454 TRACE_ASSERT(context->negotiated_pco != NULL); | |
| 455 | |
| 456 context->negotiated_pco->c_pco_value = (U8)pco_len; | |
| 457 memcpy(context->negotiated_pco->pco_value, pco, (size_t)pco_len); | |
| 458 } | |
| 459 | |
| 460 /* | |
| 461 +------------------------------------------------------------------------------ | |
| 462 | Function : sm_nw_free_*_pco | |
| 463 +------------------------------------------------------------------------------ | |
| 464 | Description : Free requested or negotiated PCO data structure | |
| 465 | | |
| 466 | Parameters : context - context data | |
| 467 +------------------------------------------------------------------------------ | |
| 468 */ | |
| 469 void | |
| 470 sm_nw_free_requested_pco(/*@special@*/struct T_SM_CONTEXT_DATA *context) | |
| 471 { | |
| 472 if (context->requested_pco != NULL) { | |
| 473 sm_mfree(context->requested_pco); | |
| 474 context->requested_pco = NULL; | |
| 475 } | |
| 476 } | |
| 477 | |
| 478 void | |
| 479 sm_nw_free_negotiated_pco(/*@special@*/struct T_SM_CONTEXT_DATA *context) | |
| 480 { | |
| 481 if (context->negotiated_pco != NULL) { | |
| 482 sm_mfree(context->negotiated_pco); | |
| 483 context->negotiated_pco = NULL; | |
| 484 } | |
| 485 } | |
| 486 | |
| 487 /* | |
| 488 +------------------------------------------------------------------------------ | |
| 489 | Function : sm_nw_allocate_and_copy_apn | |
| 490 +------------------------------------------------------------------------------ | |
| 491 | Description : Allocate and copy APN data structure. Inserted into context | |
| 492 | data structure. | |
| 493 | | |
| 494 | Parameters : context - Context data | |
| 495 | apn - APN data structure | |
| 496 +------------------------------------------------------------------------------ | |
| 497 */ | |
| 498 void sm_nw_allocate_and_copy_apn(/*@special@*/ | |
| 499 struct T_SM_CONTEXT_DATA *context, | |
| 500 U8 c_apn, /*@unique@*/ U8 *apn) | |
| 501 { | |
| 502 #ifdef DEBUG_VERBOSE | |
| 503 (void)TRACE_FUNCTION("sm_nw_allocate_and_copy_apn"); | |
| 504 #endif | |
| 505 | |
| 506 TRACE_ASSERT(context->apn == NULL); | |
| 507 context->apn = (T_SMREG_apn *)M_ALLOC((U32)sizeof(T_SMREG_apn)); | |
| 508 TRACE_ASSERT(context->apn != NULL); | |
| 509 context->apn->c_apn_buf = c_apn; | |
| 510 memcpy(context->apn->apn_buf, apn, (size_t)c_apn); | |
| 511 } | |
| 512 | |
| 513 /* | |
| 514 +------------------------------------------------------------------------------ | |
| 515 | Function : sm_nw_free_apn | |
| 516 +------------------------------------------------------------------------------ | |
| 517 | Description : Free APN data structure | |
| 518 | | |
| 519 | Parameters : context - Context data | |
| 520 +------------------------------------------------------------------------------ | |
| 521 */ | |
| 522 void sm_nw_free_apn(/*@special@*/ struct T_SM_CONTEXT_DATA *context) | |
| 523 { | |
| 524 #ifdef DEBUG_VERBOSE | |
| 525 (void)TRACE_FUNCTION("sm_nw_free_apn"); | |
| 526 #endif | |
| 527 | |
| 528 if (context->apn != NULL) { | |
| 529 sm_mfree(context->apn); | |
| 530 context->apn = NULL; | |
| 531 } | |
| 532 } | |
| 533 | |
| 534 /* | |
| 535 +------------------------------------------------------------------------------ | |
| 536 | Function : sm_nw_is_address_and_apn_equal | |
| 537 +------------------------------------------------------------------------------ | |
| 538 | Description : Compare requested IP address and APN with incoming ditto | |
| 539 | | |
| 540 | Parameters : context - Context data | |
| 541 | address - incoming IP address | |
| 542 | v_apn - valid flag for APN | |
| 543 | apn - APN value (void if v_apn == FALSE) | |
| 544 +------------------------------------------------------------------------------ | |
| 545 */ | |
| 546 BOOL sm_nw_is_address_and_apn_equal(struct T_SM_CONTEXT_DATA *context, | |
| 547 T_NAS_ip *context_address, | |
| 548 T_M_SM_address *msg_address, | |
| 549 U8 v_apn, T_M_SM_apn *apn) | |
| 550 { | |
| 551 /* Compare IP address */ | |
| 552 if (context_address->ctrl_ip_address == NAS_is_ip_not_present) { | |
| 553 return FALSE; | |
| 554 } else if (msg_address->pdp_type_org == (U8)M_SM_IETF_ORG && | |
| 555 context->pdp_type == msg_address->pdp_type_no) | |
| 556 { | |
| 557 if (context->pdp_type == (U8)SMREG_PDP_IPV4) | |
| 558 { | |
| 559 if (msg_address->c_add_info == (U8)NAS_SIZE_IPv4_ADDR && | |
| 560 memcmp(context_address->ip_address.ipv4_addr.a4, | |
| 561 msg_address->add_info, (size_t)NAS_SIZE_IPv4_ADDR) == 0) | |
| 562 { | |
| 563 /* IP address equal: FALLTHROUGH */ | |
| 564 } else { | |
| 565 return FALSE; | |
| 566 } | |
| 567 } else if (context->pdp_type == (U8)SMREG_PDP_IPV6) | |
| 568 { | |
| 569 if (msg_address->c_add_info == (U8)NAS_SIZE_IPv6_ADDR && | |
| 570 memcmp(context_address->ip_address.ipv6_addr.a6, | |
| 571 msg_address->add_info, (size_t)NAS_SIZE_IPv6_ADDR) == 0) | |
| 572 { | |
| 573 /* IP address equal: FALLTHROUGH */ | |
| 574 } else { | |
| 575 return FALSE; | |
| 576 } | |
| 577 } else { /* Bogus pdp_type */ | |
| 578 return FALSE; | |
| 579 } | |
| 580 } else { | |
| 581 return FALSE; | |
| 582 } | |
| 583 | |
| 584 /* Compare APN */ | |
| 585 if (v_apn == (U8)TRUE) { | |
| 586 /* Incoming APN present: Requested APN must also be present, and have same length and values */ | |
| 587 if (context->apn != NULL) { | |
| 588 if (context->apn->c_apn_buf == apn->c_apn_value) { | |
| 589 if (memcmp(context->apn->apn_buf, apn->apn_value, | |
| 590 (size_t)apn->c_apn_value) == 0) { | |
| 591 return TRUE; | |
| 592 } | |
| 593 } | |
| 594 } | |
| 595 return FALSE; | |
| 596 } else { | |
| 597 /* If incoming APN is absent, equality depends on the presence of a requested APN */ | |
| 598 return (context->apn == NULL); | |
| 599 } | |
| 600 } | |
| 601 | |
| 602 /* | |
| 603 +------------------------------------------------------------------------------ | |
| 604 | Function : sm_nw_allocate_and_copy_requested_tft | |
| 605 +------------------------------------------------------------------------------ | |
| 606 | Description : Allocate and copy TFT data structure. Inserted into context | |
| 607 | data structure. | |
| 608 | | |
| 609 | Parameters : context - Context data | |
| 610 | tft - TFT data structure | |
| 611 +------------------------------------------------------------------------------ | |
| 612 */ | |
| 613 void sm_nw_allocate_and_copy_requested_tft(/*@special@*/ | |
| 614 struct T_SM_CONTEXT_DATA *context, | |
| 615 /*@in@*/ | |
| 616 T_NAS_tft *tft) | |
| 617 { | |
| 618 #ifdef DEBUG_VERBOSE | |
| 619 (void)TRACE_FUNCTION("sm_nw_allocate_and_copy_requested_tft"); | |
| 620 #endif | |
| 621 | |
| 622 /* Free TFT memory if a TFT was already present but with a different | |
| 623 * number of elements. */ | |
| 624 if (context->requested_tft.ptr_tft_pf != NULL && | |
| 625 context->requested_tft.c_tft_pf != tft->c_tft_pf) | |
| 626 { | |
| 627 sm_nw_free_requested_tft(context); | |
| 628 } | |
| 629 | |
| 630 /* Allocate memory if TFT was not present before, or if it was freed above.*/ | |
| 631 if (context->requested_tft.ptr_tft_pf == NULL) | |
| 632 { | |
| 633 context->requested_tft.c_tft_pf = tft->c_tft_pf; | |
| 634 context->requested_tft.ptr_tft_pf = (T_NAS_tft_pf *) | |
| 635 M_ALLOC((U32)sizeof(T_NAS_tft_pf) * (U32)context->requested_tft.c_tft_pf); | |
| 636 TRACE_ASSERT(context->requested_tft.ptr_tft_pf != NULL); | |
| 637 } | |
| 638 | |
| 639 memcpy(context->requested_tft.ptr_tft_pf, tft->ptr_tft_pf, | |
| 640 sizeof(T_NAS_tft_pf) * (size_t)context->requested_tft.c_tft_pf); | |
| 641 context->requested_tft.tft_precence_mask = sm_tft_precence_mask(tft->ptr_tft_pf, tft->c_tft_pf); | |
| 642 } | |
| 643 | |
| 644 /* | |
| 645 +------------------------------------------------------------------------------ | |
| 646 | Function : sm_nw_allocate_active_tft | |
| 647 +------------------------------------------------------------------------------ | |
| 648 | Description : Allocate active TFT data structure. Inserted into context | |
| 649 | data structure. | |
| 650 | | |
| 651 | Parameters : context - Context data | |
| 652 +------------------------------------------------------------------------------ | |
| 653 */ | |
| 654 void sm_nw_allocate_active_tft(/*@special@*/struct T_SM_CONTEXT_DATA *context) | |
| 655 { | |
| 656 #ifdef DEBUG_VERBOSE | |
| 657 (void)TRACE_FUNCTION("sm_nw_allocate_active_tft"); | |
| 658 #endif | |
| 659 | |
| 660 TRACE_ASSERT (context->active_tft.ptr_tft_pf == NULL); | |
| 661 context->active_tft.c_tft_pf = (U8)0; | |
| 662 context->active_tft.ptr_tft_pf = (T_NAS_tft_pf *) | |
| 663 M_ALLOC((U32)sizeof(T_NAS_tft_pf) * (U32)NAS_SIZE_TFT_FILTER); | |
| 664 TRACE_ASSERT(context->active_tft.ptr_tft_pf != NULL); | |
| 665 context->active_tft.tft_precence_mask = (U8)0; | |
| 666 } | |
| 667 | |
| 668 /* | |
| 669 +------------------------------------------------------------------------------ | |
| 670 | Function : sm_nw_free_requested_tft | |
| 671 +------------------------------------------------------------------------------ | |
| 672 | Description : Free TFT data structure | |
| 673 | | |
| 674 | Parameters : context - Context data | |
| 675 +------------------------------------------------------------------------------ | |
| 676 */ | |
| 677 void sm_nw_free_requested_tft(/*@special@*/struct T_SM_CONTEXT_DATA *context) | |
| 678 { | |
| 679 #ifdef DEBUG_VERBOSE | |
| 680 (void)TRACE_FUNCTION("sm_nw_free_requested_tft"); | |
| 681 #endif | |
| 682 | |
| 683 if (context->requested_tft.ptr_tft_pf != NULL) { | |
| 684 sm_mfree(context->requested_tft.ptr_tft_pf); | |
| 685 context->requested_tft.ptr_tft_pf = NULL; | |
| 686 context->requested_tft.c_tft_pf = (U8)0; | |
| 687 context->requested_tft.tft_precence_mask = (U8)0; | |
| 688 } | |
| 689 } | |
| 690 | |
| 691 /* | |
| 692 +------------------------------------------------------------------------------ | |
| 693 | Function : sm_nw_free_active_tft | |
| 694 +------------------------------------------------------------------------------ | |
| 695 | Description : Free TFT data structure | |
| 696 | | |
| 697 | Parameters : context - Context data | |
| 698 +------------------------------------------------------------------------------ | |
| 699 */ | |
| 700 void sm_nw_free_active_tft(/*@special@*/struct T_SM_CONTEXT_DATA *context) | |
| 701 { | |
| 702 #ifdef DEBUG_VERBOSE | |
| 703 (void)TRACE_FUNCTION("sm_nw_free_active_tft"); | |
| 704 #endif | |
| 705 | |
| 706 if (context->active_tft.ptr_tft_pf != NULL) { | |
| 707 sm_mfree(context->active_tft.ptr_tft_pf); | |
| 708 context->active_tft.ptr_tft_pf = NULL; | |
| 709 context->active_tft.c_tft_pf = (U8)0; | |
| 710 context->active_tft.tft_precence_mask = (U8)0; | |
| 711 } | |
| 712 } | |
| 713 | |
| 714 /* | |
| 715 +------------------------------------------------------------------------------ | |
| 716 | Function : sm_nw_store_requested_address | |
| 717 +------------------------------------------------------------------------------ | |
| 718 | Description : Utility function which stores the IP address requested from | |
| 719 | the network. | |
| 720 | | |
| 721 | Parameters : context - context data | |
| 722 | pdp_type - PDP type number | |
| 723 | ctrl_ip_address - IP address type | |
| 724 | ip_address - IP address (void if ctrl_ip_address == NAS_is_ip_not_present) | |
| 725 +------------------------------------------------------------------------------ | |
| 726 */ | |
| 727 void sm_nw_store_requested_address(struct T_SM_CONTEXT_DATA *context, | |
| 728 U8 pdp_type, | |
| 729 T_NAS_ctrl_ip_address ctrl_ip_address, | |
| 730 T_NAS_ip_address *ip_address) | |
| 731 { | |
| 732 context->pdp_type = pdp_type; | |
| 733 context->requested_address.ctrl_ip_address = ctrl_ip_address; | |
| 734 if (ctrl_ip_address != NAS_is_ip_not_present) { | |
| 735 if (pdp_type == (U8)SMREG_PDP_PPP || | |
| 736 (pdp_type == (U8)SMREG_PDP_IPV4 && ctrl_ip_address != NAS_is_ipv4) || | |
| 737 (pdp_type == (U8)SMREG_PDP_IPV6 && ctrl_ip_address != NAS_is_ipv6)) { | |
| 738 (void)TRACE_ERROR("Mismatching pdp_type and ip_address controller field in SMREG_PDP_ACTIVATE_REQ - using union controller!"); | |
| 739 } | |
| 740 switch (ctrl_ip_address) | |
| 741 { | |
| 742 case NAS_is_ipv4: | |
| 743 context->pdp_type = (U8)SMREG_PDP_IPV4; | |
| 744 memcpy(context->requested_address.ip_address.ipv4_addr.a4, | |
| 745 ip_address->ipv4_addr.a4, (size_t)NAS_SIZE_IPv4_ADDR); | |
| 746 break; | |
| 747 case NAS_is_ipv6: | |
| 748 context->pdp_type = (U8)SMREG_PDP_IPV6; | |
| 749 memcpy(context->requested_address.ip_address.ipv6_addr.a6, | |
| 750 ip_address->ipv6_addr.a6, (size_t)NAS_SIZE_IPv6_ADDR); | |
| 751 break; | |
| 752 default: | |
| 753 break; | |
| 754 } | |
| 755 } | |
| 756 } | |
| 757 | |
| 758 /* | |
| 759 +------------------------------------------------------------------------------ | |
| 760 | Function : sm_nw_store_negotiated_address | |
| 761 +------------------------------------------------------------------------------ | |
| 762 | Description : Utility function which stores the address received from the | |
| 763 | network. | |
| 764 | | |
| 765 | Parameters : context - context data | |
| 766 | v_address - valid flag for address | |
| 767 | address - IP address (void if v_address == FALSE) | |
| 768 +------------------------------------------------------------------------------ | |
| 769 */ | |
| 770 void sm_nw_store_negotiated_address(struct T_SM_CONTEXT_DATA *context, | |
| 771 T_M_SM_address *address, | |
| 772 U8 v_address) | |
| 773 { | |
| 774 if (v_address == (U8)TRUE && address->pdp_type_org == (U8)M_SM_IETF_ORG) { | |
| 775 /* Update PDP type from message */ | |
| 776 context->pdp_type = address->pdp_type_no; | |
| 777 if (address->pdp_type_no == (U8)M_SM_IP4_TYPE) { | |
| 778 if (address->c_add_info != (U8)NAS_SIZE_IPv4_ADDR) { | |
| 779 (void)TRACE_EVENT_P1("Warning: IPv4 address has length %d != 4!", | |
| 780 (int)address->c_add_info); | |
| 781 } | |
| 782 context->negotiated_address.ctrl_ip_address = NAS_is_ipv4; | |
| 783 memcpy(&context->negotiated_address.ip_address, &address->add_info, (size_t)NAS_SIZE_IPv4_ADDR); | |
| 784 } else if (address->pdp_type_no == (U8)M_SM_IP6_TYPE) { | |
| 785 if (address->c_add_info != (U8)NAS_SIZE_IPv6_ADDR) { | |
| 786 (void)TRACE_EVENT_P1("Warning: IPv6 address has length %d != 16!", | |
| 787 (int)address->c_add_info); | |
| 788 } | |
| 789 context->negotiated_address.ctrl_ip_address = NAS_is_ipv6; | |
| 790 memcpy(&context->negotiated_address.ip_address, &address->add_info, (size_t)NAS_SIZE_IPv6_ADDR); | |
| 791 } else { | |
| 792 (void)TRACE_EVENT_P1("ERROR: Invalid PDP type %d; address discarded!", | |
| 793 address->pdp_type_no); | |
| 794 } | |
| 795 } else { | |
| 796 /* Check for static IP address allocation/request; | |
| 797 * PDP addr IE is not included in this case [3G 24.008, 9.5.2.1] */ | |
| 798 switch (context->requested_address.ctrl_ip_address) | |
| 799 { | |
| 800 case NAS_is_ipv4: | |
| 801 context->pdp_type = (U8)SMREG_PDP_IPV4; | |
| 802 context->negotiated_address.ctrl_ip_address = NAS_is_ipv4; | |
| 803 memcpy(context->negotiated_address.ip_address.ipv4_addr.a4, | |
| 804 context->requested_address .ip_address.ipv4_addr.a4, | |
| 805 (size_t)NAS_SIZE_IPv4_ADDR); | |
| 806 break; | |
| 807 case NAS_is_ipv6: | |
| 808 context->pdp_type = (U8)SMREG_PDP_IPV6; | |
| 809 context->negotiated_address.ctrl_ip_address = NAS_is_ipv6; | |
| 810 memcpy(context->negotiated_address.ip_address.ipv6_addr.a6, | |
| 811 context->requested_address .ip_address.ipv6_addr.a6, | |
| 812 (size_t)NAS_SIZE_IPv6_ADDR); | |
| 813 break; | |
| 814 default: | |
| 815 /* PPP or other non-IP address context; i.e. no static address alloc. */ | |
| 816 context->negotiated_address.ctrl_ip_address = NAS_is_ip_not_present; | |
| 817 } | |
| 818 } | |
| 819 } | |
| 820 | |
| 821 /* | |
| 822 +------------------------------------------------------------------------------ | |
| 823 | Function : sm_nw_copy_negotiated_address_to_requested | |
| 824 +------------------------------------------------------------------------------ | |
| 825 | Description : Utility function which copies the address received from the | |
| 826 | network to be the requested address. Used for context | |
| 827 | reactivations, which must use the negotiated IP address. | |
| 828 | | |
| 829 | Parameters : context - context data | |
| 830 +------------------------------------------------------------------------------ | |
| 831 */ | |
| 832 void sm_nw_copy_negotiated_address_to_requested(struct T_SM_CONTEXT_DATA *context) | |
| 833 { | |
| 834 sm_nw_store_requested_address(context, context->pdp_type, | |
| 835 context->negotiated_address.ctrl_ip_address, | |
| 836 &context->negotiated_address.ip_address); | |
| 837 } | |
| 838 | |
| 839 /* | |
| 840 +------------------------------------------------------------------------------ | |
| 841 | Function : sm_is_address_changed_with_reactivation | |
| 842 +------------------------------------------------------------------------------ | |
| 843 | Description : Utility function which compares the address of the air message | |
| 844 | and the address already stored in the context. This function | |
| 845 | is useful only in PDP REACTIVATION cases. If the addresses | |
| 846 | are not equal the function returns false and the pdp context | |
| 847 | gets deactivated. | |
| 848 | | |
| 849 | Parameters : context - context data, air message address | |
| 850 +------------------------------------------------------------------------------ | |
| 851 */ | |
| 852 BOOL sm_is_address_changed_with_reactivation(struct T_SM_CONTEXT_DATA *context, | |
| 853 T_M_SM_address *address, | |
| 854 U8 v_address) | |
| 855 { | |
| 856 BOOL result = FALSE; | |
| 857 if (sm_is_context_pending_reactivation(context)) | |
| 858 { | |
| 859 if (v_address == (U8)TRUE && address->pdp_type_org == (U8)M_SM_IETF_ORG) | |
| 860 { | |
| 861 if ( (address->pdp_type_no == (U8)M_SM_IP4_TYPE) && | |
| 862 (context->negotiated_address.ctrl_ip_address == NAS_is_ipv4) ) | |
| 863 { | |
| 864 if (memcmp(&context->negotiated_address.ip_address, | |
| 865 &address->add_info, (size_t)NAS_SIZE_IPv4_ADDR) != 0) | |
| 866 { | |
| 867 result = TRUE; | |
| 868 } | |
| 869 } else if ( (address->pdp_type_no == (U8)M_SM_IP6_TYPE) && | |
| 870 (context->negotiated_address.ctrl_ip_address == NAS_is_ipv6) ) | |
| 871 { | |
| 872 if (memcmp(&context->negotiated_address.ip_address, | |
| 873 &address->add_info, (size_t)NAS_SIZE_IPv6_ADDR) != 0) | |
| 874 { | |
| 875 result = TRUE; | |
| 876 } | |
| 877 } | |
| 878 } | |
| 879 /* Clear the pending reactivation flag. We don't need this anymore. */ | |
| 880 sm_set_context_pending_reactivation(context, FALSE); | |
| 881 } | |
| 882 if (result == TRUE) { | |
| 883 (void)TRACE_EVENT_P1( "PDP address changed with reactivation. Deactivate nsapi %d", | |
| 884 context->nsapi ); | |
| 885 } | |
| 886 return result; | |
| 887 } | |
| 888 /*==== END OF FILE ==========================================================*/ |
