Thinktank

A building-block for DIY Bluetooth audio devices

I’m a late adopter of Bluetooth, having previously tried Bluetooth in its earlier days, hearing something that sounded like my music was being fed down a drain pipe, and deciding that Bluetooth was rubbish… it wasn’t until I bought a Logitech H830 headset that I found that Bluetooth can actually sound decent… moreover when I bought the Logitech Zone Wireless, that bi-directional Bluetooth can also sound decent.

Now, the Zone Wireless is fine if I’m in the office, or out walking somewhere. It’ll fit underneath the coolie hat if I decide to wear that, otherwise it works with a cap just fine. BUT, if I’m camping or at a WICEN event, I’m often wearing a full-brim hard hat. The headband on the Zone Wireless is a problem.

I really wanted a Bluetooth device that could be put on a lanyard, and I just plug in a regular common-garden variety wired headset. The closest I can get to this is a motorcycle headset — as these have to accommodate a wide variety of helmet styles, the radio module and the headset are actually separate components, and so conceivably, I can make my own compatible adaptor to plug in. Then, it wouldn’t matter… want to wear the hard hat? No problem, I already have modded earmuffs with a headset. Want to use it on the bike? Sure, plug the helmet straight in. Or am I in the office again? No problem, normal headset.

It’d also be nice to share that wired headset with a wired audio device… prime example here is a radio transceiver. Yes, there are devices that will make those do Bluetooth… and there are radios that have Bluetooth. I had one of the latter: Yaesu VX8-DR … it’s Bluetooth was next to useless… idiosyncratic and unreliable.

I see the Sena SR-10 mentioned in a few places as a way to “Bluetooth-enable” a two-way radio… but aside from being pricey, I see three complaints being raised: unreliable/slow pairing, intermittent darlek-like distortion on transmit and a noticeable connection delay on incoming signals.

I pondered doing my own… and I’ve slowly amassed parts to do exactly that. But, the other day, I stumbled on another option: Altronics sell a CSR8635 Bluetooth module. This advertises the ability to talk to two Bluetooth devices, and wideband voice. CSR’s own datasheet seems to give some hints as to how it can be used.

One catch, is the pads on this device are a 1mm spacing — so mounting this on some perfboard is going to be a big challenge. I prefer the minimalism of a module like this over a Raspberry Pi Zero W… a lot less to go wrong, and likely much better battery life.

Demise of 4KQ: one week on

So, it’s been 8 days since we woke up to the non-stop sports yap-trap that we were promised would be coming on the 1st July. Not that I heard much of it. I made a point of staying up and listening to the last of the old station before it went. The final few hours of the broadcast were ad-free and the final things heard on the station were:

  • Don McLean’s American Pie
  • The Beatles The End (from their album, Abbey Road — minus the secret track Her Maj)
  • crickets sound effect — fading out to silence

Then, shortly after… it cut over to the new mob. They just had a playlist going for the first 6 hours, with the cut-over about a minute into Survivor’s Eye Of The Tiger. I put the radio on mute shortly after and got some sleep… at 5AM they were still playing music, but with occasional cut-ins with various announcers mentioning what was coming after 6AM. When 6AM rolled around, I listened for a minute, then switched off for good.

The old website changed to being just a blank page.

Radio personality moves

Not sure where everyone has gone, but here’s what I do know:

  • Bob Gallagher, who some might know from 97.3’s breakfast program, and who chaired 4KQ’s last 4 morning on air… moved over to 4BH.
  • Vanessa Gibson (apologies if I have spelling wrong, I’ve never seen it written), who was one of the more promenant morning news readers at 4KQ has stayed with the 693kHz frequency on SEN-Q
  • 4KQ’s breakfast crew have moved to 4BC — an odd match if ever I saw one given that trio’s love for music and 4BC being a talk-back radio station

Station changes

4BH have switched formats to a “classic hits” format like the old 4KQ with a subset covering 1960 ~ 1989 (inclusive). I say subset because 4KQ in their final days were already playing Seal Crazy (released 1992), Natalie Imbruglia Torn (1997) and Savage Garden The Animal Song (released 1999).

Whether they’re playing any of Brisbane’s “historic” bands remains to be seen.

4BC’s program seems to suggest they’re still sticking with their “news talk” format. Maybe music in the mornings, then the gab-fest begins.

97.3 still don’t acknowledge the existence of anything prior to 1980.

River 94.9 is still a very weak signal into Brisbane — if you’re in the right spot you can get them but otherwise they’re practically inaudible. Odd, since they share the tower at The Knobby with VK4RAI, and I both hear that and can work that repeater quite reliably with far less power than what River 94.9 would be transmitting. Clearly they are still beaming west, and what we hear in Brisbane is just what’s coming off the back of the beam.

How things have changed for me

Well, from my perspective… that Friday morning was quite disorienting. You get used to the time-calls and regular news updates which give you an idea of how time had passed. I put my own music on that morning… and yes, was a minute or two late for my workplace morning stand-up because I wasn’t watching the clock!

A week on, and apparently I’ve broken one of my own music listening records according to Last.FM:

I had gone from listening to just 17 songs in total (most of those would have been the Friday afternoon), to over 1300. In the last 6 weeks of 4KQ I actually stopped listening to a lot of my music: I figured there was plenty of time for that once they went — I wouldn’t have 4KQ to listen to much longer, enjoy them whilst you’ve got them.

I also didn’t do any channel-hopping: previously if Abba came on (it’s a long story, but basically you didn’t want to be found listening to that group in a late 90s high-school), I’d switch stations or switch to my own music, sometimes for hours.

At mid-day I’d ordinarily flip over to Triple-M Classic Rock as they have a Essential Vinyl show which is often an interesting deep-dive into a particular iconic album from past decades, and is often interesting from the perspective of getting to know songs from an artist I might not otherwise know much about. Obscure entities like Buckingham Nicks (basically the precursor to the modern Fleetwood Mac) are in my shopping list thanks to that show. Just like a lot of my present collection can be tracked back to special features put on by 4KQ as well.

This last week… I didn’t do any of that. So where my music listening might’ve at most started at around 10:00AM or later… now basically I’ve been listening to my own music collection from 5:00AM through to to around 7:10PM. I have a cron job that manages it:

# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
0 5 * * * ( pulsemixer --unmute --id $( pulsemixer -l | grep -F qt-dab | awk '{ print $4 }' | sed 's/,//g' ) )>/tmp/unmute.log 2>&1
0 5 * * * pidof strawberry > /dev/null && env DISPLAY=:0.0 strawberry -p
0 5 * * * ( /usr/bin/amixer -c Generic -- sset Master -36dB )>/dev/null 2>&1
10 5 * * * ( /usr/bin/amixer -c Generic -- sset Master -33dB )>/dev/null 2>&1
20 5 * * * ( /usr/bin/amixer -c Generic -- sset Master -30dB )>/dev/null 2>&1
30 5 * * * ( /usr/bin/amixer -c Generic -- sset Master -27dB )>/dev/null 2>&1
40 5 * * * ( /usr/bin/amixer -c Generic -- sset Master -24dB )>/dev/null 2>&1
50 5 * * * ( /usr/bin/amixer -c Generic -- sset Master -21dB )>/dev/null 2>&1
0 6 * * * ( /usr/bin/amixer -c Generic -- sset Master -18dB )>/dev/null 2>&1
10 6 * * * ( /usr/bin/amixer -c Generic -- sset Master -15dB )>/dev/null 2>&1
0 18 * * * ( /usr/bin/amixer -c Generic -- sset Master -15dB )>/dev/null 2>&1
10 18 * * * ( /usr/bin/amixer -c Generic -- sset Master -18dB )>/dev/null 2>&1
20 18 * * * ( /usr/bin/amixer -c Generic -- sset Master -21dB )>/dev/null 2>&1
30 18 * * * ( /usr/bin/amixer -c Generic -- sset Master -24dB )>/dev/null 2>&1
40 18 * * * ( /usr/bin/amixer -c Generic -- sset Master -27dB )>/dev/null 2>&1
50 18 * * * ( /usr/bin/amixer -c Generic -- sset Master -30dB )>/dev/null 2>&1
0 19 * * * ( /usr/bin/amixer -c Generic -- sset Master -33dB )>/dev/null 2>&1
10 19 * * * pidof strawberry > /dev/null && env DISPLAY=:0.0 strawberry -q
10 19 * * * ( /usr/bin/amixer -c Generic -- sset Master -36dB )>/dev/null 2>&1
20 19 * * * ( /usr/bin/amixer -c Generic -- sset Master -192dB )>/dev/null 2>&1

The amixer calls were there before, and would control the volume. qt-dab would sit on the desktop and receive 24/7. Now, strawberry sits on the desktop, and I’m using its CLI to start and stop: strawberry -p to fire things off in the morning, then strawberry -q to finish playing that last song before going silent.

It’s got a lot to be desired… maybe if I get creative with a text-to-speech engine, I might get some time-calls and a bit of news headlines to replicate some of what I’ve lost, although it’ll be a very poor substitute to what I had on the old station. It might just be “good enough” though… it’ll give me a time reference.

My feelings on this

While I’ve been able to largely “replace” 4KQ on my own stereo… I’m still a bit peeved by the whole experience. There’s a lot of music that’s very hard to get / impossible to get, that they used to play. Railroad Gin’s You Told The World, Do Ya Love Me and The Academy Rock being three that used to play on 4KQ… but so far have proven unobtainium. Other bands like New World, Moscos and Stone, among others… are similarly buried somewhere in record company vaults, never to be seen again.

We’re just left to fight over what few second-hand albums exist in circulation… or pirate.

