/**************************************************************
***************************************************************
**
** Host Application, Copyright (C) 2002-2004
** Ikanos Communication, 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 $
**************************************************************/

/*******  Include Files         ***************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "dapi_define.h"
#include "uiUtil.h"
#include "oampdb.h"
#include "apistruct.h"

#include "dapi_parms.h" /* this is needed to have #define gets from bmeconfig.h */
/*******  Defines               ***************************************/
#define STATIC	static

#define MAX_PSD_INDEX         (13)

char PsdMaskNames[MAX_PSD_INDEX][32] = {
  "DEFAULT_PSD",   // 0
  "ANSI_M1_CAB",   // 1
  "ANSI_M2_CAB",   // 2
  "ETSI_M1_CAB",   // 3
  "ETSI_M2_CAB",   // 4
  "ANNEX_F",       // 5
  "ANSI_M1_EX",    // 6
  "ANSI_M2_EX",    // 7
  "ETSI_M1_EX",    // 8
  "ETSI_M2_EX",    // 9
  "RESERVED",      // 10 
  "PSD_K",         // 11
  "PSD_CHINA"      // 12
};

extern int ReceiveTLCommand( U8 *bTlStr);

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

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

          L O C A L    F U N C T I O N S

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

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

          F U N C T I O N     I N T E R F A C E S 

************************************************************************
***********************************************************************/
int getBandPlan (int bandPlan)
{
  int validSelection = 0;
  int tempNum=0;
  char tempStr[20];

  do
  {
    printf("\nBand Plan Selection\n");
#if !((defined(P2CO) || defined(P2CPE)) || defined (BME_CPE_20))
    printf("\n1)  Flex-138-8500 10/10");
    printf("\n2)  Flex-138-8500 25/25");
#endif
    printf("\n3)  998-138-8500 Long Reach");
    printf("\n4)  998-138-12000 High Data Rate");
#if !((defined(P2CO) || defined(P2CPE)) || defined (BME_CPE_20))
    printf("\n5)  Flex-138-8500 Fixed Rate 13/13");
#else
  	printf("\n6)  997-138-8500");
	printf("\n7)  Flex-138-4400");
	printf("\n8)  998-138-4400");
	printf("\n9)  997-138-4400");
	printf("\n11) 998-138-4400-optBand");
	printf("\n12) 997-138-4400-optBand"); 
    printf("\n18) 998-138-12000 4K Tones");
    printf("\n19) 997-138-12000 4K Tones");
    printf("\n20) 998-138-17000 4K Tones (17A)");
    printf("\n21) 998-138-30000 4K Tones (30A)");
#endif
    printf("\n\nEnter Band Plan selection [%d]: ", bandPlan);

    gets(tempStr);
    
    if (strlen(tempStr)==0)
    {
      tempNum=bandPlan;   // Null or CR entered means leave bandPlan alone
    }
    else
    {
      tempNum = atoi(tempStr);
    }
    
    if (((tempNum >= 1) && (tempNum <= 21)) && (tempNum != 13))
	    validSelection = 1;
		else
      printf("\nIncorrection selection!!\n\n");
  } while (!validSelection);

  return (tempNum);
}

int getBmeBandPlan (int bandPlanSelect)
{
  int bmeBandPlan;

  switch (bandPlanSelect)
  {
    case 1  : bmeBandPlan = BP14_MXU_3;     break;
    case 2  : bmeBandPlan = BP7_MXU_3;      break;
    case 4  : bmeBandPlan = BP3_998_4;      break;
    case 5  : bmeBandPlan = BP15_MXU_3;     break;
    case 6  : bmeBandPlan = BP16_997_4B_4P; break;
    case 7  : bmeBandPlan = BP8_MXU_2;      break;
    case 8  : bmeBandPlan = BP17_998_138_4400;	break;
	case 9	: bmeBandPlan = BP18_997_138_4400;	break;
	case 10	: bmeBandPlan = BP23_998_138_16000;	break;
	case 11 : bmeBandPlan = BP22_998_138_4400_opBand;	break;		
	case 12 : bmeBandPlan = BP21_997_138_4400_opBand;	break;
        case 14 : bmeBandPlan = BP24_998_3B_8KHZ;	break;
        case 15 : bmeBandPlan = BP25_998_138_17600;	break;
        case 16 : bmeBandPlan = BP26_CH1_3;	break;
        case 17 : bmeBandPlan = BP27_CH1_4;	break;
    case 18 : bmeBandPlan = BP13_MXU_3; break;
    case 19 : bmeBandPlan = BP14_MXU_3; break;
    case 20 : bmeBandPlan = BP11_998_2; break;
    case 21 : bmeBandPlan = BP9_998_2; break;
    default :
    case 3  : bmeBandPlan = BP2_998_3;      break;
  }														 
	return (bmeBandPlan);
}

