FreeCalypso > hg > freecalypso-citrine
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 */ |