Exemplo n.º 1
0
static bool ieee80211_btamp_conn_state_secured_event(void *ctx, u_int16_t event, u_int16_t event_data_len, void *event_data) 
{
    wlan_btamp_conn_sm_t    sm = (wlan_btamp_conn_sm_t) ctx;
    bool                    retVal = true;

    switch(event) {
    case IEEE80211_BTAMP_CONN_EVENT_DISASSOC:
    case IEEE80211_BTAMP_CONN_EVENT_DEAUTH:
        sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_DOWN;
        sm->last_reason = WLAN_BTAMP_CONN_SM_PEER_DISCONNECTED;
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_BEACONING); 
        break;

    case IEEE80211_BTAMP_CONN_EVENT_DISCONNECT_REQUEST:
        sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_DOWN;
        sm->last_reason = *((wlan_btamp_conn_sm_event_reason *)event_data);
        wlan_mlme_deauth_request(sm->vap_handle, sm->peer, IEEE80211_REASON_AUTH_LEAVE);
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_BEACONING); 
        break;

    default:
        retVal = false;
        break;
    }

    return retVal;
}
Exemplo n.º 2
0
static bool ieee80211_btamp_conn_state_join_event(void *ctx, u_int16_t event, u_int16_t event_data_len, void *event_data) 
{
    wlan_btamp_conn_sm_t    sm = (wlan_btamp_conn_sm_t) ctx;
    bool                    retVal = true;

    switch(event) {

    case IEEE80211_BTAMP_CONN_EVENT_JOIN_COMPLETE:
        ieee80211_sm_transition_to(sm->hsm_handle, IEEE80211_BTAMP_CONN_STATE_AUTH); 
        break;

    case IEEE80211_BTAMP_CONN_EVENT_TIMEOUT:
        sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_FAILED;
        sm->last_reason = WLAN_BTAMP_CONN_SM_CONNECT_TIMEDOUT;
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_BEACONING); 
        break;

    case IEEE80211_BTAMP_CONN_EVENT_DISCONNECT_REQUEST:
        sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_DOWN;
        sm->last_reason = *((wlan_btamp_conn_sm_event_reason *)event_data);
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_BEACONING); 
        break;

    default:
        retVal = false;
        break;
    }

    return retVal;
}
Exemplo n.º 3
0
static bool ieee80211_assoc_state_join_event(void *ctx, u_int16_t event, u_int16_t event_data_len, void *event_data) 
{
    wlan_assoc_sm_t sm = (wlan_assoc_sm_t) ctx;
    switch(event) {
    case IEEE80211_ASSOC_EVENT_JOIN_SUCCESS:
        if (wlan_scan_entry_assoc_state(sm->scan_entry) >= AP_ASSOC_STATE_AUTH) {
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_ASSOC); 
        } else {
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_AUTH); 
        }
        return true;
        break;

    case IEEE80211_ASSOC_EVENT_BEACON_WAIT_TIMEOUT:
    case IEEE80211_ASSOC_EVENT_BEACON_MISS:
    case IEEE80211_ASSOC_EVENT_JOIN_FAIL:
    case IEEE80211_ASSOC_EVENT_DISCONNECT_REQUEST:
    case IEEE80211_ASSOC_EVENT_DISASSOC_REQUEST:
       /* cancel pending mlme operation */
        wlan_mlme_cancel(sm->vap_handle);
        if (wlan_mlme_operation_in_progress(sm->vap_handle)) {
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_MLME_WAIT); 
        } else {
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_INIT); 
        }
        return true;
        break;

    default:
        return false;
    }
}
Exemplo n.º 4
0
static bool ieee80211_assoc_state_auth_event(void *ctx, u_int16_t event, u_int16_t event_data_len, void *event_data) 
{
    wlan_assoc_sm_t sm = (wlan_assoc_sm_t) ctx;

    switch(event) {

    case IEEE80211_ASSOC_EVENT_AUTH_SUCCESS:
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_ASSOC); 
        return true;
        break;

    case IEEE80211_ASSOC_EVENT_AUTH_FAIL:
    case IEEE80211_ASSOC_EVENT_TIMEOUT:
        sm->last_failure = WLAN_ASSOC_SM_REASON_AUTH_FAILED;
        if (sm->cur_auth_attempts < sm->max_auth_attempts) {
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_AUTH); 
            return true;
            break;
        }

        IEEE80211_DPRINTF(sm->vap_handle,IEEE80211_MSG_STATE,"%s: max auth attempts reached \n",__func__);
        if (sm->scan_entry) {
               wlan_scan_entry_set_assoc_state(sm->scan_entry, AP_ASSOC_STATE_NONE);
        }
        /* fall thru */
       
    case IEEE80211_ASSOC_EVENT_DISCONNECT_REQUEST:
    case IEEE80211_ASSOC_EVENT_DISASSOC_REQUEST:
       /* cancel pending mlme operation */
        wlan_mlme_cancel(sm->vap_handle);
        if (wlan_mlme_operation_in_progress(sm->vap_handle)) {
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_MLME_WAIT); 
        } else {
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_INIT); 
        }
        return true;
        break;

    case IEEE80211_ASSOC_EVENT_DEAUTH:
        ieee80211_send_event(sm, WLAN_ASSOC_SM_EVENT_REJOINING, WLAN_ASSOC_SM_REASON_DEAUTH);
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_AUTH); 
        return true;
        break;

    default:
        return false;
        
    }
}
Exemplo n.º 5
0
static bool ieee80211_btamp_conn_state_assoc_event(void *ctx, u_int16_t event, u_int16_t event_data_len, void *event_data) 
{
    wlan_btamp_conn_sm_t    sm = (wlan_btamp_conn_sm_t) ctx;
    bool                    retVal = true;

    switch(event) {
    case IEEE80211_BTAMP_CONN_EVENT_ASSOC_SUCCESS:
        ieee80211_sm_transition_to(sm->hsm_handle, IEEE80211_BTAMP_CONN_STATE_CONNECTED); 
        break;

    case IEEE80211_BTAMP_CONN_EVENT_ASSOC_FAIL:
        sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_FAILED;
        sm->last_reason = WLAN_BTAMP_CONN_SM_REASON_NONE;
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_BEACONING); 
        break;

    case IEEE80211_BTAMP_CONN_EVENT_TIMEOUT:
        if (!sm->initiating) {
            sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_FAILED;
            sm->last_reason = WLAN_BTAMP_CONN_SM_CONNECT_TIMEDOUT;
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_BEACONING); 
            break;
        }
        if (sm->cur_assoc_attempts >= sm->max_assoc_attempts) {
            IEEE80211_DPRINTF(sm->vap_handle,IEEE80211_MSG_STATE,"%s: max assoc attempts reached \n",__func__);
            sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_FAILED;
            sm->last_reason = WLAN_BTAMP_CONN_SM_CONNECT_TIMEDOUT;
            ieee80211_sm_transition_to(sm->hsm_handle, IEEE80211_BTAMP_CONN_STATE_BEACONING); 
        } else {
            IEEE80211_DPRINTF(sm->vap_handle,IEEE80211_MSG_STATE,"%s: Assoc timeout, retry ...\n",__func__);
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_ASSOC); 
        }
        break;

    case IEEE80211_BTAMP_CONN_EVENT_DISCONNECT_REQUEST:
        sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_DOWN;
        sm->last_reason = *((wlan_btamp_conn_sm_event_reason *)event_data);
        wlan_mlme_deauth_request(sm->vap_handle, sm->peer, IEEE80211_REASON_AUTH_LEAVE);
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_BEACONING); 
        break;

    case IEEE80211_BTAMP_CONN_EVENT_DEAUTH:
        sm->last_failure = WLAN_BTAMP_CONN_SM_CONNECTION_DOWN;
        sm->last_reason = WLAN_BTAMP_CONN_SM_PEER_DISCONNECTED;
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_BTAMP_CONN_STATE_BEACONING); 
        break;

    default:
        retVal = false;
        break;
    }

    return retVal;
}
Exemplo n.º 6
0
static bool ieee80211_btamp_conn_state_beaconing_event(void *ctx, u_int16_t event, u_int16_t event_data_len, void *event_data) 
{
    wlan_btamp_conn_sm_t    sm = (wlan_btamp_conn_sm_t) ctx;
    bool                    retVal = true;

    switch(event) {
    case IEEE80211_BTAMP_CONN_EVENT_CONNECT_REQUEST:
        if (sm->initiating) {
            ieee80211_sm_transition_to(sm->hsm_handle, IEEE80211_BTAMP_CONN_STATE_JOIN); 
        } else {
            ieee80211_sm_transition_to(sm->hsm_handle, IEEE80211_BTAMP_CONN_STATE_AUTH); 
        }
        break;

    case IEEE80211_BTAMP_CONN_EVENT_DISCONNECT_REQUEST:
        break;

    default:
        retVal = false;
        break;
    }
    return retVal;
}
Exemplo n.º 7
0
static bool ieee80211_assoc_state_run_event(void *ctx, u_int16_t event, u_int16_t event_data_len, void *event_data) 
{
    wlan_assoc_sm_t sm = (wlan_assoc_sm_t) ctx;
    wlan_if_t vap = sm->vap_handle;
    u_int32_t time_elapsed;

    switch(event) {
    case IEEE80211_ASSOC_EVENT_BEACON_MISS:
        sm->last_failure = WLAN_ASSOC_SM_REASON_BEACON_MISS;    /* beacon miss */ 
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_INIT); 
        return true;
        break;
    case IEEE80211_ASSOC_EVENT_DISASSOC:
        time_elapsed = CONVERT_SYSTEM_TIME_TO_MS(OS_GET_TIMESTAMP() - sm->last_connected_time);
        if ((sm->last_reason == IEEE80211_REASON_AUTH_EXPIRE || sm->last_reason == IEEE80211_REASON_ASSOC_EXPIRE) &&
            (vap->auto_assoc)) {
            ieee80211_send_event(sm, WLAN_ASSOC_SM_EVENT_REJOINING, WLAN_ASSOC_SM_REASON_DISASSOC);
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_JOIN); 
#if ATH_SUPPORT_WPA_SUPPLICANT_CHECK_TIME
        } else if(sm->cur_rejoin_attempts < vap->iv_rejoint_attemp_time ) {
            sm->cur_rejoin_attempts++;
            ieee80211_send_event(sm, WLAN_ASSOC_SM_EVENT_REJOINING, WLAN_ASSOC_SM_REASON_DISASSOC);
            ieee80211_sm_transition_to(sm->hsm_handle, IEEE80211_ASSOC_STATE_JOIN); 
        } else {
#else
        } else if(sm->cur_rejoin_attempts < REJOIN_ATTEMP_TIME && time_elapsed < REJOIN_CHECKING_TIME) {
            sm->cur_rejoin_attempts++;
            ieee80211_send_event(sm, WLAN_ASSOC_SM_EVENT_REJOINING, WLAN_ASSOC_SM_REASON_DISASSOC);
            ieee80211_sm_transition_to(sm->hsm_handle, IEEE80211_ASSOC_STATE_JOIN); 
        } else {
#endif 
            ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_INIT); 
        }
        return true;
        break;

    case IEEE80211_ASSOC_EVENT_DEAUTH:
        time_elapsed = CONVERT_SYSTEM_TIME_TO_MS(OS_GET_TIMESTAMP() - sm->last_connected_time);
        if ((sm->last_reason == IEEE80211_REASON_AUTH_EXPIRE || sm->last_reason == IEEE80211_REASON_ASSOC_EXPIRE) &&
            (vap->auto_assoc)) {
            ieee80211_send_event(sm, WLAN_ASSOC_SM_EVENT_REJOINING, WLAN_ASSOC_SM_REASON_DEAUTH);
           ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_JOIN); 
