Difference between revisions of "Landis+Gyr GridStream Protocol"
Line 9: | Line 9: | ||
===Packet Structure=== | ===Packet Structure=== | ||
− | ====Sync | + | ====Sync and Header==== |
− | + | ----The sync word that the Landis+Gyr smart meters send is shown below, this can be used in GNU Radio or other tools to receive only packets transmitted by the meters. Note that at the start of the header we begin using start and stop bits. These must be stripped off the the data during processing. | |
− | + | {| class="wikitable" | |
− | + | |+Sync and Header | |
− | + | ! colspan="6" |Sync | |
− | + | ! colspan="3" |Header | |
− | + | |- | |
− | + | !0xAA | |
− | + | !0xAA | |
− | 10101010 10101010 10101010 10101010 | + | !0xAA |
− | + | !0xAA | |
− | + | !0xAA | |
− | + | !0xA | |
− | + | !0x00 | |
− | + | !0xFF | |
+ | !0x2A | ||
+ | |- | ||
+ | |10101010 | ||
+ | |10101010 | ||
+ | |10101010 | ||
+ | |10101010 | ||
+ | |10101010 | ||
+ | |1010 | ||
+ | |0 '''00000000''' 1 | ||
+ | |0 '''11111111''' 1 | ||
+ | |0 '''00101010''' 1 | ||
+ | |} | ||
+ | Using GNU Radio it was found that shortening the Sync requirements a bit and incorporating part of the header leads to the cleanest data for further downstream processing. The modified sync shown in 8 bit chunks is shown below. | ||
+ | {| class="wikitable" | ||
+ | |+Sync Word used with GNURadio | ||
+ | !0xAA | ||
+ | !0xAA | ||
+ | !0xAA | ||
+ | !0xAA | ||
+ | !0xA0 | ||
+ | !0x05 | ||
+ | !0xFF | ||
+ | |- | ||
+ | |10101010 | ||
+ | |10101010 | ||
+ | |10101010 | ||
+ | |10101010 | ||
+ | |10100000 | ||
+ | |00000101 | ||
+ | |11111111 | ||
+ | |} | ||
+ | The final byte of the sync (0x2A) along with it's start and stop bits are discarded as part of the processing. | ||
+ | ----<br /> | ||
====Type, Length and Sub Type==== | ====Type, Length and Sub Type==== | ||
− | + | ----Add data here | |
+ | <br /> | ||
+ | ----<br /> | ||
====Data==== | ====Data==== | ||
− | + | ----Add data here | |
+ | ----<br /> | ||
====Checksum==== | ====Checksum==== | ||
<br /> | <br /> | ||
Line 345: | Line 381: | ||
{| class="wikitable" | {| class="wikitable" | ||
|+0xD5 Captured packet | |+0xD5 Captured packet | ||
+ | ! rowspan="3" |Pkt | ||
+ | !1 | ||
+ | !2 | ||
+ | !3 | ||
+ | | | ||
+ | !4 | ||
+ | !5 | ||
+ | !6 | ||
+ | !7 | ||
+ | !8 | ||
+ | !9 | ||
+ | !10 | ||
+ | | | ||
+ | !11 | ||
+ | !12 | ||
+ | |- | ||
+ | ! colspan="3" |Not part of CRC calc | ||
+ | | | ||
+ | ! colspan="7" |Data | ||
+ | | | ||
! | ! | ||
+ | ! | ||
+ | |- | ||
!Header | !Header | ||
!Type | !Type | ||
!Length | !Length | ||
+ | | | ||
!SubType | !SubType | ||
!Meter ID #1 | !Meter ID #1 | ||
Line 356: | Line 415: | ||
!Unknown | !Unknown | ||
!Unknown | !Unknown | ||
+ | | | ||
!CRC | !CRC | ||
!Trailing | !Trailing | ||
|- | |- | ||
− | | | + | |1 |
|00FF2A | |00FF2A | ||
|D5 | |D5 | ||
|0016 | |0016 | ||
+ | ! | ||
|21 | |21 | ||
|F05FCB84 | |F05FCB84 | ||
Line 370: | Line 431: | ||
|273205 | |273205 | ||
|00781930 | |00781930 | ||
+ | ! | ||
|CB72 | |CB72 | ||
|00 | |00 | ||
Line 379: | Line 441: | ||
<code>3) Packet Length = 0x0016</code> | <code>3) Packet Length = 0x0016</code> | ||
− | <code>4) Unknown | + | <code>4) Unknown = 0x21</code> |
<code>5) Meter ID #1 = F05FCB84</code> | <code>5) Meter ID #1 = F05FCB84</code> | ||
Line 385: | Line 447: | ||
<code>6) Meter ID #2 = F0FC4DB1</code> | <code>6) Meter ID #2 = F0FC4DB1</code> | ||
− | <code>7) Unknown | + | <code>7) Unknown = 0xE288</code> |
− | <code>8) Unknown | + | <code>8) Unknown = 0x0100</code> |
− | <code>9) Unknown | + | <code>9) Unknown= 0x273205</code> |
− | <code>10) Unknown | + | <code>10) Unknown = 0x00781930</code> |
<code>11) Checksum = 0xCB72</code> | <code>11) Checksum = 0xCB72</code> |
Revision as of 00:00, 6 March 2021
Contents
Reverse Engineering and Analysis
Packet Structure
Sync and Header
The sync word that the Landis+Gyr smart meters send is shown below, this can be used in GNU Radio or other tools to receive only packets transmitted by the meters. Note that at the start of the header we begin using start and stop bits. These must be stripped off the the data during processing.
Sync | Header | |||||||
---|---|---|---|---|---|---|---|---|
0xAA | 0xAA | 0xAA | 0xAA | 0xAA | 0xA | 0x00 | 0xFF | 0x2A |
10101010 | 10101010 | 10101010 | 10101010 | 10101010 | 1010 | 0 00000000 1 | 0 11111111 1 | 0 00101010 1 |
Using GNU Radio it was found that shortening the Sync requirements a bit and incorporating part of the header leads to the cleanest data for further downstream processing. The modified sync shown in 8 bit chunks is shown below.
0xAA | 0xAA | 0xAA | 0xAA | 0xA0 | 0x05 | 0xFF |
---|---|---|---|---|---|---|
10101010 | 10101010 | 10101010 | 10101010 | 10100000 | 00000101 | 11111111 |
The final byte of the sync (0x2A) along with it's start and stop bits are discarded as part of the processing.
Type, Length and Sub Type
Add data here
Data
Add data here
Checksum
Captured Meter Data
There have been two packet types observed thus far, a 0x55 and a 0xD5 packet.
- 0x55 appears to be broadcasts from the meters and happen frequently. They have been observed multiple times per minute from a single meter.
- 0xD5 appears to be a packet for transporting data across the mesh network. Each D5 packet will contain two meter ID's, Meter ID #1 and Meter ID #2. There are many 0xD5 packet length and types that have been observed, some are shown below.
0x55 Meter Data
The data below was captured from the same meter (F0EE36DB) and shows some of the values that can change with each transmission. Different meters have different fixed data and some of the data changes less frequently as well.
Pkt | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Not part of CRC calc | Data | |||||||||||||||||||
Header | Type | Length | SubType | Unknown | Unknown | Unknown | Unknown | Counter | Uptime (seconds) | Unknown | Meter ID | Unknown | Unknown | Unknown | Unknown | CRC | Trailing | |||
1 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 0C | 0001ECBF | A483 | F0EE36DB | 0100 | 2132 | 04384F | 7E80 | 0896 | 04 | ||
2 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 16 | 0001ECC6 | A483 | F0EE36DB | 0100 | 2132 | 043AC5 | 7E80 | F47E | 04 | ||
3 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 2A | 0001ED05 | A483 | F0EE36DB | 0100 | 2132 | 041207 | 7E80 | A412 | 04 | ||
4 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 34 | 0001ED29 | A483 | F0EE36DB | 0100 | 2132 | 041FF9 | 7E80 | D9C4 | 04 | ||
5 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 38 | 0001ED37 | A483 | F0EE36DB | 0100 | 2132 | 042571 | 7E80 | 963C | 04 | ||
6 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 42 | 0001ED5C | A483 | F0EE36DB | 0100 | 2132 | 0433A9 | 7E80 | 8384 | 04 | ||
7 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 4C | 0001ED60 | A483 | F0EE36DB | 0100 | 2132 | 04354D | 7E80 | 2CB6 | 04 | ||
8 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 4E | 0001ED79 | A483 | F0EE36DB | 0100 | 2132 | 043F25 | 7E80 | 871A | 04 | ||
9 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 60 | 0001EDA6 | A483 | F0EE36DB | 0100 | 2132 | 040F05 | 7E80 | 25C9 | 04 | ||
10 | 00FF2A | 55 | 0023 | 30 | FFFFFFFFFFFF | 50 | CF8DD9E2 | C0 | 6A | 0001EDCD | A483 | F0EE36DB | 0100 | 2132 | 041E55 | 7E80 | F33F | 04 |
1) Header = 0x00FF2A
2) Packet Type = 0x55
3) Packet Length = 0x0023
4) SubType = 0x30
5) Unknown = FFFFFFFFFFFF (Empty Data Slot?)
6) Unknown = 0x50
7) Unknown = CF8DD9E2 (Appears to either be location identifier or duplicate meter ID in some cases)
8) Unknown = C0
9) Counter = 02 (Increments some amount with each transmission and rolls over at 0xFF)
10) Uptime = 0x0001ECA3 (Value in seconds since meter powered on, easy way to see last time there was an outage!)
11) Unknown Identifier #5 = 0xA483
12) Meter ID = 0xF0EE36DB
13) Unknown = 0x0100
14) Unknown = 0x2132
15) Unknown = 0x042D19
16) Unknown = 0x7E80
17) Checksum = 0xF154
18) Trailing byte = 0x04
0xD5 Meter Data
There appear to be multiple packet lengths and styles for the 0xD5 packet. There are some samples below showing
Pkt | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Not part of CRC calc | Data | |||||||||||||
Header | Type | Length | SubType | Meter ID #1 | Meter ID #2 | Unknown | Unknown | Unknown | Unknown | CRC | Trailing | |||
1 | 00FF2A | D5 | 0016 | 21 | F05FCB84 | F0FC4DB1 | E288 | 0100 | 273205 | 00781930 | CB72 | 00 |
1) Header = 0x00FF2A
2) Packet Type = 0xD5
3) Packet Length = 0x0016
4) Unknown = 0x21
5) Meter ID #1 = F05FCB84
6) Meter ID #2 = F0FC4DB1
7) Unknown = 0xE288
8) Unknown = 0x0100
9) Unknown= 0x273205
10) Unknown = 0x00781930
11) Checksum = 0xCB72
12) Trailing byte = 0x00
00FF2A D5 0016 21 F073B577 F062363D FA88 0100 1F6C04 14E93E70 CF80 04
00FF2A D5 0017 29 8073AEAC F0F28D56 1288 0100 1F3204 041CBB1930 2D2A 04
00FF2A D5 001B 21 F10679E2 8073CE7D F498 0100 106C02 0A15F9055F06571A80 37C5 00
00FF2A D5 001C 29 8073ADB3 8073CE7D 9088 0100 106C02 040A99CF055F3A4B1170 A696 04
00FF2A D5 0021 22 F05A1A60 8073CE7D D8010100106C020520301D81800A99CF055F3ADD1410 A560 04
00FF2A D5 0047 51 F05A4BCC F03D4CD7 5A6032F37F0001DA2E00022BE9 A483 010150D075D9E2E0 F03D4CD7
000103240403030806080801000000036EE8001F6C0401E9203020818018C22930 9294 00