As to the mess that started this: so the ACMA have a rule that limits the number of radio stations a company can control. Fair enough, they want to promote diversity, and having all the eggs in one basket does not help this. I get where the ACMA is coming from.

Here, There & Everywhere own the Australian Radio Network, who until this year, owned 4KQ. They also own 97.3. Some bright-spark at HT&E saw dollars in buying up rival network Grant Broadcasting who owned various regional stations such as River 94.9 (Ipswich) and Hot Tomato (Gold Coast), and merging them into ARN. That meant ARN were now over the threshold.

That decision to chase the dollar, on the surface of it, seems to me to be nothing less than a complete slap in the face to the Brisbane radio listenership and the staff of 4KQ, the latter of whom had given their working lives to the station. 30 years for a single announcer to work a shift is an Australian record that 4KQ and Laurel Edwards broke. This is how HT&E pay her loyalty. I think that speaks volumes.

Plans now

Immediate plans

The morning crew I used to listen to are back on air on Monday, so perhaps I’ll set up the radio for 4BC, and see how they go.

I expect there’ll be quite a few gaffs from a trio that have been used to saying “4KQ” and “32230693” for decades (Laurel Edwards has been doing that on-air longer than anyone else). Mark Hine got so used to saying 4KQ he accidentally (as ground announcer) blurted “… on Classic Hits 4K-” to the audience at The Gabba… cutting himself off when he realised which workplace he was at.

It’ll be interesting to see how they work music into their news format. That’ll be a deciding factor as to whether I continue listening after the morning stand-up, or whether I switch to my own music until the next morning.

Radio station ideas / aspirations

So to be clear, I’m not going to rush into starting up something myself. While I do have some music knowledge, and that’s probably the subject about running a commercial music radio station I would rate as being strongest — my knowledge has gaps so large a sperm whale could swim through in comfort! If that’s the state of my knowledge in that field, this does not bode well for other critical-knowledge areas.

Really I’d need to team up with people who have some media experience. I have some technical knowledge, but there’s a big difference between a 100W SSB amateur radio station which is small enough to be bicycle-mounted, and a honking big 10kW broadcast MW AM station. I’d also need very deep pockets to commission said station.

Requirements for digital-rights management being imposed by the PPCA make Internet streaming impractical. That would basically just leave DAB+. There may be room there… seems channel 9B has a little more space than 9A does, but who knows? I’d have to ask, find out what their fees and technical requirements are. Then, I’d have to then figure out what the going rate was for advertising slots, and work out the finances from there.

I don’t know how the music needs to be obtained at this point. I’m guessing purchasing MP3s from legal sources (the same that we might as individuals) may be acceptable since they’re fundamentally the same recordings — and we’d have a separate content license that would cover their broadcast. This is a guess though, I might be wrong.

It’s a big job — and not one I’m particularly suited for. I’m happy to sit back and let someone who knows what they’re doing go ahead and do it.

The idea of such a station would be a very loose copy of 4KQ in so far as we’d be playing similar music. Not the same, because to be honest I actually do not know what songs were “hits” in this city. I have some recollections of what I’ve heard, but likely this is just the tip of the iceberg.

I did manage to grab some feature playlists (e.g. Sizzling 70s, Easter Count-down, all-sorts… etc) from 4KQ before the site went offline. Those, when de-duplicated, amount to about 3500 songs, about 70% I already had. I can’t publish these as they belong to the Australian Radio Network (I have contacted ARN about this but not heard anything — I’ll take that as a “no, do not publish”) … but nothing stops me picking through the listings and incorporating the artists mentioned into my library where see them. If I see collections that are readily available, I’ll make note of them here.

What would the format look like? Well, musically it’ll be a mix of the heavier rock that you’d hear on stations like Triple M, and the softer stuff of 4KQ. Not exclusively focused on Brisbane hits, as I don’t have a record of what was popular… I just have a “rough idea” of what artists were popular, and would likely work on that basis. That might change if someone who does have records of this came on-board and could basically guide me on this or take on the music-director role properly.

The first days would likely be ad-free as we try to build up an audience and attract advertisers. Those booking advertising slots would have to organise their own recordings since we wouldn’t have studios to help them with that. The station would be “automatic”: no announcers, news, weather… just music, and later we’d get ad breaks in to help pay the bills and start building up a revenue stream.

If revenue picked up enough, then maybe we could organise to hire studio time and do pre-recorded shows, or perhaps live ones if we can figure out how to link studio and transmitter.

Some ideas for shows that’d work pre-recorded:

  • Classic Artists Today: a look at artists we know from the 60s~90s that are still producing music and what they’re doing these days… for example Jeff Lynne is still doing music with Electric Light Orchestra, The Who and Manfred Mann’s Earth Band did a few new songs in the early part of this century, Fleetwood Mac are still active.
  • Sunday Spotlight: a deep dive into an artist’s work (e.g. a show about George Harrison would start with his role in The Beatles, but then cover solo work and his work in The Traveling Wilburys; Graham Gouldman might cover his early songwriting for The Hollies, The Ohio Express then his later work with 10cc, solo work, and his team-up with Andrew Gold in Wax; Brian Cadd could have enough material to fill several hours I think with Axiom, The Groop and solo work, along with producing for other artists).

This is better done by someone who knows what they’re doing, and I know right now, that is not me, certainly not as a solo act. I suspect this will be at least a year off, likely longer if it happens at all.

A lot will depend on demand. I have a day job that’s paying the bills, there’s no sense of rushing off from that into the great unknown, no matter how much I might feel like a career change after some 20+ years connection with (and subsequent frustration with) the IT industry in one form or another! Time will tell.

Building a broadcast station: initial due diligence

So, recently I started giving consideration to building a station… starting of course with how the station might broadcast to an audience. This is in no way a sign that I’ll actually go and do it: to survive I need about AU$30000/year (yeah, I have low overheads at present) and I doubt a dinky little radio station is going to make me that much money.

That said, this is an industry I know little about, so it’s hard to know what the finances would look like.

Content licensing

Irrespective of how the broadcast is done, a station like 4KQ will need a content license for the music broadcast. Not just music though, news updates and even the weather are potentially in the scope of content licenses.

These can be negotiated with individual holders in some cases. I know for small narrowcasting services you can obtain a license through OneMusic, however looking at their offerings they don’t seem to cater to broadcasting services. Turns out there is one that does: the Phonographic Performance Company of Australia.

What this would all cost is a complete unknown.

Radio Broadcasting

The above only lets you use content in a broadcast, it doesn’t let you actually transmit anything on any radio frequency. For this, two things are needed (in addition to the broadcasting equipment). Both come from the ACMA:

  • Broadcast station license: This doesn’t cover transmitters, this is merely the right to have a radio station servicing a given geographical area, irrespective of how it reaches that area.
  • Apparatus license from the ACMA.

I’m not sure whether this is true of DAB+, the transmitters themselves are operated by Digital Radio Broadcasting Pty Ltd, it could be that the stations “piggy-back” on their license the way the do on the actual transmitter itself.

If we did decide to commission a transmitter, that’ll get expensive fast. I don’t expect much change out of AU$1M, in fact, even that may not be sufficient! Then there’s running costs: a 10kW class-B transmitter PA stage will need at least 12-15kW on signal peaks and it will want it now! So likely, 3-phase power is needed, and with a beefy local energy store to smooth out those sharp peaks.

An AM transmitter will also occupy a decent-size land area. If you want an idea; have a look at the 4QR/4QG site or 4KQ’s site as examples. That size area does not come cheap.

Internet broadcasting

This looks to be, in the short-term, the cheaper option if we aim to start small first. We still need the content license, but potentially there are fewer unknowns in the costs. The interesting bit is the content license requirements, specifically I had a look at the forms needed to apply for such a license… this question stuck out:

“What security measures will be in place to prevent downloading or stream ripping?”

This is a tricky-one. In terms of technology my first choice would be something like icecast to manage the audio streams, but this is trivially ripped (possibly using nothing more exotic than wget).

DAB+ can be ripped trivially — qt-dab has both a “frame dump” and an “audio dump”; the former gives you the raw HE-AAC frames, the latter gives you decompressed PCM audio. The same tool can even rip the whole multiplex, recording every single station simultaneously (all 28 stations for the Brisbane DAB 1 multiplex).

Fundamentally, our ears do not hear digital signals, they only respond to analogue pressure waves (travelling through a gas or liquid). To listen to a “digital” station, it must first be converted from whatever on-air format it’s in to a plain uncompressed audio stream, passed through a digital-to-analogue converter, then amplified to electrically drive a speaker transducer which converts the electrical signal into the sound-pressure waves that our ears respond to.

Those sound pressure waves are not protected from being converted back to an electrical signal, having that electrical signal sampled through a analogue-to-digital converter and captured by a storage device.

Years ago, yes, I had some pirated music, and this included a copy of Cold Chisel’s Khe Sanh (I now have a legally purchased CD of that song, and the MP3 no longer exists on my equipment), in which you could hear someone gently placing a microphone in front of a speaker and nudging it forward. That method works whether the source material is a Victorian-era wax-cylinder phonograph recording or a Blu-ray disc. It would also work for any streaming service you care to mention.

Indeed, most of the listening devices feature headphone sockets or Bluetooth interfaces — it is entirely possible to sample the analogue or digital electrical signal without the acoustic conversion. Most computer sound devices feature a “monitor” port you can record from, and there’s nothing stopping you plugging in a device that advertises itself to two hosts as a USB Audio class device, piping audio from one to the other.

Yes, there’s signal degradation doing that, but this does not matter in a piracy law suit: it could be downmixed to mono and downsampled to a 2kHz sample rate with a 4-bit resolution, and still be a copyright violation.