unsigned char getPsdMaskLevel(unsigned char psdMaskLevel)
{
  int i;
  U8 newPsdIndex=0;
  char tempStr[20]; 

  gets (tempStr); // Dummy gets() to consume '\n'


  printf("\n\nPSD MASK SELECTION INDEX");
  for (i = 0; i < MAX_PSD_INDEX; i++)
    printf("\n   %2u => %s", i, PsdMaskNames[i]);
  printf("\nCurrent PSD Mask is %s\n", PsdMaskNames[oampGetPsdIndex]);

  /* Read the PSD Mask Index from the user */
  do {
    printf("\nEnter New PSD Mask Index [%u]: ", oampGetPsdIndex);
    gets(tempStr);
    newPsdIndex = (strlen(tempStr) > 0) ? (U8)atoi(tempStr) : oampGetPsdIndex;
    if (newPsdIndex >= MAX_PSD_INDEX)
      printf("\nInvalid entry %u. (0 < Index < %u)", newPsdIndex, MAX_PSD_INDEX);
  } while (newPsdIndex >= MAX_PSD_INDEX);

  /* Copy the new PSD Mask index to the flash */
  oampSetPsdLevel(newPsdIndex);

  if (psdMaskLevel != oampGetPsdIndex)
    printf("\nPSD Mask changed to %s", PsdMaskNames[oampGetPsdIndex]);

  return(newPsdIndex);	

}

void getMaxPsd (void)
{
  int i, fband;
  tMaxPsd tempMaxPsd = DEFAULT_MAX_PSD;
  char tempStr[256]; 
  U8 newPsdLevel;

  printf("\n\nModify the Maximum PSD Level ? (y/n):");
  gets(tempStr);

  if (tempStr[0] == 'y')
  {

    printf("\nThe maximum PSD level is in the format of (-140 + X*0.5)dBm/Hz"); 
    printf("\nFor example, 160 is -60dBm/Hz; 140 is -70dBm/Hz; 120 is -80dBm/Hz\n\n");

    // Read input from user
    for (i = 0, fband = 0; i < tempMaxPsd.NumPsd; i+=2, fband++)
    {

      if (i+1 != tempMaxPsd.NumPsd)
      {
        printf ("\t FB%02u)  %5ukHz - %5ukHz [%3u]:", fband,
                tempMaxPsd.PsdTone[i].Freq, tempMaxPsd.PsdTone[i+1].Freq,
                oampGetMaxPsd.PsdTone[i].PsdLevel);

        gets(tempStr);
        if (strlen(tempStr) > 0) {
          newPsdLevel = (U8)atoi(tempStr);
          tempMaxPsd.PsdTone[i].PsdLevel = newPsdLevel; 
          tempMaxPsd.PsdTone[i+1].PsdLevel = newPsdLevel;
        } else {
          tempMaxPsd.PsdTone[i].PsdLevel = oampGetMaxPsd.PsdTone[i].PsdLevel;
          tempMaxPsd.PsdTone[i+1].PsdLevel = oampGetMaxPsd.PsdTone[i+1].PsdLevel;
        }
      }
      else
      {
        /* Handle the last unpaired tone (if any) */
        printf("\t FB%02u)  Above %5ukHz [%3u]:", fband,
               tempMaxPsd.PsdTone[i].Freq,
               oampGetMaxPsd.PsdTone[i].PsdLevel);
        gets(tempStr);
        if (strlen(tempStr) > 0)
          tempMaxPsd.PsdTone[i].PsdLevel = (U8)atoi(tempStr);
        else
          tempMaxPsd.PsdTone[i].PsdLevel = oampGetMaxPsd.PsdTone[i].PsdLevel;

      }

    }

    /* Store the Max Psd structure in the flash */
    oampSetMaxPsd(&tempMaxPsd);

  }

  printf("\n");

}

