Task 2 should be finished

This commit is contained in:
ti_mo
2026-05-22 19:16:08 +02:00
parent 2fa2bf7f9a
commit 0df0c5da43
4 changed files with 591 additions and 41 deletions
+219 -8
View File
@@ -1,18 +1,81 @@
channel_bandwidth = "CBW20"; % 20MHz
addpath("from_matlab_example");
rxFrame1 = trace1.iq(:);
rxFrame2 = trace2.iq(:);
rxFrame3 = trace3.iq(:);
rxFrame4 = trace4.iq(:);
function beaconFrames = extractBeaconFrames(rxFrame)
beaconFrames = [];
searchOffset = 0;
beaconFrames1 = extractBeaconFrames(rxFrame1);
beaconFrames2 = extractBeaconFrames(rxFrame2);
beaconFrames3 = extractBeaconFrames(rxFrame3);
beaconFrames4 = extractBeaconFrames(rxFrame4);
% 1.
disp("Beacon Frame 1")
printBeaconTable(beaconFrames1);
disp("Beacon Frame 2")
printBeaconTable(beaconFrames2);
disp("Beacon Frame 3")
printBeaconTable(beaconFrames3);
disp("Beacon Frame 4")
printBeaconTable(beaconFrames4);
% 2.
%{
Address 1: used to announce the destination station, in a beacon frame its
FF:FF:FF:FF:FF:FF (meaning broadcast to all stations)
Address 2: used to remark the source device address of the frame,
the ap mac who sent the beacon is inserted
Address 3: used for the bssid of the device sending the beacon, means
usually address 2 equals address 3, when no virtual ap is used
Address 4: this field does not exists, after the seq ctrl the frame body
follows containing beacon data instead of an address, like
timestamp, beacon interval, capability info, ssid, potentially
the channel number, see the extracts from 2.1
%}
% 3.
%{
Downlink:
Address 1: MAC of the destination station
Address 2: MAC of the AP which further routes the frame
Address 3: MAC of the initial sender which has started the process of
the frame to AP's
Address 4: not used
Uplink:
Address 1: MAC of the AP the WiFi frame should route through
(the connected AP)
Address 2: MAC of the sending station
Address 3: used to store the final destination MAC address
Address 4: not used
4 Address case:
Address 4: is only used in wireless bridge solutions, environments where
multiple AP's connect different LAN's to one big one
%}
function beaconFrames = extractBeaconFrames(rxFrame)
beaconFrames = struct( ...
"SSID", {}, ...
"BSSID", {}, ...
"Offset", {}, ...
"MAC_Config", {}, ...
"Bits", {}, ...
"SNR_dB", {} ...
);
searchOffset = 0;
index = 1;
while searchOffset < length(rxFrame)
oldOffset = searchOffset;
[bitsData, decParams, searchOffset, res] = recoverOFDMBits(rxFrame, searchOffset);
if searchOffset <= oldOffset
searchOffset = oldOffset + 1;
end
if isempty(bitsData)
continue;
end
@@ -20,10 +83,158 @@ function beaconFrames = extractBeaconFrames(rxFrame)
[cfgMAC, ~, decodeStatus] = wlanMPDUDecode(bitsData, SuppressWarnings=true);
if ~decodeStatus && matches(cfgMAC.FrameType, "Beacon")
disp("Beacon at " + searchOffset);
beaconFrames(end + 1) = cfgMAC;
if isempty(cfgMAC.ManagementConfig.SSID)
ssid = "Hidden";
else
ssid = string(cfgMAC.ManagementConfig.SSID);
end
if isfield(res, "PacketOffset")
beaconFrames(index).Offset = res.PacketOffset;
else
beaconFrames(index).Offset = oldOffset;
end
if isfield(res, "LLTFSNR")
beaconFrames(index).SNR_dB = res.LLTFSNR;
else
beaconFrames(index).SNR_dB = NaN;
end
beaconFrames(index).SSID = ssid;
beaconFrames(index).BSSID = string(cfgMAC.Address3);
beaconFrames(index).MAC_Config = cfgMAC;
beaconFrames(index).Bits = bitsData;
index = index + 1;
end
end
end
beaconFrames1 = extractBeaconFrames(rxFrame1);
function printBeaconTable(beaconFrames)
beaconCount = numel(beaconFrames);
tableFormat = "%-20s %-18s %-10s %-8s %-8s %-8s %-12s %-8s %-80s\n";
if(beaconCount < 1)
disp("No valid beacons could be extracted")
return;
end
fprintf("\n");
fprintf(tableFormat, ...
"SSID", "BSSID", "Interval", "B. ch.", "Op. ch.", "SNR", "Vendor", "Std.", "Rates");
for i = 1 : beaconCount
mgmt = beaconFrames(i).MAC_Config.ManagementConfig;
ssid = string(beaconFrames(i).SSID);
bssid = toMACAddress(beaconFrames(i).BSSID);
interval = string(mgmt.BeaconInterval);
snr = sprintf("%.1f", beaconFrames(i).SNR_dB);
[bch, opch] = extractChannels(mgmt);
vendor = lookupVendor(beaconFrames(i).BSSID);
rates = getRates(mgmt);
std = getWifiStandard(mgmt);
fprintf(tableFormat, ...
ssid, bssid, interval, bch, opch, snr, vendor, std, rates);
end
fprintf("\n");
end
function mac = toMACAddress(mac)
mac = upper(string(mac));
if strlength(mac) ~= 12
return;
end
macChars = char(mac);
mac = string(sprintf("%s:%s:%s:%s:%s:%s", ...
macChars(1:2), ...
macChars(3:4), ...
macChars(5:6), ...
macChars(7:8), ...
macChars(9:10), ...
macChars(11:12)));
end
function rates = getRates(mgmt)
basicRates = string(mgmt.BasicRates);
additionalRates = string(mgmt.AdditionalRates);
if isempty(basicRates) && isempty(additionalRates)
rates = "-";
return;
end
basicRates = "[" + strjoin(basicRates, ", ") + "]";
rates = strjoin([basicRates, additionalRates], ", ");
end
function vendor = lookupVendor(bssid)
bssid = upper(string(bssid));
if strlength(bssid) < 6
vendor = "-";
return;
end
oui = extractBefore(bssid, 7);
switch oui
case { "C884A1", "5CE176" }
vendor = "Cisco";
case { "6466B3", "647002" }
vendor = "TP-Link";
otherwise
vendor = "Unknown";
end
end
function std = getWifiStandard(mgmt)
rates = [string(mgmt.BasicRates), string(mgmt.AdditionalRates)];
if any(contains(rates, ["6 Mbps", "9 Mbps", "12 Mbps", "18 Mbps", "24 Mbps", "36 Mbps", "48 Mbps", "54 Mbps"]))
std = "802.11g";
elseif any(contains(rates, ["1 Mbps", "2 Mbps", "5.5 Mbps", "11 Mbps"]))
std = "802.11b";
else
std = "Unknown";
end
end
function [b_ch, op_ch] = extractChannels(mgmt)
b_ch = "-";
op_ch = "-";
ies = mgmt.InformationElements;
if(isempty(ies))
return;
end
for i = 1 : size(ies, 1)
id = ies{i, 1};
value = ies{i, 2};
if isempty(id) || isempty(value)
continue;
end
switch id(1)
case 3
b_ch = string(double(value(1)));
case 61
op_ch = string(double(value(1)));
end
if ~strcmp(b_ch, "-") && ~strcmp(op_ch, "-")
return;
end
end
end