diff --git a/README.md b/README.md index 2e0c53a..538d849 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,15 @@ This should work together with `esp-wifi`. It currently won't work without. Howe See the examples for how to use it. A key thing is to enable the feature `big-heap` in esp-wifi since more heap memory is needed to get this working. +In general this is heavy in terms of heap memory used and code size. If you can, you should prefer using something like `embedded-tls`. + For now it's missing advanced configuration options which will be added step-by-step. +Currently this won't work on ESP32-S2 - getting it to work will require tweaking the memory usage a lot! + +The examples use one hard-coded address of `www.google.com` which might not always work. +Also the examples include hard-coded certificates which will expire some day. + ## License Licensed under either of: diff --git a/examples-esp32/Cargo.toml b/examples-esp32/Cargo.toml index 6b0dd57..c44582b 100644 --- a/examples-esp32/Cargo.toml +++ b/examples-esp32/Cargo.toml @@ -17,18 +17,16 @@ embassy-time = { version = "0.1.0", features = ["nightly"], optional = true } embassy-executor = { package = "embassy-executor", git = "https://github.com/embassy-rs/embassy/", rev = "cd9a65b", features = ["nightly", "integrated-timers"], optional = true } embassy-net = { git = "https://github.com/embassy-rs/embassy", rev = "26474ce6eb759e5add1c137f3417845e0797df3a", features = ["nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"], optional = true } -esp-wifi = { git = "https://github.com/esp-rs/esp-wifi.git", features = ["big-heap", "phy-enable-usb", "esp32", "embedded-svc", "wifi"], rev = "f79819d49d5dbb6899ef3e4de0fce837cac672ba" } +esp-wifi = { git = "https://github.com/esp-rs/esp-wifi.git", features = ["big-heap", "phy-enable-usb", "esp32", "embedded-svc", "wifi"], rev = "cce6738220f4f12ab4db92f74295e762f5425e99" } smoltcp = { version = "0.9.1", default-features=false, features = ["proto-igmp", "proto-ipv4", "socket-tcp", "socket-icmp", "socket-udp", "medium-ethernet", "proto-dhcpv4", "socket-raw", "socket-dhcpv4"] } embedded-svc = { version = "0.23.1", default-features = false} log = "0.4.16" embedded-hal = "0.2" -embedded-storage = "0.3.0" -crc = "3.0.0" embedded-io = "0.4.0" heapless = "0.7.16" critical-section = "1.0.1" -esp-mbedtls = { path = "/projects/esp/esp-mbedtls/esp-mbedtls", features = ["async"] } +esp-mbedtls = { path = "../esp-mbedtls", features = ["async"] } [[example]] name = "async" diff --git a/examples-esp32c3/Cargo.toml b/examples-esp32c3/Cargo.toml index 22a57b7..3cf5e4f 100644 --- a/examples-esp32c3/Cargo.toml +++ b/examples-esp32c3/Cargo.toml @@ -17,18 +17,16 @@ embassy-time = { version = "0.1.0", features = ["nightly"], optional = true } embassy-executor = { package = "embassy-executor", git = "https://github.com/embassy-rs/embassy/", rev = "cd9a65b", features = ["nightly", "integrated-timers"], optional = true } embassy-net = { git = "https://github.com/embassy-rs/embassy", rev = "26474ce6eb759e5add1c137f3417845e0797df3a", features = ["nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"], optional = true } -esp-wifi = { git = "https://github.com/esp-rs/esp-wifi.git", features = ["big-heap", "phy-enable-usb", "esp32c3", "embedded-svc", "wifi"], rev = "f79819d49d5dbb6899ef3e4de0fce837cac672ba" } +esp-wifi = { git = "https://github.com/esp-rs/esp-wifi.git", features = ["big-heap", "phy-enable-usb", "esp32c3", "embedded-svc", "wifi"], rev = "cce6738220f4f12ab4db92f74295e762f5425e99" } smoltcp = { version = "0.9.1", default-features=false, features = ["proto-igmp", "proto-ipv4", "socket-tcp", "socket-icmp", "socket-udp", "medium-ethernet", "proto-dhcpv4", "socket-raw", "socket-dhcpv4"] } embedded-svc = { version = "0.23.1", default-features = false} log = "0.4.16" embedded-hal = "0.2" -embedded-storage = "0.3.0" -crc = "3.0.0" embedded-io = "0.4.0" heapless = "0.7.16" critical-section = "1.0.1" -esp-mbedtls = { path = "/projects/esp/esp-mbedtls/esp-mbedtls", features = ["async"] } +esp-mbedtls = { path = "../esp-mbedtls", features = ["async"] } [[example]] name = "async" @@ -40,6 +38,3 @@ async = ["esp-wifi/esp32c3-async", "esp-wifi/embassy-net", "embassy-executor", " [patch.crates-io] esp32c3-hal = { git = "https://github.com/esp-rs/esp-hal", package = "esp32c3-hal", rev = "e5d1c603b0d4833632c2358ad3fad36964bf0ed5"} esp-hal-common = { git = "https://github.com/esp-rs/esp-hal", package = "esp-hal-common", rev = "e5d1c603b0d4833632c2358ad3fad36964bf0ed5"} - -[patch.'https://github.com/esp-rs/esp-wifi.git'] -esp-wifi = { path = "/projects/esp/esp-wifi/esp-wifi" } diff --git a/examples-esp32s3/.cargo/config.toml b/examples-esp32s3/.cargo/config.toml new file mode 100644 index 0000000..b48af12 --- /dev/null +++ b/examples-esp32s3/.cargo/config.toml @@ -0,0 +1,15 @@ +[target.xtensa-esp32s3-none-elf] +runner = "espflash flash --monitor" + +[build] +rustflags = [ + "-C", "link-arg=-Tlinkall.x", + "-C", "link-arg=-nostartfiles", + "-C", "link-arg=-Trom_functions.x", + "-C", "target-feature=-loop", +] + +target = "xtensa-esp32s3-none-elf" + +[unstable] +build-std = ["core"] diff --git a/examples-esp32s3/.gitignore b/examples-esp32s3/.gitignore new file mode 100644 index 0000000..73fab07 --- /dev/null +++ b/examples-esp32s3/.gitignore @@ -0,0 +1,10 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb diff --git a/examples-esp32s3/Cargo.toml b/examples-esp32s3/Cargo.toml new file mode 100644 index 0000000..9783e74 --- /dev/null +++ b/examples-esp32s3/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "examples" +version = "0.1.0" +authors = ["bjoernQ "] +edition = "2021" +license = "MIT OR Apache-2.0" + +[profile.release] +debug = true + +[dependencies] +hal = { package = "esp32s3-hal", version = "0.8.0" } +esp-backtrace = { version = "0.6.0", features = ["esp32s3", "panic-handler", "print-uart", "exception-handler"] } +esp-println = { version = "0.4.0", features = ["esp32s3","log"] } + +embassy-time = { version = "0.1.0", features = ["nightly"], optional = true } +embassy-executor = { package = "embassy-executor", git = "https://github.com/embassy-rs/embassy/", rev = "cd9a65b", features = ["nightly", "integrated-timers"], optional = true } +embassy-net = { git = "https://github.com/embassy-rs/embassy", rev = "26474ce6eb759e5add1c137f3417845e0797df3a", features = ["nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"], optional = true } + +esp-wifi = { git = "https://github.com/esp-rs/esp-wifi.git", features = ["big-heap", "phy-enable-usb", "esp32s3", "embedded-svc", "wifi"], rev = "cce6738220f4f12ab4db92f74295e762f5425e99" } +smoltcp = { version = "0.9.1", default-features=false, features = ["proto-igmp", "proto-ipv4", "socket-tcp", "socket-icmp", "socket-udp", "medium-ethernet", "proto-dhcpv4", "socket-raw", "socket-dhcpv4"] } +embedded-svc = { version = "0.23.1", default-features = false} +log = "0.4.16" +embedded-hal = "0.2" +embedded-io = "0.4.0" +heapless = "0.7.16" +critical-section = "1.0.1" + +esp-mbedtls = { path = "../esp-mbedtls", features = ["async"] } + +[[example]] +name = "async" +required-features = ["async"] + +[features] +async = ["esp-wifi/esp32s3-async", "esp-wifi/embassy-net", "embassy-executor", "embassy-net", "embassy-time", "embedded-io/async"] + +[patch.crates-io] +esp32s3-hal = { git = "https://github.com/esp-rs/esp-hal", package = "esp32s3-hal", rev = "e5d1c603b0d4833632c2358ad3fad36964bf0ed5"} +esp-hal-common = { git = "https://github.com/esp-rs/esp-hal", package = "esp-hal-common", rev = "e5d1c603b0d4833632c2358ad3fad36964bf0ed5"} diff --git a/examples-esp32s3/examples/async.rs b/examples-esp32s3/examples/async.rs new file mode 100644 index 0000000..84af309 --- /dev/null +++ b/examples-esp32s3/examples/async.rs @@ -0,0 +1,274 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use embassy_executor::_export::StaticCell; +use embassy_net::tcp::TcpSocket; +use embassy_net::{Config, Ipv4Address, Stack, StackResources}; + +use embassy_executor::Executor; +use embassy_time::{Duration, Timer}; +use embedded_svc::wifi::{ClientConfiguration, Configuration, Wifi}; +use esp_backtrace as _; +use esp_mbedtls::{asynch::Session, set_debug, Mode, TlsVersion}; +use esp_println::logger::init_logger; +use esp_println::{print, println}; +use esp_wifi::initialize; +use esp_wifi::wifi::{WifiController, WifiDevice, WifiEvent, WifiMode, WifiState}; +use hal::clock::{ClockControl, CpuClock}; +use hal::Rng; +use hal::{embassy, peripherals::Peripherals, prelude::*, timer::TimerGroup, Rtc}; + +const SSID: &str = env!("SSID"); +const PASSWORD: &str = env!("PASSWORD"); + +macro_rules! singleton { + ($val:expr) => {{ + type T = impl Sized; + static STATIC_CELL: StaticCell = StaticCell::new(); + let (x,) = STATIC_CELL.init(($val,)); + x + }}; +} + +static EXECUTOR: StaticCell = StaticCell::new(); + +#[entry] +fn main() -> ! { + init_logger(log::LevelFilter::Info); + + let peripherals = Peripherals::take(); + + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze(); + + let mut rtc = Rtc::new(peripherals.RTC_CNTL); + + // Disable watchdog timers + rtc.rwdt.disable(); + + let timer = TimerGroup::new( + peripherals.TIMG1, + &clocks, + &mut system.peripheral_clock_control, + ); + initialize( + timer.timer0, + Rng::new(peripherals.RNG), + system.radio_clock_control, + &clocks, + ) + .unwrap(); + + let (wifi, _) = peripherals.RADIO.split(); + let (wifi_interface, controller) = esp_wifi::wifi::new_with_mode(wifi, WifiMode::Sta); + + let timer_group0 = TimerGroup::new( + peripherals.TIMG0, + &clocks, + &mut system.peripheral_clock_control, + ); + embassy::init(&clocks, timer_group0.timer0); + + let config = Config::Dhcp(Default::default()); + + let seed = 1234; // very random, very secure seed + + // Init network stack + let stack = &*singleton!(Stack::new( + wifi_interface, + config, + singleton!(StackResources::<3>::new()), + seed + )); + + let executor = EXECUTOR.init(Executor::new()); + executor.run(|spawner| { + spawner.spawn(connection(controller)).ok(); + spawner.spawn(net_task(&stack)).ok(); + spawner.spawn(task(&stack)).ok(); + }); +} + +#[embassy_executor::task] +async fn connection(mut controller: WifiController<'static>) { + println!("start connection task"); + println!("Device capabilities: {:?}", controller.get_capabilities()); + loop { + match esp_wifi::wifi::get_wifi_state() { + WifiState::StaConnected => { + // wait until we're no longer connected + controller.wait_for_event(WifiEvent::StaDisconnected).await; + Timer::after(Duration::from_millis(5000)).await + } + _ => {} + } + if !matches!(controller.is_started(), Ok(true)) { + let client_config = Configuration::Client(ClientConfiguration { + ssid: SSID.into(), + password: PASSWORD.into(), + ..Default::default() + }); + controller.set_configuration(&client_config).unwrap(); + println!("Starting wifi"); + controller.start().await.unwrap(); + println!("Wifi started!"); + } + println!("About to connect..."); + + match controller.connect().await { + Ok(_) => println!("Wifi connected!"), + Err(e) => { + println!("Failed to connect to wifi: {e:?}"); + Timer::after(Duration::from_millis(5000)).await + } + } + } +} + +#[embassy_executor::task] +async fn net_task(stack: &'static Stack>) { + stack.run().await +} + +#[embassy_executor::task] +async fn task(stack: &'static Stack>) { + let mut rx_buffer = [0; 4096]; + let mut tx_buffer = [0; 4096]; + + loop { + if stack.is_link_up() { + break; + } + Timer::after(Duration::from_millis(500)).await; + } + + println!("Waiting to get IP address..."); + loop { + if let Some(config) = stack.config() { + println!("Got IP: {}", config.address); + break; + } + Timer::after(Duration::from_millis(500)).await; + } + + let mut socket = TcpSocket::new(&stack, &mut rx_buffer, &mut tx_buffer); + + socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); + + let remote_endpoint = (Ipv4Address::new(142, 250, 186, 36), 443); // www.google.com + println!("connecting..."); + let r = socket.connect(remote_endpoint).await; + if let Err(e) = r { + println!("connect error: {:?}", e); + loop {} + } + + set_debug(0); + + let tls: Session<_, 4096> = Session::new( + socket, + "www.google.com", + Mode::Client, + TlsVersion::Tls1_3, + Some(CERT), + ) + .unwrap(); + + println!("Start tls connect"); + let mut tls = tls.connect().await.unwrap(); + + println!("connected!"); + let mut buf = [0; 1024]; + + use embedded_io::asynch::Read; + use embedded_io::asynch::Write; + + let r = tls + .write_all(b"GET /notfound HTTP/1.0\r\nHost: www.google.com\r\n\r\n") + .await; + if let Err(e) = r { + println!("write error: {:?}", e); + loop {} + } + + loop { + let n = match tls.read(&mut buf).await { + Ok(n) => n, + Err(e) => { + println!("read error: {:?}", e); + break; + } + }; + print!("{}", core::str::from_utf8(&buf[..n]).unwrap()); + } + println!(); + + loop {} +} + +static CERT: &str = " +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd +-----END CERTIFICATE----- +\0"; diff --git a/examples-esp32s3/examples/sync.rs b/examples-esp32s3/examples/sync.rs new file mode 100644 index 0000000..6f18f2c --- /dev/null +++ b/examples-esp32s3/examples/sync.rs @@ -0,0 +1,209 @@ +#![no_std] +#![no_main] + +use embedded_io::blocking::*; +use embedded_svc::{ + ipv4::Interface, + wifi::{ClientConfiguration, Configuration, Wifi}, +}; +use esp_backtrace as _; +use esp_mbedtls::Session; +use esp_mbedtls::{set_debug, Mode, TlsVersion}; +use esp_println::{logger::init_logger, print, println}; +use esp_wifi::{ + current_millis, + wifi::{utils::create_network_interface, WifiMode}, + wifi_interface::WifiStack, +}; +use hal::timer::TimerGroup; +use hal::{ + clock::{ClockControl, CpuClock}, + peripherals::Peripherals, + prelude::*, + Rng, Rtc, +}; +use smoltcp::{iface::SocketStorage, wire::Ipv4Address}; + +const SSID: &str = env!("SSID"); +const PASSWORD: &str = env!("PASSWORD"); + +#[entry] +fn main() -> ! { + init_logger(log::LevelFilter::Info); + + let peripherals = Peripherals::take(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze(); + + let mut rtc = Rtc::new(peripherals.RTC_CNTL); + + // Disable watchdog timers + rtc.rwdt.disable(); + + let (wifi, _) = peripherals.RADIO.split(); + let mut socket_set_entries: [SocketStorage; 3] = Default::default(); + let (iface, device, mut controller, sockets) = + create_network_interface(wifi, WifiMode::Sta, &mut socket_set_entries); + let wifi_stack = WifiStack::new(iface, device, sockets, current_millis); + + let rngp = Rng::new(peripherals.RNG); + let timer = TimerGroup::new( + peripherals.TIMG1, + &clocks, + &mut system.peripheral_clock_control, + ); + esp_wifi::initialize(timer.timer0, rngp, system.radio_clock_control, &clocks).unwrap(); + + println!("Call wifi_connect"); + let client_config = Configuration::Client(ClientConfiguration { + ssid: SSID.into(), + password: PASSWORD.into(), + ..Default::default() + }); + controller.set_configuration(&client_config).unwrap(); + controller.start().unwrap(); + controller.connect().unwrap(); + + println!("Wait to get connected"); + loop { + let res = controller.is_connected(); + match res { + Ok(connected) => { + if connected { + break; + } + } + Err(err) => { + println!("{:?}", err); + loop {} + } + } + } + + // wait for getting an ip address + println!("Wait to get an ip address"); + loop { + wifi_stack.work(); + + if wifi_stack.is_iface_up() { + println!("Got ip {:?}", wifi_stack.get_ip_info()); + break; + } + } + + println!("We are connected!"); + + println!("Making HTTP request"); + let mut rx_buffer = [0u8; 1536]; + let mut tx_buffer = [0u8; 1536]; + let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); + + socket.work(); + + socket + .open(Ipv4Address::new(142, 250, 186, 36), 443) // google.com + .unwrap(); + + set_debug(0); + + let tls = Session::new( + socket, + "www.google.com", + Mode::Client, + TlsVersion::Tls1_3, + Some(CERT), + ) + .unwrap(); + + println!("Start tls connect"); + let mut tls = tls.connect().unwrap(); + + println!("Write to connection"); + tls.write(b"GET /notfound HTTP/1.0\r\nHost: www.google.com\r\n\r\n") + .unwrap(); + + println!("Read from connection"); + let mut buffer = [0u8; 4096]; + loop { + match tls.read(&mut buffer) { + Ok(len) => { + print!("{}", unsafe { + core::str::from_utf8_unchecked(&buffer[..len as usize]) + }); + } + Err(_) => { + println!(); + break; + } + } + } + println!("Done"); + + loop {} +} + +static CERT: &str = " +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd +-----END CERTIFICATE----- +\0"; diff --git a/examples-esp32s3/rust-toolchain.toml b/examples-esp32s3/rust-toolchain.toml new file mode 100644 index 0000000..a2f5ab5 --- /dev/null +++ b/examples-esp32s3/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "esp" diff --git a/examples-esp32s3/src/lib.rs b/examples-esp32s3/src/lib.rs new file mode 100644 index 0000000..ef2940e --- /dev/null +++ b/examples-esp32s3/src/lib.rs @@ -0,0 +1,3 @@ +#![no_std] + +// see examples