Line 38:
Line 38:
Packets are sent using IrDA-SIR (using [[ir:USER]]), with a 8N1 encoding (eight data bits, one stop bit, without parity). Each one is formed by a 2-byte header, a varint with the payload size, an obfuscated payload, and trailing error detection byte.
Packets are sent using IrDA-SIR (using [[ir:USER]]), with a 8N1 encoding (eight data bits, one stop bit, without parity). Each one is formed by a 2-byte header, a varint with the payload size, an obfuscated payload, and trailing error detection byte.
−
== Packet header ==
+
== Layer 1 - framing format ==
−
The packet header is fixed and consists in a synchronization byte (0xA5), followed by a unused (possibly RFU) zero byte. After these two hardcoded bytes, there's a varint representing the payload size, which may use one byte or two, depending on the how big the payload is.
+
Frames are encoded using two different yet very simmilar formats, depending on how large the payload to be transmitted is:
−
* For payloads with less than 64 bytes, the third byte represents the payload size.
* For payloads with less than 64 bytes, the third byte represents the payload size.
* For packets with up to 16383 bytes, the size is split in two bytes, with the third byte being the upper 6 bits of the payload size, OR'd with 0x40, and the fourth being the lower eight bits of the payload size
* For packets with up to 16383 bytes, the size is split in two bytes, with the third byte being the upper 6 bits of the payload size, OR'd with 0x40, and the fourth being the lower eight bits of the payload size
−
For packets with less than 64 bytes:
+
{| class="wikitable" style="margin: 0 auto; text-align: center;"
−
{| class="wikitable" border="1"
+
|+IR framing format - short frame
−
! Sync
+
|-
−
! RFU
+
! style="border-top: none" | Byte
−
! Size
+
! style="width:10%;"| 7
+
! style="width:10%;"| 6
+
! style="width:10%;"| 5
+
! style="width:10%;"| 4
+
! style="width:10%;"| 3
+
! style="width:10%;"| 2
+
! style="width:10%;"| 1
+
! style="width:10%;"| 0
+
|-
+
! 0x00
+
| colspan="8"|Synchronization byte (<code>0xA5</code>)
+
|-
+
! 0x01
+
| colspan="8"|Reserved for future use (<code>0x00</code>)
+
|-
+
! 0x02
+
| RFU (<code>0</code>)
+
| Short frame (<code>0</code>)
+
| colspan="6"|Payload size
|-
|-
−
| 0xA5
+
! 0x03
−
| 0x00
+
| colspan="8"|Payload byte 0
−
| size
+
|-
+
| colspan="9"|...
+
|-
+
! 0x03+n-1
+
| colspan="8"|Payload byte n-1
+
|-
+
! 0x03+n
+
| colspan="8"|[[CRC-8-CCITT]] computer over whole packet
|}
|}
−
For packets with up to 16383 bytes:
+
−
{| class="wikitable" border="1"
+
{| class="wikitable" style="margin: 0 auto; text-align: center;"
−
! Sync
+
|+IR framing format - long frame
−
! RFU
+
|-
−
! Size (1)
+
! style="border-top: none" | Byte
−
! Size (2)
+
! style="width:10%;"| 7
+
! style="width:10%;"| 6
+
! style="width:10%;"| 5
+
! style="width:10%;"| 4
+
! style="width:10%;"| 3
+
! style="width:10%;"| 2
+
! style="width:10%;"| 1
+
! style="width:10%;"| 0
+
|-
+
! 0x00
+
| colspan="8"|Synchronization byte (<code>0xA5</code>)
+
|-
+
! 0x01
+
| colspan="8"|Reserved for future use (<code>0x00</code>)
+
|-
+
! 0x02
+
| RFU (<code>0</code>)
+
| Long frame (<code>1</code>)
+
| colspan="6"|Payload size (upper 6 bits)
+
|-
+
! 0x03
+
| colspan="8"|Payload size (lower 8 bits)
+
|-
+
! 0x04
+
| colspan="8"|Payload byte 0
|-
|-
−
| 0xA5
+
| colspan="9"|...
−
| 0x00
+
|-
−
| (size >> 8) <nowiki>|</nowiki> 0x40
+
! 0x04+n-1
−
| size & 0xFF
+
| colspan="8"|Payload byte n-1
+
|-
+
! 0x04+n
+
| colspan="8"|[[CRC-8-CCITT]] computer over whole packet
|}
|}
+
+
=== Header ===
+
The packet header is fixed and consists in a synchronization byte (0xA5), followed by a unused (possibly RFU) zero byte. After these two hardcoded bytes, there's a varint representing the payload size, which may use one byte or two, depending on the how big the payload is.
In C:
In C:
Line 87:
Line 141:
}</nowiki>
}</nowiki>
−
== Payload ==
+
=== Payload ===
The payload is obfuscated using a XOR-based encryption. In C:
The payload is obfuscated using a XOR-based encryption. In C:
<nowiki>void payloadObfuscate(const void * voidplain, void * voidcipher, size_t size) {
<nowiki>void payloadObfuscate(const void * voidplain, void * voidcipher, size_t size) {
Line 118:
Line 172:
}</nowiki>
}</nowiki>
−
== Error detection ==
+
=== Error detection ===
The trailing error detection byte is calculated using [[CRC-8-CCITT]] <b>over the whole packet</b> (both the header and the payload)
The trailing error detection byte is calculated using [[CRC-8-CCITT]] <b>over the whole packet</b> (both the header and the payload)