/**************************************************************
$Workfile:   elmui.c  $
***************************************************************
**
** FIRMWARE, Copyright (C) 2000-2002
** Ikanos Communications, Fremont, CA
** All rights reserved. 
**
** The information and contents of this file are the
** proprietary information of Ikanos Communication and may not
** be disclosed or used without the formal written approval of
** Ikanos Communication
**
$Revision: 1.2 $
$Date: 2006/12/12 10:53:06 $
***************************************************************/


/**************************************************************

	This file contains functions for 
	  ELM related user interface:
		
**************************************************************/

#include <stdio.h>
#include <string.h>

#include "ipos.h"
#include "appconfig.h"
#include "apperrCode.h"
#include "apposmacro.h"
#include "portmap.h"
#include "oamp.h"

#include "elmdef.h"
#include "elmapp.h"

extern int	getPortNum (ipos_port_id *pid);
extern readEventLogFromFlash( U32 nvramEventLogSize );
/* initial source of the event log is from flash memory ... */
/* count of events to show is 1000 ... */

app_elm thisAppElm = { { 0, 0 }, 0, 1, DEFAULT_EVENT_LOG_COUNT };

#ifdef ALASKA
extern int readFromVdsl(char *buffer);
extern int writeToVdsl(char *buffer);
#endif

static void
uiClearEventLogSource( void )
{
	thisAppElm.localSourceEventLog = 0;
	thisAppElm.remoteSourceEventLog.bmeNum = 0;
	thisAppElm.remoteSourceEventLog.portNum = 0;
	thisAppElm.fromFlashMemory = 0;
}

static void
uiCheckEventLogSource( void )
{
	if (thisAppElm.localSourceEventLog == 0 &&
	    thisAppElm.remoteSourceEventLog.bmeNum == 0 &&
	    thisAppElm.remoteSourceEventLog.portNum == 0 &&
	    thisAppElm.fromFlashMemory == 0)
	{
		printf( "Warning: source of the event log is not known\n" );
	}
}

static void
uiShowEventLogSource( void )
{
	if (thisAppElm.remoteSourceEventLog.bmeNum > 0)
	{
		printf( "remote event log from port b%dp%d\n",
			 thisAppElm.remoteSourceEventLog.bmeNum,
			 thisAppElm.remoteSourceEventLog.portNum
		);
	}
	else if (thisAppElm.localSourceEventLog > 0)
	{
		printf( "local event log from BME %d\n", thisAppElm.localSourceEventLog );
	}
	else if (thisAppElm.fromFlashMemory != 0)
	{
		printf( "local event log saved to flash memory\n" );

	}
}

static void
uiGetCountEventsToShow( eELMEventLogState currentEventLogState )
{
	U8	 str[ 80 ];
#ifdef ALASKA
	U8	 str1[ 80 ];
#endif
	U8	*tmpAddr;
	U16	 defaultEventCount = DEFAULT_EVENT_LOG_COUNT, tmpEventCount = 0;

	if (currentEventLogState == eELM_VALID_EVENT_LOG) {
		tmpAddr = sysGetEventLogAddr( 0 );
		defaultEventCount = iposCountofEntriesInEventLog( tmpAddr, DEFAULT_EVENT_LOG_SIZE );
	}

#ifdef ALASKA
        printf("Enter number of events to show [%u]: ", defaultEventCount );
        sprintf(str1, "CONTINUE");
        if(writeToVdsl((char *)&str1) == -1)
          return;

        fflush(stdout);
        if( readFromVdsl((char *)&str) == -1)
          return;
        if (strlen( str ) < 1)
        {
                return;
        }
        tmpEventCount = atoi(str);
#else
	sprintf( &str[ 0 ], "Enter number of events to show [%u]: ", defaultEventCount );
	printf( &str[ 0 ] );
	gets( &str[ 0 ] );
	tmpEventCount = atoi( &str[ 0 ] );
#endif
	if (tmpEventCount < 1 || tmpEventCount > defaultEventCount)
	  tmpEventCount = defaultEventCount;
	thisAppElm.countEventsToDisplay = tmpEventCount;
}

static void
uiShowEventsInBuffer( U8 *evlAddr, U16 countofEvents )
{
	int	iter;

	iter = 1;
	while (strlen( evlAddr ) > 0 && iter <= countofEvents)
	{
		printf( "%2d: %s\n", iter, evlAddr );
		evlAddr += (strlen( evlAddr ) + 1);
		iter++;
	}
}

static int
uiShowEventLogInteractive( void )
{
	char	*tmpAddr;
	U16	 countofEventsToShow = 0;

	uiCheckEventLogSource();
	uiGetCountEventsToShow( eELM_VALID_EVENT_LOG );
	uiShowEventLogSource();

	countofEventsToShow = thisAppElm.countEventsToDisplay;
	tmpAddr = sysGetEventLogAddr( 0 );
	uiShowEventsInBuffer( tmpAddr, countofEventsToShow );
	return( IPOS_SUCCESS );
}

