diff --git a/README.md b/README.md index 1c9e736..6cd8242 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ -# cd sphinx-key +# sphinx-key These notes were tested for macOS ### deps +`cd sphinx-key` + ##### cargo nightly: `rustup install nightly` @@ -30,12 +32,12 @@ These notes were tested for macOS ### flash -`espflash /dev/tty.SLAB_USBtoUART target/riscv32imc-esp-espidf/debug/sphinx-key` - -If the above command does not work, try this one below: - `espflash target/riscv32imc-esp-espidf/debug/sphinx-key` ### monitor -`espmonitor /dev/ttyUSB0` \ No newline at end of file +```sh +ls /dev/tty.* +ls /dev/cu.* +espmonitor /dev/tty.usbserial-1420 +``` \ No newline at end of file diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 61dbd3f..b13b529 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -1,3 +1,3 @@ pub fn say_hi() { - println!("hi!"); + println!("hi from signer module!"); } \ No newline at end of file diff --git a/sphinx-key/Cargo.toml b/sphinx-key/Cargo.toml index 130b9f2..0a153a8 100644 --- a/sphinx-key/Cargo.toml +++ b/sphinx-key/Cargo.toml @@ -24,6 +24,8 @@ esp-idf-hal = "0.37" anyhow = {version = "1", features = ["backtrace"]} log = "0.4" url = "2" +serde_urlencoded = "0.7.1" +serde = "1.0.137" [build-dependencies] embuild = "0.29" diff --git a/sphinx-key/go.sh b/sphinx-key/go.sh new file mode 100755 index 0000000..1102d9f --- /dev/null +++ b/sphinx-key/go.sh @@ -0,0 +1,3 @@ +cargo build +espflash target/riscv32imc-esp-espidf/debug/sphinx-key +espmonitor /dev/tty.usbserial-1420 \ No newline at end of file diff --git a/sphinx-key/src/srv/html.rs b/sphinx-key/src/conn/html.rs similarity index 100% rename from sphinx-key/src/srv/html.rs rename to sphinx-key/src/conn/html.rs diff --git a/sphinx-key/src/conn/mod.rs b/sphinx-key/src/conn/mod.rs new file mode 100644 index 0000000..f79c242 --- /dev/null +++ b/sphinx-key/src/conn/mod.rs @@ -0,0 +1,47 @@ +mod html; +pub mod wifi; + +use url; +use embedded_svc::httpd::*; +use esp_idf_svc::httpd as idf; +use std::sync::{Condvar, Mutex, Arc}; +use embedded_svc::httpd::registry::Registry; +use esp_idf_sys::{self}; +use esp_idf_svc::nvs::*; +use esp_idf_svc::nvs_storage::EspNvsStorage; +use embedded_svc::storage::Storage; +use serde::Deserialize; + +#[derive(Clone, Debug, Deserialize)] +pub struct Config { + pub broker: String, + // pub ssid: String, + // pub pass: String, +} + +/* +curl -X POST 192.168.71.1/config?broker=52.91.253.115%3A1883&ssid=apples%26acorns&pass=42flutes + +curl -X POST 192.168.71.1/config?broker=52.91.253.115%3A1883 +*/ + +#[allow(unused_variables)] +pub fn config_server(mutex: Arc<(Mutex>, Condvar)>, store: Arc>) -> Result { + + let server = idf::ServerRegistry::new() + .at("/") + .get(|_| Ok(html::HTML.into()))? + .at("/config") + .post(move |mut request| { + let bod = &request.query_string() + .ok_or(anyhow::anyhow!("failed to parse query string"))?;; + let conf = serde_urlencoded::from_str::(bod)?; + + let mut wait = mutex.0.lock().unwrap(); + *wait = Some(conf); + mutex.1.notify_one(); + Ok("{\"success\":true}".to_owned().into()) + })?; + + server.start(&Default::default()) +} \ No newline at end of file diff --git a/sphinx-key/src/conn/wifi.rs b/sphinx-key/src/conn/wifi.rs new file mode 100644 index 0000000..def82d6 --- /dev/null +++ b/sphinx-key/src/conn/wifi.rs @@ -0,0 +1,117 @@ +use esp_idf_svc::wifi::*; +use esp_idf_svc::sysloop::*; +use esp_idf_svc::netif::*; +use esp_idf_svc::nvs::EspDefaultNvs; +use esp_idf_svc::ping; + +use embedded_svc::wifi::*; +use embedded_svc::httpd::Result; +use embedded_svc::ping::Ping; +use embedded_svc::ipv4; + +use log::*; +use anyhow::bail; +use std::time::Duration; +use std::sync::Arc; + +const SSID: &str = "apples&acorns"; +const PASS: &str = "42flutes"; + +#[cfg(not(feature = "qemu"))] +#[allow(dead_code)] +pub fn connect( + netif_stack: Arc, + sys_loop_stack: Arc, + default_nvs: Arc, +) -> Result> { + let mut wifi = Box::new(EspWifi::new(netif_stack, sys_loop_stack, default_nvs)?); + + info!("Wifi created, about to scan"); + + let ap_infos = wifi.scan()?; + + let ours = ap_infos.into_iter().find(|a| a.ssid == SSID); + + let channel = if let Some(ours) = ours { + info!( + "Found configured access point {} on channel {}", + SSID, ours.channel + ); + Some(ours.channel) + } else { + info!( + "Configured access point {} not found during scanning, will go with unknown channel", + SSID + ); + None + }; + + // let conf = Configuration::Client( + // ClientConfiguration { + // ssid: SSID.into(), + // password: PASS.into(), + // channel, + // ..Default::default() + // }; + // ); + // let conf = Configuration::AccessPoint( + // AccessPointConfiguration { + // ssid: "aptest111".into(), + // channel: channel.unwrap_or(1), + // ..Default::default() + // }, + // ); + let conf = Configuration::Mixed( + ClientConfiguration { + ssid: SSID.into(), + password: PASS.into(), + channel, + ..Default::default() + }, + AccessPointConfiguration { + ssid: "aptest123".into(), + channel: channel.unwrap_or(1), + ..Default::default() + }, + ); + wifi.set_configuration(&conf)?; + + info!("Wifi configuration set, about to get status"); + + wifi.wait_status_with_timeout(Duration::from_secs(20), |status| !status.is_transitional()) + .map_err(|e| anyhow::anyhow!("Unexpected Wifi status: {:?}", e))?; + + let status = wifi.get_status(); + + if let Status( + ClientStatus::Started(ClientConnectionStatus::Connected(ClientIpStatus::Done(ip_settings))), + ApStatus::Started(ApIpStatus::Done), + ) = status + { + info!("Wifi connected"); + + ping(&ip_settings)?; + } else { + bail!("Unexpected Wifi status: {:?}", status); + } + + Ok(wifi) +} + + +fn ping(ip_settings: &ipv4::ClientSettings) -> Result<()> { + info!("About to do some pings for {:?}", ip_settings); + + let ping_summary = + ping::EspPing::default().ping(ip_settings.subnet.gateway, &Default::default())?; + if ping_summary.transmitted != ping_summary.received { + bail!( + "Pinging gateway {} resulted in timeouts", + ip_settings.subnet.gateway + ); + } + + info!("Pinging done"); + + Ok(()) +} \ No newline at end of file diff --git a/sphinx-key/src/main.rs b/sphinx-key/src/main.rs index 95a2e03..4b1bbe6 100644 --- a/sphinx-key/src/main.rs +++ b/sphinx-key/src/main.rs @@ -1,11 +1,25 @@ #![allow(unused_imports)] -mod srv; +mod conn; -use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported use sphinx_key_signer; +use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported +use std::thread; +use log::*; + use std::sync::{Condvar, Mutex, Arc}; +use std::time::*; + +use esp_idf_svc::nvs::*; +use esp_idf_svc::nvs_storage::EspNvsStorage; +use esp_idf_svc::netif::*; +use esp_idf_svc::eventloop::*; +use esp_idf_svc::sysloop::*; +use esp_idf_svc::wifi::*; + use embedded_svc::httpd::*; +use embedded_svc::wifi::*; + // use log::*; // use url; @@ -14,13 +28,60 @@ fn main() -> Result<()> { // or else some patches to the runtime implemented by esp-idf-sys might not link properly. esp_idf_sys::link_patches(); - println!("Hello, world!"); + esp_idf_svc::log::EspLogger::initialize_default(); sphinx_key_signer::say_hi(); + // let init_conf = Some(conn::Config{ + // broker: "52.91.253.115:1883".to_string(), + // }); let mutex = Arc::new((Mutex::new(None), Condvar::new())); - let _httpd = srv::httpd(mutex.clone()); + let netif_stack = Arc::new(EspNetifStack::new()?); + let sys_loop_stack = Arc::new(EspSysLoopStack::new()?); + let default_nvs = Arc::new(EspDefaultNvs::new()?); + let storage = Arc::new(Mutex::new(EspNvsStorage::new_default(default_nvs.clone(), "sphinx", true).expect("NVS FAIL"))); + + #[allow(clippy::redundant_clone)] + #[allow(unused_mut)] + let mut wifi = conn::wifi::connect( + netif_stack.clone(), + sys_loop_stack.clone(), + default_nvs.clone(), + )?; + + // conn::tcp::tcp_bind().expect("failed TCP bind"); + + let httpd = conn::config_server(mutex.clone(), storage); + + info!("=====> yo yo"); + + let mut wait = mutex.0.lock().unwrap(); + + let config = loop { + if let Some(conf) = &*wait { + break conf; + } else { + wait = mutex + .1 + .wait_timeout(wait, Duration::from_secs(1)) + .unwrap() + .0; + println!("tick..."); + } + }; + + println!("===> config! {:?}", config); + + let mut i = 0; + loop { + thread::sleep(Duration::from_secs(5)); + i = i + 1; + println!("wait forever... {}", i); + } + + // drop(httpd); + // println!("Httpd stopped"); /* shutdown */ // drop(httpd); diff --git a/sphinx-key/src/srv/mod.rs b/sphinx-key/src/srv/mod.rs deleted file mode 100644 index 708806a..0000000 --- a/sphinx-key/src/srv/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -mod html; - -use embedded_svc::httpd::*; -use esp_idf_svc::httpd as idf; -use std::sync::{Condvar, Mutex, Arc}; -use embedded_svc::httpd::registry::Registry; -use esp_idf_sys::{self}; - -#[allow(unused_variables)] -pub fn httpd(mutex: Arc<(Mutex>, Condvar)>) -> Result { - - let server = idf::ServerRegistry::new() - .at("/") - .get(|_| { - Ok(html::HTML.into()) - })?; - - server.start(&Default::default()) -} \ No newline at end of file