VOID MultipathEntryInsert( IN PRTMP_ADAPTER pAd, IN UCHAR LinkIdx, IN PUCHAR pMac) { PMESH_MULTIPATH_ENTRY pEntry; UINT8 HashId = *(pMac + 5); ULONG Now; if (!VALID_MESH_LINK_ID(LinkIdx)) return; pEntry = MultipathEntryLookUp(pAd, LinkIdx, pMac); if(pEntry == NULL) { if ((pEntry = MultipathEntyAlloc(pAd)) == NULL) return; insertTailList(&pAd->MeshTab.MeshLink[LinkIdx].Entry.MultiPathHash[HashId], (PLIST_ENTRY)pEntry); } DBGPRINT(RT_DEBUG_TRACE, ("Block multipath pkt to link(%d) from SA=%02x:%02x:%02x:%02x:%02x:%02x\n", LinkIdx, pMac[0], pMac[1], pMac[2], pMac[3], pMac[4], pMac[5])); NdisGetSystemUpTime(&Now); COPY_MAC_ADDR(pEntry->MeshSA, pMac); pEntry->ReferTime = Now; return; }
VOID MultipathEntryMaintain( IN PRTMP_ADAPTER pAd, IN UCHAR LinkIdx) { ULONG i; PMESH_MULTIPATH_ENTRY pEntry; ULONG Now; if (!VALID_MESH_LINK_ID(LinkIdx)) return; NdisGetSystemUpTime(&Now); for (i = 0; i < MULTIPATH_HASH_TAB_SIZE; i++) { pEntry = (PMESH_MULTIPATH_ENTRY)(pAd->MeshTab.MeshLink[LinkIdx].Entry.MultiPathHash[i].pHead); while (pEntry) { PMESH_MULTIPATH_ENTRY pEntryNext = pEntry->pNext; if (RTMP_TIME_AFTER(Now, pEntry->ReferTime + (pAd->MeshTab.MeshMultiCastAgeOut * OS_HZ / 1000))) { delEntryList(&pAd->MeshTab.MeshLink[LinkIdx].Entry.MultiPathHash[i], (PLIST_ENTRY)pEntry); MultipathEntyFree(pAd, pEntry); } pEntry = pEntryNext; } } return; }
VOID NeighborTableUpdate( IN PRTMP_ADAPTER pAd) { INT i; PMESH_NEIGHBOR_TAB pNeighborTab = pAd->MeshTab.pMeshNeighborTab; PMESH_NEIGHBOR_ENTRY pNeighborEntry = NULL; ULONG Now; if(pNeighborTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("pAd->MeshTab.pMeshNeighborTab equal NULL.\n")); return; } for (i = 0; i < MAX_NEIGHBOR_MP; i++) { pNeighborEntry = &pAd->MeshTab.pMeshNeighborTab->NeighborMP[i]; if (pNeighborEntry->Valid == FALSE) continue; NdisGetSystemUpTime(&Now); /*if ((++pNeighborEntry->IdleCnt > NEIGHBOR_MP_IDLE_CNT)) */ if(RTMP_TIME_AFTER(Now, pNeighborEntry->LastBeaconTime + (MESH_NEIGHBOR_BEACON_IDLE_TIME * OS_HZ / 1000) )) { if (MeshValid(&pAd->MeshTab) && (pNeighborEntry->State == CANDIDATE_MP) && (PeerLinkValidCheck(pAd, pNeighborEntry->MeshLinkIdx) == TRUE)) { MlmeEnqueue(pAd, MESH_LINK_MNG_STATE_MACHINE, MESH_LINK_MNG_CNCL, 0, NULL, pNeighborEntry->MeshLinkIdx); } if ( (pAd->MeshTab.UCGEnable && pNeighborEntry->Channel == pAd->MeshTab.MeshChannel) || !pAd->MeshTab.UCGEnable) DeleteNeighborMP(pAd, pNeighborEntry->PeerMac); } else { if (VALID_MESH_LINK_ID(pNeighborEntry->MeshLinkIdx)) { if ((pNeighborEntry->State == LINK_AVAILABLE) && (pNeighborEntry->ExtChOffset != pAd->MeshTab.MeshLink[pNeighborEntry->MeshLinkIdx].Entry.ExtChOffset)) { DBGPRINT(RT_DEBUG_TRACE, ("Link%d:Neighbor ExtChOffset change from %d to %d , kill the link!\n" ,pNeighborEntry->MeshLinkIdx ,pNeighborEntry->ExtChOffset,pAd->MeshTab.MeshLink[pNeighborEntry->MeshLinkIdx].Entry.ExtChOffset)); MlmeEnqueue(pAd, MESH_LINK_MNG_STATE_MACHINE, MESH_LINK_MNG_CNCL, 0, NULL, pNeighborEntry->MeshLinkIdx); RTMP_MLME_HANDLER(pAd); } } } } return; }
PMESH_MULTIPATH_ENTRY MultipathEntryLookUp( IN PRTMP_ADAPTER pAd, IN UCHAR LinkIdx, IN PUCHAR pMac) { UINT8 HashId = *(pMac + 5); PMESH_MULTIPATH_ENTRY pEntry; if (!VALID_MESH_LINK_ID(LinkIdx)) return NULL; pEntry = (PMESH_MULTIPATH_ENTRY)(pAd->MeshTab.MeshLink[LinkIdx].Entry.MultiPathHash[HashId].pHead); while (pEntry != NULL) { if(MAC_ADDR_EQUAL(pEntry->MeshSA, pMac)) break; pEntry = pEntry->pNext; } return pEntry; }
VOID MultipathEntryDelete( IN PRTMP_ADAPTER pAd, IN UCHAR LinkIdx, IN PUCHAR pMac) { UINT8 HashId = *(pMac + 5); PMESH_MULTIPATH_ENTRY pEntry; if (!VALID_MESH_LINK_ID(LinkIdx)) return; pEntry = MultipathEntryLookUp(pAd, LinkIdx, pMac); if (pEntry != NULL) { DBGPRINT(RT_DEBUG_TRACE, ("release multipath pkt to link(%d) from SA=%02x:%02x:%02x:%02x:%02x:%02x\n", LinkIdx, pMac[0], pMac[1], pMac[2], pMac[3], pMac[4], pMac[5])); delEntryList(&pAd->MeshTab.MeshLink[LinkIdx].Entry.MultiPathHash[HashId], (PLIST_ENTRY)pEntry); MultipathEntyFree(pAd, pEntry); } }
VOID MultipathListDelete( IN PRTMP_ADAPTER pAd, IN UCHAR LinkIdx) { ULONG i; PMESH_MULTIPATH_ENTRY pEntry; if (!VALID_MESH_LINK_ID(LinkIdx)) return; DBGPRINT(RT_DEBUG_TRACE, ("release all multipath pkt of link(%d)\n", LinkIdx)); for (i = 0; i < MULTIPATH_HASH_TAB_SIZE; i++) { pEntry = (PMESH_MULTIPATH_ENTRY)removeHeadList(&pAd->MeshTab.MeshLink[LinkIdx].Entry.MultiPathHash[i]); while (pEntry != NULL) { MultipathEntyFree(pAd, pEntry); pEntry = (PMESH_MULTIPATH_ENTRY)removeHeadList(&pAd->MeshTab.MeshLink[LinkIdx].Entry.MultiPathHash[i]); } } return; }
VOID CandidateMPSelect( IN PRTMP_ADAPTER pAd) { INT i; PMESH_NEIGHBOR_TAB pNeighborTab = pAd->MeshTab.pMeshNeighborTab; PMESH_NEIGHBOR_ENTRY pNeighborEntry = NULL; if(pNeighborTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("pAd->MeshTab.pMeshNeighborTab equal NULL.\n")); return; } if ((pAd->MeshTab.CPI == 0) && (pNeighborTab->NeighborNr == 0)) { pAd->MeshTab.CPI = RandomMeshCPI(pAd); } else { pNeighborEntry = NeighMPWithMaxCPI(pAd, pNeighborTab); if ((pNeighborEntry != NULL) && (pAd->MeshTab.CPI < pNeighborEntry->CPI)) { if (pAd->CommonCfg.Channel != pNeighborEntry->Channel) { pAd->MeshTab.CPI = pNeighborEntry->CPI; /* start UCG Procedural. */ } } if (pAd->MeshTab.MeshAutoLink == FALSE) return; for (i = 0; i < pNeighborTab->NeighborNr; i++) { pNeighborEntry = &pNeighborTab->NeighborMP[i]; if (!NeighborMPCheck(pAd, pNeighborEntry->MeshId, (UINT8)pNeighborEntry->PathProtocolId, (UINT8)pNeighborEntry->PathMetricId)) continue; DBGPRINT(RT_DEBUG_TRACE, ("(%d) CPI=%d Apl=%d channel=%d state=%d\n", i, pNeighborEntry->CPI, pNeighborEntry->MeshCapability.field.AcceptPeerLinks, pNeighborEntry->Channel, pNeighborEntry->State)); DBGPRINT(RT_DEBUG_TRACE, ("%d %d %d %d %d\n", (GetMeshSecurity(pAd)==MeshCheckPeerMpCipher(pNeighborEntry->CapabilityInfo, pNeighborEntry->RSNIE, pNeighborEntry->RSNIE_Len)), (pNeighborEntry->MeshCapability.field.AcceptPeerLinks), (pNeighborEntry->State == NEIGHBOR_MP), MeshChCheck(pAd, pNeighborEntry), ((pAd->MeshTab.CPI <= pNeighborEntry->CPI) ||((pAd->MeshTab.CPI == pNeighborEntry->CPI) && (memcmp(pNeighborEntry->PeerMac, pAd->MeshTab.CurrentAddress, MAC_ADDR_LEN) < 0))))); if ((GetMeshSecurity(pAd)==MeshCheckPeerMpCipher(pNeighborEntry->CapabilityInfo, pNeighborEntry->RSNIE, pNeighborEntry->RSNIE_Len)) && (pNeighborEntry->MeshCapability.field.AcceptPeerLinks) && (pNeighborEntry->State == NEIGHBOR_MP) && MeshChCheck(pAd, pNeighborEntry) && ((pAd->MeshTab.CPI <= pNeighborEntry->CPI) ||((pAd->MeshTab.CPI == pNeighborEntry->CPI) && (memcmp(pNeighborEntry->PeerMac, pAd->MeshTab.CurrentAddress, MAC_ADDR_LEN) < 0))) ) { ULONG LinkIdx = MeshLinkAlloc(pAd, pNeighborEntry->PeerMac, MESH_LINK_DYNAMIC); DBGPRINT(RT_DEBUG_TRACE, ("(%d) pick LinkId=%ld\n", i, LinkIdx)); if (VALID_MESH_LINK_ID(LinkIdx)) { pAd->MeshTab.CPI = pNeighborEntry->CPI; pNeighborEntry->State = CANDIDATE_MP; pNeighborEntry->MeshLinkIdx = LinkIdx; } } } } return; }