static void
uiGetLocalBmeEventLog( void )
{
#ifndef ALASKA
	char	str[ 80 ];
#endif
	char    *tmpAddr;
	U16	bmeNum = 0, countofEvents = 0;

	if (iposELMXferInProgress( 0 ))		/* 0 --> any transfer at all */
	{
		printf( "ELM application in progress, cannot proceed\n" );
		return;
	}

#ifndef ALASKA
	if (MAX_NUM_OF_BMES > 1)
	{
		printf( "Enter bme number: ");
		gets( &str[ 0 ] );
		bmeNum = atoi( &str[ 0 ] );
	}
	else
#endif
	  bmeNum = 1;

	/*  no.  use uiShowEventLog, below, to show the events */

#ifndef ALASKA
	/*printf( "Enter number of events to show: " );
	gets( &str[ 0 ] );
	countofEvents = atoi( &str[ 0 ] );*/
#endif

	tmpAddr = sysGetEventLogAddr( 0 );				/* 0 -> local log */
	iposGetBmeEventLog( bmeNum, tmpAddr, DEFAULT_EVENT_LOG_SIZE, eELM_BME_IS_HUNG, 0, 0, NULL );

	uiClearEventLogSource();
	thisAppElm.localSourceEventLog = bmeNum;
	countofEvents = iposCountofEntriesInEventLog( tmpAddr, DEFAULT_EVENT_LOG_SIZE );
	printf( "\nevent log buffer has %d entries\n", countofEvents );

	uiShowEventLogInteractive();

	return;
}

#ifdef VTU_O

/* OAMP job */

static	void
uiShowRemoteEventLogJob( U32 parameter1, U32 parameter2, ipos_msg_buf *pBuf )
{
	oamp_cb_msg	*pMsg;
	U8		*tmpAddr = NULL;
	ipos_port_id	 pid;
	U8		 uid;
	int		 status;

	if(pBuf==NULL)
	{
		printf( "Invalid msg buffer in uiShowRemoteEventLogJob\n" );
		return;
	}

	pMsg = (oamp_cb_msg *) pBuf->pDataBuf;
	pid = pMsg->portId;
	uid = pMsg->uid;
	if (pMsg->parLen != sizeof( U8 * ))
	{
		printf(
	   "unexpected parameter length of %d in uiShowRemoteEventLogJob for port b%dp%d\n",
	    pMsg->parLen, pid.bmeNum, pid.portNum
		);
	}
	else
	  memcpy( &tmpAddr, pMsg->par, sizeof(U8 *) );
	status = pMsg->status;

	if (status == ELM_ERROR_CKSUM)
	  printf( "Warning: check sum mismatch in event log from port b%dp%d\n",
		   pid.bmeNum, pid.portNum
	  );

	if (tmpAddr != NULL)
	{
		uiShowEventLogSource();
		uiShowEventsInBuffer( tmpAddr, thisAppElm.countEventsToDisplay );
	}

	iposMsgFree(pBuf);
	printf( PROMPT );
}

static int
uiSubmitJobShowRemoteEventLog( ipos_port_id pid, U8 uid, int status, void *pPar )
{
	ipos_msg_buf	*pBuf;
	oamp_cb_msg	*pMsg;

	pBuf=iposMsgGet();
	if(pBuf==NULL)
	{
		printf("Failed to get a msg buffer in uiSubmitJobShowRemoteEventLog\n");
		return( IPOS_ERROR );
	}

	pBuf->len=sizeof(oamp_cb_msg);
	
	pMsg=(oamp_cb_msg *) pBuf->pDataBuf;
	pMsg->portId=pid;
	pMsg->uid=uid;
	pMsg->parLen=sizeof(void *);
	memcpy( pMsg->par, &pPar, sizeof(void *) );
	pMsg->status=status;
	pMsg->cntRpt=0;

	if (appOampJobAdd( pid.bmeNum, uiShowRemoteEventLogJob, 0l, 0l, pBuf ) != IPOS_SUCCESS)
	{
		iposMsgFree(pBuf);
		return( IPOS_ERROR );
	}

	return( IPOS_SUCCESS );
}

/* completion function for getting the remote event log

   this one displays a warning if the check sums fail to match, and then continues.  */

static void
uiRemoteBmeEventLogComplete( ipos_port_id pid, U8 uid, int status, void *pPar )
{
	U16	 countofEvents = 0;
	U8	*tmpAddr;

	if (status != IPOS_SUCCESS && status != ELM_ERROR_CKSUM)
	{
		printf( "Error getting remote event log from port b%dp%d, error code: %d\n",
			 pid.bmeNum, pid.portNum, status
		);
		uiClearEventLogSource();
		printf( PROMPT );
		return;
	}

	if (pPar == NULL)		/* this is a programming error ... */
	{
		printf(
		   "Event log buffer is NULL in uiRemoteBmeEventLogComplete for port b%dp%d\n",
		    pid.bmeNum, pid.portNum
		);
		printf( PROMPT );
		return;
	}

	thisAppElm.remoteSourceEventLog.bmeNum = pid.bmeNum;
	thisAppElm.remoteSourceEventLog.portNum = pid.portNum;
	printf( "\nBME Event Log from port b%dp%d:\n", pid.bmeNum, pid.portNum );
	tmpAddr = pPar;
	countofEvents = iposCountofEntriesInEventLog( tmpAddr, DEFAULT_EVENT_LOG_SIZE );
	printf( "has %d entries\n", countofEvents );
	printf( PROMPT );

	uiSubmitJobShowRemoteEventLog( pid, uid, status, pPar );
}

