connect.c

来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 652 行 · 第 1/2 页

C
652
字号
        *(ptr + 2) = 1;
        *(ptr + 3) = pAd->PortCfg.Channel;
        *(ptr + 4) = 0;//pAd->PortCfg.RadarDetect.CSCount;
        ptr      += 5;
        FrameLen += 5;
    }

	// step 2 - update TIM IE
    if (pAd->Mlme.DtimCount == 0)
        pAd->Mlme.DtimCount = pAd->Mlme.DtimPeriod - 1;
    else
        pAd->Mlme.DtimCount -= 1;
    
    ptr = (UCHAR *)pBcnHdr + FrameLen;
    *ptr = IE_TIM;
    *(ptr + 2) = pAd->Mlme.DtimCount;
    *(ptr + 3) = pAd->Mlme.DtimPeriod;

    if (byte0 || byte1) // there's some backlog frame for AID 1-15
    {
        *(ptr + 4) = 0;      // Virtual TIM bitmap stars from AID #0
        *(ptr + 5) = byte0;
        *(ptr + 6) = byte1;
        *(ptr + 7) = byte2;
        *(ptr + 8) = byte3;
        *(ptr + 9) = byte4;
        *(ptr + 10) = byte5;
        *(ptr + 11) = byte6;
        *(ptr + 12) = byte7;
        if (byte7)      *(ptr + 1) = 11; // IE length
        else if (byte6) *(ptr + 1) = 10; // IE length
        else if (byte5) *(ptr + 1) = 9;  // IE length
        else if (byte4) *(ptr + 1) = 8;  // IE length
        else if (byte3) *(ptr + 1) = 7;  // IE length
        else if (byte2) *(ptr + 1) = 6;  // IE length
        else if (byte1) *(ptr + 1) = 5;  // IE length
        else            *(ptr + 1) = 4;  // IE length
    }
    else if (byte2 || byte3) // there's some backlogged frame for AID 16-31
    {
        *(ptr + 4) = 2;      // Virtual TIM bitmap starts from AID #16
        *(ptr + 5) = byte2;
        *(ptr + 6) = byte3;
        *(ptr + 7) = byte4;
        *(ptr + 8) = byte5;
        *(ptr + 9) = byte6;
        *(ptr + 10) = byte7;
        if (byte7)      *(ptr + 1) = 9; // IE length
        else if (byte6) *(ptr + 1) = 8; // IE length
        else if (byte5) *(ptr + 1) = 7; // IE length
        else if (byte4) *(ptr + 1) = 6; // IE length
        else if (byte3) *(ptr + 1) = 5; // IE length
        else            *(ptr + 1) = 4; // IE length
    }
    else if (byte4 || byte5) // there's some backlogged frame for AID 32-47
    {
        *(ptr + 4) = 4;      // Virtual TIM bitmap starts from AID #32
        *(ptr + 5) = byte4;
        *(ptr + 6) = byte5;
        *(ptr + 7) = byte6;
        *(ptr + 8) = byte7;
        if (byte7)      *(ptr + 1) = 7; // IE length
        else if (byte6) *(ptr + 1) = 6; // IE length
        else if (byte5) *(ptr + 1) = 5; // IE length
        else            *(ptr + 1) = 4; // IE length
    }
    else if (byte6 || byte7) // there's some backlogged frame for AID 48-63
    {
        *(ptr + 4) = 6;      // Virtual TIM bitmap starts from AID #48
        *(ptr + 5) = byte6;
        *(ptr + 6) = byte7;
        if (byte7)      *(ptr + 1) = 5; // IE length
        else            *(ptr + 1) = 4; // IE length
    }
    else // no backlogged frames
    {
        *(ptr + 1) = 4; // IE length
        *(ptr + 4) = 0;
        *(ptr + 5) = 0;
    }
    
    // bit0 means backlogged mcast/bcast
    *(ptr + 4) |= (pAd->PortCfg.MBSSID[apidx].TimBitmap & 0x01); 
    
    // adjust BEACON length according to the new TIM
    FrameLen += (2 + *(ptr+1)); 

	// Update ERP and extended tx rate
    if ((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11G))
    {
        UCHAR ExtendedRatesLen = pAd->PortCfg.SupportedRatesLen - 4;
        
        //
        // fill ERP IE
        // 
        ptr = (UCHAR *)pBcnHdr + FrameLen; // pTxD->DataByteCnt;
        *ptr = IE_ERP;
        *(ptr + 1) = 1;
        *(ptr + 2) = pAd->Mlme.ErpIeContent;

        //
        // fill up EXTENDED RATE IE.
        // 
        *(ptr + 3) = IE_EXT_SUPP_RATES;
        *(ptr + 4) = ExtendedRatesLen;
        NdisMoveMemory(ptr + 5, &pAd->PortCfg.SupportedRates[4], *(ptr + 4));
        ptr      += (3 + 2 + ExtendedRatesLen);
        FrameLen += (3 + 2 + ExtendedRatesLen);
    }

