|
|
| 1055 |
return isLast; |
1055 |
return isLast; |
| 1056 |
} |
1056 |
} |
| 1057 |
|
1057 |
|
| 1058 |
WifiMode |
|
|
| 1059 |
WifiRemoteStationManager::GetControlAnswerMode (WifiMode reqMode) |
| 1060 |
{ |
| 1061 |
/** |
| 1062 |
* The standard has relatively unambiguous rules for selecting a |
| 1063 |
* control response rate (the below is quoted from IEEE 802.11-2012, |
| 1064 |
* Section 9.7): |
| 1065 |
* |
| 1066 |
* To allow the transmitting STA to calculate the contents of the |
| 1067 |
* Duration/ID field, a STA responding to a received frame shall |
| 1068 |
* transmit its Control Response frame (either CTS or ACK), other |
| 1069 |
* than the BlockAck control frame, at the highest rate in the |
| 1070 |
* BSSBasicRateSet parameter that is less than or equal to the |
| 1071 |
* rate of the immediately previous frame in the frame exchange |
| 1072 |
* sequence (as defined in Annex G) and that is of the same |
| 1073 |
* modulation class (see Section 9.7.8) as the received frame... |
| 1074 |
*/ |
| 1075 |
NS_LOG_FUNCTION (this << reqMode); |
| 1076 |
WifiMode mode = GetDefaultMode (); |
| 1077 |
bool found = false; |
| 1078 |
//First, search the BSS Basic Rate set |
| 1079 |
for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++) |
| 1080 |
{ |
| 1081 |
if ((!found || i->IsHigherDataRate (mode)) |
| 1082 |
&& (!i->IsHigherDataRate (reqMode)) |
| 1083 |
&& (IsAllowedControlAnswerModulationClass (reqMode.GetModulationClass (), i->GetModulationClass ()))) |
| 1084 |
{ |
| 1085 |
mode = *i; |
| 1086 |
//We've found a potentially-suitable transmit rate, but we |
| 1087 |
//need to continue and consider all the basic rates before |
| 1088 |
//we can be sure we've got the right one. |
| 1089 |
found = true; |
| 1090 |
} |
| 1091 |
} |
| 1092 |
if (GetHtSupported () || GetVhtSupported () || GetHeSupported ()) |
| 1093 |
{ |
| 1094 |
if (!found) |
| 1095 |
{ |
| 1096 |
mode = GetDefaultMcs (); |
| 1097 |
for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++) |
| 1098 |
{ |
| 1099 |
if ((!found || i->IsHigherDataRate (mode)) |
| 1100 |
&& (!i->IsHigherDataRate (reqMode)) |
| 1101 |
&& (i->GetModulationClass () == reqMode.GetModulationClass ())) |
| 1102 |
{ |
| 1103 |
mode = *i; |
| 1104 |
//We've found a potentially-suitable transmit rate, but we |
| 1105 |
//need to continue and consider all the basic rates before |
| 1106 |
//we can be sure we've got the right one. |
| 1107 |
found = true; |
| 1108 |
} |
| 1109 |
} |
| 1110 |
} |
| 1111 |
} |
| 1112 |
//If we found a suitable rate in the BSSBasicRateSet, then we are |
| 1113 |
//done and can return that mode. |
| 1114 |
if (found) |
| 1115 |
{ |
| 1116 |
NS_LOG_DEBUG ("WifiRemoteStationManager::GetControlAnswerMode returning " << mode); |
| 1117 |
return mode; |
| 1118 |
} |
| 1119 |
|
| 1120 |
/** |
| 1121 |
* If no suitable basic rate was found, we search the mandatory |
| 1122 |
* rates. The standard (IEEE 802.11-2007, Section 9.6) says: |
| 1123 |
* |
| 1124 |
* ...If no rate contained in the BSSBasicRateSet parameter meets |
| 1125 |
* these conditions, then the control frame sent in response to a |
| 1126 |
* received frame shall be transmitted at the highest mandatory |
| 1127 |
* rate of the PHY that is less than or equal to the rate of the |
| 1128 |
* received frame, and that is of the same modulation class as the |
| 1129 |
* received frame. In addition, the Control Response frame shall |
| 1130 |
* be sent using the same PHY options as the received frame, |
| 1131 |
* unless they conflict with the requirement to use the |
| 1132 |
* BSSBasicRateSet parameter. |
| 1133 |
* |
| 1134 |
* \todo Note that we're ignoring the last sentence for now, because |
| 1135 |
* there is not yet any manipulation here of PHY options. |
| 1136 |
*/ |
| 1137 |
for (uint8_t idx = 0; idx < m_wifiPhy->GetNModes (); idx++) |
| 1138 |
{ |
| 1139 |
WifiMode thismode = m_wifiPhy->GetMode (idx); |
| 1140 |
/* If the rate: |
| 1141 |
* |
| 1142 |
* - is a mandatory rate for the PHY, and |
| 1143 |
* - is equal to or faster than our current best choice, and |
| 1144 |
* - is less than or equal to the rate of the received frame, and |
| 1145 |
* - is of the same modulation class as the received frame |
| 1146 |
* |
| 1147 |
* ...then it's our best choice so far. |
| 1148 |
*/ |
| 1149 |
if (thismode.IsMandatory () |
| 1150 |
&& (!found || thismode.IsHigherDataRate (mode)) |
| 1151 |
&& (!thismode.IsHigherDataRate (reqMode)) |
| 1152 |
&& (IsAllowedControlAnswerModulationClass (reqMode.GetModulationClass (), thismode.GetModulationClass ()))) |
| 1153 |
{ |
| 1154 |
mode = thismode; |
| 1155 |
//As above; we've found a potentially-suitable transmit |
| 1156 |
//rate, but we need to continue and consider all the |
| 1157 |
//mandatory rates before we can be sure we've got the right one. |
| 1158 |
found = true; |
| 1159 |
} |
| 1160 |
} |
| 1161 |
if (GetHtSupported () || GetVhtSupported () || GetHeSupported ()) |
| 1162 |
{ |
| 1163 |
for (uint8_t idx = 0; idx < m_wifiPhy->GetNMcs (); idx++) |
| 1164 |
{ |
| 1165 |
WifiMode thismode = m_wifiPhy->GetMcs (idx); |
| 1166 |
if (thismode.IsMandatory () |
| 1167 |
&& (!found || thismode.IsHigherDataRate (mode)) |
| 1168 |
&& (!thismode.IsHigherCodeRate (reqMode)) |
| 1169 |
&& (thismode.GetModulationClass () == reqMode.GetModulationClass ())) |
| 1170 |
{ |
| 1171 |
mode = thismode; |
| 1172 |
//As above; we've found a potentially-suitable transmit |
| 1173 |
//rate, but we need to continue and consider all the |
| 1174 |
//mandatory rates before we can be sure we've got the right one. |
| 1175 |
found = true; |
| 1176 |
} |
| 1177 |
} |
| 1178 |
} |
| 1179 |
|
| 1180 |
/** |
| 1181 |
* If we still haven't found a suitable rate for the response then |
| 1182 |
* someone has messed up the simulation config. This probably means |
| 1183 |
* that the WifiPhyStandard is not set correctly, or that a rate that |
| 1184 |
* is not supported by the PHY has been explicitly requested in a |
| 1185 |
* WifiRemoteStationManager (or descendant) configuration. |
| 1186 |
* |
| 1187 |
* Either way, it is serious - we can either disobey the standard or |
| 1188 |
* fail, and I have chosen to do the latter... |
| 1189 |
*/ |
| 1190 |
if (!found) |
| 1191 |
{ |
| 1192 |
NS_FATAL_ERROR ("Can't find response rate for " << reqMode); |
| 1193 |
} |
| 1194 |
|
| 1195 |
NS_LOG_DEBUG ("WifiRemoteStationManager::GetControlAnswerMode returning " << mode); |
| 1196 |
return mode; |
| 1197 |
} |
| 1198 |
|
| 1199 |
WifiTxVector |
| 1200 |
WifiRemoteStationManager::GetCtsTxVector (Mac48Address address, WifiMode rtsMode) |
| 1201 |
{ |
| 1202 |
NS_ASSERT (!address.IsGroup ()); |
| 1203 |
WifiMode ctsMode = GetControlAnswerMode (rtsMode); |
| 1204 |
WifiTxVector v; |
| 1205 |
v.SetMode (ctsMode); |
| 1206 |
v.SetPreambleType (GetPreambleForTransmission (ctsMode.GetModulationClass (), GetShortPreambleEnabled (), UseGreenfieldForDestination (address))); |
| 1207 |
v.SetTxPowerLevel (DoGetCtsTxPowerLevel (address, ctsMode)); |
| 1208 |
v.SetChannelWidth (GetChannelWidthForTransmission (ctsMode, DoGetCtsTxChannelWidth (address, ctsMode))); |
| 1209 |
v.SetGuardInterval (DoGetCtsTxGuardInterval (address, ctsMode)); |
| 1210 |
v.SetNss (DoGetCtsTxNss (address, ctsMode)); |
| 1211 |
v.SetNess (DoGetCtsTxNess (address, ctsMode)); |
| 1212 |
v.SetStbc (0); |
| 1213 |
return v; |
| 1214 |
} |
| 1215 |
|
| 1216 |
WifiTxVector |
| 1217 |
WifiRemoteStationManager::GetAckTxVector (Mac48Address address, WifiMode dataMode) |
| 1218 |
{ |
| 1219 |
NS_ASSERT (!address.IsGroup ()); |
| 1220 |
WifiMode ackMode = GetControlAnswerMode (dataMode); |
| 1221 |
WifiTxVector v; |
| 1222 |
v.SetMode (ackMode); |
| 1223 |
v.SetPreambleType (GetPreambleForTransmission (ackMode.GetModulationClass (), GetShortPreambleEnabled (), UseGreenfieldForDestination (address))); |
| 1224 |
v.SetTxPowerLevel (DoGetAckTxPowerLevel (address, ackMode)); |
| 1225 |
v.SetChannelWidth (GetChannelWidthForTransmission (ackMode, DoGetAckTxChannelWidth (address, ackMode))); |
| 1226 |
v.SetGuardInterval (DoGetAckTxGuardInterval (address, ackMode)); |
| 1227 |
v.SetNss (DoGetAckTxNss (address, ackMode)); |
| 1228 |
v.SetNess (DoGetAckTxNess (address, ackMode)); |
| 1229 |
v.SetStbc (0); |
| 1230 |
return v; |
| 1231 |
} |
| 1232 |
|
| 1233 |
WifiTxVector |
| 1234 |
WifiRemoteStationManager::GetBlockAckTxVector (Mac48Address address, WifiMode blockAckReqMode) |
| 1235 |
{ |
| 1236 |
NS_ASSERT (!address.IsGroup ()); |
| 1237 |
WifiMode blockAckMode = GetControlAnswerMode (blockAckReqMode); |
| 1238 |
WifiTxVector v; |
| 1239 |
v.SetMode (blockAckMode); |
| 1240 |
v.SetPreambleType (GetPreambleForTransmission (blockAckMode.GetModulationClass (), GetShortPreambleEnabled (), UseGreenfieldForDestination (address))); |
| 1241 |
v.SetTxPowerLevel (DoGetBlockAckTxPowerLevel (address, blockAckMode)); |
| 1242 |
v.SetChannelWidth (GetChannelWidthForTransmission (blockAckMode, DoGetBlockAckTxChannelWidth (address, blockAckMode))); |
| 1243 |
v.SetGuardInterval (DoGetBlockAckTxGuardInterval (address, blockAckMode)); |
| 1244 |
v.SetNss (DoGetBlockAckTxNss (address, blockAckMode)); |
| 1245 |
v.SetNess (DoGetBlockAckTxNess (address, blockAckMode)); |
| 1246 |
v.SetStbc (0); |
| 1247 |
return v; |
| 1248 |
} |
| 1249 |
|
| 1250 |
uint8_t |
| 1251 |
WifiRemoteStationManager::DoGetCtsTxPowerLevel (Mac48Address address, WifiMode ctsMode) |
| 1252 |
{ |
| 1253 |
return m_defaultTxPowerLevel; |
| 1254 |
} |
| 1255 |
|
| 1256 |
uint16_t |
| 1257 |
WifiRemoteStationManager::DoGetCtsTxChannelWidth (Mac48Address address, WifiMode ctsMode) |
| 1258 |
{ |
| 1259 |
return m_wifiPhy->GetChannelWidth (); |
| 1260 |
} |
| 1261 |
|
| 1262 |
uint16_t |
| 1263 |
WifiRemoteStationManager::DoGetCtsTxGuardInterval (Mac48Address address, WifiMode ctsMode) |
| 1264 |
{ |
| 1265 |
return ConvertGuardIntervalToNanoSeconds (ctsMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())); |
| 1266 |
} |
| 1267 |
|
| 1268 |
uint8_t |
| 1269 |
WifiRemoteStationManager::DoGetCtsTxNss (Mac48Address address, WifiMode ctsMode) |
| 1270 |
{ |
| 1271 |
return 1; |
| 1272 |
} |
| 1273 |
|
| 1274 |
uint8_t |
| 1275 |
WifiRemoteStationManager::DoGetCtsTxNess (Mac48Address address, WifiMode ctsMode) |
| 1276 |
{ |
| 1277 |
return 0; |
| 1278 |
} |
| 1279 |
|
| 1280 |
uint8_t |
| 1281 |
WifiRemoteStationManager::DoGetAckTxPowerLevel (Mac48Address address, WifiMode ackMode) |
| 1282 |
{ |
| 1283 |
return m_defaultTxPowerLevel; |
| 1284 |
} |
| 1285 |
|
| 1286 |
uint16_t |
| 1287 |
WifiRemoteStationManager::DoGetAckTxChannelWidth (Mac48Address address, WifiMode ctsMode) |
| 1288 |
{ |
| 1289 |
return m_wifiPhy->GetChannelWidth (); |
| 1290 |
} |
| 1291 |
|
| 1292 |
uint16_t |
| 1293 |
WifiRemoteStationManager::DoGetAckTxGuardInterval (Mac48Address address, WifiMode ackMode) |
| 1294 |
{ |
| 1295 |
return ConvertGuardIntervalToNanoSeconds (ackMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())); |
| 1296 |
} |
| 1297 |
|
| 1298 |
uint8_t |
| 1299 |
WifiRemoteStationManager::DoGetAckTxNss (Mac48Address address, WifiMode ackMode) |
| 1300 |
{ |
| 1301 |
return 1; |
| 1302 |
} |
| 1303 |
|
| 1304 |
uint8_t |
| 1305 |
WifiRemoteStationManager::DoGetAckTxNess (Mac48Address address, WifiMode ackMode) |
| 1306 |
{ |
| 1307 |
return 0; |
| 1308 |
} |
| 1309 |
|
| 1310 |
uint8_t |
| 1311 |
WifiRemoteStationManager::DoGetBlockAckTxPowerLevel (Mac48Address address, WifiMode blockAckMode) |
| 1312 |
{ |
| 1313 |
return m_defaultTxPowerLevel; |
| 1314 |
} |
| 1315 |
|
| 1316 |
uint16_t |
| 1317 |
WifiRemoteStationManager::DoGetBlockAckTxChannelWidth (Mac48Address address, WifiMode ctsMode) |
| 1318 |
{ |
| 1319 |
return m_wifiPhy->GetChannelWidth (); |
| 1320 |
} |
| 1321 |
|
| 1322 |
uint16_t |
| 1323 |
WifiRemoteStationManager::DoGetBlockAckTxGuardInterval (Mac48Address address, WifiMode blockAckMode) |
| 1324 |
{ |
| 1325 |
return ConvertGuardIntervalToNanoSeconds (blockAckMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())); |
| 1326 |
} |
| 1327 |
|
| 1328 |
uint8_t |
| 1329 |
WifiRemoteStationManager::DoGetBlockAckTxNss (Mac48Address address, WifiMode blockAckMode) |
| 1330 |
{ |
| 1331 |
return 1; |
| 1332 |
} |
| 1333 |
|
| 1334 |
uint8_t |
| 1335 |
WifiRemoteStationManager::DoGetBlockAckTxNess (Mac48Address address, WifiMode blockAckMode) |
| 1336 |
{ |
| 1337 |
return 0; |
| 1338 |
} |
| 1339 |
|
| 1340 |
uint8_t |
1058 |
uint8_t |
| 1341 |
WifiRemoteStationManager::GetDefaultTxPowerLevel (void) const |
1059 |
WifiRemoteStationManager::GetDefaultTxPowerLevel (void) const |
| 1342 |
{ |
1060 |
{ |