⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iwctl.c

📁 VIA VT6655 x86下的Linux Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -