FreeCalypso > hg > fc-magnetite
comparison src/gpf3/ccd/asn1_integ.c @ 2:c41a534f33c6
src/gpf3: preened GPF goo from TCS3.2
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Sep 2016 23:52:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:864b8cc0cf63 | 2:c41a534f33c6 |
---|---|
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 */ |