
#include <stdlib.h>
#include <tx_api.h>
#include <gpiomux_def.h>
#include <bsp_api.h>
#include <bsp.h>
#include <boardParams.h>
#include <narmapi.h>
#include <cliapi.h>
#include <iam_netos.hh>
#include "iam.hh"
#include <sysaccess.h>

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

#include "country_codes.h"
#include "wln_api.h"
#include "clisvr.h"
#include "cliwireless.h"
#include "dnsc_api.h"


#if (BSP_CLI_INCLUDE_IN_BSP && (BSP_CLI_SERIAL_ENABLE || BSP_CLI_TELNET_ENABLE || BSP_CLI_SSH_ENABLE))


#if BSP_WANT_WIRELESS


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

/* Description of each wireless protocol mode */
static const char *wln_modes[] = {
         "Infrastructure",
         "Ad hoc (join or create)",
         "Ad hoc (join only)",
         "Any type",
};


/* these options must be in sequence of the OPTION index number */
static char *cli_set_wireless_options[CLI_SET_WIRELESS_OPTION_MAX+1] =
    {
        "ip",
        "submask",
        "gateway",
        "dhcp",
        "primarydns",
        "secondarydns",
		"dhcpv6",
		"staticv6",
		"ipv6",
		"prefixlen",
        "protmode",
        "ssid",
        "channel",
        "authentication",

        "maxtxrate",
        "txpower",
        "wepkey1",
        "wepkey2",
        "wepkey3",
        "wepkey4",
        "wepindex",
        "wepmode",
        "encryption",   /* CLI_SET_WIRELESS_OPTION_ENCRYPTION 18 */

#if BSP_WANT_WPA
        "username",
        "password",
        "psk",
        "outer_eap",
        "inner_eap",    /* CLI_SET_WIRELESS_OPTION_INNER_EAP 23 */
#endif
        "country",
        "band",
        "802.11",
        "802.11d",
        NULL
    };

static char *cli_set_wireless_on_off[] =
    {
        "on",
        "off",
        NULL
    };

static char *cli_set_wireless_type[] =
    {
        "bss",
        "ibss_create",
        "ibss_join",
        "any",
        NULL
    };

static char *cli_set_wireless_authent[] =
    {
        "open",
        "wep_auth",
        "any",
#if BSP_WANT_WPA
        "sharedkey",
        "wpa_psk",
        "wpa_auth",
        "leap",
#endif
        NULL
    };


static char *cli_set_wireless_encrypt[] =
    {
        "open",
        "wep",
        "any",
#if BSP_WANT_WPA
        "tkip",
        "ccmp",
#endif
        NULL
    };

#if BSP_WANT_WPA
static unsigned long encryp_codes[] = 
{
    WLN_ENCR_OPEN, WLN_ENCR_WEP, WLN_ENCR_ANY, 
    WLN_ENCR_TKIP, WLN_ENCR_CCMP
};
#endif

static char *cli_set_wireless_wepmode[] =
    {
        "64bit",
        "128bit",
        NULL
    };
 
static char *cli_set_wireless_txrate_options[] =
    {
        "0",
        "1mb",
        "2mb",
        "5.5mb",
        "11mb",
#ifdef BSP_ARM9
        "6mb",
        "9mb",
        "12mb",
        "18mb",
        "24mb",
        "36mb",
        "48mb",
        "54mb",
#endif
        NULL
    };

#if BSP_WANT_WPA
static char *cli_set_wireless_outer_eap[] =
    {
        "peap",
        "tls",
        "ttls",
        "any",
        NULL
    };

static char *cli_set_wireless_inner_eap[] =
    {
        "gtc",
        "md5",
        "mschapv2",
        "otp",
        "chap",
        "mschap",
        "ttls_mschapv2",
        "pap",
        "any",
        "none",
        NULL
    };

#endif

static const char *cli_set_wireless_frequency_band[] = {
        "all bands: a, b and g",
        "band a only", 
        "band b only",   
        "band bg",    
};

int setWepKeyN(int fd, int index, char *inBuf,  NaWlnParams_t *wp) {
    int i, n;
    int len = strlen(inBuf);
    unsigned char key[WLN_WEP104_SIZE];

    if ((len == 0) || (len%2 != 0) ||
            ((len != (WLN_WEP104_SIZE * 2)) && (len != (WLN_WEP40_SIZE * 2)))) {
        return cli_bad_option(fd, inBuf);
    }

    char *buf = inBuf;
    for (i = 0; i < WLN_WEP104_SIZE; i++) {
        if (isxdigit(buf[2*i]) && isxdigit(buf[2*i+1]) &&
                sscanf(&buf[2*i], "%2x", &n) == 1) {
            key[i] = n;
        } else {
            break;
        }
    }

    if (i == WLN_WEP40_SIZE || i == WLN_WEP104_SIZE) {
        memset(wp->wep_key[index], 0, WLN_WEP104_SIZE);
        memcpy(wp->wep_key[index], key, i);
    } else {
        return cli_bad_option(fd, inBuf);
    }

    return 0;
}
int cli_process_dhcp_option(int fd, char * result, NaIamParams_t *interface)
{
   int rc = 0;

   switch (naCliWhichOp(result, cli_set_wireless_on_off)) {
        case CLI_SET_NETWORK_OPTION_ON:
            /*
             * Disable the static configuration to make IAM get an address from the network.
             * The protocols actually used by IAM are determined by the settings stored
             * in NVRAM.
             */
            interface->staticParams.isEnabled = FALSE;

            break;

        case CLI_SET_NETWORK_OPTION_OFF:
            /*
             * Enabling the static configuration will cause IAM to ignore the settings used
             * for DHCP, BOOTP, et al on the same interface.
             */
            interface->staticParams.isEnabled = TRUE;

            break;
        default:
            rc = -1;
            break;
    }

    return rc;
}

void cli_print_supported_countries(int fd)
{
    int i, j;
    wln_country_code_t * country_list;
    int                 list_len;
    char                country_name[80];

    country_list = wln_get_supported_country_list(&list_len);
    if (country_list == NULL)
    {
        naCliPrintf(fd, "\r\nNo Supported country is setup.");
        goto _ret;
    }

    naCliPrintf(fd, "   Supported Countires: (");

    for (i=0; i < list_len; i++)
    {
        strcpy(country_name, wln_get_country_string_from_code(country_list[i]));
        for (j=0; j < strlen(country_name); j++)
        {
            if (country_name[j] == ' ') country_name[j] = '-';
        }
        naCliPrintf(fd, "%s", country_name);
        if ((i+1) < list_len) 
            naCliPrintf(fd, "|");

    }
    naCliPrintf(fd, ")\r\n\r\n");
_ret:
    return;
}

int cli_set_country_option(int fd, char * string, wln_country_code_t * country_code)
{
    int                 rc = -1;
    int                 i;
    wln_country_code_t  country;

    for (i=0; i < strlen(string); i++)
    {
        if (string[i] == '-') string[i] = ' ';
    }

    country = wln_get_country_code_from_string(string);
    if (country != COUNTRY_NOTFOUND)
    {
        if (wln_is_country_valid(country) == 1)
        {
            *country_code = country;
            rc = 0;
        }
    }
    return rc;
}


