<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Wellnitz::WLANTimes;

use strict;
use Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw(
);



# Calculate RTT times for 802.11
# Packet sizes are for IP packet data sizes (excl. header)
# Currently, RTC/CTS is not supported!


sub new {
   my ($class, $args) = @_;
   my $self = {};
   bless ($self, $class);
   $self-&gt;{NETNAME} = $args;
   return $self;
}


sub param80211bshort {
	my (%param, $rate);

	### PHY
	# Preamble is 72 bits @ 1Mbps DBPSK (72 microseconds)
	# PLCP Header is 48 bits @ 2Mbps DQPSK (24 microseconds)
	$param{phyhead} = 96;

	### MAC
	$param{machead}  = 8*(24 + 8); # 24 Bytes MAC Header + 8 Bytes LLC
	$param{mactail}  = 32; # 32 Bit FCS
	$param{slot}	 = 20;
	$param{sifs}     = 10;
	$param{difs}     = 2 * $param{slot} + $param{sifs};

	# Allowed rates
	foreach $rate (1, 2, 5.5, 11) {
		$param{rates}-&gt;{$rate} = 1;
	}

	return %param;
}


sub param80211blong {
	my (%param, $rate);

	### PHY
	# Preamble is 144 bits @ 1Mbps DBPSK (144 microseconds)
	# PLCP Header is 48 bits @ 1Mbps DBPSK (48 microseconds)
	$param{phyhead} = 192;
	$param{phytail} = 0;

	### MAC
	$param{machead}  = 8*(24 + 8); # 24 Bytes MAC Header + 8 Bytes LLC
	$param{mactail}  = 32; # 32 Bit FCS
	$param{slot}	 = 20;
	$param{sifs}     = 10;
	$param{difs}     = 2 * $param{slot} + $param{sifs};

	# Allowed rates
	foreach $rate (1, 2, 5.5, 11) {
		$param{rates}-&gt;{$rate} = 1;
	}

	return %param;
}

sub param80211g {
	my (%param, $rate);

	### PHY
	# HEAD: 
	#   * Preamble - 12 symbols @ 6MBps BPSK (16 microseconds)
	#   * Signal   -  1 symbol  @ 6MBps BPSK ( 4 microseconds)
	$param{phyhead} = 16+4;

	# TAIL:
	#   * Every packet is followed by 6 mircoseconds signal extension
	#   * Padding fills up every packet up to a full symbol (symbol size
	#     depend on actual data rate)
	$param{phytail} = 6;

	### MAC
	$param{machead}  = 8*(24 + 8); # 24 Bytes MAC Header + 8 Bytes LLC
	$param{mactail}  = 32; # 32 Bit FCS
	$param{sifs}     = 10;
	# 802.11g has two different slot times
	#   20 us - long slot time  - compatible with 802.11/802.11b
	#    9 us - short slot time - only to be used if only 802.11g stations are present
	# The 802.11only slot time is used in the function below
	$param{slot}	 = 20;
	$param{difs}     = 2 * $param{slot} + $param{sifs};


	# Allowed rates
	foreach $rate  (6, 9, 12, 18, 24, 36, 48, 54) {
		$param{rates}-&gt;{$rate} = 1;
	}

	# Bits per Symbol
	$param{bitspersymbol}-&gt;{6}  = 24;
	$param{bitspersymbol}-&gt;{9}  = 36;
	$param{bitspersymbol}-&gt;{12} = 48;
	$param{bitspersymbol}-&gt;{18} = 72;
	$param{bitspersymbol}-&gt;{24} = 96;
	$param{bitspersymbol}-&gt;{36} = 144;
	$param{bitspersymbol}-&gt;{48} = 192;
	$param{bitspersymbol}-&gt;{54} = 216;

	return %param;
}


sub param80211gonly {
	my (%param);

	%param = param80211g();

	# 802.11g has two different slot times
	#   20 us - long slot time  - compatible with 802.11/802.11b
	#    9 us - short slot time - only to be used if only 802.11g stations are present
	$param{slot}	 = 9;
	$param{difs}     = 2 * $param{slot} + $param{sifs};

	return %param;
}


sub getnetwork {
	my ($network, $rate) = @_;
	my %net;

	if ($network eq "80211b-short") {
		%net = param80211bshort();
	} elsif ($network eq "80211b-long") {
		%net = param80211blong();
	} elsif ($network eq "80211g") {
		%net = param80211g();
	} elsif ($network eq "80211g-only") {
		%net = param80211g();
	} elsif ($network eq "any") {
		%net = param80211g();
		return %net if (defined($net{rates}-&gt;{$rate}));
		%net = param80211bshort();
		return %net if (defined($net{rates}-&gt;{$rate}));
		%net = param80211blong();
		return %net if (defined($net{rates}-&gt;{$rate}));
	} else {
		die "Don't know how to handle network ".$network."\n";
	}

	return %net;
}


sub txtime {
	my ($self, $rate, $packetsize, $cwmin, $cwmax) = @_;
	my (%net, $time, $payload, $symbols);

	%net = getnetwork($self-&gt;{NETNAME}, $rate);
	# Check if rate is allowed with technology
	die "Rate ".$rate." not allowed with network ".$self-&gt;{NETNAME}."\n"
		if (!defined($net{rates}-&gt;{$rate}));

	# Add 20 bytes IP header to packet
	$packetsize += 20;

	### Calculate transmission time
	
	# Wait DIFS + avg. backoff time
	$time = $net{difs} + ($cwmax - $cwmin)*$net{slot};

	# Determine payload size
	$payload = $net{machead} + 8*$packetsize + $net{mactail};

	# Add padding - only necessary for 802.11g/OFDM
	if ($net{bitspersymbol}-&gt;{$rate}) {
		$symbols = sprintf "%u", $payload / $net{bitspersymbol}-&gt;{$rate};
		if ($payload &gt; $symbols*$net{bitspersymbol}-&gt;{$rate}) {
			$payload = ++$symbols * $net{bitspersymbol}-&gt;{$rate};
		}
	}
	
	# Add data packet
	$time += $net{phyhead} + $payload / $rate + $net{phytail};
	
	return $time;
}


sub acktime {
	my ($self, $rate) = @_;
	my (%net);

	%net = getnetwork($self-&gt;{NETNAME}, $rate);
	# Check if rate is allowed with technology
	die "Rate ".$rate." not allowed with network ".$self-&gt;{NETNAME}."\n"
		if (!defined($net{rates}-&gt;{$rate}));

	return $net{sifs} + $net{phyhead} + (14*8) / $rate + $net{phytail};
}


sub rtttimes {
	my ($self, $rate, $packetsize, $cwmin, $cwmax) = @_;
	my $time;

	# Calculate minimum rtt
	$time = 2 * txtime($self, $rate, $packetsize, $cwmin, $cwmax);
	$time += acktime($self, $rate);
	
	return $time;
}

1;
</pre></body></html>