alim-zanibekov / teltonika

Teltonika TCP/UDP codecs implementation in go
MIT License
16 stars 4 forks source link

Interesting packet from FMC880 (firmware bug in FMC880?) #4

Open borud opened 4 months ago

borud commented 4 months ago

hi,

Thanks for a great library. I started using it and things seem to work pretty well. Today I came across a packet from an FMC880 that the device keeps trying to send to the server over and over again.

The packet is sent over TCP and this is the hex encoding of it (this is just a dump of the entire buffer, so the stuff at the end is just zeroes from the zeroed buffer):

00000000000003c68e04000001909d6417c801062c583a25ce28b9004f004530000000ef0011000500ef0000f00100150300c800004501000a00b5000800b60004004234a90018000000430ef700440052001100900012fc4c0013fb77000f03e8000200f100005e89001000003f9a00000000000001909d606e5201062bc70c25ccd6d50096010032000000ef0011000500ef0100f00100150500c800004501000a00b5000800b60005004237780018000000430ed500440000001100da0012fd0e0013f9ef000f03e8000200f100005e89001000003a6400000000000001909d4f2c5001062bc70c25ccd6d5009601002c000000ef0011000500ef0000f00100150500c800004501000a00b5000800b60005004234b10018000000430f0300440041001100db0012fd0d0013f9e9000f0047000200f100005e89001000003a6400000000000001909d4e03d501062c0f5025cdd1170068008130004800f700030002013d0100f70500000000000000010101025801dffe02f95d01c2fdc4f97001b1fde2f96f0193fdd2f97001a1fe01f95f0171fdfff95001b1fdf3f97e01a1fe01f95f0200fdd5f97d01eefe12f95c01affe31f96d01d0fe33f9aa01cffe62f9a901b1fe43f9ba01a0fe51f99b0200fe05f99b01d0fe33f99b0170fe6ff99b0161fe6ff9ab0164fe22f9cd0192fe22f99d0183fe32f9cc0170fe6ff99b0142fe4ff99d0133fe6ef9bc0172fe30f99d01c2fe15f9cb019ffe70f99a0182fe11f97e0183fdf2f99f0152fe2ff98e0163fe21f9ae0181fe2ff96e0152fe2ff98e0162fe30f98e0191fe11f97e01c0fe12f97d019ffe20f94e0180fe2ff95e0192fde1f96001a1fdf1f95f01d1fdc4f96f01a2fdc2f95101bffdf0f9300182fde1f96101d1fdb3f94101a1fdd0f93201c2fda3f95101b1fdd1f94101b1fdd1f94101effde3f94e01b0fdf1f94001c0fde1f94001c1fdd2f9500171fdeef92201b0fde1f94001a1fdc1f93201a0fdc0f9130171fdcff92301dffdb2f9120190fdfff9300191fde0f9410191fe00f95f0172fdd0f94201cffde1f92001bdfdeef8e201affdd0f91201c0fdc2f93101a1fdb1f93301bffde0f92101f1fd74f92301a1fd80f8f601d1fd83f91401a0fdaff8f401a0fde0f92101affdc0f90301bffdd0f90201dffdb1f90201cefdbff8e301eefda2f8f3019ffdaef8c501f0fd94f932019ffddff90201b0fe01f94f01ddfdfff90001bbfe4cf8ee01befe30f94d01cdfe1ff90f01cffdf2f94f019ffe1ff93f01b1fdd2f9600191fe00f95f0184fdc3f9910192fe12f99d01a0fe10f95e0180fe4ff97c01a1fe31f98c01a0fe21f96e0193fdf2f98f0191fe21f98d0400006a960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

I wrote my own parser for the packet and IO elements and it seems to confirm that your code is correct. The packet looks corrupt since NumberOfData1 equals 4 and NumberOfData2 equals 1. And your teltonika.DecodeTCPFromSlice function returns the error 'Number of Data 1' is not equal to 'Number of Data 2'. 4 != 1".

I thought I'd give you a copy of the packet in case you see something that is off here. But I think both your code and mine parses it correctly and correctly concludes it is buggy. Right?

borud commented 4 months ago

The test code looks like this:

package server

import (
    "encoding/binary"
    "encoding/hex"
    "fmt"
    "testing"
    "time"

    "github.com/alim-zanibekov/teltonika"
    "github.com/davecgh/go-spew/spew"
    "github.com/lab5e/tracker/pkg/bufreader"
    "github.com/stretchr/testify/require"
)