void copyMaxPsdArray (U8 *maxPsdArray)
{
  int i;
  U16 index1, index2;
  tMaxPsd tempMaxPsd;

  memset (maxPsdArray, 0, MAX_PSD_MSG_LENGTH);

  memcpy(&tempMaxPsd, &oampGetMaxPsd, sizeof(tMaxPsd)); 

  maxPsdArray[0] = tempMaxPsd.NumPsd;

  for (i = 0; i < tempMaxPsd.NumPsd; i+=2)
  {
    // Ceil the start indices of bands
    index1 = (U16)ceil((float)tempMaxPsd.PsdTone[i].Freq/(4.3125f));
    maxPsdArray[i*3 + 1] = (U8)((index1>>8) & 0xff);
    maxPsdArray[i*3 + 2] = (U8)(index1 & 0xff);
    maxPsdArray[i*3 + 3] = (U8)(tempMaxPsd.PsdTone[i].PsdLevel);

    // Floor the stop indices of bands
    if (i+1 != tempMaxPsd.NumPsd)
    {
      index2 = (U16)floor((float)tempMaxPsd.PsdTone[i+1].Freq/(4.3125f));
      maxPsdArray[(i+1)*3 + 1] = (U8)((index2>>8) & 0xff);
      maxPsdArray[(i+1)*3 + 2] = (U8)(index2 & 0xff);
      maxPsdArray[(i+1)*3 + 3] = (U8)(tempMaxPsd.PsdTone[i+1].PsdLevel);
    }

  }

}

void getCO_PSD_const_array()
{
	float			k0[3];
	float			k1[3];
	float			k0_hi[3];
	float			k1_hi[3];
	int				updateFlag;
	//char 			tempStr[20];
	S32				*ok0, *ok1, *ok0_hi, *ok1_hi;
	
	ok0 = &oampGetK0_array(0);
	ok1 = &oampGetK1_array(0);
	ok0_hi = &oampGetK0_hi_array(0);
	ok1_hi = &oampGetK1_hi_array(0);
	printf("Updating CO RX PSD const array [1=yes, 0=no]: ");
	scanf("%d", &updateFlag);
//	updateFlag = atoi(tempStr);
	
	if(updateFlag == 1) {	

		printf("Enter CO Rx PSD constants for \n[\n\tK1[0]=%f, \n\tK1[1]=%f, \n\tK1[2]=%f, "
		                                        "\n\tK1[3]=%f, \n\tK1[4]=%f, \n\tK1[5]=%f\n]: ", 
				(float)(ok0[0])/1000.0,
				(float)(ok0[1])/1000.0,
				(float)(ok0[2])/1000.0,
				(float)(ok0_hi[0])/1000.0,
				(float)(ok0_hi[1])/1000.0,
				(float)(ok0_hi[2])/1000.0);
				scanf("%f %f %f %f %f %f", k0, k0+1, k0+2, k0_hi, k0_hi+1, k0_hi+2);

		printf("Enter CO Rx PSD constants for \n[\n\tK2[0]=%f, \n\tK2[1]=%f, \n\tK2[2]=%f, "
		                                        "\n\tK2[3]=%f, \n\tK2[4]=%f, \n\tK2[5]=%f\n]: ", 
				(float)(ok1[0])/1000.0,
				(float)(ok1[1])/1000.0,
				(float)(ok1[2])/1000.0,
				(float)(ok1_hi[0])/1000.0,
				(float)(ok1_hi[1])/1000.0,
				(float)(ok1_hi[2])/1000.0);
				scanf("%f %f %f %f %f %f", k1, k1+1, k1+2, k1_hi, k1_hi+1, k1_hi+2);

		oampSetK_array(k0, k1, k0_hi, k1_hi);												
	}
}


