BOOLEAN APFowardWirelessStaToWirelessSta(
IN RTMP_ADAPTER *pAd,
IN PNDIS_PACKET pPacket,
IN ULONG FromWhichBSSID)
{
MAC_TABLE_ENTRY *pEntry = NULL;
BOOLEAN bAnnounce, bDirectForward;
UCHAR *pHeader802_3;
PNDIS_PACKET pForwardPacket;
#ifdef INF_AMAZON_SE
/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
RTMP_SET_PACKET_NOBULKOUT(pPacket, FALSE);
#endif /* INF_AMAZON_SE */
#ifdef APCLI_SUPPORT
/* have no need to forwad the packet to WM */
if (FromWhichBSSID >= MIN_NET_DEVICE_FOR_APCLI)
/* need annouce to upper layer */
return TRUE;
else
#endif /* APCLI_SUPPORT */
#ifdef WDS_SUPPORT
/* have no need to forwad the packet to WM */
if (FromWhichBSSID >= MIN_NET_DEVICE_FOR_WDS)
/* need annouce to upper layer */
return TRUE;
#endif /* WDS_SUPPORT */
pEntry = NULL;
bAnnounce = TRUE;
bDirectForward = FALSE;
pHeader802_3 = GET_OS_PKT_DATAPTR(pPacket);
if (pHeader802_3[0] & 0x01)
{
/*
* In the case, the BSS have only one STA behind.
* AP have no necessary to forward the M/Bcase packet back to STA again.
*/
if (
((FromWhichBSSID < MAX_MBSSID_NUM(pAd)) &&
(FromWhichBSSID < HW_BEACON_MAX_NUM) &&
(pAd->ApCfg.MBSSID[FromWhichBSSID].StaCount > 1)))
{
if (pAd->ApCfg.MBSSID[FromWhichBSSID].IsolateInterStaMBCast == 0)
{
bDirectForward = TRUE;
}
}
/* tell caller to deliver the packet to upper layer */
bAnnounce = TRUE;
}
else
{
#ifdef CLIENT_WDS
{
MAC_TABLE_ENTRY *pFromEntry = NULL;
PUCHAR pEntryAddr;
pEntry = MacTableLookup(pAd, pHeader802_3);
if ((pEntry == NULL)
&& (pEntryAddr = CliWds_ProxyLookup(pAd, pHeader802_3)) != NULL)
{
pEntry = MacTableLookup(pAd, pEntryAddr);
pFromEntry = MacTableLookup(pAd, pHeader802_3 + MAC_ADDR_LEN);
if ((pFromEntry == NULL)
&& (pEntryAddr = CliWds_ProxyLookup(pAd, pHeader802_3 + MAC_ADDR_LEN)) != NULL)
{
pFromEntry = MacTableLookup(pAd, pEntryAddr);
}
if (pEntry == pFromEntry)
{
DBGPRINT(RT_DEBUG_TRACE, ("%s : Do not send it back\n", __FUNCTION__));
pEntry = NULL;
}
}
}
#else
/* if destinated STA is a associated wireless STA */
pEntry = MacTableLookup(pAd, pHeader802_3);
#endif /* CLIENT_WDS*/
if (pEntry && (pEntry->Sst == SST_ASSOC) && IS_ENTRY_CLIENT(pEntry))
{
bDirectForward = TRUE;
bAnnounce = FALSE;
if (FromWhichBSSID == pEntry->apidx)
{/* STAs in same SSID */
if ((pAd->ApCfg.MBSSID[pEntry->apidx].IsolateInterStaTraffic == 1))
{
/* release the packet */
bDirectForward = FALSE;
bAnnounce = FALSE;
}
}
else
{/* STAs in different SSID */
if (pAd->ApCfg.IsolateInterStaTrafficBTNBSSID == 1 ||
((FromWhichBSSID < MAX_MBSSID_NUM(pAd)) &&
(FromWhichBSSID < HW_BEACON_MAX_NUM) &&
(pAd->ApCfg.MBSSID[pEntry->apidx].wdev.VLAN_VID != pAd->ApCfg.MBSSID[FromWhichBSSID].wdev.VLAN_VID)))
/* destination VLAN ID != source VLAN ID */
{
/*
Do not need to care WDS mode because packets from a
WDS interface will be passed to upper layer for bridging.
*/
bDirectForward = FALSE;
bAnnounce = FALSE;
}
}
}
else
{
/* announce this packet to upper layer (bridge) */
bDirectForward = FALSE;
bAnnounce = TRUE;
}
}
if (bDirectForward)
{
/* build an NDIS packet */
pForwardPacket = RTMP_DUPLICATE_PACKET(pAd, pPacket, FromWhichBSSID);
if (pForwardPacket == NULL)
{
return bAnnounce;
}
{
/* 1.1 apidx != 0, then we need set packet mbssid attribute. */
RTMP_SET_PACKET_NET_DEVICE_MBSSID(pForwardPacket, MAIN_MBSSID); /* set a default value */
if (pEntry && (pEntry->apidx != 0))
{
RTMP_SET_PACKET_NET_DEVICE_MBSSID(pForwardPacket, pEntry->apidx);
if ( pEntry && pEntry->wcid != MCAST_WCID)
{
RTMP_SET_PACKET_WDEV(pPacket, pEntry->wdev->wdev_idx);
}
}
/* send bc/mc frame back to the same bss */
if (!pEntry)
{
RTMP_SET_PACKET_NET_DEVICE_MBSSID(pForwardPacket, FromWhichBSSID);
//also need to send back to same bss
if ((FromWhichBSSID >= 0) &&
(FromWhichBSSID < pAd->ApCfg.BssidNum) &&
(FromWhichBSSID < MAX_MBSSID_NUM(pAd)) &&
(FromWhichBSSID < HW_BEACON_MAX_NUM))
{
RTMP_SET_PACKET_WDEV(pForwardPacket, pAd->ApCfg.MBSSID[FromWhichBSSID].wdev.wdev_idx);
}
}
RTMP_SET_PACKET_WCID(pForwardPacket, pEntry ? pEntry->wcid : MCAST_WCID);
RTMP_SET_PACKET_MOREDATA(pForwardPacket, FALSE);
#ifdef INF_AMAZON_SE
/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
RTMP_SET_PACKET_NOBULKOUT(pForwardPacket, TRUE);
#endif /* INF_AMAZON_SE */
APSendPacket(pAd, pForwardPacket);
}
/* Dequeue outgoing frames from TxSwQueue0..3 queue and process it */
RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
}
return bAnnounce;
}