WiFi QoS Configuration Guide for NS-3

A complete guide to implementing all WiFi Access Classes (AC_VO, AC_VI, AC_BE, AC_BK) in your NS-3 WiFi simulations

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 Range0xC0 - 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 Range0x80 - 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 Range0x00 - 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 Range0x40 - 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

Updated on