2020-04-19 16:54:27 +00:00
/** @file uaputl.c
*
* @ brief Program to send AP commands to the driver / firmware of the uAP
* driver .
*
*
* Copyright 2014 - 2020 NXP
*
2020-04-26 02:53:08 +00:00
* This software file ( the File ) is distributed by NXP
* under the terms of the GNU General Public License Version 2 , June 1991
* ( the License ) . You may use , redistribute and / or modify the File in
* accordance with the terms and conditions of the License , a copy of which
* is available by writing to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA or on the
* worldwide web at http : //www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
2020-04-19 16:54:27 +00:00
*
2020-04-26 02:53:08 +00:00
* THE FILE IS DISTRIBUTED AS - IS , WITHOUT WARRANTY OF ANY KIND , AND THE
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
* ARE EXPRESSLY DISCLAIMED . The License provides additional details about
* this warranty disclaimer .
2020-04-19 16:54:27 +00:00
*
*/
/****************************************************************************
Change log :
03 / 01 / 08 : Initial creation
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/****************************************************************************
Header files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <stdarg.h>
# include <sys/types.h>
# include <unistd.h>
# include <sys/socket.h>
# include <sys/select.h>
# include <stdio.h>
# include <getopt.h>
# include <netinet/in.h>
# include <errno.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <linux/if.h>
# include <sys/ioctl.h>
# include <errno.h>
# include "uaputl.h"
# include "uapcmd.h"
/****************************************************************************
Definitions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/** Default debug level */
int debug_level = MSG_NONE ;
/** Enable or disable debug outputs */
# define DEBUG 1
/** Convert character to integer */
# define CHAR2INT(x) (((x) >= 'A') ? ((x) - 'A' + 10) : ((x) - '0'))
/** Supported stream modes */
# define HT_STREAM_MODE_1X1 0x11
# define HT_STREAM_MODE_2X2 0x22
static int get_bss_config ( t_u8 * buf ) ;
/****************************************************************************
Global variables
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/** Device name */
static char dev_name [ IFNAMSIZ + 1 ] ;
/** Option for cmd */
struct option cmd_options [ ] = {
{ " help " , 0 , 0 , ' h ' } ,
{ 0 , 0 , 0 , 0 }
} ;
/** Flag to check if custom IE is present in sys_config response from FW */
int custom_ie_present = 0 ;
/** Flag to check if max mgmt IE is printed in sys_config response from FW */
int max_mgmt_ie_print = 0 ;
/** Flag to bypass re-route path */
int uap_ioctl_no_reroute = 0 ;
/****************************************************************************
Local functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ brief Convert char to hex integer
*
* @ param chr Char
* @ return Hex integer
*/
unsigned char
hexc2bin ( char chr )
{
if ( chr > = ' 0 ' & & chr < = ' 9 ' )
chr - = ' 0 ' ;
else if ( chr > = ' A ' & & chr < = ' F ' )
chr - = ( ' A ' - 10 ) ;
else if ( chr > = ' a ' & & chr < = ' f ' )
chr - = ( ' a ' - 10 ) ;
return chr ;
}
/**
* @ brief Check protocol is valid or not
*
* @ param protocol Protocol
*
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
is_protocol_valid ( int protocol )
{
int ret = UAP_FAILURE ;
switch ( protocol ) {
case PROTOCOL_NO_SECURITY :
case PROTOCOL_STATIC_WEP :
case PROTOCOL_WPA :
case PROTOCOL_WPA2 :
case PROTOCOL_WPA2_MIXED :
case PROTOCOL_WPA3_SAE :
ret = UAP_SUCCESS ;
break ;
default :
printf ( " ERR: Invalid Protocol: %d \n " , protocol ) ;
break ;
}
return ret ;
}
/**
* @ brief Function to check valid rate
*
*
* @ param rate Rate to verify
*
* return UAP_SUCCESS or UAP_FAILURE
* */
int
is_rate_valid ( int rate )
{
int ret = UAP_SUCCESS ;
switch ( rate ) {
case 2 :
case 4 :
case 11 :
case 13 :
case 22 :
case 12 :
case 18 :
case 24 :
case 48 :
case 72 :
case 96 :
case 108 :
case 36 :
break ;
default :
ret = UAP_FAILURE ;
break ;
}
return ret ;
}
/**
* @ brief Check for mandatory rates
*
*
* 2 , 4 , 11 , 22 must be present
*
* 6 12 and 24 must be present for ofdm
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_FAILURE or UAP_SUCCESS
*
*/
static int
check_mandatory_rates ( int argc , char * * argv )
{
int i ;
int tmp ;
t_u32 rate_bitmap = 0 ;
int cck_enable = 0 ;
int ofdm_enable = 0 ;
# define BITMAP_RATE_1M 0x01
# define BITMAP_RATE_2M 0x02
# define BITMAP_RATE_5_5M 0x04
# define BITMAP_RATE_11M 0x8
# define B_RATE_MANDATORY 0x0f
# define BITMAP_RATE_6M 0x10
# define BITMAP_RATE_12M 0x20
# define BITMAP_RATE_24M 0x40
# define G_RATE_MANDATORY 0x70
for ( i = 0 ; i < argc ; i + + ) {
tmp = ( A2HEXDECIMAL ( argv [ i ] ) & ~ BASIC_RATE_SET_BIT ) ;
switch ( tmp ) {
case 2 :
cck_enable = 1 ;
rate_bitmap | = BITMAP_RATE_1M ;
break ;
case 4 :
cck_enable = 1 ;
rate_bitmap | = BITMAP_RATE_2M ;
break ;
case 11 :
cck_enable = 1 ;
rate_bitmap | = BITMAP_RATE_5_5M ;
break ;
case 22 :
cck_enable = 1 ;
rate_bitmap | = BITMAP_RATE_11M ;
break ;
case 12 :
ofdm_enable = 1 ;
rate_bitmap | = BITMAP_RATE_6M ;
break ;
case 24 :
ofdm_enable = 1 ;
rate_bitmap | = BITMAP_RATE_12M ;
break ;
case 48 :
ofdm_enable = 1 ;
rate_bitmap | = BITMAP_RATE_24M ;
break ;
case 18 :
case 36 :
case 72 :
case 96 :
case 108 :
ofdm_enable = 1 ;
break ;
}
}
# ifdef WIFI_DIRECT_SUPPORT
if ( strncmp ( dev_name , " wfd " , 3 ) )
# endif
if ( ( rate_bitmap & B_RATE_MANDATORY ) ! = B_RATE_MANDATORY ) {
if ( cck_enable ) {
printf ( " Basic Rates 2, 4, 11 and 22 (500K units) \n " " must be present in basic or non-basic rates \n " ) ;
return UAP_FAILURE ;
}
}
if ( ofdm_enable & &
( ( rate_bitmap & G_RATE_MANDATORY ) ! = G_RATE_MANDATORY ) ) {
printf ( " OFDM Rates 12, 24 and 48 ( 500Kb units) \n "
" must be present in basic or non-basic rates \n " ) ;
return UAP_FAILURE ;
}
return UAP_SUCCESS ;
}
/**
* @ brief Convert string to hex integer
*
* @ param s A pointer string buffer
* @ return Hex integer
*/
unsigned int
a2hex ( char * s )
{
unsigned int val = 0 ;
if ( ! strncasecmp ( " 0x " , s , 2 ) ) {
s + = 2 ;
}
while ( * s & & isxdigit ( * s ) ) {
val = ( val < < 4 ) + hexc2bin ( * s + + ) ;
}
return val ;
}
/**
* @ brief Dump hex data
*
* @ param prompt A pointer prompt buffer
* @ param p A pointer to data buffer
* @ param len The len of data buffer
* @ param delim Delim char
* @ return None
*/
void
hexdump_data ( char * prompt , void * p , int len , char delim )
{
int i ;
unsigned char * s = p ;
if ( prompt ) {
printf ( " %s: len=%d \n " , prompt , ( int ) len ) ;
}
for ( i = 0 ; i < len ; i + + ) {
if ( i ! = len - 1 )
printf ( " %02x%c " , * s + + , delim ) ;
else
printf ( " %02x \n " , * s ) ;
if ( ( i + 1 ) % 16 = = 0 )
printf ( " \n " ) ;
}
printf ( " \n " ) ;
}
# if DEBUG
/**
* @ brief Conditional printf
*
* @ param level Severity level of the message
* @ param fmt Printf format string , followed by optional arguments
*/
void
uap_printf ( int level , char * fmt , . . . )
{
va_list ap ;
va_start ( ap , fmt ) ;
if ( level < = debug_level ) {
vprintf ( fmt , ap ) ;
}
va_end ( ap ) ;
}
/**
* @ brief Dump hex data
*
* @ param prompt A pointer prompt buffer
* @ param p A pointer to data buffer
* @ param len The len of data buffer
* @ param delim Delim char
* @ return None
*/
void
hexdump ( char * prompt , void * p , int len , char delim )
{
if ( debug_level < MSG_ALL )
return ;
hexdump_data ( prompt , p , len , delim ) ;
}
# endif
/**
* @ brief Hex to number
*
* @ param c Hex value
* @ return Integer value or - 1
*/
int
hex2num ( char c )
{
if ( c > = ' 0 ' & & c < = ' 9 ' )
return c - ' 0 ' ;
if ( c > = ' a ' & & c < = ' f ' )
return c - ' a ' + 10 ;
if ( c > = ' A ' & & c < = ' F ' )
return c - ' A ' + 10 ;
return - 1 ;
}
/**
* @ brief Show usage information for the sys_info command
*
* $ return N / A
*/
void
print_sys_info_usage ( void )
{
printf ( " \n Usage : sys_info \n " ) ;
return ;
}
/**
* @ brief Get Max sta num from firmware
*
* @ return max number of stations
*/
int
get_max_sta_num_supported ( t_u16 * max_sta_num_supported )
{
apcmdbuf_sys_configure * cmd_buf = NULL ;
tlvbuf_max_sta_num * tlv = NULL ;
t_u8 * buffer = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_SUCCESS ;
/* Initialize the command length */
cmd_len = sizeof ( apcmdbuf_sys_configure ) + sizeof ( tlvbuf_max_sta_num ) ;
/* Initialize the command buffer */
buffer = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buffer , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_max_sta_num * ) ( buffer + sizeof ( apcmdbuf_sys_configure ) ) ;
/* Fill the command buffer */
cmd_buf - > cmd_code = APCMD_SYS_CONFIGURE ;
cmd_buf - > size = cmd_len ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
tlv - > tag = MRVL_MAX_STA_CNT_TLV_ID ;
tlv - > length = 4 ;
cmd_buf - > action = ACTION_GET ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > max_sta_num_configured =
uap_cpu_to_le16 ( tlv - > max_sta_num_configured ) ;
tlv - > max_sta_num_supported =
uap_cpu_to_le16 ( tlv - > max_sta_num_supported ) ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
endian_convert_tlv_header_in ( tlv ) ;
tlv - > max_sta_num_configured =
uap_le16_to_cpu ( tlv - > max_sta_num_configured ) ;
tlv - > max_sta_num_supported =
uap_le16_to_cpu ( tlv - > max_sta_num_supported ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( ( cmd_buf - > cmd_code ! =
( APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK ) ) | |
( tlv - > tag ! = MRVL_MAX_STA_CNT_TLV_ID ) ) {
printf ( " ERR:Corrupted response! cmd_code=%x, Tlv->tag=%x \n " , cmd_buf - > cmd_code , tlv - > tag ) ;
free ( buffer ) ;
return UAP_FAILURE ;
}
/* Print response */
if ( cmd_buf - > result ! = CMD_SUCCESS ) {
printf ( " ERR:Could not get max station number! \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( tlv - > length = = 4 ) {
* max_sta_num_supported =
tlv - > max_sta_num_supported ;
} else {
* max_sta_num_supported = MAX_STA_COUNT ;
}
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
if ( buffer )
free ( buffer ) ;
return ret ;
}
/**
* @ brief Parse domain name for domain_code
*
* @ param dom_name Domain name
* @ return domain_code / UAP_FAILURE
*/
static t_u8
parse_domain_name ( char * domain_name )
{
t_u8 domain_code = UAP_FAILURE ;
if ( strstr ( domain_name , " DOMAIN_CODE_ " ) ) {
domain_name + = sizeof ( " DOMAIN_CODE_ " ) - 1 ;
if ( ! ( strncmp ( domain_name , " FCC " , sizeof ( " FCC " ) - 1 ) ) )
domain_code = DOMAIN_CODE_FCC ;
else if ( ! ( strcmp ( domain_name , " ETSI " ) ) )
domain_code = DOMAIN_CODE_ETSI ;
else if ( ! ( strcmp ( domain_name , " MKK " ) ) )
domain_code = DOMAIN_CODE_MKK ;
else if ( ! ( strcmp ( domain_name , " IN " ) ) )
domain_code = DOMAIN_CODE_IN ;
else if ( ! ( strcmp ( domain_name , " MY " ) ) )
domain_code = DOMAIN_CODE_MY ;
}
return domain_code ;
}
/**
* @ brief Parse domain file for country information
*
* @ param country Country name
* @ param band Band Info . 0x01 : B band , 0x02 : G band , 0x04 : A band .
* @ param sub_bands Band information
* @ param pdomain_code Pointer to receive domain_code
* @ return number of band / UAP_FAILURE
*/
t_u8
parse_domain_file ( char * country , int band , ieeetypes_subband_set_t * sub_bands ,
t_u8 * pdomain_code )
{
FILE * fp ;
char str [ 64 ] ;
char domain_name [ 64 ] ;
int cflag = 0 ;
int dflag = 0 ;
int found = 0 ;
int skip = 0 ;
int j = - 1 , reset_j = 0 ;
t_u8 no_of_sub_band = 0 ;
char * strp = NULL ;
int ret = 0 ;
fp = fopen ( " config/80211d_domain.conf " , " r " ) ;
if ( fp = = NULL ) {
printf ( " File opening Error \n " ) ;
return UAP_FAILURE ;
}
/**
* Search specific domain name
*/
memset ( domain_name , 0 , sizeof ( domain_name ) ) ;
memset ( str , 0 , 64 ) ;
while ( ! feof ( fp ) ) {
ret = fscanf ( fp , " %63s " , str ) ;
if ( ret < = 0 )
break ;
if ( cflag ) {
strncpy ( domain_name , str , sizeof ( domain_name ) - 1 ) ;
cflag = 0 ;
}
if ( ! strcmp ( str , " COUNTRY: " ) ) {
/** Store next string to domain_name */
cflag = 1 ;
}
if ( ! strcmp ( str , country ) ) {
/** Country is matched ;)*/
found = 1 ;
break ;
}
}
if ( ! found ) {
printf ( " No match found for Country = %s in the 80211d_domain.conf \n " , country ) ;
fclose ( fp ) ;
found = 0 ;
return UAP_FAILURE ;
}
/**
* Search domain specific information
*/
while ( ! feof ( fp ) ) {
ret = fscanf ( fp , " %63s " , str ) ;
if ( ret < = 0 )
break ;
if ( feof ( fp )
) {
break ;
}
if ( dflag & & ! strcmp ( str , " DOMAIN: " ) ) {
if ( ( band & BAND_A ) = = 0 )
break ;
/* parse next domain */
cflag = 0 ;
dflag = 0 ;
j = - 1 ;
reset_j = 0 ;
}
if ( dflag ) {
j + + ;
if ( strchr ( str , ' , ' ) )
reset_j = 1 ;
strp = strtok ( str , " , " ) ;
if ( strp = = NULL ) {
if ( reset_j ) {
j = - 1 ;
reset_j = 0 ;
}
continue ;
} else {
strncpy ( str , strp , ( sizeof ( str ) - 1 ) ) ;
}
if ( IS_HEX_OR_DIGIT ( str ) = = UAP_FAILURE ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
fclose ( fp ) ;
return UAP_FAILURE ;
}
switch ( j ) {
case 0 :
sub_bands [ no_of_sub_band ] . first_chan =
( t_u8 ) A2HEXDECIMAL ( str ) ;
break ;
case 1 :
sub_bands [ no_of_sub_band ] . no_of_chan =
( t_u8 ) A2HEXDECIMAL ( str ) ;
break ;
case 2 :
sub_bands [ no_of_sub_band + + ] . max_tx_pwr =
( t_u8 ) A2HEXDECIMAL ( str ) ;
break ;
default :
printf ( " ERR: Incorrect 80211d_domain.conf file \n " ) ;
fclose ( fp ) ;
return UAP_FAILURE ;
}
if ( reset_j ) {
j = - 1 ;
reset_j = 0 ;
}
}
if ( cflag & & ! strcmp ( str , domain_name ) ) {
/* Followed will be the band details */
cflag = 0 ;
if ( band & ( BAND_B | BAND_G ) | | skip )
dflag = 1 ;
else
skip = 1 ;
}
if ( ! dflag & & ! strcmp ( str , " DOMAIN: " ) ) {
cflag = 1 ;
}
}
fclose ( fp ) ;
if ( pdomain_code & & no_of_sub_band & & ( band & BAND_A ) ) {
* pdomain_code = parse_domain_name ( domain_name ) ;
}
return ( no_of_sub_band ) ;
}
/**
*
* @ brief Set / Get SNMP MIB
*
* @ param action 0 - GET 1 - SET
* @ param oid Oid
* @ param size Size of oid value
* @ param oid_buf Oid value
* @ return UAP_FAILURE or UAP_SUCCESS
*
*/
int
sg_snmp_mib ( t_u16 action , t_u16 oid , t_u16 size , t_u8 * oid_buf )
{
apcmdbuf_snmp_mib * cmd_buf = NULL ;
tlvbuf_header * tlv = NULL ;
int ret = UAP_FAILURE ;
t_u8 * buf = NULL ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
t_u16 cmd_len ;
int i ;
cmd_len = sizeof ( apcmdbuf_snmp_mib ) + sizeof ( tlvbuf_header ) + size ;
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return ret ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate Headers */
cmd_buf = ( apcmdbuf_snmp_mib * ) buf ;
tlv = ( tlvbuf_header * ) ( buf + sizeof ( apcmdbuf_snmp_mib ) ) ;
cmd_buf - > size = buf_len - BUF_HEADER_SIZE ;
cmd_buf - > result = 0 ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > cmd_code = HostCmd_SNMP_MIB ;
tlv - > type = uap_cpu_to_le16 ( oid ) ;
tlv - > len = uap_cpu_to_le16 ( size ) ;
for ( i = 0 ; action & & ( i < size ) ; i + + ) {
tlv - > data [ i ] = oid_buf [ i ] ;
}
cmd_buf - > action = uap_cpu_to_le16 ( action ) ;
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result = = CMD_SUCCESS ) {
if ( ! action ) {
/** Relocate the headers */
tlv = ( tlvbuf_header * ) ( ( t_u8 * ) cmd_buf +
sizeof
( apcmdbuf_snmp_mib ) ) ;
for ( i = 0 ;
i < MIN ( uap_le16_to_cpu ( tlv - > len ) , size ) ;
i + + ) {
oid_buf [ i ] = tlv - > data [ i ] ;
}
}
ret = UAP_SUCCESS ;
} else {
printf ( " ERR:Command Response incorrect! \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
free ( buf ) ;
return ret ;
}
/**
* @ brief Creates a sys_info request and sends to the driver
*
* Usage : " sys_info "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_sys_info ( int argc , char * argv [ ] )
{
apcmdbuf_sys_info_request * cmd_buf = NULL ;
apcmdbuf_sys_info_response * response_buf = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_SUCCESS ;
int opt ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_sys_info_usage ( ) ;
return UAP_FAILURE ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc ! = 0 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_sys_info_usage ( ) ;
return UAP_FAILURE ;
}
/* Alloc buf for command */
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate headers */
cmd_len = sizeof ( apcmdbuf_sys_info_request ) ;
cmd_buf = ( apcmdbuf_sys_info_request * ) buf ;
response_buf = ( apcmdbuf_sys_info_response * ) buf ;
/* Fill the command buffer */
cmd_buf - > cmd_code = APCMD_SYS_INFO ;
cmd_buf - > size = cmd_len ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( response_buf - > cmd_code ! =
( APCMD_SYS_INFO | APCMD_RESP_CHECK ) ) {
printf ( " ERR:Corrupted response! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
/* Print response */
if ( response_buf - > result = = CMD_SUCCESS ) {
printf ( " System information = %s \n " ,
response_buf - > sys_info ) ;
} else {
printf ( " ERR:Could not retrieve system information! \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
free ( buf ) ;
return ret ;
}
/**
* @ brief Show usage information for deepsleep command
*
* $ return N / A
*/
void
print_deepsleep_usage ( void )
{
printf ( " \n Usage : deepsleep [MODE][IDLE_TIME] " ) ;
printf ( " \n Options: MODE : 0 - Disable auto deep sleep mode " ) ;
printf ( " \n 1 - Enable auto deep sleep mode " ) ;
printf ( " \n IDLE_TIME: Idle time in milliseconds, default value is 100 ms " ) ;
printf ( " \n empty - get auto deep sleep mode \n " ) ;
return ;
}
/**
* @ brief Creates deepsleep request and send to driver
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_deepsleep ( int argc , char * argv [ ] )
{
int opt ;
deep_sleep_para param ;
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_deepsleep_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( param ) ) ;
/* Check arguments */
if ( argc > 2 ) {
printf ( " ERR:wrong arguments. Only support 2 arguments \n " ) ;
print_deepsleep_usage ( ) ;
return UAP_FAILURE ;
}
param . subcmd = UAP_DEEP_SLEEP ;
if ( argc ) {
if ( argc > = 1 ) {
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) | |
( ( atoi ( argv [ 0 ] ) < 0 ) | | ( atoi ( argv [ 0 ] ) > 1 ) ) ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_deepsleep_usage ( ) ;
return UAP_FAILURE ;
}
}
param . action = 1 ;
param . deep_sleep = ( t_u16 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
param . idle_time = 0 ;
if ( argc = = 2 ) {
if ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_deepsleep_usage ( ) ;
return UAP_FAILURE ;
}
param . idle_time = ( t_u16 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
}
} else {
param . action = 0 ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
if ( argc )
printf ( " ERR: deep sleep must be disabled before changing idle time \n " ) ;
else {
perror ( " " ) ;
printf ( " ERR:deep sleep failed \n " ) ;
}
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( ! argc ) {
if ( param . deep_sleep = = 1 ) {
printf ( " deep sleep mode: enabled \n " ) ;
printf ( " idle time = %dms \n " , param . idle_time ) ;
} else {
printf ( " deep sleep mode: disabled \n " ) ;
}
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Configure Band Steering
*
* Usage : band_steering_cfg state block_2g_prb_req max_btm_req_allowed
*
* State 0 or 1
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_band_steering ( int argc , char * argv [ ] )
{
int opt ;
band_steer_para param ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u8 state = 0 ;
t_u8 block2gPrbReq = 0 ;
t_u8 maxBtmReqAllowed = 0 ;
t_u8 i ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
printf ( " \n Usage: band_steering_cfg <state 0/1> <block_2g_prb_req> <max_btm_req_allowed> \n " ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( param ) ) ;
/* Check arguments */
if ( ! ( argc = = 0 | | argc = = 2 | | argc = = 4 | | argc = = 6 ) ) {
printf ( " ERR:wrong arguments. \n " ) ;
return UAP_FAILURE ;
}
param . subcmd = UAP_BAND_STEER ;
if ( argc ) {
if ( strcmp ( argv [ 0 ] , " state " ) & &
strcmp ( argv [ 0 ] , " block_2g_prb_req " ) & &
strcmp ( argv [ 0 ] , " max_btm_req_allowed " ) ) {
printf ( " ERR: Incorrect input. Either state, block_2g_prb_req or max_btm_req_allowed is needed. \n " ) ;
return UAP_FAILURE ;
}
/** SET */
for ( i = 0 ; i < argc ; i = i + 2 ) {
if ( strcmp ( argv [ i ] , " state " ) = = 0 ) {
param . action + = ACT_SET_STATE ;
if ( strcmp ( argv [ i + 1 ] , " 0 " ) = = 0 ) {
state = 0 ;
} else if ( strcmp ( argv [ i + 1 ] , " 1 " ) = = 0 ) {
state = 1 ;
} else {
printf ( " ERR: Invalid State value. " ) ;
return UAP_FAILURE ;
}
} else if ( strcmp ( argv [ i ] , " block_2g_prb_req " ) = = 0 ) {
param . action + = ACT_SET_BLOCK_2G_PRB_REQ ;
block2gPrbReq = atoi ( argv [ i + 1 ] ) ;
if ( block2gPrbReq < 0 | | block2gPrbReq > 15 ) {
printf ( " ERR: Invalid block_2g_prb_req value. Enter value between 0 and 15 " ) ;
return UAP_FAILURE ;
}
} else if ( strcmp ( argv [ i ] , " max_btm_req_allowed " ) = = 0 ) {
param . action + = ACT_SET_MAX_BTM_REQ_ALLOWED ;
maxBtmReqAllowed = atoi ( argv [ i + 1 ] ) ;
if ( maxBtmReqAllowed < = 0 | |
maxBtmReqAllowed > 255 ) {
printf ( " ERR: Invalid max_btm_req_allowed value. " ) ;
return UAP_FAILURE ;
}
} else {
printf ( " ERR: Incorrect input. state, block_2g_prb_req and/or max_btm_req_allowed is needed in decimal format. " ) ;
return UAP_FAILURE ;
}
}
}
param . state = state ;
param . block_2g_prb_req = block2gPrbReq ;
param . max_btm_req_allowed = maxBtmReqAllowed ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ;
if ( argc ) {
printf ( " Set Successfull \n " ) ;
printf ( " state = %d \n " , param . state ) ;
printf ( " block_2g_prb_req = %d \n " , param . block_2g_prb_req ) ;
printf ( " max_btm_req_allowed = %d \n " , param . max_btm_req_allowed ) ;
} else {
printf ( " Get Successfull \n " ) ;
if ( param . state = = 1 ) {
printf ( " band steering mode: enabled \n " ) ;
printf ( " block_2g_prb_req = %d \n " ,
param . block_2g_prb_req ) ;
printf ( " max_btm_req_allowed = %d \n " ,
param . max_btm_req_allowed ) ;
} else {
printf ( " band steering: disabled \n " ) ;
}
close ( sockfd ) ;
return UAP_FAILURE ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for tx_data_pause command
*
* $ return N / A
*/
void
print_txdatapause_usage ( void )
{
printf ( " \n Usage : tx_data_pause [ENABLE][TX_BUF_CNT] " ) ;
printf ( " \n Options: ENABLE : 0 - Disable Tx data pause events " ) ;
printf ( " \n 1 - Enable Tx data pause events " ) ;
printf ( " \n TX_BUF_CNT: Max number of TX buffer for PS clients " ) ;
printf ( " \n empty - get Tx data pause settings \n " ) ;
return ;
}
/**
* @ brief Set / get txpause setting
*
* @ param txpause A pointer to the Tx data pause parameters structure
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
send_txpause_ioctl ( tx_data_pause_para * txpause )
{
struct ifreq ifr ;
t_s32 sockfd ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) txpause ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:txpause is not supported by %s \n " , dev_name ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Creates tx_data_pause request and sends to driver
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_txdatapause ( int argc , char * argv [ ] )
{
int opt ;
tx_data_pause_para param ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_txdatapause_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( param ) ) ;
/* Check arguments */
if ( argc > 2 ) {
printf ( " ERR: Wrong number of arguments \n " ) ;
print_txdatapause_usage ( ) ;
return UAP_FAILURE ;
}
param . subcmd = UAP_TX_DATA_PAUSE ;
if ( argc ) {
if ( argc > = 1 ) {
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) | |
( ( atoi ( argv [ 0 ] ) < TX_DATA_PAUSE_DISABLE ) | |
( atoi ( argv [ 0 ] ) > TX_DATA_PAUSE_ENABLE ) ) ) {
printf ( " ERR: First argument can either be 0 or 1 \n " ) ;
print_txdatapause_usage ( ) ;
return UAP_FAILURE ;
}
}
if ( argc = = 1 ) {
param . action = ACTION_GET ;
if ( UAP_FAILURE = = send_txpause_ioctl ( & param ) ) {
return UAP_FAILURE ;
}
}
param . action = ACTION_SET ;
param . txpause = ( t_u16 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
if ( argc = = 2 ) {
if ( IS_HEX_OR_DIGIT ( argv [ 1 ] ) = = UAP_FAILURE ) {
printf ( " ERR: Max buffer length must be numeric \n " ) ;
print_txdatapause_usage ( ) ;
return UAP_FAILURE ;
}
param . txbufcnt = ( t_u16 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
}
} else {
param . action = ACTION_GET ;
}
if ( UAP_FAILURE = = send_txpause_ioctl ( & param ) )
return UAP_FAILURE ;
if ( ( argc = = 2 ) & & ( ( t_u16 ) A2HEXDECIMAL ( argv [ 1 ] ) ! = param . txbufcnt ) ) {
printf ( " Max number of TX buffer allowed for all PS client: %d \n " , param . txbufcnt ) ;
return UAP_FAILURE ;
}
if ( ! argc ) {
printf ( " Tx data pause: %s \n " ,
( param . txpause = = 1 ) ? " enabled " : " disabled " ) ;
printf ( " Max number of TX buffer allowed for all PS client: %d \n " , param . txbufcnt ) ;
}
return UAP_SUCCESS ;
}
/**
* @ brief Process host_cmd
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return N / A
*/
int
apcmd_hostcmd ( int argc , char * argv [ ] )
{
apcmdbuf * hdr ;
t_u8 * buffer = NULL ;
int ret = UAP_SUCCESS ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
char cmdname [ 256 ] ;
if ( argc < = 2 ) {
printf ( " Error: invalid no of arguments \n " ) ;
printf ( " Syntax: ./uaputl hostcmd <hostcmd.conf> <cmdname> \n " ) ;
return UAP_FAILURE ;
}
buffer = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buffer , 0 , buf_len ) ;
sprintf ( cmdname , " %s " , argv [ 2 ] ) ;
ret = prepare_host_cmd_buffer ( argv [ 1 ] , cmdname , buffer ) ;
if ( ret = = UAP_FAILURE )
goto _exit_ ;
/* Locate headers */
hdr = ( apcmdbuf * ) buffer ;
cmd_len = hdr - > size + BUF_HEADER_SIZE ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) buffer , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
hdr - > cmd_code & = HostCmd_CMD_ID_MASK ;
if ( ! hdr - > result ) {
printf ( " UAPHOSTCMD: CmdCode=%#04x, Size=%#04x, SeqNum=%#04x, Result=%#04x \n " , hdr - > cmd_code , hdr - > size , hdr - > seq_num , hdr - > result ) ;
hexdump_data ( " payload " ,
( void * ) ( buffer + APCMDHEADERLEN ) ,
hdr - > size - ( APCMDHEADERLEN -
BUF_HEADER_SIZE ) , ' ' ) ;
} else
printf ( " UAPHOSTCMD failed: CmdCode=%#04x, Size=%#04x, SeqNum=%#04x, Result=%#04x \n " , hdr - > cmd_code , hdr - > size , hdr - > seq_num , hdr - > result ) ;
} else
printf ( " ERR:Command sending failed! \n " ) ;
_exit_ :
if ( buffer )
free ( buffer ) ;
return ret ;
}
# ifdef SDIO
/**
* @ brief Show usage information for cmd52rw command
*
* $ return N / A
*/
void
print_cmd52rw_usage ( void )
{
printf ( " \n Usage : sdcmd52rw <FN no.> <address> [data] " ) ;
printf ( " \n Options: FN no : SDIO function number. " ) ;
printf ( " \n address: SDIO address " ) ;
printf ( " \n data: data for SDIO write operation. " ) ;
printf ( " \n Read is performed if data is not provided. " ) ;
return ;
}
/**
* @ brief Process cmd52 read / write handler
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return N / A
*/
int
apcmd_cmd52_readwrite ( int argc , char * argv [ ] )
{
int opt ;
sdcmd52_para param ;
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_cmd52rw_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( sdcmd52_para ) ) ;
/* Check arguments */
if ( argc < 2 | | argc > 3 ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_cmd52rw_usage ( ) ;
return UAP_FAILURE ;
}
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) | |
( IS_HEX_OR_DIGIT ( argv [ 1 ] ) = = UAP_FAILURE ) ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_cmd52rw_usage ( ) ;
return UAP_FAILURE ;
}
param . cmd52_params [ 0 ] = ( t_u8 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
if ( param . cmd52_params [ 0 ] > 7 ) {
printf ( " ERR: Invalid function number! \n " ) ;
return UAP_FAILURE ;
}
param . cmd52_params [ 1 ] = ( t_u8 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
param . action = 0 ;
if ( argc = = 3 ) {
if ( IS_HEX_OR_DIGIT ( argv [ 2 ] ) = = UAP_FAILURE ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_cmd52rw_usage ( ) ;
return UAP_FAILURE ;
}
param . cmd52_params [ 2 ] = ( t_u8 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
param . action = 1 ;
}
param . subcmd = UAP_SDCMD52_RW ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:cmd52rw failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( argc = = 2 )
printf ( " Cmd52 read done. " ) ;
else
printf ( " Cmd52 write done. " ) ;
printf ( " func=%d, reg=%d, data=0x%02X \n " ,
param . cmd52_params [ 0 ] , param . cmd52_params [ 1 ] ,
param . cmd52_params [ 2 ] ) ;
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
# endif
/**
* @ brief Show usage information for addbapara command
*
* $ return N / A
*/
void
print_addbapara_usage ( void )
{
printf ( " \n Usage : addbapara [timeout txwinsize rxwinsize] " ) ;
printf ( " \n Options: timeout : 0 - Disable " ) ;
printf ( " \n 1 - 65535 : Block Ack Timeout in TU " ) ;
printf ( " \n txwinsize: Buffer size for ADDBA request " ) ;
printf ( " \n rxwinsize: Buffer size for ADDBA response " ) ;
printf ( " \n txamsdu: amsdu for ADDBA request " ) ;
printf ( " \n rxamsdu: amsdu for ADDBA response " ) ;
printf ( " \n empty - get ADDBA parameters \n " ) ;
return ;
}
/**
* @ brief Creates addbaparam request and send to driver
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_addbapara ( int argc , char * argv [ ] )
{
int opt ;
addba_param param ;
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_addbapara_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( param ) ) ;
/* Check arguments */
if ( ( argc ! = 0 ) & & ( argc ! = 5 ) ) {
printf ( " ERR:wrong arguments. Only support 0 or 5 arguments \n " ) ;
print_addbapara_usage ( ) ;
return UAP_FAILURE ;
}
param . subcmd = UAP_ADDBA_PARA ;
if ( argc ) {
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE )
| | ( IS_HEX_OR_DIGIT ( argv [ 1 ] ) = = UAP_FAILURE )
| | ( IS_HEX_OR_DIGIT ( argv [ 2 ] ) = = UAP_FAILURE )
| | ( IS_HEX_OR_DIGIT ( argv [ 3 ] ) = = UAP_FAILURE )
| | ( IS_HEX_OR_DIGIT ( argv [ 4 ] ) = = UAP_FAILURE )
) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_addbapara_usage ( ) ;
return UAP_FAILURE ;
}
param . action = 1 ;
param . timeout = ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
if ( param . timeout > DEFAULT_BLOCK_ACK_TIMEOUT ) {
printf ( " ERR: Block Ack timeout should be in range [1-65535] \n " ) ;
print_addbapara_usage ( ) ;
return UAP_FAILURE ;
}
param . txwinsize = ( t_u32 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
param . rxwinsize = ( t_u32 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
if ( param . txwinsize > MAX_TXRX_WINDOW_SIZE | |
param . rxwinsize > MAX_TXRX_WINDOW_SIZE ) {
printf ( " ERR: Tx/Rx window size should not be greater than 1023 \n " ) ;
print_addbapara_usage ( ) ;
return UAP_FAILURE ;
}
param . txamsdu = ( t_u8 ) A2HEXDECIMAL ( argv [ 3 ] ) ;
param . rxamsdu = ( t_u8 ) A2HEXDECIMAL ( argv [ 4 ] ) ;
if ( param . txamsdu > 1 | | param . rxamsdu > 1 ) {
printf ( " ERR: Tx/Rx amsdu should not be 0 or 1 \n " ) ;
print_addbapara_usage ( ) ;
return UAP_FAILURE ;
}
} else {
param . action = 0 ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:ADDBA PARA failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( ! argc ) {
printf ( " ADDBA parameters: \n " ) ;
printf ( " \t timeout=%d \n " , ( int ) param . timeout ) ;
printf ( " \t txwinsize=%d \n " , ( int ) param . txwinsize ) ;
printf ( " \t rxwinsize=%d \n " , ( int ) param . rxwinsize ) ;
printf ( " \t txamsdu=%d \n " , ( int ) param . txamsdu ) ;
printf ( " \t rxamsdu=%d \n " , ( int ) param . rxamsdu ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for aggrpriotbl command
*
* $ return N / A
*/
void
print_aggrpriotbl_usage ( void )
{
printf ( " \n Usage : aggrpriotbl <m0> <n0> <m1> <n1> ... <m7> <n7> " ) ;
printf ( " \n Options: <mx> : 0 - 7, 0xff to disable AMPDU aggregation. " ) ;
printf ( " \n <nx> : 0 - 7, 0xff to disable AMSDU aggregation. " ) ;
printf ( " \n empty - get the priority table \n " ) ;
return ;
}
/**
* @ brief Creates aggrpriotbl request and send to driver
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_aggrpriotbl ( int argc , char * argv [ ] )
{
int opt ;
aggr_prio_tbl prio_tbl ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u8 value ;
int i ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_aggrpriotbl_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & prio_tbl , 0 , sizeof ( prio_tbl ) ) ;
/* Check arguments */
if ( ( argc ! = 0 ) & & ( argc ! = 16 ) ) {
printf ( " ERR:wrong arguments. Only support 0 or 16 arguments \n " ) ;
print_aggrpriotbl_usage ( ) ;
return UAP_FAILURE ;
}
prio_tbl . subcmd = UAP_AGGR_PRIOTBL ;
if ( argc ) {
for ( i = 0 ; i < argc ; i + + ) {
if ( ( IS_HEX_OR_DIGIT ( argv [ i ] ) = = UAP_FAILURE ) ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_aggrpriotbl_usage ( ) ;
return UAP_FAILURE ;
}
value = ( t_u8 ) A2HEXDECIMAL ( argv [ i ] ) ;
if ( ( value > 7 ) & & ( value ! = 0xff ) ) {
printf ( " ERR: Invalid priority, Valid value 0-7, 0xff to disable aggregation. \n " ) ;
print_aggrpriotbl_usage ( ) ;
return UAP_FAILURE ;
}
}
prio_tbl . action = 1 ;
for ( i = 0 ; i < MAX_NUM_TID ; i + + ) {
prio_tbl . ampdu [ i ] = ( t_u8 ) A2HEXDECIMAL ( argv [ i * 2 ] ) ;
prio_tbl . amsdu [ i ] = ( t_u8 ) A2HEXDECIMAL ( argv [ i * 2 + 1 ] ) ;
}
} else {
prio_tbl . action = 0 ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & prio_tbl ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: priority table failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( ! argc ) {
printf ( " AMPDU/AMSDU priority table: " ) ;
for ( i = 0 ; i < MAX_NUM_TID ; i + + ) {
printf ( " %d %d " , prio_tbl . ampdu [ i ] , prio_tbl . amsdu [ i ] ) ;
}
printf ( " \n " ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for addbareject command
*
* $ return N / A
*/
void
print_addba_reject_usage ( void )
{
printf ( " \n Usage : addbareject <m0> <m1> ... <m7> " ) ;
printf ( " \n Options: <mx> : 1 enables rejection of ADDBA request for TidX. " ) ;
printf ( " \n 0 would accept any ADDBAs for TidX. " ) ;
printf ( " \n empty - get the addbareject table \n " ) ;
return ;
}
/**
* @ brief Creates addbareject request and send to driver
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_addbareject ( int argc , char * argv [ ] )
{
int opt ;
addba_reject_para param ;
struct ifreq ifr ;
t_s32 sockfd ;
int i ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_addba_reject_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( param ) ) ;
/* Check arguments */
if ( ( argc ! = 0 ) & & ( argc ! = 8 ) ) {
printf ( " ERR:wrong arguments. Only support 0 or 8 arguments \n " ) ;
print_addba_reject_usage ( ) ;
return UAP_FAILURE ;
}
param . subcmd = UAP_ADDBA_REJECT ;
if ( argc ) {
for ( i = 0 ; i < argc ; i + + ) {
if ( ( ISDIGIT ( argv [ i ] ) = = UAP_FAILURE ) | |
( atoi ( argv [ i ] ) < 0 ) | | ( atoi ( argv [ i ] ) > 1 ) ) {
printf ( " ERR: Only allow 0 or 1 \n " ) ;
print_addba_reject_usage ( ) ;
return UAP_FAILURE ;
}
}
param . action = 1 ;
for ( i = 0 ; i < MAX_NUM_TID ; i + + ) {
param . addba_reject [ i ] = ( t_u8 ) atoi ( argv [ i ] ) ;
}
} else {
param . action = 0 ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: addba reject table failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( ! argc ) {
printf ( " addba reject table: " ) ;
for ( i = 0 ; i < MAX_NUM_TID ; i + + ) {
printf ( " %d " , param . addba_reject [ i ] ) ;
}
printf ( " \n " ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Creates get_fw_info request and send to driver
*
*
* @ param pfw_info Pointer to FW information structure
* @ return 0 - - success , otherwise fail
*/
int
get_fw_info ( fw_info * pfw_info )
{
struct ifreq ifr ;
t_s32 sockfd ;
memset ( pfw_info , 0 , sizeof ( fw_info ) ) ;
pfw_info - > subcmd = UAP_FW_INFO ;
pfw_info - > action = 0 ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return - 1 ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) pfw_info ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: get fw info failed \n " ) ;
close ( sockfd ) ;
return - 1 ;
}
/* Close socket */
close ( sockfd ) ;
return 0 ;
}
/**
* @ brief Show usage information for HT Tx command
*
* $ return N / A
*/
void
print_ht_tx_usage ( void )
{
printf ( " \n Usage : httxcfg [<txcfg>] " ) ;
printf ( " \n Options: txcfg : This is a bitmap and should be used as following " ) ;
printf ( " \n Bit 15-7: Reserved set to 0 " ) ;
printf ( " \n Bit 6: Short GI in 40 Mhz enable/disable " ) ;
printf ( " \n Bit 5: Short GI in 20 Mhz enable/disable " ) ;
printf ( " \n Bit 4: Green field enable/disable " ) ;
printf ( " \n Bit 3-2: Reserved set to 0 " ) ;
printf ( " \n Bit 1: 20/40 Mhz enable disable. " ) ;
printf ( " \n Bit 0: Reserved set to 0 " ) ;
return ;
}
/**
* @ brief Process HT Tx configuration
* @ param argc Number of arguments
* @ param argv A pointer to arguments array
* @ return MLAN_STATUS_SUCCESS - - success , otherwise - - fail
*/
int
apcmd_sys_cfg_ht_tx ( int argc , char * argv [ ] )
{
int opt ;
ht_tx_cfg_para param ;
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_ht_tx_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( param ) ) ;
/* Check arguments */
if ( argc = = 0 ) {
param . action = ACTION_GET ;
} else if ( argc = = 1 ) {
param . action = ACTION_SET ;
param . tx_cfg . httxcap = ( t_u16 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
} else {
print_ht_tx_usage ( ) ;
return UAP_FAILURE ;
}
param . subcmd = UAP_HT_TX_CFG ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: HT Tx configuration failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
/* Handle response */
if ( param . action = = ACTION_GET ) {
printf ( " HT Tx cfg: 0x%08x \n " , param . tx_cfg . httxcap ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for vhtcfg command
*
* $ return N / A
*/
void
print_vht_usage ( void )
{
printf ( " \n Usage : vhtcfg <band> <txrx> <bwcfg> <vhtcap> <tx_mcs_map> "
" <rx_mcs_map> " ) ;
printf ( " \n Option: band : This is the band info for vhtcfg settings. " ) ;
printf ( " \n 0: Settings for both 2.4G and 5G bands " ) ;
printf ( " \n 1: Settings for 2.4G band " ) ;
printf ( " \n 2: Settings for 5G band " ) ;
printf ( " \n txrx : This parameter specifies the configuration of VHT " " operation for TX or/and VHT capabilities. " ) ;
printf ( " \n 1: configuration of VHT capabilities tx " ) ;
printf ( " \n 2: configuration of VHT capabilities rx " ) ;
printf ( " \n bwcfg : This parameter specifies the bandwidth (BW) "
" configuration applied to the vhtcfg. " ) ;
printf ( " \n If <txrx> is 1/3 (Tx operations) " ) ;
printf ( " \n 0: Tx BW follows the BW (20/40 MHz) from " " 11N CFG " ) ;
printf ( " \n 1: Tx BW follows the BW (80/160/80+80 MHz) " " from VHT Capabilities. " ) ;
printf ( " \n vhtcap : This parameter specifies the VHT capabilities info. " ) ;
printf ( " \n tx_mcs_map : This parameter specifies the TX MCS map. " ) ;
printf ( " \n rx_mcs_map : This parameter specifies the RX MCS map. \n " ) ;
return ;
}
/**
* @ brief Handle response of the vhtcfg command
*
* @ param vhtcfg Pointer to structure eth_priv_vhtcfg
*
* $ return N / A
*/
void
print_vht_response ( struct eth_priv_vhtcfg * vhtcfg )
{
/* GET operation */
/* Band */
if ( vhtcfg - > band = = BAND_SELECT_BG )
printf ( " Band: 2.4G \n " ) ;
else
printf ( " Band: 5G \n " ) ;
/* BW confi9 */
if ( vhtcfg - > txrx & 0x3 ) {
if ( vhtcfg - > bwcfg = = 0 )
printf ( " BW config: the 11N config \n " ) ;
else
printf ( " BW config: the VHT Capabilities \n " ) ;
}
/* Tx/Rx */
if ( vhtcfg - > txrx & 0x1 )
printf ( " VHT operation for Tx: 0x%08x \n " ,
vhtcfg - > vht_cap_info ) ;
if ( vhtcfg - > txrx & 0x2 )
/* VHT capabilities */
printf ( " VHT Capabilities Info: 0x%08x \n " ,
vhtcfg - > vht_cap_info ) ;
/* MCS */
printf ( " Tx MCS set: 0x%04x \n " , vhtcfg - > vht_tx_mcs ) ;
printf ( " Rx MCS set: 0x%04x \n " , vhtcfg - > vht_rx_mcs ) ;
}
/**
* @ brief Set / Get 11 AC configurations
* @ param argc Number of arguments
* @ param argv A pointer to arguments array
* @ return MLAN_STATUS_SUCCESS - - success , otherwise - - fail
*/
int
apcmd_sys_cfg_vht ( int argc , char * argv [ ] )
{
int opt , i = 0 ;
vht_cfg_para param ;
struct eth_priv_vhtcfg vhtcfg ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u8 * respbuf = NULL , num = 0 ;
fw_info fw ;
if ( 0 = = get_fw_info ( & fw ) ) {
/*check whether support 802.11AC through BAND_AAC bit */
if ( ! ( fw . fw_bands & BAND_AAC ) ) {
printf ( " ERR: No support 802 11AC. \n " ) ;
return UAP_FAILURE ;
}
} else {
printf ( " ERR: get_fw_info fail \n " ) ;
return UAP_FAILURE ;
}
memset ( & param , 0 , sizeof ( param ) ) ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_vht_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
respbuf = ( t_u8 * ) malloc ( MRVDRV_SIZE_OF_CMD_BUFFER ) ;
if ( ! respbuf ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( respbuf , 0 , MRVDRV_SIZE_OF_CMD_BUFFER ) ;
/* Check arguments */
if ( ( argc > 6 ) | | ( argc < 2 ) ) {
printf ( " ERR: Invalid number of arguments. \n " ) ;
print_vht_usage ( ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
if ( ( atoi ( argv [ 0 ] ) < 0 ) | | ( atoi ( argv [ 0 ] ) > 2 ) ) {
printf ( " ERR: Invalid band selection. \n " ) ;
print_vht_usage ( ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
} else {
param . vht_cfg . band = ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
}
if ( ( atoi ( argv [ 1 ] ) < = 0 ) | | ( atoi ( argv [ 1 ] ) > 3 ) ) {
printf ( " ERR: Invalid Tx/Rx selection. \n " ) ;
print_vht_usage ( ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
} else {
param . vht_cfg . txrx = ( t_u32 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
}
if ( argc = = 2 ) {
param . action = ACTION_GET ;
} else if ( argc > 2 ) {
param . vht_cfg . band = ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
param . vht_cfg . txrx = ( t_u32 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
if ( argc = = 3 ) {
printf ( " ERR: Invalid number of arguments. \n " ) ;
print_vht_usage ( ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
if ( argc > = 4 ) {
if ( ( atoi ( argv [ 2 ] ) < 0 ) | | ( atoi ( argv [ 2 ] ) > 1 ) | |
( ( atoi ( argv [ 2 ] ) = = 1 ) & &
( atoi ( argv [ 0 ] ) & BAND_SELECT_BG ) ) ) {
printf ( " ERR: Invalid BW cfg selection. \n " ) ;
print_vht_usage ( ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
} else {
param . vht_cfg . bwcfg =
( t_u32 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
}
param . vht_cfg . vht_cap_info =
( t_u32 ) A2HEXDECIMAL ( argv [ 3 ] ) ;
if ( argc = = 4 ) {
param . vht_cfg . vht_tx_mcs = 0xffffffff ;
param . vht_cfg . vht_rx_mcs = 0xffffffff ;
} else {
if ( argc = = 5 ) {
printf ( " ERR: Invalid number of arguments. \n " ) ;
print_vht_usage ( ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
param . vht_cfg . vht_tx_mcs =
( t_u32 ) A2HEXDECIMAL ( argv [ 4 ] ) ;
param . vht_cfg . vht_rx_mcs =
( t_u32 ) A2HEXDECIMAL ( argv [ 5 ] ) ;
}
}
param . action = ACTION_SET ;
} else {
print_vht_usage ( ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
param . subcmd = UAP_VHT_CFG ;
memcpy ( respbuf , & param , sizeof ( vht_cfg_para ) ) ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) respbuf ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: 11ac VHT configuration failed \n " ) ;
close ( sockfd ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
/* Handle response */
if ( param . action = = ACTION_GET ) {
/* Process result */
/* the first attribute is the number of vhtcfg entries */
num = * respbuf ;
printf ( " 11AC VHT Configuration: \n " ) ;
for ( i = 0 ; i < num ; i + + ) {
memcpy ( & vhtcfg , respbuf + 1 + i * sizeof ( vhtcfg ) ,
sizeof ( vhtcfg ) ) ;
print_vht_response ( & vhtcfg ) ;
}
} else
printf ( " 11AC VHT Configuration success! \n " ) ;
/* Close socket */
close ( sockfd ) ;
if ( respbuf )
free ( respbuf ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for TX BF command
*
* $ return N / A
*/
void
print_tx_bf_usage ( void )
{
printf ( " \n Usage : httxbfcfg <ACTION> [ACT_DATA] " ) ;
printf ( " \n Options: ACTION : 1 - Performs NDP Sounding for PEER " ) ;
printf ( " \n 2 - TX BF interval in milliseconds " ) ;
printf ( " \n 3 - Not to perform any sounding " ) ;
printf ( " \n 4 - TX BF SNR Threshold for peer " ) ;
printf ( " \n ACT_DATA : Specific data for the above actions " ) ;
printf ( " \n For 1: PEER MAC and status " ) ;
printf ( " \n For 2: TX BF interval " ) ;
printf ( " \n For 3: PEER MAC " ) ;
printf ( " \n For 4: PEER MAC and SNR " ) ;
printf ( " \n empty - get action specific settings \n " ) ;
return ;
}
/**
* @ brief Handle response of the TX BF command
*
* @ param param Pointer to structure tx_bf_cfg_para
*
* $ return N / A
*/
void
print_tx_bf_response ( tx_bf_cfg_para * param )
{
int i ;
trigger_sound_args * bf_sound = param - > body . bf_sound ;
tx_bf_peer_args * tx_bf_peer = param - > body . tx_bf_peer ;
snr_thr_args * bf_snr = param - > body . bf_snr ;
bf_periodicity_args * bf_periodicity = param - > body . bf_periodicity ;
bf_global_cfg_args * bf_global = & param - > body . bf_global_cfg ;
switch ( param - > bf_action ) {
case BF_GLOBAL_CONFIGURATION :
printf ( " Global BF Status :%s \n " ,
bf_global - > bf_enbl ? " ENABLED " : " DISABLED " ) ;
printf ( " Global Sounding Status :%s \n " ,
bf_global - > sounding_enbl ? " ENABLED " : " DISABLED " ) ;
printf ( " Default FB Type :%d \n " , bf_global - > fb_type ) ;
printf ( " Default SNR Threshold :%d \n " , bf_global - > snr_threshold ) ;
printf ( " Default Sounding Interval :%d \n " ,
bf_global - > sounding_interval ) ;
printf ( " Beamforming Mode :%d \n " , bf_global - > bf_mode ) ;
break ;
case TRIGGER_SOUNDING_FOR_PEER :
printf ( " PEER MAC = %02X:%02X:%02X:%02X:%02X:%02X, STATUS = %s \n " , bf_sound - > peer_mac [ 0 ] , bf_sound - > peer_mac [ 1 ] , bf_sound - > peer_mac [ 2 ] , bf_sound - > peer_mac [ 3 ] , bf_sound - > peer_mac [ 4 ] , bf_sound - > peer_mac [ 5 ] , bf_sound - > status ? " Failure " : " Success " ) ;
break ;
case SET_GET_BF_PERIODICITY :
printf ( " PEER MAC = %02x:%02x:%02x:%02x:%02x:%02x, Interval (ms) = %d \n " , bf_periodicity - > peer_mac [ 0 ] , bf_periodicity - > peer_mac [ 1 ] , bf_periodicity - > peer_mac [ 2 ] , bf_periodicity - > peer_mac [ 3 ] , bf_periodicity - > peer_mac [ 4 ] , bf_periodicity - > peer_mac [ 5 ] , bf_periodicity - > interval ) ;
break ;
case TX_BF_FOR_PEER_ENBL :
for ( i = 0 ; i < param - > no_of_peers ; i + + ) {
printf ( " PEER MAC = %02x:%02x:%02x:%02x:%02x:%02x \n " ,
tx_bf_peer - > peer_mac [ 0 ] , tx_bf_peer - > peer_mac [ 1 ] ,
tx_bf_peer - > peer_mac [ 2 ] , tx_bf_peer - > peer_mac [ 3 ] ,
tx_bf_peer - > peer_mac [ 4 ] ,
tx_bf_peer - > peer_mac [ 5 ] ) ;
printf ( " BF Status : %s \n " ,
tx_bf_peer - > bf_enbl ? " ENABLED " : " DISABLED " ) ;
printf ( " Sounding Status : %s \n " ,
tx_bf_peer - >
sounding_enbl ? " ENABLED " : " DISABLED " ) ;
printf ( " FB Type : %d \n " , tx_bf_peer - > fb_type ) ;
tx_bf_peer + + ;
}
break ;
case SET_SNR_THR_PEER :
for ( i = 0 ; i < param - > no_of_peers ; i + + ) {
printf ( " PEER MAC = %02x:%02x:%02x:%02x:%02x:%02x, SNR = %d \n " , bf_snr - > peer_mac [ 0 ] , bf_snr - > peer_mac [ 1 ] , bf_snr - > peer_mac [ 2 ] , bf_snr - > peer_mac [ 3 ] , bf_snr - > peer_mac [ 4 ] , bf_snr - > peer_mac [ 5 ] , bf_snr - > snr ) ;
bf_snr + + ;
}
break ;
}
}
/** Tx BF Global conf argument index */
# define BF_ENABLE_PARAM 1
# define SOUND_ENABLE_PARAM 2
# define FB_TYPE_PARAM 3
# define SNR_THRESHOLD_PARAM 4
# define SOUND_INTVL_PARAM 5
# define BF_MODE_PARAM 6
# define BF_CFG_ACT_GET 0
# define BF_CFG_ACT_SET 1
/**
* @ brief Creates TX BF request and send to driver
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_sys_cfg_tx_bf ( int argc , char * argv [ ] )
{
int opt , ret = UAP_FAILURE ;
tx_bf_cfg_para param ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u32 bf_action = 0 ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_tx_bf_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( param ) ) ;
/* Check arguments */
if ( argc < 1 ) {
printf ( " ERR: wrong arguments. \n " ) ;
print_tx_bf_usage ( ) ;
return UAP_FAILURE ;
}
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) | |
( ( atoi ( argv [ 0 ] ) < BF_GLOBAL_CONFIGURATION ) | |
( atoi ( argv [ 0 ] ) > SET_SNR_THR_PEER ) ) ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_tx_bf_usage ( ) ;
return UAP_FAILURE ;
}
bf_action = ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
param . subcmd = UAP_TX_BF_CFG ;
param . bf_action = bf_action ;
switch ( bf_action ) {
case BF_GLOBAL_CONFIGURATION :
if ( argc ! = 1 & & argc ! = 7 ) {
printf ( " Invalid argument for Global BF Configuration \n " ) ;
return UAP_FAILURE ;
}
if ( argc = = 1 ) {
param . bf_cmd_action = BF_CFG_ACT_GET ;
param . action = ACTION_GET ;
} else {
param . bf_cmd_action = BF_CFG_ACT_SET ;
param . action = ACTION_SET ;
param . body . bf_global_cfg . bf_enbl =
atoi ( argv [ BF_ENABLE_PARAM ] ) ;
param . body . bf_global_cfg . sounding_enbl =
atoi ( argv [ SOUND_ENABLE_PARAM ] ) ;
param . body . bf_global_cfg . fb_type =
atoi ( argv [ FB_TYPE_PARAM ] ) ;
param . body . bf_global_cfg . snr_threshold =
atoi ( argv [ SNR_THRESHOLD_PARAM ] ) ;
param . body . bf_global_cfg . sounding_interval =
atoi ( argv [ SOUND_INTVL_PARAM ] ) ;
param . body . bf_global_cfg . bf_mode =
atoi ( argv [ BF_MODE_PARAM ] ) ;
}
break ;
case TRIGGER_SOUNDING_FOR_PEER :
if ( argc ! = 2 ) {
printf ( " ERR: wrong arguments. \n " ) ;
print_tx_bf_usage ( ) ;
return UAP_FAILURE ;
}
if ( ( ret =
mac2raw ( argv [ 1 ] ,
param . body . bf_sound [ 0 ] . peer_mac ) ) ! = UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " ,
ret = = UAP_FAILURE ? " Invalid MAC " : ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " :
" Multicast " ) ;
return UAP_FAILURE ;
}
param . bf_cmd_action = BF_CFG_ACT_SET ;
param . action = ACTION_SET ;
break ;
case SET_GET_BF_PERIODICITY :
if ( argc ! = 2 & & argc ! = 3 ) {
printf ( " ERR: wrong arguments. \n " ) ;
print_tx_bf_usage ( ) ;
return UAP_FAILURE ;
}
if ( ( ret =
mac2raw ( argv [ 1 ] ,
param . body . bf_periodicity [ 0 ] . peer_mac ) ) ! =
UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " ,
ret = = UAP_FAILURE ? " Invalid MAC " : ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " :
" Multicast " ) ;
return UAP_FAILURE ;
}
if ( argc = = 3 ) {
if ( IS_HEX_OR_DIGIT ( argv [ 2 ] ) = = UAP_FAILURE )
return UAP_FAILURE ;
param . body . bf_periodicity [ 0 ] . interval =
( t_u32 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
param . bf_cmd_action = BF_CFG_ACT_SET ;
param . action = ACTION_SET ;
} else {
param . bf_cmd_action = BF_CFG_ACT_GET ;
param . action = ACTION_GET ;
}
break ;
case TX_BF_FOR_PEER_ENBL :
if ( argc ! = 1 & & argc ! = 5 ) {
printf ( " ERR: wrong arguments. \n " ) ;
print_tx_bf_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc = = 1 ) {
param . bf_cmd_action = BF_CFG_ACT_GET ;
param . action = ACTION_GET ;
} else {
if ( ( ret =
mac2raw ( argv [ 1 ] ,
param . body . tx_bf_peer [ 0 ] . peer_mac ) ) ! =
UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " ,
ret = =
UAP_FAILURE ? " Invalid MAC " : ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " :
" Multicast " ) ;
return UAP_FAILURE ;
}
param . body . tx_bf_peer - > bf_enbl = atoi ( argv [ 2 ] ) ;
param . body . tx_bf_peer - > sounding_enbl = atoi ( argv [ 3 ] ) ;
param . body . tx_bf_peer - > fb_type = atoi ( argv [ 4 ] ) ;
param . bf_cmd_action = BF_CFG_ACT_SET ;
param . action = ACTION_SET ;
}
break ;
case SET_SNR_THR_PEER :
if ( argc ! = 1 & & argc ! = 3 ) {
printf ( " ERR: wrong arguments. \n " ) ;
print_tx_bf_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc = = 1 ) {
param . bf_cmd_action = BF_CFG_ACT_GET ;
param . action = ACTION_GET ;
} else {
if ( ( ret =
mac2raw ( argv [ 1 ] ,
param . body . bf_snr [ 0 ] . peer_mac ) ) ! =
UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " ,
ret = =
UAP_FAILURE ? " Invalid MAC " : ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " :
" Multicast " ) ;
return UAP_FAILURE ;
}
if ( IS_HEX_OR_DIGIT ( argv [ 2 ] ) = = UAP_FAILURE )
return UAP_FAILURE ;
param . body . bf_snr [ 0 ] . snr = ( t_u8 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
param . bf_cmd_action = BF_CFG_ACT_SET ;
param . action = ACTION_SET ;
}
break ;
default :
return UAP_FAILURE ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: TX BF configuration failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
printf ( " TX BF configuration successful \n " ) ;
/* Handle response */
if ( param . action = = ACTION_GET )
print_tx_bf_response ( & param ) ;
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for hscfg command
*
* $ return N / A
*/
void
print_hscfg_usage ( void )
{
printf ( " \n Usage : hscfg [condition [[GPIO# [gap]]]] " ) ;
printf ( " \n Options: condition : bit 0 = 1 -- broadcast data " ) ;
printf ( " \n bit 1 = 1 -- unicast data " ) ;
printf ( " \n bit 2 = 1 -- mac event " ) ;
printf ( " \n bit 3 = 1 -- multicast packet " ) ;
printf ( " \n bit 6 = 1 -- mgmt frame received " ) ;
printf ( " \n GPIO: the pin number (e.g. 0-7) of GPIO used to wakeup the host " ) ;
printf ( " \n or 0xff interface (e.g. SDIO) used to wakeup the host " ) ;
printf ( " \n gap: time between wakeup signal and wakeup event (in milliseconds) " ) ;
printf ( " \n or 0xff for special setting when GPIO is used to wakeup host " ) ;
printf ( " \n empty - get current host sleep parameters \n " ) ;
return ;
}
/**
* @ brief Creates host sleep parameter request and send to driver
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_hscfg ( int argc , char * argv [ ] )
{
int opt ;
int i = 0 ;
ds_hs_cfg hscfg ;
struct ifreq ifr ;
t_s32 sockfd ;
if ( ( argc = = 2 ) & & strstr ( argv [ 1 ] , " -1 " ) )
strcpy ( argv [ 1 ] , " 0xffff " ) ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_hscfg_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & hscfg , 0 , sizeof ( hscfg ) ) ;
hscfg . subcmd = UAP_HS_CFG ;
/* Check arguments */
if ( argc > 3 ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_hscfg_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc ) {
for ( i = 0 ; i < argc ; i + + ) {
if ( IS_HEX_OR_DIGIT ( argv [ i ] ) = = UAP_FAILURE ) {
printf ( " ERR: Invalid argument %s \n " , argv [ i ] ) ;
print_hscfg_usage ( ) ;
return UAP_FAILURE ;
}
}
}
if ( argc ) {
hscfg . flags | = HS_CFG_FLAG_SET | HS_CFG_FLAG_CONDITION ;
hscfg . conditions = ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
if ( hscfg . conditions > = 0xffff )
hscfg . conditions = HS_CFG_CANCEL ;
if ( ( hscfg . conditions ! = HS_CFG_CANCEL ) & &
( hscfg . conditions & ~ HS_CFG_CONDITION_MASK ) ) {
printf ( " ERR:Illegal conditions 0x%x \n " ,
hscfg . conditions ) ;
print_hscfg_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc > 1 ) {
hscfg . flags | = HS_CFG_FLAG_GPIO ;
hscfg . gpio = ( t_u32 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
if ( hscfg . gpio > 255 ) {
printf ( " ERR:Illegal gpio 0x%x \n " , hscfg . gpio ) ;
print_hscfg_usage ( ) ;
return UAP_FAILURE ;
}
}
if ( argc > 2 ) {
hscfg . flags | = HS_CFG_FLAG_GAP ;
hscfg . gap = ( t_u32 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
}
} else {
hscfg . flags = HS_CFG_FLAG_GET ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & hscfg ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:UAP_HS_CFG failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( ! argc ) {
printf ( " Host sleep parameters: \n " ) ;
printf ( " \t conditions=%d \n " , ( int ) hscfg . conditions ) ;
printf ( " \t GPIO=%d \n " , ( int ) hscfg . gpio ) ;
printf ( " \t gap=%d \n " , ( int ) hscfg . gap ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for hssetpara command
*
* $ return N / A
*/
void
print_hssetpara_usage ( void )
{
printf ( " \n Usage : hssetpara condition [[GPIO# [gap]]] " ) ;
printf ( " \n Options: condition : bit 0 = 1 -- broadcast data " ) ;
printf ( " \n bit 1 = 1 -- unicast data " ) ;
printf ( " \n bit 2 = 1 -- mac event " ) ;
printf ( " \n bit 3 = 1 -- multicast packet " ) ;
printf ( " \n bit 6 = 1 -- mgmt frame received " ) ;
printf ( " \n GPIO: the pin number (e.g. 0-7) of GPIO used to wakeup the host " ) ;
printf ( " \n or 0xff interface (e.g. SDIO) used to wakeup the host " ) ;
printf ( " \n gap: time between wakeup signal and wakeup event (in milliseconds) " ) ;
printf ( " \n or 0xff for special setting when GPIO is used to wakeup host \n " ) ;
return ;
}
/**
* @ brief Creates host sleep parameter request and send to driver
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_hssetpara ( int argc , char * argv [ ] )
{
int opt ;
int i = 0 ;
ds_hs_cfg hscfg ;
struct ifreq ifr ;
t_s32 sockfd ;
if ( ( argc = = 2 ) & & strstr ( argv [ 1 ] , " -1 " ) )
strcpy ( argv [ 1 ] , " 0xffff " ) ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_hssetpara_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & hscfg , 0 , sizeof ( hscfg ) ) ;
hscfg . subcmd = UAP_HS_SET_PARA ;
/* Check arguments */
if ( ( argc < 1 ) | | ( argc > 3 ) ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_hssetpara_usage ( ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < argc ; i + + ) {
if ( IS_HEX_OR_DIGIT ( argv [ i ] ) = = UAP_FAILURE ) {
printf ( " ERR: Invalid argument %s \n " , argv [ i ] ) ;
print_hssetpara_usage ( ) ;
return UAP_FAILURE ;
}
}
hscfg . flags | = HS_CFG_FLAG_SET | HS_CFG_FLAG_CONDITION ;
hscfg . conditions = ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
if ( hscfg . conditions > = 0xffff )
hscfg . conditions = HS_CFG_CANCEL ;
if ( ( hscfg . conditions ! = HS_CFG_CANCEL ) & &
( hscfg . conditions & ~ HS_CFG_CONDITION_MASK ) ) {
printf ( " ERR:Illegal conditions 0x%x \n " , hscfg . conditions ) ;
print_hssetpara_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc > 1 ) {
hscfg . flags | = HS_CFG_FLAG_GPIO ;
hscfg . gpio = ( t_u32 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
if ( hscfg . gpio > 255 ) {
printf ( " ERR:Illegal gpio 0x%x \n " , hscfg . gpio ) ;
print_hssetpara_usage ( ) ;
return UAP_FAILURE ;
}
}
if ( argc > 2 ) {
hscfg . flags | = HS_CFG_FLAG_GAP ;
hscfg . gap = ( t_u32 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , strlen ( dev_name ) ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & hscfg ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:UAP_HS_SET_PARA failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
printf ( " Host sleep parameters setting successful! \n " ) ;
printf ( " \t conditions=%d \n " , ( int ) hscfg . conditions ) ;
printf ( " \t GPIO=%d \n " , ( int ) hscfg . gpio ) ;
printf ( " \t gap=%d \n " , ( int ) hscfg . gap ) ;
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief get dfs repeater mode
*
* @ param mode status of DFS repeater mode is returned here
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
uap_ioctl_dfs_repeater_mode ( int * mode )
{
struct ifreq ifr ;
dfs_repeater_mode param ;
t_s32 sockfd ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
param . action = ACTION_GET ;
param . subcmd = UAP_DFS_REPEATER_MODE ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
printf ( " ERR:UAP_DFS_REPEATER_MODE is not "
" supported by %s \n " , dev_name ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
* mode = ( int ) param . mode ;
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Get CAC timer status
*
* @ param mode status of CAC timer is returned here
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
uap_ioctl_cac_timer_status ( unsigned int * mode )
{
struct ifreq ifr ;
cac_timer_status param ;
t_s32 sockfd ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
param . action = ACTION_GET ;
param . subcmd = UAP_CAC_TIMER_STATUS ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
printf ( " ERR:UAP_CAC_TIMER_STATUS is not "
" supported by %s \n " , dev_name ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
* mode = ( int ) param . mode ;
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Set / get power mode
*
* @ param pm A pointer to ps_mgmt structure
* @ param flag flag for query
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
send_power_mode_ioctl ( ps_mgmt * pm , int flag )
{
struct ifreq ifr ;
t_s32 sockfd ;
t_u32 result = 0 ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) pm ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_POWER_MODE , & ifr ) ) {
memcpy ( ( void * ) & result , ( void * ) pm , sizeof ( result ) ) ;
if ( result = = 1 ) {
printf ( " ERR:Power mode needs to be disabled before modifying it \n " ) ;
} else {
perror ( " " ) ;
printf ( " ERR:UAP_POWER_MODE is not supported by %s \n " ,
dev_name ) ;
}
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( flag ) {
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
switch ( pm - > ps_mode ) {
case 0 :
printf ( " power mode = Disabled \n " ) ;
break ;
case 1 :
printf ( " power mode = Periodic DTIM PS \n " ) ;
break ;
case 2 :
printf ( " power mode = Inactivity based PS \n " ) ;
break ;
}
if ( pm - > flags & PS_FLAG_SLEEP_PARAM ) {
printf ( " Sleep param: \n " ) ;
printf ( " \t ctrl_bitmap=%d \n " , ( int ) pm - > sleep_param . ctrl_bitmap ) ;
printf ( " \t min_sleep=%d us \n " , ( int ) pm - > sleep_param . min_sleep ) ;
printf ( " \t max_sleep=%d us \n " , ( int ) pm - > sleep_param . max_sleep ) ;
}
if ( pm - > flags & PS_FLAG_INACT_SLEEP_PARAM ) {
printf ( " Inactivity sleep param: \n " ) ;
printf ( " \t inactivity_to=%d us \n " ,
( int ) pm - > inact_param . inactivity_to ) ;
printf ( " \t min_awake=%d us \n " , ( int ) pm - > inact_param . min_awake ) ;
printf ( " \t max_awake=%d us \n " , ( int ) pm - > inact_param . max_awake ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the pscfg command
*
* $ return N / A
*/
void
print_pscfg_usage ( void )
{
printf ( " \n Usage : pscfg [MODE] [CTRL INACTTO MIN_SLEEP MAX_SLEEP MIN_AWAKE MAX_AWAKE] " ) ;
printf ( " \n Options: MODE : 0 - disable power mode " ) ;
printf ( " \n 1 - periodic DTIM power save mode " ) ;
printf ( " \n 2 - inactivity based power save mode " ) ;
printf ( " \n PS PARAMS: " ) ;
printf ( " \n CTRL: 0 - disable protection frame Tx before PS " ) ;
printf ( " \n 1 - enable protection frame Tx before PS " ) ;
printf ( " \n INACTTO: Inactivity timeout in miroseconds " ) ;
printf ( " \n MIN_SLEEP: Minimum sleep duration in microseconds " ) ;
printf ( " \n MAX_SLEEP: Maximum sleep duration in miroseconds " ) ;
printf ( " \n MIN_AWAKE: Minimum awake duration in microseconds " ) ;
printf ( " \n MAX_AWAKE: Maximum awake duration in microseconds " ) ;
printf ( " \n MIN_AWAKE,MAX_AWAKE only valid for inactivity based power save mode " ) ;
printf ( " \n empty - get current power mode \n " ) ;
return ;
}
/**
* @ brief Creates power mode request and send to driver
* and sends to the driver
*
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_pscfg ( int argc , char * argv [ ] )
{
int opt ;
ps_mgmt pm ;
int ret = UAP_SUCCESS ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_pscfg_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & pm , 0 , sizeof ( ps_mgmt ) ) ;
/* Check arguments */
if ( ( argc > 7 ) | |
( ( argc ! = 0 ) & & ( argc ! = 1 ) & & ( argc ! = 5 ) & & ( argc ! = 7 ) ) ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_pscfg_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc ) {
if ( send_power_mode_ioctl ( & pm , 1 ) = = UAP_FAILURE )
return UAP_FAILURE ;
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > 2 ) ) {
printf ( " ERR:Illegal power mode %s. Must be either '0' '1' or '2'. \n " , argv [ 0 ] ) ;
print_pscfg_usage ( ) ;
return UAP_FAILURE ;
}
pm . flags = PS_FLAG_PS_MODE ;
pm . ps_mode = atoi ( argv [ 0 ] ) ;
if ( ( pm . ps_mode = = PS_MODE_DISABLE ) & & ( argc > 1 ) ) {
printf ( " ERR: Illegal parameter for disable power mode \n " ) ;
print_pscfg_usage ( ) ;
return UAP_FAILURE ;
}
if ( ( pm . ps_mode ! = PS_MODE_INACTIVITY ) & & ( argc > 5 ) ) {
printf ( " ERR:Min awake period and Max awake period are valid only for inactivity based power save mode \n " ) ;
print_pscfg_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc > = 5 ) {
if ( ( ISDIGIT ( argv [ 1 ] ) = = 0 ) | | ( atoi ( argv [ 1 ] ) < 0 ) | |
( atoi ( argv [ 1 ] ) > 1 ) ) {
printf ( " ERR:Illegal ctrl bitmap = %s. Must be either '0' or '1'. \n " , argv [ 1 ] ) ;
print_pscfg_usage ( ) ;
return UAP_FAILURE ;
}
pm . flags | =
PS_FLAG_SLEEP_PARAM | PS_FLAG_INACT_SLEEP_PARAM ;
pm . sleep_param . ctrl_bitmap = atoi ( argv [ 1 ] ) ;
if ( ( ISDIGIT ( argv [ 2 ] ) = = 0 ) | | ( ISDIGIT ( argv [ 3 ] ) = = 0 )
| | ( ISDIGIT ( argv [ 4 ] ) = = 0 ) ) {
printf ( " ERR:Illegal parameter \n " ) ;
print_pscfg_usage ( ) ;
return UAP_FAILURE ;
}
pm . inact_param . inactivity_to = atoi ( argv [ 2 ] ) ;
pm . sleep_param . min_sleep = atoi ( argv [ 3 ] ) ;
pm . sleep_param . max_sleep = atoi ( argv [ 4 ] ) ;
if ( pm . sleep_param . min_sleep > pm . sleep_param . max_sleep ) {
printf ( " ERR: MIN_SLEEP value should be less than or equal to MAX_SLEEP \n " ) ;
return UAP_FAILURE ;
}
if ( pm . sleep_param . min_sleep < PS_SLEEP_PARAM_MIN | |
( ( pm . sleep_param . max_sleep > PS_SLEEP_PARAM_MAX ) & &
pm . sleep_param . ctrl_bitmap ) ) {
printf ( " ERR: Incorrect value of sleep period. Please check README \n " ) ;
return UAP_FAILURE ;
}
if ( argc = = 7 ) {
if ( ( ISDIGIT ( argv [ 5 ] ) = = 0 ) | |
( ISDIGIT ( argv [ 6 ] ) = = 0 ) ) {
printf ( " ERR:Illegal parameter \n " ) ;
print_pscfg_usage ( ) ;
return UAP_FAILURE ;
}
pm . inact_param . min_awake = atoi ( argv [ 5 ] ) ;
pm . inact_param . max_awake = atoi ( argv [ 6 ] ) ;
if ( pm . inact_param . min_awake >
pm . inact_param . max_awake ) {
printf ( " ERR: MIN_AWAKE value should be less than or equal to MAX_AWAKE \n " ) ;
return UAP_FAILURE ;
}
if ( pm . inact_param . min_awake <
PS_AWAKE_PERIOD_MIN ) {
printf ( " ERR: Incorrect value of MIN_AWAKE period. \n " ) ;
return UAP_FAILURE ;
}
}
}
}
ret = send_power_mode_ioctl ( & pm , 0 ) ;
return ret ;
}
/**
* @ brief Get bss status started / stopped
*
* @ param current bss status
* @ return UAP_SUCCESS / UAP_FAILURE
*/
static int
get_bss_status ( int * status )
{
apcmdbuf_sys_configure * cmd_buf = NULL ;
tlvbuf_bss_status * tlv = NULL ;
t_u8 * buffer = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_FAILURE ;
/* Initialize the command length */
cmd_len = sizeof ( apcmdbuf_sys_configure ) + sizeof ( tlvbuf_bss_status ) ;
/* Initialize the command buffer */
buffer = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buffer , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_bss_status * ) ( buffer + sizeof ( apcmdbuf_sys_configure ) ) ;
/* Fill the command buffer */
cmd_buf - > cmd_code = APCMD_SYS_CONFIGURE ;
cmd_buf - > size = cmd_len ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
tlv - > tag = MRVL_BSS_STATUS_TLV_ID ;
tlv - > length = 2 ;
cmd_buf - > action = ACTION_GET ;
endian_convert_tlv_header_out ( tlv ) ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
endian_convert_tlv_header_in ( tlv ) ;
tlv - > bss_status = uap_le16_to_cpu ( tlv - > bss_status ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( ( cmd_buf - > cmd_code ! =
( APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK ) ) | |
( tlv - > tag ! = MRVL_BSS_STATUS_TLV_ID ) ) {
printf ( " ERR:Corrupted response! cmd_code=%x, Tlv->tag=%x \n " , cmd_buf - > cmd_code , tlv - > tag ) ;
free ( buffer ) ;
return UAP_FAILURE ;
}
/* Print response */
if ( cmd_buf - > result = = CMD_SUCCESS ) {
if ( tlv - > bss_status = = 0 )
* status = UAP_BSS_STOP ;
else
* status = UAP_BSS_START ;
} else {
printf ( " ERR:Could not get BSS status! \n " ) ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
if ( buffer )
free ( buffer ) ;
return ret ;
}
/**
* @ brief start / stop / reset bss
*
* @ param mode bss control mode
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
send_bss_ctl_ioctl ( int mode )
{
struct ifreq ifr ;
t_s32 sockfd ;
t_u32 data = ( t_u32 ) mode ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & data ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_BSS_CTRL , & ifr ) ) {
printf ( " ERR:UAP_BSS_CTRL fail, result=%d \n " , ( int ) data ) ;
switch ( mode ) {
case UAP_BSS_START :
if ( data = = BSS_FAILURE_START_INVAL )
printf ( " ERR:Could not start BSS! Invalid BSS parameters. \n " ) ;
else
printf ( " ERR:Could not start BSS! \n " ) ;
break ;
case UAP_BSS_STOP :
printf ( " ERR:Could not stop BSS! \n " ) ;
break ;
case UAP_BSS_RESET :
printf ( " ERR:Could not reset system! \n " ) ;
break ;
}
close ( sockfd ) ;
return UAP_FAILURE ;
}
switch ( mode ) {
case UAP_BSS_START :
printf ( " BSS start successful! \n " ) ;
break ;
case UAP_BSS_STOP :
printf ( " BSS stop successful! \n " ) ;
break ;
case UAP_BSS_RESET :
printf ( " System reset successful! \n " ) ;
break ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the sys_reset command
*
* $ return N / A
*/
void
print_sys_reset_usage ( void )
{
printf ( " \n Usage : sys_reset \n " ) ;
return ;
}
/**
* @ brief Creates a sys_reset request and sends to the driver
*
* Usage : " sys_reset "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_sys_reset ( int argc , char * argv [ ] )
{
int opt ;
int ret = UAP_SUCCESS ;
ps_mgmt pm ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_sys_reset_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc ! = 0 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_sys_reset_usage ( ) ;
return UAP_FAILURE ;
}
memset ( & pm , 0 , sizeof ( ps_mgmt ) ) ;
pm . flags = PS_FLAG_PS_MODE ;
pm . ps_mode = PS_MODE_DISABLE ;
if ( send_power_mode_ioctl ( & pm , 0 ) = = UAP_FAILURE )
return UAP_FAILURE ;
ret = send_bss_ctl_ioctl ( UAP_BSS_RESET ) ;
return ret ;
}
/**
* @ brief Show usage information for the bss_start command
*
* $ return N / A
*/
void
print_bss_start_usage ( void )
{
printf ( " \n Usage : bss_start \n " ) ;
return ;
}
/**
* @ brief Creates a BSS start request and sends to the driver
*
* Usage : " bss_start "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_bss_start ( int argc , char * argv [ ] )
{
int opt ;
t_u8 * buf = NULL ;
t_u16 buf_len = 0 ;
int status = 0 ;
int ret = UAP_SUCCESS ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_bss_start_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc ! = 0 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_bss_start_usage ( ) ;
return UAP_FAILURE ;
}
if ( get_bss_status ( & status ) ! = UAP_SUCCESS ) {
printf ( " ERR:Cannot get current bss status! \n " ) ;
return UAP_FAILURE ;
}
if ( status = = UAP_BSS_START ) {
printf ( " ERR: Could not start BSS! BSS already started! \n " ) ;
return UAP_FAILURE ;
}
/* Query BSS settings */
/* Alloc buf for command */
buf_len = sizeof ( apcmdbuf_bss_configure ) + sizeof ( bss_config_t ) ;
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( ( char * ) buf , 0 , buf_len ) ;
/* Get all parametes first */
if ( get_bss_config ( buf ) = = UAP_FAILURE ) {
printf ( " ERR:Reading current bss configuration \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
ret = check_bss_config ( buf + sizeof ( apcmdbuf_bss_configure ) ) ;
if ( ret = = UAP_FAILURE ) {
printf ( " ERR: Wrong bss configuration! \n " ) ;
goto done ;
}
ret = send_bss_ctl_ioctl ( UAP_BSS_START ) ;
done :
if ( buf )
free ( buf ) ;
return ret ;
}
/**
* @ brief Show usage information for the bss_stop command
*
* $ return N / A
*/
void
print_bss_stop_usage ( void )
{
printf ( " \n Usage : bss_stop \n " ) ;
return ;
}
/**
* @ brief Creates a BSS stop request and sends to the driver
*
* Usage : " bss_stop "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_bss_stop ( int argc , char * argv [ ] )
{
int opt ;
int status = 0 ;
int ret = UAP_SUCCESS ;
unsigned int cac_timer = 0 ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_bss_stop_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ; /* Check arguments */
if ( argc ! = 0 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_bss_stop_usage ( ) ;
return UAP_FAILURE ;
}
if ( get_bss_status ( & status ) ! = UAP_SUCCESS ) {
printf ( " ERR:Cannot get current bss status! \n " ) ;
return UAP_FAILURE ;
}
if ( ( status ! = UAP_BSS_STOP )
| | ( ( uap_ioctl_cac_timer_status ( & cac_timer ) = = UAP_SUCCESS )
& & ( cac_timer ) )
)
ret = send_bss_ctl_ioctl ( UAP_BSS_STOP ) ;
else {
printf ( " ERR: Could not stop BSS! BSS already stopped! \n " ) ;
ret = UAP_FAILURE ;
}
return ret ;
}
void
print_skip_cac_usage ( void )
{
printf ( " \n Usage : skip_cac [MODE] " ) ;
printf ( " \n Options: MODE : 0 - Disable skip CAC mode " ) ;
printf ( " \n 1 - Enable skip CAC mode " ) ;
printf ( " \n empty - get skip CAC mode \n " ) ;
return ;
}
/**
* @ brief Skip CAC for next immediate BSS_START
*
* Usage : " skip_cac [1/0] "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_skip_cac ( int argc , char * argv [ ] )
{
int opt ;
skip_cac_para param ;
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_skip_cac_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & param , 0 , sizeof ( param ) ) ;
/* Check arguments */
if ( argc > 1 ) {
printf ( " ERR:wrong arguments. Only support 1 argument \n " ) ;
print_skip_cac_usage ( ) ;
return UAP_FAILURE ;
}
param . subcmd = UAP_SKIP_CAC ;
if ( argc ) {
if ( argc = = 1 ) {
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) | |
( ( atoi ( argv [ 0 ] ) < 0 ) | | ( atoi ( argv [ 0 ] ) > 1 ) ) ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_skip_cac_usage ( ) ;
return UAP_FAILURE ;
}
}
param . action = 1 ;
param . skip_cac = ( t_u16 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
} else {
param . action = 0 ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
if ( argc )
printf ( " ERR:skip_cac set failed \n " ) ;
else {
perror ( " " ) ;
printf ( " ERR:skip_cac get failed \n " ) ;
}
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( ! argc ) {
if ( param . skip_cac = = 1 ) {
printf ( " skip CAC mode: enabled \n " ) ;
} else {
printf ( " skip CAC mode: disabled \n " ) ;
}
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the sta_list command
*
* $ return N / A
*/
void
print_sta_list_usage ( void )
{
printf ( " \n Usage : sta_list \n " ) ;
return ;
}
/**
* @ brief Creates a STA list request and sends to the driver
*
* Usage : " sta_list "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_sta_list ( int argc , char * argv [ ] )
{
struct ifreq ifr ;
t_s32 sockfd ;
sta_list list ;
int i = 0 ;
int opt ;
int rssi = 0 ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_sta_list_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc ! = 0 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_sta_list_usage ( ) ;
return UAP_FAILURE ;
}
memset ( & list , 0 , sizeof ( sta_list ) ) ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & list ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_GET_STA_LIST , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:UAP_GET_STA_LIST is not supported by %s \n " ,
dev_name ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
printf ( " Number of STA = %d \n \n " , list . sta_count ) ;
for ( i = 0 ; i < list . sta_count ; i + + ) {
printf ( " STA %d information: \n " , i + 1 ) ;
printf ( " ===================== \n " ) ;
printf ( " MAC Address: " ) ;
print_mac ( list . info [ i ] . mac_address ) ;
printf ( " \n Power mgmt status: %s \n " ,
( list . info [ i ] . power_mgmt_status = =
0 ) ? " active " : " power save " ) ;
printf ( " Mode: %s \n " ,
( list . info [ i ] . bandmode = =
BAND_B ) ? " 11b, " : ( list . info [ i ] . bandmode = =
BAND_G ) ? " 11g, " : ( list . info [ i ] .
bandmode = =
BAND_A ) ? " 11a, "
: ( list . info [ i ] . bandmode = =
BAND_GN ) ? " 2.4G_11n, " : ( list . info [ i ] . bandmode = =
BAND_AN ) ? " 5G_11n, "
: ( list . info [ i ] . bandmode = =
BAND_GAC ) ? " 2.4G_11ac, " : ( list . info [ i ] . bandmode = =
BAND_AAC ) ? " 5G_11ac, "
: ( list . info [ i ] . bandmode = =
BAND_GAX ) ? " 2.4G_11ax, " : ( list . info [ i ] . bandmode = =
BAND_AAX ) ? " 5G_11ax, " :
" unknown " ) ;
/** On some platform, s8 is same as unsigned char*/
rssi = ( int ) list . info [ i ] . rssi ;
if ( rssi > 0x7f )
rssi = - ( 256 - rssi ) ;
printf ( " Rssi : %d dBm \n \n " , rssi ) ;
if ( list . info [ i ] . ie_len )
hexdump_data ( " IE " , ( void * ) list . info [ i ] . ie_buf ,
list . info [ i ] . ie_len , ' ' ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the sta_deauth command
*
* $ return N / A
*/
void
print_sta_deauth_usage ( void )
{
printf ( " \n Usage : sta_deauth <STA_MAC_ADDRESS> \n " ) ;
return ;
}
/**
* @ brief Creates a STA deauth request and sends to the driver
*
* Usage : " sta_deauth <STA_MAC_ADDRESS> "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_sta_deauth ( int argc , char * argv [ ] )
{
APCMDBUF_STA_DEAUTH * cmd_buf = NULL ;
t_u8 * buffer = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_FAILURE ;
int opt ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_sta_deauth_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc ! = 1 ) {
printf ( " ERR:wrong arguments! Must provide STA_MAC_ADDRESS. \n " ) ;
print_sta_deauth_usage ( ) ;
return UAP_FAILURE ;
}
/* Initialize the command length */
cmd_len = sizeof ( APCMDBUF_STA_DEAUTH ) ;
/* Initialize the command buffer */
buffer = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buffer , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( APCMDBUF_STA_DEAUTH * ) buffer ;
/* Fill the command buffer */
cmd_buf - > cmd_code = APCMD_STA_DEAUTH ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
if ( ( ret = mac2raw ( argv [ 0 ] , cmd_buf - > sta_mac_address ) ) ! = UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " , ret = = UAP_FAILURE ? " Invalid MAC " :
ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " : " Multicast " ) ;
free ( buffer ) ;
return UAP_FAILURE ;
}
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( cmd_buf - > cmd_code ! = ( APCMD_STA_DEAUTH | APCMD_RESP_CHECK ) ) {
printf ( " ERR:Corrupted response! \n " ) ;
free ( buffer ) ;
return UAP_FAILURE ;
}
/* Print response */
if ( cmd_buf - > result = = CMD_SUCCESS ) {
printf ( " Deauthentication successful! \n " ) ;
} else {
printf ( " ERR:Deauthentication unsuccessful! \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
if ( buffer )
free ( buffer ) ;
return ret ;
}
/**
* @ brief Show usage information for the sta_deauth_ext command
*
* $ return N / A
*/
void
print_sta_deauth_ext_usage ( void )
{
printf ( " \n Usage : sta_deauth <STA_MAC_ADDRESS> <REASCON_CODE> \n " ) ;
return ;
}
/**
* @ brief Creates a STA deauth request and sends to the driver
*
* Usage : " sta_deauth <STA_MAC_ADDRESS><REASON_CODE> "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_sta_deauth_ext ( int argc , char * argv [ ] )
{
int ret = UAP_SUCCESS ;
int opt ;
deauth_param param ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u32 result = 0 ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_sta_deauth_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc ! = 2 ) {
printf ( " ERR:wrong arguments! Must provide STA_MAC_ADDRESS, REASON_CODE. \n " ) ;
print_sta_deauth_ext_usage ( ) ;
return UAP_FAILURE ;
}
memset ( & param , 0 , sizeof ( deauth_param ) ) ;
if ( ( ret = mac2raw ( argv [ 0 ] , param . mac_addr ) ) ! = UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " , ret = = UAP_FAILURE ? " Invalid MAC " :
ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " : " Multicast " ) ;
return UAP_FAILURE ;
}
if ( ( IS_HEX_OR_DIGIT ( argv [ 1 ] ) = = UAP_FAILURE ) | |
( atoi ( argv [ 1 ] ) > MAX_DEAUTH_REASON_CODE ) ) {
printf ( " ERR: Invalid input for reason code \n " ) ;
return UAP_FAILURE ;
}
param . reason_code = ( t_u16 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_STA_DEAUTH , & ifr ) ) {
memcpy ( ( void * ) & result , ( void * ) & param , sizeof ( result ) ) ;
if ( result = = 1 )
printf ( " ERR:UAP_STA_DEAUTH fail \n " ) ;
else
perror ( " " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
printf ( " Station deauth successful \n " ) ;
/* Close socket */
close ( sockfd ) ;
return ret ;
}
/**
* @ brief Show usage information for the radioctrl command
*
* $ return N / A
*/
void
print_radio_ctl_usage ( void )
{
printf ( " \n Usage : radioctrl [ 0 | 1 ] \n " ) ;
return ;
}
/**
* @ brief Creates a Radio control request and sends to the driver
*
* Usage : " radioctrl [0 | 1] "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_radio_ctl ( int argc , char * argv [ ] )
{
int opt ;
int param [ 2 ] = { 0 , 0 } ; /* action (Set/Get), Control (ON/OFF) */
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_radio_ctl_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc > 1 ) {
printf ( " ERR:wrong arguments! Only 1 or 0 arguments are supported. \n " ) ;
print_radio_ctl_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc & & ( is_input_valid ( RADIOCONTROL , argc , argv ) ! = UAP_SUCCESS ) ) {
print_radio_ctl_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc ) {
param [ 0 ] = ACTION_SET ;
param [ 1 ] = atoi ( argv [ 0 ] ) ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_RADIO_CTL , & ifr ) ) {
printf ( " ERR:UAP_RADIO_CTL fail \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( argc )
printf ( " Radio setting successful \n " ) ;
else
printf ( " Radio is %s. \n " , ( param [ 1 ] ) ? " on " : " off " ) ;
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the txratecfg command
*
* $ return N / A
*/
void
print_txratecfg_usage ( void )
{
printf ( " \n Usage : txratecfg <datarate index> Index should be one of the following. \n " ) ;
printf ( " \n [l] is <format> " ) ;
printf ( " \n <format> - This parameter specifies the data rate format used in this command " ) ;
printf ( " \n 0: LG " ) ;
printf ( " \n 1: HT " ) ;
printf ( " \n 2: VHT " ) ;
printf ( " \n 3: HE " ) ;
printf ( " \n 0xff: Auto " ) ;
printf ( " \n " ) ;
printf ( " \n [m] is <index> " ) ;
printf ( " \n <index> - This parameter specifies the rate or MCS index " ) ;
printf ( " \n If <format> is 0 (LG), " ) ;
printf ( " \n 0 1 Mbps " ) ;
printf ( " \n 1 2 Mbps " ) ;
printf ( " \n 2 5.5 Mbps " ) ;
printf ( " \n 3 11 Mbps " ) ;
printf ( " \n 4 6 Mbps " ) ;
printf ( " \n 5 9 Mbps " ) ;
printf ( " \n 6 12 Mbps " ) ;
printf ( " \n 7 18 Mbps " ) ;
printf ( " \n 8 24 Mbps " ) ;
printf ( " \n 9 36 Mbps " ) ;
printf ( " \n 10 48 Mbps " ) ;
printf ( " \n 11 54 Mbps " ) ;
printf ( " \n If <format> is 1 (HT), " ) ;
printf ( " \n 0 MCS0 " ) ;
printf ( " \n 1 MCS1 " ) ;
printf ( " \n 2 MCS2 " ) ;
printf ( " \n 3 MCS3 " ) ;
printf ( " \n 4 MCS4 " ) ;
printf ( " \n 5 MCS5 " ) ;
printf ( " \n 6 MCS6 " ) ;
printf ( " \n 7 MCS7 " ) ;
printf ( " \n 8 MCS8 " ) ;
printf ( " \n 9 MCS9 " ) ;
printf ( " \n 10 MCS10 " ) ;
printf ( " \n 11 MCS11 " ) ;
printf ( " \n 12 MCS12 " ) ;
printf ( " \n 13 MCS13 " ) ;
printf ( " \n 14 MCS14 " ) ;
printf ( " \n 15 MCS15 " ) ;
printf ( " \n 32 MCS32 " ) ;
printf ( " \n If <format> is 2 (VHT), " ) ;
printf ( " \n 0 MCS0 " ) ;
printf ( " \n 1 MCS1 " ) ;
printf ( " \n 2 MCS2 " ) ;
printf ( " \n 3 MCS3 " ) ;
printf ( " \n 4 MCS4 " ) ;
printf ( " \n 5 MCS5 " ) ;
printf ( " \n 6 MCS6 " ) ;
printf ( " \n 7 MCS7 " ) ;
printf ( " \n 8 MCS8 " ) ;
printf ( " \n 9 MCS9 " ) ;
printf ( " \n [n] is <nss> " ) ;
printf ( " \n <nss> - This parameter specifies the NSS. It is valid only for VHT " ) ;
printf ( " \n If <format> is 2 (VHT), " ) ;
printf ( " \n 1 NSS1 " ) ;
printf ( " \n 2 NSS2 " ) ;
printf ( " \n If <format> is 3 (HE), " ) ;
printf ( " \n 0 MCS0 " ) ;
printf ( " \n 1 MCS1 " ) ;
printf ( " \n 2 MCS2 " ) ;
printf ( " \n 3 MCS3 " ) ;
printf ( " \n 4 MCS4 " ) ;
printf ( " \n 5 MCS5 " ) ;
printf ( " \n 6 MCS6 " ) ;
printf ( " \n 7 MCS7 " ) ;
printf ( " \n 8 MCS8 " ) ;
printf ( " \n 9 MCS9 " ) ;
printf ( " \n 10 MCS10 " ) ;
printf ( " \n 11 MCS11 " ) ;
printf ( " \n [n] is <nss> " ) ;
printf ( " \n <nss> - This parameter specifies the NSS. It is valid only for HE " ) ;
printf ( " \n If <format> is 3 (HE), " ) ;
printf ( " \n 1 NSS1 " ) ;
printf ( " \n 2 NSS2 " ) ;
printf ( " \n " ) ;
return ;
}
/**
* @ brief Creates a Tx Rate Config get request and sends to the driver
* @ param rate_config Tx rate config struct
* @ return UAP_SUCCESS / UAP_FAILURE
*/
static int
get_tx_rate_cfg ( tx_rate_cfg_t * rate_config )
{
struct ifreq ifr ;
t_s32 sockfd ;
int ret = UAP_SUCCESS ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( rate_config , 0 , sizeof ( tx_rate_cfg_t ) ) ;
rate_config - > subcmd = UAP_TX_RATE_CFG ;
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , strlen ( dev_name ) ) ;
ifr . ifr_ifru . ifru_data = ( void * ) rate_config ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
printf ( " ERR:UAP_IOCTL_CMD fail \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
/* Close socket */
close ( sockfd ) ;
return ret ;
}
static char * rate_format [ 4 ] = { " LG " , " HT " , " VHT " , " HE " } ;
static char * lg_rate [ ] = { " 1 Mbps " , " 2 Mbps " , " 5.5 Mbps " , " 11 Mbps " ,
" 6 Mbps " , " 9 Mbps " , " 12 Mbps " , " 18 Mbps " ,
" 24 Mbps " , " 36 Mbps " , " 48 Mbps " , " 54 Mbps "
} ;
/**
* @ brief Creates a Tx Rate Config request and sends to the driver
*
* Usage : " txratecfg <datarate> "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_tx_rate_cfg ( int argc , char * argv [ ] )
{
int opt ;
int status = 0 ;
tx_rate_cfg_t tx_rate_config ;
struct ifreq ifr ;
t_s32 sockfd ;
HTCap_t htcap ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_txratecfg_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc > 3 ) {
printf ( " ERR:wrong arguments! Only 0~3 arguments are supported. \n " ) ;
print_txratecfg_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc & & ( is_input_valid ( TXRATECFG , argc , argv ) ! = UAP_SUCCESS ) ) {
print_txratecfg_usage ( ) ;
return UAP_FAILURE ;
}
memset ( & tx_rate_config , 0 , sizeof ( tx_rate_cfg_t ) ) ;
tx_rate_config . subcmd = UAP_TX_RATE_CFG ;
if ( argc ) {
tx_rate_config . action = ACTION_SET ;
tx_rate_config . rate_format = A2HEXDECIMAL ( argv [ 0 ] ) ;
if ( argc > = 2 )
tx_rate_config . rate = A2HEXDECIMAL ( argv [ 1 ] ) ;
if ( argc > = 3 )
tx_rate_config . nss = A2HEXDECIMAL ( argv [ 2 ] ) ;
if ( argc = = 4 )
tx_rate_config . rate_setting = A2HEXDECIMAL ( argv [ 3 ] ) ;
tx_rate_config . user_data_cnt = argc ;
/* If bss is already started and uAP is in (short GI in 20 MHz + GF) mode, block MCS0-MCS7 rates */
if ( get_bss_status ( & status ) ! = UAP_SUCCESS ) {
printf ( " ERR:Cannot get current bss status! \n " ) ;
return UAP_FAILURE ;
}
if ( UAP_SUCCESS = = get_sys_cfg_11n ( & htcap ) ) {
if ( htcap . supported_mcs_set [ 0 ] & &
( status = = UAP_BSS_START ) ) {
if ( ( ( tx_rate_config . rate > = 0 ) & &
( tx_rate_config . rate < = 7 ) )
& &
( IS_11N_20MHZ_SHORTGI_ENABLED
( htcap . ht_cap_info ) & &
IS_11N_GF_ENABLED ( htcap . ht_cap_info ) ) ) {
printf ( " ERR: Invalid rate for bss in (20MHz Short GI + Green Field) mode \n " ) ;
return UAP_FAILURE ;
}
if ( ( tx_rate_config . rate = = 32 ) & &
( ! ( IS_11N_40MHZ_ENABLED
( htcap . ht_cap_info ) ) ) ) {
printf ( " ERR:uAP must be configured to operate in 40MHz if tx_rate is MCS32 \n " ) ;
return UAP_FAILURE ;
}
}
}
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , strlen ( dev_name ) ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & tx_rate_config ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
printf ( " ERR:UAP_IOCTL_CMD fail \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( argc ) {
printf ( " Transmit Rate setting successful \n " ) ;
} else {
/* GET operation */
printf ( " Tx Rate Configuration: \n " ) ;
/* format */
if ( tx_rate_config . rate_format = = 0xFF ) {
printf ( " Type: 0xFF (Auto) \n " ) ;
} else if ( tx_rate_config . rate_format < = 3 ) {
printf ( " Type: %d (%s) \n " ,
tx_rate_config . rate_format ,
rate_format [ tx_rate_config . rate_format ] ) ;
if ( tx_rate_config . rate_format = = 0 )
printf ( " Rate Index: %d (%s) \n " ,
tx_rate_config . rate ,
lg_rate [ tx_rate_config . rate ] ) ;
else if ( tx_rate_config . rate_format > = 1 )
printf ( " MCS Index: %d \n " ,
( int ) tx_rate_config . rate ) ;
if ( tx_rate_config . rate_format = = 2 | |
tx_rate_config . rate_format = = 3 )
printf ( " NSS: %d \n " ,
( int ) tx_rate_config . nss ) ;
if ( tx_rate_config . rate_setting = = 0xffff )
printf ( " Rate setting :Preamble type/BW/GI/STBC/.. : auto \n " ) ;
else {
printf ( " Preamble type: %x \n " ,
( tx_rate_config . rate_setting & 0x0003 ) ) ;
printf ( " BW: %x \n " ,
( tx_rate_config .
rate_setting & 0x001C ) > > 2 ) ;
printf ( " LTF + GI size %x \n " ,
( tx_rate_config .
rate_setting & 0x0060 ) > > 5 ) ;
printf ( " STBC %x \n " ,
( tx_rate_config .
rate_setting & 0x0080 ) > > 7 ) ;
printf ( " DCM %x \n " ,
( tx_rate_config .
rate_setting & 0x0100 ) > > 8 ) ;
printf ( " Coding %x \n " ,
( tx_rate_config .
rate_setting & 0x0200 ) > > 9 ) ;
printf ( " maxPE %x \n " ,
( tx_rate_config .
rate_setting & 0x3000 ) > > 12 ) ;
}
} else {
printf ( " Unknown rate format. \n " ) ;
}
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the antcfg
* command
*
* $ return N / A
*/
void
print_antcfg_usage ( void )
{
printf ( " \n Usage : antcfg [<TX_MODE> <RX_MODE>] \n " ) ;
printf ( " \n MODE : 1 - Antenna A " ) ;
printf ( " \n 2 - Antenna B " ) ;
printf ( " \n 3 - Antenna A+B " ) ;
printf ( " \n empty - Get current antenna settings \n " ) ;
return ;
}
/**
* @ brief Creates a RF Antenna Mode Config request and sends to the driver
*
* Usage : " antcfg [MODE] "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_antcfg ( int argc , char * argv [ ] )
{
int opt ;
int tx_val = 0 ;
int rx_val = 0 ;
ant_cfg_t antenna_config ;
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_antcfg_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc > 2 ) {
printf ( " ERR:wrong arguments! \n " ) ;
print_antcfg_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc ) {
sscanf ( argv [ 0 ] , " %x " , ( unsigned int * ) & tx_val ) ;
if ( tx_val < 1 | | tx_val > 0x303 ) {
printf ( " ERR:Illegal ANTENNA parameter %s. Must be either '1', '2' or '3'. \n " , argv [ 0 ] ) ;
print_antcfg_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc = = 2 ) {
sscanf ( argv [ 1 ] , " %x " , ( unsigned int * ) & rx_val ) ;
if ( rx_val < 1 | | rx_val > 0x303 ) {
printf ( " ERR:Illegal RX ANTENNA parameter %s. Must be either '1', '2' or '3'. \n " , argv [ 1 ] ) ;
print_antcfg_usage ( ) ;
return UAP_FAILURE ;
}
}
}
memset ( & antenna_config , 0 , sizeof ( ant_cfg_t ) ) ;
antenna_config . subcmd = UAP_ANTENNA_CFG ;
if ( argc ) {
antenna_config . action = ACTION_SET ;
if ( argc = = 1 ) {
antenna_config . tx_mode = tx_val ;
antenna_config . rx_mode = tx_val ;
} else {
antenna_config . tx_mode = tx_val ;
antenna_config . rx_mode = rx_val ;
}
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , strlen ( dev_name ) ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & antenna_config ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
printf ( " ERR:UAP_IOCTL_CMD fail \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( argc ) {
printf ( " Antenna mode setting successful \n " ) ;
} else {
printf ( " TX Antenna mode is 0x%x. \n " , antenna_config . tx_mode ) ;
printf ( " RX Antenna mode is 0x%x. \n " , antenna_config . rx_mode ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the htstreamcfg
* command
*
* $ return N / A
*/
void
print_htstreamcfg_usage ( void )
{
printf ( " \n Usage : htstreamcfg [<n>] \n " ) ;
printf ( " \n Where <n> " ) ;
printf ( " \n 0x11: HT stream 1x1 mode " ) ;
printf ( " \n 0x22: HT stream 2x2 mode \n " ) ;
return ;
}
/**
* @ brief Set / get HT stream configurations
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_htstreamcfg ( int argc , char * argv [ ] )
{
int opt ;
htstream_cfg_t htstream_cfg ;
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_htstreamcfg_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
memset ( & htstream_cfg , 0 , sizeof ( htstream_cfg ) ) ;
if ( argc = = 0 ) {
htstream_cfg . action = ACTION_GET ;
} else if ( argc = = 1 ) {
if ( ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ! = HT_STREAM_MODE_1X1
& & ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ! = HT_STREAM_MODE_2X2 ) {
printf ( " ERR:Invalid argument \n " ) ;
return UAP_FAILURE ;
}
htstream_cfg . action = ACTION_SET ;
htstream_cfg . stream_cfg = ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
} else {
print_htstreamcfg_usage ( ) ;
return UAP_FAILURE ;
}
htstream_cfg . subcmd = UAP_HT_STREAM_CFG ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & htstream_cfg ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: HT STREAM configuration failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
/* Handle response */
if ( htstream_cfg . action = = ACTION_GET ) {
if ( htstream_cfg . stream_cfg = = HT_STREAM_MODE_1X1 )
printf ( " HT stream is in 1x1 mode \n " ) ;
else if ( htstream_cfg . stream_cfg = = HT_STREAM_MODE_2X2 )
printf ( " HT stream is in 2x2 mode \n " ) ;
else
printf ( " HT stream is unknown mode \n " ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
static int
get_802_11ac_cfg ( struct eth_priv_vhtcfg * vhtcfg )
{
t_u8 * buf = NULL ;
t_u8 * pos = NULL ;
mrvl_priv_cmd * cmd = NULL ;
struct ifreq ifr ;
t_s32 sockfd ;
buf = ( t_u8 * ) malloc ( MRVDRV_SIZE_OF_CMD_BUFFER ) ;
if ( ! buf ) {
printf ( " ERR: cannot allocate buffer for command payload \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , MRVDRV_SIZE_OF_CMD_BUFFER ) ;
cmd = ( mrvl_priv_cmd * ) malloc ( sizeof ( mrvl_priv_cmd ) ) ;
if ( ! cmd ) {
printf ( " ERR: cannot allocate buffer for cmd \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
/*prepare command: mlanutl uap0 vhtcfg 2 3 , GET operation */
pos = buf ;
strncpy ( ( char * ) pos , CMD_NXP , strlen ( CMD_NXP ) ) ;
pos + = strlen ( CMD_NXP ) ;
strncpy ( ( char * ) pos , " vhtcfg2 3 " , strlen ( " vhtcfg2 3 " ) ) ;
/* fill up buffer */
cmd - > buf = buf ;
cmd - > used_len = 0 ;
cmd - > total_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
/* Perform IOCTL */
memset ( & ifr , 0 , sizeof ( struct ifreq ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , strlen ( dev_name ) ) ;
ifr . ifr_ifru . ifru_data = ( void * ) cmd ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
if ( cmd )
free ( cmd ) ;
if ( buf )
free ( buf ) ;
return UAP_FAILURE ;
}
if ( ioctl ( sockfd , MRVLPRIVCMD , & ifr ) ) {
if ( cmd )
free ( cmd ) ;
if ( buf )
free ( buf ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
/* Process result */
memcpy ( vhtcfg , buf + 1 , sizeof ( struct eth_priv_vhtcfg ) ) ;
close ( sockfd ) ;
free ( cmd ) ;
free ( buf ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the sys_config command
*
* $ return N / A
*/
void
print_sys_config_usage ( void )
{
printf ( " \n Usage : sys_config [CONFIG_FILE] \n " ) ;
printf ( " \n If CONFIG_FILE is provided, a 'set' is performed, else a 'get' is performed. \n " ) ;
printf ( " CONFIG_FILE is file contain all the Micro AP settings. \n " ) ;
return ;
}
/**
* @ brief Show usage information for the rdeeprom command
*
* $ return N / A
*/
void
print_apcmd_read_eeprom_usage ( void )
{
printf ( " \n Usage: rdeeprom <offset> <bytecount> \n " ) ;
printf ( " offset : 0,4,8,..., multiple of 4 \n " ) ;
printf ( " bytecount : 4-20, multiple of 4 \n " ) ;
return ;
}
/**
* @ brief Show protocol tlv
*
* @ param protocol Protocol number
*
* $ return N / A
*/
void
print_protocol ( t_u16 protocol )
{
switch ( protocol ) {
case 0 :
case PROTOCOL_NO_SECURITY :
printf ( " PROTOCOL = No security \n " ) ;
break ;
case PROTOCOL_STATIC_WEP :
printf ( " PROTOCOL = Static WEP \n " ) ;
break ;
case PROTOCOL_WPA :
printf ( " PROTOCOL = WPA \n " ) ;
break ;
case PROTOCOL_WPA2 :
printf ( " PROTOCOL = WPA2 \n " ) ;
break ;
case PROTOCOL_WPA | PROTOCOL_WPA2 :
printf ( " PROTOCOL = WPA/WPA2 \n " ) ;
break ;
case PROTOCOL_WPA3_SAE :
printf ( " PROTOCOL = WPA3 SAE \n " ) ;
break ;
default :
printf ( " Unknown PROTOCOL: 0x%x \n " , protocol ) ;
break ;
}
}
/**
* @ brief Show wep tlv
*
* @ param tlv Pointer to wep tlv
*
* $ return N / A
*/
void
print_wep_key ( tlvbuf_wep_key * tlv )
{
int i ;
t_u16 tlv_len ;
tlv_len = * ( t_u8 * ) & tlv - > length ;
tlv_len | = ( * ( ( t_u8 * ) & tlv - > length + 1 ) < < 8 ) ;
if ( tlv_len < = 2 ) {
printf ( " wrong wep_key tlv: length=%d \n " , tlv_len ) ;
return ;
}
printf ( " WEP KEY_%d = " , tlv - > key_index ) ;
for ( i = 0 ; i < tlv_len - 2 ; i + + )
printf ( " %02x " , tlv - > key [ i ] ) ;
if ( tlv - > is_default )
printf ( " \n Default WEP Key = %d \n " , tlv - > key_index ) ;
else
printf ( " \n " ) ;
}
/**
* @ brief Parses a command line
*
* @ param line The line to parse
* @ param args Pointer to the argument buffer to be filled in
* @ return Number of arguments in the line or EOF
*/
static int
parse_line ( char * line , char * args [ ] )
{
int arg_num = 0 ;
int is_start = 0 ;
int is_quote = 0 ;
int is_escape = 0 ;
int length = 0 ;
int i = 0 ;
int j = 0 ;
arg_num = 0 ;
length = strlen ( line ) ;
/* Process line */
/* Find number of arguments */
is_start = 0 ;
is_quote = 0 ;
for ( i = 0 ; i < length ; i + + ) {
/* Ignore leading spaces */
if ( is_start = = 0 ) {
if ( line [ i ] = = ' ' ) {
continue ;
} else if ( line [ i ] = = ' \t ' ) {
continue ;
} else if ( line [ i ] = = ' \n ' ) {
break ;
} else {
is_start = 1 ;
args [ arg_num ] = & line [ i ] ;
arg_num + + ;
}
}
if ( is_start = = 1 ) {
if ( ( line [ i ] = = ' \\ ' ) & & ( i < ( length - 1 ) ) ) {
if ( line [ i + 1 ] = = ' " ' ) {
is_escape = 1 ;
for ( j = i ; j < length - 1 ; j + + ) {
line [ j ] = line [ j + 1 ] ;
}
line [ length - 1 ] = ' \0 ' ;
continue ;
}
}
/* Ignore comments */
if ( line [ i ] = = ' # ' ) {
if ( is_quote = = 0 ) {
line [ i ] = ' \0 ' ;
arg_num - - ;
}
break ;
}
/* Separate by '=' */
if ( line [ i ] = = ' = ' ) {
if ( is_quote = = 0 ) {
line [ i ] = ' \0 ' ;
is_start = 0 ;
continue ;
}
}
/* Separate by ',' */
if ( line [ i ] = = ' , ' ) {
if ( is_quote = = 0 ) {
line [ i ] = ' \0 ' ;
is_start = 0 ;
continue ;
}
}
/* Change ',' to ' ', but not inside quotes */
if ( ( line [ i ] = = ' , ' ) & & ( is_quote = = 0 ) ) {
line [ i ] = ' ' ;
continue ;
}
}
/* Remove newlines */
if ( line [ i ] = = ' \n ' ) {
line [ i ] = ' \0 ' ;
}
/* Check for quotes */
if ( line [ i ] = = ' " ' ) {
if ( is_escape ) {
is_escape = 0 ;
/* no change in is_quote */
} else {
is_quote = ( is_quote = = 1 ) ? 0 : 1 ;
}
continue ;
}
if ( ( ( line [ i ] = = ' ' ) | | ( line [ i ] = = ' \t ' ) ) & & ( is_quote = = 0 ) ) {
line [ i ] = ' \0 ' ;
is_start = 0 ;
continue ;
}
}
return arg_num ;
}
/**
* @ brief Parse function for a configuration line
*
* @ param s Storage buffer for data
* @ param size Maximum size of data
* @ param stream File stream pointer
* @ param line Pointer to current line within the file
* @ param _pos Output string or NULL
* @ return String or NULL
*/
static char *
config_get_line ( char * s , int size , FILE * stream , int * line , char * * _pos )
{
* _pos = mlan_config_get_line ( stream , s , size , line ) ;
return * _pos ;
}
/**
* @ brief Read the profile and sends to the driver
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
apcmd_sys_config_profile ( int argc , char * argv [ ] )
{
FILE * config_file = NULL ;
char * line = NULL ;
int li = 0 ;
char * pos = NULL ;
int arg_num = 0 ;
char * args [ 30 ] ;
int i ;
int is_ap_config = 0 ;
int is_ap_mac_filter = 0 ;
apcmdbuf_sys_configure * cmd_buf = NULL ;
HTCap_t htcap ;
int enable_11n = - 1 ;
t_u16 tlv_offset_11n = 0 ;
t_u32 supported_mcs_set = 0 ;
t_u8 * buffer = NULL ;
t_u8 * tmp_buffer = NULL ;
t_u16 cmd_len = 0 ;
t_u16 tlv_len = 0 ;
int keyindex = - 1 ;
int protocol = - 1 ;
int pwkcipher_wpa = - 1 ;
int pwkcipher_wpa2 = - 1 ;
int gwkcipher = - 1 ;
tlvbuf_sta_mac_addr_filter * filter_tlv = NULL ;
tlvbuf_channel_config * channel_band_tlv = NULL ;
int filter_mac_count = - 1 ;
int tx_data_rate = - 1 ;
int tx_beacon_rate = - 1 ;
int mcbc_data_rate = - 1 ;
t_u8 rate [ MAX_RATES ] ;
int found = 0 ;
char country_80211d [ 4 ] ;
t_u8 state_80211d = 0 ;
int chan_mode = 0 ;
int band = 0 ;
int band_flag = 0 ;
int chan_number = 0 ;
t_u16 max_sta_num_supported = 0 ;
fw_info fw ;
struct eth_priv_vhtcfg vhtcfg = { 0 } ;
int ret = UAP_SUCCESS ;
memset ( rate , 0 , MAX_RATES ) ;
/* Check if file exists */
config_file = fopen ( argv [ 0 ] , " r " ) ;
if ( config_file = = NULL ) {
printf ( " \n ERR:Config file can not open. \n " ) ;
return UAP_FAILURE ;
}
line = ( char * ) malloc ( MAX_CONFIG_LINE ) ;
if ( ! line ) {
printf ( " ERR:Cannot allocate memory for line \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
memset ( line , 0 , MAX_CONFIG_LINE ) ;
/* Parse file and process */
while ( config_get_line ( line , MAX_CONFIG_LINE , config_file , & li , & pos ) ) {
# if DEBUG
uap_printf ( MSG_DEBUG , " DBG:Received config line (%d) = %s \n " ,
li , line ) ;
# endif
arg_num = parse_line ( line , args ) ;
# if DEBUG
uap_printf ( MSG_DEBUG , " DBG:Number of arguments = %d \n " ,
arg_num ) ;
for ( i = 0 ; i < arg_num ; i + + ) {
uap_printf ( MSG_DEBUG , " \t DBG:Argument %d. %s \n " , i + 1 ,
args [ i ] ) ;
}
# endif
/* Check for end of AP configurations */
if ( is_ap_config = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 ) {
is_ap_config = 0 ;
if ( tx_data_rate ! = - 1 ) {
if ( ( ! rate [ 0 ] ) & & ( tx_data_rate ) & &
( is_tx_rate_valid
( ( t_u8 ) tx_data_rate ) ! =
UAP_SUCCESS ) ) {
printf ( " ERR: Invalid Tx Data Rate \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( rate [ 0 ] & & tx_data_rate ) {
for ( i = 0 ; rate [ i ] ! = 0 ; i + + ) {
if ( ( rate [ i ] &
~ BASIC_RATE_SET_BIT )
= = tx_data_rate ) {
found = 1 ;
break ;
}
}
if ( ! found ) {
printf ( " ERR: Invalid Tx Data Rate \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
}
if ( tx_beacon_rate ! = - 1 ) {
if ( ( ! rate [ 0 ] ) & & ( tx_beacon_rate ) & &
( is_tx_rate_valid
( ( t_u8 ) tx_beacon_rate ) ! =
UAP_SUCCESS ) ) {
printf ( " ERR: Invalid Tx Beacon Rate \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( rate [ 0 ] & & tx_beacon_rate ) {
for ( i = 0 ; rate [ i ] ! = 0 ; i + + ) {
if ( ( rate [ i ] &
~ BASIC_RATE_SET_BIT )
= = tx_beacon_rate ) {
found = 1 ;
break ;
}
}
if ( ! found ) {
printf ( " ERR: Invalid Tx Beacon Rate \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
/* Append a new TLV */
tlvbuf_tx_data_rate * tlv = NULL ;
tlv_len = sizeof ( tlvbuf_tx_data_rate ) ;
tmp_buffer =
realloc ( buffer ,
cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append tx beacon rate TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf =
( apcmdbuf_sys_configure * )
buffer ;
tlv = ( tlvbuf_tx_data_rate * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_TX_BEACON_RATE_TLV_ID ;
tlv - > length = 2 ;
tlv - > tx_data_rate = tx_beacon_rate ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > tx_data_rate =
uap_cpu_to_le16 ( tlv - >
tx_data_rate ) ;
}
if ( mcbc_data_rate ! = - 1 ) {
if ( ( ! rate [ 0 ] ) & & ( mcbc_data_rate ) & &
( is_mcbc_rate_valid
( ( t_u8 ) mcbc_data_rate ) ! =
UAP_SUCCESS ) ) {
printf ( " ERR: Invalid Tx Data Rate \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( rate [ 0 ] & & mcbc_data_rate ) {
for ( i = 0 ; rate [ i ] ! = 0 ; i + + ) {
if ( rate [ i ] &
BASIC_RATE_SET_BIT )
{
if ( ( rate [ i ] &
~ BASIC_RATE_SET_BIT )
= =
mcbc_data_rate )
{
found = 1 ;
break ;
}
}
}
if ( ! found ) {
printf ( " ERR: Invalid MCBC Data Rate \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
/* Append a new TLV */
tlvbuf_mcbc_data_rate * tlv = NULL ;
tlv_len = sizeof ( tlvbuf_mcbc_data_rate ) ;
tmp_buffer =
realloc ( buffer ,
cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append tx data rate TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf =
( apcmdbuf_sys_configure * )
buffer ;
tlv = ( tlvbuf_mcbc_data_rate * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_MCBC_DATA_RATE_TLV_ID ;
tlv - > length = 2 ;
tlv - > mcbc_datarate = mcbc_data_rate ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > mcbc_datarate =
uap_cpu_to_le16 ( tlv - >
mcbc_datarate ) ;
}
if ( ( protocol = = PROTOCOL_STATIC_WEP ) & &
( enable_11n = = 1 ) ) {
printf ( " ERR:WEP cannot be used when AP operates in 802.11n mode. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( ( protocol = = PROTOCOL_WPA2_MIXED ) & &
( ( pwkcipher_wpa < 0 ) | |
( pwkcipher_wpa2 < 0 ) ) ) {
printf ( " ERR:Both PwkCipherWPA and PwkCipherWPA2 should be defined for Mixed mode. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( ( ( pwkcipher_wpa > = 0 ) | |
( pwkcipher_wpa2 > = 0 ) ) & &
( gwkcipher > = 0 ) ) {
if ( ( protocol = = PROTOCOL_WPA ) | |
( protocol = = PROTOCOL_WPA2_MIXED ) ) {
if ( enable_11n ! = - 1 ) {
if ( is_cipher_valid_with_11n ( pwkcipher_wpa , gwkcipher , protocol , enable_11n ) ! = UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA pairwise cipher combination! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
} else if
( is_cipher_valid_with_proto
( pwkcipher_wpa ,
gwkcipher ,
protocol ) ! =
UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA pairwise cipher combination! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
if ( ( protocol = = PROTOCOL_WPA2 ) | |
( protocol = = PROTOCOL_WPA2_MIXED )
| | ( protocol = = PROTOCOL_WPA3_SAE )
) {
if ( enable_11n ! = - 1 ) {
if ( is_cipher_valid_with_11n ( pwkcipher_wpa2 , gwkcipher , protocol , enable_11n ) ! = UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA2 pairwise cipher combination! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
} else if
( is_cipher_valid_with_proto
( pwkcipher_wpa2 ,
gwkcipher ,
protocol ) ! =
UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA2 pairwise cipher combination! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
}
if ( 0 = = get_fw_info ( & fw ) ) {
/*check whether support 802.11AC through BAND_AAC bit */
if ( fw . fw_bands & BAND_AAC ) {
ret = get_802_11ac_cfg ( & vhtcfg ) ;
if ( ret ! = UAP_SUCCESS )
goto done ;
if ( enable_11n ! = - 1 ) {
/* Note: When 11AC is disabled, FW sets vht_rx_mcs to 0xffff */
if ( ( vhtcfg .
vht_rx_mcs ! =
0xffff ) & &
( ! enable_11n ) ) {
printf ( " ERR: 11n must be enabled when AP operates in 11ac mode. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
} else
printf ( " No support 802 11AC. \n " ) ;
} else {
printf ( " ERR: get_fw_info fail \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( protocol ! = - 1 ) {
tlvbuf_protocol * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_protocol ) ;
tmp_buffer =
realloc ( buffer ,
cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append protocol TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf =
( apcmdbuf_sys_configure * )
buffer ;
tlv = ( tlvbuf_protocol * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_PROTOCOL_TLV_ID ;
tlv - > length = 2 ;
tlv - > protocol = protocol ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > protocol =
uap_cpu_to_le16 ( tlv - > protocol ) ;
if ( protocol &
( PROTOCOL_WPA | PROTOCOL_WPA2 |
PROTOCOL_WPA3_SAE ) ) {
tlvbuf_akmp * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_akmp ) ;
tmp_buffer =
realloc ( buffer ,
cmd_len +
tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append AKMP TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf =
( apcmdbuf_sys_configure
* ) buffer ;
tlv = ( tlvbuf_akmp * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_AKMP_TLV_ID ;
tlv - > length = 4 ; /* sizeof(tlvbuf_akmp) - TLVHEADER */
if ( protocol &
PROTOCOL_WPA3_SAE ) {
tlv - > key_mgmt =
KEY_MGMT_SAE ;
} else {
tlv - > key_mgmt =
KEY_MGMT_PSK ;
}
endian_convert_tlv_header_out
( tlv ) ;
tlv - > key_mgmt =
uap_cpu_to_le16 ( tlv - >
key_mgmt ) ;
tlv - > key_mgmt_operation = 0 ;
}
}
if ( pwkcipher_wpa > = 0 ) {
tlvbuf_pwk_cipher * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_pwk_cipher ) ;
tmp_buffer =
realloc ( buffer ,
cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append cipher TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf =
( apcmdbuf_sys_configure * )
buffer ;
tlv = ( tlvbuf_pwk_cipher * ) ( buffer +
cmd_len ) ;
memset ( tlv , 0 , tlv_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_CIPHER_PWK_TLV_ID ;
tlv - > length =
sizeof ( tlvbuf_pwk_cipher ) -
TLVHEADER_LEN ;
tlv - > pairwise_cipher = pwkcipher_wpa ;
tlv - > protocol = PROTOCOL_WPA ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > protocol =
uap_cpu_to_le16 ( tlv - > protocol ) ;
}
if ( pwkcipher_wpa2 > = 0 ) {
tlvbuf_pwk_cipher * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_pwk_cipher ) ;
tmp_buffer =
realloc ( buffer ,
cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append cipher TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf =
( apcmdbuf_sys_configure * )
buffer ;
tlv = ( tlvbuf_pwk_cipher * ) ( buffer +
cmd_len ) ;
memset ( tlv , 0 , tlv_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_CIPHER_PWK_TLV_ID ;
tlv - > length =
sizeof ( tlvbuf_pwk_cipher ) -
TLVHEADER_LEN ;
tlv - > pairwise_cipher = pwkcipher_wpa2 ;
tlv - > protocol = PROTOCOL_WPA2 ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > protocol =
uap_cpu_to_le16 ( tlv - > protocol ) ;
}
if ( gwkcipher > = 0 ) {
tlvbuf_gwk_cipher * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_gwk_cipher ) ;
tmp_buffer =
realloc ( buffer ,
cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append cipher TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf =
( apcmdbuf_sys_configure * )
buffer ;
tlv = ( tlvbuf_gwk_cipher * ) ( buffer +
cmd_len ) ;
memset ( tlv , 0 , tlv_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_CIPHER_GWK_TLV_ID ;
tlv - > length =
sizeof ( tlvbuf_gwk_cipher ) -
TLVHEADER_LEN ;
tlv - > group_cipher = gwkcipher ;
endian_convert_tlv_header_out ( tlv ) ;
}
cmd_buf - > size = cmd_len ;
/* Send collective command */
if ( uap_ioctl
( ( t_u8 * ) cmd_buf , & cmd_len ,
cmd_len ) = = UAP_SUCCESS ) {
if ( cmd_buf - > result ! = CMD_SUCCESS ) {
printf ( " ERR: Failed to set the configuration! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
} else {
printf ( " ERR: Command sending failed! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
cmd_len = 0 ;
if ( buffer ) {
free ( buffer ) ;
buffer = NULL ;
}
continue ;
}
}
/* Check for beginning of AP configurations */
if ( strcmp ( args [ 0 ] , " ap_config " ) = = 0 ) {
is_ap_config = 1 ;
cmd_len = sizeof ( apcmdbuf_sys_configure ) ;
if ( buffer ) {
free ( buffer ) ;
buffer = NULL ;
}
buffer = ( t_u8 * ) malloc ( cmd_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate memory! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
cmd_buf - > cmd_code = APCMD_SYS_CONFIGURE ;
cmd_buf - > size = cmd_len ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
cmd_buf - > action = ACTION_SET ;
continue ;
}
/* Check for end of AP MAC address filter configurations */
if ( is_ap_mac_filter = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 ) {
is_ap_mac_filter = 0 ;
if ( filter_tlv - > count ! = filter_mac_count ) {
printf ( " ERR:Number of MAC address provided does not match 'Count' \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( filter_tlv - > count ) {
filter_tlv - > length =
( filter_tlv - > count * ETH_ALEN ) +
2 ;
cmd_len - =
( MAX_MAC_ONESHOT_FILTER -
filter_mac_count ) * ETH_ALEN ;
} else {
filter_tlv - > length =
( MAX_MAC_ONESHOT_FILTER *
ETH_ALEN ) + 2 ;
memset ( filter_tlv - > mac_address , 0 ,
MAX_MAC_ONESHOT_FILTER *
ETH_ALEN ) ;
}
cmd_buf - > size = cmd_len ;
endian_convert_tlv_header_out ( filter_tlv ) ;
if ( uap_ioctl
( ( t_u8 * ) cmd_buf , & cmd_len ,
cmd_len ) = = UAP_SUCCESS ) {
if ( cmd_buf - > result ! = CMD_SUCCESS ) {
printf ( " ERR: Failed to set the configuration! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
} else {
printf ( " ERR: Command sending failed! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
cmd_len = 0 ;
if ( buffer ) {
free ( buffer ) ;
buffer = NULL ;
}
continue ;
}
}
if ( strcmp ( args [ 0 ] , " 11d_enable " ) = = 0 ) {
if ( IS_HEX_OR_DIGIT ( args [ 1 ] ) = = UAP_FAILURE ) {
printf ( " ERR: valid input for state are 0 or 1 \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
state_80211d = ( t_u8 ) A2HEXDECIMAL ( args [ 1 ] ) ;
if ( ( state_80211d ! = 0 ) & & ( state_80211d ! = 1 ) ) {
printf ( " ERR: valid input for state are 0 or 1 \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( sg_snmp_mib
( ACTION_SET , OID_80211D_ENABLE ,
sizeof ( state_80211d ) , & state_80211d )
= = UAP_FAILURE ) {
ret = UAP_FAILURE ;
goto done ;
}
}
if ( strcmp ( args [ 0 ] , " country " ) = = 0 ) {
apcmdbuf_cfg_80211d * cmd_buf = NULL ;
ieeetypes_subband_set_t sub_bands [ MAX_SUB_BANDS ] ;
t_u8 no_of_sub_band = 0 ;
t_u16 buf_len ;
t_u16 cmdlen ;
t_u8 * buf = NULL ;
if ( ( strlen ( args [ 1 ] ) > 3 ) | | ( strlen ( args [ 1 ] ) = = 0 ) ) {
printf ( " In-correct country input \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
strncpy ( country_80211d , args [ 1 ] ,
sizeof ( country_80211d ) - 1 ) ;
for ( i = 0 ; ( unsigned int ) i < strlen ( country_80211d ) ;
i + + ) {
if ( ( country_80211d [ i ] < ' A ' ) | |
( country_80211d [ i ] > ' z ' ) ) {
printf ( " Invalid Country Code \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( country_80211d [ i ] > ' Z ' )
country_80211d [ i ] =
country_80211d [ i ] - ' a ' + ' A ' ;
}
no_of_sub_band =
parse_domain_file ( country_80211d , band ,
sub_bands , NULL ) ;
if ( no_of_sub_band = = UAP_FAILURE ) {
printf ( " Parsing Failed \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
buf_len = sizeof ( apcmdbuf_cfg_80211d ) ;
buf_len + =
no_of_sub_band *
sizeof ( ieeetypes_subband_set_t ) ;
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
memset ( buf , 0 , buf_len ) ;
cmd_buf = ( apcmdbuf_cfg_80211d * ) buf ;
cmdlen = buf_len ;
cmd_buf - > size = cmdlen - BUF_HEADER_SIZE ;
cmd_buf - > result = 0 ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > action = uap_cpu_to_le16 ( ACTION_SET ) ;
cmd_buf - > cmd_code = HostCmd_CMD_802_11D_DOMAIN_INFO ;
cmd_buf - > domain . tag = uap_cpu_to_le16 ( TLV_TYPE_DOMAIN ) ;
cmd_buf - > domain . length =
uap_cpu_to_le16 ( sizeof ( domain_param_t )
- BUF_HEADER_SIZE +
( no_of_sub_band *
sizeof
( ieeetypes_subband_set_t ) ) ) ;
memset ( cmd_buf - > domain . country_code , ' ' ,
sizeof ( cmd_buf - > domain . country_code ) ) ;
memcpy ( cmd_buf - > domain . country_code , country_80211d ,
strlen ( country_80211d ) ) ;
memcpy ( cmd_buf - > domain . subband , sub_bands ,
no_of_sub_band *
sizeof ( ieeetypes_subband_set_t ) ) ;
/* Send the command */
if ( uap_ioctl ( ( t_u8 * ) cmd_buf , & cmdlen , cmdlen ) = =
UAP_SUCCESS ) {
if ( cmd_buf - > result ! = CMD_SUCCESS ) {
printf ( " ERR: Failed to set the configuration! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
} else {
printf ( " ERR: Command sending failed! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( buf )
free ( buf ) ;
}
/* Check for beginning of AP MAC address filter configurations */
if ( strcmp ( args [ 0 ] , " ap_mac_filter " ) = = 0 ) {
is_ap_mac_filter = 1 ;
cmd_len =
sizeof ( apcmdbuf_sys_configure ) +
sizeof ( tlvbuf_sta_mac_addr_filter ) +
( MAX_MAC_ONESHOT_FILTER * ETH_ALEN ) ;
if ( buffer ) {
free ( buffer ) ;
buffer = NULL ;
}
buffer = ( t_u8 * ) malloc ( cmd_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate memory! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
cmd_buf - > cmd_code = APCMD_SYS_CONFIGURE ;
cmd_buf - > size = cmd_len ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
cmd_buf - > action = ACTION_SET ;
filter_tlv =
( tlvbuf_sta_mac_addr_filter * ) ( buffer +
sizeof
( apcmdbuf_sys_configure ) ) ;
filter_tlv - > tag = MRVL_STA_MAC_ADDR_FILTER_TLV_ID ;
filter_tlv - > length = 2 ;
filter_tlv - > count = 0 ;
filter_mac_count = 0 ;
continue ;
}
if ( ( strcmp ( args [ 0 ] , " FilterMode " ) = = 0 ) & & is_ap_mac_filter ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) | |
( atoi ( args [ 1 ] ) > 2 ) ) {
printf ( " ERR:Illegal FilterMode paramter %d. Must be either '0', '1', or '2'. \n " , atoi ( args [ 1 ] ) ) ;
ret = UAP_FAILURE ;
goto done ;
}
filter_tlv - > filter_mode = atoi ( args [ 1 ] ) ;
continue ;
}
if ( ( strcmp ( args [ 0 ] , " Count " ) = = 0 ) & & is_ap_mac_filter ) {
filter_tlv - > count = atoi ( args [ 1 ] ) ;
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | |
( filter_tlv - > count > MAX_MAC_ONESHOT_FILTER ) ) {
printf ( " ERR: Illegal Count parameter. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
if ( ( strncmp ( args [ 0 ] , " mac_ " , 4 ) = = 0 ) & & is_ap_mac_filter ) {
if ( filter_mac_count < MAX_MAC_ONESHOT_FILTER ) {
if ( mac2raw
( args [ 1 ] ,
& filter_tlv - > mac_address [ filter_mac_count *
ETH_ALEN ] ) ! =
UAP_SUCCESS ) {
printf ( " ERR: Invalid MAC address %s \n " ,
args [ 1 ] ) ;
ret = UAP_FAILURE ;
goto done ;
}
filter_mac_count + + ;
} else {
printf ( " ERR: Filter table can not have more than %d MAC addresses \n " , MAX_MAC_ONESHOT_FILTER ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
if ( strcmp ( args [ 0 ] , " SSID " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:SSID field is blank! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
tlvbuf_ssid * tlv = NULL ;
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
args [ 1 ] + + ;
}
if ( args [ 1 ] [ strlen ( args [ 1 ] ) - 1 ] = = ' " ' ) {
args [ 1 ] [ strlen ( args [ 1 ] ) - 1 ] = ' \0 ' ;
}
if ( ( strlen ( args [ 1 ] ) > MAX_SSID_LENGTH ) | |
( strlen ( args [ 1 ] ) = = 0 ) ) {
printf ( " ERR:SSID length out of range (%d to %d). \n " , MIN_SSID_LENGTH , MAX_SSID_LENGTH ) ;
ret = UAP_FAILURE ;
goto done ;
}
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_ssid ) + strlen ( args [ 1 ] ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot realloc SSID TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_ssid * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_SSID_TLV_ID ;
tlv - > length = strlen ( args [ 1 ] ) ;
memcpy ( tlv - > ssid , args [ 1 ] , tlv - > length ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
}
if ( strcmp ( args [ 0 ] , " BeaconPeriod " ) = = 0 ) {
if ( is_input_valid ( BEACONPERIOD , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_beacon_period * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_beacon_period ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot realloc beacon period TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_beacon_period * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_BEACON_PERIOD_TLV_ID ;
tlv - > length = 2 ;
tlv - > beacon_period_ms = ( t_u16 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > beacon_period_ms =
uap_cpu_to_le16 ( tlv - > beacon_period_ms ) ;
}
if ( strcmp ( args [ 0 ] , " ChanList " ) = = 0 ) {
if ( is_input_valid ( SCANCHANNELS , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_channel_list * tlv = NULL ;
channel_list * pchan_list = NULL ;
/* Append a new TLV */
tlv_len =
sizeof ( tlvbuf_channel_list ) +
( ( arg_num - 1 ) * sizeof ( channel_list ) ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append channel list TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_channel_list * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_CHANNELLIST_TLV_ID ;
tlv - > length = sizeof ( channel_list ) * ( arg_num - 1 ) ;
pchan_list = ( channel_list * ) tlv - > chan_list ;
for ( i = 0 ; i < ( arg_num - 1 ) ; i + + ) {
band_flag = - 1 ;
sscanf ( args [ i + 1 ] , " %d.%d " , & chan_number ,
& band_flag ) ;
pchan_list - > chan_number = chan_number ;
pchan_list - > bandcfg . chanBand = BAND_2GHZ ;
if ( ( ( band_flag ! = - 1 ) & & ( band_flag ) ) | |
( chan_number > MAX_CHANNELS_BG ) ) {
pchan_list - > bandcfg . chanBand =
BAND_5GHZ ;
}
pchan_list + + ;
}
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " Channel " ) = = 0 ) {
if ( is_input_valid ( CHANNEL , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_channel_config * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_channel_config ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append channel TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_channel_config * ) ( buffer + cmd_len ) ;
channel_band_tlv = tlv ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_CHANNELCONFIG_TLV_ID ;
tlv - > length =
sizeof ( tlvbuf_channel_config ) - TLVHEADER_LEN ;
tlv - > chan_number = ( t_u8 ) atoi ( args [ 1 ] ) ;
if ( tlv - > chan_number > MAX_CHANNELS_BG )
band = BAND_A ;
else
band = BAND_B | BAND_G ;
if ( ( arg_num - 1 ) = = 2 ) {
chan_mode = atoi ( args [ 2 ] ) ;
memset ( & ( tlv - > bandcfg ) , 0 ,
sizeof ( tlv - > bandcfg ) ) ;
if ( chan_mode & BITMAP_ACS_MODE ) {
int mode ;
if ( uap_ioctl_dfs_repeater_mode ( & mode )
= = UAP_SUCCESS ) {
if ( mode ) {
printf ( " ERR: ACS in DFS Repeater mode " " is not allowed \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
tlv - > bandcfg . scanMode = SCAN_MODE_ACS ;
}
if ( chan_mode & BITMAP_CHANNEL_ABOVE )
tlv - > bandcfg . chan2Offset =
SEC_CHAN_ABOVE ;
if ( chan_mode & BITMAP_CHANNEL_BELOW )
tlv - > bandcfg . chan2Offset =
SEC_CHAN_BELOW ;
} else
memset ( & ( tlv - > bandcfg ) , 0 ,
sizeof ( tlv - > bandcfg ) ) ;
if ( tlv - > chan_number > MAX_CHANNELS_BG ) {
tlv - > bandcfg . chanBand = BAND_5GHZ ;
}
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " Band " ) = = 0 ) {
if ( is_input_valid ( BAND , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
if ( channel_band_tlv = = NULL ) {
printf ( " ERR: Channel parameter should be specified before Band \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
/* If band is provided, clear previous value of band */
channel_band_tlv - > bandcfg . chanBand = BAND_2GHZ ;
if ( atoi ( args [ 1 ] ) = = 0 ) {
band = BAND_B | BAND_G ;
} else {
channel_band_tlv - > bandcfg . chanBand = BAND_5GHZ ;
band = BAND_A ;
}
}
if ( strcmp ( args [ 0 ] , " AP_MAC " ) = = 0 ) {
tlvbuf_ap_mac_address * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_ap_mac_address ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append ap_mac TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_ap_mac_address * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
cmd_buf - > action = ACTION_SET ;
tlv - > tag = MRVL_AP_MAC_ADDRESS_TLV_ID ;
tlv - > length = ETH_ALEN ;
if ( ( ret =
mac2raw ( args [ 1 ] ,
tlv - > ap_mac_addr ) ) ! = UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " ,
ret = =
UAP_FAILURE ? " Invalid MAC " : ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " :
" Multicast " ) ;
ret = UAP_FAILURE ;
goto done ;
}
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " Rate " ) = = 0 ) {
if ( is_input_valid ( RATE , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
printf ( " ERR: Invalid Rate input \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_rates * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_rates ) + arg_num - 1 ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append rates TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_rates * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_RATES_TLV_ID ;
tlv - > length = arg_num - 1 ;
for ( i = 0 ; i < tlv - > length ; i + + ) {
rate [ i ] = tlv - > operational_rates [ i ] =
( t_u8 ) A2HEXDECIMAL ( args [ i + 1 ] ) ;
}
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " TxPowerLevel " ) = = 0 ) {
if ( is_input_valid ( TXPOWER , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
printf ( " ERR:Invalid TxPowerLevel \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
tlvbuf_tx_power * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_tx_power ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append tx power level TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_tx_power * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_TX_POWER_TLV_ID ;
tlv - > length = 1 ;
tlv - > tx_power_dbm = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
}
if ( strcmp ( args [ 0 ] , " BroadcastSSID " ) = = 0 ) {
if ( is_input_valid ( BROADCASTSSID , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_bcast_ssid_ctl * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_bcast_ssid_ctl ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append SSID broadcast control TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_bcast_ssid_ctl * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_BCAST_SSID_CTL_TLV_ID ;
tlv - > length = 1 ;
tlv - > bcast_ssid_ctl = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " RTSThreshold " ) = = 0 ) {
if ( is_input_valid ( RTSTHRESH , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_rts_threshold * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_rts_threshold ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append RTS threshold TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_rts_threshold * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_RTS_THRESHOLD_TLV_ID ;
tlv - > length = 2 ;
tlv - > rts_threshold = ( t_u16 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > rts_threshold =
uap_cpu_to_le16 ( tlv - > rts_threshold ) ;
}
if ( strcmp ( args [ 0 ] , " FragThreshold " ) = = 0 ) {
if ( is_input_valid ( FRAGTHRESH , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_frag_threshold * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_frag_threshold ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append Fragmentation threshold TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_frag_threshold * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_FRAG_THRESHOLD_TLV_ID ;
tlv - > length = 2 ;
tlv - > frag_threshold = ( t_u16 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > frag_threshold =
uap_cpu_to_le16 ( tlv - > frag_threshold ) ;
}
if ( strcmp ( args [ 0 ] , " DTIMPeriod " ) = = 0 ) {
if ( is_input_valid ( DTIMPERIOD , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_dtim_period * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_dtim_period ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append DTIM period TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_dtim_period * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_DTIM_PERIOD_TLV_ID ;
tlv - > length = 1 ;
tlv - > dtim_period = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " RSNReplayProtection " ) = = 0 ) {
if ( is_input_valid ( RSNREPLAYPROT , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_rsn_replay_prot * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_rsn_replay_prot ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append RSN replay protection TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_rsn_replay_prot * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_RSN_REPLAY_PROT_TLV_ID ;
tlv - > length = 1 ;
tlv - > rsn_replay_prot = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " TxBeaconRate " ) = = 0 ) {
if ( is_input_valid ( TXBEACONRATE , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tx_beacon_rate = ( t_u16 ) A2HEXDECIMAL ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " MCBCdataRate " ) = = 0 ) {
if ( is_input_valid ( MCBCDATARATE , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
mcbc_data_rate = ( t_u16 ) A2HEXDECIMAL ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " PktFwdCtl " ) = = 0 ) {
if ( is_input_valid ( PKTFWD , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_pkt_fwd_ctl * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_pkt_fwd_ctl ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append packet forwarding control TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_pkt_fwd_ctl * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_PKT_FWD_CTL_TLV_ID ;
tlv - > length = 1 ;
tlv - > pkt_fwd_ctl = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " StaAgeoutTimer " ) = = 0 ) {
if ( is_input_valid
( STAAGEOUTTIMER , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_sta_ageout_timer * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_sta_ageout_timer ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append STA ageout timer TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_sta_ageout_timer * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_STA_AGEOUT_TIMER_TLV_ID ;
tlv - > length = 4 ;
tlv - > sta_ageout_timer_ms = ( t_u32 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > sta_ageout_timer_ms =
uap_cpu_to_le32 ( tlv - > sta_ageout_timer_ms ) ;
}
if ( strcmp ( args [ 0 ] , " PSStaAgeoutTimer " ) = = 0 ) {
if ( is_input_valid
( PSSTAAGEOUTTIMER , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_ps_sta_ageout_timer * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_ps_sta_ageout_timer ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append PS STA ageout timer TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_ps_sta_ageout_timer * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_PS_STA_AGEOUT_TIMER_TLV_ID ;
tlv - > length = 4 ;
tlv - > ps_sta_ageout_timer_ms = ( t_u32 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > ps_sta_ageout_timer_ms =
uap_cpu_to_le32 ( tlv - > ps_sta_ageout_timer_ms ) ;
}
if ( strcmp ( args [ 0 ] , " AuthMode " ) = = 0 ) {
if ( is_input_valid ( AUTHMODE , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_auth_mode * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_auth_mode ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append auth mode TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_auth_mode * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_AUTH_TLV_ID ;
tlv - > length = 1 ;
tlv - > auth_mode = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " KeyIndex " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " KeyIndex is blank! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
if ( ISDIGIT ( args [ 1 ] ) = = 0 ) {
printf ( " ERR:Illegal KeyIndex parameter. Must be either '0', '1', '2', or '3'. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
keyindex = atoi ( args [ 1 ] ) ;
if ( ( keyindex < 0 ) | | ( keyindex > 3 ) ) {
printf ( " ERR:Illegal KeyIndex parameter. Must be either '0', '1', '2', or '3'. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
}
if ( strncmp ( args [ 0 ] , " Key_ " , 4 ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:%s is blank! \n " , args [ 0 ] ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
tlvbuf_wep_key * tlv = NULL ;
int key_len = 0 ;
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
if ( ( strlen ( args [ 1 ] ) ! = 2 ) & &
( strlen ( args [ 1 ] ) ! = 7 ) & &
( strlen ( args [ 1 ] ) ! = 15 ) ) {
printf ( " ERR:Wrong key length! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
key_len = strlen ( args [ 1 ] ) - 2 ;
} else {
if ( ( strlen ( args [ 1 ] ) ! = 0 ) & &
( strlen ( args [ 1 ] ) ! = 10 ) & &
( strlen ( args [ 1 ] ) ! = 26 ) ) {
printf ( " ERR:Wrong key length! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( UAP_FAILURE = = ishexstring ( args [ 1 ] ) ) {
printf ( " ERR:Only hex digits are allowed when key length is 10 or 26 \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
key_len = strlen ( args [ 1 ] ) / 2 ;
}
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_wep_key ) + key_len ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append WEP key configurations TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_wep_key * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_WEP_KEY_TLV_ID ;
tlv - > length = key_len + 2 ;
if ( strcmp ( args [ 0 ] , " Key_0 " ) = = 0 ) {
tlv - > key_index = 0 ;
} else if ( strcmp ( args [ 0 ] , " Key_1 " ) = = 0 ) {
tlv - > key_index = 1 ;
} else if ( strcmp ( args [ 0 ] , " Key_2 " ) = = 0 ) {
tlv - > key_index = 2 ;
} else if ( strcmp ( args [ 0 ] , " Key_3 " ) = = 0 ) {
tlv - > key_index = 3 ;
}
if ( keyindex = = tlv - > key_index ) {
tlv - > is_default = 1 ;
} else {
tlv - > is_default = 0 ;
}
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
memcpy ( tlv - > key , & args [ 1 ] [ 1 ] ,
strlen ( args [ 1 ] ) - 2 ) ;
} else {
string2raw ( args [ 1 ] , tlv - > key ) ;
}
endian_convert_tlv_header_out ( tlv ) ;
}
}
if ( strcmp ( args [ 0 ] , " PSK " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:PSK is blank! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
tlvbuf_wpa_passphrase * tlv = NULL ;
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
args [ 1 ] + + ;
}
if ( args [ 1 ] [ strlen ( args [ 1 ] ) - 1 ] = = ' " ' ) {
args [ 1 ] [ strlen ( args [ 1 ] ) - 1 ] = ' \0 ' ;
}
tlv_len =
sizeof ( tlvbuf_wpa_passphrase ) +
strlen ( args [ 1 ] ) ;
if ( strlen ( args [ 1 ] ) > MAX_WPA_PASSPHRASE_LENGTH ) {
printf ( " ERR:PSK too long. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( strlen ( args [ 1 ] ) < MIN_WPA_PASSPHRASE_LENGTH ) {
printf ( " ERR:PSK too short. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( strlen ( args [ 1 ] ) = =
MAX_WPA_PASSPHRASE_LENGTH ) {
if ( UAP_FAILURE = = ishexstring ( args [ 1 ] ) ) {
printf ( " ERR:Only hex digits are allowed when passphrase's length is 64 \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
/* Append a new TLV */
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append WPA passphrase TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_wpa_passphrase * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_WPA_PASSPHRASE_TLV_ID ;
tlv - > length = strlen ( args [ 1 ] ) ;
memcpy ( tlv - > passphrase , args [ 1 ] , tlv - > length ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
}
if ( strcmp ( args [ 0 ] , " Protocol " ) = = 0 ) {
if ( is_input_valid ( PROTOCOL , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
protocol = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
if ( ( strcmp ( args [ 0 ] , " PairwiseCipher " ) = = 0 ) | |
( strcmp ( args [ 0 ] , " GroupCipher " ) = = 0 ) ) {
printf ( " ERR:PairwiseCipher and GroupCipher are not supported. \n " " Please configure pairwise cipher using parameters PwkCipherWPA or PwkCipherWPA2 \n " " and group cipher using GwkCipher in the config file. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( ( protocol = = PROTOCOL_NO_SECURITY ) | |
( protocol = = PROTOCOL_STATIC_WEP ) ) {
if ( ( strcmp ( args [ 0 ] , " PwkCipherWPA " ) = = 0 ) | |
( strcmp ( args [ 0 ] , " PwkCipherWPA2 " ) = = 0 )
| | ( strcmp ( args [ 0 ] , " GwkCipher " ) = = 0 ) ) {
printf ( " ERR:Pairwise cipher and group cipher should not be defined for Open and WEP mode. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
if ( strcmp ( args [ 0 ] , " PwkCipherWPA " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:PwkCipherWPA is blank! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
if ( ISDIGIT ( args [ 1 ] ) = = 0 ) {
printf ( " ERR:Illegal PwkCipherWPA parameter. Must be either bit '2' or '3'. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( atoi ( args [ 1 ] ) & ~ CIPHER_BITMAP ) {
printf ( " ERR:Illegal PwkCipherWPA parameter. Must be either bit '2' or '3'. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
pwkcipher_wpa = atoi ( args [ 1 ] ) ;
if ( enable_11n & &
protocol ! = PROTOCOL_WPA2_MIXED ) {
memset ( & htcap , 0 , sizeof ( htcap ) ) ;
if ( UAP_SUCCESS = =
get_sys_cfg_11n ( & htcap ) ) {
if ( htcap . supported_mcs_set [ 0 ]
& & ( atoi ( args [ 1 ] ) = =
CIPHER_TKIP ) ) {
printf ( " ERR: WPA/TKIP cannot be used when AP operates in 802.11n mode. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
}
}
}
if ( strcmp ( args [ 0 ] , " PwkCipherWPA2 " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:PwkCipherWPA2 is blank! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
if ( ISDIGIT ( args [ 1 ] ) = = 0 ) {
printf ( " ERR:Illegal PwkCipherWPA2 parameter. Must be either bit '2' or '3'. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( atoi ( args [ 1 ] ) & ~ CIPHER_BITMAP ) {
printf ( " ERR:Illegal PwkCipherWPA2 parameter. Must be either bit '2' or '3'. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
pwkcipher_wpa2 = atoi ( args [ 1 ] ) ;
if ( enable_11n & &
protocol ! = PROTOCOL_WPA2_MIXED ) {
memset ( & htcap , 0 , sizeof ( htcap ) ) ;
if ( UAP_SUCCESS = =
get_sys_cfg_11n ( & htcap ) ) {
if ( htcap . supported_mcs_set [ 0 ]
& & ( atoi ( args [ 1 ] ) = =
CIPHER_TKIP ) ) {
printf ( " ERR: WPA/TKIP cannot be used when AP operates in 802.11n mode. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
}
}
}
}
if ( strcmp ( args [ 0 ] , " GwkCipher " ) = = 0 ) {
if ( is_input_valid ( GWK_CIPHER , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
gwkcipher = atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " GroupRekeyTime " ) = = 0 ) {
if ( is_input_valid
( GROUPREKEYTIMER , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_group_rekey_timer * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_group_rekey_timer ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append group rekey timer TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_group_rekey_timer * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_GRP_REKEY_TIME_TLV_ID ;
tlv - > length = 4 ;
tlv - > group_rekey_time_sec = ( t_u32 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > group_rekey_time_sec =
uap_cpu_to_le32 ( tlv - > group_rekey_time_sec ) ;
}
if ( strcmp ( args [ 0 ] , " MaxStaNum " ) = = 0 ) {
if ( is_input_valid ( MAXSTANUM , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
if ( get_max_sta_num_supported ( & max_sta_num_supported ) = =
UAP_FAILURE ) {
ret = UAP_FAILURE ;
goto done ;
}
if ( atoi ( args [ 1 ] ) > max_sta_num_supported ) {
printf ( " ERR: MAX_STA_NUM must be less than %d \n " , max_sta_num_supported ) ;
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_max_sta_num * tlv = NULL ;
/* Append a new TLV */
tlv_len =
sizeof ( tlvbuf_max_sta_num ) -
sizeof ( tlv - > max_sta_num_supported ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot realloc max station number TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_max_sta_num * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_MAX_STA_CNT_TLV_ID ;
tlv - > length = 2 ;
tlv - > max_sta_num_configured = ( t_u16 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > max_sta_num_configured =
uap_cpu_to_le16 ( tlv - > max_sta_num_configured ) ;
}
if ( strcmp ( args [ 0 ] , " Retrylimit " ) = = 0 ) {
if ( is_input_valid ( RETRYLIMIT , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_retry_limit * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_retry_limit ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot realloc retry limit TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_retry_limit * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_RETRY_LIMIT_TLV_ID ;
tlv - > length = 1 ;
tlv - > retry_limit = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " PairwiseUpdateTimeout " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_eapol_pwk_hsk_timeout * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_eapol_pwk_hsk_timeout ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append pairwise update timeout TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_eapol_pwk_hsk_timeout * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_EAPOL_PWK_HSK_TIMEOUT_TLV_ID ;
tlv - > length = 4 ;
tlv - > pairwise_update_timeout = ( t_u32 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > pairwise_update_timeout =
uap_cpu_to_le32 ( tlv - > pairwise_update_timeout ) ;
}
if ( strcmp ( args [ 0 ] , " PairwiseHandshakeRetries " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_eapol_pwk_hsk_retries * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_eapol_pwk_hsk_retries ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append pairwise handshake retries TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_eapol_pwk_hsk_retries * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_EAPOL_PWK_HSK_RETRIES_TLV_ID ;
tlv - > length = 4 ;
tlv - > pwk_retries = ( t_u32 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > pwk_retries = uap_cpu_to_le32 ( tlv - > pwk_retries ) ;
}
if ( strcmp ( args [ 0 ] , " GroupwiseUpdateTimeout " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_eapol_gwk_hsk_timeout * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_eapol_gwk_hsk_timeout ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append groupwise update timeout TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_eapol_gwk_hsk_timeout * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_EAPOL_GWK_HSK_TIMEOUT_TLV_ID ;
tlv - > length = 4 ;
tlv - > groupwise_update_timeout = ( t_u32 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > groupwise_update_timeout =
uap_cpu_to_le32 ( tlv - > groupwise_update_timeout ) ;
}
if ( strcmp ( args [ 0 ] , " GroupwiseHandshakeRetries " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) ) {
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_eapol_gwk_hsk_retries * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_eapol_gwk_hsk_retries ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append groupwise handshake retries TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_eapol_gwk_hsk_retries * ) ( buffer +
cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_EAPOL_GWK_HSK_RETRIES_TLV_ID ;
tlv - > length = 4 ;
tlv - > gwk_retries = ( t_u32 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
tlv - > gwk_retries = uap_cpu_to_le32 ( tlv - > gwk_retries ) ;
}
if ( strcmp ( args [ 0 ] , " Enable11n " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) ! = UAP_SUCCESS ) | |
( atoi ( args [ 1 ] ) < 0 ) | | ( atoi ( args [ 1 ] ) > 1 ) ) {
printf ( " ERR: Invalid Enable11n value \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_htcap_t * tlv = NULL ;
enable_11n = atoi ( args [ 1 ] ) ;
memset ( & htcap , 0 , sizeof ( htcap ) ) ;
if ( UAP_SUCCESS ! = get_sys_cfg_11n ( & htcap ) ) {
printf ( " ERR: Reading current 11n configuration. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_htcap_t ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append HT Cap TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_htcap_t * ) ( buffer + cmd_len ) ;
tlv_offset_11n = cmd_len ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = HT_CAPABILITY_TLV_ID ;
tlv - > length = sizeof ( HTCap_t ) ;
memcpy ( & tlv - > ht_cap , & htcap , sizeof ( HTCap_t ) ) ;
if ( enable_11n = = 1 ) {
/* enable mcs rate */
tlv - > ht_cap . supported_mcs_set [ 0 ] =
DEFAULT_MCS_SET_0 ;
tlv - > ht_cap . supported_mcs_set [ 4 ] =
DEFAULT_MCS_SET_4 ;
if ( 0 = = get_fw_info ( & fw ) ) {
if ( ( fw . hw_dev_mcs_support & 0x0f ) > = 2 )
tlv - > ht_cap .
supported_mcs_set [ 1 ] =
DEFAULT_MCS_SET_1 ;
}
} else {
/* disable mcs rate */
tlv - > ht_cap . supported_mcs_set [ 0 ] = 0 ;
tlv - > ht_cap . supported_mcs_set [ 4 ] = 0 ;
tlv - > ht_cap . supported_mcs_set [ 1 ] = 0 ;
}
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " HTCapInfo " ) = = 0 ) {
if ( enable_11n < = 0 ) {
printf ( " ERR: Enable11n parameter should be set before HTCapInfo. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( ( IS_HEX_OR_DIGIT ( args [ 1 ] ) = = UAP_FAILURE ) | |
( ( ( ( t_u16 ) A2HEXDECIMAL ( args [ 1 ] ) ) &
( ~ HT_CAP_CONFIG_MASK ) ) ! = HT_CAP_CHECK_MASK ) ) {
printf ( " ERR: Invalid HTCapInfo value \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
/* Find HT tlv pointer in buffer and set HTCapInfo */
tlvbuf_htcap_t * tlv = NULL ;
tlv = ( tlvbuf_htcap_t * ) ( buffer + tlv_offset_11n ) ;
tlv - > ht_cap . ht_cap_info =
DEFAULT_HT_CAP_VALUE & ~ HT_CAP_CONFIG_MASK ;
tlv - > ht_cap . ht_cap_info | =
( t_u16 ) A2HEXDECIMAL ( args [ 1 ] ) &
HT_CAP_CONFIG_MASK ;
tlv - > ht_cap . ht_cap_info =
uap_cpu_to_le16 ( tlv - > ht_cap . ht_cap_info ) ;
}
if ( strcmp ( args [ 0 ] , " AMPDU " ) = = 0 ) {
if ( enable_11n < = 0 ) {
printf ( " ERR: Enable11n parameter should be set before AMPDU. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( ( IS_HEX_OR_DIGIT ( args [ 1 ] ) = = UAP_FAILURE ) | |
( ( A2HEXDECIMAL ( args [ 1 ] ) ) > AMPDU_CONFIG_MASK ) ) {
printf ( " ERR: Invalid AMPDU value \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
/* Find HT tlv pointer in buffer and set AMPDU */
tlvbuf_htcap_t * tlv = NULL ;
tlv = ( tlvbuf_htcap_t * ) ( buffer + tlv_offset_11n ) ;
tlv - > ht_cap . ampdu_param =
( t_u8 ) A2HEXDECIMAL ( args [ 1 ] ) & AMPDU_CONFIG_MASK ;
}
if ( strcmp ( args [ 0 ] , " HT_MCS_MAP " ) = = 0 ) {
if ( enable_11n < = 0 ) {
printf ( " ERR: Enable11n parameter should be set before HT_MCS_MAP. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( 0 = = get_fw_info ( & fw ) ) {
/* Check upper nibble of MCS support value
* and block MCS_SET_1 when 2 X2 is not supported
* by the underlying hardware */
if ( ( ( fw . hw_dev_mcs_support & 0xf0 ) <
STREAM_2X2_MASK ) & &
( A2HEXDECIMAL ( args [ 1 ] ) & MCS_SET_1_MASK ) ) {
printf ( " ERR: Invalid HT_MCS_MAP \n " ) ;
goto done ;
}
}
/* Find HT tlv pointer in buffer and set supported MCS set */
tlvbuf_htcap_t * tlv = NULL ;
tlv = ( tlvbuf_htcap_t * ) ( buffer + tlv_offset_11n ) ;
supported_mcs_set = ( t_u32 ) A2HEXDECIMAL ( args [ 1 ] ) ;
supported_mcs_set = uap_cpu_to_le32 ( supported_mcs_set ) ;
memcpy ( tlv - > ht_cap . supported_mcs_set ,
& supported_mcs_set , sizeof ( t_u32 ) ) ;
}
if ( strcmp ( args [ 0 ] , " Enable2040Coex " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) | |
( atoi ( args [ 1 ] ) > 1 ) ) {
printf ( " ERR: Invalid Enable2040Coex value \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
tlvbuf_2040_coex * tlv = NULL ;
/* Append a new TLV */
tlv_len = sizeof ( tlvbuf_2040_coex ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append 2040 coex TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_2040_coex * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_2040_BSS_COEX_CONTROL_TLV_ID ;
tlv - > length = 1 ;
tlv - > enable = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
if ( strcmp ( args [ 0 ] , " PreambleType " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) | |
( atoi ( args [ 1 ] ) > 2 ) ) {
printf ( " ERR: Invalid PreambleType value \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
/* Append a new TLV */
tlvbuf_preamble_ctl * tlv = NULL ;
tlv_len = sizeof ( tlvbuf_preamble_ctl ) ;
tmp_buffer = realloc ( buffer , cmd_len + tlv_len ) ;
if ( ! tmp_buffer ) {
printf ( " ERR:Cannot append preamble type TLV! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
} else {
buffer = tmp_buffer ;
tmp_buffer = NULL ;
}
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_preamble_ctl * ) ( buffer + cmd_len ) ;
cmd_len + = tlv_len ;
/* Set TLV fields */
tlv - > tag = MRVL_PREAMBLE_CTL_TLV_ID ;
tlv - > length = 1 ;
tlv - > preamble_type = ( t_u8 ) atoi ( args [ 1 ] ) ;
endian_convert_tlv_header_out ( tlv ) ;
}
# if DEBUG
if ( cmd_len ! = 0 ) {
hexdump ( " Command Buffer " , ( void * ) cmd_buf , cmd_len ,
' ' ) ;
}
# endif
}
done :
fclose ( config_file ) ;
if ( buffer )
free ( buffer ) ;
if ( line )
free ( line ) ;
return ret ;
}
/**
* @ brief Get band from current channel
* @ param band
* @ return UAP_SUCCESS / UAP_FAILURE
*/
static int
get_band ( int * band )
{
apcmdbuf_sys_configure * cmd_buf = NULL ;
tlvbuf_channel_config * tlv = NULL ;
t_u8 * buffer = NULL ;
t_u16 cmd_len ;
int ret = UAP_SUCCESS ;
/* Initialize the command length */
cmd_len =
sizeof ( apcmdbuf_sys_configure ) + sizeof ( tlvbuf_channel_config ) ;
/* Initialize the command buffer */
buffer = ( t_u8 * ) malloc ( cmd_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
memset ( buffer , 0 , cmd_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_channel_config * ) ( buffer +
sizeof ( apcmdbuf_sys_configure ) ) ;
/* Fill the command buffer */
cmd_buf - > cmd_code = APCMD_SYS_CONFIGURE ;
cmd_buf - > size = cmd_len ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
tlv - > tag = MRVL_CHANNELCONFIG_TLV_ID ;
tlv - > length = sizeof ( tlvbuf_channel_config ) - TLVHEADER_LEN ;
cmd_buf - > action = ACTION_GET ;
endian_convert_tlv_header_out ( tlv ) ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , cmd_len ) ;
endian_convert_tlv_header_in ( tlv ) ;
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( ( cmd_buf - > cmd_code ! =
( APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK ) ) | |
( tlv - > tag ! = MRVL_CHANNELCONFIG_TLV_ID ) ) {
printf ( " ERR:Corrupted response! cmd_code=%x, Tlv->tag=%x \n " , cmd_buf - > cmd_code , tlv - > tag ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( cmd_buf - > result = = CMD_SUCCESS ) {
if ( tlv - > chan_number > MAX_CHANNELS_BG )
* band = BAND_A ;
else
* band = BAND_B | BAND_G ;
} else {
printf ( " ERR:Could not get band! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
done :
if ( buffer )
free ( buffer ) ;
return ret ;
}
/**
* @ brief Show usage information for the cfg_80211d command
*
* $ return N / A
*/
void
print_apcmd_cfg_80211d_usage ( void )
{
printf ( " \n Usage: cfg_80211d <state 0/1> <country Country_code> \n " ) ;
return ;
}
/**
* @ brief Show usage information for the uap_stats command
*
* $ return N / A
*/
void
print_apcmd_uap_stats ( void )
{
printf ( " Usage: uap_stats \n " ) ;
return ;
}
/**
* SNMP MIB OIDs Table
*/
static oids_table snmp_oids [ ] = {
{ 0x0b , 4 , " dot11LocalTKIPMICFailures " } ,
{ 0x0c , 4 , " dot11CCMPDecryptErrors " } ,
{ 0x0d , 4 , " dot11WEPUndecryptableCount " } ,
{ 0x0e , 4 , " dot11WEPICVErrorCount " } ,
{ 0x0f , 4 , " dot11DecryptFailureCount " } ,
{ 0x12 , 4 , " dot11FailedCount " } ,
{ 0x13 , 4 , " dot11RetryCount " } ,
{ 0x14 , 4 , " dot11MultipleRetryCount " } ,
{ 0x15 , 4 , " dot11FrameDuplicateCount " } ,
{ 0x16 , 4 , " dot11RTSSuccessCount " } ,
{ 0x17 , 4 , " dot11RTSFailureCount " } ,
{ 0x18 , 4 , " dot11ACKFailureCount " } ,
{ 0x19 , 4 , " dot11ReceivedFragmentCount " } ,
{ 0x1a , 4 , " dot11MulticastReceivedFrameCount " } ,
{ 0x1b , 4 , " dot11FCSErrorCount " } ,
{ 0x1c , 4 , " dot11TransmittedFrameCount " } ,
{ 0x1d , 4 , " dot11RSNATKIPCounterMeasuresInvoked " } ,
{ 0x1e , 4 , " dot11RSNA4WayHandshakeFailures " } ,
{ 0x1f , 4 , " dot11MulticastTransmittedFrameCount " }
} ;
/**
* @ brief Get uAP stats
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
*
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_uap_stats ( int argc , char * argv [ ] )
{
t_u8 no_of_oids = sizeof ( snmp_oids ) / sizeof ( snmp_oids [ 0 ] ) ;
t_u16 i , j ;
int size ;
apcmdbuf_snmp_mib * cmd_buf = NULL ;
t_u8 * buf = NULL ;
tlvbuf_header * tlv = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int opt ;
t_u16 oid_size , byte2 = 0 ;
t_u32 byte4 = 0 ;
int ret = UAP_SUCCESS ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_apcmd_uap_stats ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
if ( argc ) {
printf ( " Error: Invalid Input \n " ) ;
print_apcmd_uap_stats ( ) ;
return UAP_FAILURE ;
}
/** Command Header */
cmd_len + = sizeof ( apcmdbuf_snmp_mib ) ;
for ( i = 0 ; i < no_of_oids ; i + + ) {
/**
* Size of Oid + Oid_value + Oid_size
*/
cmd_len + = snmp_oids [ i ] . len + sizeof ( tlvbuf_header ) ;
}
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate Headers */
cmd_buf = ( apcmdbuf_snmp_mib * ) buf ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > result = 0 ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > cmd_code = HostCmd_SNMP_MIB ;
cmd_buf - > action = uap_cpu_to_le16 ( ACTION_GET ) ;
tlv = ( tlvbuf_header * ) ( ( t_u8 * ) cmd_buf + sizeof ( apcmdbuf_snmp_mib ) ) ;
/* Add oid, oid_size and oid_value for each OID */
for ( i = 0 ; i < no_of_oids ; i + + ) {
/** Copy Index as Oid */
tlv - > type = uap_cpu_to_le16 ( snmp_oids [ i ] . type ) ;
/** Copy its size */
tlv - > len = uap_cpu_to_le16 ( snmp_oids [ i ] . len ) ;
/** Next TLV */
tlv = ( tlvbuf_header * ) & ( tlv - > data [ snmp_oids [ i ] . len ] ) ;
}
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result = = CMD_SUCCESS ) {
tlv = ( tlvbuf_header * ) ( ( t_u8 * ) cmd_buf +
sizeof ( apcmdbuf_snmp_mib ) ) ;
size = cmd_buf - > size - ( sizeof ( apcmdbuf_snmp_mib ) -
BUF_HEADER_SIZE ) ;
while ( ( unsigned int ) size > = sizeof ( tlvbuf_header ) ) {
tlv - > type = uap_le16_to_cpu ( tlv - > type ) ;
for ( i = 0 ; i < no_of_oids ; i + + ) {
if ( snmp_oids [ i ] . type = = tlv - > type ) {
printf ( " %s: " ,
snmp_oids [ i ] . name ) ;
break ;
}
}
oid_size = uap_le16_to_cpu ( tlv - > len ) ;
switch ( oid_size ) {
case 1 :
printf ( " %d " ,
( unsigned int ) tlv - > data [ 0 ] ) ;
break ;
case 2 :
memcpy ( & byte2 , & tlv - > data [ 0 ] ,
sizeof ( oid_size ) ) ;
printf ( " %d " ,
( unsigned int )
uap_le16_to_cpu ( byte2 ) ) ;
break ;
case 4 :
memcpy ( & byte4 , & tlv - > data [ 0 ] ,
sizeof ( oid_size ) ) ;
printf ( " %d " ,
( unsigned int )
uap_le32_to_cpu ( byte4 ) ) ;
break ;
default :
for ( j = 0 ; j < oid_size ; j + + ) {
printf ( " %d " ,
( t_u8 ) tlv - > data [ j ] ) ;
}
break ;
}
/** Next TLV */
tlv = ( tlvbuf_header * ) & ( tlv - > data [ oid_size ] ) ;
size - = ( sizeof ( tlvbuf_header ) + oid_size ) ;
size = ( size > 0 ) ? size : 0 ;
printf ( " \n " ) ;
}
} else {
printf ( " ERR:Command Response incorrect! \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
free ( buf ) ;
return ret ;
}
/**
* @ brief parser for sys_cfg_80211d input
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ param output Stores indexes for " state, country "
* arguments
*
* @ return NA
*
*/
static void
parse_input_80211d ( int argc , char * * argv , int output [ 2 ] [ 2 ] )
{
int i , j , k = 0 ;
char * keywords [ 2 ] = { " state " , " country " } ;
for ( i = 0 ; i < 2 ; i + + )
output [ i ] [ 0 ] = - 1 ;
for ( i = 0 ; i < argc ; i + + ) {
for ( j = 0 ; j < 2 ; j + + ) {
if ( strcmp ( argv [ i ] , keywords [ j ] ) = = 0 ) {
output [ j ] [ 1 ] = output [ j ] [ 0 ] = i ;
k = j ;
break ;
}
}
output [ k ] [ 1 ] + = 1 ;
}
}
/**
* @ brief Set / Get 802.11 D country information
*
* Usage : cfg_80211d state country_code
*
* State 0 or 1
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_cfg_80211d ( int argc , char * argv [ ] )
{
apcmdbuf_cfg_80211d * cmd_buf = NULL ;
ieeetypes_subband_set_t * subband = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int output [ 2 ] [ 2 ] ;
int ret = UAP_SUCCESS ;
int opt ;
int status = 0 ;
int i , j ;
t_u8 state = 0 ;
char country [ 4 ] = { ' ' , ' ' , 0 , 0 } ;
t_u8 sflag = 0 , cflag = 0 ;
ieeetypes_subband_set_t sub_bands [ MAX_SUB_BANDS ] ;
t_u8 no_of_sub_band = 0 ;
int band ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
if ( argc ) {
if ( strcmp ( argv [ 0 ] , " state " ) & & strcmp ( argv [ 0 ] , " country " ) ) {
printf ( " ERR: Incorrect input. Either state or country is needed. " ) ;
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_FAILURE ;
}
/** SET */
parse_input_80211d ( argc , argv , output ) ;
/** State */
if ( ( output [ 0 ] [ 0 ] ! = - 1 ) & & ( output [ 0 ] [ 1 ] > output [ 0 ] [ 0 ] ) ) {
if ( ( output [ 0 ] [ 1 ] - output [ 0 ] [ 0 ] ) ! = 2 ) {
printf ( " ERR: Invalid state inputs \n " ) ;
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_FAILURE ;
}
if ( IS_HEX_OR_DIGIT ( argv [ output [ 0 ] [ 0 ] + 1 ] ) = =
UAP_FAILURE ) {
printf ( " ERR: valid input for state are 0 or 1 \n " ) ;
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_FAILURE ;
}
state = ( t_u8 ) A2HEXDECIMAL ( argv [ output [ 0 ] [ 0 ] + 1 ] ) ;
if ( ( state ! = 0 ) & & ( state ! = 1 ) ) {
printf ( " ERR: valid input for state are 0 or 1 \n " ) ;
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_FAILURE ;
}
sflag = 1 ;
}
/** Country */
if ( ( output [ 1 ] [ 0 ] ! = - 1 ) & & ( output [ 1 ] [ 1 ] > output [ 1 ] [ 0 ] ) ) {
if ( ( output [ 1 ] [ 1 ] - output [ 1 ] [ 0 ] ) ! = 2 ) {
printf ( " ERR: Invalid country inputs \n " ) ;
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_FAILURE ;
}
if ( ( strlen ( argv [ output [ 1 ] [ 0 ] + 1 ] ) > 3 ) | |
( strlen ( argv [ output [ 1 ] [ 0 ] + 1 ] ) = = 0 ) ) {
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_FAILURE ;
}
/* Only 2 characters of country code are copied here as indoor/outdoor
* conditions are not handled in domain file */
strncpy ( country , argv [ output [ 1 ] [ 0 ] + 1 ] , 2 ) ;
for ( i = 0 ; ( unsigned int ) i < strlen ( country ) ; i + + ) {
if ( ( country [ i ] < ' A ' ) | | ( country [ i ] > ' z ' ) ) {
printf ( " Invalid Country Code \n " ) ;
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_FAILURE ;
}
if ( country [ i ] > ' Z ' )
country [ i ] = country [ i ] - ' a ' + ' A ' ;
}
cflag = 1 ;
if ( ! get_band ( & band ) ) {
printf ( " ERR:couldn't get band from channel! \n " ) ;
return UAP_FAILURE ;
}
/** Get domain information from the file */
no_of_sub_band =
parse_domain_file ( country , band , sub_bands ,
NULL ) ;
if ( no_of_sub_band = = UAP_FAILURE ) {
printf ( " Parsing Failed \n " ) ;
return UAP_FAILURE ;
}
}
if ( get_bss_status ( & status ) ! = UAP_SUCCESS ) {
printf ( " ERR:Cannot get current bss status! \n " ) ;
return UAP_FAILURE ;
}
if ( status = = UAP_BSS_START ) {
printf ( " ERR: 11d status can not be changed after BSS start! \n " ) ;
return UAP_FAILURE ;
}
}
if ( argc & & ! cflag & & ! sflag ) {
printf ( " ERR: Invalid input \n " ) ;
print_apcmd_cfg_80211d_usage ( ) ;
return UAP_FAILURE ;
}
if ( sflag & & ! cflag ) {
/**
* Update MIB only and return
*/
if ( sg_snmp_mib
( ACTION_SET , OID_80211D_ENABLE , sizeof ( state ) ,
& state ) = = UAP_SUCCESS ) {
printf ( " 802.11d %sd \n " , state ? " enable " : " disable " ) ;
return UAP_SUCCESS ;
} else {
return UAP_FAILURE ;
}
}
cmd_len = sizeof ( apcmdbuf_cfg_80211d ) ;
if ( cflag ) {
cmd_len + = no_of_sub_band * sizeof ( ieeetypes_subband_set_t ) ;
} else {
/** Get */
cmd_len + = MAX_SUB_BANDS * sizeof ( ieeetypes_subband_set_t ) ;
}
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_cfg_80211d * ) buf ;
cmd_len = argc ? cmd_len :
/** Set */
( sizeof ( apcmdbuf_cfg_80211d ) - sizeof ( domain_param_t ) ) ;
/** Get */
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > result = 0 ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > action = argc ? ACTION_SET : ACTION_GET ;
cmd_buf - > action = uap_cpu_to_le16 ( cmd_buf - > action ) ;
cmd_buf - > cmd_code = HostCmd_CMD_802_11D_DOMAIN_INFO ;
if ( cflag ) {
/* third character of country code is copied here as indoor/outdoor
* condition is not supported in domain file */
strncpy ( country , argv [ output [ 1 ] [ 0 ] + 1 ] , sizeof ( country ) - 1 ) ;
for ( i = 0 ; ( unsigned int ) i < strlen ( country ) ; i + + ) {
if ( ( country [ i ] < ' A ' ) | | ( country [ i ] > ' z ' ) ) {
printf ( " Invalid Country Code \n " ) ;
print_apcmd_cfg_80211d_usage ( ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
if ( country [ i ] > ' Z ' )
country [ i ] = country [ i ] - ' a ' + ' A ' ;
}
cmd_buf - > domain . tag = uap_cpu_to_le16 ( TLV_TYPE_DOMAIN ) ;
cmd_buf - > domain . length = uap_cpu_to_le16 ( sizeof ( domain_param_t )
- BUF_HEADER_SIZE
+
( no_of_sub_band *
sizeof
( ieeetypes_subband_set_t ) ) ) ;
memset ( cmd_buf - > domain . country_code , ' ' ,
sizeof ( cmd_buf - > domain . country_code ) ) ;
memcpy ( cmd_buf - > domain . country_code , country , strlen ( country ) ) ;
memcpy ( cmd_buf - > domain . subband , sub_bands ,
no_of_sub_band * sizeof ( ieeetypes_subband_set_t ) ) ;
}
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result = = CMD_SUCCESS ) {
if ( argc ) {
printf ( " Set executed successfully \n " ) ;
if ( sflag ) {
if ( sg_snmp_mib
( ACTION_SET , OID_80211D_ENABLE ,
sizeof ( state ) ,
& state ) = = UAP_SUCCESS ) {
printf ( " 802.11d %sd \n " ,
state ? " enable " :
" disable " ) ;
}
}
} else {
j = uap_le16_to_cpu ( cmd_buf - > domain . length ) ;
if ( sg_snmp_mib
( ACTION_GET , OID_80211D_ENABLE ,
sizeof ( state ) , & state )
= = UAP_SUCCESS ) {
printf ( " State = %sd \n " ,
state ? " enable " : " disable " ) ;
}
if ( cmd_buf - > domain . country_code [ 0 ] | |
cmd_buf - > domain . country_code [ 1 ] | |
cmd_buf - > domain . country_code [ 2 ] ) {
printf ( " Country string = %c%c%c " ,
cmd_buf - > domain . country_code [ 0 ] ,
cmd_buf - > domain . country_code [ 1 ] ,
cmd_buf - > domain . country_code [ 2 ] ) ;
j - = sizeof ( cmd_buf - > domain .
country_code ) ;
subband =
( ieeetypes_subband_set_t * )
cmd_buf - > domain . subband ;
printf ( " \n Sub-band info= " ) ;
printf ( " \t (1st, #chan, MAX-power) \n " ) ;
for ( i = 0 ; i < ( j / 3 ) ; i + + ) {
printf ( " \t \t (%d, \t %d, \t %d dbm) \n " , subband - > first_chan , subband - > no_of_chan , subband - > max_tx_pwr ) ;
subband + + ;
}
}
}
} else {
printf ( " ERR:Command Response incorrect! \n " ) ;
if ( argc )
printf ( " 11d info is allowed to set only before bss start. \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
free ( buf ) ;
return ret ;
}
/**
* @ brief Creates a sys_config request and sends to the driver
*
* Usage : " Usage : sys_config [CONFIG_FILE] "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_sys_config ( int argc , char * argv [ ] )
{
apcmdbuf_sys_configure * cmd_buf = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len ;
t_u16 buf_len ;
int ret = UAP_SUCCESS ;
int opt ;
char * * argv_dummy = NULL ;
ps_mgmt pm ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_sys_config_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc > 1 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_sys_config_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc = = 1 ) {
/* Read profile and send command to firmware */
ret = apcmd_sys_config_profile ( argc , argv ) ;
return ret ;
}
/** Query AP's setting */
buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
/* Alloc buf for command */
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Reset custom_ie_present flag */
custom_ie_present = 0 ;
/* Reset max_mgmt_ie_print flag */
max_mgmt_ie_print = 0 ;
/* Locate headers */
cmd_len = sizeof ( apcmdbuf_sys_configure ) ;
cmd_buf = ( apcmdbuf_sys_configure * ) buf ;
/* Fill the command buffer */
cmd_buf - > cmd_code = APCMD_SYS_CONFIGURE ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( cmd_buf - > cmd_code ! =
( APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK ) ) {
printf ( " ERR:Corrupted response! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
/* Print response */
if ( cmd_buf - > result = = CMD_SUCCESS ) {
printf ( " AP settings: \n " ) ;
print_tlv ( buf + sizeof ( apcmdbuf_sys_configure ) ,
cmd_buf - > size -
sizeof ( apcmdbuf_sys_configure ) +
BUF_HEADER_SIZE ) ;
if ( apcmd_addbapara ( 1 , argv_dummy ) = = UAP_FAILURE ) {
printf ( " Couldn't get ADDBA parameters \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
if ( apcmd_aggrpriotbl ( 1 , argv_dummy ) = = UAP_FAILURE ) {
printf ( " Couldn't get AMSDU/AMPDU priority table \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
if ( apcmd_addbareject ( 1 , argv_dummy ) = = UAP_FAILURE ) {
printf ( " Couldn't get ADDBA reject table \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
printf ( " \n 802.11D setting: \n " ) ;
if ( apcmd_cfg_80211d ( 1 , argv_dummy ) = = UAP_FAILURE ) {
free ( buf ) ;
return UAP_FAILURE ;
}
if ( ! custom_ie_present ) {
printf ( " \n Custom IE settings: \n " ) ;
if ( apcmd_sys_cfg_custom_ie ( 1 , argv_dummy ) = =
UAP_FAILURE ) {
free ( buf ) ;
return UAP_FAILURE ;
}
}
} else {
printf ( " ERR:Could not retrieve system configure \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
free ( buf ) ;
memset ( & pm , 0 , sizeof ( ps_mgmt ) ) ;
ret = send_power_mode_ioctl ( & pm , 0 ) ;
return ret ;
}
/** Update domain info with given country and band
*
* @ param country_80211d country to be set
* @ param band band of operation
* @ return UAP_SUCCESS / UAP_FAILURE
*/
static int
update_domain_info ( char * country_80211d , int band )
{
apcmdbuf_cfg_80211d * cmd_buf = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
ieeetypes_subband_set_t sub_bands [ MAX_SUB_BANDS ] ;
t_u8 no_of_sub_band = 0 ;
char country [ 4 ] = { ' ' , ' ' , 0 , 0 } ;
int ret = UAP_SUCCESS ;
t_u8 domain_code = 0 ;
rgn_dom_code_t * prgn_dom_code = NULL ;
/* Get currently set country code from FW */
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_cfg_80211d * ) buf ;
cmd_len = ( sizeof ( apcmdbuf_cfg_80211d ) - sizeof ( domain_param_t ) ) ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > result = 0 ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > action = ACTION_GET ;
cmd_buf - > action = uap_cpu_to_le16 ( cmd_buf - > action ) ;
cmd_buf - > cmd_code = HostCmd_CMD_802_11D_DOMAIN_INFO ;
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
if ( ( ret = = UAP_SUCCESS ) & & ( cmd_buf - > result = = CMD_SUCCESS ) & &
( cmd_buf - > domain . country_code [ 0 ] | |
cmd_buf - > domain . country_code [ 1 ] | |
cmd_buf - > domain . country_code [ 2 ] ) ) {
country [ 0 ] = cmd_buf - > domain . country_code [ 0 ] ;
country [ 1 ] = cmd_buf - > domain . country_code [ 1 ] ;
} else {
/* country_80211d will only be used if country code is not already set */
country [ 0 ] = country_80211d [ 0 ] ;
country [ 1 ] = country_80211d [ 1 ] ;
}
if ( band = = BAND_A )
printf ( " Enabling 11d for 11h operation and setting country code to %s \n " , country ) ;
cmd_len = sizeof ( apcmdbuf_cfg_80211d ) ;
/** Get domain information from the file */
no_of_sub_band =
parse_domain_file ( country , band , sub_bands , & domain_code ) ;
if ( no_of_sub_band = = UAP_FAILURE ) {
printf ( " Parsing Failed \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
/* Copy third character of country code here */
if ( cmd_buf - > domain . country_code [ 2 ] ) {
country [ 2 ] = cmd_buf - > domain . country_code [ 2 ] ;
} else {
country [ 2 ] = country_80211d [ 2 ] ;
}
/* Set domain for this country code */
memset ( buf , 0 , buf_len ) ;
cmd_len + = no_of_sub_band * sizeof ( ieeetypes_subband_set_t ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_cfg_80211d * ) buf ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > result = 0 ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > action = ACTION_SET ;
cmd_buf - > action = uap_cpu_to_le16 ( cmd_buf - > action ) ;
cmd_buf - > cmd_code = HostCmd_CMD_802_11D_DOMAIN_INFO ;
cmd_buf - > domain . tag = uap_cpu_to_le16 ( TLV_TYPE_DOMAIN ) ;
cmd_buf - > domain . length = uap_cpu_to_le16 ( sizeof ( domain_param_t )
- BUF_HEADER_SIZE
+
( no_of_sub_band *
sizeof
( ieeetypes_subband_set_t ) ) ) ;
memset ( cmd_buf - > domain . country_code , ' ' ,
sizeof ( cmd_buf - > domain . country_code ) ) ;
memcpy ( cmd_buf - > domain . country_code , country , strlen ( country ) ) ;
memcpy ( cmd_buf - > domain . subband , sub_bands ,
no_of_sub_band * sizeof ( ieeetypes_subband_set_t ) ) ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result ! = CMD_SUCCESS ) {
printf ( " ERR:Command Response incorrect! \n " ) ;
printf ( " 11d info is allowed to set only before bss start. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
if ( ( band = = BAND_A ) & & domain_code ) {
/* Send 11D_CMD a second time, with reg_dom_code TLV appended.
* Use hostcmd instead of re - route . */
cmd_len = cmd_buf - > size + BUF_HEADER_SIZE ;
prgn_dom_code = ( rgn_dom_code_t * ) ( ( t_u8 * ) cmd_buf + cmd_len ) ;
cmd_len + = sizeof ( rgn_dom_code_t ) ;
cmd_buf - > size + = sizeof ( rgn_dom_code_t ) ;
# if DEBUG
uap_printf ( MSG_DEBUG ,
" Adding Region Domain Code TLV. Domain_code=%d \n " ,
domain_code ) ;
# endif
prgn_dom_code - > tag =
uap_cpu_to_le16 ( MRVL_REGION_DOMAIN_CODE_TLV_ID ) ;
prgn_dom_code - > length = uap_cpu_to_le16 ( sizeof ( rgn_dom_code_t )
- BUF_HEADER_SIZE ) ;
prgn_dom_code - > domain_code = domain_code ;
/* Send the command */
uap_ioctl_no_reroute = 1 ;
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
uap_ioctl_no_reroute = 0 ;
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result ! = CMD_SUCCESS ) {
printf ( " ERR:Command Response incorrect! \n " ) ;
printf ( " 11d info is allowed to set only before bss start. \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
}
done :
if ( buf )
free ( buf ) ;
return ret ;
}
/**
* @ brief Covert MCS Rate Bitmap to MCS Rate index
*
* @ param rate_bitmap Pointer to rate bitmap
* @ param size Size of the bitmap array
*
* @ return Rate index
*/
int
get_rate_index_from_bitmap ( t_u16 * rate_bitmap , int size )
{
int i ;
for ( i = 0 ; i < size * 8 ; i + + ) {
if ( rate_bitmap [ i / 16 ] & ( 1 < < ( i % 16 ) ) ) {
return i ;
}
}
return 0 ;
}
/**
* @ brief Checks current system configuration
*
* @ param buf pointer to TLV buffer
* @ param len TLV buffer length
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
check_sys_config ( t_u8 * buf , t_u16 len )
{
tlvbuf_header * pcurrent_tlv = ( tlvbuf_header * ) buf ;
int tlv_buf_left = len ;
t_u16 tlv_type ;
t_u16 tlv_len ;
tlvbuf_channel_config * channel_tlv = NULL ;
tlvbuf_channel_list * chnlist_tlv = NULL ;
tlvbuf_pwk_cipher * pwk_cipher_tlv = NULL ;
tlvbuf_gwk_cipher * gwk_cipher_tlv = NULL ;
tlvbuf_auth_mode * auth_tlv = NULL ;
tlvbuf_protocol * protocol_tlv = NULL ;
tlvbuf_wep_key * wep_key_tlv = NULL ;
tlvbuf_wpa_passphrase * passphrase_tlv = NULL ;
tlvbuf_rates * rates_tlv = NULL ;
tlvbuf_mcbc_data_rate * mcbc_data_rate_tlv = NULL ;
t_u16 protocol = 0 ;
t_u16 mcbc_data_rate = 0 ;
t_u16 op_rates_len = 0 ;
t_u8 acs_mode_enabled = 0 ;
t_u8 * cbuf = NULL ;
apcmdbuf_cfg_80211d * cmd_buf = NULL ;
t_u16 buf_len , cmd_len ;
char country_80211d [ 4 ] = { ' U ' , ' S ' , ' ' , 0 } ;
t_u8 state_80211h = 0 ;
int channel_tlv_band = BAND_B | BAND_G ;
t_u8 secondary_ch_set = 0 ;
int scan_channels_band = BAND_B | BAND_G ;
t_u8 state_80211d = 0 ;
t_u8 rate = 0 ;
t_u32 rate_bitmap = 0 ;
tlvbuf_htcap_t * ht_cap_tlv = NULL ;
t_u16 enable_40Mhz = 0 ;
t_u16 enable_20Mhz_sgi = 0 ;
t_u16 enable_gf = 0 ;
t_u8 enable_11n = 0 ;
int flag = 0 ;
fw_info fw ;
channel_list * pchan_list ;
tlvbuf_tx_power * txpower_tlv = NULL ;
int i = 0 , ret = UAP_SUCCESS ;
int pairwise_cipher_wpa = - 1 ;
int pairwise_cipher_wpa2 = - 1 ;
int group_cipher = - 1 ;
int chan_list_len = 0 ;
int key_set = 0 ;
t_u8 channel = 0 ;
tx_rate_cfg_t tx_rate_config ;
t_u32 mcs_rate_index = 0 ;
struct eth_priv_vhtcfg vhtcfg = { 0 } ;
# define BITMAP_RATE_1M 0x01
# define BITMAP_RATE_2M 0x02
# define BITMAP_RATE_5_5M 0x04
# define BITMAP_RATE_11M 0x8
# define B_RATE_MANDATORY 0x0f
if ( pcurrent_tlv = = NULL ) {
printf ( " ERR: No TLV buffer available! \n " ) ;
return UAP_FAILURE ;
}
ret = sg_snmp_mib ( ACTION_GET , OID_80211D_ENABLE , sizeof ( state_80211d ) ,
& state_80211d ) ;
buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
cbuf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! cbuf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( cbuf , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_cfg_80211d * ) cbuf ;
cmd_len = ( sizeof ( apcmdbuf_cfg_80211d ) - sizeof ( domain_param_t ) ) ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > action = uap_cpu_to_le16 ( ACTION_GET ) ;
cmd_buf - > cmd_code = HostCmd_CMD_802_11D_DOMAIN_INFO ;
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
if ( ret = = UAP_SUCCESS & & cmd_buf - > result = = CMD_SUCCESS ) {
if ( cmd_buf - > domain . country_code [ 0 ] | |
cmd_buf - > domain . country_code [ 1 ] | |
cmd_buf - > domain . country_code [ 2 ] ) {
strncpy ( country_80211d ,
( char * ) cmd_buf - > domain . country_code ,
COUNTRY_CODE_LEN ) ;
}
}
free ( cbuf ) ;
/* get region code to handle special cases */
memset ( & fw , 0 , sizeof ( fw ) ) ;
if ( get_fw_info ( & fw ) ) {
printf ( " Could not get fw info! \n " ) ;
return UAP_FAILURE ;
}
if ( get_tx_rate_cfg ( & tx_rate_config ) = = UAP_FAILURE ) {
printf ( " Could not get tx_rate_cfg! \n " ) ;
return UAP_FAILURE ;
}
while ( tlv_buf_left > = ( int ) sizeof ( tlvbuf_header ) & &
( ret ! = UAP_FAILURE ) ) {
tlv_type = * ( t_u8 * ) & pcurrent_tlv - > type ;
tlv_type | = ( * ( ( t_u8 * ) & pcurrent_tlv - > type + 1 ) < < 8 ) ;
tlv_len = * ( t_u8 * ) & pcurrent_tlv - > len ;
tlv_len | = ( * ( ( t_u8 * ) & pcurrent_tlv - > len + 1 ) < < 8 ) ;
if ( ( sizeof ( tlvbuf_header ) + tlv_len ) >
( unsigned int ) tlv_buf_left ) {
printf ( " wrong tlv: tlv_len=%d, tlv_buf_left=%d \n " ,
tlv_len , tlv_buf_left ) ;
break ;
}
switch ( tlv_type ) {
case MRVL_CHANNELCONFIG_TLV_ID :
channel_tlv = ( tlvbuf_channel_config * ) pcurrent_tlv ;
channel = channel_tlv - > chan_number ;
if ( ( ! state_80211d ) & &
( channel_tlv - > chan_number = = MAX_CHANNELS_BG )
& &
( strncmp ( country_80211d , " JP " , COUNTRY_CODE_LEN - 1 )
= = 0 )
) {
printf ( " ERR: Invalid channel 14, 802.11d disabled, country code JP! \n " ) ;
return UAP_FAILURE ;
}
if ( channel_tlv - > bandcfg . chanBand = = BAND_5GHZ )
channel_tlv_band = BAND_A ;
secondary_ch_set = channel_tlv - > bandcfg . chan2Offset ;
if ( channel_tlv_band ! = BAND_A ) {
/* When country code is not Japan, allow channels 5-11 for US and 5-13 for non-US
* only for secondary channel below */
if ( secondary_ch_set = = SEC_CHAN_BELOW ) {
if ( ! strncmp
( country_80211d , " US " ,
COUNTRY_CODE_LEN - 1 ) ) {
if ( channel_tlv - > chan_number >
DEFAULT_MAX_CHANNEL_BELOW ) {
printf ( " ERR: Only channels 5-11 are allowed with secondary channel below for the US \n " ) ;
return UAP_FAILURE ;
}
} else if ( strncmp
( country_80211d , " JP " ,
COUNTRY_CODE_LEN - 1 ) ) {
if ( channel_tlv - > chan_number >
DEFAULT_MAX_CHANNEL_BELOW_NON_US )
{
printf ( " ERR: Only channels 5-13 are allowed with secondary channel below for " " non-Japan countries! \n " ) ;
return UAP_FAILURE ;
}
}
}
/* When country code is not Japan, allow channels 1-7 for US and 1-9 for non-US
* only for secondary channel above */
if ( secondary_ch_set = = SEC_CHAN_ABOVE ) {
if ( ! strncmp
( country_80211d , " US " ,
COUNTRY_CODE_LEN - 1 ) ) {
if ( channel_tlv - > chan_number >
DEFAULT_MAX_CHANNEL_ABOVE ) {
printf ( " ERR: Only channels 1-7 are allowed with secondary channel above for the US \n " ) ;
return UAP_FAILURE ;
}
} else if ( strncmp
( country_80211d , " JP " ,
COUNTRY_CODE_LEN - 1 ) ) {
if ( channel_tlv - > chan_number >
DEFAULT_MAX_CHANNEL_ABOVE_NON_US )
{
printf ( " ERR: Only channels 1-9 are allowed with secondary channel above for " " non-Japan countries! \n " ) ;
return UAP_FAILURE ;
}
}
}
}
if ( ! ( channel_tlv - > bandcfg . scanMode = = SCAN_MODE_ACS ) ) {
if ( check_channel_validity_11d
( channel_tlv - > chan_number , channel_tlv_band ,
1 ) = = UAP_FAILURE )
return UAP_FAILURE ;
if ( state_80211d ) {
/* Set country code to JP if channel is 8 or 12 and band is 5GHZ */
if ( ( channel_tlv - > chan_number <
MAX_CHANNELS_BG ) & &
( channel_tlv_band = = BAND_A ) )
strncpy ( country_80211d , " JP " ,
sizeof ( country_80211d ) -
1 ) ;
} else {
if ( ( channel_tlv_band = = BAND_A ) & &
( ( channel_tlv - > chan_number = = 8 ) | |
( channel_tlv - > chan_number = =
12 ) ) ) {
printf ( " ERR:Invalid band for given channel \n " ) ;
return UAP_FAILURE ;
}
}
} else {
acs_mode_enabled = 1 ;
}
# define JP_REGION_0xFE 0xFE
if ( fw . region_code = = JP_REGION_0xFE & &
( ( channel_tlv - > chan_number = = 12 ) | |
( channel_tlv - > chan_number = = 13 ) ) ) {
printf ( " ERR:Channel 12 or 13 is not allowed for region code 0xFE \n " ) ;
return UAP_FAILURE ;
}
break ;
case MRVL_CHANNELLIST_TLV_ID :
chnlist_tlv = ( tlvbuf_channel_list * ) pcurrent_tlv ;
pchan_list =
( channel_list * ) & ( chnlist_tlv - > chan_list ) ;
if ( tlv_len % sizeof ( channel_list ) ) {
printf ( " ERR:Invalid Scan channel list TLV! \n " ) ;
return UAP_FAILURE ;
}
chan_list_len = tlv_len / sizeof ( channel_list ) ;
for ( i = 0 ; i < chan_list_len ; i + + ) {
scan_channels_band = BAND_B | BAND_G ;
if ( ( scan_channels_band ! = BAND_A ) & &
( pchan_list - > bandcfg . chanBand = =
BAND_5GHZ ) ) {
scan_channels_band = BAND_A ;
}
if ( check_channel_validity_11d
( pchan_list - > chan_number ,
scan_channels_band , 0 ) = = UAP_FAILURE )
return UAP_FAILURE ;
pchan_list + + ;
}
break ;
case MRVL_TX_POWER_TLV_ID :
txpower_tlv = ( tlvbuf_tx_power * ) pcurrent_tlv ;
if ( state_80211d ) {
if ( check_tx_pwr_validity_11d
( txpower_tlv - > tx_power_dbm ) = = UAP_FAILURE )
return UAP_FAILURE ;
}
break ;
case MRVL_CIPHER_PWK_TLV_ID :
pwk_cipher_tlv = ( tlvbuf_pwk_cipher * ) pcurrent_tlv ;
pwk_cipher_tlv - > protocol =
uap_le16_to_cpu ( pwk_cipher_tlv - > protocol ) ;
if ( pwk_cipher_tlv - > protocol = = PROTOCOL_WPA )
pairwise_cipher_wpa =
pwk_cipher_tlv - > pairwise_cipher ;
else if ( pwk_cipher_tlv - > protocol = = PROTOCOL_WPA2 )
pairwise_cipher_wpa2 =
pwk_cipher_tlv - > pairwise_cipher ;
break ;
case MRVL_CIPHER_GWK_TLV_ID :
gwk_cipher_tlv = ( tlvbuf_gwk_cipher * ) pcurrent_tlv ;
group_cipher = gwk_cipher_tlv - > group_cipher ;
break ;
case MRVL_AUTH_TLV_ID :
auth_tlv = ( tlvbuf_auth_mode * ) pcurrent_tlv ;
break ;
case MRVL_PROTOCOL_TLV_ID :
protocol_tlv = ( tlvbuf_protocol * ) pcurrent_tlv ;
protocol = uap_le16_to_cpu ( protocol_tlv - > protocol ) ;
break ;
case MRVL_WPA_PASSPHRASE_TLV_ID :
passphrase_tlv = ( tlvbuf_wpa_passphrase * ) pcurrent_tlv ;
break ;
case MRVL_WEP_KEY_TLV_ID :
wep_key_tlv = ( tlvbuf_wep_key * ) pcurrent_tlv ;
if ( wep_key_tlv - > is_default ) {
key_set = 1 ;
}
break ;
case HT_CAPABILITY_TLV_ID :
ht_cap_tlv = ( tlvbuf_htcap_t * ) pcurrent_tlv ;
ht_cap_tlv - > ht_cap . ht_cap_info =
uap_le16_to_cpu ( ht_cap_tlv - > ht_cap . ht_cap_info ) ;
if ( ht_cap_tlv - > ht_cap . supported_mcs_set [ 0 ] ) {
enable_11n = 1 ;
enable_40Mhz =
IS_11N_40MHZ_ENABLED ( ht_cap_tlv - > ht_cap .
ht_cap_info ) ;
enable_20Mhz_sgi =
IS_11N_20MHZ_SHORTGI_ENABLED
( ht_cap_tlv - > ht_cap . ht_cap_info ) ;
enable_gf =
IS_11N_GF_ENABLED ( ht_cap_tlv - > ht_cap .
ht_cap_info ) ;
}
break ;
case MRVL_RATES_TLV_ID :
rates_tlv = ( tlvbuf_rates * ) pcurrent_tlv ;
op_rates_len = tlv_len ;
break ;
case MRVL_MCBC_DATA_RATE_TLV_ID :
mcbc_data_rate_tlv =
( tlvbuf_mcbc_data_rate * ) pcurrent_tlv ;
mcbc_data_rate =
uap_le16_to_cpu ( mcbc_data_rate_tlv - >
mcbc_datarate ) ;
if ( mcbc_data_rate & &
( is_mcbc_rate_valid ( ( t_u8 ) mcbc_data_rate ) ! =
UAP_SUCCESS ) ) {
printf ( " ERR: Invalid MCBC Data Rate \n " ) ;
return UAP_FAILURE ;
}
break ;
}
tlv_buf_left - = ( sizeof ( tlvbuf_header ) + tlv_len ) ;
pcurrent_tlv = ( tlvbuf_header * ) ( pcurrent_tlv - > data + tlv_len ) ;
}
if ( ( protocol = = PROTOCOL_STATIC_WEP ) & & ! key_set ) {
printf ( " ERR:WEP keys not set! \n " ) ;
return UAP_FAILURE ;
}
if ( auth_tlv = = NULL ) {
printf ( " ERR: No authentication found \n " ) ;
return UAP_FAILURE ;
}
if ( ( auth_tlv - > auth_mode = = 1 ) & & ( protocol ! = PROTOCOL_STATIC_WEP ) ) {
printf ( " ERR:Shared key authentication is not allowed for Open/WPA/WPA2/Mixed mode \n " ) ;
return UAP_FAILURE ;
}
if ( passphrase_tlv = = NULL ) {
printf ( " ERR: No passphrase found \n " ) ;
return UAP_FAILURE ;
}
if ( ( ( protocol = = PROTOCOL_WPA ) | | ( protocol = = PROTOCOL_WPA2 )
| | ( protocol = = PROTOCOL_WPA3_SAE )
| | ( protocol = = PROTOCOL_WPA2_MIXED ) )
& & ! ( passphrase_tlv - > length ) ) {
printf ( " ERR:Passphrase must be set for WPA/WPA2/Mixed/WPA3 SAE mode \n " ) ;
return UAP_FAILURE ;
}
if ( ( protocol = = PROTOCOL_WPA ) | | ( protocol = = PROTOCOL_WPA2_MIXED ) ) {
if ( is_cipher_valid ( pairwise_cipher_wpa , group_cipher ) ! =
UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA pairwise cipher combination! \n " ) ;
return UAP_FAILURE ;
}
}
if ( ( protocol = = PROTOCOL_WPA2 ) | | ( protocol = = PROTOCOL_WPA2_MIXED )
| | ( protocol = = PROTOCOL_WPA3_SAE )
) {
if ( is_cipher_valid ( pairwise_cipher_wpa2 , group_cipher ) ! =
UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA2 pairwise cipher combination! \n " ) ;
return UAP_FAILURE ;
}
}
if ( chnlist_tlv = = NULL ) {
printf ( " ERR: No channel list found \n " ) ;
return UAP_FAILURE ;
}
if ( acs_mode_enabled ) {
pchan_list = ( channel_list * ) & ( chnlist_tlv - > chan_list ) ;
for ( i = 0 ; i < chan_list_len ; i + + ) {
if ( ( ! state_80211d ) & &
( pchan_list - > chan_number = = MAX_CHANNELS_BG )
& &
( strncmp ( country_80211d , " JP " , COUNTRY_CODE_LEN - 1 )
= = 0 )
) {
printf ( " ERR: Invalid scan channel 14, 802.11d disabled, country code JP! \n " ) ;
return UAP_FAILURE ;
}
if ( fw . region_code = = JP_REGION_0xFE & &
( ( pchan_list - > chan_number = = 12 ) | |
( pchan_list - > chan_number = = 13 ) ) ) {
printf ( " ERR:Scan Channel 12 or 13 is not allowed for region code 0xFE \n " ) ;
return UAP_FAILURE ;
}
pchan_list + + ;
}
if ( ! state_80211d ) {
/* Block scan channels 8 and 12 in 5GHz band if 11d is not enabled and country code not set to JP */
pchan_list =
( channel_list * ) & ( chnlist_tlv - > chan_list ) ;
for ( i = 0 ; i < chan_list_len ; i + + ) {
if ( ( pchan_list - > bandcfg . chanBand = = BAND_5GHZ )
& & ( ( pchan_list - > chan_number = = 8 ) | |
( pchan_list - > chan_number = = 12 ) ) ) {
printf ( " ERR: Invalid band for scan channel %d \n " , pchan_list - > chan_number ) ;
return UAP_FAILURE ;
}
pchan_list + + ;
}
}
if ( state_80211d ) {
/* Set default country code to US */
strncpy ( country_80211d , " US " ,
sizeof ( country_80211d ) - 1 ) ;
pchan_list =
( channel_list * ) & ( chnlist_tlv - > chan_list ) ;
for ( i = 0 ; i < chan_list_len ; i + + ) {
/* Set country code to JP if channel is 8 or 12 and band is 5GHZ */
if ( ( pchan_list - > chan_number < MAX_CHANNELS_BG )
& & ( scan_channels_band = = BAND_A ) ) {
strncpy ( country_80211d , " JP " ,
sizeof ( country_80211d ) - 1 ) ;
}
if ( check_channel_validity_11d
( pchan_list - > chan_number ,
scan_channels_band , 0 ) = = UAP_FAILURE )
return UAP_FAILURE ;
pchan_list + + ;
}
if ( update_domain_info
( country_80211d ,
scan_channels_band ) = = UAP_FAILURE ) {
return UAP_FAILURE ;
}
}
}
# ifdef WIFI_DIRECT_SUPPORT
if ( strncmp ( dev_name , " wfd " , 3 ) )
# endif
if ( ( ! acs_mode_enabled & &
( channel_tlv_band = = ( BAND_B | BAND_G ) ) )
| | ( acs_mode_enabled & &
( scan_channels_band = = ( BAND_B | BAND_G ) ) ) ) {
if ( rates_tlv = = NULL ) {
printf ( " ERR: No rates found \n " ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < op_rates_len ; i + + ) {
rate = rates_tlv - >
operational_rates [ i ] &
~ BASIC_RATE_SET_BIT ;
switch ( rate ) {
case 2 :
rate_bitmap | = BITMAP_RATE_1M ;
break ;
case 4 :
rate_bitmap | = BITMAP_RATE_2M ;
break ;
case 11 :
rate_bitmap | = BITMAP_RATE_5_5M ;
break ;
case 22 :
rate_bitmap | = BITMAP_RATE_11M ;
break ;
}
}
if ( ( rate_bitmap & B_RATE_MANDATORY ) ! =
B_RATE_MANDATORY ) {
if ( acs_mode_enabled )
printf ( " ERR: Rates/Scan channels do not match! \n " ) ;
else
printf ( " ERR: Rates/Channel do not match! \n " ) ;
return UAP_FAILURE ;
}
}
if ( ( ! acs_mode_enabled & & ( channel_tlv_band = = BAND_A ) )
| | ( acs_mode_enabled & & ( scan_channels_band = = BAND_A ) ) ) {
if ( rates_tlv = = NULL ) {
printf ( " ERR: No rates found \n " ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < op_rates_len ; i + + ) {
rate = rates_tlv - >
operational_rates [ i ] & ~ BASIC_RATE_SET_BIT ;
switch ( rate ) {
case 2 :
case 4 :
case 11 :
case 22 :
if ( acs_mode_enabled )
printf ( " ERR: Rates/Scan channels do not match! \n " ) ;
else
printf ( " ERR: Rates/Channel do not match! \n " ) ;
return UAP_FAILURE ;
}
}
state_80211h = 1 ;
if ( sg_snmp_mib
( ACTION_SET , OID_80211H_ENABLE , sizeof ( state_80211h ) ,
& state_80211h )
= = UAP_FAILURE ) {
return UAP_FAILURE ;
}
if ( update_domain_info ( country_80211d , BAND_A ) = = UAP_FAILURE ) {
return UAP_FAILURE ;
}
}
# define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & MBIT(17))
# define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & MBIT(24))
if ( enable_40Mhz ) {
if ( ! ISSUPP_CHANWIDTH40 ( fw . hw_dot_11n_dev_cap ) ) {
printf ( " ERR: It's not support HT40 from Hardware Cap \n " ) ;
return UAP_FAILURE ;
}
}
if ( enable_11n ) {
/*For protocol = Mixed, 11n enabled, only allow TKIP cipher for WPA protocol, not for WPA2 */
if ( ( protocol = = PROTOCOL_WPA2_MIXED ) & &
( pairwise_cipher_wpa2 = = CIPHER_TKIP ) ) {
printf ( " ERR: WPA2 pairwise cipher cannot be TKIP when AP operates in 802.11n Mixed mode. \n " ) ;
return UAP_FAILURE ;
} else if ( protocol = = PROTOCOL_STATIC_WEP ) {
printf ( " ERR: WEP cannot be used when AP operates in 802.11n mode. \n " ) ;
return UAP_FAILURE ;
}
}
if ( ( tx_rate_config . rate = = UAP_RATE_INDEX_MCS32 ) & & ! enable_40Mhz ) {
printf ( " ERR:uAP must be configured to operate in 40MHz if tx_rate is MCS32 \n " ) ;
return UAP_FAILURE ;
}
if ( enable_20Mhz_sgi & & enable_gf ) {
if ( ( tx_rate_config . rate > = UAP_RATE_INDEX_MCS0 ) & &
( tx_rate_config . rate < = UAP_RATE_INDEX_MCS7 ) ) {
printf ( " ERR: Invalid tx_rate for uAP in (20MHz Short GI + Green Field) mode \n " ) ;
return UAP_FAILURE ;
}
}
mcs_rate_index =
get_rate_index_from_bitmap ( tx_rate_config . bitmap_rates ,
sizeof ( tx_rate_config . bitmap_rates ) ) ;
if ( ( mcs_rate_index > = UAP_RATE_BITMAP_MCS0 ) & &
( mcs_rate_index < = UAP_RATE_BITMAP_MCS127 ) ) {
mcs_rate_index - = ( UAP_RATE_BITMAP_MCS0 - UAP_RATE_INDEX_MCS0 ) ;
if ( ( mcs_rate_index = = UAP_RATE_INDEX_MCS32 ) & ! enable_40Mhz ) {
printf ( " ERR:uAP must be configured to operate in 40MHz if rate_bitmap contains MCS32 \n " ) ;
return UAP_FAILURE ;
}
if ( enable_20Mhz_sgi & & enable_gf ) {
if ( ( mcs_rate_index > = UAP_RATE_INDEX_MCS0 ) & &
( mcs_rate_index < = UAP_RATE_INDEX_MCS7 ) ) {
printf ( " ERR: Invalid tx_rate for uAP in (20MHz Short GI + Green Field) mode \n " ) ;
return UAP_FAILURE ;
}
}
}
/* if 11d enabled, Channel 14, country code "JP", only B rates are allowed */
if ( ( channel = = 14 ) & & state_80211d & &
( strncmp ( country_80211d , " JP " , COUNTRY_CODE_LEN - 1 ) = = 0 ) ) {
if ( rates_tlv = = NULL ) {
printf ( " ERR:No rates found \n " ) ;
return UAP_FAILURE ;
}
if ( enable_11n ) {
printf ( " ERR:11n must be disabled and the only B rates are allowed if 11d enabled and country code is JP with channel 14. \n " ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < op_rates_len ; i + + ) {
rate = rates_tlv - >
operational_rates [ i ] & ~ BASIC_RATE_SET_BIT ;
switch ( rate ) {
case 2 :
case 4 :
case 11 :
case 22 :
break ;
default :
printf ( " ERR:If 11d enabled, channel 14 and country code is JP, the only B rates are allowed. \n " ) ;
return UAP_FAILURE ;
}
}
}
/* Channels 14, 165 are not allowed to operate in 40MHz mode */
if ( ! acs_mode_enabled & & enable_40Mhz ) {
if ( ( channel = = 14 )
| | ( channel = = 165 )
) {
printf ( " ERR:Invalid channel %d for 40MHz operation \n " ,
channel ) ;
return UAP_FAILURE ;
} else if ( ! secondary_ch_set ) {
printf ( " ERR:Secondary channel should be set when 40Mhz is enabled! \n " ) ;
return UAP_FAILURE ;
}
}
/* Channels 14, 140, 165 are not allowed to operate in 40MHz mode */
if ( acs_mode_enabled & & enable_40Mhz ) {
if ( chnlist_tlv = = NULL ) {
printf ( " ERR: No channel list found \n " ) ;
return UAP_FAILURE ;
}
pchan_list = ( channel_list * ) & ( chnlist_tlv - > chan_list ) ;
for ( i = 0 ; i < chan_list_len ; i + + ) {
if ( ( pchan_list - > chan_number ! = 14 )
& & ( pchan_list - > chan_number ! = 140 ) & &
( pchan_list - > chan_number ! = 165 )
) {
flag = 1 ;
break ;
}
pchan_list + + ;
}
if ( ! flag ) {
printf ( " ERR:Invalid channels in scan channel list for 40MHz operation \n " ) ;
return UAP_FAILURE ;
}
}
if ( 0 = = get_fw_info ( & fw ) ) {
/*check whether support 802.11AC through BAND_AAC bit */
if ( fw . fw_bands & BAND_AAC ) {
ret = get_802_11ac_cfg ( & vhtcfg ) ;
if ( UAP_SUCCESS = = ret ) {
/* Note: When 11AC is disabled, FW sets vht_rx_mcs to 0xffff */
if ( ( vhtcfg . vht_rx_mcs ! = 0xffff ) & &
( ! enable_11n ) ) {
printf ( " ERR: 11ac enable while 11n disable, it is forbidden! \n " ) ;
return UAP_FAILURE ;
}
} else {
printf ( " Don't support 802.11AC \n " ) ;
return UAP_SUCCESS ;
}
} else
printf ( " No support 802 11AC. \n " ) ;
} else {
printf ( " ERR: get_fw_info fail \n " ) ;
return UAP_FAILURE ;
}
return ret ;
}
/**
* @ brief Checks current bss configuration
*
* @ param buf pointer to bss_config_t
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
check_bss_config ( t_u8 * buf )
{
bss_config_t * bss_config = NULL ; ;
t_u8 acs_mode_enabled = 0 ;
t_u8 * cbuf = NULL ;
apcmdbuf_cfg_80211d * cmd_buf = NULL ;
t_u16 buf_len , cmd_len ;
char country_80211d [ 4 ] = { ' U ' , ' S ' , ' ' , 0 } ;
t_u8 state_80211h = 0 ;
int channel_tlv_band = BAND_B | BAND_G ;
t_u8 secondary_ch_set = 0 ;
int scan_channels_band = BAND_B | BAND_G ;
t_u8 state_80211d = 0 ;
t_u8 rate = 0 ;
t_u32 rate_bitmap = 0 ;
t_u16 enable_40Mhz = 0 ;
t_u16 enable_20Mhz_sgi = 0 ;
t_u16 enable_gf = 0 ;
t_u8 enable_11n = 0 ;
int flag = 0 ;
fw_info fw ;
int i = 0 , ret = UAP_SUCCESS ;
tx_rate_cfg_t tx_rate_config ;
t_u32 mcs_rate_index = 0 ;
struct eth_priv_vhtcfg vhtcfg = { 0 } ;
# define BITMAP_RATE_1M 0x01
# define BITMAP_RATE_2M 0x02
# define BITMAP_RATE_5_5M 0x04
# define BITMAP_RATE_11M 0x8
# define B_RATE_MANDATORY 0x0f
if ( NULL = = buf ) {
printf ( " ERR: No buffer for bss_configure! \n " ) ;
return UAP_FAILURE ;
}
bss_config = ( bss_config_t * ) buf ;
ret = sg_snmp_mib ( ACTION_GET , OID_80211D_ENABLE , sizeof ( state_80211d ) ,
& state_80211d ) ;
buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
cbuf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! cbuf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( cbuf , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_cfg_80211d * ) cbuf ;
cmd_len = ( sizeof ( apcmdbuf_cfg_80211d ) - sizeof ( domain_param_t ) ) ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > action = uap_cpu_to_le16 ( ACTION_GET ) ;
cmd_buf - > cmd_code = HostCmd_CMD_802_11D_DOMAIN_INFO ;
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
if ( ret = = UAP_SUCCESS & & cmd_buf - > result = = CMD_SUCCESS ) {
if ( cmd_buf - > domain . country_code [ 0 ] | |
cmd_buf - > domain . country_code [ 1 ] | |
cmd_buf - > domain . country_code [ 2 ] ) {
strncpy ( country_80211d ,
( char * ) cmd_buf - > domain . country_code ,
COUNTRY_CODE_LEN ) ;
}
}
free ( cbuf ) ;
/* get region code to handle special cases */
memset ( & fw , 0 , sizeof ( fw ) ) ;
if ( get_fw_info ( & fw ) ) {
printf ( " Could not get fw info! \n " ) ;
return UAP_FAILURE ;
}
if ( get_tx_rate_cfg ( & tx_rate_config ) = = UAP_FAILURE ) {
printf ( " Could not get tx_rate_cfg! \n " ) ;
return UAP_FAILURE ;
}
if ( ( ! state_80211d ) & & ( bss_config - > channel = = MAX_CHANNELS_BG )
& & ( strncmp ( country_80211d , " JP " , COUNTRY_CODE_LEN - 1 ) = = 0 )
) {
printf ( " ERR: Invalid channel 14, 802.11d disabled, country code JP! \n " ) ;
return UAP_FAILURE ;
}
if ( ( fw . fw_bands & ( BAND_B | BAND_G | BAND_GN | BAND_GAC ) )
& & ! ( fw . fw_bands & ( BAND_A | BAND_AAC ) )
) {
if ( bss_config - > channel > MAX_CHANNELS_BG ) {
printf ( " ERR: Invalid channel in 2.4GHz band! \n " ) ;
return UAP_FAILURE ;
}
}
if ( ! ( fw . fw_bands & ( BAND_B | BAND_G | BAND_GN
| BAND_GAC ) ) & & ( fw . fw_bands & ( BAND_A
| BAND_AAC ) ) ) {
if ( bss_config - > channel < 36 | |
bss_config - > channel > MAX_CHANNELS ) {
printf ( " ERR: Invalid channel in 5GHz band! \n " ) ;
return UAP_FAILURE ;
}
}
if ( bss_config - > bandcfg . chanBand = = BAND_5GHZ )
channel_tlv_band = BAND_A ;
secondary_ch_set = bss_config - > bandcfg . chan2Offset ;
if ( channel_tlv_band ! = BAND_A ) {
/* When country code is not Japan, allow channels 5-11 for US and 5-13 for non-US
* only for secondary channel below */
if ( secondary_ch_set = = SEC_CHAN_BELOW ) {
if ( ! strncmp
( country_80211d , " US " , COUNTRY_CODE_LEN - 1 ) ) {
if ( bss_config - > channel >
DEFAULT_MAX_CHANNEL_BELOW ) {
printf ( " ERR: Only channels 5-11 are allowed with secondary channel below for the US \n " ) ;
return UAP_FAILURE ;
}
} else if ( strncmp
( country_80211d , " JP " ,
COUNTRY_CODE_LEN - 1 ) ) {
if ( bss_config - > channel >
DEFAULT_MAX_CHANNEL_BELOW_NON_US ) {
printf ( " ERR: Only channels 5-13 are allowed with secondary channel below for " " non-Japan countries! \n " ) ;
return UAP_FAILURE ;
}
}
}
/* When country code is not Japan, allow channels 1-7 for US and 1-9 for non-US
* only for secondary channel above */
if ( secondary_ch_set = = SEC_CHAN_ABOVE ) {
if ( ! strncmp
( country_80211d , " US " , COUNTRY_CODE_LEN - 1 ) ) {
if ( bss_config - > channel >
DEFAULT_MAX_CHANNEL_ABOVE ) {
printf ( " ERR: Only channels 1-7 are allowed with secondary channel above for the US \n " ) ;
return UAP_FAILURE ;
}
} else if ( strncmp
( country_80211d , " JP " ,
COUNTRY_CODE_LEN - 1 ) ) {
if ( bss_config - > channel >
DEFAULT_MAX_CHANNEL_ABOVE_NON_US ) {
printf ( " ERR: Only channels 1-9 are allowed with secondary channel above for " " non-Japan countries! \n " ) ;
return UAP_FAILURE ;
}
}
}
}
if ( ! ( bss_config - > bandcfg . scanMode = = SCAN_MODE_ACS ) ) {
if ( check_channel_validity_11d
( bss_config - > channel , channel_tlv_band , 1 ) = = UAP_FAILURE )
return UAP_FAILURE ;
if ( state_80211d ) {
/* Set country code to JP if channel is 8 or 12 and band is 5GHZ */
if ( ( bss_config - > channel < MAX_CHANNELS_BG ) & &
( channel_tlv_band = = BAND_A ) )
strncpy ( country_80211d , " JP " ,
sizeof ( country_80211d ) - 1 ) ;
} else {
if ( ( channel_tlv_band = = BAND_A ) & &
( ( bss_config - > channel = = 8 ) | |
( bss_config - > channel = = 12 ) ) ) {
printf ( " ERR:Invalid band for given channel \n " ) ;
return UAP_FAILURE ;
}
}
} else {
acs_mode_enabled = 1 ;
}
# define JP_REGION_0xFE 0xFE
if ( fw . region_code = = JP_REGION_0xFE & &
( ( bss_config - > channel = = 12 ) | | ( bss_config - > channel = = 13 ) ) ) {
printf ( " ERR:Channel 12 or 13 is not allowed for region code 0xFE \n " ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < bss_config - > num_of_chan ; i + + ) {
scan_channels_band = BAND_B | BAND_G ;
if ( ( scan_channels_band ! = BAND_A ) & &
( bss_config - > chan_list [ i ] . bandcfg . chanBand = = BAND_5GHZ ) ) {
scan_channels_band = BAND_A ;
}
if ( check_channel_validity_11d
( bss_config - > chan_list [ i ] . chan_number , scan_channels_band ,
0 ) = = UAP_FAILURE )
return UAP_FAILURE ;
}
if ( state_80211d ) {
if ( check_tx_pwr_validity_11d ( bss_config - > tx_power_level ) = =
UAP_FAILURE )
return UAP_FAILURE ;
}
if ( bss_config - > supported_mcs_set [ 0 ] ) {
enable_11n = 1 ;
enable_40Mhz = IS_11N_40MHZ_ENABLED ( bss_config - > ht_cap_info ) ;
enable_20Mhz_sgi =
IS_11N_20MHZ_SHORTGI_ENABLED ( bss_config - > ht_cap_info ) ;
enable_gf = IS_11N_GF_ENABLED ( bss_config - > ht_cap_info ) ;
}
if ( bss_config - > mcbc_data_rate & &
( is_mcbc_rate_valid ( bss_config - > mcbc_data_rate ) ! = UAP_SUCCESS ) ) {
printf ( " ERR: Invalid MCBC Data Rate \n " ) ;
return UAP_FAILURE ;
}
if ( ( bss_config - > protocol = = PROTOCOL_STATIC_WEP )
& & ( 0 = = bss_config - > wep_cfg . key0 . is_default )
& & ( 0 = = bss_config - > wep_cfg . key1 . is_default )
& & ( 0 = = bss_config - > wep_cfg . key2 . is_default )
& & ( 0 = = bss_config - > wep_cfg . key3 . is_default ) ) {
printf ( " ERR:WEP keys not set! \n " ) ;
return UAP_FAILURE ;
}
if ( ( bss_config - > auth_mode = = 1 ) & &
( bss_config - > protocol ! = PROTOCOL_STATIC_WEP ) ) {
printf ( " ERR:Shared key authentication is not allowed for Open/WPA/WPA2/Mixed mode \n " ) ;
return UAP_FAILURE ;
}
if ( ( ( bss_config - > protocol = = PROTOCOL_WPA ) | |
( bss_config - > protocol = = PROTOCOL_WPA2 )
| | ( bss_config - > protocol = = PROTOCOL_WPA3_SAE )
| | ( bss_config - > protocol = = PROTOCOL_WPA2_MIXED ) ) & &
! ( bss_config - > wpa_cfg . length ) ) {
printf ( " ERR:Passphrase must be set for WPA/WPA2/Mixed/WPA3 SAE mode \n " ) ;
return UAP_FAILURE ;
}
if ( ( bss_config - > protocol = = PROTOCOL_WPA ) | |
( bss_config - > protocol = = PROTOCOL_WPA2_MIXED ) ) {
if ( is_cipher_valid
( bss_config - > wpa_cfg . pairwise_cipher_wpa ,
bss_config - > wpa_cfg . group_cipher ) ! = UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA pairwise cipher combination! \n " ) ;
return UAP_FAILURE ;
}
}
if ( ( bss_config - > protocol = = PROTOCOL_WPA2 ) | |
( bss_config - > protocol = = PROTOCOL_WPA2_MIXED )
| | ( bss_config - > protocol = = PROTOCOL_WPA3_SAE )
) {
if ( is_cipher_valid
( bss_config - > wpa_cfg . pairwise_cipher_wpa2 ,
bss_config - > wpa_cfg . group_cipher ) ! = UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA2 pairwise cipher combination! \n " ) ;
return UAP_FAILURE ;
}
}
if ( 0 = = bss_config - > num_of_chan ) {
printf ( " ERR: No channel list found \n " ) ;
return UAP_FAILURE ;
}
if ( acs_mode_enabled ) {
for ( i = 0 ; i < bss_config - > num_of_chan ; i + + ) {
if ( ( ! state_80211d ) & &
( bss_config - > chan_list [ i ] . chan_number = =
MAX_CHANNELS_BG )
& &
( strncmp ( country_80211d , " JP " , COUNTRY_CODE_LEN - 1 )
= = 0 )
) {
printf ( " ERR: Invalid scan channel 14, 802.11d disabled, country code JP! \n " ) ;
return UAP_FAILURE ;
}
if ( fw . region_code = = JP_REGION_0xFE & &
( ( bss_config - > chan_list [ i ] . chan_number = = 12 ) | |
( bss_config - > chan_list [ i ] . chan_number = = 13 ) ) ) {
printf ( " ERR:Scan Channel 12 or 13 is not allowed for region code 0xFE \n " ) ;
return UAP_FAILURE ;
}
}
if ( ! state_80211d ) {
/* Block scan channels 8 and 12 in 5GHz band if 11d is not enabled and country code not set to JP */
for ( i = 0 ; i < bss_config - > num_of_chan ; i + + ) {
if ( ( bss_config - > chan_list [ i ] . bandcfg .
chanBand = = BAND_5GHZ )
& &
( ( bss_config - > chan_list [ i ] . chan_number = = 8 )
| | ( bss_config - > chan_list [ i ] . chan_number = =
12 ) ) ) {
printf ( " ERR: Invalid band for scan channel %d \n " , bss_config - > chan_list [ i ] . chan_number ) ;
return UAP_FAILURE ;
}
}
}
if ( state_80211d ) {
/* Set default country code to US */
strncpy ( country_80211d , " US " ,
sizeof ( country_80211d ) - 1 ) ;
for ( i = 0 ; i < bss_config - > num_of_chan ; i + + ) {
/* Set country code to JP if channel is 8 or 12 and band is 5GHZ */
if ( ( bss_config - > chan_list [ i ] . chan_number <
MAX_CHANNELS_BG ) & &
( scan_channels_band = = BAND_A ) ) {
strncpy ( country_80211d , " JP " ,
sizeof ( country_80211d ) - 1 ) ;
}
if ( check_channel_validity_11d
( bss_config - > chan_list [ i ] . chan_number ,
scan_channels_band , 0 ) = = UAP_FAILURE )
return UAP_FAILURE ;
}
if ( update_domain_info
( country_80211d ,
scan_channels_band ) = = UAP_FAILURE ) {
return UAP_FAILURE ;
}
}
}
# ifdef WIFI_DIRECT_SUPPORT
if ( strncmp ( dev_name , " wfd " , 3 ) )
# endif
if ( ( ! acs_mode_enabled & &
( channel_tlv_band = = ( BAND_B | BAND_G ) ) )
| | ( acs_mode_enabled & &
( scan_channels_band = = ( BAND_B | BAND_G ) ) ) ) {
if ( 0 = = bss_config - > rates [ 0 ] ) {
printf ( " ERR: No rates found \n " ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < MAX_DATA_RATES & & bss_config - > rates [ i ] ;
i + + ) {
rate = bss_config - >
rates [ i ] & ~ BASIC_RATE_SET_BIT ;
switch ( rate ) {
case 2 :
rate_bitmap | = BITMAP_RATE_1M ;
break ;
case 4 :
rate_bitmap | = BITMAP_RATE_2M ;
break ;
case 11 :
rate_bitmap | = BITMAP_RATE_5_5M ;
break ;
case 22 :
rate_bitmap | = BITMAP_RATE_11M ;
break ;
}
}
if ( ( rate_bitmap & B_RATE_MANDATORY ) ! =
B_RATE_MANDATORY ) {
if ( acs_mode_enabled )
printf ( " ERR: Rates/Scan channels do not match! \n " ) ;
else
printf ( " ERR: Rates/Channel do not match! \n " ) ;
return UAP_FAILURE ;
}
}
if ( ( ! acs_mode_enabled & & ( channel_tlv_band = = BAND_A ) )
| | ( acs_mode_enabled & & ( scan_channels_band = = BAND_A ) ) ) {
if ( 0 = = bss_config - > rates [ 0 ] ) {
printf ( " ERR: No rates found \n " ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < MAX_DATA_RATES & & bss_config - > rates [ i ] ; i + + ) {
rate = bss_config - > rates [ i ] & ~ BASIC_RATE_SET_BIT ;
switch ( rate ) {
case 2 :
case 4 :
case 11 :
case 22 :
if ( acs_mode_enabled )
printf ( " ERR: Rates/Scan channels do not match! \n " ) ;
else
printf ( " ERR: Rates/Channel do not match! \n " ) ;
return UAP_FAILURE ;
}
}
state_80211h = 1 ;
if ( sg_snmp_mib
( ACTION_SET , OID_80211H_ENABLE , sizeof ( state_80211h ) ,
& state_80211h )
= = UAP_FAILURE ) {
return UAP_FAILURE ;
}
if ( update_domain_info ( country_80211d , BAND_A ) = = UAP_FAILURE ) {
return UAP_FAILURE ;
}
}
# define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & MBIT(17))
# define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & MBIT(24))
if ( enable_40Mhz ) {
if ( ! ISSUPP_CHANWIDTH40 ( fw . hw_dot_11n_dev_cap ) ) {
printf ( " ERR: It's not support HT40 from Hardware Cap \n " ) ;
return UAP_FAILURE ;
}
}
if ( enable_11n ) {
/*For protocol = Mixed, 11n enabled, only allow TKIP cipher for WPA protocol, not for WPA2 */
if ( ( bss_config - > protocol = = PROTOCOL_WPA2_MIXED ) & &
( bss_config - > wpa_cfg . pairwise_cipher_wpa2 = = CIPHER_TKIP ) ) {
printf ( " ERR: WPA2 pairwise cipher cannot be TKIP when AP operates in 802.11n Mixed mode. \n " ) ;
return UAP_FAILURE ;
} else if ( bss_config - > protocol = = PROTOCOL_STATIC_WEP ) {
printf ( " ERR: WEP cannot be used when AP operates in 802.11n mode. \n " ) ;
return UAP_FAILURE ;
}
}
if ( ( tx_rate_config . rate = = UAP_RATE_INDEX_MCS32 ) & & ! enable_40Mhz ) {
printf ( " ERR:uAP must be configured to operate in 40MHz if tx_rate is MCS32 \n " ) ;
return UAP_FAILURE ;
}
if ( enable_20Mhz_sgi & & enable_gf ) {
if ( ( tx_rate_config . rate > = UAP_RATE_INDEX_MCS0 ) & &
( tx_rate_config . rate < = UAP_RATE_INDEX_MCS7 ) ) {
printf ( " ERR: Invalid tx_rate for uAP in (20MHz Short GI + Green Field) mode \n " ) ;
return UAP_FAILURE ;
}
}
mcs_rate_index =
get_rate_index_from_bitmap ( tx_rate_config . bitmap_rates ,
sizeof ( tx_rate_config . bitmap_rates ) ) ;
if ( ( mcs_rate_index > = UAP_RATE_BITMAP_MCS0 ) & &
( mcs_rate_index < = UAP_RATE_BITMAP_MCS127 ) ) {
mcs_rate_index - = ( UAP_RATE_BITMAP_MCS0 - UAP_RATE_INDEX_MCS0 ) ;
if ( ( mcs_rate_index = = UAP_RATE_INDEX_MCS32 ) & ! enable_40Mhz ) {
printf ( " ERR:uAP must be configured to operate in 40MHz if rate_bitmap contains MCS32 \n " ) ;
return UAP_FAILURE ;
}
if ( enable_20Mhz_sgi & & enable_gf ) {
if ( ( mcs_rate_index > = UAP_RATE_INDEX_MCS0 ) & &
( mcs_rate_index < = UAP_RATE_INDEX_MCS7 ) ) {
printf ( " ERR: Invalid tx_rate for uAP in (20MHz Short GI + Green Field) mode \n " ) ;
return UAP_FAILURE ;
}
}
}
/* if 11d enabled, Channel 14, country code "JP", only B rates are allowed*/
if ( ( bss_config - > channel = = 14 ) & & state_80211d & &
( strncmp ( country_80211d , " JP " , COUNTRY_CODE_LEN - 1 ) = = 0 ) ) {
if ( 0 = = bss_config - > rates [ 0 ] ) {
printf ( " ERR:No rates found \n " ) ;
return UAP_FAILURE ;
}
if ( enable_11n ) {
printf ( " ERR:11n must be disabled and the only B rates are allowed if 11d enabled and country code is JP with channel 14. \n " ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < MAX_DATA_RATES & & bss_config - > rates [ i ] ; i + + ) {
rate = bss_config - > rates [ i ] & ~ BASIC_RATE_SET_BIT ;
switch ( rate ) {
case 2 :
case 4 :
case 11 :
case 22 :
break ;
default :
printf ( " ERR:If 11d enabled, channel 14 and country code is JP, the only B rates are allowed. \n " ) ;
return UAP_FAILURE ;
}
}
}
/* Channels 14, 165 are not allowed to operate in 40MHz mode */
if ( ! acs_mode_enabled & & enable_40Mhz ) {
if ( ( bss_config - > channel = = 14 )
| | ( bss_config - > channel = = 165 )
) {
printf ( " ERR:Invalid channel %d for 40MHz operation \n " ,
bss_config - > channel ) ;
return UAP_FAILURE ;
} else if ( ! secondary_ch_set ) {
printf ( " ERR:Secondary channel should be set when 40Mhz is enabled! \n " ) ;
return UAP_FAILURE ;
}
}
/* Channels 14, 140, 165 are not allowed to operate in 40MHz mode */
if ( acs_mode_enabled & & enable_40Mhz ) {
if ( bss_config - > num_of_chan = = 0 ) {
printf ( " ERR: No channel list found \n " ) ;
return UAP_FAILURE ;
}
for ( i = 0 ; i < bss_config - > num_of_chan ; i + + ) {
if ( ( bss_config - > chan_list [ i ] . chan_number ! = 14 )
& & ( bss_config - > chan_list [ i ] . chan_number ! = 140 ) & &
( bss_config - > chan_list [ i ] . chan_number ! = 165 )
) {
flag = 1 ;
break ;
}
}
if ( ! flag ) {
printf ( " ERR:Invalid channels in scan channel list for 40MHz operation \n " ) ;
return UAP_FAILURE ;
}
}
if ( 0 = = get_fw_info ( & fw ) ) {
/*check whether support 802.11AC through BAND_AAC bit */
if ( fw . fw_bands & BAND_AAC ) {
ret = get_802_11ac_cfg ( & vhtcfg ) ;
if ( UAP_SUCCESS = = ret ) {
/* Note: When 11AC is disabled, FW sets vht_rx_mcs to 0xffff */
if ( ( vhtcfg . vht_rx_mcs ! = 0xffff ) & &
( ! enable_11n ) ) {
printf ( " ERR: 11ac enable while 11n disable, it is forbidden! \n " ) ;
return UAP_FAILURE ;
}
} else {
printf ( " Don't support 802.11AC \n " ) ;
return UAP_SUCCESS ;
}
} else
printf ( " No support 802 11AC. \n " ) ;
} else {
printf ( " ERR: get_fw_info fail \n " ) ;
return UAP_FAILURE ;
}
return ret ;
}
/**
* @ brief Send read / write command along with register details to the driver
* @ param reg Reg type
* @ param offset Pointer to register offset string
* @ param strvalue Pointer to value string
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
apcmd_regrdwr_process ( int reg , char * offset , char * strvalue )
{
apcmdbuf_reg_rdwr * cmd_buf = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_SUCCESS ;
char * whichreg ;
/* Alloc buf for command */
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate headers */
cmd_len = sizeof ( apcmdbuf_reg_rdwr ) ;
cmd_buf = ( apcmdbuf_reg_rdwr * ) buf ;
/* Fill the command buffer */
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
switch ( reg ) {
case CMD_MAC :
whichreg = " MAC " ;
cmd_buf - > cmd_code = HostCmd_CMD_MAC_REG_ACCESS ;
break ;
case CMD_BBP :
whichreg = " BBP " ;
cmd_buf - > cmd_code = HostCmd_CMD_BBP_REG_ACCESS ;
break ;
case CMD_RF :
cmd_buf - > cmd_code = HostCmd_CMD_RF_REG_ACCESS ;
whichreg = " RF " ;
break ;
default :
printf ( " Invalid register set specified. \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
if ( strvalue ) {
cmd_buf - > action = 1 ; // WRITE
} else {
cmd_buf - > action = 0 ; // READ
}
cmd_buf - > action = uap_cpu_to_le16 ( cmd_buf - > action ) ;
cmd_buf - > offset = A2HEXDECIMAL ( offset ) ;
cmd_buf - > offset = uap_cpu_to_le16 ( cmd_buf - > offset ) ;
if ( strvalue ) {
cmd_buf - > value = A2HEXDECIMAL ( strvalue ) ;
cmd_buf - > value = uap_cpu_to_le32 ( cmd_buf - > value ) ;
}
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result = = CMD_SUCCESS ) {
printf ( " Successfully executed the command \n " ) ;
printf ( " %s[0x%04hx] = 0x%08x \n " ,
whichreg , uap_le16_to_cpu ( cmd_buf - > offset ) ,
uap_le32_to_cpu ( cmd_buf - > value ) ) ;
} else {
printf ( " ERR:Command sending failed! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
free ( buf ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Send read command for EEPROM
*
* Usage : " Usage : rdeeprom <offset> <byteCount> "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_read_eeprom ( int argc , char * argv [ ] )
{
apcmdbuf_eeprom_access * cmd_buf = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
t_u16 byte_count , offset ;
int ret = UAP_SUCCESS ;
int opt ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_apcmd_read_eeprom_usage ( ) ;
return UAP_FAILURE ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( ! argc | |
( argc & & is_input_valid ( RDEEPROM , argc , argv ) ! = UAP_SUCCESS ) ) {
print_apcmd_read_eeprom_usage ( ) ;
return UAP_FAILURE ;
}
offset = A2HEXDECIMAL ( argv [ 0 ] ) ;
byte_count = A2HEXDECIMAL ( argv [ 1 ] ) ;
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_eeprom_access * ) buf ;
cmd_len = sizeof ( apcmdbuf_eeprom_access ) ;
cmd_buf - > size = sizeof ( apcmdbuf_eeprom_access ) - BUF_HEADER_SIZE ;
cmd_buf - > result = 0 ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > action = 0 ;
cmd_buf - > cmd_code = HostCmd_EEPROM_ACCESS ;
cmd_buf - > offset = uap_cpu_to_le16 ( offset ) ;
cmd_buf - > byte_count = uap_cpu_to_le16 ( byte_count ) ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result = = CMD_SUCCESS ) {
printf ( " Successfully executed the command \n " ) ;
byte_count = uap_le16_to_cpu ( cmd_buf - > byte_count ) ;
offset = uap_le16_to_cpu ( cmd_buf - > offset ) ;
hexdump_data ( " EEPROM " , ( void * ) cmd_buf - > value ,
byte_count , ' ' ) ;
} else {
printf ( " ERR:Command Response incorrect! \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
free ( buf ) ;
return ret ;
}
/**
* @ brief Show usage information for the regrdwr command
* command
*
* $ return N / A
*/
void
print_regrdwr_usage ( void )
{
printf ( " \n Usage : uaputl.exe regrdwr <TYPE> <OFFSET> [value] \n " ) ;
printf ( " \n TYPE Options: 1 - read/write MAC register " ) ;
printf ( " \n 2 - read/write BBP register " ) ;
printf ( " \n 3 - read/write RF register " ) ;
printf ( " \n " ) ;
return ;
}
/**
* @ brief Provides interface to perform read / write operations on regsiters
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_regrdwr ( int argc , char * argv [ ] )
{
int opt ;
t_s32 reg ;
int ret = UAP_SUCCESS ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_regrdwr_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( ( argc < 2 ) | | ( argc > 3 ) ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_regrdwr_usage ( ) ;
return UAP_FAILURE ;
}
if ( ( atoi ( argv [ 0 ] ) ! = 1 ) & & ( atoi ( argv [ 0 ] ) ! = 2 ) & &
( atoi ( argv [ 0 ] ) ! = 3 ) ) {
printf ( " ERR:Illegal register type %s. Must be either '1','2' or '3'. \n " , argv [ 0 ] ) ;
print_regrdwr_usage ( ) ;
return UAP_FAILURE ;
}
reg = atoi ( argv [ 0 ] ) ;
ret = apcmd_regrdwr_process ( reg , argv [ 1 ] , argc > 2 ? argv [ 2 ] : NULL ) ;
return ret ;
}
/**
* @ brief Show usage information for the memaccess command
* command
*
* $ return N / A
*/
void
print_memaccess_usage ( void )
{
printf ( " \n Usage : uaputl.exe memaccess <ADDRESS> [value] \n " ) ;
printf ( " \n Read/Write memory location " ) ;
printf ( " \n ADDRESS: Address of the memory location to be read/written " ) ;
printf ( " \n Value : Value to be written at that address \n " ) ;
return ;
}
/**
* @ brief Provides interface to perform read / write memory location
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_memaccess ( int argc , char * argv [ ] )
{
int opt ;
apcmdbuf_mem_access * cmd_buf = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_SUCCESS ;
char * address = NULL ;
char * value = NULL ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_memaccess_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( ( argc < 1 ) | | ( argc > 2 ) ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_memaccess_usage ( ) ;
return UAP_FAILURE ;
}
address = argv [ 0 ] ;
if ( argc = = 2 )
value = argv [ 1 ] ;
/* Alloc buf for command */
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate headers */
cmd_len = sizeof ( apcmdbuf_mem_access ) ;
cmd_buf = ( apcmdbuf_mem_access * ) buf ;
/* Fill the command buffer */
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
cmd_buf - > cmd_code = HostCmd_CMD_MEM_ACCESS ;
if ( value )
cmd_buf - > action = 1 ; // WRITE
else
cmd_buf - > action = 0 ; // READ
cmd_buf - > action = uap_cpu_to_le16 ( cmd_buf - > action ) ;
cmd_buf - > address = A2HEXDECIMAL ( address ) ;
cmd_buf - > address = uap_cpu_to_le32 ( cmd_buf - > address ) ;
if ( value ) {
cmd_buf - > value = A2HEXDECIMAL ( value ) ;
cmd_buf - > value = uap_cpu_to_le32 ( cmd_buf - > value ) ;
}
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result = = CMD_SUCCESS ) {
printf ( " Successfully executed the command \n " ) ;
printf ( " [0x%04x] = 0x%08x \n " ,
uap_le32_to_cpu ( cmd_buf - > address ) ,
uap_le32_to_cpu ( cmd_buf - > value ) ) ;
} else {
printf ( " ERR:Command sending failed! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
free ( buf ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Creates a sys_debug request to send data packet directly to driver
* @ param pkt_type packet type 0 or 5.
* @ param control management packet tx control field .
* @ param file packet data file .
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_debug_data_packet_inject ( int pkt_type , int control , char * file )
{
struct ifreq ifr ;
t_s32 sockfd ;
t_u8 * buf = NULL ;
t_u32 data_len ;
FILE * fp = NULL ;
pkt_header * header = NULL ;
/* Check if file exists */
fp = fopen ( file , " r " ) ;
if ( fp = = NULL ) {
printf ( " \n ERR:Data file can not be opened %s. \n " , file ) ;
return UAP_FAILURE ;
}
buf = ( t_u8 * ) malloc ( MRVDRV_SIZE_OF_PKT_BUFFER ) ;
if ( buf = = NULL ) {
printf ( " Error: allocate memory for packet buffer failed \n " ) ;
fclose ( fp ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , MRVDRV_SIZE_OF_PKT_BUFFER ) ;
header = ( pkt_header * ) buf ;
data_len = fparse_for_hex ( fp , buf + sizeof ( pkt_header ) ) ;
fclose ( fp ) ;
if ( data_len > ( MRVDRV_SIZE_OF_PKT_BUFFER - sizeof ( pkt_header ) ) ) {
printf ( " ERR: Config file is too big %d \n " , data_len ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
header - > tx_pkt_type = pkt_type ;
header - > tx_control = control ;
header - > pkt_len = data_len ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) buf ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAPHOSTPKTINJECT , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:ioctl is not supported by %s \n " , dev_name ) ;
close ( sockfd ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
/* Close socket */
close ( sockfd ) ;
if ( buf )
free ( buf ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the bss_config command
*
* $ return N / A
*/
void
print_bss_config_usage ( void )
{
printf ( " \n Usage : bss_config [CONFIG_FILE] \n " ) ;
printf ( " \n If CONFIG_FILE is provided, a 'set' is performed, else a 'get' is performed. \n " ) ;
printf ( " CONFIG_FILE is file containing all the BSS settings. \n " ) ;
return ;
}
/**
* @ brief Read the BSS profile and populate structure
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ param bss Pointer to BSS configuration buffer
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
parse_bss_config ( int argc , char * argv [ ] , bss_config_t * bss )
{
FILE * config_file = NULL ;
char * line = NULL ;
int li = 0 ;
char * pos = NULL ;
int arg_num = 0 ;
char * args [ 30 ] ;
int i ;
int is_ap_config = 0 ;
int is_ap_mac_filter = 0 ;
int keyindex = - 1 ;
int pwkcipher_wpa = - 1 ;
int pwkcipher_wpa2 = - 1 ;
int gwkcipher = - 1 ;
int protocol = - 1 ;
int tx_beacon_rate = - 1 ;
int tx_data_rate = - 1 ;
int mcbc_data_rate = - 1 ;
int num_rates = 0 ;
int found = 0 ;
int filter_mac_count = - 1 ;
int retval = UAP_SUCCESS ;
int chan_mode = 0 ;
int band_flag = 0 ;
int chan_number = 0 ;
t_u16 max_sta_num_supported = 0 ;
fw_info fw ;
HTCap_t htcap ;
int enable_11n = - 1 ;
t_u32 supported_mcs_set = 0 ;
int ac = 0 ;
int is_wmm_parameters = 0 ;
char oui_type [ 4 ] = { 0x00 , 0x50 , 0xf2 , 0x02 } ;
struct eth_priv_vhtcfg vhtcfg = { 0 } ;
/* Check if file exists */
config_file = fopen ( argv [ 0 ] , " r " ) ;
if ( config_file = = NULL ) {
printf ( " \n ERR:Config file can not open. \n " ) ;
return UAP_FAILURE ;
}
line = ( char * ) malloc ( MAX_CONFIG_LINE ) ;
if ( ! line ) {
printf ( " ERR:Cannot allocate memory for line \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
memset ( line , 0 , MAX_CONFIG_LINE ) ;
/* Parse file and process */
while ( config_get_line ( line , MAX_CONFIG_LINE , config_file , & li , & pos ) ) {
# if DEBUG
uap_printf ( MSG_DEBUG , " DBG:Received config line (%d) = %s \n " ,
li , line ) ;
# endif
arg_num = parse_line ( line , args ) ;
# if DEBUG
uap_printf ( MSG_DEBUG , " DBG:Number of arguments = %d \n " ,
arg_num ) ;
for ( i = 0 ; i < arg_num ; i + + ) {
uap_printf ( MSG_DEBUG , " \t DBG:Argument %d. %s \n " , i + 1 ,
args [ i ] ) ;
}
# endif
/* Check for end of AP configurations */
if ( is_ap_config = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 ) {
is_ap_config = 0 ;
if ( tx_data_rate ! = - 1 ) {
if ( ( ! bss - > rates [ 0 ] ) & & ( tx_data_rate )
& &
( is_tx_rate_valid
( ( t_u8 ) tx_data_rate ) ! =
UAP_SUCCESS ) ) {
printf ( " ERR: Invalid Tx Data Rate \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( bss - > rates [ 0 ] & & tx_data_rate ) {
for ( i = 0 ; bss - > rates [ i ] ! = 0 ;
i + + ) {
if ( ( bss - >
rates [ i ] &
~ BASIC_RATE_SET_BIT )
= = tx_data_rate ) {
found = 1 ;
break ;
}
}
if ( ! found ) {
printf ( " ERR: Invalid Tx Data Rate \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
/* Set Tx data rate field */
bss - > tx_data_rate = tx_data_rate ;
}
if ( tx_beacon_rate ! = - 1 ) {
if ( ( ! bss - > rates [ 0 ] ) & & ( tx_beacon_rate )
& &
( is_tx_rate_valid
( ( t_u8 ) tx_beacon_rate ) ! =
UAP_SUCCESS ) ) {
printf ( " ERR: Invalid Tx Beacon Rate \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( bss - > rates [ 0 ] & & tx_beacon_rate ) {
for ( i = 0 ; bss - > rates [ i ] ! = 0 ;
i + + ) {
if ( ( bss - >
rates [ i ] &
~ BASIC_RATE_SET_BIT )
= = tx_beacon_rate ) {
found = 1 ;
break ;
}
}
if ( ! found ) {
printf ( " ERR: Invalid Tx Beacon Rate \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
/* Set Tx beacon rate field */
bss - > tx_beacon_rate = tx_beacon_rate ;
}
if ( mcbc_data_rate ! = - 1 ) {
if ( ( ! bss - > rates [ 0 ] ) & & ( mcbc_data_rate )
& &
( is_mcbc_rate_valid
( ( t_u8 ) mcbc_data_rate ) ! =
UAP_SUCCESS ) ) {
printf ( " ERR: Invalid Tx Data Rate \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( bss - > rates [ 0 ] & & mcbc_data_rate ) {
for ( i = 0 ; bss - > rates [ i ] ! = 0 ;
i + + ) {
if ( bss - >
rates [ i ] &
BASIC_RATE_SET_BIT )
{
if ( ( bss - >
rates [ i ] &
~ BASIC_RATE_SET_BIT )
= =
mcbc_data_rate )
{
found = 1 ;
break ;
}
}
}
if ( ! found ) {
printf ( " ERR: Invalid MCBC Data Rate \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
/* Set MCBC data rate field */
bss - > mcbc_data_rate = mcbc_data_rate ;
}
if ( ( protocol = = PROTOCOL_STATIC_WEP ) & &
( enable_11n = = 1 ) ) {
printf ( " ERR:WEP cannot be used when AP operates in 802.11n mode. \n " ) ;
goto done ;
}
if ( 0 = = get_fw_info ( & fw ) ) {
/*check whether support 802.11AC through BAND_AAC bit */
if ( fw . fw_bands & BAND_AAC ) {
retval = get_802_11ac_cfg
( & vhtcfg ) ;
if ( retval ! = UAP_SUCCESS )
goto done ;
if ( ( enable_11n = = 1 ) & &
( vhtcfg . vht_rx_mcs ! =
0xffff ) ) {
printf ( " ERR: 11n must be enabled when AP operates in 11ac mode. \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
} else
printf ( " No support 802 11AC. \n " ) ;
} else {
printf ( " ERR: get_fw_info fail \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( ( protocol = = PROTOCOL_WPA2_MIXED ) & &
( ( pwkcipher_wpa < 0 ) | |
( pwkcipher_wpa2 < 0 ) ) ) {
printf ( " ERR:Both PwkCipherWPA and PwkCipherWPA2 should be defined for Mixed mode. \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( protocol ! = - 1 ) {
bss - > protocol = protocol ;
if ( protocol &
( PROTOCOL_WPA | PROTOCOL_WPA2 ) ) {
/* Set key management field */
bss - > key_mgmt = KEY_MGMT_PSK ;
bss - > key_mgmt_operation = 0 ;
}
}
if ( ( ( pwkcipher_wpa > = 0 ) | |
( pwkcipher_wpa2 > = 0 ) ) & &
( gwkcipher > = 0 ) ) {
if ( ( protocol = = PROTOCOL_WPA ) | |
( protocol = = PROTOCOL_WPA2_MIXED ) ) {
if ( enable_11n ! = - 1 ) {
if ( is_cipher_valid_with_11n ( pwkcipher_wpa , gwkcipher , protocol , enable_11n ) ! = UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA pairwise cipher combination! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
} else if
( is_cipher_valid_with_proto
( pwkcipher_wpa ,
gwkcipher ,
protocol ) ! =
UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA pairwise cipher combination! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
if ( ( protocol = = PROTOCOL_WPA2 ) | |
( protocol = = PROTOCOL_WPA2_MIXED )
| | ( protocol = = PROTOCOL_WPA3_SAE )
) {
if ( enable_11n ! = - 1 ) {
if ( is_cipher_valid_with_11n ( pwkcipher_wpa2 , gwkcipher , protocol , enable_11n ) ! = UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA2 pairwise cipher combination! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
} else if
( is_cipher_valid_with_proto
( pwkcipher_wpa2 ,
gwkcipher ,
protocol ) ! =
UAP_SUCCESS ) {
printf ( " ERR:Wrong group cipher and WPA2 pairwise cipher combination! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
/* Set pairwise and group cipher fields */
bss - > wpa_cfg . pairwise_cipher_wpa =
pwkcipher_wpa ;
bss - > wpa_cfg . pairwise_cipher_wpa2 =
pwkcipher_wpa2 ;
bss - > wpa_cfg . group_cipher = gwkcipher ;
}
continue ;
}
}
/* Check for beginning of AP configurations */
if ( strcmp ( args [ 0 ] , " ap_config " ) = = 0 ) {
is_ap_config = 1 ;
continue ;
}
/* Check for end of AP MAC address filter configurations */
if ( is_ap_mac_filter = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 ) {
is_ap_mac_filter = 0 ;
if ( bss - > filter . mac_count ! = filter_mac_count ) {
printf ( " ERR:Number of MAC address provided does not match 'Count' \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( bss - > filter . filter_mode & &
( bss - > filter . mac_count = = 0 ) ) {
printf ( " ERR:Filter list can not be empty for %s Filter mode \n " , ( bss - > filter . filter_mode = = 1 ) ? " 'Allow' " : " 'Block' " ) ;
retval = UAP_FAILURE ;
goto done ;
}
continue ;
}
}
/* Check for beginning of AP MAC address filter configurations */
if ( strcmp ( args [ 0 ] , " ap_mac_filter " ) = = 0 ) {
is_ap_mac_filter = 1 ;
bss - > filter . mac_count = 0 ;
filter_mac_count = 0 ;
continue ;
}
if ( ( strcmp ( args [ 0 ] , " FilterMode " ) = = 0 ) & & is_ap_mac_filter ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) | |
( atoi ( args [ 1 ] ) > 2 ) ) {
printf ( " ERR:Illegal FilterMode paramter %d. Must be either '0', '1', or '2'. \n " , atoi ( args [ 1 ] ) ) ;
retval = UAP_FAILURE ;
goto done ;
}
bss - > filter . filter_mode = atoi ( args [ 1 ] ) ;
continue ;
}
if ( ( strcmp ( args [ 0 ] , " Count " ) = = 0 ) & & is_ap_mac_filter ) {
bss - > filter . mac_count = atoi ( args [ 1 ] ) ;
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | |
( bss - > filter . mac_count > MAX_MAC_ONESHOT_FILTER ) ) {
printf ( " ERR: Illegal Count parameter. \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
if ( ( strncmp ( args [ 0 ] , " mac_ " , 4 ) = = 0 ) & & is_ap_mac_filter ) {
if ( filter_mac_count < MAX_MAC_ONESHOT_FILTER ) {
if ( mac2raw
( args [ 1 ] ,
bss - > filter . mac_list [ filter_mac_count ] ) ! =
UAP_SUCCESS ) {
printf ( " ERR: Invalid MAC address %s \n " ,
args [ 1 ] ) ;
retval = UAP_FAILURE ;
goto done ;
}
filter_mac_count + + ;
} else {
printf ( " ERR: Filter table can not have more than %d MAC addresses \n " , MAX_MAC_ONESHOT_FILTER ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
/* Check for end of Wmm Parameters configurations */
if ( is_wmm_parameters = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 ) {
is_wmm_parameters = 0 ;
continue ;
}
}
/* Check for beginning of Sticky Tim Sta MAC address Configurations */
if ( strcmp ( args [ 0 ] , " Wmm_parameters " ) = = 0 ) {
is_wmm_parameters = 1 ;
memset ( & ( bss - > wmm_para ) , 0 , sizeof ( bss - > wmm_para ) ) ;
memcpy ( bss - > wmm_para . ouitype , oui_type ,
sizeof ( oui_type ) ) ;
bss - > wmm_para . ouisubtype = 1 ;
bss - > wmm_para . version = 1 ;
continue ;
}
if ( ( strcmp ( args [ 0 ] , " Qos_info " ) = = 0 ) & & is_wmm_parameters ) {
bss - > wmm_para . qos_info = A2HEXDECIMAL ( args [ 1 ] ) ;
printf ( " wmm_para.qos_info = %2x \n " ,
bss - > wmm_para . qos_info ) ;
if ( ( bss - > wmm_para . qos_info ! = ENABLE_WMM_PS ) & &
( bss - > wmm_para . qos_info ! = DISABLE_WMM_PS ) ) {
printf ( " ERR:qos_info must be either 0x80 or 0x00. \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
if ( ( strcmp ( args [ 0 ] , " AC_BE " ) = = 0 ) & & is_wmm_parameters ) {
ac = 0 ;
}
if ( ( strcmp ( args [ 0 ] , " AC_BK " ) = = 0 ) & & is_wmm_parameters ) {
ac = 1 ;
}
if ( ( strcmp ( args [ 0 ] , " AC_VI " ) = = 0 ) & & is_wmm_parameters ) {
ac = 2 ;
}
if ( ( strcmp ( args [ 0 ] , " AC_VO " ) = = 0 ) & & is_wmm_parameters ) {
ac = 3 ;
}
if ( ( strcmp ( args [ 0 ] , " Aifsn " ) = = 0 ) & & is_wmm_parameters ) {
bss - > wmm_para . ac_params [ ac ] . aci_aifsn . aifsn =
( t_u8 ) A2HEXDECIMAL ( args [ 1 ] ) ;
printf ( " wmm_para.ac_params[%d].aci_aifsn.aifsn = %x \n " ,
ac , bss - > wmm_para . ac_params [ ac ] . aci_aifsn . aifsn ) ;
bss - > wmm_para . ac_params [ ac ] . aci_aifsn . aci = ( t_u8 ) ac ;
printf ( " wmm_para.ac_params[%d].aci_aifsn.aci = %x \n " ,
ac , bss - > wmm_para . ac_params [ ac ] . aci_aifsn . aci ) ;
}
if ( ( strcmp ( args [ 0 ] , " Ecw_max " ) = = 0 ) & & is_wmm_parameters ) {
bss - > wmm_para . ac_params [ ac ] . ecw . ecw_max =
( t_u8 ) A2HEXDECIMAL ( args [ 1 ] ) ;
printf ( " wmm_para.ac_params[%d].ecw.ecw_max = %x \n " , ac ,
bss - > wmm_para . ac_params [ ac ] . ecw . ecw_max ) ;
}
if ( ( strcmp ( args [ 0 ] , " Ecw_min " ) = = 0 ) & & is_wmm_parameters ) {
bss - > wmm_para . ac_params [ ac ] . ecw . ecw_min =
( t_u8 ) A2HEXDECIMAL ( args [ 1 ] ) ;
printf ( " wmm_para.ac_params[%d].ecw.ecw_min = %x \n " , ac ,
bss - > wmm_para . ac_params [ ac ] . ecw . ecw_min ) ;
}
if ( ( strcmp ( args [ 0 ] , " Tx_op " ) = = 0 ) & & is_wmm_parameters ) {
bss - > wmm_para . ac_params [ ac ] . tx_op_limit =
( t_u8 ) A2HEXDECIMAL ( args [ 1 ] ) ;
printf ( " wmm_para.ac_params[%d].tx_op_limit = %x \n " , ac ,
bss - > wmm_para . ac_params [ ac ] . tx_op_limit ) ;
}
if ( strcmp ( args [ 0 ] , " SSID " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:SSID field is blank! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
} else {
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
args [ 1 ] + + ;
}
if ( args [ 1 ] [ strlen ( args [ 1 ] ) - 1 ] = = ' " ' ) {
args [ 1 ] [ strlen ( args [ 1 ] ) - 1 ] = ' \0 ' ;
}
if ( ( strlen ( args [ 1 ] ) > MAX_SSID_LENGTH ) | |
( strlen ( args [ 1 ] ) = = 0 ) ) {
printf ( " ERR:SSID length out of range (%d to %d). \n " , MIN_SSID_LENGTH , MAX_SSID_LENGTH ) ;
retval = UAP_FAILURE ;
goto done ;
}
/* Set SSID field */
bss - > ssid . ssid_len = strlen ( args [ 1 ] ) ;
memcpy ( bss - > ssid . ssid , args [ 1 ] ,
bss - > ssid . ssid_len ) ;
}
}
if ( strcmp ( args [ 0 ] , " BeaconPeriod " ) = = 0 ) {
if ( is_input_valid ( BEACONPERIOD , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set beacon period field */
bss - > beacon_period = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " ChanList " ) = = 0 ) {
if ( is_input_valid ( SCANCHANNELS , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set channel list field */
if ( ( arg_num - 1 ) < MAX_CHANNELS ) {
bss - > num_of_chan = arg_num - 1 ;
} else {
bss - > num_of_chan = MAX_CHANNELS ;
}
for ( i = 0 ; ( unsigned int ) i < bss - > num_of_chan ; i + + ) {
sscanf ( args [ i + 1 ] , " %d.%d " , & chan_number ,
& band_flag ) ;
bss - > chan_list [ i ] . chan_number = chan_number ;
bss - > chan_list [ i ] . bandcfg . chanBand = BAND_2GHZ ;
if ( ( ( band_flag ! = - 1 ) & & ( band_flag ) ) | |
( chan_number > MAX_CHANNELS_BG ) ) {
bss - > chan_list [ i ] . bandcfg . chanBand =
BAND_5GHZ ;
}
}
}
if ( strcmp ( args [ 0 ] , " Channel " ) = = 0 ) {
if ( is_input_valid ( CHANNEL , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set channel field */
bss - > channel = ( t_u8 ) atoi ( args [ 1 ] ) ;
if ( ( arg_num - 1 ) = = 2 ) {
chan_mode = atoi ( args [ 2 ] ) ;
memset ( & ( bss - > bandcfg ) , 0 ,
sizeof ( bss - > bandcfg ) ) ;
if ( chan_mode & BITMAP_ACS_MODE ) {
int mode ;
if ( uap_ioctl_dfs_repeater_mode ( & mode )
= = UAP_SUCCESS ) {
if ( mode ) {
printf ( " ERR: ACS in DFS Repeater mode " " is not allowed \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
bss - > bandcfg . scanMode = SCAN_MODE_ACS ;
}
if ( chan_mode & BITMAP_CHANNEL_ABOVE )
bss - > bandcfg . chan2Offset =
SEC_CHAN_ABOVE ;
if ( chan_mode & BITMAP_CHANNEL_BELOW )
bss - > bandcfg . chan2Offset =
SEC_CHAN_BELOW ;
} else
memset ( & ( bss - > bandcfg ) , 0 ,
sizeof ( bss - > bandcfg ) ) ;
if ( bss - > channel > MAX_CHANNELS_BG )
bss - > bandcfg . chanBand = BAND_5GHZ ;
}
if ( strcmp ( args [ 0 ] , " Band " ) = = 0 ) {
if ( is_input_valid ( BAND , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Clear previously set band */
bss - > bandcfg . chanBand = BAND_2GHZ ;
if ( atoi ( args [ 1 ] ) = = 1 )
bss - > bandcfg . chanBand = BAND_5GHZ ;
}
if ( strcmp ( args [ 0 ] , " AP_MAC " ) = = 0 ) {
int ret ;
if ( ( ret =
mac2raw ( args [ 1 ] , bss - > mac_addr ) ) ! = UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " ,
ret = =
UAP_FAILURE ? " Invalid MAC " : ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " :
" Multicast " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
if ( strcmp ( args [ 0 ] , " Rate " ) = = 0 ) {
if ( is_input_valid ( RATE , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
printf ( " ERR: Invalid Rate input \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
/* Set rates field */
if ( ( arg_num - 1 ) < MAX_DATA_RATES ) {
num_rates = arg_num - 1 ;
} else {
num_rates = MAX_DATA_RATES ;
}
for ( i = 0 ; i < num_rates ; i + + ) {
bss - > rates [ i ] = ( t_u8 ) A2HEXDECIMAL ( args [ i + 1 ] ) ;
}
}
if ( strcmp ( args [ 0 ] , " TxPowerLevel " ) = = 0 ) {
if ( is_input_valid ( TXPOWER , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
printf ( " ERR:Invalid TxPowerLevel \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
/* Set Tx power level field */
bss - > tx_power_level = ( t_u8 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " BroadcastSSID " ) = = 0 ) {
if ( is_input_valid ( BROADCASTSSID , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set broadcast SSID control field */
bss - > bcast_ssid_ctl = ( t_u8 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " RTSThreshold " ) = = 0 ) {
if ( is_input_valid ( RTSTHRESH , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set RTS threshold field */
bss - > rts_threshold = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " FragThreshold " ) = = 0 ) {
if ( is_input_valid ( FRAGTHRESH , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set Frag threshold field */
bss - > frag_threshold = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " DTIMPeriod " ) = = 0 ) {
if ( is_input_valid ( DTIMPERIOD , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set DTIM period field */
bss - > dtim_period = ( t_u8 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " RSNReplayProtection " ) = = 0 ) {
if ( is_input_valid ( RSNREPLAYPROT , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set RSN replay protection field */
bss - > wpa_cfg . rsn_protection = ( t_u8 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " PairwiseUpdateTimeout " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set Pairwise Update Timeout field */
bss - > pairwise_update_timeout = ( t_u32 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " PairwiseHandshakeRetries " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set Pairwise Hanshake Retries */
bss - > pwk_retries = ( t_u32 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " GroupwiseUpdateTimeout " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set Groupwise Update Timeout field */
bss - > groupwise_update_timeout = ( t_u32 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " GroupwiseHandshakeRetries " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set Groupwise Hanshake Retries */
bss - > gwk_retries = ( t_u32 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " TxBeaconRate " ) = = 0 ) {
if ( is_input_valid ( TXBEACONRATE , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
tx_beacon_rate = ( t_u16 ) A2HEXDECIMAL ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " MCBCdataRate " ) = = 0 ) {
if ( is_input_valid ( MCBCDATARATE , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
mcbc_data_rate = ( t_u16 ) A2HEXDECIMAL ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " PktFwdCtl " ) = = 0 ) {
if ( is_input_valid ( PKTFWD , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set packet forward control field */
bss - > pkt_forward_ctl = ( t_u8 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " StaAgeoutTimer " ) = = 0 ) {
if ( is_input_valid
( STAAGEOUTTIMER , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set STA ageout timer field */
bss - > sta_ageout_timer = ( t_u32 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " PSStaAgeoutTimer " ) = = 0 ) {
if ( is_input_valid
( PSSTAAGEOUTTIMER , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set PS STA ageout timer field */
bss - > ps_sta_ageout_timer = ( t_u32 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " AuthMode " ) = = 0 ) {
if ( is_input_valid ( AUTHMODE , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set auth mode field */
bss - > auth_mode = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " KeyIndex " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " KeyIndex is blank! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
} else {
if ( ISDIGIT ( args [ 1 ] ) = = 0 ) {
printf ( " ERR:Illegal KeyIndex parameter. Must be either '0', '1', '2', or '3'. \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
keyindex = atoi ( args [ 1 ] ) ;
if ( ( keyindex < 0 ) | | ( keyindex > 3 ) ) {
printf ( " ERR:Illegal KeyIndex parameter. Must be either '0', '1', '2', or '3'. \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
switch ( keyindex ) {
case 0 :
bss - > wep_cfg . key0 . is_default = 1 ;
break ;
case 1 :
bss - > wep_cfg . key1 . is_default = 1 ;
break ;
case 2 :
bss - > wep_cfg . key2 . is_default = 1 ;
break ;
case 3 :
bss - > wep_cfg . key3 . is_default = 1 ;
break ;
}
}
}
if ( strncmp ( args [ 0 ] , " Key_ " , 4 ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:%s is blank! \n " , args [ 0 ] ) ;
retval = UAP_FAILURE ;
goto done ;
} else {
int key_len = 0 ;
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
if ( ( strlen ( args [ 1 ] ) ! = 2 ) & &
( strlen ( args [ 1 ] ) ! = 7 ) & &
( strlen ( args [ 1 ] ) ! = 15 ) ) {
printf ( " ERR:Wrong key length! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
key_len = strlen ( args [ 1 ] ) - 2 ;
} else {
if ( ( strlen ( args [ 1 ] ) ! = 0 ) & &
( strlen ( args [ 1 ] ) ! = 10 ) & &
( strlen ( args [ 1 ] ) ! = 26 ) ) {
printf ( " ERR:Wrong key length! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( UAP_FAILURE = = ishexstring ( args [ 1 ] ) ) {
printf ( " ERR:Only hex digits are allowed when key length is 10 or 26 \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
key_len = strlen ( args [ 1 ] ) / 2 ;
}
/* Set WEP key fields */
if ( strcmp ( args [ 0 ] , " Key_0 " ) = = 0 ) {
bss - > wep_cfg . key0 . key_index = 0 ;
bss - > wep_cfg . key0 . length = key_len ;
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
memcpy ( bss - > wep_cfg . key0 . key ,
& args [ 1 ] [ 1 ] ,
strlen ( args [ 1 ] ) - 2 ) ;
} else {
string2raw ( args [ 1 ] ,
bss - > wep_cfg . key0 .
key ) ;
}
} else if ( strcmp ( args [ 0 ] , " Key_1 " ) = = 0 ) {
bss - > wep_cfg . key1 . key_index = 1 ;
bss - > wep_cfg . key1 . length = key_len ;
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
memcpy ( bss - > wep_cfg . key1 . key ,
& args [ 1 ] [ 1 ] ,
strlen ( args [ 1 ] ) - 2 ) ;
} else {
string2raw ( args [ 1 ] ,
bss - > wep_cfg . key1 .
key ) ;
}
} else if ( strcmp ( args [ 0 ] , " Key_2 " ) = = 0 ) {
bss - > wep_cfg . key2 . key_index = 2 ;
bss - > wep_cfg . key2 . length = key_len ;
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
memcpy ( bss - > wep_cfg . key2 . key ,
& args [ 1 ] [ 1 ] ,
strlen ( args [ 1 ] ) - 2 ) ;
} else {
string2raw ( args [ 1 ] ,
bss - > wep_cfg . key2 .
key ) ;
}
} else if ( strcmp ( args [ 0 ] , " Key_3 " ) = = 0 ) {
bss - > wep_cfg . key3 . key_index = 3 ;
bss - > wep_cfg . key3 . length = key_len ;
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
memcpy ( bss - > wep_cfg . key3 . key ,
& args [ 1 ] [ 1 ] ,
strlen ( args [ 1 ] ) - 2 ) ;
} else {
string2raw ( args [ 1 ] ,
bss - > wep_cfg . key3 .
key ) ;
}
}
}
}
if ( strcmp ( args [ 0 ] , " PSK " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:PSK is blank! \n " ) ;
retval = UAP_FAILURE ;
goto done ;
} else {
if ( args [ 1 ] [ 0 ] = = ' " ' ) {
args [ 1 ] + + ;
}
if ( args [ 1 ] [ strlen ( args [ 1 ] ) - 1 ] = = ' " ' ) {
args [ 1 ] [ strlen ( args [ 1 ] ) - 1 ] = ' \0 ' ;
}
if ( strlen ( args [ 1 ] ) > MAX_WPA_PASSPHRASE_LENGTH ) {
printf ( " ERR:PSK too long. \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( strlen ( args [ 1 ] ) < MIN_WPA_PASSPHRASE_LENGTH ) {
printf ( " ERR:PSK too short. \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
if ( strlen ( args [ 1 ] ) = =
MAX_WPA_PASSPHRASE_LENGTH ) {
if ( UAP_FAILURE = = ishexstring ( args [ 1 ] ) ) {
printf ( " ERR:Only hex digits are allowed when passphrase's length is 64 \n " ) ;
retval = UAP_FAILURE ;
goto done ;
}
}
/* Set WPA passphrase field */
bss - > wpa_cfg . length = strlen ( args [ 1 ] ) ;
memcpy ( bss - > wpa_cfg . passphrase , args [ 1 ] ,
bss - > wpa_cfg . length ) ;
}
}
if ( strcmp ( args [ 0 ] , " Protocol " ) = = 0 ) {
if ( is_input_valid ( PROTOCOL , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set protocol field */
protocol = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
if ( ( strcmp ( args [ 0 ] , " PairwiseCipher " ) = = 0 ) | |
( strcmp ( args [ 0 ] , " GroupCipher " ) = = 0 ) ) {
printf ( " ERR:PairwiseCipher and GroupCipher are not supported. \n " " Please configure pairwise cipher using parameters PwkCipherWPA or PwkCipherWPA2 \n " " and group cipher using GwkCipher in the config file. \n " ) ;
goto done ;
}
if ( ( protocol = = PROTOCOL_NO_SECURITY ) | |
( protocol = = PROTOCOL_STATIC_WEP ) ) {
if ( ( strcmp ( args [ 0 ] , " PwkCipherWPA " ) = = 0 ) | |
( strcmp ( args [ 0 ] , " PwkCipherWPA2 " ) = = 0 )
| | ( strcmp ( args [ 0 ] , " GwkCipher " ) = = 0 ) ) {
printf ( " ERR:Pairwise cipher and group cipher should not be defined for Open and WEP mode. \n " ) ;
goto done ;
}
}
if ( strcmp ( args [ 0 ] , " PwkCipherWPA " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:PwkCipherWPA is blank! \n " ) ;
goto done ;
} else {
if ( ISDIGIT ( args [ 1 ] ) = = 0 ) {
printf ( " ERR:Illegal PwkCipherWPA parameter. Must be either bit '2' or '3'. \n " ) ;
goto done ;
}
if ( atoi ( args [ 1 ] ) & ~ CIPHER_BITMAP ) {
printf ( " ERR:Illegal PwkCipherWPA parameter. Must be either bit '2' or '3'. \n " ) ;
goto done ;
}
pwkcipher_wpa = atoi ( args [ 1 ] ) ;
if ( enable_11n & &
protocol ! = PROTOCOL_WPA2_MIXED ) {
memset ( & htcap , 0 , sizeof ( htcap ) ) ;
if ( UAP_SUCCESS = =
get_sys_cfg_11n ( & htcap ) ) {
if ( htcap . supported_mcs_set [ 0 ]
& & ( atoi ( args [ 1 ] ) = =
CIPHER_TKIP ) ) {
printf ( " ERR: WPA/TKIP cannot be used when AP operates in 802.11n mode. \n " ) ;
return UAP_FAILURE ;
}
}
}
}
}
if ( strcmp ( args [ 0 ] , " PwkCipherWPA2 " ) = = 0 ) {
if ( arg_num = = 1 ) {
printf ( " ERR:PwkCipherWPA2 is blank! \n " ) ;
goto done ;
} else {
if ( ISDIGIT ( args [ 1 ] ) = = 0 ) {
printf ( " ERR:Illegal PwkCipherWPA2 parameter. Must be either bit '2' or '3'. \n " ) ;
goto done ;
}
if ( atoi ( args [ 1 ] ) & ~ CIPHER_BITMAP ) {
printf ( " ERR:Illegal PwkCipherWPA2 parameter. Must be either bit '2' or '3'. \n " ) ;
goto done ;
}
pwkcipher_wpa2 = atoi ( args [ 1 ] ) ;
if ( enable_11n & &
protocol ! = PROTOCOL_WPA2_MIXED ) {
memset ( & htcap , 0 , sizeof ( htcap ) ) ;
if ( UAP_SUCCESS = =
get_sys_cfg_11n ( & htcap ) ) {
if ( htcap . supported_mcs_set [ 0 ]
& & ( atoi ( args [ 1 ] ) = =
CIPHER_TKIP ) ) {
printf ( " ERR: WPA/TKIP cannot be used when AP operates in 802.11n mode. \n " ) ;
return UAP_FAILURE ;
}
}
}
}
}
if ( strcmp ( args [ 0 ] , " GwkCipher " ) = = 0 ) {
if ( is_input_valid ( GWK_CIPHER , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
goto done ;
}
gwkcipher = atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " GroupRekeyTime " ) = = 0 ) {
if ( is_input_valid
( GROUPREKEYTIMER , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set group rekey time field */
bss - > wpa_cfg . gk_rekey_time = ( t_u32 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " MaxStaNum " ) = = 0 ) {
if ( is_input_valid ( MAXSTANUM , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
if ( get_max_sta_num_supported ( & max_sta_num_supported ) = =
UAP_FAILURE ) {
retval = UAP_FAILURE ;
goto done ;
}
if ( atoi ( args [ 1 ] ) > max_sta_num_supported ) {
printf ( " ERR: MAX_STA_NUM must be less than %d \n " , max_sta_num_supported ) ;
retval = UAP_FAILURE ;
goto done ;
}
/* Set max STA number field */
bss - > max_sta_count = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " Retrylimit " ) = = 0 ) {
if ( is_input_valid ( RETRYLIMIT , arg_num - 1 , args + 1 ) ! =
UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set retry limit field */
bss - > retry_limit = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " PreambleType " ) = = 0 ) {
if ( is_input_valid ( PREAMBLETYPE , arg_num - 1 , args + 1 )
! = UAP_SUCCESS ) {
retval = UAP_FAILURE ;
goto done ;
}
/* Set preamble type field */
bss - > preamble_type = ( t_u8 ) atoi ( args [ 1 ] ) ;
}
if ( strcmp ( args [ 0 ] , " Enable11n " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) ! = UAP_SUCCESS ) | |
( atoi ( args [ 1 ] ) < 0 ) | | ( atoi ( args [ 1 ] ) > 1 ) ) {
printf ( " ERR: Invalid Enable11n value \n " ) ;
goto done ;
}
enable_11n = atoi ( args [ 1 ] ) ;
memset ( & htcap , 0 , sizeof ( htcap ) ) ;
if ( UAP_SUCCESS ! = get_sys_cfg_11n ( & htcap ) ) {
printf ( " ERR: Reading current 11n configuration. \n " ) ;
goto done ;
}
bss - > ht_cap_info = htcap . ht_cap_info ;
bss - > ampdu_param = htcap . ampdu_param ;
memcpy ( bss - > supported_mcs_set , htcap . supported_mcs_set ,
16 ) ;
bss - > ht_ext_cap = htcap . ht_ext_cap ;
bss - > tx_bf_cap = htcap . tx_bf_cap ;
bss - > asel = htcap . asel ;
if ( enable_11n = = 1 ) {
/* enable mcs rate */
bss - > supported_mcs_set [ 0 ] = DEFAULT_MCS_SET_0 ;
bss - > supported_mcs_set [ 4 ] = DEFAULT_MCS_SET_4 ;
if ( 0 = = get_fw_info ( & fw ) ) {
if ( ( fw . hw_dev_mcs_support & 0x0f ) > = 2 )
bss - > supported_mcs_set [ 1 ] =
DEFAULT_MCS_SET_1 ;
}
} else {
/* disable mcs rate */
bss - > supported_mcs_set [ 0 ] = 0 ;
bss - > supported_mcs_set [ 4 ] = 0 ;
bss - > supported_mcs_set [ 1 ] = 0 ;
}
}
if ( strcmp ( args [ 0 ] , " HTCapInfo " ) = = 0 ) {
if ( enable_11n < = 0 ) {
printf ( " ERR: Enable11n parameter should be set before HTCapInfo. \n " ) ;
goto done ;
}
if ( ( IS_HEX_OR_DIGIT ( args [ 1 ] ) = = UAP_FAILURE ) | |
( ( ( ( t_u16 ) A2HEXDECIMAL ( args [ 1 ] ) ) &
( ~ HT_CAP_CONFIG_MASK ) ) ! = HT_CAP_CHECK_MASK ) ) {
printf ( " ERR: Invalid HTCapInfo value \n " ) ;
goto done ;
}
bss - > ht_cap_info =
DEFAULT_HT_CAP_VALUE & ~ HT_CAP_CONFIG_MASK ;
bss - > ht_cap_info | =
( t_u16 ) A2HEXDECIMAL ( args [ 1 ] ) &
HT_CAP_CONFIG_MASK ;
bss - > ht_cap_info = uap_cpu_to_le16 ( bss - > ht_cap_info ) ;
}
if ( strcmp ( args [ 0 ] , " AMPDU " ) = = 0 ) {
if ( enable_11n < = 0 ) {
printf ( " ERR: Enable11n parameter should be set before AMPDU. \n " ) ;
goto done ;
}
if ( ( IS_HEX_OR_DIGIT ( args [ 1 ] ) = = UAP_FAILURE ) | |
( ( A2HEXDECIMAL ( args [ 1 ] ) ) > AMPDU_CONFIG_MASK ) ) {
printf ( " ERR: Invalid AMPDU value \n " ) ;
goto done ;
}
/* Find HT tlv pointer in buffer and set AMPDU */
bss - > ampdu_param =
( t_u8 ) A2HEXDECIMAL ( args [ 1 ] ) & AMPDU_CONFIG_MASK ;
}
if ( strcmp ( args [ 0 ] , " HT_MCS_MAP " ) = = 0 ) {
if ( enable_11n < = 0 ) {
printf ( " ERR: Enable11n parameter should be set before HT_MCS_MAP. \n " ) ;
goto done ;
}
if ( ( IS_HEX_OR_DIGIT ( args [ 1 ] ) = = UAP_FAILURE ) ) {
printf ( " ERR: Invalid HT_MCS_MAP value \n " ) ;
goto done ;
}
if ( 0 = = get_fw_info ( & fw ) ) {
/* Check upper nibble of MCS support value
* and block MCS_SET_1 when 2 X2 is not supported
* by the underlying hardware */
if ( ( ( fw . hw_dev_mcs_support & 0xf0 ) <
STREAM_2X2_MASK ) & &
( A2HEXDECIMAL ( args [ 1 ] ) & MCS_SET_1_MASK ) ) {
printf ( " ERR: Invalid HT_MCS_MAP \n " ) ;
goto done ;
}
}
supported_mcs_set = ( t_u32 ) A2HEXDECIMAL ( args [ 1 ] ) ;
supported_mcs_set = uap_cpu_to_le32 ( supported_mcs_set ) ;
memcpy ( bss - > supported_mcs_set , & supported_mcs_set ,
sizeof ( t_u32 ) ) ;
}
if ( strcmp ( args [ 0 ] , " Enable2040Coex " ) = = 0 ) {
if ( ( ISDIGIT ( args [ 1 ] ) = = 0 ) | | ( atoi ( args [ 1 ] ) < 0 ) | |
( atoi ( args [ 1 ] ) > 1 ) ) {
printf ( " ERR:Invalid Enable2040Coex value. \n " ) ;
goto done ;
}
bss - > enable_2040coex = ( t_u8 ) atoi ( args [ 1 ] ) ;
}
}
done :
fclose ( config_file ) ;
if ( line )
free ( line ) ;
return retval ;
}
/**
* @ brief Show all the BSS configuration in the buffer
*
* @ param buf Pointer to BSS configuration buffer
*
* $ return N / A
*/
void
print_bss_config ( bss_config_t * buf )
{
int i = 0 ;
int flag = 0 ;
if ( ! buf ) {
printf ( " ERR:Empty BSS config! \n " ) ;
return ;
}
/* Print AP MAC address */
printf ( " AP MAC address = " ) ;
print_mac ( buf - > mac_addr ) ;
printf ( " \n " ) ;
/* Print SSID */
if ( buf - > ssid . ssid_len ) {
printf ( " SSID = %s \n " , buf - > ssid . ssid ) ;
}
/* Print broadcast SSID control */
printf ( " SSID broadcast = %s \n " ,
( buf - > bcast_ssid_ctl = = 1 ) ? " enabled " : " disabled " ) ;
/* Print DTIM period */
printf ( " DTIM period = %d \n " , buf - > dtim_period ) ;
/* Print beacon period */
printf ( " Beacon period = %d \n " , buf - > beacon_period ) ;
/* Print rates */
printf ( " Basic Rates = " ) ;
for ( i = 0 ; i < MAX_DATA_RATES ; i + + ) {
if ( ! buf - > rates [ i ] )
break ;
if ( buf - > rates [ i ] > ( BASIC_RATE_SET_BIT - 1 ) ) {
flag = flag ? : 1 ;
printf ( " 0x%x " , buf - > rates [ i ] ) ;
}
}
printf ( " %s \n Non-Basic Rates = " , flag ? " " : " ( none ) " ) ;
for ( flag = 0 , i = 0 ; i < MAX_DATA_RATES ; i + + ) {
if ( ! buf - > rates [ i ] )
break ;
if ( buf - > rates [ i ] < BASIC_RATE_SET_BIT ) {
flag = flag ? : 1 ;
printf ( " 0x%x " , buf - > rates [ i ] ) ;
}
}
printf ( " %s \n " , flag ? " " : " ( none ) " ) ;
/* Print Tx data rate */
printf ( " Tx data rate = " ) ;
if ( buf - > tx_data_rate = = 0 )
printf ( " auto \n " ) ;
else
printf ( " 0x%x \n " , buf - > tx_data_rate ) ;
/* Print MCBC data rate */
printf ( " MCBC data rate = " ) ;
if ( buf - > mcbc_data_rate = = 0 )
printf ( " auto \n " ) ;
else
printf ( " 0x%x \n " , buf - > mcbc_data_rate ) ;
/* Print Tx power level */
printf ( " Tx power = %d dBm \n " , buf - > tx_power_level ) ;
/* Print Tx antenna */
printf ( " Tx antenna = %s \n " , ( buf - > tx_antenna ) ? " B " : " A " ) ;
/* Print Rx antenna */
printf ( " Rx antenna = %s \n " , ( buf - > rx_antenna ) ? " B " : " A " ) ;
/* Print packet forward control */
printf ( " %s handles packet forwarding - \n " ,
( ( buf - > pkt_forward_ctl & PKT_FWD_FW_BIT ) = =
0 ) ? " Host " : " Firmware " ) ;
printf ( " \t Intra-BSS broadcast packets are %s \n " ,
( ( buf - > pkt_forward_ctl & PKT_FWD_INTRA_BCAST ) = =
0 ) ? " allowed " : " denied " ) ;
printf ( " \t Intra-BSS unicast packets are %s \n " ,
( ( buf - > pkt_forward_ctl & PKT_FWD_INTRA_UCAST ) = =
0 ) ? " allowed " : " denied " ) ;
printf ( " \t Inter-BSS unicast packets are %s \n " ,
( ( buf - > pkt_forward_ctl & PKT_FWD_INTER_UCAST ) = =
0 ) ? " allowed " : " denied " ) ;
/* Print maximum STA count */
printf ( " Max Station Number configured = %d \n " , buf - > max_sta_count ) ;
/* Print mgmt frame FWD control */
printf ( " MGMT frame Fwd Control = 0x%x \n " , buf - > mgmt_ie_passthru_mask ) ;
/* Print MAC filter */
if ( buf - > filter . filter_mode = = 0 ) {
printf ( " Filter Mode = Filter table is disabled \n " ) ;
} else {
if ( buf - > filter . filter_mode = = 1 ) {
printf ( " Filter Mode = Allow MAC addresses specified in the allowed list \n " ) ;
} else if ( buf - > filter . filter_mode = = 2 ) {
printf ( " Filter Mode = Block MAC addresses specified in the banned list \n " ) ;
} else {
printf ( " Filter Mode = Unknown \n " ) ;
}
for ( i = 0 ; i < buf - > filter . mac_count ; i + + ) {
printf ( " MAC_%d = " , i ) ;
print_mac ( buf - > filter . mac_list [ i ] ) ;
printf ( " \n " ) ;
}
}
/* Print STA ageout timer */
printf ( " STA ageout timer = %d \n " , buf - > sta_ageout_timer ) ;
/* Print PS STA ageout timer */
printf ( " PS STA ageout timer = %d \n " , buf - > ps_sta_ageout_timer ) ;
/* Print RTS threshold */
printf ( " RTS threshold = %d \n " , buf - > rts_threshold ) ;
/* Print Fragmentation threshold */
printf ( " Fragmentation threshold = %d \n " , buf - > frag_threshold ) ;
/* Print retry limit */
printf ( " Retry Limit = %d \n " , buf - > retry_limit ) ;
/* Print preamble type */
printf ( " Preamble type = %s \n " , ( buf - > preamble_type = = 0 ) ?
" auto " : ( ( buf - > preamble_type = = 1 ) ? " short " : " long " ) ) ;
/* Print channel */
printf ( " Channel = %d \n " , buf - > channel ) ;
printf ( " Band = %s \n " ,
( buf - > bandcfg . chanBand = = BAND_5GHZ ) ? " 5GHz " : " 2.4GHz " ) ;
printf ( " Channel Select Mode = %s \n " ,
( buf - > bandcfg . scanMode = = SCAN_MODE_ACS ) ? " ACS " : " Manual " ) ;
if ( buf - > bandcfg . chan2Offset = = SEC_CHAN_NONE )
printf ( " no secondary channel \n " ) ;
else if ( buf - > bandcfg . chan2Offset = = SEC_CHAN_ABOVE )
printf ( " secondary channel is above primary channel \n " ) ;
else if ( buf - > bandcfg . chan2Offset = = SEC_CHAN_BELOW )
printf ( " secondary channel is below primary channel \n " ) ;
/* Print channel list */
printf ( " Channels List = " ) ;
for ( i = 0 ; ( unsigned int ) i < buf - > num_of_chan ; i + + ) {
printf ( " \n %d \t %sGHz " , buf - > chan_list [ i ] . chan_number ,
( buf - > chan_list [ i ] . bandcfg . chanBand = =
BAND_5GHZ ) ? " 5 " : " 2.4 " ) ;
}
printf ( " \n " ) ;
/* Print auth mode */
switch ( buf - > auth_mode ) {
case 0 :
printf ( " AUTHMODE = Open authentication \n " ) ;
break ;
case 1 :
printf ( " AUTHMODE = Shared key authentication \n " ) ;
break ;
case 3 :
printf ( " AUTHMODE = WPA3 SAE \n " ) ;
break ;
case 255 :
printf ( " AUTHMODE = Auto (open and shared key) \n " ) ;
break ;
default :
printf ( " ERR: Invalid authmode=%d \n " , buf - > auth_mode ) ;
break ;
}
/* Print protocol */
switch ( buf - > protocol ) {
case 0 :
case PROTOCOL_NO_SECURITY :
printf ( " PROTOCOL = No security \n " ) ;
break ;
case PROTOCOL_STATIC_WEP :
printf ( " PROTOCOL = Static WEP \n " ) ;
break ;
case PROTOCOL_WPA :
printf ( " PROTOCOL = WPA \n " ) ;
break ;
case PROTOCOL_WPA2 :
printf ( " PROTOCOL = WPA2 \n " ) ;
break ;
case PROTOCOL_WPA | PROTOCOL_WPA2 :
printf ( " PROTOCOL = WPA/WPA2 \n " ) ;
break ;
case PROTOCOL_WPA3_SAE :
printf ( " PROTOCOL = WPA3 SAE \n " ) ;
break ;
default :
printf ( " Unknown PROTOCOL: 0x%x \n " , buf - > protocol ) ;
break ;
}
/* Print key management */
if ( buf - > key_mgmt = = KEY_MGMT_PSK )
printf ( " KeyMgmt = PSK \n " ) ;
else
printf ( " KeyMgmt = NONE \n " ) ;
/* Print WEP configurations */
if ( buf - > wep_cfg . key0 . length ) {
printf ( " WEP KEY_0 = " ) ;
for ( i = 0 ; i < buf - > wep_cfg . key0 . length ; i + + ) {
printf ( " %02x " , buf - > wep_cfg . key0 . key [ i ] ) ;
}
( buf - > wep_cfg . key0 .
is_default ) ? ( printf ( " <Default> \n " ) ) : ( printf ( " \n " ) ) ;
} else {
printf ( " WEP KEY_0 = NONE \n " ) ;
}
if ( buf - > wep_cfg . key1 . length ) {
printf ( " WEP KEY_1 = " ) ;
for ( i = 0 ; i < buf - > wep_cfg . key1 . length ; i + + ) {
printf ( " %02x " , buf - > wep_cfg . key1 . key [ i ] ) ;
}
( buf - > wep_cfg . key1 .
is_default ) ? ( printf ( " <Default> \n " ) ) : ( printf ( " \n " ) ) ;
} else {
printf ( " WEP KEY_1 = NONE \n " ) ;
}
if ( buf - > wep_cfg . key2 . length ) {
printf ( " WEP KEY_2 = " ) ;
for ( i = 0 ; i < buf - > wep_cfg . key2 . length ; i + + ) {
printf ( " %02x " , buf - > wep_cfg . key2 . key [ i ] ) ;
}
( buf - > wep_cfg . key2 .
is_default ) ? ( printf ( " <Default> \n " ) ) : ( printf ( " \n " ) ) ;
} else {
printf ( " WEP KEY_2 = NONE \n " ) ;
}
if ( buf - > wep_cfg . key3 . length ) {
printf ( " WEP KEY_3 = " ) ;
for ( i = 0 ; i < buf - > wep_cfg . key3 . length ; i + + ) {
printf ( " %02x " , buf - > wep_cfg . key3 . key [ i ] ) ;
}
( buf - > wep_cfg . key3 .
is_default ) ? ( printf ( " <Default> \n " ) ) : ( printf ( " \n " ) ) ;
} else {
printf ( " WEP KEY_3 = NONE \n " ) ;
}
/* Print WPA configurations */
if ( buf - > protocol & PROTOCOL_WPA ) {
switch ( buf - > wpa_cfg . pairwise_cipher_wpa ) {
case CIPHER_TKIP :
printf ( " PwkCipherWPA = TKIP \n " ) ;
break ;
case CIPHER_AES_CCMP :
printf ( " PwkCipherWPA = AES CCMP \n " ) ;
break ;
case CIPHER_TKIP | CIPHER_AES_CCMP :
printf ( " PwkCipherWPA = TKIP + AES CCMP \n " ) ;
break ;
case CIPHER_NONE :
printf ( " PwkCipherWPA = None \n " ) ;
break ;
default :
printf ( " Unknown PwkCipherWPA 0x%x \n " ,
buf - > wpa_cfg . pairwise_cipher_wpa ) ;
break ;
}
}
if ( buf - > protocol & ( PROTOCOL_WPA2 | PROTOCOL_WPA3_SAE ) ) {
switch ( buf - > wpa_cfg . pairwise_cipher_wpa2 ) {
case CIPHER_TKIP :
printf ( " PwkCipherWPA2 = TKIP \n " ) ;
break ;
case CIPHER_AES_CCMP :
printf ( " PwkCipherWPA2 = AES CCMP \n " ) ;
break ;
case CIPHER_TKIP | CIPHER_AES_CCMP :
printf ( " PwkCipherWPA2 = TKIP + AES CCMP \n " ) ;
break ;
case CIPHER_NONE :
printf ( " PwkCipherWPA2 = None \n " ) ;
break ;
default :
printf ( " Unknown PwkCipherWPA2 0x%x \n " ,
buf - > wpa_cfg . pairwise_cipher_wpa2 ) ;
break ;
}
}
switch ( buf - > wpa_cfg . group_cipher ) {
case CIPHER_TKIP :
printf ( " GroupCipher = TKIP \n " ) ;
break ;
case CIPHER_AES_CCMP :
printf ( " GroupCipher = AES CCMP \n " ) ;
break ;
case CIPHER_NONE :
printf ( " GroupCipher = None \n " ) ;
break ;
default :
printf ( " Unknown Group cipher 0x%x \n " ,
buf - > wpa_cfg . group_cipher ) ;
break ;
}
printf ( " RSN replay protection = %s \n " ,
( buf - > wpa_cfg . rsn_protection ) ? " enabled " : " disabled " ) ;
printf ( " Pairwise Handshake timeout = %d \n " ,
buf - > pairwise_update_timeout ) ;
printf ( " Pairwise Handshake Retries = %d \n " , buf - > pwk_retries ) ;
printf ( " Groupwise Handshake timeout = %d \n " ,
buf - > groupwise_update_timeout ) ;
printf ( " Groupwise Handshake Retries = %d \n " , buf - > gwk_retries ) ;
if ( buf - > wpa_cfg . length > 0 ) {
printf ( " WPA passphrase = " ) ;
for ( i = 0 ; ( unsigned int ) i < buf - > wpa_cfg . length ; i + + )
printf ( " %c " , buf - > wpa_cfg . passphrase [ i ] ) ;
printf ( " \n " ) ;
} else {
printf ( " WPA passphrase = None \n " ) ;
}
if ( buf - > wpa_cfg . gk_rekey_time = = 0 )
printf ( " Group re-key time = disabled \n " ) ;
else
printf ( " Group re-key time = %d second \n " ,
buf - > wpa_cfg . gk_rekey_time ) ;
printf ( " 20/40 coex = %s \n " ,
( buf - > enable_2040coex ) ? " enabled " : " disabled " ) ;
printf ( " wmm parameters: \n " ) ;
printf ( " \t qos_info = 0x%x \n " , buf - > wmm_para . qos_info ) ;
printf ( " \t BE: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d \n " ,
buf - > wmm_para . ac_params [ AC_BE ] . aci_aifsn . aifsn ,
buf - > wmm_para . ac_params [ AC_BE ] . ecw . ecw_max ,
buf - > wmm_para . ac_params [ AC_BE ] . ecw . ecw_min ,
buf - > wmm_para . ac_params [ AC_BE ] . tx_op_limit ) ;
printf ( " \t BK: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d \n " ,
buf - > wmm_para . ac_params [ AC_BK ] . aci_aifsn . aifsn ,
buf - > wmm_para . ac_params [ AC_BK ] . ecw . ecw_max ,
buf - > wmm_para . ac_params [ AC_BK ] . ecw . ecw_min ,
buf - > wmm_para . ac_params [ AC_BK ] . tx_op_limit ) ;
printf ( " \t VI: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d \n " ,
buf - > wmm_para . ac_params [ AC_VI ] . aci_aifsn . aifsn ,
buf - > wmm_para . ac_params [ AC_VI ] . ecw . ecw_max ,
buf - > wmm_para . ac_params [ AC_VI ] . ecw . ecw_min ,
buf - > wmm_para . ac_params [ AC_VI ] . tx_op_limit ) ;
printf ( " \t VO: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d \n " ,
buf - > wmm_para . ac_params [ AC_VO ] . aci_aifsn . aifsn ,
buf - > wmm_para . ac_params [ AC_VO ] . ecw . ecw_max ,
buf - > wmm_para . ac_params [ AC_VO ] . ecw . ecw_min ,
buf - > wmm_para . ac_params [ AC_VO ] . tx_op_limit ) ;
return ;
}
/**
* @ brief Send command to Read the BSS profile
*
* @ param buf Pointer to bss command buffer for get
* @ return UAP_SUCCESS or UAP_FAILURE
*/
static int
get_bss_config ( t_u8 * buf )
{
apcmdbuf_bss_configure * cmd_buf = NULL ;
t_s32 sockfd ;
struct ifreq ifr ;
cmd_buf = ( apcmdbuf_bss_configure * ) buf ;
cmd_buf - > action = ACTION_GET ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
# if DEBUG
/* Dump request buffer */
hexdump ( " Get Request buffer " , ( void * ) buf ,
sizeof ( apcmdbuf_bss_configure )
+ sizeof ( bss_config_t ) , ' ' ) ;
# endif
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) cmd_buf ;
if ( ioctl ( sockfd , UAP_BSS_CONFIG , & ifr ) ) {
printf ( " ERR:UAP_BSS_CONFIG is not supported by %s \n " , dev_name ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
# if DEBUG
/* Dump request buffer */
hexdump ( " Get Response buffer " , ( void * ) buf ,
sizeof ( apcmdbuf_bss_configure )
+ sizeof ( bss_config_t ) , ' ' ) ;
# endif
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Creates a bss_config request and sends to the driver
*
* Usage : " Usage : bss_config [CONFIG_FILE] "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_bss_config ( int argc , char * argv [ ] )
{
apcmdbuf_bss_configure * cmd_buf = NULL ;
bss_config_t * bss = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len ;
t_u16 buf_len ;
int ret = UAP_SUCCESS ;
int opt ;
t_s32 sockfd ;
struct ifreq ifr ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_bss_config_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc > 1 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_bss_config_usage ( ) ;
return UAP_FAILURE ;
}
/* Query BSS settings */
/* Alloc buf for command */
buf_len = sizeof ( apcmdbuf_bss_configure ) + sizeof ( bss_config_t ) ;
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( ( char * ) buf , 0 , buf_len ) ;
/* Locate headers */
cmd_len = sizeof ( apcmdbuf_bss_configure ) ;
cmd_buf = ( apcmdbuf_bss_configure * ) buf ;
bss = ( bss_config_t * ) ( buf + cmd_len ) ;
/* Get all parametes first */
if ( get_bss_config ( buf ) = = UAP_FAILURE ) {
printf ( " ERR:Reading current parameters \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
if ( argc = = 1 ) {
/* Parse config file and populate structure */
ret = parse_bss_config ( argc , argv , bss ) ;
if ( ret = = UAP_FAILURE ) {
free ( buf ) ;
return ret ;
}
cmd_len + = sizeof ( bss_config_t ) ;
cmd_buf - > action = ACTION_SET ;
/* Send the command */
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) cmd_buf ;
# if DEBUG
/* Dump request buffer */
hexdump ( " Request buffer " , ( void * ) buf , buf_len , ' ' ) ;
# endif
if ( ioctl ( sockfd , UAP_BSS_CONFIG , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:UAP_BSS_CONFIG is not supported by %s \n " ,
dev_name ) ;
close ( sockfd ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
# if DEBUG
/* Dump respond buffer */
hexdump ( " Respond buffer " , ( void * ) buf , buf_len , ' ' ) ;
# endif
close ( sockfd ) ;
} else {
/* Print response */
printf ( " BSS settings: \n " ) ;
print_bss_config ( bss ) ;
}
free ( buf ) ;
return ret ;
}
/**
* @ brief Read the profile and sends to the driver
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
apcmd_coex_config_profile ( int argc , char * argv [ ] )
{
FILE * config_file = NULL ;
char * line = NULL ;
int i , index , li = 0 ;
int ret = UAP_SUCCESS ;
char * pos = NULL ;
int arg_num = 0 ;
char * args [ 30 ] ;
int is_coex_config = 0 ;
int is_coex_common_config = 0 ;
int is_coex_sco_config = 0 ;
int is_coex_acl_config = 0 ;
t_u8 * buf = NULL ;
apcmdbuf_coex_config * cmd_buf = NULL ;
tlvbuf_coex_common_cfg * coex_common_tlv ;
tlvbuf_coex_sco_cfg * coex_sco_tlv ;
tlvbuf_coex_acl_cfg * coex_acl_tlv ;
t_u16 acl_enabled = 0 ;
t_u32 conf_bitmap = 0 ;
t_u32 ap_coex_enable = 0 ;
t_u16 cmd_len = 0 , tlv_len = 0 ;
t_u16 sco_prot_qtime [ 4 ] = { 0 , 0 , 0 , 0 } , sco_prot_rate =
0 , sco_acl_freq = 0 ;
t_u16 acl_bt_time = 0 , acl_wlan_time = 0 , acl_prot_rate = 0 ;
/* Check if file exists */
config_file = fopen ( argv [ 0 ] , " r " ) ;
if ( config_file = = NULL ) {
printf ( " \n ERR:Config file can not open. \n " ) ;
return UAP_FAILURE ;
}
line = ( char * ) malloc ( MAX_CONFIG_LINE ) ;
if ( ! line ) {
printf ( " ERR:Cannot allocate memory for line \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
bzero ( line , MAX_CONFIG_LINE ) ;
/* fixed command length */
cmd_len = sizeof ( apcmdbuf_coex_config ) + sizeof ( tlvbuf_coex_common_cfg )
+ sizeof ( tlvbuf_coex_sco_cfg ) + sizeof ( tlvbuf_coex_acl_cfg ) ;
/* alloc buf for command */
buf = ( t_u8 * ) malloc ( cmd_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
bzero ( ( char * ) buf , cmd_len ) ;
cmd_buf = ( apcmdbuf_coex_config * ) buf ;
/* Fill the command buffer */
cmd_buf - > cmd_code = HostCmd_ROBUST_COEX ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
cmd_buf - > action = uap_cpu_to_le16 ( ACTION_SET ) ;
/* Parse file and process */
while ( config_get_line ( line , MAX_CONFIG_LINE , config_file , & li , & pos ) ) {
# if DEBUG
uap_printf ( MSG_DEBUG , " DBG:Received config line (%d) = %s \n " ,
li , line ) ;
# endif
arg_num = parse_line ( line , args ) ;
# if DEBUG
uap_printf ( MSG_DEBUG , " DBG:Number of arguments = %d \n " ,
arg_num ) ;
for ( i = 0 ; i < arg_num ; i + + ) {
uap_printf ( MSG_DEBUG , " \t DBG:Argument %d. %s \n " , i + 1 ,
args [ i ] ) ;
}
# endif
/* Check for end of Coex configurations */
if ( is_coex_acl_config = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 ) {
coex_acl_tlv =
( tlvbuf_coex_acl_cfg * ) ( cmd_buf - >
tlv_buffer +
tlv_len ) ;
coex_acl_tlv - > tag = MRVL_BT_COEX_ACL_CFG_TLV_ID ;
coex_acl_tlv - > length =
sizeof ( tlvbuf_coex_acl_cfg ) -
sizeof ( tlvbuf_header ) ;
endian_convert_tlv_header_out ( coex_acl_tlv ) ;
coex_acl_tlv - > enabled =
uap_cpu_to_le16 ( acl_enabled ) ;
coex_acl_tlv - > bt_time =
uap_cpu_to_le16 ( acl_bt_time ) ;
coex_acl_tlv - > wlan_time =
uap_cpu_to_le16 ( acl_wlan_time ) ;
coex_acl_tlv - > protection_rate =
uap_cpu_to_le16 ( acl_prot_rate ) ;
tlv_len + = sizeof ( tlvbuf_coex_acl_cfg ) ;
is_coex_acl_config = 0 ;
}
} else if ( is_coex_sco_config = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 ) {
coex_sco_tlv =
( tlvbuf_coex_sco_cfg * ) ( cmd_buf - >
tlv_buffer +
tlv_len ) ;
coex_sco_tlv - > tag = MRVL_BT_COEX_SCO_CFG_TLV_ID ;
coex_sco_tlv - > length =
sizeof ( tlvbuf_coex_sco_cfg ) -
sizeof ( tlvbuf_header ) ;
endian_convert_tlv_header_out ( coex_sco_tlv ) ;
for ( i = 0 ; i < 4 ; i + + )
coex_sco_tlv - > protection_qtime [ i ] =
uap_cpu_to_le16 ( sco_prot_qtime
[ i ] ) ;
coex_sco_tlv - > protection_rate =
uap_cpu_to_le16 ( sco_prot_rate ) ;
coex_sco_tlv - > acl_frequency =
uap_cpu_to_le16 ( sco_acl_freq ) ;
tlv_len + = sizeof ( tlvbuf_coex_sco_cfg ) ;
is_coex_sco_config = 0 ;
}
} else if ( is_coex_common_config = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 ) {
coex_common_tlv =
( tlvbuf_coex_common_cfg * ) ( cmd_buf - >
tlv_buffer +
tlv_len ) ;
coex_common_tlv - > tag =
MRVL_BT_COEX_COMMON_CFG_TLV_ID ;
coex_common_tlv - > length =
sizeof ( tlvbuf_coex_common_cfg ) -
sizeof ( tlvbuf_header ) ;
endian_convert_tlv_header_out ( coex_common_tlv ) ;
coex_common_tlv - > config_bitmap =
uap_cpu_to_le32 ( conf_bitmap ) ;
coex_common_tlv - > ap_bt_coex =
uap_cpu_to_le32 ( ap_coex_enable ) ;
tlv_len + = sizeof ( tlvbuf_coex_common_cfg ) ;
is_coex_common_config = 0 ;
}
} else if ( is_coex_config = = 1 ) {
if ( strcmp ( args [ 0 ] , " } " ) = = 0 )
is_coex_config = 0 ;
}
if ( strcmp ( args [ 0 ] , " coex_config " ) = = 0 ) {
is_coex_config = 1 ;
} else if ( strcmp ( args [ 0 ] , " common_config " ) = = 0 ) {
is_coex_common_config = 1 ;
} else if ( strcmp ( args [ 0 ] , " sco_config " ) = = 0 ) {
is_coex_sco_config = 1 ;
} else if ( strcmp ( args [ 0 ] , " acl_config " ) = = 0 ) {
is_coex_acl_config = 1 ;
}
if ( ( strcmp ( args [ 0 ] , " bitmap " ) = = 0 ) & & is_coex_common_config ) {
if ( is_input_valid
( COEX_COMM_BITMAP , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
conf_bitmap = ( t_u32 ) A2HEXDECIMAL ( args [ 1 ] ) ;
} else if ( ( strcmp ( args [ 0 ] , " APBTCoex " ) = = 0 ) & &
is_coex_common_config ) {
if ( is_input_valid
( COEX_COMM_AP_COEX , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
ap_coex_enable = ( t_u32 ) A2HEXDECIMAL ( args [ 1 ] ) ;
} else if ( ( strncmp ( args [ 0 ] , " protectionFromQTime " , 19 ) = = 0 ) & &
is_coex_sco_config ) {
index = atoi ( args [ 0 ] + strlen ( " protectionFromQTime " ) ) ;
if ( index < 0 | | index > 3 ) {
printf ( " ERR:Incorrect index %d. \n " , index ) ;
ret = UAP_FAILURE ;
goto done ;
}
if ( is_input_valid ( COEX_PROTECTION , arg_num , args ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
sco_prot_qtime [ index ] = ( t_u16 ) atoi ( args [ 1 ] ) ;
} else if ( ( strcmp ( args [ 0 ] , " scoProtectionFromRate " ) = = 0 ) & &
is_coex_sco_config ) {
if ( is_input_valid ( COEX_PROTECTION , arg_num , args ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
sco_prot_rate = ( t_u16 ) atoi ( args [ 1 ] ) ;
} else if ( ( strcmp ( args [ 0 ] , " aclFrequency " ) = = 0 ) & &
is_coex_sco_config ) {
if ( is_input_valid
( COEX_SCO_ACL_FREQ , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
sco_acl_freq = ( t_u16 ) atoi ( args [ 1 ] ) ;
} else if ( ( strcmp ( args [ 0 ] , " enabled " ) = = 0 ) & &
is_coex_acl_config ) {
if ( is_input_valid
( COEX_ACL_ENABLED , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
acl_enabled = ( t_u16 ) atoi ( args [ 1 ] ) ;
} else if ( ( strcmp ( args [ 0 ] , " btTime " ) = = 0 ) & &
is_coex_acl_config ) {
if ( is_input_valid
( COEX_ACL_BT_TIME , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
acl_bt_time = ( t_u16 ) atoi ( args [ 1 ] ) ;
} else if ( ( strcmp ( args [ 0 ] , " wlanTime " ) = = 0 ) & &
is_coex_acl_config ) {
if ( is_input_valid
( COEX_ACL_WLAN_TIME , arg_num - 1 ,
args + 1 ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
acl_wlan_time = ( t_u16 ) atoi ( args [ 1 ] ) ;
} else if ( ( strcmp ( args [ 0 ] , " aclProtectionFromRate " ) = = 0 ) & &
is_coex_acl_config ) {
if ( is_input_valid ( COEX_PROTECTION , arg_num , args ) ! =
UAP_SUCCESS ) {
ret = UAP_FAILURE ;
goto done ;
}
acl_prot_rate = ( t_u16 ) atoi ( args [ 1 ] ) ;
}
}
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , cmd_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( cmd_buf - > cmd_code ! =
( HostCmd_ROBUST_COEX | APCMD_RESP_CHECK ) ) {
printf ( " ERR:Corrupted response! \n " ) ;
ret = UAP_FAILURE ;
goto done ;
}
/* Print response */
if ( cmd_buf - > result = = CMD_SUCCESS ) {
printf ( " BT Coex settings sucessfully set. \n " ) ;
} else {
printf ( " ERR:Could not set coex configuration. \n " ) ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
done :
fclose ( config_file ) ;
if ( buf )
free ( buf ) ;
if ( line )
free ( line ) ;
return ret ;
}
/**
* @ brief Show usage information for the coex_config command
*
* $ return N / A
*/
void
print_coex_config_usage ( void )
{
printf ( " \n Usage : coex_config [CONFIG_FILE] \n " ) ;
printf ( " \n If CONFIG_FILE is provided, a 'set' is performed, else a 'get' is performed. \n " ) ;
return ;
}
/**
* @ brief Creates a coex_config request and sends to the driver
*
* Usage : " Usage : coex_config [CONFIG_FILE] "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
apcmd_coex_config ( int argc , char * argv [ ] )
{
apcmdbuf_coex_config * cmd_buf = NULL ;
tlvbuf_coex_common_cfg * coex_common_tlv ;
tlvbuf_coex_sco_cfg * coex_sco_tlv ;
tlvbuf_coex_acl_cfg * coex_acl_tlv ;
tlvbuf_coex_stats * coex_stats_tlv ;
t_u8 * buf = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_SUCCESS ;
int opt ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_coex_config_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc > 1 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_coex_config_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc = = 1 ) {
/* Read profile and send command to firmware */
ret = apcmd_coex_config_profile ( argc , argv ) ;
return ret ;
}
/* fixed command length */
cmd_len = sizeof ( apcmdbuf_coex_config ) + sizeof ( tlvbuf_coex_common_cfg )
+ sizeof ( tlvbuf_coex_sco_cfg ) + sizeof ( tlvbuf_coex_acl_cfg )
+ sizeof ( tlvbuf_coex_stats ) ;
/* alloc buf for command */
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
bzero ( ( char * ) buf , buf_len ) ;
cmd_buf = ( apcmdbuf_coex_config * ) buf ;
coex_common_tlv = ( tlvbuf_coex_common_cfg * ) cmd_buf - > tlv_buffer ;
coex_common_tlv - > tag = MRVL_BT_COEX_COMMON_CFG_TLV_ID ;
coex_common_tlv - > length =
sizeof ( tlvbuf_coex_common_cfg ) - sizeof ( tlvbuf_header ) ;
endian_convert_tlv_header_out ( coex_common_tlv ) ;
coex_sco_tlv = ( tlvbuf_coex_sco_cfg * ) ( cmd_buf - > tlv_buffer +
sizeof ( tlvbuf_coex_common_cfg ) ) ;
coex_sco_tlv - > tag = MRVL_BT_COEX_SCO_CFG_TLV_ID ;
coex_sco_tlv - > length =
sizeof ( tlvbuf_coex_sco_cfg ) - sizeof ( tlvbuf_header ) ;
endian_convert_tlv_header_out ( coex_sco_tlv ) ;
coex_acl_tlv = ( tlvbuf_coex_acl_cfg * ) ( cmd_buf - > tlv_buffer +
sizeof ( tlvbuf_coex_common_cfg ) +
sizeof ( tlvbuf_coex_sco_cfg ) ) ;
coex_acl_tlv - > tag = MRVL_BT_COEX_ACL_CFG_TLV_ID ;
coex_acl_tlv - > length =
sizeof ( tlvbuf_coex_acl_cfg ) - sizeof ( tlvbuf_header ) ;
endian_convert_tlv_header_out ( coex_acl_tlv ) ;
coex_stats_tlv = ( tlvbuf_coex_stats * ) ( cmd_buf - > tlv_buffer +
sizeof ( tlvbuf_coex_common_cfg ) +
sizeof ( tlvbuf_coex_sco_cfg )
+ sizeof ( tlvbuf_coex_acl_cfg ) ) ;
coex_stats_tlv - > tag = MRVL_BT_COEX_STATS_TLV_ID ;
coex_stats_tlv - > length =
sizeof ( tlvbuf_coex_stats ) - sizeof ( tlvbuf_header ) ;
endian_convert_tlv_header_out ( coex_stats_tlv ) ;
/* Fill the command buffer */
cmd_buf - > cmd_code = HostCmd_ROBUST_COEX ;
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
cmd_buf - > action = uap_cpu_to_le16 ( ACTION_GET ) ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( cmd_buf - > cmd_code ! =
( HostCmd_ROBUST_COEX | APCMD_RESP_CHECK ) ) {
printf ( " ERR:Corrupted response! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
/* Print response */
if ( cmd_buf - > result = = CMD_SUCCESS ) {
printf ( " BT Coex settings: \n " ) ;
print_tlv ( buf + sizeof ( apcmdbuf_coex_config ) ,
cmd_buf - > size - sizeof ( apcmdbuf_coex_config ) +
BUF_HEADER_SIZE ) ;
} else {
printf ( " ERR:Could not retrieve coex configuration. \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
free ( buf ) ;
return ret ;
}
/**
* @ brief Show usage information for the mic_err command
*
* $ return N / A
*/
void
print_mic_err_usage ( void )
{
printf ( " \n Usage : mic_err <STA_MAC_ADDRESS> \n " ) ;
return ;
}
/**
* @ brief report station mic error to the driver
*
* Usage : " mic_err <STA_MAC_ADDRESS> "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_mic_err ( int argc , char * argv [ ] )
{
int ret = UAP_SUCCESS ;
int opt ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u8 mac_addr [ ETH_ALEN ] ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_mic_err_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc ! = 1 ) {
printf ( " ERR:wrong arguments! Must provide STA_MAC_ADDRESS. \n " ) ;
print_mic_err_usage ( ) ;
return UAP_FAILURE ;
}
memset ( mac_addr , 0 , ETH_ALEN ) ;
if ( ( ret = mac2raw ( argv [ 0 ] , mac_addr ) ) ! = UAP_SUCCESS ) {
printf ( " ERR: %s Address \n " , ret = = UAP_FAILURE ? " Invalid MAC " :
ret = =
UAP_RET_MAC_BROADCAST ? " Broadcast " : " Multicast " ) ;
return UAP_FAILURE ;
}
# if DEBUG
/* Dump mac address */
hexdump ( " report mic error " , ( void * ) mac_addr , ETH_ALEN , ' ' ) ;
# endif
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) mac_addr ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_REPORT_MIC_ERR , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:UAP_REPORT_MIC_ERR is not supported by %s \n " ,
dev_name ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
printf ( " MIC error reporting successful! \n " ) ;
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the sta_deauth_ext command
*
* $ return N / A
*/
void
print_set_key_usage ( void )
{
printf ( " \n Usage : key_material <MAC_ADDRESS> <KEY> [KEY_ID] \n " ) ;
printf ( " \n MAC_ADDRESS: station mac address or ff:ff:ff:ff:ff:ff " ) ;
printf ( " \n KEY: hex string, valid length 32 or 64 \n " ) ;
return ;
}
/**
* @ brief Creates a set key request and sends to the driver
*
* Usage : " set_key <MAC_ADDRESS><KEY>[KEY_ID] "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_set_key ( int argc , char * argv [ ] )
{
int ret = UAP_SUCCESS ;
int opt ;
struct ifreq ifr ;
t_s32 sockfd ;
encrypt_key key ;
int key_id = 0 ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_set_key_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc < 2 | | argc > 3 ) {
print_set_key_usage ( ) ;
return UAP_FAILURE ;
}
memset ( & key , 0 , sizeof ( encrypt_key ) ) ;
ret = mac2raw ( argv [ 0 ] , key . mac_addr ) ;
if ( ( ret ! = UAP_SUCCESS ) & & ( ret ! = UAP_RET_MAC_BROADCAST ) ) {
printf ( " ERR: %s Address \n " ,
ret = = UAP_FAILURE ? " Invalid MAC " : " Multicast " ) ;
return UAP_FAILURE ;
}
if ( ( strlen ( argv [ 1 ] ) ! = 32 ) & & ( strlen ( argv [ 1 ] ) ! = 64 ) ) {
printf ( " ERR: key must be hex string with length 32 or 64 " ) ;
print_set_key_usage ( ) ;
return UAP_FAILURE ;
}
if ( UAP_FAILURE = = ishexstring ( argv [ 1 ] ) ) {
printf ( " ERR:Only hex digits are allowed \n " ) ;
print_set_key_usage ( ) ;
return UAP_FAILURE ;
}
if ( argc = = 3 ) {
if ( ( ISDIGIT ( argv [ 2 ] ) = = 0 ) | | ( atoi ( argv [ 2 ] ) < 0 ) | |
( atoi ( argv [ 2 ] ) > 3 ) ) {
printf ( " ERR:Illegal key id %s. Must be either '0', '1', '2', or '3'. \n " , argv [ 2 ] ) ;
print_set_key_usage ( ) ;
return UAP_FAILURE ;
}
key_id = atoi ( argv [ 2 ] ) ;
}
key . key_len = strlen ( argv [ 1 ] ) / 2 ;
string2raw ( argv [ 1 ] , key . key_material ) ;
key . key_index = key_id ;
# if DEBUG
/* dump key buffer */
hexdump ( " set key " , ( void * ) & key , sizeof ( encrypt_key ) , ' ' ) ;
# endif
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & key ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_SET_KEY , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:UAP_SET_KEY is not supported by %s \n " , dev_name ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
printf ( " Key setting successful. \n " ) ;
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the sys_cfg_custom_ie
* command
*
* $ return N / A
*/
void
print_sys_cfg_custom_ie_usage ( void )
{
printf ( " \n Usage : sys_cfg_custom_ie [INDEX] [MASK] [IEBuffer] " ) ;
printf ( " \n empty - Get all IE settings \n " ) ;
printf ( " \n INDEX: 0 - Get/Set IE index 0 setting " ) ;
printf ( " \n 1 - Get/Set IE index 1 setting " ) ;
printf ( " \n 2 - Get/Set IE index 2 setting " ) ;
printf ( " \n 3 - Get/Set IE index 3 setting " ) ;
printf ( " \n . " ) ;
printf ( " \n . " ) ;
printf ( " \n . " ) ;
printf ( " \n -1 - Append/Delete IE automatically " ) ;
printf ( " \n Delete will delete the IE from the matching IE buffer " ) ;
printf ( " \n Append will append the IE to the buffer with the same mask " ) ;
printf ( " \n MASK : Management subtype mask value as per bit defintions " ) ;
printf ( " \n : Bit 0 - Association request. " ) ;
printf ( " \n : Bit 1 - Association response. " ) ;
printf ( " \n : Bit 2 - Reassociation request. " ) ;
printf ( " \n : Bit 3 - Reassociation response. " ) ;
printf ( " \n : Bit 4 - Probe request. " ) ;
printf ( " \n : Bit 5 - Probe response. " ) ;
printf ( " \n : Bit 8 - Beacon. " ) ;
printf ( " \n MASK : MASK = 0 to clear the mask and the IE buffer " ) ;
printf ( " \n IEBuffer : IE Buffer in hex (max 256 bytes) \n \n " ) ;
return ;
}
/** custom IE, auto mask value */
# define UAP_CUSTOM_IE_AUTO_MASK 0xffff
/**
* @ brief Get max management IE index
* @ param max_mgmt_ie
* @ param print flag
* @ return UAP_SUCCESS / UAP_FAILURE
*/
static int
get_max_mgmt_ie ( int * max_mgmt_ie , int flag )
{
apcmdbuf_sys_configure * cmd_buf = NULL ;
tlvbuf_max_mgmt_ie * tlv = NULL ;
t_u8 * buffer = NULL ;
t_u16 cmd_len = 0 , i = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_SUCCESS ;
* max_mgmt_ie = 0 ;
/* Initialize the command length */
cmd_len = sizeof ( apcmdbuf_sys_configure ) + sizeof ( tlvbuf_max_mgmt_ie ) ;
/* Initialize the command buffer */
buffer = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buffer , 0 , buf_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_max_mgmt_ie * ) ( buffer + sizeof ( apcmdbuf_sys_configure ) ) ;
/* Fill the command buffer */
cmd_buf - > cmd_code = APCMD_SYS_CONFIGURE ;
cmd_buf - > size = cmd_len ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
tlv - > tag = MRVL_MAX_MGMT_IE_TLV_ID ;
tlv - > length = 0 ;
cmd_buf - > action = ACTION_GET ;
endian_convert_tlv_header_out ( tlv ) ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
endian_convert_tlv_header_in ( tlv ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( ( cmd_buf - > cmd_code ! =
( APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK ) ) | |
( tlv - > tag ! = MRVL_MAX_MGMT_IE_TLV_ID ) ) {
printf ( " ERR:Corrupted response! cmd_code=%x, Tlv->tag=%x \n " , cmd_buf - > cmd_code , tlv - > tag ) ;
free ( buffer ) ;
return UAP_FAILURE ;
}
/* Print response */
if ( cmd_buf - > result = = CMD_SUCCESS ) {
tlv - > count = uap_le16_to_cpu ( tlv - > count ) ;
for ( i = 0 ; i < tlv - > count ; i + + ) {
tlv - > info [ i ] . buf_size =
uap_le16_to_cpu ( tlv - > info [ i ] . buf_size ) ;
tlv - > info [ i ] . buf_count =
uap_le16_to_cpu ( tlv - > info [ i ] . buf_count ) ;
* max_mgmt_ie + = tlv - > info [ i ] . buf_count ;
if ( flag ) {
printf ( " buf%d_size = %d \n " , i ,
tlv - > info [ i ] . buf_size ) ;
printf ( " number of buffers = %d \n " ,
tlv - > info [ i ] . buf_count ) ;
printf ( " \n " ) ;
}
}
} else {
printf ( " ERR:Could not get max_mgmt_ie_index! \n " ) ;
ret = UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
}
if ( buffer )
free ( buffer ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Creates a sys_cfg request for custom IE settings
* and sends to the driver
*
* Usage : " sys_cfg_custom_ie [INDEX] [MASK] [IEBuffer] "
*
* Options : INDEX : 0 - Get / Set IE index 0 setting
* 1 - Get / Set IE index 1 setting
* 2 - Get / Set IE index 2 setting
* 3 - Get / Set IE index 3 setting
* .
* .
* .
* MASK : Management subtype mask value
* IEBuffer : IE Buffer in hex
* empty - Get all IE settings
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_sys_cfg_custom_ie ( int argc , char * argv [ ] )
{
tlvbuf_custom_ie * tlv = NULL ;
tlvbuf_max_mgmt_ie * max_mgmt_ie_tlv = NULL ;
custom_ie * ie_ptr = NULL ;
t_u8 * buffer = NULL ;
t_u16 buf_len = 0 ;
t_u16 mgmt_subtype_mask = 0 ;
int ie_buf_len = 0 , ie_len = 0 , i = 0 , max_mgmt_ie = 0 , print_flag = 0 ;
struct ifreq ifr ;
t_s32 sockfd ;
if ( argc = = 1 & & max_mgmt_ie_print = = 0 ) {
/* Print buffer sizes only if (argc == 1) i.e. get all indices one by one
* & & ( max_mgmt_ie_print = = 0 ) i . e . max mgmt IE is not printed via sys_config cmd */
print_flag = 1 ;
}
/* Reset the max_mgmt_ie_print for successive cmds */
max_mgmt_ie_print = 0 ;
if ( ! get_max_mgmt_ie ( & max_mgmt_ie , print_flag ) ) {
printf ( " ERR:couldn't get max_mgmt_ie! \n " ) ;
return UAP_FAILURE ;
}
if ( max_mgmt_ie = = 0 ) {
max_mgmt_ie = MAX_MGMT_IE_INDEX ;
# if DEBUG
uap_printf ( MSG_DEBUG ,
" WARN: max_mgmt_ie=0, defaulting to MAX_MGMT_IE_INDEX \n " ) ;
# endif
}
/* Check arguments */
if ( argc > 4 ) {
printf ( " ERR:Too many arguments. \n " ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
/* Error checks and initialize the command length */
if ( argc > = 2 ) {
if ( ( ( IS_HEX_OR_DIGIT ( argv [ 1 ] ) = = UAP_FAILURE ) & &
( atoi ( argv [ 1 ] ) ! = - 1 ) ) | | ( atoi ( argv [ 1 ] ) < - 1 ) ) {
printf ( " ERR:Illegal index %s \n " , argv [ 1 ] ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
}
switch ( argc ) {
case 1 :
buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
break ;
case 2 :
if ( ( atoi ( argv [ 1 ] ) < 0 ) | | ( atoi ( argv [ 1 ] ) > = max_mgmt_ie ) ) {
printf ( " ERR:Illegal index %s. Must be either greater than or equal to 0 and less than %d for Get Operation \n " , argv [ 1 ] , max_mgmt_ie ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
break ;
case 3 :
if ( UAP_FAILURE = = ishexstring ( argv [ 2 ] ) | |
A2HEXDECIMAL ( argv [ 2 ] ) ! = 0 ) {
printf ( " ERR: Mask value should be 0 to clear IEBuffers. \n " ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
if ( atoi ( argv [ 1 ] ) = = - 1 ) {
printf ( " ERR: Buffer should be provided for automatic deletion. \n " ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
buf_len = sizeof ( tlvbuf_custom_ie ) + sizeof ( custom_ie ) ;
break ;
case 4 :
/* This is to check negative numbers and special symbols */
if ( UAP_FAILURE = = IS_HEX_OR_DIGIT ( argv [ 2 ] ) ) {
printf ( " ERR:Mask value must be 0 or hex digits \n " ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
/* If above check is passed and mask is not hex, then it must be 0 */
if ( ( ISDIGIT ( argv [ 2 ] ) = = UAP_SUCCESS ) & & atoi ( argv [ 2 ] ) ) {
printf ( " ERR:Mask value must be 0 or hex digits \n " ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
if ( UAP_FAILURE = = ishexstring ( argv [ 3 ] ) ) {
printf ( " ERR:Only hex digits are allowed \n " ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
ie_buf_len = strlen ( argv [ 3 ] ) ;
if ( ! strncasecmp ( " 0x " , argv [ 3 ] , 2 ) ) {
ie_len = ( ie_buf_len - 2 + 1 ) / 2 ;
argv [ 3 ] + = 2 ;
} else
ie_len = ( ie_buf_len + 1 ) / 2 ;
if ( ie_len > MAX_IE_BUFFER_LEN ) {
printf ( " ERR:Incorrect IE length %d \n " , ie_buf_len ) ;
print_sys_cfg_custom_ie_usage ( ) ;
return UAP_FAILURE ;
}
mgmt_subtype_mask = ( t_u16 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
buf_len = sizeof ( tlvbuf_custom_ie ) + sizeof ( custom_ie ) + ie_len ;
break ;
}
/* Initialize the command buffer */
buffer = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buffer , 0 , buf_len ) ;
tlv = ( tlvbuf_custom_ie * ) buffer ;
tlv - > tag = MRVL_MGMT_IE_LIST_TLV_ID ;
if ( argc = = 1 | | argc = = 2 ) {
if ( argc = = 1 )
tlv - > length = 0 ;
else {
tlv - > length = sizeof ( t_u16 ) ;
ie_ptr = ( custom_ie * ) ( tlv - > ie_data ) ;
ie_ptr - > ie_index = ( t_u16 ) ( atoi ( argv [ 1 ] ) ) ;
}
} else {
/* Locate headers */
ie_ptr = ( custom_ie * ) ( tlv - > ie_data ) ;
/* Set TLV fields */
tlv - > length = sizeof ( custom_ie ) + ie_len ;
ie_ptr - > ie_index = atoi ( argv [ 1 ] ) ;
ie_ptr - > mgmt_subtype_mask = mgmt_subtype_mask ;
ie_ptr - > ie_length = ie_len ;
if ( argc = = 4 )
string2raw ( argv [ 3 ] , ie_ptr - > ie_buffer ) ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
if ( buffer )
free ( buffer ) ;
return UAP_FAILURE ;
}
if ( argc ! = 1 ) {
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) buffer ;
/* Perform ioctl */
if ( ioctl ( sockfd , UAP_CUSTOM_IE , & ifr ) ) {
if ( errno < 0 ) {
perror ( " ioctl[UAP_CUSTOM_IE] " ) ;
printf ( " ERR:Command sending failed! \n " ) ;
} else {
printf ( " custom IE configuration failed! \n " ) ;
}
close ( sockfd ) ;
if ( buffer )
free ( buffer ) ;
return UAP_FAILURE ;
}
/* Print response */
if ( argc > 2 ) {
printf ( " custom IE setting successful \n " ) ;
} else {
printf ( " Querying custom IE successful \n " ) ;
tlv = ( tlvbuf_custom_ie * ) buffer ;
ie_len = tlv - > length ;
ie_ptr = ( custom_ie * ) ( tlv - > ie_data ) ;
if ( tlv - > tag = = MRVL_MGMT_IE_LIST_TLV_ID ) {
while ( ( unsigned int ) ie_len > =
sizeof ( custom_ie ) ) {
printf ( " Index [%d] \n " ,
ie_ptr - > ie_index ) ;
if ( ie_ptr - > ie_length )
printf ( " Management Subtype Mask = 0x%02x \n " , ie_ptr - > mgmt_subtype_mask = = 0 ? UAP_CUSTOM_IE_AUTO_MASK : ie_ptr - > mgmt_subtype_mask ) ;
else
printf ( " Management Subtype Mask = 0x%02x \n " , ie_ptr - > mgmt_subtype_mask ) ;
hexdump_data ( " IE Buffer " ,
( void * ) ie_ptr - > ie_buffer ,
( ie_ptr - > ie_length ) , ' ' ) ;
ie_len - =
sizeof ( custom_ie ) +
ie_ptr - > ie_length ;
ie_ptr = ( custom_ie * ) ( ( t_u8 * ) ie_ptr +
sizeof ( custom_ie )
+
ie_ptr - >
ie_length ) ;
}
}
max_mgmt_ie_tlv =
( tlvbuf_max_mgmt_ie * ) ( buffer +
sizeof ( tlvbuf_custom_ie )
+ tlv - > length ) ;
if ( max_mgmt_ie_tlv ) {
if ( max_mgmt_ie_tlv - > tag = =
MRVL_MAX_MGMT_IE_TLV_ID ) {
for ( i = 0 ; i < max_mgmt_ie_tlv - > count ;
i + + ) {
printf ( " buf%d_size = %d \n " , i ,
max_mgmt_ie_tlv - > info [ i ] .
buf_size ) ;
printf ( " number of buffers = %d \n " , max_mgmt_ie_tlv - > info [ i ] . buf_count ) ;
printf ( " \n " ) ;
}
}
}
}
}
/* Special handling for all indices: Get all IEs one-by-one */
if ( argc = = 1 ) {
for ( i = 0 ; i < max_mgmt_ie ; i + + ) {
tlv - > length = sizeof ( t_u16 ) ;
ie_ptr = ( custom_ie * ) ( tlv - > ie_data ) ;
ie_ptr - > ie_index = ( t_u16 ) ( i ) ;
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) buffer ;
/* Perform ioctl */
if ( ioctl ( sockfd , UAP_CUSTOM_IE , & ifr ) ) {
if ( errno < 0 ) {
perror ( " ioctl[UAP_CUSTOM_IE] " ) ;
printf ( " ERR:Command sending failed! \n " ) ;
} else {
printf ( " custom IE configuration failed! \n " ) ;
}
close ( sockfd ) ;
if ( buffer )
free ( buffer ) ;
return UAP_FAILURE ;
}
/* Print response */
tlv = ( tlvbuf_custom_ie * ) buffer ;
ie_len = tlv - > length ;
ie_ptr = ( custom_ie * ) ( tlv - > ie_data ) ;
if ( tlv - > tag = = MRVL_MGMT_IE_LIST_TLV_ID ) {
while ( ( unsigned int ) ie_len > =
sizeof ( custom_ie ) ) {
printf ( " Index [%d] \n " ,
ie_ptr - > ie_index ) ;
if ( ie_ptr - > ie_length )
printf ( " Management Subtype Mask = 0x%02x \n " , ie_ptr - > mgmt_subtype_mask = = 0 ? UAP_CUSTOM_IE_AUTO_MASK : ie_ptr - > mgmt_subtype_mask ) ;
else
printf ( " Management Subtype Mask = 0x%02x \n " , ie_ptr - > mgmt_subtype_mask ) ;
hexdump_data ( " IE Buffer " ,
( void * ) ie_ptr - > ie_buffer ,
( ie_ptr - > ie_length ) , ' ' ) ;
ie_len - =
sizeof ( custom_ie ) +
ie_ptr - > ie_length ;
ie_ptr = ( custom_ie * ) ( ( t_u8 * ) ie_ptr +
sizeof ( custom_ie )
+
ie_ptr - >
ie_length ) ;
}
}
}
printf ( " Querying custom IE successful \n " ) ;
}
if ( buffer )
free ( buffer ) ;
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the dfstesting command
*
* $ return N / A
*/
void
print_dfstesting_usage ( void )
{
printf ( " \n Usage : dfstesting [USER_CAC_PD USER_NOP_PD NO_CHAN_CHANGE FIXED_CHAN_NUM] \n " ) ;
printf ( " \n empty - Get all dfstesting settings \n " ) ;
printf ( " \n USER_CAC_PD: user configured Channel Availability Check period " ) ;
printf ( " \n 0 - disable, use default (60000) " ) ;
printf ( " \n 1-65535 - CAC period in msec " ) ;
printf ( " \n USER_NOP_PD: user configured Non-Occupancy Period " ) ;
printf ( " \n 0 - disable, use default (1800) " ) ;
printf ( " \n 1-65535 - NOP period in sec " ) ;
printf ( " \n NO_CHAN_CHANGE: user setting, don't change channel on radar " ) ;
printf ( " \n 0 - disable, default behavior " ) ;
printf ( " \n non-zero - enable, overrides below setting " ) ;
printf ( " \n FIXED_CHAN_NUM: user fixed channel to change to on radar " ) ;
printf ( " \n 0 - disable, use random channel [default] " ) ;
printf ( " \n 1-255 - set fixed channel (not checked for validity) \n " ) ;
return ;
}
/**
* @ brief user configuration of dfs testing settings
*
* Usage : " dfstesting [USER_CAC_PD USER_NOP_PD NO_CHAN_CHANGE FIXED_CHAN_NUM] "
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_dfstesting ( int argc , char * argv [ ] )
{
int opt ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u32 val ;
dfs_testing_para dfs_test ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_dfstesting_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
memset ( & dfs_test , 0x00 , sizeof ( dfs_test ) ) ;
/* Check arguments */
if ( argc = = 0 ) {
dfs_test . action = ACTION_GET ;
} else if ( argc = = 4 ) {
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) | |
( IS_HEX_OR_DIGIT ( argv [ 1 ] ) = = UAP_FAILURE ) | |
( IS_HEX_OR_DIGIT ( argv [ 2 ] ) = = UAP_FAILURE ) | |
( IS_HEX_OR_DIGIT ( argv [ 3 ] ) = = UAP_FAILURE ) ) {
printf ( " ERR: Only Number values are allowed \n " ) ;
print_dfstesting_usage ( ) ;
return UAP_FAILURE ;
}
val = A2HEXDECIMAL ( argv [ 0 ] ) ;
if ( val > 0xfffff ) {
printf ( " ERR: invalid user_cac_pd value! \n " ) ;
return UAP_FAILURE ;
}
dfs_test . usr_cac_period = ( t_u32 ) val ;
val = A2HEXDECIMAL ( argv [ 1 ] ) ;
if ( val > 0xffff ) {
printf ( " ERR: invalid user_nop_pd value! \n " ) ;
return UAP_FAILURE ;
}
dfs_test . usr_nop_period = ( t_u16 ) val ;
val = A2HEXDECIMAL ( argv [ 2 ] ) ;
dfs_test . no_chan_change = ( t_u8 ) ( val ? 1 : 0 ) ;
val = A2HEXDECIMAL ( argv [ 3 ] ) ;
if ( val > 0xff ) {
printf ( " ERR: invalid fixed_chan_num value! \n " ) ;
return UAP_FAILURE ;
}
dfs_test . fixed_new_chan = ( t_u8 ) val ;
dfs_test . action = ACTION_SET ;
} else {
printf ( " ERR: invalid number of arguments! Must be 0 or 4. \n " ) ;
print_dfstesting_usage ( ) ;
return UAP_FAILURE ;
}
dfs_test . subcmd = UAP_DFS_TESTING ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & dfs_test ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: UAP_DFS_TESTING is not supported by %s \n " ,
dev_name ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( argc )
printf ( " DFS testing setting successful! \n " ) ;
else
printf ( " DFS testing settings: \n "
" user_cac_period = %d msec \n "
" user_nop_period = %d sec \n "
" no_channel_change = %d \n "
" fixed_channel_num = %d \n " ,
dfs_test . usr_cac_period , dfs_test . usr_nop_period ,
dfs_test . no_chan_change , dfs_test . fixed_new_chan ) ;
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the cscount_cfg
* command
*
* $ return N / A
*/
void
print_cscount_cfg_usage ( void )
{
printf ( " \n Usage : cscount [<n>] " ) ;
printf ( " \n Where <n> " ) ;
printf ( " \n 5-20: No of beacons with Channel Switch Count IE \n " ) ;
return ;
}
/**
* @ brief Set / get cs_count configuration
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_cscount_cfg ( int argc , char * argv [ ] )
{
int opt ;
cscount_cfg_t cscount_cfg ;
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_cscount_cfg_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
memset ( & cscount_cfg , 0 , sizeof ( cscount_cfg ) ) ;
if ( argc = = 0 ) {
cscount_cfg . action = ACTION_GET ;
} else if ( argc = = 1 ) {
if ( ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) < 5
& & ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) > 20 ) {
printf ( " ERR:Invalid Channel switch count value \n " ) ;
return UAP_FAILURE ;
}
cscount_cfg . action = ACTION_SET ;
cscount_cfg . cs_count = ( t_u32 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
} else {
print_cscount_cfg_usage ( ) ;
return UAP_FAILURE ;
}
cscount_cfg . subcmd = UAP_CHAN_SWITCH_COUNT_CFG ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & cscount_cfg ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: Channel switch count configuration failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
/* Handle response */
if ( cscount_cfg . action = = ACTION_GET ) {
printf ( " Channel Switch count = %d \n " , cscount_cfg . cs_count ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the mgmtframectrl command
*
* $ return N / A
*/
void
print_mgmtframectrl_usage ( void )
{
printf ( " \n Usage : mgmtframectrl [MASK] \n " ) ;
printf ( " empty - Get management frame control mask \n " ) ;
printf ( " MASK - Set management frame control mask \n " ) ;
}
/**
* @ brief Creates management frame control request and send to driver
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
apcmd_mgmt_frame_control ( int argc , char * argv [ ] )
{
int opt ;
mgmt_frame_ctrl param ; /* Action =0, Mask =0 */
struct ifreq ifr ;
t_s32 sockfd ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_mgmtframectrl_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( argc > 1 ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_mgmtframectrl_usage ( ) ;
return UAP_FAILURE ;
}
if ( ( argc ) & & ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) ) {
printf ( " ERR: Invalid argument %s \n " , argv [ 0 ] ) ;
print_mgmtframectrl_usage ( ) ;
return UAP_FAILURE ;
}
memset ( & param , 0 , sizeof ( mgmt_frame_ctrl ) ) ;
param . subcmd = UAP_MGMT_FRAME_CONTROL ;
if ( argc ) {
param . action = ACTION_SET ;
param . mask = ( t_u16 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
} else {
param . action = ACTION_GET ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , strlen ( dev_name ) ) ;
ifr . ifr_ifru . ifru_data = ( void * ) & param ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:UAP_IOCTL_CMD failed \n " ) ;
close ( sockfd ) ;
return UAP_FAILURE ;
}
if ( ! argc ) {
printf ( " Management Frame control mask = 0x%02x \n " ,
( int ) param . mask ) ;
}
/* Close socket */
close ( sockfd ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for the sys_cfg_pmf command
* command
*
* $ return N / A
*/
void
print_sys_cfg_pmf ( void )
{
printf ( " \n Usage : uaputl.exe sys_cfg_pmf [MFPC] [MFPR] \n " ) ;
printf ( " \n Set/Get PMF capabilities " ) ;
printf ( " \n empty - Get PMF capabilites \n " ) ;
printf ( " \n MFPC: Management frames protection capable " ) ;
printf ( " \n 0 - Not capable " ) ;
printf ( " \n 1 - capable " ) ;
printf ( " \n MFPR: Management frames protection required " ) ;
printf ( " \n don't care if MFPC is set to 0 " ) ;
printf ( " \n 0 - Not required " ) ;
printf ( " \n 1 - required \n " ) ;
return ;
}
int
apcmd_sys_cfg_pmf ( int argc , char * argv [ ] )
{
int opt ;
apcmdbuf_pmf_params * cmd_buf = NULL ;
t_u8 * buf = NULL ;
t_u16 cmd_len = 0 ;
t_u16 buf_len = MRVDRV_SIZE_OF_CMD_BUFFER ;
int ret = UAP_SUCCESS ;
t_u8 mfpc = 0 ;
t_u8 mfpr = 0 ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_sys_cfg_pmf ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
/* Check arguments */
if ( ( argc > 2 ) ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_sys_cfg_pmf ( ) ;
return UAP_FAILURE ;
}
if ( argc > 0 )
mfpc = atoi ( argv [ 0 ] ) ;
if ( mfpc & & ( argc = = 1 ) ) {
printf ( " ERR:wrong arguments. \n " ) ;
print_sys_cfg_pmf ( ) ;
return UAP_FAILURE ;
}
if ( mfpc & & ( argc = = 2 ) )
mfpr = atoi ( argv [ 1 ] ) ;
/* Alloc buf for command */
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer from command! \n " ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_len ) ;
/* Locate headers */
cmd_len = sizeof ( apcmdbuf_pmf_params ) ;
cmd_buf = ( apcmdbuf_pmf_params * ) buf ;
/* Fill the command buffer */
cmd_buf - > size = cmd_len - BUF_HEADER_SIZE ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
cmd_buf - > cmd_code = HostCmd_CMD_PMF_PARAMS ;
if ( argc = = 0 )
cmd_buf - > action = ACTION_GET ;
else
cmd_buf - > action = ACTION_SET ;
cmd_buf - > action = uap_cpu_to_le16 ( cmd_buf - > action ) ;
cmd_buf - > params . mfpc = mfpc ;
cmd_buf - > params . mfpr = mfpr ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , buf_len ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
if ( cmd_buf - > result = = CMD_SUCCESS ) {
printf ( " Successfully executed the command \n " ) ;
printf ( " mfpc: %d, mfpr: %d \n " ,
cmd_buf - > params . mfpc , cmd_buf - > params . mfpr ) ;
} else {
printf ( " ERR:Command sending failed! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
} else {
printf ( " ERR:Command sending failed! \n " ) ;
free ( buf ) ;
return UAP_FAILURE ;
}
free ( buf ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Show usage information for uap operation control command
*
* $ return N / A
*/
void
print_uap_oper_ctrl_usage ( void )
{
printf ( " \n Usage : uap_oper_ctrl <control> <chanopt> <bandcfg> <channel> " ) ;
printf ( " \n set/get uap operation when in-STA disconnected from ext-AP if multi channel is disabled " ) ;
printf ( " \n control: 0: default, do nothing " ) ;
printf ( " \n 2: uap stops and restart automatically " ) ;
printf ( " \n chanopt : specify which channel should be used when uap restarts automatically " ) ;
printf ( " \n 1: uap restarts on default 2.4G/channel 6 " ) ;
printf ( " \n 2: uap restart on band/channel configured by driver previously " ) ;
printf ( " \n 3: uap restart on band/channel configured by parameter bandcfg/channel " ) ;
printf ( " \n bandcfg : This parameter specifies the bandwidth (BW) " ) ;
printf ( " \n 0: 20Mhz " ) ;
printf ( " \n 2: 40Mhz " ) ;
printf ( " \n 3: 80Mhz " ) ;
printf ( " \n channel : This parameter specifies the channel will be used when chanopt is 3. " ) ;
return ;
}
/**
* @ brief Set / Get uap operation when in - STA disconnected from ext - AP
* @ param argc Number of arguments
* @ param argv A pointer to arguments array
* @ return MLAN_STATUS_SUCCESS - - success , otherwise - - fail
*/
int
apcmd_uap_oper_ctrl ( int argc , char * argv [ ] )
{
int opt ;
uap_operation_ctrl param ;
struct eth_priv_uap_oper_ctrl * uap_oper = NULL ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u8 * respbuf = NULL ;
memset ( & param , 0 , sizeof ( param ) ) ;
while ( ( opt = getopt_long ( argc , argv , " + " , cmd_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
default :
print_uap_oper_ctrl_usage ( ) ;
return UAP_SUCCESS ;
}
}
argc - = optind ;
argv + = optind ;
respbuf = ( t_u8 * ) malloc ( MRVDRV_SIZE_OF_CMD_BUFFER ) ;
if ( ! respbuf ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return UAP_FAILURE ;
}
memset ( respbuf , 0 , MRVDRV_SIZE_OF_CMD_BUFFER ) ;
/* Check arguments */
if ( argc > 4 ) {
printf ( " ERR: Invalid number of arguments. \n " ) ;
print_uap_oper_ctrl_usage ( ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
if ( argc > 0 ) {
param . uap_oper . ctrl = ( t_u16 ) A2HEXDECIMAL ( argv [ 0 ] ) ;
if ( param . uap_oper . ctrl = = 2 )
param . uap_oper . chan_opt = ( t_u16 ) A2HEXDECIMAL ( argv [ 1 ] ) ;
if ( argc = = 4 & & param . uap_oper . chan_opt = = 3 ) {
param . uap_oper . bandcfg = ( t_u8 ) A2HEXDECIMAL ( argv [ 2 ] ) ;
param . uap_oper . channel = ( t_u8 ) A2HEXDECIMAL ( argv [ 3 ] ) ;
}
param . action = ACTION_SET ;
} else {
param . action = ACTION_GET ;
}
param . subcmd = UAP_OPERATION_CTRL ;
memcpy ( respbuf , & param , sizeof ( uap_operation_ctrl ) ) ;
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) respbuf ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR: uap operation control set/get failed \n " ) ;
close ( sockfd ) ;
free ( respbuf ) ;
return UAP_FAILURE ;
}
/* Handle response */
if ( param . action = = ACTION_GET ) {
/* Process result */
uap_oper =
( struct eth_priv_uap_oper_ctrl * ) ( respbuf +
2 * sizeof ( t_u32 ) ) ;
printf ( " uap operation control %x \n " , uap_oper - > ctrl ) ;
printf ( " uap channel operation %x \n " , uap_oper - > chan_opt ) ;
if ( uap_oper - > chan_opt = = 3 ) {
printf ( " uap bandwidth %s \n " ,
uap_oper - >
bandcfg ? ( ( uap_oper - > bandcfg = = 2 ) ? " 40Mhz " :
" 80Mhz " ) : " 20Mhz " ) ;
printf ( " uap channel %d \n " , uap_oper - > channel ) ;
}
} else
printf ( " uap operation control set success! \n " ) ;
/* Close socket */
close ( sockfd ) ;
if ( respbuf )
free ( respbuf ) ;
return UAP_SUCCESS ;
}
/** Structure of command table*/
typedef struct {
/** Command name */
char * cmd ;
/** Command function pointer */
int ( * func ) ( int argc , char * argv [ ] ) ;
/** Command usuage */
char * help ;
} command_table ;
/** AP command table */
static command_table ap_command [ ] = {
{ " sys_config " , apcmd_sys_config , " \t Set/get uAP's profile " } ,
{ " sys_info " , apcmd_sys_info , " \t Display system info " } ,
{ " sys_reset " , apcmd_sys_reset , " \t Reset uAP " } ,
{ " bss_start " , apcmd_bss_start , " \t Start the BSS " } ,
{ " bss_stop " , apcmd_bss_stop , " \t Stop the BSS " } ,
{ " skip_cac " , apcmd_skip_cac , " \t Skip the CAC " } ,
{ " sta_deauth " , apcmd_sta_deauth , " \t Deauth client " } ,
{ " sta_list " , apcmd_sta_list , " \t Display list of clients " } ,
{ " sys_cfg_ap_mac_address " , apcmd_sys_cfg_ap_mac_address ,
" Set/get uAP mac address " } ,
{ " sys_cfg_ssid " , apcmd_sys_cfg_ssid , " \t Set/get uAP ssid " } ,
{ " sys_cfg_beacon_period " , apcmd_sys_cfg_beacon_period ,
" Set/get uAP beacon period " } ,
{ " sys_cfg_dtim_period " , apcmd_sys_cfg_dtim_period ,
" Set/get uAP dtim period " } ,
{ " sys_cfg_bss_status " , apcmd_sys_cfg_bss_status , " Get BSS status " } ,
{ " sys_cfg_channel " , apcmd_sys_cfg_channel ,
" \t Set/get uAP radio channel " } ,
{ " sys_cfg_channel_ext " , apcmd_sys_cfg_channel_ext ,
" \t Set/get uAP radio channel, band and mode " } ,
{ " sys_cfg_scan_channels " , apcmd_sys_cfg_scan_channels ,
" Set/get uAP radio channel list " } ,
{ " sys_cfg_rates " , apcmd_sys_cfg_rates , " \t Set/get uAP rates " } ,
{ " sys_cfg_rates_ext " , apcmd_sys_cfg_rates_ext , " \t Set/get uAP rates " } ,
{ " sys_cfg_tx_power " , apcmd_sys_cfg_tx_power , " Set/get uAP tx power " } ,
{ " sys_cfg_bcast_ssid_ctl " , apcmd_sys_cfg_bcast_ssid_ctl ,
" Set/get uAP broadcast ssid " } ,
{ " sys_cfg_preamble_ctl " , apcmd_sys_cfg_preamble_ctl ,
" Get uAP preamble " } ,
{ " antcfg " , apcmd_antcfg , " Set/get uAP tx/rx antenna " } ,
{ " htstreamcfg " , apcmd_htstreamcfg ,
" Set/get uAP HT stream configurations " } ,
{ " sys_cfg_rts_threshold " , apcmd_sys_cfg_rts_threshold ,
" Set/get uAP rts threshold " } ,
{ " sys_cfg_frag_threshold " , apcmd_sys_cfg_frag_threshold ,
" Set/get uAP frag threshold " } ,
{ " radioctrl " , apcmd_radio_ctl , " Set/get uAP radio on/off " } ,
{ " sys_cfg_tx_beacon_rate " , apcmd_sys_cfg_tx_beacon_rate ,
" Set/get uAP tx beacon rate " } ,
{ " txratecfg " , apcmd_tx_rate_cfg , " Set/get trasnmit data rate " } ,
{ " sys_cfg_mcbc_data_rate " , apcmd_sys_cfg_mcbc_data_rate ,
" Set/get uAP MCBC rate " } ,
{ " sys_cfg_rsn_replay_prot " , apcmd_sys_cfg_rsn_replay_prot ,
" Set/get RSN replay protection " } ,
{ " sys_cfg_pkt_fwd_ctl " , apcmd_sys_cfg_pkt_fwd_ctl ,
" Set/get uAP packet forwarding " } ,
{ " sys_cfg_sta_ageout_timer " , apcmd_sys_cfg_sta_ageout_timer ,
" Set/get station ageout timer " } ,
{ " sys_cfg_ps_sta_ageout_timer " , apcmd_sys_cfg_ps_sta_ageout_timer ,
" Set/get PS station ageout timer " } ,
{ " sys_cfg_auth " , apcmd_sys_cfg_auth ,
" \t Set/get uAP authentication mode " } ,
{ " sys_cfg_protocol " , apcmd_sys_cfg_protocol ,
" Set/get uAP security protocol " } ,
{ " sys_cfg_wep_key " , apcmd_sys_cfg_wep_key , " \t Set/get uAP wep key " } ,
{ " sys_cfg_cipher " , apcmd_sys_cfg_cipher ,
" \t Set/get uAP WPA/WPA2 cipher " } ,
{ " sys_cfg_pwk_cipher " , apcmd_sys_cfg_pwk_cipher ,
" \t Set/get uAP WPA/WPA2 pairwise cipher " } ,
{ " sys_cfg_gwk_cipher " , apcmd_sys_cfg_gwk_cipher ,
" \t Set/get uAP WPA/WPA2 group cipher " } ,
{ " sys_cfg_wpa_passphrase " , apcmd_sys_cfg_wpa_passphrase ,
" Set/get uAP WPA or WPA2 passphrase " } ,
{ " sys_cfg_wpa3_sae_password " , apcmd_sys_cfg_wpa3_sae_password ,
" Set/get uAP WPA3 SAE password " } ,
{ " sys_cfg_group_rekey_timer " , apcmd_sys_cfg_group_rekey_timer ,
" Set/get uAP group re-key time " } ,
{ " sys_cfg_max_sta_num " , apcmd_sys_cfg_max_sta_num ,
" Set/get uAP max station number " } ,
{ " sys_cfg_retry_limit " , apcmd_sys_cfg_retry_limit ,
" Set/get uAP retry limit number " } ,
{ " sys_cfg_sticky_tim_config " , apcmd_sys_cfg_sticky_tim_config ,
" Set/get uAP sticky TIM configuration " } ,
{ " sys_cfg_sticky_tim_sta_mac_addr " ,
apcmd_sys_cfg_sticky_tim_sta_mac_addr ,
" Set/get uAP sticky TIM sta MAC address " } ,
{ " sys_cfg_eapol_pwk_hsk " , apcmd_sys_cfg_eapol_pwk_hsk ,
" Set/getuAP pairwise Handshake timeout value and retries " } ,
{ " sys_cfg_eapol_gwk_hsk " , apcmd_sys_cfg_eapol_gwk_hsk ,
" Set/getuAP groupwise Handshake timeout value and retries " } ,
{ " sys_cfg_custom_ie " , apcmd_sys_cfg_custom_ie ,
" \t Set/get custom IE configuration " } ,
{ " sta_filter_table " , apcmd_sta_filter_table , " Set/get uAP mac filter " } ,
{ " regrdwr " , apcmd_regrdwr , " \t \t Read/Write register command " } ,
{ " memaccess " , apcmd_memaccess ,
" \t Read/Write to a memory address command " } ,
{ " rdeeprom " , apcmd_read_eeprom , " \t Read EEPROM " } ,
{ " cfg_data " , apcmd_cfg_data ,
" \t Get/Set configuration file from/to firmware " } ,
{ " sys_cfg_80211d " , apcmd_cfg_80211d , " \t Set/Get 802.11D info " } ,
{ " uap_stats " , apcmd_uap_stats , " \t Get uAP stats " } ,
{ " pscfg " , apcmd_pscfg , " \t \t Set/get uAP power mode " } ,
{ " bss_config " , apcmd_bss_config , " \t Set/get BSS configuration " } ,
{ " sta_deauth_ext " , apcmd_sta_deauth_ext , " \t Deauth client " } ,
{ " mic_err " , apcmd_mic_err , " \t \t Report station mic error " } ,
{ " key_material " , apcmd_set_key , " \t Set key " } ,
{ " coex_config " , apcmd_coex_config ,
" \t Set/get uAP BT coex configuration " } ,
{ " hscfg " , apcmd_hscfg , " \t \t Set/get uAP host sleep parameters. " } ,
{ " hssetpara " , apcmd_hssetpara ,
" \t \t Set/get uAP host sleep parameters. " } ,
{ " addbapara " , apcmd_addbapara , " \t Set/get uAP ADDBA parameters. " } ,
{ " aggrpriotbl " , apcmd_aggrpriotbl ,
" \t Set/get uAP priority table for AMPDU/AMSDU. " } ,
{ " addbareject " , apcmd_addbareject , " \t Set/get uAP addbareject table. " } ,
{ " sys_cfg_11n " , apcmd_sys_cfg_11n , " \t Set/get uAP 802.11n parameters. " } ,
# ifdef RX_PACKET_COALESCE
{ " rxpktcoal_cfg " , apcmd_rx_pkt_coalesce ,
" \t Set/get RX Packet coalesing paramterts. " } ,
# endif
{ " httxbfcfg " , apcmd_sys_cfg_tx_bf , " \t Set/get uAP TX BF parameters. " } ,
{ " httxcfg " , apcmd_sys_cfg_ht_tx , " \t \t Set/get uAP HT Tx parameters. " } ,
{ " vhtcfg " , apcmd_sys_cfg_vht , " \t \t Set/get uAP VHT parameters. " } ,
{ " sys_cfg_wmm " , apcmd_sys_cfg_wmm ,
" \t Set/get uAP beacon wmm parameters. " } ,
{ " sys_cfg_ap_wmm " , apcmd_sys_cfg_ap_wmm ,
" \t Set/get uAP hardware wmm parameters. " } ,
{ " deepsleep " , apcmd_deepsleep , " \t Set/get deepsleep mode. " } ,
{ " hostcmd " , apcmd_hostcmd , " \t \t Set/get hostcmd " } ,
{ " tx_data_pause " , apcmd_txdatapause ,
" \t Set/get Tx data pause settings. " } ,
# ifdef SDIO
{ " sdcmd52rw " , apcmd_cmd52_readwrite ,
" \t Read or write using sdio command 52. " } ,
# endif
{ " sys_cfg_2040_coex " , apcmd_sys_cfg_2040_coex ,
" \t Set/get 20/40 coex settings. " } ,
{ " dfstesting " , apcmd_dfstesting , " \t Configure DFS Testing settings. " } ,
{ " cscount " , apcmd_cscount_cfg , " \t Configure DFS Channel Switch Count. " } ,
{ " mgmtframectrl " , apcmd_mgmt_frame_control ,
" \t Specifies mask indicating management frames to be sent from host. " } ,
{ " sys_cfg_restrict_client_mode " , apcmd_sys_cfg_restrict_client_mode ,
" \t Set/get the mode in which client stations can connect to the uAP. " } ,
{ " sys_cfg_pmf " , apcmd_sys_cfg_pmf , " \t Set/get PMF capabilities. " } ,
{ " uap_oper_ctrl " , apcmd_uap_oper_ctrl ,
" \t Set/get uap operation control value. " } ,
{ " band_steering_cfg " , apcmd_band_steering ,
" \t Configure Band Steering. " } ,
{ NULL , NULL , 0 }
} ;
/**
* @ brief Prints usage information of uaputl
*
* @ return N / A
*/
static void
print_tool_usage ( void )
{
int i ;
printf ( " uaputl.exe - uAP utility ver %s \n " , UAP_VERSION ) ;
printf ( " Usage: \n "
" \t uaputl.exe [options] <command> [command parameters] \n " ) ;
printf ( " Options: \n "
" \t --help \t Display help \n "
" \t -v \t Display version \n "
" \t -i <interface> \n " " \t -d <debug_level=0|1|2> \n " ) ;
printf ( " Commands: \n " ) ;
for ( i = 0 ; ap_command [ i ] . cmd ; i + + )
printf ( " \t %-4s \t \t %s \n " , ap_command [ i ] . cmd , ap_command [ i ] . help ) ;
printf ( " \n "
" For more information on the usage of each command use: \n "
" \t uaputl.exe <command> --help \n " ) ;
}
/****************************************************************************
Global functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/** Option parameter*/
static struct option ap_options [ ] = {
{ " help " , 0 , NULL , ' h ' } ,
{ " interface " , 1 , NULL , ' i ' } ,
{ " debug " , 1 , NULL , ' d ' } ,
{ " version " , 0 , NULL , ' v ' } ,
{ NULL , 0 , NULL , ' \0 ' }
} ;
/**
* @ brief Checks if given channel in ' a ' band is valid or not .
*
* @ param channel Channel number
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
is_valid_a_band_channel ( int channel )
{
int ret = UAP_SUCCESS ;
switch ( channel ) {
case 16 :
case 34 :
case 36 :
case 38 :
case 40 :
case 42 :
case 44 :
case 46 :
case 48 :
case 52 :
case 56 :
case 60 :
case 64 :
case 100 :
case 104 :
case 108 :
case 112 :
case 116 :
case 120 :
case 124 :
case 128 :
case 132 :
case 136 :
case 140 :
case 144 :
case 149 :
case 153 :
case 157 :
case 161 :
case 165 :
break ;
default :
ret = UAP_FAILURE ;
break ;
}
return ret ;
}
/**
* @ brief Checks if secondary channel can be set above given primary channel in ' a ' band or not .
*
* @ param channel Channel number
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
is_valid_a_band_channel_above ( int channel )
{
int ret = UAP_SUCCESS ;
switch ( channel ) {
case 36 :
case 44 :
case 52 :
case 60 :
case 100 :
case 108 :
case 116 :
case 124 :
case 132 :
case 140 :
case 149 :
case 157 :
break ;
default :
ret = UAP_FAILURE ;
break ;
}
return ret ;
}
/**
* @ brief Checks if secondary channel can be set below given primary channel in ' a ' band or not .
*
* @ param channel Channel number
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
is_valid_a_band_channel_below ( int channel )
{
int ret = UAP_SUCCESS ;
switch ( channel ) {
case 40 :
case 48 :
case 56 :
case 64 :
case 104 :
case 112 :
case 120 :
case 128 :
case 136 :
case 153 :
case 161 :
break ;
default :
ret = UAP_FAILURE ;
break ;
}
return ret ;
}
/**
* @ brief Checkes a particular input for validatation .
*
* @ param cmd Type of input
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
is_input_valid ( valid_inputs cmd , int argc , char * argv [ ] )
{
int i ;
int chan_number = 0 ;
int band = 0 ;
int ch ;
int ret = UAP_SUCCESS ;
if ( argc = = 0 )
return UAP_FAILURE ;
switch ( cmd ) {
case RDEEPROM :
if ( argc ! = 2 ) {
printf ( " ERR: Argument count mismatch \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( ISDIGIT ( argv [ 1 ] ) = = 0 )
| | ( A2HEXDECIMAL ( argv [ 0 ] ) & 0x03 ) | |
( ( int ) ( A2HEXDECIMAL ( argv [ 0 ] ) ) < 0 ) | |
( A2HEXDECIMAL ( argv [ 1 ] ) & 0x03 ) | |
( A2HEXDECIMAL ( argv [ 1 ] ) < 4 ) | |
( A2HEXDECIMAL ( argv [ 1 ] ) > 20 ) ) {
printf ( " ERR: Invalid inputs for Read EEPROM \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case SCANCHANNELS :
if ( argc > MAX_CHANNELS ) {
printf ( " ERR: Invalid List of Channels \n " ) ;
ret = UAP_FAILURE ;
} else {
for ( i = 0 ; i < argc ; i + + ) {
chan_number = - 1 ;
band = - 1 ;
sscanf ( argv [ i ] , " %d.%d " , & chan_number , & band ) ;
if ( ( chan_number = = - 1 ) | | ( chan_number < 1 ) | |
( chan_number > MAX_CHANNELS ) ) {
printf ( " ERR: Channel must be in the range of 1 to %d \n " , MAX_CHANNELS ) ;
ret = UAP_FAILURE ;
break ;
}
if ( ( chan_number > MAX_CHANNELS_BG ) & &
! ( is_valid_a_band_channel ( chan_number ) ) ) {
printf ( " ERR: Invalid Channel in 'a' band! \n " ) ;
ret = UAP_FAILURE ;
break ;
}
if ( ( band < - 1 ) | | ( band > 1 ) ) {
printf ( " ERR:Band must be either 0 or 1 \n " ) ;
ret = UAP_FAILURE ;
break ;
} else {
if ( ( ( chan_number < MAX_CHANNELS_BG ) & &
( chan_number ! = 8 ) & &
( chan_number ! = 12 ) & & ( band = = 1 ) )
| | ( ( chan_number > MAX_CHANNELS_BG )
& & ( band = = 0 ) ) ) {
printf ( " ERR:Invalid band for given channel \n " ) ;
ret = UAP_FAILURE ;
break ;
}
}
}
if ( ( ret ! = UAP_FAILURE ) & &
( has_dup_channel ( argc , argv ) ! = UAP_SUCCESS ) ) {
printf ( " ERR: Duplicate channel values entered \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( ret ! = UAP_FAILURE ) & &
( has_diff_band ( argc , argv ) ! = UAP_SUCCESS ) ) {
printf ( " ERR: Scan channel list should contain channels from only one band \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case TXPOWER :
if ( ( argc > 1 ) | | ( ISDIGIT ( argv [ 0 ] ) = = 0 ) ) {
printf ( " ERR:Invalid Transmit power \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( atoi ( argv [ 0 ] ) < MIN_TX_POWER ) | |
( atoi ( argv [ 0 ] ) > MAX_TX_POWER ) ) {
printf ( " ERR: TX Powar must be in the rage of %d to %d. \n " , MIN_TX_POWER , MAX_TX_POWER ) ;
ret = UAP_FAILURE ;
}
}
break ;
case PROTOCOL :
if ( ( argc > 2 ) | | ( ISDIGIT ( argv [ 0 ] ) = = 0 ) ) {
printf ( " ERR:Invalid Protocol \n " ) ;
ret = UAP_FAILURE ;
} else
ret = is_protocol_valid ( atoi ( argv [ 0 ] ) ) ;
break ;
case AKM_SUITE :
if ( argc = = 2 ) {
if ( A2HEXDECIMAL ( argv [ 1 ] ) &
~ ( KEY_MGMT_PSK | KEY_MGMT_PSK_SHA256 | KEY_MGMT_EAP
| KEY_MGMT_NONE | KEY_MGMT_SAE ) ) {
printf ( " ERR: Invalid AKM suite \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case CHANNEL :
if ( ( argc ! = 1 ) & & ( argc ! = 2 ) ) {
printf ( " ERR: Incorrect arguments for channel. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( argc = = 2 ) {
if ( ( ISDIGIT ( argv [ 1 ] ) = = 0 ) | |
( atoi ( argv [ 1 ] ) & ~ CHANNEL_MODE_MASK ) ) {
printf ( " ERR: Invalid Mode \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 1 ] ) & BITMAP_ACS_MODE ) & &
( atoi ( argv [ 0 ] ) ! = 0 ) ) {
printf ( " ERR: Channel must be 0 for ACS; MODE = 1. \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 1 ] ) & BITMAP_CHANNEL_ABOVE ) & &
( atoi ( argv [ 1 ] ) & BITMAP_CHANNEL_BELOW ) ) {
printf ( " ERR: secondary channel above and below both are enabled \n " ) ;
ret = UAP_FAILURE ;
}
}
if ( ( argc = = 1 ) | | ( ! ( atoi ( argv [ 1 ] ) & BITMAP_ACS_MODE ) ) ) {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) < 1 ) | |
( atoi ( argv [ 0 ] ) > MAX_CHANNELS ) ) {
printf ( " ERR: Channel must be in the range of 1 to %d \n " , MAX_CHANNELS ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 0 ] ) > MAX_CHANNELS_BG ) & &
! ( is_valid_a_band_channel ( atoi ( argv [ 0 ] ) ) ) ) {
printf ( " ERR: Invalid Channel in 'a' band! \n " ) ;
ret = UAP_FAILURE ;
}
ch = atoi ( argv [ 0 ] ) ;
if ( ch < = MAX_CHANNELS_BG ) {
if ( ( argc = = 2 ) & &
( atoi ( argv [ 1 ] ) &
BITMAP_CHANNEL_ABOVE ) & &
( atoi ( argv [ 0 ] ) >
MAX_CHANNEL_ABOVE ) ) {
printf ( " ERR: only allow channel 1-9 for secondary channel above \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( argc = = 2 ) & &
( atoi ( argv [ 1 ] ) &
BITMAP_CHANNEL_BELOW ) & &
( ( atoi ( argv [ 0 ] ) < MIN_CHANNEL_BELOW )
| | ( atoi ( argv [ 0 ] ) = = 14 ) ) ) {
printf ( " ERR: only allow channel 5-13 for secondary channel below \n " ) ;
ret = UAP_FAILURE ;
}
} else {
if ( argc = = 2 ) {
if ( ( atoi ( argv [ 1 ] ) &
BITMAP_CHANNEL_BELOW ) & &
! is_valid_a_band_channel_below
( atoi ( argv [ 0 ] ) ) ) {
printf ( " ERR: For given primary channel secondary channel can not be set below \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 1 ] ) &
BITMAP_CHANNEL_ABOVE ) & &
! is_valid_a_band_channel_above
( atoi ( argv [ 0 ] ) ) ) {
printf ( " ERR: For given primary channel secondary channel can not be set above \n " ) ;
ret = UAP_FAILURE ;
}
}
}
}
}
break ;
case CHANNEL_EXT :
if ( argc > 3 ) {
printf ( " ERR: Incorrect arguments for channel_ext. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( argc = = 3 ) {
if ( ( ISDIGIT ( argv [ 2 ] ) = = 0 ) | |
( atoi ( argv [ 2 ] ) & ~ CHANNEL_MODE_MASK ) ) {
printf ( " ERR: Invalid Mode \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 2 ] ) & BITMAP_ACS_MODE ) & &
( atoi ( argv [ 0 ] ) ! = 0 ) ) {
printf ( " ERR: Channel must be 0 for ACS; MODE = 1. \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 2 ] ) & BITMAP_CHANNEL_ABOVE ) & &
( atoi ( argv [ 2 ] ) & BITMAP_CHANNEL_BELOW ) ) {
printf ( " ERR: secondary channel above and below both are enabled \n " ) ;
ret = UAP_FAILURE ;
}
}
if ( ( argc = = 2 ) & &
( ( ISDIGIT ( argv [ 1 ] ) = = 0 ) | | ( atoi ( argv [ 1 ] ) < 0 ) | |
atoi ( argv [ 1 ] ) > 1 ) ) {
printf ( " ERR:Invalid band \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( argc = = 1 ) | |
( ( argc = = 3 ) & &
! ( atoi ( argv [ 2 ] ) & BITMAP_ACS_MODE ) ) ) {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) < 1 ) | |
( atoi ( argv [ 0 ] ) > MAX_CHANNELS ) ) {
printf ( " ERR: Channel must be in the range of 1 to %d \n " , MAX_CHANNELS ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 0 ] ) > MAX_CHANNELS_BG ) & &
! ( is_valid_a_band_channel ( atoi ( argv [ 0 ] ) ) ) ) {
printf ( " ERR: Invalid Channel in 'a' band! \n " ) ;
ret = UAP_FAILURE ;
}
ch = atoi ( argv [ 0 ] ) ;
if ( ch < = MAX_CHANNELS_BG ) {
if ( ( argc = = 3 ) & &
( atoi ( argv [ 2 ] ) &
BITMAP_CHANNEL_ABOVE ) & &
( atoi ( argv [ 0 ] ) >
MAX_CHANNEL_ABOVE ) ) {
printf ( " ERR: only allow channel 1-9 for secondary channel above \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( argc = = 3 ) & &
( atoi ( argv [ 2 ] ) &
BITMAP_CHANNEL_BELOW ) & &
( ( atoi ( argv [ 0 ] ) < MIN_CHANNEL_BELOW )
| | ( atoi ( argv [ 0 ] ) = = 14 ) ) ) {
printf ( " ERR: only allow channel 5-13 for secondary channel below \n " ) ;
ret = UAP_FAILURE ;
}
} else {
if ( argc = = 3 ) {
if ( ( atoi ( argv [ 2 ] ) &
BITMAP_CHANNEL_BELOW ) & &
! is_valid_a_band_channel_below
( atoi ( argv [ 0 ] ) ) ) {
printf ( " ERR: For given primary channel secondary channel can not be set below \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 2 ] ) &
BITMAP_CHANNEL_ABOVE ) & &
! is_valid_a_band_channel_above
( atoi ( argv [ 0 ] ) ) ) {
printf ( " ERR: For given primary channel secondary channel can not be set above \n " ) ;
ret = UAP_FAILURE ;
}
}
}
}
}
break ;
case BAND :
if ( argc > 1 ) {
printf ( " ERR: Incorrect number of BAND arguments. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > 1 ) ) {
printf ( " ERR: Invalid band. \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case RATE :
if ( argc > MAX_RATES ) {
printf ( " ERR: Incorrect number of RATES arguments. \n " ) ;
ret = UAP_FAILURE ;
} else {
for ( i = 0 ; i < argc ; i + + ) {
if ( ( IS_HEX_OR_DIGIT ( argv [ i ] ) = = UAP_FAILURE ) | |
( is_rate_valid
( A2HEXDECIMAL ( argv [ i ] ) &
~ BASIC_RATE_SET_BIT )
! = UAP_SUCCESS ) ) {
printf ( " ERR:Unsupported rate. \n " ) ;
ret = UAP_FAILURE ;
break ;
}
}
if ( ( ret ! = UAP_FAILURE ) & &
( has_dup_rate ( argc , argv ) ! = UAP_SUCCESS ) ) {
printf ( " ERR: Duplicate rate values entered \n " ) ;
ret = UAP_FAILURE ;
}
if ( check_mandatory_rates ( argc , argv ) ! = UAP_SUCCESS ) {
ret = UAP_FAILURE ;
}
}
break ;
case BROADCASTSSID :
if ( argc ! = 1 ) {
printf ( " ERR:wrong BROADCASTSSID arguments. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( ( atoi ( argv [ 0 ] ) ! = 0 ) & & ( atoi ( argv [ 0 ] ) ! = 1 ) & &
( atoi ( argv [ 0 ] ) ! = 2 ) ) ) {
printf ( " ERR:Illegal parameter %s for BROADCASTSSID. Must be either '0', '1' or '2'. \n " , argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
}
break ;
case RTSTHRESH :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for RTSTHRESHOLD \n " ) ;
ret = UAP_FAILURE ;
} else if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > MAX_RTS_THRESHOLD ) ) {
printf ( " ERR:Illegal RTSTHRESHOLD %s. The value must between 0 and %d \n " , argv [ 0 ] , MAX_RTS_THRESHOLD ) ;
ret = UAP_FAILURE ;
}
break ;
case FRAGTHRESH :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for FRAGTHRESH \n " ) ;
ret = UAP_FAILURE ;
} else if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) < MIN_FRAG_THRESHOLD ) | |
( atoi ( argv [ 0 ] ) > MAX_FRAG_THRESHOLD ) ) {
printf ( " ERR:Illegal FRAGTHRESH %s. The value must between %d and %d \n " , argv [ 0 ] , MIN_FRAG_THRESHOLD , MAX_FRAG_THRESHOLD ) ;
ret = UAP_FAILURE ;
}
break ;
case DTIMPERIOD :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for DTIMPERIOD \n " ) ;
ret = UAP_FAILURE ;
} else if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 1 ) | |
( atoi ( argv [ 0 ] ) > MAX_DTIM_PERIOD ) ) {
printf ( " ERR: DTIMPERIOD Value must be in range of 1 to %d \n " , MAX_DTIM_PERIOD ) ;
ret = UAP_FAILURE ;
}
break ;
case RSNREPLAYPROT :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for RSNREPLAYPROT \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > 1 ) ) {
printf ( " ERR:Illegal RSNREPLAYPROT parameter %s. Must be either '0' or '1'. \n " , argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
}
break ;
case RADIOCONTROL :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for RADIOCONTROL \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > 1 ) ) {
printf ( " ERR:Illegal RADIOCONTROL parameter %s. Must be either '0' or '1'. \n " , argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
}
break ;
case TXRATECFG :
if ( argc > 3 ) {
printf ( " ERR:Incorrect number of arguments for DATARATE \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ( argc > = 1 ) & &
( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) ) | |
( ( argc > = 2 ) & &
( IS_HEX_OR_DIGIT ( argv [ 1 ] ) = = UAP_FAILURE ) )
| | ( ( argc > = 3 ) & &
( IS_HEX_OR_DIGIT ( argv [ 2 ] ) = = UAP_FAILURE ) )
) {
printf ( " ERR: invalid Tx data rate \n " ) ;
ret = UAP_FAILURE ;
} else if ( argc > = 1 ) {
if ( A2HEXDECIMAL ( argv [ 0 ] ) = = 0xFF ) {
if ( argc ! = 1 ) {
printf ( " ERR: invalid auto rate input \n " ) ;
ret = UAP_FAILURE ;
}
} else {
if ( ( A2HEXDECIMAL ( argv [ 0 ] ) > 3 )
) {
printf ( " ERR: invalid format \n " ) ;
ret = UAP_FAILURE ;
}
if ( argc > = 2 ) {
if ( ( ( A2HEXDECIMAL ( argv [ 0 ] ) = =
0 ) & &
( A2HEXDECIMAL ( argv [ 1 ] ) >
11 ) ) | |
( ( A2HEXDECIMAL ( argv [ 0 ] ) = =
1 ) & &
( A2HEXDECIMAL ( argv [ 1 ] ) ! =
32 ) & &
( A2HEXDECIMAL ( argv [ 1 ] ) >
15 )
) ) {
printf ( " ERR:Incorrect TxRate %s. \n " , argv [ 1 ] ) ;
ret = UAP_FAILURE ;
}
}
if ( argc = = 3 ) {
if ( ( ( A2HEXDECIMAL ( argv [ 0 ] ) ! =
2 ) & &
( A2HEXDECIMAL ( argv [ 0 ] ) ! =
3 ) ) | |
( ( A2HEXDECIMAL ( argv [ 2 ] ) < 1 )
| | ( A2HEXDECIMAL ( argv [ 2 ] ) >
2 ) ) ) {
printf ( " ERR:Incorrect nss. \n " ) ;
ret = UAP_FAILURE ;
}
}
}
}
}
break ;
case MCBCDATARATE :
case TXBEACONRATE :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for DATARATE \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = UAP_FAILURE ) {
printf ( " ERR: invalid data rate \n " ) ;
ret = UAP_FAILURE ;
} else if ( ( A2HEXDECIMAL ( argv [ 0 ] ) ! = 0 ) & &
( is_rate_valid
( A2HEXDECIMAL ( argv [ 0 ] ) &
~ BASIC_RATE_SET_BIT ) ! = UAP_SUCCESS ) ) {
printf ( " ERR: invalid data rate \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case PKTFWD :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for PKTFWD. \n " ) ;
ret = UAP_FAILURE ;
} else if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( ( atoi ( argv [ 0 ] ) < 0 ) | | ( atoi ( argv [ 0 ] ) > 15 ) ) ) {
printf ( " ERR:Illegal PKTFWD parameter %s. Must be within '0' and '15'. \n " , argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
break ;
case STAAGEOUTTIMER :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for STAAGEOUTTIMER. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( ( atoi ( argv [ 0 ] ) ! = 0 ) & &
( ( atoi ( argv [ 0 ] ) <
MIN_STAGE_OUT_TIME ) | |
( atoi ( argv [ 0 ] ) >
MAX_STAGE_OUT_TIME ) ) ) )
{
printf ( " ERR:Illegal STAAGEOUTTIMER %s. Must be between %d and %d. \n " , argv [ 0 ] , MIN_STAGE_OUT_TIME , MAX_STAGE_OUT_TIME ) ;
ret = UAP_FAILURE ;
}
}
break ;
case PSSTAAGEOUTTIMER :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for PSSTAAGEOUTTIMER. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( ( atoi ( argv [ 0 ] ) ! = 0 ) & &
( ( atoi ( argv [ 0 ] ) <
MIN_STAGE_OUT_TIME ) | |
( atoi ( argv [ 0 ] ) >
MAX_STAGE_OUT_TIME ) ) ) )
{
printf ( " ERR:Illegal PSSTAAGEOUTTIMER %s. Must be between %d and %d. \n " , argv [ 0 ] , MIN_STAGE_OUT_TIME , MAX_STAGE_OUT_TIME ) ;
ret = UAP_FAILURE ;
}
}
break ;
case AUTHMODE :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for AUTHMODE \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( ( atoi ( argv [ 0 ] ) ! = 0 ) & &
( atoi ( argv [ 0 ] ) ! = 1 )
& & ( atoi ( argv [ 0 ] ) ! = 3 )
& & ( atoi ( argv [ 0 ] ) ! =
255 ) ) ) {
printf ( " ERR:Illegal AUTHMODE parameter %s. Must be either '0','1','3' or 255''. \n " , argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
}
break ;
case GROUPREKEYTIMER :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for GROUPREKEYTIMER. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > MAX_GRP_TIMER ) ) {
printf ( " ERR: GROUPREKEYTIMER range is [0:%d] (0 for disable) \n " , MAX_GRP_TIMER ) ;
ret = UAP_FAILURE ;
}
}
break ;
case MAXSTANUM :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for MAXSTANUM \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < = 0 ) ) {
printf ( " ERR:Invalid STA_NUM argument %s. \n " ,
argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
}
break ;
case BEACONPERIOD :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of argument for BEACONPERIOD. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) < MIN_BEACON_PERIOD )
| | ( atoi ( argv [ 0 ] ) > MAX_BEACON_PERIOD ) ) {
printf ( " ERR: BEACONPERIOD must be in range of %d to %d. \n " , MIN_BEACON_PERIOD , MAX_BEACON_PERIOD ) ;
ret = UAP_FAILURE ;
}
}
break ;
case RETRYLIMIT :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for RETRY LIMIT \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) > MAX_RETRY_LIMIT ) | |
( atoi ( argv [ 0 ] ) < 0 ) ) {
printf ( " ERR:RETRY_LIMIT must be in the range of [0:%d]. The input was %s. \n " , MAX_RETRY_LIMIT , argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
}
break ;
case STICKYTIMCONFIG :
if ( ( argc ! = 1 ) & & ( argc ! = 3 ) ) {
printf ( " ERR:Incorrect number of arguments for STICKY_TIM_CONFIG \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > 2 ) ) {
printf ( " ERR:Enable parameter must be 0, 1 or 2 \n " ) ;
ret = UAP_FAILURE ;
break ;
}
if ( ( ( atoi ( argv [ 0 ] ) ! = 1 ) & & ( argc > 1 ) ) ) {
printf ( " ERR: Invalid arguments \n " ) ;
ret = UAP_FAILURE ;
break ;
}
if ( ( atoi ( argv [ 0 ] ) = = 1 ) & & ( argc ! = 3 ) ) {
printf ( " ERR: Both duration and sticky bit mask must be provided for ENABLE = 1 \n " ) ;
ret = UAP_FAILURE ;
break ;
}
if ( argc > 1 ) {
if ( ( ISDIGIT ( argv [ 1 ] ) = = 0 ) ) {
printf ( " ERR: Invalid duration \n " ) ;
ret = UAP_FAILURE ;
break ;
}
if ( ( ISDIGIT ( argv [ 2 ] ) = = 0 ) | |
( atoi ( argv [ 2 ] ) < 1 ) | |
( atoi ( argv [ 2 ] ) > 3 ) ) {
printf ( " ERR:Invalid sticky bit mask \n " ) ;
ret = UAP_FAILURE ;
break ;
}
}
}
break ;
case STICKYTIMSTAMACADDR :
if ( ( argc ! = 1 ) & & ( argc ! = 2 ) ) {
printf ( " ERR:Incorrect number of STICKY_TIM_STA_MAC_ADDR arguments \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( argc = = 2 ) & &
( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > 1 ) ) ) {
printf ( " ERR:Invalid control parameter \n " ) ;
ret = UAP_FAILURE ;
break ;
}
}
break ;
case COEX2040CONFIG :
if ( argc ! = 1 ) {
printf ( " ERR: Incorrect number of 2040 COEX CONFIG arguments \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > 1 ) ) {
printf ( " ERR:Invalid enable parameter \n " ) ;
ret = UAP_FAILURE ;
break ;
}
}
break ;
case EAPOL_PWK_HSK :
if ( argc ! = 2 ) {
printf ( " ERR:Incorrect number of EAPOL_PWK_HSK arguments. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( ISDIGIT ( argv [ 1 ] ) = = 0 )
| | ( atoi ( argv [ 0 ] ) < 0 ) | | ( atoi ( argv [ 1 ] ) < 0 ) ) {
printf ( " ERR:Illegal parameters for EAPOL_PWK_HSK. Must be digits greater than equal to zero. \n " ) ;
}
}
break ;
case EAPOL_GWK_HSK :
if ( argc ! = 2 ) {
printf ( " ERR:Incorrect number of EAPOL_GWK_HSK arguments. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( ISDIGIT ( argv [ 1 ] ) = = 0 )
| | ( atoi ( argv [ 0 ] ) < 0 ) | | ( atoi ( argv [ 1 ] ) < 0 ) ) {
printf ( " ERR:Illegal parameters for EAPOL_GWK_HSK. Must be digits greater than equal to zero. \n " ) ;
}
}
break ;
case PREAMBLETYPE :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for PREAMBLE TYPE \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) > MAX_PREAMBLE_TYPE ) | |
( atoi ( argv [ 0 ] ) < 0 ) ) {
printf ( " ERR:PREAMBLE TYPE must be in the range of [0:%d]. The input was %s. \n " , MAX_PREAMBLE_TYPE , argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
}
break ;
case COEX_COMM_BITMAP :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of argument for Bitmap. \n " ) ;
ret = UAP_FAILURE ;
} else {
/* Only bit 0 is supported now, hence check for 1 or 0 */
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) < 0 ) | | ( atoi ( argv [ 0 ] ) > 1 ) ) {
printf ( " ERR: Bitmap must have value of 1 or 0. \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case COEX_COMM_AP_COEX :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of argument for APBTCoex. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( IS_HEX_OR_DIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) < 0 ) | | ( atoi ( argv [ 0 ] ) > 1 ) ) {
printf ( " ERR: APBTCoex must have value of 1 or 0. \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case COEX_SCO_ACL_FREQ :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for aclFrequency. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ISDIGIT ( argv [ 0 ] ) = = 0 ) {
printf ( " ERR: Incorrect value for aclFrequency. \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case COEX_ACL_ENABLED :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for (acl) enabled. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) > 1 ) ) {
printf ( " ERR: (acl) enabled must have value of 1 or 0. \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case COEX_ACL_BT_TIME :
case COEX_ACL_WLAN_TIME :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for bt/wlan time. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ISDIGIT ( argv [ 0 ] ) = = 0 ) {
printf ( " ERR: Incorrect value for bt/wlan time. \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case COEX_PROTECTION :
if ( argc ! = 2 ) {
printf ( " ERR:Incorrect number of arguments for %s. \n " ,
argv [ 0 ] ) ;
ret = UAP_FAILURE ;
} else {
if ( ISDIGIT ( argv [ 1 ] ) = = 0 ) {
printf ( " ERR: Incorrect value for %s. \n " ,
argv [ 0 ] ) ;
ret = UAP_FAILURE ;
}
}
break ;
case PWK_CIPHER :
if ( ( argc ! = 1 ) & & ( argc ! = 2 ) ) {
printf ( " ERR:Incorrect number of arguments for pwk_cipher. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) & ~ PROTOCOL_BITMAP ) ) {
printf ( " Invalid Protocol paramter. \n " ) ;
ret = UAP_FAILURE ;
}
if ( argc = = 2 ) {
if ( ( ISDIGIT ( argv [ 1 ] ) = = 0 ) | |
( atoi ( argv [ 1 ] ) & ~ CIPHER_BITMAP ) ) {
printf ( " Invalid pairwise cipher. \n " ) ;
ret = UAP_FAILURE ;
}
}
}
break ;
case GWK_CIPHER :
if ( argc ! = 1 ) {
printf ( " ERR:Incorrect number of arguments for gwk_cipher. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | |
( atoi ( argv [ 0 ] ) & ~ CIPHER_BITMAP ) | |
( atoi ( argv [ 0 ] ) = = AES_CCMP_TKIP ) ) {
printf ( " Invalid group cipher. \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
case RESTRICT_CLIENT_MODE :
if ( ( argc ! = 1 ) & & ( argc ! = 2 ) ) {
printf ( " ERR: Incorrect number of arguments. \n " ) ;
ret = UAP_FAILURE ;
} else {
if ( ( ISDIGIT ( argv [ 0 ] ) = = 0 ) | | ( ( argc = = 2 ) & &
( ( IS_HEX_OR_DIGIT
( argv [ 1 ] ) = = 0 ) | |
( ( atoi ( argv [ 0 ] ) < 0 ) | |
( atoi ( argv [ 0 ] ) >
1 ) ) ) ) ) {
printf ( " ERR: Invalid arguments \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( atoi ( argv [ 0 ] ) = = 1 ) & & ( argc = = 1 ) ) {
printf ( " ERR: Mode_config parameter must be provided to enable this feature. \n " ) ;
ret = UAP_FAILURE ;
}
if ( ( argc = = 2 ) & &
( ( ( A2HEXDECIMAL ( argv [ 1 ] ) < < 8 ) ! = B_ONLY_MASK ) & &
( ( A2HEXDECIMAL ( argv [ 1 ] ) < < 8 ) ! = G_ONLY_MASK ) & &
( ( A2HEXDECIMAL ( argv [ 1 ] ) < < 8 ) ! = A_ONLY_MASK ) & &
( ( A2HEXDECIMAL ( argv [ 1 ] ) < < 8 ) ! = N_ONLY_MASK ) & &
( ( A2HEXDECIMAL ( argv [ 1 ] ) < < 8 ) ! = AC_ONLY_MASK ) ) ) {
printf ( " ERR: Exactly one mode can be enabled at a time. \n " ) ;
ret = UAP_FAILURE ;
}
}
break ;
default :
ret = UAP_FAILURE ;
break ;
}
return ret ;
}
/**
* @ brief Converts colon separated MAC address to hex value
*
* @ param mac A pointer to the colon separated MAC string
* @ param raw A pointer to the hex data buffer
* @ return UAP_SUCCESS or UAP_FAILURE
* UAP_RET_MAC_BROADCAST - if broadcast mac
* UAP_RET_MAC_MULTICAST - if multicast mac
*/
int
mac2raw ( char * mac , t_u8 * raw )
{
unsigned int temp_raw [ ETH_ALEN ] ;
int num_tokens = 0 ;
int i ;
if ( strlen ( mac ) ! = ( ( 2 * ETH_ALEN ) + ( ETH_ALEN - 1 ) ) ) {
return UAP_FAILURE ;
}
num_tokens = sscanf ( mac , " %2x:%2x:%2x:%2x:%2x:%2x " ,
temp_raw + 0 , temp_raw + 1 , temp_raw + 2 ,
temp_raw + 3 , temp_raw + 4 , temp_raw + 5 ) ;
if ( num_tokens ! = ETH_ALEN ) {
return UAP_FAILURE ;
}
for ( i = 0 ; i < num_tokens ; i + + )
raw [ i ] = ( t_u8 ) temp_raw [ i ] ;
if ( memcmp ( raw , " \xff \xff \xff \xff \xff \xff " , ETH_ALEN ) = = 0 ) {
return UAP_RET_MAC_BROADCAST ;
} else if ( raw [ 0 ] & 0x01 ) {
return UAP_RET_MAC_MULTICAST ;
}
return UAP_SUCCESS ;
}
/**
* @ brief Converts a string to hex value
*
* @ param str A pointer to the string
* @ param raw A pointer to the raw data buffer
* @ return Number of bytes read
*/
int
string2raw ( char * str , unsigned char * raw )
{
int len = ( strlen ( str ) + 1 ) / 2 ;
do {
if ( ! isxdigit ( * str ) ) {
return - 1 ;
}
* str = toupper ( * str ) ;
* raw = CHAR2INT ( * str ) < < 4 ;
+ + str ;
* str = toupper ( * str ) ;
if ( * str = = ' \0 ' )
break ;
* raw | = CHAR2INT ( * str ) ;
+ + raw ;
} while ( * + + str ! = ' \0 ' ) ;
return len ;
}
/**
* @ brief Prints a MAC address in colon separated form from hex data
*
* @ param raw A pointer to the hex data buffer
* @ return N / A
*/
void
print_mac ( t_u8 * raw )
{
printf ( " %02x:%02x:%02x:%02x:%02x:%02x " , ( unsigned int ) raw [ 0 ] ,
( unsigned int ) raw [ 1 ] , ( unsigned int ) raw [ 2 ] , ( unsigned int ) raw [ 3 ] ,
( unsigned int ) raw [ 4 ] , ( unsigned int ) raw [ 5 ] ) ;
return ;
}
/**
* @ brief Check hex string
*
* @ param hex A pointer to hex string
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
ishexstring ( void * hex )
{
int i , a ;
char * p = hex ;
int len = strlen ( p ) ;
if ( ! strncasecmp ( " 0x " , p , 2 ) ) {
p + = 2 ;
len - = 2 ;
}
for ( i = 0 ; i < len ; i + + ) {
a = hex2num ( * p ) ;
if ( a < 0 )
return UAP_FAILURE ;
p + + ;
}
return UAP_SUCCESS ;
}
/**
* @ brief Show auth tlv
*
* @ param tlv Pointer to auth tlv
*
* $ return N / A
*/
void
print_auth ( tlvbuf_auth_mode * tlv )
{
switch ( tlv - > auth_mode ) {
case 0 :
printf ( " AUTHMODE = Open authentication \n " ) ;
break ;
case 1 :
printf ( " AUTHMODE = Shared key authentication \n " ) ;
break ;
case 3 :
printf ( " AUTHMODE = WPA3 SAE \n " ) ;
break ;
case 255 :
printf ( " AUTHMODE = Auto (open and shared key) \n " ) ;
break ;
default :
printf ( " ERR: Invalid authmode=%d \n " , tlv - > auth_mode ) ;
break ;
}
}
/**
*
* @ brief Show cipher tlv
*
* @ param tlv Pointer to cipher tlv
*
* $ return N / A
*/
void
print_cipher ( tlvbuf_cipher * tlv )
{
switch ( tlv - > pairwise_cipher ) {
case CIPHER_TKIP :
printf ( " PairwiseCipher = TKIP \n " ) ;
break ;
case CIPHER_AES_CCMP :
printf ( " PairwiseCipher = AES CCMP \n " ) ;
break ;
case CIPHER_TKIP | CIPHER_AES_CCMP :
printf ( " PairwiseCipher = TKIP + AES CCMP \n " ) ;
break ;
case CIPHER_NONE :
printf ( " PairwiseCipher = None \n " ) ;
break ;
default :
printf ( " Unknown Pairwise cipher 0x%x \n " , tlv - > pairwise_cipher ) ;
break ;
}
switch ( tlv - > group_cipher ) {
case CIPHER_TKIP :
printf ( " GroupCipher = TKIP \n " ) ;
break ;
case CIPHER_AES_CCMP :
printf ( " GroupCipher = AES CCMP \n " ) ;
break ;
case CIPHER_NONE :
printf ( " GroupCipher = None \n " ) ;
break ;
default :
printf ( " Unknown Group cipher 0x%x \n " , tlv - > group_cipher ) ;
break ;
}
}
/**
* @ brief Show pairwise cipher tlv
*
* @ param tlv Pointer to pairwise cipher tlv
*
* $ return N / A
*/
void
print_pwk_cipher ( tlvbuf_pwk_cipher * tlv )
{
switch ( tlv - > protocol ) {
case PROTOCOL_WPA :
printf ( " Protocol WPA : " ) ;
break ;
case PROTOCOL_WPA2 :
printf ( " Protocol WPA2 : " ) ;
break ;
case PROTOCOL_WPA3_SAE :
printf ( " Protocol WPA3_SAE : " ) ;
break ;
default :
printf ( " Unknown Protocol 0x%x \n " , tlv - > protocol ) ;
break ;
}
switch ( tlv - > pairwise_cipher ) {
case CIPHER_TKIP :
printf ( " PairwiseCipher = TKIP \n " ) ;
break ;
case CIPHER_AES_CCMP :
printf ( " PairwiseCipher = AES CCMP \n " ) ;
break ;
case CIPHER_TKIP | CIPHER_AES_CCMP :
printf ( " PairwiseCipher = TKIP + AES CCMP \n " ) ;
break ;
case CIPHER_NONE :
printf ( " PairwiseCipher = None \n " ) ;
break ;
default :
printf ( " Unknown Pairwise cipher 0x%x \n " , tlv - > pairwise_cipher ) ;
break ;
}
}
/**
* @ brief Show group cipher tlv
*
* @ param tlv Pointer to group cipher tlv
*
* $ return N / A
*/
void
print_gwk_cipher ( tlvbuf_gwk_cipher * tlv )
{
switch ( tlv - > group_cipher ) {
case CIPHER_TKIP :
printf ( " GroupCipher = TKIP \n " ) ;
break ;
case CIPHER_AES_CCMP :
printf ( " GroupCipher = AES CCMP \n " ) ;
break ;
case CIPHER_NONE :
printf ( " GroupCipher = None \n " ) ;
break ;
default :
printf ( " Unknown Group cipher 0x%x \n " , tlv - > group_cipher ) ;
break ;
}
}
/**
* @ brief Show mac filter tlv
*
* @ param tlv Pointer to filter tlv
*
* $ return N / A
*/
void
print_mac_filter ( tlvbuf_sta_mac_addr_filter * tlv )
{
int i ;
switch ( tlv - > filter_mode ) {
case 0 :
printf ( " Filter Mode = Filter table is disabled \n " ) ;
return ;
case 1 :
if ( ! tlv - > count ) {
printf ( " No mac address is allowed to connect \n " ) ;
} else {
printf ( " Filter Mode = Allow mac address specified in the allowed list \n " ) ;
}
break ;
case 2 :
if ( ! tlv - > count ) {
printf ( " No mac address is blocked \n " ) ;
} else {
printf ( " Filter Mode = Block MAC addresses specified in the banned list \n " ) ;
}
break ;
}
for ( i = 0 ; i < tlv - > count ; i + + ) {
printf ( " MAC_%d = " , i ) ;
print_mac ( & tlv - > mac_address [ i * ETH_ALEN ] ) ;
printf ( " \n " ) ;
}
}
/**
* @ brief Show rate tlv
*
* @ param tlv Pointer to rate tlv
*
* $ return N / A
*/
void
print_rate ( tlvbuf_rates * tlv )
{
int flag = 0 ;
int i ;
t_u16 tlv_len ;
tlv_len = * ( t_u8 * ) & tlv - > length ;
tlv_len | = ( * ( ( t_u8 * ) & tlv - > length + 1 ) < < 8 ) ;
printf ( " Basic Rates = " ) ;
for ( i = 0 ; i < tlv_len ; i + + ) {
if ( tlv - > operational_rates [ i ] > ( BASIC_RATE_SET_BIT - 1 ) ) {
flag = flag ? : 1 ;
printf ( " 0x%x " , tlv - > operational_rates [ i ] ) ;
}
}
printf ( " %s \n Non-Basic Rates = " , flag ? " " : " ( none ) " ) ;
for ( flag = 0 , i = 0 ; i < tlv_len ; i + + ) {
if ( tlv - > operational_rates [ i ] < BASIC_RATE_SET_BIT ) {
flag = flag ? : 1 ;
printf ( " 0x%x " , tlv - > operational_rates [ i ] ) ;
}
}
printf ( " %s \n " , flag ? " " : " ( none ) " ) ;
}
/**
* @ brief Show all the tlv in the buf
*
* @ param buf Pointer to tlv buffer
* @ param len Tlv buffer len
*
* $ return N / A
*/
void
print_tlv ( t_u8 * buf , t_u16 len )
{
tlvbuf_header * pcurrent_tlv = ( tlvbuf_header * ) buf ;
int tlv_buf_left = len ;
t_u16 tlv_type ;
t_u16 tlv_len ;
t_u16 tlv_val_16 ;
t_u32 tlv_val_32 ;
t_u8 ssid [ 33 ] ;
int i = 0 ;
tlvbuf_ap_mac_address * mac_tlv ;
tlvbuf_ssid * ssid_tlv ;
tlvbuf_beacon_period * beacon_tlv ;
tlvbuf_dtim_period * dtim_tlv ;
tlvbuf_rates * rates_tlv ;
tlvbuf_tx_power * txpower_tlv ;
tlvbuf_bcast_ssid_ctl * bcast_tlv ;
tlvbuf_preamble_ctl * preamble_tlv ;
tlvbuf_bss_status * bss_status_tlv ;
tlvbuf_rts_threshold * rts_tlv ;
tlvbuf_mcbc_data_rate * mcbcrate_tlv ;
tlvbuf_pkt_fwd_ctl * pkt_fwd_tlv ;
tlvbuf_sta_ageout_timer * ageout_tlv ;
tlvbuf_ps_sta_ageout_timer * ps_ageout_tlv ;
tlvbuf_auth_mode * auth_tlv ;
tlvbuf_protocol * proto_tlv ;
tlvbuf_akmp * akmp_tlv ;
tlvbuf_cipher * cipher_tlv ;
tlvbuf_pwk_cipher * pwk_cipher_tlv ;
tlvbuf_gwk_cipher * gwk_cipher_tlv ;
tlvbuf_group_rekey_timer * rekey_tlv ;
tlvbuf_wpa_passphrase * psk_tlv ;
tlvbuf_coex_common_cfg * coex_common_tlv ;
tlvbuf_coex_sco_cfg * coex_sco_tlv ;
tlvbuf_coex_acl_cfg * coex_acl_tlv ;
tlvbuf_coex_stats * coex_stats_tlv ;
tlvbuf_wep_key * wep_tlv ;
tlvbuf_frag_threshold * frag_tlv ;
tlvbuf_sta_mac_addr_filter * filter_tlv ;
tlvbuf_max_sta_num * max_sta_tlv ;
tlvbuf_retry_limit * retry_limit_tlv ;
tlvbuf_eapol_pwk_hsk_timeout * pwk_timeout_tlv ;
tlvbuf_eapol_pwk_hsk_retries * pwk_retries_tlv ;
tlvbuf_eapol_gwk_hsk_timeout * gwk_timeout_tlv ;
tlvbuf_eapol_gwk_hsk_retries * gwk_retries_tlv ;
tlvbuf_channel_config * channel_tlv ;
tlvbuf_channel_list * chnlist_tlv ;
channel_list * pchan_list ;
t_u16 custom_ie_len ;
tlvbuf_rsn_replay_prot * replay_prot_tlv ;
tlvbuf_custom_ie * custom_ie_tlv ;
custom_ie * custom_ie_ptr ;
tlvbuf_max_mgmt_ie * max_mgmt_ie_tlv ;
tlvbuf_wmm_para_t * wmm_para_tlv ;
int flag = 0 ;
tlvbuf_htcap_t * ht_cap_tlv ;
tlvbuf_htinfo_t * ht_info_tlv ;
tlvbuf_2040_coex * coex_2040_tlv ;
# ifdef RX_PACKET_COALESCE
tlvbuf_rx_pkt_coal_t * rx_pkt_coal_tlv ;
# endif
# if DEBUG
uap_printf ( MSG_DEBUG , " tlv total len=%d \n " , len ) ;
# endif
while ( tlv_buf_left > = ( int ) sizeof ( tlvbuf_header ) ) {
tlv_type = * ( t_u8 * ) & pcurrent_tlv - > type ;
tlv_type | = ( * ( ( t_u8 * ) & pcurrent_tlv - > type + 1 ) < < 8 ) ;
tlv_len = * ( t_u8 * ) & pcurrent_tlv - > len ;
tlv_len | = ( * ( ( t_u8 * ) & pcurrent_tlv - > len + 1 ) < < 8 ) ;
if ( ( sizeof ( tlvbuf_header ) + tlv_len ) >
( unsigned int ) tlv_buf_left ) {
printf ( " wrong tlv: tlv_len=%d, tlv_buf_left=%d \n " ,
tlv_len , tlv_buf_left ) ;
break ;
}
switch ( tlv_type ) {
case MRVL_AP_MAC_ADDRESS_TLV_ID :
mac_tlv = ( tlvbuf_ap_mac_address * ) pcurrent_tlv ;
printf ( " AP MAC address = " ) ;
print_mac ( mac_tlv - > ap_mac_addr ) ;
printf ( " \n " ) ;
break ;
case MRVL_SSID_TLV_ID :
memset ( ssid , 0 , sizeof ( ssid ) ) ;
ssid_tlv = ( tlvbuf_ssid * ) pcurrent_tlv ;
strncpy ( ( char * ) ssid , ( char * ) ssid_tlv - > ssid ,
sizeof ( ssid ) - 1 ) ;
printf ( " SSID = %s \n " , ssid ) ;
break ;
case MRVL_BEACON_PERIOD_TLV_ID :
beacon_tlv = ( tlvbuf_beacon_period * ) pcurrent_tlv ;
tlv_val_16 = * ( t_u8 * ) & beacon_tlv - > beacon_period_ms ;
tlv_val_16 | =
( * ( ( t_u8 * ) & beacon_tlv - > beacon_period_ms + 1 ) < <
8 ) ;
printf ( " Beacon period = %d \n " , tlv_val_16 ) ;
break ;
case MRVL_DTIM_PERIOD_TLV_ID :
dtim_tlv = ( tlvbuf_dtim_period * ) pcurrent_tlv ;
printf ( " DTIM period = %d \n " , dtim_tlv - > dtim_period ) ;
break ;
case MRVL_CHANNELCONFIG_TLV_ID :
channel_tlv = ( tlvbuf_channel_config * ) pcurrent_tlv ;
printf ( " Channel = %d \n " , channel_tlv - > chan_number ) ;
printf ( " Band = %s \n " ,
( channel_tlv - > bandcfg . chanBand = =
BAND_5GHZ ) ? " 5GHz " : " 2.4GHz " ) ;
printf ( " Channel Select Mode = %s \n " ,
( channel_tlv - > bandcfg . scanMode = =
SCAN_MODE_ACS ) ? " ACS " : " Manual " ) ;
if ( channel_tlv - > bandcfg . chan2Offset = = SEC_CHAN_NONE )
printf ( " no secondary channel \n " ) ;
else if ( channel_tlv - > bandcfg . chan2Offset = =
SEC_CHAN_ABOVE )
printf ( " secondary channel is above primary channel \n " ) ;
else if ( channel_tlv - > bandcfg . chan2Offset = =
SEC_CHAN_BELOW )
printf ( " secondary channel is below primary channel \n " ) ;
break ;
case MRVL_CHANNELLIST_TLV_ID :
chnlist_tlv = ( tlvbuf_channel_list * ) pcurrent_tlv ;
printf ( " Channels List = " ) ;
pchan_list =
( channel_list * ) & ( chnlist_tlv - > chan_list ) ;
if ( tlv_len % sizeof ( channel_list ) ) {
break ;
}
for ( i = 0 ;
( unsigned int ) i < ( tlv_len / sizeof ( channel_list ) ) ;
i + + ) {
printf ( " \n %d \t %sGHz " , pchan_list - > chan_number ,
( pchan_list - > bandcfg . chanBand = =
BAND_5GHZ ) ? " 5 " : " 2.4 " ) ;
pchan_list + + ;
}
printf ( " \n " ) ;
break ;
case MRVL_RSN_REPLAY_PROT_TLV_ID :
replay_prot_tlv =
( tlvbuf_rsn_replay_prot * ) pcurrent_tlv ;
printf ( " RSN replay protection = %s \n " ,
replay_prot_tlv - >
rsn_replay_prot ? " enabled " : " disabled " ) ;
break ;
case MRVL_RATES_TLV_ID :
rates_tlv = ( tlvbuf_rates * ) pcurrent_tlv ;
print_rate ( rates_tlv ) ;
break ;
case MRVL_TX_POWER_TLV_ID :
txpower_tlv = ( tlvbuf_tx_power * ) pcurrent_tlv ;
printf ( " Tx power = %d dBm \n " ,
txpower_tlv - > tx_power_dbm ) ;
break ;
case MRVL_BCAST_SSID_CTL_TLV_ID :
bcast_tlv = ( tlvbuf_bcast_ssid_ctl * ) pcurrent_tlv ;
printf ( " SSID broadcast = %s \n " ,
( bcast_tlv - > bcast_ssid_ctl = =
1 ) ? " enabled " : " disabled " ) ;
break ;
case MRVL_PREAMBLE_CTL_TLV_ID :
preamble_tlv = ( tlvbuf_preamble_ctl * ) pcurrent_tlv ;
printf ( " Preamble type = %s \n " ,
( preamble_tlv - > preamble_type = =
0 ) ? " auto " : ( ( preamble_tlv - > preamble_type = =
1 ) ? " short " : " long " ) ) ;
break ;
case MRVL_BSS_STATUS_TLV_ID :
bss_status_tlv = ( tlvbuf_bss_status * ) pcurrent_tlv ;
printf ( " BSS status = %s \n " ,
( bss_status_tlv - > bss_status = =
0 ) ? " stopped " : " started " ) ;
break ;
case MRVL_RTS_THRESHOLD_TLV_ID :
rts_tlv = ( tlvbuf_rts_threshold * ) pcurrent_tlv ;
tlv_val_16 = * ( t_u8 * ) & rts_tlv - > rts_threshold ;
tlv_val_16 | =
( * ( ( t_u8 * ) & rts_tlv - > rts_threshold + 1 ) < < 8 ) ;
printf ( " RTS threshold = %d \n " , tlv_val_16 ) ;
break ;
case MRVL_FRAG_THRESHOLD_TLV_ID :
frag_tlv = ( tlvbuf_frag_threshold * ) pcurrent_tlv ;
tlv_val_16 = * ( t_u8 * ) & frag_tlv - > frag_threshold ;
tlv_val_16 | =
( * ( ( t_u8 * ) & frag_tlv - > frag_threshold + 1 ) < < 8 ) ;
printf ( " Fragmentation threshold = %d \n " , tlv_val_16 ) ;
break ;
case MRVL_MCBC_DATA_RATE_TLV_ID :
mcbcrate_tlv = ( tlvbuf_mcbc_data_rate * ) pcurrent_tlv ;
tlv_val_16 = * ( t_u8 * ) & mcbcrate_tlv - > mcbc_datarate ;
tlv_val_16 | =
( * ( ( t_u8 * ) & mcbcrate_tlv - > mcbc_datarate + 1 ) < <
8 ) ;
if ( mcbcrate_tlv - > mcbc_datarate = = 0 )
printf ( " MCBC data rate = auto \n " ) ;
else
printf ( " MCBC data rate = 0x%x \n " , tlv_val_16 ) ;
break ;
case MRVL_PKT_FWD_CTL_TLV_ID :
pkt_fwd_tlv = ( tlvbuf_pkt_fwd_ctl * ) pcurrent_tlv ;
printf ( " %s handles packet forwarding - \n " ,
( ( pkt_fwd_tlv - > pkt_fwd_ctl & PKT_FWD_FW_BIT ) = =
0 ) ? " Host " : " Firmware " ) ;
printf ( " \t Intra-BSS broadcast packets are %s \n " ,
( ( pkt_fwd_tlv - >
pkt_fwd_ctl & PKT_FWD_INTRA_BCAST ) = =
0 ) ? " allowed " : " denied " ) ;
printf ( " \t Intra-BSS unicast packets are %s \n " ,
( ( pkt_fwd_tlv - >
pkt_fwd_ctl & PKT_FWD_INTRA_UCAST ) = =
0 ) ? " allowed " : " denied " ) ;
printf ( " \t Inter-BSS unicast packets are %s \n " ,
( ( pkt_fwd_tlv - >
pkt_fwd_ctl & PKT_FWD_INTER_UCAST ) = =
0 ) ? " allowed " : " denied " ) ;
break ;
case MRVL_STA_AGEOUT_TIMER_TLV_ID :
ageout_tlv = ( tlvbuf_sta_ageout_timer * ) pcurrent_tlv ;
tlv_val_32 = * ( t_u8 * ) & ageout_tlv - > sta_ageout_timer_ms ;
tlv_val_32 | =
( * ( ( t_u8 * ) & ageout_tlv - > sta_ageout_timer_ms + 1 )
< < 8 ) ;
tlv_val_32 | =
( * ( ( t_u8 * ) & ageout_tlv - > sta_ageout_timer_ms + 2 )
< < 16 ) ;
tlv_val_32 | =
( * ( ( t_u8 * ) & ageout_tlv - > sta_ageout_timer_ms + 3 )
< < 24 ) ;
printf ( " STA ageout timer = %d \n " , ( int ) tlv_val_32 ) ;
break ;
case MRVL_PS_STA_AGEOUT_TIMER_TLV_ID :
ps_ageout_tlv =
( tlvbuf_ps_sta_ageout_timer * ) pcurrent_tlv ;
tlv_val_32 =
* ( t_u8 * ) & ps_ageout_tlv - > ps_sta_ageout_timer_ms ;
tlv_val_32 | =
( *
( ( t_u8 * ) & ps_ageout_tlv - >
ps_sta_ageout_timer_ms + 1 ) < < 8 ) ;
tlv_val_32 | =
( *
( ( t_u8 * ) & ps_ageout_tlv - >
ps_sta_ageout_timer_ms + 2 ) < < 16 ) ;
tlv_val_32 | =
( *
( ( t_u8 * ) & ps_ageout_tlv - >
ps_sta_ageout_timer_ms + 3 ) < < 24 ) ;
printf ( " PS STA ageout timer = %d \n " , ( int ) tlv_val_32 ) ;
break ;
case MRVL_AUTH_TLV_ID :
auth_tlv = ( tlvbuf_auth_mode * ) pcurrent_tlv ;
print_auth ( auth_tlv ) ;
break ;
case MRVL_PROTOCOL_TLV_ID :
proto_tlv = ( tlvbuf_protocol * ) pcurrent_tlv ;
tlv_val_16 = * ( t_u8 * ) & proto_tlv - > protocol ;
tlv_val_16 | =
( * ( ( t_u8 * ) & proto_tlv - > protocol + 1 ) < < 8 ) ;
print_protocol ( tlv_val_16 ) ;
break ;
case MRVL_AKMP_TLV_ID :
akmp_tlv = ( tlvbuf_akmp * ) pcurrent_tlv ;
tlv_val_16 = * ( t_u8 * ) & akmp_tlv - > key_mgmt ;
tlv_val_16 | = ( * ( ( t_u8 * ) & akmp_tlv - > key_mgmt + 1 ) < < 8 ) ;
if ( tlv_val_16 & ( KEY_MGMT_PSK | KEY_MGMT_PSK_SHA256 ) ) {
if ( tlv_val_16 & KEY_MGMT_PSK )
printf ( " KeyMgmt = PSK \n " ) ;
if ( tlv_val_16 & KEY_MGMT_PSK_SHA256 )
printf ( " KeyMgmt = PSK_SHA256 \n " ) ;
tlv_val_16 =
* ( t_u8 * ) & akmp_tlv - > key_mgmt_operation ;
if ( tlv_len > sizeof ( t_u16 ) ) {
tlv_val_16 | =
( *
( ( t_u8 * ) & akmp_tlv - >
key_mgmt_operation + 1 ) < < 8 ) ;
printf ( " Key Exchange on : %s. \n " ,
( tlv_val_16 & 0x01 ) ? " Host " :
" Device " ) ;
printf ( " 1x Authentication on : %s. \n " ,
( tlv_val_16 & 0x10 ) ? " Host " :
" Device " ) ;
}
}
if ( tlv_val_16 & KEY_MGMT_EAP )
printf ( " KeyMgmt = EAP " ) ;
if ( tlv_val_16 & KEY_MGMT_NONE )
printf ( " KeyMgmt = NONE " ) ;
break ;
case MRVL_CIPHER_TLV_ID :
cipher_tlv = ( tlvbuf_cipher * ) pcurrent_tlv ;
print_cipher ( cipher_tlv ) ;
break ;
case MRVL_CIPHER_PWK_TLV_ID :
pwk_cipher_tlv = ( tlvbuf_pwk_cipher * ) pcurrent_tlv ;
pwk_cipher_tlv - > protocol =
uap_le16_to_cpu ( pwk_cipher_tlv - > protocol ) ;
print_pwk_cipher ( pwk_cipher_tlv ) ;
break ;
case MRVL_CIPHER_GWK_TLV_ID :
gwk_cipher_tlv = ( tlvbuf_gwk_cipher * ) pcurrent_tlv ;
print_gwk_cipher ( gwk_cipher_tlv ) ;
break ;
case MRVL_GRP_REKEY_TIME_TLV_ID :
rekey_tlv = ( tlvbuf_group_rekey_timer * ) pcurrent_tlv ;
tlv_val_32 = * ( t_u8 * ) & rekey_tlv - > group_rekey_time_sec ;
tlv_val_32 | =
( * ( ( t_u8 * ) & rekey_tlv - > group_rekey_time_sec + 1 )
< < 8 ) ;
tlv_val_32 | =
( * ( ( t_u8 * ) & rekey_tlv - > group_rekey_time_sec + 2 )
< < 16 ) ;
tlv_val_32 | =
( * ( ( t_u8 * ) & rekey_tlv - > group_rekey_time_sec + 3 )
< < 24 ) ;
if ( tlv_val_32 = = 0 )
printf ( " Group re-key time = disabled \n " ) ;
else
printf ( " Group re-key time = %d second \n " ,
tlv_val_32 ) ;
break ;
case MRVL_WPA_PASSPHRASE_TLV_ID :
psk_tlv = ( tlvbuf_wpa_passphrase * ) pcurrent_tlv ;
if ( tlv_len > 0 ) {
printf ( " WPA passphrase = " ) ;
for ( i = 0 ; i < tlv_len ; i + + )
printf ( " %c " , psk_tlv - > passphrase [ i ] ) ;
printf ( " \n " ) ;
} else
printf ( " WPA passphrase = None \n " ) ;
break ;
case MRVL_WEP_KEY_TLV_ID :
wep_tlv = ( tlvbuf_wep_key * ) pcurrent_tlv ;
print_wep_key ( wep_tlv ) ;
break ;
case MRVL_STA_MAC_ADDR_FILTER_TLV_ID :
filter_tlv = ( tlvbuf_sta_mac_addr_filter * ) pcurrent_tlv ;
print_mac_filter ( filter_tlv ) ;
break ;
case MRVL_MAX_STA_CNT_TLV_ID :
max_sta_tlv = ( tlvbuf_max_sta_num * ) pcurrent_tlv ;
tlv_val_16 =
* ( t_u8 * ) & max_sta_tlv - > max_sta_num_configured ;
tlv_val_16 | =
( *
( ( t_u8 * ) & max_sta_tlv - > max_sta_num_configured +
1 ) < < 8 ) ;
printf ( " Max Station Number configured = %d \n " ,
tlv_val_16 ) ;
if ( max_sta_tlv - > length = = 4 ) {
tlv_val_16 =
* ( t_u8 * ) & max_sta_tlv - >
max_sta_num_supported ;
tlv_val_16 | =
( *
( ( t_u8 * ) & max_sta_tlv - >
max_sta_num_supported + 1 ) < < 8 ) ;
printf ( " Max Station Number supported = %d \n " ,
tlv_val_16 ) ;
}
break ;
case MRVL_RETRY_LIMIT_TLV_ID :
retry_limit_tlv = ( tlvbuf_retry_limit * ) pcurrent_tlv ;
printf ( " Retry Limit = %d \n " ,
retry_limit_tlv - > retry_limit ) ;
break ;
case MRVL_EAPOL_PWK_HSK_TIMEOUT_TLV_ID :
pwk_timeout_tlv =
( tlvbuf_eapol_pwk_hsk_timeout * ) pcurrent_tlv ;
pwk_timeout_tlv - > pairwise_update_timeout =
uap_le32_to_cpu ( pwk_timeout_tlv - >
pairwise_update_timeout ) ;
printf ( " Pairwise handshake timeout = %d \n " ,
pwk_timeout_tlv - > pairwise_update_timeout ) ;
break ;
case MRVL_EAPOL_PWK_HSK_RETRIES_TLV_ID :
pwk_retries_tlv =
( tlvbuf_eapol_pwk_hsk_retries * ) pcurrent_tlv ;
pwk_retries_tlv - > pwk_retries =
uap_le32_to_cpu ( pwk_retries_tlv - > pwk_retries ) ;
printf ( " Pairwise handshake retries = %d \n " ,
pwk_retries_tlv - > pwk_retries ) ;
break ;
case MRVL_EAPOL_GWK_HSK_TIMEOUT_TLV_ID :
gwk_timeout_tlv =
( tlvbuf_eapol_gwk_hsk_timeout * ) pcurrent_tlv ;
gwk_timeout_tlv - > groupwise_update_timeout =
uap_le32_to_cpu ( gwk_timeout_tlv - >
groupwise_update_timeout ) ;
printf ( " Groupwise handshake timeout = %d \n " ,
gwk_timeout_tlv - > groupwise_update_timeout ) ;
break ;
case MRVL_EAPOL_GWK_HSK_RETRIES_TLV_ID :
gwk_retries_tlv =
( tlvbuf_eapol_gwk_hsk_retries * ) pcurrent_tlv ;
gwk_retries_tlv - > gwk_retries =
uap_le32_to_cpu ( gwk_retries_tlv - > gwk_retries ) ;
printf ( " Groupwise handshake retries = %d \n " ,
gwk_retries_tlv - > gwk_retries ) ;
break ;
case MRVL_MGMT_IE_LIST_TLV_ID :
custom_ie_tlv = ( tlvbuf_custom_ie * ) pcurrent_tlv ;
custom_ie_len = tlv_len ;
custom_ie_ptr = ( custom_ie * ) ( custom_ie_tlv - > ie_data ) ;
while ( custom_ie_len > = sizeof ( custom_ie ) ) {
custom_ie_ptr - > ie_index =
uap_le16_to_cpu ( custom_ie_ptr - >
ie_index ) ;
custom_ie_ptr - > ie_length =
uap_le16_to_cpu ( custom_ie_ptr - >
ie_length ) ;
custom_ie_ptr - > mgmt_subtype_mask =
uap_le16_to_cpu ( custom_ie_ptr - >
mgmt_subtype_mask ) ;
printf ( " Index [%d] \n " , custom_ie_ptr - > ie_index ) ;
if ( custom_ie_ptr - > ie_length )
printf ( " Management Subtype Mask = 0x%02x \n " , custom_ie_ptr - > mgmt_subtype_mask = = 0 ? UAP_CUSTOM_IE_AUTO_MASK : custom_ie_ptr - > mgmt_subtype_mask ) ;
else
printf ( " Management Subtype Mask = 0x%02x \n " , custom_ie_ptr - > mgmt_subtype_mask ) ;
hexdump_data ( " IE Buffer " ,
( void * ) custom_ie_ptr - > ie_buffer ,
( custom_ie_ptr - > ie_length ) , ' ' ) ;
custom_ie_len - =
sizeof ( custom_ie ) +
custom_ie_ptr - > ie_length ;
custom_ie_ptr =
( custom_ie * ) ( ( t_u8 * ) custom_ie_ptr +
sizeof ( custom_ie ) +
custom_ie_ptr - > ie_length ) ;
}
custom_ie_present = 1 ;
break ;
case MRVL_MAX_MGMT_IE_TLV_ID :
max_mgmt_ie_tlv = ( tlvbuf_max_mgmt_ie * ) pcurrent_tlv ;
max_mgmt_ie_tlv - > count =
uap_le16_to_cpu ( max_mgmt_ie_tlv - > count ) ;
for ( i = 0 ; i < max_mgmt_ie_tlv - > count ; i + + ) {
max_mgmt_ie_tlv - > info [ i ] . buf_size =
uap_le16_to_cpu ( max_mgmt_ie_tlv - >
info [ i ] . buf_size ) ;
max_mgmt_ie_tlv - > info [ i ] . buf_count =
uap_le16_to_cpu ( max_mgmt_ie_tlv - >
info [ i ] . buf_count ) ;
printf ( " buf%d_size = %d \n " , i ,
max_mgmt_ie_tlv - > info [ i ] . buf_size ) ;
printf ( " number of buffers = %d \n " ,
max_mgmt_ie_tlv - > info [ i ] . buf_count ) ;
printf ( " \n " ) ;
}
max_mgmt_ie_print = 1 ;
break ;
case MRVL_BT_COEX_COMMON_CFG_TLV_ID :
printf ( " Coex common configuration: \n " ) ;
coex_common_tlv =
( tlvbuf_coex_common_cfg * ) pcurrent_tlv ;
printf ( " \t Config Bitmap = 0x%02x \n " ,
uap_le32_to_cpu ( coex_common_tlv - > config_bitmap ) ) ;
printf ( " \t AP Coex Enabled = %d \n " ,
uap_le32_to_cpu ( coex_common_tlv - > ap_bt_coex ) ) ;
break ;
case MRVL_BT_COEX_SCO_CFG_TLV_ID :
printf ( " Coex sco configuration: \n " ) ;
coex_sco_tlv = ( tlvbuf_coex_sco_cfg * ) pcurrent_tlv ;
for ( i = 0 ; i < 4 ; i + + )
printf ( " \t Qtime protection [%d] = %d usecs \n " ,
i ,
uap_le16_to_cpu ( coex_sco_tlv - >
protection_qtime [ i ] ) ) ;
printf ( " \t Protection frame rate = %d \n " ,
uap_le16_to_cpu ( coex_sco_tlv - > protection_rate ) ) ;
printf ( " \t ACL frequency = %d \n " ,
uap_le16_to_cpu ( coex_sco_tlv - > acl_frequency ) ) ;
break ;
case MRVL_BT_COEX_ACL_CFG_TLV_ID :
printf ( " Coex acl configuration: " ) ;
coex_acl_tlv = ( tlvbuf_coex_acl_cfg * ) pcurrent_tlv ;
coex_acl_tlv - > enabled =
uap_le16_to_cpu ( coex_acl_tlv - > enabled ) ;
printf ( " %s \n " ,
( coex_acl_tlv - >
enabled ) ? " enabled " : " disabled " ) ;
if ( coex_acl_tlv - > enabled ) {
printf ( " \t BT time = %d usecs \n " ,
uap_le16_to_cpu ( coex_acl_tlv - > bt_time ) ) ;
printf ( " \t WLan time = %d usecs \n " ,
uap_le16_to_cpu ( coex_acl_tlv - >
wlan_time ) ) ;
printf ( " \t Protection frame rate = %d \n " ,
uap_le16_to_cpu ( coex_acl_tlv - >
protection_rate ) ) ;
}
break ;
case MRVL_BT_COEX_STATS_TLV_ID :
printf ( " Coex statistics: \n " ) ;
coex_stats_tlv = ( tlvbuf_coex_stats * ) pcurrent_tlv ;
printf ( " \t Null not sent = %d \n " ,
uap_le32_to_cpu ( coex_stats_tlv - > null_not_sent ) ) ;
printf ( " \t Null queued = %d \n " ,
uap_le32_to_cpu ( coex_stats_tlv - > null_queued ) ) ;
printf ( " \t Null not queued = %d \n " ,
uap_le32_to_cpu ( coex_stats_tlv - >
null_not_queued ) ) ;
printf ( " \t CF End queued = %d \n " ,
uap_le32_to_cpu ( coex_stats_tlv - > cf_end_queued ) ) ;
printf ( " \t CF End not queued = %d \n " ,
uap_le32_to_cpu ( coex_stats_tlv - >
cf_end_not_queued ) ) ;
printf ( " \t Null allocation failures = %d \n " ,
uap_le32_to_cpu ( coex_stats_tlv - >
null_alloc_fail ) ) ;
printf ( " \t CF End allocation failures = %d \n " ,
uap_le32_to_cpu ( coex_stats_tlv - >
cf_end_alloc_fail ) ) ;
break ;
case HT_CAPABILITY_TLV_ID :
printf ( " \n HT Capability Info: \n " ) ;
ht_cap_tlv = ( tlvbuf_htcap_t * ) pcurrent_tlv ;
if ( ! ht_cap_tlv - > ht_cap . supported_mcs_set [ 0 ] ) {
printf ( " 802.11n is disabled \n " ) ;
} else {
printf ( " 802.11n is enabled \n " ) ;
printf ( " ht_cap_info=0x%x, ampdu_param=0x%x tx_bf_cap=%#x \n " , uap_le16_to_cpu ( ht_cap_tlv - > ht_cap . ht_cap_info ) , ht_cap_tlv - > ht_cap . ampdu_param , uap_le32_to_cpu ( ht_cap_tlv - > ht_cap . tx_bf_cap ) ) ;
printf ( " supported MCS set: \n " ) ;
for ( i = 0 ; i < MCS_SET_LEN ; i + + ) {
printf ( " 0x%x " ,
ht_cap_tlv - > ht_cap .
supported_mcs_set [ i ] ) ;
}
printf ( " \n " ) ;
}
break ;
case HT_INFO_TLV_ID :
ht_info_tlv = ( tlvbuf_htinfo_t * ) pcurrent_tlv ;
if ( ht_info_tlv - > length ) {
printf ( " \n HT Information Element: \n " ) ;
printf ( " Primary channel = %d \n " ,
ht_info_tlv - > ht_info . pri_chan ) ;
printf ( " Secondary channel offset = %d \n " ,
( int ) GET_SECONDARY_CHAN ( ht_info_tlv - >
ht_info . field2 ) ) ;
printf ( " STA channel width = %dMHz \n " ,
IS_CHANNEL_WIDTH_40 ( ht_info_tlv - > ht_info .
field2 ) ? 40 : 20 ) ;
printf ( " RIFS %s \n " ,
IS_RIFS_ALLOWED ( ht_info_tlv - > ht_info .
field2 ) ? " Allowed " :
" Prohibited " ) ;
ht_info_tlv - > ht_info . field3 =
uap_le16_to_cpu ( ht_info_tlv - > ht_info .
field3 ) ;
ht_info_tlv - > ht_info . field4 =
uap_le16_to_cpu ( ht_info_tlv - > ht_info .
field4 ) ;
printf ( " HT Protection = %d \n " ,
( int ) GET_HT_PROTECTION ( ht_info_tlv - >
ht_info . field3 ) ) ;
printf ( " Non-Greenfield HT STAs present: %s \n " ,
NONGF_STA_PRESENT ( ht_info_tlv - > ht_info .
field3 ) ? " Yes " :
" No " ) ;
printf ( " OBSS Non-HT STAs present: %s \n " ,
OBSS_NONHT_STA_PRESENT ( ht_info_tlv - >
ht_info .
field3 ) ? " Yes " :
" No " ) ;
for ( i = 0 ; i < MCS_SET_LEN ; i + + ) {
if ( ht_info_tlv - > ht_info .
basic_mcs_set [ i ] ) {
printf ( " Basic_mcs_set: \n " ) ;
flag = 1 ;
break ;
}
}
if ( flag ) {
for ( i = 0 ; i < MCS_SET_LEN ; i + + )
printf ( " %x " ,
ht_info_tlv - > ht_info .
basic_mcs_set [ i ] ) ;
printf ( " \n " ) ;
}
}
break ;
case MRVL_2040_BSS_COEX_CONTROL_TLV_ID :
coex_2040_tlv = ( tlvbuf_2040_coex * ) pcurrent_tlv ;
printf ( " 20/40 coex = %s \n " ,
( coex_2040_tlv - >
enable ) ? " enabled " : " disabled " ) ;
break ;
case VENDOR_SPECIFIC_IE_TLV_ID :
wmm_para_tlv = ( tlvbuf_wmm_para_t * ) pcurrent_tlv ;
printf ( " wmm parameters: \n " ) ;
printf ( " \t qos_info = 0x%x \n " ,
wmm_para_tlv - > wmm_para . qos_info ) ;
printf ( " \t BE: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d \n " ,
wmm_para_tlv - > wmm_para . ac_params [ AC_BE ] .
aci_aifsn . aifsn ,
wmm_para_tlv - > wmm_para . ac_params [ AC_BE ] . ecw .
ecw_max ,
wmm_para_tlv - > wmm_para . ac_params [ AC_BE ] . ecw .
ecw_min ,
uap_le16_to_cpu ( wmm_para_tlv - > wmm_para .
ac_params [ AC_BE ] . tx_op_limit ) ) ;
printf ( " \t BK: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d \n " ,
wmm_para_tlv - > wmm_para . ac_params [ AC_BK ] .
aci_aifsn . aifsn ,
wmm_para_tlv - > wmm_para . ac_params [ AC_BK ] . ecw .
ecw_max ,
wmm_para_tlv - > wmm_para . ac_params [ AC_BK ] . ecw .
ecw_min ,
uap_le16_to_cpu ( wmm_para_tlv - > wmm_para .
ac_params [ AC_BK ] . tx_op_limit ) ) ;
printf ( " \t VI: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d \n " ,
wmm_para_tlv - > wmm_para . ac_params [ AC_VI ] .
aci_aifsn . aifsn ,
wmm_para_tlv - > wmm_para . ac_params [ AC_VI ] . ecw .
ecw_max ,
wmm_para_tlv - > wmm_para . ac_params [ AC_VI ] . ecw .
ecw_min ,
uap_le16_to_cpu ( wmm_para_tlv - > wmm_para .
ac_params [ AC_VI ] . tx_op_limit ) ) ;
printf ( " \t VO: AIFSN=%d, CW_MAX=%d CW_MIN=%d, TXOP=%d \n " ,
wmm_para_tlv - > wmm_para . ac_params [ AC_VO ] .
aci_aifsn . aifsn ,
wmm_para_tlv - > wmm_para . ac_params [ AC_VO ] . ecw .
ecw_max ,
wmm_para_tlv - > wmm_para . ac_params [ AC_VO ] . ecw .
ecw_min ,
uap_le16_to_cpu ( wmm_para_tlv - > wmm_para .
ac_params [ AC_VO ] . tx_op_limit ) ) ;
break ;
# ifdef RX_PACKET_COALESCE
case MRVL_RX_PKT_COAL_TLV_ID :
rx_pkt_coal_tlv = ( tlvbuf_rx_pkt_coal_t * ) pcurrent_tlv ;
printf ( " RX packet coalesce threshold=%d \n " ,
uap_le32_to_cpu ( rx_pkt_coal_tlv - > rx_pkt_count ) ) ;
printf ( " RX packet coalesce timeout in msec=%d \n " ,
uap_le16_to_cpu ( rx_pkt_coal_tlv - > delay ) ) ;
break ;
# endif
default :
break ;
}
tlv_buf_left - = ( sizeof ( tlvbuf_header ) + tlv_len ) ;
pcurrent_tlv = ( tlvbuf_header * ) ( pcurrent_tlv - > data + tlv_len ) ;
}
return ;
}
/**
* @ brief Checks if command requires driver handling , and if so ,
* repackage and send as regular command , instead of hostcmd .
*
* @ param cmd Pointer to the command buffer
* @ param size Pointer to the command size . This value is
* overwritten by the function with the size of the
* received response .
* @ param buf_size Size of the allocated command buffer
* @ param reroute_ret Pointer to return value of rerouted command
* @ return UAP_SUCCESS ( handled here , further processing not needed )
* or UAP_FAILURE ( not handled here , proceed as usual )
*/
static int
uap_ioctl_reroute ( t_u8 * cmd , t_u16 * size , t_u16 buf_size , int * reroute_ret )
{
t_u8 reroute = 0 ;
t_u16 cmd_code = 0 ;
t_u16 cmd_action = 0 ;
apcmdbuf_cfg_80211d * hcmd_domain = NULL ;
apcmdbuf_snmp_mib * hcmd_snmp = NULL ;
tlvbuf_header * tlv = NULL ;
struct ifreq ifr ;
t_s32 sockfd ;
t_u8 * buf = NULL ;
t_u16 buf_len = 0 ;
snmp_mib_param * snmp_param = NULL ;
domain_info_param * domain_param = NULL ;
/* assume input is a hostcmd */
cmd_code = ( ( apcmdbuf * ) ( cmd ) ) - > cmd_code ;
/* just check if we need to re-route right now */
switch ( cmd_code ) {
case HostCmd_SNMP_MIB :
hcmd_snmp = ( apcmdbuf_snmp_mib * ) cmd ;
tlv = ( tlvbuf_header * ) ( cmd + sizeof ( apcmdbuf_snmp_mib ) ) ;
cmd_action = uap_le16_to_cpu ( hcmd_snmp - > action ) ;
/* reroute CMD_SNMP_MIB: SET */
if ( cmd_action = = ACTION_SET ) {
reroute = 1 ;
buf_len =
sizeof ( snmp_mib_param ) +
uap_le16_to_cpu ( tlv - > len ) ;
}
break ;
case HostCmd_CMD_802_11D_DOMAIN_INFO :
hcmd_domain = ( apcmdbuf_cfg_80211d * ) cmd ;
cmd_action = uap_le16_to_cpu ( hcmd_domain - > action ) ;
/* reroute CMD_DOMAIN_INFO: SET */
if ( cmd_action = = ACTION_SET ) {
reroute = 1 ;
buf_len = sizeof ( domain_info_param ) + ( * size
-
sizeof
( apcmdbuf_cfg_80211d )
+
sizeof
( domain_param_t ) ) ;
}
break ;
}
/* Exit early if not re-routing */
if ( ! reroute | | uap_ioctl_no_reroute )
return UAP_FAILURE ;
/* Prepare buffer */
# if DEBUG
uap_printf ( MSG_DEBUG , " DBG: rerouting CMD 0x%04x \n " , cmd_code ) ;
# endif
buf = ( t_u8 * ) malloc ( buf_len ) ;
if ( ! buf ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
goto done_no_socket ;
}
memset ( buf , 0 , buf_len ) ;
/* Prepare param */
switch ( cmd_code ) {
case HostCmd_SNMP_MIB :
snmp_param = ( snmp_mib_param * ) buf ;
snmp_param - > subcmd = UAP_SNMP_MIB ;
snmp_param - > action = cmd_action ;
snmp_param - > oid = uap_le16_to_cpu ( tlv - > type ) ;
snmp_param - > oid_val_len = uap_le16_to_cpu ( tlv - > len ) ;
memcpy ( snmp_param - > oid_value , tlv - > data ,
MIN ( sizeof ( t_u32 ) , snmp_param - > oid_val_len ) ) ;
break ;
case HostCmd_CMD_802_11D_DOMAIN_INFO :
domain_param = ( domain_info_param * ) buf ;
domain_param - > subcmd = UAP_DOMAIN_INFO ;
domain_param - > action = cmd_action ;
memcpy ( domain_param - > tlv , & hcmd_domain - > domain ,
buf_len - sizeof ( domain_info_param ) ) ;
tlv = ( tlvbuf_header * ) domain_param - > tlv ;
tlv - > type = uap_le16_to_cpu ( tlv - > type ) ;
tlv - > len = uap_le16_to_cpu ( tlv - > len ) ;
break ;
}
# if DEBUG
/* Dump request buffer */
hexdump ( " Reroute Request buffer " , buf , buf_len , ' ' ) ;
# endif
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
goto done_no_socket ;
}
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) buf ;
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , UAP_IOCTL_CMD , & ifr ) ) {
* reroute_ret = UAP_FAILURE ;
perror ( " " ) ;
# if DEBUG
uap_printf ( MSG_DEBUG , " ERR: reroute of CMD 0x%04x failed \n " ,
cmd_code ) ;
# endif
goto done ;
}
* reroute_ret = UAP_SUCCESS ;
done :
/* Close socket */
close ( sockfd ) ;
done_no_socket :
if ( buf )
free ( buf ) ;
return UAP_SUCCESS ;
}
/**
* @ brief Performs the ioctl operation to send the command to
* the driver .
*
* @ param cmd Pointer to the command buffer
* @ param size Pointer to the command size . This value is
* overwritten by the function with the size of the
* received response .
* @ param buf_size Size of the allocated command buffer
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
uap_ioctl ( t_u8 * cmd , t_u16 * size , t_u16 buf_size )
{
struct ifreq ifr ;
apcmdbuf * header = NULL ;
t_s32 sockfd ;
int reroute_ret = 0 ;
mrvl_priv_cmd * mrvl_cmd = NULL ;
t_u8 * buf = NULL , * temp = NULL ;
t_u16 mrvl_header_len = 0 ;
int ret = UAP_SUCCESS ;
# ifdef WIFI_DIRECT_SUPPORT
if ( strncmp ( dev_name , " wfd " , 3 ) )
# endif
if ( uap_ioctl_reroute ( cmd , size , buf_size , & reroute_ret ) = =
UAP_SUCCESS ) {
return reroute_ret ;
}
if ( buf_size < * size ) {
printf ( " buf_size should not less than cmd buffer size \n " ) ;
return UAP_FAILURE ;
}
/* Open socket */
if ( ( sockfd = socket ( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
printf ( " ERR:Cannot open socket \n " ) ;
return UAP_FAILURE ;
}
* ( t_u32 * ) cmd = buf_size - BUF_HEADER_SIZE ;
mrvl_header_len = strlen ( CMD_NXP ) + strlen ( PRIV_CMD_HOSTCMD ) ;
buf = ( unsigned char * ) malloc ( buf_size + sizeof ( mrvl_priv_cmd ) +
mrvl_header_len ) ;
if ( buf = = NULL ) {
close ( sockfd ) ;
return UAP_FAILURE ;
}
memset ( buf , 0 , buf_size + sizeof ( mrvl_priv_cmd ) + mrvl_header_len ) ;
/* Fill up buffer */
mrvl_cmd = ( mrvl_priv_cmd * ) buf ;
mrvl_cmd - > buf = buf + sizeof ( mrvl_priv_cmd ) ;
mrvl_cmd - > used_len = 0 ;
mrvl_cmd - > total_len = buf_size + mrvl_header_len ;
/* Copy NXP command string */
temp = mrvl_cmd - > buf ;
strncpy ( ( char * ) temp , CMD_NXP , strlen ( CMD_NXP ) ) ;
temp + = ( strlen ( CMD_NXP ) ) ;
/* Insert command string */
strncpy ( ( char * ) temp , PRIV_CMD_HOSTCMD , strlen ( PRIV_CMD_HOSTCMD ) ) ;
temp + = ( strlen ( PRIV_CMD_HOSTCMD ) ) ;
memcpy ( temp , ( t_u8 * ) cmd , * size ) ;
/* Initialize the ifr structure */
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
strncpy ( ifr . ifr_ifrn . ifrn_name , dev_name , IFNAMSIZ - 1 ) ;
ifr . ifr_ifru . ifru_data = ( void * ) mrvl_cmd ;
header = ( apcmdbuf * ) ( buf + sizeof ( mrvl_priv_cmd ) + mrvl_header_len ) ;
header - > size = * size - BUF_HEADER_SIZE ;
if ( header - > cmd_code = = APCMD_SYS_CONFIGURE ) {
apcmdbuf_sys_configure * sys_cfg ;
sys_cfg = ( apcmdbuf_sys_configure * ) header ;
sys_cfg - > action = uap_cpu_to_le16 ( sys_cfg - > action ) ;
}
endian_convert_request_header ( header ) ;
# if DEBUG
/* Dump request buffer */
hexdump ( " Request buffer " , mrvl_cmd ,
* size + sizeof ( mrvl_priv_cmd ) + mrvl_header_len , ' ' ) ;
# endif
/* Perform ioctl */
errno = 0 ;
if ( ioctl ( sockfd , MRVLPRIVCMD , & ifr ) ) {
perror ( " " ) ;
printf ( " ERR:MRVLPRIVCMD is not supported by %s \n " , dev_name ) ;
ret = UAP_FAILURE ;
goto done ;
}
endian_convert_response_header ( header ) ;
header - > cmd_code & = HostCmd_CMD_ID_MASK ;
header - > cmd_code | = APCMD_RESP_CHECK ;
* size = header - > size ;
/* Validate response size */
if ( * size > ( buf_size - BUF_HEADER_SIZE ) ) {
printf ( " ERR:Response size (%d) greater than buffer size (%d)! Aborting! \n " , * size , buf_size ) ;
ret = UAP_FAILURE ;
goto done ;
}
memcpy ( cmd , ( t_u8 * ) header , * size + BUF_HEADER_SIZE ) ;
# if DEBUG
/* Dump respond buffer */
hexdump ( " Respond buffer " , mrvl_cmd ,
* size + BUF_HEADER_SIZE + sizeof ( mrvl_priv_cmd ) +
mrvl_header_len , ' ' ) ;
# endif
done :
/* Close socket */
close ( sockfd ) ;
if ( buf )
free ( buf ) ;
return ret ;
}
/**
* @ brief Get protocol from the firmware
*
* @ param proto A pointer to protocol var
* @ return UAP_SUCCESS / UAP_FAILURE
*/
int
get_sys_cfg_protocol ( t_u16 * proto )
{
apcmdbuf_sys_configure * cmd_buf = NULL ;
tlvbuf_protocol * tlv = NULL ;
t_u8 * buffer = NULL ;
t_u16 cmd_len ;
int ret = UAP_FAILURE ;
cmd_len = sizeof ( apcmdbuf_sys_configure ) + sizeof ( tlvbuf_protocol ) ;
/* Initialize the command buffer */
buffer = ( t_u8 * ) malloc ( cmd_len ) ;
if ( ! buffer ) {
printf ( " ERR:Cannot allocate buffer for command! \n " ) ;
return ret ;
}
memset ( buffer , 0 , cmd_len ) ;
/* Locate headers */
cmd_buf = ( apcmdbuf_sys_configure * ) buffer ;
tlv = ( tlvbuf_protocol * ) ( buffer + sizeof ( apcmdbuf_sys_configure ) ) ;
/* Fill the command buffer */
cmd_buf - > cmd_code = APCMD_SYS_CONFIGURE ;
cmd_buf - > size = cmd_len ;
cmd_buf - > seq_num = 0 ;
cmd_buf - > result = 0 ;
cmd_buf - > action = ACTION_GET ;
tlv - > tag = MRVL_PROTOCOL_TLV_ID ;
tlv - > length = 2 ;
endian_convert_tlv_header_out ( tlv ) ;
/* Send the command */
ret = uap_ioctl ( ( t_u8 * ) cmd_buf , & cmd_len , cmd_len ) ;
endian_convert_tlv_header_in ( tlv ) ;
/* Process response */
if ( ret = = UAP_SUCCESS ) {
/* Verify response */
if ( cmd_buf - > cmd_code ! =
( APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK ) ) {
printf ( " ERR:Corrupted response! cmd_code=%x, Tlv->tag=%x \n " , cmd_buf - > cmd_code , tlv - > tag ) ;
free ( buffer ) ;
return UAP_FAILURE ;
}
if ( cmd_buf - > result = = CMD_SUCCESS ) {
tlv - > protocol = uap_le16_to_cpu ( tlv - > protocol ) ;
memcpy ( proto , & tlv - > protocol , sizeof ( tlv - > protocol ) ) ;
} else {
ret = UAP_FAILURE ;
}
}
if ( buffer )
free ( buffer ) ;
return ret ;
}
/**
* @ brief Check cipher is valid or not
*
* @ param pairwisecipher Pairwise cipher
* @ param groupcipher Group cipher
* @ param protocol Protocol
* @ param enable_11n 11 n enabled or not .
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
is_cipher_valid_with_11n ( int pairwisecipher , int groupcipher ,
int protocol , int enable_11n )
{
if ( ( pairwisecipher = = CIPHER_NONE ) & & ( groupcipher = = CIPHER_NONE ) )
return UAP_SUCCESS ;
if ( pairwisecipher = = CIPHER_TKIP ) {
/* Ok to have TKIP in mixed mode */
if ( enable_11n & & protocol ! = PROTOCOL_WPA2_MIXED ) {
printf ( " ERR: WPA/TKIP cannot be used when AP operates in 802.11n mode. \n " ) ;
return UAP_FAILURE ;
}
}
if ( ( pairwisecipher = = CIPHER_TKIP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_AES_CCMP ) & &
( groupcipher = = CIPHER_AES_CCMP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_AES_CCMP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_BITMAP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
return UAP_FAILURE ;
}
/**
* @ brief Check cipher is valid or not based on proto
*
* @ param pairwisecipher Pairwise cipher
* @ param groupcipher Group cipher
* @ param protocol Protocol
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
is_cipher_valid_with_proto ( int pairwisecipher , int groupcipher , int protocol )
{
HTCap_t htcap ;
if ( ( pairwisecipher = = CIPHER_NONE ) & & ( groupcipher = = CIPHER_NONE ) )
return UAP_SUCCESS ;
if ( pairwisecipher = = CIPHER_TKIP ) {
/* Ok to have TKIP in mixed mode */
if ( protocol ! = PROTOCOL_WPA2_MIXED ) {
memset ( & htcap , 0 , sizeof ( htcap ) ) ;
if ( UAP_SUCCESS = = get_sys_cfg_11n ( & htcap ) ) {
if ( htcap . supported_mcs_set [ 0 ] ) {
printf ( " ERR: WPA/TKIP cannot be used when AP operates in 802.11n mode. \n " ) ;
return UAP_FAILURE ;
}
}
}
}
if ( ( pairwisecipher = = CIPHER_TKIP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_AES_CCMP ) & &
( groupcipher = = CIPHER_AES_CCMP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_AES_CCMP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_BITMAP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
return UAP_FAILURE ;
}
/**
* @ brief Check cipher is valid or not
*
* @ param pairwisecipher Pairwise cipher
* @ param groupcipher Group cipher
* @ return UAP_SUCCESS or UAP_FAILURE
*/
int
is_cipher_valid ( int pairwisecipher , int groupcipher )
{
HTCap_t htcap ;
t_u16 proto = 0 ;
if ( ( pairwisecipher = = CIPHER_NONE ) & & ( groupcipher = = CIPHER_NONE ) )
return UAP_SUCCESS ;
if ( pairwisecipher = = CIPHER_TKIP ) {
if ( UAP_SUCCESS = = get_sys_cfg_protocol ( & proto ) ) {
/* Ok to have TKIP in mixed mode */
if ( proto ! = PROTOCOL_WPA2_MIXED ) {
memset ( & htcap , 0 , sizeof ( htcap ) ) ;
if ( UAP_SUCCESS = = get_sys_cfg_11n ( & htcap ) ) {
if ( htcap . supported_mcs_set [ 0 ] ) {
printf ( " ERR: WPA/TKIP cannot be used when AP operates in 802.11n mode. \n " ) ;
return UAP_FAILURE ;
}
}
}
}
}
if ( ( pairwisecipher = = CIPHER_TKIP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_AES_CCMP ) & &
( groupcipher = = CIPHER_AES_CCMP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_AES_CCMP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
if ( ( pairwisecipher = = CIPHER_BITMAP ) & & ( groupcipher = = CIPHER_TKIP ) )
return UAP_SUCCESS ;
return UAP_FAILURE ;
}
/**
* @ brief The main function
*
* @ param argc Number of arguments
* @ param argv Pointer to the arguments
* @ return 0 or 1
*/
int
main ( int argc , char * argv [ ] )
{
int opt , i ;
int ret = 0 ;
memset ( dev_name , 0 , sizeof ( dev_name ) ) ;
strcpy ( dev_name , DEFAULT_DEV_NAME ) ;
/* Parse arguments */
while ( ( opt =
getopt_long ( argc , argv , " +hi:d:v " , ap_options , NULL ) ) ! = - 1 ) {
switch ( opt ) {
case ' i ' :
if ( strlen ( optarg ) < IFNAMSIZ ) {
memset ( dev_name , 0 , sizeof ( dev_name ) ) ;
strncpy ( dev_name , optarg , strlen ( optarg ) ) ;
}
printf ( " dev_name:%s \n " , dev_name ) ;
break ;
case ' v ' :
printf ( " uaputl.exe - uAP utility ver %s \n " ,
UAP_VERSION ) ;
exit ( 0 ) ;
case ' d ' :
debug_level = strtoul ( optarg , NULL , 10 ) ;
# if DEBUG
uap_printf ( MSG_DEBUG , " debug_level=%x \n " , debug_level ) ;
# endif
break ;
case ' h ' :
default :
print_tool_usage ( ) ;
exit ( 0 ) ;
}
}
argc - = optind ;
argv + = optind ;
optind = 0 ;
if ( argc < 1 ) {
print_tool_usage ( ) ;
exit ( 1 ) ;
}
/* Process command */
for ( i = 0 ; ap_command [ i ] . cmd ; i + + ) {
if ( strncmp
( ap_command [ i ] . cmd , argv [ 0 ] , strlen ( ap_command [ i ] . cmd ) ) )
continue ;
if ( strlen ( ap_command [ i ] . cmd ) ! = strlen ( argv [ 0 ] ) )
continue ;
ret = ap_command [ i ] . func ( argc , argv ) ;
break ;
}
if ( ! ap_command [ i ] . cmd ) {
printf ( " ERR: %s is not supported \n " , argv [ 0 ] ) ;
exit ( 1 ) ;
}
if ( ret = = UAP_FAILURE )
return - 1 ;
else
return 0 ;
}