FreeCalypso > hg > freecalypso-citrine
comparison ccd/asn1_integ.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.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 */ |
