コード例 #1
0
ファイル: ieee80211_resmgr.c プロジェクト: KHATEEBNSIT/AP
/*
 * BSS channel request. (Scan Module)
 */
int ieee80211_resmgr_request_bsschan(ieee80211_resmgr_t resmgr,
                                     u_int16_t reqid)
{
    struct ieee80211_resmgr_sm_event event;
    struct vap_iter_check_state_params params;
    struct ieee80211com *ic = resmgr->ic;

    event.vap = NULL;
    event.chan = NULL; 

    if (ieee80211_resmgr_active(ic)) {
        /* ResMgr SM active, check for active VAPs */
        OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);

        /* If there are no VAPs active, there is no BSS channel. Scanner can continueously scan all channels */
        if (!params.vaps_running && !params.vap_starting) {
            return EINVAL;
        }
    }
    
    /* Post event to ResMgr SM */
    if (ieee80211_resmgr_sm_dispatch(resmgr, IEEE80211_RESMGR_EVENT_BSSCHAN_REQUEST, &event) == EOK){
        return EBUSY;  /* processing req asynchronously */
    } else {
        return EOK;    /* caller can change channel */
    }
}
コード例 #2
0
ファイル: ieee80211_resmgr.c プロジェクト: KHATEEBNSIT/AP
static void ieee80211_resmgr_reset_power_state(ieee80211_resmgr_t resmgr)
{
    int pm_state;
    struct ieee80211com *ic = resmgr->ic;
    ieee80211_resmgr_vap_pmstate_t combined_state = VAP_PM_FULL_SLEEP;

    IEEE80211_RESMGR_LOCK(resmgr);

    if (resmgr->is_scan_in_progress) {
        combined_state = VAP_PM_ACTIVE;
    } else {
        wlan_iterate_vap_list(ic, ieee80211_vap_iter_pm_state, (void *)&combined_state);
    }

    switch(combined_state) {
    case VAP_PM_FULL_SLEEP:
        pm_state = IEEE80211_PWRSAVE_FULL_SLEEP;
        break;
    case VAP_PM_NW_SLEEP:
        pm_state = IEEE80211_PWRSAVE_NETWORK_SLEEP;
        break;
    default:
        pm_state = IEEE80211_PWRSAVE_AWAKE;
        break;
    }
    if (pm_state != resmgr->pm_state) {
        IEEE80211_DPRINTF_IC(ic, IEEE80211_MSG_POWER, IEEE80211_VERBOSE_LOUD,
                "%s: changing chip power state from %s to %s \n",
                __func__, state_to_name[resmgr->pm_state],
                state_to_name[pm_state]);
        resmgr->pm_state = pm_state;
        ic->ic_pwrsave_set_state(ic, pm_state);
    }
    IEEE80211_RESMGR_UNLOCK(resmgr);
}
コード例 #3
0
ファイル: ieee80211_common.c プロジェクト: KHATEEBNSIT/AP
/*
 * returns number of vaps ready.
 */
u_int16_t
ieee80211_vaps_ready(struct ieee80211com *ic, enum ieee80211_opmode opmode)
{
    struct ieee80211_iter_vaps_ready_arg params;
    u_int16_t nready = 0;
    OS_MEMZERO(&params, sizeof(params));
    wlan_iterate_vap_list(ic,ieee80211_vap_iter_ready_vaps,(void *) &params);
    switch(opmode) {
        case IEEE80211_M_HOSTAP:
        case IEEE80211_M_BTAMP:
            nready = params.num_ap_vaps_ready;
            break;

        case IEEE80211_M_IBSS:
            nready = params.num_ibss_vaps_ready;
            break;

        case IEEE80211_M_STA:
            nready = params.num_sta_vaps_ready;
            break;

        default:
            break;
    }
    return nready;
}
コード例 #4
0
ファイル: ieee80211_common.c プロジェクト: KHATEEBNSIT/AP
/*
 * returns number of vaps active.
 */
