u16 *num_modes;
struct hostapd_hw_modes *modes;
int last_mode, last_chan_idx;
+ int failed;
};
static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
mode->num_channels + new_channels,
sizeof(struct hostapd_channel_data));
if (!channel)
- return NL_SKIP;
+ return NL_STOP;
mode->channels = channel;
mode->num_channels += new_channels;
mode->rates = os_calloc(mode->num_rates, sizeof(int));
if (!mode->rates)
- return NL_SKIP;
+ return NL_STOP;
idx = 0;
mode = os_realloc_array(phy_info->modes,
*phy_info->num_modes + 1,
sizeof(*mode));
- if (!mode)
- return NL_SKIP;
+ if (!mode) {
+ phy_info->failed = 1;
+ return NL_STOP;
+ }
phy_info->modes = mode;
mode = &phy_info->modes[*(phy_info->num_modes)];
phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
ret = phy_info_freqs(phy_info, mode, tb_band[NL80211_BAND_ATTR_FREQS]);
- if (ret != NL_OK)
- return ret;
- ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
- if (ret != NL_OK)
+ if (ret == NL_OK)
+ ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
+ if (ret != NL_OK) {
+ phy_info->failed = 1;
return ret;
+ }
return NL_OK;
}
.num_modes = num_modes,
.modes = NULL,
.last_mode = -1,
+ .failed = 0,
};
*num_modes = 0;
if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
nl80211_set_regulatory_flags(drv, &result);
+ if (result.failed) {
+ int i;
+
+ for (i = 0; result.modes && i < *num_modes; i++) {
+ os_free(result.modes[i].channels);
+ os_free(result.modes[i].rates);
+ }
+ os_free(result.modes);
+ return NULL;
+ }
return wpa_driver_nl80211_postprocess_modes(result.modes,
num_modes);
}