PSI Report
2024-07-03
Background of this project
Working at a university means a lot of things, but also a lot of external dependencies and factors that can support the work. But those same things can also make it more difficult. One of them is Wifi. However, if we focus on the wifi at our university, we can assume that hardly anyone will claim that it works perfectly. To be more precise, many students and others who depend on it will confirm the existing lack of proper wifi connection. As a result, students (myself included) are unable to work for several hours. Therefore, the goal of this project is to understand if this is a subjective perception or if the wifi is really as bad as described.
Under these circumstances, an extensive measurement would be quite interesting, but since the effort (both financial and time) had to be limited, the following limitations were set:
- we only measure our location (ERBA), which is only one of about 50 locations of the University of Bamberg
- we measure the wifi connection with devices that are connected to the wifi 24/7 (in the optimal case)
- We define the usability of the WLAN network later.
- We measure in about 10 locations of the ERBA (mainly locations where there are a lot of students). Since the university has many locations, we can’t assume that the values we experience here are about the same in other locations, for this I want to countercheck my results with the official eduroam statistics, which we’ll take a look at in the next section.
Structure of the eduroam network
Before we start measuring data, let us have a quick look at the structure of Eduroam, because it is not as simple as a normal home network. Eduroam (short for education roaming) is a global network that provides WLAN access for researchers and educators in more than a hundred countries. In Germany alone, there are 2925 service locations with 2925 independent Identity Providers (1 location = 1 IdP, because each university has its own IdP). Compared to other countries, Germany has the most IdPs and ranks third in terms of service locations (behind Brazil and the USA). In Germany alone, there are over 700,000 requests per 2 hours at peak times. (over the last week of 10.06.2024 - 16.06.2024 [1]):
To get an idea of how active the German eduroam usage is, we compare the events reported to the central eduroam monitor (known as F-ticks). F-Ticks is a modular solution which provides a standardised message syntax for event reporting [3]. Looking at the event count table for the same period [2] , we see that Germany is in first place with over 27,000,000 requests.
Overall, we can see that Germany is an active user of eduroam, but we can also confirm our suspicion that the eduroam network does not work all the time (27M okay ticks and 5M fail ticks, resulting in ~16.88% failure).
Data mining - How and what we collected
What was the plan?
For a long time measurement (about 6 months) I wanted to reduce the effort of maintainability, which means that the software should be as simple as possible and store all the raw data so that the data analysis part can be done at the end, external dependencies on packages etc. should be kept as low as possible and the hardware should be placed in places where the risk of being stolen or manipulated is low. Since I did not need any specific hardware or high computing power, I decided to use Raspberry Pi 3 Model B, since it is based on a Linux operating system and has embedded wifi chips (which was the only requirement we had). In addition, each Pi came with a SanDisk SD card, a case, and an external power supply.
For the script on the pis, I wanted to reduce the amount of dependencies and possible integration problems, so I used bash with mostly basic linux tools. All logs were parsed into a single log file named {timestamp}-{hostname}.txt and uploaded at the end of the script to a simple php script on a central server which would then send a confirmation code, if this confirmation code was received the pi would delete the local log file, otherwise the log file would be saved for the next iteration and then the upload would be retried.
For the first version of the script, I measured the following parameters:
- internal ping (server @ erba)
- external ping (server @ cloudflare)
- traceroute to external server
- DNS check
- Download file test (external server)
#!/bin/bash
host=pi01
externalFileDownloadUrl=https://psi-project.jochenmehlich.de/10MB.zip
testFileHash=f1c9645dbc14efddc7d8a322685f26eb
internalPingHost=141.13.129.225
logName=$(date +%s)"-"$host.txt
currentDay=$(date)
currentTime=$(uptime | head -n1 | cut -d " " -f2)
currentMinute=$(uptime | head -n1 | cut -d " " -f2 | cut -d ":" -f2)
echo "#*#NEWTEST " $currentDay >> $logName
# External Ping test
echo "#*#E-PingStart " $currentTime >> $logName
ping -c 20 1.1.1.1 >> $logName
echo "#*#E-PingEND" >> $logName
# External Ping Test End
# Internal Ping Test
echo "#*#IPingStart" >> $logName
ping -c 20 $internalPingHost >> $logName
echo "#*#IPingEnd" >> $logName
# TraceRoute
echo "#*#TraceRouteStart" >> $logName
traceroute 1.1.1.1 >> $logName
echo "#*#TraceRouteEnd" >> $logName
# DNS Check
echo "#*#DNSCheckStart" >> $logName
dig jochenmehlich.de >> $logName
echo "#*#DNSCheckFinished" >> $logName
# 5-Minute Testing
if ! (($currentMinute % 5)); then
# External Download Test (5 Min)
SECONDS=0
echo "#*#EDOWNSTART Starting external Download test" >> $logName
wget $externalFileDownloadUrl --content-disposition -a $logName
echo "#*#EDOWNLOAD took: " $SECONDS >> $logName
fileHash=$(md5sum 10MB.zip | head -n1 | cut -d " " -f1)
rm 10MB.zip
[[ $testFileHash == $fileHash ]] && downloadValid=true || downloadValid=false
echo "#*#EDOWNLOADValid: " $downloadValid >> $logName
fi
echo "#*#TESTEND" >> $logName
# Try uploading logfile to main server
for filename in $(find . -maxdepth 1 -name \*.txt)
do
if curl -F "uploadedfile=@./$filename" https://psi-project.jochenmehlich.de/upload.php | grep "uploadDone";
then
echo $filename "uploaded, deleting now"
rm $filename
else
echo $filename "failed"
fi
done
With a new version of the script, I added a full wifi range scan so that any wifi network within range of the raspi is logged, and also changed the download file from a 10MB file to a 1MB file to reduce bandwidth usage (10 measurements per minute x 10MB x 24h x 60 = 144GB). The reduction in bandwidth usage was implemented to be both responsible and less noticeable, as has often been preached at various Chaos Computer Club talks.
New version of the script:
#!/bin/bash
host=pi012_dekanat
externalFileDownloadUrl=https://psi-project.jochenmehlich.de/1MB.zip
testFileHash=63c75b582ff65e5d913bb495baff44f6
internalPingHost=141.13.129.225
logName=$(date +%s)"-"$host.txt
currentDay=$(date)
currentTime=$(uptime | head -n1 | cut -d " " -f2)
currentMinute=$(uptime | head -n1 | cut -d " " -f2 | cut -d ":" -f2)
echo "#*#NEWTEST " $currentDay >> $logName
echo "#*#WIFIScanStart" >> $logName
sudo iwlist wlan0 scan >> $logName
echo "#*#WIFIScanEnd" >> $logName
# External Ping test
echo "#*#E-PingStart " $currentTime >> $logName
ping -c 20 1.1.1.1 >> $logName
echo "#*#E-PingEND" >> $logName
# External Ping Test End
# Internal Ping Test
echo "#*#IPingStart" >> $logName
ping -c 20 $internalPingHost >> $logName
echo "#*#IPingEnd" >> $logName
# TraceRoute
echo "#*#TraceRouteStart" >> $logName
traceroute 1.1.1.1 >> $logName
echo "#*#TraceRouteEnd" >> $logName
# DNS Check
echo "#*#DNSCheckStart" >> $logName
dig jochenmehlich.de >> $logName
echo "#*#DNSCheckFinished" >> $logName
# 5-Minute Testing
#if ! (($currentMinute % 5)); then
# External Download Test (5 Min)
SECONDS=0
fileTime=$(date +%s)
echo "#*#EDOWNSTART Starting external Download test" >> $logName
timeout 20s wget $externalFileDownloadUrl -O /root/$fileTime --content-disposition -a $logName
echo "#*#EDOWNLOAD took: " $SECONDS >> $logName
fileHash=$(md5sum /root/$fileTime | head -n1 | cut -d " " -f1)
rm /root/$fileTime
[[ $testFileHash == $fileHash ]] && downloadValid=true || downloadValid=false
echo "#*#EDOWNLOADValid: " $downloadValid >> $logName
#fi
echo "#*#TESTEND" >> $logName
# Try uploading logfile to main server
for filename in $(find . -maxdepth 1 -name \*.txt)
do
if curl -F "uploadedfile=@./$filename" https://psi-project.jochenmehlich.de/upload.php | grep "uploadDone";
then
echo $filename "uploaded, deleting now"
rm $filename
else
echo $filename "failed"
fi
done
What data did we get?
If we look at the log file of a measurement, we get the following output:
#*#NEWTEST Thu 19 Oct 11:41:01 BST 2023
#*#WIFIScanStart
wlan0 Scan completed :
Cell 01 - Address: 9C:8C:D8:73:53:20
Channel:1
Frequency:2.412 GHz (Channel 1)
Quality=44/70 Signal level=-66 dBm
Encryption key:on
ESSID:"eduroam"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
9 Mb/s; 12 Mb/s; 18 Mb/s
Bit Rates:24 Mb/s; 36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=0000000000000000
Extra: Last beacon: 40ms ago
IE: Unknown: 0007656475726F616D
IE: Unknown: 010802040B160C121824
IE: Unknown: 030101
IE: Unknown: 0706444520010D14
IE: Unknown: 200100
IE: Unknown: 23020800
IE: Unknown: 2A0103
IE: Unknown: 3204B0C8E0EC
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (2) : 802.1x unknown (5)
IE: Unknown: 0B0501001DA46C
IE: Unknown: 460573D001000D
IE: Unknown: 3305040105090D
IE: Unknown: 4306000CA46CA46C
IE: Unknown: 2D1AAD0903FFFFFFFF00000000000000000100000000000000000000
IE: Unknown: 3D1601000400000000000000000000000000000000000000
IE: Unknown: 7F0A04000800000000400040
IE: Unknown: FF1D230501081A4010006008881FC3831C010800AAFFAAFF1B1CC7711CC771
IE: Unknown: FF0724F43F0028FCFF
IE: Unknown: FF0E260F03A4FF27A4FF4243FF6232FF
IE: Unknown: DD180050F20201018F0003A4000027A4000042435E0062322F00
IE: Unknown: DD168CFDF0040000494C51030209720100000000FEFF0000
IE: Unknown: DD078CFDF004010100
Cell 02 - Address: 9C:8C:D8:73:53:21
Channel:1
Frequency:2.412 GHz (Channel 1)
Quality=44/70 Signal level=-66 dBm
Encryption key:off
ESSID:"@BayernWLAN "
Bit Rates:12 Mb/s; 18 Mb/s; 24 Mb/s; 36 Mb/s; 48 Mb/s
54 Mb/s
Mode:Master
Extra:tsf=0000000000000000
Extra: Last beacon: 40ms ago
IE: Unknown: 000C4042617965726E574C414E20
IE: Unknown: 01069824B048606C
IE: Unknown: 030101
IE: Unknown: 0706444520010D14
IE: Unknown: 200100
IE: Unknown: 23020800
IE: Unknown: 2A0103
IE: Unknown: 0B0501001DA46C
IE: Unknown: 460573D001000D
IE: Unknown: 3305040105090D
IE: Unknown: 4306000CA46CA46C
IE: Unknown: 2D1AAD0903FFFFFFFF00000000000000000100000000000000000000
IE: Unknown: 3D1601000400000000000000000000000000000000000000
IE: Unknown: 7F0A04000800000000400040
IE: Unknown: FF1D230501081A4010006008881FC3831C010800AAFFAAFF1B1CC7711CC771
IE: Unknown: FF0724F43F0028FCFF
IE: Unknown: DD28506F9A1C9C8CD87353221D5F6F7765746D5F4042617965726E574C414E2031393138373231323833
IE: Unknown: FF0E260F03A4FF27A4FF4243FF6232FF
IE: Unknown: DD180050F20201018F0003A4000027A4000042435E0062322F00
IE: Unknown: DD168CFDF0040000494C51030209720100000000FEFF0000
IE: Unknown: DD078CFDF004010100
Cell 03 - Address: 9C:8C:D8:73:6E:20
Channel:9
Frequency:2.452 GHz (Channel 9)
Quality=45/70 Signal level=-65 dBm
Encryption key:on
ESSID:"eduroam"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
9 Mb/s; 12 Mb/s; 18 Mb/s
Bit Rates:24 Mb/s; 36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=0000000000000000
Extra: Last beacon: 40ms ago
IE: Unknown: 0007656475726F616D
IE: Unknown: 010802040B160C121824
IE: Unknown: 030109
IE: Unknown: 050400010100
IE: Unknown: 0706444520010D14
IE: Unknown: 200100
IE: Unknown: 23020800
IE: Unknown: 2A0103
IE: Unknown: 3204B0C8E0EC
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (2) : 802.1x unknown (5)
IE: Unknown: 0B0502002A8A66
IE: Unknown: 3305040105090D
IE: Unknown: 4306000CA177A177
IE: Unknown: 460573D001000D
IE: Unknown: 2D1AAD0903FFFFFFFF00000000000000000100000000000000000000
IE: Unknown: 3D1609000400000000000000000000000000000000000000
IE: Unknown: 7F0A04000800000000400040
IE: Unknown: FF1D230501081A4010006008881FC3831C010800AAFFAAFF1B1CC7711CC771
IE: Unknown: FF0724F43F000AFCFF
IE: Unknown: FF0E260703A4FF27A4FF4243FF6232FF
IE: Unknown: DD180050F2020101870003A4000027A4000042435E0062322F00
IE: Unknown: DD168CFDF0040000494C51030209720100000000FEFF0000
IE: Unknown: DD078CFDF004010100
IE: Unknown: DD07000B8601040808
Cell 04 - Address: 9C:8C:D8:73:6E:21
Channel:9
Frequency:2.452 GHz (Channel 9)
Quality=45/70 Signal level=-65 dBm
Encryption key:off
ESSID:"@BayernWLAN "
Bit Rates:12 Mb/s; 18 Mb/s; 24 Mb/s; 36 Mb/s; 48 Mb/s
54 Mb/s
Mode:Master
Extra:tsf=0000000000000000
Extra: Last beacon: 40ms ago
IE: Unknown: 000C4042617965726E574C414E20
IE: Unknown: 01069824B048606C
IE: Unknown: 030109
IE: Unknown: 0706444520010D14
IE: Unknown: 200100
IE: Unknown: 23020800
IE: Unknown: 2A0103
IE: Unknown: 0B0501002E8A66
IE: Unknown: 460573D001000D
IE: Unknown: 3305040105090D
IE: Unknown: 4306000C8A668A66
IE: Unknown: 2D1AAD0903FFFFFFFF00000000000000000100000000000000000000
IE: Unknown: 3D1609000400000000000000000000000000000000000000
IE: Unknown: 7F0A04000800000000400040
IE: Unknown: FF1D230501081A4010006008881FC3831C010800AAFFAAFF1B1CC7711CC771
IE: Unknown: FF0724F43F000AFCFF
IE: Unknown: DD28506F9A1C9C8CD8736E221D5F6F7765746D5F4042617965726E574C414E2031393138373231323833
IE: Unknown: FF0E260703A4FF27A4FF4243FF6232FF
IE: Unknown: DD180050F2020101870003A4000027A4000042435E0062322F00
IE: Unknown: DD168CFDF0040000494C51030209720100000000FEFF0000
IE: Unknown: DD078CFDF004010100
Cell 05 - Address: FA:72:A1:31:19:C1
Channel:6
Frequency:2.437 GHz (Channel 6)
Quality=45/70 Signal level=-65 dBm
Encryption key:on
ESSID:"Hannah01"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s
Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s
36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=0000000000000000
Extra: Last beacon: 40ms ago
IE: Unknown: 000848616E6E61683031
IE: Unknown: 010482848B96
IE: Unknown: 030106
IE: Unknown: 050400020000
IE: Unknown: 0706444504010D14
IE: Unknown: 3B055153548081
IE: Unknown: 2A0100
IE: Unknown: 32080C1218243048606C
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
IE: Unknown: 2D1A6F0913FF00000000000000000000000000000000000000000000
IE: Unknown: 3D1606000600000000000000000000000000000000000000
IE: Unknown: DD180050F2020101810003A4000027A4000042435E0062322F00
IE: Unknown: BF0C12718033FEFF8601FEFF8601
IE: Unknown: C005000000FEFF
IE: Unknown: C3020014
IE: Unknown: 7F080500000000000040
IE: Unknown: DD088CFDF00101020100
IE: Unknown: DD0A0017F206010103010000
Cell 06 - Address: 12:62:E5:28:1C:7B
Channel:6
Frequency:2.437 GHz (Channel 6)
Quality=28/70 Signal level=-82 dBm
Encryption key:on
ESSID:"DIRECT-7B-HP PageWide Pro 477dw"
Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s
36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=0000000000000000
Extra: Last beacon: 40ms ago
IE: Unknown: 001F4449524543542D37422D48502050616765576964652050726F203437376477
IE: Unknown: 01088C129824B048606C
IE: Unknown: 030106
IE: Unknown: 200100
IE: Unknown: 23021100
IE: Unknown: 2A0100
IE: Unknown: 2F0100
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
IE: Unknown: 2D1A20001AFF00000000000000000000000000000000000000000000
IE: Unknown: 3D1606080000000000000000000000000000000000000000
IE: Unknown: DD090010180200000C0000
IE: Unknown: DD180050F202010184000364000027A4000041435E0061322F00
IE: Unknown: DD9E0050F204104A0001101044000102103B00010310470010759C538A7CD059DB990621EFB04DD92B1021000248501023001948502050616765576964652050726F203437376477204D4650102400064433513230421042000A434E3841344A593042541054000800030050F204000110110001201008000240081049000600372A0001201049001700013710060010759C538A7CD059DB990621EFB04DD92B
IE: Unknown: DD6408000900040000000001020100031A48502050616765576964652050726F203437376477204D4650000406343737647700050B434E3841344A593042540006108A539C75D07CDB59990621EFB04DD92B070400000000080200D40902003B0A0400000000
#*#WIFIScanEnd
#*#E-PingStart 11:41:01
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=52 time=14.4 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=52 time=15.0 ms
64 bytes from 1.1.1.1: icmp_seq=3 ttl=52 time=15.2 ms
64 bytes from 1.1.1.1: icmp_seq=4 ttl=52 time=17.5 ms
64 bytes from 1.1.1.1: icmp_seq=5 ttl=52 time=16.1 ms
64 bytes from 1.1.1.1: icmp_seq=6 ttl=52 time=16.9 ms
64 bytes from 1.1.1.1: icmp_seq=7 ttl=52 time=20.2 ms
64 bytes from 1.1.1.1: icmp_seq=8 ttl=52 time=13.8 ms
64 bytes from 1.1.1.1: icmp_seq=9 ttl=52 time=14.3 ms
64 bytes from 1.1.1.1: icmp_seq=10 ttl=52 time=15.6 ms
64 bytes from 1.1.1.1: icmp_seq=11 ttl=52 time=14.8 ms
64 bytes from 1.1.1.1: icmp_seq=12 ttl=52 time=15.7 ms
64 bytes from 1.1.1.1: icmp_seq=13 ttl=52 time=18.3 ms
64 bytes from 1.1.1.1: icmp_seq=14 ttl=52 time=17.4 ms
64 bytes from 1.1.1.1: icmp_seq=15 ttl=52 time=36.7 ms
64 bytes from 1.1.1.1: icmp_seq=16 ttl=52 time=16.7 ms
64 bytes from 1.1.1.1: icmp_seq=17 ttl=52 time=14.2 ms
64 bytes from 1.1.1.1: icmp_seq=18 ttl=52 time=15.1 ms
64 bytes from 1.1.1.1: icmp_seq=19 ttl=52 time=16.5 ms
64 bytes from 1.1.1.1: icmp_seq=20 ttl=52 time=14.2 ms
--- 1.1.1.1 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19026ms
rtt min/avg/max/mdev = 13.822/16.933/36.728/4.805 ms
#*#E-PingEND
#*#IPingStart
PING 141.13.129.225 (141.13.129.225) 56(84) bytes of data.
64 bytes from 141.13.129.225: icmp_seq=1 ttl=245 time=3.12 ms
64 bytes from 141.13.129.225: icmp_seq=2 ttl=245 time=9.00 ms
64 bytes from 141.13.129.225: icmp_seq=3 ttl=245 time=3.64 ms
64 bytes from 141.13.129.225: icmp_seq=4 ttl=245 time=3.75 ms
64 bytes from 141.13.129.225: icmp_seq=5 ttl=245 time=15.1 ms
64 bytes from 141.13.129.225: icmp_seq=6 ttl=245 time=3.39 ms
64 bytes from 141.13.129.225: icmp_seq=7 ttl=245 time=4.51 ms
64 bytes from 141.13.129.225: icmp_seq=8 ttl=245 time=3.50 ms
64 bytes from 141.13.129.225: icmp_seq=9 ttl=245 time=6.51 ms
64 bytes from 141.13.129.225: icmp_seq=10 ttl=245 time=129 ms
64 bytes from 141.13.129.225: icmp_seq=11 ttl=245 time=3.82 ms
64 bytes from 141.13.129.225: icmp_seq=12 ttl=245 time=6.91 ms
64 bytes from 141.13.129.225: icmp_seq=13 ttl=245 time=3.77 ms
64 bytes from 141.13.129.225: icmp_seq=14 ttl=245 time=9.14 ms
64 bytes from 141.13.129.225: icmp_seq=15 ttl=245 time=3.21 ms
64 bytes from 141.13.129.225: icmp_seq=16 ttl=245 time=3.26 ms
64 bytes from 141.13.129.225: icmp_seq=17 ttl=245 time=4.26 ms
64 bytes from 141.13.129.225: icmp_seq=18 ttl=245 time=3.25 ms
64 bytes from 141.13.129.225: icmp_seq=19 ttl=245 time=3.15 ms
64 bytes from 141.13.129.225: icmp_seq=20 ttl=245 time=6.66 ms
--- 141.13.129.225 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19026ms
rtt min/avg/max/mdev = 3.115/11.444/128.992/27.124 ms
#*#IPingEnd
#*#TraceRouteStart
#*#TraceRouteEnd
#*#DNSCheckStart
#*#DNSCheckFinished
#*#EDOWNSTART Starting external Download test
--2023-10-19 11:41:40-- https://psi-project.jochenmehlich.de/1MB.zip
Resolving psi-project.jochenmehlich.de (psi-project.jochenmehlich.de)... 88.99.93.158
Connecting to psi-project.jochenmehlich.de (psi-project.jochenmehlich.de)|88.99.93.158|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1048576 (1.0M) [application/zip]
Saving to: ‘/root/1697712100’
0K .......... .......... .......... .......... .......... 4% 871K 1s
50K .......... .......... .......... .......... .......... 9% 1.24M 1s
100K .......... .......... .......... .......... .......... 14% 1.71M 1s
150K .......... .......... .......... .......... .......... 19% 1.79M 1s
200K .......... .......... .......... .......... .......... 24% 1.34M 1s
250K .......... .......... .......... .......... .......... 29% 1.57M 1s
300K .......... .......... .......... .......... .......... 34% 932K 1s
350K .......... .......... .......... .......... .......... 39% 998K 1s
400K .......... .......... .......... .......... .......... 43% 1.80M 0s
450K .......... .......... .......... .......... .......... 48% 1.64M 0s
500K .......... .......... .......... .......... .......... 53% 1.92M 0s
550K .......... .......... .......... .......... .......... 58% 2.59M 0s
600K .......... .......... .......... .......... .......... 63% 1.89M 0s
650K .......... .......... .......... .......... .......... 68% 1.29M 0s
700K .......... .......... .......... .......... .......... 73% 1.33M 0s
750K .......... .......... .......... .......... .......... 78% 1.37M 0s
800K .......... .......... .......... .......... .......... 83% 1.32M 0s
850K .......... .......... .......... .......... .......... 87% 1.87M 0s
900K .......... .......... .......... .......... .......... 92% 2.47M 0s
950K .......... .......... .......... .......... .......... 97% 2.21M 0s
1000K .......... .......... .... 100% 2.86M=0.7s
2023-10-19 11:41:41 (1.48 MB/s) - ‘/root/1697712100’ saved [1048576/1048576]
#*#EDOWNLOAD took: 1
#*#EDOWNLOADValid: true
#*#TESTEND
We can see that I used the prefix #*#
for the location markers, the idea behind this action was that when extracting the data I can separate the log file by these markers, since the probability that these will occur naturally is very low. For further evaluation we split the log files into the individual test parameters and then have the values read out (usually via regex) and written into a database, in this case we use a python script for the extraction and write into a sqlite database, also we validate the log files in case something happened to the log output and corrupted the file. The file will be moved to another directory and listed in an invalid file. The biggest type of corrupted files were caused by write errors (mostly when the power connection is suddenly lost).
import sqlite3, zipfile, time, os, shutil
from pathlib import Path
from deepdiff import DeepDiff
from datetime import datetime
os.makedirs(os.path.dirname("data/invalid/not.txt"), exist_ok=True)
os.makedirs(os.path.dirname("data/done/not.txt"), exist_ok=True)
con = sqlite3.connect("data/dev.db")
con.row_factory = lambda cursor, row: row[0]
cur = con.cursor()
cur.execute("""create table zips
(
id integer not null
constraint zips_pk
primary key autoincrement,
filename varchar not null
constraint zips_pk_2
unique,
extractedAt datetime default current_timestamp not null
);""")
con.commit()
res = cur.execute("SELECT filename from zips")
scannedFiles = res.fetchall()
start_time = time.time()
for p in Path("zips/").rglob("*.zip"):
if str(p) not in scannedFiles:
print("Extracting {}".format(p))
with zipfile.ZipFile("{}".format(p), "r") as zip_ref:
zip_ref.extractall("data/raw")
cur.execute("INSERT INTO zips(filename) values ('{}')".format(p))
con.commit()
print("finished")
else:
print("Skipped {} (Already in database)".format(p))
print("--- %s seconds ---" % (time.time() - start_time))
cur.execute("""create table files
(
id integer not null
constraint files_pk
primary key autoincrement,
filename varchar not null
constraint files_pk_2
unique,
analyzedAt timestamp default CURRENT_TIMESTAMP
);""")
con.commit()
cur.execute("""create table nodes(
nodename varchar,
displayname varchar,
id integer
constraint nodes_pk
primary key autoincrement
);""")
con.commit()
cur.execute("""create table measurement
(
id integer
constraint measurement_pk
primary key,
node integer
constraint measurement_nodes_id_fk
references nodes,
timestamp timestamp not null,
num_wifis integer,
eping_avg float,
eping_max float,
eping_min float,
iping_avg float,
iping_max float,
iping_min float,
eping_loss integer,
iping_loss integer,
downloadValid boolean,
downloadTime integer,
logs text
);""")
con.commit()
cur.execute("""create table wifis
(
id integer
constraint wifis_pk
primary key autoincrement,
cellID varchar,
address varchar,
frequency integer,
channel integer,
quality integer,
signalLevel integer,
ssid varchar,
bitrates varchar,
measurement integer
constraint wifis_measurement_id_fk
references measurement
);
""")
con.commit()
res = cur.execute("SELECT filename from files")
scannedFiles = res.fetchall()
start_time = time.time()
verifier = {}
def verifierincrease(value):
global verifier
verifier[value] = verifier[value] + 1
validFormat = {
"newtest": 1,
"epingstart": 1,
"epingend": 1,
"ipingstart": 1,
"ipingend": 1,
"traceroutestart": 1,
"tracerouteend": 1,
"dnsstart": 1,
"dnsend": 1,
"edownloadstart": 1,
"edownloadvalid": 1,
"edownloadtime": 1,
"testend": 1
}
def verifierreset():
global verifier
verifier = {
"newtest": 0,
"wifiscanstart": 0,
"wifiscanend": 0,
"epingstart": 0,
"epingend": 0,
"ipingstart": 0,
"ipingend": 0,
"traceroutestart": 0,
"tracerouteend": 0,
"dnsstart": 0,
"dnsend": 0,
"edownloadstart": 0,
"edownloadvalid": 0,
"edownloadtime": 0,
"testend": 0
}
sublogs = {}
logStatus = -1
def getOperations(line):
global logStatus
if "#*#NEWTEST" in line:
verifierincrease("newtest")
elif "#*#WIFIScanStart" in line:
logStatus = 0
verifierincrease("wifiscanstart")
elif "#*#WIFIScanEnd" in line:
logStatus = -1
verifierincrease("wifiscanend")
elif "#*#E-PingStart" in line:
logStatus = 1
verifierincrease("epingstart")
elif "#*#E-PingEND" in line:
logStatus = -1
verifierincrease("epingend")
elif "#*#IPingStart" in line:
logStatus = 2
verifierincrease("ipingstart")
elif "#*#IPingEnd" in line:
logStatus = -1
verifierincrease("ipingend")
elif "#*#TraceRouteStart" in line:
verifierincrease("traceroutestart")
elif "#*#TraceRouteEnd" in line:
verifierincrease("tracerouteend")
elif "#*#DNSCheckStart" in line:
verifierincrease("dnsstart")
elif "#*#DNSCheckFinished" in line:
verifierincrease("dnsend")
elif "#*#EDOWNSTART" in line:
verifierincrease("edownloadstart")
elif "#*#EDOWNLOAD took:" in line:
verifierincrease("edownloadtime")
sublogs["downloadtime"] = int(line.split(":")[-1])
elif "#*#EDOWNLOADValid" in line:
verifierincrease("edownloadvalid")
sublogs["downloadvalid"] = "true" in line.split(":")[-1]
elif "#*#TESTEND" in line:
verifierincrease("testend")
if logStatus == 0:
sublogs["wifi"] = sublogs["wifi"] + line
elif logStatus == 1:
sublogs["eping"] = sublogs["eping"] + line
elif logStatus == 2:
sublogs["iping"] = sublogs["iping"] + line
def fileValid():
global verifier
if verifier["wifiscanend"] != verifier["wifiscanstart"]:
return False
wifi = verifier.pop("wifiscanstart")
verifier.pop("wifiscanend")
if validFormat == verifier:
verifier["hasWIFI"] = wifi == 1
return True
else:
print(DeepDiff(validFormat, verifier))
return False
def getWifiNum():
try:
networks = sublogs["wifi"].split("Cell")
networks.pop(0)
return len(networks)
except:
return 0
def getNodeId(nodename):
results = cur.execute("SELECT id from nodes where nodename = '{}'".format(nodename))
results = results.fetchall()
if len(results) == 1:
return results[0]
else:
cur.execute("INSERT INTO nodes(nodename) values ('{}')".format(nodename))
con.commit()
return cur.lastrowid
def addWifis(mID):
global sublogs
networks = sublogs["wifi"].split("Cell")
networks.pop(0)
for network in networks:
data = {}
data["cellID"] = int(network[:network.index("-")])
data["address"] = network[network.index("Address:")+9 : network.index("\n")]
data["frequency"] = int(float(network[network.index("Frequency:")+10: network.index("GHz")]) * 1000)
data["channel"] = int(network[network.index("(Channel ") +9 : network.index(")")])
data["quality"] = int(network[network.index("Quality=")+8:network.index("/70")])
data["signalLevel"] = int(network[network.index("Signal level=") +13 : network.index("dBm")])
if "SSID:" in network:
ssid = network[network.index("SSID:")+7 : network.index("Bit Rates")]
if '"' in ssid:
data["ssid"] = ssid[:ssid.index('"')]
else:
data["ssid"] = ""
else:
data["ssid"] = "#*#NOSSID"
if "Bit" in network:
bitrates = network[network.index("Bit") + 10: network.index("Mode")]
bitrates = bitrates.replace(";", "")
bitrates = bitrates.replace("\n", "")
bitrates = bitrates.replace (" ", "")
bitrates = bitrates.split("Mb/s")
bitrates.pop()
data["bitrates"] = bitrates
else:
data["bitrates"] = []
query = """INSERT INTO wifis(cellID, address, frequency, channel, quality, signalLevel, ssid, bitrates, measurement) VALUES(
{},"{}","{}",{},{},{},"{}","{}",{});""".format(
data["cellID"],
data["address"],
data["frequency"],
data["channel"],
data["quality"],
data["signalLevel"],
data["ssid"],
data["bitrates"],
mID)
cur.execute(query)
con.commit()
for p in Path("data/raw/done/").rglob("*.txt"):
if str(p) not in scannedFiles:
verifierreset()
logfile = open(p, "r").readlines()
filename = str(p)
sublogs = {
"wifi": "",
"eping": "",
"iping": "",
"downloadvalid": -1,
"downloadtime": -1
}
for line in logfile:
getOperations(line)
if fileValid():
node = filename.split("-", 1)[-1][:-4]
node = getNodeId(node) # just handle with db ids
eping = {}
iping = {}
epingTimes = sublogs["eping"].split("rtt")[-1].split("=")[-1].split("/")[0:3]
try:
eping["min"] = epingTimes[0]
eping["avg"] = epingTimes[1]
eping["max"] = epingTimes[2]
eping["loss"] = int(sublogs["eping"].split("received, ")[-1].split("% packet loss")[0].split("errors,")[-1])
except:
eping["min"] = -1
eping["avg"] = -1
eping["max"] = -1
eping["loss"] = -1
ipingTimes = sublogs["iping"].split("rtt")[-1].split("=")[-1].split("/")[0:3]
try:
iping["min"] = ipingTimes[0]
iping["avg"] = ipingTimes[1]
iping["max"] = ipingTimes[2]
iping["loss"] = int(sublogs["iping"].split("received, ")[-1].split("% packet loss")[0].split("errors,")[-1])
except:
iping["min"] = -1
iping["avg"] = -1
iping["max"] = -1
iping["loss"] = -1
timestamp = filename.split("/")[-1].split("-", 1)[0]
timestamp = datetime.utcfromtimestamp(int(timestamp)).strftime("%Y-%m-%d %H:%M:00.000")
num_wifis = getWifiNum()
log = ""
for line in logfile:
log = log + line
log = log.replace('"', "'")
query = """INSERT INTO measurement(node, timestamp, num_wifis, eping_avg, eping_max, eping_min, eping_loss, iping_avg,
iping_max, iping_min, iping_loss, downloadValid, downloadTime, logs) values (
{},'{}',{},{},{},{},{},{},{},{},{},{},{},"{}")""".format(
node,
timestamp,
num_wifis,
eping["avg"],
eping["max"],
eping["min"],
eping["loss"],
iping["avg"],
iping["max"],
iping["min"],
iping["loss"],
sublogs["downloadvalid"],
sublogs["downloadtime"],
log
)
cur.execute(query)
con.commit()
mID = cur.lastrowid
if num_wifis != 0:
addWifis(mID)
cur.execute("INSERT into files(filename) values ('{}')".format(filename))
shutil.move(filename, "data/done/{}".format(filename.split("/")[-1]))
print("Done with {}".format(filename))
else:
print("File invalid")
shutil.copy(filename, "data/invalid/{}".format(filename.split("/")[-1]))
else:
print("Skipped {} (Already in database)".format(p))
print("--- %s seconds ---" % (time.time() - start_time))
After successfully executing the script, we get 5 tables, but only 3 of them are important for further data analysis:
- The nodes table (which matches the nodename with an identifier):
- The measurement table (with all values):
- The wifi table (with all wifi ssids and the extracted values)
Data analytics
The data was then manually cleaned. This means that the differences between ’eduroam’ and ’eduroam ’ were matched to the same ’eduroam’ case to make the analysis more precise. Let us play with the data. First, we want to see how many measurements we have where the file download was valid, this will give us an overview of how many measurements were successful on a basic view.
SELECT
count(*) AS Total,
sum(case when downloadvalid = true then 1 else 0 end) AS DownloadValid,
sum(case when downloadvalid = false then 1 else 0 end) AS DownloadInvalid
FROM public.measurement
Out of about 2,300,603 measurements, only 67,338 failed the download tests (thats about 3%), which seems very good. But just because a 1MB file was successfully downloaded does not mean that the wifi is working, lets check it based on the external packet loss.
SELECT
count(*) AS Total,
sum(case when eping_loss = 0 then 1 else 0 end) AS NoPackageLoss,
sum(case when eping_loss != 0 then 1 else 0 end) AS PackageLoss
FROM public.measurement
Now we are already at 238,323 measurements with packet loss (~11%). Lets have a look at the packet loss distribution
select count(*), eping_loss from public.measurement
where eping_loss != -1
group by eping_loss;
Loss in % | 0 | 5 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 2062280 | 136648 | 26150 | 6469 | 2590 | 1652 | 1318 | 1020 | 885 | 836 | 822 | 537 | 457 | 391 | 412 | 266 | 280 | 250 | 204 | 211 |
Lets define the unusability of the wifi if the ping (external) is about 100 and has a packageloss (eping_loss != 0) and the downloadfile test was invalid, even if the wifi technically works with some of these parameters, the overall experience is not very good.
SELECT
count(*) AS Total,
sum(case when downloadvalid = true and eping_loss = 0 and eping_avg < 100 and eping_avg != -1 then 1 else 0 end) AS Useable,
sum(case when downloadvalid = false or eping_loss != 0 or eping_avg > 100 or eping_avg = -1 then 1 else 0 end) AS Unusable
FROM public.measurement
total | useable | unusable |
---|---|---|
2300603 | 2051236 | 249367 |
For better clarification, I divided the unusable into more cases so that we can understand why the measurement becomes unusable and how it correlates with other parameters, for this we have 7 cases:
- Case 1: Every parameter fails
- Case 2: Only the download fails
- Case 3: Only the external ping fails
- Case 4: Only the external ping averages about 100ms or is invalid (-1)
- Case 5: The download fails and the external ping has a loss
- Case 6: The download fails and the external ping averages about 100ms or is invalid (-1)
- Case 7: The external ping has a loss and the external ping averages about 100ms or is invalid (-1)
SELECT
count(*) AS Total,
sum(case when downloadvalid = false and eping_loss != 0 and (eping_avg > 100 or eping_avg = -1) then 1 else 0 end) AS Case1, -- All invalid
sum(case when downloadvalid = false and eping_loss = 0 and eping_avg < 100 and eping_avg != -1 then 1 else 0 end) AS Case2, -- Download invalid
sum(case when downloadvalid = true and eping_loss != 0 and eping_avg < 100 and eping_avg != -1 then 1 else 0 end) AS Case3, -- Eping loss
sum(case when downloadvalid = true and eping_loss = 0 and (eping_avg > 100 or eping_avg = -1) then 1 else 0 end) AS Case4, -- EPing AVG invalid
sum(case when downloadvalid = false and eping_loss != 0 and eping_avg < 100 and eping_avg != -1 then 1 else 0 end) AS Case5, -- Download invalid und Eping loss
sum(case when downloadvalid = false and eping_loss = 0 and (eping_avg > 100 or eping_avg = -1) then 1 else 0 end) AS Case6, -- Download invalid und Eping too high
sum(case when downloadvalid = true and eping_loss != 0 and (eping_avg > 100 or eping_avg = -1) then 1 else 0 end) AS Case7 -- Eping Loss and Eping avg invalid
FROM public.measurement
total | case1 | case2 | case3 | case4 | case5 | case6 | case7 |
---|---|---|---|---|---|---|---|
2300603 | 57772 | 5049 | 171206 | 4517 | 3039 | 1478 | 6306 |
To make sure that all cases has been covered, we can simply add the values together and we should get the same number as in the previous query. (which is also true in this case)
It is often pointed out to the responsible committee (ICT Advisory Board (dt. IuK-Beirat)) that one of the major problems with WLAN is that there are so many other WLAN networks and these have a major impact on the performance of eduroam due to the not exactly large frequency range, which sounds quite logical. So let’s take a look at how the data reflects this.
SELECT count(*), num_wifis from public.measurement
where downloadvalid = false or eping_loss != 0 or eping_avg > 100 or eping_avg = -1
group by num_wifis
num_wifis | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 36463 | 2836 | 4313 | 10344 | 14951 | 18230 | 14715 | 13455 | 12631 | 13572 | 14883 | 15030 | 14498 | 13233 | 12406 | 10723 | 8150 | 5607 | 3579 | 2132 | 1501 | 1336 | 1262 | 1197 | 951 | 584 | 367 | 175 | 87 | 46 | 29 | 25 | 15 | 16 | 7 | 7 | 7 | 2 | 1 | 1 |
We can observe that as the number increases, in some cases the number of incorrect measurements actually increases. But here too, looking only at the absolute figures can lead to a fallacy, which is why the analysis should be carried out again with relative figures in any case.
num_wifis | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
total | 775449 | 3556 | 25981 | 35675 | 67928 | 83435 | 97600 | 102781 | 112581 | 118742 | 119606 | 117246 | 107555 | 93637 | 84503 | 74056 | 63412 | 50973 | 39853 | 30702 | 24285 | 19651 | 16294 | 12938 | 9477 | 6071 | 3518 | 1718 | 776 | 291 | 147 | 76 | 36 | 20 | 14 | 8 | 7 | 1 | 2 | 1 | 1 |
unusable | 36463 | 2836 | 4313 | 10344 | 14951 | 18230 | 14715 | 13455 | 12631 | 13572 | 14883 | 15030 | 14498 | 13233 | 12406 | 10723 | 8150 | 5607 | 3579 | 2132 | 1501 | 1336 | 1262 | 1197 | 951 | 584 | 367 | 175 | 87 | 46 | 29 | 25 | 15 | 16 | 7 | 7 | 7 | 0 | 2 | 1 | 1 |
usable | 738986 | 720 | 21668 | 25331 | 52977 | 65205 | 82885 | 89326 | 99950 | 105170 | 104723 | 102216 | 93057 | 80404 | 72097 | 63333 | 55262 | 45366 | 36274 | 28570 | 22784 | 18315 | 15032 | 11741 | 8526 | 5487 | 3151 | 1543 | 689 | 245 | 118 | 51 | 21 | 4 | 7 | 1 | 0 | 1 | 0 | 0 | 0 |
failedrate (%) | 4 | 79 | 16 | 28 | 22 | 21 | 15 | 13 | 11 | 11 | 12 | 12 | 13 | 14 | 14 | 14 | 12 | 10 | 8 | 6 | 6 | 6 | 7 | 9 | 10 | 9 | 10 | 10 | 11 | 15 | 19 | 32 | 41 | 80 | 50 | 87 | 100 | 0 | 100 | 100 | 100 |
The relative approach is much more meaningful for us; we observe here that the error rate is relatively high, especially with four SSIDS, and then levels off sharply. From 30 SSIDs onwards, the error rate rises extremely again.
with t1 as (select count(*) as num from public.wifis where ssid='eduroam' group by measurement)
select count(*), num from t1 group by num order by num;
num | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|
count | 306794 | 466511 | 377573 | 169725 | 96488 | 44786 | 23881 | 6333 | 15167 | 7093 | 7 |
Let us see how many of these measurements fail (= unusable) relative to the number of detected eduroam SSIDs (number of accesspoints providing the eduroam network in this area).
with t1 as (select count(*) as num from public.wifis inner join public.measurement on public.wifis.measurement = public.measurement.id where (public.measurement.downloadvalid = false or public.measurement.eping_loss != 0 or public.measurement.eping_avg > 100 or public.measurement.eping_avg = -1) and public.wifis.ssid = 'eduroam' group by public.wifis.measurement)
select count(*), num from t1 group by num order by num;
num | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
count | 67471 | 55228 | 28570 | 16832 | 12426 | 10061 | 6497 | 1108 | 2694 | 1227 |
As before, this tells us relatively little about when the wifi is not working properly, it becomes much more interesting when we look at the relative frequencies, for which I have created a separate temporary table to avoid huge SQL queries.
SELECT * FROM public.tmp_eduroam_1 LIMIT 100;
num | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|
total count | 306794 | 466511 | 377573 | 169725 | 96488 | 44786 | 23881 | 6333 | 15167 | 7093 | 7 |
fail count | 67471 | 55228 | 28570 | 16382 | 12426 | 10061 | 6497 | 1108 | 2694 | 1227 | 0 |
failrate (%) | 22% | 12% | 8% | 10% | 13% | 22% | 27% | 17% | 18% | 17% | 0% |
It is not really surprising that if there is only one SSID, the failure rate is relatively high, but above all we also see that if many access points provide eduroam, the failure rate quickly becomes very high. This measurement shows that 3 eduroam access points have the lowest failure rate.
select count(*) from public.wifis where ssid='eduroam' group by address;
A total of 94 different eduroam access points were recorded on the Erba site (depending on the SSID address). On the pretext that every access point that offers eduroam also offers bayernwlan, we can use the Bavarian government’s online list [4] to check whether we have recorded everything correctly.
We see that the WLAN is not as functional as promised, on average we have error rates of 11-16%. We also have several clear factors that differentiate the measurement stations from conventional devices:
- They were stationary
- They had a technical user who did not need to authenticate to the network via an easyroam certificate authority.
- They were permanently connected to the WLAN
Whether you see these factors as negative or positive is up to you, but I would like to point out that I have often noticed in the log files of my laptop, for example, that the login went smoothly, but the DHCP server failed to assign an IP, especially when logging into the wifi.
What happens next? In order to collect data on a permanent basis, I have reduced the amount of data many times over, so that the PIs only send heartbeats to a central instance, which then creates an uptime history, which - mainly due to the smaller amount of data - can record the performance of the WLAN over a much longer period of time. It is also planned (and in some cases already agreed) to include fixed servers connected directly via LAN in the measurement to see if there are parallels between WLAN and LAN in terms of downtime.
Depending on how much work you want to do, you can consider how to optimize the method for reporting problems with the WLAN (e.g. without having Internet access). The integration of “normal” devices (i.e. laptops that move around the building and are verified by the easyroam authentication point) and the expansion to other campus locations could be other aspects.
Overall, you can clearly see that there is much more to be done to show that it doesn’t work. And even if we know why it doesn’t work, it would be exciting in the long run to know what needs to be done to make it work and to solve the problems that arise on an almost weekly - and depending on the period, even daily - basis.
The goal of the project, to show that it’s not all about you, was achieved. Personally, I would answer the question of whether it’s as bad as we thought with a big NO, but I also believe that everyone has to define the answer for themselves.
Some useless facts
- 57 unique IPhone Hotspots were recorded during the time
- 89 unique Samsumg Galaxy Hotspot were recorded during the time
- 115 unique Audi Hotspots were recorded
- 91 unique VW Hotspots were recorded
- All measurements added up to over 4TB of network traffic (just for the file download tests)
- No raspberry pi got stolen
- One ssid had a rickroll
Sources
- [1] https://monitor.eduroam.org/f_ticks_graphs.php?gtype=basic&country=de&obid=all>ime=2024-06-10%2000:00:00::2024-06-16%2023:59:59
- [2] https://monitor.eduroam.org/f_ticks_stats.php?gtype=matrix&country=de&obid=all>ime=2024-06-10%2000:00:00::2024-06-16%2023:59:59
- [3] https://monitor.eduroam.org/f_ticks_about.php
- [4] https://www.wlan-bayern.de/#/map/view/49.903400793119616,10.869174599647524,17,49.8916044,10.8868478
With the help of a selected number of language tools (e.g. DeepL) the quality of this report was improved.