More updates to speccy pushed to github this weekend. It gained the ability to toggle on-and-off line and scatter plots. Also, it now takes care of enabling spectral scan and then scanning channels (by exec()-ing iw, naughty me) so you can just tell it the device and it does the rest. Code is still ugly but gradually taking shape. There’s an animated gif for those that want to see what it currently looks like in operation.
I settled on (somewhat inefficiently) smoothing the line graph with a centered moving average using a 5-sample window length, which met the strict theoretical basis of “it looked kind of right.” I did not yet incorporate the time-based plot I was playing with.
It could certainly be faster. Profiling shows that the vast majority of time is spent drawing 9-pixel rectangles in Cairo. I suppose that even if Cairo was using an accelerated backend, which I don’t believe it is in my case, that this would be something more efficiently done by rendering to a client pixmap anyway. Lots of low-hanging fruit everywhere, but I’m resisting the urge to really optimize anything at this early stage.
Also yesterday I finally cleaned up the somewhat messy serial port installation on one of my ath10k routers with the help of a drill. These cheap cables work well but do require a bit of attention with the glue gun — I find the plastic case around the USB port / converter board is always coming un-snapped and falling off otherwise.
This is roughly what I had in mind for the time/frequency plot for my little spectrum visualizer. Time is on the y-axis and frequency on the x-axis. There are some interesting artifacts here, especially on the higher channels. Probably bugs in my implementation, but we’ll see as I develop it further.
I messed around with “speccy” a bit today to see what I could do with it to make it look slightly nicer. It really needed a grid so one can more easily see the frequencies and power levels. So now it looks like this:
(This is with iperf running on channel 6 to a nearby AP).
I have in mind a couple of other visualizations. An obvious one is to show the overall max or average power level rather than a scatter plot. This would be a cleaner display, although there could be co-channel interference sources you wouldn’t see that way. Here’s a first cut at that:
I am doing some averaging for multiple (~8) samples with the same subcarrier frequency, but clearly more smoothing is needed. Also I notice that I occasionally get some artifact where all the subcarriers have the exact same power level. Not sure what that is, but it wants filtering.
Another interesting visualization would be a scrolling chart of frequency vs time, with power level indicated by pixel intensity. Then you could get an idea of historical changes in the medium. (Oh hey, the neighbors are watching Netflix now.)
The code is still an ugly pile of hacks, which it will probably continue to be until I decide just what kind of processing needs doing on the raw samples. Sorry for that.
…is a thing now.
# iw dev
type mesh point
channel 149 (5745 MHz), width: 80 MHz, center1: 5775 MHz
# iperf -c 192.168.1.20
Client connecting to 192.168.1.20, TCP port 5001
TCP window size: 43.8 KByte (default)
[ 3] local 192.168.1.21 port 34175 connected with 192.168.1.20 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 148 MBytes 124 Mbits/sec
In response to my previous post about UART access on the Alfa AWUS036NHA, I got a nice email from Jim Ewing about the DWM-W034, an ath9k_htc device that apparently is embedded inside HDTVs and readily available for $10. He found the TX/RX pins on the board, and it looks like it would be a bit easier to put a socket on one of these compared to the Alfa since there are no pesky chips nearby.
With his permission, and so that this information doesn’t get lost to the sands of time, here’s the pic he sent me. Enjoy!
I’ve had my ath10k AP (TP-Link Archer C7 v2) since last October or so, with the goal of having a VHT-capable device with which to test (currently non-existent) VHT mesh. Unfortunately, for nearly all of that time, I’ve been stuck on a firmware crash shortly after bringing up the device. Not that I’ve spent a whole lot of time on it, but there’s only so much one can do when getting to the point of “firmware crashes and it has something to do with peers but that’s all I know and I don’t have the time, tools, or code to dig deeper.”
I think there’s some variant on rubber duck debugging where you complain publicly about some issue, and doing that makes you think about it more, and then the way forward is magically revealed. That, plus some helpful hints from the residents of the ath10k ML, got me over the hump, so now it works!
Next up, finding a spare mini PCIe slot for the other ath10k device I have, and getting the VHT bits done…
My ath10k-based router now has serial headers, after I managed to crash it a few times over the weekend while testing out some patches. Thank you, TP-Link, for making the pins so easily accessible, to the extent that it’s easier to whip out the soldering iron than remind oneself how to setup kexec/kdump.
I do need to get one of these nifty usb-serial cables so that the JTAG ribbon cable + FTDI-breakout-on-a-breadboard monstrosity can go back into the
parts bin, but it is working fine otherwise. [The pictured 7-segment display and TTL chips are just misdirection, by the way.]
There was a momentary bit of confusion on my part when the console showed the router stuck in a loop requesting recovery firmware over TFTP instead of the normal boot process…until I realized that the reset button was wedged in the depressed state by the case. Whoops.
The ath9k and later chips support a spectral scan feature for measuring channel occupancy. I played with it for the first time last week over the Thanksgiving holiday. Simon Wunderlich’s FFT_eval is a great tool to look at the captured RF spectrum, but I found myself wanting something more real-time, and the various other things I found on github with that aim didn’t work for me. So, this too-ugly-to-live python hack happened.
It turns out that the samples are rather coarse and infrequent, so the result is not as dynamic as I’d hoped. However, I made the pretty heatmap below with a few hours’ worth of samples, and although I didn’t yet label frequencies, you can see a couple of channels in active use. There’s still plenty of room for improvement in the visualization.
My wmediumd rewrite is a bit further along thanks to getting a few hours to hack on it this weekend. It can now accurately simulate throughput between a pair of radios using legacy rates. For example, if we set the SNR between two devices to 20 dB, then they can communicate at a nominal 54 mbps rate, yielding about 26 Mbps achieved in iperf:
[ 3] 0.0-10.0 sec 31.2 MBytes 26.1 Mbits/sec
At 15 dB, we can send between 24 and 36 Mbps nominal rates, which yields:
[ 3] 0.0-10.1 sec 21.0 MBytes 17.5 Mbits/sec
Note that achieved throughput is quite a bit lower than nominal, as in real life — if aggregation were implemented then they would be closer.
The basic architecture is pretty simple: frames are queued on a per-sender management or data queue depending on type, and delivery time is computed based on whether or not there is loss and the contention window parameters of the queues. A timerfd is used to schedule reporting of frame delivery back to the kernel at appropriate times. The delivery time does not take into account actual contention, although this could be done in principle by looking at all the queued frames for all stations.
I haven’t really decided what to do about configuration. I stripped out the jamming and probability matrix configurations, as I feel like doing things on a signal level basis are simpler. But at this point there’s no real way to specify signal levels either (other than hardcoding), and some scenarios probably want something dynamic (e.g. mobile stations).
Changes are in my wmediumd master branch. Unfortunately, I won’t have much time to work on this for the next two months, but patches for the many TODOs are welcome.
Thanks to some inquries on linux-wireless, I took a look at wmediumd recently. The code could use a bit of work, and there are some features I’ve been meaning to add since forever, so I started gutting it with an eye towards sprucing up the architecture and feature set (changes can be found here).
One of the questions from the mailing list was whether wmediumd adds a lot of overhead compared to mac80211_hwsim. It is of course doing more work, with additional memory copies, context switches, etc — but is it enough to make wmediumd unworkable?
So I did a quick TCP iperf test on my laptop with an open mesh, and get the following numbers.
hwsim without wmediumd:
[ 3] 0.0-10.0 sec 1.36 GBytes 1.16 Gbits/sec
hwsim with wmediumd:
[ 3] 0.0-10.0 sec 1.27 GBytes 1.09 Gbits/sec
It looks like wmediumd is doing fine. This is with monitors running, the non-monitor case does about twice that. Actually, I think this is a bit lower than it should be, but considering both cases are close, and a good deal faster than your typical wifi connection, it’s probably good enough for some level of bandwidth simulation.