static void
uiGetRemoteBmeEventLog( void )
{
	ipos_port_id	 pid;
	int		 lineNum;
	int		 eventLogType;
	char		 str[ 80 ];
	U8		*thisEventLogAddr;
	extern int	 iposELMXferInProgress( int portNum );

	if (iposELMXferInProgress( 0 ))		/* 0 --> any transfer at all */
	{
		printf( "ELM application in progress, cannot proceed\n" );
		return;
	}

	if (getPortNum(&pid) < 0)
	{
		return;
	}
	if (oampGetPortState(pid) != uSHOWTIME)
	{
		printf(
    "\nPort b%dp%d not in showtime, cannot proceed\n", pid.bmeNum, pid.portNum
		);
		return;
	}

	if (getLineNum(pid, &lineNum) != IPOS_SUCCESS)
	{
		printf(
    "\nprogramming problem, cannot get port index for b%dp%d\n", pid.bmeNum, pid.portNum
		);
		return;
	}
	thisEventLogAddr = sysGetEventLogAddr( lineNum );

	printf( "Select event log type from the remote system:\n" );
	/*printf( "  %d) current contents of event log buffer\n", eELM_CURRENT_BME_LOG );*/
	printf( "  %d) new BME event log\n", eELM_NEW_BME_LOG );
	printf( "  %d) BME event log saved to NVRAM\n", eELM_SAVED_BME_LOG );
	printf( "Enter remote event log type: ");
	gets( &str[ 0 ] );
	eventLogType = atoi( &str[ 0 ] );

	uiGetCountEventsToShow( eELM_INVALID_EVENT_LOG );

/* erase source of BME event log.  when get remote
   event log process completes, it will mark the source */

	uiClearEventLogSource();

	iposGetRemoteEventLog( pid, thisEventLogAddr, DEFAULT_EVENT_LOG_SIZE, eventLogType, 0, 0, uiRemoteBmeEventLogComplete );

	return;
}
#endif

#ifdef VTU_O
void
uiElmMenu( void )
{
	int	elmCmd = 0;
	char	str[ 82 ];

	printf( "\n   1) Get new local BME event log" );
	printf( "\n   2) Get remote BME event log" );
	printf( "\n   3) Display contents of the event log buffer" );
	printf( "\n   4) Display the BME event log saved to NVRAM" );
	printf( "\n   99) Exit from menu" );
	printf ("\n\nSelect ELM option: ");
	gets( str );
	if (strlen( str ) < 1)
	{
		return;
	}
	sscanf( str,"%i", &elmCmd ); 

	switch (elmCmd)
	{
	  case 1:
		uiGetLocalBmeEventLog();
		break;

	  case 2:
		uiGetRemoteBmeEventLog();
		break;

	  case 3:
	  case 4:
		if (elmCmd == 4)
		{
			readEventLogFromFlash( DEFAULT_EVENT_LOG_SIZE );
			uiClearEventLogSource();
			thisAppElm.fromFlashMemory = 1;
		}
		uiShowEventLogInteractive();
		break;

	  case 99:
		break;

	  default:
		printf( "Invalid ELM selection %s\n", str );
		break;
	}
}
#endif

#ifdef VTU_R
void
uiElmMenu( void )
{
	int	elmCmd = 0;
	char	str[ 82 ];

	printf( "\n   1) Get new local BME event log" );
	printf( "\n   2) Display contents of the event log buffer" );
#ifndef ALASKA
	printf( "\n   3) Display the BME event log saved to NVRAM" );
#ifdef CPE_40
	printf( "\n   4) Reset BME" );
#endif
#endif
	printf( "\n   99) Exit from menu" );
	printf ("\n\nSelect ELM option: ");

#ifdef ALASKA
    sprintf(str, "CONTINUE");
    if(writeToVdsl((char *)&str) == -1)
        return;
    fflush(stdout);
    if( readFromVdsl((char *)&str) == -1)
        return;
#else
	gets( str );
#endif
	if (strlen( str ) < 1)
	{
		return;
	}
	sscanf( str,"%i", &elmCmd ); 

	switch (elmCmd)
	{
	  case 1:
		uiGetLocalBmeEventLog();
		break;

	  case 2:
#ifndef ALASKA
	  case 3:
		if (elmCmd == 3)
		{
			readEventLogFromFlash( DEFAULT_EVENT_LOG_SIZE );
			uiClearEventLogSource();
			thisAppElm.fromFlashMemory = 1;
		}
#endif
		uiShowEventLogInteractive();
		break;

#ifdef CPE_40
	  case 4:
		reInitBme ();

	  break;
#endif

	  case 99:
		break;

	  default:
		printf( "Invalid ELM selection %s\n", str );
		break;
	}
#ifdef ALASKA
    sprintf(str, "END");
    writeToVdsl((char *)&str);
#endif
}
#endif