u_int16_t
ieee80211_vaps_active(struct ieee80211com *ic)
{
    u_int16_t nactive=0;
    wlan_iterate_vap_list(ic,ieee80211_vap_iter_active_vaps,(void *) &nactive);
    return nactive;
}
コード例 #5
0
/*
 * State PAUSING
 */
static void ieee80211_resmgr_state_multichan_pausing_entry(void *ctx) 
{
    ieee80211_resmgr_t resmgr = (ieee80211_resmgr_t) ctx;
    struct ieee80211com *ic = resmgr->ic;

    /* Send Pause request to all active VAPs */
    wlan_iterate_vap_list(ic, ieee80211_vap_iter_pause_request, NULL);
}
コード例 #6
0
ファイル: ieee80211_common.c プロジェクト: KHATEEBNSIT/AP
systime_t
ieee80211com_get_traffic_indication_timestamp(struct ieee80211com *ic)
{
    systime_t    traffic_timestamp = 0;

    wlan_iterate_vap_list(ic, ieee80211_vap_iter_last_traffic_timestamp,(void *) &traffic_timestamp);

    return traffic_timestamp;
}
コード例 #7
0
ファイル: ieee80211_common.c プロジェクト: KHATEEBNSIT/AP
/*
 * Per-ieee80211com inactivity timer callback.
 * used for checking any kind of inactivity in the
 * COM device.
 */
static OS_TIMER_FUNC(ieee80211_inact_timeout)
{
	struct ieee80211com *ic;
    OS_GET_TIMER_ARG(ic, struct ieee80211com *);
    ieee80211_timeout_stations(&ic->ic_sta);
    ieee80211_timeout_fragments(ic, IEEE80211_FRAG_TIMEOUT*1000);
    wlan_iterate_vap_list(ic,ieee80211_vap_iter_mlme_inact_timeout,NULL);
    OS_SET_TIMER(&ic->ic_inact_timer, IEEE80211_INACT_WAIT*1000);
}
コード例 #8
0
ファイル: ieee80211_mlme_sta.c プロジェクト: jorneytu/wlan
void 
ieee80211_beacon_miss(struct ieee80211com *ic)
{
    /*
     * Do not ignore a beacon miss during scan now that the scan algorithm 
     * has frequent returns to the home channel,
     */

    if (IEEE80211_IS_RADAR_ENABLED(ic))
        return;

    wlan_iterate_vap_list(ic, ieee80211_vap_iter_beacon_miss, NULL);
}
コード例 #9
0
/*
 * State RESUMING
 */
static void ieee80211_resmgr_state_multichan_chanswitch_entry(void *ctx) 
{
    ieee80211_resmgr_t resmgr = (ieee80211_resmgr_t) ctx;
    struct ieee80211com *ic = resmgr->ic;
    struct vap_iter_unpause_params params = {0, 0};

    /* Set required channel */
    ic->ic_curchan = resmgr->scandata.chan;
    ic->ic_scan_end(ic);
    ic->ic_set_channel(ic);

    /* Unpause VAPs operating on selected BSS channel */
    params.chan = ic->ic_curchan;
    wlan_iterate_vap_list(ic, ieee80211_vap_iter_unpause_request, &params);
}
コード例 #10
0
/*
 * Set country code
 */
