/*
 *  Copyright (c) 1996-2007 Digi International Inc., All Rights Reserved
 *
 *  This software contains proprietary and confidential information of Digi
 *  International Inc.  By accepting transfer of this copy, Recipient agrees
 *  to retain this software in confidence, to prevent disclosure to others,
 *  and to make no use of this software other than that for which it was
 *  delivered.  This is an unpublished copyrighted work of Digi International
 *  Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 *  prohibited.
 *
 *  Restricted Rights Legend
 *
 *  Use, duplication, or disclosure by the Government is subject to
 *  restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 *  Technical Data and Computer Software clause at DFARS 252.227-7031 or
 *  subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 *  Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 *  Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 * =======================================================================
 *  This file contains startup dialog routines. THE CODE IN THIS FILE MUST 
 *  BE CUSTOMIZED TO SUPPORT YOUR APPLICATION HARDWARE.  The default 
 *  implementation supports the NET+OS development boards
 *                                                                        
 *                                                                        
 * Edit Date/Ver   Edit Description
 * ==============  ===================================================
 * LZ   02/08/00   added "printf("APPLICATION: %s\r\n", APP_DIALOG_APP_NAME)"
 * LZ   02/16/00   changed "Copyright (c) 1999" to "Copyright (c) 2000"
 * SW   03/06/00   cast return value of getchar() to char avoid a run time error
 * LZ   04/05/00   Added support for little endian.
 * LZ   06/06/00   Added more comments for NVM.
 *                 Added code to handle no NVM case.
 * DXL  07/06/00   netosConfigDialog () return -1 if APP_DIALOG_PORT is not defined 
 * LZ   07/12/00   if !nvParams.useDhcp, then print IP addresses.
 * PMJ  10/18/00   Updated to support dynamic PPP NVRAM parameters.
 * PMJ  10/19/00   Corrected problems with mislabeling of COM1 ports to COM2
 * PMJ  10/26/00   Removed private function NAResolve_MAC in place of public API.
 * NGUR 08/13/01   Add useAppConfh.
 * PMJ  03/20/02   Added root password protection to the system dialog on modification.
 * PMJ  03/22/02   Included dialog capabilities for root password, administrators 
 *                 password, Fixed Key setting and Kerberos parameters.
 * PMJ  03/29/02   Included dialog capabilities for SNTP Servers. 
 * PMJ  04/11/02   Included dialog capabilities for the Kerberos parameters: KDC address,
 *                 username, password, and realmname.   Cleaned up some application 
 *                 issues with the dialog.
 * PMJ  04/23/02   Corrected compiler Warnings.
 * SW   04/30/02   Added GNU support for redirecting std I/O
 * DXL  08/21/002  Use API define for application configuration; 
 *                  Removed unneccessary layeers if conditions
 *
 */

#include "bsp_sys.h"
#include "bsp_net.h"
#include "npttypes.h"
#include <bsp_api.h>

#if BSP_ENABLE_DIALOG
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "tx_api.h"
#include "appconf_api.h"
#include "boardParams.h"
#include "netosIo.h"
#include "netoserr.h"
#include "sysAccess.h"
#include "dialog.h"
#include "NASecurity.h"
#include "bsp_local.h"
#include "termios.h"
#include "narmapi.h"
#include "iam_params.h"
#include "naflash.h"

#if BSP_WANT_WPA
#include "wpa_api.h"
#endif

#if (BSP_WPS_START == TRUE)

#include "wps_api.h"
#include "bsp_fs.h"
#if (BSP_ENABLE_WCN_UFD == TRUE)
#include "wcn_ufd.h"
#endif

#endif

/*  For now -- a way to check that our platforms are done properly  */
#ifndef BSP_WANT_ETHERNET
#error BSP_WANT_ETHERNET not defined in bsp_net.h
#endif
#ifndef BSP_WANT_PPP
#error BSP_WANT_PPP not defined in bsp_net.h
#endif
#ifndef BSP_WANT_WIRELESS
#error BSP_WANT_WIRELESS not defined in bsp_net.h
#endif
#ifndef BSP_WANT_WPA
#error BSP_WANT_WPA not defined in bsp_net.h
#endif

#define SERIALNUMBER_LENGTH     8
#define MAX_IPADDRESS_LENGTH    15
#define NADIALOG_VERIFY         0x01
#define NADIALOG_CUSTOM_REPLY   0x02
#define NADIALOG_CUSTOM_DEF_YES 0x04
#define DIALOGUPDATED 0xFF
#define LAST_RESORT_BAUD_RATE   9600

static int fd;
static unsigned inch, outch, errch;

#ifdef NETOS_GNU_TOOLS
#include <stdio.h>
#include <unistd.h>
#include <sys/fcntl.h>  /* for open */
typedef _ssize_t (*readtype) (void *, char *, int);
typedef _ssize_t (*writetype) (void *, const char *, int);
extern void   _EXFUN(__sinit,(struct _reent *));
#define CHECK_INIT(fp) \
  do                                    \
    {                                   \
      if ((fp)->_data == 0)             \
        (fp)->_data = _REENT;           \
      if (!(fp)->_data->__sdidinit)     \
        __sinit ((fp)->_data);          \
    }                                   \
  while (0)
/* need to save cookies, and read/write only */
static void *readFn, *writeFn;
static int _infile, _outfile, _errfile;

#define SAVE_IO_FOR_DIALOG     CHECK_INIT(stdin); CHECK_INIT(stdout); CHECK_INIT(stderr);\
                readFn = stdin->_read; writeFn= stdout->_write;\
        inch = (int)stdin->_cookie; outch=(int)stdout->_cookie;errch=(int)stderr->_cookie;\
        _infile=stdin->_file; _outfile=stdout->_file; _errfile=stderr->_file;

#define RESTORE_IO               stdin->_read = (void*)readFn;stdout->_write= (void*)writeFn;\
        stdin->_cookie=(_PTR)inch; stdout->_cookie=(_PTR)outch;stderr->_cookie=(_PTR)errch;\
        stdin->_file=_infile; stdout->_file=_outfile; stderr->_file=_errfile;
#else
typedef int (*readtype) (void *, char *, int);
typedef int (*writetype) (void *, const char *, int);
#endif

#if BSP_ETH_WIFI_BRIDGE || BSP_WANT_ETHERNET
static bpDuplexLevelType kbGetDuplex(char * desc, bpDuplexLevelType setting);
#endif

#if BSP_WANT_ETHERNET || BSP_WANT_WIRELESS
static int promptForMacAddress (char *description, unsigned char *macAddress);
#endif
static int checkSerialNumber(char * buffer);

#if BSP_WANT_WIRELESS
static wln_country_code_t wln_country_code = COUNTRY_UNITED_STATES;
#define DFS_CHANNEL_MASK_LOW            (0x80000000)
#define DFS_CHANNEL_MASK_HIGH           (0x00003fff)
#endif

#if (BSP_WPS_START == TRUE)
static int dialogWPSEnabled = 0;
#endif

/*ad*
 * Determine if a baud rate is valid.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @param baudrate  baudrate to validate
 *
 * @return TRUE     baud rate is valid for dialog
 * @return FALSE    baud rate is not valid for dialog
*ad*/
static BOOLEAN isBaudRateValid(unsigned long baudrate)
{
    return ((baudrate == 1200)||(baudrate == 2400)||(baudrate == 4800)||(baudrate == 9600)||
           (baudrate == 19200)||(baudrate == 38400)||(baudrate == 57600)||(baudrate == 115200));
}

/*ad*
 * Get a baudrate that can be used for the dialog.  The selection is as follows.
 *
 * 1.  Use the baudrate passed to us if it is valid.
 * 2.  Next try the value returned by NAGetAppBspBaudRate().
 * 3.  If all else fails, use LAST_RESORT_BAUD_RATE.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @param tryThisOneFirst   suggested baud rate
 *
 * @return  baud rate to use for dialog
*ad*/
static unsigned long getUsableBaudrate(unsigned long const tryThisOneFirst)
{
    unsigned long result = LAST_RESORT_BAUD_RATE;
    
    if (isBaudRateValid(tryThisOneFirst))
    {
        result = tryThisOneFirst;
    }
    else if (isBaudRateValid(NAGetAppBspBaudRate()))
    {
        result = NAGetAppBspBaudRate();
    }
    
    return result;
}

#if BSP_ETH_WIFI_BRIDGE || BSP_WANT_ETHERNET
/*ad*
 * Determine if the duplex setting is within range.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @param   setting     duplex setting to validate
 *
 * @return TRUE         is in range
 * @return FALSE        out of range
*ad*/
static BOOLEAN isDuplexValid(bpDuplexLevelType setting)
{
    return ((setting == bpHalfDuplex) || (setting == bpFullDuplex) || (setting == bpDefaultDuplex));
}

        

/*ad*
 * Return a text description of the duplex setting.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @param setting       duplex setting to translate to a text string
 *
 * @return "Half Duplex"    half duplex setting
 * @return "Full Duplex"    full duplex setting
 * @return "Default"        use default duplex setting of hub
 * @return "Invalid Duplex Setting" duplex setting is out of range
*ad*/
static char * getDuplexString(bpDuplexLevelType setting)
{
    char *result = "Invalid Duplex Setting";
    static char * const duplexString[] = {"half", "full", "default"};
    
    if (isDuplexValid(setting))
    {
        result = duplexString[setting];
    }
    
    return result;
}
#endif /* BSP_WANT_ETHERNET */

/*ad*
 *
 * Sets up stdin, stdout, and stderr to be redirected
 * out the @link BSP_DIALOG_PORT if @link BSP_ENABLE_DIALOG is defined.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 * @see @link BSP_ENABLE_DIALOG
 * @see @link BSP_DIALOG_PORT
 *
 * @param     flag              0: NONBLOCK I/O
 *                              1: BLOCK I/O
 * @param     nvParamsPtr       Pointer to structure with development board parameters
 *
 * @return    >0                channel ID
 *
*ad*/
static int NAOpenDialog(int flag, devBoardParamsType * nvParamsPtr)
{
    int rc;
    unsigned long baudrate;
    struct termios tios;

#ifdef NETOS_GNU_TOOLS
    SAVE_IO_FOR_DIALOG
#elif defined(__CC_ARM)
        /* Save IO */
    inch = stdin->handle;
    outch = stdout->handle;
    errch = stderr->handle;
#else
    /* Save IO */
    inch = stdin->io_channel;
    outch = stdout->io_channel;
    errch = stderr->io_channel;
#endif

    /* open device */
    if (flag == 0)
    {
        fd = open (NAGetAppDialogPort (), (O_RDWR | O_NONBLOCK) );
    }
    else
    {
       fd = open (NAGetAppDialogPort (), O_RDWR );
    }
        
    if (fd <0)
    {
        netosFatalError("APP_DIALOG_PORT improperly defined", ERROR_CLASS_BSP, ERROR_BAD_DIALOG_PORT);
        return -1;
    }

#ifdef NETOS_GNU_TOOLS
    CHECK_INIT(stdin);
    CHECK_INIT(stdout);
    CHECK_INIT(stderr);
    
    /* need to override the following so that
       std I/O will call into DDI */
    stdout->_cookie = (_PTR)fd;
    stdout->_file =fd;
    stdin->_cookie = (_PTR)fd;
    stdin->_file = fd;
    stderr->_cookie = (_PTR)fd;
    stderr->_file = fd;
    stdin->_read = (readtype)read;
    stdout->_write = (writetype)write;
    stderr->_write = (writetype)write;
#elif defined(__CC_ARM)
    stdin->handle = fd;
    stdout->handle = fd;
    stderr->handle = fd;
#else
    stdin->io_channel = fd;
    stdout->io_channel = fd;
    stderr->io_channel = fd;
#endif
    
    baudrate = getUsableBaudrate(nvParamsPtr->baudrate);
    
        tcgetattr(fd, &tios);
        cfsetospeed(&tios, baudrate);
        rc = tcsetattr(fd, TCSANOW, &tios);
     
    if (rc < 0) 
    {
        netosFatalError("error when change baud rate in Dialog.c", ERROR_CLASS_BSP, ERROR_INVALID_DIALOG_BAUDRATE);
    }

    /* give serial driver a chance to fully initialize and stabilize */
    tx_thread_sleep(BSP_TICKS_PER_SECOND);

    return fd;
}

/*ad*
 *
 * Print out the board's IP address with descriptions.
 *
 * @param   buffer    points to the string which contains some descriptions.
 * @param   ip        ip address
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD SHOULD YOU USE DIFFERENT 
 *          DISPLAY FORMAT. The implementation below is for NET+OS development 
 *          boards only.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 *
*ad*/ 
static void printIpAddress(char * buffer, unsigned long ip)
{
#ifndef _LITTLE_ENDIAN
    printf(buffer, (ip >> 24) & 0xFF,
                   (ip >> 16) & 0xFF,
                   (ip >> 8)  & 0xFF,
                   (ip) & 0xFF);
#else
    printf(buffer, (ip) & 0xFF,
                   (ip >> 8)  & 0xFF,
                   (ip >> 16) & 0xFF,
                   (ip >> 24) & 0xFF);
#endif
}

#if BSP_WANT_ETHERNET || BSP_WANT_WIRELESS

static void printIpv6Address(char * buffer, struct sockaddr_storage *address)
{
	char addrString[MAX_IP_ADDR_STR_LEN];
    
	if (inet_ntop(address->ss_family, &address->addr.ipv6.sin6_addr, addrString, MAX_IP_ADDR_STR_LEN))
		printf(buffer, addrString);
}


