📄 wlan_config.c
字号:
/*
* File : wlanconfig.c
*
* Program to configure addition paramters into the wlan driver
*
* Usage:
*
* wlanconfig <ethX> <cmd> [...]
*/
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <linux/if.h>
#include <sys/ioctl.h>
#include <linux/wireless.h>
#include <linux/if_ether.h>
#include <linux/byteorder/swab.h>
#ifdef EXTSCAN
#include "wlan_config.h"
#endif
#ifdef BYTE_SWAP
#define cpu_to_le16(x) __swab16(x)
#else
#define cpu_to_le16(x) (x)
#endif
/* TODO These defenitions need to moved to one file, as these should
* be visible to wlan_config.c
*/
#ifndef __ATTRIB_ALIGN__
#define __ATTRIB_ALIGN__ __attribute__((aligned(4)))
#endif
#ifndef __ATTRIB_PACK__
#define __ATTRIB_PACK__ __attribute__((packed))
#endif
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#include "wlan_defs.h"
#include "wlan_types.h"
#include "host.h"
#ifdef WMM
#include "wlan_wmm.h"
#endif
#include "hostcmd.h"
#include "wlan_wext.h"
#ifdef DEBUG
#define PRINTF printf
#else
#define PRINTF(...)
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif /* MIN */
enum COMMANDS {
CMD_RDMAC,
CMD_WRMAC,
CMD_RDBBP,
CMD_WRBBP,
CMD_RDRF,
CMD_WRRF,
CMD_RDBCA,
CMD_WRBCA,
CMD_RDEEPROM,
/* TODO: Move these as low-level driver ioctl calls */
CMD_CMD52R,
CMD_CMD52W,
CMD_CMD53R,
CMD_CMD53W,
#ifdef SUBSCRIBE_EVENT_CTRL
CMD_SUB_EVENT,
#endif
#ifdef BG_SCAN
CMD_BG_SCAN_CONFIG,
#endif
#ifdef WMM
CMD_WMM_TSPEC,
CMD_WMM_ACK_POLICY,
CMD_WMM_AC_WPAIE,
#endif /* WMM */
#ifdef CAL_DATA
CMD_CAL_DATA,
CMD_CAL_DATA_EXT,
#endif
CMD_CFREGR,
CMD_CFREGW,
CMD_GETRATE,
CMD_SLEEPPARAMS,
CMD_BCA,
CMD_REQUESTTPC,
CMD_BCA_TS,
CMD_SCAN_BSSID,
CMD_SETADHOCCH,
CMD_GETADHOCCH,
CMD_REASSOCIATE,
#ifdef EXTSCAN
CMD_EXTSCAN,
CMD_SCAN_LIST,
#endif
};
static char *commands[] = {
"rdmac",
"wrmac",
"rdbbp",
"wrbbp",
"rdrf",
"wrrf",
"rdbca",
"wrbca",
"rdeeprom",
"sdcmd52r",
"sdcmd52w",
"sdcmd53r",
"sdcmd53w",
#ifdef SUBSCRIBE_EVENT_CTRL
"subevent",
#endif
#ifdef BG_SCAN
"bgscanconfig",
#endif
#ifdef WMM
"wmmtspec",
"wmm_ack_policy",
"wmmparaie",
#endif /* WMM */
#ifdef CAL_DATA
"caldata",
"caldataext",
#endif
"rdcfreg",
"wrcfreg",
"getrate",
"sleepparams",
"bca",
"requesttpc",
"bca-ts",
"scanbssid",
"setadhocch",
"getadhocch",
"reassociate",
#ifdef EXTSCAN
"extscan",
"getscanlist",
#endif
};
#define MAX_COMMANDS (sizeof(commands)/sizeof(commands[0]))
enum SUB_CMDS {
SUBCMD_MODE,
SUBCMD_ANTENNA,
SUBCMD_BTFREQ,
SUBCMD_TXPRIORITYLOW32,
SUBCMD_TXPRIORITYHIGH32,
SUBCMD_RXPRIORITYLOW32,
SUBCMD_RXPRIORITYHIGH32,
};
static char *sub_cmds[] = {
"mode",
"antenna",
"btfreq",
"txprioritylow32",
"txpriorityhigh32",
"rxprioritylow32",
"rxpriorityhigh32",
};
#define MAX_SUBCOMMANDS (sizeof(sub_cmds)/sizeof(sub_cmds[0]))
#ifdef SUBSCRIBE_EVENT_CTRL
int sub_event_parse_action(EventSubscribe *EventData, int line, char *value);
int sub_event_parse_event(EventSubscribe *EventData, int line, char *value);
int sub_event_parse_RSSI(EventSubscribe *EventData, int line, char *value);
int sub_event_parse_SNR(EventSubscribe *EventData, int line, char *value);
int sub_event_parse_failcnt(EventSubscribe *EventData, int line, char *value);
int sub_event_parse_beacon_missed(EventSubscribe *EventData, int line, char *value);
static struct sub_event_fields {
char *name;
int (*parser)(EventSubscribe *EventData, int line, char *value);
} sub_event_fields[] = {
{ "Action", sub_event_parse_action },
{ "Event", sub_event_parse_event },
{ "RSSI", sub_event_parse_RSSI },
{ "SNR", sub_event_parse_SNR },
{ "FailureCount", sub_event_parse_failcnt },
{ "BcnMissed", sub_event_parse_beacon_missed },
};
#define NUM_SUB_EVENT_FIELDS (sizeof(sub_event_fields) / sizeof(sub_event_fields[0]))
#endif
#ifdef BG_SCAN
u16 TLVChanSize;
u16 TLVSsidSize;
u16 TLVProbeSize;
u16 ActualPos = sizeof(HostCmd_DS_802_11_BG_SCAN_CONFIG);
int bgscan_parse_action(u8 *CmdBuf, int line, char *value);
int bgscan_parse_enable(u8 *CmdBuf, int line, char *value);
int bgscan_parse_bsstype(u8 *CmdBuf, int line, char *value);
int bgscan_parse_channelsperscan(u8 *CmdBuf, int line, char *value);
int bgscan_parse_discardwhenfull(u8 *CmdBuf, int line, char *value);
int bgscan_parse_scaninternal(u8 *CmdBuf, int line, char *value);
int bgscan_parse_storecondition(u8 *CmdBuf, int line, char *value);
int bgscan_parse_reportconditions(u8 *CmdBuf, int line, char *value);
int bgscan_parse_maxscanresults(u8 *CmdBuf, int line, char *value);
int bgscan_parse_ssid(u8 *CmdBuf, int line, char *value);
int bgscan_parse_probes(u8 *CmdBuf, int line, char *value);
int bgscan_parse_channellist(u8 *CmdBuf, int line, char *value);
static struct bgscan_fields {
char *name;
int (*parser)(u8 *CmdBuf, int line, char *value);
} bgscan_fields[] = {
{ "Action", bgscan_parse_action },
{ "Enable", bgscan_parse_enable },
{ "BssType", bgscan_parse_bsstype },
{ "ChannelsPerScan", bgscan_parse_channelsperscan },
{ "DiscardWhenFull", bgscan_parse_discardwhenfull },
{ "ScanInternal", bgscan_parse_scaninternal },
{ "StoreCondition", bgscan_parse_storecondition },
{ "ReportConditions", bgscan_parse_reportconditions },
{ "MaxScanResults", bgscan_parse_maxscanresults },
{ "SSID1", bgscan_parse_ssid },
{ "SSID2", bgscan_parse_ssid },
{ "SSID3", bgscan_parse_ssid },
{ "SSID4", bgscan_parse_ssid },
{ "SSID5", bgscan_parse_ssid },
{ "SSID6", bgscan_parse_ssid },
{ "Probes", bgscan_parse_probes },
{ "ChannelList", bgscan_parse_channellist },
};
#define NUM_BGSCAN_FIELDS (sizeof(bgscan_fields) / sizeof(bgscan_fields[0]))
#endif
void display_usage(void);
int findcommand(int maxcmds, char *cmds[], char *cmd);
int process_read_register(int cmd, char *stroffset);
int process_write_register(int cmd, char *stroffset, char *strvalue);
int ascii2hex(unsigned char *d, char *s, uint dlen);
unsigned int a2hex(char *s);
void hexdump(char *prompt, void *p, int len, char delim);
int process_sdcmd52r(int argc, char *argv[]);
int process_sdcmd52w(int argc, char *argv[]);
int process_sdcmd53r(void);
#ifdef CAL_DATA
int process_cal_data(int argc, char *argv[]);
int process_cal_data_ext(int argc, char *argv[]);
#endif
#ifdef SUBSCRIBE_EVENT_CTRL
int process_event_subscribe(int argc, char *argv[]);
#endif
#ifdef BG_SCAN
int process_bg_scan_config(int argc, char *argv[]);
#endif
int fparse_for_hex(FILE *fp, u8 *dst);
int fparse_for_cmd_and_hex(FILE *fp, u8 *dst, u8 *cmd);
int process_adhocencryption_key(int cmd, char *setget, char *key);
int process_write_cfreg(char *stroffset, char *strvalue);
int process_read_cfreg(char *stroffset);
int process_read_eeprom(char *stroffset, char *strnob);
static int sockfd;
static char DevName[IFNAMSIZ + 1];
#define IW_MAX_PRIV_DEF 128
#define IW_PRIV_IOCTL_COUNT (SIOCIWLASTPRIV-SIOCIWFIRSTPRIV+1)
static int Priv_count;
static struct iw_priv_args Priv_args[IW_MAX_PRIV_DEF];
#ifdef WMM
int process_wmm_ack_policy(int argc, char *argv[]);
int process_wmm_para_conf(int argc, char *argv[], int cmd);
#endif /* WMM */
static int get_private_info(const char *ifname)
{
/* This function sends the SIOCGIWPRIV command which is
* handled by the kernel. and gets the total number of
* private ioctl's available in the host driver.
*/
struct iwreq iwr;
int s, ret = 0;
struct iw_priv_args *pPriv = Priv_args ;
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("socket[PF_INET,SOCK_DGRAM]");
return -1;
}
memset(&iwr, 0, sizeof(iwr));
strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
iwr.u.data.pointer = (caddr_t) pPriv;
iwr.u.data.length = IW_MAX_PRIV_DEF;
iwr.u.data.flags = 0;
if (ioctl(s, SIOCGIWPRIV, &iwr) < 0) {
perror("ioctl[SIOCGIWPRIV]");
ret = -1;
} else {
/* Return the number of private ioctls */
ret = iwr.u.data.length;
}
close(s);
return ret;
}
/*
* Add the private commands handled by the host driver
* it can be either subcommand or the main command
*/
static char *priv_ioctl_names[] = {
"getrate",
"sleepparams",
"bca",
"bca-ts",
"scanbssid",
"requesttpc",
"setadhocch",
"getadhocch",
"reassociate",
#ifdef EXTSCAN
"extscan",
"getscanlist",
#endif
};
/*
* These two static array contains the main command number and the
* subcommand number respectively
*/
static int PRIV_IOCTL[sizeof(priv_ioctl_names)/sizeof(priv_ioctl_names[0])];
static int PRIV_SUBIOCTL[sizeof(priv_ioctl_names)/sizeof(priv_ioctl_names[0])];
#define IOCTL_WLANGETRATE PRIV_IOCTL[0]
#define SUBIOCTL_WLANGETRATE PRIV_SUBIOCTL[0]
#define IOCTL_WLANSLEEPPARAMS PRIV_IOCTL[1]
#define SUBIOCTL_WLANSLEEPPARAMS PRIV_SUBIOCTL[1]
#define IOCTL_WLANBCA PRIV_IOCTL[2]
#define SUBIOCTL_WLANBCA PRIV_SUBIOCTL[2]
#define IOCTL_WLANBCA_TS PRIV_IOCTL[3]
#define SUBIOCTL_WLANBCA_TS PRIV_SUBIOCTL[3]
#define IOCTL_WLANSCAN_BSSID PRIV_IOCTL[4]
#define SUBIOCTL_WLANSCAN_BSSID PRIV_SUBIOCTL[4]
#define IOCTL_WLANREQUESTTPC PRIV_IOCTL[5]
#define SUBIOCTL_WLANREQUESTTPC PRIV_SUBIOCTL[5]
#define IOCTL_WLANSETADHOCCH PRIV_IOCTL[6]
#define SUBIOCTL_WLANSETADHOCCH PRIV_SUBIOCTL[6]
#define IOCTL_WLANGETADHOCCH PRIV_IOCTL[7]
#define SUBIOCTL_WLANGETADHOCCH PRIV_SUBIOCTL[7]
#define IOCTL_WLANREASSOCIATE PRIV_IOCTL[8]
#define SUBIOCTL_WLANREASSOCIATE PRIV_SUBIOCTL[8]
#ifdef EXTSCAN
#define IOCTL_WLANEXTSCAN PRIV_IOCTL[9]
#define SUBIOCTL_WLANEXTSCAN PRIV_SUBIOCTL[9]
#define IOCTL_WLANSCAN PRIV_IOCTL[10]
#define SUBIOCTL_WLANSCAN PRIV_SUBIOCTL[10]
#endif
int marvell_get_subioctl_no(int i, int *sub_cmd)
{
int j;
if (Priv_args[i].cmd >= SIOCDEVPRIVATE) {
*sub_cmd = 0;
return Priv_args[i].cmd;
}
j = -1;
/* Find the matching *real* ioctl */
while ((++j < Priv_count) && ((Priv_args[j].name[0] != '\0') ||
(Priv_args[j].set_args != Priv_args[i].set_args) ||
(Priv_args[j].get_args != Priv_args[i].get_args)));
/* If not found... */
if (j == Priv_count) {
printf("%s: Invalid private ioctl definition for: 0x%x\n",
DevName, Priv_args[i].cmd);
return -1;
}
/* TODO handle the case of IW_PRIV_SIZE_FIXED */
/* Save sub-ioctl number */
*sub_cmd = Priv_args[i].cmd;
/* Return the real IOCTL number */
return Priv_args[j].cmd;
}
static int marvell_get_ioctl_no(const char *ifname, const char *priv_cmd,
int *sub_cmd)
{
int i;
/* Are there any private ioctls? */
if (Priv_count <= 0) {
/* Could skip this message ? */
printf("%-8.8s no private ioctls.\n", ifname);
} else {
//printf("%-8.8s Available private ioctl :\n", ifname);
for (i = 0; i < Priv_count; i++) {
if (Priv_args[i].name[0] &&
!strcmp(Priv_args[i].name, priv_cmd)) {
return marvell_get_subioctl_no(i, sub_cmd);
}
}
}
return -1;
}
void marvell_init_ioctl_numbers(const char *ifname)
{
int i;
/* Read the private ioctls */
Priv_count = get_private_info(ifname);
for (i = 0; i < sizeof(priv_ioctl_names)/sizeof(priv_ioctl_names[0]);
i++) {
PRIV_IOCTL[i] = marvell_get_ioctl_no(ifname,
priv_ioctl_names[i], &PRIV_SUBIOCTL[i]);
}
/*
if (IOCTL_WLANEXTSCAN < 0 && IOCTL_WLANSPECIFICSCAN >= SIOCDEVPRIVATE) {
IOCTL_WLANEXTSCAN = IOCTL_WLANSPECIFICSCAN;
SUBIOCTL_WLANEXTSCAN = SUBIOCTL_WLANSPECIFICSCAN;
}
*/
}
#define WLAN_MAX_RATES 14
#define GIGA 1e9
#define MEGA 1e6
#define KILO 1e3
int print_bitrate(double rate, int current, int fixed)
{
char scale = 'k', buf[128];
int divisor = KILO;
if (!current)
rate *= 500000;
if (rate >= GIGA) {
scale = 'G';
divisor = GIGA;
} else if (rate >= MEGA) {
scale = 'M';
divisor = MEGA;
}
snprintf(buf, sizeof(buf), "%g %cb/s", rate/divisor, scale);
if (current) {
printf("\t Current Bit Rate%c%s\n\n",
(fixed) ? '=' : ':', buf);
} else {
printf("\t %s\n", buf);
}
return 0;
}
int process_get_rate(void)
{
unsigned char bitrate[WLAN_MAX_RATES];
struct iwreq iwr;
int i = 0;
memset(&iwr, 0, sizeof(iwr));
strncpy(iwr.ifr_name, DevName, IFNAMSIZ);
iwr.u.data.pointer = (caddr_t) bitrate;
iwr.u.data.length = sizeof(bitrate);
if (IOCTL_WLANGETRATE <= 0) {
return -EOPNOTSUPP;
}
if (SUBIOCTL_WLANGETRATE > 0) {
iwr.u.data.flags = SUBIOCTL_WLANGETRATE;
}
if (ioctl(sockfd, IOCTL_WLANGETRATE, &iwr) < 0) {
perror("wlanconfig");
return -1;
}
printf("%-8.16s %d available bit-rates :\n",
DevName, iwr.u.data.length);
for (i = 0 ; i < iwr.u.data.length; i++) {
print_bitrate(bitrate[i], 0, 0);
}
if (ioctl(sockfd, SIOCGIWRATE, &iwr)) {
perror("wlanconfig");
return -1;
}
print_bitrate(iwr.u.bitrate.value, 1, iwr.u.bitrate.fixed);
return 0;
}
int ishexstring(char *s)
{
int tmp, ret = -1;
while(*s) {
tmp = toupper(*s);
if (tmp >= 'A' && tmp <= 'F') {
ret = 0;
break;
}
s++;
}
return ret;
}
int atoval(char *buf)
{
if (!strncasecmp(buf, "0x", 2))
return a2hex(buf+2);
else if (!ishexstring(buf))
return a2hex(buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -