Introduction
Quality of Service (QoS) in WiFi networks is essential for managing different types of traffic with varying priority requirements. The IEEE 802.11e standard defines four Access Classes (ACs) to prioritize different types of traffic:
Voice Traffic (AC_VO)
-
Ultra-low latency: < 150ms end-to-end delay
-
Minimal jitter: Consistent packet delivery timing
-
High priority: Must preempt other traffic types
Video Traffic (AC_VI)
-
Low latency: < 400ms for interactive video
-
Moderate jitter tolerance: Some buffering acceptable
-
High bandwidth: Large packet sizes and high data rates
Best Effort Traffic (AC_BE)
-
Standard priority: Fair sharing with other data traffic
-
Variable performance: Adapts to network conditions
-
Most common: Default for general internet traffic
Background Traffic (AC_BK)
-
Lowest priority: Should not interfere with other traffic
-
Delay tolerant: Can wait for available bandwidth
-
Bulk transfers: Large file transfers, system updates
Implementation Guide
Step 1: Enable QoS Support in WiFi MAC
Enable QoS support on both the Access Point (AP) and Station (STA):
// Enable QoS on Station
mac.SetType("ns3::StaWifiMac",
"Ssid", SsidValue(ssid),
"QosSupported", BooleanValue(true));
// Enable QoS on Access Point
mac.SetType("ns3::ApWifiMac",
"EnableBeaconJitter", BooleanValue(false),
"Ssid", SsidValue(ssid),
"QosSupported", BooleanValue(true));
Critical: Without QoS support enabled, all traffic will be treated as legacy 802.11 traffic, ignoring any priority settings.
Step 2: Configure Applications for Different Access Classes
The key to traffic classification is setting the Type of Service (TOS) field in the IP header. Different TOS values map to different access classes.
For UDP Traffic:
UdpClientHelper client(serverAddress, port);
client.SetAttribute("MaxPackets", UintegerValue(4294967295U));
client.SetAttribute("Interval", TimeValue(Seconds(packetInterval)));
client.SetAttribute("PacketSize", UintegerValue(payloadSize));
// Set TOS field - choose appropriate value for desired access class
client.SetAttribute("Tos", UintegerValue(tosValue)); // See mapping table below
For TCP Traffic:
OnOffHelper onoff("ns3::TcpSocketFactory", Ipv4Address::GetAny());
onoff.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
onoff.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]"));
onoff.SetAttribute("PacketSize", UintegerValue(payloadSize));
onoff.SetAttribute("DataRate", DataRateValue(dataRate));
// Set TOS field - choose appropriate value for desired access class
onoff.SetAttribute("Tos", UintegerValue(tosValue)); // See mapping table below
Step 3: Complete TOS to Access Class Mapping
NS-3 automatically maps TOS values to WiFi Access Classes according to the 802.11e standard:
AC_VO (Voice) - Highest Priority
TOS Range: 0xC0 - 0xFF (192-255 decimal)
// Common AC_VO TOS values:
client.SetAttribute("Tos", UintegerValue(0xE0)); // 224 - Standard voice (recommended)
client.SetAttribute("Tos", UintegerValue(0xF0)); // 240 - High priority voice
client.SetAttribute("Tos", UintegerValue(0xFF)); // 255 - Maximum priority voice (emergency)
client.SetAttribute("Tos", UintegerValue(0xC0)); // 192 - Minimum AC_VO priority
AC_VI (Video) - High Priority
TOS Range: 0x80 - 0xBF (128-191 decimal)
// Common AC_VI TOS values:
client.SetAttribute("Tos", UintegerValue(0xA0)); // 160 - Standard video (recommended)
client.SetAttribute("Tos", UintegerValue(0xB0)); // 176 - High priority video (4K/8K)
client.SetAttribute("Tos", UintegerValue(0x90)); // 144 - Lower priority video (thumbnails)
client.SetAttribute("Tos", UintegerValue(0x80)); // 128 - Minimum AC_VI priority
AC_BE (Best Effort) - Normal Priority
TOS Range: 0x00 - 0x3F (0-63 decimal)
// Common AC_BE TOS values:
client.SetAttribute("Tos", UintegerValue(0x00)); // 0 - Default best effort (most common)
client.SetAttribute("Tos", UintegerValue(0x20)); // 32 - Interactive web browsing
client.SetAttribute("Tos", UintegerValue(0x10)); // 16 - Standard data transfer
client.SetAttribute("Tos", UintegerValue(0x3F)); // 63 - Maximum AC_BE priority
AC_BK (Background) - Lowest Priority
TOS Range: 0x40 - 0x7F (64-127 decimal)
// Common AC_BK TOS values:
client.SetAttribute("Tos", UintegerValue(0x60)); // 96 - Standard background (recommended)
client.SetAttribute("Tos", UintegerValue(0x40)); // 64 - Minimum background priority
client.SetAttribute("Tos", UintegerValue(0x70)); // 112 - Higher background priority
client.SetAttribute("Tos", UintegerValue(0x7F)); // 127 - Maximum AC_BK priority
Complete Reference Table
Access Class | TOS Range (Hex) | TOS Range (Decimal) | Recommended Value | Typical Applications |
|---|---|---|---|---|
AC_VO | 0xC0 - 0xFF | 192 - 255 | 0xE0 (224) | VoIP, voice calls, emergency services |
AC_VI | 0x80 - 0xBF | 128 - 191 | 0xA0 (160) | Video streaming, video calls, gaming |
AC_BE | 0x00 - 0x3F | 0 - 63 | 0x00 (0) | Web browsing, email, FTP, HTTP |
AC_BK | 0x40 - 0x7F | 64 - 127 | 0x60 (96) | File downloads, backups, system updates |
Complete Multi-Class Example
Here's a comprehensive example showing how to configure all four access classes in a single simulation:
// ... WiFi and network setup code ...
// Enable QoS on all devices
mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "QosSupported", BooleanValue(true));
mac.SetType("ns3::ApWifiMac", "QosSupported", BooleanValue(true), "Ssid", SsidValue(ssid));
// ... IP addressing and routing setup ...
// Voice Application (AC_VO) - Highest Priority
UdpClientHelper voiceClient(serverAddress, 9001);
voiceClient.SetAttribute("Tos", UintegerValue(0xE0)); // AC_VO
voiceClient.SetAttribute("PacketSize", UintegerValue(160)); // Small voice packets
voiceClient.SetAttribute("Interval", TimeValue(MilliSeconds(20))); // 20ms intervals
ApplicationContainer voiceApps = voiceClient.Install(clientNodes);
// Video Application (AC_VI) - High Priority
UdpClientHelper videoClient(serverAddress, 9002);
videoClient.SetAttribute("Tos", UintegerValue(0xA0)); // AC_VI
videoClient.SetAttribute("PacketSize", UintegerValue(1200)); // Video packets
videoClient.SetAttribute("Interval", TimeValue(MilliSeconds(33))); // ~30fps
ApplicationContainer videoApps = videoClient.Install(clientNodes);
// Data Application (AC_BE) - Normal Priority
UdpClientHelper dataClient(serverAddress, 9003);
dataClient.SetAttribute("Tos", UintegerValue(0x00)); // AC_BE (default)
dataClient.SetAttribute("PacketSize", UintegerValue(1500)); // Full MTU
dataClient.SetAttribute("Interval", TimeValue(MilliSeconds(10))); // High rate data
ApplicationContainer dataApps = dataClient.Install(clientNodes);
// Background Application (AC_BK) - Lowest Priority
UdpClientHelper backgroundClient(serverAddress, 9004);
backgroundClient.SetAttribute("Tos", UintegerValue(0x60)); // AC_BK
backgroundClient.SetAttribute("PacketSize", UintegerValue(1500)); // Large packets
backgroundClient.SetAttribute("Interval", TimeValue(MilliSeconds(5))); // Bulk transfer
ApplicationContainer backgroundApps = backgroundClient.Install(clientNodes);
// Start all applications simultaneously to test prioritization
Time startTime = Seconds(1.0);
voiceApps.Start(startTime);
videoApps.Start(startTime);
dataApps.Start(startTime);
backgroundApps.Start(startTime);
Application-Specific Configuration Examples
Voice Applications (AC_VO)
// VoIP Call
UdpClientHelper voip(serverAddr, 5060);
voip.SetAttribute("Tos", UintegerValue(0xE0)); // Standard voice
voip.SetAttribute("PacketSize", UintegerValue(160)); // G.711 codec
voip.SetAttribute("Interval", TimeValue(MilliSeconds(20))); // 50 pps
// Emergency Services
UdpClientHelper emergency(serverAddr, 911);
emergency.SetAttribute("Tos", UintegerValue(0xFF)); // Maximum priority
emergency.SetAttribute("PacketSize", UintegerValue(160));
emergency.SetAttribute("Interval", TimeValue(MilliSeconds(20)));
// Voice Signaling (SIP)
UdpClientHelper signaling(serverAddr, 5060);
signaling.SetAttribute("Tos", UintegerValue(0xC0)); // Lower voice priority
signaling.SetAttribute("PacketSize", UintegerValue(200));
signaling.SetAttribute("Interval", TimeValue(Seconds(1))); // Infrequent
Video Applications (AC_VI)
// 4K Video Streaming
UdpClientHelper video4k(serverAddr, 8080);
video4k.SetAttribute("Tos", UintegerValue(0xB0)); // High video priority
video4k.SetAttribute("PacketSize", UintegerValue(1400));
video4k.SetAttribute("Interval", TimeValue(MilliSeconds(16))); // 60fps
// Video Conferencing
UdpClientHelper videoConf(serverAddr, 8080);
videoConf.SetAttribute("Tos", UintegerValue(0xA0)); // Standard video
videoConf.SetAttribute("PacketSize", UintegerValue(1200));
videoConf.SetAttribute("Interval", TimeValue(MilliSeconds(33))); // 30fps
// Video Thumbnails
UdpClientHelper thumbnails(serverAddr, 8080);
thumbnails.SetAttribute("Tos", UintegerValue(0x80)); // Lower video priority
thumbnails.SetAttribute("PacketSize", UintegerValue(800));
thumbnails.SetAttribute("Interval", TimeValue(MilliSeconds(100))); // 10fps
Data Applications (AC_BE)
// Interactive Web Browsing
UdpClientHelper webBrowsing(serverAddr, 80);
webBrowsing.SetAttribute("Tos", UintegerValue(0x20)); // Higher BE priority
webBrowsing.SetAttribute("PacketSize", UintegerValue(1500));
webBrowsing.SetAttribute("Interval", TimeValue(MilliSeconds(50)));
// Email/Standard Data
UdpClientHelper email(serverAddr, 25);
email.SetAttribute("Tos", UintegerValue(0x00)); // Default BE
email.SetAttribute("PacketSize", UintegerValue(1000));
email.SetAttribute("Interval", TimeValue(MilliSeconds(100)));
Background Applications (AC_BK)
// File Downloads
UdpClientHelper fileDownload(serverAddr, 21);
fileDownload.SetAttribute("Tos", UintegerValue(0x60)); // Standard background
fileDownload.SetAttribute("PacketSize", UintegerValue(1500));
fileDownload.SetAttribute("Interval", TimeValue(MilliSeconds(10))); // Bulk transfer
// System Backup
UdpClientHelper backup(serverAddr, 22);
backup.SetAttribute("Tos", UintegerValue(0x40)); // Lowest priority
backup.SetAttribute("PacketSize", UintegerValue(1500));
backup.SetAttribute("Interval", TimeValue(MilliSeconds(5))); // High volume
Performance Validation
Measuring QoS Effectiveness
Use NS-3's flow monitor to measure per-access-class performance:
// Install FlowMonitor
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor = flowmon.InstallAll();
// After simulation
monitor->CheckForLostPackets();
Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier>(flowmon.GetClassifier());
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats();
// Analyze per-flow (per-access-class) statistics
for (auto& flow : stats) {
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(flow.first);
// Calculate metrics
double throughput = flow.second.rxBytes * 8.0 / simulationTime.GetSeconds() / 1000000.0; // Mbps
double avgDelay = flow.second.delaySum.GetSeconds() / flow.second.rxPackets; // seconds
double packetLoss = (double)(flow.second.txPackets - flow.second.rxPackets) / flow.second.txPackets * 100;
std::cout << "Flow " << flow.first << " (Port " << t.destinationPort << ")"
<< " Throughput: " << throughput << " Mbps"
<< " Avg Delay: " << avgDelay * 1000 << " ms"
<< " Packet Loss: " << packetLoss << " %"
<< std::endl;
}
Performance Characteristics and Expected Behavior
When QoS is properly configured, you should observe the following prioritization:
Access Class | Channel Access Priority | Expected Latency | Throughput Under Congestion | Jitter |
|---|---|---|---|---|
AC_VO | Highest (shortest wait) | Lowest (< 10ms) | Maintained/prioritized | Minimal |
AC_VI | High | Low (< 50ms) | Good performance | Low |
AC_BE | Normal | Moderate (< 200ms) | Fair sharing | Moderate |
AC_BK | Lowest (longest wait) | Highest (> 500ms) | Reduced under load | High |