So I wonder what “counts” as a security measure. No doubt this was a request put in by the record companies who seem to forget the above limitation. Maybe services like Listener and iHeartRadio have some tricks up their sleeve… who knows? Firefox seems to see iHeartRadio like any other website, and of course, to pipewire, Firefox is just like any other pulseaudio client, so stream ripping is very doable.

Also interesting was the question of: “How will access by countries other than Australia be restricted?” We seem to live in a world where VPNs don’t exist or are 100% detectable by the hosts. If I can stand up a VPN server, and “dial” into it from my tablet from any sufficiently-open Internet connection on the planet: practically anyone can. In doing so, it would look like I’m streaming from my home Internet connection, not from the real connection.

Funding the costs

So, for a station to “stand on its own feet”, it would need to find a revenue stream that pays for the above. The way most do it is through advertising, and there are groups like Commercial Radio Australia that cater to that. No idea what they pay broadcasters, but I’d imagine it’s a function of service area, number of listeners and the listener demographics.

This is hard to know in advance. The station I’m looking at as a model targeted the 40+ market (noting that I myself am not in that age bracket). Some of this group will be less technically inclined to do Internet streaming unless there’s some sort of dedicated streaming client available through their device’s software repositories. Integration into smart speaker voice assistants is a desirable feature to some this group, but many I’ll bet are listening the same way they’ve done for decades: traditional radio broadcast.

I think a “new” Internet-only station is going to struggle justifying the same fee for an advertising slot as an established 75-year old broadcast station.

Asking for donations might be another avenue, but having done work for a few charities in my time, this is definitely not an easy way to raise funds. Staff would essentially be volunteers: this would be at best a side-hustle for me and anyone else that joins me in this venture.

Subscription services for Internet broadcasting could work, but then you’re competing against the likes of Spotify, Deezer, Bandcamp, et all… that’s tough going! They don’t make much, and pass even less on as royalties. Plus, the listeners will likely demand more than just an advertising-free experience, they’ll probably want music-on-demand, which is a whole different class of content-license, and would have to be factored into the subscription fees.

Time will tell on the above, but that at least gives some thought as to what I’d be up for if I decided to take this thought-exercise further.

Demise of a Brisbane Icon: 4KQ to become “sports” station from 1st July

So, this is quite sad news… I learned this on Friday morning that one of Brisbane’s longer-serving radio stations will be taken over by new management and will change its format from being a “classic hits” music station, to being a 24/7 sports coverage station.

It had been operated by the Australian Radio Network who had recently done a merger with a rival network, Grant Broadcasters, picking up their portfolio which included their portfolio of stations which included a number of other Greater Brisbane region stations. This tipped them over the edge and so they had to let one go, the unlucky victim was their oldest: 4KQ.

Now, you’re thinking, big deal, there are lots of radio stations out there, including Internet radio. Here’s why this matters. Back in the 90s, pretty much all of the stations here in Brisbane were locally run. They might’ve been part of a wider network, but generally, the programming about shows and music was decided on by people in this area. Lots of songs were hits only in Brisbane. There are some songs that did not make the music charts anywhere else world-wide. But, here in Brisbane, we requested those songs.

Sometimes the artists knew about this, sometimes not.

Over time, other stations have adjusted their format, and in many cases, abandoned local programming, doing everything from Sydney and Melbourne. Southern Cross Austereo tried this with Triple M years ago, and in the end they had to reverse the decision as their ratings tanked and complaints inundated the station.

4KQ represented one of the last stations to keep local programming. I’m not sure how many still do, but in particular this station was unique amongst the offerings in this area due to its wide coverage of popular music spanning 1960 ~ 1995, and in particular, its focus on the Brisbane top-40 charts.

Some of the radio programs too were great: Brent James in particular had an art for painting a picture of Brisbane at that time for both people who were there to experience it, those who missed out because they lived someplace else, and people like myself who were either too young to remember or not alive at the time in the first place. A lot of their other staff too, had a lot of music knowledge and trivia — yes you can reproduce the play lists with one’s own music collection, but the stories behind the hits are harder to replicate. Laurel Edwards is due to celebrate her 30th year with the station — that’s a long commitment, and it’s sad to think that this will be her last through no fault or decision of her own.

It’s loss as a music station is a major blow to the history of this city. To paraphrase Joni Mitchell, they’ve torn down Festival Hall to put up an apartment block!

A new normal

The question is, where to now? The real sad bit is that this was a successful station that was only culled because of a regulatory compliance issue: ARN now had too many stations in the Greater Brisbane area, and had to let one go. They reluctantly put it up for sale, and sure enough, a buyer took it, but that buyer was not interested in preserving anything other than the frequency, license and broadcast equipment.

In some ways, AM is a better fit for the yap-fest that is SEN-Q. They presently broadcast on DAB+ at 24kbps in essentially AM-radio quality. 4KQ has always been a MW station, originally transmitting at 650kHz back in 1947, moving to 690kHz a year later… then getting shuffled up 3kHz to its present-day 693kHz in 1978 when the authorities (in their wisdom at the time) decided to “make room” by moving all stations to a 9kHz spacing.

Music has never been a particularly good fit for AM radio, but back in 1947 that was the only viable option. FM did exist thanks to the work of Edwin Armstrong, but his patents were still active back then and the more complicated system was less favourable to radio manufacturers at a time when few could afford a radio (or the receiver license to operate it). So AM it was for most broadcasters of that time. “FM radio” as we know it today, wouldn’t come into existence in Brisbane until around 1980, by which time 4KQ was well-and-truly established.

The question remains though… ratings were pretty good, clearly there is demand for such a station. They had a winning formula. Could an independent station carry forward their legacy?

The options

So, in July we’ll have to get used to a new status-quo. It’s not known how long this will last. I am not advocating vigilante action against the new owners. The question will be, is there enough support for a phoenix to rise out of the ashes, and if so, how?

Existing station adopting 4KQ’s old format?

This might happen. Not sure who would be willing to throw out what they have now to try this out but this may be an option. There are a few stations that might be “close enough” to absorb such a change:

  • 4BH (1116kHz AM) does specialise in the “older” music, but it tends to be the softer “easy listening” stuff, they don’t do the heavier stuff that 4KQ and others do. (e.g. you won’t hear AC/DC)
  • KIIS 97.3 (97.3MHz FM) was 4KQ’s sister station, at present they only do music from the 80s onwards.
  • Triple M (104.5MHz FM) would be their closest competitor. They still do some 60s-80s stuff, but they’re more focused on today’s music. There’s a sister-station, Triple M Classic Rock (202.928MHz DAB+) but they are an interstate station, with no regional focus.
  • Outside of Brisbane, River 94.9 (94.9MHz FM) in Ipswich would be the closest to 4KQ. They make frequent mentions of 4IP and its charts. Alas, they are likely beaming west as they are not receivable in this part of Brisbane at least. (VK4RAI on the other hand, located on the same tower can be received, and worked from here… so maybe it’s just a case of more transmit power and a new antenna to service Brisbane?)

I did a tune-around the other day and didn’t hear anything other than those which was in any way comparable.

Interesting aside, 4IP of course was the hit station of its day. These days, if you look up that call-sign, you get directed to RadioTAB… another sports radio station network. Ironic that its rival meets the same fate at the hands of a rival sports radio network.

A new station?

Could enough of us band together and start afresh? Well, this will be tough. It’d be a nice thing if we could, and maybe provide work for those who started the year thinking their job was mostly secure only to find they’ve got two more months left… but the tricky bit is we’re starting from scratch.

FM station?

A new FM station might be ideal in terms of suiting the format, and I did look into this. Alas, not going to happen unless there’s a sacrifice of some sort. I did a search on the ACMA license database; putting in Mt. Coot-tha as the location (likely position of hypothetical transmitter, I think I chose Ch 9 site, but any on that hill will do), giving a radius of 200km and a frequency range of 87-109MHz.

Broadcast FM radio stations are typically spaced out every 800kHz; so 87.7MHz, 88.5MHz, 89.3MHz, … etc. Every such frequency was either directly taken, or had a station within 400kHz of it. Even if the frequency “sounded” clear, it likely was being used by a station I could not receive. A big number of them are operated by churches and community centres, likely low-power narrowcast stations.

The FM broadcast band, as seen from a roof-top 2m “flower pot” in The Gap.

There’s only two ways a new station can spring up on FM in the Brisbane area:

  • an existing station closes down, relinquishing the frequency
  • all the existing stations reduce their deviation, allowing for new stations to be inserted in between the existing ones

The first is not likely to happen. Let’s consider the latter option though. FM bandwidth is decided by the deviation. That is, the modulating signal, as it swings from its minimum trough to its maximum peak, causes the carrier of the transmitter to deviate above or below its nominal frequency in proportion to the input signal amplitude. Sometimes the deviation is almost identical to the bandwidth of the modulating signal (narrowband FM) or sometimes it’s much greater (wideband FM).

UHF CB radios for example; deviate either 2.5kHz or 5kHz, depending on whether the radio is a newer “80-channel” device or an older “40-channel” device. This is narrowband FM. When the ACMA decided to “make room” on UHF CB, they did so by “grandfathering” the old 40-channel class license, and decreeing that new “80-channel” sets are to use a 2.5kHz deviation instead of 5kHz. This reduced the “size” of each channel by half. In between each 40-channel frequency, they inserted a new 80-channel frequency.

This is simple enough with a narrowband FM signal like UHF CB. There’s no sub-carriers to worry about, and it’s not high-fidelity, just plain old analogue voice.

