SPTCP

From 3dbrew
Jump to navigation Jump to search

Similar to TCP, but on layer 2 (no IP, only MAC), with control flags and handles data segmentation. Used to send data packets (SPMTP) in a StreetPass exchange.

Header Structure

Offset Size Description
0x0 0x2 Magic value (0x5959)
0x2 0x2 Header size (0x18) + payload (SPMTP) size + 0x18
0x4 0x4 Constant (0xaddeafbe)
0x8 0x4 Number of payload bytes sent (used when payload has to be segmented in multiple packets)
0xC 0x4 Number of payload bytes received from peer
0x10 0x1 (Header size (0x18) + 0x18) right shifted 2 places (this is always 0x0c)
0x11 0x1 Flags
0x12 0x2 Payload buffer size (by default 0xb838)
0x14 0x4 Padding (0x00000000)

Flags

The flag field encodes the following flags, from bit nº0 to bit nº5 respectively: FIN, SYN, RST, PSH, ACK, END.

Buffer

By default, the 3DS uses a buffer of size 0x38b8 (appears as 0xb838 in the SPTCP header since it is sent in little endian). No other buffer size has been observed being used. Similar to the sliding window protocol of TCP, it indicates the amount of payload bytes the 3DS can send before having to wait for the other 3DS to send an ACK.

The SPMTP data is always encapsulated in one (or multiple if segmented) SPTCP header with at least the ACK flag set. If the PSH flag is set too, it means the buffer size limit has been reached, and if the END flag is also set, it means the 3DS has finished sending the current SPMTP payload. In both cases, the receiver 3DS has to send an ACK that contains the number of payload bytes received from the current SPMTP until that point.

Aside from this buffer, it has been observed that the maximum payload chunk size is hardcoded to be 0x38b8. Since this is also the default buffer size, when it reaches the buffer limit it has also reached the current chunk length so the 3DS sends the packet with ACK + PSH + END flags, even though it may not be the actual end of the message. Both Info SPMTP and Message Box SPMTP headers have a field containing the total payload length, this value should be used to check if the ACK + PSH + END actually indicates the end of the current message or not.

Conversation Flow

Handshake

Before sending any new SPMTP payload, the 3DS (A) has to do the three-way handshake with its peer (B): (A) sends a SYN, (B) sends a SYN + ACK, (A) sends a ACK. Then (A) sends the SPMTP.

A sends:
0000   59 59 30 00 ad de af be 00 00 00 00 00 00 00 00   YY0.............
0010   0c 02 b8 38 00 00 00 00                           ...8....

B sends:
0000   59 59 30 00 ad de af be 00 00 00 00 00 00 00 00   YY0.............
0010   0c 12 b8 38 00 00 00 00                           ...8....

A sends:
0000   59 59 30 00 ad de af be 00 00 00 00 00 00 00 00   YY0.............
0010   0c 10 b8 38 00 00 00 00                           ...8....

Info SPMTP state

The first messages of the conversation consist of info SPMTP messages. These messages' format can be seen at SPMTP#Handshake_Packets. They are small enough to fit in 1 Ethernet MTU, so they don't get segmented, and therefore are all sent with the ACK + PSH + END flags.

The number of info messages, their type and the order in which they get sent are always the same. Alternating between client and master, the order is as follows: 0x41, 0x42, 0x43, 0x43, 0x11, 0x12, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, 0x81, 0x81. Each 3DS has to initiate the handshake before sending one of these messages, and the other 3DS replies with an ACK to each of these messages.

Message Box SPMTP

After sending all the Info SPMTP messages, both 3DS start exchanging StreetPass messages (SPMTP#TMP_Box_Packets).

- If the 3DS (A) is sending a message, but it has reached the buffer limit, the receiver 3DS (B) will reply with an ACK and (A) will immediately continue sending data without needing to perform the handshake again.

- If the 3DS (A) has finished sending a message, and it has more messages to send of that same game, the receiver 3DS (B) will reply with an ACK and (A) will immediately continue sending the next message without needing to perform the handshake again.

- If the 3DS (A) has finished sending a message, it doesn't have more messages to send of the current game, and the receiver 3DS (B) does have more messages to send, then (B) will reply with an ACK and initiate the handshake, then it will be (B)'s turn to send messages.

- If the 3DS (A) has finished sending a message, it doesn't have more messages to send of the current game but does have more messages to send from other games, and the receiver 3DS (B) does not have any more messages from any game to send, then (B) will reply with an ACK and (A) will initiate the handshake and send its next message.

- If the 3DS (A) has finished sending a message, it doesn't have more messages to send from any game, and neither does the receiver 3DS (B), then (B) will reply with an ACK and a FIN. (A) will reply an ACK + FIN and lastly (B) will reply with an ACK. The conversation ends.

The order in which they exchange the games messages is determined by the order they specified in the Info SPMTP 0x81 message.