📄 iwctl.c
字号:
/*
* Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
* All rights reserved.
*
* This software is copyrighted by and is the sole property of
* VIA Networking Technologies, Inc. This software may only be used
* in accordance with the corresponding license agreement. Any unauthorized
* use, duplication, transmission, distribution, or disclosure of this
* software is expressly forbidden.
*
* This software is provided by VIA Networking Technologies, Inc. "as is"
* and any express or implied warranties, including, but not limited to, the
* implied warranties of merchantability and fitness for a particular purpose
* are disclaimed. In no event shall VIA Networking Technologies, Inc.
* be liable for any direct, indirect, incidental, special, exemplary, or
* consequential damages.
*
* File: iwctl.c
*
* Purpose: wireless ext & ioctl functions
*
* Author: Lyndon Chen
*
* Date: July 5, 2006
*
* Functions:
*
* Revision History:
*
*/
#if !defined(__DEVICE_H__)
#include "device.h"
#endif
#if !defined(__IOCTL_H__)
#include "ioctl.h"
#endif
#if !defined(__IOCMD_H__)
#include "iocmd.h"
#endif
#if !defined(__MAC_H__)
#include "mac.h"
#endif
#if !defined(__CARD_H__)
#include "card.h"
#endif
#if !defined(__HOSTAP_H__)
#include "hostap.h"
#endif
#if !defined(__UMEM_H__)
#include "umem.h"
#endif
#if !defined(__POWER_H__)
#include "power.h"
#endif
#if !defined(__RF_H__)
#include "rf.h"
#endif
#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
#endif
/*--------------------- Static Definitions -------------------------*/
#define SUPPORTED_WIRELESS_EXT 17
#ifdef WIRELESS_EXT
static const long frequency_list[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
5700, 5745, 5765, 5785, 5805, 5825
};
#endif
/*--------------------- Static Classes ----------------------------*/
//static int msglevel =MSG_LEVEL_DEBUG;
static int msglevel =MSG_LEVEL_INFO;
/*--------------------- Static Variables --------------------------*/
/*--------------------- Static Functions --------------------------*/
/*--------------------- Export Variables --------------------------*/
#ifdef WIRELESS_EXT
#if WIRELESS_EXT > 12
struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
{
PSDevice pDevice = dev->priv;
pDevice->wstats.status = pDevice->eOPMode;
pDevice->wstats.qual.qual = pDevice->byCurrSQ;
pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI;
pDevice->wstats.qual.noise = 0;
pDevice->wstats.qual.updated = 1;
pDevice->wstats.discard.nwid = 0;
pDevice->wstats.discard.code = 0;
pDevice->wstats.discard.fragment = 0;
pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr[1];
pDevice->wstats.discard.misc = 0;
pDevice->wstats.miss.beacon = 0;
return &pDevice->wstats;
}
#endif
/*------------------------------------------------------------------*/
static int iwctl_commit(struct net_device *dev,
struct iw_request_info *info,
void *wrq,
char *extra)
{
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n");
return 0;
}
/*
* Wireless Handler : get protocol name
*/
int iwctl_giwname(struct net_device *dev,
struct iw_request_info *info,
char *wrq,
char *extra)
{
strcpy(wrq, "802.11-a/b/g");
return 0;
}
#if WIRELESS_EXT > 13
/*
* Wireless Handler : set scan
*/
int iwctl_siwscan(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *wrq,
char *extra)
{
PSDevice pDevice = (PSDevice)dev->priv;
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n");
spin_lock_irq(&pDevice->lock);
bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
spin_unlock_irq(&pDevice->lock);
return 0;
}
/*
* Wireless Handler : get scan results
*/
int iwctl_giwscan(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
char *extra)
{
int ii, jj, kk;
PSDevice pDevice = (PSDevice)dev->priv;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
PKnownBSS pBSS;
PWLAN_IE_SSID pItemSSID;
PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates;
char *current_ev = extra;
char *end_buf = extra + IW_SCAN_MAX_DATA;
char *current_val = NULL;
struct iw_event iwe;
long ldBm;
#if WIRELESS_EXT > 14
char buf[MAX_WPA_IE_LEN * 2 + 30];
#endif /* WIRELESS_EXT > 14 */
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n");
if (pMgmt->eScanState == WMAC_IS_SCANNING) {
// In scanning..
return -EAGAIN;
}
pBSS = &(pMgmt->sBSSList[0]);
for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
if (current_ev >= end_buf)
break;
pBSS = &(pMgmt->sBSSList[jj]);
if (pBSS->bActive) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN);
current_ev = iwe_stream_add_event(current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWMODE;
if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
iwe.u.mode = IW_MODE_INFRA;
}
else {
iwe.u.mode = IW_MODE_ADHOC;
}
iwe.len = IW_EV_UINT_LEN;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWESSID;
pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
iwe.u.data.length = pItemSSID->len;
iwe.u.data.flags = 1;
current_ev = iwe_stream_add_point(current_ev,end_buf, &iwe, pItemSSID->abySSID);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVQUAL;
RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
iwe.u.qual.level = ldBm;;
iwe.u.qual.noise = 0;
iwe.u.qual.qual = 0;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWENCODE;
iwe.u.data.length = 0;
if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
}else {
iwe.u.data.flags = IW_ENCODE_DISABLED;
}
current_ev = iwe_stream_add_point(current_ev,end_buf, &iwe, pItemSSID->abySSID);
pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = pBSS->uChannel;
iwe.u.freq.e = 0;
iwe.u.freq.i = 0;
current_ev = iwe_stream_add_event(current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
current_val = current_ev + IW_EV_LCP_LEN;
for (kk = 0 ; kk < 12 ; kk++) {
if (pSuppRates->abyRates[kk] == 0)
break;
// Bit rate given in 500 kb/s units (+ 0x80)
iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
}
for (kk = 0 ; kk < 8 ; kk++) {
if (pExtSuppRates->abyRates[kk] == 0)
break;
// Bit rate given in 500 kb/s units (+ 0x80)
iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
}
if((current_val - current_ev) > IW_EV_LCP_LEN)
current_ev = current_val;
#if WIRELESS_EXT > 14
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval);
iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
#if WIRELESS_EXT > 17
if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = pBSS->wWPALen;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, pBSS->byWPAIE);
}
if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = pBSS->wRSNLen;
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, pBSS->byRSNIE);
}
#else // WIRELESS_EXT > 17
if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
u8 *p = buf;
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
p += sprintf(p, "wpa_ie=");
for (ii = 0; ii < pBSS->wWPALen; ii++) {
p += sprintf(p, "%02x", pBSS->byWPAIE[ii]);
}
iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
}
if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
u8 *p = buf;
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
p += sprintf(p, "rsn_ie=");
for (ii = 0; ii < pBSS->wRSNLen; ii++) {
p += sprintf(p, "%02x", pBSS->byRSNIE[ii]);
}
iwe.u.data.length = strlen(buf);
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
}
#endif
#endif
}
}// for
wrq->length = current_ev - extra;
return 0;
}
#endif /* WIRELESS_EXT > 13 */
/*
* Wireless Handler : set frequence or channel
*/
int iwctl_siwfreq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *wrq,
char *extra)
{
PSDevice pDevice = (PSDevice)dev->priv;
int rc = 0;
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
// If setting by frequency, convert to a channel
if((wrq->e == 1) &&
(wrq->m >= (int) 2.412e8) &&
(wrq->m <= (int) 2.487e8)) {
int f = wrq->m / 100000;
int c = 0;
while((c < 14) && (f != frequency_list[c]))
c++;
wrq->e = 0;
wrq->m = c + 1;
}
// Setting by channel number
if((wrq->m > 14) || (wrq->e > 0))
rc = -EOPNOTSUPP;
else {
int channel = wrq->m;
if((channel < 1) || (channel > 14)) {
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
rc = -EINVAL;
} else {
// Yes ! We can set it !!!
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
pDevice->uChannel = channel;
}
}
return rc;
}
/*
* Wireless Handler : get frequence or channel
*/
int iwctl_giwfreq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *wrq,
char *extra)
{
PSDevice pDevice = (PSDevice)dev->priv;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
#ifdef WEXT_USECHANNELS
wrq->m = (int)pMgmt->uCurrChannel;
wrq->e = 0;
#else
{
int f = (int)pMgmt->uCurrChannel - 1;
if(f < 0)
f = 0;
wrq->m = frequency_list[f] * 100000;
wrq->e = 1;
}
#endif
return 0;
}
/*
* Wireless Handler : set operation mode
*/
int iwctl_siwmode(struct net_device *dev,
struct iw_request_info *info,
__u32 *wmode,
char *extra)
{
PSDevice pDevice = (PSDevice)dev->priv;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
int rc = 0;
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
return rc;
}
switch(*wmode) {
case IW_MODE_ADHOC:
if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
if (pDevice->flags & DEVICE_FLAGS_OPENED) {
pDevice->bCommit = TRUE;
}
}
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
break;
case IW_MODE_AUTO:
case IW_MODE_INFRA:
if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
if (pDevice->flags & DEVICE_FLAGS_OPENED) {
pDevice->bCommit = TRUE;
}
}
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
break;
case IW_MODE_MASTER:
pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
rc = -EOPNOTSUPP;
break;
if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
pMgmt->eConfigMode = WMAC_CONFIG_AP;
if (pDevice->flags & DEVICE_FLAGS_OPENED) {
pDevice->bCommit = TRUE;
}
}
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
break;
case IW_MODE_REPEAT:
pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
rc = -EOPNOTSUPP;
break;
default:
rc = -EINVAL;
}
return rc;
}
/*
* Wireless Handler : get operation mode
*/
int iwctl_giwmode(struct net_device *dev,
struct iw_request_info *info,
__u32 *wmode,
char *extra)
{
PSDevice pDevice = (PSDevice)dev->priv;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
// If not managed, assume it's ad-hoc
switch (pMgmt->eConfigMode) {
case WMAC_CONFIG_ESS_STA:
*wmode = IW_MODE_INFRA;
break;
case WMAC_CONFIG_IBSS_STA:
*wmode = IW_MODE_ADHOC;
break;
case WMAC_CONFIG_AUTO:
*wmode = IW_MODE_INFRA;
break;
case WMAC_CONFIG_AP:
*wmode = IW_MODE_MASTER;
break;
default:
*wmode = IW_MODE_ADHOC;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -