Обратный инжиниринг Panasonic IR Code Checksum

Я работаю над блоком переменного тока Panasonic, которым управляет ИК-пульт дистанционного управления. Пульт отправляет 12 bytes.

Первые 5 bytes всегда идентичны. Следующие 6 bytes соответствуют температуре кондиционера, вентилятору, функции и другим параметрам, которые я смог выяснить самостоятельно.

Последний byte — это контрольная сумма, которая каким-то образом получается из первого 11 bytes (или из байта 6 в 11)

Поскольку я заново создаю ИК-коды во время выполнения, мне нужно иметь возможность вычислять контрольную сумму для этих пакетов. Я пробовал со многими стандартными алгоритмами контрольных сумм, ни один из них не дал значимых результатов.

Не могли бы вы помочь мне узнать, какая функция контрольной суммы используется для этого устройства?


Вот список пакетов, состоящий из 11 bytes заголовка+данных и 1 byte контрольной суммы, которые мне удалось захватить с устройства:

40 00 14 81 25 00 A0 65 00 00 00 26
40 00 14 81 25 00 A0 68 00 00 07 30
40 00 14 81 25 04 28 65 00 00 00 2A
40 00 14 81 25 04 28 68 00 00 00 2D
40 00 14 81 25 04 28 68 00 00 02 2F
40 00 14 81 25 04 28 68 00 00 03 30
40 00 14 81 25 04 28 68 00 00 04 31
40 00 14 81 25 04 28 68 00 00 05 32
40 00 14 81 25 04 28 68 00 00 07 34
40 00 14 81 25 04 28 69 00 00 01 2F
40 00 14 81 25 04 A0 68 00 00 07 34
40 00 14 81 25 08 9A 68 00 00 07 41
40 00 14 81 25 08 9C 68 00 00 07 43
40 00 14 81 25 08 9E 68 00 00 07 45
40 00 14 81 25 08 A0 68 00 00 00 31
40 00 14 81 25 08 A0 68 00 00 01 32
40 00 14 81 25 08 A0 68 00 00 02 33
40 00 14 81 25 08 A0 68 00 00 03 34
40 00 14 81 25 08 A0 68 00 00 07 38
40 00 14 81 25 08 A2 68 00 00 07 3A
40 00 14 81 25 08 A4 68 00 00 07 3C
40 00 14 81 25 08 A6 68 00 00 07 3E
40 00 14 81 25 08 A8 68 00 00 07 40
40 00 14 81 25 08 AA 68 00 00 07 42
40 00 14 81 25 08 AC 68 00 00 07 44
40 00 14 81 25 08 AE 68 00 00 07 46
40 00 14 81 25 09 A0 68 00 00 07 39
40 00 14 81 25 0A A0 68 00 00 07 3A
40 00 14 81 25 0C A0 68 00 00 07 3C
40 00 14 81 25 40 18 65 00 00 00 29
40 00 14 81 25 40 1A 65 00 00 00 2B
40 00 14 81 25 40 1C 65 00 00 00 2D
40 00 14 81 25 40 1E 65 00 00 00 2F
40 00 14 81 25 40 20 65 00 00 00 22
40 00 14 81 25 40 22 65 00 00 00 24
40 00 14 81 25 40 24 65 00 00 00 26
40 00 14 81 25 40 26 65 00 00 00 28
40 00 14 81 25 40 28 65 00 00 00 2A
40 00 14 81 25 40 2A 65 00 00 00 2C
40 00 14 81 25 40 2C 65 00 00 00 2E
40 00 14 81 25 40 2E 65 00 00 00 30
40 00 14 81 25 40 30 65 00 00 00 23
40 00 14 81 25 40 32 65 00 00 00 25
40 00 14 81 25 40 34 65 00 00 00 27
40 00 14 81 25 40 34 68 00 00 04 2E
40 00 14 81 25 80 1C 68 00 00 00 34
40 00 14 81 25 80 20 65 00 00 00 26
40 00 14 81 25 C0 20 65 00 00 00 2A
40 00 14 81 25 C0 28 68 00 00 02 37

