Thoughts on going down the network stack

👋 This page was last updated ~4 years ago. Just so you know.

So!

I have no shortage of ongoing writing projects - I still need to edit and publish the final parts of making our own executable packer, and I've recently announced I was working on a Rust book/series. Those are still both on the table.

Buuut... I'm also looking at other things. My best writing happens when I'm learning about something at the same time I'm writing about it. So for example, the Rust book is a bit harder to write, because I'm mostly trying to distill knowledge I've already absorbed (for the most part).

On the other hand, the ELF (executable packer) series was great for that - I knew a little about ELF, enough to think something interesting could be done with it, but not enough to send me into analysis paralysis - I didn't have to figure out in which order to tackle various questions, because I was just hunting down the answers to my own questions, as they came up.

Of course the downside of working this way is I'm in a constant state of not being qualified enough to write about whatever I'm writing about. But that's where more knowledgeable readers come in with helpful feedback!

So, in the spirit of writing about things I don't yet understand - I've been looking at embedded hardware recently. I just see a lot of "Rust on embedded" tweets going around, and tiny stuff has that cool factor, I just knew at some point I'd buy a board and try to figure out something fun to do with it.

So I did! I bought the BBC micro:bit.

Why that one? Well, it was reasonably-priced, and could ship to France quickly enough (Covid-19 means shipping times are way longer now). Also, I've seen some people run Rust code on it.

The micro:bit has an nRF51822 SoC (System on a Chip) on it:

The nRF51822 is a general purpose, ultra-low power SoC ideally suited for Bluetooth® Low Energy and 2.4 GHz proprietary wireless applications. It is built around the 32-bit ARM® Cortex™-M0 CPU with 256/128 KB flash and 32/16 KB RAM. The flexible 2.4 GHz radio supports Bluetooth Low Energy and 2.4 GHz proprietary protocols, such as Gazell.

While I was thinking of things to do with this chip (besides blinking its LEDs furiously), my eye was caught by "2.4 Ghz radio".

You know what else is in the 2.4 GHz band?

Cool bear

Cool bear's hot tip

Micro-wave ovens!

Yes, and?

Cool bear

Cool bear's hot tip

Bluetooth Low-Energy!

Yes, but the nRF51 already does that - that's no fun!

Cool bear

Cool bear's hot tip

Uhhh... 802.11g?

Correct! Aka that Wi-Fi protocol from 2003.

How cool would that be? I feel like projects are always a lot more fun if they can hook into existing systems - just like the our ELF dynamic loader can run programs built with GCC, or how our userland ICMP implementation can ping real-world servers on the internet.

So immediately my instinct told me this was a very dumb idea. But I like very dumb ideas! I figured at some point, something would prevent me from, somehow, programming an nRF51 so it does 802.11 instead of Bluetooth Low Energy.

I figured... the radio would probably be too weak. Bluetooth Low Energy is for short-distance communications, it uses a lot less energy than Wi-Fi. But maybe.. if I stick my micro:bit really close to an access point...

I also figured the ARM Cortex-M0 CPU would probably be too slow. From my initial research on 802.11, the time you have to process and reply to a given message is short (in the neighborhood of 10μs).

But then, after talking to a few more folks involved with wireless networking at various levels, I stumbled upon the actual stopping point: Bluetooth LE and 802.11 simply use different modulation schemes.

What's a modulation scheme?

Well, as a software engineer, I'm mostly thinking of data as bytes - which usually end up being a collection of 8 bits. And I was naively thinking, okay, the radio module just lets us read and write bits at a certain rate.

And to a certain extent, I was right! I just sorta, kinda, forgot, that when the data escapes through the antenna, it does so in analog form - as a wave.

If you've ever wondered what the difference between "AM" and "FM" radio is, this will be familiar to you.

In AM, you mess with the amplitude of the wave - how far up and down it goes:

In FM, you mess with the frequency of the wave - how often/how fast it goes up and down:

That's for analog modulation - when you're sending audio, for example (which is already a wave!). Digital modulation is, from my understanding, roughly the same, except you decide on values that mean "0" and values that mean "1".

Bluetooth uses GFSK (Gaussian Frequency Shift-Keying) - which means it uses different frequencies to send a 0 or a 1. I'm still not crystal clear on the Gaussian filter part, but Wikipedia tells me it makes the transition smoother.

802.11g, however, in the low bitrate modes I was looking at, is using BPSK (Binary Phase Shift Keying), which changes not the frequency, not the amplitude, but the phase of the wave:

What's the problem then? An nRF51 radio should still be able to do that, right?

Well, yes and no. Even though part of the Bluetooth LE stack is implemented in software, running on the nRF51's CPU (and various dedicated chips), the modulation and demodulation is definitely not done in software.

Further research indicated that it would be, in theory, possible to do your own modulation/demodulation using a Field-Programmable Gate Array (FPGA).

Some additional hardware is required besides the FPGA itself, though, and programming an FPGA is not as comfy as writing ARM assembly. So, you know, for a first embedded hardware project, it seems a tiny bit out of reach.

Cool bear

Cool bear's hot tip

Not to mention that to debug any of it, you'd need very expensive measuring hardware. Even a good oscilloscope will set you back quite a bit.

But I'm not discouraged. First off, I'm going to find something else to do on the micro:bit. It has a LED array I'm sure we can do fun things with.

And second, I'm really curious about modulation schemes now. So I'm thinking, if we don't have hardware... we can just simulate all of it.

Not accurately, of course. I don't want to get into actually simulating waves in a physical spaces, and having them bounce around, and influence each other.. but a bit of random noise added, and some artificial signal loss would do just fine...

And once we have modulation/demodulation in software, who knows what else we can build on top of it! And it would be a series anyone can follow along.

So I'm excited! Cautiously so. I really want to finish the other stuff before fully committing to this, but I think some signal processing is not outside the scope of my writing project.

Well, that's it for now. We'll see where this goes. I was a bit worried going into this new territory alone, but I've already gotten the opportunity to ask my dumb questions to a few folks, and I'm sure as time goes on, other opportunities will present themselves.

After all, the best way to get the right answer on the internet is to post the wrong answer!

Comment on /r/fasterthanlime

(JavaScript is required to see this. Or maybe my stuff broke)

Here's another article just for you:

Cracking Electron apps open

I use the draw.io desktop app to make diagrams for my website. I run it on an actual desktop, like Windows or macOS, but the asset pipeline that converts .drawio files, to .pdf, to .svg, and then to .svg again (but smaller) runs on Linux.

So I have a Rust program somewhere that opens headless chromium, and loads just the HTML/JS/CSS part of draw.io I need to render my diagrams, and then use Chromium's "print to PDF" functionality to save a PDF.