COBS (Consistent Overhead Byte Stuffing): framing determinístico e recuperação real
O COBS surge como resposta direta às fragilidades do SLIP. Ele parte de um princípio simples, porém poderoso: eliminar completamente um valor do payload (normalmente 0x00) e usá-lo exclusivamente como delimitador de pacote. Com isso, o framing torna-se determinístico, auto-sincronizável e com overhead previsível.
Diferente do SLIP, o COBS não depende de escapes condicionais. Ele reorganiza os dados em blocos prefixados por comprimento, garantindo que o delimitador nunca apareça dentro do pacote codificado. O resultado é um fluxo que se re-sincroniza sozinho após erros, sem estados frágeis.

Ideia central do COBS
- O byte
0x00não aparece no payload codificado - Cada bloco começa com um contador (1–255)
- O contador indica quantos bytes não-zero vêm a seguir
- Um
0x00no payload original “quebra” o bloco
No fluxo final:
[bloco][bloco][bloco] 0x00
O 0x00 marca fim de pacote, sempre.
Exemplo conceitual
Payload original:
11 22 00 33 44 55
Após COBS:
03 11 22 04 33 44 55 00
Interpretação:
03→ dois bytes seguem (11 22)04→ três bytes seguem (33 44 55)00→ fim de pacote
Mesmo que um byte se perca, o receptor re-encontra o próximo 0x00 e volta a alinhar o stream.
Encoder COBS — implementação didática em C
#include <stdint.h>
#include <stddef.h>
size_t cobs_encode(const uint8_t *input, size_t length, uint8_t *output)
{
size_t read_index = 0;
size_t write_index = 1;
size_t code_index = 0;
uint8_t code = 1;
while (read_index < length) {
if (input[read_index] == 0) {
output[code_index] = code;
code = 1;
code_index = write_index++;
read_index++;
} else {
output[write_index++] = input[read_index++];
code++;
if (code == 0xFF) {
output[code_index] = code;
code = 1;
code_index = write_index++;
}
}
}
output[code_index] = code;
output[write_index++] = 0x00; // delimitador
return write_index;
}
Observe duas propriedades importantes:
- Sem estados frágeis
- Overhead máximo conhecido: 1 byte a cada 254 bytes
Isso é ouro em sistemas de tempo real.
Decoder COBS — recuperação previsível
int cobs_decode(const uint8_t *input, size_t length, uint8_t *output)
{
size_t read_index = 0;
size_t write_index = 0;
while (read_index < length) {
uint8_t code = input[read_index++];
if (code == 0 || read_index + code - 1 > length) {
return -1; // erro de framing
}
for (uint8_t i = 1; i < code; i++) {
output[write_index++] = input[read_index++];
}
if (code != 0xFF && read_index < length) {
output[write_index++] = 0x00;
}
}
return (int)write_index;
}
Aqui está o ponto-chave: erros são detectáveis e localizados. Um pacote inválido pode ser descartado sem corromper o fluxo seguinte.
Por que COBS é realmente auto-sincronizável
Em termos de engenharia de protocolo, o COBS atende aos critérios mais exigentes:
- Delimitador único e inequívoco (
0x00) - Parsing puramente streaming
- Recuperação após erro sem reset global
- Complexidade O(n)
- Nenhuma dependência de temporização
Por isso ele é amplamente usado em:
- UART industrial
- SPI em modo streaming
- CAN encapsulado
- RPC embarcado
- Gateways MCU ↔ Linux
Boas e más escolhas com COBS
Boas escolhas
- Transporte binário puro
- Protocolos próprios
- Links com ruído
- Sistemas distribuídos
- Integração com CRC externo
Más escolhas
- Payload textual humano
- Mensagens muito pequenas (overhead irrelevante, mas sem ganho)
- Quando já existe framing físico (ex: CAN clássico)
Comparação direta: SLIP × COBS
| Critério | SLIP | COBS |
|---|---|---|
| Auto-sincronização | Fraca | Forte |
| Overhead | Variável | Determinístico |
| Recuperação de erro | Limitada | Previsível |
| Parsing streaming | Frágil | Robusto |
| Uso em produção | Raro | Comum |
O COBS não “parece” simples à primeira vista, mas é simples onde importa: no comportamento do sistema.
Conclusão parcial
Se SLIP é didático, o COBS é engenharia madura. Ele não tenta ser semântico, não tenta ser bonito — ele transporta bytes com dignidade.
Na próxima seção, vamos entrar no CBOR:
- O que ele resolve (e o que não resolve)
- Por que ele não substitui COBS
- Como combinar COBS + CBOR corretamente