114 lines
4.1 KiB
Rust
114 lines
4.1 KiB
Rust
use alloc::string::ToString;
|
|
use embassy_executor::Spawner;
|
|
use embassy_sync::pubsub::DynSubscriber;
|
|
use esp_wifi::{EspWifiController, wifi::{ClientConfiguration, WifiDevice}};
|
|
use log::*;
|
|
use alloc::format;
|
|
|
|
use embassy_net::dns::DnsSocket;
|
|
use embassy_net::tcp::client::{TcpClient, TcpClientState};
|
|
use embassy_net::{Config, StackResources};
|
|
use nalgebra::Vector2;
|
|
use reqwless::client::{HttpClient, TlsConfig};
|
|
use static_cell::StaticCell;
|
|
|
|
use crate::{backoff::Backoff, events::{Prediction, Telemetry}};
|
|
|
|
#[embassy_executor::task]
|
|
async fn net_task(mut runner: embassy_net::Runner<'static, WifiDevice<'static>>) {
|
|
info!("Network stack is running");
|
|
runner.run().await
|
|
}
|
|
|
|
static RESOURCES: StaticCell<StackResources<5>> = StaticCell::new();
|
|
|
|
// TODO: Wifi task needs to know when there is data to upload, so it only connects when needed.
|
|
#[embassy_executor::task]
|
|
pub async fn wireless_task(mut telemetry: DynSubscriber<'static, Telemetry>, wifi_init: &'static mut EspWifiController<'static>, wifi_device: esp_hal::peripherals::WIFI<'static>) {
|
|
let (mut wifi, interfaces) = esp_wifi::wifi::new(wifi_init, wifi_device)
|
|
.expect("Failed to initialize WIFI!");
|
|
wifi.set_configuration(&esp_wifi::wifi::Configuration::Client(
|
|
ClientConfiguration {
|
|
ssid: "The Frequency".to_string(),
|
|
auth_method: esp_wifi::wifi::AuthMethod::WPA2Personal,
|
|
password: "thepasswordkenneth".to_string(),
|
|
..Default::default()
|
|
}
|
|
)).unwrap();
|
|
wifi.set_mode(esp_wifi::wifi::WifiMode::Sta).unwrap();
|
|
wifi.set_power_saving(esp_wifi::config::PowerSaveMode::Maximum).unwrap();
|
|
wifi.start_async().await.unwrap();
|
|
|
|
let device = interfaces.sta;
|
|
// TODO: Somehow grab a real random seed from main()
|
|
let seed = 0;
|
|
|
|
let config = Config::dhcpv4(Default::default());
|
|
let (stack, runner) = embassy_net::new(device, config, RESOURCES.init_with(|| { StackResources::new() }), seed as u64);
|
|
info!("Launching network task");
|
|
Spawner::for_current_executor().await.must_spawn(net_task(runner));
|
|
|
|
loop {
|
|
Backoff::from_secs(3).forever().attempt(async || {
|
|
info!("Connecting to wifi...");
|
|
match wifi.connect_async().await {
|
|
Ok(_) => Ok(()),
|
|
Err(e) => {
|
|
error!("Wifi error: {e:?}");
|
|
Err(())
|
|
}
|
|
}
|
|
}).await.unwrap();
|
|
|
|
info!("Waiting for DHCP");
|
|
stack.wait_config_up().await;
|
|
|
|
info!("Online!");
|
|
let ip_cfg = stack.config_v4().unwrap();
|
|
info!("ip={ip_cfg:?}");
|
|
|
|
let mut rx_buf = [0; 4096];
|
|
let mut tx_buf = [0; 4096];
|
|
let dns = DnsSocket::new(stack);
|
|
let tcp_state = TcpClientState::<1, 4096, 4096>::new();
|
|
let tcp = TcpClient::new(stack, &tcp_state);
|
|
let tls = TlsConfig::new(
|
|
seed as u64,
|
|
&mut rx_buf,
|
|
&mut tx_buf,
|
|
reqwless::client::TlsVerify::None,
|
|
);
|
|
|
|
let mut client = HttpClient::new_with_tls(&tcp, &dns, tls);
|
|
|
|
loop {
|
|
if let Telemetry::Prediction(Prediction::Location(coords)) = telemetry.next_message_pure().await {
|
|
if let Err(e) = push_location(&mut client, coords).await {
|
|
error!("HTTP error in publishing location: {e:?}");
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn push_location(client: &mut HttpClient<'_, TcpClient<'_, 1, 4096, 4096>, DnsSocket<'_>>, location: Vector2<f64>) -> Result<(), reqwless::Error> {
|
|
let mut buffer = [0u8; 4096];
|
|
let base = "https://nextcloud.malloc.hackerbots.net/nextcloud/index.php/apps/phonetrack/logGet/a062000067304e9dee6590f1b8f9e0db/renderbug";
|
|
let url = format!("{base}?lat={}&lon={}", location.y, location.x);
|
|
info!("Pushing to {url}");
|
|
let mut http_req = client
|
|
.request(
|
|
reqwless::request::Method::GET,
|
|
&url,
|
|
)
|
|
.await?;
|
|
let response = http_req.send(&mut buffer).await?;
|
|
|
|
info!("Got response");
|
|
let res = response.body().read_to_end().await?;
|
|
|
|
let content = core::str::from_utf8(res).unwrap();
|
|
info!("{content}");
|
|
Ok(())
|
|
} |