Changes

4,360 bytes removed ,  15:21, 17 April 2015
m
Undo revision 12391 by Socram8888 (talk)
Line 1: Line 1: −
This service was added with [[2.0.0-2]]. It employs a custom packet format with obfuscation and error detection.
+
#REDIRECT [[IR Services#IR Service "ir:USER"]]
 
  −
= Command set =
  −
When sending data, SendIrnop is used when the size is <=0xFC, otherwise SendIrnopLarge is used.
  −
 
  −
{| class="wikitable" border="1"
  −
|-
  −
!  Command Header
  −
!  Available since system version
  −
!  Description
  −
|-
  −
| 0x00010182
  −
| [[2.0.0-2]]
  −
| InitializeIrnop
  −
|-
  −
| 0x00020000
  −
| [[2.0.0-2]]
  −
| FinalizeIrnop
  −
|-
  −
| 0x00030000
  −
| [[2.0.0-2]]
  −
| ClearReceiveBuffer
  −
|-
  −
| 0x00040000
  −
| [[2.0.0-2]]
  −
| ClearSendBuffer
  −
|-
  −
| 0x0005....
  −
| [[2.0.0-2]]
  −
| WaitConnection
  −
|-
  −
| 0x00060040
  −
| [[2.0.0-2]]
  −
| RequireConnection (u8 input)
  −
|-
  −
| 0x0007....
  −
| [[2.0.0-2]]
  −
| AutoConnection
  −
|-
  −
| 0x0008....
  −
| [[2.0.0-2]]
  −
| AnyConnection
  −
|-
  −
| 0x00090000
  −
| [[2.0.0-2]]
  −
| Disconnect
  −
|-
  −
| 0x000A0000
  −
| [[2.0.0-2]]
  −
| GetReceiveEvent (writes event handle to cmdreply[3])
  −
|-
  −
| 0x000B0000
  −
| [[2.0.0-2]]
  −
| GetSendEvent (writes event handle to cmdreply[3])
  −
|-
  −
| 0x000C0000
  −
| [[2.0.0-2]]
  −
| GetConnectionStatusEvent (writes event handle to cmdreply[3])
  −
|-
  −
| 0x000D0042
  −
| [[2.0.0-2]]
  −
| SendIrnop (u32 size, ((Size<<14) <nowiki>|</nowiki> 2), inbufptr)
  −
|-
  −
| 0x000E0042
  −
| [[2.0.0-2]]
  −
| SendIrnopLarge (u32 size, ((Size<<8) <nowiki>|</nowiki> 10), inbufptr)
  −
|-
  −
| 0x000F....
  −
| [[2.0.0-2]]
  −
| ReceiveIrnop
  −
|-
  −
| 0x0010....
  −
| [[2.0.0-2]]
  −
| ReceiveIrnopLarge
  −
|-
  −
| 0x0011....
  −
| [[2.0.0-2]]
  −
| GetLatestReceiveErrorResult
  −
|-
  −
| 0x0012....
  −
| [[2.0.0-2]]
  −
| GetLatestSendErrorResult
  −
|-
  −
| 0x0013....
  −
| [[2.0.0-2]]
  −
| GetConnectionStatus
  −
|-
  −
| 0x0014....
  −
| [[2.0.0-2]]
  −
| GetTryingToConnectStatus
  −
|-
  −
| 0x0015....
  −
| [[2.0.0-2]]
  −
| GetReceiveSizeFreeAndUsed
  −
|-
  −
| 0x0016....
  −
| [[2.0.0-2]]
  −
| GetSendSizeFreeAndUsed
  −
|-
  −
| 0x0017....
  −
| [[2.2.0-X]]
  −
| GetConnectionRole
  −
|-
  −
| 0x00180182
  −
| [[2.2.0-X]]
  −
| InitializeIrnopShared (u32, u32, u32, u32, u32, u8, 0, handle)
  −
|-
  −
| 0x00190040
  −
| [[2.2.0-X]]
  −
| ReleaseReceivedData (32bit_value input)
  −
|-
  −
| 0x001A0040
  −
| [[2.2.0-X]]
  −
| SetOwnMachineId (u8 input)
  −
|}
  −
 
  −
= Protocol description =
  −
Packets are sent using IrDA-SIR, 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)
 
48

edits