Browse Source

Add more documentation, add NetworkNodeID enum

pull/156/head
Jhynjhiruu 11 months ago
parent
commit
5287023486
  1. 8
      ctru-rs/examples/local-networking.rs
  2. 75
      ctru-rs/src/services/uds.rs

8
ctru-rs/examples/local-networking.rs

@ -165,7 +165,7 @@ fn main() { @@ -165,7 +165,7 @@ fn main() {
Ok(p) => {
if let Some((pkt, node)) = p {
println!(
"{:02X}{:02X}{:02X}{:02X} from {:04X}",
"{:02X}{:02X}{:02X}{:02X} from {:?}",
pkt[0], pkt[1], pkt[2], pkt[3], node
);
}
@ -186,7 +186,7 @@ fn main() { @@ -186,7 +186,7 @@ fn main() {
if mode != ConnectionType::Spectator {
uds.send_packet(
&transfer_data.to_le_bytes(),
ctru_sys::UDS_BROADCAST_NETWORKNODEID as _,
NodeID::Broadcast,
data_channel,
SendFlags::Default,
)
@ -241,7 +241,7 @@ fn main() { @@ -241,7 +241,7 @@ fn main() {
Ok(p) => {
if let Some((pkt, node)) = p {
println!(
"{:02X}{:02X}{:02X}{:02X} from {:04X}",
"{:02X}{:02X}{:02X}{:02X} from {:?}",
pkt[0], pkt[1], pkt[2], pkt[3], node
);
}
@ -261,7 +261,7 @@ fn main() { @@ -261,7 +261,7 @@ fn main() {
let transfer_data = hid.keys_held().bits();
uds.send_packet(
&transfer_data.to_le_bytes(),
ctru_sys::UDS_BROADCAST_NETWORKNODEID as _,
NodeID::Broadcast,
data_channel,
SendFlags::Default,
)

75
ctru-rs/src/services/uds.rs

@ -20,11 +20,11 @@ use macaddr::MacAddr6; @@ -20,11 +20,11 @@ use macaddr::MacAddr6;
bitflags! {
/// Flags used for sending packets to a network.
#[allow(missing_docs)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SendFlags: u8 {
/// According to libctru source, it's not really known what these do.
/// Unknown function according to `libctru`.
const Default = ctru_sys::UDS_SENDFLAG_Default as u8;
/// Broadcast the data frame even when sending to a non-broadcast address.
const Broadcast = ctru_sys::UDS_SENDFLAG_Broadcast as u8;
}
}
@ -94,6 +94,43 @@ impl TryFrom<u8> for ConnectionType { @@ -94,6 +94,43 @@ impl TryFrom<u8> for ConnectionType {
}
}
/// ID for a node on the network.
#[doc(alias = "NetworkNodeID")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NodeID {
/// No node ID set (not connected to a network).
None,
/// A normal node on the network, counting from 1 (the host) to 16, inclusive.
Node(u8),
/// Broadcast to all nodes
Broadcast,
}
impl From<NodeID> for u16 {
fn from(value: NodeID) -> Self {
match value {
NodeID::None => 0,
NodeID::Node(node) => node as u16,
NodeID::Broadcast => ctru_sys::UDS_BROADCAST_NETWORKNODEID as u16,
}
}
}
impl TryFrom<u16> for NodeID {
type Error = ();
fn try_from(value: u16) -> std::result::Result<Self, Self::Error> {
match value as u32 {
0 => Ok(Self::None),
ctru_sys::UDS_HOST_NETWORKNODEID..=ctru_sys::UDS_MAXNODES => {
Ok(Self::Node(value as u8))
}
ctru_sys::UDS_BROADCAST_NETWORKNODEID => Ok(Self::Broadcast),
_ => Err(()),
}
}
}
/// Information about a network node.
#[allow(missing_docs)]
#[doc(alias = "udsNodeInfo")]
@ -105,7 +142,7 @@ pub struct NodeInfo { @@ -105,7 +142,7 @@ pub struct NodeInfo {
unk_x1c: u16,
pub flag: u8,
pad_x1f: u8,
pub node_id: u16,
pub node_id: NodeID,
pad_x22: u16,
word_x24: u32,
}
@ -121,7 +158,10 @@ impl From<ctru_sys::udsNodeInfo> for NodeInfo { @@ -121,7 +158,10 @@ impl From<ctru_sys::udsNodeInfo> for NodeInfo {
unk_x1c: value.__bindgen_anon_1.__bindgen_anon_1.unk_x1c,
flag: value.__bindgen_anon_1.__bindgen_anon_1.flag,
pad_x1f: value.__bindgen_anon_1.__bindgen_anon_1.pad_x1f,
node_id: value.NetworkNodeID,
node_id: value
.NetworkNodeID
.try_into()
.expect("UDS service should always provide a valid NetworkNodeID"),
pad_x22: value.pad_x22,
word_x24: value.word_x24,
}
@ -163,11 +203,12 @@ impl From<ctru_sys::udsNetworkScanInfo> for NetworkScanInfo { @@ -163,11 +203,12 @@ impl From<ctru_sys::udsNetworkScanInfo> for NetworkScanInfo {
#[doc(alias = "udsConnectionStatus")]
#[derive(Debug)]
pub struct ConnectionStatus {
/// Raw status information
// TODO: is this in some kind of readable format?
pub status: u32,
unk_x4: u32,
/// Network node ID for the current device.
pub cur_node_id: u16,
pub cur_node_id: NodeID,
unk_xa: u16,
unk_xc: [u32; 8],
/// Number of nodes connected to the network.
@ -185,7 +226,10 @@ impl From<ctru_sys::udsConnectionStatus> for ConnectionStatus { @@ -185,7 +226,10 @@ impl From<ctru_sys::udsConnectionStatus> for ConnectionStatus {
Self {
status: value.status,
unk_x4: value.unk_x4,
cur_node_id: value.cur_NetworkNodeID,
cur_node_id: value
.cur_NetworkNodeID
.try_into()
.expect("UDS service should always provide a valid NetworkNodeID"),
unk_xa: value.unk_xa,
unk_xc: value.unk_xc,
total_nodes: value.total_nodes,
@ -196,7 +240,7 @@ impl From<ctru_sys::udsConnectionStatus> for ConnectionStatus { @@ -196,7 +240,7 @@ impl From<ctru_sys::udsConnectionStatus> for ConnectionStatus {
}
/// Status of the service handle.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ServiceStatus {
/// Not connected to or hosting a network.
Disconnected,
@ -252,7 +296,7 @@ impl Uds { @@ -252,7 +296,7 @@ impl Uds {
/// Initialise a new service handle.
/// No `new_with_buffer_size` function is provided, as there isn't really a
/// reason to use any size other than the default.
///
///
/// The `username` parameter should be a max 10-byte (not 10 code point!) UTF-8 string, converted to UTF-16 internally.
/// Pass `None` to use the 3DS's configured username.
///
@ -754,7 +798,7 @@ impl Uds { @@ -754,7 +798,7 @@ impl Uds {
pub fn send_packet(
&self,
packet: &[u8],
to_nodes: u16,
address: NodeID,
channel: u8,
flags: SendFlags,
) -> Result<(), Error> {
@ -768,7 +812,7 @@ impl Uds { @@ -768,7 +812,7 @@ impl Uds {
let code = ResultCode(unsafe {
ctru_sys::udsSendTo(
to_nodes,
address.into(),
channel,
flags.bits(),
packet.as_ptr().cast(),
@ -815,7 +859,7 @@ impl Uds { @@ -815,7 +859,7 @@ impl Uds {
/// # }
/// ```
#[doc(alias = "udsPullPacket")]
pub fn pull_packet(&self) -> Result<Option<(Vec<u8>, u16)>, Error> {
pub fn pull_packet(&self) -> Result<Option<(Vec<u8>, NodeID)>, Error> {
if self.service_status() == ServiceStatus::Disconnected {
return Err(Error::NotConnected);
}
@ -843,7 +887,12 @@ impl Uds { @@ -843,7 +887,12 @@ impl Uds {
None
} else {
// TODO: to_vec() first, then truncate() and shrink_to_fit()?
Some((frame[..actual_size].to_vec(), src_node_id))
Some((
frame[..actual_size].to_vec(),
src_node_id
.try_into()
.expect("UDS service should always provide a valid NetworkNodeID"),
))
})
}

Loading…
Cancel
Save