Skip to content
Snippets Groups Projects
dsl_cpe_control.c 255 KiB
Newer Older
  • Learn to ignore specific revisions
  • Kenneth Johansson's avatar
    Kenneth Johansson committed
    /******************************************************************************
    
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
             Copyright 2016 - 2019 Intel Corporation
             Copyright 2015 - 2016 Lantiq Beteiligungs-GmbH & Co. KG
             Copyright 2009 - 2014 Lantiq Deutschland GmbH
             Copyright 2007 - 2008 Infineon Technologies AG
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    
      For licensing information, see the file 'LICENSE' in the root folder of
      this software module.
    
    ******************************************************************************/
    
    /*
    Includes
    */
    #include "dsl_cpe_control.h"
    #include "dsl_cpe_cli.h"
    #include "dsl_cpe_cli_console.h"
    #include "dsl_cpe_debug.h"
    #include "drv_dsl_cpe_api_ioctl.h"
    #include "dsl_cpe_simulator.h"
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
    #if defined(INCLUDE_DSL_JSON_PARSING) && (INCLUDE_DSL_JSON_PARSING == 1)
    #include "dsl_cpe_status_parser.h"
       #if defined(DSL_DEBUG_TOOL_INTERFACE) || defined(INCLUDE_DSL_CPE_DTI_SUPPORT)
       #include <ifaddrs.h>    /* getifaddrs */
       #include <arpa/inet.h>  /* inet_ntoa */
       #endif
    #endif /* defined(INCLUDE_DSL_JSON_PARSING) && (INCLUDE_DSL_JSON_PARSING == 1) */
    
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    #include <limits.h>
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    
    #if defined (INCLUDE_DSL_CPE_API_DANUBE)
    #include "drv_dsl_cpe_cmv_danube.h"
    #endif
    
    #if defined(INCLUDE_DSL_CPE_DTI_SUPPORT)
    #include "dsl_cpe_dti.h"
    #endif
    
    #if defined (INCLUDE_DSL_CPE_API_VRX)
    #include "dsl_cpe_bnd_vrx.h"
    #endif
    
    #define DSL_CPE_STATIC static
    
    #include "dsl_cpe_init_cfg.h"
    
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
    #if defined(INCLUDE_DSL_JSON_PARSING) && (INCLUDE_DSL_JSON_PARSING == 1)
    #include "dsl_cpe_configuration_parser.h"
    #endif /* defined(INCLUDE_DSL_JSON_PARSING) && (INCLUDE_DSL_JSON_PARSING == 1) */
    
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    #undef DSL_CCA_DBG_BLOCK
    #define DSL_CCA_DBG_BLOCK DSL_CCA_DBG_APP
    
    #ifdef LINUX
    struct termios stored_stdout_settings;
    struct termios stored_stdin_settings;
    #endif /* LINUX */
    
    #ifdef RTEMS
    #ifdef INCLUDE_DSL_DRV_STATIC_LINKED_FIRMWARE
    #include "AmazonSE_310801.h"
    #endif /* INCLUDE_DSL_DRV_STATIC_LINKED_FIRMWARE*/
    DSL_CPE_ThreadCtrl DslMainControl;
    static DSL_int_t errno = 0;
    #endif /*RTEMS*/
    
    DSL_boolean_t bScriptError = DSL_FALSE;
    
    /* the console only works in forground mode, so no daemonize ! */
    #ifndef INCLUDE_DSL_API_CONSOLE
    
    #if defined(INCLUDE_TCP_SIMULATOR) && defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)
    DSL_char_t *g_sRemoteTcpServerIp = DSL_NULL;
    #endif /* defined(INCLUDE_TCP_SIMULATOR) && defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)*/
    
    /* 'daemon()' function is not working correctly therefore this feature has been
       disabled here.
       You might use the '&' operator to start the dsl_cpe_control application
       within background */
    #undef USE_DAEMONIZE
    #if 0
    #ifdef __UCLIBC__
    #define UCLIBC_VER ((__UCLIBC_MAJOR__*10000) + (__UCLIBC_MINOR__*100) + __UCLIBC_SUBLEVEL__)
    #if (UCLIBC_VER >= 926)
          /* Older versions of uClibc than our tested version (0.9.26) seams to have
             problems with the daemon function */
    #define USE_DAEMONIZE   1
    #endif
    #else
       /* assume that other libraries will work! */
    /*#define USE_DAEMONIZE   1*/
    #endif /* __UCLIBC__ */
    #endif
    
    #endif /* INCLUDE_DSL_API_CONSOLE */
    
    #if defined(INCLUDE_DSL_CPE_API_VRX)
    DSL_CPE_STATIC  DSL_char_t *sLowLevCfgName = DSL_NULL;
    
    DSL_CPE_STATIC DSL_MultimodeFsmConfigData_t g_MultimodeFsmConfig =
                                                {DSL_FW_TYPE_NA};
    
    DSL_CPE_STATIC DSL_ActivationFsmConfigData_t g_ActivationFsmConfig =
                                                {DSL_ACT_SEQ_STD, DSL_ACT_MODE_NA};
    
    DSL_CPE_STATIC DSL_boolean_t g_RememberFsmConfig =
                                                {DSL_TRUE};
    #endif
    
    DSL_CPE_STATIC DSL_SystemInterfaceConfigData_t g_sSysIfCfg[DSL_MODE_LAST];
    #ifdef INCLUDE_DSL_CPE_CLI_SUPPORT
    DSL_CPE_STATIC  const DSL_CPE_EVT_CodeString_t eventString[] =
    {
       {DSL_EVENT_I_LINE_FAILURES, "DSL_EVENT_I_LINE_FAILURES"},
       {DSL_EVENT_I_DATA_PATH_FAILURES, "DSL_EVENT_I_DATA_PATH_FAILURES"},
       {DSL_EVENT_I_LINE_THRESHOLD_CROSSING, "DSL_EVENT_I_LINE_THRESHOLD_CROSSING"},
       {DSL_EVENT_I_CHANNEL_THRESHOLD_CROSSING, "DSL_EVENT_I_CHANNEL_THRESHOLD_CROSSING"},
       {DSL_EVENT_I_DATA_PATH_THRESHOLD_CROSSING, "DSL_EVENT_I_DATA_PATH_THRESHOLD_CROSSING"},
       {DSL_EVENT_I_RETX_THRESHOLD_CROSSING, "DSL_EVENT_I_RETX_THRESHOLD_CROSSING"},
       {DSL_EVENT_I_CHANNEL_DATARATE_SHIFT_THRESHOLD_CROSSING, "DSL_EVENT_I_CHANNEL_DATARATE_SHIFT_THRESHOLD_CROSSING"},
       {DSL_EVENT_S_LINIT_FAILURE, "DSL_EVENT_S_LINIT_FAILURE"},
       {DSL_EVENT_S_LINE_STATE, "DSL_EVENT_S_LINE_STATE"},
       {DSL_EVENT_S_LINE_POWERMANAGEMENT_STATE, "DSL_EVENT_S_LINE_POWERMANAGEMENT_STATE"},
       {DSL_EVENT_S_CHANNEL_DATARATE, "DSL_EVENT_S_CHANNEL_DATARATE"},
       {DSL_EVENT_S_FIRMWARE_ERROR, "DSL_EVENT_S_FIRMWARE_ERROR"},
       {DSL_EVENT_S_INIT_READY, "DSL_EVENT_S_INIT_READY"},
       {DSL_EVENT_S_FE_INVENTORY_AVAILABLE, "DSL_EVENT_S_FE_INVENTORY_AVAILABLE"},
       {DSL_EVENT_S_FE_TESTPARAMS_AVAILABLE, "DSL_EVENT_S_FE_TESTPARAMS_AVAILABLE"},
       {DSL_EVENT_S_SYSTEM_STATUS, "DSL_EVENT_S_SYSTEM_STATUS"},
       {DSL_EVENT_S_PM_SYNC, "DSL_EVENT_S_PM_SYNC"},
       {DSL_EVENT_S_LINE_TRANSMISSION_STATUS, "DSL_EVENT_S_LINE_TRANSMISSION_STATUS"},
       {DSL_EVENT_S_SHOWTIME_LOGGING, "DSL_EVENT_S_SHOWTIME_LOGGING"},
       {DSL_EVENT_S_FIRMWARE_REQUEST, "DSL_EVENT_S_FIRMWARE_REQUEST"},
       {DSL_EVENT_S_FIRMWARE_DOWNLOAD_STATUS, "DSL_EVENT_S_FIRMWARE_DOWNLOAD_STATUS"},
       {DSL_EVENT_S_AUTOBOOT_STATUS, "DSL_EVENT_S_AUTOBOOT_STATUS"},
       {DSL_EVENT_S_SNMP_MESSAGE_AVAILABLE, "DSL_EVENT_S_SNMP_MESSAGE_AVAILABLE"},
       {DSL_EVENT_S_SYSTEM_INTERFACE_STATUS, "DSL_EVENT_S_SYSTEM_INTERFACE_STATUS"},
       {DSL_EVENT_LAST, DSL_NULL}
    };
    #endif /* INCLUDE_DSL_CPE_CLI_SUPPORT*/
    
    /*
    local prototypes
    */
    DSL_CPE_STATIC  DSL_void_t DSL_CPE_ArgParse (
       DSL_int32_t argc,
       DSL_char_t * argv[]
    );
    
    DSL_CPE_STATIC DSL_Error_t DSL_CPE_SysIfCfgCheck(
       DSL_int_t nArgs,
       DSL_CPE_ArgElement_t *pArgList
    );
    
    DSL_CPE_STATIC  DSL_void_t DSL_CPE_ArgParseSysIfCfg (
       DSL_char_t * optarg
    );
    
    #ifndef DSL_CPE_DEBUG_DISABLE
    DSL_CPE_STATIC  DSL_void_t DSL_CPE_ArgParseCommonDebugLevel (
       DSL_char_t * optarg
    );
    #endif
    
    DSL_CPE_STATIC  DSL_void_t DSL_CPE_Help (
       DSL_char_t * sApplicationName
    );
    
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
    DSL_CPE_STATIC  DSL_void_t DSL_CPE_Interruption(void);
    
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    DSL_CPE_STATIC  DSL_void_t DSL_CPE_Termination(void);
    
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
    #if defined(INCLUDE_DSL_JSON_PARSING) && (INCLUDE_DSL_JSON_PARSING == 1)
    DSL_CPE_STATIC  DSL_void_t DSL_CPE_Reconfiguration(void);
    #endif /* defined(INCLUDE_DSL_JSON_PARSING) && (INCLUDE_DSL_JSON_PARSING == 1) */
    
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    DSL_CPE_STATIC DSL_Error_t DSL_CPE_FwInfoFromWhatstringGet(
       DSL_char_t *pWhatString,
       DSL_int_t *pFwApplication,
       DSL_uint8_t *nPlatformId
    );
    
    
    DSL_CPE_STATIC  DSL_CPE_Control_Context_t *gDSLContext = DSL_NULL;
    
    #ifndef DSL_CPE_REMOVE_PIPE_SUPPORT
    extern DSL_Error_t DSL_CPE_Pipe_Init (DSL_CPE_Control_Context_t * pContext);
    #ifdef INCLUDE_DSL_RESOURCE_STATISTICS
    extern DSL_Error_t DSL_CPE_Pipe_StaticResourceUsageGet(DSL_uint32_t *pStatResUsage);
    #endif /* INCLUDE_DSL_RESOURCE_STATISTICS*/
    #endif
    
    DSL_char_t *g_sFirmwareName1 = DSL_NULL;
    DSL_FirmwareFeatures_t g_nFwFeatures1 = {DSL_FW_XDSLMODE_CLEANED, DSL_FW_XDSLFEATURE_CLEANED,
       DSL_FW_XDSLFEATURE_CLEANED};
    
    DSL_char_t *g_sFirmwareName2 = DSL_NULL;
    DSL_FirmwareFeatures_t g_nFwFeatures2 = {DSL_FW_XDSLMODE_CLEANED, DSL_FW_XDSLFEATURE_CLEANED,
       DSL_FW_XDSLFEATURE_CLEANED};
    
    #ifdef INCLUDE_SCRIPT_NOTIFICATION
    DSL_char_t *g_sRcScript = DSL_NULL;
    DSL_CPE_STATIC  DSL_boolean_t bScriptWarn = DSL_FALSE;
    #endif
    
    DSL_boolean_t g_bWaitBeforeLinkActivation[DSL_CPE_MAX_DSL_ENTITIES];
    DSL_boolean_t g_bWaitBeforeConfigWrite[DSL_CPE_MAX_DSL_ENTITIES];
    DSL_boolean_t g_bWaitBeforeRestart[DSL_CPE_MAX_DSL_ENTITIES];
    
    static DSL_LineStateValue_t g_nPrevLineState[DSL_CPE_MAX_DSL_ENTITIES];
    
    #ifdef INCLUDE_DSL_CPE_CMV_SCRIPTS_SUPPORT
    #  ifdef INCLUDE_DSL_CPE_FILESYSTEM_SUPPORT
    DSL_char_t *g_sAdslScript = DSL_NULL;
    DSL_char_t *g_sVdslScript = DSL_NULL;
    #  else
    #include "dsl_cpe_autoboot_script_adsl.h"
    DSL_char_t *g_sAdslScript = g_sAdslScript_static;
    #if defined(INCLUDE_DSL_CPE_API_VRX)
    #include "dsl_cpe_autoboot_script_vdsl.h"
    DSL_char_t *g_sVdslScript = g_sVdslScript_static;
    #else
    DSL_char_t *g_sVdslScript = DSL_NULL;
    #endif /* defined(INCLUDE_DSL_CPE_API_VRX)*/
    #   endif /* INCLUDE_DSL_CPE_FILESYSTEM_SUPPORT*/
    DSL_boolean_t g_bAutoContinueWaitBeforeLinkActivation[DSL_CPE_MAX_DSL_ENTITIES];
    DSL_boolean_t g_bAutoContinueWaitBeforeConfigWrite[DSL_CPE_MAX_DSL_ENTITIES];
    DSL_boolean_t g_bAutoContinueWaitBeforeRestart[DSL_CPE_MAX_DSL_ENTITIES];
    #endif /* INCLUDE_DSL_CPE_CMV_SCRIPTS_SUPPORT*/
    
    /*
    local variables
    */
    DSL_CPE_STATIC  DSL_int32_t bHelp = -1;
    DSL_CPE_STATIC  DSL_int32_t bGetVersion = -1;
    DSL_CPE_STATIC  DSL_int32_t bInit = -1;
    DSL_CPE_STATIC  DSL_int32_t bXtuOctets = -1;
    
    /* Events and resource handling is enabled for all available types by default! */
    DSL_CPE_STATIC  DSL_boolean_t bEventActivation = DSL_TRUE;
    DSL_CPE_STATIC  DSL_uint32_t nResourceActivationMask = 0x00000000;
    
    #if defined (INCLUDE_DSL_CPE_API_DANUBE) && !defined(RTEMS)
       DSL_int32_t bOptimize = 1;
    #else
       DSL_int32_t bOptimize = -1;
    #endif /* defined (INCLUDE_DSL_CPE_API_DANUBE)*/
    
    #if defined(RTEMS)
    DSL_CPE_STATIC  DSL_int32_t bMsgDump = 1;
    #else
    DSL_CPE_STATIC  DSL_int32_t bMsgDump = -1;
    #endif /* defined(RTEMS)*/
    
    #ifndef DSL_CPE_DEBUG_DISABLE
    DSL_CPE_STATIC  DSL_int32_t  g_bDebugLevelApp = -1;
    DSL_CPE_STATIC  DSL_uint32_t g_nDebugLevelApp = 0;
    DSL_CPE_STATIC  DSL_int32_t  g_bDebugLevelDrv = -1;
    DSL_CPE_STATIC  DSL_uint32_t g_nDebugLevelDrv = 0;
    #endif /* #ifndef DSL_CPE_DEBUG_DISABLE*/
    
    #ifdef DSL_DEBUG_TOOL_INTERFACE
    DSL_CPE_STATIC  DSL_int32_t bTcpMessageIntf = -1;
    #endif
    
    #ifdef INCLUDE_DSL_CPE_DTI_SUPPORT
    DSL_CPE_STATIC  DSL_int32_t bDTI = -1;
    #endif
    
    #ifdef USE_DAEMONIZE
    DSL_CPE_STATIC  DSL_int_t bNotSilent = 1;
    #endif /* USE_DAEMONIZE */
    
    #ifdef INCLUDE_DSL_CPE_CLI_SUPPORT
    DSL_CPE_STATIC  DSL_int32_t bConsole = -1;
    DSL_CPE_Console_Context_t *pConsoleContext = DSL_NULL;
    #endif
    
    DSL_CPE_STATIC  DSL_int_t g_bFirmware1 = -1;
    DSL_CPE_STATIC  DSL_int_t g_bFirmware2 = -1;
    
    DSL_CPE_STATIC  DSL_G997_XTUSystemEnablingData_t g_nXtseInit;
    DSL_CPE_STATIC  DSL_uint8_t g_nMsgDumpDbgLvl;
    
    #ifndef DSL_CPE_DEBUG_DISABLE
    
    #define MAX_DBG_MOD_PAIRS     10
    DSL_CPE_STATIC DSL_DBG_ModuleLevelData_t g_nDbgDrvLevel[MAX_DBG_MOD_PAIRS] = {{0,0}};
    DSL_CPE_STATIC DSL_DBG_ModuleLevelData_t g_nDbgAppLevel[MAX_DBG_MOD_PAIRS] = {{0,0}};
    
    #endif /*DSL_CPE_DEBUG_DISABLE*/
    
    #ifdef INCLUDE_DSL_CPE_CLI_SUPPORT
    typedef struct
    {
       /** reference to registered CLI */
       DSL_CLI_Context_t *pCLIContext;
       /** running status of pipe task */
       volatile DSL_boolean_t bRun;
    } dummy_console_t;
    
    DSL_CPE_STATIC  dummy_console_t dummy_console;
    
    DSL_CPE_STATIC  DSL_Error_t DSL_CPE_Control_Exit (DSL_void_t * pContext);
    #endif
    
    #ifdef LINUX
    #if defined (INCLUDE_DSL_CPE_API_DANUBE)
       #define DSL_CPE_DEFAULT_FIRMWARE_1  "/opt/lantiq/firmware/ModemHWE.bin"
       #define DSL_CPE_DEFAULT_FIRMWARE_2  ""
    #elif defined(INCLUDE_DSL_CPE_API_VRX)
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
       #define DSL_CPE_DEFAULT_FIRMWARE_1  "/lib/firmware/xcpe_hw.bin"
       #define DSL_CPE_DEFAULT_FIRMWARE_2  "/lib/firmware/xcpe_hw_2p.bin"
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    #endif
    #elif defined(VXWORKS)
    #if defined (INCLUDE_DSL_CPE_API_DANUBE)
       #define DSL_CPE_DEFAULT_FIRMWARE_1  "modemhwe.bin"
       #define DSL_CPE_DEFAULT_FIRMWARE_2  ""
    #elif defined(INCLUDE_DSL_CPE_API_VRX)
       #define DSL_CPE_DEFAULT_FIRMWARE_1  "xcpe_hw.bin"
       #define DSL_CPE_DEFAULT_FIRMWARE_2  "xcpe_hw_2p.bin"
    #endif
    #elif defined(RTEMS)
       #define DSL_CPE_DEFAULT_FIRMWARE_1  "cgi_pFileData_modemfw_bin"
       #define DSL_CPE_DEFAULT_FIRMWARE_2  ""
    #elif defined(WIN32)
    #if defined (INCLUDE_DSL_CPE_API_DANUBE)
       #define DSL_CPE_DEFAULT_FIRMWARE_1  "..\\firmware\\modemhwe.bin"
       #define DSL_CPE_DEFAULT_FIRMWARE_2  ""
    #elif defined(INCLUDE_DSL_CPE_API_VRX)
       #define DSL_CPE_DEFAULT_FIRMWARE_1  "..\\firmware\\xcpe_hw.bin"
       #define DSL_CPE_DEFAULT_FIRMWARE_2  "..\\firmware\\xcpe_hw_2.bin"
    #endif
    #else
       #define DSL_CPE_DEFAULT_FIRMWARE_1  ""
       #define DSL_CPE_DEFAULT_FIRMWARE_2  ""
    #endif
    
    const DSL_char_t *sDefaultFirmwareName1 = (DSL_char_t *)DSL_CPE_DEFAULT_FIRMWARE_1;
    const DSL_char_t *sDefaultFirmwareName2 = (DSL_char_t *)DSL_CPE_DEFAULT_FIRMWARE_2;
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
    const DSL_uint8_t g_nDefaultFWDownloadTimeoutSec = 10;
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
    
    #ifdef INCLUDE_SCRIPT_NOTIFICATION
       #if defined (INCLUDE_DSL_CPE_API_DANUBE)
          #define DSL_CPE_DEFAULT_RC_SCRIPT "./adslrc.sh"
       #else
          #define DSL_CPE_DEFAULT_RC_SCRIPT "./xdslrc.sh"
       #endif
       const DSL_char_t *sDefaultRcScript = DSL_CPE_DEFAULT_RC_SCRIPT;
    #endif
    
    #ifdef DSL_DEBUG_TOOL_INTERFACE
    DSL_char_t *g_sTcpMessagesSocketAddr = DSL_NULL;
    DSL_uint16_t g_nTcpMessagesSocketPort = 0;
    DSL_boolean_t g_bEnableTcpCli = DSL_FALSE;
    #endif
    
    #ifdef INCLUDE_DSL_CPE_DTI_SUPPORT
    DSL_char_t *sDtiSocketAddr = DSL_NULL;
    #endif
    
    
    DSL_uint8_t g_nDevices = 1;
    DSL_uint8_t g_nLines = 1;
    DSL_uint8_t g_nChannels = 1;
    
    /*DSL_InitData_t gInitCfgData;*/
    
    
    DSL_CPE_STATIC  struct option long_options[] = {
       {"help      ", 0, 0, 'h'},
       {"version   ", 0, 0, 'v'},
       {"init      ", 1, 0, 'i'},
    #if defined(INCLUDE_DSL_CPE_API_VRX)
       #if (DSL_CPE_MAX_DSL_ENTITIES > 1) && defined(INCLUDE_DSL_CPE_CLI_SUPPORT)
       {"backward  ", 0, 0, 'b'},
       #endif /* (DSL_CPE_MAX_DSL_ENTITIES > 1) && defined(INCLUDE_DSL_CPE_CLI_SUPPORT)*/
       {"low_cfg   ", 1, 0, 'l'},
    #endif
    #ifdef INCLUDE_DSL_CPE_CLI_SUPPORT
       {"console   ", 0, 0, 'c'},
    #endif
       {"event_cnf ", 1, 0, 'e'},
       {"msg_dump  ", 1, 0, 'm'},
    #ifndef DSL_CPE_DEBUG_DISABLE
       {"dbg_level ", 1, 0, 'D'},
    #endif /* #ifndef DSL_CPE_DEBUG_DISABLE*/
    #ifdef INCLUDE_DSL_CPE_FILESYSTEM_SUPPORT
    #ifdef INCLUDE_DSL_CPE_CMV_SCRIPTS_SUPPORT
       {"auto_scr_1", 1, 0, 'a'},
    #if defined(INCLUDE_DSL_CPE_API_VRX)
       {"auto_scr_2", 1, 0, 'A'},
    #endif
    #endif
    #endif
    #ifdef USE_DAEMONIZE
       {"silent    ", 0, 0, 'q'},
    #endif /* USE_DAEMONIZE */
       {"firmware1 ", 1, 0, 'f'},
       {"firmware2 ", 1, 0, 'F'}, /*TODO: fail if not ocb */
    #if defined (INCLUDE_DSL_CPE_API_DANUBE)
       {"opt_off   ", 1, 0, 'o'},
    #endif
    #ifdef INCLUDE_SCRIPT_NOTIFICATION
       {"notif     ", 1, 0, 'n'},
    #endif
    #if defined(INCLUDE_TCP_SIMULATOR) && defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)
       {"remoteTcp ", 1, 0, 'r'},
    #endif /* defined(INCLUDE_TCP_SIMULATOR) && defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)*/
    #ifdef DSL_DEBUG_TOOL_INTERFACE
       {"tcpmsg    ", 1, 0, 't'},
    #endif
    #if defined(INCLUDE_DSL_CPE_DTI_SUPPORT)
       {"dti       ", 1, 0, 'd'},
    #endif /* defined(INCLUDE_DSL_CPE_DTI_SUPPORT)*/
    #ifdef INCLUDE_DSL_CPE_API_VRX
       {"multimode ", 1, 0, 'M'},
    #endif
       {"tc-layer  ", 1, 0, 'T'},
    #ifdef INCLUDE_DSL_CPE_API_VRX
       {"sequence  ", 1, 0, 'S'},
       {"remember  ", 1, 0, 'R'},
    #endif
    #ifndef DSL_CPE_DEBUG_DISABLE
       {"debug_drv ", 1, 0, 'g'},
       {"debug_app ", 1, 0, 'G'},
    #endif
       {"devices   ", 1, 0, 'V'},
       {"lines     ", 1, 0, 'L'},
       {"channels  ", 1, 0, 'C'},
       {0, 0, 0, 0}
    };
    
    /* 1 colon means there is a required parameter */
    /* 2 colons means there is an optional parameter */
    DSL_CPE_STATIC  const DSL_char_t GETOPT_LONG_OPTSTRING[] = "hvi::"
    #if defined(INCLUDE_DSL_CPE_API_VRX)
       #if (DSL_CPE_MAX_DSL_ENTITIES > 1) && defined(INCLUDE_DSL_CPE_CLI_SUPPORT)
       "b"
       #endif /* (DSL_CPE_MAX_DSL_ENTITIES > 1) && defined(INCLUDE_DSL_CPE_CLI_SUPPORT)*/
       "l:"
    #endif
    #ifdef INCLUDE_DSL_CPE_CLI_SUPPORT
       "c"
    #endif
       "e:m::"
    #ifndef DSL_CPE_DEBUG_DISABLE
       "D:"
    #endif /* #ifndef DSL_CPE_DEBUG_DISABLE*/
    #ifdef INCLUDE_DSL_CPE_FILESYSTEM_SUPPORT
    #ifdef INCLUDE_DSL_CPE_CMV_SCRIPTS_SUPPORT
       "a:"
    #if defined(INCLUDE_DSL_CPE_API_VRX)
       "A:"
    #endif /* defined(INCLUDE_DSL_CPE_API_VRX)*/
    #endif
    #endif
    #ifdef USE_DAEMONIZE
       "q"
    #endif
       "f:"
       "F:"
    #if defined (INCLUDE_DSL_CPE_API_DANUBE)
       "o"
    #endif
    #ifdef INCLUDE_SCRIPT_NOTIFICATION
       "n:"
    #endif
    #if defined(INCLUDE_TCP_SIMULATOR) && defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)
       "r:"
    #endif /* defined(INCLUDE_TCP_SIMULATOR) && defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)*/
    #ifdef DSL_DEBUG_TOOL_INTERFACE
       "t::"
    #endif
    #ifdef INCLUDE_DSL_CPE_DTI_SUPPORT
       "d::"
    #endif
    #ifdef INCLUDE_DSL_CPE_API_VRX
       "M:"
    #endif
       "T:"
    #ifdef INCLUDE_DSL_CPE_API_VRX
       "S:R:"
    #endif
    #ifndef DSL_CPE_DEBUG_DISABLE
       "g::G::"
    #endif /* #ifndef DSL_CPE_DEBUG_DISABLE*/
       "V:"
       "L:"
       "C:"
       ;
    
    /*lint -save -e786 */ \
    DSL_CPE_STATIC  DSL_char_t description[][105] = {
       {"help screen"},
       {"display version"},
       {"init device w/ <xtu> Bits seperated by underscore (e.g. -i05_01_04_00_04_01_00_00)"},
    #if defined(INCLUDE_DSL_CPE_API_VRX)
       #if (DSL_CPE_MAX_DSL_ENTITIES > 1) && defined(INCLUDE_DSL_CPE_CLI_SUPPORT)
       {"CLI backward compatible mode"},
       #endif /*(DSL_CPE_MAX_DSL_ENTITIES > 1)*/
       {"low level configuration file"},
    #endif
    #ifdef INCLUDE_DSL_CPE_CLI_SUPPORT
       {"start console"},
    #endif
       {"configure instance activation handling <enable/disable>[_mask] (e.g. -e1_1)"},
       {"enable message dump"},
    #ifndef DSL_CPE_DEBUG_DISABLE
       {"config debug level -D<app>{_<drv>} (0=NO, 1=LOW, 2=NORMAL, 3=HIGH, 4=OFF), e.g. -D3"},
    #endif /* #ifndef DSL_CPE_DEBUG_DISABLE*/
    #ifdef INCLUDE_DSL_CPE_FILESYSTEM_SUPPORT
    #ifdef INCLUDE_DSL_CPE_CMV_SCRIPTS_SUPPORT
       {"autoboot start script for ADSL (empty by default)"},
    #if defined(INCLUDE_DSL_CPE_API_VRX)
       {"autoboot start script for VDSL (empty by default)"},
    #endif /* defined(INCLUDE_DSL_CPE_API_VRX)*/
    #endif
    #endif
    #ifdef USE_DAEMONIZE
       "silent mode, no output from background",
    #endif
       {"firmware file, default " DSL_CPE_DEFAULT_FIRMWARE_1},
       {"2nd firmware file, default " DSL_CPE_DEFAULT_FIRMWARE_2},
    #if defined (INCLUDE_DSL_CPE_API_DANUBE)
       {"deactivate footprint optimizations"},
    #endif
    #ifdef INCLUDE_SCRIPT_NOTIFICATION
       {"notification script name, default " DSL_CPE_DEFAULT_RC_SCRIPT},
    #endif
    #if defined(INCLUDE_TCP_SIMULATOR) && defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)
       {"remote TCP debug server IP address"},
    #endif /* defined(INCLUDE_TCP_SIMULATOR) && defined(DSL_CPE_SIMULATOR_DRIVER) && defined(WIN32)*/
    #ifdef DSL_DEBUG_TOOL_INTERFACE
       {"enable dbgtool, listen only on <ipaddr> (optional, e.g. -t0.0.0.0)"},
    #endif
    #ifdef INCLUDE_DSL_CPE_DTI_SUPPORT
       {"enable DTI support on default tcp port 9000, listen only on <ipaddr> (optional)"},
    #endif
    #ifdef INCLUDE_DSL_CPE_API_VRX
       {"set multimode config -M<NextMode> (e.g. -M1)"},
       {"config TC-Layer -T<TcA>:<TcCfgUsA>:<TcCfDsA>_<TcV>:<TcCfgUsV>:<TcCfDsV> (e.g. -T1:0x0:0x0_2:0x0:0x0)"},
    #else
       {"config TC-Layer -T<TcA>:<TcCfgUsA>:<TcCfgDsA> (e.g. -T1:0x0:0x0)"},
    #endif
    #ifdef INCLUDE_DSL_CPE_API_VRX
       {"set activation sequence -S<Sequence>_<Mode> (e.g. -S0_0)"},
       {"set remember config -R<Remember> (e.g. -R1)"},
    #endif
    #ifndef DSL_CPE_DEBUG_DISABLE
       {"Driver modules debug level -g<Module>_<Level>{_<Module>_<Level>} e.g. -g1:2_14:FF"},
       {"Application modules debug level -G<Module>_<Level>{_<Module>_<Level>} e.g. -G1:40"},
    #endif /* #ifndef DSL_CPE_DEBUG_DISABLE*/
       {"Number of devices"},
       {"Number of lines per device"},
       {"Number of channels per line"},
       {0}
    };
    
    /*lint -restore */
    
    DSL_CPE_STATIC  const DSL_char_t *dsl_cpe_ctl_version = "@(#)" PACKAGE_VERSION;
    
    DSL_CPE_STATIC DSL_boolean_t DSL_CPE_UpdateLayoutConfiguration()
    {
       DSL_boolean_t ret = DSL_TRUE;
       DSL_CPE_Control_Context_t *pCtrlCtx = DSL_CPE_GetGlobalContext();
    
       if (g_nDevices <= 0 || g_nDevices >2 ||
           g_nLines <= 0 || g_nLines >2     ||
           g_nChannels <= 0 || g_nChannels >2 ||
           g_nDevices * g_nLines > 2)
       {
          printf(DSL_CPE_PREFIX " Invalid device configuration, devices:%d, lines:%d, channels:%d"DSL_CPE_CRLF,
                 g_nDevices, g_nLines, g_nChannels);
          g_nDevices = 1;
          g_nLines = 1;
          g_nChannels = 1;
          return DSL_FALSE;
       }
       if (g_nLines > 1)
          g_RememberFsmConfig = DSL_FALSE;
     if (DSL_CPE_DSL_ENTITIES > 1)
          pCtrlCtx->bBackwardCompMode = DSL_FALSE;
    #ifdef RTEMS
       if (g_nDevices > 1)
       {
          printf(DSL_CPE_PREFIX "No support for DSL_CPE_MAX_DEVICE_NUMBER > 1 under RTEMS!!!" DSL_CPE_CRLF);
          ret = DSL_FALSE;
       }
    #endif
       if (g_nLines * g_nDevices > 1)
       {
    #  ifndef INCLUDE_FW_REQUEST_SUPPORT
         printf(DSL_CPE_PREFIX "Bonding is only supported with the FW request feature!!!"DSL_CPE_CRLF);
          ret = DSL_FALSE;
    #  endif
    #  ifndef INCLUDE_SCRIPT_NOTIFICATION
         printf(DSL_CPE_PREFIX "Bonding is only supported with the Script Notification feature!!!"DSL_CPE_CRLF);
          ret = DSL_FALSE;
    #  endif
       }
       return ret;
    }
    DSL_CPE_Control_Context_t *DSL_CPE_GetGlobalContext (
       DSL_void_t
    )
    {
       if (gDSLContext == DSL_NULL)
       {
          DSL_CCA_DEBUG(DSL_CCA_DBG_ERR, (DSL_CPE_PREFIX
             "ERROR, requesting for global context, which is zero" DSL_CPE_CRLF));
       }
    
       return gDSLContext;
    }
    
    #ifndef DSL_CPE_DEBUG_DISABLE
    DSL_CPE_STATIC DSL_void_t DSL_CPE_DebugInitCommon(DSL_uint32_t dbg_level)
    {
       DSL_CCA_debugLevels_t nCcaDbgLvl = DSL_CCA_DBG_NONE;
       DSL_int_t i = 0;
       DSL_boolean_t bSetLvl = DSL_TRUE;
    
       /* Set common debug level for all application related modules if defined by
          '-D' startup option */
       switch (dbg_level)
       {
          case 0:
             /* Nothing to do */
             bSetLvl = DSL_FALSE;
             break;
          case 1:
             nCcaDbgLvl = DSL_CCA_DBG_MSG;
             break;
          case 2:
             nCcaDbgLvl = DSL_CCA_DBG_WRN;
             break;
          case 3:
             nCcaDbgLvl = DSL_CCA_DBG_ERR;
             break;
          case 4:
             nCcaDbgLvl = DSL_CCA_DBG_NONE;
             break;
          default:
             /* Invalid */
             bSetLvl = DSL_FALSE;
             printf(DSL_CPE_PREFIX
                "Invalid argument (%d) for '-D' option - will be ignored!"
                DSL_CPE_CRLF, dbg_level);
             break;
       }
    
       if (bSetLvl == DSL_TRUE)
       {
          for (i = (DSL_CCA_DBG_NO_BLOCK + 1); i < DSL_CCA_DBG_LAST_BLOCK; ++i)
          {
             DSL_CCA_g_dbgLvl[i].nDbgLvl = nCcaDbgLvl;
          }
       }
    
       return;
    }
    
    DSL_CPE_STATIC DSL_void_t DSL_CPE_DebugInitModule()
    {
       DSL_int_t i = 0;
    
       /* Set debug module specific application debug levels as defined by '-g'
          startup option */
       for (i = 0; (i < MAX_DBG_MOD_PAIRS) && (g_nDbgAppLevel[i].nDbgModule != 0); ++i)
       {
          if (g_nDbgAppLevel[i].nDbgModule >= DSL_CCA_DBG_MAX_ENTRIES)
          {
             continue;
          }
    
          DSL_CCA_g_dbgLvl[g_nDbgAppLevel[i].nDbgModule].nDbgLvl =
             g_nDbgAppLevel[i].nDbgLevel;
       }
    
       return;
    }
    #endif /* #ifndef DSL_CPE_DEBUG_DISABLE*/
    
    void DSL_CPE_Echo (
       DSL_char_t *buf)
    {
       DSL_char_t *str;
       DSL_char_t cmd[64];
    
       if (buf == DSL_NULL)
       {
          return;
       }
    
       /* remove leading whitespaces */
       for (str = buf; str && *str && isspace((int)(*str)); ++str)
       {
          ;
       }
    
       sscanf (str, "%64s", cmd);
    
       if (strcmp (cmd, "echo") == 0)
       {
          str += 4;
       }
       if (str[0] == ' ') str++;
    
       DSL_CPE_FPrintf (DSL_CPE_STDOUT, "%s \n", str);
    
       return;
    }
    
    #ifdef INCLUDE_DSL_CPE_CLI_SUPPORT
    /* Use this to format arrays of unspecified contents as hex values */
    DSL_void_t DSL_CPE_ArraySPrintF(
       DSL_char_t *pDst,
       DSL_void_t *pSrc,
       DSL_uint16_t nSrcSize,
       DSL_uint16_t nSrcElementSize,
       DSL_CPE_ArrayPrintFormat_t nFormat)
    {
       DSL_uint16_t i = 0, j = 0, elements = 0;
       DSL_uint32_t nVal = 0;
       DSL_char_t c;
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
       DSL_int_t ret = 0, counter = 256;
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    
       elements = nSrcSize/nSrcElementSize;
    
       if (nFormat == DSL_ARRAY_FORMAT_HEX)
       {
    
          ret = cpe_control_snprintf_s(pDst, counter, "(");
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
          counter -= ret;
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
          pDst++;
       }
    
       for (i = 0; i < elements; i++)
       {
          if ((i != 0) && (nFormat == DSL_ARRAY_FORMAT_HEX))
          {
    
             ret = cpe_control_snprintf_s(pDst, counter, ",");
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
             counter -= ret;
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
             pDst ++;
          }
    
          if (nFormat == DSL_ARRAY_FORMAT_HEX)
          {
             switch (nSrcElementSize)
             {
             case 1:
    
                ret = cpe_control_snprintf_s(pDst, counter, "%02X",
                                             ((DSL_uint8_t*)pSrc)[i]);
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
                break;
             case 2:
    
                ret = cpe_control_snprintf_s(pDst, counter, "%04X",
                                             ((DSL_uint16_t*)pSrc)[i]);
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
                break;
             case 4:
    
                ret = cpe_control_snprintf_s(pDst, counter, "%08X",
                                             ((DSL_uint32_t*)pSrc)[i]);
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
                break;
             default:
    
                ret = cpe_control_snprintf_s(pDst, counter, "xx");
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
                break;
             }
    
             if(ret > 0)
             {
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
                counter -= ret;
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
                pDst += ret;
             }
          }
          else
          {
             switch (nSrcElementSize)
             {
             case 1:
                nVal = (DSL_uint32_t)(((DSL_uint8_t*)pSrc)[i]);
                break;
             case 2:
                nVal = (DSL_uint32_t)(((DSL_uint16_t*)pSrc)[i]);
                break;
             case 4:
                nVal = (DSL_uint32_t)(((DSL_uint32_t*)pSrc)[i]);
                break;
             default:
                nVal = 0;
                break;
             }
    
             for (j = 0; j < nSrcElementSize; j++)
             {
                c = (DSL_char_t)(nVal >> j);
                if (isprint((int)c) != 0)
                {
    
                   ret = cpe_control_snprintf_s(pDst, counter, "%c", c);
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
                   counter -= ret;
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
                   pDst += ret;
                }
                else
                {
                   if (nFormat == DSL_ARRAY_FORMAT_PRINT_STRING)
                   {
    
                      ret = cpe_control_snprintf_s(pDst, counter, "%c", '.');
    
    Oussama Ghorbel's avatar
    Oussama Ghorbel committed
                      counter -= ret;
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
                      pDst += ret;
                   }
                }
             }
          }
       }
    
       if (nFormat == DSL_ARRAY_FORMAT_HEX)
       {
    
          ret = cpe_control_snprintf_s(pDst, counter, ")");
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
       }
    }
    
    /**
       Parses the given character string for given token and sets the resulting
       pointer to the given offset of tokens within the given string.
    
       \param DSL_char_t *pCommands
          Specifies a string that shall be parsed
       \param DSL_int_t nParamNr
          Specifies the number of tokens that shall be found and of which the
          pointer has to be incresed.
       \param DSL_char_t *pSeps
          Specifies the separators to be srearched for
       \param DSL_char_t *pCmdOffset
          Returns a pointer to the command string including token offset if found
    */
    DSL_Error_t DSL_CPE_MoveCharPtr(
       DSL_char_t *pCommands,
       DSL_int_t nParamNr,
       DSL_char_t *pSeps,
       DSL_char_t **pCmdOffset)
    {
       DSL_Error_t nRet = DSL_SUCCESS;
       DSL_int_t i = 0;
       DSL_char_t *pTmp = DSL_NULL;
    
       pTmp = pCommands;
    
       for (i = 0; i < nParamNr; i++)
       {
          if (pTmp == DSL_NULL) break;
    
          pTmp = strpbrk(pTmp, pSeps);
          if (pTmp != DSL_NULL)
          {
             pTmp++;
          }
          else
          {
             break;
          }
       }
    
       if (i < nParamNr)
       {
          nRet = DSL_ERROR;
          *pCmdOffset = pCommands;
       }
       else
       {
          nRet = DSL_SUCCESS;
          *pCmdOffset = pTmp;
       }
    
       return nRet;
    }
    
    
    #if defined(INCLUDE_DSL_CPE_API_VRX)
    DSL_Error_t DSL_CPE_GetMacAdrFromString(
       DSL_char_t *pString,
       DSL_CPE_MacAddress_t *pMacAdr)
    {
       DSL_Error_t nRet = DSL_SUCCESS;
       DSL_char_t string[20] = { 0 };
       DSL_char_t sMacAddr[3] = {0};
       DSL_char_t seps[] = ":";
       DSL_char_t *token;
       DSL_int_t i = 0;
    
    
    
       cpe_control_strncpy_s(string, sizeof(string)-1,
                             pString, cpe_control_strnlen_s(pString, sizeof(string)-1));
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
       string[sizeof(string)-1] = 0;
    
    
       DSL_size_t strmax = sizeof(string);
       char *pNextToken = DSL_NULL;
    
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
       /* Get first token */
    
       token = cpe_control_strtok_s(string, &strmax, seps, &pNextToken);
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
       if (token != DSL_NULL)
       {
          for (i = 0; i < DSL_MAC_ADDRESS_OCTETS; i++)
          {
             sscanf (token, "%3s", (unsigned char *)sMacAddr);
    
             sscanf (token, "%hhx", (unsigned char *)&(pMacAdr->nAdr[i]));
    
             if ( ((strcmp (&sMacAddr[1], "0") != 0) && ( (pMacAdr->nAdr[i] & 0xF) == 0)) )
             {
                i=0;
                break;
             }
    
             sMacAddr[1] = '\0';
             if ( ((strcmp (&sMacAddr[0], "0") != 0) && ( ((pMacAdr->nAdr[i] >> 4) & 0xF) == 0)) )
             {
                i=0;
                break;
             }
    
             /* Get next token */
    
             token = cpe_control_strtok_s(DSL_NULL, &strmax, seps, &pNextToken);
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    
             /* Exit scanning if no further information is included */
             if (token == DSL_NULL)
             {
                break;
             }
          }
       }
    
       if (i < (DSL_MAC_ADDRESS_OCTETS - 1))
       {
          nRet = DSL_ERROR;
       }
       else
       {
          nRet = DSL_SUCCESS;
       }
    
       return nRet;
    }
    #endif /* defined(INCLUDE_DSL_CPE_API_VRX) */
    #endif /* INCLUDE_DSL_CPE_CLI_SUPPORT */
    
    #ifndef DSL_CPE_DEBUG_DISABLE
    DSL_CPE_STATIC
    DSL_Error_t DSL_CPE_DebugPairExtract(DSL_char_t** argv, DSL_uint_t *module, DSL_uint_t *level)
    {
       DSL_int_t items, symbols;
    
       if ( (argv == NULL) || (*argv == NULL) )
       {
          DSL_CCA_DEBUG(DSL_CCA_DBG_ERR, (DSL_CPE_PREFIX
             "NULL debug pair string." DSL_CPE_CRLF));
          return DSL_ERROR;
       }
    
       items = sscanf(*argv, "%u:%x%n", module, level, &symbols);
    
       if ( items != 2 )
       {
          DSL_CCA_DEBUG(DSL_CCA_DBG_ERR, (DSL_CPE_PREFIX
             "Wrong debug module syntax. %d" DSL_CPE_CRLF, items));
          return DSL_ERROR;
       }
    
       *argv += symbols;
    
       return DSL_SUCCESS;
    }
    #endif /*#ifndef DSL_CPE_DEBUG_DISABLE*/
    
    DSL_CPE_STATIC DSL_int_t DSL_CPE_ArgsExtract(
       DSL_char_t **pArg,
       DSL_char_t *pcSeparators,
       DSL_int_t nArgListNum,
       DSL_CPE_ArgElement_t *pArgList)
    {
    
       DSL_char_t cString[DSL_CPE_ARGS_EXTRACT_STRING_LEN] = { 0 };
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
       DSL_char_t *pcToken;
       DSL_int_t i = 0, nRet = 0;
    
       DSL_size_t nStrMax = DSL_CPE_ARGS_EXTRACT_STRING_LEN;
       DSL_char_t *pNextToken = DSL_NULL;
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    
       /* Set pointer to beginning of next parameter group */
       if ((**pArg == '_') && (*(*pArg+1) != '\0')) *pArg = *pArg + 1;
    
    
       cpe_control_strncpy_s(cString, sizeof(cString)-1,
                             *pArg, cpe_control_strnlen_s(*pArg, sizeof(cString)-1));
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
       cString[sizeof(cString)-1]=0;
    
       pcToken = cpe_control_strtok_s(cString, &nStrMax, pcSeparators, &pNextToken);
    
    Kenneth Johansson's avatar
    Kenneth Johansson committed
    
       if (pcToken != DSL_NULL)
       {
          nRet++;