Example #1
0
/* Receive assoc/reassoc response 
 * - the caller of this routine validates the frame and ensures that the opmode == STA
 */
void ieee80211_mlme_recv_assoc_response(struct ieee80211_node *ni, 
                                        int                   subtype,
                                        u_int16_t             capability, 
                                        u_int16_t             status_code, 
                                        u_int16_t             aid,
                                        u_int8_t              *ie_data, 
                                        u_int32_t             ie_length, 
                                        wbuf_t                wbuf)
{
    struct ieee80211vap           *vap = ni->ni_vap;
    struct ieee80211_mlme_priv    *mlme_priv = vap->iv_mlme_priv;
    struct ieee80211com           *ic = ni->ni_ic;    
    int                           mlme_request_type = mlme_priv->im_request_type;
    int                           error;
    u_int32_t                     rxlinkspeed, txlinkspeed; /* bits/sec */

    IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s im_request_type=%d status=%d (0x%08X)\n", 
        __func__,
        mlme_priv->im_request_type,
        status_code, status_code);

    /* Ignore if no request in progress */
    if ((mlme_priv->im_request_type != MLME_REQ_ASSOC) &&
        (mlme_priv->im_request_type != MLME_REQ_REASSOC))
    {
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Incorrect request type %d\n", 
            __func__, mlme_priv->im_request_type);
        return;
    }

    if (!OS_CANCEL_TIMER(&mlme_priv->im_timeout_timer)) {
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Timed-out already\n", __func__);
        return;
    }

    if (status_code != IEEE80211_STATUS_SUCCESS) {
        goto complete;
    }

    /* Validate AID */
    aid  &= ~IEEE80211_FIELD_TYPE_AID;
    if ((aid > 2007) || (aid == 0))
    {
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Association response contains invalid AID=%d\n", __func__, aid);
        status_code = IEEE80211_STATUS_UNSPECIFIED;
        goto complete;
    }

    error = mlme_process_asresp_elements(ni, ie_data, ie_length);
    if (error) {
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: mlme_process_asresp_elements failed\n", __func__);
        status_code = IEEE80211_STATUS_UNSPECIFIED;
        goto complete;
    }

    /* Association successful */

