VOID RTMPConflictSsidDetection( IN PRTMP_ADAPTER pAd, IN PUCHAR pSsid, IN UCHAR SsidLen, IN CHAR Rssi0, IN CHAR Rssi1, IN CHAR Rssi2) { int i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Conflict SSID detection */ if (SSID_EQUAL(pSsid, SsidLen, pAd->ApCfg.MBSSID[i].Ssid, pAd->ApCfg.MBSSID[i].SsidLen)) { CHAR RcvdRssi; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Rssi0, RSSI_0), ConvertToRssi(pAd, Rssi1, RSSI_1), ConvertToRssi(pAd, Rssi2, RSSI_2)); pAd->ApCfg.MBSSID[i].RcvdConflictSsidCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdConflictSsid = RcvdRssi; return; } } }
BOOLEAN RTMPReplayAttackDetection( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr2, IN CHAR Rssi0, IN CHAR Rssi1, IN CHAR Rssi2) { int i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Conflict SSID detection */ if (NdisEqualMemory(pAddr2, pAd->ApCfg.MBSSID[i].Bssid, MAC_ADDR_LEN)) { CHAR RcvdRssi; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Rssi0, RSSI_0), ConvertToRssi(pAd, Rssi1, RSSI_1), ConvertToRssi(pAd, Rssi2, RSSI_2)); pAd->ApCfg.MBSSID[i].RcvdReplayAttackCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdReplayAttack = RcvdRssi; return TRUE; } } return FALSE; }
/* ========================================================================== Description: TPC Request action frame handler. Parametrs: Elme - MLME message containing the received frame Return : None. ========================================================================== */ static VOID PeerTpcReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; PUCHAR pFramePtr = pFr->Octet; UINT8 DialogToken; UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid); UINT8 LinkMargin = 0; CHAR RealRssi; // link margin: Ratio of the received signal power to the minimum desired by the station (STA). The // STA may incorporate rate information and channel conditions, including interference, into its computation // of link margin. RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); // skip Category and action code. pFramePtr += 2; // Dialog token. NdisMoveMemory(&DialogToken, pFramePtr, 1); LinkMargin = (RealRssi / MIN_RCV_PWR); if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken)) EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin); return; }
VOID RTMPConflictSsidDetection( IN PRTMP_ADAPTER pAd, IN PUCHAR pSsid, IN UCHAR SsidLen, IN CHAR Rssi0, IN CHAR Rssi1, IN CHAR Rssi2) { INT i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Conflict SSID detection */ if (SSID_EQUAL(pSsid, SsidLen, pAd->ApCfg.MBSSID[i].Ssid, pAd->ApCfg.MBSSID[i].SsidLen)) { CHAR RcvdRssi; struct raw_rssi_info rssi_info; rssi_info.raw_rssi[0] = Rssi0; rssi_info.raw_rssi[1] = Rssi1; rssi_info.raw_rssi[2] = Rssi2; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, &rssi_info, RSSI_IDX_0), ConvertToRssi(pAd, &rssi_info, RSSI_IDX_1), ConvertToRssi(pAd, &rssi_info, RSSI_IDX_2)); pAd->ApCfg.MBSSID[i].RcvdConflictSsidCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdConflictSsid = RcvdRssi; return; } } }
BOOLEAN RTMPReplayAttackDetection( IN RTMP_ADAPTER *pAd, IN UCHAR *pAddr2, IN RX_BLK *rxblk) { INT i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Conflict SSID detection */ if (NdisEqualMemory(pAddr2, pAd->ApCfg.MBSSID[i].wdev.bssid, MAC_ADDR_LEN)) { CHAR RcvdRssi; struct raw_rssi_info rssi_info; rssi_info.raw_rssi[0] = rxblk->rx_signal.raw_rssi[0]; rssi_info.raw_rssi[1] = rxblk->rx_signal.raw_rssi[1]; rssi_info.raw_rssi[2] = rxblk->rx_signal.raw_rssi[2]; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, &rssi_info, RSSI_IDX_0), ConvertToRssi(pAd, &rssi_info, RSSI_IDX_1), ConvertToRssi(pAd, &rssi_info, RSSI_IDX_2)); pAd->ApCfg.MBSSID[i].RcvdReplayAttackCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdReplayAttack = RcvdRssi; return TRUE; } } return FALSE; }
/* * Update_Rssi_Sample() in ap/ap_data.c. */ VOID AntDiversity_Update_Rssi_Sample( IN PRTMP_ADAPTER pAd, IN RSSI_SAMPLE *pRssi, IN PRXWI_STRUC pRxWI) { CHAR rssi0 = pRxWI->RSSI0; CHAR rssi1 = pRxWI->RSSI1; CHAR rssi2 = pRxWI->RSSI2; if (rssi0 != 0) { pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0); pRssi->LastRssi0Jiffy = jiffies; pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0; pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3; }
/* * Read RSSI from BBP R50/R51/R52 */ INT AntDiversity_BBPRead( IN PRTMP_ADAPTER pAd, IN INT Ant) { UCHAR BBPReg; CHAR rssi_once = 0; INT32 RSSI; INT rssi_total = 0, rssi_avg = 0, rssi_count = 0, i; switch(Ant){ case 0: BBPReg = 50; break; case 1: BBPReg = 51; break; case 2: BBPReg = 52; break; default: DBGPRINT(RT_DEBUG_ERROR,("Don't support more than 3 antennas yet")); BUG(); return 0; } for(i=0; i< atomic_read(&BBP_RSSI_SAMPLE_COUNT); i++){ RTMP_BBP_IO_READ8_BY_REG_ID_SHORT_DELAY(pAd, BBPReg, &rssi_once); RSSI = ConvertToRssi(pAd, rssi_once, Ant); // Max-Min filter if(RSSI < atomic_read(&BBP_RSSI_RANGE_MAX) && RSSI > atomic_read(&BBP_RSSI_RANGE_MIN)){ rssi_count ++; rssi_total += RSSI; ADDBGPRINT("%02d ", RSSI); }else ADDBGPRINT("%02d* ", RSSI); if(atomic_read(&BBP_RSSI_SAMPLE_INTERVAL)){ set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(atomic_read(&BBP_RSSI_SAMPLE_INTERVAL))); // sleep } } rssi_avg = rssi_count ? rssi_total / rssi_count : 0; ADDBGPRINT("Ant%d==> %02d\n", Ant, rssi_avg); return rssi_avg; }
static VOID APPeerAuthReqAtIdleAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { INT i; USHORT Seq, Alg, RspReason, Status; UCHAR Addr1[MAC_ADDR_LEN]; UCHAR Addr2[MAC_ADDR_LEN]; CHAR Chtxt[CIPHER_TEXT_LEN]; UINT32 apidx; PHEADER_802_11 pRcvHdr; HEADER_802_11 AuthHdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; MAC_TABLE_ENTRY *pEntry; UCHAR ChTxtIe = 16, ChTxtLen = CIPHER_TEXT_LEN; MULTISSID_STRUCT *pMbss; struct wifi_dev *wdev; CHAR rssi; if (! APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, &Alg, &Seq, &Status, Chtxt )) return; /* Find which MBSSID to be authenticate */ apidx = get_apidx_by_addr(pAd, Addr1); if (apidx >= pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n")); return; } pMbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &pMbss->wdev; if ((wdev->if_dev == NULL) || ((wdev->if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(wdev->if_dev)))) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); return; } pEntry = MacTableLookup(pAd, Addr2); if (pEntry && IS_ENTRY_CLIENT(pEntry)) { #ifdef DOT11W_PMF_SUPPORT if ((CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE)) && (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)) goto SendAuth; #endif /* DOT11W_PMF_SUPPORT */ if (!RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, MAC_ADDR_LEN)) { MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); pEntry = NULL; DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n")); } else { if (pEntry->bIAmBadAtheros == TRUE) { AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n")); pEntry->bIAmBadAtheros = FALSE; } #ifdef DOT11_N_SUPPORT BASessionTearDownALL(pAd, pEntry->wcid); #endif /* DOT11_N_SUPPORT */ ASSERT(pEntry->Aid == Elem->Wcid); } } #ifdef DOT11W_PMF_SUPPORT SendAuth: #endif /* DOT11W_PMF_SUPPORT */ pRcvHdr = (PHEADER_802_11)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from " "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", apidx, Seq, Alg, Status, Elem->Wcid, PRINT_MAC(Addr2))); /* YF@20130102: Refuse the weak signal of AuthReq */ rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, (CHAR)Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, (CHAR)Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, (CHAR)Elem->Rssi2, RSSI_2)); DBGPRINT(RT_DEBUG_TRACE, ("%s: AUTH_FAIL_REQ Threshold = %d, AUTH_NO_RSP_REQ Threshold = %d, AUTH RSSI = %d\n", wdev->if_dev->name, pMbss->AuthFailRssiThreshold, pMbss->AuthNoRspRssiThreshold, rssi)); if (((pMbss->AuthFailRssiThreshold != 0) && (rssi < pMbss->AuthFailRssiThreshold)) || ((pMbss->AuthNoRspRssiThreshold != 0) && (rssi < pMbss->AuthNoRspRssiThreshold))) { DBGPRINT(RT_DEBUG_TRACE, ("Reject this AUTH_REQ due to Weak Signal.\n")); if ((pMbss->AuthFailRssiThreshold != 0) && (rssi < pMbss->AuthFailRssiThreshold)) APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0); return; } /* fail in ACL checking => send an AUTH-Fail seq#2. */ if (! ApCheckAccessControlList(pAd, Addr2, apidx)) { ASSERT(Seq == 1); ASSERT(pEntry == NULL); APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("Failed in ACL checking => send an AUTH seq#2 with " "Status code = %d\n", MLME_UNSPECIFY_FAIL)); return; } if ((Alg == AUTH_MODE_OPEN) && (pMbss->wdev.AuthMode != Ndis802_11AuthModeShared)) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, Addr2, wdev, apidx, OPMODE_AP, TRUE); if (pEntry) { #ifdef DOT11W_PMF_SUPPORT if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE)) || (pEntry->PortSecured != WPA_802_1X_PORT_SECURED)) #endif /* DOT11W_PMF_SUPPORT */ { pEntry->AuthState = AS_AUTH_OPEN; pEntry->Sst = SST_AUTH; /* what if it already in SST_ASSOC ??????? */ } APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_SUCCESS); } else ; /* MAC table full, what should we respond ????? */ } else if ((Alg == AUTH_MODE_KEY) && ((wdev->AuthMode == Ndis802_11AuthModeShared) || (wdev->AuthMode == Ndis802_11AuthModeAutoSwitch))) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, Addr2, wdev, apidx, OPMODE_AP, TRUE); if (pEntry) { pEntry->AuthState = AS_AUTHENTICATING; pEntry->Sst = SST_NOT_AUTH; /* what if it already in SST_ASSOC ??????? */ /* log this STA in AuthRspAux machine, only one STA is stored. If two STAs using */ /* SHARED_KEY authentication mingled together, then the late comer will win. */ COPY_MAC_ADDR(&pAd->ApMlmeAux.Addr, Addr2); for(i=0; i<CIPHER_TEXT_LEN; i++) pAd->ApMlmeAux.Challenge[i] = RandomByte(pAd); RspReason = 0; Seq++; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if(NStatus != NDIS_STATUS_SUCCESS) return; /* if no memory, can't do anything */ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH seq#2 (Challenge)\n")); MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, wdev->if_addr, wdev->bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AuthHdr, 2, &Alg, 2, &Seq, 2, &RspReason, 1, &ChTxtIe, 1, &ChTxtLen, CIPHER_TEXT_LEN, pAd->ApMlmeAux.Challenge, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } else ; /* MAC table full, what should we respond ???? */ } else { /* wrong algorithm */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_ALG_NOT_SUPPORT); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Alg=%d, Seq=%d, AuthMode=%d\n", Alg, Seq, pAd->ApCfg.MBSSID[apidx].wdev.AuthMode)); } }
/* ======================================================================== Routine Description: This routine is used to check if a rogue AP sent an 802.11 management frame to a client using our BSSID. Arguments: pAd - Pointer to our adapter pHeader - Pointer to 802.11 header Return Value: TRUE - This is a spoofed frame FALSE - This isn't a spoofed frame ======================================================================== */ BOOLEAN RTMPSpoofedMgmtDetection( IN PRTMP_ADAPTER pAd, IN PHEADER_802_11 pHeader, IN CHAR Rssi0, IN CHAR Rssi1, IN CHAR Rssi2) { int i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Spoofed BSSID detection */ if (NdisEqualMemory(pHeader->Addr2, pAd->ApCfg.MBSSID[i].Bssid, MAC_ADDR_LEN)) { CHAR RcvdRssi; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Rssi0, RSSI_0), ConvertToRssi(pAd, Rssi1, RSSI_1), ConvertToRssi(pAd, Rssi2, RSSI_2)); switch (pHeader->FC.SubType) { case SUBTYPE_ASSOC_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedAssocRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAssocResp = RcvdRssi; break; case SUBTYPE_REASSOC_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedReassocRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedReassocResp = RcvdRssi; break; case SUBTYPE_PROBE_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedProbeRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedProbeResp = RcvdRssi; break; case SUBTYPE_BEACON: pAd->ApCfg.MBSSID[i].RcvdSpoofedBeaconCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedBeacon = RcvdRssi; break; case SUBTYPE_DISASSOC: pAd->ApCfg.MBSSID[i].RcvdSpoofedDisassocCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDisassoc = RcvdRssi; break; case SUBTYPE_AUTH: pAd->ApCfg.MBSSID[i].RcvdSpoofedAuthCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAuth = RcvdRssi; break; case SUBTYPE_DEAUTH: pAd->ApCfg.MBSSID[i].RcvdSpoofedDeauthCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDeauth = RcvdRssi; break; default: pAd->ApCfg.MBSSID[i].RcvdSpoofedUnknownMgmtCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedUnknownMgmt = RcvdRssi; break; } return TRUE; } } return FALSE; }
/* ======================================================================== Routine Description: This routine is used to check if a rogue AP sent an 802.11 management frame to a client using our BSSID. Arguments: pAd - Pointer to our adapter pHeader - Pointer to 802.11 header Return Value: TRUE - This is a spoofed frame FALSE - This isn't a spoofed frame ======================================================================== */ BOOLEAN RTMPSpoofedMgmtDetection( IN RTMP_ADAPTER *pAd, IN HEADER_802_11 *pHeader, IN RX_BLK *rxblk) { INT i; for (i = 0; i < pAd->ApCfg.BssidNum; i++) { /* Spoofed BSSID detection */ if (NdisEqualMemory(pHeader->Addr2, pAd->ApCfg.MBSSID[i].wdev.bssid, MAC_ADDR_LEN)) { CHAR RcvdRssi; struct raw_rssi_info rssi_info; rssi_info.raw_rssi[0] = rxblk->rx_signal.raw_rssi[0]; rssi_info.raw_rssi[1] = rxblk->rx_signal.raw_rssi[1]; rssi_info.raw_rssi[2] = rxblk->rx_signal.raw_rssi[2]; RcvdRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, &rssi_info, RSSI_IDX_0), ConvertToRssi(pAd, &rssi_info, RSSI_IDX_1), ConvertToRssi(pAd, &rssi_info, RSSI_IDX_2)); switch (pHeader->FC.SubType) { case SUBTYPE_ASSOC_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedAssocRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAssocResp = RcvdRssi; break; case SUBTYPE_REASSOC_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedReassocRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedReassocResp = RcvdRssi; break; case SUBTYPE_PROBE_RSP: pAd->ApCfg.MBSSID[i].RcvdSpoofedProbeRespCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedProbeResp = RcvdRssi; break; case SUBTYPE_BEACON: pAd->ApCfg.MBSSID[i].RcvdSpoofedBeaconCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedBeacon = RcvdRssi; break; case SUBTYPE_DISASSOC: pAd->ApCfg.MBSSID[i].RcvdSpoofedDisassocCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDisassoc = RcvdRssi; break; case SUBTYPE_AUTH: pAd->ApCfg.MBSSID[i].RcvdSpoofedAuthCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedAuth = RcvdRssi; break; case SUBTYPE_DEAUTH: pAd->ApCfg.MBSSID[i].RcvdSpoofedDeauthCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedDeauth = RcvdRssi; break; default: pAd->ApCfg.MBSSID[i].RcvdSpoofedUnknownMgmtCount ++; pAd->ApCfg.MBSSID[i].RssiOfRcvdSpoofedUnknownMgmt = RcvdRssi; break; } return TRUE; } } return FALSE; }
VOID PeerBeaconAtScanAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; UCHAR Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel, SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe; CF_PARM CfParm; USHORT BeaconPeriod, AtimWin, CapabilityInfo; PFRAME_802_11 pFrame; LARGE_INTEGER TimeStamp; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; USHORT LenVIE; UCHAR CkipFlag; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; ULONG RalinkIe; UCHAR VarIE[MAX_VIE_LEN]; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; pFrame = (PFRAME_802_11) Elem->Msg; pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; #ifdef DOT11_N_SUPPORT RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE)); #endif if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, (PCHAR)Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &CfParm, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, &PreNHtCapabilityLen, &HtCapability, &AddHtInfoLen, &AddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { ULONG Idx; CHAR Rssi = 0; Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); if (Idx != BSS_NOT_FOUND) Rssi = pAd->ScanTab.BssEntry[Idx].Rssi; Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); #ifdef DOT11_N_SUPPORT if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) HtCapabilityLen = SIZE_HT_CAP_IE; #endif Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (PCHAR)Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE) { UCHAR RegClass; PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass); TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel); } #endif #endif if (Idx != BSS_NOT_FOUND) { NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); } } }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PAPCLI_STRUCT pApCliEntry = NULL; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; #endif /* DOT11_N_SUPPORT */ USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; BCN_IE_LIST *ie_list = NULL; if (ifIndex >= MAX_APCLI_NUM) return; pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; /* Check the Probe-Rsp's Ssid. */ if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) matchFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pApCliEntry->ApCliMlmeAux.VarIELen = LenVIE; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.VarIEs, pVIE, pApCliEntry->ApCliMlmeAux.VarIELen); } else { /* ignore this response */ pApCliEntry->ApCliMlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pApCliEntry->ApCliMlmeAux.VarIELen = 0; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->ApCliMlmeAux.Rssi, (LONG)RealRssi)); if (pApCliEntry->ApCliMlmeAux.Rssi > (LONG)RealRssi) goto LabelErr; else pApCliEntry->ApCliMlmeAux.Rssi = RealRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pApCliEntry->ApCliMlmeAux.ProbeTimer, &Cancelled); } NdisMoveMemory(pApCliEntry->ApCliMlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pApCliEntry->ApCliMlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN); pApCliEntry->ApCliMlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pApCliEntry->ApCliMlmeAux.BssType = ie_list->BssType; pApCliEntry->ApCliMlmeAux.BeaconPeriod = ie_list->BeaconPeriod; pApCliEntry->ApCliMlmeAux.Channel = ie_list->Channel; pApCliEntry->ApCliMlmeAux.AtimWin = ie_list->AtimWin; pApCliEntry->ApCliMlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pApCliEntry->ApCliMlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pApCliEntry->ApCliMlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to ApCliMlmeAux for creating assoication request */ /* Also filter out not supported rate */ pApCliEntry->ApCliMlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pApCliEntry->ApCliMlmeAux.SupRate, &pApCliEntry->ApCliMlmeAux.SupRateLen); pApCliEntry->ApCliMlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->ApCliMlmeAux.ExtRate, &pApCliEntry->ApCliMlmeAux.ExtRateLen); #ifdef DOT11_N_SUPPORT NdisZeroMemory(pApCliEntry->RxMcsSet,sizeof(pApCliEntry->RxMcsSet)); /* filter out un-supported ht rates */ if ((ie_list->HtCapabilityLen > 0) && (pApCliEntry->DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { RTMPZeroMemory(&pApCliEntry->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE); pApCliEntry->ApCliMlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pApCliEntry->ApCliMlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo); if (ie_list->AddHtInfoLen > 0) { CentralChannel = ie_list->AddHtInfo.ControlChan; /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, ie_list->AddHtInfo.ControlChan)); } } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&pApCliEntry->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPZeroMemory(&pApCliEntry->ApCliMlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); pApCliEntry->ApCliMlmeAux.HtCapabilityLen = 0; } ApCliUpdateMlmeRate(pAd, ifIndex); #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { NdisMoveMemory(&pApCliEntry->ApCliMlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pApCliEntry->ApCliMlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pApCliEntry->ApCliMlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&pApCliEntry->ApCliMlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pApCliEntry->ApCliMlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pApCliEntry->ApCliMlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pApCliEntry->ApCliMlmeAux.SupRateLen, pApCliEntry->ApCliMlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /*Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; #ifdef WSC_AP_SUPPORT #ifdef DOT11_N_SUPPORT if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == TRUE)) { ADD_HTINFO RootApHtInfo, ApHtInfo; ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo; RootApHtInfo = ie_list->AddHtInfo.AddHtInfo; if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (RootApHtInfo.RecomWidth) && (RootApHtInfo.ExtChanOffset != ApHtInfo.ExtChanOffset)) { /*STRING ChStr[5] = {0}; */ if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE) Set_HtExtcha_Proc(pAd, "1"); else Set_HtExtcha_Proc(pAd, "0"); goto LabelErr; } } #endif /* DOT11_N_SUPPORT */ #endif /* WSC_AP_SUPPORT */ if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); MlmeHandler(pAd); } } /* not to me BEACON, ignored */ } /* sanity check fail, ignore this frame */ LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; }
/* ========================================================================== Description: peer sends beacon back when scanning ========================================================================== */ VOID ApCliPeerProbeRspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PFRAME_802_11 pFrame; UCHAR *VarIE = NULL; USHORT LenVIE; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; CHAR RealRssi = -127; BCN_IE_LIST *ie_list = NULL; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } /* Init Variable IE structure */ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); pFrame = (PFRAME_802_11) Elem->Msg; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { ULONG Idx; CHAR Rssi = -127; RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20)); #ifdef P2P_SUPPORT MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_PEER_PROB_RSP, Elem->MsgLen, Elem->Msg, ie_list->Channel); #endif /* P2P_SUPPORT */ /* ignore BEACON not in this channel */ if (ie_list->Channel != pAd->MlmeAux.Channel #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 && (pAd->CommonCfg.bOverlapScanning == FALSE) #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ ) { goto __End_Of_APPeerBeaconAtScanAction; } #ifdef DOT11_N_SUPPORT if ((RealRssi > OBSS_BEACON_RSSI_THRESHOLD) && (ie_list->HtCapability.HtCapInfo.Forty_Mhz_Intolerant)) /* || (HtCapabilityLen == 0))) */ { Handle_BSS_Width_Trigger_Events(pAd); } #endif /* DOT11_N_SUPPORT */ #ifdef IDS_SUPPORT /* Conflict SSID detection */ if (ie_list->Channel == pAd->CommonCfg.Channel) RTMPConflictSsidDetection(pAd, ie_list->Ssid, ie_list->SsidLen, Elem->Rssi0, Elem->Rssi1, Elem->Rssi2, Elem->AntSel); #endif /* IDS_SUPPORT */ /* This correct im-proper RSSI indication during SITE SURVEY issue. Always report bigger RSSI during SCANNING when receiving multiple BEACONs from the same AP. This case happens because BEACONs come from adjacent channels, so RSSI become weaker as we switch to more far away channels. */ Idx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Idx != BSS_NOT_FOUND) Rssi = pAd->ScanTab.BssEntry[Idx].Rssi; /* TODO: 2005-03-04 dirty patch. we should change all RSSI related variables to SIGNED SHORT for easy/efficient reading and calaulation */ RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20)); if ((RealRssi + pAd->BbpRssiToDbmDelta) > Rssi) Rssi = RealRssi + pAd->BbpRssiToDbmDelta; Idx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -Rssi, LenVIE, pVIE); if (Idx != BSS_NOT_FOUND) { NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); } } /* sanity check fail, ignored */ __End_Of_APPeerBeaconAtScanAction: /*scan beacon in pastive */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if (ie_list->Channel == pAd->ApCfg.AutoChannel_Channel) { if (AutoChBssSearchWithSSID(pAd, ie_list->Bssid, (PUCHAR)ie_list->Ssid, ie_list->SsidLen, ie_list->Channel) == BSS_NOT_FOUND) pAd->pChannelInfo->ApCnt[pAd->ApCfg.current_channel_index]++; AutoChBssInsertEntry(pAd, ie_list->Bssid, (CHAR *)ie_list->Ssid, ie_list->SsidLen, ie_list->Channel, ie_list->NewExtChannelOffset, RealRssi); } } #endif /* CONFIG_AP_SUPPORT */ LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PAPCLI_STRUCT pApCliEntry = NULL; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel = 0; #endif /* DOT11_N_SUPPORT */ USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; BCN_IE_LIST *ie_list = NULL; /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; ULONG Bssidx; #ifdef P2P_SUPPORT MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_PEER_PROB_RSP, Elem->MsgLen, Elem->Msg, ie_list->Channel); #endif /* P2P_SUPPORT */ /* Update ScanTab */ Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ goto LabelErr; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; /* Check the Probe-Rsp's Ssid. */ if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) matchFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pAd->ApCliMlmeAux.VarIELen = LenVIE; NdisMoveMemory(pAd->ApCliMlmeAux.VarIEs, pVIE, pAd->ApCliMlmeAux.VarIELen); } else { /* ignore this response */ pAd->ApCliMlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pAd->ApCliMlmeAux.VarIELen = 0; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20); LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pAd->ApCliMlmeAux.Rssi, (LONG)RealRssi)); if (pAd->ApCliMlmeAux.Rssi > (LONG)RealRssi) goto LabelErr; else pAd->ApCliMlmeAux.Rssi = RealRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pAd->ApCliMlmeAux.ProbeTimer, &Cancelled); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { /* Stop Scan and resume */ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); pAd->MlmeAux.Channel = 0; ScanNextChannel(pAd, OPMODE_AP); } DBGPRINT(RT_DEBUG_TRACE, ("%s:: Swich Channel = %d. and STOP Scanning!!\n", __FUNCTION__, ie_list->Channel)); } NdisMoveMemory(pAd->ApCliMlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pAd->ApCliMlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pAd->ApCliMlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN); pAd->ApCliMlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pAd->ApCliMlmeAux.BssType = ie_list->BssType; pAd->ApCliMlmeAux.BeaconPeriod = ie_list->BeaconPeriod; pAd->ApCliMlmeAux.Channel = ie_list->Channel; pAd->ApCliMlmeAux.AtimWin = ie_list->AtimWin; pAd->ApCliMlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pAd->ApCliMlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pAd->ApCliMlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to MlmeAux for creating assoication request */ /* Also filter out not supported rate */ pAd->ApCliMlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pAd->ApCliMlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pAd->ApCliMlmeAux.SupRate, &pAd->ApCliMlmeAux.SupRateLen); pAd->ApCliMlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pAd->ApCliMlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pAd->ApCliMlmeAux.ExtRate, &pAd->ApCliMlmeAux.ExtRateLen); #ifdef DOT11_N_SUPPORT NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet,sizeof(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet)); /* filter out un-supported ht rates */ if ((ie_list->HtCapabilityLen > 0) && (pApCliEntry->DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { #ifdef P2P_SUPPORT BOOLEAN P2PGroup_BW; UCHAR BwFallBack = 0; #endif /* P2P_SUPPORT */ RTMPZeroMemory(&pAd->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE); pAd->ApCliMlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pAd->ApCliMlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo); RTMPMoveMemory(&pAd->ApCliMlmeAux.AddHtInfo, &ie_list->AddHtInfo, SIZE_ADD_HT_INFO_IE); if (ie_list->AddHtInfoLen > 0) { CentralChannel = ie_list->AddHtInfo.ControlChan; /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, ie_list->AddHtInfo.ControlChan)); } #ifdef P2P_SUPPORT if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != CentralChannel) && (pAd->StaActive.SupportedHtPhy.ChannelWidth == BW_40)) { DBGPRINT(RT_DEBUG_OFF, ("PeerBeaconAtJoinAction HT===> Channel offset = %d not match INFRA Channel offset %d .\n", pAd->MlmeAux.CentralChannel, CentralChannel)); //goto LabelErr; } /*P2PChannelInit(pAd, MAIN_MBSSID); */ pAd->ApCliMlmeAux.CentralChannel = CentralChannel; //P2PInitChannelRelatedValue(pAd); if (pAd->ApCliMlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40) P2PGroup_BW = TRUE; else P2PGroup_BW = FALSE; AdjustChannelRelatedValue(pAd, &BwFallBack, ifIndex, P2PGroup_BW, pAd->ApCliMlmeAux.Channel, pAd->ApCliMlmeAux.CentralChannel); if (BwFallBack == 1) { DBGPRINT(RT_DEBUG_TRACE, ("Infra STA connection to 40MHz AP, but Infra extra and P2P Group extra is different!!!\n")); pAd->ApCliMlmeAux.HtCapability.HtCapInfo.ChannelWidth = BW_20; pAd->ApCliMlmeAux.CentralChannel = pAd->ApCliMlmeAux.Channel; pAd->ApCliMlmeAux.bBwFallBack = TRUE; } else { pAd->ApCliMlmeAux.bBwFallBack = FALSE; } pAd->ApCliMlmeAux.ConCurrentCentralChannel = pAd->CommonCfg.CentralChannel; #endif /* P2P_SUPPORT */ } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&pAd->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPZeroMemory(&pAd->ApCliMlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); pAd->ApCliMlmeAux.HtCapabilityLen = 0; } #ifdef P2P_SUPPORT P2PUpdateMlmeRate(pAd); #else RTMPUpdateMlmeRate(pAd); #endif /* P2P_SUPPORT */ #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { NdisMoveMemory(&pAd->ApCliMlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pAd->ApCliMlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->ApCliMlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&pAd->ApCliMlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pAd->ApCliMlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pAd->ApCliMlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pAd->ApCliMlmeAux.SupRateLen, pAd->ApCliMlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /*Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } } /* not to me BEACON, ignored */ } /* sanity check fail, ignore this frame */ LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PAPCLI_STRUCT pApCliEntry = NULL; struct wifi_dev *wdev; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; #endif /* DOT11_N_SUPPORT */ USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState; BCN_IE_LIST *ie_list = NULL; UCHAR PhyMode = pAd->CommonCfg.PhyMode; PFRAME_802_11 pFrame = NULL; if (ifIndex >= MAX_APCLI_NUM) return; /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); pFrame = (PFRAME_802_11)Elem->Msg; pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; ULONG Bssidx; LONG RealRssi = -127; #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE RealRssi = (LONG)(RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2))); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ /* Update ScanTab */ Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ #ifdef CUSTOMER_DCC_FEATURE Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE, Elem->Snr0, Elem->Snr1); #else Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE); #endif if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ { DBGPRINT(RT_DEBUG_ERROR, ("ERROR: Driver ScanTable Full In Apcli ProbeRsp Join\n")); goto LabelErr; } NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE DBGPRINT(RT_DEBUG_TRACE, ("Info: Update the SSID %s in Kernel Table\n", ie_list->Ssid)); RT_CFG80211_SCANNING_INFORM(pAd, Bssidx, ie_list->Channel, (UCHAR *)Elem->Msg, Elem->MsgLen, RealRssi); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; wdev = &pApCliEntry->wdev; /* Check the Probe-Rsp's Ssid. */ #ifdef WSC_AP_SUPPORT if ((pApCliEntry->WscControl.WscConfMode != WSC_DISABLE) && (pApCliEntry->WscControl.bWscTrigger == TRUE)) { #ifdef SMART_MESH if((pApCliEntry->WscControl.WscMode == 2) && (pApCliEntry->WscControl.bWscPBCAddrMode == TRUE)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->WscControl.WscPBCAddr, ie_list->Bssid); else #endif /* SMART_MESH */ { if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; } if(pApCliEntry->WscControl.WscSsid.SsidLength != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->WscControl.WscSsid.Ssid, pApCliEntry->WscControl.WscSsid.SsidLength,ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; } else #endif /* WSC_AP_SUPPORT */ { /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; } /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) { matchFlag = TRUE; #ifdef SMART_MESH matchFlag = FALSE; #endif /* SMART_MESH */ } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef WSC_AP_SUPPORT && ((pApCliEntry->WscControl.WscConfMode == WSC_DISABLE) || (pApCliEntry->WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE /* When using CFG80211 and trigger WPS, do not check security. */ && ! (pApCliEntry->wpa_supplicant_info.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pApCliEntry->MlmeAux.VarIELen = LenVIE; NdisMoveMemory(pApCliEntry->MlmeAux.VarIEs, pVIE, pApCliEntry->MlmeAux.VarIELen); } else { /* ignore this response */ pApCliEntry->MlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->wdev.AuthMode >= Ndis802_11AuthModeWPA #ifdef WSC_AP_SUPPORT && ((pApCliEntry->WscControl.WscConfMode == WSC_DISABLE) || (pApCliEntry->WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pApCliEntry->MlmeAux.VarIELen = 0; } #ifdef SMART_MESH PSMART_MESH_CFG pSmartMeshCfg = NULL; pSmartMeshCfg = &pApCliEntry->SmartMeshCfg; if(((pSmartMeshCfg->HiFiFlagMask != 0) && (pSmartMeshCfg->HiFiFlagValue != 0)) && ((ie_list->VIEFlag & pSmartMeshCfg->HiFiFlagMask) == pSmartMeshCfg->HiFiFlagValue)) { pAd->ScanTab.BssEntry[Bssidx].bHyperFiPeer = TRUE; pApCliEntry->MlmeAux.bHyperFiPeer = TRUE; } else { pAd->ScanTab.BssEntry[Bssidx].bHyperFiPeer = FALSE; pApCliEntry->MlmeAux.bHyperFiPeer = FALSE; } if((pSmartMeshCfg->bHiFiPeerFilter == TRUE) && (pAd->ScanTab.BssEntry[Bssidx].bHyperFiPeer == FALSE)) { DBGPRINT(RT_DEBUG_OFF, ("Reject this PROBE_RSP due to not desired Hyper-Fi peer(%02X:%02X:%02X:%02X:%02X:%02X).\n",PRINT_MAC(pAd->ScanTab.BssEntry[Bssidx].Bssid))); goto LabelErr; } if(pAd->ScanTab.BssEntry[Bssidx].bSupportSmartMesh != ie_list->bSupportSmartMesh) pAd->ScanTab.BssEntry[Bssidx].bSupportSmartMesh = ie_list->bSupportSmartMesh; if(pAd->ScanTab.BssEntry[Bssidx].bSupportSmartMesh) { pApCliEntry->MlmeAux.bSupportSmartMesh = TRUE; DBGPRINT(RT_DEBUG_OFF, ("AP supports SMART MESH\n")); } else pApCliEntry->MlmeAux.bSupportSmartMesh = FALSE; if(pAd->ScanTab.BssEntry[Bssidx].bHyperFiPeer) DBGPRINT(RT_DEBUG_OFF, ("AP is Hyper-Fi device\n")); #endif /* SMART_MESH */ #ifdef MWDS if(pAd->ScanTab.BssEntry[Bssidx].bSupportMWDS != ie_list->bSupportMWDS) pAd->ScanTab.BssEntry[Bssidx].bSupportMWDS = ie_list->bSupportMWDS; if(pAd->ScanTab.BssEntry[Bssidx].bSupportMWDS) { pApCliEntry->MlmeAux.bSupportMWDS = TRUE; DBGPRINT(RT_DEBUG_OFF, ("AP supports MWDS\n")); } else pApCliEntry->MlmeAux.bSupportMWDS = FALSE; #endif /* MWDS */ #ifdef WSC_AP_SUPPORT #ifdef SMART_MESH_HIDDEN_WPS if(pAd->ScanTab.BssEntry[Bssidx].bSupportHiddenWPS != ie_list->bSupportHiddenWPS) pAd->ScanTab.BssEntry[Bssidx].bSupportHiddenWPS = ie_list->bSupportHiddenWPS; if(pAd->ScanTab.BssEntry[Bssidx].bSupportHiddenWPS) DBGPRINT(RT_DEBUG_OFF, ("AP supports HiddenWPS\n")); if(pAd->ScanTab.BssEntry[Bssidx].bRunningHiddenWPS != ie_list->bRunningHiddenWPS) pAd->ScanTab.BssEntry[Bssidx].bRunningHiddenWPS = ie_list->bRunningHiddenWPS; if(pAd->ScanTab.BssEntry[Bssidx].bRunningHiddenWPS) DBGPRINT(RT_DEBUG_OFF, ("AP is running HiddenWPS\n")); #endif /* SMART_MESH_HIDDEN_WPS */ #endif /* WSC_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); LONG RealMaxRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->MlmeAux.Rssi, (LONG)RealMaxRssi)); if (pApCliEntry->MlmeAux.Rssi > (LONG)RealMaxRssi) goto LabelErr; else pApCliEntry->MlmeAux.Rssi = RealMaxRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pApCliEntry->MlmeAux.ProbeTimer, &Cancelled); } NdisMoveMemory(pApCliEntry->MlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pApCliEntry->MlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pApCliEntry->MlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN); pApCliEntry->MlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pApCliEntry->MlmeAux.BssType = ie_list->BssType; pApCliEntry->MlmeAux.BeaconPeriod = ie_list->BeaconPeriod; pApCliEntry->MlmeAux.Channel = ie_list->Channel; pApCliEntry->MlmeAux.CentralChannel = ie_list->Channel; /* by default */ pApCliEntry->MlmeAux.AtimWin = ie_list->AtimWin; pApCliEntry->MlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pApCliEntry->MlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pApCliEntry->MlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to MlmeAux for creating assoication request */ /* Also filter out not supported rate */ pApCliEntry->MlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.SupRate, &pApCliEntry->MlmeAux.SupRateLen); pApCliEntry->MlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.ExtRate, &pApCliEntry->MlmeAux.ExtRateLen); #ifdef APCLI_CERT_SUPPORT /* Get the ext capability info element */ if (pAd->bApCliCertTest == TRUE #ifdef DOT11N_DRAFT3 && pAd->CommonCfg.bBssCoexEnable == TRUE #endif /* DOT11N_DRAFT3 */ ) { NdisMoveMemory(&pApCliEntry->MlmeAux.ExtCapInfo, &ie_list->ExtCapInfo,sizeof(ie_list->ExtCapInfo)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 DBGPRINT(RT_DEBUG_TRACE, ("\x1b[31m ApCliMlmeAux.ExtCapInfo=%d \x1b[m\n", pApCliEntry->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); //zero debug 210121122 pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ } #endif /* APCLI_CERT_SUPPORT */ #ifdef DOT11_N_SUPPORT NdisZeroMemory(pApCliEntry->RxMcsSet,sizeof(pApCliEntry->RxMcsSet)); #ifdef APCLI_AUTO_BW_SUPPORT PhyMode = pApCliEntry->wdev.PhyMode; DBGPRINT(RT_DEBUG_OFF, ("%s: check HT Rule --> %d %d %d %d\n", __FUNCTION__, (ie_list->HtCapabilityLen > 0), (pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable), WMODE_CAP_N(pApCliEntry->wdev.PhyMode), !(pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus)))); #endif /* APCLI_AUTO_BW_SUPPORT */ /* filter out un-supported ht rates */ if ((ie_list->HtCapabilityLen > 0) && (pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(PhyMode) && /* For Dissallow TKIP rule on STA */ !(pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus))) { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pApCliEntry->MlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pApCliEntry->MlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo); if (ie_list->AddHtInfoLen > 0) { CentralChannel = ie_list->AddHtInfo.ControlChan; /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); pApCliEntry->MlmeAux.CentralChannel = CentralChannel; DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>CentralCh = %d, ControlCh = %d\n", CentralChannel, ie_list->AddHtInfo.ControlChan)); } } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPZeroMemory(&pApCliEntry->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); pApCliEntry->MlmeAux.HtCapabilityLen = 0; } ApCliUpdateMlmeRate(pAd, ifIndex); #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (WMODE_CAP_N(PhyMode)) { NdisMoveMemory(&pApCliEntry->MlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&pApCliEntry->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /* We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /* Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; #ifdef APCLI_AUTO_BW_SUPPORT if ((ie_list->HtCapabilityLen > 0) && (ie_list->HtCapability.HtCapInfo.ChannelWidth == BW_40)) { ApCliAutoBwAction(pAd, ifIndex); } #endif /* APCLI_AUTO_BW_SUPPORT */ if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } #ifdef SMART_MESH_MONITOR if(pFrame && (pFrame->Hdr.FC.SubType == SUBTYPE_PROBE_RSP)) { struct nsmpif_drvevnt_buf drvevnt; drvevnt.data.proberesp.type = NSMPIF_DRVEVNT_AP_PROBE_RESP; drvevnt.data.proberesp.channel = ie_list->Channel; COPY_MAC_ADDR(drvevnt.data.proberesp.ap_mac, ie_list->Addr2); drvevnt.data.proberesp.is_ucast = 1; drvevnt.data.proberesp.rate = pAd->LastMgmtRxRate; drvevnt.data.proberesp.rssi = RealRssi; drvevnt.data.proberesp.snr = ConvertToSnr(pAd, Elem->Signal); #ifdef RTMP_MAC if (pAd->chipCap.hif_type == HIF_RTMP) { if (IS_RT6352(pAd)) { if ((42 - drvevnt.data.proberesp.snr) >= 0) drvevnt.data.proberesp.snr = (42 - drvevnt.data.proberesp.snr); else drvevnt.data.proberesp.snr = 0; } } #endif /* RTMP_MAC */ NdisZeroMemory(drvevnt.data.proberesp.ssid,sizeof(drvevnt.data.proberesp.ssid)); NdisCopyMemory(drvevnt.data.proberesp.ssid,ie_list->Ssid,ie_list->SsidLen); drvevnt.data.proberesp.cap = 0; #ifdef DOT11_N_SUPPORT if(ie_list->HtCapabilityLen > 0) drvevnt.data.proberesp.cap |= NSMP_WLCAP_80211_N; #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (ie_list->vht_cap_len > 0) drvevnt.data.proberesp.cap |= NSMP_WLCAP_80211_AC; #endif /* DOT11_VHT_AC */ // Bandwdith if (ie_list->HtCapability.HtCapInfo.ChannelWidth == BW_40) { #ifdef DOT11_VHT_AC if(ie_list->vht_op_len > 0 && ie_list->vht_op_ie.vht_op_info.ch_width >= 1) drvevnt.data.proberesp.cap |= NSMP_WLCAP_HT80; else #endif /* DOT11_VHT_AC */ drvevnt.data.proberesp.cap |= NSMP_WLCAP_HT40; } // RX/TX STREAM drvevnt.data.proberesp.cap |= \ (ie_list->HtCapability.MCSSet[3] != 0x00) ? (NSMP_WLCAP_RX_4_STREAMS|NSMP_WLCAP_TX_4_STREAMS) :\ (ie_list->HtCapability.MCSSet[2] != 0x00) ? (NSMP_WLCAP_RX_3_STREAMS|NSMP_WLCAP_TX_3_STREAMS) :\ (ie_list->HtCapability.MCSSet[1] != 0x00) ? (NSMP_WLCAP_RX_2_STREAMS|NSMP_WLCAP_TX_2_STREAMS) : 0; /* Vendor information element */ drvevnt.data.proberesp.ntgr_vie_len = ie_list->vendor_ie_len; NdisZeroMemory(drvevnt.data.proberesp.ntgr_vie,sizeof(drvevnt.data.proberesp.ntgr_vie)); if(ie_list->vendor_ie_len > 0) NdisCopyMemory(drvevnt.data.proberesp.ntgr_vie,ie_list->vendor_ie,ie_list->vendor_ie_len); RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM,NSMPIF_DRVEVNT_AP_PROBE_RESP, NULL, (PUCHAR)&drvevnt.data.proberesp, sizeof(drvevnt.data.proberesp)); } #endif /* SMART_MESH_MONITOR */ } } LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PAPCLI_STRUCT pApCliEntry = NULL; struct wifi_dev *wdev; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; #endif /* DOT11_N_SUPPORT */ USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState; BCN_IE_LIST *ie_list = NULL; if (ifIndex >= MAX_APCLI_NUM) return; /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; ULONG Bssidx; CHAR RealRssi = -127; RealRssi = (LONG)(RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2))); /* Update ScanTab */ Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ { DBGPRINT(RT_DEBUG_ERROR, ("ERROR: Driver ScanTable Full In Apcli ProbeRsp Join\n")); goto LabelErr; } NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE DBGPRINT(RT_DEBUG_TRACE, ("Info: Update the SSID %s in Kernel Table\n", ie_list->Ssid)); RT_CFG80211_SCANNING_INFORM(pAd, Bssidx, ie_list->Channel, (UCHAR *)Elem->Msg, Elem->MsgLen, RealRssi); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; wdev = &pApCliEntry->wdev; /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; /* Check the Probe-Rsp's Ssid. */ if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) matchFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE /* When using CFG80211 and trigger WPS, do not check security. */ && ! (pApCliEntry->wpa_supplicant_info.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS) #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pApCliEntry->MlmeAux.VarIELen = LenVIE; NdisMoveMemory(pApCliEntry->MlmeAux.VarIEs, pVIE, pApCliEntry->MlmeAux.VarIELen); } else { /* ignore this response */ pApCliEntry->MlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->wdev.AuthMode >= Ndis802_11AuthModeWPA ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pApCliEntry->MlmeAux.VarIELen = 0; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->MlmeAux.Rssi, (LONG)RealRssi)); if (pApCliEntry->MlmeAux.Rssi > (LONG)RealRssi) goto LabelErr; else pApCliEntry->MlmeAux.Rssi = RealRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pApCliEntry->MlmeAux.ProbeTimer, &Cancelled); } NdisMoveMemory(pApCliEntry->MlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pApCliEntry->MlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pApCliEntry->MlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN); pApCliEntry->MlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pApCliEntry->MlmeAux.BssType = ie_list->BssType; pApCliEntry->MlmeAux.BeaconPeriod = ie_list->BeaconPeriod; pApCliEntry->MlmeAux.Channel = ie_list->Channel; pApCliEntry->MlmeAux.AtimWin = ie_list->AtimWin; pApCliEntry->MlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pApCliEntry->MlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pApCliEntry->MlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to MlmeAux for creating assoication request */ /* Also filter out not supported rate */ pApCliEntry->MlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.SupRate, &pApCliEntry->MlmeAux.SupRateLen); pApCliEntry->MlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.ExtRate, &pApCliEntry->MlmeAux.ExtRateLen); #ifdef APCLI_CERT_SUPPORT /* Get the ext capability info element */ if (pAd->bApCliCertTest == TRUE #ifdef DOT11N_DRAFT3 && pAd->CommonCfg.bBssCoexEnable == TRUE #endif /* DOT11N_DRAFT3 */ ) { NdisMoveMemory(&pApCliEntry->MlmeAux.ExtCapInfo, &ie_list->ExtCapInfo,sizeof(ie_list->ExtCapInfo)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 DBGPRINT(RT_DEBUG_TRACE, ("\x1b[31m ApCliMlmeAux.ExtCapInfo=%d \x1b[m\n", pApCliEntry->MlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); //zero debug 210121122 pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ } #endif /* APCLI_CERT_SUPPORT */ #ifdef DOT11_N_SUPPORT NdisZeroMemory(pApCliEntry->RxMcsSet,sizeof(pApCliEntry->RxMcsSet)); /* filter out un-supported ht rates */ if ((ie_list->HtCapabilityLen > 0) && (pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(pAd->CommonCfg.PhyMode) && /* For Dissallow TKIP rule on STA */ !(pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus))) { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pApCliEntry->MlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pApCliEntry->MlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo); if (ie_list->AddHtInfoLen > 0) { CentralChannel = ie_list->AddHtInfo.ControlChan; /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>CentralCh = %d, ControlCh = %d\n", CentralChannel, ie_list->AddHtInfo.ControlChan)); } } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPZeroMemory(&pApCliEntry->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); pApCliEntry->MlmeAux.HtCapabilityLen = 0; } ApCliUpdateMlmeRate(pAd, ifIndex); #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { NdisMoveMemory(&pApCliEntry->MlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pApCliEntry->MlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&pApCliEntry->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pApCliEntry->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /* We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /* Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } } } LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; }
/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; UCHAR /* Ssid[MAX_LEN_OF_SSID], */ SsidLen=0, BssType, Channel=0, MessageToMe, DtimCount, DtimPeriod, BcastFlag; UCHAR *Ssid = NULL; LARGE_INTEGER TimeStamp; USHORT BeaconPeriod, AtimWin, CapabilityInfo; /* UINT FrameLen = 0; */ CF_PARM Cf; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; USHORT LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; /* UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5 */ UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; ULONG RalinkIe; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; /* HT_CAPABILITY_IE HtCapability; */ /* ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE */ HT_CAPABILITY_IE *pHtCapability = NULL; ADD_HT_INFO_IE *pAddHtInfo = NULL; /* AP might use this additional ht info IE */ UCHAR HtCapabilityLen; UCHAR AddHtInfoLen; UCHAR NewChannel; UCHAR NewExtChannelOffset = 0xff; PAPCLI_STRUCT pApCliEntry = NULL; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; #endif /* DOT11_N_SUPPORT */ #ifdef CONFIG_STA_SUPPORT UCHAR pPreNHtCapabilityLen = 0; #endif /* CONFIG_STA_SUPPORT */ EXT_CAP_INFO_ELEMENT ExtCapInfo; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; if (ifIndex >= MAX_APCLI_NUM) return; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&pHtCapability, sizeof(HT_CAPABILITY_IE)); if (pHtCapability == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&pAddHtInfo, sizeof(ADD_HT_INFO_IE)); if (pAddHtInfo == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } os_alloc_mem(NULL, (UCHAR **)&Ssid, MAX_LEN_OF_SSID); if (Ssid == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } /* Init Variable IE structure */ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE)); RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE)); RTMPZeroMemory(&QosCapability, sizeof(QosCapability)); RTMPZeroMemory(&EdcaParm, sizeof(EdcaParm)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, (PCHAR) Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &Cf, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, #ifdef CONFIG_STA_SUPPORT &pPreNHtCapabilityLen, #endif /* CONFIG_STA_SUPPORT */ pHtCapability, &ExtCapInfo, &AddHtInfoLen, pAddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, Bssid); else bssidEmptyFlag = TRUE; /* Check the Probe-Rsp's Ssid. */ if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, Ssid, SsidLen); else ssidEmptyFlag = TRUE; /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) matchFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pApCliEntry->ApCliMlmeAux.VarIELen = LenVIE; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.VarIEs, pVIE, pApCliEntry->ApCliMlmeAux.VarIELen); } else { /* ignore this response */ pApCliEntry->ApCliMlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pApCliEntry->ApCliMlmeAux.VarIELen = 0; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->ApCliMlmeAux.Rssi, (LONG)RealRssi)); if (pApCliEntry->ApCliMlmeAux.Rssi > (LONG)RealRssi) goto LabelErr; else pApCliEntry->ApCliMlmeAux.Rssi = RealRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pApCliEntry->ApCliMlmeAux.ProbeTimer, &Cancelled); } NdisMoveMemory(pApCliEntry->ApCliMlmeAux.Ssid, Ssid, SsidLen); pApCliEntry->ApCliMlmeAux.SsidLen = SsidLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.Bssid, Bssid, MAC_ADDR_LEN); pApCliEntry->ApCliMlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pApCliEntry->ApCliMlmeAux.BssType = BssType; pApCliEntry->ApCliMlmeAux.BeaconPeriod = BeaconPeriod; pApCliEntry->ApCliMlmeAux.Channel = Channel; pApCliEntry->ApCliMlmeAux.AtimWin = AtimWin; pApCliEntry->ApCliMlmeAux.CfpPeriod = Cf.CfpPeriod; pApCliEntry->ApCliMlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; pApCliEntry->ApCliMlmeAux.APRalinkIe = RalinkIe; /* Copy AP's supported rate to ApCliMlmeAux for creating assoication request */ /* Also filter out not supported rate */ pApCliEntry->ApCliMlmeAux.SupRateLen = SupRateLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.SupRate, SupRate, SupRateLen); RTMPCheckRates(pAd, pApCliEntry->ApCliMlmeAux.SupRate, &(pApCliEntry->ApCliMlmeAux.SupRateLen)); pApCliEntry->ApCliMlmeAux.ExtRateLen = ExtRateLen; NdisMoveMemory(pApCliEntry->ApCliMlmeAux.ExtRate, ExtRate, ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->ApCliMlmeAux.ExtRate, &pApCliEntry->ApCliMlmeAux.ExtRateLen); #ifdef APCLI_CERT_SUPPORT /* Get the ext capability info element */ if (pAd->bApCliCertTest == TRUE) { NdisMoveMemory(&pApCliEntry->ApCliMlmeAux.ExtCapInfo, &ExtCapInfo,sizeof(ExtCapInfo)); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 DBGPRINT(RT_DEBUG_TRACE, ("\x1b[31m ApCliMlmeAux.ExtCapInfo=%d \x1b[m\n", pApCliEntry->ApCliMlmeAux.ExtCapInfo.BssCoexistMgmtSupport)); //zero debug 210121122 if (pAd->CommonCfg.bBssCoexEnable == TRUE) pAd->CommonCfg.ExtCapIE.BssCoexistMgmtSupport = 1; #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ } #endif /* APCLI_CERT_SUPPORT */ #ifdef DOT11_N_SUPPORT NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet,sizeof(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet)); /* filter out un-supported ht rates */ if ((HtCapabilityLen > 0) && (pApCliEntry->DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { RTMPZeroMemory(&(pApCliEntry->ApCliMlmeAux.HtCapability), SIZE_HT_CAP_IE); pApCliEntry->ApCliMlmeAux.NewExtChannelOffset = NewExtChannelOffset; pApCliEntry->ApCliMlmeAux.HtCapabilityLen = HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, pHtCapability, pAddHtInfo); if (AddHtInfoLen > 0) { CentralChannel = pAddHtInfo->ControlChan; /* Check again the Bandwidth capability of this AP. */ if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = pAddHtInfo->ControlChan - 2; } else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = pAddHtInfo->ControlChan + 2; } DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, pAddHtInfo->ControlChan)); } } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&(pApCliEntry->ApCliMlmeAux.HtCapability), SIZE_HT_CAP_IE); RTMPZeroMemory(&(pApCliEntry->ApCliMlmeAux.AddHtInfo), SIZE_ADD_HT_INFO_IE); pApCliEntry->ApCliMlmeAux.HtCapabilityLen = 0; } ApCliUpdateMlmeRate(pAd, ifIndex); #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) { NdisMoveMemory(&(pApCliEntry->ApCliMlmeAux.APEdcaParm), &EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&(pApCliEntry->ApCliMlmeAux.APQbssLoad), &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&(pApCliEntry->ApCliMlmeAux.APQosCapability), &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&(pApCliEntry->ApCliMlmeAux.APEdcaParm), sizeof(EDCA_PARM)); NdisZeroMemory(&(pApCliEntry->ApCliMlmeAux.APQbssLoad), sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&(pApCliEntry->ApCliMlmeAux.APQosCapability), sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pApCliEntry->ApCliMlmeAux.SupRateLen, pApCliEntry->ApCliMlmeAux.ExtRateLen)); if (AironetCellPowerLimit != 0xFF) { /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); } else /*Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; #ifdef WSC_AP_SUPPORT #ifdef DOT11_N_SUPPORT if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == TRUE)) { ADD_HTINFO RootApHtInfo, ApHtInfo; ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo; RootApHtInfo = pAddHtInfo->AddHtInfo; if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (RootApHtInfo.RecomWidth) && (RootApHtInfo.ExtChanOffset != ApHtInfo.ExtChanOffset)) { /*STRING ChStr[5] = {0}; */ if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE) Set_HtExtcha_Proc(pAd, "1"); else Set_HtExtcha_Proc(pAd, "0"); goto LabelErr; } } #endif /* DOT11_N_SUPPORT */ #endif /* WSC_AP_SUPPORT */ if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } } /* not to me BEACON, ignored */ } /* sanity check fail, ignore this frame */ LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (pHtCapability != NULL) os_free_mem(NULL, pHtCapability); if (pAddHtInfo != NULL) os_free_mem(NULL, pAddHtInfo); if (Ssid != NULL) os_free_mem(NULL, Ssid); return; }
VOID PeerBeaconAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe, DtimCount, DtimPeriod, BcastFlag, NewChannel; LARGE_INTEGER TimeStamp; USHORT BeaconPeriod, AtimWin, CapabilityInfo; CF_PARM Cf; BOOLEAN TimerCancelled; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; USHORT LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; USHORT Status; UCHAR VarIE[MAX_VIE_LEN]; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; ULONG RalinkIe; ULONG Idx; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; BOOLEAN bAllowNrate = FALSE; #endif pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, (PCHAR)Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &Cf, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, &PreNHtCapabilityLen, &HtCapability, &AddHtInfoLen, &AddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12)) return; if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel)); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0; pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3; pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1; pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3; pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2; pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3; if (pAd->MlmeAux.SsidLen == 0) { NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); pAd->MlmeAux.SsidLen = SsidLen; } else { Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel); if (Idx == BSS_NOT_FOUND) { CHAR Rssi = 0; Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod, &Cf, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); if (Idx != BSS_NOT_FOUND) { NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; } } else { CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; } } NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN); pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pAd->MlmeAux.BssType = BssType; pAd->MlmeAux.BeaconPeriod = BeaconPeriod; pAd->MlmeAux.Channel = Channel; pAd->MlmeAux.AtimWin = AtimWin; pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod; pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; pAd->MlmeAux.APRalinkIe = RalinkIe; pAd->MlmeAux.SupRateLen = SupRateLen; NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); pAd->MlmeAux.ExtRateLen = ExtRateLen; NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16); #ifdef DOT11_N_SUPPORT if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled)) || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) { bAllowNrate = TRUE; } pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (bAllowNrate))) { RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE); NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16); pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE; pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE; if (PreNHtCapabilityLen > 0) pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE; RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n", pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth)); if (AddHtInfoLen > 0) { CentralChannel = AddHtInfo.ControlChan; if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = AddHtInfo.ControlChan - 2; } else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = AddHtInfo.ControlChan + 2; } if (pAd->MlmeAux.CentralChannel != CentralChannel) DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel)); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan)); } } else #endif { if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0)) pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel; pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; pAd->MlmeAux.NewExtChannelOffset = 0xff; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pAd->MlmeAux.HtCapabilityLen = 0; RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); } RTMPUpdateMlmeRate(pAd); if ((pAd->CommonCfg.bWmmCapable) #ifdef DOT11_N_SUPPORT || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) #endif ) { NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else { NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen)); if (AironetCellPowerLimit != 0xFF) { ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); } else pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status); } } }
VOID PeerBeacon( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; CHAR Ssid[MAX_LEN_OF_SSID]; CF_PARM CfParm; UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0; UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0; USHORT CapabilityInfo, AtimWin, BeaconPeriod; LARGE_INTEGER TimeStamp; USHORT TbttNumToNextWakeUp; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; USHORT LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; ULONG RalinkIe; UCHAR VarIE[MAX_VIE_LEN]; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; UCHAR HtCapabilityLen, PreNHtCapabilityLen; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; #ifdef RALINK_ATE if (ATE_ON(pAd)) { return; } #endif if (!(INFRA_ON(pAd) || ADHOC_ON(pAd) )) return; pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &CfParm, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, &PreNHtCapabilityLen, &HtCapability, &AddHtInfoLen, &AddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { BOOLEAN is_my_bssid, is_my_ssid; ULONG Bssidx, Now; BSS_ENTRY *pBss; CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE; is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE; if ((! is_my_ssid) && (! is_my_bssid)) return; if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC) return; #ifdef DOT11_N_SUPPORT if (AddHtInfoLen != 0) Channel = AddHtInfo.ControlChan; if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) HtCapabilityLen = SIZE_HT_CAP_IE; #endif Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); if (Bssidx == BSS_NOT_FOUND) { Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel, RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) return; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); } if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel)) { AsicSwitchChannel(pAd, 1, FALSE); AsicLockChannel(pAd, 1); LinkDown(pAd, FALSE); MlmeQueueInit(&pAd->Mlme.Queue); BssTableInit(&pAd->ScanTab); RTMPusecDelay(1000000); for (index = 0 ; index < pAd->ChannelListNum; index++) { if (pAd->ChannelList[index].Channel == NewChannel) { pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel; pAd->CommonCfg.Channel = NewChannel; AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel)); break; } } if (index >= pAd->ChannelListNum) { DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); } } if ((! is_my_bssid) && ADHOC_ON(pAd)) { INT i; if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus) { return; } for (i = 0; i < 6; i++) { if (Bssid[i] > pAd->CommonCfg.Bssid[i]) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n", Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5])); AsicDisableSync(pAd); COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid); AsicSetBssid(pAd, pAd->CommonCfg.Bssid); MakeIbssBeacon(pAd); AsicEnableIbssSync(pAd); is_my_bssid = TRUE; break; } else if (Bssid[i] < pAd->CommonCfg.Bssid[i]) break; } } NdisGetSystemUpTime(&Now); pBss = &pAd->ScanTab.BssEntry[Bssidx]; pBss->Rssi = RealRssi; pBss->LastBeaconRxTime = Now; if (is_my_bssid) { RXWI_STRUC RxWI; pAd->StaCfg.DtimCount = DtimCount; pAd->StaCfg.DtimPeriod = DtimPeriod; pAd->StaCfg.LastBeaconRxTime = Now; RxWI.RSSI0 = Elem->Rssi0; RxWI.RSSI1 = Elem->Rssi1; RxWI.RSSI2 = Elem->Rssi2; Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI); if (AironetCellPowerLimit != 0xFF) { ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); } else { pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; } if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) { UCHAR MaxSupportedRateIn500Kbps = 0; UCHAR idx; MAC_TABLE_ENTRY *pEntry; for (idx=0; idx<SupRateLen; idx++) { if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f)) MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f; } for (idx=0; idx<ExtRateLen; idx++) { if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f)) MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f; } pEntry = MacTableLookup(pAd, Addr2); if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) || (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now))) { if (pEntry == NULL) pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE); if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, &AddHtInfo, AddHtInfoLen, CapabilityInfo) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n")); return; } if (pEntry && (Elem->Wcid == RESERVED_WCID)) { idx = pAd->StaCfg.DefaultKeyId; RTMP_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry); } } if (pEntry && pEntry->ValidAsCLI) pEntry->LastBeaconRxTime = Now; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); pAd->IndicateMediaState = NdisMediaStateConnected; RTMP_IndicateMediaState(pAd); pAd->ExtraInfo = GENERAL_LINK_UP; AsicSetBssid(pAd, pAd->CommonCfg.Bssid); Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); if (Bssidx == BSS_NOT_FOUND) { Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); } DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n")); } } if (INFRA_ON(pAd)) { BOOLEAN bUseShortSlot, bUseBGProtection; bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo); if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) AsicSetSlotTime(pAd, bUseShortSlot); bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp)); if (pAd->CommonCfg.Channel > 14) bUseBGProtection = FALSE; if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { if (bUseBGProtection) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); } else { OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); } DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection)); } #ifdef DOT11_N_SUPPORT if ((AddHtInfoLen != 0) && ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) || (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent))) { pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent; pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode; if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) { AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE); } else AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode)); } #endif if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) && ERP_IS_USE_BARKER_PREAMBLE(Erp)) { MlmeSetTxPreamble(pAd, Rt802_11PreambleLong); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n")); } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (EdcaParm.bValid == TRUE) && (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n", pAd->CommonCfg.APEdcaParm.EdcaUpdateCount, EdcaParm.EdcaUpdateCount)); AsicSetEdcaParm(pAd, &EdcaParm); } NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave)) { UCHAR FreeNumber; if (MessageToMe) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO) { pAd->CommonCfg.bNeedSendTriggerFrame = TRUE; } else RTMP_PS_POLL_ENQUEUE(pAd); } else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM)) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif } else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) || (pAd->TxSwQueue[QID_AC_BE].Number != 0) || (pAd->TxSwQueue[QID_AC_VI].Number != 0) || (pAd->TxSwQueue[QID_AC_VO].Number != 0) || (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif } else { if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_BE])) { } else { USHORT NextDtim = DtimCount; if (NextDtim == 0) NextDtim = DtimPeriod; TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount; if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim)) TbttNumToNextWakeUp = NextDtim; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp; AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp); } } } } } } }
void send_monitor_packets( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk) { struct sk_buff *pOSPkt; wlan_ng_prism2_header *ph; int rate_index = 0; USHORT header_len = 0; UCHAR temp_header[40] = {0}; u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96, 108, 109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 0,1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80}; ASSERT(pRxBlk->pRxPacket); if (pRxBlk->DataSize < 10) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize)); goto err_free_sk_buff; } if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header))); goto err_free_sk_buff; } pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0); if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) { pRxBlk->DataSize -= LENGTH_802_11; if ((pRxBlk->pHeader->FC.ToDs == 1) && (pRxBlk->pHeader->FC.FrDs == 1)) header_len = LENGTH_802_11_WITH_ADDR4; else header_len = LENGTH_802_11; // QOS if (pRxBlk->pHeader->FC.SubType & 0x08) { header_len += 2; // Data skip QOS contorl field pRxBlk->DataSize -=2; } // Order bit: A-Ralink or HTC+ if (pRxBlk->pHeader->FC.Order) { header_len += 4; // Data skip HTC contorl field pRxBlk->DataSize -= 4; } // Copy Header if (header_len <= 40) NdisMoveMemory(temp_header, pRxBlk->pData, header_len); // skip HW padding if (pRxBlk->RxD.L2PAD) pRxBlk->pData += (header_len + 2); else pRxBlk->pData += header_len; } //end if if (pRxBlk->DataSize < pOSPkt->len) { skb_trim(pOSPkt,pRxBlk->DataSize); } else { skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len)); } //end if if ((pRxBlk->pData - pOSPkt->data) > 0) { skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data)); skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data)); } //end if if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) { if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__)); goto err_free_sk_buff; } //end if } //end if if (header_len > 0) NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len); ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header)); NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header)); ph->msgcode = DIDmsg_lnxind_wlansniffrm; ph->msglen = sizeof(wlan_ng_prism2_header); strcpy(ph->devname, pAd->net_dev->name); ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; ph->hosttime.status = 0; ph->hosttime.len = 4; ph->hosttime.data = jiffies; ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; ph->mactime.status = 0; ph->mactime.len = 0; ph->mactime.data = 0; ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx; ph->istx.status = 0; ph->istx.len = 0; ph->istx.data = 0; ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel; ph->channel.status = 0; ph->channel.len = 4; ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel; ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; ph->rssi.status = 0; ph->rssi.len = 4; ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));; ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; ph->signal.status = 0; ph->signal.len = 4; ph->signal.data = 0; //rssi + noise; ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise; ph->noise.status = 0; ph->noise.len = 4; ph->noise.data = 0; if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) { rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS); } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM) rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4; else rate_index = (UCHAR)(pRxBlk->pRxWI->MCS); if (rate_index < 0) rate_index = 0; if (rate_index > 255) rate_index = 255; ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate; ph->rate.status = 0; ph->rate.len = 4; ph->rate.data = ralinkrate[rate_index]; ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; ph->frmlen.status = 0; ph->frmlen.len = 4; ph->frmlen.data = (u_int32_t)pRxBlk->DataSize; pOSPkt->pkt_type = PACKET_OTHERHOST; pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev); pOSPkt->ip_summed = CHECKSUM_NONE; netif_rx(pOSPkt); return; err_free_sk_buff: RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); return; }
void STA_MonPktSend( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk) { PNET_DEV pNetDev; PNDIS_PACKET pRxPacket; PHEADER_802_11 pHeader; USHORT DataSize; UINT32 MaxRssi; UCHAR L2PAD, PHYMODE, BW, ShortGI, MCS, AMPDU, STBC, RSSI1; UCHAR BssMonitorFlag11n, Channel, CentralChannel; UCHAR *pData, *pDevName; /* sanity check */ ASSERT(pRxBlk->pRxPacket); if (pRxBlk->DataSize < 10) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize)); goto err_free_sk_buff; } if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE) { DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header))); goto err_free_sk_buff; } /* init */ MaxRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2)); pNetDev = get_netdev_from_bssid(pAd, BSS0); pRxPacket = pRxBlk->pRxPacket; pHeader = pRxBlk->pHeader; pData = pRxBlk->pData; DataSize = pRxBlk->DataSize; L2PAD = pRxBlk->RxD.L2PAD; PHYMODE = pRxBlk->pRxWI->PHYMODE; BW = pRxBlk->pRxWI->BW; ShortGI = pRxBlk->pRxWI->ShortGI; MCS = pRxBlk->pRxWI->MCS; AMPDU = pRxBlk->RxD.AMPDU; STBC = pRxBlk->pRxWI->STBC; RSSI1 = pRxBlk->pRxWI->RSSI1; BssMonitorFlag11n = 0; #ifdef MONITOR_FLAG_11N_SNIFFER_SUPPORT BssMonitorFlag11n = (pAd->StaCfg.BssMonitorFlag & MONITOR_FLAG_11N_SNIFFER); #endif /* MONITOR_FLAG_11N_SNIFFER_SUPPORT */ pDevName = (UCHAR *)RtmpOsGetNetDevName(pAd->net_dev); Channel = pAd->CommonCfg.Channel; CentralChannel = pAd->CommonCfg.CentralChannel; /* pass the packet */ send_monitor_packets(pNetDev, pRxPacket, pHeader, pData, DataSize, L2PAD, PHYMODE, BW, ShortGI, MCS, AMPDU, STBC, RSSI1, BssMonitorFlag11n, pDevName, Channel, CentralChannel, MaxRssi); return; err_free_sk_buff: RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); return; }
/* ========================================================================== Description: Process the received ProbeRequest from clients Parameters: Elem - msg containing the ProbeReq frame ========================================================================== */ VOID APPeerProbeReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PEER_PROBE_REQ_PARAM ProbeReqParam; HEADER_802_11 ProbeRspHdr; NDIS_STATUS NStatus; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0, TmpLen; LARGE_INTEGER FakeTimestamp; UCHAR DsLen = 1; UCHAR ErpIeLen = 1; UCHAR apidx = 0, PhyMode, SupRateLen; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2; MULTISSID_STRUCT *mbss; struct wifi_dev *wdev; CHAR rssi = 0, idx = 0; if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, &ProbeReqParam)) return; for(apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { mbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &mbss->wdev; RSNIe = IE_WPA; if ((wdev->if_dev == NULL) || ((wdev->if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(wdev->if_dev)))) { /* the interface is down, so we can not send probe response */ continue; } PhyMode = wdev->PhyMode; if ( ((((ProbeReqParam.SsidLen == 0) && (!mbss->bHideSsid)) || ((ProbeReqParam.SsidLen == mbss->SsidLen) && NdisEqualMemory(ProbeReqParam.Ssid, mbss->Ssid, (ULONG) ProbeReqParam.SsidLen))) ) ) ; else continue; /* check next BSS */ rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, (CHAR)Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, (CHAR)Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, (CHAR)Elem->Rssi2, RSSI_2)); if ((mbss->ProbeRspRssiThreshold != 0) && (rssi < mbss->ProbeRspRssiThreshold)) { DBGPRINT(RT_DEBUG_INFO, ("%s: PROBE_RSP Threshold = %d , PROBE RSSI = %d\n", wdev->if_dev->name, mbss->ProbeRspRssiThreshold, rssi)); continue; } /* allocate and send out ProbeRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, ProbeReqParam.Addr2, wdev->if_addr, wdev->bssid); if ((wdev->AuthMode == Ndis802_11AuthModeWPA) || (wdev->AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((wdev->AuthMode == Ndis802_11AuthModeWPA2) ||(wdev->AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; { SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == WMODE_B) SupRateLen = 4; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &ProbeRspHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &mbss->CapabilityInfo, 1, &SsidIe, 1, &mbss->SsidLen, mbss->SsidLen, mbss->Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); } if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ErpIe, 1, &ErpIeLen, 1, &pAd->ApCfg.ErpIeContent, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } #ifdef A_BAND_SUPPORT /* add Channel switch announcement IE */ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->Dot11_H.CSCount, END_OF_ARGS); FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen, NewExtLen; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif /* YF@20120419: Fix IOT Issue with Atheros STA on Windows 7 When IEEE80211H flag turn on. */ HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); NewExtLen = 1; /*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */ #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability, 1, &AddHtInfoIe, 1, &AddHtLen, sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &AddHtLen, AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #endif /* DOT11_N_SUPPORT */ /* Append RSN_IE when WPA OR WPAPSK, */ if (wdev->AuthMode < Ndis802_11AuthModeWPA) ; /* enough information */ else if ((wdev->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &mbss->RSNIE_Len[0], mbss->RSNIE_Len[0], mbss->RSN_IE[0], 1, &RSNIe2, 1, &mbss->RSNIE_Len[1], mbss->RSNIE_Len[1], mbss->RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &mbss->RSNIE_Len[0], mbss->RSNIE_Len[0], mbss->RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } /* Extended Capabilities IE */ { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D1.10, HT Information Exchange Support */ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].wdev.DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { extCapInfo.BssCoexistMgmtSupport = 1; } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->phy_ctrl.FlgQloadEnable != 0) { FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer+FrameLen); } #endif /* AP_QLOAD_SUPPORT */ /* add WMM IE here */ if (mbss->wdev.bWmmCapable) { UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &mbss->UapsdInfo); #endif /* UAPSD_SUPPORT */ for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen, TmpLen2=0; UCHAR *TmpFrame = NULL; os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); if (TmpFrame != NULL) { NdisZeroMemory(TmpFrame, 256); /* prepare channel information */ #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif /* EXT_BUILD_CHANNEL_LIST */ os_free_mem(NULL, TmpFrame); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) && (wdev->DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); /* P802.11n_D1.10, HT Information Exchange Support */ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].wdev.DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { extCapInfo.BssCoexistMgmtSupport = 1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen2=0; UCHAR TmpFrame[256]; UCHAR CountryIe = IE_COUNTRY; UCHAR MaxTxPower=16; #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (pAd->CommonCfg.Channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) { /* prepare power constraint IE */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 3, PowerConstraintIE, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { ULONG TmpLen; UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; UINT8 ie_len; VHT_TXPWR_ENV_IE txpwr_env; ie_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &vht_txpwr_env_ie, 1, &ie_len, ie_len, &txpwr_env, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_VHT_AC */ } #endif /* A_BAND_SUPPORT */ NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); /* prepare channel information */ MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; }/* Country IE - */ #ifdef A_BAND_SUPPORT /* add Channel switch announcement IE */ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->Dot11_H.CSCount, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); } #endif /* DOT11_N_SUPPORT */ FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen;/*, NewExtLen; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = AddHtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pAd->CommonCfg.Channel > 14)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer+FrameLen), SUBTYPE_PROBE_RSP); } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back Byte0.b3=1 for rssi-feedback */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pAd->CommonCfg.bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pAd->CommonCfg.bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (pAd->CommonCfg.b256QAM_2G && WMODE_2G_ONLY(pAd->CommonCfg.PhyMode)) RalinkSpecificIe[5] |= 0x8; #endif /* DOT11_VHT_AC */ #ifdef RSSI_FEEDBACK if (ProbeReqParam.bRequestRssi == TRUE) { MAC_TABLE_ENTRY *pEntry=NULL; DBGPRINT(RT_DEBUG_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", PRINT_MAC(Addr2))); RalinkSpecificIe[5] |= 0x8; pEntry = MacTableLookup(pAd, Addr2); if (pEntry != NULL) { RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi0; RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi1; RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi2; } } #endif /* RSSI_FEEDBACK */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } /* 802.11n 11.1.3.2.2 active scanning. sending probe response with MCS rate is */ for (idx = 0; idx < mbss->ProbeRspTimes; idx++) MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }