comparison src/g23m-gprs/sm/sm_memory_handler.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: 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 ==========================================================*/