int cli_process_country_option(int fd, char * string, wln_country_code_t * country_code)
{
    int                 rc = -1;

    rc = cli_set_country_option(fd, string, country_code);

    if (rc != 0) 
    {
        cli_print_supported_countries(fd);
    }

    return rc;
}

static char *dh_80211_options[] = { "d", "h", "none" };

int cli_process_802_11_dh_options(int fd, char * string, unsigned long * option)
{
   int rc = 0;

   switch (naCliWhichOp(string, dh_80211_options)) {
        case 0:
            *option |= WLN_OPT_MULTI_DOMAIN;

            break;

        case 1:
            *option |= (WLN_OPT_SPECTRUM_MGMT | WLN_OPT_MULTI_DOMAIN);

            break;

        case 2:
            *option &= ~(WLN_OPT_MULTI_DOMAIN | WLN_OPT_SPECTRUM_MGMT);

            break;
        default:
            rc = -1;
            break;
    }

    return rc;
}


int cli_process_802_11_d_options(int fd, char * string, unsigned long * option)
{
   int rc = 0;

   switch (naCliWhichOp(string, cli_set_wireless_on_off)) {
        case CLI_SET_NETWORK_OPTION_ON:
            *option |= WLN_OPT_MULTI_DOMAIN;

            break;

        case CLI_SET_NETWORK_OPTION_OFF:
            *option &= ~WLN_OPT_MULTI_DOMAIN;

            break;
        default:
            rc = -1;
            break;
    }

    return rc;
}

/*
 * WLN_BAND_DEFAULT 0
 * WLN_BAND_A       1
 * WLN_BAND_B       2
 * WLN_BAND_BG      3
 * WLN_BAND_MAX     4
*/
#ifdef BSP_ARM9
static char *supported_bands[WLN_BAND_MAX+1] = {
    "all", "a", "b", "bg", NULL
};
#else
static char *supported_bands[WLN_BAND_MAX+1] = {
    "b", NULL
};
#endif

void cli_print_supported_bands(int fd)
{
    int i;

    naCliPrintf(fd, "   Supported bands: (");

    for (i=0; supported_bands[i] != NULL; i++)
    {
#if (AIROHA_TRANSCEIVER == 1 )
        if (!isRF_AIROHA_7230()) 
        {   /* skip a band since it's not AIROHA 7230 */
            if (strcmp(supported_bands[i],"a") == 0) 
                continue;
        }
#endif
         naCliPrintf(fd, "%s", supported_bands[i]);
         if (supported_bands[i+1] != NULL)
             naCliPrintf(fd, "|");
    }
    naCliPrintf(fd, ")\r\n");
}

int cli_set_band_option(int fd, char * string, int * band)
{
    int rc = -1;
    int select_band;

    select_band = naCliWhichOp(string, supported_bands);

    if (select_band >= WLN_BAND_DEFAULT && select_band < WLN_BAND_MAX)
    {
        if (select_band != WLN_BAND_A) 
        {
            *band = select_band;
            rc = 0;
        }
#if (AIROHA_TRANSCEIVER == 1 )
        else if (isRF_AIROHA_7230()) 
        {
            *band = select_band;
            rc = 0;
         }
#endif
    }

    return rc;
}

int cli_process_band_option(int fd, char * string, int * band)
{
    int rc ;

    rc = cli_set_band_option(fd, string, band);
    if (rc != 0)
    {
        cli_print_supported_bands(fd);
    }

    return rc;
}

void cli_print_supported_channels(int fd, wln_country_code_t country_code, int band)
{

    int n, max, min;
    unsigned long mask[2];

    if (wln_get_channel_mask(country_code, mask) < 0)
    {
        naCliPrintf(fd, "\r\nNo Channel available for this country.\r\n");
        goto _ret;
    }
        
    max = ((band == WLN_BAND_B) || (band == WLN_BAND_BG)) ? 14 : WLN_CHAN_NUM;
    min = (band == WLN_BAND_A) ? 17 : 1;
        
    naCliPrintf(fd, "   Supported channels: (0 for search");
    for (n = min; n <= max; n++)
    {
        if (mask[(n-1)/32] & (1 << (n-1)%32))
        {
            if (n > 14)
                naCliPrintf(fd, "|a%d", wln_get_chan_info(n, NULL));
            else
                naCliPrintf(fd, "|%d", wln_get_chan_info(n, NULL));
        }
    }
    naCliPrintf(fd, ")\r\n\r\n");

_ret:
    return;
}

int cli_set_channel_option(int fd, char * string, int * channel, BOOL *chan_11a)
{
    int rc = -1;
    int n, value;
      
    if ((*string == 'a') || (*string == 'A'))
    {
        n = sscanf((string+1), "%d", &value);
        *chan_11a = TRUE;
    }
    else
    {
        n = sscanf(string, "%d", &value);
        *chan_11a = FALSE;
    }
    
    if (n == 1)
    {
        *channel = value;
        rc = 0;
        goto _ret;
    }

_ret:

    return rc;
}

int cli_process_channel_option(int fd, char * string, int * channel, BOOL *chan_11a)
{
    int rc;

    rc = cli_set_channel_option(fd, string, channel, chan_11a);
    /* we don't print supported channels here.
     * we need to process the all options in setwireless command
     * before printing supported channels if invalid channels 
     */
    return rc;
}

int cli_check_channel_option(int fd, int channel, devBoardParamsType * paramPtr, BOOL chan_11a)
{
    int rc = 0;
    int max, min;
    int sys_channel;
    unsigned long mask[2];

    if (channel == 0)
    {
        /* 0 is always accepted for SEARCH */
        paramPtr->wlnParams.channel = WLN_CHAN_SCAN;
        rc = 1;
        goto _ret;
    }

    if (wln_get_channel_mask((wln_country_code_t) paramPtr->wlnExtParams.wlnCountryCode, mask) < 0)
    {
        goto _ret;
    }
        
    max = ((paramPtr->wlnParams.band == WLN_BAND_B) || (paramPtr->wlnParams.band == WLN_BAND_BG)) ? 14 : WLN_CHAN_NUM;
    min = ((paramPtr->wlnParams.band == WLN_BAND_A)) ? 17 : 1;
        
    if (paramPtr->wlnParams.band == WLN_BAND_A) 
    {
        chan_11a = TRUE;
    }
            
    sys_channel = wln_is_channel_supported( (uint32 *)mask, channel, chan_11a);

    if (sys_channel > min && sys_channel <= max && mask[(sys_channel-1)/32] & (1 << (sys_channel-1)%32))
    {   /* good channel */
        paramPtr->wlnParams.channel = sys_channel;
        rc = 1;
    }
    else
    {
        naCliPrintf(fd, "\r\nerror: invalid option!\r\n");
        cli_print_supported_channels(fd, (wln_country_code_t) paramPtr->wlnExtParams.wlnCountryCode, paramPtr->wlnParams.band);
    }

_ret:

    return rc;
}


/*
 *
 *  Function: int cli_parse_set_wireless_parms(int fd, int n, char *args[], NaIamCfg_t *interface)
 *
 *  Description:
 *
 *      This function parses the supplied parameters and sets the values referenced by interface.
 *
 *  Parameters:
 *
 *      fd         Interface file descriptor. 
 *      n          The number of arguments to parse
 *      args       The arguments to parse
 *      interface  An Interface Address Manager configuration structure
 *
 *  Return Values:
 *
 *      <0         failure
 *      0          Success
 *
 */
