Skip to content

Commit

Permalink
Add static ip config
Browse files Browse the repository at this point in the history
Untested
  • Loading branch information
mkj committed Jun 25, 2023
1 parent 3d02cc4 commit dfb6c76
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 18 deletions.
59 changes: 54 additions & 5 deletions embassy/demos/common/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use defmt::{debug, error, info, panic, trace, warn};
use hmac::{Hmac, Mac};
use sha2::Sha256;

use heapless::String;
use heapless::{String, Vec};

use embassy_net::{StaticConfigV4, Ipv4Cidr, Ipv4Address};

use sunset_sshwire_derive::*;

Expand Down Expand Up @@ -51,7 +53,11 @@ pub struct SSHConfig {
/// WPA2 passphrase. None is Open network.
pub wifi_pw: Option<String<63>>,

/// For wl5500. cyw43 uses its own internal
pub mac: [u8; 6],

/// `None` for DHCP
pub ip4_static: Option<StaticConfigV4>,
}

fn random_mac() -> Result<[u8; 6]> {
Expand All @@ -62,15 +68,14 @@ fn random_mac() -> Result<[u8; 6]> {
Ok(mac)
}


impl SSHConfig {
/// Bump this when the format changes
pub const CURRENT_VERSION: u8 = 5;
pub const CURRENT_VERSION: u8 = 6;
/// A buffer this large will fit any SSHConfig.
// It can be updated by looking at
// `cargo test -- roundtrip_config`
// in the demos/common directory
pub const BUF_SIZE: usize = 449;
pub const BUF_SIZE: usize = 460;

/// Creates a new config with default parameters.
///
Expand All @@ -91,6 +96,7 @@ impl SSHConfig {
wifi_net,
wifi_pw,
mac,
ip4_static: None,
})
}

Expand Down Expand Up @@ -152,6 +158,38 @@ where
bool::dec(s)?.then(|| SSHDecode::dec(s)).transpose()
}

fn enc_ip4config(v: &Option<StaticConfigV4>, s: &mut dyn SSHSink) -> WireResult<()> {
v.is_some().enc(s)?;
if let Some(v) = v {
v.address.address().0.enc(s)?;
v.address.prefix_len().enc(s)?;
// to [u8; 4]
let gw = v.gateway.map(|a| a.0);
enc_option(&gw, s)?;
}
Ok(())
}

fn dec_ip4config<'de, S>(s: &mut S) -> WireResult<Option<StaticConfigV4>>
where
S: SSHSource<'de>,
{
let opt = bool::dec(s)?;
opt.then(|| {
let ad: [u8; 4] = SSHDecode::dec(s)?;
let ad = Ipv4Address::from_bytes(&ad);
let prefix = SSHDecode::dec(s)?;
let gw: Option<[u8; 4]> = dec_option(s)?;
let gateway = gw.map(|gw| Ipv4Address::from_bytes(&gw));
Ok(StaticConfigV4 {
address: Ipv4Cidr::new(ad, prefix),
gateway,
dns_servers: Vec::new(),
})
})
.transpose()
}

