|
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); |
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 |
|
858 |
NS_LOG_FUNCTION (this); |
875 |
NS_LOG_FUNCTION (this); |
859 |
RegularWifiMac::TxOk (hdr); |
876 |
RegularWifiMac::TxOk (hdr); |
860 |
|
877 |
|
861 |
if (hdr.IsAssocResp () |
878 |
if ((hdr.IsAssocResp () || hdr.IsReassocResp ()) |
862 |
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
879 |
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
863 |
{ |
880 |
{ |
864 |
NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ()); |
881 |
NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ()); |
|
872 |
NS_LOG_FUNCTION (this); |
889 |
NS_LOG_FUNCTION (this); |
873 |
RegularWifiMac::TxFailed (hdr); |
890 |
RegularWifiMac::TxFailed (hdr); |
874 |
|
891 |
|
875 |
if (hdr.IsAssocResp () |
892 |
if ((hdr.IsAssocResp () || hdr.IsReassocResp ()) |
876 |
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
893 |
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
877 |
{ |
894 |
{ |
878 |
NS_LOG_DEBUG ("assoc failed with sta=" << hdr.GetAddr1 ()); |
895 |
NS_LOG_DEBUG ("assoc failed with sta=" << hdr.GetAddr1 ()); |
|
1077 |
//One of the Basic Rate set mode is not |
1094 |
//One of the Basic Rate set mode is not |
1078 |
//supported by the station. So, we return an assoc |
1095 |
//supported by the station. So, we return an assoc |
1079 |
//response with an error status. |
1096 |
//response with an error status. |
1080 |
SendAssocResp (hdr->GetAddr2 (), false); |
1097 |
SendAssocResp (hdr->GetAddr2 (), false, false); |
1081 |
} |
1098 |
} |
1082 |
else |
1099 |
else |
1083 |
{ |
1100 |
{ |
|
1136 |
if (!isHtStation) |
1153 |
if (!isHtStation) |
1137 |
{ |
1154 |
{ |
1138 |
m_nonHtStations.push_back (hdr->GetAddr2 ()); |
1155 |
m_nonHtStations.push_back (hdr->GetAddr2 ()); |
|
|
1156 |
m_nonHtStations.unique (); |
1139 |
} |
1157 |
} |
1140 |
if (!isErpStation && isDsssStation) |
1158 |
if (!isErpStation && isDsssStation) |
1141 |
{ |
1159 |
{ |
1142 |
m_nonErpStations.push_back (hdr->GetAddr2 ()); |
1160 |
m_nonErpStations.push_back (hdr->GetAddr2 ()); |
|
|
1161 |
m_nonErpStations.unique (); |
1143 |
} |
1162 |
} |
1144 |
// send assoc response with success status. |
1163 |
// send assoc response with success status. |
1145 |
SendAssocResp (hdr->GetAddr2 (), true); |
1164 |
SendAssocResp (hdr->GetAddr2 (), true, false); |
|
|
1165 |
} |
1166 |
return; |
1167 |
} |
1168 |
else if (hdr->IsReassocReq ()) |
1169 |
{ |
1170 |
//first, verify that the the station's supported |
1171 |
//rate set is compatible with our Basic Rate set |
1172 |
MgtReassocRequestHeader reassocReq; |
1173 |
packet->RemoveHeader (reassocReq); |
1174 |
CapabilityInformation capabilities = reassocReq.GetCapabilities (); |
1175 |
m_stationManager->AddSupportedPlcpPreamble (from, capabilities.IsShortPreamble ()); |
1176 |
SupportedRates rates = reassocReq.GetSupportedRates (); |
1177 |
bool problem = false; |
1178 |
bool isHtStation = false; |
1179 |
bool isOfdmStation = false; |
1180 |
bool isErpStation = false; |
1181 |
bool isDsssStation = false; |
1182 |
for (uint8_t i = 0; i < m_stationManager->GetNBasicModes (); i++) |
1183 |
{ |
1184 |
WifiMode mode = m_stationManager->GetBasicMode (i); |
1185 |
if (!rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth ()))) |
1186 |
{ |
1187 |
if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)) |
1188 |
{ |
1189 |
isDsssStation = false; |
1190 |
} |
1191 |
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM) |
1192 |
{ |
1193 |
isErpStation = false; |
1194 |
} |
1195 |
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM) |
1196 |
{ |
1197 |
isOfdmStation = false; |
1198 |
} |
1199 |
if (isDsssStation == false && isErpStation == false && isOfdmStation == false) |
1200 |
{ |
1201 |
problem = true; |
1202 |
break; |
1203 |
} |
1204 |
} |
1205 |
else |
1206 |
{ |
1207 |
if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)) |
1208 |
{ |
1209 |
isDsssStation = true; |
1210 |
} |
1211 |
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM) |
1212 |
{ |
1213 |
isErpStation = true; |
1214 |
} |
1215 |
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM) |
1216 |
{ |
1217 |
isOfdmStation = true; |
1218 |
} |
1219 |
} |
1220 |
} |
1221 |
m_stationManager->AddSupportedErpSlotTime (from, capabilities.IsShortSlotTime () && isErpStation); |
1222 |
if (m_htSupported) |
1223 |
{ |
1224 |
//check whether the HT STA supports all MCSs in Basic MCS Set |
1225 |
HtCapabilities htcapabilities = reassocReq.GetHtCapabilities (); |
1226 |
if (htcapabilities.IsSupportedMcs (0)) |
1227 |
{ |
1228 |
isHtStation = true; |
1229 |
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) |
1230 |
{ |
1231 |
WifiMode mcs = m_stationManager->GetBasicMcs (i); |
1232 |
if (!htcapabilities.IsSupportedMcs (mcs.GetMcsValue ())) |
1233 |
{ |
1234 |
problem = true; |
1235 |
break; |
1236 |
} |
1237 |
} |
1238 |
} |
1239 |
} |
1240 |
if (m_vhtSupported) |
1241 |
{ |
1242 |
//check whether the VHT STA supports all MCSs in Basic MCS Set |
1243 |
VhtCapabilities vhtcapabilities = reassocReq.GetVhtCapabilities (); |
1244 |
if (vhtcapabilities.GetVhtCapabilitiesInfo () != 0) |
1245 |
{ |
1246 |
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) |
1247 |
{ |
1248 |
WifiMode mcs = m_stationManager->GetBasicMcs (i); |
1249 |
if (!vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
1250 |
{ |
1251 |
problem = true; |
1252 |
break; |
1253 |
} |
1254 |
} |
1255 |
} |
1256 |
} |
1257 |
if (m_heSupported) |
1258 |
{ |
1259 |
//check whether the HE STA supports all MCSs in Basic MCS Set |
1260 |
HeCapabilities hecapabilities = reassocReq.GetHeCapabilities (); |
1261 |
if (hecapabilities.GetSupportedMcsAndNss () != 0) |
1262 |
{ |
1263 |
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) |
1264 |
{ |
1265 |
WifiMode mcs = m_stationManager->GetBasicMcs (i); |
1266 |
if (!hecapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
1267 |
{ |
1268 |
problem = true; |
1269 |
break; |
1270 |
} |
1271 |
} |
1272 |
} |
1273 |
} |
1274 |
if (problem) |
1275 |
{ |
1276 |
//One of the Basic Rate set mode is not |
1277 |
//supported by the station. So, we return an reassoc |
1278 |
//response with an error status. |
1279 |
SendAssocResp (hdr->GetAddr2 (), false, true); |
1280 |
} |
1281 |
else |
1282 |
{ |
1283 |
//station supports all rates in Basic Rate Set. |
1284 |
//record all its supported modes in its associated WifiRemoteStation |
1285 |
for (uint8_t j = 0; j < m_phy->GetNModes (); j++) |
1286 |
{ |
1287 |
WifiMode mode = m_phy->GetMode (j); |
1288 |
if (rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth ()))) |
1289 |
{ |
1290 |
m_stationManager->AddSupportedMode (from, mode); |
1291 |
} |
1292 |
} |
1293 |
if (m_htSupported) |
1294 |
{ |
1295 |
HtCapabilities htCapabilities = reassocReq.GetHtCapabilities (); |
1296 |
if (htCapabilities.IsSupportedMcs (0)) |
1297 |
{ |
1298 |
m_stationManager->AddStationHtCapabilities (from, htCapabilities); |
1299 |
} |
1300 |
} |
1301 |
if (m_vhtSupported) |
1302 |
{ |
1303 |
VhtCapabilities vhtCapabilities = reassocReq.GetVhtCapabilities (); |
1304 |
//we will always fill in RxHighestSupportedLgiDataRate field at TX, so this can be used to check whether it supports VHT |
1305 |
if (vhtCapabilities.GetRxHighestSupportedLgiDataRate () > 0) |
1306 |
{ |
1307 |
m_stationManager->AddStationVhtCapabilities (from, vhtCapabilities); |
1308 |
for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) |
1309 |
{ |
1310 |
WifiMode mcs = m_phy->GetMcs (i); |
1311 |
if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VHT && vhtCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
1312 |
{ |
1313 |
m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs); |
1314 |
//here should add a control to add basic MCS when it is implemented |
1315 |
} |
1316 |
} |
1317 |
} |
1318 |
} |
1319 |
if (m_heSupported) |
1320 |
{ |
1321 |
HeCapabilities heCapabilities = reassocReq.GetHeCapabilities (); |
1322 |
//todo: once we support non constant rate managers, we should add checks here whether HE is supported by the peer |
1323 |
m_stationManager->AddStationHeCapabilities (from, heCapabilities); |
1324 |
for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) |
1325 |
{ |
1326 |
WifiMode mcs = m_phy->GetMcs (i); |
1327 |
if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HE && heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
1328 |
{ |
1329 |
m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs); |
1330 |
//here should add a control to add basic MCS when it is implemented |
1331 |
} |
1332 |
} |
1333 |
} |
1334 |
m_stationManager->RecordWaitAssocTxOk (from); |
1335 |
if (!isHtStation) |
1336 |
{ |
1337 |
m_nonHtStations.push_back (hdr->GetAddr2 ()); |
1338 |
m_nonHtStations.unique (); |
1339 |
} |
1340 |
if (!isErpStation && isDsssStation) |
1341 |
{ |
1342 |
m_nonErpStations.push_back (hdr->GetAddr2 ()); |
1343 |
m_nonErpStations.unique (); |
1344 |
} |
1345 |
// send reassoc response with success status. |
1346 |
SendAssocResp (hdr->GetAddr2 (), true, true); |
1146 |
} |
1347 |
} |
1147 |
return; |
1348 |
return; |
1148 |
} |
1349 |
} |