/* 
	UIMaintenance Menu 
	
		It acquires information from user that needed to be send to BME to transmit 
		test signal. 
		
		Input: ptr to variable of type ipos_test_signals
		
		output: int
			-1	; no action to be taken by the caller
			1	; send test signal request to BME
			2	; send port deactivation to BME
*/
int uiMaintenanceMenu (ipos_test_signals * pTestSig)
{
 int in, i;
 char str[256];
#ifdef ALASKA
 char writeMsg[20];
#endif
 int	status = -1;
 int 	loop = 1;
 U16 * pTone;

  	memset ((char *)pTestSig, 0, sizeof(ipos_test_signals));
  	while ( loop )
	{
  		printf("\nTransmit/Receive Maintenance ");
  		printf("\n\t 1) Transmit quiet ");
  		printf("\n\t 2) Transmit tones ");
  		printf("\n\t 3) Transmit tones REQ");
  		printf("\n\t 4) Transmit single tone sweep ");
  		printf("\n\t 5) Transmit op-training ");
  		printf("\n\t 6) Transmit op-synchro ");
  		printf("\n\t 7) Transmit op-medley ");
  		printf("\n\t 8) Transmit Garabit ");
  		printf("\n\t 9) Terminate transmit maintenance mode ");
  		printf("\n\t20) Receive Average Power ");
        printf("\n\t21) Capture Afifo Data (3 symbols)" );
      printf("\n\t25) Receive Average Power(dbm/hz for qln only)");
  		printf("\n\t99) Exit from menu ");
  		printf("\nSelect option: ");
  
#ifdef ALASKA
    sprintf(writeMsg, "CONTINUE");
    if(writeToVdsl((char *)&writeMsg) == -1)
	break;
    fflush(stdout);
    if( readFromVdsl((char *)&str) == -1)
	break;
#else
		gets(str);
#endif
		in = atoi(str);
	
		switch (in)
		{
			case 1:
				pTestSig->SigType = HPI_XMT_QUIET;
				loop = 0;
				status = 1;
				break;
			case 2:
			case 3:
				pTestSig->SigType = (U8)in;
				while (1)
				{
					printf("\n\t Number of tones to be transmitted (0-3): ");

#ifdef ALASKA
      sprintf(writeMsg, "CONTINUE");
      if(writeToVdsl((char *)&writeMsg) == -1)
        return status;
      fflush(stdout);
      if( readFromVdsl((char *)&str) == -1)
	break;
#else
					gets (str);
#endif
					in = atoi(str);
					if ( (in >= 0) && (in < 4) )
					{
						pTestSig->NumTones = (U8)in;
						break;
					}
				}

				pTone = &(pTestSig->Tone1);
				for (i=0 ; i<pTestSig->NumTones ; i++)
				{
					printf("\n\t Transmit Tone #%d (freq/4.3125Khz): ", i+1);

#ifdef ALASKA
    sprintf(writeMsg, "CONTINUE");
    if(writeToVdsl((char *)&writeMsg) == -1)
        return status;
    fflush(stdout);
    if( readFromVdsl((char *)&str) == -1)
	break;
#else
					gets (str);
#endif
					in = atoi(str);
					pTone[i] = (U16)in;
				}
				loop = 0;
				status = 1;
				break;
			case 4:
				pTestSig->SigType  = HPI_XMT_TONE_SWEEP;
				pTestSig->NumTones = 1;
				
				printf("\n\t Transmit Tone (freq/4.3125Khz): ");

#ifdef ALASKA
    sprintf(writeMsg, "CONTINUE");
    if(writeToVdsl((char *)&writeMsg) == -1)
        return status;
    fflush(stdout);
    if( readFromVdsl((char *)&str) == -1)
	break;
#else
				gets (str);
#endif
				in = atoi(str);
				pTestSig->Tone1 = (U16)in;
					
				while (1)
				{
					printf("\n\t Sweep Interval in 250 msec increament (max of 120 sec): ");

#ifdef ALASKA
    sprintf(writeMsg, "CONTINUE");
    if(writeToVdsl((char *)&writeMsg) == -1)
        return status;
    fflush(stdout);
    if( readFromVdsl((char *)&str) == -1)
	break;
#else
					gets (str);
#endif
					in = atoi(str);
					if ( (in > 0) && (in < 481) )
					{
						pTestSig->SweepInterval = (U16)in;
						break;
					}
				}
				loop = 0;
				status = 1;
				break;
			case 5:
				pTestSig->SigType = HPI_XMT_TRAINING_SYMBOL;
				loop = 0;
				status = 1;
				break;
			case 6:
				pTestSig->SigType = HPI_XMT_SYNCHRO_SYMBOL;
				loop = 0;
				status = 1;
				break;
			case 7:
				pTestSig->SigType = HPI_XMT_MEDLEY_SYMBOL;
				loop = 0;
				status = 1;
				break;
			case 8:
				pTestSig->SigType = HPI_XMT_GARABIT;
				loop = 0;
				status = 1;
				break;
			case 9:
				loop = 0;
				status = 3;
				break;
			case 20:
				pTestSig->SigType = HPI_RX_POWER;
        pTestSig->NumTones = 0;
				loop = 0;
				status = 2;
				break;
			case 25: /* To get the Rawdata in dBm/Hz format*/
				pTestSig->SigType = HPI_RX_POWER;
        pTestSig->NumTones = 1;
				loop = 0;
				status = 2;
				break;    
            case 21:
                pTestSig->SigType = HPI_CAP_AFIFO;
				loop = 0;
				status = 2;
				break;
			case 99:
				loop = 0;
				break;
			default:
				break;
		}
	}

#ifdef ALASKA
    sprintf(writeMsg, "END");
    if( writeToVdsl((char *)&writeMsg) == -1)
	status = -1;
#endif

	return(status);	
}

