|
|
| 719 |
} |
719 |
} |
| 720 |
|
720 |
|
| 721 |
void |
721 |
void |
| 722 |
ApWifiMac::SendAssocResp (Mac48Address to, bool success) |
722 |
ApWifiMac::SendAssocResp (Mac48Address to, bool success, bool isReassoc) |
| 723 |
{ |
723 |
{ |
| 724 |
NS_LOG_FUNCTION (this << to << success); |
724 |
NS_LOG_FUNCTION (this << to << success << isReassoc); |
| 725 |
WifiMacHeader hdr; |
725 |
WifiMacHeader hdr; |
| 726 |
hdr.SetType (WIFI_MAC_MGT_ASSOCIATION_RESPONSE); |
726 |
hdr.SetType (isReassoc ? WIFI_MAC_MGT_REASSOCIATION_RESPONSE : WIFI_MAC_MGT_ASSOCIATION_RESPONSE); |
| 727 |
hdr.SetAddr1 (to); |
727 |
hdr.SetAddr1 (to); |
| 728 |
hdr.SetAddr2 (GetAddress ()); |
728 |
hdr.SetAddr2 (GetAddress ()); |
| 729 |
hdr.SetAddr3 (GetAddress ()); |
729 |
hdr.SetAddr3 (GetAddress ()); |
|
|
| 736 |
if (success) |
736 |
if (success) |
| 737 |
{ |
737 |
{ |
| 738 |
code.SetSuccess (); |
738 |
code.SetSuccess (); |
| 739 |
uint16_t aid = GetNextAssociationId (); |
739 |
uint16_t aid; |
| 740 |
m_staList.insert (std::make_pair (aid, to)); |
740 |
bool found = false; |
|
|
741 |
if (isReassoc) |
| 742 |
{ |
| 743 |
for (std::map<uint16_t, Mac48Address>::const_iterator i = m_staList.begin (); i != m_staList.end (); ++i) |
| 744 |
{ |
| 745 |
if (i->second == to) |
| 746 |
{ |
| 747 |
aid = i->first; |
| 748 |
found = true; |
| 749 |
break; |
| 750 |
} |
| 751 |
} |
| 752 |
} |
| 753 |
if (!found) |
| 754 |
{ |
| 755 |
aid = GetNextAssociationId (); |
| 756 |
m_staList.insert (std::make_pair (aid, to)); |
| 757 |
} |
| 741 |
assoc.SetAssociationId (aid); |
758 |
assoc.SetAssociationId (aid); |
| 742 |
} |
759 |
} |
| 743 |
else |
760 |
else |
|
|
| 857 |
{ |
874 |
{ |
| 858 |
NS_LOG_FUNCTION (this); |
875 |
NS_LOG_FUNCTION (this); |
| 859 |
RegularWifiMac::TxOk (hdr); |
876 |
RegularWifiMac::TxOk (hdr); |
| 860 |
|
877 |
if ((hdr.IsAssocResp () || hdr.IsReassocResp ()) |
| 861 |
if (hdr.IsAssocResp () |
|
|
| 862 |
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
878 |
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
| 863 |
{ |
879 |
{ |
| 864 |
NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ()); |
880 |
NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ()); |
|
|
| 872 |
NS_LOG_FUNCTION (this); |
888 |
NS_LOG_FUNCTION (this); |
| 873 |
RegularWifiMac::TxFailed (hdr); |
889 |
RegularWifiMac::TxFailed (hdr); |
| 874 |
|
890 |
|
| 875 |
if (hdr.IsAssocResp () |
891 |
if ((hdr.IsAssocResp () || hdr.IsReassocResp ()) |
| 876 |
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
892 |
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
| 877 |
{ |
893 |
{ |
| 878 |
NS_LOG_DEBUG ("assoc failed with sta=" << hdr.GetAddr1 ()); |
894 |
NS_LOG_DEBUG ("association failed with sta=" << hdr.GetAddr1 ()); |
| 879 |
m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ()); |
895 |
m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ()); |
| 880 |
} |
896 |
} |
| 881 |
} |
897 |
} |
|
|
| 884 |
ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr) |
900 |
ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr) |
| 885 |
{ |
901 |
{ |
| 886 |
NS_LOG_FUNCTION (this << packet << hdr); |
902 |
NS_LOG_FUNCTION (this << packet << hdr); |
| 887 |
|
|
|
| 888 |
Mac48Address from = hdr->GetAddr2 (); |
903 |
Mac48Address from = hdr->GetAddr2 (); |
| 889 |
|
|
|
| 890 |
if (hdr->IsData ()) |
904 |
if (hdr->IsData ()) |
| 891 |
{ |
905 |
{ |
| 892 |
Mac48Address bssid = hdr->GetAddr1 (); |
906 |
Mac48Address bssid = hdr->GetAddr1 (); |
|
|
| 961 |
if (hdr->IsProbeReq ()) |
975 |
if (hdr->IsProbeReq ()) |
| 962 |
{ |
976 |
{ |
| 963 |
NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ()); |
977 |
NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ()); |
|
|
978 |
NS_LOG_DEBUG ("Probe request received from " << from << ": send probe response"); |
| 964 |
SendProbeResp (from); |
979 |
SendProbeResp (from); |
| 965 |
return; |
980 |
return; |
| 966 |
} |
981 |
} |
|
|
| 968 |
{ |
983 |
{ |
| 969 |
if (hdr->IsAssocReq ()) |
984 |
if (hdr->IsAssocReq ()) |
| 970 |
{ |
985 |
{ |
|
|
986 |
NS_LOG_DEBUG ("Association request received from " << from); |
| 971 |
//first, verify that the the station's supported |
987 |
//first, verify that the the station's supported |
| 972 |
//rate set is compatible with our Basic Rate set |
988 |
//rate set is compatible with our Basic Rate set |
| 973 |
MgtAssocRequestHeader assocReq; |
989 |
MgtAssocRequestHeader assocReq; |
|
|
| 1074 |
} |
1090 |
} |
| 1075 |
if (problem) |
1091 |
if (problem) |
| 1076 |
{ |
1092 |
{ |
| 1077 |
//One of the Basic Rate set mode is not |
1093 |
NS_LOG_DEBUG ("One of the Basic Rate set mode is not supported by the station: send association response with an error status"); |
| 1078 |
//supported by the station. So, we return an assoc |
1094 |
SendAssocResp (hdr->GetAddr2 (), false, false); |
| 1079 |
//response with an error status. |
|
|
| 1080 |
SendAssocResp (hdr->GetAddr2 (), false); |
| 1081 |
} |
1095 |
} |
| 1082 |
else |
1096 |
else |
| 1083 |
{ |
1097 |
{ |
| 1084 |
//station supports all rates in Basic Rate Set. |
1098 |
NS_LOG_DEBUG ("The Basic Rate set modes are supported by the station"); |
| 1085 |
//record all its supported modes in its associated WifiRemoteStation |
1099 |
//record all its supported modes in its associated WifiRemoteStation |
| 1086 |
for (uint8_t j = 0; j < m_phy->GetNModes (); j++) |
1100 |
for (uint8_t j = 0; j < m_phy->GetNModes (); j++) |
| 1087 |
{ |
1101 |
{ |
|
|
| 1136 |
if (!isHtStation) |
1150 |
if (!isHtStation) |
| 1137 |
{ |
1151 |
{ |
| 1138 |
m_nonHtStations.push_back (hdr->GetAddr2 ()); |
1152 |
m_nonHtStations.push_back (hdr->GetAddr2 ()); |
|
|
1153 |
m_nonHtStations.unique (); |
| 1139 |
} |
1154 |
} |
| 1140 |
if (!isErpStation && isDsssStation) |
1155 |
if (!isErpStation && isDsssStation) |
| 1141 |
{ |
1156 |
{ |
| 1142 |
m_nonErpStations.push_back (hdr->GetAddr2 ()); |
1157 |
m_nonErpStations.push_back (hdr->GetAddr2 ()); |
|
|
1158 |
m_nonErpStations.unique (); |
| 1143 |
} |
1159 |
} |
| 1144 |
// send assoc response with success status. |
1160 |
NS_LOG_DEBUG ("Send association response with success status"); |
| 1145 |
SendAssocResp (hdr->GetAddr2 (), true); |
1161 |
SendAssocResp (hdr->GetAddr2 (), true, false); |
|
|
1162 |
} |
| 1163 |
return; |
| 1164 |
} |
| 1165 |
else if (hdr->IsReassocReq ()) |
| 1166 |
{ |
| 1167 |
NS_LOG_DEBUG ("Reassociation request received from " << from); |
| 1168 |
//first, verify that the the station's supported |
| 1169 |
//rate set is compatible with our Basic Rate set |
| 1170 |
MgtReassocRequestHeader reassocReq; |
| 1171 |
packet->RemoveHeader (reassocReq); |
| 1172 |
CapabilityInformation capabilities = reassocReq.GetCapabilities (); |
| 1173 |
m_stationManager->AddSupportedPlcpPreamble (from, capabilities.IsShortPreamble ()); |
| 1174 |
SupportedRates rates = reassocReq.GetSupportedRates (); |
| 1175 |
bool problem = false; |
| 1176 |
bool isHtStation = false; |
| 1177 |
bool isOfdmStation = false; |
| 1178 |
bool isErpStation = false; |
| 1179 |
bool isDsssStation = false; |
| 1180 |
for (uint8_t i = 0; i < m_stationManager->GetNBasicModes (); i++) |
| 1181 |
{ |
| 1182 |
WifiMode mode = m_stationManager->GetBasicMode (i); |
| 1183 |
if (!rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth ()))) |
| 1184 |
{ |
| 1185 |
if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)) |
| 1186 |
{ |
| 1187 |
isDsssStation = false; |
| 1188 |
} |
| 1189 |
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM) |
| 1190 |
{ |
| 1191 |
isErpStation = false; |
| 1192 |
} |
| 1193 |
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM) |
| 1194 |
{ |
| 1195 |
isOfdmStation = false; |
| 1196 |
} |
| 1197 |
if (isDsssStation == false && isErpStation == false && isOfdmStation == false) |
| 1198 |
{ |
| 1199 |
problem = true; |
| 1200 |
break; |
| 1201 |
} |
| 1202 |
} |
| 1203 |
else |
| 1204 |
{ |
| 1205 |
if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)) |
| 1206 |
{ |
| 1207 |
isDsssStation = true; |
| 1208 |
} |
| 1209 |
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM) |
| 1210 |
{ |
| 1211 |
isErpStation = true; |
| 1212 |
} |
| 1213 |
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM) |
| 1214 |
{ |
| 1215 |
isOfdmStation = true; |
| 1216 |
} |
| 1217 |
} |
| 1218 |
} |
| 1219 |
m_stationManager->AddSupportedErpSlotTime (from, capabilities.IsShortSlotTime () && isErpStation); |
| 1220 |
if (m_htSupported) |
| 1221 |
{ |
| 1222 |
//check whether the HT STA supports all MCSs in Basic MCS Set |
| 1223 |
HtCapabilities htcapabilities = reassocReq.GetHtCapabilities (); |
| 1224 |
if (htcapabilities.IsSupportedMcs (0)) |
| 1225 |
{ |
| 1226 |
isHtStation = true; |
| 1227 |
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) |
| 1228 |
{ |
| 1229 |
WifiMode mcs = m_stationManager->GetBasicMcs (i); |
| 1230 |
if (!htcapabilities.IsSupportedMcs (mcs.GetMcsValue ())) |
| 1231 |
{ |
| 1232 |
problem = true; |
| 1233 |
break; |
| 1234 |
} |
| 1235 |
} |
| 1236 |
} |
| 1237 |
} |
| 1238 |
if (m_vhtSupported) |
| 1239 |
{ |
| 1240 |
//check whether the VHT STA supports all MCSs in Basic MCS Set |
| 1241 |
VhtCapabilities vhtcapabilities = reassocReq.GetVhtCapabilities (); |
| 1242 |
if (vhtcapabilities.GetVhtCapabilitiesInfo () != 0) |
| 1243 |
{ |
| 1244 |
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) |
| 1245 |
{ |
| 1246 |
WifiMode mcs = m_stationManager->GetBasicMcs (i); |
| 1247 |
if (!vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
| 1248 |
{ |
| 1249 |
problem = true; |
| 1250 |
break; |
| 1251 |
} |
| 1252 |
} |
| 1253 |
} |
| 1254 |
} |
| 1255 |
if (m_heSupported) |
| 1256 |
{ |
| 1257 |
//check whether the HE STA supports all MCSs in Basic MCS Set |
| 1258 |
HeCapabilities hecapabilities = reassocReq.GetHeCapabilities (); |
| 1259 |
if (hecapabilities.GetSupportedMcsAndNss () != 0) |
| 1260 |
{ |
| 1261 |
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) |
| 1262 |
{ |
| 1263 |
WifiMode mcs = m_stationManager->GetBasicMcs (i); |
| 1264 |
if (!hecapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
| 1265 |
{ |
| 1266 |
problem = true; |
| 1267 |
break; |
| 1268 |
} |
| 1269 |
} |
| 1270 |
} |
| 1271 |
} |
| 1272 |
if (problem) |
| 1273 |
{ |
| 1274 |
NS_LOG_DEBUG ("One of the Basic Rate set mode is not supported by the station: send reassociation response with an error status"); |
| 1275 |
SendAssocResp (hdr->GetAddr2 (), false, true); |
| 1276 |
} |
| 1277 |
else |
| 1278 |
{ |
| 1279 |
NS_LOG_DEBUG ("The Basic Rate set modes are supported by the station"); |
| 1280 |
//update all its supported modes in its associated WifiRemoteStation |
| 1281 |
for (uint8_t j = 0; j < m_phy->GetNModes (); j++) |
| 1282 |
{ |
| 1283 |
WifiMode mode = m_phy->GetMode (j); |
| 1284 |
if (rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth ()))) |
| 1285 |
{ |
| 1286 |
m_stationManager->AddSupportedMode (from, mode); |
| 1287 |
} |
| 1288 |
} |
| 1289 |
if (m_htSupported) |
| 1290 |
{ |
| 1291 |
HtCapabilities htCapabilities = reassocReq.GetHtCapabilities (); |
| 1292 |
if (htCapabilities.IsSupportedMcs (0)) |
| 1293 |
{ |
| 1294 |
m_stationManager->AddStationHtCapabilities (from, htCapabilities); |
| 1295 |
} |
| 1296 |
} |
| 1297 |
if (m_vhtSupported) |
| 1298 |
{ |
| 1299 |
VhtCapabilities vhtCapabilities = reassocReq.GetVhtCapabilities (); |
| 1300 |
//we will always fill in RxHighestSupportedLgiDataRate field at TX, so this can be used to check whether it supports VHT |
| 1301 |
if (vhtCapabilities.GetRxHighestSupportedLgiDataRate () > 0) |
| 1302 |
{ |
| 1303 |
m_stationManager->AddStationVhtCapabilities (from, vhtCapabilities); |
| 1304 |
for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) |
| 1305 |
{ |
| 1306 |
WifiMode mcs = m_phy->GetMcs (i); |
| 1307 |
if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VHT && vhtCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
| 1308 |
{ |
| 1309 |
m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs); |
| 1310 |
//here should add a control to add basic MCS when it is implemented |
| 1311 |
} |
| 1312 |
} |
| 1313 |
} |
| 1314 |
} |
| 1315 |
if (m_heSupported) |
| 1316 |
{ |
| 1317 |
HeCapabilities heCapabilities = reassocReq.GetHeCapabilities (); |
| 1318 |
//todo: once we support non constant rate managers, we should add checks here whether HE is supported by the peer |
| 1319 |
m_stationManager->AddStationHeCapabilities (from, heCapabilities); |
| 1320 |
for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) |
| 1321 |
{ |
| 1322 |
WifiMode mcs = m_phy->GetMcs (i); |
| 1323 |
if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HE && heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
| 1324 |
{ |
| 1325 |
m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs); |
| 1326 |
//here should add a control to add basic MCS when it is implemented |
| 1327 |
} |
| 1328 |
} |
| 1329 |
} |
| 1330 |
m_stationManager->RecordWaitAssocTxOk (from); |
| 1331 |
if (!isHtStation) |
| 1332 |
{ |
| 1333 |
m_nonHtStations.push_back (hdr->GetAddr2 ()); |
| 1334 |
m_nonHtStations.unique (); |
| 1335 |
} |
| 1336 |
if (!isErpStation && isDsssStation) |
| 1337 |
{ |
| 1338 |
m_nonErpStations.push_back (hdr->GetAddr2 ()); |
| 1339 |
m_nonErpStations.unique (); |
| 1340 |
} |
| 1341 |
NS_LOG_DEBUG ("Send reassociation response with success status"); |
| 1342 |
SendAssocResp (hdr->GetAddr2 (), true, true); |
| 1146 |
} |
1343 |
} |
| 1147 |
return; |
1344 |
return; |
| 1148 |
} |
1345 |
} |
| 1149 |
else if (hdr->IsDisassociation ()) |
1346 |
else if (hdr->IsDisassociation ()) |
| 1150 |
{ |
1347 |
{ |
|
|
1348 |
NS_LOG_DEBUG ("Disassociation received from " << from); |
| 1151 |
m_stationManager->RecordDisassociated (from); |
1349 |
m_stationManager->RecordDisassociated (from); |
| 1152 |
for (std::map<uint16_t, Mac48Address>::const_iterator j = m_staList.begin (); j != m_staList.end (); j++) |
1350 |
for (std::map<uint16_t, Mac48Address>::const_iterator j = m_staList.begin (); j != m_staList.end (); j++) |
| 1153 |
{ |
1351 |
{ |