mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 23:24:15 +01:00
remote connection preparations
This commit is contained in:
parent
90a79eccb8
commit
33c6e2bbdc
@ -25,9 +25,13 @@ struct Cli {
|
|||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Commands,
|
command: Commands,
|
||||||
|
|
||||||
/// Use SC64 device matching provided serial number
|
/// Connect to SC64 device on provided serial port
|
||||||
#[arg(long)]
|
#[arg(short, long, conflicts_with = "remote")]
|
||||||
sn: Option<String>,
|
port: Option<String>,
|
||||||
|
|
||||||
|
/// Connect to SC64 device on provided remote address
|
||||||
|
#[arg(short, long, conflicts_with = "port")]
|
||||||
|
remote: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
@ -64,6 +68,9 @@ enum Commands {
|
|||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: FirmwareCommands,
|
command: FirmwareCommands,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Expose SC64 device over network
|
||||||
|
Server(ServerArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args)]
|
#[derive(Args)]
|
||||||
@ -170,6 +177,13 @@ struct FirmwareArgs {
|
|||||||
firmware: PathBuf,
|
firmware: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Args)]
|
||||||
|
struct ServerArgs {
|
||||||
|
/// Listen on provided address:port
|
||||||
|
#[arg(default_value = "127.0.0.1:9064")]
|
||||||
|
address: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, ValueEnum)]
|
#[derive(Clone, ValueEnum)]
|
||||||
enum SaveType {
|
enum SaveType {
|
||||||
None,
|
None,
|
||||||
@ -224,6 +238,11 @@ impl From<TvType> for sc64::TvType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Connection {
|
||||||
|
Local(Option<String>),
|
||||||
|
Remote(String),
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
@ -232,7 +251,7 @@ fn main() {
|
|||||||
panic::set_hook(Box::new(|_| {}));
|
panic::set_hook(Box::new(|_| {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
match panic::catch_unwind(|| handle_command(&cli.command, cli.sn)) {
|
match panic::catch_unwind(|| handle_command(&cli.command, cli.port, cli.remote)) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(payload) => {
|
Err(payload) => {
|
||||||
eprintln!("{}", panic_message(&payload).red());
|
eprintln!("{}", panic_message(&payload).red());
|
||||||
@ -241,17 +260,23 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_command(command: &Commands, sn: Option<String>) {
|
fn handle_command(command: &Commands, port: Option<String>, remote: Option<String>) {
|
||||||
|
let connection = if let Some(remote) = remote {
|
||||||
|
Connection::Remote(remote)
|
||||||
|
} else {
|
||||||
|
Connection::Local(port)
|
||||||
|
};
|
||||||
let result = match command {
|
let result = match command {
|
||||||
Commands::List => handle_list_command(),
|
Commands::List => handle_list_command(),
|
||||||
Commands::Upload(args) => handle_upload_command(sn, args),
|
Commands::Upload(args) => handle_upload_command(connection, args),
|
||||||
Commands::DownloadSave(args) => handle_download_save_command(sn, args),
|
Commands::DownloadSave(args) => handle_download_save_command(connection, args),
|
||||||
Commands::_64DD(args) => handle_64dd_command(sn, args),
|
Commands::_64DD(args) => handle_64dd_command(connection, args),
|
||||||
Commands::Debug(args) => handle_debug_command(sn, args),
|
Commands::Debug(args) => handle_debug_command(connection, args),
|
||||||
Commands::Dump(args) => handle_dump_command(sn, args),
|
Commands::Dump(args) => handle_dump_command(connection, args),
|
||||||
Commands::Info => handle_info_command(sn),
|
Commands::Info => handle_info_command(connection),
|
||||||
Commands::Set { command } => handle_set_command(sn, command),
|
Commands::Set { command } => handle_set_command(connection, command),
|
||||||
Commands::Firmware { command } => handle_firmware_command(sn, command),
|
Commands::Firmware { command } => handle_firmware_command(connection, command),
|
||||||
|
Commands::Server(args) => handle_server_command(connection, args),
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
@ -260,18 +285,18 @@ fn handle_command(command: &Commands, sn: Option<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_list_command() -> Result<(), sc64::Error> {
|
fn handle_list_command() -> Result<(), sc64::Error> {
|
||||||
let devices = sc64::list_serial_devices()?;
|
let devices = sc64::list_local_devices()?;
|
||||||
|
|
||||||
println!("{}", "Found devices:".bold());
|
println!("{}", "Found devices:".bold());
|
||||||
for (i, d) in devices.iter().enumerate() {
|
for (i, d) in devices.iter().enumerate() {
|
||||||
println!(" {i}: {}", d.sn);
|
println!(" {i}: [{}] at port [{}]", d.serial_number, d.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_upload_command(sn: Option<String>, args: &UploadArgs) -> Result<(), sc64::Error> {
|
fn handle_upload_command(connection: Connection, args: &UploadArgs) -> Result<(), sc64::Error> {
|
||||||
let mut sc64 = init_sc64(sn, true)?;
|
let mut sc64 = init_sc64(connection, true)?;
|
||||||
|
|
||||||
let (rom_file_unbuffered, rom_name, rom_length) = open_file(&args.rom)?;
|
let (rom_file_unbuffered, rom_name, rom_length) = open_file(&args.rom)?;
|
||||||
let mut rom_file = BufReader::new(rom_file_unbuffered);
|
let mut rom_file = BufReader::new(rom_file_unbuffered);
|
||||||
@ -328,10 +353,10 @@ fn handle_upload_command(sn: Option<String>, args: &UploadArgs) -> Result<(), sc
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_download_save_command(
|
fn handle_download_save_command(
|
||||||
sn: Option<String>,
|
connection: Connection,
|
||||||
args: &DownloadSaveArgs,
|
args: &DownloadSaveArgs,
|
||||||
) -> Result<(), sc64::Error> {
|
) -> Result<(), sc64::Error> {
|
||||||
let mut sc64 = init_sc64(sn, true)?;
|
let mut sc64 = init_sc64(connection, true)?;
|
||||||
|
|
||||||
let (mut file, name) = create_file(&args.path)?;
|
let (mut file, name) = create_file(&args.path)?;
|
||||||
|
|
||||||
@ -342,8 +367,8 @@ fn handle_download_save_command(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_64dd_command(sn: Option<String>, args: &_64DDArgs) -> Result<(), sc64::Error> {
|
fn handle_64dd_command(connection: Connection, args: &_64DDArgs) -> Result<(), sc64::Error> {
|
||||||
let _ = (sn, args);
|
let _ = (connection, args);
|
||||||
|
|
||||||
// TODO: handle 64DD stuff
|
// TODO: handle 64DD stuff
|
||||||
|
|
||||||
@ -355,13 +380,13 @@ fn handle_64dd_command(sn: Option<String>, args: &_64DDArgs) -> Result<(), sc64:
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_debug_command(sn: Option<String>, args: &DebugArgs) -> Result<(), sc64::Error> {
|
fn handle_debug_command(connection: Connection, args: &DebugArgs) -> Result<(), sc64::Error> {
|
||||||
let mut debug_handler = debug::new(args.gdb)?;
|
let mut debug_handler = debug::new(args.gdb)?;
|
||||||
if let Some(port) = args.gdb {
|
if let Some(port) = args.gdb {
|
||||||
println!("GDB TCP socket listening at [0.0.0.0:{port}]");
|
println!("GDB TCP socket listening at [0.0.0.0:{port}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut sc64 = init_sc64(sn, true)?;
|
let mut sc64 = init_sc64(connection, true)?;
|
||||||
|
|
||||||
if args.isv.is_some() {
|
if args.isv.is_some() {
|
||||||
sc64.configure_is_viewer_64(args.isv)?;
|
sc64.configure_is_viewer_64(args.isv)?;
|
||||||
@ -403,8 +428,8 @@ fn handle_debug_command(sn: Option<String>, args: &DebugArgs) -> Result<(), sc64
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_dump_command(sn: Option<String>, args: &DumpArgs) -> Result<(), sc64::Error> {
|
fn handle_dump_command(connection: Connection, args: &DumpArgs) -> Result<(), sc64::Error> {
|
||||||
let mut sc64 = init_sc64(sn, true)?;
|
let mut sc64 = init_sc64(connection, true)?;
|
||||||
|
|
||||||
let (mut dump_file, dump_name) = create_file(&args.path)?;
|
let (mut dump_file, dump_name) = create_file(&args.path)?;
|
||||||
|
|
||||||
@ -421,8 +446,8 @@ fn handle_dump_command(sn: Option<String>, args: &DumpArgs) -> Result<(), sc64::
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_info_command(sn: Option<String>) -> Result<(), sc64::Error> {
|
fn handle_info_command(connection: Connection) -> Result<(), sc64::Error> {
|
||||||
let mut sc64 = init_sc64(sn, false)?;
|
let mut sc64 = init_sc64(connection, true)?;
|
||||||
|
|
||||||
let (major, minor) = sc64.check_firmware_version()?;
|
let (major, minor) = sc64.check_firmware_version()?;
|
||||||
let state = sc64.get_device_state()?;
|
let state = sc64.get_device_state()?;
|
||||||
@ -453,8 +478,8 @@ fn handle_info_command(sn: Option<String>) -> Result<(), sc64::Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_set_command(sn: Option<String>, command: &SetCommands) -> Result<(), sc64::Error> {
|
fn handle_set_command(connection: Connection, command: &SetCommands) -> Result<(), sc64::Error> {
|
||||||
let mut sc64 = init_sc64(sn, true)?;
|
let mut sc64 = init_sc64(connection, true)?;
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
SetCommands::Rtc => {
|
SetCommands::Rtc => {
|
||||||
@ -484,7 +509,7 @@ fn handle_set_command(sn: Option<String>, command: &SetCommands) -> Result<(), s
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_firmware_command(
|
fn handle_firmware_command(
|
||||||
sn: Option<String>,
|
connection: Connection,
|
||||||
command: &FirmwareCommands,
|
command: &FirmwareCommands,
|
||||||
) -> Result<(), sc64::Error> {
|
) -> Result<(), sc64::Error> {
|
||||||
match command {
|
match command {
|
||||||
@ -502,7 +527,7 @@ fn handle_firmware_command(
|
|||||||
}
|
}
|
||||||
|
|
||||||
FirmwareCommands::Backup(args) => {
|
FirmwareCommands::Backup(args) => {
|
||||||
let mut sc64 = init_sc64(sn, false)?;
|
let mut sc64 = init_sc64(connection, false)?;
|
||||||
|
|
||||||
let (mut backup_file, backup_name) = create_file(&args.firmware)?;
|
let (mut backup_file, backup_name) = create_file(&args.firmware)?;
|
||||||
|
|
||||||
@ -523,7 +548,7 @@ fn handle_firmware_command(
|
|||||||
}
|
}
|
||||||
|
|
||||||
FirmwareCommands::Update(args) => {
|
FirmwareCommands::Update(args) => {
|
||||||
let mut sc64 = init_sc64(sn, false)?;
|
let mut sc64 = init_sc64(connection, false)?;
|
||||||
|
|
||||||
let (mut update_file, update_name, update_length) = open_file(&args.firmware)?;
|
let (mut update_file, update_name, update_length) = open_file(&args.firmware)?;
|
||||||
|
|
||||||
@ -546,8 +571,26 @@ fn handle_firmware_command(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_sc64(sn: Option<String>, check_firmware: bool) -> Result<sc64::SC64, sc64::Error> {
|
fn handle_server_command(connection: Connection, args: &ServerArgs) -> Result<(), sc64::Error> {
|
||||||
let mut sc64 = sc64::new(sn)?;
|
let port = if let Connection::Local(port) = connection {
|
||||||
|
port
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let _server = sc64::new_server(port, args.address.clone())?;
|
||||||
|
|
||||||
|
let exit = setup_exit_flag();
|
||||||
|
while !exit.load(Ordering::Relaxed) {}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_sc64(connection: Connection, check_firmware: bool) -> Result<sc64::SC64, sc64::Error> {
|
||||||
|
let mut sc64 = match connection {
|
||||||
|
Connection::Local(port) => sc64::new_local(port),
|
||||||
|
Connection::Remote(remote) => sc64::new_remote(remote),
|
||||||
|
}?;
|
||||||
|
|
||||||
if check_firmware {
|
if check_firmware {
|
||||||
sc64.check_firmware_version()?;
|
sc64.check_firmware_version()?;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use super::{error::Error, utils};
|
use super::{error::Error, utils};
|
||||||
use std::{collections::VecDeque, time::Duration};
|
use std::{collections::VecDeque, time::Duration};
|
||||||
|
|
||||||
pub struct Device {
|
pub struct LocalDevice {
|
||||||
pub sn: String,
|
|
||||||
pub port: String,
|
pub port: String,
|
||||||
|
pub serial_number: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Command {
|
pub struct Command {
|
||||||
@ -184,33 +184,33 @@ impl Link for SerialLink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_serial_devices() -> Result<Vec<Device>, Error> {
|
pub fn list_local_devices() -> Result<Vec<LocalDevice>, Error> {
|
||||||
const SC64_VID: u16 = 0x0403;
|
const SC64_VID: u16 = 0x0403;
|
||||||
const SC64_PID: u16 = 0x6014;
|
const SC64_PID: u16 = 0x6014;
|
||||||
const SC64_SID: &str = "SC64";
|
const SC64_SID: &str = "SC64";
|
||||||
|
|
||||||
let mut devices: Vec<Device> = Vec::new();
|
let mut serial_devices: Vec<LocalDevice> = Vec::new();
|
||||||
|
|
||||||
for device in serialport::available_ports()?.into_iter() {
|
for device in serialport::available_ports()?.into_iter() {
|
||||||
if let serialport::SerialPortType::UsbPort(info) = device.port_type {
|
if let serialport::SerialPortType::UsbPort(info) = device.port_type {
|
||||||
let sn = info.serial_number.unwrap_or("".to_string());
|
let serial_number = info.serial_number.unwrap_or("".to_string());
|
||||||
if info.vid == SC64_VID && info.pid == SC64_PID && sn.starts_with(SC64_SID) {
|
if info.vid == SC64_VID && info.pid == SC64_PID && serial_number.starts_with(SC64_SID) {
|
||||||
devices.push(Device {
|
serial_devices.push(LocalDevice {
|
||||||
sn,
|
|
||||||
port: device.port_name,
|
port: device.port_name,
|
||||||
|
serial_number,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if devices.len() == 0 {
|
if serial_devices.len() == 0 {
|
||||||
return Err(Error::new("No SC64 devices found"));
|
return Err(Error::new("No SC64 devices found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(devices);
|
return Ok(serial_devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_serial(port: &str) -> Result<Box<dyn Link>, Error> {
|
pub fn new_local(port: &str) -> Result<Box<dyn Link>, Error> {
|
||||||
let mut link = SerialLink {
|
let mut link = SerialLink {
|
||||||
serial: serialport::new(port, 115_200).open()?,
|
serial: serialport::new(port, 115_200).open()?,
|
||||||
packets: VecDeque::new(),
|
packets: VecDeque::new(),
|
||||||
|
@ -7,7 +7,7 @@ mod utils;
|
|||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
error::Error,
|
error::Error,
|
||||||
link::list_serial_devices,
|
link::list_local_devices,
|
||||||
types::{
|
types::{
|
||||||
BootMode, ButtonMode, ButtonState, CicSeed, DataPacket, DdDiskState, DdDriveType, DdMode,
|
BootMode, ButtonMode, ButtonState, CicSeed, DataPacket, DdDiskState, DdDriveType, DdMode,
|
||||||
DebugPacket, DiskPacket, FpgaDebugData, McuStackUsage, SaveType, Switch, TvType,
|
DebugPacket, DiskPacket, FpgaDebugData, McuStackUsage, SaveType, Switch, TvType,
|
||||||
@ -684,21 +684,15 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(sn: Option<String>) -> Result<SC64, Error> {
|
pub fn new_local(port: Option<String>) -> Result<SC64, Error> {
|
||||||
let port = match sn {
|
let port = if let Some(port) = port {
|
||||||
Some(sn) => match list_serial_devices()?.iter().find(|d| d.sn == sn) {
|
port
|
||||||
Some(device) => device.port.clone(),
|
} else {
|
||||||
None => {
|
list_local_devices()?[0].port.clone()
|
||||||
return Err(Error::new(
|
|
||||||
"No SC64 device found matching provided serial number",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => list_serial_devices()?[0].port.clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut sc64 = SC64 {
|
let mut sc64 = SC64 {
|
||||||
link: link::new_serial(&port)?,
|
link: link::new_local(&port)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let identifier = sc64
|
let identifier = sc64
|
||||||
@ -711,3 +705,13 @@ pub fn new(sn: Option<String>) -> Result<SC64, Error> {
|
|||||||
|
|
||||||
Ok(sc64)
|
Ok(sc64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_remote(remote: String) -> Result<SC64, Error> {
|
||||||
|
let _ = remote;
|
||||||
|
Err(Error::new("Remote connection not implemented yet"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_server(port: Option<String>, bind: String) -> Result<(), Error> {
|
||||||
|
let _ = (port, bind);
|
||||||
|
Err(Error::new("SC64 server not implemented yet"))
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user