int cli_parse_set_wireless_parms(int fd, int num, char *args[], NaIamParams_t *interface,
                                 devBoardParamsType *nvParamsPtr) {
    int     rc = -1;
    char    * equal_separator = "=";
    char    * result1[4];
    int     i, n, res;
    int     option_count;
    int     channel;
    BOOL    chan_11a = FALSE;    

    /* get the channel value first */    
    channel = wln_get_chan_info(nvParamsPtr->wlnParams.channel, NULL);

    /* look at each parameter. */
    for (i=0; i < num; i++) {
        /* split up the current option result1[0] holds the option and */
        /* result1[1] holds the value. */
        option_count = naCliSplitStr(args[i], result1, 4, equal_separator);

        if ((option_count != 2) || (result1[1] == NULL)) {
            return cli_bad_option(fd, args[i]);
        }

        /* process the current option */
        switch (naCliWhichOp(result1[0], cli_set_wireless_options)) {
        case CLI_SET_NETWORK_OPTION_IP:

            /* result1[1] is an IP address */
            if (cliCheckIpAddress(result1[1])) {
                /* set the static IP address portion of the interface. */
                interface->staticParams.IPV4_ADDR(ipAddress) = NAInet_addr(result1[1]);
            } else {
                return cli_bad_option(fd, result1[1]);
            }
            break;

        case CLI_SET_NETWORK_OPTION_SUBMASK:

            /* result1[1] is an IP SubMask */
            if (cliCheckIpAddress(result1[1])) {
                /* set the static IP subnet mask portion of the interface. */
                interface->staticParams.subnetMask = NAInet_addr(result1[1]);
            } else {
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_NETWORK_OPTION_GATEWAY:

            /* result1[1] is the IP address of the gateway */
            if (cliCheckIpAddress(result1[1])) {
                /* set the static IP address for the gateway portion of the interface. */
                interface->staticParams.IPV4_ADDR(gateway) = NAInet_addr(result1[1]);
            } else {
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_NETWORK_OPTION_DHCP:

            if (cli_process_dhcp_option(fd, result1[1], interface) != 0)
            {
                return cli_bad_option(fd, result1[1]);
            }

            break;

			case CLI_SET_NETWORK_OPTION_DHCPV6:
			{
            switch (naCliWhichOp(result1[1], cli_set_wireless_on_off)) {
            case CLI_SET_NETWORK_OPTION_ON:
                interface->staticParams.ipv6IsEnabled |= NA_IAM_DHCPV6_ENABLED;
                break;

            case CLI_SET_NETWORK_OPTION_OFF:
                interface->staticParams.ipv6IsEnabled &= ~NA_IAM_DHCPV6_ENABLED;
                break;

            default:
                return cli_bad_option(fd, result1[1]);
            }
			}
			break;

		case CLI_SET_NETWORK_OPTION_STATICV6:
			{
            switch (naCliWhichOp(result1[1], cli_set_wireless_on_off)) {
            case CLI_SET_NETWORK_OPTION_ON:
                interface->staticParams.ipv6IsEnabled |= NA_IAM_STATICV6_ENABLED;
                break;

            case CLI_SET_NETWORK_OPTION_OFF:
                interface->staticParams.ipv6IsEnabled &= ~NA_IAM_STATICV6_ENABLED;
                break;

            default:
                return cli_bad_option(fd, result1[1]);
			}
            }
			break;

		case CLI_SET_NETWORK_OPTION_PREFIX:
			{
				int num = atoi(result1[1]);
				if (num >= 0 && num <= 128)
				{
					interface->staticParams.ipv6PrefixLen = (WORD8) num;
				}
				else	
				{
					naCliPrintf(fd, "IPv6 network prefix length must be between 0 and 128\r\n");
					return cli_bad_option(fd, result1[1]);
				}
			}
			break;

		case CLI_SET_NETWORK_OPTION_IPV6:
			{
				struct sockaddr_storage ipv6addr;
				if (inet_pton(AF_INET6, result1[1], &ipv6addr.addr.ipv6.sin6_addr) == 1) 
				{
					ipv6addr.ss_family = AF_INET6;
					ipv6addr.ss_len = sizeof(struct sockaddr_in6);

					if (naValidateIpv6Information(&ipv6addr, interface->staticParams.ipv6PrefixLen) == 0)
					{
						interface->staticParams.ipv6Address = ipv6addr;
					}
					else
					if (naValidateIpv6Information(&ipv6addr, 64) == 0)
					{
						interface->staticParams.ipv6Address = ipv6addr;
						interface->staticParams.ipv6PrefixLen = 64;
						naCliPrintf(fd, "IPv6 network prefix length defauled to 64\r\n");
					}
					else
					{
						naCliPrintf(fd, "Invalid IPv6 address / prefix length combination\r\n");
						return cli_bad_option(fd, result1[1]);
					}
				}
				else
				{
					naCliPrintf(fd, "Invalid IPv6 address\r\n");
					return cli_bad_option(fd, result1[1]);
				}
			}
			break;

        case CLI_SET_NETWORK_OPTION_PRIMARY:

            /* result1[1] is an primary DNS IP */
            if (cliCheckIpAddress(result1[1])) {
                /* set the static IP address for the primary DNS portion of the interface. */
                interface->staticParams.IPV4_ADDR(primaryDns) = NAInet_addr(result1[1]);
            } else {
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_NETWORK_OPTION_SECONDARY:

            /* result1[1] is an primary DNS IP */
            if (cliCheckIpAddress(result1[1])) {
                /* set the static IP address for the secondary DNS portion of the interface. */
                interface->staticParams.IPV4_ADDR(secondaryDns) = NAInet_addr(result1[1]);
            } else {
                return cli_bad_option(fd, result1[1]);
            }

            break;


        case CLI_SET_WIRELESS_OPTION_TYPE:
            switch (naCliWhichOp(result1[1], cli_set_wireless_type)) {
            case CLI_SET_WIRELESS_OPTION_INFRA:
                nvParamsPtr->wlnParams.bss_type = CLI_SET_WIRELESS_OPTION_INFRA;

                break;

            case CLI_SET_WIRELESS_OPTION_CREATEJOIN:
                nvParamsPtr->wlnParams.bss_type = CLI_SET_WIRELESS_OPTION_CREATEJOIN;

                break;

            case CLI_SET_WIRELESS_OPTION_JOIN:
                nvParamsPtr->wlnParams.bss_type = CLI_SET_WIRELESS_OPTION_JOIN;

                break;

            case CLI_SET_WIRELESS_OPTION_ALL:
                nvParamsPtr->wlnParams.bss_type = CLI_SET_WIRELESS_OPTION_ALL;

                break;

            default:
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_WIRELESS_OPTION_SSID:
            n = strlen(result1[1]);
            /* ANY means to search for the SSID */
            if (strcmp(result1[1], "ANY") == 0) {
                n = 0;
            }

            memcpy (nvParamsPtr->wlnParams.ssid, result1[1], n);
            nvParamsPtr->wlnParams.ssid_len = n;

            break;

        case CLI_SET_WIRELESS_OPTION_COUNTRY_NAME:
            if (cli_process_country_option(fd, result1[1], (wln_country_code_t *)&nvParamsPtr->wlnExtParams.wlnCountryCode) != 0)
            {
                return cli_bad_option(fd, result1[1]);
            }
            break;
        case CLI_SET_WIRELESS_OPTION_80211:

#if (AIROHA_TRANSCEIVER == 1 )
            if (isRF_AIROHA_7230()) 
            {
                if (cli_process_802_11_dh_options(fd, result1[1], 
                          (unsigned long *)&nvParamsPtr->wlnParams.options) != 0)
                {
                    return cli_bad_option(fd, result1[1]);
                }
            }
            break;
#else
           return cli_bad_option(fd, result1[1]);
#endif

        case CLI_SET_WIRELESS_OPTION_80211_D:
#if (AIROHA_TRANSCEIVER == 1 )
            /* if support AIROHA_7230, we dont support this */
            if (isRF_AIROHA_7230()) 
            {
               return cli_bad_option(fd, result1[1]);
            }
#endif
            if (cli_process_802_11_d_options(fd, result1[1], 
                         (unsigned long *)&nvParamsPtr->wlnParams.options) != 0)
            {
                return cli_bad_option(fd, result1[1]);
            }
            break;

        case CLI_SET_WIRELESS_OPTION_BAND:
#ifdef BSP_ARM9       
            if (cli_process_band_option(fd, result1[1], &nvParamsPtr->wlnParams.band) != 0)
            {
                return cli_bad_option(fd, result1[1]);
            }
            break;
#endif
            return cli_bad_option(fd, result1[1]);

        case CLI_SET_WIRELESS_OPTION_CHANNEL:
            if (cli_process_channel_option(fd, result1[1], &channel, &chan_11a) != 0)
            {
                return cli_bad_option(fd, result1[1]);
            }
            break;

        case CLI_SET_WIRELESS_OPTION_WEPKEY1:
            setWepKeyN(fd, 0, result1[1],  &nvParamsPtr->wlnParams);
            break;

        case CLI_SET_WIRELESS_OPTION_WEPKEY2:
            setWepKeyN(fd, 1, result1[1],  &nvParamsPtr->wlnParams);
            break;

        case CLI_SET_WIRELESS_OPTION_WEPKEY3:
            setWepKeyN(fd, 2, result1[1],  &nvParamsPtr->wlnParams);
            break;

        case CLI_SET_WIRELESS_OPTION_WEPKEY4:
            setWepKeyN(fd, 3, result1[1],  &nvParamsPtr->wlnParams);
            break;

        case CLI_SET_WIRELESS_OPTION_WEPMODE:
            switch (naCliWhichOp(result1[1], cli_set_wireless_wepmode)) {
            case CLI_SET_WIRELESS_OPTION_WEPMODE_64:
                nvParamsPtr->wlnParams.wep_key_len = WLN_WEP40_SIZE;
                break;

            case CLI_SET_WIRELESS_OPTION_WEPMODE_128:
                nvParamsPtr->wlnParams.wep_key_len = WLN_WEP104_SIZE;
                break;

            default:
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_WIRELESS_OPTION_WEPINDEX:
            n = sscanf(result1[1], "%d", &res);
            if (n == 1 && res >= 1 && res <= 4) {
                nvParamsPtr->wlnParams.wep_key_id = res-1;
            } else {
                return cli_bad_option(fd, result1[1]);
            }

            break;


        case CLI_SET_WIRELESS_OPTION_TXPOWER:
            n = sscanf(result1[1], "%d", &res);
            if (n == 1 && res >= WLN_TXPOWER_MIN && res <= WLN_TXPOWER_MAX) {
                nvParamsPtr->wlnParams.tx_power = res;
            } else {
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_WIRELESS_OPTION_MATXRATE:
            switch (naCliWhichOp(result1[1], cli_set_wireless_txrate_options)) {
            case CLI_SET_WIRELESS_TXRATE_OPTION_ANY:
                nvParamsPtr->wlnParams.tx_rate = 0;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_1:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_1_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_2:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_2_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_5_5:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_5_5_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_11:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_11_MBPS;
                break;

#ifdef BSP_ARM9
            case CLI_SET_WIRELESS_TXRATE_OPTION_6:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_6_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_9:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_9_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_12:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_12_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_18:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_18_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_24:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_24_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_36:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_36_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_48:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_48_MBPS;
                break;

            case CLI_SET_WIRELESS_TXRATE_OPTION_54:
                nvParamsPtr->wlnParams.tx_rate = WLN_RATE_54_MBPS;
                break;
#endif

            default:
                return cli_bad_option(fd, result1[1]);
            }

            break;


        case CLI_SET_WIRELESS_OPTION_AUTHENTICATION:
            switch (naCliWhichOp(result1[1], cli_set_wireless_authent)) {

            case CLI_SET_WIRELESS_OPTION_AUTH_OPEN:
                nvParamsPtr->wlnParams.authen = WLN_AUTH_OPEN;
                break;

            case CLI_SET_WIRELESS_OPTION_AUTH_SHAREDKEY:
                nvParamsPtr->wlnParams.authen = WLN_AUTH_SHAREDKEY;
                break;

#if BSP_WANT_WPA
            case CLI_SET_WIRELESS_OPTION_AUTH_WEP_AUTH:
                nvParamsPtr->wlnParams.authen = WLN_AUTH_WEP_8021X;
                break;

            case CLI_SET_WIRELESS_OPTION_AUTH_ANY:
                nvParamsPtr->wlnParams.authen = WLN_AUTH_ANY;
                break;

            case CLI_SET_WIRELESS_OPTION_AUTH_WPA_PSK:
                nvParamsPtr->wlnParams.authen = WLN_AUTH_WPA_PSK;
                break;

            case CLI_SET_WIRELESS_OPTION_AUTH_WPA_AUTH:
                nvParamsPtr->wlnParams.authen = WLN_AUTH_WPA_8021X;
                break;


            case CLI_SET_WIRELESS_OPTION_AUTH_LEAP:
                nvParamsPtr->wlnParams.authen = WLN_AUTH_LEAP;

                break;
#endif

            default:
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_WIRELESS_OPTION_ENCRYPTION:
            switch (naCliWhichOp(result1[1], cli_set_wireless_encrypt)) {
            case CLI_SET_WIRELESS_OPTION_ENCRYPT_OPEN:
                nvParamsPtr->wlnParams.encrypt = WLN_ENCR_OPEN;
                break;

            case CLI_SET_WIRELESS_OPTION_ENCRYPT_WEP:
                nvParamsPtr->wlnParams.encrypt = WLN_ENCR_WEP;
                break;

            case CLI_SET_WIRELESS_OPTION_ENCRYPT_ANY:
                nvParamsPtr->wlnParams.encrypt = WLN_ENCR_ANY;
                break;

#if BSP_WANT_WPA

            case CLI_SET_WIRELESS_OPTION_ENCRYPT_TKIP:
                nvParamsPtr->wlnParams.encrypt = WLN_ENCR_TKIP;
                break;

            case CLI_SET_WIRELESS_OPTION_ENCRYPT_CCMP:
                nvParamsPtr->wlnParams.encrypt = WLN_ENCR_CCMP;
                break;
#endif

            default:
                return cli_bad_option(fd, result1[1]);
            }

            break;



#if BSP_WANT_WPA

        case CLI_SET_WIRELESS_OPTION_OUTER_EAP:
            switch (naCliWhichOp(result1[1], cli_set_wireless_outer_eap)) {
            case CLI_SET_WIRELESS_OPTION_OUTER_EAP_PEAP:
                nvParamsPtr->wlnParams.eap_methods = WLN_EAP_PEAP;
                break;

            case CLI_SET_WIRELESS_OPTION_OUTER_EAP_TLS:
                nvParamsPtr->wlnParams.eap_methods = WLN_EAP_TLS;
                break;

            case CLI_SET_WIRELESS_OPTION_OUTER_EAP_TTLS:
                nvParamsPtr->wlnParams.eap_methods = WLN_EAP_TTLS;
                break;

            case CLI_SET_WIRELESS_OPTION_OUTER_EAP_ANY:
                nvParamsPtr->wlnParams.eap_methods = WLN_EAP_ANY;
                break;

            default:
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_WIRELESS_OPTION_INNER_EAP:
            switch (naCliWhichOp(result1[1], cli_set_wireless_inner_eap)) {
            case CLI_SET_WIRELESS_OPTION_INNER_EAP_GTC:
                nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_INNER_ANY;
                nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_GTC;
                break;

            case CLI_SET_WIRELESS_OPTION_INNER_EAP_MD5:
                nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_INNER_ANY;
                nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_MD5;
                break;

            case CLI_SET_WIRELESS_OPTION_INNER_EAP_OTP:
                nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_INNER_ANY;
                nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_OTP;
                break;

            case CLI_SET_WIRELESS_OPTION_INNER_EAP_CHAP:
                nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_INNER_ANY;
                nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_TTLS_CHAP;
                break;

            case CLI_SET_WIRELESS_OPTION_INNER_EAP_MSCHAP:
                nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_INNER_ANY;
                nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_TTLS_MSCHAP;
                break;

            case CLI_SET_WIRELESS_OPTION_INNER_EAP_TTLS_MSCHAPV2:
                nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_INNER_ANY;
                nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_TTLS_MSCHAPV2;
                break;

            case CLI_SET_WIRELESS_OPTION_INNER_EAP_PAP:
                nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_INNER_ANY;
                nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_TTLS_PAP;
                break;

            case CLI_SET_WIRELESS_OPTION_INNER_EAP_ANY:
                nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_INNER_ANY;
                break;

            case CLI_SET_WIRELESS_OPTION_INNER_EAP_NONE:
                nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_INNER_ANY;
                break;

            default:
                return cli_bad_option(fd, result1[1]);
            }

            break;

        case CLI_SET_WIRELESS_OPTION_LOGIN:

            n = strlen(result1[1]);
            if (n >= 0 && n <= WLN_IDENT_SIZE) {
                strcpy(nvParamsPtr->wlnParams.identity, result1[1]);
            } else {
                return cli_bad_option(fd, result1[1]);
            }
            break;

        case CLI_SET_WIRELESS_OPTION_PASSWORD:

            n = strlen(result1[1]);
            if (n >= 0 && n <= WLN_PWD_SIZE) {
                strncpy(nvParamsPtr->wlnParams.password, result1[1], WLN_PWD_SIZE);
            } else {
                return cli_bad_option(fd, result1[1]);
            }
            break;

        case CLI_SET_WIRELESS_OPTION_PSK:
            n = strlen(result1[1]);
            if (n >= 8 && n <= 63) {
                naCliPrintf(fd,"Calculating key (about 30 seconds)...\r\n");
                wpa_passphrase_to_psk(result1[1], (
                                          char*)nvParamsPtr->wlnParams.ssid,
                                      nvParamsPtr->wlnParams.ssid_len,
                                      nvParamsPtr->wlnParams.wpa_psk);
            } else {
                return cli_bad_option(fd, result1[1]);
            }

            break;

#endif /* BSP_WANT_WPA */

        default:
            return cli_bad_option(fd, args[i]);

        }
    }
    
#if BSP_WANT_WPA    
    // EAP is currently only configurable through the CLI. If, however,
    // LEAP authentication is selected then the outer EAP must be set to
    // LEAP as well. If it is not enabled then outer EAP must have LEAP off.
    if (nvParamsPtr->wlnParams.authen & WLN_AUTH_LEAP) {
        nvParamsPtr->wlnParams.eap_methods |= WLN_EAP_LEAP;
    } else {
        nvParamsPtr->wlnParams.eap_methods &= ~WLN_EAP_LEAP;
    }
#endif /* BSP_WANT_WPA */

#if BSP_WANT_WPA    
    /* Currently, we don't support ANY/ANY authentication & encryption
     * due to WPA code.
     */
    if (nvParamsPtr->wlnParams.authen == WLN_AUTH_ANY && 
        nvParamsPtr->wlnParams.encrypt == WLN_ENCR_ANY)
    {
        naCliPrintf(fd, "ERROR: Invalid Authentication and Encryption\r\n");
        naCliPrintf(fd, "       Unsupported Encryption for this authentication\r\n");
        return rc;
    }
    /* For OPEN or Shared key, we don't support TKIP or CCMP */
    if (nvParamsPtr->wlnParams.authen == WLN_AUTH_OPEN || nvParamsPtr->wlnParams.authen == WLN_AUTH_SHAREDKEY)
    {
        if (nvParamsPtr->wlnParams.encrypt == WLN_ENCR_TKIP || nvParamsPtr->wlnParams.encrypt == WLN_ENCR_CCMP)
        {
        naCliPrintf(fd, "ERROR: Invalid Authentication and Encryption\r\n");
        naCliPrintf(fd, "       Unsupported Encryption for this authentication\r\n");
        return rc;
        }
    }

    /* For LEAP or WEP, we only support WEB */
    if ((nvParamsPtr->wlnParams.authen == WLN_AUTH_LEAP || nvParamsPtr->wlnParams.authen == WLN_AUTH_WEP_8021X) && 
        nvParamsPtr->wlnParams.encrypt != WLN_ENCR_WEP)
    {
        naCliPrintf(fd, "ERROR: Invalid Authentication and Encryption\r\n");
        naCliPrintf(fd, "       Unsupported Encryption for this authentication\r\n");
        return rc;
    }

    /* For WPA 802.1x, we don't support OPEN */
    if ((nvParamsPtr->wlnParams.authen == WLN_AUTH_WPA_PSK || nvParamsPtr->wlnParams.authen == WLN_AUTH_WPA_8021X) && 
        nvParamsPtr->wlnParams.encrypt == WLN_ENCR_OPEN)
    {
        naCliPrintf(fd, "ERROR: Invalid Authentication and Encryption\r\n");
        naCliPrintf(fd, "       Unsupported Encryption for this authentication\r\n");
        return rc;
    }
#endif

    if (cli_check_channel_option(fd, channel, nvParamsPtr, chan_11a) == 1)
    {
        rc = 0;
    }

    return rc;
}

static unsigned long auth_codes[] = {
    WLN_AUTH_OPEN, WLN_AUTH_SHAREDKEY,
#if BSP_WANT_WPA
    WLN_AUTH_WEP_8021X, WLN_AUTH_WPA_PSK, WLN_AUTH_WPA_8021X, 
    WLN_AUTH_LEAP, 
//    WLN_AUTH_EAP_FAST
#endif
};

static char * auth_string[] = {
    "Open System", "Shared Key", 
#if BSP_WANT_WPA
    "WEP (802.1x)", "WPA Personal (WPA-PSK)", "WPA Enterprise (WPA-802.1X)", 
    "Cisco LEAP", 
//    "Cisco EAP FAST"
#endif
};

void cli_print_authentication(int fd, devBoardParamsType * nvParams)
{
    int i = 0;

    naCliPrintf(fd, "\r\n%-42s\r\n", "Authentication");
    naCliPrintf(fd, "%-42s\r\n",     "--------------");
    
    for (i=0; i < asizeof(auth_codes); i++)
    {
        if (nvParams->wlnParams.authen & auth_codes[i]) 
        {
            naCliPrintf(fd, "%-42s: %s", auth_string[i], "Enabled");

#if BSP_WANT_WPA
            if ((nvParams->wlnParams.bss_type == WLN_BSS_IBSS || 
                 nvParams->wlnParams.bss_type == WLN_BSS_IBSS_JOIN) && 
                auth_codes[i] != WLN_AUTH_OPEN && auth_codes[i] != WLN_AUTH_SHAREDKEY)
            {
                naCliPrintf(fd, "(Not used for ad hoc mode)");

            }
            if (auth_codes[i] == WLN_AUTH_WPA_PSK && nvParams->wlnParams.ssid_len == 0)
            {
                naCliPrintf(fd, "\r\n%-42s: %s", "", "Must specify an SSID to use WPA-PSK");
            }
#endif
            naCliPrintf(fd, "\r\n");

        }

    }
}

void cli_print_encryption(int fd, devBoardParamsType * nvParams)
{
#if BSP_WANT_WPA
    int i=0;

    naCliPrintf(fd, "\r\n%-42s\r\n", "Encryption");
    naCliPrintf(fd, "%-42s\r\n",     "----------");
    
    if (nvParams->wlnParams.encrypt == WLN_ENCR_ANY)
    {
        naCliPrintf(fd, "%-42s: %s", cli_set_wireless_encrypt[i], "Enabled");
        naCliPrintf(fd, "\r\n");
    }


    for (i=0; i < asizeof(encryp_codes); i++)
    {
        if ((nvParams->wlnParams.encrypt & encryp_codes[i]) && (encryp_codes[i] != WLN_ENCR_ANY))
        {
            naCliPrintf(fd, "%-42s: %s", cli_set_wireless_encrypt[i], "Enabled");
            naCliPrintf(fd, "\r\n");
        }
    }
#endif /* BSP_WANT_WPA */

}

int cli_set_wireless_help_display(int fd, devBoardParamsType * nvParamsPtr) 
{

    naCliPrintf(fd, "\r\n\r\nsyntax: setwireless [options...]\r\n\r\n");
    naCliPrintf(fd, "options:\r\n\r\n");
    naCliPrintf(fd, "   ip = ip address (nnn.nnn.nnn.nnn)\r\n");
    naCliPrintf(fd, "   submask = subnet mask address (nnn.nnn.nnn.nnn)\r\n");
    naCliPrintf(fd, "   gateway = gateway address (nnn.nnn.nnn.nnn)\r\n");
    naCliPrintf(fd, "   dhcp = (on|off)\r\n");
    naCliPrintf(fd, "   primarydns = primary DNS address (nnn.nnn.nnn.nnn)\r\n");
    naCliPrintf(fd, "   secondarydns = secondary DNS address (nnn.nnn.nnn.nnn)\r\n");
	naCliPrintf(fd, "   dhcpv6 = (on|off)\r\n");
    naCliPrintf(fd, "   staticv6 = (on|off)\r\n");
	naCliPrintf(fd, "   ipv6 == (static ipv6 address)\r\n");
	naCliPrintf(fd, "   prefixlen == (ipv6 prefix length)\r\n");

    naCliPrintf(fd, "   country = country name\r\n");
    cli_print_supported_countries(fd);

    naCliPrintf(fd, "   protmode = (bss|ibss_create|ibss_join|any)\r\n");
    naCliPrintf(fd, "   ssid = Wireless SSID (enter 'ANY' to search)\r\n");
#if (AIROHA_TRANSCEIVER == 1)
    if (isRF_AIROHA_7230()) 
    {
        naCliPrintf(fd, "   802.11 = 802.11 Options\r\n");
        naCliPrintf(fd, "            (none: no option\r\n");
        naCliPrintf(fd, "            (d: 802.11d Multi Domain Capability)\r\n");
        naCliPrintf(fd, "            (h: 802.11h Spectrum Management Capability)\r\n");
    }
    else
#endif
    {
    naCliPrintf(fd, "   802.11d = Multi Domain Capablitiy (on|off)\r\n");
    }
#ifdef BSP_ARM9       
    /* only ARM9 supports frequency band selections 
     * ARM7 supports B only.
     */
     naCliPrintf(fd, "   band = frequency band\r\n");
     cli_print_supported_bands(fd);
#endif

#if BSP_WANT_WPA
    naCliPrintf(fd, "   authentication = (open|sharedkey|wep_auth|wpa_psk|wpa_auth|leap|any)\r\n");
#else
    naCliPrintf(fd, "   authentication = (open|sharedkey)\r\n");
#endif
    naCliPrintf(fd, "   channel = channel number\r\n");
    cli_print_supported_channels(fd, nvParamsPtr->wlnExtParams.wlnCountryCode, nvParamsPtr->wlnParams.band);

    naCliPrintf(fd, "   wepkeyN=(10 or 26 digit hex digits) {N = wepindex, 1-4}\r\n");
    naCliPrintf(fd, "   wepindex=(1-4)\r\n");
#ifdef BSP_ARM9
	naCliPrintf(fd, "   maxtxrate=(0 for any, 1mb|2mb|5.5mb|6mb|9mb|11mb|12mb|18mb|24mb|36mb|48mb|54mb)\r\n"); 
#else
    naCliPrintf(fd, "   maxtxrate=(0 for any, 1mb|2mb|5.5mb|11mb)\r\n");
#endif
    naCliPrintf(fd, "   txpower=(0-16)\r\n");
#if BSP_WANT_WPA

    naCliPrintf(fd, "   psk=(passphrase string) {used for wpa_psk}\r\n");
    naCliPrintf(fd, "   username=(user id for wireless network)\r\n");
    naCliPrintf(fd, "   password=(password for wireless network)\r\n");
    naCliPrintf(fd, "   encryption=(open|wep|tkip|ccmp|any)\r\n");
    naCliPrintf(fd, "   outer_eap=(peap|tls|ttls|any)\r\n");
    naCliPrintf(fd, "   inner_eap=(gtc|md5|mschapv2|otp|tls|chap|mschap|ttls_mschapv2|pap|any|none)\r\n");

#endif

    naCliPrintf(fd, "\r\n");
    return 0;
}

/*
 *
 *  Function: int cli_set_wireless_help(int fd, int n, char *args[])
 *
 *  Description:
 *
 *      This function is called to display help for the setwireless command.
 *
 *  Parameters:
 *
 *      fd       Interface file descriptor. 
 *      n        The number of arguments to parse
 *      args     The arguments to parse
 *
 *  Return Values:
 *
 *      0          Success
 *
 */
int cli_set_wireless_help(int fd, int nargs, char *args[]) 
{
    int     rc = 0;
    char    * equal_separator = "=";
    char    * result1[4];
    int     i;
    int     option_count;
    devBoardParamsType *nvParams;
    NaIamParams_t *interface;

    nvParams = (devBoardParamsType *) malloc(sizeof(devBoardParamsType));
    if (nvParams == NULL)
    {
        naCliPrintf(fd, "\r\nError: Out of Memory!!!\r\n");
        goto _ret;
    }

    /* Read current settings. */
    customizeReadDevBoardParams(nvParams);

    /* Extract the configuration structure from the NVRAM structure.  There should be a configuration */
    /* settings for the wln0 interface.  If not, then reinitialize the structure. */
    interface = customizeIamFindInterfaceConfig(BP_WLN_INTERFACE, &nvParams->iamParamsInfo);
    if (interface == NULL) {
        interface = customizeIamFindUnusedInterfaceConfig(&nvParams->iamParamsInfo, FALSE);
        if (interface)
            customizeIamGetDefaultInterfaceConfig(BP_WLN_INTERFACE, interface);
    }

    /* Look for each parameter. 
     * The options for channel depends on country name and/or band;
     * so save the country name and band and display the channel options
     * for the specified country name and/or in the same command line.
     */
    for (i=0; i < nargs; i++) {
        /* split up the current option result1[0] holds the option and */
        /* result1[1] holds the value. */
        option_count = naCliSplitStr(args[i], result1, 4, equal_separator);

        if ((option_count != 2) || (result1[1] == NULL)) {
            break;
        }

        /* process the current option */
        switch (naCliWhichOp(result1[0], cli_set_wireless_options)) {

            case CLI_SET_WIRELESS_OPTION_COUNTRY_NAME:
                cli_set_country_option(fd, result1[1], (wln_country_code_t *)&nvParams->wlnExtParams.wlnCountryCode);
                break;
#ifdef BSP_ARM9       
            case CLI_SET_WIRELESS_OPTION_BAND:
                cli_set_band_option(fd, result1[1], &nvParams->wlnParams.band);
                break;
#endif
            default:
                break;
            }
        }
    
    /* display syntax with option choices */
    cli_set_wireless_help_display(fd, nvParams);
_ret:
    if (nvParams != NULL) free(nvParams);
    return rc;    
}


/*
*
*  Function: int cli_set_wireless(int fd, int n, char *args[])
*
*  Description:
*
*      This function is called when a setwireless command is typed into the cli.
*
*  Parameters:
*
*      fd       Interface file descriptor. 
*      n        The number of arguments to parse
*      args     The arguments to parse
*
*  Return Values:
*
*      <0         failure
*      0          Success
*
*/
int cli_set_wireless(int fd, int n, char *args[]) {
    devBoardParamsType * nvParams;  /* should not use stack space for nvParams */
    NaIamParams_t *interface, *interface_autoip;
    char *ipv6_addr;
    char ipv6Address[MAX_IP_ADDR_STR_LEN];
	struct sockaddr_storage dnsServers[4];

    NaIamIfIpCfg_t config;

    char addr[16];
    int i, cnt, numDNS, status = 0;

    nvParams = (devBoardParamsType *) malloc(sizeof(devBoardParamsType));
    if (nvParams == NULL)
    {
        naCliPrintf(fd, "Out of Memory!!!\r\n");
        return -1;
    }

    /* Read current settings. */
    customizeReadDevBoardParams(nvParams);

    /* Extract the configuration structure from the NVRAM structure.  There should be a configuration */
    /* settings for the wln0 interface.  If not, then reinitialize the structure. */
    interface = customizeIamFindInterfaceConfig(BP_WLN_INTERFACE, &nvParams->iamParamsInfo);
    if (interface == NULL) 
	{
        interface = customizeIamFindUnusedInterfaceConfig(&nvParams->iamParamsInfo, FALSE);
        if (interface)
            customizeIamGetDefaultInterfaceConfig(BP_WLN_INTERFACE, interface);
    }

    /* If no parameters show current values. */
    if (n == 0) 
	{
		customizeIamGetIfconfig(BP_WLN_INTERFACE, &config); 

        naCliPrintf(fd, "\r\n\rWireless Network Settings\r\n\r\n");
        naCliPrintf(fd, "%-42s: ", "DHCPv4");

        if (interface->staticParams.isEnabled) 
		{ /* static address */
            naCliPrintf(fd, "%s\r\n", "Disabled");

            NAInet_toa(interface->staticParams.IPV4_ADDR(ipAddress), addr);
            naCliPrintf(fd, "%-42s: %s\r\n", "IP Address", addr);
            NAInet_toa(interface->staticParams.subnetMask, addr);
            naCliPrintf(fd, "%-42s: %s\r\n", "Subnet Mask", addr);
            NAInet_toa(interface->staticParams.IPV4_ADDR(gateway), addr);
            naCliPrintf(fd, "%-42s: %s\r\n", "Gateway", addr);
            NAInet_toa(interface->staticParams.IPV4_ADDR(primaryDns), addr);
            naCliPrintf(fd, "%-42s: %s\r\n", "Primary DNS", addr);
            NAInet_toa(interface->staticParams.IPV4_ADDR(secondaryDns), addr);
            naCliPrintf(fd, "%-42s: %s\r\n", "Secondary DNS", addr);

        } 
		else 
		{ /* DHCP */
            naCliPrintf(fd, "%s\r\n", "Enabled");

			NAInet_toa(config.addrV4[0].IPV4_ADDR(ipAddress), addr);
            naCliPrintf(fd, "%-42s: %s\r\n", "IPv4 Address", addr);

			if (config.addrV4[0].IPV4_ADDR(ipAddress))
			{
				NAInet_toa(config.addrV4[0].subnet.ipv4SubnetMask, addr);
				naCliPrintf(fd, "%-42s: %s\r\n", "Subnet Mask", addr);

				NAInet_toa(config.IPV4_ADDR(defaultV4Gateway), addr);
				naCliPrintf(fd, "%-42s: %s\r\n", "Gateway", addr);
			}
        }

        interface_autoip = customizeIamFindInterfaceConfig(BP_WLN_0INTERFACE, &nvParams->iamParamsInfo);
        if (interface_autoip->autoipParams.isEnabled)
        {
			if (config.addrV4[1].method == NA_IAM_METHOD_AUTOIP && config.addrV4[1].IPV4_ADDR(ipAddress))
			{
				NAInet_toa(config.addrV4[1].IPV4_ADDR(ipAddress), addr);
				naCliPrintf(fd, "\r\n%-42s: %s\r\n", "Auto IP Address", addr);
			}
        }
		naCliPrintf(fd, "\r\n");
		if (interface->staticParams.ipv6IsEnabled & NA_IAM_STATICV6_ENABLED)
		{
			ipv6_addr = (char *)&interface->staticParams.ipv6Address.addr.ipv6.sin6_addr;

			/* Convert v6 address to ASCII. */
			inet_ntop(AF_INET6, ipv6_addr, ipv6Address, MAX_IP_ADDR_STR_LEN);
			naCliPrintf(fd, "%-42s: %s, prefixlen %d\r\n", "IPv6 Static Address", ipv6Address, interface->staticParams.ipv6PrefixLen);
		}
		else
			naCliPrintf(fd, "%-42s: %s\r\n", "IPv6 Static Address", "Disabled");

		if (interface->staticParams.ipv6IsEnabled & NA_IAM_DHCPV6_ENABLED)
		{
			if (config.dhcpV6.method == NA_IAM_METHOD_DHCPV6)
			{
				ipv6_addr = (char *)&config.dhcpV6.ipAddress.addr.ipv6.sin6_addr;

				/* Convert v6 address to ASCII. */
				inet_ntop(AF_INET6, ipv6_addr, ipv6Address, MAX_IP_ADDR_STR_LEN);
				naCliPrintf(fd, "%-42s: %s\r\n", "DHCPv6 Address", ipv6Address);
			}
			else
				naCliPrintf(fd, "%-42s: %s\r\n", "DHCPv6", "Enabled");
		}
		else
			naCliPrintf(fd, "%-42s: %s\r\n", "DHCPv6", "Disabled");

		cnt = 0;

		for (i = 0; i < NA_MAX_HOMES_PER_IF; i++)
		{
			if (config.autoCfgV6[i].method != NA_IAM_METHOD_NONE)
			{ 
				ipv6_addr = (char *)&config.autoCfgV6[i].ipAddress.addr.ipv6.sin6_addr;

				/* Convert v6 address to ASCII. */
				inet_ntop(AF_INET6, ipv6_addr, ipv6Address, MAX_IP_ADDR_STR_LEN);
				cnt++;
				if (cnt == 1)
				{
					naCliPrintf(fd, "%-42s: %s\r\n", "IPv6 Autoconfigured Address", ipv6Address);
				}
				else
				{
					naCliPrintf(fd, "%-42s: %s\r\n", " ", ipv6Address, ipv6Address);
				}
			}
		}
		/* example of DNS api usage. */
        numDNS = DNSGetServers(dnsServers, 4);
		cnt = 0;

		for (i = 0; i < numDNS; i++)
		{
			if (dnsServers[i].ss_family == AF_INET || dnsServers[i].ss_family == AF_INET6)
			{
				cnt++;
				if (dnsServers[i].ss_family == AF_INET)
					NAInet_toa(IPV4_ADDR(dnsServers[i]), ipv6Address);
				else
				{
					ipv6_addr = (char *)&dnsServers[i].addr.ipv6.sin6_addr;
					inet_ntop(AF_INET6, ipv6_addr, ipv6Address, MAX_IP_ADDR_STR_LEN);
				}
				if (cnt == 1)
					naCliPrintf(fd, "\r\n%-42s: %s\r\n", "DNS Servers", ipv6Address);
				else
					naCliPrintf(fd, "%-42s: %s\r\n", " ", ipv6Address);
			}
        }

		naCliPrintf(fd, "\r\n");

        if (nvParams->wlnParams.bss_type <= WLN_BSS_ANY)
            naCliPrintf(fd, "%-42s: %s\r\n", "Protocol Mode", wln_modes[nvParams->wlnParams.bss_type]);

        if (nvParams->wlnParams.ssid_len == 0)
            naCliPrintf(fd, "%-42s: %s\r\n", "SSID", "0 (search)");
        else
            naCliPrintf(fd, "%-42s: %.*s\r\n", "SSID", nvParams->wlnParams.ssid_len, nvParams->wlnParams.ssid);

        /* country name */
         if (wln_is_country_valid((wln_country_code_t)nvParams->wlnExtParams.wlnCountryCode))    
            naCliPrintf(fd, "%-42s: %s\r\n", "Country Name", wln_get_country_string_from_code((wln_country_code_t)nvParams->wlnExtParams.wlnCountryCode));
        else
            naCliPrintf(fd, "%-42s: %s\r\n", "Country Name", "Not Configured");


        /* 802.11 D */
        naCliPrintf(fd, "%-42s: ", "Multi Domain Capability (802.11d)");
        if ((nvParams->wlnParams.options &  WLN_OPT_MULTI_DOMAIN))
        {
            naCliPrintf(fd, "%s\r\n", "Enabled");
        }
        else
        {
            naCliPrintf(fd, "%s\r\n", "Disabled");
        }

        /* 802.11 H */
#if (AIROHA_TRANSCEIVER == 1 )
        if (isRF_AIROHA_7230()) 
        {
            naCliPrintf(fd, "%-42s: ", "Spectrum Management Capability (802.11h)");
            if ((nvParams->wlnParams.options &  WLN_OPT_SPECTRUM_MGMT))
            {
                naCliPrintf(fd, "%s\r\n", "Enabled");
            }
            else
            {
                naCliPrintf(fd, "%s\r\n", "Disabled");
            }
        }
#endif

        /* Frequency band */        
        naCliPrintf(fd, "%-42s: %s\r\n", "Frequency Band", cli_set_wireless_frequency_band[nvParams->wlnParams.band]);

        /* channel */
        naCliPrintf(fd, "%-42s: ", "Channel");
        if(nvParams->wlnParams.channel == WLN_CHAN_SCAN)
            naCliPrintf(fd, "%s\r\n", "0 (search)");
        else
        {
            int n = wln_get_chan_info(nvParams->wlnParams.channel, NULL);
            
            if (nvParams->wlnParams.channel > 14)
                naCliPrintf(fd, "a%d\r\n", n);
            else
                naCliPrintf(fd, "%d\r\n", n);
            if ((nvParams->wlnParams.band == WLN_BAND_B || nvParams->wlnParams.band == WLN_BAND_BG) &&
                (nvParams->wlnParams.channel > 14))
            {
                naCliPrintf(fd, "%s\r\n", "Unknown");
            }
        }

        cli_print_authentication(fd, nvParams);

        /* Encryption */        
        cli_print_encryption(fd, nvParams);

        naCliPrintf(fd, "\r\n%-42s: %s\r\n", "Username", nvParams->wlnParams.identity);

        if (nvParams != NULL) free(nvParams);
        return 0;
    }

    /* Parse the arguments and set the values into interface*/
    if (cli_parse_set_wireless_parms (fd, n, args, interface, nvParams) == 0)
    {

        /* Save settings. */
        status = customizeWriteDevBoardParams(nvParams);

        if (status != BP_SUCCESS) {
            naCliPrintf(fd, "\r\n\r\nCritical error saving wireless settings!\r\n");
        } else {
            naCliPrintf(fd, "\r\n\r\nWireless settings have been saved.\r\n");
        }
    }
    if (nvParams != NULL) free(nvParams);
    return 0;
}
#endif /* BSP_WANT_WIRELESS */


#endif /* (BSP_CLI_INCLUDE_IN_BSP && (BSP_CLI_SERIAL_ENABLE || BSP_CLI_TELNET_ENABLE || BSP_CLI_SSH_ENABLE)) */