impl SSHEncode for SSHConfig {
fn enc(&self, s: &mut dyn SSHSink) -> WireResult<()> {
info!("enc si");
Expand All @@ -176,6 +214,8 @@ impl SSHEncode for SSHConfig {

self.mac.enc(s)?;

enc_ip4config(&self.ip4_static, s)?;

Ok(())
}
}
Expand Down Expand Up @@ -208,6 +248,8 @@ impl<'de> SSHDecode<'de> for SSHConfig {

let mac = SSHDecode::dec(s)?;

let ip4_static = dec_ip4config(s)?;

Ok(Self {
hostkey,
console_pw,
Expand All @@ -218,6 +260,7 @@ impl<'de> SSHDecode<'de> for SSHConfig {
wifi_net,
wifi_pw,
mac,
ip4_static,
})
}
}
Expand Down Expand Up @@ -320,7 +363,13 @@ mod tests {
wifi_pw: Some(
core::str::from_utf8([b'f'; 63].as_slice()).unwrap().into(),
),
mac: [6,2,3,4,5,6],
mac: [6, 2, 3, 4, 5, 6],
ip4_static: Some(embassy_net::StaticConfigV4 {
address: embassy_net::Ipv4Cidr::new(embassy_net::Ipv4Address::UNSPECIFIED, 8),
gateway: Some(embassy_net::Ipv4Address::UNSPECIFIED),
// no dns servers. may need changing later?
dns_servers: heapless::Vec::new(),
}),
};

// test once to determine size to print
Expand Down
3 changes: 3 additions & 0 deletions embassy/demos/picow/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ mod wifi;
#[cfg(not(any(feature = "cyw43", feature = "w5500")))]
compile_error!("No network device selected. Use cyw43 or w5500 feature");

#[cfg(all(feature = "cyw43", feature = "w5500"))]
compile_error!("Select only one of cyw43 or w5500");

use demo_common::{SSHConfig, Shell};

use takepipe::TakePipe;
Expand Down
83 changes: 72 additions & 11 deletions embassy/demos/picow/src/picowmenu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,25 @@ use core::fmt::Write;
use core::future::{poll_fn, Future};
use core::ops::DerefMut;
use core::sync::atomic::Ordering::{Relaxed, SeqCst};
use core::str::FromStr;

use embedded_io::{asynch, Io};

use embassy_sync::waitqueue::MultiWakerRegistration;
use embassy_time::Duration;
use embassy_net::{Ipv4Cidr, Ipv4Address};

use heapless::{String, Vec};

use crate::flashconfig;
use crate::demo_common;
use crate::flashconfig;
use crate::GlobalState;
use demo_common::{BufOutput, SSHConfig};

use demo_common::menu::*;

use sunset::*;
use sunset::packets::Ed25519PubKey;
use sunset::*;

// arbitrary in bytes, for sizing buffers
const MAX_PW_LEN: usize = 50;
Expand Down Expand Up @@ -95,7 +97,10 @@ impl MenuCtx {
let _ = writeln!(self.out, "serial can't loop");
} else {
if self.state.usb_pipe.is_in_use() {
let _ = writeln!(self.out, "Opening usb1, stealing existing session");
let _ = writeln!(
self.out,
"Opening usb1, stealing existing session"
);
} else {
let _ = writeln!(self.out, "Opening usb1");
}
Expand All @@ -111,7 +116,10 @@ impl MenuCtx {
let _ = writeln!(self.out, "serial can't loop");
} else {
if self.state.serial1_pipe.is_in_use() {
let _ = writeln!(self.out, "Opening serial1, stealing existing session");
let _ = writeln!(
self.out,
"Opening serial1, stealing existing session"
);
} else {
let _ = writeln!(self.out, "Opening serial1");
}
Expand Down Expand Up @@ -404,6 +412,32 @@ const NET_ITEM: Item<MenuCtx> = Item {
},
help: None,
},
&Item {
command: "dhcp",
item_type: ItemType::Callback {
parameters: &[],
function: do_net_dhcp,
},
help: None,
},
&Item {
command: "static",
item_type: ItemType::Callback {
parameters: &[
Parameter::Mandatory {
parameter_name: "address/netmask",
help: None,
},
Parameter::Optional {
parameter_name: "gateway",
help: None,
},
],

function: do_net_static,
},
help: None,
},
],
entry: None,
exit: None,
Expand Down Expand Up @@ -607,12 +641,10 @@ fn do_admin_clear_pw(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx
// fn do_gpio_set(_item: &Item<MenuCtx>, _args: &[&str], _context: &mut MenuCtx) {}

fn do_erase_config(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) {
context.with_config(|c, out| {
match SSHConfig::new() {
Ok(n) => *c = n,
Err(e) => {
let _ = writeln!(out, "failed: {e}");
}
context.with_config(|c, out| match SSHConfig::new() {
Ok(n) => *c = n,
Err(e) => {
let _ = writeln!(out, "failed: {e}");
}
});
context.need_save = true;
Expand All @@ -633,7 +665,8 @@ fn do_bootsel(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) {
fn do_about(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) {
let _ = writeln!(
context,
"Sunset SSH, USB serial\nMatt Johnston <[email protected]>\n{}", env!("GIT_REV"),
"Sunset SSH, USB serial\nMatt Johnston <[email protected]>\n{}",
env!("GIT_REV"),
);
}

Expand Down Expand Up @@ -696,6 +729,34 @@ fn do_net_info(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) {
});
}

fn do_net_dhcp(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) {
context.with_config(|c, out| {
c.ip4_static = None;
});
}

fn do_net_static(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) {
context.with_config(|c, out| {
let ip = Ipv4Cidr::from_str(args[0]);
let gw = if args[1].is_empty() {
Ok(None)
} else {
Some(Ipv4Address::from_str(args[1])).transpose()
};
match (ip, gw) {
(Ok(address), Ok(gateway)) => {
c.ip4_static = Some(embassy_net::StaticConfigV4 {
address,
gateway,
dns_servers: Vec::new(),
})
}
_ => {
let _ = write!(out, "Bad args");
}
}
});
}

// Returns an error on EOF etc.
pub(crate) async fn request_pw<E>(
Expand Down
8 changes: 7 additions & 1 deletion embassy/demos/picow/src/w5500.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,19 @@ pub(crate) async fn w5500_stack(
.await;
spawner.spawn(ethernet_task(runner)).unwrap();

let config = if let Some(ref s) = config.lock().await.ip4_static {
embassy_net::Config::ipv4_static(s.clone())
} else {
embassy_net::Config::dhcpv4(Default::default())
};

// Generate random seed
let seed = OsRng.next_u64();

// Init network stack
let stack = &*make_static!(Stack::new(
device,
embassy_net::Config::dhcpv4(Default::default()),
config,
make_static!(StackResources::<{ crate::NUM_SOCKETS }>::new()),
seed
));
Expand Down
6 changes: 5 additions & 1 deletion embassy/demos/picow/src/wifi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ pub(crate) async fn wifi_stack(spawner: &Spawner,
}
}

let config = embassy_net::Config::dhcpv4(Default::default());
let config = if let Some(ref s) = config.lock().await.ip4_static {
embassy_net::Config::ipv4_static(s.clone())
} else {
embassy_net::Config::dhcpv4(Default::default())
};

let seed = OsRng.next_u64();

Expand Down

0 comments on commit dfb6c76

Please sign in to comment.