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