Skip to content

Commit

Permalink
Add padding to NCA files over USB transmission
Browse files Browse the repository at this point in the history
  • Loading branch information
satelliteseeker committed Oct 21, 2018
1 parent 38b11f2 commit f33c735
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 11 deletions.
3 changes: 3 additions & 0 deletions include/install/usb_nsp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

namespace tin::install::nsp
{
static const size_t PADDING_SIZE = 0x1000;
static const u32 CMD_ID_FILE_RANGE = 1;
static const u32 CMD_ID_FILE_RANGE_PADDED = 2;
class USBNSP : public RemoteNSP
{
private:
Expand Down
2 changes: 1 addition & 1 deletion include/util/usb_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace tin::util
static void SendCmdHeader(u32 cmdId, size_t dataSize);

static void SendExitCmd();
static USBCmdHeader SendFileRangeCmd(std::string nspName, u64 offset, u64 size);
static USBCmdHeader SendFileRangeCmd(u32 cmdId, std::string nspName, u64 offset, u64 size);
};

size_t USBRead(void* out, size_t len);
Expand Down
15 changes: 10 additions & 5 deletions source/install/usb_nsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ namespace tin::install::nsp
int USBThreadFunc(void* in)
{
USBFuncArgs* args = reinterpret_cast<USBFuncArgs*>(in);
tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(args->nspName, args->pfs0Offset, args->ncaSize);
tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(CMD_ID_FILE_RANGE_PADDED, args->nspName, args->pfs0Offset, args->ncaSize);

u8* buf = (u8*)memalign(0x1000, 0x100000);
u8* buf = (u8*)memalign(0x1000, tin::data::BUFFER_SEGMENT_DATA_SIZE);
u64 sizeRemaining = header.dataSize;
size_t tmpSizeRead = 0;

try
{
while (sizeRemaining)
{
tmpSizeRead = usbCommsRead(buf, std::min(sizeRemaining, (u64)0x100000));
size_t padding = 0;
if (header.cmdId == CMD_ID_FILE_RANGE_PADDED) {
padding = PADDING_SIZE;
}

tmpSizeRead = usbCommsRead(buf, std::min(sizeRemaining + padding, tin::data::BUFFER_SEGMENT_DATA_SIZE)) - padding;
//LOG_DEBUG("Read bytes\n")
//printBytes(nxlinkout, buf, tmpSizeRead, true);
sizeRemaining -= tmpSizeRead;
Expand All @@ -57,7 +62,7 @@ namespace tin::install::nsp
break;
}

args->bufferedPlaceholderWriter->AppendData(buf, tmpSizeRead);
args->bufferedPlaceholderWriter->AppendData(buf + padding, tmpSizeRead);
}
}
catch (std::exception& e)
Expand Down Expand Up @@ -151,7 +156,7 @@ namespace tin::install::nsp

void USBNSP::BufferData(void* buf, off_t offset, size_t size)
{
tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(m_nspName, offset, size);
tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(CMD_ID_FILE_RANGE, m_nspName, offset, size);
tin::util::USBRead(buf, header.dataSize);
}
}
4 changes: 2 additions & 2 deletions source/util/usb_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace tin::util
USBCmdManager::SendCmdHeader(0, 0);
}

USBCmdHeader USBCmdManager::SendFileRangeCmd(std::string nspName, u64 offset, u64 size)
USBCmdHeader USBCmdManager::SendFileRangeCmd(u32 cmdId, std::string nspName, u64 offset, u64 size)
{
struct FileRangeCmdHeader
{
Expand All @@ -37,7 +37,7 @@ namespace tin::util
fRangeHeader.nspNameLen = nspName.size();
fRangeHeader.padding = 0;

USBCmdManager::SendCmdHeader(1, sizeof(FileRangeCmdHeader) + fRangeHeader.nspNameLen);
USBCmdManager::SendCmdHeader(cmdId, sizeof(FileRangeCmdHeader) + fRangeHeader.nspNameLen);
USBWrite(&fRangeHeader, sizeof(FileRangeCmdHeader));
USBWrite(nspName.c_str(), fRangeHeader.nspNameLen);

Expand Down
19 changes: 16 additions & 3 deletions tools/usb_install_pc.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@

CMD_ID_EXIT = 0
CMD_ID_FILE_RANGE = 1
CMD_ID_FILE_RANGE_PADDED = 2

CMD_TYPE_RESPONSE = 1

BUFFER_SEGMENT_DATA_SIZE = 0x100000
PADDING_SIZE = 0x1000

def send_response_header(out_ep, cmd_id, data_size):
out_ep.write(b'TUC0') # Tinfoil USB Command 0
out_ep.write(struct.pack('<B', CMD_TYPE_RESPONSE))
Expand All @@ -44,7 +48,7 @@ def send_response_header(out_ep, cmd_id, data_size):
out_ep.write(struct.pack('<Q', data_size))
out_ep.write(b'\x00' * 0xC)

def file_range_cmd(nsp_dir, in_ep, out_ep, data_size):
def file_range_cmd(nsp_dir, in_ep, out_ep, data_size, padding=False):
file_range_header = in_ep.read(0x20)

range_size = struct.unpack('<Q', file_range_header[:8])[0]
Expand All @@ -54,20 +58,27 @@ def file_range_cmd(nsp_dir, in_ep, out_ep, data_size):
nsp_name = bytes(in_ep.read(nsp_name_len)).decode('utf-8')

print('Range Size: {}, Range Offset: {}, Name len: {}, Name: {}'.format(range_size, range_offset, nsp_name_len, nsp_name))
send_response_header(out_ep, CMD_ID_FILE_RANGE, range_size)
cmd_id = CMD_ID_FILE_RANGE
if padding:
cmd_id = CMD_ID_FILE_RANGE_PADDED
send_response_header(out_ep, cmd_id, range_size)

with open(nsp_name, 'rb') as f:
f.seek(range_offset)

curr_off = 0x0
end_off = range_size
read_size = 0x100000
read_size = BUFFER_SEGMENT_DATA_SIZE
if (padding):
read_size -= PADDING_SIZE

while curr_off < end_off:
if curr_off + read_size >= end_off:
read_size = end_off - curr_off

buf = f.read(read_size)
if (padding):
buf = b'\x00' * PADDING_SIZE + buf
out_ep.write(data=buf, timeout=0)
curr_off += read_size

Expand All @@ -91,6 +102,8 @@ def poll_commands(nsp_dir, in_ep, out_ep):
break
elif cmd_id == CMD_ID_FILE_RANGE:
file_range_cmd(nsp_dir, in_ep, out_ep, data_size)
elif cmd_id == CMD_ID_FILE_RANGE_PADDED:
file_range_cmd(nsp_dir, in_ep, out_ep, data_size, padding=True)

def send_nsp_list(nsp_dir, out_ep):
nsp_path_list = list()
Expand Down

0 comments on commit f33c735

Please sign in to comment.