|
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 |
{ |