Analogue television used FM for its audio, and in later years, did so in stereo. I’m not sure what the deviation is for broadcast FM radio or television, but I do know that the deviation used for television audio is narrower than that used for FM radio. So evidently, FM stereo stations could possibly have their deviation reduced, and still transmit a stereo signal. I’m not sure what the trade-off of that would be though. TV stations didn’t have to worry about mobile receivers, and most viewers were using dedicated, directional antennas which better handled multi-path propagation (which would otherwise cause ghosting).

Also, TV stations to my knowledge, while they did transmit sub-carriers for FM stereo, they didn’t transmit RDS like FM radio stations do. Reducing the deviation may have implications on signal robustness for mobile users and for over-the-air services like RDS. I don’t know.

That said, lets suppose it could be done, and say Triple M (104.5MHz) and B105 (105.3MHz) decided to drop their deviation by half: we could then maybe squeeze a new station in at 104.1MHz. The apparent “volume” of the other two stations would drop by maybe 3dB, so people will need to turn their volume knobs up higher, but might work.

I do not know however if this is technically possible though. In short, I think we can consider a new FM station a pipe dream that is unlikely to happen.

New AM station?

A new AM station might be more doable. A cursory look at the same database, putting in much the same parameters but this time, a 300km radius and a frequency range of 500kHz-1.7MHz, seems to suggest there are lots of seemingly “unallocated” 9kHz slots. I don’t know what the frequency allocation strategy is for AM stations within a geographic area. I went a wider radius because MW stations do propagate quite far at night: I can pick up 4BU in Bundaberg and ABC Radio Emerald from my home.

The tricky bit is physically setting up the transmitter. MW transmitters are big, and use lots of power. 4KQ for example transmitted 10kW during daylight hours. Given it’s a linear PA in that transmitter, that means it’s consuming 20kW, and when it hits a “peak” it will want that power now!

The antennas are necessarily large; 693kHz has a wavelength of 432m, so a ¼-wave groundplane is going to be in the order of 100m tall. You can compromise that a bit with some clever engineering (e.g. see 4QR’s transmitter site off the Bruce Highway at Bald Hills — guess what the capacitance hat on the top is for!) but nothing will shrink that antenna into something that will fit a suburban back yard.

You will need a big open area to erect the antenna, and that antenna will need an extensive groundplane installed in the ground. The stay-wires holding the mast up will also need a big clearance from the fence as they will be live! Then you’ve got to keep the transmitter fed with the power it demands.

Finding a place is going to be a challenge. It doesn’t have to be elevated for MW like it does for VHF services (FM broadcast, DAB+), but the sheer size of the area needed will make purchasing the land expensive.

And you’ve got to consider your potential neighbours too, some of whom may have valid concerns about the transmitter: not liking the appearance of a big tower “in their back yard”, concerns about interference, concerns about “health effects”… etc.

DAB+?

This could be more doable. I don’t know what costs would be, and the big downside is that DAB+ radios are more expensive, as well as the DAB+ signal being more fragile (particularly when mobile). Audio quality would be much better than AM, but not quite as good as FM (in my opinion).

It’d basically be a case of opening an account with Digital Radio Broadcasting Pty Ltd, who operate the Channel 9A (202.928MHz) and Channel 9B (204.64MHz) transmitters. Then presumably, we’d have to encode our audio stream as HE-AAC and stream it to them somehow, possibly over the Internet.

The prevalence of “pop-up” stations seems to suggest this method may be comparatively cost-effective for larger audiences compared to commissioning and running our own dedicated transmitter, since the price does not change whether we have 10 listeners or 10000: it’s one stream going to the transmitter, then from there, the same signal is radiated out to all.

Internet streaming?

Well, this really isn’t radio, it’s an audio stream on a website at this point. The listener will need an Internet connection of their own, and you, the station operator, will be paying for each listener that connects. The listener also pays too: their ISP will bill them for data usage.

A 64kbps audio stream will consume around 230MB every 8 hours. If you stream it during your typical 8-hour work day, think a CD landing on your desk every 3 days. That’s the data you’re consuming. That data needs to be paid for, because each listener will have their own stream. If there’s only a dozen or so listeners, Internet radio wins … but if things get big (and 4KQ’s listenership was big), it’ll get expensive fast.

The other downside is that some listeners may not have an Internet connection, or the technical know-how to stream a radio station. I for example, do not have Internet access when riding the bicycle, so Internet radio is a no-go in that situation. I also refuse to stream Internet radio at work as I do not believe I should be using a workplace Internet connection for personal entertainment.

Staff?

The elephant in the room is staffing… there’s a workforce that kept 4KQ going who would soon be out of work, would they still be around if such a station were to materialise in the near future? I don’t know. Some of the announcers may want a new position in the field, others may be willing to go back to other vocations, and some are of an age that they may decide hanging up the headphones sounds tempting.

I guess that will be a decision for each person involved. For the listeners though, we’ve come to know these people, and will miss not hearing from them if they do wind up not returning to the air.

In the meantime

What am I doing now? Well, not saving up for a broadcast radio license (as much as my 5-year-old self would be disgusted at me passing up such an opportunity). I am expanding my music collection… and I guess over the next two months, I’ll be taking special note of songs I listen to that aren’t in my collection so I can chase down copies: ideally CDs or FLAC recordings (legally purchased of course!)… or LPs if CDs are too difficult.

Record companies and artists could help here — there are services like ZDigital that allow people to purchase and download individual songs or full albums in FLAC format. There are also lots of albums that were released decades ago, that have not been re-released by record companies. Sometimes record companies don’t release particular songs because they seemingly “weren’t popular”, or were popular in only a few specific geographic areas (like Brisbane).

People like us do not want to pirate music. We want to support the artists. Their songs did get played on radio, and still do; but may not be for much longer. Not everything is on Spotify, and sometimes that big yellow taxi has a habit of taking those hits away that you previously purchased. They could help themselves, and the artists they represent, by releasing some of these “less popular” songs as FLAC recordings for people to purchase. (Or MP3 if they really insist… but some of us prefer FLAC for archival copies.)

The songs have been produced, the recordings already exist, it seems it’s little skin of their nose to just release them as digital-only singles on these purchase-for-download platforms. I can understand not wanting to spend money pressing discs and having to market and ship them, but a file? Some emails, a few signed agreements and one file transfer and it’s done. Not complicated or expensive.

Please, help us help you.

Anyway… I guess I have a shopping list to compile.

Experimentation with cycle clothing: 8 years later

Well, some might recall a few years ago I was trying ideas for cycle clothing, and later followed up with some findings.

My situation has changed a bit… the death of a former work colleague shook me up quite a bit, and while I have been riding, I haven’t been doing it nearly as much. Then, COVID-19 reared its ugly head.

Suffice to say, my commute is now one side of the bedroom to the other. Right at this moment, I’m in self-imposed lockdown until I can get my booster shot: I had my second AstraZenica shot on the 4th November, and the Queensland Government has moved the booster shots to being 3 months after the second shot, so for me, that means I’m due on the 4th February. I’m already booked in with a local chemist here in The Gap, I did that weeks ago so that the appointment would be nailed to the floor, and thus currently I’m doing everything in my power to ensure that appointment goes ahead on-time.

I haven’t been on the bike much at all. That doesn’t mean though that I stop thinking about how I can make my ride more comfortable.

Castle Clothing Coveralls

Yes, I’m the one clad in yellow far left.

They had quite few positives:

  • They were great in wet weather
  • They were great in ambient temperatures below 20°C
  • The pocket was handy for storing keys/a phone/a wallet
  • They had good visibility day and night
  • They keep the wind out well. (On the Main Range, Threadbo Top Station was reporting 87km/hr wind gusts that day.)

But, they weren’t without their issues:

  • They’re (unsurprisingly) no good on a sunny summer’s day (on the day that photo was taken, it was borderline too hot, weather prediction was for showers and those didn’t happen)
  • They’re knackered after about 30 washes or so: the outer waterproof layer peels off the lining
  • In intermittent rain / sunshine, they’d keep you dry during the rainy bit, but when the sun came out, you’d get steamed

To cap it off, they’re no longer being manufactured. Castle Clothing have basically canned them. They’ve got a plain yellow version with no stripes, but otherwise, nothing like their old product. I wound up buying 4 of them in the end… the first two had to be chucked because of the aforementioned peeling problem, the other two are in good condition now, but eventually they’ll need replacement.

Mammoth Workwear do have some alternatives. The “Supertouch” ones I have tried, they’re even shorter lived than the Castle ones, and feel like wearing a plastic bag. The others are either not night-time visible, or they’re lined for winter use.

So, back to research again.

Zentai suits?

Now, I know I’ve said previously I’m no MAMIL… and for the most part I stand by this. I did try wearing a stinger suit on the bike once… on the plus side they are very breathable, so quite comfortable to ride in. BUT, three negatives with stinger suits:

That got me thinking, what’s the difference between a stinger suit and an open-face zentai suit? Not a lot. The zentai suit, if it has gloves, can be bought as a “mitten” or (more commonly) a proper multi-finger glove version. They come in a lot more colours than a stinger suit does. They’re about the same price. And there’s no logos, just plain colours (or you can do various patterns/designs if that’s your thing).

A downside is that the zipper is at the back, which means answering calls from nature is more difficult. But then again, some stinger suits and most wetsuits also feature a back-entry.

I’ve got two coming to try the idea out. I suspect they’ll get worn over other clothing, I’ll just duck into a loo, take my shirt off, put the zentai suit on, then jump on the bike to ride to my destination… that way my shirt isn’t soaked with sweat. We’ll see.