person SIAV    schedule 07.02.2017    source источник


Ответы (1)


Я нашел кандидата функция контрольной суммы, которая соответствует всем вашим данным, но я думаю, что необходимы дальнейшие корректировки, потому что я подозреваю, что магическое число Я использую зависит от что-то еще, что я не учел должным образом.


Это функция, которую мне удалось реконструировать:

uint8_t get_checksum(const uint8_t data[], const size_t size)
{
    assert(data);

    uint8_t checksum = 0;

    for (size_t i = 0; i < size; ++i)
    {
        checksum += (data[i] >> 4) + (data[i] & 0x0f);
    }

    checksum -= 8; /* magic number */

    return checksum;
};

Альтернативная версия:

uint8_t get_checksum(const uint8_t data[], const size_t size)
{
    assert(data);

    uint8_t checksum = 0xF8; /* magic number */

    for (size_t i = 0; i < size; ++i)
    {
        checksum += (data[i] >> 4) + (data[i] & 0x0f);
    }

    return checksum;
};

Пример:

#include<stdio.h>
#include<stdint.h>
#include<assert.h>

uint8_t get_checksum(const uint8_t data[], const size_t size)
{
    assert(data);

    uint8_t checksum = 0xF8; /* magic number */

    for (size_t i = 0; i < size; ++i)
    {
        checksum += (data[i] >> 4) + (data[i] & 0x0f);
    }

    return checksum;
};

int main ()
{
    const size_t xlen = 49;
    const size_t ylen = 12;
    uint8_t v[49][12] = {
        {0x40,0x00,0x14,0x81,0x25,0x00,0xA0,0x65,0x00,0x00,0x00,0x26},
        {0x40,0x00,0x14,0x81,0x25,0x00,0xA0,0x68,0x00,0x00,0x07,0x30},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x65,0x00,0x00,0x00,0x2A},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x00,0x2D},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x02,0x2F},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x03,0x30},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x04,0x31},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x05,0x32},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x07,0x34},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x69,0x00,0x00,0x01,0x2F},
        {0x40,0x00,0x14,0x81,0x25,0x04,0xA0,0x68,0x00,0x00,0x07,0x34},
        {0x40,0x00,0x14,0x81,0x25,0x08,0x9A,0x68,0x00,0x00,0x07,0x41},
        {0x40,0x00,0x14,0x81,0x25,0x08,0x9C,0x68,0x00,0x00,0x07,0x43},
        {0x40,0x00,0x14,0x81,0x25,0x08,0x9E,0x68,0x00,0x00,0x07,0x45},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x00,0x31},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x01,0x32},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x02,0x33},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x03,0x34},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x07,0x38},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA2,0x68,0x00,0x00,0x07,0x3A},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA4,0x68,0x00,0x00,0x07,0x3C},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA6,0x68,0x00,0x00,0x07,0x3E},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA8,0x68,0x00,0x00,0x07,0x40},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xAA,0x68,0x00,0x00,0x07,0x42},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xAC,0x68,0x00,0x00,0x07,0x44},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xAE,0x68,0x00,0x00,0x07,0x46},
        {0x40,0x00,0x14,0x81,0x25,0x09,0xA0,0x68,0x00,0x00,0x07,0x39},
        {0x40,0x00,0x14,0x81,0x25,0x0A,0xA0,0x68,0x00,0x00,0x07,0x3A},
        {0x40,0x00,0x14,0x81,0x25,0x0C,0xA0,0x68,0x00,0x00,0x07,0x3C},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x18,0x65,0x00,0x00,0x00,0x29},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x1A,0x65,0x00,0x00,0x00,0x2B},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x1C,0x65,0x00,0x00,0x00,0x2D},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x1E,0x65,0x00,0x00,0x00,0x2F},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x20,0x65,0x00,0x00,0x00,0x22},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x22,0x65,0x00,0x00,0x00,0x24},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x24,0x65,0x00,0x00,0x00,0x26},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x26,0x65,0x00,0x00,0x00,0x28},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x28,0x65,0x00,0x00,0x00,0x2A},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x2A,0x65,0x00,0x00,0x00,0x2C},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x2C,0x65,0x00,0x00,0x00,0x2E},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x2E,0x65,0x00,0x00,0x00,0x30},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x30,0x65,0x00,0x00,0x00,0x23},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x32,0x65,0x00,0x00,0x00,0x25},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x34,0x65,0x00,0x00,0x00,0x27},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x34,0x68,0x00,0x00,0x04,0x2E},
        {0x40,0x00,0x14,0x81,0x25,0x80,0x1C,0x68,0x00,0x00,0x00,0x34},
        {0x40,0x00,0x14,0x81,0x25,0x80,0x20,0x65,0x00,0x00,0x00,0x26},
        {0x40,0x00,0x14,0x81,0x25,0xC0,0x20,0x65,0x00,0x00,0x00,0x2A},
        {0x40,0x00,0x14,0x81,0x25,0xC0,0x28,0x68,0x00,0x00,0x02,0x37}
    };

    // packet has 11 bytes, 1 byte is for the checksum
    for (size_t i = 0; i < xlen; ++i)
    {
        uint8_t checksum = get_checksum(v[i], 11);

        printf("result: %02x -- should be: %02x -- %s\n",
               checksum, v[i][ylen - 1],
               (checksum - v[i][ylen - 1] == 0 ? "OK" : "ERROR"));
    }
}

Выход:

result: 26 -- should be: 26 -- OK
result: 30 -- should be: 30 -- OK
result: 2a -- should be: 2a -- OK
result: 2d -- should be: 2d -- OK
result: 2f -- should be: 2f -- OK
result: 30 -- should be: 30 -- OK
result: 31 -- should be: 31 -- OK
result: 32 -- should be: 32 -- OK
result: 34 -- should be: 34 -- OK
result: 2f -- should be: 2f -- OK
result: 34 -- should be: 34 -- OK
result: 41 -- should be: 41 -- OK
result: 43 -- should be: 43 -- OK
result: 45 -- should be: 45 -- OK
result: 31 -- should be: 31 -- OK
result: 32 -- should be: 32 -- OK
result: 33 -- should be: 33 -- OK
result: 34 -- should be: 34 -- OK
result: 38 -- should be: 38 -- OK
result: 3a -- should be: 3a -- OK
result: 3c -- should be: 3c -- OK
result: 3e -- should be: 3e -- OK
result: 40 -- should be: 40 -- OK
result: 42 -- should be: 42 -- OK
result: 44 -- should be: 44 -- OK
result: 46 -- should be: 46 -- OK
result: 39 -- should be: 39 -- OK
result: 3a -- should be: 3a -- OK
result: 3c -- should be: 3c -- OK
result: 29 -- should be: 29 -- OK
result: 2b -- should be: 2b -- OK
result: 2d -- should be: 2d -- OK
result: 2f -- should be: 2f -- OK
result: 22 -- should be: 22 -- OK
result: 24 -- should be: 24 -- OK
result: 26 -- should be: 26 -- OK
result: 28 -- should be: 28 -- OK
result: 2a -- should be: 2a -- OK
result: 2c -- should be: 2c -- OK
result: 2e -- should be: 2e -- OK
result: 30 -- should be: 30 -- OK
result: 23 -- should be: 23 -- OK
result: 25 -- should be: 25 -- OK
result: 27 -- should be: 27 -- OK
result: 2e -- should be: 2e -- OK
result: 34 -- should be: 34 -- OK
result: 26 -- should be: 26 -- OK
result: 2a -- should be: 2a -- OK
result: 37 -- should be: 37 -- OK
person Patrick Trentin    schedule 07.02.2017
comment
@SIAV рад, что это помогает, если вы можете создать больше образцов и получить неправильный результат, обновите свой вопрос и добавьте комментарий здесь, чтобы я мог исправить свой ответ. - person Patrick Trentin; 08.02.2017