Control4 · Zigbee · reverse engineering · step-by-step guide

How Control4 “masks” its Zigbee — and how we deciphered it

Control4 doesn't use a secret network. It uses the same Zigbee as Philips Hue or Sonoff. The only thing that changes is the language it speaks in the last layer. This is the full explanation, with the real bytes we captured in the lab.

1

The idea in one sentence

Every Zigbee network works like envelopes tucked inside envelopes. Each envelope is a “layer” that wraps the next one. Control4 uses exactly the same envelopes as everyone else… until the last one. In the innermost envelope, where other brands write in a standard language, Control4 writes in its own private language.

RADIO · IEEE 802.15.4 (the air, 2.4 GHz) NETWORK · Zigbee PRO (the mesh, routing) TRANSPORT · APS (which “mailbox” it reaches) THE LETTER · the language here Control4 is different
The 3 outer layers are identical on every Zigbee brand. Only the letter in the center changes.
2

The four layers, side by side

This is the key diagram of the whole thing. On the left, any normal Zigbee device (a Sonoff, a Hue). On the right, Control4. The first three layers are the same. Only the top one —the application language— is different.

Sonoff / Hue (standard) Control4 APPLICATION · ZCL 01 42 01 (binary) APPLICATION · own ASCII 0t01 sa c4.zr.bb… ▲ THIS IS THE WHOLE DIFFERENCE ▲ APS · transport APS · transport NWK · Zigbee PRO NWK · Zigbee PRO RADIO · 802.15.4 RADIO · 802.15.4 these three layers are identical — the same Zigbee for everyone
Control4's “mystery” lives in a single layer. The radio and the mesh are standard.
Analogy: it's the same envelope, the same mail carrier and the same address everyone uses. But inside, the letter is written in a language only the Control4 controller (the “Director”) can read.
3

A real command, end to end

Let's follow a real button: you press Play on the SR260 remote. This is what actually happens, step by step — every piece of data here came out of our lab.

👆 Play SR260 ON THE AIR (ASCII text) 0t01 sa c4.zr.bb 1d … profile 0xC25C · cluster 0x0001 📡 antenna captures CatSniffer 🧅 peel the envelopes radio → network → APS → payload 🔤 the quirk translates C4 ASCII → standard event 🏠 Home Assistant understands button = "play" · short_press
From finger to event: the same data crosses six steps. The “aha” is in the blue box at the top.
4

The 40 bytes, inside out

This is the Play-button frame exactly as it travels, byte by byte. Notice that almost all of it is text a human can read — that was the surprise. Each color is a field with its meaning.

30
0
74
t
30
0
31
1
20
·
73
s
61
a
20
·
63
c
34
4
2e
.
7a
z
72
r
2e
.
62
b
62
b
20
·
31
1
64
d
20
·
30
0
30
0
30
0
30
0
20
·
30
0
30
0
30
0
30
0
20
·
30
0
30
0
30
0
30
0
30
0
30
0
30
0
30
0
0d
\r
0a
\n
0t = type: “announce” 01 = sequence number sa = verb: “state” c4.zr.bb = “button pressed” 1d = button 0x1d = Play padding / end of line
0t
Message type. “0t” = announce: the device reports something unprompted. (Others: 0s=set, 0g=get, 0r=report.)
01
Sequence number. To keep count of the messages.
sa
Verb. “sa” = state announcement.
c4.zr.bb
The namespace. zr = zigbee remote, bb = button begin (key going down). It's the “noun + action”.
1d
The argument. 0x1d in hexadecimal = 29 = the Play key in the 50-button map.
5

How it “switches language”

Here's the whole trick. For the same action, look at what a standard device sends versus what Control4 sends. It's not that Control4 is encrypted — it's that it speaks another language, one of text instead of binary codes.

Standard Zigbee (ZCL)
01 42 01

Three binary bytes. 01=header, 42=sequence, 01=command “On”. Unreadable without the ZCL table. Compact, but opaque.

Control4 (own ASCII)
0t01 sa c4.dmx.ls 00 00 64

Readable text. c4.dmx.ls = “light state”, 64 = 100 in decimal = brightness at 100%. Longer, but it's literally a language with words.

Why they built it this way: a text protocol is easy for the manufacturer to debug and extend — you add a new “word” without breaking anything. The cost is that nobody else understands it… until someone builds the dictionary. Which is what we did.
6

How we deciphered it (in reverse)

Reverse engineering = going from the frame to the meaning, with no manual. These are the six steps we followed, and where we stand.

1 Capture the antenna hears the air 2 Decrypt network with the Zigbee key 3 Peel layers remove the envelopes 4 It's text! recognize the language 5 Dictionary 6 Translate
Steps 1, 3 and 4 already done in the lab (with real captures). Step 2 over the EA-1 awaits its key. Steps 5–6 = the quirks repo.
1 · Capture
The CatSniffer in monitor mode saves every frame off the air. Done — we have captures on channels 13 and 14.
2 · Decrypt
The network layer is encrypted with the Zigbee key. On our network we have it; on the EA-1's it has to be recovered (the big open item of Phase 3).
3 · Peel
Wireshark + our dissector strip radio→network→APS and leave the raw payload. Done.
4 · Recognize
The payload isn't binary ZCL: it's readable ASCII text. That was the finding that opens everything.
5 · Dictionary
Press each button, see which frame comes out, and note it down. That's how the map of the 50 buttons and ~50 verbs is built.
6 · Translate
The quirk converts each C4 sentence into the standard event Home Assistant understands, live.
7

The final translation

The last step, concrete: the Control4 sentence goes in one side, and comes out as an event any Home Assistant automation can use — without knowing a single word of Control4.

in (Control4 language) 0t01 sa c4.zr.bb 1d quirk translator out (standard language) button="play" · short_press
The quirk is an executable dictionary. It translates both ways: events coming in and commands going out.

What to take away

Control4 never hid its network — it uses everyone's Zigbee. It hid its vocabulary, in the last layer. And a vocabulary isn't broken: it's learned, by pressing buttons and noting what comes out.

That's why the same method works for any “closed” brand: the lock is almost never in the radio. It's in who holds the dictionary — and who controls the coordinator.

The proof, on real hardware

Everything above, working. You press the red Control4 button on the SR260 remote — and a Sonoff module (another brand, incompatible with Control4) turns on. The only bridge is Home Assistant with the quirks translating the protocol, with no Control4 controller.

~60 s demo, no audio, with subtitles. Control4 button → Sonoff: two incompatible brands talking through the quirks.

The full detail —flashing the CatSniffer, the quirks, the wiring, the pairing and the automation— is in the step-by-step install →

Control4 Zigbee lab · data and bytes taken from real captures and code analysis. Independent reverse engineering, for research and interoperability. Not affiliated with Control4 / Snap One.