# Integridade e checksums

Esta referência descreve os checksums matemáticos usados para validar a integridade dos dados ao se comunicar pela conexão serial.

## Verificação de redundância longitudinal (LRC)

Cada mensagem operacional trocada entre o SP e o PP (ex: `Y19`, `Y15`, `Y02`) deve ser acrescida de um byte de validação LRC para garantir que o payload não foi corrompido durante a transmissão serial.

### Escopo de validação do LRC

O cálculo do byte LRC deve abranger todos os caracteres no payload ativo começando imediatamente *após* o caractere de controle `<STX>` e terminando imediatamente *após* o caractere de controle `<ETX>`.

* **Incluído**: Caracteres do payload, separadores `<FS>`, `<ETX>`.
* **Excluído**: `<STX>`, `<ACK>`, `<NAK>` e o próprio byte `{LRC}` calculado anteriormente.

### Algoritmo LRC

O LRC é um cálculo direto de OU exclusivo (XOR) executado sequencialmente sobre cada byte na string de destino.

**Lógica de Pseudocódigo**:

```python
def calculate_lrc(payload_string, etx_char):
    lrc = 0
    # Processa toda a string do payload
    for byte in payload_string:
        lrc = lrc ^ ord(byte)
    
    # Processa o caractere ETX 
    lrc = lrc ^ ord(etx_char)
    
    return lrc
```

### Ação em caso de falha de LRC

Ao receber uma mensagem:

1. A parte receptora (seja SP ou PP) deve calcular independentemente o LRC do bloco de dados recebido até o `<ETX>`.
2. Compare o LRC calculado com o byte `{LRC}` fornecido ao final da mensagem.
3. Se eles coincidirem, o receptor retorna um caractere `<ACK>` (Acknowledge).
4. Se eles divergirem, o receptor retorna um caractere `<NAK>` (Negative Acknowledge). O remetente deve então retransmitir imediatamente todo o pacote idêntico.

## Verificação de redundância cíclica (CRC-16)

Embora o byte LRC garanta a integridade de comandos operacionais curtos, o terminal exige uma estrutura de validação mais robusta para transferências massivas de dados, especificamente durante downloads de aplicativos remotos via comando `YDL`.

### Escopo do CRC

Durante o download de um arquivo `YDL`, o arquivo é dividido em vários blocos gerenciáveis. O SP deve calcular um CRC sobre o payload de dados `[DDA]` para *cada fragmento individual* e enviar esse CRC junto com o fragmento.

### Algoritmo CRC (CRC-16/CCITT-FALSE)

O sistema utiliza um CRC de 16 bits baseado no polinômio padrão CCITT. Abaixo está a lista de parâmetros padrão:

* **Largura**: 16 bits
* **Polinômio**: `0x1021` (`X^16 + X^12 + X^5 + 1`)
* **Valor Inicial**: `0xFFFF`
* **Entrada Refletida**: False
* **Resultado Refletido**: False
* **Valor XOR Final**: `0x0000`

### Nota de implementação

Como o CRC atua sobre o bloco de dados do pacote `YDL`, a própria mensagem `YDL` *ainda requer um byte `{LRC}` padrão ao final de seu quadro* para validar a string de transmissão. Portanto, uma transmissão YDL contém duas camadas distintas de integridade: o CRC verificando o fragmento binário do APK e o LRC verificando o quadro serial ascii que transmite esse fragmento.