One is a black one, which was primarily bought to replace one of the stinger suits for swimming activities, but I can also evaluate the fabric too (it is the usual lycra material).

The other is a silver one (thus a lycra/latex blend), to try out the visibility — it’ll be interesting to see whether it’s somewhat water-repellent due to the latex mix in the material, and see what effect this has on sweat.

Both of these are open-face! You should never try swimming with a full-face zentai suit. I can’t imagine getting caught in the rain ending well either, and the ability to see where you’re going is paramount when operating any vehicle (especially a bicycle)!

They’ll turn up in a week or two, I can try them out then. Maybe won’t be the final solution, but it may answer a few questions.

Heavy Wet/Cold weather gear

So, with the lighter-weight class out of the way, that turns my attention to what to do in truly foul weather, or just bitterly cold weather.

Now, let me define the latter: low single digits °C. Possibly with a westerly breeze carrying it. For some reading this, this will feel like a hot summer’s day, but for those of us in Brisbane, temperatures this low are what we see in the middle of winter.

The waterproof overalls I was wearing before worked well in dry-but-cold weather, however I did note my hands copped the cold… I needed gloves. The ends of the legs also could get tangled with the chain if I wasn’t careful, and my shoes would still get wet. Riggers boots work okay for this, but they’re hard to come by.

I happened to stumble on Sujuvat ratkaisut Oy, who do specialist wet-weather clothing meant for Europe. Meeko (who runs the site) has a commercial relationship with a few manufacturers, notably AJGroup who supply the material for a lot of Meeko’s “extreme” range.

The suits are a variant of PVC, which will mean they’re less breathable than what I have now, but should also mean they’re a lot more durable. There’s a decent range of colours available, with many options having the possibility of reflective bands, attached gloves and attached wellington boots. It’s worth noting the BikeSuit (no longer available) I was looking at 8 years ago was also a PVC outfit.

In the winter time, the big problem is not so much sweat, but rather, sweat being hit by wind-chill. Thus I’m ordering one of the Extreme Drainage Coveralls to try them out.

I’ve seen something similar out of AliExpress, however the options there are often built for the Chinese market… so rarely feature size options that fit someone like myself. Most of the Chinese ones are dark colours, with one “tan”-coloured option listed, and a couple of rubber ones that were lighter colours (a dark “pink”, and a yellow). Some of the rubber ones also had a strange opening arrangement: a tube opening in the stomach, which you pulled yourself through, then clamped shut with a peg. Innovative, but looks very untidy and just begging to get caught in something! I’ll stick with something a bit more conventional.

The coverall I’m ordering will be a 500g/m² white fabric… so about twice the weight of my current Castle workwear overalls (which are about 330g/m²), and will have the gloves and boots attached. I’m curious to see how that’s done up close, and see how it works out in my use case.

Being a white rather than a yellow/orange will make them less visible in the day time, but I suspect this won’t be much of an issue as it’s night-time visibility I’m particularly after. Also, being white instead of a “strong” fluro colour will likely be better at horse endurance rides, as horses tend to react to fluro colours.

The zip arrangement intrigues me as well… it’s been placed up high so that you can pretty much wade into water up to your chest and not get wet. There’s a lighter-weight option of the same suit, however with fewer options for colours. If the extreme version doesn’t work out for cycling, I might look at this alternative (the bike doesn’t react to strong colours like a horse does).

There’s about a 2-month lead-time on this gear because it’s made-to-order, a reasonable trade-off given you get to more-or-less get it made exactly how you want it. Looking around, I’m seeing off-the-shelf not-customisable outfits at AU$400 a pop, €160 (~AU$252) is looking a good option.

The fact that this is being run as a small side-hustle is commendable. I look forward to seeing the product.

Demise of classic hardware

So, this year I had a new-year’s resolution of sorts… when we first started this “work from home” journey due to China’s “gift”, I just temporarily set up on the dinner table, which was of course, meant to be another few months.

Well, nearly 2 years later, we’re still working from home, and work has expanded to the point that a move to the office, on any permanent basis, is pretty much impossible now unless the business moves to a bigger building. With this in mind, I decided I’d clear off the dinner table, and clean up my room sufficiently to set up my workstation in there.

That meant re-arranging some things, but for the most part, I had the space already. So some stuff I wasn’t using got thrown into boxes to be moved into the garage. My CD collection similarly got moved into the garage (I have it on the computer, but need to retain the physical discs as they represent my “personal use license”), and lo and behold, I could set up my workstation.

The new workspace

One of my colleagues spotted the Indy and commented about the old classic SGI logo. Some might notice there’s also an O2 lurking in the shadows. Those who have known me for a while, will remember I did help maintain a Linux distribution for these classic machines, among others, and had a reasonable collection of my own:

My Indy, O2 and Indigo2 R10000
The Octane, booting up

These machines were all eBay purchases, as is the Sun monitor pictured (it came with the Octane). Sadly, fast forward a number of years, and these machines are mostly door stops and paperweights now.

The Octane’s and Indigo2’s demises

The Octane died when I tried to clean it out with a vacuum cleaner, without realising the effect of static electricity generated by the vacuum cleaner itself. I might add mine was a particularly old unit: it had a 175MHz R10000 CPU, and I remember the Linux kernel didn’t recognise the power management circuitry in the PSU without me manually patching it.

The Indigo2 mysteriously stopped working without any clear reason why, I’ve never actually tried to diagnose the issue.

That left the Indy and the O2 as working machines. I haven’t fired them up in a long time until today. I figured, what the hell, do they still run?

Trying the Indy and O2 out

Plug in the Indy, hit the power button… nothing. Dead as a doornail. Okay, put it aside… what about the O2?

I plug it in, shuffle it closer to the monitor so I can connect it. ‘Lo and behold:

The O2 lives!

Of course, the machine was set up to use a serial console as its primary interface, and boot-up was running very slow.

Booting up… very slowly…

It sat there like that for a while, figuring the action was happening on a serial port, I went to go get my null modem cable, only to find a log-in prompt by the time I got back.

Next was remembering what password I was using when I last ran this machine. We had the OpenSSL heartbleed vulnerability happen since then, and at about that time, I revoked all OpenPGP keys and changed all passwords, so it isn’t what I use today. I couldn’t get in as root, but my regular user account worked, and I was able to change the root password via sudo.

Remembering my old log-in credentials, from 22 years ago it seems

The machine soon crashed after that. I tried rebooting, this time I tweaked some PROM settings (and yes, I was rusty remembering how to do it) to be able to see what was going. (I had the null modem cable in hand, but didn’t feel like trying to blindly find the serial port at the back of my desktop.)

Changing PROM settings
The subsequent boot, and crash

Evidently, I had a dud disk. This did not surprise me in the slightest. I also noticed the PSU fan was not spinning, possibly seized after years of non-use.

Okay, there were two disks installed in this machine, both 80-pin SCA SCSI drives. Which one was it? I took a punt and tried the one furtherest away from the I/O ports.

Success, she boots now

I managed to reset the root password, before the machine powered itself off (possibly because of overheating). I suspect the machine will need the dust blown out of it (safely! — not using the method that killed the Octane!), and the HDDs will need replacements. The guilty culprit was this one (which I guessed correctly first go):

a 4GB HDD was a big drive back in 1998!

The computer I’m typing this on has a HDD that stores 1000 of these drives. Today, there are modern alternatives, such as SCSI2SD that could get this machine running fully if needed. The tricky bit would be handling the 80-pin hot-swap interface. There’d be some hardware hacking needed to connect the two, but AU$145 plus an adaptor seems like a safer bet than trying some random used HDD.

So, replacement for the HDDs, a clean-out, and possibly a new fan or two, and that machine will be back to “working” state. Of course the Linux landscape has moved on since then, Debian no longer support the MIPS4 ISA that the RM5200 CPU understands, Gentoo still could work on this though, and maybe OpenBSD still support this too. In short, this machine is enough of a “go-er” that it should not be sent to land-fill… yet.

Turning my attention back to the Indy

So the Indy was my first SGI machine. Bought to better understand the MIPS processor architecture, and perhaps gain enough understanding to try and breathe life into a Cobalt Qube II server appliance (remember those?), it did teach me a lot about Linux and how things vary between platforms.

I figured I might as well pop the cover and see if there’s anything “obviously” wrong. The procedure I was rusty on, but I recalled there was a little catch on the back of the case that needed to be release before the cover slid off. So I lugged the 20″ CRT off the top of the machine, pulled the non-functioning Indy out, and put it on the table to inspect further.

Upon trying to pop the cover (gently!), the top of the case just exploded. Two pieces of the top cover go flying, and the RF shield parts company with the cover’s underside.

The RF shield parted company with the underside of the lid

I was left with a handful of small plastic fragments that were the heat-set posts holding the RF shield to the inside of the lid.

Some of the fragments that once held the RF shield in place

Clearly, the plastic has become brittle over the years. These machines were released in 1993, I think this might be a 1994-model as it has a slightly upgraded R4600 CPU in it.

As to the machine itself, I had a quick sticky-beak, there didn’t seem to be any immediately obvious things, but to be honest, I didn’t do a very thorough check. Maybe there’s some corrosion under the motherboard I didn’t spot, maybe it’s just a blown fuse in the PSU, who knows?

The inside of the Indy

This particular machine had 256MB RAM (a lot for its day), 8-bit Newport XL graphics, the “Indy Presenter” LCD interface (somewhere, we have the 15″ monitor it came with — sadly the connecting cable has some damaged conductors), and the HDD is a 9.1GB HDD I added some time back.

Where to now?

