Line 8:
Line 8:
UDS [[NWMUDS:Bind|data_channel]] 0x1 is used for spectator data, while all non-spectator data uses data_channel 0x2. The spectator data is received by connecting to the network as a spectator then receiving data-frames, this is handled when scanning for DLP networks.
UDS [[NWMUDS:Bind|data_channel]] 0x1 is used for spectator data, while all non-spectator data uses data_channel 0x2. The spectator data is received by connecting to the network as a spectator then receiving data-frames, this is handled when scanning for DLP networks.
+
+
The spectator data includes the 48x48 icon, this has the same format as [[SMDH]].
This is the data starting at offset 0x0 for UDS PullPacket/SendTo:
This is the data starting at offset 0x0 for UDS PullPacket/SendTo:
Line 30:
Line 32:
| 0x6
| 0x6
| 0x2
| 0x2
−
| ?
+
| u16, unknown. For spectator data this is only used for the metadata frame.
|-
|-
| 0x8
| 0x8
Line 57:
Line 59:
|}
|}
−
Total_frames is at least 0x4 normally. When a sysupdate is included, total_frames is 0x4+<total frames required for the titlelist(normally 0x1)>.
+
Total_frames is at least 0x4 normally. When a sysupdate is included, total_frames is 0x4+<total frames required for the titlelist(normally 0x1)>. Total_frames should be <=0x20, but the code doesn't check for this specific value.
+
+
==== Checksum ====
+
The checksum seed is the 4-byte output from [[PS:EncryptDecryptAes|encrypting]] zeros with AES-CTR using [[PSPXI:EncryptDecryptAes|keytype5]]. The CTR is the output from this: "for(i=0; i<0x10; i++)ctr[i] = ctrseed[i] ^ host_macaddress[i % 6];" This ctrseed is a fixed 0x10-byte random-data block stored in DLP-sysmodule .rodata.
+
This seed is initialized after connecting to/creating the DLP network.
+
+
The checksum stored in the above data frame header is then calculated using this checksum seed.
+
+
First, the calc_checksum is initialized to 0. Then calc_checksum is added with ''all'' words in the data frame loaded as big-endian, with the data-frame checksum cleared to zero here. If the frame_size isn't word-aligned, the remaining <4-bytes are loaded as big-endian for adding as well.
+
+
Then this is run:
+
//During init before the above adding, shift and count are initialized:
+
//shift = (((u8*)&checksum_seed)[2] & 0xf) + 0x4;
+
//count = (((u8*)&checksum_seed)[3] & 0x7) + 0x2;
+
for(pos=0; pos<count; pos++)checksum = (checksum<<shift | checksum>>shift) ^ checksum_seed;//The u32 checksum_seed is byte-swapped on 3DS for this.
+
+
Lastly the calculated checksum is written to output as big-endian(hence on 3DS it's byte-swapped before writing to output).
−
Frames:
+
==== Frames ====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 68:
Line 86:
| 0x0
| 0x0
| 0x300
| 0x300
−
| Various metadata, two UTF-16 strings displayed by the DLP-client, and the start of the icon gfx.
+
| Metadata + start of the icon gfx, see below.
|-
|-
| 0x1-0x3
| 0x1-0x3
Line 81:
Line 99:
The structure of each spectator frame relative to "frame-specific payload" is described below.
The structure of each spectator frame relative to "frame-specific payload" is described below.
−
==== Metadata frame ====
+
===== Metadata frame =====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 89:
Line 107:
|-
|-
| 0x0
| 0x0
−
| 0x2F0
+
| 0x8
−
|
+
| u64 DLP-child titleID. Must be a CTR TID-high, with the TID-high set for DLP-child. The low 4-bits of the TID-low must be clear.
+
|-
+
| 0x8
+
| 0x2
+
| u16, probably the DLP-child title-version.
+
|-
+
| 0xA
+
| 0x1
+
| u8, unknown.
+
|-
+
| 0xB
+
| 0x1
+
| u8, unknown.
+
|-
+
| 0xC
+
| 0x4
+
| u32, chunk_size. This is the chunk_size used for transferring the CIA. This is the exact size used for the FS .cia file-reads on the host, and the exact size used for [[Application_Manager_Services|AM]] CIA file-writes on the client(s). Normally this is 0x0003FFC0. This appears to be validated by the client at some point, using a large value for this triggers an "connection interrupted" error when trying to connect.
+
|-
+
| 0x10
+
| 0x2
+
| Unused by the DLP-client(sysmodule).
+
|-
+
| 0x12
+
| 0x2
+
| u16, unknown.
+
|-
+
| 0x14
+
| 0x4
+
| Unused by the DLP-client(sysmodule).
+
|-
+
| 0x18
+
| 0x10
+
| Unknown 0x10-byte structure.
+
|-
+
| 0x28
+
| 0x4
+
| u32, unknown.
+
|-
+
| 0x2C
+
| 0x4
+
| u32, unknown. Must be <=0x02000000.
+
|-
+
| 0x30
+
| 0x80 (0x3F characters are copied)
+
| UTF-16 Application name string. The last u16 is ignored, value 0x0 is always written to output for it instead.
+
|-
+
| 0xB0
+
| 0x100 (0x7F characters are copied)
+
| UTF-16 Description string. The last u16 is ignored, value 0x0 is always written to output for it instead.
+
|-
+
| 0x1B0
+
| 0x138
+
| Array of 0x9C u16s for the start of the icon gfx.
+
|-
+
| 0x2E8
+
| 0x1
+
| u8, unknown. Written to outptr+2.
+
|-
+
| 0x2E9
+
| 0x1
+
| u8, unknown. Written to outptr+1.
+
|-
+
| 0x2EA
+
| 0x1
+
| u8, unknown. Written to outptr+0.
+
|-
+
| 0x2EB
+
| 0x1
+
| u8, unknown. Written to outptr+3.
+
|-
+
| 0x2EC
+
| 0x1
+
| u8, unknown. Written to outptr+4.
+
|-
+
| 0x2ED
+
| 0x1
+
| u8, unknown. Written to outptr+7.
+
|-
+
| 0x2EE
+
| 0x1
+
| u8, unknown. Written to outptr+6.
+
|-
+
| 0x2EF
+
| 0x1
+
| u8, unknown. Written to outptr+5.
|}
|}
−
==== Icon gfx frame ====
+
If the u16 at frameheader+0x6 is less than 0x101, the 8-bytes at outptr are cleared to all-zero, instead of copying the data from offset 0x2E8.
+
+
===== Icon gfx frame =====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 102:
Line 206:
| 0x0
| 0x0
| 0x598
| 0x598
−
|
+
| Array of 0x2CC u16s for the gfx data.
|}
|}
−
==== Sysupdate titlelist frame ====
+
===== Sysupdate titlelist frame =====
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-