Resolve DNS A record
This commit is contained in:
parent
95ad37bcaa
commit
97238b56f7
4 changed files with 128 additions and 9 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
|
@ -902,6 +902,12 @@ version = "1.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "no-std-net"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
|
|
@ -1009,6 +1015,7 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
|
"sntpc",
|
||||||
"static_cell",
|
"static_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1341,6 +1348,15 @@ dependencies = [
|
||||||
"managed",
|
"managed",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sntpc"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de6292f240a2bf33ae7156cb354802bca8ecfacf96b820a6ec2f2e9f5c01f260"
|
||||||
|
dependencies = [
|
||||||
|
"no-std-net",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ssmarshal"
|
name = "ssmarshal"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ log ="*"
|
||||||
panic-halt = "*"
|
panic-halt = "*"
|
||||||
portable-atomic = { version = "*", features = ["critical-section"] }
|
portable-atomic = { version = "*", features = ["critical-section"] }
|
||||||
rand = { version = "*", default-features = false }
|
rand = { version = "*", default-features = false }
|
||||||
|
sntpc = { version = "*", default-features = false }
|
||||||
static_cell = "*"
|
static_cell = "*"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
|
||||||
53
src/main.rs
53
src/main.rs
|
|
@ -2,12 +2,17 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
mod picow_time;
|
||||||
|
|
||||||
extern crate panic_halt;
|
extern crate panic_halt;
|
||||||
|
|
||||||
use cyw43::JoinOptions;
|
use cyw43::JoinOptions;
|
||||||
use cyw43_pio::PioSpi;
|
use cyw43_pio::PioSpi;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::{Config, DhcpConfig, StackResources};
|
use embassy_net::{
|
||||||
|
dns::{DnsQueryType, DnsSocket},
|
||||||
|
Config, DhcpConfig, IpAddress, StackResources,
|
||||||
|
};
|
||||||
use embassy_rp::{
|
use embassy_rp::{
|
||||||
bind_interrupts,
|
bind_interrupts,
|
||||||
clocks::RoscRng,
|
clocks::RoscRng,
|
||||||
|
|
@ -18,15 +23,16 @@ use embassy_rp::{
|
||||||
};
|
};
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use picow_time::PicowUDPBuffer;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use static_cell::StaticCell;
|
use static_cell::StaticCell;
|
||||||
|
|
||||||
const HOSTNAME: &str = "picow";
|
const HOSTNAME: &str = "picow";
|
||||||
|
const NTP_ENDPOINT: &str = "time.google.com";
|
||||||
|
const WAIT_SECOND: u64 = 7;
|
||||||
const WIRELESS_CREDENTIALS: &[(&str, &str)] =
|
const WIRELESS_CREDENTIALS: &[(&str, &str)] =
|
||||||
&include!(concat!(env!("OUT_DIR"), "/wireless-credentials.rs"));
|
&include!(concat!(env!("OUT_DIR"), "/wireless-credentials.rs"));
|
||||||
|
|
||||||
const WIRELESS_SCAN_PERIOD_SECOND: u64 = 7;
|
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
PIO0_IRQ_0 => pio::InterruptHandler<PIO0>;
|
PIO0_IRQ_0 => pio::InterruptHandler<PIO0>;
|
||||||
USBCTRL_IRQ => usb::InterruptHandler<USB>;
|
USBCTRL_IRQ => usb::InterruptHandler<USB>;
|
||||||
|
|
@ -107,11 +113,11 @@ async fn main(spawner: Spawner) -> ! {
|
||||||
.set_power_management(cyw43::PowerManagementMode::PowerSave)
|
.set_power_management(cyw43::PowerManagementMode::PowerSave)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// set hostname
|
// hostname
|
||||||
let mut dhcpv4_config = DhcpConfig::default();
|
let mut dhcpv4_config = DhcpConfig::default();
|
||||||
dhcpv4_config.hostname = HOSTNAME.try_into().ok();
|
dhcpv4_config.hostname = HOSTNAME.try_into().ok();
|
||||||
|
|
||||||
// setup network stack
|
// network stack
|
||||||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
|
||||||
let (network_stack, network_runner) = embassy_net::new(
|
let (network_stack, network_runner) = embassy_net::new(
|
||||||
network_device,
|
network_device,
|
||||||
|
|
@ -141,8 +147,8 @@ async fn main(spawner: Spawner) -> ! {
|
||||||
.0
|
.0
|
||||||
{
|
{
|
||||||
info!("Unable to join any wireless network with provided credentials");
|
info!("Unable to join any wireless network with provided credentials");
|
||||||
info!("Sleep for {WIRELESS_SCAN_PERIOD_SECOND} seconds before rescan");
|
info!("Sleep for {WAIT_SECOND} seconds before rescan");
|
||||||
Timer::after_secs(WIRELESS_SCAN_PERIOD_SECOND).await;
|
Timer::after_secs(WAIT_SECOND).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,8 +162,37 @@ async fn main(spawner: Spawner) -> ! {
|
||||||
// turn on led to indicate network connection
|
// turn on led to indicate network connection
|
||||||
wireless_control.gpio_set(0, true).await;
|
wireless_control.gpio_set(0, true).await;
|
||||||
|
|
||||||
|
// dns client
|
||||||
|
let dns_client = DnsSocket::new(network_stack);
|
||||||
|
|
||||||
|
// udp client
|
||||||
|
// let mut udp_buffer = PicowUDPBuffer::default();
|
||||||
|
// let udp_client = udp_buffer.socket(network_stack);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
info!("System is idle");
|
let ntp_ipv4 = match dns_client.query(NTP_ENDPOINT, DnsQueryType::A).await {
|
||||||
Timer::after_secs(1).await;
|
Ok(address) => match address.first() {
|
||||||
|
Some(IpAddress::Ipv4(ipv4)) => ipv4.octets(),
|
||||||
|
None => {
|
||||||
|
info!(
|
||||||
|
"DNS A record lookup returned no IPv4 address: {}",
|
||||||
|
NTP_ENDPOINT
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(error) => {
|
||||||
|
info!(
|
||||||
|
"DNS A record lookup returned error: {}, {:?}",
|
||||||
|
NTP_ENDPOINT, error
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
info!(
|
||||||
|
"Resolved IPv4 address for {}: {}.{}.{}.{}",
|
||||||
|
NTP_ENDPOINT, ntp_ipv4[0], ntp_ipv4[1], ntp_ipv4[1], ntp_ipv4[3]
|
||||||
|
);
|
||||||
|
Timer::after_secs(WAIT_SECOND).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
67
src/picow_time.rs
Normal file
67
src/picow_time.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
use embassy_net::{
|
||||||
|
udp::{PacketMetadata, UdpSocket},
|
||||||
|
Stack,
|
||||||
|
};
|
||||||
|
use embassy_time::{Duration, Instant};
|
||||||
|
use sntpc::NtpTimestampGenerator;
|
||||||
|
|
||||||
|
const UDP_BUFFER_SIZE_BYTE: usize = 1 << 12;
|
||||||
|
const UDP_METADATA_SIZE: usize = 1 << 3;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct PicowTimestampGenerator {
|
||||||
|
duration: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PicowTimestampGenerator {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
duration: Instant::now().duration_since(Instant::MIN),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NtpTimestampGenerator for PicowTimestampGenerator {
|
||||||
|
fn init(&mut self) {
|
||||||
|
self.duration = Instant::now().duration_since(Instant::MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timestamp_sec(&self) -> u64 {
|
||||||
|
self.duration.as_secs()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timestamp_subsec_micros(&self) -> u32 {
|
||||||
|
(self.duration.as_micros() % 1000000) as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PicowUDPBuffer {
|
||||||
|
receive_buffer: [u8; UDP_BUFFER_SIZE_BYTE],
|
||||||
|
receive_metadata: [PacketMetadata; UDP_METADATA_SIZE],
|
||||||
|
transmit_buffer: [u8; UDP_BUFFER_SIZE_BYTE],
|
||||||
|
transmit_metadata: [PacketMetadata; UDP_METADATA_SIZE],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PicowUDPBuffer {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
receive_buffer: [0; UDP_BUFFER_SIZE_BYTE],
|
||||||
|
receive_metadata: [PacketMetadata::EMPTY; UDP_METADATA_SIZE],
|
||||||
|
transmit_buffer: [0; UDP_BUFFER_SIZE_BYTE],
|
||||||
|
transmit_metadata: [PacketMetadata::EMPTY; UDP_METADATA_SIZE],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PicowUDPBuffer {
|
||||||
|
pub fn socket<'me>(&'me mut self, network_stack: Stack<'me>) -> UdpSocket<'me> {
|
||||||
|
UdpSocket::new(
|
||||||
|
network_stack,
|
||||||
|
&mut self.receive_metadata,
|
||||||
|
&mut self.receive_buffer,
|
||||||
|
&mut self.transmit_metadata,
|
||||||
|
&mut self.transmit_buffer,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue