Home‎ > ‎How-to‎ > ‎GlowWithTheShow‎ > ‎

Hacking GWTS

0x9? Packet Header
Many of the Glow with the Show commands are sent using this packet format. Each packet may contain multiple commands. Note that sending a new command does not completely reset previous commands. For example, if you have the had pulsing green, then you send a command to change the hat to red, the hat will change to red, but continue to pulse.

0x9? Packet Header

# +-+-+-+-+-+-+-+-+--------------------+-+-+-+-+-+-+-+-+

# |  HDR  |  LEN  |      PAYLOAD       |       CRC     |

# +-------+-+-+-+-+--------------------+-+-+-+-+-+-+-+-+

#HDR, 4-bits = 0b1001 = 9

#LEN, 4-bits, Number of bytes in payload-1

#     1-byte payload would have length 0b0000

#     2-byte payload would have length 0b0001

#PAYLOAD, variable length in bytes

#     Contains command(s) for the GWTS ears.

#CRC, 1-byte, calculated across HDR, LEN, and PAYLOAD

#     8-bit CRC value as the last byte and uses a

#      polynomial of X^8 + X^5 + X^4 + X^0


Simple Example: This GWTS command changes the color of the ears to green. 0x90 62 1A
HDR: 0x90 = 0b10010000. The first nibble (4-bits) 0b1001 = 9, it's always 9.
LEN: The 2nd nibble 0b0000 is the payload length -1. In this example the payload (0x62) length is 1 byte. So the payload length minus 1 is zero.
PAYLOAD: 0x62 : This command tells the ears to simply change color to green.
CRC: 0x1A : This is the result of an 8-bit CRC check using 0x82 as a Polynomial across 0x9062. You can see the math by entering 9062 here.

The following sections represent the commands that can be placed in the payload of the 0x9 command packets. You can can combine multiple commands into a single payload.

Setting Basic Colors using single byte command
Each color has an assigned code that will change both the ears to the specified color. To set just the right ear add 8 to the base code.
 Color
Both Ears
Code
Both
Ears
Command
Right
Ear
Code
Right
Ear
Command
 Off0x60  0x90 60 A60x680x90 68 64 
 Blue
0x61 0x90 61 F80x690x90 69 3A
 Green0x62 0x90 62 1A0x6A0x90 6A D8
 Cyan0x63  0x90 63 440x6B0x90 6B 86
 Red0x64  0x90 64 C70x6C0x90 6C 05
 Magenta0x65 0x90 65 990x6D 0x90 6D 5B
 Yellow0x66  0x90 66 7B0x6E 0x90 6E B9
 White0x67 0x90 67 250x6F0x90 6F 24

Setting Extended Colors using 0x0E command
Each of the following color codes follows 0x0E to specify one of the extended colors. This will change the color of both ears. To change the color of just the right ear add 128 (0x80) to the base code. Lots of pastel colors here. I described them the best I could you can explore the finer hues on your own :)

Format for both ears: 0x91 0E [00-1D] [CRC]
Format for right ears: 0x91 0E [(00-1D)+0x80] [CRC]

ColorBoth Ears CodeBoth Ears CommandRight Ear CodeRight Ear Command
Cool White0x000x91 0E 00 5F 0x800x91 0E 80 D3
 0x010x91 0E 01 010x81 0x91 0E 81 8D
Light Blue0x020x91 0E 02 E3 0x82 0x91 0E 82 6F
Light Purple0x030x91 0E 03 BD 0x83  todo
Blue0x04 0x91 0E 04 3E 0x84  
Pinkish White0x050x91 0E 05 60 0x85  
Lavender0x060x91 0E 06 82 0x86  
Light Purple0x07 0x91 0E 07 DC 0x87  
Purple0x08 0x91 0E 08 9D 0x88  

0x09 0x91 0E 09 C3 0x89  

0x0A 0x91 0E 0A 21 0x8A 
 0x0B 0x91 0E 0B 7F 0x8B  
 0x0C 0x91 0E 0C FC 0x8C  
 0x0D 0x91 0E 0D A2 0x8D  
 0x0E 0x91 0E 0E 40 0x8E  
 0x0F 0x91 0E 0F 1E0x8F  

