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

📄 hw_features.c

📁 hostapd源代码
💻 C
字号:
/* * hostapd / Hardware feature query and different modes * Copyright 2002-2003, Instant802 Networks, Inc. * Copyright 2005-2006, Devicescape Software, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include "hostapd.h"#include "hw_features.h"#include "driver.h"#include "config.h"#include "ieee802_11.h"#include "eloop.h"void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,			      size_t num_hw_features){	int i;	if (hw_features == NULL)		return;	for (i = 0; i < num_hw_features; i++) {		free(hw_features[i].channels);		free(hw_features[i].rates);	}	free(hw_features);}int hostapd_get_hw_features(struct hostapd_iface *iface){	struct hostapd_data *hapd = iface->bss[0];	int ret = 0, i, j;	u16 num_modes, flags;	struct hostapd_hw_modes *modes;	modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags);	if (modes == NULL) {		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_DEBUG,			       "Fetching hardware channel/rate support not "			       "supported.");		return -1;	}	iface->hw_flags = flags;	hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);	iface->hw_features = modes;	iface->num_hw_features = num_modes;	for (i = 0; i < num_modes; i++) {		struct hostapd_hw_modes *feature = &modes[i];		/* set flag for channels we can use in current regulatory		 * domain */		for (j = 0; j < feature->num_channels; j++) {			/* TODO: add regulatory domain lookup */			unsigned char power_level = 0;			unsigned char antenna_max = 0;			if ((feature->mode == HOSTAPD_MODE_IEEE80211G ||			     feature->mode == HOSTAPD_MODE_IEEE80211B) &&			    feature->channels[j].chan >= 1 &&			    feature->channels[j].chan <= 11) {				power_level = 20;				feature->channels[j].flag |=					HOSTAPD_CHAN_W_SCAN;			} else				feature->channels[j].flag &=					~HOSTAPD_CHAN_W_SCAN;			hostapd_set_channel_flag(hapd, feature->mode,						 feature->channels[j].chan,						 feature->channels[j].flag,						 power_level,						 antenna_max);		}	}	return ret;}static int hostapd_prepare_rates(struct hostapd_data *hapd,				 struct hostapd_hw_modes *mode){	int i, num_basic_rates = 0;	int basic_rates_a[] = { 60, 120, 240, -1 };	int basic_rates_b[] = { 10, 20, -1 };	int basic_rates_g[] = { 10, 20, 55, 110, -1 };	int *basic_rates;	if (hapd->iconf->basic_rates)		basic_rates = hapd->iconf->basic_rates;	else switch (mode->mode) {	case HOSTAPD_MODE_IEEE80211A:		basic_rates = basic_rates_a;		break;	case HOSTAPD_MODE_IEEE80211B:		basic_rates = basic_rates_b;		break;	case HOSTAPD_MODE_IEEE80211G:		basic_rates = basic_rates_g;		break;	default:		return -1;	}	if (hostapd_set_rate_sets(hapd, hapd->iconf->supported_rates,				  basic_rates, mode->mode)) {		printf("Failed to update rate sets in kernel module\n");	}	free(hapd->iface->current_rates);	hapd->iface->num_rates = 0;	hapd->iface->current_rates =		malloc(mode->num_rates * sizeof(struct hostapd_rate_data));	if (!hapd->iface->current_rates) {		printf("Failed to allocate memory for rate table.\n");		return -1;	}	for (i = 0; i < mode->num_rates; i++) {		struct hostapd_rate_data *rate;		if (hapd->iconf->supported_rates &&		    !hostapd_rate_found(hapd->iconf->supported_rates,					mode->rates[i].rate))			continue;		rate = &hapd->iface->current_rates[hapd->iface->num_rates];		memcpy(rate, &mode->rates[i],		       sizeof(struct hostapd_rate_data));		if (hostapd_rate_found(basic_rates, rate->rate)) {			rate->flags |= HOSTAPD_RATE_BASIC;			num_basic_rates++;		} else			rate->flags &= ~HOSTAPD_RATE_BASIC;		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,			      "RATE[%d] rate=%d flags=0x%x\n",			      hapd->iface->num_rates, rate->rate, rate->flags);		hapd->iface->num_rates++;	}	if (hapd->iface->num_rates == 0 || num_basic_rates == 0) {		printf("No rates remaining in supported/basic rate sets "		       "(%d,%d).\n", hapd->iface->num_rates, num_basic_rates);		return -1;	}	return 0;}int hostapd_select_hw_mode(struct hostapd_iface *iface){	int i, j, ok;	if (iface->num_hw_features < 1)		return -1;	iface->current_mode = NULL;	for (i = 0; i < iface->num_hw_features; i++) {		struct hostapd_hw_modes *mode = &iface->hw_features[i];		if (mode->mode == iface->conf->hw_mode) {			iface->current_mode = mode;			break;		}	}	if (iface->current_mode == NULL) {		printf("Hardware does not support configured mode\n");		hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_WARNING,			       "Hardware does not support configured mode");		return -1;	}	ok = 0;	for (j = 0; j < iface->current_mode->num_channels; j++) {		struct hostapd_channel_data *chan =			&iface->current_mode->channels[j];		if ((chan->flag & HOSTAPD_CHAN_W_SCAN) &&		    (chan->chan == iface->conf->channel)) {			ok = 1;			break;		}	}	if (ok == 0 && iface->conf->channel != 0) {		hostapd_logger(iface->bss[0], NULL,			       HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_WARNING,			       "Configured channel (%d) not found from the "			       "channel list of current mode (%d) %s",			       iface->conf->channel,			       iface->current_mode->mode,			       hostapd_hw_mode_txt(iface->current_mode->mode));		iface->current_mode = NULL;	}	if (iface->current_mode == NULL) {		hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_WARNING,			       "Hardware does not support configured channel");		return -1;	}	if (hostapd_prepare_rates(iface->bss[0], iface->current_mode)) {		printf("Failed to prepare rates table.\n");		hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,					   HOSTAPD_LEVEL_WARNING,					   "Failed to prepare rates table.");		return -1;	}	return 0;}const char * hostapd_hw_mode_txt(int mode){	switch (mode) {	case HOSTAPD_MODE_IEEE80211A:		return "IEEE 802.11a";	case HOSTAPD_MODE_IEEE80211B:		return "IEEE 802.11b";	case HOSTAPD_MODE_IEEE80211G:		return "IEEE 802.11g";	default:		return "UNKNOWN";	}}int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan){	int i;	if (!hapd->iface->current_mode)		return 0;	for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {		struct hostapd_channel_data *ch =			&hapd->iface->current_mode->channels[i];		if (ch->chan == chan)			return ch->freq;	}	return 0;}int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq){	int i;	if (!hapd->iface->current_mode)		return 0;	for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {		struct hostapd_channel_data *ch =			&hapd->iface->current_mode->channels[i];		if (ch->freq == freq)			return ch->chan;	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -