comparison src/gpf/ccd/asn1_integ.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4e78acac3d88
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul : asn1_integ.c
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : Definition of encoding and decoding functions for ASN1_INTEGER
18 | elements
19 +-----------------------------------------------------------------------------
20 */
21
22 /*
23 * Standard definitions like UCHAR, ERROR etc.
24 */
25 #include "typedefs.h"
26 #include "header.h"
27
28 /*
29 * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only
30 * look at ccdapi.h
31 */
32 #undef USE_DRIVER
33 #include "ccdapi.h"
34
35 /*
36 * Types and functions for bit access and manipulation
37 */
38 #include "ccd_globs.h"
39 #include "bitfun.h"
40
41 /*
42 * Prototypes of ccd internal functions
43 */
44 #include "ccd.h"
45
46 /*
47 * Declaration of coder/decoder tables
48 */
49 #include "ccdtable.h"
50 #include "ccddata.h"
51
52 #ifndef RUN_INT_RAM
53 /*
54 +--------------------------------------------------------------------+
55 | PROJECT : CCD (6144) MODULE : asn1_integ |
56 | STATE : code ROUTINE : Read_unique_Integer |
57 +--------------------------------------------------------------------+
58
59 PURPOSE : Decode integer with only one possible value.
60 Such a value is never encoded.
61 */
62 void Read_unique_Integer (const ULONG e_ref, T_CCD_Globs *globs)
63 {
64 ULONG varRef, valRef;
65 U8 *value;
66
67 varRef = (ULONG) melem[e_ref].elemRef;
68 valRef = (ULONG) mvar[varRef].valueDefs;
69 #ifdef DEBUG_CCD
70 #ifndef CCD_SYMBOLS
71 TRACE_CCD (globs, "Read_unique_Integer()");
72 #else
73 TRACE_CCD (globs, "Read_unique_Integer() %s", ccddata_get_alias((USHORT) e_ref, 1));
74 #endif
75 #endif
76
77 if (mval[valRef].startValue EQ 0)
78 {
79 /*
80 * Do not do anything for empty sequences and NULL elements.
81 * (Hint: Integers with only one possible value equal to 0 are
82 * automatically processed through memory reset of the C-structure
83 * at the beginning of decode activities or after each dynamic
84 * memory allocation.)
85 */
86 return;
87 }
88 else
89 {
90 /*
91 * For optional elements we have already set the valid flag in the
92 * C-structure while processing ASN1_SEQ.
93 */
94 if (melem[e_ref].optional)
95 {
96 if (globs->pstruct[globs->pstructOffs++] EQ FALSE)
97 return;
98 }
99
100 #ifdef DYNAMIC_ARRAYS
101 if ( is_pointer_type(e_ref) )
102 {
103 value = PER_allocmem(e_ref, 1, globs);
104
105 if (value EQ (U8 *)ccdError)
106 return;
107
108 /*
109 * Store pointer to allocated memory in c structure.
110 */
111 *(U8 **)(globs->pstruct + globs->pstructOffs) = value;
112 }
113 else
114 #endif
115 value = globs->pstruct + globs->pstructOffs;
116
117 switch (mvar[varRef].cType)
118 {
119 case 'B':
120 *(U8*) value = (U8) mval[valRef].startValue;
121 break;
122 case 'C':
123 *(S8*) value = (S8) mval[valRef].startValue;
124 break;
125 case 'S':
126 *(U16*) value = (U16) mval[valRef].startValue;
127 break;
128 case 'T':
129 *(S16*) value = (S16) mval[valRef].startValue;
130 break;
131 case 'L':
132 *(U32*) value = (U32) mval[valRef].startValue;
133 break;
134 case 'M':
135 *(S32*) value = (S32) mval[valRef].startValue;
136 break;
137 default:
138 ccd_recordFault (globs,ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, value);
139 break;
140 }
141 return;
142 }
143 }
144 #endif /* !RUN_INT_RAM */
145
146 #ifndef RUN_INT_RAM
147 /*
148 +--------------------------------------------------------------------+
149 | PROJECT : CCD (6144) MODULE : asn1_integ |
150 | STATE : code ROUTINE : cdc_asn1_integ_decode |
151 +--------------------------------------------------------------------+
152
153 PURPOSE : Encoding of the PER integer type for UMTS
154 PER-visible constraints restrict the integer value to be a
155 constrained whole number. This gives a lower and an upper
156 bound for the integer. The lb is also called offset. The
157 encoded value is the difference between the actual and the
158 offset value.
159 A possible and meant default value is never encoded.
160 */
161 SHORT cdc_asn1_integ_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
162 {
163 ULONG repeat=1, maxRep=1, varRef, valRef;
164 BOOL DefaultFound= FALSE;
165 S32 IfnotPresent;
166 UBYTE *value, *old_pstruct = NULL;
167
168 varRef = (ULONG) melem[e_ref].elemRef;
169
170 #ifdef DEBUG_CCD
171 #ifndef CCD_SYMBOLS
172 TRACE_CCD (globs, "cdc_asn1_integ_decode()");
173 #else
174 TRACE_CCD (globs, "cdc_asn1_integ_decode() %s", ccddata_get_alias((USHORT) e_ref, 1));
175 #endif
176 #endif
177
178 /*
179 * Set the offset in the C-structure on the value for this element.
180 */
181 globs->pstructOffs = melem[e_ref].structOffs;
182
183 /*
184 * Decode an empty sequence, a NULL element or an integer of constant value.
185 */
186 if (mvar[varRef].bSize EQ 0)
187 {
188 Read_unique_Integer (e_ref, globs);
189 return 1;
190 }
191 valRef = (ULONG) mvar[varRef].valueDefs;
192
193 /*
194 * Set pstrcutOffs and maxRep. Check the valid flag in case of optional elements.
195 */
196 if (PER_CommonBegin (e_ref, &maxRep, globs) NEQ ccdOK)
197 return 1;
198
199 #ifdef DYNAMIC_ARRAYS
200 /*
201 * Allocate memory if this is a pointer type (dynamic array)
202 */
203 if ( is_pointer_type(e_ref) ) {
204 old_pstruct = globs->pstruct;
205 if ( PER_allocmem_and_update(e_ref, maxRep, globs) NEQ ccdOK)
206 /* No memory - Return. Error already set in function call above. */
207 return 1;
208 }
209 #endif
210
211 /*
212 * Check if there is a default value for the element.
213 * If yes, just set it aside for a later comparision.
214 */
215 if (mval[valRef+1].isDefault EQ 2)
216 {
217 IfnotPresent = mval[valRef+1].startValue;
218 DefaultFound = TRUE;
219 }
220
221 /*
222 * Decode all elements of the array.
223 */
224 while ( repeat <= maxRep)
225 {
226
227 value = globs->pstruct + globs->pstructOffs;
228
229 /*
230 * There is a default value for this integer elment.
231 * While decoding of the ASN1-SEQUENCE contiaing this integer
232 * we have used a particular byte of C-structure to signalize
233 * the decoding of a default value (byte set to 0).
234 */
235 if (DefaultFound AND !globs->pstruct[melem[e_ref].structOffs])
236 {
237 switch (mvar[varRef].cType)
238 {
239 case 'B':
240 *(U8*) value = (U8) IfnotPresent;
241 break;
242 case 'C':
243 *(S8*) value = (S8) IfnotPresent;
244 break;
245 case 'S':
246 *(U16*) value = (U16) IfnotPresent;
247 break;
248 case 'T':
249 *(S16*) value = (S16) IfnotPresent;
250 break;
251 case 'L':
252 *(U32*) value = (U32) IfnotPresent;
253 break;
254 case 'M':
255 *(S32*) value = (S32) IfnotPresent;
256 break;
257 default:
258 ccd_recordFault (globs,ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, value);
259 return 1;
260 }
261 }
262 /*
263 * There is no default value defined for this integer elment.
264 * Read the value from the bit buffer.
265 */
266 else
267 {
268 U32 ub, lb;
269 ULONG readBits;
270 U32 DecodedValue;
271
272 lb = mval[valRef].startValue;
273 ub = mval[valRef].endValue;
274
275 /*
276 * Read the non-negative value from the air message.
277 */
278 readBits = bf_getBits (mvar[varRef].bSize, globs);
279
280
281 if (readBits <= (U32)(ub - lb))
282 {
283 DecodedValue = lb + readBits;
284 /*
285 * Add the offset to the read value to get the actual one.
286
287 */
288 switch (mvar[varRef].cType)
289 {
290 case 'B':
291 *(U8*) value = (U8) DecodedValue;
292 break;
293 case 'C':
294 *(S8*) value = (S8) DecodedValue;
295 break;
296 case 'S':
297 *(U16*) value = (U16) DecodedValue;
298 break;
299 case 'T':
300 *(S16*) value = (S16) DecodedValue;
301 break;
302 case 'L':
303 *(U32*) value = (U32) DecodedValue;
304 break;
305 case 'M':
306 *(S32*) value = (S32) DecodedValue;
307 break;
308 default:
309 ccd_recordFault (globs,ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, value);
310 break;
311 }
312 }
313 else
314 {
315 #ifdef DEBUG_CCD
316 TRACE_CCD (globs, "integer out of range! %ld require: %ld .. %ld ", DecodedValue, lb, ub);
317 #endif
318 if (melem[e_ref].optional)
319 ccd_recordFault (globs, ERR_ASN1_OPT_IE, CONTINUE, (USHORT) e_ref, value);
320 else
321 ccd_recordFault (globs, ERR_ASN1_MAND_IE, CONTINUE, (USHORT) e_ref, value);
322 }
323 }
324 repeat ++;
325 globs->pstructOffs += mvar[varRef].cSize;
326 }/*while*/
327
328 #ifdef DYNAMIC_ARRAYS
329 if (old_pstruct NEQ NULL)
330 globs->pstruct = old_pstruct;
331 #endif
332
333 return 1;
334 }
335 #endif /* !RUN_INT_RAM */
336
337 #ifndef RUN_INT_RAM
338 /*
339 +--------------------------------------------------------------------+
340 | PROJECT : CCD (6144) MODULE : asn1_integ |
341 | STATE : code ROUTINE : cdc_asn1_integ_encode |
342 +--------------------------------------------------------------------+
343
344 PURPOSE : Encoding of the PER integer type for UMTS
345 PER-visible constraints restrict the integer value to be a
346 constrained whole number. This gives a lower and an upper
347 bound for the integer. The lb is also called offset. The
348 encoded value is the difference between the actual and the
349 offset value. Hence encoded values are non-negative.
350 A possible and meant default value is never encoded.
351 */
352 SHORT cdc_asn1_integ_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
353 {
354 ULONG repeat=1, maxRep=1, varRef, valRef;
355 BOOL DefaultFound= FALSE;
356 S32 IfnotPresent;
357 U8 *base_pstruct;
358
359 #ifdef DEBUG_CCD
360 #ifndef CCD_SYMBOLS
361 TRACE_CCD (globs, "cdc_asn1_integ_encode()");
362 #else
363 TRACE_CCD (globs, "cdc_asn1_integ_encode() %s", ccddata_get_alias((USHORT) e_ref, 1));
364 #endif
365 #endif
366
367 varRef = (ULONG) melem[e_ref].elemRef;
368 valRef = (ULONG) mvar[varRef].valueDefs;
369
370 /*
371 * Don't do anything for empty sequences, NULL elements or integers of constant value.
372 */
373 if (mvar[varRef].bSize EQ 0)
374 return 1;
375
376 /*
377 * Set pstrcutOffs and maxRep. Check the valid flag in case of optional elements.
378 */
379 if (PER_CommonBegin (e_ref, &maxRep, globs) NEQ ccdOK)
380 return 1;
381
382 /*
383 * Check if there is a default value for the element.
384 * If yes, just set it aside for a later comparision.
385 */
386 if (mval[valRef+1].isDefault EQ 2)
387 {
388 IfnotPresent = mval[valRef+1].startValue;
389 DefaultFound = TRUE;
390 }
391
392 #ifdef DYNAMIC_ARRAYS
393 if ( is_pointer_type(e_ref) )
394 {
395 base_pstruct = *(U8 **)(globs->pstruct + globs->pstructOffs);
396 if (ccd_check_pointer(base_pstruct) == ccdOK)
397 {
398 globs->pstructOffs = 0;
399 }
400 else
401 {
402 ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref,
403 &globs->pstruct[globs->pstructOffs]);
404 return 1;
405 }
406 }
407 else
408 #endif
409 base_pstruct = globs->pstruct;
410
411 /*
412 * Encode all elements of the array.
413 */
414 while ( repeat <= maxRep)
415 {
416 S32 ub, lb, value;
417 UBYTE *p;
418
419 /*
420 * setup the read pointer to the element in the C-structure
421 */
422 p = base_pstruct + globs->pstructOffs;
423
424 switch (mvar[varRef].cType)
425 {
426 case 'B':
427 value = (S32)*(UBYTE *) p;
428 break;
429 case 'C':
430 value = (S32)*(S8 *) p;
431 break;
432 case 'S':
433 value = (S32)*(USHORT *) p;
434 break;
435 case 'T':
436 value = (S32)*(S16 *) p;
437 break;
438 case 'L':
439 /*
440 * This type casting can be critical.
441 * Thus the case of bSize=32 will be handled separately.
442 */
443 if (mvar[varRef].bSize < 32)
444 {
445 value = (S32)*(U32 *) p;
446 }
447 break;
448 case 'M':
449 value = *(S32 *) p;
450 break;
451 default:
452 ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, p);
453 return 1;
454 }
455
456 if (mvar[varRef].cType EQ 'L' AND
457 (mvar[varRef].bSize EQ 32))
458 {
459 ULONG CriticalValue;
460 U32 lb, ub;
461 CriticalValue = *(U32 *) p;
462 if (!DefaultFound OR (U32)IfnotPresent NEQ CriticalValue)
463 {
464 lb = (U32) mval[valRef].startValue;
465 ub = (U32) mval[valRef].endValue;
466 if (lb <= CriticalValue && CriticalValue <= ub)
467 {
468 bf_writeVal (CriticalValue - lb, mvar[varRef].bSize, globs);
469 }
470 }
471 else
472 {
473 #ifdef DEBUG_CCD
474 TRACE_CCD (globs, "integer out of range! %ld require: %ld .. %ld ",
475 value, lb, ub);
476 #endif
477 ccd_recordFault (globs, ERR_INT_VALUE, CONTINUE, (USHORT) e_ref, p);
478 }
479 }
480 else
481 {
482 /*
483 * Encode only non-default values.
484 */
485 if (!DefaultFound OR IfnotPresent NEQ value)
486 {
487 /*
488 * A non-negative-binary-integer will be encoded since the offset must
489 * be subtracted from the value read from the C-structure.
490 */
491 lb = mval[valRef].startValue;
492 ub = mval[valRef].endValue;
493 if (lb <= value AND value <= ub)
494 {
495 bf_writeVal ((ULONG)(value - lb), mvar[varRef].bSize, globs);
496 }
497 else
498 {
499 #ifdef DEBUG_CCD
500 TRACE_CCD (globs, "integer out of range! %ld require: %ld .. %ld ", value, lb, ub);
501 #endif
502 ccd_recordFault (globs, ERR_INT_VALUE, CONTINUE, (USHORT) e_ref, p);
503 }
504 }
505 }
506 repeat ++;
507 globs->pstructOffs += mvar[varRef].cSize;
508 }/* while-loop */
509
510 return 1;
511 }
512 #endif /* !RUN_INT_RAM */