const (
    data = "00000000000003c68e04000001909d6417c801062c583a25ce28b9004f004530000000ef0011000500ef0000f00100150300c800004501000a00b5000800b60004004234a90018000000430ef700440052001100900012fc4c0013fb77000f03e8000200f100005e89001000003f9a00000000000001909d606e5201062bc70c25ccd6d50096010032000000ef0011000500ef0100f00100150500c800004501000a00b5000800b60005004237780018000000430ed500440000001100da0012fd0e0013f9ef000f03e8000200f100005e89001000003a6400000000000001909d4f2c5001062bc70c25ccd6d5009601002c000000ef0011000500ef0000f00100150500c800004501000a00b5000800b60005004234b10018000000430f0300440041001100db0012fd0d0013f9e9000f0047000200f100005e89001000003a6400000000000001909d4e03d501062c0f5025cdd1170068008130004800f700030002013d0100f70500000000000000010101025801dffe02f95d01c2fdc4f97001b1fde2f96f0193fdd2f97001a1fe01f95f0171fdfff95001b1fdf3f97e01a1fe01f95f0200fdd5f97d01eefe12f95c01affe31f96d01d0fe33f9aa01cffe62f9a901b1fe43f9ba01a0fe51f99b0200fe05f99b01d0fe33f99b0170fe6ff99b0161fe6ff9ab0164fe22f9cd0192fe22f99d0183fe32f9cc0170fe6ff99b0142fe4ff99d0133fe6ef9bc0172fe30f99d01c2fe15f9cb019ffe70f99a0182fe11f97e0183fdf2f99f0152fe2ff98e0163fe21f9ae0181fe2ff96e0152fe2ff98e0162fe30f98e0191fe11f97e01c0fe12f97d019ffe20f94e0180fe2ff95e0192fde1f96001a1fdf1f95f01d1fdc4f96f01a2fdc2f95101bffdf0f9300182fde1f96101d1fdb3f94101a1fdd0f93201c2fda3f95101b1fdd1f94101b1fdd1f94101effde3f94e01b0fdf1f94001c0fde1f94001c1fdd2f9500171fdeef92201b0fde1f94001a1fdc1f93201a0fdc0f9130171fdcff92301dffdb2f9120190fdfff9300191fde0f9410191fe00f95f0172fdd0f94201cffde1f92001bdfdeef8e201affdd0f91201c0fdc2f93101a1fdb1f93301bffde0f92101f1fd74f92301a1fd80f8f601d1fd83f91401a0fdaff8f401a0fde0f92101affdc0f90301bffdd0f90201dffdb1f90201cefdbff8e301eefda2f8f3019ffdaef8c501f0fd94f932019ffddff90201b0fe01f94f01ddfdfff90001bbfe4cf8ee01befe30f94d01cdfe1ff90f01cffdf2f94f019ffe1ff93f01b1fdd2f9600191fe00f95f0184fdc3f9910192fe12f99d01a0fe10f95e0180fe4ff97c01a1fe31f98c01a0fe21f96e0193fdf2f98f0191fe21f98d0400006a960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
)