I was hanging on to these machines with the thinking that someone who was interested in experimenting with RISC machines might want them — find them a new home rather than sending them to landfill. I guess that’s still an option for the O2, as it still boots: so long as its remaining HDD doesn’t die it’ll be fine.

For the others, there’s the possibility of combining bits to make a functional frankenmachine from lots of parts. The Indy will need a new PROM battery if someone does manage to breathe life into it.

The Octane had two SCSI interfaces, one of which was dead — a problem that was known-of before I even acquired it. The PROM would bitch and moan about the dead SCSI interface for a good two minutes before giving up and dumping you in the boot menu. Press 1, and it’d hand over to arcload, which would boot a Linux kernel from a disk on the working controller. Linux would see the dead SCSI controller, and proceed to ignore it, booting just fine as if nothing had happened.

The Indigo2 R10000 was always the red-hedded step child: an artefact of the machine’s design. The IP22 design (Indy and Indigo2) was never designed with the intent of being used with a R10000 CPU, and the speculative execution features played havoc with caching on this design. The Octane worked fine because it was designed from the outset to run this CPU. The O2 could be made to work because of a quirk of its hardware design, but the Indigo2 was not so flexible, so kernel-space code had to hack around the problem in software.

I guess I’d still like to see the machines go to a good home, but no idea who that’d be in this day and age. Somewhere, I have a partial disc set of Irix 6.5, and there’s also a 20″ SGI GDM5410 monitor (not the Sun monitor pictured above) that, at last check, did still work.

It’ll be a sad day when these go to the tip.

6LoWHAM: TCP over sensor networks

I stumbled across this article regarding the use of TCP over sensor networks. Now, TCP has been done with AX.25 before, and generally suffers greatly from packet collisions. Apparently (I haven’t read more than the first few paragraphs of this article), implementations TCP can be tuned to improve performance in such networks, which may mean TCP can be made more practical on packet radio networks.

Prior to seeing this, I had thought 6LoWHAM would “tunnel” TCP over a conventional AX.25 connection using I-frames and S-frames to carry TCP segments with some header prepended so that multiple TCP connections between two peers can share the same AX.25 connection.

I’ve printed it out, and made a note of it here… when I get a moment I may give this a closer look. Ultimately I still think multicast communications is the way forward here: radio inherently favours one-to-many communications due to it being a shared medium, but there are definitely situations in which being able to do one-to-one communications applies; and for those, TCP isn’t a bad solution.

Comments having read the article

So, I had a read through it. The take-aways seem to be this:

  • TCP was historically seen as “too heavy” because the MCUs of the day (circa 2002) lacked the RAM needed for TCP data structures. More modern MCUs have orders of magnitude more RAM (32KiB vs 512B) today, and so this is less of an issue.
    • For 6LoWHAM, intended for single-board computers running Linux, this will not be an issue.
  • A lot of early experiments with TCP over sensor networks tried to set a conservative MSS based on the actual link MTU, leading to TCP headers dominating the lower-level frame. Leaning on 6LoWPAN’s ability to fragment IP datagrams lead to much improved performance.
    • 6LoWHAM uses AX.25 which can support 256-byte frames; vs 128-byte 802.15.4 frames on 6LoWPAN. Maybe gains can be made this way, but we’re already a bit ahead on this.
  • Much of the document considered battery-powered nodes, in which the radio transceiver was powered down completely for periods of time to save power, and the effects this had on TCP communications. Optimisations were able to be made that reduced the impact of such power-down events.
    • 6LoWHAM will likely be using conventional VHF/UHF transceivers. Hand-helds often implement a “battery saver” mode — often this is configured inside the device with no external control possible (thus it will not be possible for us to control, or even detect, when the receiver is powered down). Mobile sets often do not implement this, and you do not want to frequently power-cycle a modern mobile transceiver at the sorts of rates that 802.15.4 radios get power-cycled!
  • Performance in ideal conditions favoured TCP, with the article authors managing to achieve 30% of the raw link bandwidth (75kbps of a theoretical 250kbps maximum), with the underlying hardware being fingered as a possible cause for performance issues.
    • Assuming we could manage the same percentage; that would equate to ~360bps on 1200-baud networks, or 2.88kbps on 9600-baud networks.
  • With up to 15% packet loss, TCP and CoAP (its nearest contender) can perform about the same in terms of reliability.
  • A significant factor in effective data rate is CSMA/CA. aioax25 effectively does CSMA/CA too.

Its interesting to note they didn’t try to do anything special with the TCP headers (e.g. Van Jacobson compression). I’ll have to have a look at TCP and see just how much overhead there is in a typical segment, and whether the roughly double MTU of AX.25 will help or not: the article recommends using MSS of approximately 3× the link MTU for “fair” conditions (so ~384 bytes), and 5× in “good” conditions (~640 bytes).

It’s worth noting a 256-byte AX.25 frame takes ~2 seconds to transmit on a 1200-baud link. You really don’t want to make that a habit! So smaller transmissions using UDP-based protocols may still be worthwhile in our application.

6LoWHAM: Thoughts on how to distribute context and applications

So, one evening I was having difficulty sleeping, so like some people count sheep, turned to a different problem…6LoWPAN relies on all nodes sharing a common “context”. This is used as a short-hand to “compress” the rather lengthy IPv6 addresses for allowing two nodes to communicate with one another by substituting particular IPv6 address subnets with a “context number” which can be represented in 4 bits.

Fundamentally, this identifier is a stand-in for the subnet address. This was a sticking-point with earlier thoughts on 6LoWHAM: how do we agree on what the context should be? My thought was, each network should be assigned a 3-bit network ID. Why 3-bit? Well, this means we can reserve some context IDs for other uses. We use SCI/DCI values 0-7 and leave 8-15 reserved; I’ll think of a use for the other half of the contexts.

The node “group” also share a SSID; the “group” SSID. This is a SSID that receives all multicast traffic for the nodes on the immediate network. This might be just a generic MCAST-n SSID, where n is the network ID; or it could be a call-sign for a local network coordinator, e.g. I might decide my network will use VK4MSL-0 for my group SSID (network 0). Probably nodes that are listening on a custom SSID should still listen for MCAST-n traffic, in case a node is attempting to join without knowing the group SSID.

AX.25 allows for 16 SSIDs per call-sign, so what about the other 8? Well, if we have a convention that we reserve SSIDs 0-7 for groups; that leaves 8-15 for stations. This can be adjusted for local requirements where needed, and would not be enforced by the protocol.

Joining a network

How does a new joining node “discover” this network? Firstly, the first node in an area is responsible for “forming” the network — a node which “forms” a network must be manually programmed with the local subnet, group SSID and other details. Ensuring all nodes with “formation” capability for a given network is beyond the scope of 6LoWHAM.

When a node joins; at first it only knows how to talk to immediate nodes. It can use MCAST-n to talk to immediate neighbours using the fe80::/64 subnet. Anyone in earshot can potentially reply. Nodes simply need to be listening for traffic on a reserved UDP port (maybe 61631; there’s an optimisation in 6LoWPAN for 61616-61631). The joining node can ask for the network context, maybe authenticate itself if needed (using asymmetric cryptography – digital signatures, no encryption).

The other nodes presumably already know the answer, but for all nodes to reply simultaneously, would lead to a pile-up. Nodes should wait a randomised delay, and if nothing is heard in that period, they then transmit what they know of the context for the given network ID.

The context information sent back should include:

  • Group SSID
  • Subnet prefix
  • (Optional) Authentication data:
    • Public key of the forming network (joining node will need to maintain its own “trust” database)
    • Hash of all earlier data items
    • Digital signature signed with included public key

Once a node knows the context for its chosen network, it is officially “joined”.

Routing to non-local endpoints

So, a node may wish to send a message to another node that’s not directly reachable. This is, after-all, the whole point of using a routing protocol atop AX.25. If we knew a route, we could encode it in the digipeater path, and use conventional AX.25 source routing. Nodes that know a reliable route are encouraged to do exactly that. But what if you don’t know your way around?

APRS uses WIDEN-n to solve this problem: it’s a dumb broadcast, but it achieves this aim beautifully. n just stands for the number of hops, and it gets decremented with each hop. Each digipeater inserts itself into the path as it sends the frame on. APRS specs normally call for everyone to broadcast all at once, pile-up be damned. FM capture effect might help here, but I’m not sure its a good policy. Simple, but in our case, we can do a little better.

We only need to broadcast far enough to reach a node that knows a route. We’ll use ROUTE-n to stand for a digipeater that is no more than n hops away from the station listed in the AX.25 destination field. n must be greater than 0 for a message to be relayed. AX.25 2.0 limits the number of digipeaters to 8 (and 2.2 to 2!), so naturally n cannot be greater than 8.

So we’ll have a two-tier approach.

Routing from a node that knows a viable route

If a node that receives a ROUTE-n destination message, knows it has a good route that is n or less hops away from the target; it picks a randomised delay (maybe 0-5 seconds range), and if no reply is heard from another node; it relays the message: the ROUTE-n is replaced by its own SSID, followed by the required digipeater path to reach the target node.

Routing from a node that does not know a viable route

In the case where a node receives this same ROUTE-n destination message, does not know a route, and hasn’t heard anyone else relay that same message; it should pick a randomised delay (5-10 second range), and if it hasn’t heard the message relayed via a specific path in that time, should do one of the following:

If n is greater than 1:

Substitute ROUTE-n in the digipeater path with its own SSID followed by ROUTE-(n-1) then transmit the message.

If n is 1 (or 0):

Substitute ROUTE-n with its own SSID (do not append ROUTE-0) then transmit the message.

Routing multicast traffic

Discovering multicast listeners

I’ll have to research MLD (RFC-3810 / RFC-4604), but that seems the sensible way forward from here.