/*ad*
 *
 * Print out the board's MAC address with descriptions.
 *
 * @param   buffer    points to the string which contains some descriptions.
 * @param   mac       points to the array which contains the MAC address
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD SHOULD YOU USE DIFFERENT 
 *          DISPLAY FORMAT. The implementation below is for NET+OS development 
 *          boards only.
 *
*ad*/ 
static void printMacAddress(char * buffer, BYTE * mac)
{
    printf(buffer, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
#endif

/*ad*
 *
 * Gets one line of the information input from keyboard.
 * It prints out the information as well.
 *
 * @param   buf     points to an array to hold the information
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
*ad*/ 
static void readLine(char * buf)
{
  char character;
  int i = 0;
  do
  {
    character = getchar();
    if (character == '\b') 
    {
       if (i > 0)
       {
          putchar(character);
          putchar(0x20);   /*space*/
          putchar(character);
          --i;
       }
    }
    
    else if (character != '\n')
    {
       buf[i] = character;
       putchar(character);
       ++i;
    }
    fflush(stdout);
  }
  while (character != '\r');
  putchar('\n');
  
  buf[i-1] = '\0';
}  

/*ad*
 *
 * Gets new password input from keyboard.
 * Prints out "***" while getting information.
 *
 * @param   buf         Points to an array that holds the new password.
 * @param   buffersize  Size of the bufffer used to hold the password string.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
*ad*/ 
static void readPassword(char * buf, unsigned int buffersize)
{
    char character;
    unsigned int i = 0;

    do
    {
        character = getchar();
        if (character == '\b') 
        {
            if (i > 0)
            {
                putchar(character);
                putchar(0x20);   /*space*/
                putchar(character);
                --i;
            }
        }
        else if ((character != '\r') && (character != '\n'))
        {
            buf[i] = character;
            putchar('*');

            /*  We need to reserve one character for the NUL at the end  */
            if (i < buffersize - 1)
            {
                ++i;
            }
        }
        fflush(stdout);
    }
    while ((character != '\r') && (character != '\n'));
    putchar('\r');
    putchar('\n');
  
    buf[i] = '\0';
}
/*ad*
 *
 * Displays items asking if you would like to update,
 * and waits for yes or no
 *
 * @param   itemDesc    Points to the string which contains description of the item.
 * @param   flag        Indicates how the item description is going to be displayed.
 *
 * @return  0           No update, keep the old setting.
 * @return  1           Yes, we need to change the setting.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
*ad*/  
static int kbGetReply(char * itemDesc, int flag)
{
    int reply;
    char buffer[128];

    while (1)
    {
        fflush(stdout);
        if (flag & NADIALOG_CUSTOM_REPLY)
        {
            printf ("%s ", itemDesc);
            fflush(stdout);

        }
        else
        {
            printf ("Would you like to update the %s ", itemDesc);
            fflush(stdout);
        }
        if (flag & NADIALOG_CUSTOM_DEF_YES)
        {
            printf ("[Y]? ");
            fflush(stdout);
        }
        else
        {
            printf ("[N]? ");
            fflush(stdout);
        }

        readLine (buffer);
        if (buffer[0] == 'y' || buffer[0] =='Y')
        {
            reply = 1;
            break;
        }
        if (buffer[0] == 'n' || buffer[0] =='N')
        {
            reply = 0;
            break;
        }
        if (buffer[0] == '\0')
        {
            reply = ((flag & NADIALOG_CUSTOM_DEF_YES) != 0);
            break;
        }
    }
    return (reply);
}

#if BSP_WANT_ETHERNET || BSP_WANT_WIRELESS
/*
 *
 *  Function: static int kbGetNumber (char *descr, int *value, int min, int max)
 *
 *  Description:
 *
 *      This routine gets a number from the keyboard.
 *
 *  Parameters:
 *
 *      descr       description string displayed to user
 *      value       default value and returned result
 *      min         minimum allowed value
 *      max         maximum allowed value
 *
 *  Return Values:
 *
 *      0             no update, value unchanged
 *      1             updated     
 *
 */ 
static int kbGetNumber(char * descr, int * value, int min, int max)
{
    char buffer[128];
    int n, result;

    while (1)
    {
        fflush(stdout);
        printf(descr, *value);
        fflush(stdout);
        readLine(buffer);  
        if (buffer[0] == '\0')
            return 0;
            
        n = sscanf(buffer, "%d", &result);
        if (n == 1 && result >= min && result <= max)
        {
            *value = result;
            return 1;
        }
        
        printf("Please enter a number between %d and %d\r\n", min, max);
    }  
}
#endif

#if BSP_WANT_WIRELESS

/* Description of each wireless protocol mode */
static const char *wln_modes[] = {
    "for any available wireless network", /* was "Infrastructure", */
    "for access point (infrastructure) networks only", /* was Ad hoc (join or create)", */
    "for peer-to-peer (ad hoc) networks only)", /* was "Ad hoc (join only)" */
    "do not join a BSS", /* added as monitor mode */
#if (BSP_WPS_START == TRUE)
    "start Wi-Fi Protected Setup", /* Wifi Protected Setup */
#endif
};
static wln_bss wln_modes_value[] = {
    WLN_BSS_ANY, 
    WLN_BSS_ESS,
    WLN_BSS_IBSS,
    WLN_BSS_NONE,
#if (BSP_WPS_START == TRUE)
    WLN_BSS_WPS,
#endif
};

/* Description of each wireless authorization mode */
static const char *wln_auth_modes[] = {
    "Any available authentication", 
    "Shared Key", 
    "WEP (802.1x)",
    "WPA Personal (WPA-PSK)",
    "WPA Enterprise (802.1x)",
    "Cisco LEAP",
    "Open System",
    "Cisco EAP FAST"
};

/* Description of each wireless transmit rate */
static const char *wln_tx_rate[] = { 
    "1", 
    "2",
    "5.5",
#ifdef BSP_ARM9                 
    "6",
    "9",
#endif
    "11",
#ifdef BSP_ARM9
    "12",
    "18",
    "24",
    "36",
    "48",
    "54",
#endif
};

static int wln_txrate_list[] = 
{
    10,   /* 1 mbps */
    20,   /* 2 mbps */
    55,   /* 5.5 mbps */        
#ifdef BSP_ARM9                 
    60,   /* 6 mbps */          
    90,   /* 9 mbps */  
#endif  
    110,  /* 11 mbps */
#ifdef BSP_ARM9         
    120,  /* 12 mbps */ 
    180,  /* 18 mbps */
    240,  /* 24 mbps */ 
    360,  /* 36 mbps */ 
    480,  /* 48 mbps */ 
    540   /* 54 mbps */
#endif
};

static int wln_txrate_num = (sizeof wln_txrate_list)/(sizeof wln_txrate_list[0]); 

#ifdef BSP_ARM9
/* Description of each frequency band */
static const char *wln_frequency_band[] = {
        "all bands: a, b and g",
        "band a only", 
        "band b only",   
        "band bg only",    
};

static int wln_txrate_list_b[] = 
{
    10,   /* 1 mbps */
    20,   /* 2 mbps */
    55,   /* 5.5 mbps */        
    110,  /* 11 mbps */
};
static const char *wln_tx_rate_b[] = { 
    "1", 
    "2",
    "5.5",
    "11",
};
static int wln_txrate_num_b = (sizeof wln_txrate_list_b)/(sizeof wln_txrate_list_b[0]); 
#endif

/* Description of wireless transmit power level */
static const char *wln_tx_power[] = {
    "maximum", 
    "normal", 
    "low"
};

static int wln_txpwr_list[] = 
{
    16,
    12,
    8
};

static int wln_txpwr_num = (sizeof wln_txpwr_list)/(sizeof wln_txpwr_list[0]); 

#define MAP_INDEX_TO_TXRATE_BIT   0
#define MAP_TXRATE_BIT_TO_INDEX   1

#define MAP_INDEX_TO_TXPWR_VALUE   0
#define MAP_TXPWR_VALUE_TO_INDEX   1

#define IS_B_BAND_ONLY             1
#define IS_NOT_B_BAND_ONLY         0

#if (AIROHA_TRANSCEIVER == TRUE) 
extern BOOLEAN isRF_AIROHA_7230(void);
#endif // (AIROHA_TRANSCEIVER == TRUE) 

static int getWlnTxRateMappedIdx(int idx, int isTxRate, int isBOnly)
{
    int retVal=0, i = 0, real_wln_txrate_num = wln_txrate_num, *real_wln_txrate_list = wln_txrate_list;

#ifdef BSP_ARM9   
    if (isBOnly == IS_B_BAND_ONLY)
    {
        real_wln_txrate_num = wln_txrate_num_b;
        real_wln_txrate_list = wln_txrate_list_b;
    }
#else
   (void)isBOnly; 
#endif
    if (isTxRate == MAP_INDEX_TO_TXRATE_BIT)
    {
        if (idx < real_wln_txrate_num)
            retVal = real_wln_txrate_list[idx];
    }
    else
    {
        /* Find display value. */
        while (i < real_wln_txrate_num)
        {
            if (real_wln_txrate_list[i] == idx)
                break; 
            i++;
        }

        retVal = (i < real_wln_txrate_num) ? i:0;
    }

    return retVal;              
}

static int kbGetTxRate(char *descr, int *value, int isBOnly)
{
    char buffer[128], *real_wln_tx_rate[20];
    int n, real_wln_txrate_num = wln_txrate_num;
    
    memcpy(real_wln_tx_rate , wln_tx_rate, sizeof real_wln_tx_rate );
#ifdef BSP_ARM9 
    if (isBOnly == IS_B_BAND_ONLY)
    {
        real_wln_txrate_num = wln_txrate_num_b;
        memcpy(real_wln_tx_rate , wln_tx_rate_b, sizeof real_wln_tx_rate );
    }
#else
   (void)isBOnly; 
#endif

    while (1)
    {
        printf(descr, *value);
        printf("    ");
        fflush(stdout);
        for (n=0; n < real_wln_txrate_num; n++)
        {
            printf("%s", real_wln_tx_rate[n]);  
            fflush(stdout);
            if (n < real_wln_txrate_num-1)
                printf(", ");
            else
                printf(" Mbps: ");
            fflush(stdout);
        }

        readLine(buffer);  

        if (buffer[0] == '\0')
            return 0;
            
        for (n=0; n < real_wln_txrate_num; n++)
        {
            if (!strcmp(buffer, real_wln_tx_rate[n]))
            {
                *value = n;
                return 1;
            }
        }
    }  
}

static int getWlnTxPwrMappedIdx(int idx, int isTxPwr)
{
    int retVal = 0, i=0;

    if (isTxPwr == MAP_INDEX_TO_TXPWR_VALUE)
    {
        if (idx < wln_txpwr_num)
            retVal = wln_txpwr_list[idx];
        else
            retVal = WLN_TXPOWER_DEFAULT;         
    }
    else if (idx <= WLN_TXPOWER_MAX)
    {    
        /* Find display value. */
        while (i < wln_txpwr_num)
        {
            if (wln_txpwr_list[i] == idx)
                break; 
            else
            {   // handle the case where user entered intermediate value
                if (i < (wln_txpwr_num - 1))
                {
                    if (idx > wln_txpwr_list[i+1])
                        break; 
                }
                else
                {
                    if (idx >= WLN_TXPOWER_MIN)
                        break; 
                }
            }
            i++;
        }

        retVal = (i < wln_txpwr_num) ? i:0;
    }

    return retVal;              
}

#if BSP_WANT_WPA
/* Description of each wireless encryption mode */
static const char *wln_encrypt_modes[] = {
    "Any available encryption", 
    "WEP", 
    "TKIP",
    "CCMP (AES)",
    "Open System (no encryption)",
};
#ifdef EAP_SUPPORT_TYPES
/* Description of each wireless outer EAP mode */
static const char *wln_outer_eap_modes[] = {
    "Any", 
    "PEAP", 
    "TLS",
    "TTLS",
};

/* Description of each wireless inner EAP mode */
static const char *wln_inner_eap_modes[] = {
    "Any", 
    "GTC", 
    "MD5",
    "MSCHAPV2",
    "OTP",
    "CHAP",         
    "MSCHAP",
    "TTLS_MSCHAPV2",
    "PAP",          
    "NONE", 
};
#endif
#endif

/*
 *
 *  Function: static void printWirelessParams (devBoardParamsType *nvParamsPtr)
 *
 *  Description:
 *
 *      This routine prints all wireless parameters.
 *
 *  Parameters:
 *
 *      nvParamsPtr     pointer to structure with development board parameters
 *
 */ 
static void printWirelessParams(devBoardParamsType * nvParamsPtr)
{
    int oldAuth = 0;
    int idx, i;
    int current_bss_type = 0;

    NaIamParams_t *interface = customizeIamFindInterfaceConfig(BP_WLN_INTERFACE, &nvParamsPtr->iamParamsInfo);
    if (interface == NULL)
    {
        /* Find an unused config record, but don't overwrite ethernet */
        interface = customizeIamFindUnusedInterfaceConfig(&nvParamsPtr->iamParamsInfo, FALSE);
        if (interface)
            customizeIamGetDefaultInterfaceConfig(BP_WLN_INTERFACE, interface);
    }

#if !BSP_ETH_WIFI_BRIDGE
    if (interface)
    {
        if (interface->staticParams.isEnabled)
        {
            printIpAddress("  Wireless IP address is %d.%d.%d.%d\r\n", interface->staticParams.IPV4_ADDR(ipAddress));
            printIpAddress("  Wireless subnet mask is %d.%d.%d.%d\r\n", interface->staticParams.subnetMask);
            printIpAddress("  Wireless IP address of default gateway to other networks is %d.%d.%d.%d\r\n", interface->staticParams.IPV4_ADDR(gateway));
        }
        else
        {
            printf("  The board will obtain wireless IP configuration parameters from the network.\r\n");
        }
		if (NaIpv6IsDhcpEnabled(interface))
		{
			printf("  DHCPv6 is enabled on wireless interface\r\n");
		}
		if (NaIpv6IsStaticEnabled(interface))
		{
			printIpv6Address("  Wireless IPv6 static  address is %s", &interface->staticParams.ipv6Address);
			printf(" prefixlen %d\r\n", interface->staticParams.ipv6PrefixLen);
		}
    }
#endif

    if (wln_is_country_valid((wln_country_code_t)nvParamsPtr->wlnExtParams.wlnCountryCode))    
        printf("  Wireless country name configured is %s\r\n", wln_get_country_string_from_code((wln_country_code_t)nvParamsPtr->wlnExtParams.wlnCountryCode));
    else
        printf("  Wireless country name is not configured\r\n");

    fflush(stdout);

    for (i =0; i < (int)asizeof(wln_modes_value); i++)
    {
        if (nvParamsPtr->wlnParams.bss_type == wln_modes_value[i])
        {
            current_bss_type = i;
            break;
        }
    }

#if (BSP_WPS_START == TRUE)
    if (dialogWPSEnabled == 1)
    {
        for (i =0; i < (int)asizeof(wln_modes_value); i++)
        {
            if (WLN_BSS_WPS == wln_modes_value[i])
            {
                current_bss_type = i;
                break;
            }
        }
        printf("  Wireless protocol mode is to %s\r\n", wln_modes[current_bss_type]);
        goto _ret;
    }
#endif

    if (nvParamsPtr->wlnParams.bss_type <= WLN_BSS_NONE) 
        printf("  Wireless protocol mode is %s\r\n", wln_modes[current_bss_type]);
        
    if (nvParamsPtr->wlnParams.ssid_len == 0)
        printf("  Wireless SSID is (search)\r\n");
    else
        printf("  Wireless SSID is %.*s\r\n", nvParamsPtr->wlnParams.ssid_len, nvParamsPtr->wlnParams.ssid);

#ifdef BSP_ARM9
#if (AIROHA_TRANSCEIVER == TRUE ) 
    if (isRF_AIROHA_7230())
    {
        if (nvParamsPtr->wlnParams.band >= WLN_BAND_MAX) 
            nvParamsPtr->wlnParams.band = WLN_BAND_ALL;
            
        printf("  Frequency band is %s\r\n", wln_frequency_band[nvParamsPtr->wlnParams.band]);
    }
    else
#endif // (AIROHA_TRANSCEIVER == TRUE)     
    {
        if (nvParamsPtr->wlnParams.band == WLN_BAND_B)
            printf("  Frequency band is band b only\r\n");
        else
        {
            if (nvParamsPtr->wlnParams.band != WLN_BAND_BG)
                nvParamsPtr->wlnParams.band = WLN_BAND_BG;
            printf("  Frequency band is band bg\r\n");
        }
    }
    
    if ((nvParamsPtr->wlnParams.band == WLN_BAND_B || nvParamsPtr->wlnParams.band == WLN_BAND_BG) &&
        (nvParamsPtr->wlnParams.channel > 14))
    {
        nvParamsPtr->wlnParams.channel = WLN_CHAN_SCAN;
    }

    if(nvParamsPtr->wlnParams.channel == WLN_CHAN_SCAN)
    {
        printf("  Wireless channel is (search %s )\r\n", wln_frequency_band[nvParamsPtr->wlnParams.band]);
    }
    else
    {
        int n = wln_get_chan_info(nvParamsPtr->wlnParams.channel, NULL);
        
        if (nvParamsPtr->wlnParams.channel > 14)
            printf("  Wireless channel is a%d\r\n", n);   
        else
            printf("  Wireless channel is %d\r\n", n);   
    }
#else  // BSP_ARM9
    printf("  Frequency band is band b only\r\n");

    if(nvParamsPtr->wlnParams.channel == WLN_CHAN_SCAN)
        printf("  Wireless channel is (search)\r\n");
    else
        printf("  Wireless channel is %d\r\n", nvParamsPtr->wlnParams.channel);
#endif // (AIROHA_TRANSCEIVER == TRUE)    

    fflush(stdout);
#ifdef BSP_ARM9
    if (nvParamsPtr->wlnParams.band == WLN_BAND_B)
    {
        idx = getWlnTxRateMappedIdx(nvParamsPtr->wlnParams.tx_rate, MAP_TXRATE_BIT_TO_INDEX, IS_B_BAND_ONLY);   
        printf("  Wireless transmit rate is %s\r\n", wln_tx_rate_b[idx]);  
    }
    else
#endif
    {
        idx = getWlnTxRateMappedIdx(nvParamsPtr->wlnParams.tx_rate, MAP_TXRATE_BIT_TO_INDEX, IS_NOT_B_BAND_ONLY);                 
        printf("  Wireless transmit rate is %s\r\n", wln_tx_rate[idx]);
    }
    idx = getWlnTxPwrMappedIdx(nvParamsPtr->wlnParams.tx_power, MAP_TXPWR_VALUE_TO_INDEX);
    printf("  Wireless transmit power is set to %s\r\n", wln_tx_power[idx]);
        
    /* Spectrum management & multi domain enabled? */
    if (nvParamsPtr->wlnParams.options & WLN_OPT_SPECTRUM_MGMT)
        printf("  Wireless spectrum management (802.11h) and  multi domain (802.11d) enabled\r\n");
    else if (nvParamsPtr->wlnParams.options & WLN_OPT_MULTI_DOMAIN)
        printf("  Wireless multi domain capability (802.11d) enabled\r\n");
    else
    {
#if (AIROHA_TRANSCEIVER == TRUE)
        if (isRF_AIROHA_7230())
            printf("  Wireless spectrum management (802.11h) and  multi domain (802.11d) disabled\r\n");
        else
#endif
            printf("  Wireless multi domain capability (802.11d) disabled\r\n");
    }
        
    /* duty cycle enabled? */
#ifdef MAC_PS_ENABLED
#if BSP_WIFI_DUTY_CYCLE_CONFIG_ENABLE
    if (nvParamsPtr->wlnParams.options & WLN_OPT_PS_ENABLE)
        printf("  Wireless powersave/duty cycle enabled [ON:%d msec, OFF:%d msec\r\n", 
                  nvParamsPtr->wlnExtParams.dutyCycle.ontime, nvParamsPtr->wlnExtParams.dutyCycle.offtime);
    else
        printf("  Wireless powersave/duty cycle disabled\r\n");
#endif
#endif

    /* Find old auth for display */
#if BSP_WANT_WPA
    if (nvParamsPtr->wlnParams.authen == WLN_AUTH_ANY) {
        oldAuth = 0;
    } 
    else
#endif
    if (nvParamsPtr->wlnParams.authen == WLN_AUTH_OPEN) {
        oldAuth = 6;
    } 
#if !BSP_WANT_WPA
    else if (nvParamsPtr->wlnParams.authen & WLN_AUTH_SHAREDKEY) {
        oldAuth = 1;                
    }
#endif   //!BSP_WANT_WPA
#if BSP_WANT_WPA
    else if (nvParamsPtr->wlnParams.authen == WLN_AUTH_ANY) {
        oldAuth = 0;
    } 
    else if (nvParamsPtr->wlnParams.authen & WLN_AUTH_SHAREDKEY) {
        oldAuth = 1;                
    }
    else if (nvParamsPtr->wlnParams.authen & WLN_AUTH_WEP_8021X) {
        oldAuth = 2;                
    } else if (nvParamsPtr->wlnParams.authen & WLN_AUTH_WPA_PSK) {
        oldAuth = 3;                
    } else if (nvParamsPtr->wlnParams.authen & WLN_AUTH_WPA_8021X) {
        oldAuth = 4;                
    } else if (nvParamsPtr->wlnParams.authen & WLN_AUTH_LEAP) {
        oldAuth = 5;                
    } else if (nvParamsPtr->wlnParams.authen & WLN_AUTH_EAP_FAST) {
        oldAuth = 7;
    }
                                        
    /* Authentication type */
    printf("  Authentication type = %s\r\n", wln_auth_modes[oldAuth]);   
    
    
    /* encryption type */
    if (nvParamsPtr->wlnParams.encrypt == WLN_ENCR_OPEN) {
        oldAuth = 4;
    } else if (nvParamsPtr->wlnParams.encrypt == WLN_ENCR_ANY) {
        oldAuth = 0;
    } else if (nvParamsPtr->wlnParams.encrypt & WLN_ENCR_WEP) {
        oldAuth = 1;
    } else if (nvParamsPtr->wlnParams.encrypt == WLN_ENCR_TKIP) {
        oldAuth = 2;
    } else if (nvParamsPtr->wlnParams.encrypt == WLN_ENCR_CCMP) {
        oldAuth = 3;
    } else
        oldAuth = 0;
    printf("  Encryption type = %s\r\n", wln_encrypt_modes[oldAuth]);      
#else
    /* Authentication type */
    printf("  Authentication type = %s\r\n", wln_auth_modes[oldAuth]);    
    
    /* encryption type */
    if (nvParamsPtr->wlnParams.encrypt & WLN_ENCR_WEP)
        printf("  Encryption type = WEP\r\n");
    else
        printf("  Encryption type = Open System (no encryption)\r\n");
#endif    

#if (BSP_WPS_START == TRUE)
_ret:
#endif
    return;

}


/*
 *
 *  Function: static int kbGetChannel (char *descr, int *value, int search)
 *
 *  Description:
 *
 *      This routine gets a number from the keyboard.
 *
 *  Parameters:
 *
 *      band        current band selected by user
 *      value       default value and returned result
 *      search      if set user will be allowed to enter 0
 *
 *  Return Values:
 *
 *      0             no update, value unchanged
 *      1             updated     
 *
 */ 
static int kbGetChannel (int band, int *value, BOOL search, BOOL spect_mgmt)
{
    char buffer[128];
    int n, result, max, min;
    uint32 mask[2];

    if (wln_get_channel_mask(wln_country_code, (unsigned long *)mask) < 0)
        return 0;
        
    max = ((band == WLN_BAND_B) || (band == WLN_BAND_BG)) ? 14 : WLN_CHAN_NUM;
    min = (band == WLN_BAND_A) ? 17 : 1;
        
    if (!spect_mgmt)
    {
        mask[0] &= ~DFS_CHANNEL_MASK_LOW;
        mask[1] &= ~DFS_CHANNEL_MASK_HIGH;
    }
        
    while (1)
    {
        fflush(stdout);
        n = wln_get_chan_info(*value, NULL);
        if (*value > 14)
            printf("\r\nChannel number: enter 0 for search [a%d]?", n);
        else
            printf("\r\nChannel number: enter 0 for search [%d]?", n);

        fflush(stdout);
        readLine(buffer);  
        if (buffer[0] == '\0')
        {
            n = 1;
            result = *value;
        }
        else
        {
            BOOL chan_11a = FALSE;
            
            if ((buffer[0] == 'a') || (buffer[0] == 'A'))
            {
                chan_11a = TRUE;                
                n = sscanf(&buffer[1], "%d", &result);
            }
            else
            {
                n = sscanf(buffer, "%d", &result);
            }
            
            result = wln_is_channel_supported(mask, result, chan_11a);
        }

        if (n == 1 && search && result == 0) /* allow channel 0 */
        {
            *value = result;
            return 1;
        }
        else if (n == 1 && result >= min && result <= max && 
                 mask[(result-1)/32] & (1 << (result-1)%32))
        {
            *value = result;
            return 1;
        }
        else
        {
            if (search)
                printf("Enter 0 for search \r\n");
            printf("Valid channel numbers are:");
            for (n = min; n <= max; n++)
            {
                if (mask[(n-1)/32] & (1 << (n-1)%32))
                {
                    if (n > 14)
                        printf("a%d, ", wln_get_chan_info(n, NULL));
                    else
                        printf("%d, ", wln_get_chan_info(n, NULL));
                }
            }
        } 
    }  
}

/*
 *
 *  Function: static int kbGetStringLimit (char *descr, char *value, int min, int max)
 *
 *  Description:
 *
 *      This routine gets a number from the keyboard.
 *
 *  Parameters:
 *
 *      descr       description string displayed to user
 *      value       default value and returned result
 *      min         minimum allowed characters
 *      max         maximum allowed characters
 *
 *  Return Values:
 *
 *      0             no update, value unchanged
 *      1             updated     
 *
 */ 
static int kbGetStringLimit(char * descr, char * value, int min, int max)
{
    char buffer[128];
    int n;

    while (1)
    {
        printf(descr, value);
        fflush(stdout);
        readLine(buffer);  
        n = strlen(buffer);
        if (n == 0)
            return 0;
        if (n >= min && n <= max)
        {
            strcpy(value, buffer);
            return 1;
        }
        
        printf("Please enter a string of %d to %d characters\r\n", min, max);
    }  
}

/*
 *
 *  Function: static int kbGetCountryCode (char *descr, char *value)
 *
 *  Description:
 *
 *      This routine gets a country code from the user.
 *
 *  Parameters:
 *
 *      descr       description string displayed to user
 *      value       default value and returned result
 *
 *  Return Values:
 *
 *      0             no update, value unchanged
 *      1             updated     
 *
 */ 
static int kbGetCountryCode(char * descr, unsigned long * value)
{
    char buffer[128];
    int n;
    wln_country_code_t code;

    while (1)
    {
        printf(descr, wln_get_country_string_from_code((wln_country_code_t)*value));
        fflush(stdout);
        readLine(buffer);  
        n = strlen(buffer);
        if (n == 0)
            return 0;

        code = wln_get_country_code_from_string(buffer);
        if (code != COUNTRY_NOTFOUND)
        {
            if (wln_is_country_valid(code))
            {
                *value = (unsigned long)code;
                return 1;
            }
        }

        printf("Got the approval from following countries... \r\n");
        wln_print_supported_countries();
    }  
}

/*
 *
 *  Function: static int kbGetWEPKey (int idx, NaWlnParams_t *params)
 *
 *  Description:
 *
 *      This routine gets a new WEP key from the keyboard.
 *
 *  Parameters:
 *
 *      idx       index of key (0-3)
 *      params      points to wireless parameters
 *
 *  Return Values:
 *
 *      0             no update, keep the old setting
 *      1             updated     
 *
 */ 
static int kbGetWEPKey(int idx, NaWlnParams_t * params)
{
    char buffer[128];
    unsigned char key[WLN_WEP104_SIZE];
    int i, n;
    
    while (1)
    {
        printf("WEP key %d [no change]? ", idx);
        fflush(stdout);
        readLine(buffer);  
        if (buffer[0] == '\0')
            return 0;
            
        for (i = 0; i < WLN_WEP104_SIZE; i++)
        {
            if (isxdigit(buffer[2*i]) && isxdigit(buffer[2*i+1]) &&
                sscanf(&buffer[2*i], "%2x", &n) == 1)
                    key[i] = n;
            else
                break;
        }
        
        if (i == WLN_WEP40_SIZE || i == WLN_WEP104_SIZE)
        {
            params->wep_key_len = i;
            memcpy(params->wep_key[idx], key, i);
            return 1;
        }

        printf("Please enter a 10 or 26 digit hex number\r\n");
    }
}

/*
 *
 *  Function: static int NAWirelessDialog (NaWlnParams_t *wp)
 *
 *  Description:
 *
 *      This routine gets the new wireless parameters.
 *
 *  Parameters:
 *
 *      wp     pointer to structure with wireless parameters
 *
 *  Return Values:
 *
 *      0:     no updates
 *      1:     some or all network information are updated
 *
 */ 
static int NAWirelessDialog(NaWlnParams_t * wp) 
{
    char buffer[256];
    int i, flag, result;
#if BSP_WANT_WPA    
    char buffer2[128];
    int encrypt = 0;
    int authen = 0; 
    int wpaFlag = 0;
    uint32 current_encrypt;
#endif  
    uint32 old_auth = wp->authen;
    uint32 old_encrypt = wp->encrypt;
    int oldAuth = 0;
    int oldEncrypt = 0;
    int txRate = 0;
    int txPower = 0;
    
#ifdef EAP_SUPPORT_TYPES    
    uint32 old_eap_methods = wp->eap_methods;
    uint32 current_eap_methods;
#endif

    uint32 current_bss_type = 0; 

#ifdef BSP_ARM9 
    uint32 current_frequency_band = 0;
#endif // BSP_ARM9

    wp->authen = WLN_AUTH_OPEN;
    wp->encrypt = WLN_ENCR_OPEN;
    wp->eap_methods = NAGetAppWlnEapMethods();
    
    /* BSS type */
    for (i =0; i < (int)asizeof(wln_modes_value); i++)
    {
        if (wp->bss_type == wln_modes_value[i])
        {
            current_bss_type = i;
            break;
        }
    }

    result = -1;    
    i = sprintf(buffer, "\r\nNetwork type [%d]?\r\n"
        "    0 %s\r\n    1 %s\r\n    2 %s\r\n    3 %s\r\n",
        current_bss_type, wln_modes[0], wln_modes[1], wln_modes[2], wln_modes[3]);

#if (BSP_WPS_START == TRUE)
    sprintf((buffer+i),"    4 %s\r\n", wln_modes[4]);
    kbGetNumber(buffer, (int *) &result, 0, 4);
#else
    kbGetNumber(buffer, (int *) &result, 0, 3);
#endif


    /* if Simple Configuration is selected, skip all wireless settings */
#if (BSP_WPS_START == TRUE)
    if (wln_modes_value[result] == WLN_BSS_WPS)
    {
        wp->authen = old_auth;
        wp->encrypt = old_encrypt;

        dialogWPSEnabled = 1;
        goto _ret;
    }
#endif

    if (result == -1)
        wp->bss_type = wln_modes_value[current_bss_type];
    else
        wp->bss_type = wln_modes_value[result];
        
    /* SSID */
    memcpy(buffer, wp->ssid, wp->ssid_len);
    buffer[wp->ssid_len] = '\0';
    if (kbGetStringLimit("Network name (SSID) (enter ANY to search) [%s]? ",
        buffer, 0, WLN_SSID_SIZE)) 
    {
        int n = strlen(buffer);
        if (strcmp(buffer, "ANY") == 0)
            n = 0;
        
        memcpy (wp->ssid, buffer, n);
        wp->ssid_len = n;
    }
    

    /* 802.11h and 802.11d options */
    if (wp->options & WLN_OPT_SPECTRUM_MGMT)    
    {
        if ((wp->bss_type == WLN_BSS_ESS) || (wp->bss_type == WLN_BSS_WPS))
        {   
            flag = 2;
        }
        else
        {
            wp->options &= ~WLN_OPT_SPECTRUM_MGMT;
            flag = 1;
        }
    }
    else if (wp->options & WLN_OPT_MULTI_DOMAIN)
        flag = 1;
    else
        flag = 0;
        
    result = -1;
    i = sprintf(buffer, "\r\nSpectrum Management/Multi Domain [%d]?\r\n    0 %s\r\n    1 %s\r\n",
                flag, "None", "Multi domain capability (802.11d)");

    flag =1;
#if (AIROHA_TRANSCEIVER == TRUE)
    if (isRF_AIROHA_7230())
    { 
        if ((wp->bss_type == WLN_BSS_ESS) || (wp->bss_type == WLN_BSS_WPS))
        {   
            sprintf((buffer+i), "    2 %s\r\n", "Spectrum management(802.11h) and multi domain(802.11d) capability");
            flag = 2;
        }
        else
        {
            /*
             * Spectrum management is not allowed if the BSS type selection
             * might allow ad hoc mode.  If the flag is set, then clear it
             * and reset it to just multi domain.
             */
            sprintf((buffer+i), "    Spectrum management(802.11h) is disabled for this network type\r\n");
        }
    }
#endif
    kbGetNumber(buffer, (int *) &result, 0, flag);
    if (result != -1)
    {
        wp->options &= ~(WLN_OPT_MULTI_DOMAIN | WLN_OPT_SPECTRUM_MGMT);
        switch (result)
        {
            case 2:
                wp->options |= WLN_OPT_SPECTRUM_MGMT;
                // fall through
            case 1:
                wp->options |= WLN_OPT_MULTI_DOMAIN;
                break;
            
            default:
                break;        
        }
    }

#ifdef BSP_ARM9
#if (AIROHA_TRANSCEIVER == TRUE)
    if (isRF_AIROHA_7230()) 
    {
        /* operating frequency band  */
        if (wp->band >= WLN_BAND_MAX) 
        {
            wp->band = WLN_BAND_ALL;
        }

        /* select the operating frequency band(s) */
        sprintf(buffer, "\r\nFrequency band[%d]?\r\n"
                "    0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n",
                wp->band, wln_frequency_band[0], wln_frequency_band[1], 
                wln_frequency_band[2], wln_frequency_band[3]);
        result = -1;    
        kbGetNumber(buffer, (int *) &result, WLN_BAND_ALL, WLN_BAND_MAX - 1);
        
        if (result != -1)
            wp->band = result;
    }
    else
#endif
    {
        /* operating frequency band  */
        current_frequency_band = (wp->band == WLN_BAND_B)?1:0;
    
        /* select the operating frequency band(s) */
        sprintf(buffer, "\r\nFrequency band[%d]?\r\n"
            "    0 for %s\r\n    1 for %s\r\n",
            current_frequency_band, "band bg", "band b only");
        result = -1;    
        kbGetNumber(buffer, (int *) &result, 0, 1);
        
        if (result == 0)
            wp->band = WLN_BAND_BG;         
        else if (result == 1)
            wp->band = WLN_BAND_B;
        else
        {   // no change, still make sure what we have is the right one
            if ((wp->band != WLN_BAND_B) && (wp->band != WLN_BAND_BG))
                wp->band = WLN_BAND_BG;     
        }
    }     
#endif  //BSP_ARM9

    /* Channel number */
    if (wp->bss_type == APP_WLN_BSS_NONE)
    {
        kbGetChannel(wp->band, &wp->channel, FALSE, 
                     (wp->options & WLN_OPT_SPECTRUM_MGMT)?TRUE:FALSE);
    }
    else
    {
        kbGetChannel(wp->band, &wp->channel, TRUE,
                     (wp->options & WLN_OPT_SPECTRUM_MGMT)?TRUE:FALSE);
    }
        

#ifdef BSP_ARM9       
    /* Find display value. */
    if (wp->band == WLN_BAND_B)
    {
        txRate = getWlnTxRateMappedIdx(wp->tx_rate, MAP_TXRATE_BIT_TO_INDEX,IS_B_BAND_ONLY);
        /* Max transmit rate */
        sprintf(buffer, "\r\nMaximum transmit rate [%s]?\r\n", wln_tx_rate_b[txRate]);
        kbGetTxRate(buffer, &txRate, 1);
        wp->tx_rate = getWlnTxRateMappedIdx(txRate, MAP_INDEX_TO_TXRATE_BIT, IS_B_BAND_ONLY);
    }
    else
#endif
    {
        txRate = getWlnTxRateMappedIdx(wp->tx_rate, MAP_TXRATE_BIT_TO_INDEX, IS_NOT_B_BAND_ONLY);
        /* Max transmit rate */
        sprintf(buffer, "\r\nMaximum transmit rate [%s]?\r\n", wln_tx_rate[txRate]);
        kbGetTxRate(buffer, &txRate, 0);
        wp->tx_rate = getWlnTxRateMappedIdx(txRate, MAP_INDEX_TO_TXRATE_BIT, IS_NOT_B_BAND_ONLY);
    }

    /* Find display value. */
    txPower = getWlnTxPwrMappedIdx(wp->tx_power, MAP_TXPWR_VALUE_TO_INDEX);
    /* Wireless transmit power level */
    sprintf(buffer, "\r\nTransmit power level [%s]?\r\n"
        "    0 for Maximum\r\n    1 for Normal\r\n    2 for Low\r\n", wln_tx_power[txPower]);
    kbGetNumber(buffer, &txPower, 0, 2);
    wp->tx_power = getWlnTxPwrMappedIdx(txPower, MAP_INDEX_TO_TXPWR_VALUE);
    printf("WIRELESS AUTHENTICATION SETTINGS:\r\n");    
    
#if !BSP_WANT_WPA
    if (wp->bss_type == WLN_BSS_IBSS || wp->bss_type == WLN_BSS_IBSS_JOIN) 
    {
        /*there is no authentication in ad hoc mode*/
        printf("\r\nAuthentication type is %s\r\n", wln_auth_modes[6]);
        wp->authen = WLN_AUTH_OPEN; 
    
        printf("\r\nWIRELESS ENCRYPTION SETTINGS:\r\n");
        /* Security type */
        oldEncrypt = 0;
        if (old_encrypt & WLN_ENCR_WEP)
                oldEncrypt = 1; 
                
        sprintf(buffer, "\r\nWireless security type [%d]?\r\n"
                "    0 for %s\r\n    1 for %s\r\n",
                oldEncrypt, "no encryption", "WEP");
          
        i = -1;      
        kbGetNumber(buffer, &i, 0, 1);  
        if (i == -1)
            i = oldEncrypt;
            
        if (i)
            wp->encrypt = WLN_ENCR_WEP;
        else
            wp->encrypt = WLN_ENCR_OPEN;
        }
        else
        {
        /* Find old auth for display */
         if (old_auth & WLN_AUTH_SHAREDKEY) {
            oldAuth = 1;                
         } else {
            oldAuth = 0;                
         }            
                                                
        /* Authentication type */
        sprintf(buffer, "\r\nAuthentication type [%d]?\r\n"
                "    0 for %s\r\n    1 for %s\r\n",
                oldAuth, wln_auth_modes[6], wln_auth_modes[1]);
            
        i = -1;    
        kbGetNumber(buffer, &i, 0, 1);  
        if (i == -1)
            i = oldAuth;
               
        if (i == 1) 
            wp->authen = WLN_AUTH_SHAREDKEY;
        else
            wp->authen = WLN_AUTH_OPEN;
                                 
        printf("\r\nWIRELESS ENCRYPTION SETTINGS:\r\n");
        /* Security type */
        oldEncrypt = 0;
        if (old_encrypt & WLN_ENCR_WEP)
                oldEncrypt = 1; 
                
        sprintf(buffer, "\r\nWireless security type [%d]?\r\n"
                "    0 for %s\r\n    1 for %s\r\n",
                oldEncrypt, "no encryption", "WEP");
          
        i = -1;      
        kbGetNumber(buffer, &i, 0, 1);  
        if (i == -1)
            i = oldEncrypt;
            
        if (i)
            wp->encrypt = WLN_ENCR_WEP;
        else
            wp->encrypt = WLN_ENCR_OPEN;
        
        }
#endif         
#if BSP_WANT_WPA
    if (wp->bss_type == WLN_BSS_IBSS || wp->bss_type == WLN_BSS_IBSS_JOIN) 
    {
        /*there is no authentication in ad hoc mode*/
        printf("\r\nAuthentication type is %s\r\n", wln_auth_modes[6]);
        wp->authen = WLN_AUTH_OPEN; 
    
        printf("\r\nWIRELESS ENCRYPTION SETTINGS:\r\n");
        /* Security type */
        oldEncrypt = 0;
        if (old_encrypt & WLN_ENCR_WEP)
                oldEncrypt = 1; 
                
        sprintf(buffer, "\r\nWireless security type [%d]?\r\n"
                "    0 for %s\r\n    1 for %s\r\n",
                oldEncrypt, "no encryption", "WEP");
          
        i = -1;      
        kbGetNumber(buffer, &i, 0, 1);  
        if (i == -1)
            i = oldEncrypt;
            
        if (i)
            wp->encrypt = WLN_ENCR_WEP;
        else
            wp->encrypt = WLN_ENCR_OPEN;
    } 
    else {
        #ifdef READ_WPA_FLAG                    
        /* Enable WPA */
        flag = NADIALOG_CUSTOM_REPLY;
        if (old_auth & (WLN_AUTH_WPA_PSK|WLN_AUTH_WPA_8021X)) {
            flag |= NADIALOG_CUSTOM_DEF_YES;
        }
            
        wpaFlag = kbGetReply ("Enable WPA", flag);
        #else
        wpaFlag = 1;
        #endif
        if (wpaFlag) {          
            
            /* Find old auth for display */
            if (old_auth == WLN_AUTH_ANY) {
                oldAuth = 0;
            } else if (old_auth == WLN_AUTH_OPEN) {
                oldAuth = 6;
            } else if (old_auth & WLN_AUTH_SHAREDKEY) {
                oldAuth = 1;
            } else if (old_auth & WLN_AUTH_WEP_8021X) {
                oldAuth = 2;
            } else if (old_auth & WLN_AUTH_WPA_PSK) {
                oldAuth = 3;
            } else if (old_auth & WLN_AUTH_WPA_8021X) {
                oldAuth = 4;
            } else if (old_auth & WLN_AUTH_LEAP) {
                oldAuth = 5;
            } else if (old_auth & WLN_AUTH_EAP_FAST) {
                oldAuth = 7;
            }
                                                
            /* Authentication type */
            sprintf(buffer, "\r\nAuthentication type [%d]?\r\n"
                "    0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n    4 for %s\r\n    5 for %s\r\n    6 for %s\r\n    7 for %s\r\n",
                oldAuth, wln_auth_modes[0], wln_auth_modes[1], 
                wln_auth_modes[2], wln_auth_modes[3], wln_auth_modes[4], wln_auth_modes[5], wln_auth_modes[6], wln_auth_modes[7]);
            
            authen = -1;    
            kbGetNumber(buffer, &authen, 0, 7);
            if (authen == -1)
                authen = oldAuth;    
            
            switch (authen) {
                case 0: 
                    wp->authen = WLN_AUTH_ANY;
                        
                    if (wp->ssid_len == 0) {
                        printf("Must specify an SSID to use WPA-PSK\r\n");
                    } else if (kbGetStringLimit("WPA Personal (WPA-PSK) passphrase [no change]?\r\n", buffer, 8, 63)) {
                        printf("Calculating key (about 30 seconds)...\r\n\r\n");
                        wpa_passphrase_to_psk (buffer, (char*)wp->ssid, wp->ssid_len, wp->wpa_psk);
                    }
        
                    printf("\r\nFor WEP (802.1x), WPA (802.1x), Cisco LEAP and Cisco EAP FAST authentication:\r\n");
                    /* Identity */
                    kbGetStringLimit("Username [no change]? ", wp->identity, 0, WLN_IDENT_SIZE);

                    /* Password */
                    while (1) {
                        printf("Password [no change]? ");
                        fflush(stdout);
                        readPassword (buffer, sizeof buffer);
                        if (buffer[0] == '\0') {
                            break;
                        }

                        printf("Re-enter password: ");
                        fflush(stdout);
                        readPassword (buffer2, sizeof buffer2);
                        if (strcmp(buffer, buffer2) == 0) {
                                strncpy(wp->password, buffer, WLN_PWD_SIZE);
                                break;
                        } else
                            printf("Passwords do not match\r\n");
                    }
                                      
                    /* Encryption type */
                    if (old_encrypt == WLN_ENCR_ANY)
                    {
                        current_encrypt = 0;
                    }
                    else if (old_encrypt == WLN_ENCR_WEP)
                    {
                        current_encrypt = 1;
                    }
                    else if (old_encrypt == WLN_ENCR_TKIP)
                    {
                        current_encrypt = 2;
                    }
                    else if (old_encrypt == WLN_ENCR_CCMP)
                    {
                        current_encrypt = 3;
                    }
                    else if (old_encrypt == WLN_ENCR_OPEN)
                    {
                        current_encrypt = 4;
                    }
                    else
                    {
                        current_encrypt = 0;
                    }
                
                    printf("\r\nWIRELESS ENCRYPTION SETTINGS:\r\n");
            
                    sprintf(buffer, "\r\nEncryption type [%d]?\r\n"
                        "    0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n    4 for %s\r\n",
                        current_encrypt, wln_encrypt_modes[0], wln_encrypt_modes[1], 
                        wln_encrypt_modes[2], wln_encrypt_modes[3], wln_encrypt_modes[4]);
                    encrypt = -1;    
                    kbGetNumber(buffer, &encrypt, 0, 4);
                    if (encrypt == -1)
                        encrypt = current_encrypt;
                    switch (encrypt) {
                        case 0: 
                            wp->encrypt = WLN_ENCR_ANY;
                            break;
                        case 1: 
                            wp->encrypt = WLN_ENCR_WEP;
                            break;
                        case 2: 
                            wp->encrypt = WLN_ENCR_TKIP;
                            break;
                        case 3: 
                            wp->encrypt = WLN_ENCR_CCMP;
                            break;
                        case 4: 
                            wp->encrypt = WLN_ENCR_OPEN;
                            break;              
                    }
                    
                    break;
                case 1: 
                    wp->authen = WLN_AUTH_SHAREDKEY;
                                      
                    /* Encryption type */
                    if (old_encrypt == WLN_ENCR_WEP)
                    {
                        current_encrypt = 0;
                    }
                    else if (old_encrypt == WLN_ENCR_OPEN)
                    {
                        current_encrypt = 1;
                    }
                    else
                    {
                        current_encrypt = 1;
                    }
                
                    printf("WIRELESS ENCRYPTION SETTINGS:\r\n");
            
                    sprintf(buffer, "\r\nEncryption type [%d]?\r\n"
                        "    0 for %s\r\n    1 for %s\r\n",
                        current_encrypt, wln_encrypt_modes[1], wln_encrypt_modes[4]);
                    encrypt = -1;    
                    kbGetNumber(buffer, &encrypt, 0, 1);
                    if (encrypt == -1)
                        encrypt = current_encrypt;
                    switch (encrypt) {
                        case 0: 
                            wp->encrypt = WLN_ENCR_WEP;
                            break;
                        case 1: 
                            wp->encrypt = WLN_ENCR_OPEN;
                            break;              
                    }                 
                    break;                                      
                case 2: 
                    wp->authen = WLN_AUTH_WEP_8021X;
                    wp->encrypt = WLN_ENCR_WEP;
        
                    printf("\r\nFor WEP (802.1x), WPA (802.1x), Cisco LEAP and Cisco EAP FAST authentication:\r\n");
                    /* Identity */
                    kbGetStringLimit("Username [no change]? ", wp->identity, 0, WLN_IDENT_SIZE);

                    /* Password */
                    while (1) {
                        printf("Password [no change]? ");
                        fflush(stdout);
                        readPassword (buffer, sizeof buffer);
                        if (buffer[0] == '\0') {
                            break;
                        }

                        printf("Re-enter password: ");
                        fflush(stdout);
                        readPassword (buffer2, sizeof buffer2);
                        if (strcmp(buffer, buffer2) == 0) {
                                strncpy(wp->password, buffer, WLN_PWD_SIZE);
                                break;
                        } else
                            printf("Passwords do not match\r\n");
                    }
                
                    break;
                case 3: 
                    wp->authen = WLN_AUTH_WPA_PSK;
                        
                    if (wp->ssid_len == 0) {
                        printf("Must specify an SSID to use WPA-PSK\r\n");
                    } else if (kbGetStringLimit("WPA Personal (WPA-PSK) passphrase [no change]?\r\n", buffer, 8, 63)) {
                        printf("Calculating key (about 30 seconds)...\r\n\r\n");
                        wpa_passphrase_to_psk (buffer, (char*)wp->ssid, wp->ssid_len, wp->wpa_psk);
                    }
                                      
                    /* Encryption type */
                    if (old_encrypt == WLN_ENCR_ANY)
                    {
                        current_encrypt = 0;
                    }
                    else if (old_encrypt == WLN_ENCR_WEP)
                    {
                        current_encrypt = 1;
                    }
                    else if (old_encrypt == WLN_ENCR_TKIP)
                    {
                        current_encrypt = 2;
                    }
                    else if (old_encrypt == WLN_ENCR_CCMP)
                    {
                        current_encrypt = 3;
                    }
                    else if (old_encrypt == WLN_ENCR_OPEN)
                    {
                        current_encrypt = 4;
                    }
                    else
                    {
                        current_encrypt = 0;
                    }
                
                    printf("WIRELESS ENCRYPTION SETTINGS:\r\n");
            
                    sprintf(buffer, "\r\nEncryption type [%d]?\r\n"
                        "    0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n    4 for %s\r\n",
                        current_encrypt, wln_encrypt_modes[0], wln_encrypt_modes[1], 
                        wln_encrypt_modes[2], wln_encrypt_modes[3], wln_encrypt_modes[4]);
                    encrypt = -1;    
                    kbGetNumber(buffer, &encrypt, 0, 4);
                    if (encrypt == -1)
                        encrypt = current_encrypt;
                    switch (encrypt) {
                        case 0: 
                            wp->encrypt = WLN_ENCR_ANY;
                            break;
                        case 1: 
                            wp->encrypt = WLN_ENCR_WEP;
                            break;
                        case 2: 
                            wp->encrypt = WLN_ENCR_TKIP;
                            break;
                        case 3: 
                            wp->encrypt = WLN_ENCR_CCMP;
                            break;
                        case 4: 
                            wp->encrypt = WLN_ENCR_OPEN;
                            break;              
                    }
                                       
                    break;
                case 4: 
                    wp->authen = WLN_AUTH_WPA_8021X;
        
                    printf("\r\nFor WEP (802.1x), WPA (802.1x), Cisco LEAP and Cisco EAP FAST authentication:\r\n");
                    /* Identity */
                    kbGetStringLimit("Username [no change]? ", wp->identity, 0, WLN_IDENT_SIZE);

                    /* Password */
                    while (1) {
                        printf("Password [no change]? ");
                        fflush(stdout);
                        readPassword (buffer, sizeof buffer);
                        if (buffer[0] == '\0') {
                            break;
                        }

                        printf("Re-enter password: ");
                        fflush(stdout);
                        readPassword (buffer2, sizeof buffer2);
                        if (strcmp(buffer, buffer2) == 0) {
                                strncpy(wp->password, buffer, WLN_PWD_SIZE);
                                break;
                        } else
                            printf("Passwords do not match\r\n");
                    }
                                      
                    /* Encryption type */
                    if (old_encrypt == WLN_ENCR_ANY)
                    {
                        current_encrypt = 0;
                    }
                    else if (old_encrypt == WLN_ENCR_WEP)
                    {
                        current_encrypt = 1;
                    }
                    else if (old_encrypt == WLN_ENCR_TKIP)
                    {
                        current_encrypt = 2;
                    }
                    else if (old_encrypt == WLN_ENCR_CCMP)
                    {
                        current_encrypt = 3;
                    }
                    else if (old_encrypt == WLN_ENCR_OPEN)
                    {
                        current_encrypt = 4;
                    }
                    else
                    {
                        current_encrypt = 0;
                    }
                
                    printf("\r\nWIRELESS ENCRYPTION SETTINGS:\r\n");
            
                    sprintf(buffer, "\r\nEncryption type [%d]?\r\n"
                        "    0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n    4 for %s\r\n",
                        current_encrypt, wln_encrypt_modes[0], wln_encrypt_modes[1], 
                        wln_encrypt_modes[2], wln_encrypt_modes[3], wln_encrypt_modes[4]);
                    encrypt = -1;    
                    kbGetNumber(buffer, &encrypt, 0, 4);
                    if (encrypt == -1)
                        encrypt = current_encrypt;
                    switch (encrypt) {
                        case 0: 
                            wp->encrypt = WLN_ENCR_ANY;
                            break;
                        case 1: 
                            wp->encrypt = WLN_ENCR_WEP;
                            break;
                        case 2: 
                            wp->encrypt = WLN_ENCR_TKIP;
                            break;
                        case 3: 
                            wp->encrypt = WLN_ENCR_CCMP;
                            break;
                        case 4: 
                            wp->encrypt = WLN_ENCR_OPEN;
                            break;              
                    }
                                                           
                    break;              
                case 5: 
                    wp->authen = WLN_AUTH_LEAP;
                    wp->encrypt = WLN_ENCR_WEP;
                    wp->eap_methods = WLN_EAP_LEAP;
        
                    printf("\r\nFor WEP (802.1x), WPA (802.1x), Cisco LEAP and Cisco EAP FAST authentication:\r\n");
                    /* Identity */
                    kbGetStringLimit("Username [no change]? ", wp->identity, 0, WLN_IDENT_SIZE);

                    /* Password */
                    while (1) {
                        printf("Password [no change]? ");
                        fflush(stdout);
                        readPassword (buffer, sizeof buffer);
                        if (buffer[0] == '\0') {
                            break;
                        }

                        printf("Re-enter password: ");
                        fflush(stdout);
                        readPassword (buffer2, sizeof buffer2);
                        if (strcmp(buffer, buffer2) == 0) {
                                strncpy(wp->password, buffer, WLN_PWD_SIZE);
                                break;
                        } else
                            printf("Passwords do not match\r\n");
                    }
                    break;              
                case 6: 
                    wp->authen = WLN_AUTH_OPEN;
                                      
                    /* Encryption type */
                    if (old_encrypt == WLN_ENCR_ANY)
                    {
                        current_encrypt = 0;
                    }
                    else if (old_encrypt == WLN_ENCR_WEP)
                    {
                        current_encrypt = 1;
                    }
                    else if (old_encrypt == WLN_ENCR_TKIP)
                    {
                        current_encrypt = 2;
                    }
                    else if (old_encrypt == WLN_ENCR_CCMP)
                    {
                        current_encrypt = 3;
                    }
                    else if (old_encrypt == WLN_ENCR_OPEN)
                    {
                        current_encrypt = 4;
                    }
                    else
                    {
                        current_encrypt = 0;
                    }
                
                    printf("WIRELESS ENCRYPTION SETTINGS:\r\n");
            
                    sprintf(buffer, "\r\nEncryption type [%d]?\r\n"
                        "    0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n    4 for %s\r\n",
                        current_encrypt, wln_encrypt_modes[0], wln_encrypt_modes[1], 
                        wln_encrypt_modes[2], wln_encrypt_modes[3], wln_encrypt_modes[4]);
                    encrypt = -1;    
                    kbGetNumber(buffer, &encrypt, 0, 4);
                    if (encrypt == -1)
                        encrypt = current_encrypt;
                    switch (encrypt) {
                        case 0: 
                            wp->encrypt = WLN_ENCR_ANY;
                            break;
                        case 1: 
                            wp->encrypt = WLN_ENCR_WEP;
                            break;
                        case 2: 
                            wp->encrypt = WLN_ENCR_TKIP;
                            break;
                        case 3: 
                            wp->encrypt = WLN_ENCR_CCMP;
                            break;
                        case 4: 
                            wp->encrypt = WLN_ENCR_OPEN;
                            break;              
                    }                                       

                    break;
                case 7:
                    wp->authen = WLN_AUTH_EAP_FAST;
                    wp->eap_methods &= WLN_EAP_INNER_ANY;
                    wp->eap_methods |= WLN_EAP_FAST;
        
                    printf("\r\nFor WEP (802.1x), WPA (802.1x), Cisco LEAP and Cisco EAP FAST authentication:\r\n");
                    /* Identity */
                    kbGetStringLimit("Username [no change]? ", wp->identity, 0, WLN_IDENT_SIZE);

                    /* Password */
                    while (1) {
                        printf("Password [no change]? ");
                        fflush(stdout);
                        readPassword (buffer, sizeof buffer);
                        if (buffer[0] == '\0') {
                            break;
                        }

                        printf("Re-enter password: ");
                        fflush(stdout);
                        readPassword (buffer2, sizeof buffer2);
                        if (strcmp(buffer, buffer2) == 0) {
                                strncpy(wp->password, buffer, WLN_PWD_SIZE);
                                break;
                        } else
                            printf("Passwords do not match\r\n");
                    }

                    /* Encryption type */
                    if (old_encrypt != WLN_ENCR_TKIP && old_encrypt != WLN_ENCR_CCMP)
                    {
                        current_encrypt = 0;
                    }
                    else
                    {
                        if (old_encrypt == WLN_ENCR_TKIP)
                        {
                            current_encrypt = 0;
                        }
                        else
                        {
                            current_encrypt = 1;
                        }
                    }

                    printf("\r\nWIRELESS ENCRYPTION SETTINGS:\r\n");
            
                    sprintf(buffer, "\r\nEncryption type [%d]?\r\n"
                        "    0 for %s\r\n    1 for %s\r\n",
                        current_encrypt, wln_encrypt_modes[2], wln_encrypt_modes[3]);
                    encrypt = -1;    
                    kbGetNumber(buffer, &encrypt, 0, 1);
                    if (encrypt == -1)
                        encrypt = current_encrypt;
                    switch (encrypt) {
                        case 0: 
                            wp->encrypt = WLN_ENCR_TKIP;
                            break;
                        case 1: 
                            wp->encrypt = WLN_ENCR_CCMP;
                            break;
                    }
                    break;
            }

#ifdef EAP_SUPPORT_TYPES
            /* Select EAP type if needed */
            if (wp->authen != WLN_AUTH_LEAP) {
                                            
                /* Outer EAP type */
                if (old_eap_methods == WLN_EAP_ANY)
                {
                    current_eap_methods = 0;
                }
                else if ((old_eap_methods & 0x0f) == WLN_EAP_PEAP)
                {
                    current_eap_methods = 1;
                }
                else if ((old_eap_methods & 0x0f) == WLN_EAP_TLS)
                {
                    current_eap_methods = 2;
                }
                else if ((old_eap_methods & 0x0f) == WLN_EAP_TTLS)
                {
                    current_eap_methods = 3;
                }
                else
                {
                    current_eap_methods = 0;
                }
                sprintf(buffer, "\r\nOuter EAP type [%d]?\r\n"
                    "Enter 0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n",
                    current_eap_methods, wln_outer_eap_modes[0], wln_outer_eap_modes[1], wln_outer_eap_modes[2], 
                    wln_outer_eap_modes[3]);
                
                encrypt = -1;    
                kbGetNumber(buffer, &encrypt, 0, 3);
                if (encrypt == -1)
                    encrypt = current_eap_methods;
                switch (encrypt) {
                    case 0: 
                        wp->eap_methods = WLN_EAP_ANY;
                        break;
                    case 1: 
                        wp->eap_methods = WLN_EAP_PEAP;
                        break;
                    case 2: 
                        wp->eap_methods = WLN_EAP_TLS;
                        break;
                    case 3: 
                        wp->eap_methods = WLN_EAP_TTLS;
                        break;                      
                }
                
                if (wp->eap_methods == WLN_EAP_TTLS) {
                    /* Inner EAP type */
                    if ((old_eap_methods & WLN_EAP_INNER_ANY) == WLN_EAP_INNER_ANY)
                    {
                        current_eap_methods = 0;
                    }
                    else if ((old_eap_methods & WLN_EAP_GTC) == WLN_EAP_GTC)
                    {
                        current_eap_methods = 1;
                    }
                    else if ((old_eap_methods & WLN_EAP_MD5) == WLN_EAP_MD5)
                    {
                        current_eap_methods = 2;
                    }
                    else if ((old_eap_methods & WLN_EAP_MSCHAPV2) == WLN_EAP_MSCHAPV2)
                    {
                        current_eap_methods = 3;
                    }
                    else if ((old_eap_methods & WLN_EAP_OTP) == WLN_EAP_OTP)
                    {
                        current_eap_methods = 4;
                    }
                    else if ((old_eap_methods & WLN_EAP_TTLS_CHAP) == WLN_EAP_TTLS_CHAP)
                    {
                        current_eap_methods = 5;
                    }
                    else if ((old_eap_methods & WLN_EAP_TTLS_MSCHAP) == WLN_EAP_TTLS_MSCHAP)
                    {
                        current_eap_methods = 6;
                    }
                    else if ((old_eap_methods & WLN_EAP_TTLS_MSCHAPV2) == WLN_EAP_TTLS_MSCHAPV2)
                    {
                        current_eap_methods = 7;
                    }
                    else if ((old_eap_methods & WLN_EAP_TTLS_PAP) == WLN_EAP_TTLS_PAP)
                    {
                        current_eap_methods = 8;
                    }
                    else
                    {
                        current_eap_methods = 0;
                    }
                    sprintf(buffer, "\r\nInner EAP type [%d]?\r\n"
                        "Enter 0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n    4 for %s\r\n    5 for %s\r\n    6 for %s\r\n    7 for %s\r\n    8 for %s\r\n",
                        current_eap_methods, wln_inner_eap_modes[0], wln_inner_eap_modes[1],wln_inner_eap_modes[2],wln_inner_eap_modes[3],
                        wln_inner_eap_modes[4],wln_inner_eap_modes[5], wln_inner_eap_modes[6], wln_inner_eap_modes[7], 
                        wln_inner_eap_modes[8]);
                    
                    encrypt = -1;    
                    kbGetNumber(buffer, &encrypt, 0, 8);
                    if (encrypt == -1)
                        encrypt = current_eap_methods;
                    switch (encrypt) {
                        case 0: 
                            wp->eap_methods |= WLN_EAP_INNER_ANY;
                            break;
                        case 1: 
                            wp->eap_methods |= WLN_EAP_GTC;
                            break;
                        case 2: 
                            wp->eap_methods |= WLN_EAP_MD5;
                            break;
                        case 3: 
                            wp->eap_methods |= WLN_EAP_MSCHAPV2;
                            break;
                        case 4: 
                            wp->eap_methods |= WLN_EAP_OTP;
                            break;                                                  
                        case 5: 
                            wp->eap_methods |= WLN_EAP_TTLS_CHAP;
                            break;
                        case 6: 
                            wp->eap_methods |= WLN_EAP_TTLS_MSCHAP;
                            break;
                        case 7: 
                            wp->eap_methods |= WLN_EAP_TTLS_MSCHAPV2;
                            break;
                        case 8: 
                            wp->eap_methods |= WLN_EAP_TTLS_PAP;
                            break;                      
                    }                   
                } else {                                
                    /* Inner EAP type */
                    if ((old_eap_methods & (WLN_EAP_GTC | WLN_EAP_MD5 | WLN_EAP_MSCHAPV2 | WLN_EAP_OTP)) == 
                        (WLN_EAP_GTC | WLN_EAP_MD5 | WLN_EAP_MSCHAPV2 | WLN_EAP_OTP))
                    {
                        current_eap_methods = 0;
                    }
                    else if ((old_eap_methods & WLN_EAP_GTC) == WLN_EAP_GTC)
                    {
                        current_eap_methods = 1;
                    }
                    else if ((old_eap_methods & WLN_EAP_MD5) == WLN_EAP_MD5)
                    {
                        current_eap_methods = 2;
                    }
                    else if ((old_eap_methods & WLN_EAP_MSCHAPV2) == WLN_EAP_MSCHAPV2)
                    {
                        current_eap_methods = 3;
                    }
                    else if ((old_eap_methods & WLN_EAP_OTP) == WLN_EAP_OTP)
                    {
                        current_eap_methods = 4;
                    }
                    else
                    {
                        current_eap_methods = 0;
                    }
                    sprintf(buffer, "\r\nInner EAP type [%d]?\r\n"
                        "Enter 0 for %s\r\n    1 for %s\r\n    2 for %s\r\n    3 for %s\r\n    4 for %s\r\n",                        
                        current_eap_methods, wln_inner_eap_modes[0], wln_inner_eap_modes[1], wln_inner_eap_modes[2], wln_inner_eap_modes[3], 
                        wln_inner_eap_modes[4]);
                    
                    encrypt = -1;    
                    kbGetNumber(buffer, &encrypt, 0, 4);
                    if (encrypt == -1)
                        encrypt = current_eap_methods;
                    switch (encrypt) {
                        case 0: 
                            wp->eap_methods |= WLN_EAP_GTC | WLN_EAP_MD5 | WLN_EAP_MSCHAPV2 | WLN_EAP_OTP;
                            break;
                        case 1: 
                            wp->eap_methods |= WLN_EAP_GTC;
                            break;
                        case 2: 
                            wp->eap_methods |= WLN_EAP_MD5;
                            break;
                        case 3: 
                            wp->eap_methods |= WLN_EAP_MSCHAPV2;
                            break;
                        case 4: 
                            wp->eap_methods |= WLN_EAP_OTP;
                            break;                      
                    }
                }                                   
            }
#endif /* #ifdef EAP_SUPPORT_TYPES */            

        }
    }
#endif // BSP_WANT_WPA
        
        if (wp->authen == WLN_AUTH_ANY || wp->authen == WLN_AUTH_SHAREDKEY ||
           ((wp->authen == WLN_AUTH_OPEN) && (wp->encrypt & WLN_ENCR_WEP))) {
            /* Default key */
            kbGetNumber("\r\nWEP default key number (0-3) [%d]? ", 
                &wp->wep_key_id, 0, 3);                 

            /* WEP keys */
            for (i = 0; i < 4; i++) {
                kbGetWEPKey(i, wp);
            }        
        }

#if (BSP_WPS_START == TRUE)
_ret:
#endif

    return DIALOGUPDATED;
}
#endif // BSP_WANT_WIRELESS

/*ad*
 *
 * Displays the target configuration and prompts the user
 * for modifications.
 *
 * @param   nvParamsPtr     pointer to structure with development board parameters
 *
 * @return  0               success
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD SHOULD YOU USE DIFFERENT 
 *          DISPLAY FORMAT. The implementation below is for NET+OS development 
 *          boards only.
 *
*ad*/ 
static int NADisplayDialog(devBoardParamsType * nvParamsPtr)
{
    extern WORD32 customizeGetRamSize(void);
#if BSP_SEEK_SDRAM
   extern int yaffs_get_nand_flash_size(const char *devName);
#endif   
    char s[20];  
#if BSP_WANT_ETHERNET || BSP_WANT_WIRELESS 
    BYTE mac_addrp[6];
#endif
    NaIamParams_t *interface = NULL;

	
    NA_UNUSED_PARAM(interface);   /* To remove GNU Compiler warning. */

    /*
     * We use to have code here that corrected invalid baudrates and waittimes before 
     * they were displayed.  I removed it since we should display invalid settings 
     * so that users will correct them.
     */
         
    printf("\r\n");
    printf("\r\n");
    printf("\r\n");
    printf("NET+OS Version %s\r\n", NETOS_VERSION_NUMBER); 
    printf("Copyright (c) 1997-2008, Digi International, Inc.\r\n");
    printf("\r\n");
#if BSP_SEEK_SDRAM
    printf("PLATFORM: %s %dM/%dM [%s]\r\n", NABspPlatform, (unsigned int) yaffs_get_nand_flash_size("/FLASH0") >> 20, (unsigned int) (customizeGetRamSize() >> 20), NAGetBspTimeStamp());
#else
    printf("PLATFORM: %s %dM/%dM [%s]\r\n", NABspPlatform, (unsigned int) NAFlashSize() >> 20, (unsigned int) (customizeGetRamSize() >> 20), NAGetBspTimeStamp());
#endif
#ifdef DOTNETMF
    printf("APPLICATION: %s\r\n", NAGetAppDialogAppName ());
#else
    printf("APPLICATION: %s [%s]\r\n", NAGetAppDialogAppName (), NAGetAppTimeStamp());
#endif
    printf("-----------------------------------------------------------------------------\r\n");
    printf("NETWORK INTERFACE PARAMETERS:\r\n");
    
#if BSP_WANT_ETHERNET
#if BSP_ETH_WIFI_BRIDGE
    interface = customizeIamFindInterfaceConfig(BP_EWB_INTERFACE, &nvParamsPtr->iamParamsInfo);
#else
    interface = customizeIamFindInterfaceConfig(BP_ETH_INTERFACE, &nvParamsPtr->iamParamsInfo);
#endif  /* not BSP_ETH_WIFI_BRIDGE */

    if (interface == NULL)
    {
        interface = customizeIamFindUnusedInterfaceConfig(&nvParamsPtr->iamParamsInfo, TRUE);
        customizeIamGetDefaultEthernetConfig(interface, 0);
    } 
    if (interface->staticParams.isEnabled)
    {
        printIpAddress("  IP address on LAN is %d.%d.%d.%d\r\n", interface->staticParams.IPV4_ADDR(ipAddress));
        printIpAddress("  LAN interface's subnet mask is %d.%d.%d.%d\r\n", interface->staticParams.subnetMask);
        printIpAddress("  IP address of default gateway to other networks is %d.%d.%d.%d\r\n", interface->staticParams.IPV4_ADDR(gateway));
    }
    else
    {
        printf("  The board will obtain IP configuration parameters from the network.\r\n");
    }
	if (NaIpv6IsDhcpEnabled(interface))
	{
		printf("  DHCPv6 is enabled on LAN\r\n");
	}
	if (NaIpv6IsStaticEnabled(interface))
	{
		printIpv6Address("  IPv6 static  address on LAN is %s", &interface->staticParams.ipv6Address);
		printf(" prefixlen %d\r\n", interface->staticParams.ipv6PrefixLen);
	}
#endif

#if BSP_WANT_WIRELESS
    printWirelessParams(nvParamsPtr);
#endif

/*  New PPP parameters allows backward compatibility with older applications    */

    if (NAGetAppEnablePPP1 ())
    {
        printIpAddress("  IP address on PPP interface 1 is %d.%d.%d.%d\r\n", nvParamsPtr->ipAddrPpp1);

        if (nvParamsPtr->ipAddrPpp1peer)
        {
            printIpAddress("  Peer IP address connected to PPP interface 1 is %d.%d.%d.%d\r\n", nvParamsPtr->ipAddrPpp1peer);
        }
    }

    if (NAGetAppEnablePPP2 ())
    {
        printIpAddress("  IP address on PPP interface 2 is %d.%d.%d.%d\r\n", nvParamsPtr->ipAddrPpp2);

        if (nvParamsPtr->ipAddrPpp2peer)
        {
            printIpAddress("  Peer IP address connected to PPP interface 2 is %d.%d.%d.%d\r\n", nvParamsPtr->ipAddrPpp2peer);
        }
    }

    if (NAGetAppUseNetworkTimeProtocol ())
    {
        /*  Display the current configured SNTP addresses, regardless of the IP address.    */
        printIpAddress("  Primary SNTP Server IP address is %d.%d.%d.%d\r\n", nvParamsPtr->ipAddrSntp1);
        printIpAddress("  Secondary SNTP Server IP address is %d.%d.%d.%d\r\n", nvParamsPtr->ipAddrSntp2);
    }

    printf("HARDWARE PARAMETERS:\r\n");   
    printf("  Serial channels will use a baud rate of %lu\r\n",nvParamsPtr->baudrate);

    memcpy(s,  nvParamsPtr->serialNumber,sizeof(nvParamsPtr->serialNumber));
    s[BP_SERIAL_NUMBER_LENGTH]=0;  /*for correct printf %s format*/
    printf("  This board's serial number is %s\r\n", s);

#if BSP_WANT_ETHERNET
    customizeGetInterfaceMACAddress(BP_ETH_INTERFACE, mac_addrp);
    printMacAddress("  This board's Ethernet MAC Address is %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\r\n",mac_addrp);
#endif
#if BSP_WANT_WIRELESS
    customizeGetInterfaceMACAddress(BP_WLN_INTERFACE, mac_addrp);
    printMacAddress("  This board's Wireless MAC Address is %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\r\n",mac_addrp);
    fflush(stdout);
#endif                  
    printf("  After board is reset, start-up code will wait %lu seconds\r\n", nvParamsPtr->waitTime);

#if BSP_WANT_ETHERNET
    printf("  Default duplex setting for Ethernet connection: %s\r\n", getDuplexString(nvParamsPtr->defaultDuplexLevel));
#endif

    printf("-----------------------------------------------------------------------------\r\n");

    return (0);
}

/*ad*
 *
 * Closes @link BSP_DIALOG_PORT if @link BSP_ENABLE_DIALOG is defined, and
 * restore stdin, stdout, and stderr.
 *
 * @return  0   success
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 * @see @link BSP_ENABLE_DIALOG
 * @see @link BSP_DIALOG_PORT
 *
*ad*/
static int NACloseDialog(void)
{
    #ifdef NETOS_GNU_TOOLS
        close (fd);

        RESTORE_IO
    #elif defined(__CC_ARM)
        close(stdin->handle);

                /* Restore IO */
        stdin->handle = inch;
        stdout->handle = outch;
        stderr->handle = errch;
    #else
        close(stdin->io_channel);

        /* Restore IO */
        stdin->io_channel = inch;
        stdout->io_channel = outch;
        stderr->io_channel = errch;
    #endif

    return (0);
}

/*ad*
 *
 * Checks for keyboard entry before timeout
 *
 * @param   timeout     Time in seconds before this routine returns
 *                      if no key is pressed.
 *
 * @return  >0          The value of the pressed key.
 * @return  0xff        Timed out.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
*ad*/ 
static char checkKeyboardInput(unsigned long timeout)
{
    unsigned int i;
    char rc=0xff;
    
      
    for (i=0; i < timeout; i++)
      {
        tx_thread_sleep(BSP_TICKS_PER_SECOND);
        rc=0;
        rc= (char) getchar();
        if ((rc != 0xff) && (rc != '\n'))
           return (rc);
      }
    return (rc);  
}


/*ad*
 *
 * Checks if the user intends to make changes, if yes, it will close
 * the dialog port and reopen it with block mode to wait for input. It also
 * authenticates thw user for the right to change. If the password is incorrect,
 * it allows the user to reenter 3 times before giving up.
 *
 * @param   nvParamsPtr Pointer to structure with development board parameters
 *
 * @return  0   Continue without any updates.
 * @return  1   Need to update.
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 *          below is for NET+OS development boards only.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
*ad*/ 
static int NAConfigureDialog(devBoardParamsType * nvParamsPtr)
{
    int rc;
    char temp;
    char buffer[128];
    unsigned int  notAuthenticated = 1;
    char password[NASYSACC_STRLEN_PASSWORD];

    if (NAGetAppUseNvram () != APP_DO_NOT_USE_NVRAM)
    {
        printf("Press any key in %lu seconds to change these settings.\r\n", nvParamsPtr->waitTime);
    }
    printf("\r\n");
   
    /*any key is pressed?*/
    temp = checkKeyboardInput(nvParamsPtr->waitTime);
    if ((temp != 0xff) && (NAGetAppUseNvram () != APP_DO_NOT_USE_NVRAM))
    {
        printf("Press A to Accept the settings, or M to Modify?");
        fflush(stdout);
    }
    else
    {
        return 0;          /*time out spared, no modification needed, continue...*/
    }

    /*let's close nonblock i/o, use block i/o*/
    NACloseDialog ();
        
    /* Open for Blocking Mode */
    NAOpenDialog (1, nvParamsPtr); 

     
    /*"A" or "a", "M" or "m"* is pressed?*/
    while (1)
    {
        readLine(buffer);
        fflush(stdout);
        if (buffer[0] == 'a' || buffer[0] =='A')
        {
            printf("continue...\r\n");
            return 0;         /*no modification needed, user needs to continue...*/
        }

        if (buffer[0] == 'm' || buffer[0] =='M')
        {
            break;
        }

        printf("Press A to Accept the settings, or M to Modify?"); 
        fflush(stdout);
    }  

    /*  "M" or "m" is pressed   */
    printf("\r\n");
    rc = NAgetSysAccess ("root", &password[0], NULL);
    if ((rc == (int) NASYSACC_LEVEL_ROOT) && (notAuthenticated))
    {
        for (rc = 0; ; rc ++)
        {
            printf("Enter the root password: ");
            fflush(stdout);
            readPassword(buffer, sizeof buffer);
            fflush(stdout);
            if (strcmp(buffer, password) == 0)
            {
                /*  OK - this is an authentic administrator */
                notAuthenticated = 0;
                break;
            }

            if (rc < 3)
            {
                printf("FAILURE: root password incorrect\r\n");
            }
            else
            {
                /*  no modification allowed, continue...*/
                printf("FAILURE: root password incorrect\r\ncontinue...\r\n");
                return 0;
            }
        }
    } 
    
    if (kbGetReply ("\r\nReset configuration to default values", NADIALOG_CUSTOM_REPLY))
    {
        customizeUseDefaultParams(nvParamsPtr);
    }

    return (1);
}

/*ad*
 *
 * Validates an IP address.
 *
 * @param   buffer  Points to the string which contains an IP address in "a.b.c.d" format.
 *
 * @return  0   invalid
 * @return  1   valid
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
*ad*/ 
static int  checkIpAddress(char * buffer)
{
   unsigned int length,i;
   unsigned int j =0;
   unsigned int val;
      
   
   length = strlen(buffer);
   
   if ( (length > MAX_IPADDRESS_LENGTH))
      return 0;
   else
   {
     for (i=0; i<length; i++)
     {
       
       if (buffer[i] =='.')
           {
             j++;
             if (j > 3)   /* only three '.' allowed */
                return 0;
           }
       else if (!(isdigit(buffer[i]))) /* all input char must be numeric */
           return 0;
     } 
     
     for (i = 0; i < 4; i++)
      {
           if (*buffer != '\0') 
           {
               val = 0;
               while (*buffer != '\0' && *buffer != '.') 
               {  
                    val *= 10;
                    val += *buffer - '0';
                    buffer++;
               }
               if (val > 255)
                  return 0;       /* any field should be less than 256 */
                  
               if (*buffer != '\0') 
                   buffer++;
           } 
       }   
   }
   return 1; 
} 

#if BSP_WANT_ETHERNET || BSP_WANT_WIRELESS

static int kbGetIpv6Address (char * prompt, struct sockaddr_storage *address)
{
    int rc;

    char buffer[128] = {0};
	struct in6_addr new_addr6;

    while (1)
    {
       printf ("%s ", prompt);
       fflush(stdout);

	   if (address->ss_family == AF_INET6)
			printIpv6Address(" [%s]? ", address);
		 
	   fflush(stdout);
	   readLine (buffer);
	   if (buffer[0] == '\0')
	   {
            rc = 0;
            break;
       }
	   else
	   {
		    memset(address, 0, sizeof *address);
			rc = inet_pton (AF_INET6, buffer, &new_addr6.ip6Addr);
			if (rc == 1)
			{
				address->ss_len = sizeof(struct sockaddr_in6);
				address->ss_family = AF_INET6;
				address->addr.ipv6.sin6_addr.ip6Addr = new_addr6.ip6Addr;
				break;
			}
	   }
       printf("Invalid IPv6 address.\r\n");
	}
	return rc;
}

#endif

/*ad*
 *
 * Prints out what kind of IP address it needs and gets it from keyboard.
 *
 * @param   ipAddrDesc  Points to string which contains some description.
 * @param   ipAddress   Points to an unsigned long which holds the old IP address.
 *                      Upon return, it will hold the new IP address if any.
 *
 * @return  0   No update, keep the old IP address.
 * @return  1   Got a new IP address.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note        THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 *              below is for NET+OS development boards only.
 *
*ad*/
static int kbGetIpAddress(char * ipAddrDesc, unsigned long * ipAddress)
{
    int rc;

    char buffer[128] = {0};

    while (1)
    {
        printf ("%s ", ipAddrDesc);
        fflush(stdout);
        printIpAddress(" [%d.%d.%d.%d]? ", *ipAddress);
        fflush(stdout);
        readLine (buffer);
        if (buffer[0] == '\0')
        {
            rc = 0;
            break;
        }

        if(checkIpAddress(buffer))
        {
            *ipAddress = NAInet_addr(buffer);
            printf ("  %s ", ipAddrDesc);
            printIpAddress("IP address is %d.%d.%d.%d\r\n", *ipAddress);
            rc = 1;
            break;
        }

        printf("Invalid IP address.\r\n");
    }

    return (rc);
}

#if BSP_WANT_ETHERNET || BSP_WANT_WIRELESS 
/*
 *
 *  Function: static int NAIPParamDialog (devBoardParamsType *nvParamsPtr, char *ifname, char *prompt)
 *
 *  Description:
 *
 *      This routine gets a new IP parameters.
 *
 *  Parameters:
 *
 *      nvParamsPtr     pointer to structure with development board parameters
 *      ifname        name of interface (BP_ETH_INTERFACE of BP_WLN_INTERFACE)
 *      prompt        string displayed to user
 *
 *  Return Values:
 *
 *      0             no update, keep the old setting
 *      1             updated     
 *
 */ 
static int NAIPParamDialog(devBoardParamsType * nvParamsPtr, char * ifname, char * prompt)
{
    int callStatus = 0;
    unsigned long temp;

    /*
     * Extract the configuration structure from the NVRAM structure.  There should be a configuration
     * settings for the interface.  If not, then reinitialize the structure.
     */
    NaIamParams_t *config = customizeIamFindInterfaceConfig(ifname, &nvParamsPtr->iamParamsInfo);

    if (config == NULL)
    {
        customizeIamGetDefaultConfig(&nvParamsPtr->iamParamsInfo);
        config = customizeIamFindInterfaceConfig(ifname, &nvParamsPtr->iamParamsInfo);
    }

    if (!config->isEnabled)
    {
        customizeIamGetDefaultInterfaceConfig(ifname, config);
    }

    if (config->dhcpParams.isEnabled)
    {
        temp = kbGetReply (prompt, NADIALOG_CUSTOM_REPLY | NADIALOG_CUSTOM_DEF_YES);
    }
    else
    {
        temp = kbGetReply (prompt, NADIALOG_CUSTOM_REPLY);
    }
    
    if (temp)
    {
        /*
         * Disable the static configuration to make ACE get an address from the network.
         * The protocols actually used by ACE are determined by the settings stored
         * in NVRAM.
         */
        config->staticParams.isEnabled = FALSE;
        config->dhcpParams.isEnabled = TRUE;
    }
    else
    {
        /* ip address */
        kbGetIpAddress ("IP address", &config->staticParams.IPV4_ADDR(ipAddress));
        
        /* subnet mask */
        kbGetIpAddress ("Subnet mask", &config->staticParams.subnetMask);
        
        /* gateway mask */
        kbGetIpAddress ("Gateway address", &config->staticParams.IPV4_ADDR(gateway));
        
        /* validate ip information. If invalid, return an error */
        callStatus = naValidateNetworkInformation(config->staticParams.IPV4_ADDR(ipAddress), 
                                                config->staticParams.subnetMask,
                                                config->staticParams.IPV4_ADDR(gateway));

        /* if error - return error code, then print message and loop */
        if(callStatus)
        {
            return callStatus;
        }

        /*
         * Enabling the static configuration will cause ACE to ignore the settings used
         * for DHCP, BOOTP, et al on the same interface.
         */
        config->staticParams.isEnabled = TRUE;
        config->dhcpParams.isEnabled = FALSE;
    }

    return DIALOGUPDATED;
}

static int NAIPv6ParamDialog(devBoardParamsType * nvParamsPtr, char * ifname, char *ifstr)
{
    int  callStatus = 0;
 	char prompt[128];
	unsigned long temp;

    NaIamParams_t *config = customizeIamFindInterfaceConfig(ifname, &nvParamsPtr->iamParamsInfo);

    if (config == NULL)
    {
        customizeIamGetDefaultConfig(&nvParamsPtr->iamParamsInfo);
        config = customizeIamFindInterfaceConfig(ifname, &nvParamsPtr->iamParamsInfo);
    }

	sprintf(prompt, "Enable DHCPv6 for the %s interface", ifstr);

	if (NaIpv6IsDhcpEnabled(config))
    {
        temp = kbGetReply (prompt, NADIALOG_CUSTOM_REPLY | NADIALOG_CUSTOM_DEF_YES);
    }
    else
    {
        temp = kbGetReply (prompt, NADIALOG_CUSTOM_REPLY);
    }
	NaIpv6SetDhcpEnabled(config, temp);

	printf ("\r\n");
	sprintf(prompt, "Enable static IPv6 for the %s interface", ifstr);

	if (NaIpv6IsStaticEnabled(config))
    {
        temp = kbGetReply (prompt, NADIALOG_CUSTOM_REPLY | NADIALOG_CUSTOM_DEF_YES);
    }
    else
    {
        temp = kbGetReply (prompt, NADIALOG_CUSTOM_REPLY);
    }
    if (temp == 0)
	{
		NaIpv6SetStaticEnabled(config, 0);
	}
	else
	{
		int prefix_len = config->staticParams.ipv6PrefixLen;
		
        /* ipv6 address */
		config->staticParams.ipv6Address.ss_family = AF_INET6;
        kbGetIpv6Address ("IPv6 address", &config->staticParams.ipv6Address);
        
        /* prefix length */
		kbGetNumber("Network prefix length [%d]? ", &prefix_len, 0, 64);
		config->staticParams.ipv6PrefixLen = (WORD8) prefix_len;
        
        /* validate IPv6 information. If invalid, return an error */
        callStatus = naValidateIpv6Information(&config->staticParams.ipv6Address, config->staticParams.ipv6PrefixLen);

       /* if error - return error code, then print message and loop */
        if(callStatus)
        {
			printf("Invalid IPv6 address / prefix length.\r\n");
            return callStatus;
        }

        NaIpv6SetStaticEnabled(config, 1);
    }

    return DIALOGUPDATED;
}
#endif

/*ad*
 *
 * Gets new network information.
 *
 * @param       nvParamsPtr         Pointer to structure with development board parameters
 *
 * @return     NOSUBNETTING         IP Address can not be subnetted.
 * @return     ZEROIPNOTALLOWED     IP Address 0.0.0.0 is not allowed.
 * @return     IPANDGWMATCH         IP Address and Gateway Address are the same.
 * @return     IPORGWISMULTICAST    IP Address or Gatweay Address is > 223.
 * @return     IPORGWISLOCALLOOP    IP Address or Gatweay Address is 127.
 * @return     ZEROOCTETNOTALLOWED  Zero is not allowed in leftmost octet of IP Address.
 * @return     ZEROMASKNOTALLOWED   Subnet mask 0.0.0.0 not allowed.
 * @return     MAXSUBNETEXCEEDED    Subnet mask can not exceed 255.255.255.252
 * @return     IPISNETWORKID        IP Address is network ID.
 * @return     IPISBROADCAST        IP Address is network broadcast address.
 * @return     GWISNETWORKID        Gateway Address is network ID.
 * @return     GWISBROADCAST        Gateway Address is network broadcast address.
 * @return     GWNOTONSUBNET        Gateway Address is not on subnet.
 * @return     DIALOGUPDAYED        Changes have been made. UpdateDialog will need to be called.
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 *       below is for NET+OS development boards only.
 *
*ad*/ 
static int NANetworkDialog(devBoardParamsType * nvParamsPtr)
{
#if BSP_WANT_ETHERNET || BSP_WANT_WIRELESS
    int callStatus = 0, updated;
#endif
#if BSP_ETH_WIFI_BRIDGE || BSP_WANT_ETHERNET
    bpDuplexLevelType newDuplex = bpDefaultDuplex;
#endif


    /*  Operator has been authenticated */
    printf("\r\n");
    printf("For each of the following questions, you can press <Return> to ");
    printf("select the value shown in braces, or you can enter a new value.\r\n"); 
    printf("\r\n");

/*
 * Ethernet and the bridge share the same NVRAM configuration space, so handle
 * their dialog stuff together.
 */
#if BSP_ETH_WIFI_BRIDGE || BSP_WANT_ETHERNET
#if BSP_ETH_WIFI_BRIDGE
    printf("ETHERNET/WIRELESS BRIDGE INTERFACE SETTINGS:\r\n\r\n");
    callStatus = NAIPParamDialog(nvParamsPtr, BP_EWB_INTERFACE, 
                    "Obtain IP settings automatically using DHCP for bridge interface");
#else
    printf("ETHERNET INTERFACE SETTINGS:\r\n\r\n");
    callStatus = NAIPParamDialog(nvParamsPtr, BP_ETH_INTERFACE, 
                    "Obtain IP settings automatically using DHCP for Ethernet interface");
#endif

    if (callStatus != DIALOGUPDATED)
    {
        return callStatus;
    }

	printf ("\r\n");

#if BSP_ETH_WIFI_BRIDGE
    callStatus = NAIPv6ParamDialog(nvParamsPtr, BP_EWB_INTERFACE, "bridge");
#else
    callStatus = NAIPv6ParamDialog(nvParamsPtr, BP_ETH_INTERFACE, "Ethernet");
#endif
    if (callStatus != DIALOGUPDATED)
    {
        return callStatus;
    }
    printf ("\r\n");

    printf("This interface must have a unique MAC address.\r\n");
#if BSP_ETH_WIFI_BRIDGE
    updated = promptForMacAddress("Bridge MAC Address ", nvParamsPtr->ethernetMac);
#else
    updated = promptForMacAddress("Ethernet MAC Address ", nvParamsPtr->ethernetMac);
#endif
     do
     {
        newDuplex = kbGetDuplex ("Ethernet duplex setting (default, full, half)? " , nvParamsPtr->defaultDuplexLevel);
        if (isDuplexValid(newDuplex) == FALSE)
        {
            printf("You must select Full duplex, Half duplex, or the PHY's Default setting.\n\n");
        }
     } while (isDuplexValid(newDuplex) == FALSE);

     updated |= (newDuplex != nvParamsPtr->defaultDuplexLevel);
     nvParamsPtr->defaultDuplexLevel = newDuplex;
#endif

#if BSP_WANT_WIRELESS
    printf ("\r\n");
    printf("WIRELESS INTERFACE SETTINGS:\r\n\r\n");

#if !BSP_ETH_WIFI_BRIDGE
/*
 * Don't care about DHCP for wireless if bridge is running, so don't confuse the
 * user by prompting for it if the bridge is running.
 */
    callStatus = NAIPParamDialog(nvParamsPtr, BP_WLN_INTERFACE, 
                    "Obtain IP settings automatically using DHCP for WIFI interface");
   
    if (callStatus != DIALOGUPDATED)
    {
        return callStatus;
    }
	printf ("\r\n");

	callStatus = NAIPv6ParamDialog(nvParamsPtr, BP_WLN_INTERFACE, "wireless");
	if (callStatus != DIALOGUPDATED)
    {
        return callStatus;
    }
#endif
    printf ("\r\n");

    printf("This interface must have a unique MAC address.\r\n");
#if BSP_WANT_ETHERNET
    updated |= promptForMacAddress("Wireless MAC Address ", nvParamsPtr->wlnParams.sta_addr);
#else
    updated = promptForMacAddress("Wireless MAC Address ", nvParamsPtr->wlnParams.sta_addr);
    if (updated)
    {
        #ifdef DEBUG_WIRELESS_MACADDRESS
        printf("NANetworkDialog: new wireless mac address");
        #endif
    }
#endif
    /* country code */    
    fflush(stdout);
    updated |= kbGetCountryCode("Country name [%s]? ", &nvParamsPtr->wlnExtParams.wlnCountryCode);
    wln_country_code = (wln_country_code_t)nvParamsPtr->wlnExtParams.wlnCountryCode;

#ifdef MAC_PS_ENABLED
#if BSP_WIFI_DUTY_CYCLE_CONFIG_ENABLE
    {
        int flag = NADIALOG_CUSTOM_REPLY;
        int value;
        
        if (nvParamsPtr->wlnParams.options & WLN_OPT_PS_ENABLE) {
            flag |= NADIALOG_CUSTOM_DEF_YES;
        }
        if (kbGetReply ("Enable duty cycle", flag))
        {
            nvParamsPtr->wlnParams.options |= WLN_OPT_PS_ENABLE;
            if (!(flag & NADIALOG_CUSTOM_DEF_YES))
            {
                updated |= 1;
            }

            value = nvParamsPtr->wlnExtParams.dutyCycle.ontime;
            updated |= kbGetNumber("ON period in milli sec (min 100) [%d]? ", 
                  &value, WLN_PS_MIN_ON_TIME, 50000);
            nvParamsPtr->wlnExtParams.dutyCycle.ontime = (unsigned short)value;
            
            value = nvParamsPtr->wlnExtParams.dutyCycle.offtime;
            updated |= kbGetNumber("OFF period in milli sec (max 500) [%d]? ", 
                  &value, 0, WLN_PS_MAX_OFF_TIME);
            nvParamsPtr->wlnExtParams.dutyCycle.offtime = (unsigned short)value;
            
        }
        else
        {
            nvParamsPtr->wlnParams.options &= ~WLN_OPT_PS_ENABLE;
            
            if (flag & NADIALOG_CUSTOM_DEF_YES)
            {
                updated |= 1;
            }
        }
    }
#endif
#endif
    
    fflush(stdout);
    updated |= NAWirelessDialog(&nvParamsPtr->wlnParams);
    
    {
        unsigned long chan_mask[2];
        
        if (wln_get_channel_mask(wln_country_code, chan_mask) < 0)
        {
            chan_mask[0] = WLN_CHANMASK_ALL;
            chan_mask[1] = WLN_CHANMASK_ALL_HIGH;
        }

        if ((nvParamsPtr->wlnParams.band == WLN_BAND_B) || 
            (nvParamsPtr->wlnParams.band == WLN_BAND_BG))
        {
            chan_mask[0] &= 0x00003FFF;
            chan_mask[1] = 0;    
        }

        if (nvParamsPtr->wlnParams.band == WLN_BAND_A)
        {
            chan_mask[0] &= 0xFFFFC000;
        }

        if (!(nvParamsPtr->wlnParams.options & WLN_OPT_SPECTRUM_MGMT))
        {   // clear DFS channels
            chan_mask[0] &= ~DFS_CHANNEL_MASK_LOW;
            chan_mask[1] &= ~DFS_CHANNEL_MASK_HIGH;
        }

        if ((nvParamsPtr->wlnParams.chan_mask != chan_mask[0]) ||
            (nvParamsPtr->wlnExtParams.ext_chan_mask != chan_mask[1]))
        {
            nvParamsPtr->wlnParams.chan_mask = chan_mask[0];
            nvParamsPtr->wlnExtParams.ext_chan_mask = chan_mask[1];
            updated |= 1;            
        }            
    }
#endif

    if (NAGetAppEnablePPP1 ())
    {
        /* ppp com1 address */
        kbGetIpAddress ("PPP interface 1", &nvParamsPtr->ipAddrPpp1);

        /* ppp com1 peer address */
        kbGetIpAddress ("PPP interface 1 Peer", &nvParamsPtr->ipAddrPpp1peer);
    }

    if (NAGetAppEnablePPP2 ())
    {
        /* ppp com2 address */
        kbGetIpAddress ("PPP interface 2", &nvParamsPtr->ipAddrPpp2);

        /* ppp com2 peer address */
        kbGetIpAddress ("PPP interface 2 Peer", &nvParamsPtr->ipAddrPpp2peer);
    }

    if (NAGetAppUseNetworkTimeProtocol ())
    {
        /*  Primary SNTP Server */
        kbGetIpAddress ("Primary SNTP Server", &nvParamsPtr->ipAddrSntp1);

        /*  Secondary SNTP Server */
        if (nvParamsPtr->ipAddrSntp1 != 0)
        {
            kbGetIpAddress ("Secondary SNTP Server", &nvParamsPtr->ipAddrSntp2);
        }
    }

    return DIALOGUPDATED;
}

/*ad*
 *
 * Displays those items you would like to update,
 * and gets the update information from keyboard.
 *
 * @param   itemDesc    Points to the string which contains descriptions of the item.
 * @param   destBuffer  points to an array to hold the new information.
 * @param   length      length boundary of new information
 * @param   flag        to indicate if we need the new information to be entered again.
 *
 * @return  0           no update, keep the old setting
 * @return  1           updated     
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD SHOULD YOU USE DIFFERENT 
 *          DISPLAY FORMAT. The implementation below is for NET+OS development 
 *          boards only.
 *
*ad*/ 
static int kbGetData(char * itemDesc, char * destBuffer, unsigned int length, int flag)
{
    int rc;

    char srcBuffer_1[128];
    char srcBuffer_2[128];

    while (1)
    {
        printf("Enter the new %s:    ", itemDesc);
        fflush(stdout);
        readPassword(srcBuffer_1, sizeof srcBuffer_1);
        if (srcBuffer_1[0] == '\0')
        {
            rc = 0;
            break;
        }

        if (strlen(srcBuffer_1) < length)
        {
            if (flag & NADIALOG_VERIFY)
            {
                /* verify input */
                printf("Re-enter the new %s: ", itemDesc);
                fflush(stdout);
                readPassword(srcBuffer_2, sizeof srcBuffer_2);
            }

            if (!(flag & NADIALOG_VERIFY)  || strcmp (srcBuffer_1, srcBuffer_2) == 0)
            {
                /*  update destination buffer  */
                memset (destBuffer, 0, length);
                strcpy (destBuffer, srcBuffer_1);
                rc = 1;
                break;
            }
            
            printf("ERROR: %s entries mismatched.\r\n", itemDesc);
        }
        else
        {
            printf("ERROR: Invalid %s.  Length must be less than %d characters.\r\n", itemDesc, length);
        }
    }

    return (rc);
}

/*ad*
 *
 * Displays those items you would like to update,
 * and gets the update information from keyboard.
 *
 * @param     itemDesc    points to the string which contains descriptions of the item.
 * @param     destBuffer  points to an array to hold the new information.
 * @param     length      length boundary of new information
 * @param     flag        to indicate if we need the answer to be yes or no,
 *                        or indicate if we need the new information to be entered again.
 *
 * @return    0           no update, keep the old setting
 * @return    1           updated     
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD SHOULD YOU USE DIFFERENT 
 *          DISPLAY FORMAT. The implementation below is for NET+OS development 
 *          boards only.
 *
*ad*/ 
static int kbGetString(char * itemDesc, char * destBuffer, int length, int flag)
{
    int rc;

    while (1)
    {
        fflush(stdout);
        if (kbGetReply (itemDesc, flag))
        {
            if (kbGetData (itemDesc, destBuffer, length, flag))
            {
                rc = 1;
                break;
            }
        }
        else
        {
            /* No update */
            rc = 0;
            break;
        }
    }
    
    return (rc);
}

/*ad*
 *
 * Gets new security information.
 *
 * @param   nvParamsPtr     pointer to structure with development board parameters
 *
 * @return  0       no updates
 * @return  1       Some or all security information was updated
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 *          below is for NET+OS development boards only.
 *
*ad*/ 
static int NASecurityDialog(devBoardParamsType * nvParamsPtr)
{
    char s[20];
    char buffer[128];
    int updated = 0;
    char *valueStr;
    char bufDesc[32];
    char password[NASYSACC_STRLEN_PASSWORD];

    if (NAGetAppRootPassword () || NAGetAppAdministratorsAccount () )
    {
        printf("\r\nSECURITY SETTINGS:\r\n\r\n");
    }

    /*  root password   */
    if (NAGetAppRootPassword ())
    {
        if (kbGetString ("Root Password", password, NASYSACC_STRLEN_PASSWORD, NADIALOG_VERIFY)) 
        {
            if (nvParamsPtr->rootPassword[0] == 0)
            {
                NAsetSysAccess (NASYSACC_DEL, "root", NAGetAppRootPassword (), NASYSACC_LEVEL_ROOT, 0);
            }
            else
            {
                NAsetSysAccess (NASYSACC_DEL, "root", nvParamsPtr->rootPassword, NASYSACC_LEVEL_ROOT, 0);
            }

            NAsetSysAccess (NASYSACC_ADD, "root", password, NASYSACC_LEVEL_ROOT, 0);

            /*  update the nvParams record  */
            memset (nvParamsPtr->rootPassword, 0, sizeof(nvParamsPtr->rootPassword));
            strcpy (nvParamsPtr->rootPassword, password);
            updated = 1;
        }
    }

    /*  administrator account password  */
    if ((valueStr = NAGetAppAdministratorsAccount ()) != NULL)
    {
        sprintf (bufDesc, "Administrator '%s' Password", valueStr);
        updated |= kbGetString (bufDesc, nvParamsPtr->adminPassword, NASYSACC_STRLEN_PASSWORD, NADIALOG_VERIFY);
    }
     
    printf("\r\n");
    printf("MISCELLANEOUS SETTINGS:\r\n");
    printf("\r\n");

    /*set the board's serial number?*/
    printf("Each development board must have a unique serial number\r\n");
    memcpy(s,  nvParamsPtr->serialNumber,sizeof(nvParamsPtr->serialNumber));
    s[BP_SERIAL_NUMBER_LENGTH]=0;  /*for correct printf %s format*/
    while (1)
    {
        printf("Set the board's serial number[%s]? ", s);
        fflush(stdout);
        readLine(buffer);  
        if (buffer[0] == '\0')
        {
            break;
        }

        if ( checkSerialNumber(buffer))
        {
                memcpy(nvParamsPtr->serialNumber, buffer ,sizeof(nvParamsPtr->serialNumber));
                memcpy(s,  nvParamsPtr->serialNumber,sizeof(nvParamsPtr->serialNumber));
                s[BP_SERIAL_NUMBER_LENGTH]=0;  /*for correct printf %s format*/
                printf("  The board's new serial number is %s\r\n", s);
                updated = 1;
                break;
        }

        printf("The board's serial number has to be A00000000-Z99999999.\r\n");
        printf("1 alpha character followed by 8 digits.\r\n");
    }
   
    printf("\r\n");
    
    /*set wait time?*/
    printf("How long (in seconds) should CPU delay before starting up [%lu]? ", nvParamsPtr->waitTime);
    fflush(stdout);
    readLine(buffer);  
    if (buffer[0] != '\0')
    {
        if(buffer[1] == '\0')
        {
            if (buffer[0] < 0x31)
            {
                nvParamsPtr->waitTime = 1;
                printf("The smallest wait time is 1 second.\r\n");
            }
            else
            {
                nvParamsPtr->waitTime = buffer[0]-0x30;        
            }
        }
        else
        {
            nvParamsPtr->waitTime = (unsigned long)((buffer[0]-0x30)*10) + (unsigned long)(buffer[1]-0x30);
        }
         
        printf("  After board is reset, start-up code will wait %lu seconds.\r\n", nvParamsPtr->waitTime);   
        updated = 1;
     }

    return (updated);
}

/*ad*
 *
 * Validates the board's serial number.
 *
 * @param      buffer    points to the string which contains serial number.
 *
 * @return     0         invalid
 * @return     1         valid
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 *          below is for NET+OS development boards only.
 *
*ad*/ 
static int checkSerialNumber(char * buffer)
{
    int i;
    int result = 0;
  
    if (((BP_SERIAL_NUMBER_LENGTH + 1) == strlen(buffer)) && (toupper(buffer[0]) == 'S'))
    {
        /*
         * Digi Manufacturing process prefixes serial numbers with a leading
         * S.  Ingore it.
         */
        memmove(buffer, &buffer[1], BP_SERIAL_NUMBER_LENGTH + 1);
    }

    if (BP_SERIAL_NUMBER_LENGTH == strlen(buffer))
    {
        /*
         * Digi serial number must consist of a letter followed by 8 digits.
         */
        if (!isalpha(buffer[0]))
        {
            goto done;
        }
        for (i = 1; i < BP_SERIAL_NUMBER_LENGTH; i++)
        {
            if (!isdigit(buffer[i]))
            {
                goto done;
            }
        }
        result = 1;
    }
    done:
    
    return result;    
} 


#if BSP_ETH_WIFI_BRIDGE || BSP_WANT_ETHERNET
/*ad*
 *
 * Prompts for a duplex level.
 *
 * @param     desc        points to the string which contains description of the item.
 * @param     setting     indicates current duplex setting
 *
 *  Return Values:
 *
 * @return     bpHalfDuplex      half duplex
 * @return     bpFullDuplex      full duplex  
 * @return     bpDefaultDuplex   automatically negotiated duplex level
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD SHOULD YOU USE DIFFERENT 
 *          DISPLAY FORMAT. The implementation below is for NET+OS development 
 *          boards only.
 *
*ad*/ 
static bpDuplexLevelType kbGetDuplex(char * desc, bpDuplexLevelType setting)
{
    bpDuplexLevelType   reply;
    char buffer[128];



    while (1)
    {
        printf ("%s[%s] ", desc, getDuplexString(setting));
        fflush(stdout);

        readLine (buffer);
        if (buffer[0] == 'f' || buffer[0] =='F')
        {
            reply = bpFullDuplex;
            break;
        }

        if (buffer[0] == 'h' || buffer[0] =='H') 
        {
            reply = bpHalfDuplex;
            break;
        }
        
        if (buffer[0] == 'd' || buffer[0] =='D') 
        {
            reply = bpDefaultDuplex;
            break;
        }
        
       if (buffer[0] == 0)
        {
            reply = setting;
            break;
        }
    }

    return (reply);
}
#endif /* BSP_WANT_ETHERNET */

#define ETHERNET_MAC_ADDRESS_LENGTH         (6)


#if BSP_WANT_ETHERNET || BSP_WANT_WIRELESS

static int promptForMacAddress (char *description, unsigned char *macAddress)
{
    char addressDescription[20];
    char buffer[128];
    int updated = 0;
    
    sprintf(addressDescription, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]);
    while (1)
    {
        BYTE tempMacAddress[ETHERNET_MAC_ADDRESS_LENGTH];
        
        printf("%s[%s]? ", description, addressDescription);
        fflush(stdout);
        readLine(buffer);  
        if (buffer[0] == '\0')
        {
            goto done;
        }

        if ( NAConvertMacAddressString(tempMacAddress, buffer) == BP_SUCCESS)
        {
            memcpy(macAddress, tempMacAddress, ETHERNET_MAC_ADDRESS_LENGTH);
            printf("  This board's new %s is %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\r\n", description,macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]);                  
            updated = 1;
            goto done;
        }

        printf("The %s must consist of 6 2-hexdigit \r\n", description);
        printf("values seperated by colons.\r\n");
    }
done:
    return updated;
}
#endif