func TestBuggyPacket(t *testing.T) {
    packet, err := hex.DecodeString(data)
    require.NoError(t, err)

    b := bufreader.New(packet, binary.BigEndian)

    preamble, err := b.Uint32()
    require.NoError(t, err)
    fmt.Printf("preamble = %d\n", preamble)

    length, err := b.Uint32()
    require.NoError(t, err)
    fmt.Printf("length = %d\n", length)

    codec, err := b.Uint8()
    require.NoError(t, err)
    fmt.Printf("codec = 0x%02x\n", codec)

    numdata1, err := b.Uint8()
    require.NoError(t, err)
    fmt.Printf("numdata = %d\n", numdata1)

    for i := 0; i < 4; i++ {
        println("element ", i)

        timestamp, err := b.Int64()
        require.NoError(t, err)
        fmt.Printf("  timestamp = %d (%s)\n", timestamp, time.UnixMilli(timestamp).Format(time.RFC3339))

        priority, err := b.Uint8()
        require.NoError(t, err)
        fmt.Printf("  priority = %d\n", priority)

        lon, err := b.Int32()
        require.NoError(t, err)
        fmt.Printf("  lon = %d\n", lon)

        lat, err := b.Int32()
        require.NoError(t, err)
        fmt.Printf("  lat = %d\n", lat)

        alt, err := b.Int16()
        require.NoError(t, err)
        fmt.Printf("  alt = %d\n", alt)

        angle, err := b.Int16()
        require.NoError(t, err)
        fmt.Printf("  angle = %d\n", angle)

        sat, err := b.Uint8()
        require.NoError(t, err)
        fmt.Printf("  sat = %d\n", sat)

        speed, err := b.Int16()
        require.NoError(t, err)
        fmt.Printf("  speed = %d\n", speed)

        eventID, err := b.Uint16()
        require.NoError(t, err)
        fmt.Printf("  eventID = %d\n", eventID)

        ioCount, err := b.Uint16()
        require.NoError(t, err)

        k := 0

        for i := 1; i <= 8; i *= 2 {
            n, err := b.Uint16()
            require.NoError(t, err)

            for j := 0; j < int(n); j++ {
                id, err := b.Uint16()
                require.NoError(t, err)
                value, err := b.ReadBytes(i)
                require.NoError(t, err)

                if k >= int(ioCount) {
                    require.Fail(t, fmt.Errorf("too many i/o elements, expected at most %d, found %d", ioCount, k).Error())
                }

                fmt.Printf("    - ioelement id=%d = data=%s\n", id, hex.EncodeToString(value))

                k++
            }

        }

        ioCountNX, err := b.Uint16()
        require.NoError(t, err)
        fmt.Printf("  ioCountNX = %d\n", ioCountNX)
        fmt.Printf("  k = %d\n", k)

        for i := k; i < int(ioCountNX); i++ {

            id, err := b.Uint16()
            require.NoError(t, err)

            length, err := b.Uint16()
            require.NoError(t, err)

            value, err := b.ReadBytes(int(length))
            require.NoError(t, err)

            if i >= int(ioCount) {
                require.Fail(t, fmt.Errorf("too many i/o elements, expected at most %d, found %d", ioCount, i).Error())
            }

            fmt.Printf("    - ionx id=%d = data=%s\n", id, hex.EncodeToString(value))
        }

    }

    numdata2, err := b.Uint8()
    require.NoError(t, err)
    fmt.Printf("numdata = %d\n", numdata2)

    checksum, err := b.Uint32()
    require.NoError(t, err)
    fmt.Printf("checksum = %d\n", checksum)

    remain := b.Remaining()

    rest, err := b.ReadBytes(remain)
    require.NoError(t, err)
    fmt.Printf("REMAIN: %d\n", remain)
    fmt.Printf("rest = %s\n", hex.EncodeToString(rest))

    fmt.Println("--------------------------------------------------------------------")
    // require.NoError(t, err)
    n, pkt, err := teltonika.DecodeTCPFromSlice(packet)
    fmt.Printf("err=%v\n", err)
    fmt.Printf("n = %d\n", n)
    fmt.Printf("pkt = %+v\n", pkt)

    spew.Dump(packet)

}

and the output it generated looks like this:


=== RUN   TestBuggyPacket
preamble = 0
length = 966
codec = 0x8e
numdata = 4
element  0
  timestamp = 1720627501000 (2024-07-10T18:05:01+02:00)
  priority = 1
  lon = 103569466
  lat = 634267833
  alt = 79
  angle = 69
  sat = 48
  speed = 0
  eventID = 239
    - ioelement id=239 = data=00
    - ioelement id=240 = data=01
    - ioelement id=21 = data=03
    - ioelement id=200 = data=00
    - ioelement id=69 = data=01
    - ioelement id=181 = data=0008
    - ioelement id=182 = data=0004
    - ioelement id=66 = data=34a9
    - ioelement id=24 = data=0000
    - ioelement id=67 = data=0ef7
    - ioelement id=68 = data=0052
    - ioelement id=17 = data=0090
    - ioelement id=18 = data=fc4c
    - ioelement id=19 = data=fb77
    - ioelement id=15 = data=03e8
    - ioelement id=241 = data=00005e89
    - ioelement id=16 = data=00003f9a
  ioCountNX = 0
  k = 17
element  1
  timestamp = 1720627261010 (2024-07-10T18:01:01+02:00)
  priority = 1
  lon = 103532300
  lat = 634181333
  alt = 150
  angle = 256
  sat = 50
  speed = 0
  eventID = 239
    - ioelement id=239 = data=01
    - ioelement id=240 = data=01
    - ioelement id=21 = data=05
    - ioelement id=200 = data=00
    - ioelement id=69 = data=01
    - ioelement id=181 = data=0008
    - ioelement id=182 = data=0005
    - ioelement id=66 = data=3778
    - ioelement id=24 = data=0000
    - ioelement id=67 = data=0ed5
    - ioelement id=68 = data=0000
    - ioelement id=17 = data=00da
    - ioelement id=18 = data=fd0e
    - ioelement id=19 = data=f9ef
    - ioelement id=15 = data=03e8
    - ioelement id=241 = data=00005e89
    - ioelement id=16 = data=00003a64
  ioCountNX = 0
  k = 17