Relaying multicast traffic

If a node knows of downstream nodes that ordinarily rely on it to contact the sender of a multicast message, and it knows the downstream nodes are subscribers to the destination multicast group, it should wait a randomised period, and forward the message on (appending its SSID in the digipeater path) to the downstream nodes.

Application thoughts

I think I have done some thoughts on what the applications for this system may be, but the other day I was looking around for “prior art” regarding one-to-many file transfer applications.

One such system that could be employed is UFTP. Yes, it mentions encryption, but that is an optional feature (and could be useful in emcomm situations). That would enable SSTV-style file sharing to all participants within the mesh network. Its ability to be proxied also lends itself to bridging to other networks like AMPRnet, D-Star packet, DMR and other systems.

Queensland: fix your broken check-in application

So, today on the radio I heard that from this Friday, our state government was “expanding” the use of their Check-in Queensland program. Now, since my last post on the topic, I have since procured a new tablet. The tablet was purchased for completely unrelated reasons, namely:

  1. to provide navigation assistance, current speed monitoring and positional logging whilst on the bicycle (basically, what my Garmin Rino-650 does)
  2. to act as a media player (basically what my little AGPTek R2 is doing — a device I’ve now outgrown)
  3. to provide a front-end for a SDR receiver I’m working on
  4. run Slack for monitoring operations at work

Since it’s a modern Android device, it happens to be able to run the COVID-19 check-in programs. So I have COVIDSafe and Check-in Queensland installed. For those to work though, I have to run my existing phone’s WiFi hotspot. A little cumbersome, but it works, and I get the best of both worlds: modern Android + my phone’s excellent cell tower reception capability.

The snag though comes when these programs need to access the Internet at times when using my phone is illegal. Queensland laws around mobile phone use changed a while back, long before COVID-19. The upshot was that, while people who hold “open” driver’s licenses may “use” a mobile phone (provided that they do not need to handle it to do so), anybody else may not “use” a phone for “any purpose”. So…

  • using it for talking to people? Banned. Even using “hands-free”? Yep, still banned.
  • using it for GPS navigation? Banned.
  • using it for playing music? Banned.

It’s a $1000 fine if you’re caught. I’m glad I don’t use a wheelchair: such mobility aids are classed as a “vehicle” under the Queensland traffic act, and you can be fined for “drink driving” if you operate one whilst drunk. So traffic laws that apply to “motor vehicles” also apply to non-“motor vehicles”.

I don’t have a driver’s license of any kind, and have no interest in getting one, my primary mode of private transport is by bicycle. I can’t see how I’d be granted permission to do something that someone on a learner’s permit or P1 provisional license is forbidden from doing. The fact that I’m not operating a “motor vehicle” does not save me, the drink-driving in a wheelchair example above tells me that I too, would be fined for riding my bicycle whilst drunk. Likely, the mobile phones apply to me too. Given this, I made the decision to not “use” a mobile phone on the bicycle “for any purpose”. “For any purpose” being anything that requires the device to be powered on.

If I’m going to be spending a few hours at the destination, and in a situation that may permit me to use the phone, I might carry it in the top-box turned off (not certain if this is permitted, but kinda hard to police), but if it’s a quick trip to the shops, I leave the mobile phone at home.

What’s this got to do with the Check-in Queensland application or my new shiny-shiny you ask? Glad you did.

The new tablet is a WiFi-only device… specifically because of the above restrictions on using a “mobile phone”. The day those restrictions get expanded to include the tablet, you can bet the tablet will be ditched when travelling as well. Thus, it receives its Internet connection via a WiFi access point. At home, that’s one of two Cisco APs that provide my home Internet service. No issue there.

If I’m travelling on foot, or as a passenger on someone else’s vehicle, I use the WiFi hot-spot function on my phone to provide this Internet service… but this obviously won’t work if I just ducked up the road on my bike to go get some grocery shopping done, as I leave the phone at home for legal reasons.

Now, the Check-in Queensland application does not work without an Internet connection, and bringing my own in this situation is legally problematic.

I can also think of situations where an Internet connection is likely to be problematic.

  • If your phone doesn’t have a reliable cell tower link, it won’t reliably connect to the Internet, Check-in Queensland will fail.
  • If your phone is on a pre-paid service and you run out of credit, your carrier will deny you an Internet service, Check-in Queensland will fail.
  • If your carrier has a nation-wide whoopsie (Telstra had one a couple of years back, Optus and Vodafone have had them too), you can find yourself with a very pretty but very useless brick in your hand. Check-in Queensland will fail.

What can be done about this?

  1. The venues could provide a WiFi service so people can log in to that, and be provided with limited Internet access to allow the check-in program to work whilst at the venue. I do not see this happening for most places.
  2. The Check-in Queensland application could simply record the QR code it saw, date/time, co-visitors, and simply store it on the device to be uploaded later when the device has a reliable Internet link.
  3. For those who have older phones (and can legally carry them), the requirement of an “application” seems completely unnecessary:
    1. Most devices made post-2010 can run a web browser capable of running an in-browser QR code scanner, and storage of the customer’s details can be achieved either through using window.localStorage or through RFC-6265 HTTP cookies. In the latter case, you’d store the details server-side, and generate an “opaque” token which would be stored on the device as a cookie. A dedicated program is not required to do the function that Check-in Queensland is performing.
    2. For older devices, pretty much anything that can access the 3G network can send and receive SMS messages. (Indeed, most 2G devices can… the only exception I know to this would be the Motorola MicroTAC 5200 which could receive but not send SMSes. The lack of a 2G network will stop you though.) Telephone carriers are required to capture and verify contact details when provisioning pre-paid and post-paid cellular services, so already have a record of “who” has been assigned which telephone number. So why not get people to text the 6-digit code that Check-In Queensland uses, to a dedicated telephone number? If there’s an outbreak, they simply contact the carrier (or the spooks in Canberra) to get the contact details.
  4. The Check-in Queensland application has a “business profile” which can be used for manual entry of a visitor’s details… hypothetically, why not turn this around? Scan a QR code that the visitor carries and provides. Such QR codes could be generated by the Check-in Queensland website, printed out on paper, then cut out to make a business-card sized code which visitors can simply carry in their wallets and present as needed. No mobile phone required! For the record, the Electoral Commission of Queensland has been doing this for our state and council elections for years.

It seems the Queensland Government is doing this fancy “app” thing “because we can”. Whilst I respect the need to effectively contact-trace, the truth is there’s no technical reason why “this” must be the implementation. We just seem to be playing a game of “follow the shepherd”. They keep trying to advertise how “smart” we are, why not prove it?

A COVID-19 check-in system of my own

So, for the past 12 months we’ve basically had a whirlwind of different “solutions” to the problem of contact tracing. The common theme amongst them seems to be they’re all technical-based, and they all assume people carry a smartphone, registered with one of the two major app stores, and made in the last few years.

Quite simply, if you’re carrying an old 3G brick from 2010, you don’t exist to these “apps”. Our own federal government tried its hand in this space by taking OpenTrace (developed by the Singapore Government and released as GPLv3 open-source) and rebadging that (and re-licensing it!) as COVIDSafe.

This had very mild success to say the least, with contact tracers telling us that this fancy “app” wasn’t telling them anything new. So much focus has been put on signing into and out of venues.

To be honest, I’m fine with this until such time as we get this gift from China under control. The concept is not what irks me, it’s its implementation.

At first, it was done on paper. Good old fashioned pen and paper. Simple, nearly foolproof, didn’t crash, didn’t need credit, didn’t need recharging, didn’t need network coverage… except for two problems:

  1. people who can’t successfully operate a pen (Hmm, what went wrong, Education Queensland?)
  2. people who can’t take the process seriously (and an app solves this how?)

So they demanded that all venues use an electronic system. Fine, so we had a myriad of different electronic web-based systems, a little messy, but it worked, and for the most part, the venue’s system didn’t care what your phone was.

A couple, even could take check-in by SMS. Still rocking a Nokia 3210 from 1998? Assuming you’ve found a 2G cell tower in range, you can still check in. Anything that can do at least 3G will be fine.

An advantage of this solution is that they have your correct mobile phone number then and it’s a simple matter for Queensland Health to talk to Telstra/Optus/Vodaphone/whoever to get your name and address from that… as a bonus, the cell sites may even have logs of your device’s IMEI roaming, so there’s more for the contact tracing kitty.

I only struck one venue out of dozens, whose system would not talk to my phone. Basically some JavaScript library didn’t load, and so it fell in a heap.

Until yesterday.

The Queensland Government has decided to foist its latest effort on everybody, the “Check-in Queensland” app. It is available on Google Play Store and Apple App Store, and their QR codes are useless without it. I can’t speak about the Apple version of the software, but for the Android one, it requires Android 5.0 or above.

Got an old reliable clunker that you keep using because it pulls the weakest signals and has a stand-by time that can be measured in days? Too bad. For me, my Android 4.1 device is not welcome. There are people out there for whom, even that, is a modern device.

Why not buy a newer phone? Well, when I bought this particular phone, back in 2015… I was looking for 3 key features:

  1. Make and receive (voice) telephone calls
  2. Send and receive short text messages
  3. Provide a Internet link for my laptop via USB/WiFi

Anything else is a bonus. It has a passable camera. It can (and does) play music. There’s a functional web browser (Firefox). There’s a selection of software I can download (via F-Droid). It Does What I Need It To Do. The battery still lasts 2-3 days between charges on stand-by. I’ve seen it outperform nearly every contemporary device on the market in areas with weak mobile coverage, and I can connect an external antenna to boost that if needed.

