int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
			      size_t buflen)
{
	struct hostapd_iface *iface = hapd->iface;
	struct hostapd_hw_modes *mode = iface->current_mode;
	int len = 0, ret, j;
	size_t i;

	ret = os_snprintf(buf + len, buflen - len,
			  "state=%s\n"
			  "phy=%s\n"
			  "freq=%d\n"
			  "num_sta_non_erp=%d\n"
			  "num_sta_no_short_slot_time=%d\n"
			  "num_sta_no_short_preamble=%d\n"
			  "olbc=%d\n"
			  "num_sta_ht_no_gf=%d\n"
			  "num_sta_no_ht=%d\n"
			  "num_sta_ht_20_mhz=%d\n"
			  "num_sta_ht40_intolerant=%d\n"
			  "olbc_ht=%d\n"
			  "ht_op_mode=0x%x\n",
			  hostapd_state_text(iface->state),
			  iface->phy,
			  iface->freq,
			  iface->num_sta_non_erp,
			  iface->num_sta_no_short_slot_time,
			  iface->num_sta_no_short_preamble,
			  iface->olbc,
			  iface->num_sta_ht_no_gf,
			  iface->num_sta_no_ht,
			  iface->num_sta_ht_20mhz,
			  iface->num_sta_ht40_intolerant,
			  iface->olbc_ht,
			  iface->ht_op_mode);
	if (os_snprintf_error(buflen - len, ret))
		return len;
	len += ret;

	if (!iface->cac_started || !iface->dfs_cac_ms) {
		ret = os_snprintf(buf + len, buflen - len,
				  "cac_time_seconds=%d\n"
				  "cac_time_left_seconds=N/A\n",
				  iface->dfs_cac_ms / 1000);
	} else {
		/* CAC started and CAC time set - calculate remaining time */
		struct os_reltime now;
		unsigned int left_time;

		os_reltime_age(&iface->dfs_cac_start, &now);
		left_time = iface->dfs_cac_ms / 1000 - now.sec;
		ret = os_snprintf(buf + len, buflen - len,
				  "cac_time_seconds=%u\n"
				  "cac_time_left_seconds=%u\n",
				  iface->dfs_cac_ms / 1000,
				  left_time);
	}
	if (os_snprintf_error(buflen - len, ret))
		return len;
	len += ret;

	ret = os_snprintf(buf + len, buflen - len,
			  "channel=%u\n"
			  "secondary_channel=%d\n"
			  "ieee80211n=%d\n"
			  "ieee80211ac=%d\n"
			  "beacon_int=%u\n"
			  "dtim_period=%d\n",
			  iface->conf->channel,
			  iface->conf->ieee80211n && !hapd->conf->disable_11n ?
			  iface->conf->secondary_channel : 0,
			  iface->conf->ieee80211n && !hapd->conf->disable_11n,
			  iface->conf->ieee80211ac &&
			  !hapd->conf->disable_11ac,
			  iface->conf->beacon_int,
			  hapd->conf->dtim_period);
	if (os_snprintf_error(buflen - len, ret))
		return len;
	len += ret;
	if (iface->conf->ieee80211ac && !hapd->conf->disable_11ac) {
		ret = os_snprintf(buf + len, buflen - len,
				  "vht_oper_chwidth=%d\n"
				  "vht_oper_centr_freq_seg0_idx=%d\n"
				  "vht_oper_centr_freq_seg1_idx=%d\n"
				  "vht_caps_info=%08x\n",
				  iface->conf->vht_oper_chwidth,
				  iface->conf->vht_oper_centr_freq_seg0_idx,
				  iface->conf->vht_oper_centr_freq_seg1_idx,
				  iface->conf->vht_capab);
		if (os_snprintf_error(buflen - len, ret))
			return len;
		len += ret;
	}

	if (iface->conf->ieee80211ac && !hapd->conf->disable_11ac && mode) {
		u16 rxmap = WPA_GET_LE16(&mode->vht_mcs_set[0]);
		u16 txmap = WPA_GET_LE16(&mode->vht_mcs_set[4]);

		ret = os_snprintf(buf + len, buflen - len,
				  "rx_vht_mcs_map=%04x\n"
				  "tx_vht_mcs_map=%04x\n",
				  rxmap, txmap);
		if (os_snprintf_error(buflen - len, ret))
			return len;
		len += ret;
	}

	if (iface->conf->ieee80211n && !hapd->conf->disable_11n) {
		ret = os_snprintf(buf + len, buflen - len,
				  "ht_caps_info=%04x\n",
				  hapd->iconf->ht_capab);
		if (os_snprintf_error(buflen - len, ret))
			return len;
		len += ret;
	}

	if (iface->conf->ieee80211n && !hapd->conf->disable_11n && mode) {
		len = hostapd_write_ht_mcs_bitmask(buf, buflen, len,
						   mode->mcs_set);
	}

	if (iface->current_rates && iface->num_rates) {
		ret = os_snprintf(buf + len, buflen - len, "supported_rates=");
		if (os_snprintf_error(buflen - len, ret))
			return len;
		len += ret;

		for (j = 0; j < iface->num_rates; j++) {
			ret = os_snprintf(buf + len, buflen - len, "%s%02x",
					  j > 0 ? " " : "",
					  iface->current_rates[j].rate / 5);
			if (os_snprintf_error(buflen - len, ret))
				return len;
			len += ret;
		}
		ret = os_snprintf(buf + len, buflen - len, "\n");
		if (os_snprintf_error(buflen - len, ret))
			return len;
		len += ret;
	}

	for (j = 0; mode && j < mode->num_channels; j++) {
		if (mode->channels[j].freq == iface->freq) {
			ret = os_snprintf(buf + len, buflen - len,
					  "max_txpower=%u\n",
					  mode->channels[j].max_tx_power);
			if (os_snprintf_error(buflen - len, ret))
				return len;
			len += ret;
			break;
		}
	}

	for (i = 0; i < iface->num_bss; i++) {
		struct hostapd_data *bss = iface->bss[i];
		ret = os_snprintf(buf + len, buflen - len,
				  "bss[%d]=%s\n"
				  "bssid[%d]=" MACSTR "\n"
				  "ssid[%d]=%s\n"
				  "num_sta[%d]=%d\n",
				  (int) i, bss->conf->iface,
				  (int) i, MAC2STR(bss->own_addr),
				  (int) i,
				  wpa_ssid_txt(bss->conf->ssid.ssid,
					       bss->conf->ssid.ssid_len),
				  (int) i, bss->num_sta);
		if (os_snprintf_error(buflen - len, ret))
			return len;
		len += ret;
	}

	if (hapd->conf->chan_util_avg_period) {
		ret = os_snprintf(buf + len, buflen - len,
				  "chan_util_avg=%u\n",
				  iface->chan_util_average);
		if (os_snprintf_error(buflen - len, ret))
			return len;
		len += ret;
	}

	return len;
}
int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
			      size_t buflen)
{
	struct hostapd_iface *iface = hapd->iface;
	int len = 0, ret;
	size_t i;

	ret = os_snprintf(buf + len, buflen - len,
			  "state=%s\n"
			  "phy=%s\n"
			  "freq=%d\n"
			  "num_sta_non_erp=%d\n"
			  "num_sta_no_short_slot_time=%d\n"
			  "num_sta_no_short_preamble=%d\n"
			  "olbc=%d\n"
			  "num_sta_ht_no_gf=%d\n"
			  "num_sta_no_ht=%d\n"
			  "num_sta_ht_20_mhz=%d\n"
			  "num_sta_ht40_intolerant=%d\n"
			  "olbc_ht=%d\n"
			  "ht_op_mode=0x%x\n",
			  hostapd_state_text(iface->state),
			  iface->phy,
			  iface->freq,
			  iface->num_sta_non_erp,
			  iface->num_sta_no_short_slot_time,
			  iface->num_sta_no_short_preamble,
			  iface->olbc,
			  iface->num_sta_ht_no_gf,
			  iface->num_sta_no_ht,
			  iface->num_sta_ht_20mhz,
			  iface->num_sta_ht40_intolerant,
			  iface->olbc_ht,
			  iface->ht_op_mode);
	if (ret < 0 || (size_t) ret >= buflen - len)
		return len;
	len += ret;

	if (!iface->cac_started || !iface->dfs_cac_ms) {
		ret = os_snprintf(buf + len, buflen - len,
				  "cac_time_seconds=%d\n"
				  "cac_time_left_seconds=N/A\n",
				  iface->dfs_cac_ms / 1000);
	} else {
		/* CAC started and CAC time set - calculate remaining time */
		struct os_reltime now;
		unsigned int left_time;

		os_reltime_age(&iface->dfs_cac_start, &now);
		left_time = iface->dfs_cac_ms / 1000 - now.sec;
		ret = os_snprintf(buf + len, buflen - len,
				  "cac_time_seconds=%u\n"
				  "cac_time_left_seconds=%u\n",
				  iface->dfs_cac_ms / 1000,
				  left_time);
	}
	if (ret < 0 || (size_t) ret >= buflen - len)
		return len;
	len += ret;

	ret = os_snprintf(buf + len, buflen - len,
			  "channel=%u\n"
			  "secondary_channel=%d\n"
			  "ieee80211n=%d\n"
			  "ieee80211ac=%d\n"
			  "vht_oper_chwidth=%d\n"
			  "vht_oper_centr_freq_seg0_idx=%d\n"
			  "vht_oper_centr_freq_seg1_idx=%d\n",
			  iface->conf->channel,
			  iface->conf->secondary_channel,
			  iface->conf->ieee80211n,
			  iface->conf->ieee80211ac,
			  iface->conf->vht_oper_chwidth,
			  iface->conf->vht_oper_centr_freq_seg0_idx,
			  iface->conf->vht_oper_centr_freq_seg1_idx);
	if (ret < 0 || (size_t) ret >= buflen - len)
		return len;
	len += ret;

	for (i = 0; i < iface->num_bss; i++) {
		struct hostapd_data *bss = iface->bss[i];
		ret = os_snprintf(buf + len, buflen - len,
				  "bss[%d]=%s\n"
				  "bssid[%d]=" MACSTR "\n"
				  "ssid[%d]=%s\n"
				  "num_sta[%d]=%d\n",
				  (int) i, bss->conf->iface,
				  (int) i, MAC2STR(bss->own_addr),
				  (int) i,
				  wpa_ssid_txt(bss->conf->ssid.ssid,
					       bss->conf->ssid.ssid_len),
				  (int) i, bss->num_sta);
		if (ret < 0 || (size_t) ret >= buflen - len)
			return len;
		len += ret;
	}

	return len;
}
int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
                              size_t buflen)
{
    struct hostapd_iface *iface = hapd->iface;
    int len = 0, ret;
    size_t i;

    ret = os_snprintf(buf + len, buflen - len,
                      "state=%s\n"
                      "phy=%s\n"
                      "freq=%d\n"
                      "num_sta_non_erp=%d\n"
                      "num_sta_no_short_slot_time=%d\n"
                      "num_sta_no_short_preamble=%d\n"
                      "olbc=%d\n"
                      "num_sta_ht_no_gf=%d\n"
                      "num_sta_no_ht=%d\n"
                      "num_sta_ht_20_mhz=%d\n"
                      "olbc_ht=%d\n"
                      "ht_op_mode=0x%x\n",
                      hostapd_state_text(iface->state),
                      iface->phy,
                      iface->freq,
                      iface->num_sta_non_erp,
                      iface->num_sta_no_short_slot_time,
                      iface->num_sta_no_short_preamble,
                      iface->olbc,
                      iface->num_sta_ht_no_gf,
                      iface->num_sta_no_ht,
                      iface->num_sta_ht_20mhz,
                      iface->olbc_ht,
                      iface->ht_op_mode);
    if (ret < 0 || (size_t) ret >= buflen - len)
        return len;
    len += ret;

    ret = os_snprintf(buf + len, buflen - len,
                      "channel=%u\n"
                      "secondary_channel=%d\n"
                      "ieee80211n=%d\n"
                      "ieee80211ac=%d\n"
                      "vht_oper_chwidth=%d\n"
                      "vht_oper_centr_freq_seg0_idx=%d\n"
                      "vht_oper_centr_freq_seg1_idx=%d\n",
                      iface->conf->channel,
                      iface->conf->secondary_channel,
                      iface->conf->ieee80211n,
                      iface->conf->ieee80211ac,
                      iface->conf->vht_oper_chwidth,
                      iface->conf->vht_oper_centr_freq_seg0_idx,
                      iface->conf->vht_oper_centr_freq_seg1_idx);
    if (ret < 0 || (size_t) ret >= buflen - len)
        return len;
    len += ret;

    for (i = 0; i < iface->num_bss; i++) {
        struct hostapd_data *bss = iface->bss[i];
        ret = os_snprintf(buf + len, buflen - len,
                          "bss[%d]=%s\n"
                          "bssid[%d]=" MACSTR "\n"
                          "ssid[%d]=%s\n"
                          "num_sta[%d]=%d\n",
                          (int) i, bss->conf->iface,
                          (int) i, MAC2STR(bss->own_addr),
                          (int) i,
                          wpa_ssid_txt(bss->conf->ssid.ssid,
                                       bss->conf->ssid.ssid_len),
                          (int) i, bss->num_sta);
        if (ret < 0 || (size_t) ret >= buflen - len)
            return len;
        len += ret;
    }

    return len;
}