element  2
  timestamp = 1720626130000 (2024-07-10T17:42:10+02:00)
  priority = 1
  lon = 103532300
  lat = 634181333
  alt = 150
  angle = 256
  sat = 44
  speed = 0
  eventID = 239
    - ioelement id=239 = data=00
    - ioelement id=240 = data=01
    - ioelement id=21 = data=05
    - ioelement id=200 = data=00
    - ioelement id=69 = data=01
    - ioelement id=181 = data=0008
    - ioelement id=182 = data=0005
    - ioelement id=66 = data=34b1
    - ioelement id=24 = data=0000
    - ioelement id=67 = data=0f03
    - ioelement id=68 = data=0041
    - ioelement id=17 = data=00db
    - ioelement id=18 = data=fd0d
    - ioelement id=19 = data=f9e9
    - ioelement id=15 = data=0047
    - ioelement id=241 = data=00005e89
    - ioelement id=16 = data=00003a64
  ioCountNX = 0
  k = 17
element  3
  timestamp = 1720626054101 (2024-07-10T17:40:54+02:00)
  priority = 1
  lon = 103550800
  lat = 634245399
  alt = 104
  angle = 129
  sat = 48
  speed = 72
  eventID = 247
    - ioelement id=317 = data=01
    - ioelement id=247 = data=05
  ioCountNX = 1
  k = 2