About the only thing I could wish for is open-source firmware and a replaceable battery. (Well, it sort-of is replaceable. Just a lot of frigging around to get at it. I managed to replace a GPS battery, so this should be doable.)

So, given this new check-in requirement, what is someone like me to do? Whilst the Queensland Government is urging people to install their application, they recognise that there are those of us who cannot because we lack anything that will run it. So they ask that venues have a device on hand that can be used to check visitors in if this situation arises.

My little “hack” simply exploits this:

# This file is part of pylabels, a Python library to create PDFs for printing
# labels.
# Copyright (C) 2012, 2013, 2014 Blair Bonnett
#
# pylabels is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# pylabels is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# pylabels.  If not, see <http://www.gnu.org/licenses/>.

import argparse
import labels
import time
from reportlab.lib.units import mm
from reportlab.graphics import shapes
from reportlab.lib import colors
from reportlab.graphics.barcode import qr

rows = 4
cols = 2
# Specifications for Avery C32028 2×4 85×54mm
specs = labels.Specification(210, 297, cols, rows, 85, 54, corner_radius=0,
        left_margin=17, right_margin=17, top_margin=31, bottom_margin=32)

def draw_label(label, width, height, checkin_id):
    label.add(shapes.String(
        42.5*mm, 50*mm,
        'COVID-19 Check-in Card',
        fontName="Helvetica", fontSize=12, textAnchor='middle'
    ))
    label.add(shapes.String(
        42.5*mm, 46*mm,
        'The Queensland Government has chosen to make the',
        fontName="Helvetica", fontSize=8, textAnchor='middle'
    ))
    label.add(shapes.String(
        42.5*mm, 43*mm,
        'CheckIn QLD application incompatible with my device.',
        fontName="Helvetica", fontSize=8, textAnchor='middle'
    ))
    label.add(shapes.String(
        42.5*mm, 40*mm,
        'Please enter my contact details into your system',
        fontName="Helvetica", fontSize=8, textAnchor='middle'
    ))
    label.add(shapes.String(
        42.5*mm, 37*mm,
        'at your convenience.',
        fontName="Helvetica", fontSize=8, textAnchor='middle'
    ))

    label.add(shapes.String(
        5*mm, 32*mm,
        'Name: Joe Citizen',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        5*mm, 28*mm,
        'Phone: 0432 109 876',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        5*mm, 24*mm,
        'Email address:',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        84*mm, 20*mm,
        'myaddress+c%o@example.com' % checkin_id,
        fontName="Courier", fontSize=12, textAnchor='end'
    ))
    label.add(shapes.String(
        5*mm, 16*mm,
        'Home address:',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        15*mm, 12*mm,
        '12 SomeDusty Rd',
        fontName="Helvetica", fontSize=12
    ))
    label.add(shapes.String(
        15*mm, 8*mm,
        'BORING SUBURB, QLD, 4321',
        fontName="Helvetica", fontSize=12
    ))

    label.add(shapes.String(
        2, 2, 'Date: ',
        fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        10*mm, 2, 12*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))
    label.add(shapes.String(
        22.5*mm, 2, '-', fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        24*mm, 2, 6*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))
    label.add(shapes.String(
        30.5*mm, 2, '-', fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        32*mm, 2, 6*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))
    label.add(shapes.String(
        40*mm, 2, 'Time: ',
        fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        50*mm, 2, 6*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))
    label.add(shapes.String(
        56.5*mm, 2, ':', fontName="Helvetica", fontSize=10
    ))
    label.add(shapes.Rect(
        58*mm, 2, 6*mm, 4*mm,
        fillColor=colors.white, strokeColor=colors.gray
    ))

    label.add(shapes.String(
        10*mm, 5*mm, 'Year',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))
    label.add(shapes.String(
        24*mm, 5*mm, 'Month',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))
    label.add(shapes.String(
        32*mm, 5*mm, 'Day',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))
    label.add(shapes.String(
        50*mm, 5*mm, 'Hour',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))
    label.add(shapes.String(
        58*mm, 5*mm, 'Minute',
        fontName="Helvetica", fontSize=6, fillColor=colors.gray
    ))

    label.add(qr.QrCodeWidget(
            '%o' % checkin_id,
            barHeight=12*mm, barWidth=12*mm, barBorder=1,
            x=73*mm, y=0
    ))

# Grab the arguments
OCTAL_T = lambda x : int(x, 8)
parser = argparse.ArgumentParser()
parser.add_argument(
        '--base', type=OCTAL_T,
        default=(int(time.time() / 86400.0) << 8)
)
parser.add_argument('--offset', type=OCTAL_T, default=0)
parser.add_argument('pages', type=int, default=1)
args = parser.parse_args()

# Figure out cards per sheet (max of 256 cards per day)
cards = min(rows * cols * args.pages, 256)

# Figure out check-in IDs
start_id = args.base + args.offset
end_id = start_id + cards
print ('Generating cards from %o to %o' % (start_id, end_id))

# Create the sheet.
sheet = labels.Sheet(specs, draw_label, border=True)

sheet.add_labels(range(start_id, end_id))

# Save the file and we are done.
sheet.save('checkin-cards.pdf')
print("{0:d} cards(s) output on {1:d} page(s).".format(sheet.label_count, sheet.page_count))

That script (which may look familiar), generates up to 256 check-in cards. The check-in cards are business card sized and look like this:

That card has:

  1. the person’s full name
  2. a contact telephone number
  3. an email address with a unique sub-address component for verification purposes (compatible with services that use + for sub-addressing like Gmail)
  4. home address
  5. date and time of check-in (using ISO-8601 date format)
  6. a QR code containing a “check-in number” (which also appears in the email sub-address)

Each card has a unique check-in number (seen above in the email address and as the content of the QR code) which is derived from the number of days since 1st January 1970 and a 8-bit sequence number; so we can generate up to 256 cards a day. The number is just meant to be unique to the person generating them, two people using this script can, and likely will, generate cards with the same check-in ID.

I actually added the QR code after I printed off a batch (thought of the idea too late). Maybe the next batch will have the QR code. This can be used with a phone app of your choosing (e.g. maybe use BarcodeScanner to copy the check-in number to the clip-board then paste it into a spreadsheet, or make your own tool) to add other data. In my case, I’ll use a paper system:

The script that generates those is here:

# This file is part of pylabels, a Python library to create PDFs for printing
# labels.
# Copyright (C) 2012, 2013, 2014 Blair Bonnett
#
# pylabels is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# pylabels is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# pylabels.  If not, see <http://www.gnu.org/licenses/>.

import argparse
import labels
import time
from reportlab.lib.units import mm
from reportlab.graphics import shapes
from reportlab.lib import colors

rows = 4
cols = 2
# Specifications for Avery C32028 2×4 85×54mm
specs = labels.Specification(210, 297, cols, rows, 85, 54, corner_radius=0,
        left_margin=17, right_margin=17, top_margin=31, bottom_margin=32)

def draw_label(label, width, height, checkin_id):
    label.add(shapes.String(
        42.5*mm, 50*mm,
        'COVID-19 Check-in Log',
        fontName="Helvetica", fontSize=12, textAnchor='middle'
    ))

    label.add(shapes.Rect(
        1*mm, 3*mm, 20*mm, 45*mm,
        fillColor=colors.lightgrey,
        strokeColor=None
    ))
    label.add(shapes.Rect(
        41*mm, 3*mm, 28*mm, 45*mm,
        fillColor=colors.lightgrey,
        strokeColor=None
    ))

    for row in range(3, 49, 5):
        label.add(shapes.Line(1*mm, row*mm, 84*mm, row*mm, strokeWidth=0.5))
    for col in (1, 21, 41, 69, 84):
        label.add(shapes.Line(col*mm, 48*mm, col*mm, 3*mm, strokeWidth=0.5))

    label.add(shapes.String(
        2*mm, 44*mm,
        'In',
        fontName="Helvetica", fontSize=8
    ))

    label.add(shapes.String(
        22*mm, 44*mm,
        'Check-In #',
        fontName="Helvetica", fontSize=8
    ))

    label.add(shapes.String(
        42*mm, 44*mm,
        'Place',
        fontName="Helvetica", fontSize=8
    ))

    label.add(shapes.String(
        83*mm, 44*mm,
        'Out',
        fontName="Helvetica", fontSize=8, textAnchor='end'
    ))

# Grab the arguments
parser = argparse.ArgumentParser()
parser.add_argument('pages', type=int, default=1)
args = parser.parse_args()

cards = rows * cols * args.pages

# Create the sheet.
sheet = labels.Sheet(specs, draw_label, border=True)

sheet.add_labels(range(cards))

# Save the file and we are done.
sheet.save('checkin-log-cards.pdf')
print("{0:d} cards(s) output on {1:d} page(s).".format(sheet.label_count, sheet.page_count))

When I see one of these Check-in Queensland QR codes, I simply pull out the log card, a blank check-in card, and a pen. I write the check-in number from the blank card (visible in the email address) in my log with the date/time, place, and on the blank card, write the same date/time and hand that to the person collecting the details.

They can write that into their device at their leisure, and it saves time not having to spell it all out. As for me, I just have to remember to write the exit time. If Queensland Health come a ringing, I have a record of where I’ve been on hand… or if I receive an email, I can use the check-in number to validate that this is legitimate, or even tell if a venue has on-sold my personal details to an advertiser.

I guess it’d be nice if the Queensland Government could at least add a form to their fancy pages that their flashy QR codes send people to, so that those who do not have the application can still at least check-in without it, but that’d be too much to ask.

In the meantime, this at least meets them half-way, and hopefully does so which ensures minimal contact and increases efficiency.