static VOID MeasureReqDelete( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken) { PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; PMEASURE_REQ_ENTRY pEntry = NULL; if(pTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__)); return; } // if empty, return if (pTab->Size == 0) { DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n")); return; } pEntry = MeasureReqLookUp(pAd, DialogToken); if (pEntry != NULL) { PMEASURE_REQ_ENTRY pPrevEntry = NULL; ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); // update Hash list do { if (pProbeEntry == pEntry) { if (pPrevEntry == NULL) { pTab->Hash[HashIdx] = pEntry->pNext; } else { pPrevEntry->pNext = pEntry->pNext; } break; } pPrevEntry = pProbeEntry; pProbeEntry = pProbeEntry->pNext; } while (pProbeEntry); NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY)); pTab->Size--; RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); } return; }
/* ========================================================================== Description: Measurement Report action frame handler. Parametrs: Elme - MLME message containing the received frame Return : None. ========================================================================== */ static VOID PeerMeasureReportAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { MEASURE_REPORT_INFO MeasureReportInfo; PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; UINT8 DialogToken; PUINT8 pMeasureReportInfo; // if (pAd->CommonCfg.bIEEE80211H != TRUE) // return; if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT))); return; } NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO)); NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT)); if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo)) { do { PMEASURE_REQ_ENTRY pEntry = NULL; // Not a autonomous measure report. // check the dialog token field. drop it if the dialog token doesn't match. if ((DialogToken != 0) && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL)) break; if (pEntry != NULL) MeasureReqDelete(pAd, pEntry->DialogToken); if (MeasureReportInfo.ReportType == RM_BASIC) { PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo; if ((pBasicReport->Map.field.Radar) && (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE)) { NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum); StartDFSProcedure(pAd, pBasicReport->ChNum, 1); } } } while (FALSE); } else DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n")); kfree(pMeasureReportInfo); return; }
VOID RRM_PeerMeasureRepAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; PUCHAR pFramePtr = pFr->Octet; ULONG MsgLen = Elem->MsgLen; PMEASURE_REQ_ENTRY pDialogEntry; PMAC_TABLE_ENTRY pEntry; UINT8 DialogToken; DBGPRINT(RT_DEBUG_TRACE, ("%s::\n", __FUNCTION__)); /* skip Category and action code. */ pFramePtr += 2; MsgLen -= 2; /* get DialogToken. */ NdisMoveMemory(&DialogToken, pFramePtr, 1); pFramePtr += 1; MsgLen -= 1; /* Not a autonomous measure report (non zero DialogToken). check the dialog token field. drop it if the dialog token doesn't match. */ pDialogEntry = NULL; if ((DialogToken != 0) && ((pDialogEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL)) return; if (pDialogEntry != NULL) MeasureReqDelete(pAd, pDialogEntry->DialogToken); do { PEID_STRUCT eid_ptr; MEASURE_REPORT_MODE ReportMode; UINT8 ReportType; PRRM_BEACON_REP_INFO pMeasureRep; /* Is the STA associated. Dorp the Measure report if it's not. */ pEntry = MacTableLookup(pAd, pFr->Hdr.Addr2); if (!pEntry || (pEntry->Sst != SST_ASSOC)) break; eid_ptr = (PEID_STRUCT)pFramePtr; while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen)) { switch(eid_ptr->Eid) { case IE_MEASUREMENT_REPORT: { LONG BcnRepLen = (LONG)eid_ptr->Len - 3; NdisMoveMemory(&ReportMode, eid_ptr->Octet + 1, 1); NdisMoveMemory(&ReportType, eid_ptr->Octet + 2, 1); pMeasureRep = (PVOID)(eid_ptr->Octet + 3); if (ReportType == RRM_MEASURE_SUBTYPE_BEACON) RRM_BeaconReportHandler(pAd, pMeasureRep, BcnRepLen); } break; default: break; } eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); } } while(FALSE); return; }
static PMEASURE_REQ_ENTRY MeasureReqInsert( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken) { INT i; ULONG HashIdx; PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab; PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry; ULONG Now; if(pTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __func__)); return NULL; } pEntry = MeasureReqLookUp(pAd, DialogToken); if (pEntry == NULL) { RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) { NdisGetSystemUpTime(&Now); pEntry = &pTab->Content[i]; if ((pEntry->Valid == TRUE) && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT))) { PMEASURE_REQ_ENTRY pPrevEntry = NULL; ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx]; // update Hash list do { if (pProbeEntry == pEntry) { if (pPrevEntry == NULL) { pTab->Hash[HashIdx] = pEntry->pNext; } else { pPrevEntry->pNext = pEntry->pNext; } break; } pPrevEntry = pProbeEntry; pProbeEntry = pProbeEntry->pNext; } while (pProbeEntry); NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY)); pTab->Size--; break; } if (pEntry->Valid == FALSE) break; } if (i < MAX_MEASURE_REQ_TAB_SIZE) { NdisGetSystemUpTime(&Now); pEntry->lastTime = Now; pEntry->Valid = TRUE; pEntry->DialogToken = DialogToken; pTab->Size++; } else { pEntry = NULL; DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __func__)); } // add this Neighbor entry into HASH table if (pEntry) { HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); if (pTab->Hash[HashIdx] == NULL) { pTab->Hash[HashIdx] = pEntry; } else { pCurrEntry = pTab->Hash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pEntry; } } RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); } return pEntry; }