#define MAX_BIT_SWAP_CMDS_PER_REQ  (4)

/* Bit Swap Request Message  */

typedef struct {
  char msg_hdr; /* Bit swap message header */

  struct {
    char cmd; /* 8-bit Bit swap command */
    short sub_channel_idx;  /* 12-bit sub channel index */
  } msg [MAX_BIT_SWAP_CMDS_PER_REQ];

} tBitSwapReqMsg;

/*
************************************************************************
        Function: Convert Bit swap Request Struct to Message

        Description:

        Return Value: Next State
************************************************************************
*/

void ConvertBitSwapReqStructToMsg (
   tBitSwapReqMsg *pReq,
   char *req)
{

  req[0] = pReq->msg_hdr;
  req[1] = pReq->msg[0].cmd;
  req[2] = (pReq->msg[0].sub_channel_idx >> 4);
  req[3] = ((pReq->msg[0].sub_channel_idx & 0xF) << 4) + (pReq->msg[1].cmd >> 4);
  req[4] = ((pReq->msg[1].cmd & 0xF) << 4) + (pReq->msg[1].sub_channel_idx >> 8);
  req[5] = (pReq->msg[1].sub_channel_idx & 0xFF);
  req[6] = pReq->msg[2].cmd;
  req[7] = (pReq->msg[2].sub_channel_idx >> 4);
  req[8] = ((pReq->msg[2].sub_channel_idx & 0xF) << 4) + (pReq->msg[3].cmd >> 4);
  req[9] = ((pReq->msg[3].cmd & 0xF) << 4) + (pReq->msg[3].sub_channel_idx >> 8);
  req[10] = (pReq->msg[3].sub_channel_idx & 0xFF);

}