#if (BSP_WPS_START == TRUE)
int NAWpsDialog(void) 
{
#define _METHOD_COUNT 3

    char    buffer[256];
    char    pin[9]="\0";
    int     result; 
    int     status;
    char    * bp;
    int     len;
    int     i, j;

    struct   wps_selection {
        unsigned int    config_method;
        unsigned int    device_id;
        char            * string;
        unsigned char   enabled;
    } wps_selections[_METHOD_COUNT] = {
        { NA_WPS_CONFIG_METHOD_PBC, NA_WPS_DEVICE_PWD_ID_PBC, "for Push Button Configuration (PBC)", 0},
        { NA_WPS_CONFIG_METHOD_LABEL | NA_WPS_CONFIG_METHOD_DISPLAY, NA_WPS_DEVICE_PWD_ID_DEFAULT, "for PIN Configuration", 0},
#if (BSP_ENABLE_WCN_UFD == TRUE)
        { NA_WPS_CONFIG_METHOD_USBA, NA_WPS_DEVICE_PWD_ID_USER_SPEC, "for WCN-UFD (USB drive)", 0},
#endif
    };
    int id_selections[_METHOD_COUNT] = {0};
    int id;

    NaWpsDevice_t * pWpsDevice = naWpsGetDevice();

    fflush(stdout);

    printf("\r\nWi-Fi Protected Setup (WPS):\r\n");
    printf("\r\nA wireless router has to support WPS \r\n");
    printf("in order to use this feature. Please Check the user\r\n");
    printf("manual.\r\n");

//    printf("\r\nAfter you have started the Simple Configuration, \r\n");
//    printf("you must start the Simple Configuartion of your router \r\n");
//    printf("that you want to connect to.\r\n");

    naWpsGetPin(pin);

    /* figure out the supported config methods */
    if (pWpsDevice != NULL)
    {
        for (i=0; i < (int)asizeof(wps_selections); i++)
        {
            if (pWpsDevice->configMethods & wps_selections[i].config_method)
            {
                wps_selections[i].enabled = 1;
            }
        }
    }

    bp = buffer;
    len = sprintf(bp, "\r\nConfiguration Type [0]?\r\n");
    bp += len;

    for (i=0, j=0; i < (int)asizeof(wps_selections); i++)
    {
        if (wps_selections[i].enabled)
        {
            id_selections[j] = i;

            if (wps_selections[i].device_id == NA_WPS_DEVICE_PWD_ID_DEFAULT)
            {
                len = sprintf(bp, "    %d %s (PIN = %8s)\r\n", j, wps_selections[i].string, pin);
            }
            else
            {
                len = sprintf(bp, "    %d %s\r\n", j, wps_selections[i].string);
            }
            bp += len;
            j++;
        }
    }

    len = sprintf(bp, "    %d exit Wi-Fi Protected Setup.\r\n", j);

    result = -1;    
    kbGetNumber(buffer, &result, 0, j);

    if (result == -1)
    {
        id = id_selections[0];
    }
    else if (result < j)
    {
        id = id_selections[result];
    }
    else
    {
        goto _ret;
    }

    
    if (wps_selections[id].config_method & NA_WPS_DEVICE_PWD_ID_USER_SPEC)
    {
        printf("Please plug your USB flash drive...\n");
    }
    else 
    {
        /* TO DO:
         * Tell USB not to run WCN.
         */
        printf("Please wait (key generation)...\r\n");

        status = naWpsStart(0, wps_selections[id].device_id, NULL, NULL, 0);
        if (status != NASTATUS_SUCCESS)
        {
            printf("\r\nUnable to start WPS 0x%x\r\n", status);
        }
        else
        {
            printf("\r\nPlease start WPS on the router...\r\n");            
#if (BSP_ENABLE_WCN_UFD == TRUE)
            naWcnUfdDisableService();
#endif
        }                                                                      

    }

_ret:    
    return 0;
}

