Hackrf Racket Bindings: Update 3

tl;dr: I can set radio parameters and also transfer RX data to a file.

I created many of the bindings for setting radio parameters, such as setting the center frequency and the sample rate. Those bindings were easy.

Figuring out the binding for the hackrf_start_rx function, and figuring out how to make use of it, was difficult and took a lot of time. This is because internally hackrf_start_rx utilizes pthreads, which apparently does not play well with the Racket environment unless you pass in special parameters to _fun ctype. Once I figured that out, I had a lot of difficult figuring out how pull data from the hackrf_transfer buffer, and I kept trying to write the data to a file but couldn’t seem to pull it off.

Anyway, I figured that out for the most part, and was able to dump RX data to a file at a speed that seemed to match up with my set sample rate, which was 8 mhz. However, I’m not quite sure about the efficiency of that operation as I was calling write-byte for each byte in the buffer. I wanted to use write-bytes instead to transfer the whole buffer in one call, but I was having trouble getting that to work.

 racket@hackrf.rkt> (hackrf-init)
 racket@hackrf.rkt> (define h (hackrf-open))
 racket@hackrf.rkt> (sensible-defaults h)
 racket@hackrf.rkt> (define out (open-output-file "out.bin"))
 racket@hackrf.rkt> (define cb (cb-rx-to-port out))
 racket@hackrf.rkt> (hackrf-start-rx h cb)
christopher@nightshade:~/Repos/hackrf-rkt$ hexdump out.bin | head
 0000000 fa00 0201 f6ff 0303 f802 0100 fc00 ff04
 0000010 fff7 fa03 01f8 fdfe fefe fbfd 0000 f6fe
 0000020 0305 f9fe fb08 02fb f803 05fd fbff ffff
 0000030 fbf9 0100 faf9 ff03 fcfd f702 0200 f902
 0000040 0102 fc03 fefe fcfc 0203 fdf4 fe06 fff8
 0000050 f9fe 0202 f7fe 0104 f401 0000 feff fb04
 0000060 05fa f702 03fa fffc fe00 fdfc fe04 f6fb
 0000070 0105 fafd f906 02ff f500 0600 fdfc 0000
 0000080 fdfc fe01 fef6 fd04 fffc f500 0004 f7fb
 0000090 0103 fb01 fe01 fdfc 0003 02f5 fd05 01fb

HackRF Racket Bindings: Update 2

It took me a while to produce one more function, which is hackrf-open. This delay was mainly because I had a shaky understanding of some of the Racket FFI concepts and functions, so I had to go back and relearn several things, especially relating to handling C pointers in Racket. Another thing that is interesting: In C you are expected to manually allocate and deallocate memory, and signal errors via an integer return value, whereas in Scheme we are expecting the memory management to happen automatically, with errors being signaled by exceptions, so there is some work to be done bridging between to two ideas.

Anyway, hackrf-open was a good step as it gives you access to the hackrf_device pointer, which has to be passed to most of the other hackrf control functions.

racket@hackrf.rkt> (define dev (hackrf-open))
racket@hackrf.rkt> dev

If you run (exit) or assign something else to dev, the program will run hackrf_close on #<cpointer:hackrf_device>.

git clone git://git.librehacker.com/pub/git/hackrf-rkt.git

Hackrf Racket Bindings: Update

I code bindings for the info functions, the functions used to pull basic information about the HackRF devices that are plugged in to USB.

racket@hackrf.rkt> (hackrf-init)
racket@hackrf.rkt> (define dl (get-hackrf-device-list))
racket@hackrf.rkt> (hackrf-device-count dl)
racket@hackrf.rkt> (hackrf-serial-numbers dl)
racket@hackrf.rkt> (hackrf-usb-board-ids dl)
racket@hackrf.rkt> (hackrf-usb-device-index dl)
racket@hackrf.rkt> (hackrf-usb-devices dl)

There are a few earlier boards that are also supported by this interface besides just the HackRF One.

I’m coding for the version of libhackrf in Debian Stretch, which I’ve discovered is a few years older than the master branch. Maybe after finishing these binds I’ll create a new Git branch for the newer library, and update the bindings for it.

Here is the repo:

git clone git://git.librehacker.com/pub/git/hackrf-rkt.git

Four IPv6 Addresses

When working with IPv6 addresses for your host, you should be familiar with four different types:

  • DHCPv6
  • Autoconfigured Addresses (SLAAC)
    • Stable
      • EUI64
      • stable-privacy
    • Privacy temporary addresses

Quick review: an IPv6 address will have a 64 bit prefix portion, specifying the network (e.g., 2001:470:b:449) and a 64 bit suffix portion, specifying the host (e.g., 1e6f:65ff:feac:7d41).

(I skipped over static addresses as that is boring.)

DHCPv6 is listed first simply because it is the least interesting of those listed. This is the traditional way to receive an IP address, where a DHCP server on your network just picks one for you. I don’t like this approach — why depend on a DHCP server when we have IPv6 autoconfiguration? The only advantage I see is that DHCP servers I work with usually pick a shorter, easier to remember suffix, if you happen to want to memorize it. E.g., I received 2001:470:b:449::2d3, where ::2d3 is the suffix.

Stable SLAAC addresses are auto-configured, but according to a deterministic algorithm, such that you can rely on your IP address being the same every time. This is important if running a server, or for some firewall rules. The EUI64 algorithm generates this IP address by joining your network prefix to a modified form of the MAC address for your network interface. Since your MAC address is usually hardcoded into the hardware, you can rely on that not changing (often) and also figure it out in advance if you need to do so. E.g, my MAC address is 1c:6f:65:ac:7d:41, on network 2001:470:b:449, so my EUI64 address is 2001:470:b:449:1e6f:65ff:feac:7d41. ♬ here’s my number, so ping me maybe

Stable EUI64 addresses are a problem if you need privacy, because your IP suffix will remain the same on every ethernet or Wi-Fi network you visit, making it rather easy to track you. If you set your host’s network connection to use privacy temporary addresses (this might be the default) your system will generate a new IP address for you periodically, with a random suffix, and use one of these when you make a new connection.

There is also available a compromise between EUI64 and privacy temporary addresses, called stable-privacy. This generates an IP address for you deterministically based on some information on your system and some information in your network environment. Consequently, you get a different IP address for each network you visit, but it is the same address always paired to each network. Part of the formula involves a secret key on your host, so in principle the process can’t be fully reversed. So, basically, you get to be a different person on each network, but they recognize you when you come back.

In Gnome desktop (my version at least) you don’t get very much control of these options from the GUI widget. In my experience it is better to learn how to use the nmcli(1) command-line tool to control Network Manager directly.

hackrf-rkt git repo

My project wasn’t big enough yet for Savannah, and I don’t like any of the other hosting options I’m familiar with, so I set up a git daemon for my libhackrf Racket bindings project:

git clone git://git.librehacker.com/pub/hackrf-rkt.git

This was something of an adventure, as (1) I found, and had to fix myself, a bug in Debian Stretch’s git-daemon-run package, and (2) the git-daemon config syntax was not quite intuitive to me, such that I had to tweak my parameters about five times while watching the system log, in order to export my repo.

Anyway, the clone should work from any IPv4 or IPv6 address, though I only tested IPv6. Let me know if there is a problem with IPv4 access.