Skip to main content

The Story of LLRP2HRP - Part 1

So, this brash American dude who ran a relay race event decided to go fancy. None of this using phones to manually scan NFC chips for race timing. He was going to have chips in bibs. He convinced another organisation that also ran races to chip in some funding ... and then went online.

He found an RFID reader system. The kind of ground mats that you run over, that connects to a box that goes beep. It was from China. It was insanely cheap. Like fall-off-the-back-of-a-truck cheap. It was delivered, hardware checks out.

It came with no software.


Commence epic yak shaving side project!


The reader is a Hopeland (previously Clou) CL7206C4. Basically an ARM9 box running (amazingly) Familiar Linux v0.8.3 with a 2 2-port UHF transceivers. The transceivers are based on the Impinj R2000 platform, which is a popular platform for race timing.

I pulled a venerable Thinkpad out of a draw and plugged it into the ethernet jack and fired up wireshark. No DHCP requests, but some documentation suggested the default IP was 192.168.100.116 so I configured an address in this range and watched as the reader helpfully started broadcasting a proprietary UDP protocol:
^tlì¡þ¶`Eó@lhÀ¨dtæt[ #ß·b^RFID_READER_INFORMATION:7206C,DHCP_SW:OFF,
IP:192.168.100.116,MASK:255.255.255.0,GATEWAY:192.168.100.1,
MAC:6c-ec-a1-fe-b6-60,PORT:9090,HOST_SERVER_IP:192.168.1.1,
HOST_SERVER_PORT:9090,MODE:SERVER,NET_STATE:INACTIVE$ 

Beautiful, and with telnet too:
$ nmap 192.168.100.116
Starting Nmap 7.60 ( https://nmap.org ) at 2019-12-04 17:08 CST
Nmap scan report for 192.168.100.116
Host is up (0.022s latency).
Not shown: 998 closed ports
PORT     STATE SERVICE
23/tcp   open  telnet
9090/tcp open  zeus-admin

I wonder what the password is ... no ... no, it can't be ...

$ telnet 192.168.100.116
Trying 192.168.100.116...
Connected to 192.168.100.116.
Escape character is '^]'.

Familiar Linux v0.8.3 (none)


(none) login: root
warning: cannot change to home directory
/ # 

The process list was typical for an embedded system - some hacky scripts that start a monolithic binary that has all the functionality.
  488 root       2916 SW  /bin/sh /bin/ping_gateway.sh 
  489 root       2920 SW  /bin/sh /bin/feeddog_auto.sh 
  491 root       2920 SW  /bin/sh /bin/auto_start_fifo.sh 
  492 root       2920 SW  /bin/sh /bin/auto_start.sh 
  523 root       1352 SW  /bin/fifo_read 
  524 root       1348 SW  /bin/feed_dog 
  525 root       9400 SW  CL7206C2 
  542 root       9400 SW  CL7206C2 
  543 root       9400 SW  CL7206C2 
  544 root       9400 SW  CL7206C2 
  545 root       9400 SW  CL7206C2 

With only TFTP to play with, I set up a TFTPD on the Thinkpad and started analysing the files. So, I could see that there was definitely a daemon listening on port 9090 looking for some kind of binary protocol - but it wouldn't talk without a specific instruction. I didn't have the instructions though. Then there are binary drivers for each of the RFID chips. Not a lot to go on.

I had a theory that this reader was an OEM model for Impinj. There are similar looking physical units, with the same chips online. Those speak Low Level Reader Protocol (LLRP), so perhaps if I fed some LLRP messages to port 9090 I could get something?

I wanted a quick and easy LLRP toolkit that I could fire up and used to send some messages. The leading options seemed to be from the Java-based "LLRP toolkit", which had a Eclipse plugin called LLRPCommander that seemed perfect. Only, it was hosted on SourceForge and didn't appear to have been updated in recent years. Not a good sign, and sure enough it didn't work with any recent version of Eclipse or Java even with a bit of hacking.

Back to the drawing board. So, Hopeland provided an "SDK" in C#. Not a language I'm familiar with, and the distribution was full of impenetrable binaries and no API documentation as such. It was also Windows-only and using a version of Visual Studio that was deprecated. I got out wine and tried to get it working in an older version, but to no avail.

Googling ensued. At one moment I was on the unofficial Hopeland YouTube channel (appears to be run by one of their employees, under their personal name). There they had screen captures of the SDK's test tool running. If you zoomed in just enough at just the right frame, you could see a debug window with the binary commands being passed to the machine. I copied down what I could:

## These sent when the app goes to advanced settings. getting settings?
AA02000000A803
AA020000002828
AA02000000A8F3
AA02000000A87B
AA0200000028A0
AA02000000A88B
# these are received after the above
AA0202000B010008080A070B060C050DE637
AA02080001FF24F1
AA020A00030000008E29
AA020A00030000006E2F

Then, I got out netcat and tried pasting them in. It worked!!

OK, so this definitely wasn't LLRP protocol ... but what was it? I definitely didn't want to try and completely reverse engineer what looked to be a complex proprietary binary protocol. I couldn't get packet captures to make progress, since the system didn't even respond unless the right packet was sent to it.

Then, after a very long and arduous Google session, I found the perfect solution, courtesy of the Bolivian government...

Comments

Popular posts from this blog

How to transfer money from Taiwan without going to the bank

We live in a digital age. The Taiwanese banking system ... a little less so. Transferring money overseas typically involves a visit to the bank between 9am and 3pm. You'll queue, fill out an outbound remittance form in duplicate, stamp and sign some things and just generally wait while staff do their best with the unfamiliar procedure. There is another way.* * for transfers < 500,000 TWD, to accounts you've previously set up in a special way :(  Background: Remittance Classifications One of the reasons for the myriad of complicated forms when dealing with foreign exchange in Taiwan is the precise codification of transfer types required by the Central Bank. Your knowledge of the existence of these two documents will boost your standing above that of the average banker: 匯出匯款之分類及說明  Code and Description of Outward Remittance Classification 匯入匯款之分類及說明 Code and Description of Inward Remittance Classification These are updated every few years, with new versions fo...

How to flash Seeed Wio-WM1110 Dev Kit with Meshtastic

The Seeed Wio-WM1110 Dev Kit is an nRF52840-based LoRa® transceiver with built-in GPS, Temperature/Humidity sensor and supports solar and battery power. Unfortunately, unlike many Meshtastic devices, this board cannot be flashed using USB. Instead, you require an external device that can connect via SWDIO. Luckily, if you have a Raspberry Pi around this is surprisingly straightforward. 1. Set up Wiring Connect GPIO pin 11 on your Raspbery Pi to the CLK pin on the Wio-WM1110. Connect GPIO pin 8 on your Raspbery Pi to the DIO pin on the Wio-WM1110. Ensure you get the GPIO numbers correct. Plug in your Raspberry Pi to USB power. Plug in the Wio-WM1110 to USB for power. 2. Install OpenOCD OpenOCD is the program we'll use for communicating with the Wio-WM1110. Install it on your Raspberry Pi. $ sudo apt update $ sudo apt install libtool autoconf automake texinfo telnet gdb-multiarch git $ git clone git://repo.or.cz/openocd.git $ cd openocd/ $ ./bootstrap $ ./configure --enable-bcm2835...

How to play Monster Hunter: World on Linux

The release of Monster Hunter: World on PC has broken records. Powered by the unfamiliar MT Engine, Linux users were worried that they might miss out on the experience. Luckily, some got it working on day 1 (hat tip Vahron and all the users on the reddit thread). Here's a way to get it working :) Upgrade to Ubuntu 18.04 Bionic Beaver. The previous release, 17.10 Artful Aardvark didn't work for me. Install lutris . Lutris is a launcher for games on Linux. There are so many different wine versions and configuration options. Lutris manages them all for you and has installers with 'known good' configurations. Open lutris and install the 'Wine Steam' runner. (Lutris -> Manage Runners -> Wine Steam -> Install). This will let Lutris run games via a wine-installed version of steam Manage the wine version of lutris to install esync-3.13 . (Lutris-> Manage Runners -> Wine -> Manager versions -> Tick esync 3.13). This will make the latest high...