/* * Handle power-save state change in station mode. */ void ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable) { struct ieee80211_node *ni = vap->iv_bss; if (!((enable != 0) ^ ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) != 0))) return; IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, "sta power save mode %s", enable ? "on" : "off"); if (!enable) { ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; ieee80211_send_nulldata(ieee80211_ref_node(ni)); /* * Flush any queued frames; we can do this immediately * because we know they'll be queued behind the null * data frame we send the ap. * XXX can we use a data frame to take us out of ps? */ if (ni->ni_psq.psq_len != 0) pwrsave_flushq(ni); } else { ni->ni_flags |= IEEE80211_NODE_PWR_MGT; ieee80211_send_nulldata(ieee80211_ref_node(ni)); } }
void ieee80211_inact_timeout_sta(struct ieee80211vap *vap) { struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; if (!mlme_priv->im_connection_up) { return; } /* * if there was an activity in the last IEEE80211_INACT_WAIT period. * then reset the counter. */ if (CONVERT_SYSTEM_TIME_TO_MS(OS_GET_TIMESTAMP() - vap->iv_last_directed_frame) < (IEEE80211_INACT_WAIT * 1000)) { vap->iv_inact_count = (vap->iv_keep_alive_timeout + IEEE80211_INACT_WAIT -1)/IEEE80211_INACT_WAIT; } if (vap->iv_inact_count) { --vap->iv_inact_count; if (vap->iv_inact_count == 0) { if (ieee80211_sta_power_send_keepalive(vap->iv_pwrsave_sta) == ENXIO) { ieee80211_send_nulldata(vap->iv_bss,false); } if (vap->iv_keep_alive_timeout) { vap->iv_inact_count = (vap->iv_keep_alive_timeout + IEEE80211_INACT_WAIT -1)/IEEE80211_INACT_WAIT; } } } }