0x10 0x91 0E 10 C2 0x90  

0x110x91 0E 11 9C 0x91  

0x12 0x91 0E 12 7E0x92  
Light Orange0x130x91 0E 13 20 0x93  
Orange0x14 0x91 0E 14 A3 0x94  
Red0x15 0x91 0E 15 FD0x95  
 0x16 0x91 0E 16 1F 0x96  
 0x17 0x91 0E 17 41 0x97  
Seagreen0x18 0x91 0E 18 000x98  
Lime0x19 0x91 0E 19 5E 0x99  
Light Green0x1A 0x91 0E 1A BC 0x9A  
 0x1B0x91 0E 1B E2 0x9B  
 0x1C 0x91 0E 1C 61 0x9C  
Off 0x1D 0x91 0E 1D 3F 0x9D  

Reset
0x24: This command resets the ears back to black and clears effects.
Used by itself the command is: 0x90 24 81

Setting Effect Speed
0x58 ??: The 0x58 command is used with the 0x9 header to set the speed of the active effect where ?? is the specified speed.
0x58 01: Represents the fastest speed
0x58 FF : Represents the slowest speed


CRC Calculation:
CRC, 1-byte, calculated across HDR, LEN, and PAYLOAD. 8-bit CRC value as the last byte and uses a polynomial of X^8 + X^5 + X^4 + X^0
Used with the 0x9? command packets. 
John's PERL source for generating GWTS CRC and Checksum: Link
Compatible online CRC calculator: Link

PERL CRC Calculator (binaries as strings)

# Test: "96 42 00 00 48 18 0C BE" Should give you "1B"
sub GWTS_crc8c_calc {
my($hex) = shift; # Space seperate Hex string to be converted
my($crc) = "00000000"; # Initialize CRC
my($poly) = "10001100"; # 0x8C
my(@bytes); (@bytes) = split(/ +/,$hex); # 1-byte per element
foreach my $byte (@bytes) { # Go byte by byte
my($binbyte) = lpad(hex2bin($byte),"0",8); # Hex2binary and left pad so string is 8 long.
my($i); for($i=0;$i<8;$i++) { # 8 times for 8 bits
if( substr($binbyte,7,1) eq substr($crc,7,1) ) { # Comparing right most bits
$binbyte = strbitwise_rshift($binbyte,1); # Right shift byte by 1 (advancing to next bit)
$crc = strbitwise_rshift($crc,1); # Right shift running CRC by 1
} else {
$binbyte = strbitwise_rshift($binbyte,1); # Right shift byte by 1 (advancing to next bit)
$crc = strbitwise_rshift($crc,1); # Right shift running CRC by 1 
$crc = strbitwise_xor($poly,$crc); # XOR the current CRC with the shifted byte
} #endif
} #end for
} # end foreach
return(bin2hex($crc)); # Convert back to hex and return CRC
} # GWTS_crc8c_calc

Sample C Implementation

uint8_t gws_crc(uint8_t *d, unsigned len{ 
    crc = 0; 
    while(
len--) { 
        crc ^= *d++; 
        unsigned n = 8; do crc = (crc & 1) ? (crc >> 1) ^ 0x8C : crc >> 1; while(--n); 
    } 
    return crc; 
/* C implementation of CRC calculator:

/* Kevin Timmerman (http://www.hifi-remote.com/forums/viewtopic.php?t=14541) */



Calculating Checksum for 0x55 AA System command

PERL Checksum for 0x55 AA Sys Command

# Calculates a checksum for a 0x55 AA system command
# 55 AA [19 04 01 02 0E 01 00 00 35] 64
sub GWTS_Checksum55AA {
my($hex) = shift;
$hex = uc($hex);
my(@bytes); (@bytes) = split(/ +/,$hex);
if( $bytes[0] eq "55" and $bytes[1] eq "AA" ) {
shift(@bytes); shift(@bytes);
} #endif

my($chksum) = 0;
foreach my $b (@bytes) {
$chksum += hex2dec($b);
} #endforeach
return(dec2hex($chksum));
} # GWTS_Checksum55AA



Comments