numdata = 1
checksum = 16930817
REMAIN: 1674
rest = dffe02f95d01c2fdc4f97001b1fde2f96f0193fdd2f97001a1fe01f95f0171fdfff95001b1fdf3f97e01a1fe01f95f0200fdd5f97d01eefe12f95c01affe31f96d01d0fe33f9aa01cffe62f9a901b1fe43f9ba01a0fe51f99b0200fe05f99b01d0fe33f99b0170fe6ff99b0161fe6ff9ab0164fe22f9cd0192fe22f99d0183fe32f9cc0170fe6ff99b0142fe4ff99d0133fe6ef9bc0172fe30f99d01c2fe15f9cb019ffe70f99a0182fe11f97e0183fdf2f99f0152fe2ff98e0163fe21f9ae0181fe2ff96e0152fe2ff98e0162fe30f98e0191fe11f97e01c0fe12f97d019ffe20f94e0180fe2ff95e0192fde1f96001a1fdf1f95f01d1fdc4f96f01a2fdc2f95101bffdf0f9300182fde1f96101d1fdb3f94101a1fdd0f93201c2fda3f95101b1fdd1f94101b1fdd1f94101effde3f94e01b0fdf1f94001c0fde1f94001c1fdd2f9500171fdeef92201b0fde1f94001a1fdc1f93201a0fdc0f9130171fdcff92301dffdb2f9120190fdfff9300191fde0f9410191fe00f95f0172fdd0f94201cffde1f92001bdfdeef8e201affdd0f91201c0fdc2f93101a1fdb1f93301bffde0f92101f1fd74f92301a1fd80f8f601d1fd83f91401a0fdaff8f401a0fde0f92101affdc0f90301bffdd0f90201dffdb1f90201cefdbff8e301eefda2f8f3019ffdaef8c501f0fd94f932019ffddff90201b0fe01f94f01ddfdfff90
001bbfe4cf8ee01befe30f94d01cdfe1ff90f01cffdf2f94f019ffe1ff93f01b1fdd2f9600191fe00f95f0184fdc3f9910192fe12f99d01a0fe10f95e0180fe4ff97c01a1fe31f98c01a0fe21f96e0193fdf2f98f0191fe21f98d0400006a9600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
--------------------------------------------------------------------
err='Number of Data 1' is not equal to 'Number of Data 2'. 4 != 1
n = 0
pkt = <nil>
([]uint8) (len=2048 cap=4096) {
 00000000  00 00 00 00 00 00 03 c6  8e 04 00 00 01 90 9d 64  |...............d|
 00000010  17 c8 01 06 2c 58 3a 25  ce 28 b9 00 4f 00 45 30  |....,X:%.(..O.E0|
 00000020  00 00 00 ef 00 11 00 05  00 ef 00 00 f0 01 00 15  |................|
 00000030  03 00 c8 00 00 45 01 00  0a 00 b5 00 08 00 b6 00  |.....E..........|
 00000040  04 00 42 34 a9 00 18 00  00 00 43 0e f7 00 44 00  |..B4......C...D.|
 00000050  52 00 11 00 90 00 12 fc  4c 00 13 fb 77 00 0f 03  |R.......L...w...|
 00000060  e8 00 02 00 f1 00 00 5e  89 00 10 00 00 3f 9a 00  |.......^.....?..|
 00000070  00 00 00 00 00 01 90 9d  60 6e 52 01 06 2b c7 0c  |........`nR..+..|
 00000080  25 cc d6 d5 00 96 01 00  32 00 00 00 ef 00 11 00  |%.......2.......|
 00000090  05 00 ef 01 00 f0 01 00  15 05 00 c8 00 00 45 01  |..............E.|
 000000a0  00 0a 00 b5 00 08 00 b6  00 05 00 42 37 78 00 18  |...........B7x..|
 000000b0  00 00 00 43 0e d5 00 44  00 00 00 11 00 da 00 12  |...C...D........|
 000000c0  fd 0e 00 13 f9 ef 00 0f  03 e8 00 02 00 f1 00 00  |................|
 000000d0  5e 89 00 10 00 00 3a 64  00 00 00 00 00 00 01 90  |^.....:d........|
 000000e0  9d 4f 2c 50 01 06 2b c7  0c 25 cc d6 d5 00 96 01  |.O,P..+..%......|
 000000f0  00 2c 00 00 00 ef 00 11  00 05 00 ef 00 00 f0 01  |.,..............|
 00000100  00 15 05 00 c8 00 00 45  01 00 0a 00 b5 00 08 00  |.......E........|
 00000110  b6 00 05 00 42 34 b1 00  18 00 00 00 43 0f 03 00  |....B4......C...|
 00000120  44 00 41 00 11 00 db 00  12 fd 0d 00 13 f9 e9 00  |D.A.............|
 00000130  0f 00 47 00 02 00 f1 00  00 5e 89 00 10 00 00 3a  |..G......^.....:|
 00000140  64 00 00 00 00 00 00 01  90 9d 4e 03 d5 01 06 2c  |d.........N....,|
 00000150  0f 50 25 cd d1 17 00 68  00 81 30 00 48 00 f7 00  |.P%....h..0.H...|
 00000160  03 00 02 01 3d 01 00 f7  05 00 00 00 00 00 00 00  |....=...........|
 00000170  01 01 01 02 58 01 df fe  02 f9 5d 01 c2 fd c4 f9  |....X.....].....|
 00000180  70 01 b1 fd e2 f9 6f 01  93 fd d2 f9 70 01 a1 fe  |p.....o.....p...|
 00000190  01 f9 5f 01 71 fd ff f9  50 01 b1 fd f3 f9 7e 01  |.._.q...P.....~.|
 000001a0  a1 fe 01 f9 5f 02 00 fd  d5 f9 7d 01 ee fe 12 f9  |...._.....}.....|
 000001b0  5c 01 af fe 31 f9 6d 01  d0 fe 33 f9 aa 01 cf fe  |\...1.m...3.....|
 000001c0  62 f9 a9 01 b1 fe 43 f9  ba 01 a0 fe 51 f9 9b 02  |b.....C.....Q...|
 000001d0  00 fe 05 f9 9b 01 d0 fe  33 f9 9b 01 70 fe 6f f9  |........3...p.o.|
 000001e0  9b 01 61 fe 6f f9 ab 01  64 fe 22 f9 cd 01 92 fe  |..a.o...d.".....|
 000001f0  22 f9 9d 01 83 fe 32 f9  cc 01 70 fe 6f f9 9b 01  |".....2...p.o...|
 00000200  42 fe 4f f9 9d 01 33 fe  6e f9 bc 01 72 fe 30 f9  |B.O...3.n...r.0.|
 00000210  9d 01 c2 fe 15 f9 cb 01  9f fe 70 f9 9a 01 82 fe  |..........p.....|
 00000220  11 f9 7e 01 83 fd f2 f9  9f 01 52 fe 2f f9 8e 01  |..~.......R./...|
 00000230  63 fe 21 f9 ae 01 81 fe  2f f9 6e 01 52 fe 2f f9  |c.!...../.n.R./.|
 00000240  8e 01 62 fe 30 f9 8e 01  91 fe 11 f9 7e 01 c0 fe  |..b.0.......~...|
 00000250  12 f9 7d 01 9f fe 20 f9  4e 01 80 fe 2f f9 5e 01  |..}... .N.../.^.|
 00000260  92 fd e1 f9 60 01 a1 fd  f1 f9 5f 01 d1 fd c4 f9  |....`....._.....|
 00000270  6f 01 a2 fd c2 f9 51 01  bf fd f0 f9 30 01 82 fd  |o.....Q.....0...|
 00000280  e1 f9 61 01 d1 fd b3 f9  41 01 a1 fd d0 f9 32 01  |..a.....A.....2.|
 00000290  c2 fd a3 f9 51 01 b1 fd  d1 f9 41 01 b1 fd d1 f9  |....Q.....A.....|
 000002a0  41 01 ef fd e3 f9 4e 01  b0 fd f1 f9 40 01 c0 fd  |A.....N.....@...|
 000002b0  e1 f9 40 01 c1 fd d2 f9  50 01 71 fd ee f9 22 01  |..@.....P.q...".|
 000002c0  b0 fd e1 f9 40 01 a1 fd  c1 f9 32 01 a0 fd c0 f9  |....@.....2.....|
 000002d0  13 01 71 fd cf f9 23 01  df fd b2 f9 12 01 90 fd  |..q...#.........|
 000002e0  ff f9 30 01 91 fd e0 f9  41 01 91 fe 00 f9 5f 01  |..0.....A....._.|
 000002f0  72 fd d0 f9 42 01 cf fd  e1 f9 20 01 bd fd ee f8  |r...B..... .....|
 00000300  e2 01 af fd d0 f9 12 01  c0 fd c2 f9 31 01 a1 fd  |............1...|
 00000310  b1 f9 33 01 bf fd e0 f9  21 01 f1 fd 74 f9 23 01  |..3.....!...t.#.|
 00000320  a1 fd 80 f8 f6 01 d1 fd  83 f9 14 01 a0 fd af f8  |................|
 00000330  f4 01 a0 fd e0 f9 21 01  af fd c0 f9 03 01 bf fd  |......!.........|
 00000340  d0 f9 02 01 df fd b1 f9  02 01 ce fd bf f8 e3 01  |................|
 00000350  ee fd a2 f8 f3 01 9f fd  ae f8 c5 01 f0 fd 94 f9  |................|
 00000360  32 01 9f fd df f9 02 01  b0 fe 01 f9 4f 01 dd fd  |2...........O...|
 00000370  ff f9 00 01 bb fe 4c f8  ee 01 be fe 30 f9 4d 01  |......L.....0.M.|
 00000380  cd fe 1f f9 0f 01 cf fd  f2 f9 4f 01 9f fe 1f f9  |..........O.....|
 00000390  3f 01 b1 fd d2 f9 60 01  91 fe 00 f9 5f 01 84 fd  |?.....`....._...|
 000003a0  c3 f9 91 01 92 fe 12 f9  9d 01 a0 fe 10 f9 5e 01  |..............^.|
 000003b0  80 fe 4f f9 7c 01 a1 fe  31 f9 8c 01 a0 fe 21 f9  |..O.|...1.....!.|
 000003c0  6e 01 93 fd f2 f9 8f 01  91 fe 21 f9 8d 04 00 00  |n.........!.....|
 000003d0  6a 96 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |j...............|
 000003e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000003f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000400  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000420  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000430  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000440  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000450  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000460  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000470  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000480  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000490  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000004a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000004b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000004c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000004d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000004e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000004f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000500  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000510  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000520  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000530  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000540  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000550  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000560  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000570  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000580  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000590  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000005a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000005b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000005c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000005d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000005e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000005f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000600  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000610  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000620  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000630  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000640  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000650  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000660  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000670  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000680  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000690  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000006a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000006b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000006c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000006d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000006e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000006f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000700  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000710  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000720  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000730  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000740  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000750  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000760  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000770  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000780  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000790  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000007a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000007b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000007c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000007d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000007e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 000007f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
}
alim-zanibekov commented 4 months ago

Hi @borud, thank you for the feedback!

It seems we both made a mistake in the code :)

"Number of Data 1" and "Number of Data 2" in your packet

00000000000003c68e0400 ... 98d0400006a96
                   ⌃ n1        ⌃ n2

I made a mistake in the 8E codec I/O elements decoding logic, specifically in the variable length I/O element read loop, I fixed the problem and now everything is working fine

package main

import (
    "encoding/hex"
    "fmt"

    "github.com/alim-zanibekov/teltonika"
    "github.com/alim-zanibekov/teltonika/ioelements"
)

func main() {
    packetHex := "00000000000003c68e04000001909d6417c801062c583a25ce28b9004f004530000000ef0011000500ef0000f0010015030" +
        "0c800004501000a00b5000800b60004004234a90018000000430ef700440052001100900012fc4c0013fb77000f03e8000200f100005" +
        "e89001000003f9a00000000000001909d606e5201062bc70c25ccd6d50096010032000000ef0011000500ef0100f00100150500c8000" +
        "04501000a00b5000800b60005004237780018000000430ed500440000001100da0012fd0e0013f9ef000f03e8000200f100005e89001" +
        "000003a6400000000000001909d4f2c5001062bc70c25ccd6d5009601002c000000ef0011000500ef0000f00100150500c8000045010" +
        "00a00b5000800b60005004234b10018000000430f0300440041001100db0012fd0d0013f9e9000f0047000200f100005e89001000003" +
        "a6400000000000001909d4e03d501062c0f5025cdd1170068008130004800f700030002013d0100f7050000000000000001010102580" +
        "1dffe02f95d01c2fdc4f97001b1fde2f96f0193fdd2f97001a1fe01f95f0171fdfff95001b1fdf3f97e01a1fe01f95f0200fdd5f97d0" +
        "1eefe12f95c01affe31f96d01d0fe33f9aa01cffe62f9a901b1fe43f9ba01a0fe51f99b0200fe05f99b01d0fe33f99b0170fe6ff99b0" +
        "161fe6ff9ab0164fe22f9cd0192fe22f99d0183fe32f9cc0170fe6ff99b0142fe4ff99d0133fe6ef9bc0172fe30f99d01c2fe15f9cb0" +
        "19ffe70f99a0182fe11f97e0183fdf2f99f0152fe2ff98e0163fe21f9ae0181fe2ff96e0152fe2ff98e0162fe30f98e0191fe11f97e0" +
        "1c0fe12f97d019ffe20f94e0180fe2ff95e0192fde1f96001a1fdf1f95f01d1fdc4f96f01a2fdc2f95101bffdf0f9300182fde1f9610" +
        "1d1fdb3f94101a1fdd0f93201c2fda3f95101b1fdd1f94101b1fdd1f94101effde3f94e01b0fdf1f94001c0fde1f94001c1fdd2f9500" +
        "171fdeef92201b0fde1f94001a1fdc1f93201a0fdc0f9130171fdcff92301dffdb2f9120190fdfff9300191fde0f9410191fe00f95f0" +
        "172fdd0f94201cffde1f92001bdfdeef8e201affdd0f91201c0fdc2f93101a1fdb1f93301bffde0f92101f1fd74f92301a1fd80f8f60" +
        "1d1fd83f91401a0fdaff8f401a0fde0f92101affdc0f90301bffdd0f90201dffdb1f90201cefdbff8e301eefda2f8f3019ffdaef8c50" +
        "1f0fd94f932019ffddff90201b0fe01f94f01ddfdfff90001bbfe4cf8ee01befe30f94d01cdfe1ff90f01cffdf2f94f019ffe1ff93f0" +
        "1b1fdd2f9600191fe00f95f0184fdc3f9910192fe12f99d01a0fe10f95e0180fe4ff97c01a1fe31f98c01a0fe21f96e0193fdf2f98f0" +
        "191fe21f98d0400006a96"

    packet, _ := hex.DecodeString(packetHex)
    _, decoded, err := teltonika.DecodeTCPFromSlice(packet)
    if err != nil {
        panic(err)
    }
    decoder := ioelements.DefaultDecoder()
    elements := make([][]*ioelements.IOElement, len(decoded.Packet.Data))
    for i, data := range decoded.Packet.Data {
        elements[i] = make([]*ioelements.IOElement, len(data.Elements))
        for j, element := range data.Elements {
            elements[i][j], err = decoder.Decode("*", element.Id, element.Value)
            if err != nil {
                panic(err)
            }
        }
    }

    for i, items := range elements {
        fmt.Printf("\nFrame #%d\n", i)
        d := decoded.Packet.Data[i]
        fmt.Printf("    timestamp: %v\n", d.TimestampMs)
        fmt.Printf("    priority: %v\n", d.Priority)
        fmt.Printf("    lng: %v\n", d.Lng)
        fmt.Printf("    lat: %v\n", d.Lat)
        fmt.Printf("    alt: %v\n", d.Altitude)
        fmt.Printf("    angle: %v\n", d.Angle)
        fmt.Printf("    speed: %v\n", d.Speed)
        fmt.Printf("    satellites: %v\n", d.Satellites)
        fmt.Printf("  I/O elements\n")
        for _, element := range items {
            fmt.Printf("    %s\n", element)
        }
    }
}

Output

Frame #0
    timestamp: 1720627501000
    priority: 1
    lng: 10.3569466
    lat: 63.4267833
    alt: 79
    angle: 69
    speed: 0
    satellites: 48
  I/O elements
    Ignition: false
    Movement: true
    GSM Signal: 3
    Sleep Mode: 0
    GNSS Status: 1
    GNSS PDOP: 0.800
    GNSS HDOP: 0.400
    External Voltage: 13.481V
    Speed: 0km/h
    Battery Voltage: 3.831V
    Battery Current: 0.082A
    Axis X: 144mG
    Axis Y: -948mG
    Axis Z: -1161mG
    Eco Score: 10.000
    Active GSM Operator: 24201
    Total Odometer: 16282

Frame #1
    timestamp: 1720627261010
    priority: 1
    lng: 10.35323
    lat: 63.4181333
    alt: 150
    angle: 256
    speed: 0
    satellites: 50
  I/O elements
    Ignition: true
    Movement: true
    GSM Signal: 5
    Sleep Mode: 0
    GNSS Status: 1
    GNSS PDOP: 0.800
    GNSS HDOP: 0.500
    External Voltage: 14.200V
    Speed: 0km/h
    Battery Voltage: 3.797V
    Battery Current: 0.000A
    Axis X: 218mG
    Axis Y: -754mG
    Axis Z: -1553mG
    Eco Score: 10.000
    Active GSM Operator: 24201
    Total Odometer: 14948

Frame #2
    timestamp: 1720626130000
    priority: 1
    lng: 10.35323
    lat: 63.4181333
    alt: 150
    angle: 256
    speed: 0
    satellites: 44
  I/O elements
    Ignition: false
    Movement: true
    GSM Signal: 5
    Sleep Mode: 0
    GNSS Status: 1
    GNSS PDOP: 0.800
    GNSS HDOP: 0.500
    External Voltage: 13.489V
    Speed: 0km/h
    Battery Voltage: 3.843V
    Battery Current: 0.065A
    Axis X: 219mG
    Axis Y: -755mG
    Axis Z: -1559mG
    Eco Score: 0.710
    Active GSM Operator: 24201
    Total Odometer: 14948

Frame #3
    timestamp: 1720626054101
    priority: 1
    lng: 10.35508
    lat: 63.4245399
    alt: 104
    angle: 129
    speed: 72
    satellites: 48
  I/O elements
    Crash event counter: 1
    Crash detection: 5
    Crash trace data: 01dffe02f95d01c2fdc4f97001b1fde2f96f0193fdd2f97001a1fe01f95f0171fdfff95001b1fdf3f97e01a1fe01f95f0200fdd5f97d01eefe12f95c01affe31f96d01d0fe33f9aa01cffe62f9a901b1fe43f9ba01a0fe51f99b0200fe05f99b01d0fe33f99b0170fe6ff99b0161fe6ff9ab0164fe22f9cd0192fe22f99d0183fe32f9cc0170fe6ff99b0142fe4ff99d0133fe6ef9bc0172fe30f99d01c2fe15f9cb019ffe70f99a0182fe11f97e0183fdf2f99f0152fe2ff98e0163fe21f9ae0181fe2ff96e0152fe2ff98e0162fe30f98e0191fe11f97e01c0fe12f97d019ffe20f94e0180fe2ff95e0192fde1f96001a1fdf1f95f01d1fdc4f96f01a2fdc2f95101bffdf0f9300182fde1f96101d1fdb3f94101a1fdd0f93201c2fda3f95101b1fdd1f94101b1fdd1f94101effde3f94e01b0fdf1f94001c0fde1f94001c1fdd2f9500171fdeef92201b0fde1f94001a1fdc1f93201a0fdc0f9130171fdcff92301dffdb2f9120190fdfff9300191fde0f9410191fe00f95f0172fdd0f94201cffde1f92001bdfdeef8e201affdd0f91201c0fdc2f93101a1fdb1f93301bffde0f92101f1fd74f92301a1fd80f8f601d1fd83f91401a0fdaff8f401a0fde0f92101affdc0f90301bffdd0f90201dffdb1f90201cefdbff8e301eefda2f8f3019ffdaef8c501f0fd94f932019ffddff90201b0fe01f94f01ddfdfff90001bbfe4cf8ee01befe30f94d01cdfe1ff90f01cffdf2f94f019ffe1ff93f01b1fdd2f9600191fe00f95f0184fdc3f9910192fe12f99d01a0fe10f95e0180fe4ff97c01a1fe31f98c01a0fe21f96e0193fdf2f98f0191fe21f98d