Skip to content

Latest commit

 

History

History
74 lines (60 loc) · 2.59 KB

crc16-checksum.md

File metadata and controls

74 lines (60 loc) · 2.59 KB

PPPP (PPCS peer-to-peer protocol)

Ankermake M5 uses the PPPP protocol for status updates, file listing, gcode uploads, camera streaming, and more.

Some types of PPPP messages have a 16-bit checksum at the end, while others have none.

This document describes how the checksum type was identified, using the open source program reveng.

CRC checksum on packets

Let's search for "aabb020000000000000000008ade".

Assumption: aabb is a header/prefix, and 8ade is the crc. Let's try brute-forcing possible CRC-16s:

$ for algo in $(./reveng -D | grep width=16 | cut -f 2 -d '"'); do printf "%-30s: %s\n" ${algo} "$(./reveng -m ${algo} -c 02000000000000000000)"; done
CRC-16/CDMA2000               : cac6
CRC-16/TELEDISK               : 4e46
CRC-16/T10-DIF                : 532a
CRC-16/USB                    : 2e32
CRC-16/MODBUS                 : d1cd
CRC-16/CMS                    : 4ecb
CRC-16/DDS-110                : 666b
CRC-16/MAXIM-DOW              : 5e35
CRC-16/ARC                    : a1ca
CRC-16/UMTS                   : 402b
CRC-16/OPENSAFETY-B           : 4168
CRC-16/LJ1200                 : f876
CRC-16/M17                    : 4eb9
CRC-16/OPENSAFETY-A           : 222c
CRC-16/DNP                    : 4234
CRC-16/EN-13757               : 88d9
CRC-16/PROFIBUS               : a574
CRC-16/IBM-SDLC               : 363b
CRC-16/MCRF4XX                : c9c4
CRC-16/GENIBUS                : c04c
CRC-16/IBM-3740               : 3fb3
CRC-16/ISO-IEC-14443-3-A      : b416
CRC-16/RIELLO                 : 4897
CRC-16/TMS37157               : 82e5
CRC-16/SPI-FUJITSU            : 5a73
CRC-16/KERMIT                 : 4e58
CRC-16/GSM                    : 2175
CRC-16/XMODEM                 : de8a
CRC-16/NRSC-5                 : 102e
CRC-16/DECT-R                 : 9a93
CRC-16/DECT-X                 : 9a92

We got a hit! It's reversed though (de8a -> 8ade)

Let's verify with a more complex example (with last two bytes manually swapped):

./reveng -w 16 -s 00000000000089000000302c6...[REDACTED]...200cc1c
width=16  poly=0x1021  init=0x0000  refin=false  refout=false  xorout=0x0000  check=0x31c3  residue=0x0000  name="CRC-16/XMODEM"

Bingo! The message data, except aabb header, has a 16-bit CRC16/XMODEM checksum appended on the end, in big endian orientation.

The following is a python proof-of-concept of calculating the checksum:

import struct
import crcmod

def ppcs_crc16(data):
    crc16 = crcmod.mkCrcFun(0x11021, rev=False, initCrc=0x0000, xorOut=0x0000)
    return struct.pack("<H", crc16(data))