void naDialogHandleWps(void)
{
    devBoardParamsType *nvParams;

    nvParams = (devBoardParamsType *)malloc(sizeof(devBoardParamsType));
    if (nvParams == NULL) goto _ret;

    if (dialogWPSEnabled)
    {
        customizeReadDevBoardParams (nvParams);

        /* Open Dialog for Non-Blocking Mode */
        NAOpenDialog (1, nvParams);

        NAWpsDialog();

        /* Close Dialog */
        NACloseDialog ();
    }
    free(nvParams);

_ret:
    return;
}

#endif


/*ad*
 *
 * Gets new hardware related information.
 *
 * @param     nvParamsPtr     pointer to structure with development board parameters
 *
 * @return    0     no updates
 * @return    1     some or all hardware related information was updated
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 *          below is for NET+OS development boards only.
 *
*ad*/    
static int NAHardwareDialog(devBoardParamsType * nvParamsPtr)
{
    char buffer[128];
    int updated = 0;
    unsigned long baudrate;

    printf("\r\n");
    printf("SERIAL CONSOLE PORT SETTINGS:\r\n");  
    
    /*set the baudrate*/
    printf("\r\n");
    
    while (1)
    {
        printf("Set the baud rate of the serial console port [%lu]?\r\n    9600, 19200, 38400, 57600, 115200\r\n",nvParamsPtr->baudrate);
        readLine(buffer);  
        if (buffer[0] == '\0')
        {
            baudrate = nvParamsPtr->baudrate;
        }
        else
        {

            baudrate = atol(buffer);
        }
        if (isBaudRateValid(baudrate))    
        {
            if (nvParamsPtr->baudrate != baudrate)
            {
                printf("  The new baud rate is %lu\r\n", baudrate);
                printf("  The baud rate will be changed on next power up\r\n");
                printf("  Please set the baud rate for your terminal accordingly\r\n");
            }
            nvParamsPtr->baudrate = baudrate;
            updated = 1;
            break;
        }

        printf("The baud rate has to be 1200, 2400, 4800, 9600, 19200, 38400, 57600, or 115200\r\n");
    }

    return (updated);
}