#ifdef AGGREGATION_SUPPORT
	// add Ralink-specific IE here - Byte0.b0=1 for aggregation
    if (pAd->PortCfg.bAggregationCapable)
    {
	        ULONG TmpLen;
	        UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00}; 
	        MakeOutgoingFrame((UCHAR *)pBcnHdr+FrameLen, &TmpLen,
	                          9,                         RalinkSpecificIe,
	                          END_OF_ARGS);
	        FrameLen += TmpLen;
    }
#endif /* AGGREGATION_SUPPORT */

    // Since FrameLen may change, update TXD
    RTMPWriteTxDescriptor(pAd, pTxD, CIPHER_NONE, 0, 0, FALSE, FALSE, TRUE, SHORT_RETRY, IFS_BACKOFF, 
        pAd->PortCfg.MlmeRate, FrameLen, QID_MGMT, PTYPE_SPECIAL|PSUBTYPE_MGMT, NULL, NULL, pAd->PortCfg.MBSSID[apidx].bWmmCapable, FALSE, FALSE, FALSE);

    // move BEACON TXD and frame content to on-chip memory
    ptr = (PUCHAR)&pAd->PortCfg.MBSSID[apidx].BeaconTxD;
    for (i=0; i<TXINFO_SIZE; i++)  // 24-byte TXINFO field
    {
        RTMP_IO_WRITE8(pAd, HW_BEACON_BASE0 + (apidx * HW_BEACON_OFFSET) + i, *ptr);
        ptr ++;
    }

    // start right after the 24-byte TXINFO field
    ptr = pAd->PortCfg.MBSSID[apidx].BeaconBuf;
//    for (i=0; i< pAd->PortCfg.MBSSID[apidx].BeaconTxD.DataByteCnt; i++)
	 for (i=0; i< FrameLen; i++)
    {
        RTMP_IO_WRITE8(pAd, HW_BEACON_BASE0 + (apidx * HW_BEACON_OFFSET) + TXINFO_SIZE + i, *ptr);
        ptr ++;
    }

    //
    // if DTIM, then move backlogged bcast/mcast frames from PSQ to TXQ whenever DtimCount==0
#if 0    
    // NOTE: This updated BEACON frame will be sent at "next" TBTT instead of at cureent TBTT. The reason is
    //       because ASIC already fetch the BEACON content down to TX FIFO before driver can make any
    //       modification. To compenstate this effect, the actual time to deilver PSQ frames will be
    //       at the time that we wrapping around DtimCount from 0 to DtimPeriod-1
    if ((pAd->ApCfg.DtimCount + 1) == pAd->ApCfg.DtimPeriod)
#else
    if (pAd->Mlme.DtimCount == 0)
#endif
    {
        PQUEUE_ENTRY    pEntry;
#ifndef THREAD_ISR
        ULONG			IrqFlags;
        ULONG			IrqFlags2;
#endif
		BOOLEAN			bPS=FALSE;

#ifndef THREAD_ISR
        RTMP_SEM_LOCK(&pAd->MacTabLock, IrqFlags);
        RTMP_SEM_LOCK(&pAd->TxSwQueueLock, IrqFlags2);
#else
		/* 
		 *  Protect TxSwQueue0 & McastPsQueue 
		 *  because use them in interrupt context 
		 */		
//		RTMP_IRQ_LOCK(IrqFlags);
#endif	/* THREAD_ISR */

        while (pAd->MacTab.McastPsQueue.Head)
        {
			bPS = TRUE;
			if (pAd->TxSwQueue[QID_AC_BE].Number <= (MAX_PACKETS_IN_QUEUE + (MAX_PACKETS_IN_MCAST_PS_QUEUE>>1))) {
	            pEntry = RemoveHeadQueue(&pAd->MacTab.McastPsQueue);
                          if(pAd->MacTab.McastPsQueue.Number){
            	                      RTMP_SET_PACKET_MOREDATA((struct sk_buff *) pEntry, TRUE);
                          }
    	        InsertHeadQueue(&pAd->TxSwQueue[QID_AC_BE], pEntry);				
			} else {
				break;
			}
        }

        DBGPRINT(RT_DEBUG_INFO, "DTIM=%d/%d, tx mcast/bcast out...\n",pAd->Mlme.DtimCount,pAd->Mlme.DtimPeriod);
        pAd->MacTab.PsQIdleCount = 0;

		if (pAd->MacTab.McastPsQueue.Number == 0 ) {
        	pAd->PortCfg.MBSSID[apidx].TimBitmap &= ~BIT32[0]; // clear MCAST/BCAST backlog bit			
		}

#ifndef THREAD_ISR
        RTMP_SEM_UNLOCK(&pAd->TxSwQueueLock, IrqFlags2);
        RTMP_SEM_UNLOCK(&pAd->MacTabLock, IrqFlags);
#else
//		RTMP_IRQ_UNLOCK(IrqFlags);
#endif /* THREAD_ISR */

        // Dequeue outgoing framea from TxSwQueue0..3 queue and process it
		if (bPS == TRUE) 
		{
	        RTMPDeQueuePacket(pAd, FALSE, TRUE);
		}
    }
}

