Ok, I figured out what the problem was with my 38 byte packet generator. The HTML/TCP/IP library I am using was encoding the bytes as UTF-8 instead of raw binary. This tweaked exactly one byte - right in the middle of my serial number. Not only did this invalidate my serial number, but it also affected the checksum since the byte was tweaked after it was calculated. I only caught it by running Wireshark and snooping my own packets.
I started using streams instead of a string for a buffer for the 38 byte payload and things started to work - this bypasses the encoder. I got a beep, the display contrast changed, the clock reset, and the Internet indicator turned on. Yaaay!
Unfortunately, this triggered a storm of 210 byte packets. Boooo!
Sound familiar? Read on for some good news:
I was able to stop the GW from jabbering by connecting to the LCX server - it would jabber long SDP packets for anywhere from 10-50 times and then mysteriously quit after the usual handshakes and LCX sending a 38 byte Real Time Clock (RTC) packet.
After analyzing what was going on, I found that the Epoch word in the RTC packet is the key. It must match what the GW expects or it goes into jabber mode. You can't set it to a constant value, unless you also trash your "serial number" - but then the Internet indicator goes off and clock updates cease. Don't forget that the Epoch word changes every two hours. The current version of SkySpy uses a bad SN (and my personal Epoch number), so you don't get jabbering.
Once I set the Epoch correctly, everything started to work!!!!
No more jabbering!
Unfortunately, everyone's Epoch value is different. I think it depends on the date and time that you register the GW. You can figure it out by looking at what LCX sends you in the 38 byte packet - note the current local time/date and current Epoch value. Then you can use this algorithm to simulate it in your own 38 byte RTC packet:
SeedDate := EncodeDate(2014, 5, 3) + EncodeTime(15, 10, 00, 0);
StartingEpoch := $7da8; // my epoch value on 3 May 2014 at 15:10:00 local time
ElapsedTime := (Now() - SeedDate); // calc integer days plus fraction of 24 hours
ElapsedEpochs := TRUNC(ElapsedTime / (2.0 / 24.0)); // Epoch updates every 2 hours
RawEpoch := ElapsedEpochs * $12; // Epoch increases by 0x12 each period
RawEpoch := RawEpoch + StartingEpoch; // calc new Epoch
RawEpoch := RawEpoch MOD $7FFF; // Epoch rolls over at $7FFF so use modulus
R.Epoch := SwapWordBytes(RawEpoch); // Make it big-endian and write it to offset 0x16..0x17 in the RTC payload
I know you PHP guys have figured out a way to simulate a registration. Does this initialize the Epoch to zero, or does it retain the original value?
If it set the Epoch to zero, then we are in Fat City - because everyone can use the same StartingEpoch. If not, then something else will have to be done. I would like to remove all dependency on the LCX cloud server.