/*ad*
 *
 * Update board parameters if there is any change.
 *
 * @param     nvParamsPtr     pointer to structure with development board parameters
 *
 * @return    0               board parameters are updated
 *
 * @location src/bsp/customize/dialog.c
 * @category BSP:Board_Params  
 * @since 6.0
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 *          below is for NET+OS development boards only.
 *
*ad*/         
static int NAUpdateDialog(devBoardParamsType * nvParamsPtr)     
{
   /* 
    * save all the changes in NVMEM
    * if the APP_USE_NVRAM flag is set to 0, just update default parameters.
    * 
    */
    printf("\r\n");
    
    if (NAGetAppUseNvram () != APP_DO_NOT_USE_NVRAM)
    {
        printf("Saving the changes in NV memory...");
        fflush(stdout);
        if (customizeWriteDevBoardParams (nvParamsPtr) == 0)
        {
            printf ("Done.\r\n");
        }
        else
        {
            printf ("\r\nError writing to NVRAM.\r\n");
            tx_thread_sleep(NABspTicksPerSecond);
        }
    }        
    else
    {
        printf("APP_USE_NVRAM is set to 0 in appconf.h.  Your changes will not be saved.\r\n");
        tx_thread_sleep(NABspTicksPerSecond);
    }
         
    tx_thread_sleep(NS_MILLISECONDS_TO_TICKS(250)); /*to see better*/
    return (0);
}