#if ATH_SUPPORT_WPA_SUPPLICANT_CHECK_TIME
        } else if(sm->cur_rejoin_attempts < vap->iv_rejoint_attemp_time ) {
            sm->cur_rejoin_attempts++;
            ieee80211_send_event(sm, WLAN_ASSOC_SM_EVENT_REJOINING, WLAN_ASSOC_SM_REASON_DEAUTH);
            ieee80211_sm_transition_to(sm->hsm_handle, IEEE80211_ASSOC_STATE_JOIN);
        } else {
#else
        } else if(sm->cur_rejoin_attempts < REJOIN_ATTEMP_TIME && time_elapsed < REJOIN_CHECKING_TIME) {
Exemplo n.º 8
0
static bool ieee80211_assoc_state_init_event(void *ctx, u_int16_t event, u_int16_t event_data_len, void *event_data) 
{
    wlan_assoc_sm_t sm = (wlan_assoc_sm_t) ctx;
    switch(event) {
    case IEEE80211_ASSOC_EVENT_CONNECT_REQUEST:
    case IEEE80211_ASSOC_EVENT_REASSOC_REQUEST:
        ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_JOIN); 
        return true;
        break;
    case IEEE80211_ASSOC_EVENT_DISCONNECT_REQUEST:
    case IEEE80211_ASSOC_EVENT_DISASSOC_REQUEST:
        return true;

    default:
        return false;
    }
}
static bool ieee80211_resmgr_state_multichan_chanswitch_event(void *ctx, u_int16_t event_type, u_int16_t event_data_len, void *event_data) 
{
    ieee80211_resmgr_t resmgr = (ieee80211_resmgr_t )ctx;
    struct ieee80211com *ic = resmgr->ic;
    ieee80211_resmgr_vap_priv_t resmgr_vap = NULL;
    ieee80211_resmgr_sm_event_t event =  (ieee80211_resmgr_sm_event_t)event_data;
    ieee80211_vap_t vap = event->vap;
    ieee80211_resmgr_notification notif;
    bool retVal = true;

    if (vap) {
        resmgr_vap = ieee80211vap_get_resmgr(vap);
    }

    switch (event_type) {
    case IEEE80211_RESMGR_EVENT_VAP_START_REQUEST:
    {
        if (!resmgr_vap)
            break;

        ieee80211_resmgr_defer_event(resmgr, resmgr_vap, event, event_type);
        break;
    }

    case IEEE80211_RESMGR_EVENT_VAP_STOPPED:
    {
        struct vap_iter_check_state_params params;

        if (!resmgr_vap)
            break;

        /* Stop associated VAP */
        resmgr_vap->state = VAP_STOPPED;

        ieee80211_resmgr_oc_sched_vap_transition(resmgr, vap, 
            resmgr_vap, OFF_CHAN_SCHED_VAP_STOPPED);
        
        OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);

        if (!params.vaps_running) {
            ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_IDLE);
        }
        break;
    }

    case IEEE80211_RESMGR_EVENT_OFFCHAN_REQUEST:
        /* Store ? */
        break;

    case IEEE80211_RESMGR_EVENT_VAP_RESUME_COMPLETE:
    {
        struct vap_iter_check_state_params params;
        resmgr_vap->state = VAP_ACTIVE;

        /* Check if all the VAPs on the channel have been unpaused */
        OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
        params.chan = ic->ic_curchan;
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);

        /* Intimate request completion to VAP module */
        if (!params.vaps_paused) {
            notif.type = IEEE80211_RESMGR_BSSCHAN_SWITCH_COMPLETE;
            notif.req_id = IEEE80211_RESMGR_REQID;
            notif.status = 0;
            notif.vap = NULL;
            IEEE80211_RESMGR_NOTIFICATION(resmgr, &notif);
            ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_BSSCHAN);
        }
        break;
    }

    case IEEE80211_RESMGR_EVENT_TSF_TIMER_EXPIRED:
    case IEEE80211_RESMGR_EVENT_TSF_TIMER_CHANGED:
    case IEEE80211_RESMGR_EVENT_OFF_CHAN_SCHED_START_REQUEST:
    case IEEE80211_RESMGR_EVENT_OFF_CHAN_SCHED_STOP_REQUEST:
        ieee80211_resmgr_off_chan_scheduler(resmgr, event_type);
        break;
        
    default:
        retVal = false;
        break;
    }

    return retVal;
}
Exemplo n.º 10
0
static bool ieee80211_resmgr_state_multichan_pausing_event(void *ctx, u_int16_t event_type, u_int16_t event_data_len, void *event_data) 
{
    ieee80211_resmgr_t resmgr = (ieee80211_resmgr_t) ctx;
    ieee80211_resmgr_sm_event_t event =  (ieee80211_resmgr_sm_event_t)event_data;
    ieee80211_vap_t vap = event->vap;
    ieee80211_resmgr_vap_priv_t resmgr_vap = NULL;
    struct ieee80211com *ic = resmgr->ic;
    bool retVal=true;
    ieee80211_resmgr_notification notif;         

    if (vap) {
        resmgr_vap = ieee80211vap_get_resmgr(vap);
    }

    switch (event_type) {
    case IEEE80211_RESMGR_EVENT_VAP_START_REQUEST:
    {
        if (resmgr_vap)
            break;

        /* Store and change state after all the vaps are paused */
        ieee80211_resmgr_defer_event(resmgr, resmgr_vap, event, event_type);
        break;
    }

    case IEEE80211_RESMGR_EVENT_VAP_STOPPED:
    {
        struct vap_iter_check_state_params params;

        if (resmgr_vap)
            break;

        /* Stop associated VAP */
        resmgr_vap->state = VAP_STOPPED;

        ieee80211_resmgr_oc_sched_vap_transition(resmgr, vap, 
            resmgr_vap, OFF_CHAN_SCHED_VAP_STOPPED);
        
        OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);
        if (!params.vaps_running) {
            ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_IDLE);
        }
        break;
    }

    case IEEE80211_RESMGR_EVENT_VAP_PAUSE_COMPLETE:
    {
        struct vap_iter_check_state_params params;

        if (resmgr_vap->state != VAP_STOPPED) {
            /* If VAP is already stopped, don't update state */
            resmgr_vap->state = VAP_PAUSED;
        }

        /* Check if all the VAPs are paused */
        OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);

        if (!params.vaps_active) {
            if (resmgr->cancel_pause) {
                /* Pending pause cancel */
                resmgr->scandata.chan = ic->ic_curchan;
                resmgr->cancel_pause = false;
                ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_RESUMING);
            } else {
                ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_OFFCHAN);
            }
        } else if (params.vaps_active == 1 && resmgr->pause_failed) {
            if (resmgr->cancel_pause) {
                /* Pending pause cancel */
                resmgr->scandata.chan = ic->ic_curchan;
                resmgr->cancel_pause = false;
                ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_RESUMING);
            } else {
                struct vap_iter_unpause_params unpause_params = {0, 0};
                /* Unpause VAPs on channel */
                unpause_params.chan = ic->ic_curchan;
                wlan_iterate_vap_list(ic, ieee80211_vap_iter_unpause_request, &unpause_params);
                resmgr->pause_failed = false;
            }
        }
        break;
    }

    case IEEE80211_RESMGR_EVENT_VAP_PAUSE_FAIL:
    {
        struct vap_iter_check_state_params params;

        /* Unpause VAPs operating on channel */
        OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
        params.chan = ic->ic_curchan; 
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);

        if (params.vaps_active > 1) {
            /* VAPs still in the process of pausing, need to unpaused them after they are paused */
            resmgr->pause_failed = true;

        } else if (params.vaps_paused) {
            if (resmgr->cancel_pause) {
                /* Pending pause cancel */
                resmgr->scandata.chan = ic->ic_curchan;
                resmgr->cancel_pause = false;
                ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_RESUMING);
            } else {
                struct vap_iter_unpause_params unpause_params = {0, 0};
                /* Unpause VAPs on channel */
                unpause_params.chan = ic->ic_curchan;
                wlan_iterate_vap_list(ic, ieee80211_vap_iter_unpause_request, &unpause_params);
            }
        } else {
            /* Check if there is a cancel pending */
            if (resmgr->cancel_pause) {
                resmgr->cancel_pause = false;
                notif.type = IEEE80211_RESMGR_BSSCHAN_SWITCH_COMPLETE;
                notif.status = EOK;
            } else {
                notif.type = IEEE80211_RESMGR_OFFCHAN_SWITCH_COMPLETE;
                notif.status = EIO;
            }
            notif.req_id = IEEE80211_RESMGR_REQID;
            notif.vap = NULL;
            IEEE80211_RESMGR_NOTIFICATION(resmgr, &notif);

            ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_BSSCHAN);
        }
        break;
    }

    case IEEE80211_RESMGR_EVENT_BSSCHAN_REQUEST:
    {
        /* Equivalent to cancelling the off channel request */
        struct vap_iter_check_state_params params;

        /* Unpause VAPs operating on channel */
        OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
        params.chan = ic->ic_curchan; 
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);

        if (params.vaps_active) {
            /* VAPs still in the process of pausing, unpause them after pause completion */
            resmgr->cancel_pause = true;

        } else if (params.vaps_paused) {
            resmgr->scandata.chan = ic->ic_curchan;
            ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_RESUMING);
        } else {
            resmgr->scandata.chan = NULL;

            /* Intimate request completion */
            notif.type = IEEE80211_RESMGR_BSSCHAN_SWITCH_COMPLETE;
            notif.req_id = IEEE80211_RESMGR_REQID;
            notif.status = 0;
            notif.vap = NULL;
            IEEE80211_RESMGR_NOTIFICATION(resmgr, &notif);

            ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_BSSCHAN);
        }
        break;
    }

    case IEEE80211_RESMGR_EVENT_VAP_RESUME_COMPLETE:
    {
        struct vap_iter_check_state_params params;
        resmgr_vap->state = VAP_ACTIVE;

        /* Check if all the VAPs on the channel have been unpaused */
        OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
        params.chan = ic->ic_curchan;
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);

        /* Intimate Pause failure to Scan Module */
        if (!params.vaps_paused) {
            if (resmgr->cancel_pause) {
                resmgr->cancel_pause = false;
                notif.type = IEEE80211_RESMGR_BSSCHAN_SWITCH_COMPLETE;
                notif.status = EOK;
            } else {
                notif.type = IEEE80211_RESMGR_OFFCHAN_SWITCH_COMPLETE;
                notif.status = EIO;
            }
            notif.req_id = IEEE80211_RESMGR_REQID;
            notif.vap = NULL;
            IEEE80211_RESMGR_NOTIFICATION(resmgr, &notif);

            ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_BSSCHAN);
        }
        break;
    }
    
    case IEEE80211_RESMGR_EVENT_TSF_TIMER_EXPIRED:
    case IEEE80211_RESMGR_EVENT_TSF_TIMER_CHANGED:
    case IEEE80211_RESMGR_EVENT_OFF_CHAN_SCHED_START_REQUEST:
    case IEEE80211_RESMGR_EVENT_OFF_CHAN_SCHED_STOP_REQUEST:
        ieee80211_resmgr_off_chan_scheduler(resmgr, event_type);
        break;
        
    default:
        retVal = false;
        break;
    }

    return retVal;
}
Exemplo n.º 11
0
static void
ieee80211_resmgr_process_deferred_events(ieee80211_resmgr_t resmgr)
{
    ieee80211_vap_t vap = NULL;
    ieee80211_resmgr_sm_event_t event = NULL;
    u_int16_t event_type = 0;
    ieee80211_resmgr_vap_priv_t resmgr_vap = NULL;
    struct ieee80211com *ic = resmgr->ic;
    bool dispatch_event = false;

    /*
     * This is a stable state, process deferred events if any ... 
     * Preference goes to deferred events from VAP first and then to SCAn
     */
    wlan_iterate_vap_list(ic, ieee80211_vap_iter_get_def_event, &vap);
    if (vap) {
        resmgr_vap = ieee80211vap_get_resmgr(vap);
        event = &resmgr_vap->def_event;
        event_type  = resmgr_vap->def_event_type;
    }

    if (event_type) {
        switch(event_type) {
        case IEEE80211_RESMGR_EVENT_VAP_START_REQUEST:
        {
            dispatch_event = true;
#if 0
            struct vap_iter_check_state_params params;
        
            resmgr_vap->state = VAP_STARTING;       
            resmgr_vap->chan = event->chan;

            /* Check for other active VAPs */
            OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
            wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);

            /* Clear deferred event before changing state */
            resmgr_vap->def_event = NULL;    
            resmgr_vap->def_event_type = 0;

            if (params.vaps_active) {
                if (resmgr->mode == IEEE80211_RESMGR_MODE_SINGLE_CHANNEL) {
                    /* Single Channel Operation
                     * New STA Vap - Switch other vaps to its channel 
                     * New non-STA Vap - Start on channel being used
                     */
                    if (vap->iv_opmode == IEEE80211_M_STA) {
                        /* Send channel switch request to active VAPs on different channels */
                        wlan_iterate_vap_list(ic, ieee80211_vap_iter_chanswitch_request, resmgr_vap->chan);
                        ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_VAP_PRESTART);
                    } else {
                        resmgr_vap->chan = ic->ic_curchan; 
                        ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_VAP_STARTING);
                    }
                }
            } else {
                ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_VAP_STARTING);
            }
