📄 ba_action.c
字号:
NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = TID; DelbaReq.Initiator = ORIGINATOR; Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __FUNCTION__)); } } return; } DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); pBAEntry = &pAd->BATable.BAOriEntry[Idx]; DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status)); // // Prepare DelBA action frame and send to the peer. // if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done)) { MLME_DELBA_REQ_STRUCT DelbaReq; MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); if (Elem != NULL) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = pBAEntry->TID; DelbaReq.Initiator = ORIGINATOR; Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); return; } } RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); BATableFreeOriEntry(pAd, Idx); if (bPassive) { //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE); }}VOID BARecSessionTearDown( IN OUT PRTMP_ADAPTER pAd, IN UCHAR Wcid, IN UCHAR TID, IN BOOLEAN bPassive){ ULONG Idx = 0; BA_REC_ENTRY *pBAEntry; if (Wcid >= MAX_LEN_OF_MAC_TABLE) { return; } // // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). // Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; if (Idx == 0) return; DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); pBAEntry = &pAd->BATable.BARecEntry[Idx]; DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status)); // // Prepare DelBA action frame and send to the peer. // if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept)) { MLME_DELBA_REQ_STRUCT DelbaReq; BOOLEAN Cancelled; //ULONG offset; //UINT32 VALUE; RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled); // // 1. Send DELBA Action Frame // if (bPassive == FALSE) { MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); if (Elem != NULL) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = TID; DelbaReq.Initiator = RECIPIENT; Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); return; } } // // 2. Free resource of BA session // // flush all pending reordering mpdus ba_refresh_reordering_mpdus(pAd, pBAEntry); NdisAcquireSpinLock(&pAd->BATabLock); // Erase Bitmap flag. pBAEntry->LastIndSeq = RESET_RCV_SEQ; pBAEntry->BAWinSize = 0; // Erase Bitmap flag at software mactable pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID))); pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0; RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID); NdisReleaseSpinLock(&pAd->BATabLock); } BATableFreeRecEntry(pAd, Idx);}VOID BASessionTearDownALL( IN OUT PRTMP_ADAPTER pAd, IN UCHAR Wcid){ int i; for (i=0; i<NUM_OF_TID; i++) { BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE); BARecSessionTearDown(pAd, Wcid, i, FALSE); }}/* ========================================================================== Description: Retry sending ADDBA Reqest. IRQL = DISPATCH_LEVEL Parametrs: p8023Header: if this is already 802.3 format, p8023Header is NULL Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. FALSE , then continue indicaterx at this moment. ========================================================================== */VOID BAOriSessionSetupTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext; MAC_TABLE_ENTRY *pEntry; PRTMP_ADAPTER pAd; if (pBAEntry == NULL) return; pAd = pBAEntry->pAdapter;#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { // Do nothing if monitor mode is on if (MONITOR_ON(pAd)) return; }#endif // CONFIG_STA_SUPPORT // #ifdef RALINK_ATE // Nothing to do in ATE mode. if (ATE_ON(pAd)) return;#endif // RALINK_ATE // pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY)) { MLME_ADDBA_REQ_STRUCT AddbaReq; NdisZeroMemory(&AddbaReq, sizeof(AddbaReq)); COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr); AddbaReq.Wcid = (UCHAR)(pEntry->Aid); AddbaReq.TID = pBAEntry->TID; AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit; AddbaReq.TimeOutValue = 0; AddbaReq.Token = pBAEntry->Token; MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq); RTMP_MLME_HANDLER(pAd); DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token)); pBAEntry->Token++; RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT); } else { BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]); }}/* ========================================================================== Description: Retry sending ADDBA Reqest. IRQL = DISPATCH_LEVEL Parametrs: p8023Header: if this is already 802.3 format, p8023Header is NULL Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. FALSE , then continue indicaterx at this moment. ========================================================================== */VOID BARecSessionIdleTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext; PRTMP_ADAPTER pAd; ULONG Now32; if (pBAEntry == NULL) return; if ((pBAEntry->REC_BA_Status == Recipient_Accept)) { NdisGetSystemUpTime(&Now32); if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT))) { pAd = pBAEntry->pAdapter; // flush all pending reordering mpdus ba_refresh_reordering_mpdus(pAd, pBAEntry); DBGPRINT(RT_DEBUG_OFF, ("%ld: REC BA session Timeout\n", Now32)); } }}VOID PeerAddBAReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { // 7.4.4.1 //ULONG Idx; UCHAR Status = 1; UCHAR pAddr[6]; FRAME_ADDBA_RSP ADDframe; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; PFRAME_ADDBA_REQ pAddreqFrame = NULL; //UCHAR BufSize; ULONG FrameLen; PULONG ptemp; PMAC_TABLE_ENTRY pMacEntry; DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid)); //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen); //ADDBA Request from unknown peer, ignore this. if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) return; pMacEntry = &pAd->MacTab.Content[Elem->Wcid]; DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n")); ptemp = (PULONG)Elem->Msg; //DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8))); if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) { if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry)) { pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); DBGPRINT(RT_DEBUG_OFF, ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid)); if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame)) Status = 0; else Status = 38; // more parameters have invalid values } else { Status = 37; // the request has been declined. } } if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI) ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC); pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); // 2. Always send back ADDBA Response NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n")); return; } NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP)); // 2-1. Prepare ADDBA Response frame.#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (ADHOC_ON(pAd)) ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); else#ifdef QOS_DLS_SUPPORT if (pAd->MacTab.Content[Elem->Wcid].ValidAsDls) ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); else#endif // QOS_DLS_SUPPORT // ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr); }#endif // CONFIG_STA_SUPPORT // ADDframe.Category = CATEGORY_BA; ADDframe.Action = ADDBA_RESP; ADDframe.Token = pAddreqFrame->Token; // What is the Status code?? need to check. ADDframe.StatusCode = Status; ADDframe.BaParm.BAPolicy = IMMED_BA; ADDframe.BaParm.AMSDUSupported = 0; ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID; ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit); if (ADDframe.BaParm.BufSize == 0) { ADDframe.BaParm.BufSize = 64; } ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue; *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm)); ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode); ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ADDBA_RSP), &ADDframe, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID, ADDframe.BaParm.BufSize));}VOID PeerAddBARspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { //UCHAR Idx, i; //PUCHAR pOutBuffer = NULL; PFRAME_ADDBA_RSP pFrame = NULL; //PBA_ORI_ENTRY pBAEntry; //ADDBA Response from unknown peer, ignore this. if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) return; DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid)); //hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen); if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen)) { pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]); DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode)); switch (pFrame->StatusCode) { case 0: // I want a BAsession with this peer as an originator. BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame); break; default: // check status == USED ??? BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE); break; } // Rcv Decline StatusCode if ((pFrame->StatusCode == 37) #ifdef CONFIG_STA_SUPPORT || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))#endif // CONFIG_STA_SUPPORT // ) { pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID; } }}VOID PeerDelBAAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { //UCHAR Idx; //PUCHAR pOutBuffer = NULL; PFRAME_DELBA_REQ pDelFrame = NULL; DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__)); //DELBA Request from unknown peer, ignore this. if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -