/******************************************************************************/
/*                       Copyright 2001 Broadcom Corporation                  */
/*                                                                            */
/* This material is the confidential trade secret and proprietary information */
/* of Broadcom Corp.  It may not be reproduced, used, sold or transferred to  */
/* any third party without the prior written consent of Broadcom Corp.        */
/* All rights reserved.                                                       */
/******************************************************************************/
/*   FileName        : bcm_modem.c                                            */
/*   Purpose         : This is a simple modem program to control BCM6410      */
/*                     It first boots the device, then configures and starts  */
/*                     the 12 lines in parallel, and monitors them            */
/*                     continuously, with very basic error management         */
/*   Limitations     : None                                                   */
/*   Author          : Emmanuel Hanssens                                      */
/*   Creation Date   : 24-Sep-2001                                            */
/*   History         : Compiled by CVS                                        */
/******************************************************************************/
/*   $Id: bcm_modem.c,v 1.26 2004/09/27 15:33:11 hanssens Exp $  */
/******************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include "bcm_genericOptions.h"
#include "bcm_utils.h"
#include "bcm_devObject.h"
#include "bcm_lineObject.h"
#include "bcm_hmiCoreServices.h"
#include "bcm_hmiLineServices.h"
#include "bcm_errorHandler.h"

/* {{{ unexpectedLineError */
      
static void unexpectedLineError(int lineId) 
{
  DevObject  *devPtr  = getLinePtr(lineId)->devPtr;

  if (CALL_HMIQA_NPL(ResetLine, devPtr,
                     LINE_MANAGER_ID(lineId)) != BCM_SUCCESS)
    FATAL_ERROR("HMI communication problem with service %s",
                ResetLineLayout.name);

  /* and print reset action */
  printf("... unexpected line error, reseting.\n");
}

/* }}} */
/* {{{ main program */

int main(int argc,char *argv[])
{
  int lineId;
  extern int lineNumber;

  printf("NB_BCM_DEV=%d   NB_LINES=%d  BCM_DEV_NB_LINES=%d\n", NB_BCM_DEV, NB_LINES, BCM_DEV_NB_LINES);
  
  GetOptions(argc, argv, "qRb:t:h:p:s:r:d:l:");
  GlobalInit();
  
  /* infinite loop for line manager configuration, start and monitoring */
  while (1)
  {
    /* message definitions */
    GetLineStatusMsgRep   lineStatusRep;
    GetLineCountersMsgRep lineCountersRep;
    
    printf("\nLine Status   AS  ES UAS  CV HEC  BEC  AS  ES UAS  CV HEC RAT[DS] RAT[US]\n");
    
    /* loop on all lines */
    for (lineId=0; lineId<NB_LINES; lineId++)
    {
      LineObject *linePtr = getLinePtr(lineId);
      DevObject  *devPtr  = linePtr->devPtr;
      
      /* only loop on one line if lineNumber option given */
      if (lineNumber != -1 && lineNumber != lineId) continue;
      
      printf("%2d  ", lineId);
      fflush(stdout);

      if (CALL_HMIQA_REP(GetLineStatus, devPtr, LINE_MANAGER_ID(lineId),
                         &lineStatusRep) != BCM_SUCCESS)
      {
        /* only thing we can do here is to reset the line */
        unexpectedLineError(lineId);
      
        /* and reset the line status to process it further */
        lineStatusRep.state = 0;
      }

      /* process the line status */
      switch (lineStatusRep.state)
      {
        /* {{{ Idle not configured */
        case LINE_STATUS_IDL_NCON: 

          printf("IDLE_NCO ");
          fflush(stdout);

          /* configure the line for both traffic and physical layer */
          if (ConfigureLine(linePtr) != BCM_SUCCESS)
          {
            /* configuration failed => try to reset line and skip */
            unexpectedLineError(lineId);
            continue;
          }

          printf("... configuration successfull.\n");
          break;
          /* }}} */

        /* {{{ Idle configured */
        case LINE_STATUS_IDL_CONF:

          printf("IDLE_CON ");
          fflush(stdout);

          /* start line */
          if (CALL_HMIQA_NPL(StartLine, devPtr,
                             LINE_MANAGER_ID(lineId)) != BCM_SUCCESS)
          {
            /* only thing we can do here is to reset the line */
            unexpectedLineError(lineId);
            continue;
          }
            
          printf("... line is started.\n");
          break;
          /* }}} */

        /* {{{ running activation */
        case LINE_STATUS_RUN_ACTI:
            
          printf("RUN_ACTI\n");
          /* do nothing, wait for next state */
          break;
          /* }}} */

        /* {{{ running initialization */
        case LINE_STATUS_RUN_INIT:
            
          printf("RUN_INIT\n");
          /* do nothing, wait for next state */
          break;
          /* }}} */

        /* {{{ running showtime */
        case LINE_STATUS_RUN_SHOW:
        case LINE_STATUS_RUN_SHOW_L2:
            
          printf("SHOWTIME ");
          fflush(stdout);

          /* get line counters */
          if (CALL_HMIQA_REP(GetLineCounters, devPtr, LINE_MANAGER_ID(lineId),
                             &lineCountersRep) != BCM_SUCCESS)
          {
            /* only thing we can do here is to reset the line */
            unexpectedLineError(lineId);
            continue;
          }
            
          /* print different counters */
          printf("%3ld %3ld %3ld %3ld %3ld %4ld %3ld %3ld %3ld %3ld %3ld %7d %7d\n",
                 lineCountersRep.derivedCounts[NE].AS,
                 lineCountersRep.derivedCounts[NE].ES,
                 lineCountersRep.derivedCounts[NE].UAS,
                 lineCountersRep.adslAnomalyCounts[B0].ne.CV,
                 lineCountersRep.atmPerfCounts[B0].ne.hecErrors,
                 lineCountersRep.atmPerfCounts[B0].ne.idleCellBitErrors,
                 lineCountersRep.derivedCounts[FE].AS,
                 lineCountersRep.derivedCounts[FE].ES,
                 lineCountersRep.derivedCounts[FE].UAS,
                 lineCountersRep.adslAnomalyCounts[B0].fe.CV,
                 lineCountersRep.atmPerfCounts[B0].fe.hecErrors,
                 lineStatusRep.linkStatus[DS].bearer[B0].actualBitRate,
                 lineStatusRep.linkStatus[US].bearer[B0].actualBitRate);

          break;
          /* }}} */

        default:
          /* either test or unkown state => reset */
          unexpectedLineError(lineId);
          continue;
          break;
      }
    } /* loop on NB_LINES lines */
    
    sleep(5);                   /* wait some time between passes */
  } /* while loop */
}
/* }}} */