complete:
    switch (mlme_priv->im_request_type) {
    case MLME_REQ_ASSOC:
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: mlme_assoc_complete status %d\n", __func__, status_code);
        if (subtype != IEEE80211_FC0_SUBTYPE_ASSOC_RESP) {
			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY, "%s: mlme_assoc_complete status type mismatched %d\n", __func__, subtype);
			return;
        }
        break;

    case MLME_REQ_REASSOC:
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: mlme_reassoc_complete status %d\n", __func__, status_code);
        if (subtype != IEEE80211_FC0_SUBTYPE_REASSOC_RESP) {
			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY, "%s: mlme_assoc_complete status type mismatched %d\n", __func__, subtype);
			return;
        }
        break;

    default:
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY, "%s: mlme_reassoc_complete status %d unexpected request type %d\n", 
            __func__, status_code, mlme_priv->im_request_type);
        return;
    }

    /* Request complete */
    mlme_priv->im_request_type = MLME_REQ_NONE;

    if (status_code == IEEE80211_STATUS_SUCCESS) {
        ASSERT(aid != 0);
        ni->ni_associd = aid;
        ni->ni_assoctime = OS_GET_TICKS() - ni->ni_assocstarttime;
#if ATH_SUPPORT_HTC
        ieee80211_update_node_target(ni, ni->ni_vap);
#endif            

        /* Association successful, put underlying H/W into ready state */
        ieee80211_vap_start(vap);
		/*AUTELAN-Added-Begin:Deleted by duanmingzhe for RIFS+LDPC issue*/
        //if (ni->ni_htcap & IEEE80211_HTCAP_C_ADVCODING)
        //    ic->ic_enable_rifs_ldpcwar(ni, 0);
        //else
        //    ic->ic_enable_rifs_ldpcwar(ni, 1);  
		/*AUTELAN-Added-End:Deleted by duanmingzhe for RIFS+LDPC issue*/      
    }

    /* indicate linkspeed */
     mlme_get_linkrate(ni, &rxlinkspeed, &txlinkspeed);
     IEEE80211_DELIVER_EVENT_LINK_SPEED(vap, rxlinkspeed, txlinkspeed);

    /* Association complete (success or failure) */
    switch (mlme_request_type) {
    case MLME_REQ_ASSOC:
        IEEE80211_DELIVER_EVENT_MLME_ASSOC_COMPLETE(vap, status_code, aid, wbuf);
        break;

    case MLME_REQ_REASSOC:
        IEEE80211_DELIVER_EVENT_MLME_REASSOC_COMPLETE(vap, status_code, aid, wbuf);
        break;

    default:
        break;
    }
}
Example #2
0
void
ieee80211_add_node_target(struct ieee80211_node *ni, struct ieee80211vap *vap,
    u_int8_t is_vap_node)
{
    struct ieee80211_node_target nt, *ntar;
    int i;
    u_int8_t nodeindex = 0;
    u_int8_t vapindex = 0xff;
    
    OS_MEMZERO(&nt, sizeof(struct ieee80211_node_target));

    //printk("%s: vap: 0x%08x, ni: 0x%08x, is_vap_node: %d\n", __FUNCTION__, vap, ni, is_vap_node);
    //print_target_node_bitmap(ni);

    for (i = 0; i < HTC_MAX_NODE_NUM; i++) {
        /* avoid upper layer add the same vap twice */
        if (IEEE80211_ADDR_EQ(ni->ni_ic->target_node_bitmap[i].ni_macaddr, ni->ni_macaddr)) {
            printk("%s: add the same node : Updating Target node  %d\n", __FUNCTION__, i);
            ieee80211_update_node_target(ni, ni->ni_vap); 
            return;
        }

        if (ni->ni_ic->target_node_bitmap[i].ni_valid == 0) {
            IEEE80211_ADDR_COPY(ni->ni_ic->target_node_bitmap[i].ni_macaddr, ni->ni_macaddr);
            ni->ni_ic->target_node_bitmap[i].ni_valid = 1;
            nodeindex = i;
            break;
        }
    }

    if (i == HTC_MAX_NODE_NUM) {
        printk("%s: exceed maximum node number\n", __FUNCTION__);
        return;
    }

    /* search for vap index of this node */
    for (i = 0; i < HTC_MAX_VAP_NUM; i++) {
        if (ni->ni_ic->target_vap_bitmap[i].vap_valid == 1 && 
            IEEE80211_ADDR_EQ(ni->ni_ic->target_vap_bitmap[i].vap_macaddr, ni->ni_vap->iv_myaddr)) {
            vapindex = i;
            break;
        }
    }

    /*
     * Fill the target node nt.
     */
    nt.ni_associd    = htons(ni->ni_associd);
    nt.ni_txpower    = htons(ni->ni_txpower);

    IEEE80211_ADDR_COPY(&nt.ni_macaddr, &(ni->ni_macaddr));
    IEEE80211_ADDR_COPY(&nt.ni_bssid, &(ni->ni_bssid));

    nt.ni_nodeindex  = nodeindex;//ni->ni_nodeindex;
    nt.ni_vapindex   = vapindex;
    nt.ni_vapnode    = 0;//add for rate control test
    nt.ni_flags      = htonl(ni->ni_flags);

    nt.ni_htcap      = htons(ni->ni_htcap);
    nt.ni_capinfo    = htons(ni->ni_capinfo);
    nt.ni_is_vapnode = is_vap_node; //1;
    nt.ni_maxampdu   = htons(ni->ni_maxampdu);
#ifdef ENCAP_OFFLOAD    
    nt.ni_ucast_keytsc = 0;
    nt.ni_mcast_keytsc = 0;
#endif

#ifdef ATH_SUPPORT_QUICK_KICKOUT
   nt.ni_kickoutlimit =  ni->ni_vap->iv_sko_th;
#else
#define ATH_NODEKICKOUT_LIMIT 50    
   nt.ni_kickoutlimit = ATH_NODEKICKOUT_LIMIT;
#endif
    
    ntar = &nt;
   
    /* save information to node target */
    ni->ni_ic->target_node_bitmap[nodeindex].ni_nodeindex = nodeindex;
    ni->ni_ic->target_node_bitmap[nodeindex].ni_vapindex = vapindex;
    ni->ni_ic->target_node_bitmap[nodeindex].ni_is_vapnode = is_vap_node;

    ni->ni_ic->ic_add_node_target(ni->ni_ic, ntar, sizeof(struct ieee80211_node_target));
    //print_nt(&nt);
}