cat_dev/fsemul/atapi/proto.rs
1//! Protocols related to ATAPI emulation.
2//!
3//! This protocol much like SDIO though, ***IS NOT STANDARD***. I'm sorry if
4//! you got a search request for ATAPI, and were looking for actual real ATAPI
5//! code. Not this weird nintendo variant.
6
7use bytes::{Bytes, BytesMut};
8use tokio::io::Error as IoError;
9use tokio_util::codec::{Decoder, Encoder};
10
11/// A codec that chunks a stream into ATAPI packets.
12///
13/// All packets towards ATAPI are 12 bytes, but going out they can be
14/// any size.
15#[derive(Copy, Clone, Debug, PartialEq, Eq)]
16pub struct ChunkATAPIEmulatorCodec;
17
18impl Decoder for ChunkATAPIEmulatorCodec {
19 type Item = BytesMut;
20 type Error = IoError;
21
22 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
23 if src.len() < 12 {
24 Ok(None)
25 } else {
26 Ok(Some(src.split_to(12)))
27 }
28 }
29}
30
31impl Encoder<Bytes> for ChunkATAPIEmulatorCodec {
32 type Error = IoError;
33
34 fn encode(&mut self, item: Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> {
35 dst.reserve(item.len());
36 dst.extend(item);
37 Ok(())
38 }
39}
40
41// KNOWN PACKET HEADERS
42//
43// - [0x3]
44// - send 32 bytes of various describes, not quite sure
45// - [0x12]
46// - sends 96 bytes, seems to have some random spattering of fields
47// - [0xCF, 0x80] -> Triggers Events in FSEmul, probably just call "EVentTrigger"
48// - [0xF0] -> send back 4, 0x0 bytes
49// - [0xF1]
50// - [0xF1, 0x00]
51// - seems to literally send 32 bytes of random data.... cool
52// - [0xF1, 0x02]
53// - seems to literally send 32 bytes of random data.... cool
54// - [0xF1, 0x01] || [0xF1, 0x03]
55// - seems to do nothing on hthe network
56// - [0xF2]
57// - [0xF2, 0x00]
58// - [0xF2, 0x01]
59// - [0xF2, 0x02]
60// - [0xF2, 0x03]
61// -> ??? calls a dynamically allocated thing
62// - [0xF2, 0x06]
63// - [0xF2, 0x07]
64// -> ??? calls a dynamically allocated thing
65// -> for f207 looks like we don't send _anything_ back by default
66// -> seems some paths check for Dvdroot, so maybe dvd stuff?
67// - [0xF3]
68// - [0xF3, 0x0] -> seems to actually be real "read file"
69// - not quite sure exactly how to parse this yet, but these are examples:
70// - first 4 bytes are "packet id"
71// - second 4 bytes are "read address" (calculate by: cast to u128 `<< 11`)
72// - last 4 bytes are "read length" (calculate by: cast to u128 `<< 11`)
73// - logs seem to indicate we:
74// 1. read a dlf file (dlf file is populated in cafe-tmp how get?)
75// 2. use that to get a max read address
76// 3. read from the file
77// 4. then pad
78// see logs below:
79// - `CSataProcessor::could not get lead out from dlffileobj {error code}`
80// - `CSataProcessor::requested read address 0x%I64x is out of bounds.`
81// - `CSataProcessor::could not read from file`
82// - `CSataProcessor::padding`
83// - `CSataProcessor::error writing to MION port`
84// - `CSataProcessor::wrote %d bytes`
85// - [0xF3, 0x1] -> send back "PC SATA EMUL" + 20 0's
86// - [0xF3, 0x2] || [0xF3, 0x3] -> send back 32 0's - seems this is always set to 0. maybe a kind of ping?
87// - [0xF5]
88// - send 32 0's
89// - [0xF6]
90// - second byte &3 != 0 -> doesn't send reply
91// - if not send what looks to be `1` encoded as 4 bytes
92// - [0xF7]
93// - send 32 0's