#ifdef APCLI_SUPPORT
/*
    ==========================================================================

	Routine	Description:
		Disconnect current BSSID

	Arguments:
		pAd				- Pointer to our adapter
		ApCliIdx		- Which ApCli interface		
	Return Value:		
		None

	Note:

	==========================================================================
*/
VOID ApCliLinkDown(
    IN 	PRTMP_ADAPTER 	pAd,
    IN	UCHAR			ifIndex)
{
    if (ifIndex < MAX_APCLI_ENTRY)
    {
    	DBGPRINT(RT_DEBUG_TRACE, "!!! APCLI LINK DOWN - IF(apcli%d)!!!\n", ifIndex);
    }
    else
    {
    	DBGPRINT(RT_DEBUG_TRACE, "!!! ERROR : APCLI LINK DOWN - IF(apcli%d)!!!\n", ifIndex);	
    	return;
    }	
    	
    if (pAd->ApCliTab.ApCliEntry[ifIndex].Valid == FALSE)	
		return;

	// Reset WPA-PSK state. Only reset when supplicant enabled
	if (pAd->ApCliTab.ApCliEntry[ifIndex].WpaState != SS_NOTUSE)
	{
		pAd->ApCliTab.ApCliEntry[ifIndex].WpaState = SS_START;
		// Clear Replay counter
		NdisZeroMemory(pAd->ApCliTab.ApCliEntry[ifIndex].ReplayCounter, 8);
	}
	
	// If link down, need to remove pairwise key for this apcli link
	if (pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode >= Ndis802_11AuthModeWPA)
	{	
		NdisZeroMemory(&pAd->ApCliTab.ApCliEntry[ifIndex].PairwiseKey, sizeof(CIPHER_KEY)); 	
		AsicRemovePairwiseKeyEntry(pAd, APCLI_PAIRWISE_KEY_OFFSET);
	}	
	
	// 802.1x port control
	pAd->ApCliTab.ApCliEntry[ifIndex].PortSecured = WPA_802_1X_PORT_NOT_SECURED;
	pAd->ApCliTab.ApCliEntry[ifIndex].MicErrCnt = 0;

}

/*
    ==========================================================================
    Description:
    ==========================================================================
*/
VOID AssocParmFill(
    IN PRTMP_ADAPTER pAd, 
    IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq, 
    IN PUCHAR                     pAddr, 
    IN USHORT                     CapabilityInfo, 
    IN ULONG                      Timeout, 
    IN USHORT                     ListenIntv) 
{
    COPY_MAC_ADDR(AssocReq->Addr, pAddr);
    // Add mask to support 802.11b mode only
    AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
    AssocReq->Timeout = Timeout;
    AssocReq->ListenIntv = ListenIntv;
}

/*
    ==========================================================================
    Description:
    ==========================================================================
*/
VOID DisassocParmFill(
    IN PRTMP_ADAPTER pAd, 
    IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq, 
    IN PUCHAR pAddr, 
    IN USHORT Reason) 
{
    COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
    DisassocReq->Reason = Reason;
}

/*
    ==========================================================================
    Description:
    ==========================================================================
*/
VOID JoinParmFill(
    IN PRTMP_ADAPTER pAd, 
    IN OUT MLME_JOIN_REQ_STRUCT *JoinReq, 
	PUCHAR Bssid,
	UCHAR SsidLen,
	PCHAR Ssid)
{
	if(JoinReq == NULL)
		return;

	if(Bssid != NULL)
		COPY_MAC_ADDR(JoinReq->Bssid, Bssid);

	if(Ssid != NULL && SsidLen != 0)
		NdisMoveMemory(JoinReq->Ssid, Ssid, SsidLen);

	return;
}
#endif /* APCLI_SUPPORT */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?