FreeCalypso > hg > fc-selenite
comparison src/gpf/ccd/ccd.c @ 5:1ea54a97e831
src/gpf: import of Magnetite src/gpf3
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Sun, 15 Jul 2018 08:11:07 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 4:6e457872f745 | 5:1ea54a97e831 |
|---|---|
| 1 /* | |
| 2 +----------------------------------------------------------------------------- | |
| 3 | Project : | |
| 4 | Modul : ccd.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 : Condat Conder Decoder - | |
| 18 | Definition of encoding and decoding functions of | |
| 19 | air interface messages | |
| 20 +----------------------------------------------------------------------------- | |
| 21 */ | |
| 22 | |
| 23 #define CCD_C | |
| 24 | |
| 25 #include <stdio.h> | |
| 26 #include <stdlib.h> | |
| 27 #include <stdarg.h> | |
| 28 #include <string.h> | |
| 29 #include <setjmp.h> | |
| 30 | |
| 31 #ifdef _MSDOS | |
| 32 #include <dos.h> | |
| 33 #include <conio.h> | |
| 34 #endif | |
| 35 | |
| 36 /* | |
| 37 * Standard definitions like UCHAR, ERROR etc. | |
| 38 */ | |
| 39 | |
| 40 #include "typedefs.h" | |
| 41 #include "header.h" | |
| 42 | |
| 43 /* | |
| 44 * Types and constants used by CCD | |
| 45 */ | |
| 46 #include "ccd_globs.h" | |
| 47 | |
| 48 /* | |
| 49 * Type definitions for CCD data tables | |
| 50 */ | |
| 51 #include "ccdtable.h" | |
| 52 | |
| 53 /* | |
| 54 * Function prototypes of CCD-CCDDATA interface | |
| 55 */ | |
| 56 #include "ccddata.h" | |
| 57 | |
| 58 /* | |
| 59 * Error codes and prototypes of exported functions by CCD | |
| 60 * (USE_DRIVER EQ undef) | |
| 61 * For prototypes only look at ccdapi.h. | |
| 62 */ | |
| 63 #undef USE_DRIVER | |
| 64 #include "ccdapi.h" | |
| 65 | |
| 66 /* | |
| 67 * Types and functions for bit access and manipulation | |
| 68 */ | |
| 69 #include "bitfun.h" | |
| 70 | |
| 71 | |
| 72 /* | |
| 73 * Prototypes of ccd internal functions | |
| 74 */ | |
| 75 #include "ccd.h" | |
| 76 | |
| 77 #if !(defined (CCD_TEST)) | |
| 78 #include "vsi.h" | |
| 79 #include "os.h" | |
| 80 #endif | |
| 81 | |
| 82 #ifdef SHARED_VSI | |
| 83 #define VSI_CALLER 0, | |
| 84 #else | |
| 85 #define VSI_CALLER | |
| 86 #endif | |
| 87 | |
| 88 #ifndef RUN_FLASH | |
| 89 /* task_null is used in ccd_signup. It must have the same RUN_... setting. */ | |
| 90 static T_CCD_TASK_TABLE task_null; | |
| 91 #endif /* !RUN_FLASH */ | |
| 92 | |
| 93 //TISH modified for MSIM | |
| 94 #if defined (CCD_TEST) || defined (_TOOLS_) || defined (WIN32) | |
| 95 /* For the DLL and for all simple environment define the task list locally */ | |
| 96 /* 10 entries should be more than enough */ | |
| 97 #define MAX_ENTITIES 10 | |
| 98 T_CCD_TASK_TABLE* ccd_task_list[MAX_ENTITIES]; | |
| 99 #else | |
| 100 extern T_CCD_TASK_TABLE* ccd_task_list[]; | |
| 101 #endif | |
| 102 | |
| 103 #ifndef RUN_FLASH | |
| 104 const T_CCD_VarTabEntry* mvar; | |
| 105 const T_CCD_SpareTabEntry* spare; | |
| 106 const T_CCD_CalcTabEntry* calc; | |
| 107 const T_CCD_CompTabEntry* mcomp; | |
| 108 const T_CCD_ElemTabEntry* melem; | |
| 109 const T_CCD_CalcIndex* calcidx; | |
| 110 const T_CCD_ValTabEntry* mval; | |
| 111 #else | |
| 112 extern const T_CCD_VarTabEntry* mvar; | |
| 113 extern const T_CCD_SpareTabEntry* spare; | |
| 114 extern const T_CCD_CalcTabEntry* calc; | |
| 115 extern const T_CCD_CompTabEntry* mcomp; | |
| 116 extern const T_CCD_ElemTabEntry* melem; | |
| 117 extern const T_CCD_CalcIndex* calcidx; | |
| 118 extern const T_CCD_ValTabEntry* mval; | |
| 119 #endif | |
| 120 | |
| 121 #ifndef RUN_FLASH | |
| 122 /* | |
| 123 * Attention: if one of the following static data shall be used in | |
| 124 * both, internal as well as external RAM, they must be made global. | |
| 125 */ | |
| 126 static USHORT max_message_id; | |
| 127 | |
| 128 /* | |
| 129 * CCD internal buffer for decoded message | |
| 130 */ | |
| 131 static UBYTE *ccd_decMsgBuffer; | |
| 132 /* | |
| 133 * Layer-specific cache for the bitlength of the message-identifier; | |
| 134 * A value of 0 indicates an empty (undetermined) entry | |
| 135 */ | |
| 136 static UBYTE *mi_length; | |
| 137 | |
| 138 /* | |
| 139 * CCD internal variables used in each call to code or decode message | |
| 140 */ | |
| 141 | |
| 142 static U8 aim_rrc_rcm; | |
| 143 static U8 aim_rrlp; | |
| 144 static U8 aim_sat; | |
| 145 | |
| 146 static T_CCD_Globs globs_all; | |
| 147 #endif /* !RUN_FLASH */ | |
| 148 | |
| 149 /* | |
| 150 * CCD will call its encoding/decoding functions through a jump table. | |
| 151 */ | |
| 152 #include "ccd_codingtypes.h" | |
| 153 #ifndef RUN_FLASH | |
| 154 T_FUNC_POINTER codec[MAX_CODEC_ID+1][2]; | |
| 155 #else | |
| 156 extern T_FUNC_POINTER codec[MAX_CODEC_ID+1][2]; | |
| 157 #endif | |
| 158 | |
| 159 #ifndef RUN_FLASH | |
| 160 /* initialized is used in ccd_signup. It must have the same RUN_... setting. */ | |
| 161 /* | |
| 162 * Initialising flag | |
| 163 */ | |
| 164 BOOL initialized = FALSE; | |
| 165 #endif /* !RUN_FLASH */ | |
| 166 | |
| 167 #ifdef SHARED_CCD | |
| 168 /* | |
| 169 * If CCD is used in a premptive multithreaded system we need | |
| 170 * a semaphore to protect the coding and decoding sections. | |
| 171 */ | |
| 172 #ifndef RUN_FLASH | |
| 173 T_HANDLE semCCD_Codec, semCCD_Buffer; | |
| 174 #else | |
| 175 extern T_HANDLE semCCD_Codec, semCCD_Buffer; | |
| 176 #endif /* RUN_FLASH */ | |
| 177 #endif /* SHARED_CCD */ | |
| 178 | |
| 179 static U8* mempat; | |
| 180 #define LOWSEGMASK 0xFFFFF000 | |
| 181 | |
| 182 #ifndef RUN_FLASH | |
| 183 #ifdef DEBUG_CCD | |
| 184 /* | |
| 185 +--------------------------------------------------------------------+ | |
| 186 | PROJECT : CCD (6144) MODULE : CCD | | |
| 187 | STATE : code ROUTINE : TRACE_CCD | | |
| 188 +--------------------------------------------------------------------+ | |
| 189 | |
| 190 PURPOSE : Error processing of the CCD. | |
| 191 | |
| 192 */ | |
| 193 | |
| 194 void TRACE_CCD (T_CCD_Globs *globs, char *format, ...) | |
| 195 { | |
| 196 va_list varpars; | |
| 197 char trace_buf[256]; | |
| 198 int i=0; | |
| 199 | |
| 200 if (!globs->TraceIt) | |
| 201 return; | |
| 202 | |
| 203 va_start (varpars, format); /* Initialize variable arguments. */ | |
| 204 #if defined CCD_TEST | |
| 205 /* | |
| 206 * use vsi_o_trace - prefix the tracestring with [CCD] | |
| 207 * so the PCO can display it in a CCD window | |
| 208 */ | |
| 209 strcpy (trace_buf, "~CCD~"); | |
| 210 i = 5; | |
| 211 #endif /* CCD_TEST */ | |
| 212 vsprintf (trace_buf+i, format, varpars); | |
| 213 va_end (varpars); /* Reset variable arguments. */ | |
| 214 | |
| 215 #ifdef CCD_TEST | |
| 216 printf ("\n%s\n", trace_buf); | |
| 217 #else | |
| 218 vsi_o_ttrace (globs->me, TC_CCD, trace_buf); | |
| 219 #endif /* CCD_TEST */ | |
| 220 | |
| 221 } | |
| 222 #endif /* !RUN_FLASH */ | |
| 223 | |
| 224 #endif | |
| 225 | |
| 226 /* | |
| 227 * Stack operations | |
| 228 */ | |
| 229 #define ST_CLEAR(globs) globs->SP=0;globs->StackOvfl=FALSE; | |
| 230 | |
| 231 #define ST_OK(globs) (globs->StackOvfl EQ FALSE) | |
| 232 | |
| 233 #define ST_CHECK(A, globs) {if (!(globs->StackOvfl) AND globs->SP < MAX_UPN_STACK_SIZE)\ | |
| 234 {(A);}\ | |
| 235 else\ | |
| 236 {globs->StackOvfl = TRUE;}} | |
| 237 | |
| 238 #define ST_PUSH(A, globs) ST_CHECK ((globs->Stack[globs->SP++] = (A)), globs) | |
| 239 | |
| 240 #define ST_POP(A, globs) ST_CHECK ((A = globs->Stack[--(globs->SP)]), globs) | |
| 241 | |
| 242 #define ST_TOP(A, globs) ST_CHECK ((A = globs->Stack[globs->SP-1]), globs) | |
| 243 | |
| 244 #ifndef RUN_FLASH | |
| 245 /* | |
| 246 * Attention: if the static function calcUPN shall be used in | |
| 247 * both, internal as well as external RAM, it must be made global. | |
| 248 */ | |
| 249 /* | |
| 250 +--------------------------------------------------------------------+ | |
| 251 | PROJECT : CCD (6144) MODULE : CCD | | |
| 252 | STATE : code ROUTINE : calcUPN | | |
| 253 +--------------------------------------------------------------------+ | |
| 254 | |
| 255 PURPOSE : calculates the UPN-term for an element. | |
| 256 | |
| 257 */ | |
| 258 LOCAL BOOL calcUPN (ULONG op, | |
| 259 ULONG num_ops, | |
| 260 ULONG *result, | |
| 261 T_CCD_Globs *globs) | |
| 262 { | |
| 263 BOOL opError; | |
| 264 ULONG op1=0,op2=0; | |
| 265 | |
| 266 opError = FALSE; | |
| 267 | |
| 268 #ifdef DEBUG_CCD | |
| 269 TRACE_CCD (globs, "Calculation of UPN-term "); | |
| 270 #endif | |
| 271 | |
| 272 while (num_ops-- AND !opError AND ST_OK(globs)) | |
| 273 { | |
| 274 switch (calc[op].operation) | |
| 275 { | |
| 276 case '+': | |
| 277 /* | |
| 278 * get the upper two elements from the stack, add them | |
| 279 * and push the result on the stack | |
| 280 */ | |
| 281 if (globs->SP >= 2) | |
| 282 { | |
| 283 ST_POP(op2, globs); | |
| 284 ST_POP(op1, globs); | |
| 285 ST_PUSH ((op1 + op2), globs); | |
| 286 } | |
| 287 #ifdef DEBUG_CCD | |
| 288 else | |
| 289 TRACE_CCD (globs, "Control parameter '+' causes invalid calculation"); | |
| 290 #endif | |
| 291 break; | |
| 292 case '-': | |
| 293 /* | |
| 294 * get the upper two elements from the stack, subtract them | |
| 295 * and push the result on the stack | |
| 296 */ | |
| 297 if (globs->SP >= 2) | |
| 298 { | |
| 299 ST_POP(op2, globs); | |
| 300 ST_POP(op1, globs); | |
| 301 ST_PUSH ((op1 - op2), globs); | |
| 302 } | |
| 303 #ifdef DEBUG_CCD | |
| 304 else | |
| 305 TRACE_CCD (globs, "Control parameter '-' causes invalid calculation"); | |
| 306 #endif | |
| 307 break; | |
| 308 case '*': | |
| 309 /* | |
| 310 * get the upper two elements from the stack, multiply them | |
| 311 * and push the result on the stack | |
| 312 */ | |
| 313 if (globs->SP >= 2) | |
| 314 { | |
| 315 ST_POP(op2, globs); | |
| 316 ST_POP(op1, globs); | |
| 317 ST_PUSH ((op1 * op2), globs); | |
| 318 } | |
| 319 #ifdef DEBUG_CCD | |
| 320 else | |
| 321 TRACE_CCD (globs, "Control parameter '*' causes invalid calculation"); | |
| 322 #endif | |
| 323 break; | |
| 324 case '/': | |
| 325 /* | |
| 326 * get the upper two elements from the stack, divide them | |
| 327 * and push the result on the stack | |
| 328 */ | |
| 329 if (globs->SP >= 2) | |
| 330 { | |
| 331 ST_POP(op2, globs); | |
| 332 if (!op2) | |
| 333 { | |
| 334 ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK, | |
| 335 (USHORT) (globs->bitpos), (USHORT) -1); | |
| 336 } | |
| 337 else | |
| 338 { | |
| 339 ST_POP(op1, globs); | |
| 340 ST_PUSH ((op1 / op2), globs); | |
| 341 } | |
| 342 } | |
| 343 #ifdef DEBUG_CCD | |
| 344 else | |
| 345 TRACE_CCD (globs, "Control parameter '/' causes invalid calculation"); | |
| 346 #endif | |
| 347 break; | |
| 348 case '&': | |
| 349 /* | |
| 350 * get the upper two elements from the stack, perform a | |
| 351 * binary AND | |
| 352 * and push the result on the stack | |
| 353 */ | |
| 354 if (globs->SP >= 2) | |
| 355 { | |
| 356 ST_POP(op2, globs); | |
| 357 ST_POP(op1, globs); | |
| 358 ST_PUSH ((op1 & op2), globs); | |
| 359 } | |
| 360 #ifdef DEBUG_CCD | |
| 361 else | |
| 362 TRACE_CCD (globs, "Control parameter '&' causes invalid calculation"); | |
| 363 #endif | |
| 364 break; | |
| 365 case '|': | |
| 366 /* | |
| 367 * get the upper two elements from the stack, perform a | |
| 368 * binary OR | |
| 369 * and push the result on the stack | |
| 370 */ | |
| 371 if (globs->SP >= 2) | |
| 372 { | |
| 373 ST_POP(op2, globs); | |
| 374 ST_POP(op1, globs); | |
| 375 ST_PUSH ((op1 | op2), globs); | |
| 376 } | |
| 377 #ifdef DEBUG_CCD | |
| 378 else | |
| 379 TRACE_CCD (globs, "Control parameter '|' causes invalid calculation"); | |
| 380 #endif | |
| 381 break; | |
| 382 case 'A': | |
| 383 /* | |
| 384 * get the upper two elements from the stack, perform a | |
| 385 * logical AND | |
| 386 * and push a TRUE or FALSE on the stack | |
| 387 */ | |
| 388 if (globs->SP >= 2) | |
| 389 { | |
| 390 ST_POP(op2, globs); | |
| 391 ST_POP(op1, globs); | |
| 392 ST_PUSH ((op1 AND op2), globs); | |
| 393 } | |
| 394 #ifdef DEBUG_CCD | |
| 395 else | |
| 396 TRACE_CCD (globs, "Control parameter 'AND' causes invalid calculation"); | |
| 397 #endif | |
| 398 break; | |
| 399 case 'O': | |
| 400 /* | |
| 401 * get the upper two elements from the stack, perform a | |
| 402 * logical OR | |
| 403 * and push a TRUE or FALSE on the stack | |
| 404 */ | |
| 405 if (globs->SP >= 2) | |
| 406 { | |
| 407 ST_POP(op2, globs); | |
| 408 ST_POP(op1, globs); | |
| 409 ST_PUSH ((op1 OR op2), globs); | |
| 410 } | |
| 411 #ifdef DEBUG_CCD | |
| 412 else | |
| 413 TRACE_CCD (globs, "Control parameter 'OR' causes invalid calculation"); | |
| 414 #endif | |
| 415 break; | |
| 416 case 'X': | |
| 417 /* | |
| 418 * get the upper two elements from the stack, perform a | |
| 419 * logical XOR | |
| 420 * and push a TRUE or FALSE on the stack | |
| 421 */ | |
| 422 if (globs->SP >= 2) | |
| 423 { | |
| 424 ST_POP(op2, globs); | |
| 425 ST_POP(op1, globs); | |
| 426 ST_PUSH ( ((op1 AND !op2) OR (!op1 AND op2)) , globs); | |
| 427 } | |
| 428 #ifdef DEBUG_CCD | |
| 429 else | |
| 430 TRACE_CCD (globs, "Control parameter 'XOR' causes invalid calculation"); | |
| 431 #endif | |
| 432 break; | |
| 433 case '=': | |
| 434 /* | |
| 435 * get the upper two elements from the stack, look if they | |
| 436 * are equal | |
| 437 * and push a TRUE or FALSE on the stack | |
| 438 */ | |
| 439 if (globs->SP >= 2) | |
| 440 { | |
| 441 ST_POP(op2, globs); | |
| 442 ST_POP(op1, globs); | |
| 443 ST_PUSH ((op1 EQ op2), globs); | |
| 444 } | |
| 445 #ifdef DEBUG_CCD | |
| 446 else | |
| 447 TRACE_CCD (globs, "Control parameter '=' causes invalid calculation"); | |
| 448 #endif | |
| 449 break; | |
| 450 case '#': | |
| 451 /* | |
| 452 * get the upper two elements from the stack, look if they | |
| 453 * are different | |
| 454 * and push a TRUE or FALSE on the stack | |
| 455 */ | |
| 456 if (globs->SP >= 2) | |
| 457 { | |
| 458 ST_POP(op2, globs); | |
| 459 ST_POP(op1, globs); | |
| 460 ST_PUSH ((op1 NEQ op2), globs); | |
| 461 } | |
| 462 #ifdef DEBUG_CCD | |
| 463 else | |
| 464 TRACE_CCD (globs, "Control parameter '#' causes invalid calculation"); | |
| 465 #endif | |
| 466 break; | |
| 467 case '>': | |
| 468 /* | |
| 469 * get the upper two elements from the stack, look if | |
| 470 * op1 > op2 | |
| 471 * and push a TRUE or FALSE on the stack | |
| 472 */ | |
| 473 if (globs->SP >= 2) | |
| 474 { | |
| 475 ST_POP(op2, globs); | |
| 476 ST_POP(op1, globs); | |
| 477 ST_PUSH ((op1 > op2), globs); | |
| 478 } | |
| 479 #ifdef DEBUG_CCD | |
| 480 else | |
| 481 TRACE_CCD (globs, "Control parameter '>' causes invalid calculation"); | |
| 482 #endif | |
| 483 break; | |
| 484 case '<': | |
| 485 /* | |
| 486 * get the upper two elements from the stack, look if | |
| 487 * op1 < op2 | |
| 488 * and push a TRUE or FALSE on the stack | |
| 489 */ | |
| 490 if (globs->SP >= 2) | |
| 491 { | |
| 492 ST_POP(op2, globs); | |
| 493 ST_POP(op1, globs); | |
| 494 ST_PUSH ((op1 < op2), globs); | |
| 495 } | |
| 496 #ifdef DEBUG_CCD | |
| 497 else | |
| 498 TRACE_CCD (globs, "Control parameter '<' causes invalid calculation"); | |
| 499 #endif | |
| 500 break; | |
| 501 case 'P': | |
| 502 /* | |
| 503 * push a constant on the stack | |
| 504 */ | |
| 505 ST_PUSH (calc[op].operand, globs); | |
| 506 #ifdef DEBUG_CCD | |
| 507 if (globs->StackOvfl == TRUE) | |
| 508 TRACE_CCD (globs, "Constant can't be pused on UPN stack"); | |
| 509 #endif | |
| 510 break; | |
| 511 case ':': | |
| 512 /* | |
| 513 * duplicate the upper element on the stack | |
| 514 */ | |
| 515 if (globs->SP >= 1) | |
| 516 { | |
| 517 ST_TOP (op1, globs); | |
| 518 ST_PUSH (op1, globs); | |
| 519 } | |
| 520 #ifdef DEBUG_CCD | |
| 521 else | |
| 522 TRACE_CCD (globs, "No UPN stack element to duplicate"); | |
| 523 #endif | |
| 524 break; | |
| 525 case 'R': | |
| 526 /* | |
| 527 * push the content of a C-structure variable on the stack | |
| 528 */ | |
| 529 { | |
| 530 /* if no register available some compilers may react with | |
| 531 a warning like this: identifier p not bound to register | |
| 532 */ | |
| 533 UBYTE *p; | |
| 534 ULONG value; | |
| 535 | |
| 536 /* | |
| 537 * normaly we have to check if the element is a VAR | |
| 538 * and not an array/substructure. | |
| 539 * - but this must be done by ccdgen | |
| 540 */ | |
| 541 | |
| 542 /* | |
| 543 * setup the read pointer to the element in the C-structure | |
| 544 */ | |
| 545 p = globs->pstruct + melem[(USHORT) calc[op].operand].structOffs; | |
| 546 | |
| 547 /* | |
| 548 * Get the element table entry from the element to read. | |
| 549 * if the element of the condition is conditional too | |
| 550 * then look for the valid flag of this element. | |
| 551 * if the element is not valid, | |
| 552 * we dont need to check the contents of it | |
| 553 */ | |
| 554 if (melem[(USHORT) calc[op].operand].optional) | |
| 555 { | |
| 556 if (*(UBYTE *) p EQ FALSE) | |
| 557 { | |
| 558 ST_PUSH (0L, globs); | |
| 559 break; | |
| 560 } | |
| 561 else | |
| 562 p++; | |
| 563 } | |
| 564 | |
| 565 /* | |
| 566 * read the contents of the element | |
| 567 */ | |
| 568 switch (mvar[melem[(USHORT) calc[op].operand].elemRef].cType) | |
| 569 { | |
| 570 case 'B': | |
| 571 value = (ULONG) * p; | |
| 572 break; | |
| 573 case 'S': | |
| 574 value = (ULONG) * (USHORT *) p; | |
| 575 break; | |
| 576 case 'L': | |
| 577 value = *(ULONG *) p; | |
| 578 break; | |
| 579 default: | |
| 580 value = 0L; | |
| 581 } | |
| 582 ST_PUSH (value, globs); | |
| 583 break; | |
| 584 } | |
| 585 case 'S': | |
| 586 /* | |
| 587 * get the upper element from the stack an | |
| 588 * set the position of the bitstream pointer to this | |
| 589 * value | |
| 590 */ | |
| 591 if (globs->SP >= 1) | |
| 592 { | |
| 593 ST_POP(op1, globs); | |
| 594 #ifdef DEBUG_CCD | |
| 595 TRACE_CCD (globs, "SETBITPOS %d (byte %d.%d)", | |
| 596 (USHORT) op1, (USHORT) (op1 / 8), (USHORT) (op1 % 8)); | |
| 597 #endif | |
| 598 bf_setBitpos ((USHORT) op1, globs); | |
| 599 } | |
| 600 #ifdef DEBUG_CCD | |
| 601 else | |
| 602 TRACE_CCD (globs, "Control parameter 'SETBITPOS' causes invalid calculation"); | |
| 603 #endif | |
| 604 break; | |
| 605 case 'G': | |
| 606 /* | |
| 607 * push the position of the bitstream pointer on the | |
| 608 * stack | |
| 609 */ | |
| 610 ST_PUSH ((ULONG) globs->bitpos, globs); | |
| 611 #ifdef DEBUG_CCD | |
| 612 TRACE_CCD (globs, "GETBITPOS %d (byte %d.%d)", | |
| 613 (USHORT) globs->bitpos, globs->bytepos, globs->byteoffs); | |
| 614 #endif | |
| 615 break; | |
| 616 case '^': | |
| 617 /* | |
| 618 * swap the upper two elements of the stack | |
| 619 */ | |
| 620 if (globs->SP >= 2) | |
| 621 { | |
| 622 ST_POP(op1, globs); | |
| 623 ST_POP(op2, globs); | |
| 624 ST_PUSH(op1, globs); | |
| 625 ST_PUSH(op2, globs); | |
| 626 } | |
| 627 #ifdef DEBUG_CCD | |
| 628 else | |
| 629 TRACE_CCD (globs, "Control parameter '^' causes invalid calculation"); | |
| 630 #endif | |
| 631 break; | |
| 632 case 'K': | |
| 633 /* | |
| 634 * Keep a value in the KEEP register. | |
| 635 */ | |
| 636 if (globs->SP >= 1) | |
| 637 { | |
| 638 ST_POP(op1, globs); | |
| 639 globs->KeepReg[calc[op].operand] = op1; | |
| 640 } | |
| 641 #ifdef DEBUG_CCD | |
| 642 else | |
| 643 TRACE_CCD (globs, "Control parameter 'KEEP' causes invalid calculation"); | |
| 644 #endif | |
| 645 break; | |
| 646 case 'L': | |
| 647 /* | |
| 648 * Copy the L part of a TLV element from the KEEP register to the UPN stack. | |
| 649 */ | |
| 650 ST_PUSH(globs->KeepReg[0]*8, globs); | |
| 651 #ifdef DEBUG_CCD | |
| 652 if (globs->StackOvfl == TRUE) | |
| 653 TRACE_CCD (globs, "Control parameter 'LTAKE' causes invalid calculation"); | |
| 654 #endif | |
| 655 break; | |
| 656 case 'T': | |
| 657 /* | |
| 658 * Take a value from the KEEP register and push it on the UPN stack. | |
| 659 */ | |
| 660 ST_PUSH(globs->KeepReg[calc[op].operand], globs); | |
| 661 #ifdef DEBUG_CCD | |
| 662 if (globs->StackOvfl == TRUE) | |
| 663 TRACE_CCD (globs, "Control parameter 'TAKE' causes invalid calculation"); | |
| 664 #endif | |
| 665 break; | |
| 666 case 'C': | |
| 667 /* | |
| 668 * Compare the value on the UPN stack with the one stored in the KEEP register. | |
| 669 * Push the higher value in the KEEP register. | |
| 670 */ | |
| 671 if (globs->SP >= 1) | |
| 672 { | |
| 673 ST_POP(op1, globs); | |
| 674 if ((globs->KeepReg[calc[op].operand]) < op1) | |
| 675 { | |
| 676 globs->KeepReg[calc[op].operand] = op1; | |
| 677 } | |
| 678 } | |
| 679 #ifdef DEBUG_CCD | |
| 680 else | |
| 681 TRACE_CCD (globs, "Control parameter 'MAX' causes invalid calculation"); | |
| 682 #endif | |
| 683 break; | |
| 684 case 'Z': | |
| 685 /* | |
| 686 * Used to mark presence of an address information part error label | |
| 687 */ | |
| 688 globs->errLabel = ERR_ADDR_INFO_PART; | |
| 689 break; | |
| 690 case 'D': | |
| 691 /* | |
| 692 * Used to mark presence of a distribution part error label | |
| 693 */ | |
| 694 globs->errLabel = ERR_DISTRIB_PART; | |
| 695 break; | |
| 696 case 'N': | |
| 697 /* | |
| 698 * Used to mark presence of a non distribution part error label | |
| 699 */ | |
| 700 globs->errLabel = ERR_NON_DISTRIB_PART; | |
| 701 break; | |
| 702 case 'M': | |
| 703 /* | |
| 704 * Used to mark presence of a message escape error label | |
| 705 */ | |
| 706 globs->errLabel = ERR_MESSAGE_ESCAPE; | |
| 707 break; | |
| 708 case 'I': | |
| 709 /* | |
| 710 * Used to mark presence of an ignore error label | |
| 711 */ | |
| 712 globs->errLabel = ERR_IGNORE; | |
| 713 break; | |
| 714 case 'l': | |
| 715 /* | |
| 716 * Take a value from the CCD STO register and push it on the UPN stack. | |
| 717 */ | |
| 718 opError = ccd_getStore (globs, calc[op].operand, &op1); | |
| 719 if (!opError) | |
| 720 { | |
| 721 ST_PUSH(op1, globs); | |
| 722 #ifdef DEBUG_CCD | |
| 723 TRACE_CCD (globs, "Push CCD STORE register [%d] value to UPN stack", | |
| 724 calc[op].operand); | |
| 725 } | |
| 726 else | |
| 727 { | |
| 728 TRACE_CCD (globs, "Reading from CCD STORE register [%d] impossible", | |
| 729 calc[op].operand); | |
| 730 #endif | |
| 731 } | |
| 732 break; | |
| 733 case 's': | |
| 734 /* | |
| 735 * Store a value in the CCD STO register. | |
| 736 */ | |
| 737 if (globs->SP >= 1) | |
| 738 { | |
| 739 ST_POP(op1, globs); | |
| 740 opError = ccd_writeStore (globs, calc[op].operand, op1); | |
| 741 #ifdef DEBUG_CCD | |
| 742 TRACE_CCD (globs, "Store value in CCD STO register [%d]", | |
| 743 calc[op].operand); | |
| 744 } | |
| 745 else | |
| 746 { | |
| 747 TRACE_CCD (globs, "Control parameter 'STORE' causes invalid calculation"); | |
| 748 #endif | |
| 749 } | |
| 750 break; | |
| 751 | |
| 752 default: | |
| 753 opError = TRUE; | |
| 754 break; | |
| 755 } | |
| 756 op++; | |
| 757 } | |
| 758 | |
| 759 if (!opError AND ST_OK(globs)) | |
| 760 { | |
| 761 if (result NEQ (ULONG *) NULL) | |
| 762 ST_POP (*result, globs); | |
| 763 return (ST_OK(globs)); | |
| 764 } | |
| 765 else | |
| 766 { | |
| 767 #ifdef DEBUG_CCD | |
| 768 if(opError) | |
| 769 TRACE_CCD (globs, "Calculation of UPN-term failed "); | |
| 770 else | |
| 771 TRACE_CCD (globs, "Calculation of UPN-term failed due to stack overflow"); | |
| 772 #endif | |
| 773 return FALSE; | |
| 774 } | |
| 775 } | |
| 776 #endif /* !RUN_FLASH */ | |
| 777 | |
| 778 #ifndef RUN_FLASH | |
| 779 /* | |
| 780 +--------------------------------------------------------------------+ | |
| 781 | PROJECT : CCD (6144) MODULE : CCD | | |
| 782 | STATE : code ROUTINE : ccd_conditionOK | | |
| 783 +--------------------------------------------------------------------+ | |
| 784 | |
| 785 PURPOSE : Check if the conditions for an element are true. | |
| 786 The elemRef references an element entry from the elem tab. | |
| 787 The function returns TRUE if the defined | |
| 788 conditions are TRUE. | |
| 789 | |
| 790 */ | |
| 791 | |
| 792 BOOL ccd_conditionOK (const ULONG e_ref, T_CCD_Globs *globs) | |
| 793 { | |
| 794 ULONG result, cond_calc_ref, num_cond_calcs, cix_ref; | |
| 795 | |
| 796 cix_ref = melem[e_ref].calcIdxRef; | |
| 797 num_cond_calcs = calcidx[cix_ref].numCondCalcs; | |
| 798 cond_calc_ref = calcidx[cix_ref].condCalcRef; | |
| 799 | |
| 800 | |
| 801 if (! calcUPN (cond_calc_ref, | |
| 802 num_cond_calcs, | |
| 803 &result, | |
| 804 globs)) | |
| 805 return FALSE; | |
| 806 | |
| 807 return (result EQ TRUE); | |
| 808 } | |
| 809 #endif /* !RUN_FLASH */ | |
| 810 | |
| 811 #ifndef RUN_FLASH | |
| 812 /* | |
| 813 +--------------------------------------------------------------------+ | |
| 814 | PROJECT : CCD (6144) MODULE : CCD | | |
| 815 | STATE : code ROUTINE : ccd_calculateRep | | |
| 816 +--------------------------------------------------------------------+ | |
| 817 | |
| 818 PURPOSE : For a given element (referenced by elemRef) calculate the | |
| 819 repeat value. | |
| 820 | |
| 821 */ | |
| 822 | |
| 823 BOOL ccd_calculateRep (const ULONG e_ref, | |
| 824 ULONG *repeat, | |
| 825 ULONG *max_repeat, | |
| 826 T_CCD_Globs *globs) | |
| 827 { | |
| 828 ULONG cix_ref, result; | |
| 829 ULONG remaining_repeats=0; | |
| 830 ULONG rep_calc_ref, num_rep_calcs; | |
| 831 | |
| 832 BOOL is_variable; | |
| 833 | |
| 834 cix_ref = melem[e_ref].calcIdxRef; | |
| 835 num_rep_calcs = calcidx[cix_ref].numRepCalcs; | |
| 836 rep_calc_ref = calcidx[cix_ref].repCalcRef; | |
| 837 | |
| 838 *max_repeat = (ULONG) melem[e_ref].maxRepeat; | |
| 839 | |
| 840 if (num_rep_calcs EQ 0) | |
| 841 { | |
| 842 if (melem[e_ref].repType EQ 'i') | |
| 843 { | |
| 844 switch (melem[e_ref].elemType) | |
| 845 { | |
| 846 case 'S': | |
| 847 remaining_repeats = (ULONG)((globs->maxBitpos-globs->bitpos) | |
| 848 / spare[melem[e_ref].elemRef].bSize); | |
| 849 break; | |
| 850 case 'F': /* Code transparent pointer to base type */ | |
| 851 case 'R': /* Pointer to base type */ | |
| 852 case 'V': | |
| 853 remaining_repeats = (ULONG)((globs->maxBitpos-globs->bitpos) | |
| 854 / mvar[melem[e_ref].elemRef].bSize); | |
| 855 break; | |
| 856 case 'D': /* Code transparent pointer to composition */ | |
| 857 case 'P': /* Pointer to composition */ | |
| 858 case 'C': | |
| 859 /* for repeated compositions the remaining repeats | |
| 860 are set to the max repeats because of the unknown | |
| 861 size of one composition */ | |
| 862 remaining_repeats = (ULONG) melem[e_ref].maxRepeat; | |
| 863 break; | |
| 864 default: | |
| 865 ccd_setError (globs, ERR_INVALID_CALC, BREAK, (USHORT) -1); | |
| 866 break; | |
| 867 } | |
| 868 | |
| 869 *repeat = MINIMUM (*max_repeat, remaining_repeats); | |
| 870 is_variable = TRUE; | |
| 871 } | |
| 872 else | |
| 873 { | |
| 874 if (melem[e_ref].repType EQ 'b') | |
| 875 { | |
| 876 remaining_repeats = (ULONG)(globs->maxBitpos-globs->bitpos); | |
| 877 *repeat = MINIMUM (*max_repeat, remaining_repeats); | |
| 878 } | |
| 879 else | |
| 880 { | |
| 881 *repeat = MINIMUM (*max_repeat, | |
| 882 (ULONG) calcidx[cix_ref].repCalcRef); | |
| 883 if (*repeat < (ULONG) calcidx[cix_ref].repCalcRef) | |
| 884 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, | |
| 885 (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 886 } | |
| 887 is_variable = FALSE; | |
| 888 } | |
| 889 } | |
| 890 else | |
| 891 { | |
| 892 is_variable = FALSE; | |
| 893 if (! calcUPN (rep_calc_ref, | |
| 894 num_rep_calcs, | |
| 895 &result, | |
| 896 globs)) | |
| 897 { | |
| 898 *repeat = *max_repeat = 0; | |
| 899 | |
| 900 ccd_setError (globs, ERR_INVALID_CALC, BREAK, (USHORT) -1); | |
| 901 } | |
| 902 else | |
| 903 { | |
| 904 if ((melem[e_ref].repType != 'b') && (melem[e_ref].repType != 's')) | |
| 905 { | |
| 906 is_variable = TRUE; | |
| 907 } | |
| 908 if (melem[e_ref].repType EQ 'i') | |
| 909 { | |
| 910 switch (melem[e_ref].elemType) | |
| 911 { | |
| 912 case 'S': | |
| 913 remaining_repeats = (ULONG)((globs->maxBitpos-globs->bitpos) | |
| 914 / spare[melem[e_ref].elemRef].bSize); | |
| 915 break; | |
| 916 case 'F': /* Code transparent pointer to base type */ | |
| 917 case 'R': /* Pointer to base type */ | |
| 918 case 'V': | |
| 919 remaining_repeats = (ULONG)((globs->maxBitpos-globs->bitpos) | |
| 920 / mvar[melem[e_ref].elemRef].bSize); | |
| 921 break; | |
| 922 default: | |
| 923 ccd_setError (globs, ERR_INVALID_CALC, BREAK, (USHORT) -1); | |
| 924 break; | |
| 925 } | |
| 926 *repeat = MINIMUM (result, remaining_repeats); | |
| 927 } | |
| 928 else | |
| 929 { | |
| 930 *repeat = MINIMUM (result, *max_repeat); | |
| 931 if (*repeat < result) | |
| 932 ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, | |
| 933 (USHORT) e_ref, globs->pstruct + globs->pstructOffs); | |
| 934 } | |
| 935 } | |
| 936 } | |
| 937 return (is_variable); | |
| 938 } | |
| 939 #endif /* !RUN_FLASH */ | |
| 940 | |
| 941 #ifndef RUN_FLASH | |
| 942 /* | |
| 943 +--------------------------------------------------------------------+ | |
| 944 | PROJECT : CCD (6144) MODULE : CCD | | |
| 945 | STATE : code ROUTINE : ccd_performOperations | | |
| 946 +--------------------------------------------------------------------+ | |
| 947 | |
| 948 PURPOSE : Perform the operation for an element. This operations | |
| 949 are executed before an element is encoded or decoded. | |
| 950 The Operations work with the UPN-Stack. | |
| 951 | |
| 952 */ | |
| 953 | |
| 954 void ccd_performOperations (ULONG num_of_ops, | |
| 955 ULONG op_def_ref, | |
| 956 T_CCD_Globs *globs) | |
| 957 { | |
| 958 if (! calcUPN (op_def_ref, | |
| 959 num_of_ops, | |
| 960 NULL, | |
| 961 globs)) | |
| 962 ccd_setError (globs, ERR_INVALID_CALC, BREAK, (USHORT) -1); | |
| 963 } | |
| 964 #endif /* !RUN_FLASH */ | |
| 965 | |
| 966 #ifndef RUN_FLASH | |
| 967 /* | |
| 968 * Attention: if the static function ccd_isOptional shall be used in | |
| 969 * both, internal as well as external RAM, it must be made global. | |
| 970 */ | |
| 971 /* | |
| 972 +--------------------------------------------------------------------+ | |
| 973 | PROJECT : CCD (6144) MODULE : CCD | | |
| 974 | STATE : code ROUTINE : ccd_isOptional | | |
| 975 +--------------------------------------------------------------------+ | |
| 976 | |
| 977 PURPOSE : Checks if a given element is optional. If the element is | |
| 978 not optional and is a composition, | |
| 979 a recursive call is performed in order to check | |
| 980 if the composition contains only optional elements. | |
| 981 In this case the whole composition is optional. | |
| 982 | |
| 983 In case of components concatenated with a CSN1 coding | |
| 984 rules the meaning of the word <optional> differs from the | |
| 985 traditional TI tool chain conventions. So far some coding | |
| 986 types (like tagged types, e.g. GSM3_TV) characterise | |
| 987 optional elements inherently. The value of their valid | |
| 988 flag indicates the presence or absence of such an element. | |
| 989 Components concatenated with a CSN1 coding type cause | |
| 990 these valid flags in the C header structure too. If you | |
| 991 find a bit in the received message stream indicating | |
| 992 optional values not included in the message (e. g. a | |
| 993 CSN1_S1 element is represented by ??, CCD will set the | |
| 994 valid flag to zero. But the whole element represented by | |
| 995 the flag is present; only the value is absent! Therefor | |
| 996 the valid flag in the C structure is not an indication of | |
| 997 an element’s absence. | |
| 998 */ | |
| 999 | |
| 1000 LOCAL BOOL ccd_isOptional (ULONG e_ref, T_CCD_Globs *globs) | |
| 1001 { | |
| 1002 ULONG cix_ref; | |
| 1003 | |
| 1004 switch (melem[e_ref].codingType) | |
| 1005 { | |
| 1006 case CCDTYPE_CSN1_S1: /* Fall through. */ | |
| 1007 case CCDTYPE_CSN1_S0: | |
| 1008 case CCDTYPE_CSN1_SHL: | |
| 1009 | |
| 1010 cix_ref = melem[e_ref].calcIdxRef; | |
| 1011 /* | |
| 1012 * If this element is conditional, check the condition. | |
| 1013 */ | |
| 1014 if (calcidx[cix_ref].numCondCalcs NEQ 0 | |
| 1015 AND ! ccd_conditionOK (e_ref, globs)) | |
| 1016 return TRUE; | |
| 1017 | |
| 1018 if (melem[e_ref].repType == 'i' AND | |
| 1019 calcidx[melem[e_ref].calcIdxRef].repCalcRef == 0) | |
| 1020 return TRUE; | |
| 1021 else | |
| 1022 return FALSE; | |
| 1023 // break; | |
| 1024 // PATCH FROM M18 | |
| 1025 case CCDTYPE_CSN1_CONCAT: | |
| 1026 return TRUE; | |
| 1027 | |
| 1028 default: | |
| 1029 break; | |
| 1030 } | |
| 1031 | |
| 1032 if (! melem[e_ref].optional) | |
| 1033 { | |
| 1034 /* | |
| 1035 * if the element is an array with an interval [0..x] | |
| 1036 * it can be handled like an optional element | |
| 1037 */ | |
| 1038 if ( ! (melem[e_ref].repType EQ 'i' | |
| 1039 AND calcidx[melem[e_ref].calcIdxRef].repCalcRef EQ 0)) | |
| 1040 { | |
| 1041 /* | |
| 1042 * if the element is not optional but it is a composition | |
| 1043 * we check recursive if the composition consists only of | |
| 1044 * optional elements | |
| 1045 */ | |
| 1046 if (melem[e_ref].elemType EQ 'C' OR | |
| 1047 melem[e_ref].elemType EQ 'D' OR | |
| 1048 melem[e_ref].elemType EQ 'P') | |
| 1049 { | |
| 1050 ULONG el, lel, c_ref; | |
| 1051 | |
| 1052 c_ref = melem[e_ref].elemRef; | |
| 1053 | |
| 1054 el = (ULONG) mcomp[c_ref].componentRef; | |
| 1055 lel = el + mcomp[c_ref].numOfComponents; | |
| 1056 | |
| 1057 while (el < lel) | |
| 1058 { | |
| 1059 if (! ccd_isOptional (el, globs)) | |
| 1060 return FALSE; | |
| 1061 el++; | |
| 1062 } | |
| 1063 } | |
| 1064 else | |
| 1065 return FALSE; | |
| 1066 } | |
| 1067 } | |
| 1068 return TRUE; | |
| 1069 } | |
| 1070 #endif /* !RUN_FLASH */ | |
| 1071 | |
| 1072 #ifndef RUN_FLASH | |
| 1073 /* | |
| 1074 +--------------------------------------------------------------------+ | |
| 1075 | PROJECT : CCD (6144) MODULE : CCD | | |
| 1076 | STATE : code ROUTINE : ccd_decodeComposition | | |
| 1077 +--------------------------------------------------------------------+ | |
| 1078 | |
| 1079 PURPOSE : decodes the bitstream to a C-Structure.The decoding | |
| 1080 rules contains the element definitions for the | |
| 1081 elements of this message. | |
| 1082 This function may called recursivly because of a | |
| 1083 substructured element definition. | |
| 1084 */ | |
| 1085 | |
| 1086 void ccd_decodeComposition (const ULONG c_ref, T_CCD_Globs *globs) | |
| 1087 { | |
| 1088 /* | |
| 1089 * index in table melem | |
| 1090 */ | |
| 1091 ULONG e_ref; /* element reference */ | |
| 1092 ULONG l_ref; /* reference to the last element of a component */ | |
| 1093 SHORT codecRet; | |
| 1094 BOOL ExtendedGroupActive = FALSE; | |
| 1095 BOOL GroupExtended = FALSE; | |
| 1096 BOOL MoreData; | |
| 1097 BOOL SetPosExpected = FALSE; | |
| 1098 int i; | |
| 1099 ULONG act_err_label; | |
| 1100 | |
| 1101 #ifdef DEBUG_CCD | |
| 1102 #ifndef CCD_SYMBOLS | |
| 1103 TRACE_CCD (globs, "ccd_decodeComposition()"); | |
| 1104 #else | |
| 1105 TRACE_CCD (globs, "ccd_decodeComposition(): Composition = %s", | |
| 1106 mcomp[c_ref].name); | |
| 1107 #endif | |
| 1108 #endif | |
| 1109 | |
| 1110 act_err_label = (ULONG) globs->errLabel; | |
| 1111 globs->ccd_recurs_level++; | |
| 1112 | |
| 1113 /* | |
| 1114 * setup the index in the melem table for this composition. | |
| 1115 * If this function is called for the first time | |
| 1116 * (ccd_recurs_level == 1) the elem-table entry for the msg_type | |
| 1117 * was skipped. | |
| 1118 */ | |
| 1119 | |
| 1120 l_ref = mcomp[c_ref].componentRef | |
| 1121 + mcomp[c_ref].numOfComponents; | |
| 1122 | |
| 1123 e_ref = mcomp[c_ref].componentRef | |
| 1124 + ((globs->ccd_recurs_level EQ 1) ? 1 : 0); | |
| 1125 | |
| 1126 /* | |
| 1127 * decode all elements | |
| 1128 */ | |
| 1129 while (e_ref < l_ref) | |
| 1130 { | |
| 1131 #ifdef ERR_TRC_STK_CCD | |
| 1132 /* save the value for tracing in error case */ | |
| 1133 globs->error_stack[globs->ccd_recurs_level] = (USHORT) e_ref; | |
| 1134 #endif /* ERR_TRC_STK_CCD */ | |
| 1135 | |
| 1136 if (melem[e_ref].extGroup != ' ' && GroupExtended && !ExtendedGroupActive) | |
| 1137 { | |
| 1138 /* | |
| 1139 * the last read extension bit signals an | |
| 1140 * extension of the group but there are no | |
| 1141 * more elements defined for this group. | |
| 1142 * This indicates a protocol extension, that must be | |
| 1143 * skipped by ccd. | |
| 1144 */ | |
| 1145 | |
| 1146 do | |
| 1147 { | |
| 1148 /* | |
| 1149 * read the ext-bit to determine the extension | |
| 1150 * of this group | |
| 1151 */ | |
| 1152 GroupExtended = (bf_readBit (globs) EQ 0); | |
| 1153 /* | |
| 1154 * skip to next octett | |
| 1155 */ | |
| 1156 #ifdef DEBUG_CCD | |
| 1157 TRACE_CCD (globs, "skipping 7 bits"); | |
| 1158 #endif | |
| 1159 bf_incBitpos (7, globs); | |
| 1160 } while (GroupExtended); | |
| 1161 } | |
| 1162 | |
| 1163 /* | |
| 1164 * check if the bitstream has ended | |
| 1165 */ | |
| 1166 if (bf_endOfBitstream(globs) AND !globs->TagPending) | |
| 1167 { | |
| 1168 ULONG cix_ref, num_prolog_steps; | |
| 1169 | |
| 1170 cix_ref = melem[e_ref].calcIdxRef; | |
| 1171 num_prolog_steps = calcidx[cix_ref].numPrologSteps; | |
| 1172 | |
| 1173 /* End of the bit stream is not reached if a call to bf_setBitpos() | |
| 1174 * is expected for the next element of the current substructure. | |
| 1175 * An instructive example is an empty "mob_id" | |
| 1176 */ | |
| 1177 if (num_prolog_steps) | |
| 1178 { | |
| 1179 ULONG prolog_step_ref = calcidx[cix_ref].prologStepRef; | |
| 1180 | |
| 1181 i = (int) (prolog_step_ref + num_prolog_steps); | |
| 1182 | |
| 1183 while (i >= (int) prolog_step_ref) | |
| 1184 { | |
| 1185 if (calc[i].operation == 'S') | |
| 1186 { | |
| 1187 SetPosExpected = TRUE; | |
| 1188 break; | |
| 1189 } | |
| 1190 i--; | |
| 1191 } | |
| 1192 } | |
| 1193 | |
| 1194 if (SetPosExpected EQ FALSE) | |
| 1195 { | |
| 1196 /* | |
| 1197 * no more bits to decode. | |
| 1198 * If at least one mandatory element is to decode | |
| 1199 * generate an error. | |
| 1200 */ | |
| 1201 | |
| 1202 while (e_ref < l_ref) | |
| 1203 { | |
| 1204 if (! ccd_isOptional (e_ref, globs)) | |
| 1205 ccd_setError (globs, ERR_MAND_ELEM_MISS, BREAK, (USHORT) -1); | |
| 1206 | |
| 1207 e_ref++; | |
| 1208 } | |
| 1209 /* after the while loop the recursion level will be decremented. */ | |
| 1210 break; | |
| 1211 } | |
| 1212 } | |
| 1213 | |
| 1214 /* | |
| 1215 * look for extension group processing | |
| 1216 */ | |
| 1217 if (melem[e_ref].extGroup NEQ ' ') | |
| 1218 { | |
| 1219 /* | |
| 1220 * extended group symbol found | |
| 1221 */ | |
| 1222 switch (melem[e_ref].extGroup) | |
| 1223 { | |
| 1224 case '+': | |
| 1225 /* | |
| 1226 * start of an extended group | |
| 1227 */ | |
| 1228 ExtendedGroupActive = TRUE; | |
| 1229 /* | |
| 1230 * read the extension bit to determine the extension | |
| 1231 * of this group | |
| 1232 */ | |
| 1233 GroupExtended = (bf_readBit (globs) EQ 0); | |
| 1234 /* | |
| 1235 * use the jump-table for selecting the decode function | |
| 1236 */ | |
| 1237 codecRet = | |
| 1238 codec[melem[e_ref].codingType][DECODE_FUN](c_ref, | |
| 1239 (USHORT)e_ref, globs); | |
| 1240 if (codecRet NEQ 0x7f) | |
| 1241 { | |
| 1242 /* | |
| 1243 * set the e_ref to the next or the same element | |
| 1244 */ | |
| 1245 e_ref += codecRet; | |
| 1246 } | |
| 1247 break; | |
| 1248 | |
| 1249 case '-': | |
| 1250 /* | |
| 1251 * end of one extension, | |
| 1252 * decode first and the read the extension bit. | |
| 1253 */ | |
| 1254 /* | |
| 1255 * use the jump-table for selecting the decode function | |
| 1256 */ | |
| 1257 codecRet = | |
| 1258 codec[melem[e_ref].codingType][DECODE_FUN](c_ref, | |
| 1259 (USHORT)e_ref, globs); | |
| 1260 if (codecRet NEQ 0x7f) | |
| 1261 { | |
| 1262 /* | |
| 1263 * set the e_ref to the next or the same element | |
| 1264 */ | |
| 1265 e_ref += codecRet; | |
| 1266 } | |
| 1267 | |
| 1268 /* | |
| 1269 * look if the previously readed extension bit | |
| 1270 * alows an extension of this group | |
| 1271 */ | |
| 1272 if (!GroupExtended) | |
| 1273 { | |
| 1274 | |
| 1275 ExtendedGroupActive = FALSE; | |
| 1276 /* | |
| 1277 * overread the following elements in the group | |
| 1278 */ | |
| 1279 /* | |
| 1280 * search the last element of the extended group | |
| 1281 */ | |
| 1282 while (e_ref < l_ref | |
| 1283 AND melem[e_ref].extGroup NEQ '*') | |
| 1284 { | |
| 1285 #ifdef DEBUG_CCD | |
| 1286 #ifdef CCD_SYMBOLS | |
| 1287 if (melem[e_ref].elemType EQ 'V') | |
| 1288 TRACE_CCD (globs, "Skipping ext-group element %s", | |
| 1289 ccddata_get_alias((USHORT) e_ref, 1)); | |
| 1290 else if (melem[e_ref].elemType EQ 'C') | |
| 1291 TRACE_CCD (globs, "Skipping ext-group element %s", | |
| 1292 mcomp[melem[e_ref].elemRef].name); | |
| 1293 else | |
| 1294 TRACE_CCD (globs, "Skipping ext-group spare"); | |
| 1295 #else | |
| 1296 TRACE_CCD (globs, "Skipping ext-group element %c-%d", | |
| 1297 melem[e_ref].elemType, | |
| 1298 e_ref); | |
| 1299 | |
| 1300 #endif | |
| 1301 #endif | |
| 1302 e_ref++; | |
| 1303 } | |
| 1304 /* | |
| 1305 * skip the last element | |
| 1306 */ | |
| 1307 e_ref++; | |
| 1308 } | |
| 1309 else | |
| 1310 { | |
| 1311 /* | |
| 1312 * read the extension bit to determine if the group | |
| 1313 * extension holds on | |
| 1314 */ | |
| 1315 GroupExtended = (bf_readBit (globs) EQ 0); | |
| 1316 } | |
| 1317 break; | |
| 1318 | |
| 1319 case '*': | |
| 1320 if (!ExtendedGroupActive) | |
| 1321 { | |
| 1322 /* | |
| 1323 * this is a single element extended group | |
| 1324 * often used for later extension of the protocol | |
| 1325 */ | |
| 1326 /* | |
| 1327 * read the extension bit to determine if a group | |
| 1328 * extension is present | |
| 1329 */ | |
| 1330 GroupExtended = (bf_readBit (globs) EQ 0); | |
| 1331 } | |
| 1332 ExtendedGroupActive = FALSE; | |
| 1333 | |
| 1334 /* | |
| 1335 * use the jump-table for selecting the decode function | |
| 1336 */ | |
| 1337 codecRet = | |
| 1338 codec[melem[e_ref].codingType][DECODE_FUN](c_ref, e_ref, globs); | |
| 1339 if (codecRet NEQ 0x7f) | |
| 1340 { | |
| 1341 /* | |
| 1342 * set the e_ref to the next or the same element | |
| 1343 */ | |
| 1344 e_ref += codecRet; | |
| 1345 } | |
| 1346 break; | |
| 1347 | |
| 1348 case '!': /* Moredata bit */ | |
| 1349 case '#': | |
| 1350 if ((MoreData = bf_readBit (globs)) EQ 1) | |
| 1351 { | |
| 1352 /* | |
| 1353 * moredata-bit is set to 1 | |
| 1354 * process this element. | |
| 1355 */ | |
| 1356 | |
| 1357 /* | |
| 1358 * use the jump-table for selecting the decode function | |
| 1359 */ | |
| 1360 codecRet = | |
| 1361 codec[melem[e_ref].codingType][DECODE_FUN](c_ref, e_ref, globs); | |
| 1362 | |
| 1363 if (melem[e_ref].extGroup EQ '#') | |
| 1364 { | |
| 1365 /* | |
| 1366 * if more data are signaled with an additional | |
| 1367 * bit but there are no | |
| 1368 * more elements defined for this group. | |
| 1369 * This indicates a protocol extension, that must be | |
| 1370 * skipped by ccd. | |
| 1371 */ | |
| 1372 | |
| 1373 do | |
| 1374 { | |
| 1375 /* | |
| 1376 * read the ext-bit to determine the extension | |
| 1377 * of this group | |
| 1378 */ | |
| 1379 GroupExtended = (bf_readBit (globs) EQ 1); | |
| 1380 /* | |
| 1381 * skip to next octett | |
| 1382 */ | |
| 1383 #ifdef DEBUG_CCD | |
| 1384 TRACE_CCD (globs, "skipping 7 bits"); | |
| 1385 #endif | |
| 1386 bf_incBitpos (7, globs); | |
| 1387 } while (!bf_endOfBitstream(globs) AND GroupExtended); | |
| 1388 | |
| 1389 } | |
| 1390 | |
| 1391 if (codecRet NEQ 0x7f) | |
| 1392 { | |
| 1393 /* | |
| 1394 * set the elemRef to the next or the same element(USHORT) | |
| 1395 */ | |
| 1396 e_ref += codecRet; | |
| 1397 } | |
| 1398 } | |
| 1399 | |
| 1400 if (!MoreData) | |
| 1401 { | |
| 1402 /* | |
| 1403 * more data bit is cleared, | |
| 1404 * overread the following elements in the group | |
| 1405 * search the last element of the extended group | |
| 1406 */ | |
| 1407 while (e_ref < l_ref | |
| 1408 AND melem[e_ref].extGroup NEQ '#') | |
| 1409 { | |
| 1410 #ifdef DEBUG_CCD | |
| 1411 #ifdef CCD_SYMBOLS | |
| 1412 if (melem[e_ref].elemType EQ 'V') | |
| 1413 TRACE_CCD (globs, "Skipping ext-group element %s", | |
| 1414 ccddata_get_alias((USHORT) e_ref, 1)); | |
| 1415 else if (melem[e_ref].elemType EQ 'C') | |
| 1416 TRACE_CCD (globs, "Skipping ext-group element %s", | |
| 1417 mcomp[melem[e_ref].elemRef].name); | |
| 1418 else | |
| 1419 TRACE_CCD (globs, "Skipping ext-group spare"); | |
| 1420 #else | |
| 1421 TRACE_CCD (globs, "Skipping ext-group element %c-%d", | |
| 1422 melem[e_ref].elemType, | |
| 1423 e_ref); | |
| 1424 | |
| 1425 #endif | |
| 1426 #endif | |
| 1427 e_ref++; | |
| 1428 } | |
| 1429 | |
| 1430 /* | |
| 1431 * skip the last element of the moredata group | |
| 1432 */ | |
| 1433 e_ref++; | |
| 1434 } | |
| 1435 break; | |
| 1436 default: | |
| 1437 ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK, | |
| 1438 (USHORT) (globs->bitpos), (USHORT) -1); | |
| 1439 break; | |
| 1440 } | |
| 1441 } | |
| 1442 else | |
| 1443 { | |
| 1444 /* | |
| 1445 * no processing action for an extended group | |
| 1446 */ | |
| 1447 | |
| 1448 /* | |
| 1449 * use the jump-table for selecting the decode function | |
| 1450 */ | |
| 1451 codecRet = | |
| 1452 codec[melem[e_ref].codingType][DECODE_FUN](c_ref, e_ref, globs); | |
| 1453 if (codecRet NEQ 0x7f) | |
| 1454 { | |
| 1455 /* | |
| 1456 * set the e_ref to the next or the same element | |
| 1457 */ | |
| 1458 e_ref += codecRet; | |
| 1459 } | |
| 1460 } | |
| 1461 } | |
| 1462 | |
| 1463 /* Reset indicator of exhaustion in the IEI table*/ | |
| 1464 for (i = 0; globs->iei_ctx[globs->ccd_recurs_level].iei_table[i].valid== TRUE; i++) | |
| 1465 { | |
| 1466 globs->iei_ctx[globs->ccd_recurs_level].iei_table[i].exhausted = FALSE; | |
| 1467 globs->iei_ctx[globs->ccd_recurs_level].iei_table[i].act_amount = 0; | |
| 1468 | |
| 1469 } | |
| 1470 | |
| 1471 globs->iei_ctx[globs->ccd_recurs_level].countSkipped = 0; | |
| 1472 globs->ccd_recurs_level--; | |
| 1473 globs->errLabel = (U8) act_err_label; | |
| 1474 } | |
| 1475 #endif /* !RUN_FLASH */ | |
| 1476 | |
| 1477 #ifndef RUN_FLASH | |
| 1478 /* | |
| 1479 * Attention: if this static function shall be used in | |
| 1480 * both, internal as well as external RAM, it must be made global. | |
| 1481 */ | |
| 1482 static void SkipExtensionOctets (ULONG *e_ref, ULONG l_ref) | |
| 1483 { | |
| 1484 /* The extended group is terminated. Skip over its IEs. */ | |
| 1485 while (*e_ref < l_ref && melem[*e_ref].extGroup != '*') | |
| 1486 (*e_ref)++; | |
| 1487 if (*e_ref < l_ref) | |
| 1488 (*e_ref)++; | |
| 1489 } | |
| 1490 #endif /* !RUN_FLASH */ | |
| 1491 | |
| 1492 #ifndef RUN_FLASH | |
| 1493 /* | |
| 1494 * Attention: if this static function shall be used in | |
| 1495 * both, internal as well as external RAM, it must be made global. | |
| 1496 */ | |
| 1497 LOCAL BOOL CheckBP_RecodeXB (ULONG ExtBitPos1, ULONG ExtBitPos2, | |
| 1498 ULONG ExtBitPos3, T_CCD_Globs *globs) | |
| 1499 { | |
| 1500 /* Absence due to validity flag, condition or a ccdWarning. */ | |
| 1501 if (ExtBitPos3 == globs->bitpos ) | |
| 1502 { | |
| 1503 globs->bitpos --; | |
| 1504 if (ExtBitPos1 NEQ ExtBitPos2) | |
| 1505 bf_recodeBit ((USHORT) ExtBitPos1, 1, globs); | |
| 1506 return FALSE; | |
| 1507 } | |
| 1508 return TRUE; | |
| 1509 } | |
| 1510 #endif /* !RUN_FLASH */ | |
| 1511 | |
| 1512 #ifndef RUN_FLASH | |
| 1513 /* | |
| 1514 +--------------------------------------------------------------------+ | |
| 1515 | PROJECT : CCD (6144) MODULE : CCD | | |
| 1516 | STATE : code ROUTINE : ccd_encodeComposition | | |
| 1517 +--------------------------------------------------------------------+ | |
| 1518 | |
| 1519 PURPOSE : codes the content of a C-Structure into a bitstream. | |
| 1520 This function may be called recursivly if an IE in the | |
| 1521 structure is itself a structured IE. | |
| 1522 | |
| 1523 For extended octet groups the following rules apply. | |
| 1524 | |
| 1525 Any IE within an extension octet is characterised by its | |
| 1526 extGroup which is one of the following: | |
| 1527 | |
| 1528 | |
| 1529 '+' octet begins with this IE. | |
| 1530 ' ' octet continues with this IE or a new octet begins. | |
| 1531 '-' octet ends with this IE. | |
| 1532 '*' octet group ends with this IE. | |
| 1533 | |
| 1534 An octet may begin with '+', '-', ' ' or '*'. | |
| 1535 An octet beginning with '-' or '*' is made of only one IE (7 bits). | |
| 1536 A group made of one octet has only one IE with '*'. | |
| 1537 If '+' is present, next IEs ending with '*' or '-' are present too. | |
| 1538 If the beginning IE with ' ' is not IE | |
| 1539 | |
| 1540 Examples of extended group configurations. | |
| 1541 _ _ _ _ _ | |
| 1542 | | | | | | | | |
| 1543 |+|*| |+| |*| one octet | |
| 1544 |_|_| |_|_|_| | |
| 1545 | |
| 1546 _ _ _ _ _ _ _ _ _ _ _ | |
| 1547 | | | | | | | | | | | | | | | |
| 1548 |+|-| |*| |+|-|*| |+| |-|*| two octets | |
| 1549 |_|_|_|_| |_|_|_| |_|_|_|_| | |
| 1550 | |
| 1551 | |
| 1552 _ _ _ _ _ _ _ _ _ _ | |
| 1553 | | | | | | | | | | | | |
| 1554 |+| | |-| |-| |-| |*| four octets | |
| 1555 |_|_|_|_|_|_|_|_|_|_| | |
| 1556 | |
| 1557 Also groups after groups are possible. | |
| 1558 _ _ _ _ _ _ _ _ _ | |
| 1559 | | | | | | | | | | | |
| 1560 |+| |-| |*|+|*|*|*| | |
| 1561 |_|_|_|_|_|_|_|_|_| | |
| 1562 | |
| 1563 The status of encoding is given as follows: | |
| 1564 | |
| 1565 ExtendedGroupActive is set to 1 if '+' is present in the encoding. | |
| 1566 ExtendedGroupActive is changed from 1 to 0 when encoding '*'. | |
| 1567 ExtendedGroupActive is set to 0 if an octet beginning with ' ' is | |
| 1568 not present. | |
| 1569 OpenNewOctet is set to 1 after encoding an IE with '-'. | |
| 1570 ExtBitPos1 is set to the globs->bitpos when writing extension bit: | |
| 1571 1) for '+' or | |
| 1572 2) for ' ' after '-' | |
| 1573 | |
| 1574 Extension bit is set to 0 if a further octet is encoded for | |
| 1575 the group. If an octet is the last one within a group, the | |
| 1576 extension bit is set to 1. | |
| 1577 | |
| 1578 While processing the first IE of an octet (e.g. for '+'), | |
| 1579 if the IE is absent, CCD will skip over all IEs up to the | |
| 1580 ending '*'. | |
| 1581 When processing IEs with ' ' and for ExtendedGroupActive=1 the valid | |
| 1582 flag is set to 1 in order to compensate probable mistakes in PS. | |
| 1583 | |
| 1584 */ | |
| 1585 | |
| 1586 void ccd_encodeComposition (const ULONG c_ref, T_CCD_Globs *globs) | |
| 1587 { | |
| 1588 ULONG e_ref; | |
| 1589 ULONG l_ref; | |
| 1590 BOOL ExtendedGroupActive = FALSE, OpenNewOctet = FALSE; | |
| 1591 ULONG ext_bit_pos1=0, ext_bit_pos2=0, ext_bit_pos3=0, more_data_bit_pos=0; | |
| 1592 int ext_bit_pending=0; | |
| 1593 UBYTE codecRet; | |
| 1594 | |
| 1595 | |
| 1596 #ifdef DEBUG_CCD | |
| 1597 #ifndef CCD_SYMBOLS | |
| 1598 TRACE_CCD (globs, "ccd_encodeComposition()"); | |
| 1599 #else | |
| 1600 TRACE_CCD (globs, "ccd_encodeComposition(): Composition = %s", | |
| 1601 mcomp[c_ref].name); | |
| 1602 #endif | |
| 1603 #endif | |
| 1604 | |
| 1605 globs->ccd_recurs_level++; | |
| 1606 | |
| 1607 /* | |
| 1608 * setup the index in the melem table for this composition. | |
| 1609 * If this function is called for the first time | |
| 1610 * (ccd_recurs_level == 1) the elem-table entry for the msg_type | |
| 1611 * was skipped. | |
| 1612 */ | |
| 1613 | |
| 1614 l_ref = (USHORT)(mcomp[c_ref].componentRef | |
| 1615 + mcomp[c_ref].numOfComponents); | |
| 1616 | |
| 1617 e_ref = (USHORT)(mcomp[c_ref].componentRef | |
| 1618 + ((globs->ccd_recurs_level EQ 1) ? 1 : 0)); | |
| 1619 | |
| 1620 /* | |
| 1621 * code all elements | |
| 1622 */ | |
| 1623 while (e_ref < l_ref) | |
| 1624 { | |
| 1625 #ifdef ERR_TRC_STK_CCD | |
| 1626 /* | |
| 1627 * Save the value for tracing in error case. | |
| 1628 */ | |
| 1629 globs->error_stack[globs->ccd_recurs_level] = (USHORT) e_ref; | |
| 1630 #endif /* ERR_TRC_STK_CCD */ | |
| 1631 | |
| 1632 /* | |
| 1633 * look for extension group processing | |
| 1634 */ | |
| 1635 if (melem[e_ref].extGroup NEQ ' ') | |
| 1636 { | |
| 1637 /* | |
| 1638 * extended group symbol found | |
| 1639 */ | |
| 1640 switch (melem[e_ref].extGroup) | |
| 1641 { | |
| 1642 case '+': | |
| 1643 | |
| 1644 /* | |
| 1645 * remember the position of the extension bit | |
| 1646 * because we maybe have to recode it. | |
| 1647 */ | |
| 1648 ext_bit_pos1 = ext_bit_pos2 = (ULONG) globs->bitpos; | |
| 1649 | |
| 1650 | |
| 1651 /* | |
| 1652 * write the extension bit. It may overwritten | |
| 1653 * later. (ext=0 -> group extended) | |
| 1654 */ | |
| 1655 bf_writeBit (0, globs); | |
| 1656 ext_bit_pos3 = (USHORT) globs->bitpos; | |
| 1657 | |
| 1658 #if defined(_TOOLS_) | |
| 1659 if (ccd_patch (globs, 0)) | |
| 1660 codecRet = 1; | |
| 1661 else | |
| 1662 #endif /* _TOOLS_ */ | |
| 1663 /* Use the jump-table for selecting encode function. */ | |
| 1664 codecRet = (UBYTE) | |
| 1665 codec[melem[e_ref].codingType][ENCODE_FUN](c_ref, e_ref, globs); | |
| 1666 | |
| 1667 /* Absence due to validity flag, conditions or a ccdWarning. */ | |
| 1668 if (!CheckBP_RecodeXB (ext_bit_pos1, ext_bit_pos2, ext_bit_pos3, globs)) | |
| 1669 { | |
| 1670 ExtendedGroupActive = FALSE; | |
| 1671 SkipExtensionOctets (&e_ref, l_ref); | |
| 1672 continue; | |
| 1673 } | |
| 1674 /* Start of an extended group */ | |
| 1675 else | |
| 1676 { | |
| 1677 OpenNewOctet = FALSE; | |
| 1678 } | |
| 1679 | |
| 1680 ExtendedGroupActive = TRUE; | |
| 1681 ext_bit_pending = 1; | |
| 1682 | |
| 1683 if (codecRet NEQ 0x7f) | |
| 1684 { | |
| 1685 /* Set the elemRef to the next or the same element. */ | |
| 1686 e_ref += codecRet; | |
| 1687 } | |
| 1688 break; | |
| 1689 | |
| 1690 /* End of one extension octet. */ | |
| 1691 case '-': | |
| 1692 /* IE must be present if the previous one was not with '-'. */ | |
| 1693 if (OpenNewOctet == FALSE) | |
| 1694 { | |
| 1695 #ifdef DEBUG_CCD | |
| 1696 if (globs->pstruct [melem[e_ref].structOffs] != TRUE) | |
| 1697 { | |
| 1698 TRACE_CCD (globs, "Wrong value for valid flag!\n...changed to 1 for ccdID=%d", | |
| 1699 e_ref); | |
| 1700 } | |
| 1701 #endif | |
| 1702 /* IE has to be present. Don't trust PS code. */ | |
| 1703 globs->pstruct [melem[e_ref].structOffs] = TRUE; | |
| 1704 } | |
| 1705 ext_bit_pos3 = (USHORT) globs->bitpos; | |
| 1706 | |
| 1707 #if defined(_TOOLS_) | |
| 1708 if (ccd_patch (globs, 0)) | |
| 1709 codecRet = 1; | |
| 1710 else | |
| 1711 #endif /* _TOOLS_ */ | |
| 1712 /* Use the jump-table for selecting encode function. */ | |
| 1713 codecRet = (UBYTE) | |
| 1714 codec[melem[e_ref].codingType][ENCODE_FUN](c_ref, e_ref, globs); | |
| 1715 | |
| 1716 if (OpenNewOctet == TRUE) | |
| 1717 { | |
| 1718 /* Absence due to validity flag, conditions or a ccdWarning. */ | |
| 1719 if (!CheckBP_RecodeXB (ext_bit_pos1, ext_bit_pos2, ext_bit_pos3, globs)) | |
| 1720 { | |
| 1721 ExtendedGroupActive = FALSE; | |
| 1722 SkipExtensionOctets (&e_ref, l_ref); | |
| 1723 continue; | |
| 1724 } | |
| 1725 } | |
| 1726 | |
| 1727 if (codecRet NEQ 0x7f) | |
| 1728 { | |
| 1729 /* Set the elemRef to the next or the same element. */ | |
| 1730 e_ref += codecRet; | |
| 1731 } | |
| 1732 | |
| 1733 /* IE with '-' belongs to the first octet. */ | |
| 1734 if (ext_bit_pending EQ 1) | |
| 1735 { | |
| 1736 ext_bit_pending++; | |
| 1737 } | |
| 1738 /* | |
| 1739 * At least one octet has been encoded for the current group. | |
| 1740 * Swap the stored positions of the extension bits. | |
| 1741 */ | |
| 1742 else | |
| 1743 { | |
| 1744 ext_bit_pos1 = ext_bit_pos2; | |
| 1745 } | |
| 1746 | |
| 1747 /* | |
| 1748 * Store the position of the extension bit | |
| 1749 * because we maybe have to recode it. | |
| 1750 */ | |
| 1751 ext_bit_pos2 = (ULONG) globs->bitpos; | |
| 1752 /* | |
| 1753 * write the extension bit. It may overwritten | |
| 1754 * later. (ext=0 -> group extended) | |
| 1755 */ | |
| 1756 bf_writeBit (0, globs); | |
| 1757 OpenNewOctet = TRUE; | |
| 1758 | |
| 1759 break; | |
| 1760 | |
| 1761 case '*': | |
| 1762 if (!ExtendedGroupActive) | |
| 1763 { | |
| 1764 /* | |
| 1765 * This is a single element extended group, often | |
| 1766 * used for later extension of the protocol | |
| 1767 * Write '1' in extension bit since group is not extended yet. | |
| 1768 */ | |
| 1769 bf_writeBit (1, globs); | |
| 1770 ext_bit_pos3 = (USHORT) globs->bitpos; | |
| 1771 | |
| 1772 #if defined(_TOOLS_) | |
| 1773 if (ccd_patch (globs, 0)) | |
| 1774 codecRet = 1; | |
| 1775 else | |
| 1776 #endif /* _TOOLS_ */ | |
| 1777 /* Use the jump-table for selecting encode function. */ | |
| 1778 codecRet = (UBYTE) | |
| 1779 codec[melem[e_ref].codingType][ENCODE_FUN](c_ref, e_ref, globs); | |
| 1780 /* Absence due to the valid flag or a ccdWarning. */ | |
| 1781 if (ext_bit_pos3 == globs->bitpos) | |
| 1782 { | |
| 1783 globs->bitpos --; | |
| 1784 } | |
| 1785 | |
| 1786 if (codecRet NEQ 0x7f) | |
| 1787 { | |
| 1788 /* Set the elemRef to the next or the same element. */ | |
| 1789 e_ref += codecRet; | |
| 1790 } | |
| 1791 } | |
| 1792 else | |
| 1793 { | |
| 1794 ExtendedGroupActive = FALSE; | |
| 1795 /* IE must be present if the previous one was not with '-'. */ | |
| 1796 if (OpenNewOctet == FALSE) | |
| 1797 { | |
| 1798 #ifdef DEBUG_CCD | |
| 1799 if (globs->pstruct [melem[e_ref].structOffs] != TRUE) | |
| 1800 { | |
| 1801 TRACE_CCD (globs, "Wrong value for valid flag!\n...changed to 1 for ccdID=%d", | |
| 1802 e_ref); | |
| 1803 } | |
| 1804 #endif | |
| 1805 /* IE has to be present. Don't trust PS code. */ | |
| 1806 globs->pstruct [melem[e_ref].structOffs] = TRUE; | |
| 1807 } | |
| 1808 | |
| 1809 #if defined(_TOOLS_) | |
| 1810 if (ccd_patch (globs, 0)) | |
| 1811 codecRet = 1; | |
| 1812 else | |
| 1813 #endif /* _TOOLS_ */ | |
| 1814 /* Use the jump-table for selecting the encode function. */ | |
| 1815 codecRet = (UBYTE) | |
| 1816 codec[melem[e_ref].codingType][ENCODE_FUN](c_ref, e_ref, globs); | |
| 1817 ext_bit_pos3 = (USHORT) globs->bitpos; | |
| 1818 | |
| 1819 if (codecRet NEQ 0x7f) | |
| 1820 { | |
| 1821 /* Set the elemRef to the next or the same element. */ | |
| 1822 e_ref += codecRet; | |
| 1823 } | |
| 1824 | |
| 1825 if ((ext_bit_pos3-1) NEQ ext_bit_pos2) | |
| 1826 { | |
| 1827 /* | |
| 1828 * if the writepointer (ext_bit_pos3) have incremented | |
| 1829 * since the first extension bit (NEQ ext_bit_pos1) | |
| 1830 * at least one element of this group is valid | |
| 1831 * and written into the bitstream. | |
| 1832 */ | |
| 1833 /* | |
| 1834 * the extended group is terminated, | |
| 1835 * so we have to switch the previously written | |
| 1836 * extBit from 0 to 1 | |
| 1837 */ | |
| 1838 bf_recodeBit ((USHORT) ext_bit_pos2, 1, globs); | |
| 1839 } | |
| 1840 else | |
| 1841 { | |
| 1842 /* | |
| 1843 * break of an extended group, no element are coded | |
| 1844 * since the last extension bit. | |
| 1845 */ | |
| 1846 /* | |
| 1847 * the extended group is terminated, | |
| 1848 * so we have to switch the previously written | |
| 1849 * extBit from 0 to 1 | |
| 1850 */ | |
| 1851 if (ext_bit_pos1 NEQ ext_bit_pos2) | |
| 1852 { | |
| 1853 bf_recodeBit ((USHORT) ext_bit_pos1, 1, globs); | |
| 1854 } | |
| 1855 /* | |
| 1856 * delete the written ext-bit because the extended | |
| 1857 * group ended. | |
| 1858 */ | |
| 1859 bf_setBitpos ((USHORT) ext_bit_pos2, globs); | |
| 1860 } | |
| 1861 } | |
| 1862 break; | |
| 1863 case '!': | |
| 1864 case '#': | |
| 1865 more_data_bit_pos = (ULONG) globs->bitpos; | |
| 1866 bf_writeBit (1, globs); | |
| 1867 | |
| 1868 #if defined(_TOOLS_) | |
| 1869 if (ccd_patch (globs, 0)) | |
| 1870 codecRet = 1; | |
| 1871 else | |
| 1872 #endif /* _TOOLS_ */ | |
| 1873 /* | |
| 1874 * use the jump-table for selecting the encode function | |
| 1875 */ | |
| 1876 codecRet = (UBYTE) | |
| 1877 codec[melem[e_ref].codingType][ENCODE_FUN](c_ref, e_ref, globs); | |
| 1878 if (codecRet NEQ 0x7f) | |
| 1879 { | |
| 1880 if (more_data_bit_pos+1 EQ globs->bitpos) | |
| 1881 { | |
| 1882 /* | |
| 1883 * rewrite the written moredata bit to 0 | |
| 1884 */ | |
| 1885 bf_setBitpos (more_data_bit_pos, globs); | |
| 1886 bf_writeBit (0, globs); | |
| 1887 /* | |
| 1888 * no coding performed -> extension group ended | |
| 1889 * We skip all elements in this group | |
| 1890 */ | |
| 1891 while (melem[e_ref].extGroup EQ '!') | |
| 1892 e_ref++; | |
| 1893 | |
| 1894 if (melem[e_ref].extGroup EQ '#') | |
| 1895 e_ref++; | |
| 1896 } | |
| 1897 else | |
| 1898 { | |
| 1899 if (melem[e_ref].extGroup EQ '#') | |
| 1900 { | |
| 1901 /* | |
| 1902 * code a zero bit for the last element | |
| 1903 */ | |
| 1904 bf_writeBit (0, globs); | |
| 1905 } | |
| 1906 e_ref++; | |
| 1907 } | |
| 1908 } | |
| 1909 break; | |
| 1910 default: | |
| 1911 ccd_setError (globs, ERR_DEFECT_CCDDATA, BREAK, | |
| 1912 (USHORT) (globs->bitpos), (USHORT) -1); | |
| 1913 break; | |
| 1914 } | |
| 1915 } | |
| 1916 else | |
| 1917 { | |
| 1918 if (ExtendedGroupActive) | |
| 1919 { | |
| 1920 ext_bit_pos3 = (USHORT) globs->bitpos; | |
| 1921 | |
| 1922 /* IE in the middle part of an ext-octet. */ | |
| 1923 if (OpenNewOctet == FALSE) | |
| 1924 { | |
| 1925 #ifdef DEBUG_CCD | |
| 1926 if (globs->pstruct [melem[e_ref].structOffs] != TRUE) | |
| 1927 { | |
| 1928 TRACE_CCD (globs, "Wrong value for valid flag!\n...changed to 1 for ccdID=%d", | |
| 1929 e_ref); | |
| 1930 } | |
| 1931 #endif | |
| 1932 globs->pstruct [melem[e_ref].structOffs] = TRUE; | |
| 1933 } | |
| 1934 } | |
| 1935 | |
| 1936 #if defined(_TOOLS_) | |
| 1937 if (ccd_patch (globs, 0)) | |
| 1938 codecRet = 1; | |
| 1939 else | |
| 1940 #endif /* _TOOLS_ */ | |
| 1941 /* Use the jump-table for selecting encode function. */ | |
| 1942 codecRet = (UBYTE) | |
| 1943 codec[melem[e_ref].codingType][ENCODE_FUN](c_ref, e_ref, globs); | |
| 1944 | |
| 1945 /* The following is only meant for IEs after an IE with '-'. */ | |
| 1946 if (ExtendedGroupActive) | |
| 1947 { | |
| 1948 if (OpenNewOctet == TRUE) | |
| 1949 { | |
| 1950 /* Absence due to validity flag, conditions or a ccdWarning. */ | |
| 1951 if (!CheckBP_RecodeXB (ext_bit_pos1, ext_bit_pos2, ext_bit_pos3, globs)) | |
| 1952 { | |
| 1953 ExtendedGroupActive = FALSE; | |
| 1954 SkipExtensionOctets (&e_ref, l_ref); | |
| 1955 continue; | |
| 1956 } | |
| 1957 /* Start of an extension octet */ | |
| 1958 else | |
| 1959 { | |
| 1960 OpenNewOctet = FALSE; | |
| 1961 } | |
| 1962 } | |
| 1963 } | |
| 1964 | |
| 1965 if (codecRet NEQ 0x7f) | |
| 1966 { | |
| 1967 /* Set the elemRef to the next or the same element. */ | |
| 1968 e_ref += codecRet; | |
| 1969 } | |
| 1970 } | |
| 1971 } | |
| 1972 | |
| 1973 globs->ccd_recurs_level--; | |
| 1974 } | |
| 1975 #endif /* !RUN_FLASH */ | |
| 1976 | |
| 1977 /* ---------------------------------------------------------------- */ | |
| 1978 /* GLOBAL FUNCTIONS */ | |
| 1979 /* ---------------------------------------------------------------- */ | |
| 1980 | |
| 1981 #ifndef RUN_FLASH | |
| 1982 /* | |
| 1983 +------------------------------------------------------------------------------ | |
| 1984 | Function : ccd_check_pointer | |
| 1985 +------------------------------------------------------------------------------ | |
| 1986 | Description : This function checks the validity of a pointer | |
| 1987 | | |
| 1988 | Parameters : ptr - the pointer | |
| 1989 | | |
| 1990 | Return : ccdOK if pointer valid, otherwise ccdError | |
| 1991 +------------------------------------------------------------------------------ | |
| 1992 */ | |
| 1993 int ccd_check_pointer (U8* ptr) | |
| 1994 { | |
| 1995 if (!ptr || ptr == mempat | |
| 1996 #ifdef WIN32 | |
| 1997 /* For windows: check also if ptr is too small */ | |
| 1998 || !(ptr && LOWSEGMASK) | |
| 1999 #endif | |
| 2000 ) | |
| 2001 { | |
| 2002 return ccdError; | |
| 2003 } | |
| 2004 return ccdOK; | |
| 2005 } | |
| 2006 #endif /* !RUN_FLASH */ | |
| 2007 | |
| 2008 #ifndef RUN_FLASH | |
| 2009 /* | |
| 2010 +--------------------------------------------------------------------+ | |
| 2011 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2012 | STATE : code ROUTINE : ccd_begin | | |
| 2013 +--------------------------------------------------------------------+ | |
| 2014 | |
| 2015 | |
| 2016 PARAMETERS: none | |
| 2017 | |
| 2018 PURPOSE: Returns the address of the CCD buffer for decoded | |
| 2019 messages and locks it until ccd_end() is called | |
| 2020 | |
| 2021 */ | |
| 2022 | |
| 2023 UBYTE* CCDDATA_PREF(ccd_begin) (void) | |
| 2024 { | |
| 2025 #ifdef SHARED_CCD | |
| 2026 /* | |
| 2027 * if the CCD is used in a premptive multithreaded system | |
| 2028 * we must lock this critical section | |
| 2029 */ | |
| 2030 vsi_s_get (VSI_CALLER semCCD_Buffer); | |
| 2031 #endif | |
| 2032 | |
| 2033 #ifdef DEBUG_CCD | |
| 2034 { | |
| 2035 #ifndef _TMS470 | |
| 2036 T_CCD_Globs globs; | |
| 2037 globs.me = 0; | |
| 2038 globs.TraceIt = 1; | |
| 2039 TRACE_CCD (&globs, "CCD Begin"); | |
| 2040 #endif | |
| 2041 } | |
| 2042 #endif | |
| 2043 return ccd_decMsgBuffer; | |
| 2044 } | |
| 2045 #endif /* !RUN_FLASH */ | |
| 2046 | |
| 2047 #ifndef RUN_FLASH | |
| 2048 /* | |
| 2049 +--------------------------------------------------------------------+ | |
| 2050 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2051 | STATE : code ROUTINE : ccd_end | | |
| 2052 +--------------------------------------------------------------------+ | |
| 2053 | |
| 2054 | |
| 2055 PARAMETERS: none | |
| 2056 | |
| 2057 PURPOSE: Unlocks the CCD buffer for decoded | |
| 2058 messages | |
| 2059 | |
| 2060 */ | |
| 2061 | |
| 2062 void CCDDATA_PREF(ccd_end) (void) | |
| 2063 { | |
| 2064 #ifdef SHARED_CCD | |
| 2065 /* | |
| 2066 * if the CCD is used in a premptive multithreaded system | |
| 2067 * we must unlock this critical section of accessing the | |
| 2068 * decoded message buffer | |
| 2069 */ | |
| 2070 vsi_s_release (VSI_CALLER semCCD_Buffer); | |
| 2071 #endif | |
| 2072 } | |
| 2073 #endif /* !RUN_FLASH */ | |
| 2074 | |
| 2075 #ifndef RUN_FLASH | |
| 2076 /* | |
| 2077 +--------------------------------------------------------------------+ | |
| 2078 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2079 | STATE : code ROUTINE : ccd_GetGlobVars | | |
| 2080 +--------------------------------------------------------------------+ | |
| 2081 | |
| 2082 | |
| 2083 PARAMETERS: | |
| 2084 | |
| 2085 PURPOSE: Determines which set of global variables to use | |
| 2086 and locks the CCD buffer (semaphore) if necessary. | |
| 2087 | |
| 2088 */ | |
| 2089 T_CCD_Globs* ccd_GetGlobVars (T_CCD_ERR_LIST_HEAD** eentry, T_CCD_STORE_LIST** stoentry) | |
| 2090 { | |
| 2091 T_CCD_TASK_TABLE* tentry; | |
| 2092 #ifndef SHARED_CCD | |
| 2093 int me = 0; | |
| 2094 #else | |
| 2095 T_HANDLE me; | |
| 2096 me = vsi_e_handle (0, NULL); | |
| 2097 if (me == VSI_ERROR) | |
| 2098 me = 0; | |
| 2099 #endif /* !SHARED_CCD */ | |
| 2100 | |
| 2101 tentry = ccd_task_list[me]; | |
| 2102 tentry->ccd_globs->me = me; | |
| 2103 *eentry = tentry->ccd_err_list; | |
| 2104 *stoentry = tentry->ccd_store; | |
| 2105 #ifdef SHARED_CCD | |
| 2106 if (tentry->ccd_globs == &globs_all) | |
| 2107 { | |
| 2108 /* | |
| 2109 * if the CCD is used in a premptive multithreaded system | |
| 2110 * we must lock this critical section | |
| 2111 */ | |
| 2112 vsi_s_get (VSI_CALLER semCCD_Codec); | |
| 2113 } | |
| 2114 #endif /* SHARED_CCD */ | |
| 2115 return tentry->ccd_globs; | |
| 2116 } | |
| 2117 #endif /* !RUN_FLASH */ | |
| 2118 | |
| 2119 #ifndef RUN_FLASH | |
| 2120 /* | |
| 2121 +--------------------------------------------------------------------+ | |
| 2122 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2123 | STATE : code ROUTINE : ccd_FreeGlobVars | | |
| 2124 +--------------------------------------------------------------------+ | |
| 2125 | |
| 2126 | |
| 2127 PARAMETERS: none | |
| 2128 | |
| 2129 PURPOSE: Unlocks the CCD buffer for decoded messages | |
| 2130 if the entity is not GRR and if | |
| 2131 the CCD is used in a premptive multithreaded system. | |
| 2132 | |
| 2133 */ | |
| 2134 void ccd_FreeGlobVars (T_CCD_Globs* globs) | |
| 2135 { | |
| 2136 #ifdef SHARED_CCD | |
| 2137 if (globs == &globs_all) | |
| 2138 { | |
| 2139 vsi_s_release (VSI_CALLER semCCD_Codec); | |
| 2140 } | |
| 2141 #endif /* SHARED_CCD */ | |
| 2142 } | |
| 2143 #endif /* !RUN_FLASH */ | |
| 2144 | |
| 2145 #ifndef RUN_FLASH | |
| 2146 #ifdef DEBUG_CCD | |
| 2147 /* | |
| 2148 +--------------------------------------------------------------------+ | |
| 2149 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2150 | STATE : code ROUTINE : ccd_dump_msg | | |
| 2151 +--------------------------------------------------------------------+ | |
| 2152 | |
| 2153 PARAMETERS: U16 l_buf | |
| 2154 - Number of bits in the encoded message or IE. | |
| 2155 | |
| 2156 U16 o_buf | |
| 2157 - Offset of the bitstream buffer in bits. | |
| 2158 | |
| 2159 U8 *buf | |
| 2160 - Bitstream buffer of the encoded message or IE. | |
| 2161 | |
| 2162 T_CCD_Globs globs | |
| 2163 - Pointer to global variables | |
| 2164 | |
| 2165 PURPOSE: Dump contents of air interface message - for debugging | |
| 2166 | |
| 2167 */ | |
| 2168 void ccd_dump_msg (U16 l_buf, U16 o_buf, U8 *buf, T_CCD_Globs *globs) | |
| 2169 { | |
| 2170 | |
| 2171 if (!globs->TraceIt) | |
| 2172 return; | |
| 2173 else | |
| 2174 { | |
| 2175 int i, j, buflen; | |
| 2176 char s[64], c[4]; | |
| 2177 | |
| 2178 buflen = (l_buf + o_buf + 7) >> 3; | |
| 2179 TRACE_CCD (globs, "-------------------------------------------------"); | |
| 2180 TRACE_CCD (globs, " CCD: Decode Message"); | |
| 2181 TRACE_CCD (globs, " Before DECODING: lbuf= %d, obuf= %d", l_buf, o_buf); | |
| 2182 TRACE_CCD (globs, " Hex dump of message to be decoded:"); | |
| 2183 | |
| 2184 s[0] = '\0'; | |
| 2185 for (i = o_buf>>3; i < buflen; i+=16) | |
| 2186 { | |
| 2187 for (j = 0; j < 16; j++) | |
| 2188 { | |
| 2189 if ((i+j) < buflen) | |
| 2190 { | |
| 2191 sprintf(c, " %02x", buf[i+j]); | |
| 2192 strcat (s, c); | |
| 2193 } | |
| 2194 } | |
| 2195 TRACE_CCD (globs, "%s", s); | |
| 2196 s[0] = '\0'; | |
| 2197 } | |
| 2198 } | |
| 2199 } | |
| 2200 #endif /* DEBUG_CCD */ | |
| 2201 #endif /* !RUN_FLASH */ | |
| 2202 | |
| 2203 #ifndef RUN_FLASH | |
| 2204 /* | |
| 2205 +--------------------------------------------------------------------+ | |
| 2206 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2207 | STATE : code ROUTINE : ccd_common_decode_init| | |
| 2208 +--------------------------------------------------------------------+ | |
| 2209 | |
| 2210 PARAMETERS: | |
| 2211 | |
| 2212 PURPOSE: Perform common CCD initialization before message decode. | |
| 2213 | |
| 2214 */ | |
| 2215 void ccd_common_decode_init(U16 l_buf, U16 o_buf, U8 *buf, T_CCD_Globs *globs) | |
| 2216 { | |
| 2217 #if defined (DEBUG_CCD) | |
| 2218 /* to avoid the vsprintf if the traces won't appear anyhow */ | |
| 2219 ULONG mask; | |
| 2220 if (vsi_gettracemask (globs->me, globs->me, &mask) != VSI_ERROR) | |
| 2221 { | |
| 2222 globs->TraceIt = mask & TC_CCD; | |
| 2223 } | |
| 2224 #endif | |
| 2225 | |
| 2226 /* | |
| 2227 * no call to setjmp() done. So ccd_Error performs no longjmp in | |
| 2228 * case of an error | |
| 2229 */ | |
| 2230 globs->jmp_mark_set = FALSE; | |
| 2231 | |
| 2232 /* setup the bitbuffer */ | |
| 2233 globs->bitbuf = buf; | |
| 2234 globs->bitpos = 0; | |
| 2235 | |
| 2236 /* cleanup the read-caches */ | |
| 2237 globs->lastbytepos16 = globs->lastbytepos32 = 0xffff; | |
| 2238 | |
| 2239 /* setup the bitoffset */ | |
| 2240 globs->bitoffs = o_buf; | |
| 2241 | |
| 2242 | |
| 2243 bf_incBitpos (o_buf, globs); | |
| 2244 | |
| 2245 /* | |
| 2246 * calclate the max bitpos to read | |
| 2247 */ | |
| 2248 globs->buflen = l_buf + o_buf; | |
| 2249 globs->maxBitpos = globs->buflen; | |
| 2250 globs->msgLen = globs->buflen; | |
| 2251 globs->errLabel = 0; | |
| 2252 globs->continue_array = TRUE; | |
| 2253 globs->SeekTLVExt = TRUE; | |
| 2254 | |
| 2255 globs->ccd_recurs_level = 0; | |
| 2256 globs->CCD_Error = ccdOK; | |
| 2257 } | |
| 2258 #endif /* !RUN_FLASH */ | |
| 2259 | |
| 2260 #ifndef RUN_FLASH | |
| 2261 /* | |
| 2262 * Attention: if this static function shall be used in | |
| 2263 * both, internal as well as external RAM, it must be made global. | |
| 2264 */ | |
| 2265 /* | |
| 2266 +--------------------------------------------------------------------+ | |
| 2267 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2268 | STATE : code ROUTINE : SeekForGSMExtensions | | |
| 2269 +--------------------------------------------------------------------+ | |
| 2270 | |
| 2271 PURPOSE: Check if there are elements left in the air message | |
| 2272 without being decoded. Assume that the next IE has the | |
| 2273 type T, TV or a TLV. Seek for Comprehension Required | |
| 2274 extensions. | |
| 2275 1) Rules to distinguish between the types: | |
| 2276 handling of unknown IEs (GSM 04.07, section 11.2.4) | |
| 2277 "Bit 8 of the IEI octet is set to "1" indicates a TV | |
| 2278 formatted type 1 standard IE or a T formatted type 2 | |
| 2279 IEs, and to "0" indicates a TLV formatted type 4 IE. | |
| 2280 Hence, a 1 valued bit 8 indicates that the whole IE is | |
| 2281 one octet long, and a 0 valued bit 8 indicates that the | |
| 2282 following octet is a length octet. | |
| 2283 1) Rules to read the length: | |
| 2284 For TLV4 encode L in one byte. | |
| 2285 For TLV5 and ASN.1 encode in one byte or more. Use | |
| 2286 0x81, 0x82 etc in the first byte to say L is encoded | |
| 2287 in one, two etc bytes. | |
| 2288 For ASN.1 BER type use 0x80 in the first byte and | |
| 2289 two otets of 0 bits after the encoded IE. | |
| 2290 For all the three types it is possible to encode L | |
| 2291 in only one byte. | |
| 2292 TLV6 is not supported. TLV6 is not a GSM standard | |
| 2293 type. It has been defined in g23net software. | |
| 2294 */ | |
| 2295 static void SeekForGSMExtensions (U8 entity, T_CCD_Globs *globs) | |
| 2296 { | |
| 2297 U8 *MsgBuf = (U8*)globs->bitbuf; | |
| 2298 U16 BP = globs->bytepos; | |
| 2299 U16 OctNr = (globs->buflen+7) >> 3; | |
| 2300 U16 errPos = 0; | |
| 2301 U8 errTag = 0xFF; | |
| 2302 U8 errCode; | |
| 2303 | |
| 2304 #ifdef DEBUG_CCD | |
| 2305 TRACE_CCD( globs, "SeekForGSMExtensions..."); | |
| 2306 #endif | |
| 2307 while (BP < OctNr) | |
| 2308 { | |
| 2309 U8 T = MsgBuf[BP]; | |
| 2310 BOOL tlv5 = FALSE; | |
| 2311 | |
| 2312 /* Expecting a CCDTYPE_GSM5_TLV type we get an unknown tag with MSB set. | |
| 2313 * Expecting other types than CCDTYPE_GSM5_TLV we get an unknown tag with | |
| 2314 * comprehension required bits (5, 6, 7 and 8 of IEI according to GSM0407) | |
| 2315 * are set to zero. | |
| 2316 */ | |
| 2317 tlv5 = (aim_sat == entity); | |
| 2318 if ( (tlv5 && ((T & 0x80) == 0x80)) | |
| 2319 || | |
| 2320 (!tlv5 && ((T & 0xf0) == 0)) ) | |
| 2321 { | |
| 2322 errTag = T; | |
| 2323 errPos = BP*8; | |
| 2324 errCode = ERR_COMPREH_REQUIRED; | |
| 2325 /* Report error. Do not analyse the rest. */ | |
| 2326 break; | |
| 2327 } | |
| 2328 else | |
| 2329 { | |
| 2330 errTag = T; | |
| 2331 errPos = BP*8; | |
| 2332 errCode = ERR_IE_NOT_EXPECTED; | |
| 2333 } | |
| 2334 | |
| 2335 /* The type is TLV or ASN.1. */ | |
| 2336 if ((T & 0x80) NEQ 0x80) | |
| 2337 { | |
| 2338 /* BP points to the first L byte */ | |
| 2339 U16 L = MsgBuf[++BP]; | |
| 2340 switch (L) | |
| 2341 { | |
| 2342 /* End Of Content (ASN.1 BER) */ | |
| 2343 case 0x80: | |
| 2344 do | |
| 2345 { | |
| 2346 BP++; | |
| 2347 } while ((*(U16*)&MsgBuf[BP]) != 0 && BP < OctNr); | |
| 2348 BP++; | |
| 2349 L = 0; | |
| 2350 break; | |
| 2351 | |
| 2352 /* Length encoding in two bytes */ | |
| 2353 case 0x81: | |
| 2354 L = MsgBuf[++BP]; | |
| 2355 break; | |
| 2356 | |
| 2357 /* Length encoding in three bytes */ | |
| 2358 case 0x82: | |
| 2359 L = (MsgBuf[++BP]) << 8; | |
| 2360 L |= MsgBuf[++BP]; | |
| 2361 break; | |
| 2362 | |
| 2363 /* Length encoding in one byte. */ | |
| 2364 default: | |
| 2365 break; | |
| 2366 } | |
| 2367 | |
| 2368 /* Skip over the bytes. */ | |
| 2369 while (L > 0 && BP < OctNr) | |
| 2370 { | |
| 2371 --L; | |
| 2372 ++BP; | |
| 2373 } | |
| 2374 | |
| 2375 } /* if TLV */ | |
| 2376 /* else: The type is T or TV. Skip one byte (see next step). */ | |
| 2377 | |
| 2378 /* | |
| 2379 * BP points to the last byte of the skipped IE, | |
| 2380 * move to the next IE. | |
| 2381 */ | |
| 2382 BP++; | |
| 2383 }/* while bytes left unread */ | |
| 2384 | |
| 2385 /* Report the summary of the found erros. */ | |
| 2386 if (errTag != 0xFF) | |
| 2387 { | |
| 2388 ccd_setError (globs, errCode, | |
| 2389 (U8)((errCode == ERR_COMPREH_REQUIRED) ? BREAK : CONTINUE), | |
| 2390 errTag, | |
| 2391 errPos, | |
| 2392 (USHORT) -1); | |
| 2393 } | |
| 2394 } | |
| 2395 #endif /* !RUN_FLASH */ | |
| 2396 | |
| 2397 #ifndef RUN_FLASH | |
| 2398 /* | |
| 2399 +--------------------------------------------------------------------+ | |
| 2400 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2401 | STATE : code ROUTINE : ccd_decodeMsg | | |
| 2402 +--------------------------------------------------------------------+ | |
| 2403 | |
| 2404 | |
| 2405 PARAMETERS: UBYTE entity | |
| 2406 - specifies the calling entity of CCD. The Constants | |
| 2407 for each valid entity is defined in MCONST.CDG | |
| 2408 | |
| 2409 UBYTE direction | |
| 2410 - specifies wether the message goes UPLINK or DOWNLINK. | |
| 2411 This is nessesary because there are same PDU-Type | |
| 2412 codes for different messages. | |
| 2413 | |
| 2414 T_MSGBUF * mBuf | |
| 2415 - specifies the bitstream buffer of the message. The | |
| 2416 struct contains the l_buf and the o_buf elements. | |
| 2417 These elements specifies the length and offset in bits | |
| 2418 of the bitstream in the T_MSGBUF component buf. | |
| 2419 | |
| 2420 UBYTE * mStruct | |
| 2421 - reference to the C-Structure of the decoded message. | |
| 2422 The type may differ so the Pointer is always typed as | |
| 2423 UBYTE* and must be casted after decoding. If this parameter | |
| 2424 is NULL CCD uses his internal buffer wich must be | |
| 2425 protected via ccd_begin() in a multithread environment. | |
| 2426 | |
| 2427 UBYTE mId | |
| 2428 - specifies the PDU-Type of the bitstream. If this | |
| 2429 parameter is not equal 0xff the CCD does not decode | |
| 2430 the pdu-type from the bitstream to decide wich decoding | |
| 2431 rules to select. Normaly this param is set to 0xff. | |
| 2432 | |
| 2433 PURPOSE: decodes a bitstream, containing a valid TETRA-Message | |
| 2434 of the Air-Interface to a corresponding C-Structure. | |
| 2435 | |
| 2436 */ | |
| 2437 | |
| 2438 BYTE CCDDATA_PREF(ccd_decodeMsg) (UBYTE entity, | |
| 2439 UBYTE direction, | |
| 2440 T_MSGBUF *mBuf, | |
| 2441 UBYTE *mStruct, | |
| 2442 UBYTE mId) | |
| 2443 { | |
| 2444 UBYTE theMsgId; | |
| 2445 USHORT mcompRef; | |
| 2446 int jmp_ret; | |
| 2447 T_CCD_Globs *globs; | |
| 2448 T_CCD_ERR_LIST_HEAD* eentry; | |
| 2449 T_CCD_STORE_LIST* stoentry; | |
| 2450 | |
| 2451 globs = ccd_GetGlobVars (&eentry, &stoentry); | |
| 2452 | |
| 2453 /* | |
| 2454 * setup the structure-buffer | |
| 2455 * | |
| 2456 * if the parameter of the decoded message buffer address is NULL | |
| 2457 * we use the internal one | |
| 2458 */ | |
| 2459 globs->pstruct = (mStruct EQ NULL) ? ccd_decMsgBuffer : mStruct; | |
| 2460 globs->pstructOffs = 0; | |
| 2461 | |
| 2462 ccd_common_decode_init(mBuf->l_buf, mBuf->o_buf, mBuf->buf, globs); | |
| 2463 ccd_err_reset (eentry); | |
| 2464 globs->errLabel = 0; | |
| 2465 globs->continue_array = TRUE; | |
| 2466 | |
| 2467 #ifdef DEBUG_CCD | |
| 2468 ccd_dump_msg(mBuf->l_buf, mBuf->o_buf, mBuf->buf, globs); | |
| 2469 #endif | |
| 2470 | |
| 2471 if (mId NEQ 0xff AND mId NEQ 0xfe) | |
| 2472 globs->pstruct[0] = theMsgId = mId; | |
| 2473 else | |
| 2474 { | |
| 2475 /* Read the message identifier */ | |
| 2476 globs->pstruct[0] = bf_decodeByteNumber ((ULONG) mi_length[entity], globs); | |
| 2477 theMsgId = globs->pstruct[0]; | |
| 2478 } | |
| 2479 | |
| 2480 /* Get entry in mmtx table for this message */ | |
| 2481 mcompRef = ccddata_get_mmtx(entity,theMsgId,direction); | |
| 2482 | |
| 2483 /* Check the message identifier */ | |
| 2484 if (theMsgId > max_message_id OR mcompRef EQ NO_REF) | |
| 2485 { | |
| 2486 #ifdef ERR_TRC_STK_CCD | |
| 2487 globs->ccd_recurs_level = 255; | |
| 2488 #endif /* ERR_TRC_STK_CCD */ | |
| 2489 ccd_setError (globs, ERR_INVALID_MID, BREAK, | |
| 2490 (USHORT) theMsgId, (USHORT) -1); | |
| 2491 ccd_FreeGlobVars (globs); | |
| 2492 ccd_err_free (eentry); | |
| 2493 return (BYTE)globs->CCD_Error; | |
| 2494 } | |
| 2495 #ifdef ERR_TRC_STK_CCD | |
| 2496 /* save the value for tracing in error case */ | |
| 2497 globs->error_stack[0] = mcompRef; | |
| 2498 #endif /* ERR_TRC_STK_CCD */ | |
| 2499 | |
| 2500 #ifdef DEBUG_CCD | |
| 2501 #ifdef CCD_SYMBOLS | |
| 2502 TRACE_CCD (globs, "CCD decode: Message = %s", | |
| 2503 mcomp[mcompRef].name); | |
| 2504 #else | |
| 2505 TRACE_CCD (globs, "CCD decode: MessageId = %x", theMsgId); | |
| 2506 #endif | |
| 2507 #endif | |
| 2508 | |
| 2509 /* | |
| 2510 * Clean up the entite C-structure before decoding. | |
| 2511 * Do not overwrite the MsgId (1. Byte) | |
| 2512 */ | |
| 2513 #ifdef DEBUG_CCD | |
| 2514 TRACE_CCD (globs, "CCD Cleaning struct %ld bytes", | |
| 2515 mcomp[mcompRef].cSize-1); | |
| 2516 #endif | |
| 2517 memset ((UBYTE *) &globs->pstruct[1], 0, | |
| 2518 (size_t)(mcomp[mcompRef].cSize - 1)); | |
| 2519 | |
| 2520 /* | |
| 2521 * clear the UPN stack | |
| 2522 */ | |
| 2523 ST_CLEAR(globs); | |
| 2524 memset ((ULONG *) &(globs->KeepReg[0]), 0, MAX_KEEP_REG_SIZE); | |
| 2525 | |
| 2526 /* | |
| 2527 * inform the GSM-CODEC about the begin of a new message | |
| 2528 */ | |
| 2529 cdc_GSM_start (globs); | |
| 2530 | |
| 2531 jmp_ret = setjmp (globs->jmp_mark); | |
| 2532 | |
| 2533 if (jmp_ret EQ 0) | |
| 2534 { | |
| 2535 globs->jmp_mark_set = TRUE; | |
| 2536 ccd_decodeComposition ((ULONG) mcompRef, globs); | |
| 2537 | |
| 2538 /* | |
| 2539 * The coding rules and the data tables must be able to lead CCD to | |
| 2540 * understand the bit buffer, element by element. If for some reason | |
| 2541 * the bit pointer points to a place after the message limit, the | |
| 2542 * encoding action is not trustworthy. Nevertheless CCD reports a | |
| 2543 * WARNING and not error. | |
| 2544 * In development phase it is helpful to detect such cases. | |
| 2545 * Otherwise the caller can supposedly still use the message. | |
| 2546 */ | |
| 2547 if (globs->bitpos > globs->buflen) | |
| 2548 { | |
| 2549 ccd_recordFault (globs, ERR_MSG_LEN, CONTINUE, mcompRef, NULL); | |
| 2550 } | |
| 2551 /* | |
| 2552 * Seek for GSM extensions with types T, TV and TLV. | |
| 2553 * (GRR, RCM/RRC and RRLP assume other extension mechanisms.) | |
| 2554 * Check only at octet border. | |
| 2555 */ | |
| 2556 else if ((globs->SeekTLVExt) && !globs->byteoffs) | |
| 2557 { | |
| 2558 SeekForGSMExtensions (entity, globs); | |
| 2559 } | |
| 2560 } | |
| 2561 | |
| 2562 | |
| 2563 #ifdef DEBUG_CCD | |
| 2564 TRACE_CCD (globs, "CCD-ERROR = %d", globs->CCD_Error); | |
| 2565 TRACE_CCD (globs, "-------------------------------------------------"); | |
| 2566 #endif /* DEBUG_CCD */ | |
| 2567 | |
| 2568 ccd_FreeGlobVars (globs); | |
| 2569 ccd_err_free (eentry); | |
| 2570 | |
| 2571 return (BYTE) globs->CCD_Error; | |
| 2572 } /* end ccd_decodeMsg () */ | |
| 2573 #endif /* !RUN_FLASH */ | |
| 2574 | |
| 2575 #ifndef RUN_FLASH | |
| 2576 /* | |
| 2577 +--------------------------------------------------------------------+ | |
| 2578 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2579 | STATE : code ROUTINE : ccd_decodeMsgPtr | | |
| 2580 +--------------------------------------------------------------------+ | |
| 2581 | |
| 2582 | |
| 2583 PARAMETERS: U8 entity | |
| 2584 - specifies the calling entity of CCD. The Constants | |
| 2585 for each valid entity is defined in MCONST.CDG | |
| 2586 | |
| 2587 U8 direction | |
| 2588 - specifies wether the message goes UPLINK or DOWNLINK. | |
| 2589 This is nessesary because there are same PDU-Type | |
| 2590 codes for different messages. | |
| 2591 | |
| 2592 U16 l_buf | |
| 2593 - Lenght of the bitstrem to be decoded. | |
| 2594 | |
| 2595 U16 o_buf | |
| 2596 - specifies the bitstream buffer of the message. The | |
| 2597 struct contains the l_buf and the o_buf elements. | |
| 2598 These elements specifies the length and offset in bits | |
| 2599 of the bitstream in the T_MSGBUF component buf. | |
| 2600 | |
| 2601 U8 *buf | |
| 2602 - specifies the bitstream buffer of the message. | |
| 2603 | |
| 2604 U8 ** mStructPtr | |
| 2605 - points to the pointer on the C-structure of the | |
| 2606 decoded message. The buffer containing this message | |
| 2607 structure will be allocated by CCD. After decoding | |
| 2608 the first element in the message C-structure contains | |
| 2609 the message (PDU) type as a UBYTE. | |
| 2610 | |
| 2611 U8 mId | |
| 2612 - specifies the PDU-Type of the bitstream. If this | |
| 2613 parameter is not equal 0xff the CCD does not decode | |
| 2614 the pdu-type from the bitstream to decide wich decoding | |
| 2615 rules to select. Normaly this param is set to 0xff. | |
| 2616 | |
| 2617 PURPOSE: Like ccd_decodeMsg, this function decodes a bitstream | |
| 2618 containing a valid TETRA-Message from the Air-Interface | |
| 2619 to a corresponding C-Structure, only this function | |
| 2620 allows the use of pointer types in the C-structure. | |
| 2621 | |
| 2622 */ | |
| 2623 #if defined DYNAMIC_ARRAYS || defined _TOOLS_ | |
| 2624 S8 CCDDATA_PREF(ccd_decodeMsgPtr) (U8 entity, | |
| 2625 U8 direction, | |
| 2626 U16 l_buf, | |
| 2627 U16 o_buf, | |
| 2628 U8* buf, | |
| 2629 U8** mStructPtr, | |
| 2630 U8 mId) | |
| 2631 { | |
| 2632 /* | |
| 2633 * Make a dummy for the DLLs, even if DYNAMIC_ARRAYS is not defined to | |
| 2634 * keep the ccd.def unique | |
| 2635 */ | |
| 2636 #ifndef DYNAMIC_ARRAYS | |
| 2637 return -1; | |
| 2638 } | |
| 2639 #else /* DYNAMIC_ARRAYS */ | |
| 2640 UBYTE theMsgId; | |
| 2641 int jmp_ret; | |
| 2642 U32 msgsize; | |
| 2643 USHORT mcompRef; | |
| 2644 T_CCD_Globs *globs; | |
| 2645 T_CCD_ERR_LIST_HEAD* eentry; | |
| 2646 T_CCD_STORE_LIST* stoentry; | |
| 2647 | |
| 2648 globs = ccd_GetGlobVars (&eentry, &stoentry); | |
| 2649 ccd_common_decode_init(l_buf, o_buf, buf, globs); | |
| 2650 ccd_err_reset (eentry); | |
| 2651 globs->errLabel = 0; | |
| 2652 globs->continue_array = TRUE; | |
| 2653 globs->alloc_head = *mStructPtr = NULL; | |
| 2654 | |
| 2655 #ifdef DEBUG_CCD | |
| 2656 TRACE_CCD( globs, "======================================================"); | |
| 2657 TRACE_CCD( globs, "ccd_decodeMsgPtr: Decoding message with pointer types."); | |
| 2658 ccd_dump_msg(l_buf, o_buf, buf, globs); | |
| 2659 #endif | |
| 2660 | |
| 2661 /* Read the message identifier. */ | |
| 2662 if (mId NEQ 0xff AND mId NEQ 0xfe) | |
| 2663 theMsgId = mId; | |
| 2664 else | |
| 2665 theMsgId = bf_decodeByteNumber ((ULONG) mi_length[entity], globs); | |
| 2666 | |
| 2667 /* Get the entry in mmtx table for this message */ | |
| 2668 mcompRef = ccddata_get_mmtx (entity,theMsgId,direction); | |
| 2669 | |
| 2670 /* Check the validity of the message identifier */ | |
| 2671 if (theMsgId > max_message_id OR mcompRef EQ NO_REF) | |
| 2672 { | |
| 2673 #ifdef ERR_TRC_STK_CCD | |
| 2674 globs->ccd_recurs_level = 255; | |
| 2675 #endif /* ERR_TRC_STK_CCD */ | |
| 2676 ccd_setError (globs, ERR_INVALID_MID, BREAK, (USHORT) theMsgId, (USHORT) -1); | |
| 2677 ccd_FreeGlobVars (globs); | |
| 2678 ccd_err_free (eentry); | |
| 2679 return (BYTE) globs->CCD_Error; | |
| 2680 } | |
| 2681 | |
| 2682 #ifdef ERR_TRC_STK_CCD | |
| 2683 /* save the value for tracing in error case */ | |
| 2684 globs->error_stack[0] = mcompRef; | |
| 2685 #endif /* ERR_TRC_STK_CCD */ | |
| 2686 | |
| 2687 #ifdef DEBUG_CCD | |
| 2688 #ifdef CCD_SYMBOLS | |
| 2689 TRACE_CCD (globs, "CCD decode: Message = %s", | |
| 2690 mcomp[mcompRef].name); | |
| 2691 #else | |
| 2692 TRACE_CCD (globs, "CCD decode: MessageId = %x", theMsgId); | |
| 2693 #endif | |
| 2694 #endif | |
| 2695 | |
| 2696 /* | |
| 2697 * Setup the structure-buffer. | |
| 2698 * Make a first simple estimation of much memory to allocate. | |
| 2699 * It is twice as much as the air interface message, rounded up | |
| 2700 * to the nearest kilobyte boundary. | |
| 2701 */ | |
| 2702 msgsize = mcomp[mcompRef].cSize; | |
| 2703 | |
| 2704 #ifdef DEBUG_CCD | |
| 2705 TRACE_CCD( globs, "Allocating %ld bytes for msg.", msgsize); | |
| 2706 #endif | |
| 2707 | |
| 2708 globs->alloc_head = (U8 *) DRP_ALLOC(msgsize, DP_NO_FRAME_GUESS); | |
| 2709 | |
| 2710 if (globs->alloc_head == NULL) | |
| 2711 { | |
| 2712 ccd_setError (globs, ERR_NO_MEM, BREAK, (USHORT) theMsgId, (USHORT) -1); | |
| 2713 ccd_FreeGlobVars (globs); | |
| 2714 ccd_err_free (eentry); | |
| 2715 return (BYTE) globs->CCD_Error; | |
| 2716 } | |
| 2717 *mStructPtr = globs->alloc_head; | |
| 2718 globs->pstruct = globs->alloc_head; | |
| 2719 globs->pstructOffs = 0; | |
| 2720 | |
| 2721 /*Write the MSG ID in the buffer*/ | |
| 2722 globs->pstruct[0] = theMsgId; | |
| 2723 | |
| 2724 /* | |
| 2725 * Clean up the entite C-structure before decoding. | |
| 2726 * Do not overwrite the MsgId (1. Byte) | |
| 2727 */ | |
| 2728 #ifdef DEBUG_CCD | |
| 2729 TRACE_CCD (globs, "CCD Cleaning struct %ld bytes", mcomp[mcompRef].cSize); | |
| 2730 #endif | |
| 2731 memset ((U8 *)globs->pstruct, 0, (size_t)(msgsize)); | |
| 2732 | |
| 2733 /* | |
| 2734 * Write the message identifier into the C-structure. | |
| 2735 */ | |
| 2736 globs->pstruct[0] = theMsgId; | |
| 2737 | |
| 2738 /* | |
| 2739 * clear the UPN stack | |
| 2740 */ | |
| 2741 ST_CLEAR(globs); | |
| 2742 memset ((ULONG *) &(globs->KeepReg[0]), 0, MAX_KEEP_REG_SIZE); | |
| 2743 | |
| 2744 /* | |
| 2745 * inform the GSM-CODEC about the begin of a new message | |
| 2746 */ | |
| 2747 cdc_GSM_start (globs); | |
| 2748 | |
| 2749 jmp_ret = setjmp (globs->jmp_mark); | |
| 2750 | |
| 2751 if (jmp_ret EQ 0) | |
| 2752 { | |
| 2753 globs->jmp_mark_set = TRUE; | |
| 2754 ccd_decodeComposition ((ULONG) mcompRef, globs); | |
| 2755 if (globs->byteoffs NEQ 0) | |
| 2756 { | |
| 2757 bf_incBitpos (8-globs->byteoffs, globs); | |
| 2758 | |
| 2759 /* There are more bits to be decoded than ccddata expects. | |
| 2760 * The additional bits may belong to unknown non-critical extensions. | |
| 2761 */ | |
| 2762 if (globs->bitpos > globs->buflen) | |
| 2763 { | |
| 2764 ccd_recordFault (globs, ERR_UNEXPECT_PAD, CONTINUE, mcompRef, NULL); | |
| 2765 } | |
| 2766 /* | |
| 2767 * Seek for GSM extensions with types T, TV and TLV. | |
| 2768 * (GRR, RCM/RRC and RRLP assume other extension mechanisms.) | |
| 2769 * Check only at octet border. | |
| 2770 */ | |
| 2771 else if ((entity != aim_rrc_rcm) | |
| 2772 && (entity != aim_rrlp) | |
| 2773 && (globs->SeekTLVExt) | |
| 2774 && !globs->byteoffs) | |
| 2775 { | |
| 2776 SeekForGSMExtensions (entity, globs); | |
| 2777 } | |
| 2778 } | |
| 2779 else | |
| 2780 { | |
| 2781 if (globs->bitpos > globs->buflen) | |
| 2782 { | |
| 2783 ccd_recordFault (globs, ERR_MSG_LEN, CONTINUE, mcompRef, NULL); | |
| 2784 } | |
| 2785 /* | |
| 2786 * Seek for GSM extensions with types T, TV and TLV. | |
| 2787 * (GRR, RCM/RRC and RRLP assume other extension mechanisms.) | |
| 2788 * Check only at octet border. | |
| 2789 */ | |
| 2790 else if ((entity != aim_rrc_rcm) | |
| 2791 && (entity != aim_rrlp) | |
| 2792 && (globs->SeekTLVExt) | |
| 2793 && !globs->byteoffs) | |
| 2794 { | |
| 2795 SeekForGSMExtensions (entity, globs); | |
| 2796 } | |
| 2797 } | |
| 2798 } | |
| 2799 | |
| 2800 #ifdef DEBUG_CCD | |
| 2801 TRACE_CCD (globs, "CCD-ERROR = %d", globs->CCD_Error); | |
| 2802 TRACE_CCD (globs, "-----------------------------------------------------"); | |
| 2803 #endif /* DEBUG_CCD */ | |
| 2804 | |
| 2805 ccd_FreeGlobVars (globs); | |
| 2806 ccd_err_free (eentry); | |
| 2807 | |
| 2808 return (BYTE) globs->CCD_Error; | |
| 2809 } /* end ccd_decodeMsgPtr () */ | |
| 2810 #endif /* !DYNAMIC_ARRAYS */ | |
| 2811 #endif /* DYNAMIC_ARRAYS || _TOOLS_ */ | |
| 2812 #endif /* !RUN_FLASH */ | |
| 2813 | |
| 2814 #ifndef RUN_FLASH | |
| 2815 /* | |
| 2816 +--------------------------------------------------------------------+ | |
| 2817 | PROJECT : CCD (6144) MODULE : CCD | | |
| 2818 | STATE : code ROUTINE : ccd_codeMsgPtr | | |
| 2819 +--------------------------------------------------------------------+ | |
| 2820 | |
| 2821 PARAMETERS: UBYTE entity | |
| 2822 - specifies the calling entity of CCD. The Constants | |
| 2823 for each valid entity is defined in MCONST.CDG | |
| 2824 | |
| 2825 UBYTE direction | |
| 2826 - specifies wether the message goes UPLINK or DOWNLINK. | |
| 2827 This is nessesary because there are same PDU-Type | |
| 2828 codes for different messages. | |
| 2829 | |
| 2830 T_MSGBUF * mBuf | |
| 2831 - specifies the bitstream buffer of the message. The | |
| 2832 struct contains the l_buf and the o_buf elements. | |
| 2833 These elements specifies the length and offset in bits | |
| 2834 of the bitstream in the T_MSGBUF component buf. | |
| 2835 The o_buf component must be specified by the caller, | |
| 2836 the l_buf component is calculated by CCD. | |
| 2837 | |
| 2838 UBYTE * mStruct | |
| 2839 - reference to the C-Structure containing the | |
| 2840 C-Representation of the decoded message. | |
| 2841 The type should be casted to UBYTE*. If this parameter | |
| 2842 is NULL CCD uses his internal buffer wich must be | |
| 2843 protected via ccd_begin() in a multithread environment. | |
| 2844 | |
| 2845 UBYTE mId | |
| 2846 - specifies the PDU-Type of the bitstream. If this | |
| 2847 parameter is not equal 0xff the CCD does not read | |
| 2848 the pdu-type from the structure component pt | |
| 2849 to decide wich decoding rules to select. | |
| 2850 Normaly this param is set to 0xff. | |
| 2851 | |
| 2852 PURPOSE: encodes a C-Structure containing the C-Representation of | |
| 2853 a valid Air-interface message to a bitstream. | |
| 2854 | |
| 2855 */ | |
| 2856 | |
| 2857 S8 CCDDATA_PREF(ccd_codeMsgPtr)(U8 entity, | |
| 2858 U8 direction, | |
| 2859 U16* l_buf, | |
| 2860 U16 o_buf, | |
| 2861 U8 *buf, | |
| 2862 U8* mStruct, | |
| 2863 U8 mId) | |
| 2864 { | |
| 2865 UBYTE theMsgId; | |
| 2866 int jmp_ret; | |
| 2867 USHORT maxBytes, mcompRef; | |
| 2868 T_CCD_Globs *globs; | |
| 2869 T_CCD_ERR_LIST_HEAD* eentry; | |
| 2870 T_CCD_STORE_LIST* stoentry; | |
| 2871 | |
| 2872 globs = ccd_GetGlobVars (&eentry, &stoentry); | |
| 2873 ccd_err_reset (eentry); | |
| 2874 | |
| 2875 #if defined (DEBUG_CCD) | |
| 2876 { | |
| 2877 /* to avoid the vsprintf if the traces won't appear anyhow */ | |
| 2878 ULONG mask; | |
| 2879 if (vsi_gettracemask (globs->me, globs->me, &mask) != VSI_ERROR) | |
| 2880 { | |
| 2881 globs->TraceIt = mask & TC_CCD; | |
| 2882 } | |
| 2883 } | |
| 2884 #endif | |
| 2885 | |
| 2886 /* | |
| 2887 * Set a sign that no call to setjmp() is done. So ccd_setError | |
| 2888 * performs no longjmp in case of an error. | |
| 2889 */ | |
| 2890 globs->jmp_mark_set = FALSE; | |
| 2891 | |
| 2892 /* Setup the bitbuffer. */ | |
| 2893 globs->bitbuf = buf; | |
| 2894 globs->bitpos = 0; | |
| 2895 | |
| 2896 /* and the structure-buffer */ | |
| 2897 globs->pstruct = (mStruct EQ NULL) ? ccd_decMsgBuffer : mStruct; | |
| 2898 globs->pstructOffs = 0; | |
| 2899 | |
| 2900 /* Cleanup the read-caches. */ | |
| 2901 globs->lastbytepos16 = globs->lastbytepos32 = 0xffff; | |
| 2902 | |
| 2903 /* Setup the bitoffset. */ | |
| 2904 globs->bitoffs = o_buf; | |
| 2905 | |
| 2906 | |
| 2907 bf_incBitpos (o_buf, globs); | |
| 2908 | |
| 2909 globs->bitbuf[globs->bytepos] = 0; | |
| 2910 | |
| 2911 globs->ccd_recurs_level = 0; | |
| 2912 | |
| 2913 globs->CCD_Error = ccdOK; | |
| 2914 | |
| 2915 globs->continue_array = TRUE; | |
| 2916 | |
| 2917 if (mId NEQ 0xff AND mId NEQ 0xfe) | |
| 2918 theMsgId = mId; | |
| 2919 else | |
| 2920 { | |
| 2921 theMsgId = globs->pstruct[0]; | |
| 2922 } | |
| 2923 | |
| 2924 mcompRef = ccddata_get_mmtx(entity,theMsgId,direction); | |
| 2925 /* Check the validity of the given message identifier. */ | |
| 2926 if (theMsgId > max_message_id OR mcompRef EQ NO_REF) | |
| 2927 { | |
| 2928 #ifdef ERR_TRC_STK_CCD | |
| 2929 globs->ccd_recurs_level = 255; | |
| 2930 #endif /* ERR_TRC_STK_CCD */ | |
| 2931 ccd_setError (globs, ERR_INVALID_MID, BREAK, (USHORT) theMsgId, (USHORT) -1); | |
| 2932 ccd_FreeGlobVars (globs); | |
| 2933 ccd_err_free (eentry); | |
| 2934 return (BYTE) globs->CCD_Error; | |
| 2935 } | |
| 2936 | |
| 2937 #ifdef ERR_TRC_STK_CCD | |
| 2938 /* save the value for tracing in error case */ | |
| 2939 globs->error_stack[0] = mcompRef; | |
| 2940 #endif /* ERR_TRC_STK_CCD */ | |
| 2941 | |
| 2942 maxBytes = (*l_buf + 7)>>3; | |
| 2943 globs->msgLen = *l_buf; | |
| 2944 | |
| 2945 #ifdef DEBUG_CCD | |
| 2946 TRACE_CCD (globs, "-------------------------------------------------"); | |
| 2947 TRACE_CCD (globs, "CCD: Code Message"); | |
| 2948 TRACE_CCD (globs, "Cleaning %d bits (%d bytes) of the bitstream", | |
| 2949 mcomp[mcompRef].bSize, maxBytes); | |
| 2950 #endif | |
| 2951 | |
| 2952 /* | |
| 2953 * Clean up the bit buffer for the encoded message before encoding. | |
| 2954 */ | |
| 2955 memset ((U8 *) &buf[(o_buf>>3)], 0, (size_t) maxBytes); | |
| 2956 /* Store the length of ereased buffer to support error handling. */ | |
| 2957 globs->buflen = *l_buf; | |
| 2958 | |
| 2959 if (mId EQ 0xff) | |
| 2960 { | |
| 2961 /* Write the message identifier. */ | |
| 2962 bf_writeBits ((U32)mi_length[entity], globs); | |
| 2963 } | |
| 2964 | |
| 2965 #ifdef DEBUG_CCD | |
| 2966 #ifdef CCD_SYMBOLS | |
| 2967 TRACE_CCD (globs, "CCD encode: Message = %s", mcomp[mcompRef].name); | |
| 2968 #else | |
| 2969 TRACE_CCD (globs, "CCD encode: MessageId = %x", theMsgId); | |
| 2970 #endif | |
| 2971 #endif | |
| 2972 | |
| 2973 /* | |
| 2974 * Clear the UPN stack. | |
| 2975 */ | |
| 2976 ST_CLEAR(globs); | |
| 2977 memset ((ULONG *) &(globs->KeepReg[0]), 0, MAX_KEEP_REG_SIZE); | |
| 2978 | |
| 2979 /* | |
| 2980 * Inform the GSM-CODEC about the begin of a new message. | |
| 2981 */ | |
| 2982 cdc_GSM_start (globs); | |
| 2983 | |
| 2984 jmp_ret = setjmp (globs->jmp_mark); | |
| 2985 | |
| 2986 if (jmp_ret EQ 0) | |
| 2987 { | |
| 2988 /* | |
| 2989 * no call to setjmp() done. So ccd_Error performs no longjmp in | |
| 2990 * case of an error | |
| 2991 */ | |
| 2992 globs->jmp_mark_set = TRUE; | |
| 2993 ccd_encodeComposition ((ULONG) mcompRef, globs); | |
| 2994 if (globs->bitpos > o_buf + *l_buf) | |
| 2995 { | |
| 2996 ccd_setError (globs, ERR_BUFFER_OF, CONTINUE, (USHORT) -1); | |
| 2997 } | |
| 2998 bf_writePadBits (globs); | |
| 2999 } | |
| 3000 | |
| 3001 *l_buf = (USHORT) globs->bitpos - (USHORT) o_buf; | |
| 3002 | |
| 3003 #ifdef DEBUG_CCD | |
| 3004 { | |
| 3005 int i, j, buflen; | |
| 3006 char s[64], c[4]; | |
| 3007 | |
| 3008 buflen = (*l_buf + o_buf + 7) >> 3; | |
| 3009 | |
| 3010 TRACE_CCD (globs, "-------------------------------------------------"); | |
| 3011 TRACE_CCD (globs, " After ENCODING: lbuf= %d, obuf= %d", *l_buf, o_buf); | |
| 3012 TRACE_CCD (globs, " Hex dump of encoded message:"); | |
| 3013 | |
| 3014 s[0] = '\0'; | |
| 3015 for (i = o_buf >> 3; i < buflen; i+=16) | |
| 3016 { | |
| 3017 for (j = 0; j < 16; j++) | |
| 3018 { | |
| 3019 if ((i+j) < buflen) | |
| 3020 { | |
| 3021 sprintf(c, " %02x", buf[i+j]); | |
| 3022 strcat (s, c); | |
| 3023 } | |
| 3024 } | |
| 3025 TRACE_CCD (globs, "%s", s); | |
| 3026 s[0] = '\0'; | |
| 3027 } | |
| 3028 } | |
| 3029 #endif | |
| 3030 | |
| 3031 #ifdef DEBUG_CCD | |
| 3032 TRACE_CCD (globs, "CCD-ERROR = %d", globs->CCD_Error); | |
| 3033 TRACE_CCD (globs, "-------------------------------------------------"); | |
| 3034 #endif | |
| 3035 | |
| 3036 ccd_FreeGlobVars (globs); | |
| 3037 ccd_err_free (eentry); | |
| 3038 | |
| 3039 return (BYTE)globs->CCD_Error; | |
| 3040 } | |
| 3041 #endif /* !RUN_FLASH */ | |
| 3042 | |
| 3043 #ifndef RUN_FLASH | |
| 3044 /* | |
| 3045 +--------------------------------------------------------------------+ | |
| 3046 | PROJECT : CCD (6144) MODULE : CCD | | |
| 3047 | STATE : code ROUTINE : ccd_codeMsg | | |
| 3048 +--------------------------------------------------------------------+ | |
| 3049 | |
| 3050 PARAMETERS: UBYTE entity | |
| 3051 - specifies the calling entity of CCD. The Constants | |
| 3052 for each valid entity is defined in MCONST.CDG | |
| 3053 | |
| 3054 UBYTE direction | |
| 3055 - specifies wether the message goes UPLINK or DOWNLINK. | |
| 3056 This is nessesary because there are same PDU-Type | |
| 3057 codes for different messages. | |
| 3058 | |
| 3059 T_MSGBUF * mBuf | |
| 3060 - specifies the bitstream buffer of the message. The | |
| 3061 struct contains the l_buf and the o_buf elements. | |
| 3062 These elements specifies the length and offset in bits | |
| 3063 of the bitstream in the T_MSGBUF component buf. | |
| 3064 The o_buf component must be specified by the caller, | |
| 3065 the l_buf component is calculated by CCD. | |
| 3066 | |
| 3067 UBYTE * mStruct | |
| 3068 - reference to the C-Structure containing the | |
| 3069 C-Representation of the decoded message. | |
| 3070 The type should be casted to UBYTE*. If this parameter | |
| 3071 is NULL CCD uses his internal buffer wich must be | |
| 3072 protected via ccd_begin() in a multithread environment. | |
| 3073 | |
| 3074 UBYTE mId | |
| 3075 - specifies the PDU-Type of the bitstream. If this | |
| 3076 parameter is not equal 0xff the CCD does not read | |
| 3077 the pdu-type from the structure component pt | |
| 3078 to decide wich decoding rules to select. | |
| 3079 Normaly this param is set to 0xff. | |
| 3080 | |
| 3081 PURPOSE: encodes a C-Structure containing the C-Representation of | |
| 3082 a valid Air-interface message to a bitstream. | |
| 3083 | |
| 3084 */ | |
| 3085 | |
| 3086 BYTE CCDDATA_PREF(ccd_codeMsg) (UBYTE entity, | |
| 3087 UBYTE direction, | |
| 3088 T_MSGBUF *mBuf, | |
| 3089 UBYTE *mStruct, | |
| 3090 UBYTE mId) | |
| 3091 { | |
| 3092 return CCDDATA_PREF(ccd_codeMsgPtr) (entity, direction, &mBuf->l_buf, | |
| 3093 mBuf->o_buf, mBuf->buf, mStruct, mId); | |
| 3094 } | |
| 3095 #endif /* !RUN_FLASH */ | |
| 3096 | |
| 3097 #ifndef RUN_FLASH | |
| 3098 /* | |
| 3099 +------------------------------------------------------------------------------ | |
| 3100 | Function : ccd_init_ccddata | |
| 3101 +------------------------------------------------------------------------------ | |
| 3102 | Description : Initialize local tables. | |
| 3103 | | |
| 3104 | Parameters : - | |
| 3105 | | |
| 3106 | Return : ccdOK, ccdWarning, or ccdError depending on the success. | |
| 3107 +------------------------------------------------------------------------------ | |
| 3108 */ | |
| 3109 ULONG CCDDATA_PREF(ccd_init_ccddata) (void) | |
| 3110 { | |
| 3111 const T_CCD_CompTabEntry *msg; | |
| 3112 USHORT mcompRef; | |
| 3113 UBYTE ret, entity, num_of_entities; | |
| 3114 USHORT messageId; | |
| 3115 #ifdef DEBUG_CCD | |
| 3116 T_CCD_Globs *globs = &globs_all; | |
| 3117 #endif | |
| 3118 | |
| 3119 aim_rrc_rcm = (U8)ccddata_get_ccdent ("UMTS_AS_ASN1_MSG"); | |
| 3120 aim_rrlp = (U8)ccddata_get_ccdent ("RRLP_ASN1_MSG"); | |
| 3121 aim_sat = (U8)ccddata_get_ccdent ("SAT"); | |
| 3122 | |
| 3123 mcomp = ccddata_get_mcomp (0); | |
| 3124 mvar = ccddata_get_mvar (0); | |
| 3125 mval = ccddata_get_mval (0); | |
| 3126 melem = ccddata_get_melem (0); | |
| 3127 spare = ccddata_get_spare (0); | |
| 3128 calc = ccddata_get_calc (0); | |
| 3129 calcidx = ccddata_get_calcidx (0); | |
| 3130 | |
| 3131 mi_length = ccddata_get_mi_length(); | |
| 3132 ccd_decMsgBuffer = ALIGN_BUF(ccddata_get_decmsgbuffer()); | |
| 3133 max_message_id = (USHORT) ccddata_get_max_message_id(); | |
| 3134 | |
| 3135 #ifdef CCD_SYMBOLS | |
| 3136 if (!ccddata_mccd_symbols()) | |
| 3137 { | |
| 3138 #ifdef CCD_TEST | |
| 3139 printf ("CCD_SYMBOLS is not set in ccddata\n"); | |
| 3140 #else /* CCD_TEST */ | |
| 3141 vsi_o_assert( VSI_CALLER OS_SYST_ERR, __FILE__, __LINE__, | |
| 3142 "CCD_SYMBOLS is not set in ccddata" ); | |
| 3143 #endif /* CCD_TEST */ | |
| 3144 } | |
| 3145 | |
| 3146 #else /* CCD_SYMBOLS */ | |
| 3147 if (ccddata_mccd_symbols()) | |
| 3148 { | |
| 3149 #ifdef CCD_TEST | |
| 3150 printf ("Undefine CCD_SYMBOLS in ccddata\n"); | |
| 3151 #else /* CCD_TEST */ | |
| 3152 vsi_o_assert( VSI_CALLER OS_SYST_ERR, __FILE__, __LINE__, | |
| 3153 "Undefine CCD_SYMBOLS in ccddata" ); | |
| 3154 #endif /* CCD_TEST */ | |
| 3155 } | |
| 3156 #endif /* CCD_SYMBOLS */ | |
| 3157 | |
| 3158 #ifdef DEBUG_CCD | |
| 3159 /* Only for TRACE_CCD call in ccd_init. */ | |
| 3160 globs->me = 0; | |
| 3161 globs->TraceIt = 1; | |
| 3162 #endif /* DEBUG_CCD */ | |
| 3163 | |
| 3164 num_of_entities = (UBYTE) ccddata_get_num_of_entities(); | |
| 3165 for (entity = 0; entity < num_of_entities; entity++) | |
| 3166 { | |
| 3167 /* | |
| 3168 * Point to the first defined Message, to get the length | |
| 3169 * of the message identifier | |
| 3170 */ | |
| 3171 msg = NULL; | |
| 3172 messageId = 0; | |
| 3173 while (msg EQ NULL AND messageId <= max_message_id) | |
| 3174 { | |
| 3175 /* | |
| 3176 * If there is no UPLINK-decoding, try the DOWNLINK. | |
| 3177 */ | |
| 3178 if ((mcompRef = ccddata_get_mmtx(entity, messageId, UPLINK)) NEQ NO_REF) | |
| 3179 msg = (T_CCD_CompTabEntry *) &mcomp[mcompRef]; | |
| 3180 else | |
| 3181 if ((mcompRef = ccddata_get_mmtx(entity, messageId, DOWNLINK)) NEQ NO_REF) | |
| 3182 msg = (T_CCD_CompTabEntry *) &mcomp[mcompRef]; | |
| 3183 else | |
| 3184 messageId++; | |
| 3185 } | |
| 3186 if (msg NEQ NULL | |
| 3187 AND melem[msg->componentRef].elemType EQ 'V' | |
| 3188 AND melem[msg->componentRef].elemRef NEQ NO_REF) | |
| 3189 { | |
| 3190 /* | |
| 3191 * if there is a message for this layer - get the length | |
| 3192 * of the first element (msg_type or pdu_type) | |
| 3193 */ | |
| 3194 mi_length[entity] =(UBYTE) (mvar[melem[msg->componentRef].elemRef].bSize); | |
| 3195 } | |
| 3196 else | |
| 3197 mi_length[entity] = 0; | |
| 3198 | |
| 3199 #ifdef DEBUG_CCD | |
| 3200 TRACE_CCD (globs, "MI-LEN [ENTITY %d] = %d", entity, mi_length[entity]); | |
| 3201 #endif | |
| 3202 } | |
| 3203 | |
| 3204 /* | |
| 3205 * Register all needed coding/decoding functions in the jump table. | |
| 3206 */ | |
| 3207 ret = cdc_init (codec); | |
| 3208 | |
| 3209 if (ret EQ ccdError) | |
| 3210 return ccdError; | |
| 3211 | |
| 3212 #ifdef DEBUG_CCD | |
| 3213 if (ret EQ ccdWarning) | |
| 3214 { | |
| 3215 TRACE_CCD (globs, "CCD: Mismatch between CCD and CCDDATA. Check the codec list.");//return ccdWarning; | |
| 3216 } | |
| 3217 #endif | |
| 3218 | |
| 3219 return ccdOK; | |
| 3220 } | |
| 3221 #endif /* !RUN_FLASH */ | |
| 3222 | |
| 3223 #ifndef RUN_FLASH | |
| 3224 /* | |
| 3225 +------------------------------------------------------------------------------ | |
| 3226 | Function : ccd_signup | |
| 3227 +------------------------------------------------------------------------------ | |
| 3228 | Description : This function sets up the local CCD data for the calling | |
| 3229 | entity. | |
| 3230 | | |
| 3231 | Parameters : ccd_reg - set if called by ccd_register, not set if called | |
| 3232 | by ccd_init | |
| 3233 | decmsgbuf_size - further enhancement: size of the entity's | |
| 3234 | decoded msg buffer size | |
| 3235 | | |
| 3236 | Return : ccdErr or ccdOK depending on the success | |
| 3237 +------------------------------------------------------------------------------ | |
| 3238 */ | |
| 3239 | |
| 3240 static int ccd_signup (int ccd_reg, int decmsgbuf_size) | |
| 3241 { | |
| 3242 #ifndef _TOOLS_ | |
| 3243 UBYTE ret; | |
| 3244 #endif | |
| 3245 #ifdef SHARED_CCD | |
| 3246 T_HANDLE me; | |
| 3247 #else | |
| 3248 int me = 0; | |
| 3249 #endif | |
| 3250 T_CCD_TASK_TABLE* tentry; | |
| 3251 | |
| 3252 #ifdef SHARED_CCD | |
| 3253 me = vsi_e_handle (0, NULL); | |
| 3254 if (me == VSI_ERROR) | |
| 3255 { | |
| 3256 me = 0; | |
| 3257 tentry = ccd_task_list[0] = &task_null; | |
| 3258 task_null.ccd_globs = &globs_all; | |
| 3259 #ifdef DEBUG_CCD | |
| 3260 TRACE_CCD (&globs_all, "Ccd initialization: task could not be identified. Try to continue with a non reentrant init"); | |
| 3261 #endif | |
| 3262 } | |
| 3263 else | |
| 3264 { | |
| 3265 if (!ccd_task_list[me]) | |
| 3266 { | |
| 3267 ccd_task_list[me] = D_ALLOC (sizeof (T_CCD_TASK_TABLE)); | |
| 3268 if (!ccd_task_list[me]) | |
| 3269 { | |
| 3270 vsi_o_assert( VSI_CALLER OS_SYST_ERR, __FILE__, __LINE__, | |
| 3271 "Could not allocate memory for ccd task table entry" ); | |
| 3272 } | |
| 3273 else | |
| 3274 { | |
| 3275 ccd_task_list[me]->ccd_globs = NULL; | |
| 3276 ccd_task_list[me]->ccd_err_list = NULL; | |
| 3277 ccd_task_list[me]->ccd_store = NULL; | |
| 3278 } | |
| 3279 } | |
| 3280 tentry = ccd_task_list[me]; | |
| 3281 tentry->decmsgbuf = NULL; | |
| 3282 if (ccd_reg) | |
| 3283 { | |
| 3284 if (!tentry->ccd_globs) | |
| 3285 { | |
| 3286 if (decmsgbuf_size != CCD_REENTRANT) | |
| 3287 { | |
| 3288 #ifdef DEBUG_CCD | |
| 3289 TRACE_CCD (tentry->ccd_globs, "Ccd_register (task %d): ignore %d for parameter decmsgbuf_size. Make non reentrant ccd_init instead.", me, decmsgbuf_size); | |
| 3290 #endif | |
| 3291 tentry->ccd_globs = &globs_all; | |
| 3292 } | |
| 3293 else | |
| 3294 { | |
| 3295 tentry->ccd_globs = D_ALLOC (sizeof(T_CCD_Globs)); | |
| 3296 if (!tentry->ccd_globs) | |
| 3297 { | |
| 3298 vsi_o_assert( VSI_CALLER OS_SYST_ERR, __FILE__, __LINE__, | |
| 3299 "Could not allocate memory for ccd_globs" ); | |
| 3300 } | |
| 3301 } | |
| 3302 } | |
| 3303 } | |
| 3304 else | |
| 3305 { | |
| 3306 tentry->ccd_globs = &globs_all; | |
| 3307 } | |
| 3308 } | |
| 3309 #else /* SHARED_CCD */ | |
| 3310 tentry = ccd_task_list[0] = &task_null; | |
| 3311 task_null.ccd_globs = &globs_all; | |
| 3312 #endif | |
| 3313 | |
| 3314 tentry->ccd_globs->me = me; | |
| 3315 if (ccd_err_init (&tentry->ccd_err_list)) | |
| 3316 { | |
| 3317 #ifdef CCD_TEST | |
| 3318 printf ("Cannot initialize error list: out of memory\n"); | |
| 3319 #else /* CCD_TEST */ | |
| 3320 vsi_o_assert( VSI_CALLER OS_SYST_ERR, __FILE__, __LINE__, | |
| 3321 "Cannot initialize error list: out of memory" ); | |
| 3322 #endif /* CCD_TEST */ | |
| 3323 return ccdError; | |
| 3324 } | |
| 3325 | |
| 3326 if (ccd_store_init (&tentry->ccd_store)) | |
| 3327 { | |
| 3328 #ifdef CCD_TEST | |
| 3329 printf ("Cannot initialize store register: out of memory\n"); | |
| 3330 #else /* CCD_TEST */ | |
| 3331 vsi_o_assert( VSI_CALLER OS_SYST_ERR, __FILE__, __LINE__, | |
| 3332 "Cannot initialize store register: out of memory" ); | |
| 3333 #endif /* CCD_TEST */ | |
| 3334 return ccdError; | |
| 3335 } | |
| 3336 | |
| 3337 if (!initialized) | |
| 3338 { | |
| 3339 #ifdef SHARED_CCD | |
| 3340 /* | |
| 3341 * if the CCD is used in a premptive multithreaded system | |
| 3342 * we must create a semaphore for the coding and decoding | |
| 3343 */ | |
| 3344 semCCD_Codec = vsi_s_open (VSI_CALLER "CCD_COD",1); | |
| 3345 semCCD_Buffer = vsi_s_open (VSI_CALLER "CCD_BUF",1); | |
| 3346 | |
| 3347 #endif /* SHARED_CCD */ | |
| 3348 | |
| 3349 #ifndef _TOOLS_ | |
| 3350 ret = (UBYTE)ccd_init_ccddata (); | |
| 3351 if (ret != ccdOK) | |
| 3352 return ret; | |
| 3353 | |
| 3354 #endif /* !_TOOLS_ */ | |
| 3355 initialized = TRUE; | |
| 3356 /* save memory init pattern */ | |
| 3357 mempat = (U8*) CCDDATA_PREF(ccd_get_numFaults ()); | |
| 3358 } | |
| 3359 return ccdOK; | |
| 3360 } | |
| 3361 | |
| 3362 BYTE CCDDATA_PREF(ccd_init) (void) | |
| 3363 { | |
| 3364 return (BYTE) ccd_signup (0, 0); | |
| 3365 } | |
| 3366 | |
| 3367 /* | |
| 3368 +------------------------------------------------------------------------------ | |
| 3369 | Function : ccd_register | |
| 3370 +------------------------------------------------------------------------------ | |
| 3371 | Description : This function sets up the local CCD data for the calling | |
| 3372 | entity. | |
| 3373 | Entities calling this function with a parameter 0 will | |
| 3374 | get an own set of CCD local data, i.e., they don't have to | |
| 3375 | synchronize with other entities to use CCD. | |
| 3376 | | |
| 3377 | Parameters : decmsgbuf_size - further enhancement: size of the entity's | |
| 3378 | decoded msg buffer size | |
| 3379 | | |
| 3380 | Return : ccdErr or ccdOK depending on the success | |
| 3381 +------------------------------------------------------------------------------ | |
| 3382 */ | |
| 3383 | |
| 3384 int ccd_register (int decmsgbuf_size) | |
| 3385 { | |
| 3386 return ccd_signup (1, decmsgbuf_size); | |
| 3387 } | |
| 3388 #endif /* !RUN_FLASH */ | |
| 3389 | |
| 3390 #ifndef RUN_FLASH | |
| 3391 /* | |
| 3392 +--------------------------------------------------------------------+ | |
| 3393 | PROJECT : CCD (6144) MODULE : CCD | | |
| 3394 | STATE : code ROUTINE : ccd_exit | | |
| 3395 +--------------------------------------------------------------------+ | |
| 3396 | |
| 3397 PURPOSE: performs a shutdown of CCD. | |
| 3398 | |
| 3399 */ | |
| 3400 | |
| 3401 int CCDDATA_PREF(ccd_exit) (void) | |
| 3402 { | |
| 3403 #ifdef SHARED_CCD | |
| 3404 T_CCD_TASK_TABLE* tentry; | |
| 3405 T_HANDLE me = vsi_e_handle (0, NULL); | |
| 3406 if (me == VSI_ERROR) | |
| 3407 return ccdError; | |
| 3408 tentry = ccd_task_list[me]; | |
| 3409 if (tentry->ccd_globs && (tentry->ccd_globs != &globs_all)) | |
| 3410 { | |
| 3411 D_FREE (tentry->ccd_globs); | |
| 3412 tentry->ccd_globs = 0; | |
| 3413 } | |
| 3414 ccd_store_exit(); | |
| 3415 ccd_err_exit (); | |
| 3416 D_FREE (ccd_task_list[me]); | |
| 3417 ccd_task_list[me] = NULL; | |
| 3418 #else | |
| 3419 ccd_store_exit(); | |
| 3420 ccd_err_exit (); | |
| 3421 #endif /* SHARED_CCD */ | |
| 3422 return ccdOK; | |
| 3423 } | |
| 3424 #endif /* !RUN_FLASH */ |