int
ieee80211_set_country_code(struct ieee80211com *ic, char *isoName, u_int16_t cc, enum ieee80211_clist_cmd cmd)
{
    int  error;

    if (!cc) {
        if (isoName == NULL) {
            if (!IEEE80211_IS_11D_ENABLED(ic))
                return 0;
        } else if((ic->ic_country_iso[0] == isoName[0]) &&
                (ic->ic_country_iso[1] == isoName[1]) &&
                (ic->ic_country_iso[2] == isoName[2])) {
            return 0;
        }
    }

    IEEE80211_DISABLE_11D(ic);

    error = ic->ic_set_country(ic, isoName, cc, cmd);
    if (error)
        return error;

    /* update the country information for 11D */
    ic->ic_get_currentCountry(ic, &ic->ic_country);

    /* update channel list */
    ieee80211_update_channellist(ic, 1);
    
    ic->ic_country_iso[0] = ic->ic_country.iso[0];
    ic->ic_country_iso[1] = ic->ic_country.iso[1];
    ic->ic_country_iso[2] = ic->ic_country.iso[2];

    ieee80211_build_countryie_all(ic);

    if (IEEE80211_IS_COUNTRYIE_ENABLED(ic)) {
        IEEE80211_ENABLE_11D(ic);
    }

    /* notify all vaps that the country changed */
    wlan_iterate_vap_list(ic, wlan_notify_country_changed, (void *)ic->ic_country.iso);

    return 0;
}
コード例 #11
0
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;
}
コード例 #12
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;
}
コード例 #13
0
static bool ieee80211_resmgr_state_multichan_idle_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;
    bool retVal = true;
    struct ieee80211com *ic = resmgr->ic;
    ieee80211_resmgr_oc_scheduler_operation_data_t next_scheduled_operation = {OC_SCHED_OP_NONE, NULL};
    ieee80211_vap_t curr_vap, next_vap;
    bool transition_vap = false;
    bool transition_scan = false;
    bool check_scheduled_operation = false;
    
    if (vap) {
        resmgr_vap = ieee80211vap_get_resmgr(vap);
    }

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

        ieee80211_resmgr_oc_sched_set_state(resmgr, OC_SCHEDULER_ON);

        /* Turn scheduler on before invoking next routine */
        ieee80211_resmgr_oc_sched_vap_transition(resmgr, vap,
            resmgr_vap, OFF_CHAN_SCHED_VAP_START);
        
        resmgr_vap->state = VAP_STARTING;
        resmgr_vap->chan = event->chan;
        
        DBG_PRINTK("VAP_STARTING:  resmgr_vap->chan = 0x%08x\n", resmgr_vap->chan);
        check_scheduled_operation = true;
        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);
        
        /* Check if any other vaps exist */
        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 && !params.vap_starting) {
            ieee80211_resmgr_oc_sched_set_state(resmgr, OC_SCHEDULER_OFF); 
        }
        else {          
            check_scheduled_operation = true;
        }
        break;
    }

    case IEEE80211_RESMGR_EVENT_VAP_UP:
    {
        struct vap_iter_unpause_params params = {0, 0};
    
        resmgr_vap->state = VAP_ACTIVE;
    
        ieee80211_resmgr_oc_sched_vap_transition(resmgr, vap, 
            resmgr_vap, OFF_CHAN_SCHED_VAP_UP);
        
        /* Unpause VAP's on same channel */
        params.chan = resmgr_vap->chan;
        if (resmgr->mode == IEEE80211_RESMGR_MODE_MULTI_CHANNEL) {
            wlan_iterate_vap_list(ic, ieee80211_vap_iter_unpause_request, &params);
        } else {
            wlan_iterate_vap_list(ic, ieee80211_vap_iter_resume_request, &params);
        }
    
        break;
    }
        
    case IEEE80211_RESMGR_EVENT_VAP_PAUSE_COMPLETE:
    case IEEE80211_RESMGR_EVENT_VAP_PAUSE_FAIL:
    case IEEE80211_RESMGR_EVENT_VAP_RESUME_COMPLETE:
    case IEEE80211_RESMGR_EVENT_CHAN_SWITCH_REQUEST:
    case IEEE80211_RESMGR_EVENT_CSA_COMPLETE:
    case IEEE80211_RESMGR_EVENT_SCHED_BSS_REQUEST:
        DBG_PRINTK("%s : [*** WARNING ***] Encountered unhandled event_type!!\n", __func__);        
        ASSERT(0);
        break;
        
    case IEEE80211_RESMGR_EVENT_BSSCHAN_REQUEST:
    {
        ieee80211_resmgr_notification notif;

        /* Is Off-Channel Scheduler active? */
        if (ieee80211_resmgr_oc_sched_get_state(resmgr) != OC_SCHEDULER_ON) {       
            /* Set home channel */
            ASSERT(resmgr->scandata.chan); /* scanner should go to foreign first? */
            if (resmgr->scandata.chan)
                ic->ic_curchan = resmgr->scandata.chan;
            ic->ic_set_channel(ic);
        }
        
        resmgr->scandata.chan = NULL;
        resmgr->scandata.scan_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);
        break;
    }

    case IEEE80211_RESMGR_EVENT_OFFCHAN_REQUEST:
    {
        ieee80211_resmgr_notification notif;

        /* Store current channel as home channel */
        resmgr->scandata.chan = ic->ic_curchan;
        resmgr->scandata.scan_chan = event->chan;

        /* Is Off-Channel Scheduler active? */
        if (ieee80211_resmgr_oc_sched_get_state(resmgr) != OC_SCHEDULER_ON) {       
            /* Set desired channel */
            ic->ic_curchan = event->chan;
            ic->ic_scan_start(ic);
            ic->ic_set_channel(ic);

            /* Intimate request completion */
            notif.type = IEEE80211_RESMGR_OFFCHAN_SWITCH_COMPLETE;
            notif.req_id = IEEE80211_RESMGR_REQID;
            notif.status = EOK;
            notif.vap = NULL;
            IEEE80211_RESMGR_NOTIFICATION(resmgr, &notif);
        }
        else {
            DBG_PRINTK("%s : OFFCHAN_REQ - max_dwell_time = %d\n", __func__, event->max_dwell_time);
            ieee80211_resmgr_oc_sched_req_duration_usec_set(resmgr->scandata.oc_sched_req, event->max_dwell_time * 1000);
            ieee80211_resmgr_oc_sched_req_start(resmgr, resmgr->scandata.oc_sched_req);
            
            ieee80211_resmgr_off_chan_scheduler(resmgr, IEEE80211_RESMGR_EVENT_OFF_CHAN_SCHED_START_REQUEST);           
        }
        
        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);
        check_scheduled_operation = true;
        break;
        
    default:
        retVal = false;
        break;
    }

    if (ieee80211_resmgr_oc_sched_get_state(resmgr) == OC_SCHEDULER_ON) {
        
        if (check_scheduled_operation == true) {
            
            /* Fetch next scheduled operation */
            ieee80211_resmgr_oc_sched_get_scheduled_operation(resmgr, &next_scheduled_operation);

            next_vap = next_scheduled_operation.vap;

            /* Take care of post operation cleanup */
            
            switch (next_scheduled_operation.operation_type) {
                
            case OC_SCHED_OP_VAP:           
                if (resmgr->current_scheduled_operation.operation_type == OC_SCHED_OP_VAP) {
                    curr_vap = resmgr->current_scheduled_operation.vap;
                    resmgr_vap = ieee80211vap_get_resmgr(curr_vap); 
                    
                    if (next_vap != curr_vap) {                     
                        DBG_PRINTK("OP_VAP:  vap_force_pause curr_vap = 0x%08x\n", curr_vap);
                        
                        /* Force pause the currently active VAP */
                        curr_vap->iv_ic->ic_vap_pause_control(curr_vap->iv_ic,curr_vap,true);
                        //ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_PAUSING);
                        
                        resmgr_vap->state = VAP_PAUSED;
                        transition_vap = true;
                    }
                }
                else {
                    transition_vap = true;
                }
                break;
                
            case OC_SCHED_OP_SCAN:
                transition_scan = true;
                /* Falling through INTENTIONALLY */
            case OC_SCHED_OP_SLEEP:
                if (resmgr->current_scheduled_operation.operation_type == OC_SCHED_OP_VAP) {
                    curr_vap = resmgr->current_scheduled_operation.vap;
                    resmgr_vap = ieee80211vap_get_resmgr(curr_vap); 
                    
                    DBG_PRINTK("OP_SCAN:  vap_force_pause curr_vap = 0x%08x\n", curr_vap);

                    /* Force pause the current VAP */
                    curr_vap->iv_ic->ic_vap_pause_control(curr_vap->iv_ic,curr_vap,true);
                    //ieee80211_sm_transition_to(resmgr->hsm_handle, IEEE80211_RESMGR_STATE_PAUSING);
                    
                    
                    resmgr_vap->state = VAP_PAUSED;
                }           
                break;
                
            case OC_SCHED_OP_NOP:
            case OC_SCHED_OP_NONE:
            default:
                break;
            }

            /* Initiate the next operation */
            if (transition_scan == true) {
                
                DBG_PRINTK("%s : transition_scan == true\n", __func__);
                ieee80211_resmgr_notification notif;
                    
                /* Set desired channel */
                ic->ic_curchan = resmgr->scandata.scan_chan;
                ic->ic_scan_start(ic);
                ic->ic_set_channel(ic);

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

            if (transition_vap == true) {
                if (next_vap != NULL) {
                    
                    DBG_PRINTK("%s : transition_vap == true\n", __func__);                  
                    resmgr_vap = ieee80211vap_get_resmgr(next_vap);

                    switch (resmgr_vap->state) {
                    case VAP_STARTING:
                        {
                            ieee80211_resmgr_notification notif;
                            struct vap_iter_check_state_params params;
                            
                            /* Check if this is the first VAP starting */
                            OS_MEMZERO(&params, sizeof(struct vap_iter_check_state_params));
                            wlan_iterate_vap_list(ic, ieee80211_vap_iter_check_state, &params);
                            
                            /* Set the requested channel */
                            if (resmgr_vap && (!params.vaps_active || !IS_CHAN_EQUAL(ic->ic_curchan, resmgr_vap->chan))) {
                                ic->ic_curchan = resmgr_vap->chan;
                                ic->ic_bsschan = ic->ic_curchan;
                                ic->ic_set_channel(ic);
                                ieee80211_reset_erp(ic, ic->ic_curmode, next_vap->iv_opmode);
                                ieee80211_wme_initparams(next_vap);
                            }
                            
                            /* Set passed channel as BSS channel */
                            ic->ic_bsschan = ic->ic_curchan;
                            
                            /* Intimate start completion to VAP module */
                            notif.type = IEEE80211_RESMGR_VAP_START_COMPLETE;
                            notif.req_id = IEEE80211_RESMGR_REQID;
                            notif.status = 0;
                            notif.vap = next_vap;
                            IEEE80211_RESMGR_NOTIFICATION(resmgr, &notif);
                        }
                        break;
                        
                    case VAP_PAUSED:
                        DBG_PRINTK("%s : vap_force_unpause; next_vap\n", __func__);
                        
                        next_vap->iv_ic->ic_vap_pause_control(next_vap->iv_ic, next_vap, false);
                        resmgr_vap->state = VAP_ACTIVE;
                        break;
                        
                    default:
                        if (ic->ic_curchan != resmgr_vap->chan) {
                            /* Set home channel */
                            DBG_PRINTK("%s : resmgr_vap->chan = 0x%08x\n", __func__, resmgr_vap->chan);
                            ic->ic_curchan = resmgr_vap->chan;
                            ic->ic_set_channel(ic);
                        }
                        break;
                    }
                }
            }
        }
    }
    
    return retVal;
}
コード例 #14
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);
    }
}
コード例 #15
0
ファイル: ieee80211_common.c プロジェクト: KHATEEBNSIT/AP
void
ieee80211_get_vap_opmode_count(struct ieee80211com *ic,
                               struct ieee80211_vap_opmode_count *vap_opmode_count)
{
    wlan_iterate_vap_list(ic, ieee80211_iter_vap_opmode, (void *) vap_opmode_count);
}