comparison ccd/asn1_integ_ext.c @ 0:75a11d740a02

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