/*ad*
 *
 * Sets up configuration dialog if @link BSP_ENABLE_DIALOG is defined.
 *
 * @location src/bsp/customize/dialog.c
 * @include <dialog.h>
 * @category BSP:Board_Params  
 * @since 6.0
 * @see @link BSP_ENABLE_DIALOG
 * @see @link BSP_DIALOG_PORT
 *
 * @note    THIS CODE MUST BE CUSTOMIZED FOR YOUR BOARD.  The implementation
 *          below is for NET+OS development boards only.
 *
*ad*/ 
void customizeDialog(void)
{
    devBoardParamsType *nvParams;
    unsigned int updated = 0;
    char myBuffer[128] = {0};

    /* array of error messages used for IP validation */
    char *validationfailure[14] =
    {    
        "No Error. Valid IP Address.",
        "IP Address is not subnetable. Subnet Mask and Gateway must be 0.0.0.0.",
        "IP Address 0.0.0.0 is not allowed.",
        "IP Address and Gateway Address match.",
        "IP Address or Gateway Address is a Multicast Address.",
        "IP Address or Gateway Address is a Local Loopback Address.",
        "IP Address or Gateway Address can not begin with 0.",
        "Subnet Mask can not be 0.0.0.0.",
        "Subnet Mask can not exceed 255.255.255.252.",
        "Invalid IP Address. It is the Network ID of the subnet.",
        "Invalid IP Address. It is the subnet Broadcast Address.",
        "Invalid Gateway Address. It is the Network ID of the subnet.",
        "Invalid Gateway Address. It is the subnet Broadcast Address.",
        "Invalid Gateway Address. It is not on the subnet."
    };

    if (NAGetAppDialogPort () == 0)
    {
        /* No DIALOG defined */ 
        return;
    }

#if MANUFACTURING_MODE
    mfgInitializeMfgPins();
#endif

    nvParams = (devBoardParamsType *)malloc(sizeof(devBoardParamsType));
    if (nvParams == NULL)
    {
        return;
    }

        /*  
         *  customizeReadDevBoardParams() reads the contents of the section of NVRAM that contains
         *  the development board's startup parameters if APP_USE_NVRAM flag is set to a nonzero value. 
         *  If APP_USE_NVRAM is 0, customizeReadDevBoardParams() reads the default parameters as defined
         *  in appconfig.h. customizeReadDevBoardParams() and default data struct are in 
         *  customize\boardParams.c.
         *
     */
    do
    {
        updated = 0;
        customizeReadDevBoardParams (nvParams);

#if MANUFACTURING_MODE
        if (areWeInTestMode())
        {
  	 	    /* Open Manufacturing/Diagnostics dialog in blocking mode */
            NAOpenDialog(1, nvParams);
            
            mfgDisplayDialog(nvParams);
            
            /* Close Manufacturing/Diagnostics Dialog */
            NACloseDialog(); 
            
            break;
        }
        else
            mfgConfigureDefaultParams(nvParams);        
#endif

        /* Open Dialog for Non-Blocking Mode */
        NAOpenDialog (0, nvParams);

        /* Display Configuration */
        NADisplayDialog (nvParams);

        /* Changing configuration? */
        if (NAConfigureDialog (nvParams) == 1)
        {

         /* 
          * we want to loop until the guy provides us with a valid set of 
          * ip address, gateway and subnet mask
          * by looping here we keep the guy from having to reenter the password
          */
          do
          {
              updated = NANetworkDialog (nvParams);
              if(updated != DIALOGUPDATED)    /*there is an error */
              {
                  printf("\r\n");
                  printf("\r\n");
                  printf("-----------------------------------------------------------------------------\r\n");
                  printf("Invalid network information entered. Please review and reenter.\r\n");
                  printf("\r\nERROR %d: %s\r\n", updated, validationfailure[updated]);
                  printf("\r\nHit return to continue.\r\n");
                  printf("-----------------------------------------------------------------------------\r\n");
                  readLine(myBuffer);
                  printf("\r\n");
              }
          } while (updated != DIALOGUPDATED);
          
          updated |= NAHardwareDialog (nvParams);
          updated |= NASecurityDialog (nvParams);
          if (updated)
          {
            /* Update Dialog */
             NAUpdateDialog (nvParams);
          }
        }
        /* Close Dialog */
        NACloseDialog ();
    
    }while (updated != 0);   
    
    free(nvParams);

}
#endif /*#if BSP_ENABLE_DIALOG*/





