static struct hostapd_hw_modes * test_driver_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags) { struct hostapd_hw_modes *modes; *num_modes = 3; *flags = 0; modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes)); if (modes == NULL) return NULL; modes[0].mode = HOSTAPD_MODE_IEEE80211G; modes[0].num_channels = 1; modes[0].num_rates = 1; modes[0].channels = os_zalloc(sizeof(struct hostapd_channel_data)); modes[0].rates = os_zalloc(sizeof(struct hostapd_rate_data)); if (modes[0].channels == NULL || modes[0].rates == NULL) { hostapd_free_hw_features(modes, *num_modes); return NULL; } modes[0].channels[0].chan = 1; modes[0].channels[0].freq = 2412; modes[0].channels[0].flag = 0; modes[0].rates[0].rate = 10; modes[0].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED | HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY; modes[1].mode = HOSTAPD_MODE_IEEE80211B; modes[1].num_channels = 1; modes[1].num_rates = 1; modes[1].channels = os_zalloc(sizeof(struct hostapd_channel_data)); modes[1].rates = os_zalloc(sizeof(struct hostapd_rate_data)); if (modes[1].channels == NULL || modes[1].rates == NULL) { hostapd_free_hw_features(modes, *num_modes); return NULL; } modes[1].channels[0].chan = 1; modes[1].channels[0].freq = 2412; modes[1].channels[0].flag = 0; modes[1].rates[0].rate = 10; modes[1].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED | HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY; modes[2].mode = HOSTAPD_MODE_IEEE80211A; modes[2].num_channels = 1; modes[2].num_rates = 1; modes[2].channels = os_zalloc(sizeof(struct hostapd_channel_data)); modes[2].rates = os_zalloc(sizeof(struct hostapd_rate_data)); if (modes[2].channels == NULL || modes[2].rates == NULL) { hostapd_free_hw_features(modes, *num_modes); return NULL; } modes[2].channels[0].chan = 60; modes[2].channels[0].freq = 5300; modes[2].channels[0].flag = 0; modes[2].rates[0].rate = 60; modes[2].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED | HOSTAPD_RATE_MANDATORY; return modes; }
static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) { hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); iface->hw_features = NULL; os_free(iface->current_rates); iface->current_rates = NULL; os_free(iface->basic_rates); iface->basic_rates = NULL; ap_list_deinit(iface); }
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; if(! hapd) return -1 ; 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; }
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; if (hostapd_drv_none(hapd)) return -1; 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++) { /* * Disable all channels that are marked not to allow * IBSS operation or active scanning. In addition, * disable all channels that require radar detection, * since that (in addition to full DFS) is not yet * supported. */ if (feature->channels[j].flag & (HOSTAPD_CHAN_NO_IBSS | HOSTAPD_CHAN_PASSIVE_SCAN | HOSTAPD_CHAN_RADAR)) feature->channels[j].flag |= HOSTAPD_CHAN_DISABLED; if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED) continue; wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d " "chan=%d freq=%d MHz max_tx_power=%d dBm", feature->mode, feature->channels[j].chan, feature->channels[j].freq, feature->channels[j].max_tx_power); } } return ret; }
int hostapd_get_hw_features(struct hostapd_iface *iface) { struct hostapd_data *hapd = iface->bss[0]; int i, j; u16 num_modes, flags; struct hostapd_hw_modes *modes; if (hostapd_drv_none(hapd)) { return -1; } 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]; int dfs_enabled = hapd->iconf->ieee80211h && (iface->drv_flags & WPA_DRIVER_FLAGS_RADAR); /* set flag for channels we can use in current regulatory * domain */ for (j = 0; j < feature->num_channels; j++) { int dfs = 0; /* * Disable all channels that are marked not to allow * to initiate radiation (a.k.a. passive scan and no * IBSS). * Use radar channels only if the driver supports DFS. */ if ((feature->channels[j].flag & HOSTAPD_CHAN_RADAR) && dfs_enabled) { dfs = 1; } else if (((feature->channels[j].flag & HOSTAPD_CHAN_RADAR) && !(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) || (feature->channels[j].flag & HOSTAPD_CHAN_NO_IR)) { feature->channels[j].flag |= HOSTAPD_CHAN_DISABLED; } if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED) { continue; } wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d " "chan=%d freq=%d MHz max_tx_power=%d dBm%s", feature->mode, feature->channels[j].chan, feature->channels[j].freq, feature->channels[j].max_tx_power, dfs ? dfs_info(&feature->channels[j]) : ""); } } return 0; }
/** * hostapd_cleanup_iface - Complete per-interface cleanup * @iface: Pointer to interface data * * This function is called after per-BSS data structures are deinitialized * with hostapd_cleanup(). */ static void hostapd_cleanup_iface(struct hostapd_iface *iface) { hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); iface->hw_features = NULL; os_free(iface->current_rates); iface->current_rates = NULL; ap_list_deinit(iface); hostapd_config_free(iface->conf); iface->conf = NULL; os_free(iface->config_fname); os_free(iface->bss); os_free(iface); }
static struct hostapd_hw_modes * hostap_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags) { struct hostapd_hw_modes *mode; int i, clen, rlen; const short chan2freq[14] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; mode = os_zalloc(sizeof(struct hostapd_hw_modes)); if (mode == NULL) return NULL; *num_modes = 1; *flags = 0; mode->mode = HOSTAPD_MODE_IEEE80211B; mode->num_channels = 14; mode->num_rates = 4; clen = mode->num_channels * sizeof(struct hostapd_channel_data); rlen = mode->num_rates * sizeof(struct hostapd_rate_data); mode->channels = os_zalloc(clen); mode->rates = os_zalloc(rlen); if (mode->channels == NULL || mode->rates == NULL) { hostapd_free_hw_features(mode, *num_modes); return NULL; } for (i = 0; i < 14; i++) { mode->channels[i].chan = i + 1; mode->channels[i].freq = chan2freq[i]; } mode->rates[0].rate = 10; mode->rates[0].flags = HOSTAPD_RATE_CCK; mode->rates[1].rate = 20; mode->rates[1].flags = HOSTAPD_RATE_CCK; mode->rates[2].rate = 55; mode->rates[2].flags = HOSTAPD_RATE_CCK; mode->rates[3].rate = 110; mode->rates[3].flags = HOSTAPD_RATE_CCK; return mode; }