NFC adapter: Difference between revisions

No edit summary
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)