#endif
            break;
        }

        default:
            break;
        }

        if (dispatch_event) {
            ieee80211_resmgr_sm_dispatch(resmgr,
                                         event_type,
                                         sizeof(struct ieee80211_resmgr_sm_event),
                                         (void *)event);
            dispatch_event = false;
        }

        /* Clear deferred event */
        ieee80211_resmgr_clear_event(resmgr, resmgr_vap);
    }

    if (resmgr->scandata.def_event_type) {    
        event = &resmgr->scandata.def_event;
        event_type = resmgr->scandata.def_event_type;

        switch(event_type) {
        case IEEE80211_RESMGR_EVENT_OFFCHAN_REQUEST:
            dispatch_event = true;
#if 0
            /* Setup channel to be set after VAPs are paused */
            resmgr->scandata.chan = event->chan;
            resmgr->scandata.canpause_timeout = event->max_time ? event->max_time: CANPAUSE_INFINITE_WAIT;

            /* Clear deferred event before changing state */
            resmgr->scandata.def_event = NULL;    
            resmgr->scandata.def_event_type = 0;

            ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_CANPAUSE);
#endif
            break;

        default:
            break;
        }

        if (dispatch_event) {
            ieee80211_resmgr_sm_dispatch(resmgr,
                                         event_type,
                                         sizeof(struct ieee80211_resmgr_sm_event),
                                         (void *)event);
        }
        ieee80211_resmgr_clear_event(resmgr, NULL);
    }
}