void
uiBitSwapMenu ( ipos_port_id pid )
{

  char str[256], *str_temp_wr, str_data[20], str_temp[40];
  int stop_Bit_Swap = 1, print_Bit_Swap_Menu = 1,/* length = 0,*/ count = 0, n_fields = 4;
  int data_val, BitSwapCmd/*, port_options*/;
  tBitSwapReqMsg bs_req;
   
  while (stop_Bit_Swap == 1) {

    BitSwapCmd = 0;
       
    if (print_Bit_Swap_Menu) {
      printf("\n Bit Swap Menu \n");
      printf("\n      1) Send Bit Swap Request");
      printf("\n     99) Exit this Menu");
    } /* End of if(print_Bit_Swap_menu) */
       
    printf("\n\n Select Option: ");
    gets (str);

    if (strlen(str) < 1) {
      print_Bit_Swap_Menu = 0;
      continue;
    } /* End of if (strlen (str) ) */

    sscanf(str, "%i", &BitSwapCmd);

    switch (BitSwapCmd) {

      case 1 :

         bs_req.msg_hdr = 0xFF;
         printf("Enter the Number of message fields (1 to 4) [4]:");
         gets(str);
         str_temp_wr = str; 
         while ( *str_temp_wr++ == ' '); 
         if (strlen(--str_temp_wr))  
           sscanf(str_temp_wr,"%d",&n_fields);

         if ((n_fields < 1) || (n_fields > 4)) {
           printf("Invalid Data Entered");
           break;
         }

         for (count = 0; count < n_fields; count++)  {

            printf ("\n");
            printf("Bit Swap Req Message FIELD-%d Command:\n", count+1);
            printf ("  0) DO_NOTHING\n");
            printf ("  1) INCREASE BITS BY_ONE\n");
            printf ("  2) DECREASE BITS BY_ONE\n");
            printf ("  3) INCREASE TX PWR BY 1DB\n");
            printf ("  4) INCREASE TX PWR BY 2DB\n");
            printf ("  5) INCREASE TX PWR BY 3DB\n");
            printf ("  6) DECREASE TX PWR BY 1DB\n");
            printf ("  7) DECREASE TX PWR BY 2DB\n");
            printf ("\n");
            printf ("Select 0-7 for Field-%d [0]: ", count+1);

            gets(str);
            str_temp_wr = str; 
            while ( *str_temp_wr++ == ' '); 
            if (strlen(--str_temp_wr))  
              sscanf (str_temp_wr,"%d",&data_val);
            else
              data_val = 0;

            if ((data_val < 0) || (data_val > 7)) {
              printf("Invalid Data Entered");
              break;
            }
            bs_req.msg[count].cmd = data_val;
            printf ("\n");
            printf ("Enter bin number (0 to 2047) [0]: ");

            gets(str);
            str_temp_wr = str; 
            while ( *str_temp_wr++ == ' '); 
            if (strlen(--str_temp_wr))  
              sscanf (str_temp_wr,"%d",&data_val);
            else
              data_val = 0;

            if ((data_val < 0) || (data_val > 2047)) {
              printf("Invalid Data Entered");
              break;
            }
            bs_req.msg[count].sub_channel_idx = data_val;
          }
               
          for (; count < 4; count++)  {
            bs_req.msg[count].cmd = 0;
            bs_req.msg[count].sub_channel_idx = 0;
          }
          printf ("\nBit Swap Req: { 0xFF, ");
          for (count = 0; count < 4; count++)  {
            printf ("{%d, %d}", bs_req.msg[count].cmd, bs_req.msg[count].sub_channel_idx);
            if (count < 3) printf(", ");
          }
          printf ("}\n");
          printf ("Do you want to send it (y/n) [y]:");
            
          gets(str);
          str_temp_wr = str; 
          while ( *str_temp_wr++ == ' '); 
          if (strlen(--str_temp_wr) == 0) 
            *str_temp_wr = 'y';

          if (*str_temp_wr == 'n') {
            printf ("Bit Swap message not sent\n");
            break;
          }
          ConvertBitSwapReqStructToMsg (&bs_req, str_data);
          for (count=0; count<=10; count++) {
            sprintf (&str_temp[2*count], "%02x", str_data[count]);
          }
          str_temp[22] = '\0';
          printf("BitSwapMsg Sent: %s\n", str_temp);
          sprintf(str,"bitswapreq:0:%i:%i:%x:%s;", pid.bmeNum, pid.portNum, 0x1, str_temp);
          ReceiveTLCommand (str);
          print_Bit_Swap_Menu = 0;
          stop_Bit_Swap = 0;
        break;

        case 99 :
          stop_Bit_Swap = 0;
        break;

        default :
          stop_Bit_Swap = 1;
          print_Bit_Swap_Menu = 1;
        break;

      } /* End of switch (Bit_SwapCmd) */

   } /* End of while (stop_Bit_Swap) */
   
} /* End of uiBitSwapMenu */

