Changes

Jump to navigation Jump to search
2,461 bytes added ,  15:22, 17 April 2015
no edit summary
Line 36: Line 36:     
= IR communications =
 
= IR communications =
 +
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 ==
 +
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.
 +
 +
* 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 less than 64 bytes:
 +
{| class="wikitable" border="1"
 +
! Sync
 +
! RFU
 +
! Size
 +
|-
 +
| 0xA5
 +
| 0x00
 +
| size
 +
|}
 +
 +
For packets with up to 16383 bytes:
 +
{| class="wikitable" border="1"
 +
! Sync
 +
! RFU
 +
! Size (1)
 +
! Size (2)
 +
|-
 +
| 0xA5
 +
| 0x00
 +
| (size >> 8) <nowiki>|</nowiki> 0x40
 +
| size & 0xFF
 +
|}
 +
 +
In C:
 +
<nowiki>uint8_t * setPacketHeader(uint8_t * buffer, size_t payloadSize) {
 +
assert(payloadSize < 16384);
 +
 +
buffer[0] = 0xA5;
 +
buffer[1] = 0x00;
 +
 +
if (payloadSize < 64) {
 +
buffer[2] = payloadSize;
 +
buffer += 3;
 +
} else {
 +
buffer[2] = 0x40 | (payloadSize >> 8);
 +
buffer[3] = payloadSize;
 +
buffer += 4;
 +
}
 +
 +
return buffer;
 +
}</nowiki>
 +
 +
== Payload ==
 +
The payload is obfuscated using a XOR-based encryption. In C:
 +
<nowiki>void payloadObfuscate(const void * voidplain, void * voidcipher, size_t size) {
 +
uint16_t * plain = (uint16_t *) voidplain;
 +
uint16_t * cipher = (uint16_t *) voidcipher;
 +
size_t halfCount = size / sizeof(uint16_t);
 +
 +
uint16_t xorval = htobe16(0xE963);
 +
size_t i;
 +
 +
for (i = 0; i < halfCount; i++) {
 +
xorval ^= plain[i];
 +
cipher[i] = xorval;
 +
}
 +
}
 +
 +
void payloadDeobfuscate(const void * voidcipher, void * voidplain, size_t size) {
 +
uint16_t * cipher = (uint16_t *) voidcipher;
 +
uint16_t * plain = (uint16_t *) voidplain;
 +
size_t halfCount = size / sizeof(uint16_t);
 +
 +
if (halfCount) {
 +
size_t i;
 +
for (i = halfCount - 1; i > 0; i--) {
 +
plain[i] = cipher[i] ^ cipher[i - 1];
 +
}
 +
 +
plain[0] = cipher[0] ^ htobe16(0xE963);
 +
}
 +
}</nowiki>
 +
 +
== 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)
 +
 
== Samples ==
 
== Samples ==
  
48

edits

Navigation menu