clean + minify
This commit is contained in:
parent
23d03920ae
commit
fc6423ad44
86
Cargo.lock
generated
86
Cargo.lock
generated
@ -290,48 +290,6 @@ version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e"
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"defmt-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-macros"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6"
|
||||
dependencies = [
|
||||
"defmt-parser",
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-parser"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-rtt"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab697b3dbbc1750b7c8b821aa6f6e7f2480b47a99bc057a2ed7b170ebef0c51"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
"defmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dhcparse"
|
||||
version = "1.0.0"
|
||||
@ -399,7 +357,6 @@ source = "git+https://github.com/embassy-rs/embassy#cae954a87ec3c5ece520b6a44168
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"critical-section",
|
||||
"defmt",
|
||||
"document-features",
|
||||
"embassy-executor-macros",
|
||||
]
|
||||
@ -427,7 +384,6 @@ source = "git+https://github.com/embassy-rs/embassy#cae954a87ec3c5ece520b6a44168
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"critical-section",
|
||||
"defmt",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
@ -436,7 +392,6 @@ name = "embassy-net"
|
||||
version = "0.7.0"
|
||||
source = "git+https://github.com/embassy-rs/embassy#cae954a87ec3c5ece520b6a44168b36e79f3f86a"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
"document-features",
|
||||
"embassy-net-driver",
|
||||
"embassy-sync",
|
||||
@ -452,9 +407,6 @@ dependencies = [
|
||||
name = "embassy-net-driver"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/embassy-rs/embassy#cae954a87ec3c5ece520b6a44168b36e79f3f86a"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embassy-net-driver-channel"
|
||||
@ -476,7 +428,6 @@ dependencies = [
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"critical-section",
|
||||
"defmt",
|
||||
"document-features",
|
||||
"embassy-embedded-hal",
|
||||
"embassy-futures",
|
||||
@ -567,9 +518,6 @@ dependencies = [
|
||||
name = "embassy-usb-driver"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/embassy-rs/embassy#cae954a87ec3c5ece520b6a44168b36e79f3f86a"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embassy-usb-logger"
|
||||
@ -834,7 +782,6 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
"hash32",
|
||||
"serde",
|
||||
"stable_deref_trait",
|
||||
@ -1031,15 +978,6 @@ version = "1.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
||||
|
||||
[[package]]
|
||||
name = "panic-probe"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4047d9235d1423d66cc97da7d07eddb54d4f154d6c13805c6d0793956f4f25b0"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
@ -1109,8 +1047,6 @@ dependencies = [
|
||||
"cortex-m-rt",
|
||||
"cyw43",
|
||||
"cyw43-pio",
|
||||
"defmt",
|
||||
"defmt-rtt",
|
||||
"dhcparse",
|
||||
"dnsparse",
|
||||
"embassy-executor",
|
||||
@ -1122,7 +1058,6 @@ dependencies = [
|
||||
"embedded-io-async",
|
||||
"heapless",
|
||||
"log",
|
||||
"panic-probe",
|
||||
"percent-encoding",
|
||||
"portable-atomic",
|
||||
"rand_core",
|
||||
@ -1494,7 +1429,6 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"byteorder",
|
||||
"cfg-if",
|
||||
"defmt",
|
||||
"heapless",
|
||||
"managed",
|
||||
]
|
||||
@ -1583,26 +1517,6 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
|
@ -16,14 +16,12 @@ default = ["dhcp", "dns", "ttt"]
|
||||
|
||||
[dependencies]
|
||||
embassy-executor = { git = "https://github.com/embassy-rs/embassy", features = [
|
||||
"defmt",
|
||||
"nightly",
|
||||
"arch-cortex-m",
|
||||
"executor-thread",
|
||||
"executor-interrupt",
|
||||
] }
|
||||
embassy-rp = { git = "https://github.com/embassy-rs/embassy", features = [
|
||||
"defmt",
|
||||
"unstable-pac",
|
||||
"rp2040",
|
||||
"time-driver",
|
||||
@ -32,7 +30,6 @@ embassy-rp = { git = "https://github.com/embassy-rs/embassy", features = [
|
||||
embassy-time = { git = "https://github.com/embassy-rs/embassy" }
|
||||
embassy-usb-logger = { git = "https://github.com/embassy-rs/embassy" }
|
||||
embassy-net = { git = "https://github.com/embassy-rs/embassy", features = [
|
||||
"defmt",
|
||||
"proto-ipv4",
|
||||
"tcp",
|
||||
"udp",
|
||||
@ -43,9 +40,6 @@ cyw43-pio = { git = "https://github.com/embassy-rs/embassy" }
|
||||
cyw43 = { git = "https://github.com/embassy-rs/embassy" }
|
||||
|
||||
embedded-io-async = "*"
|
||||
defmt = "*"
|
||||
defmt-rtt = "*"
|
||||
panic-probe = "*"
|
||||
cortex-m = { version = "*", features = ["inline-asm"] }
|
||||
cortex-m-rt = "*"
|
||||
static_cell = "*"
|
||||
|
2
build.rs
2
build.rs
@ -32,5 +32,5 @@ fn main() {
|
||||
println!("cargo:rustc-link-arg-bins=--nmagic");
|
||||
println!("cargo:rustc-link-arg-bins=-Tlink.x");
|
||||
println!("cargo:rustc-link-arg-bins=-Tlink-rp.x");
|
||||
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
|
||||
// println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
|
||||
}
|
||||
|
@ -1,15 +1,10 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<script>
|
||||
var ws = new WebSocket("/chat");
|
||||
</script>
|
||||
</head>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Apps</h1>
|
||||
<ul>
|
||||
<li><a href="http://pico.wifi:8080">Tic Tac Toe</a> (team blue)</li>
|
||||
<li><a href="http://pico.wifi:8081">Tic Tac Toe</a> (team red)</li>
|
||||
<li><a href="/ttt?team=0">Tic Tac Toe</a> (team blue)</li>
|
||||
<li><a href="/ttt?team=1">Tic Tac Toe</a> (team red)</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -23,7 +23,18 @@ impl App for IndexApp {
|
||||
"/" | "/index" | "/index.html" => (
|
||||
HttpResCode::Ok,
|
||||
"html",
|
||||
Some(include_str!("./index.html").into()),
|
||||
#[cfg(debug_assertions)]
|
||||
Some(include_str!("index.html").into()),
|
||||
#[cfg(not(debug_assertions))]
|
||||
Some(include_str!("../../static/index.min.html").into()),
|
||||
),
|
||||
"/htmx.js" => (
|
||||
HttpResCode::Ok,
|
||||
"javascript",
|
||||
#[cfg(debug_assertions)]
|
||||
Some(include_str!("../../static/htmx.js").into()),
|
||||
#[cfg(not(debug_assertions))]
|
||||
Some(include_str!("../../static/htmx.min.js").into()),
|
||||
),
|
||||
path => {
|
||||
let (path, args) = path.split_once('?').unwrap_or((path, ""));
|
||||
@ -39,7 +50,11 @@ impl App for IndexApp {
|
||||
let Some(team) = team else {
|
||||
return (HttpResCode::BadRequest, "", None);
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
let html = include_str!("ttt.html");
|
||||
#[cfg(not(debug_assertions))]
|
||||
let html = include_str!("../../static/ttt.min.html");
|
||||
|
||||
let mut content = Vec::new();
|
||||
let r: Result<(), &str> = try {
|
||||
let (html1, html2) = html.split_once("/ttt.js").ok_or("")?;
|
||||
@ -60,8 +75,11 @@ impl App for IndexApp {
|
||||
let r: Result<(), &str> = try {
|
||||
content.push("const team = ")?;
|
||||
content.push(team)?;
|
||||
content.push(";\n")?;
|
||||
content.push(";")?;
|
||||
#[cfg(debug_assertions)]
|
||||
content.push(include_str!("ttt.js"))?;
|
||||
#[cfg(not(debug_assertions))]
|
||||
content.push(include_str!("../../static/ttt.min.js"))?;
|
||||
};
|
||||
unwrap(r).await;
|
||||
(HttpResCode::Ok, "javascript", Some(Content(content)))
|
||||
|
@ -31,12 +31,6 @@ pub trait App {
|
||||
|
||||
pub struct Content<'a>(pub Vec<&'a str, 8>);
|
||||
|
||||
// pub enum Content<'a> {
|
||||
// Str(&'a str),
|
||||
// /// Return the number of bytes written
|
||||
// /// (fn that writes content, length)
|
||||
// Fn(fn(&mut [u8]) -> usize, usize),
|
||||
// }
|
||||
impl<'a> From<&'a str> for Content<'a> {
|
||||
fn from(value: &'a str) -> Self {
|
||||
let mut v = Vec::new();
|
||||
|
@ -1,6 +1,5 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<!-- <script src="./htmx.js"></script> -->
|
||||
<style type="text/css">
|
||||
body {
|
||||
#grid {
|
||||
|
@ -27,7 +27,6 @@ const ws = new WebSocket(
|
||||
);
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
console.log(event.data);
|
||||
if (typeof event.data == "string") {
|
||||
let msg = JSON.parse(event.data);
|
||||
let cells = [];
|
||||
@ -46,18 +45,12 @@ ws.onmessage = (event) => {
|
||||
|
||||
if (tagName === "button") {
|
||||
cell.addEventListener("click", (event) => {
|
||||
console.log(i);
|
||||
ws.send(new Uint8Array([i]));
|
||||
});
|
||||
}
|
||||
|
||||
cell.setAttribute("team", owner);
|
||||
|
||||
// if (msg.board & (1 << i != 0) || msg.board & (1 << (i + 9))) {
|
||||
// if (msg.board & (1 << (i + 9) != 0)) {
|
||||
// col = "firebrick";
|
||||
// }
|
||||
// }
|
||||
cells.push(cell);
|
||||
}
|
||||
document.getElementById("grid").replaceChildren(...cells);
|
||||
|
@ -1,9 +1,8 @@
|
||||
use core::ops::Not;
|
||||
use core::str::from_utf8_unchecked;
|
||||
use core::{ops::Not, sync::atomic::Ordering};
|
||||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
use heapless::{String, Vec};
|
||||
use log::{info, warn};
|
||||
use pico_website::{unwrap, unwrap_opt};
|
||||
use serde::Serialize;
|
||||
@ -60,8 +59,6 @@ impl Game {
|
||||
|
||||
static GAME: Mutex<ThreadModeRawMutex, Game> = Mutex::new(Game::default());
|
||||
|
||||
// {"board"=[null,null,null,null,null,null,null,null,null],"turn"=null,"winner":null}
|
||||
|
||||
pub struct TttApp {
|
||||
team: Team,
|
||||
last_game: Game,
|
||||
@ -82,67 +79,17 @@ impl TttApp {
|
||||
json_buf: [0; 128],
|
||||
}
|
||||
}
|
||||
// pub fn is_ended(&self, board: u32) -> (bool, Option<Team>) {
|
||||
// if let Some((_, t)) = self.end {
|
||||
// return (true, t);
|
||||
// }
|
||||
// for (t, m) in [(Team::Zero, 0), (Team::One, 9)] {
|
||||
// for w in [
|
||||
// 0b111000000,
|
||||
// 0b000111000,
|
||||
// 0b000000111,
|
||||
// 0b100100100,
|
||||
// 0b010010010,
|
||||
// 0b001001001,
|
||||
// 0b100010001,
|
||||
// 0b001010100,
|
||||
// ] {
|
||||
// if board & (w << m) == (w << m) {
|
||||
// return (true, Some(t));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ((board | (board >> 9)) & 0b111111111) == 0b111111111 {
|
||||
// return (true, None);
|
||||
// }
|
||||
// (false, None)
|
||||
// }
|
||||
// pub fn update_end_state(&mut self, board: &mut u32) {
|
||||
// if let Some((i, _)) = self.end {
|
||||
// if i + Duration::from_secs(7) < Instant::now() {
|
||||
// self.end = None;
|
||||
// // BOARD.store(0, Ordering::Release);
|
||||
// *board = 0;
|
||||
// }
|
||||
// } else {
|
||||
// if let (true, t) = self.is_ended(*board) {
|
||||
// self.end = Some((Instant::now(), t));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
impl App for TttApp {
|
||||
fn socket_name(&self) -> &'static str {
|
||||
self.team.name()
|
||||
}
|
||||
async fn handle_request<'a>(
|
||||
&'a mut self,
|
||||
path: &str,
|
||||
_req_type: HttpRequestType,
|
||||
_content: &str,
|
||||
) -> (HttpResCode, &'static str, Option<Content<'a>>) {
|
||||
match path {
|
||||
"/" | "/index" | "/index.html" | "/ttt" | "/ttt.html" => (
|
||||
HttpResCode::Ok,
|
||||
"html",
|
||||
Some(include_str!("ttt.html").into()),
|
||||
),
|
||||
_ => (HttpResCode::NotFound, "", None),
|
||||
match self.team {
|
||||
Team::Zero => "ttt0",
|
||||
Team::One => "ttt1",
|
||||
}
|
||||
}
|
||||
fn accept_ws(&self, path: &str) -> bool {
|
||||
matches!(path, "/blue" | "/red")
|
||||
(self.team == Team::Zero && path == "/blue") || (self.team == Team::One && path == "/red")
|
||||
}
|
||||
async fn handle_ws<'a, const BUF_SIZE: usize, const RES_HEAD_BUF_SIZE: usize>(
|
||||
&'a mut self,
|
||||
@ -154,22 +101,18 @@ impl App for TttApp {
|
||||
loop {
|
||||
Timer::after_millis(1).await;
|
||||
let Ok(mut game) = GAME.try_lock() else {
|
||||
info!("locked");
|
||||
info!("game locked");
|
||||
continue;
|
||||
};
|
||||
// match GAME.try_lock() ;
|
||||
if self.last_game != *game {
|
||||
// let json = unwrap(serde_json_core::to_string::<Game, 128>(&game)).await;
|
||||
let n = unwrap(serde_json_core::to_slice(&(*game), &mut self.json_buf)).await;
|
||||
let json =
|
||||
unsafe { from_utf8_unchecked(&unwrap_opt(self.json_buf.get(..n)).await) };
|
||||
info!("{:?}", json);
|
||||
ws.send(WsMsg::Text(json)).await?;
|
||||
self.last_game = game.clone();
|
||||
}
|
||||
if ws.last_msg.elapsed() >= Duration::from_secs(5) {
|
||||
ws.send(WsMsg::Ping(&[])).await?;
|
||||
info!("ping");
|
||||
}
|
||||
if self.end.map(|e| e.elapsed()).unwrap_or_default() > Duration::from_secs(5) {
|
||||
self.end = None;
|
||||
@ -179,17 +122,15 @@ impl App for TttApp {
|
||||
};
|
||||
}
|
||||
while let Some(r) = ws.rcv().await? {
|
||||
info!("{:?}", r);
|
||||
if let WsMsg::Bytes([c]) = r {
|
||||
let c = *c as usize;
|
||||
info!("c={}", c);
|
||||
if c >= game.board.len() {
|
||||
warn!("Cell played is too big!");
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if game.board[c].is_some() {
|
||||
warn!("Cell is already taken!");
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if game.turn == Some(self.team) {
|
||||
game.board[c] = Some(self.team);
|
||||
@ -199,17 +140,18 @@ impl App for TttApp {
|
||||
}
|
||||
} else {
|
||||
warn!("It's not your turn!");
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
info!("{:#?}", game);
|
||||
}
|
||||
}
|
||||
|
||||
// Timer::after_secs(1).await;
|
||||
}
|
||||
};
|
||||
warn!("error: {:?}", r);
|
||||
Timer::after_micros(100).await;
|
||||
if r.is_err() {
|
||||
warn!(
|
||||
"Socket {}: error in ws, terminating connection",
|
||||
self.socket_name()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ pub async fn dhcp_server(stack: Stack<'static>) {
|
||||
|
||||
info!("Starting DHCP server");
|
||||
loop {
|
||||
Timer::after_secs(0).await;
|
||||
let (n, _) = unwrap(socket.recv_from(&mut buf).await).await;
|
||||
|
||||
let msg = unwrap_opt(buf.get(..n)).await;
|
||||
@ -54,7 +55,6 @@ pub async fn dhcp_server(stack: Stack<'static>) {
|
||||
rapid_commit = true;
|
||||
}
|
||||
info!("Dhcp: received {:?} message", msg_type);
|
||||
Timer::after_secs(0).await;
|
||||
|
||||
match msg_type {
|
||||
DhcpMsgType::DISCOVER | DhcpMsgType::REQUEST => {
|
||||
@ -127,7 +127,6 @@ pub async fn dhcp_server(stack: Stack<'static>) {
|
||||
)
|
||||
.await;
|
||||
info!("Dhcp: offer/ack sent for ip 192.254.0.{}", current_ip);
|
||||
Timer::after_secs(0).await;
|
||||
|
||||
if msg_type == DhcpMsgType::REQUEST || rapid_commit {
|
||||
current_ip += 1;
|
||||
@ -161,8 +160,7 @@ async fn write_dhcp_opts<const N: usize>(buf: &mut Vec<u8, N>, op_codes: &[u8])
|
||||
59 => (4, &3500_u32.to_be_bytes()), // rebinding time
|
||||
80 => (0, &[]),
|
||||
_ => {
|
||||
info!("Dhcp: unhandled requested option {}", o);
|
||||
Timer::after_secs(0).await;
|
||||
warn!("Dhcp: unhandled requested option {}", o);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
use core::{fmt::Debug, panic::PanicInfo};
|
||||
use embassy_time::Timer;
|
||||
use log::info;
|
||||
use log::error;
|
||||
|
||||
pub async fn unwrap<T, E: Debug>(res: Result<T, E>) -> T {
|
||||
match res {
|
||||
Ok(v) => v,
|
||||
Err(e) => loop {
|
||||
info!("FATAL ERROR : {:?}", e);
|
||||
error!("FATAL ERROR : {:?}", e);
|
||||
Timer::after_secs(5).await;
|
||||
},
|
||||
}
|
||||
@ -24,9 +24,9 @@ pub async fn assert(condition: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't work
|
||||
// TODO: make this log work
|
||||
#[panic_handler]
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
info!("PANIC: {}", info);
|
||||
error!("PANIC: {}", info);
|
||||
loop {}
|
||||
}
|
||||
|
24
src/main.rs
24
src/main.rs
@ -1,12 +1,6 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![allow(async_fn_in_trait)]
|
||||
#![deny(
|
||||
// clippy::unwrap_used,
|
||||
// clippy::expect_used,
|
||||
clippy::panic,
|
||||
clippy::indexing_slicing
|
||||
)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
#![feature(slice_split_once)]
|
||||
#![feature(try_blocks)]
|
||||
@ -16,8 +10,6 @@
|
||||
use core::net::Ipv4Addr;
|
||||
|
||||
use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi};
|
||||
use defmt::warn;
|
||||
use defmt_rtt as _;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::{Config, StackResources};
|
||||
use embassy_rp::bind_interrupts;
|
||||
@ -70,13 +62,6 @@ async fn main(spawner: Spawner) {
|
||||
spawner.spawn(logger_task(driver)).unwrap();
|
||||
let mut rng = RoscRng;
|
||||
|
||||
// let mut i = 0;
|
||||
// loop {
|
||||
// info!("test{}", i);
|
||||
// Timer::after_secs(1).await;
|
||||
// i += 1;
|
||||
// }
|
||||
|
||||
let fw = include_bytes!("../cyw43-firmware/43439A0.bin");
|
||||
let clm = include_bytes!("../cyw43-firmware/43439A0_clm.bin");
|
||||
let pwr = Output::new(p.PIN_23, Level::Low);
|
||||
@ -171,9 +156,6 @@ async fn main(spawner: Spawner) {
|
||||
// Wait for DHCP, not necessary when using static IP
|
||||
info!("waiting for DHCP...");
|
||||
stack.wait_config_up().await;
|
||||
// while !stack.is_config_up() {
|
||||
// Timer::after_millis(100).await;
|
||||
// }
|
||||
info!("DHCP is now up!");
|
||||
info!(
|
||||
"ip : {}",
|
||||
@ -182,12 +164,6 @@ async fn main(spawner: Spawner) {
|
||||
.address
|
||||
)
|
||||
}
|
||||
// embassy_time::Timer::after_secs(5).await;
|
||||
// info!("test0");
|
||||
|
||||
// embassy_time::Timer::after_secs(3).await;
|
||||
|
||||
// panic!("test");
|
||||
|
||||
#[cfg(feature = "dhcp")]
|
||||
unwrap(spawner.spawn(dhcp::dhcp_server(stack))).await;
|
||||
|
@ -32,10 +32,6 @@ pub async fn chat_listen_task(stack: embassy_net::Stack<'static>, port: u16) {
|
||||
}
|
||||
|
||||
pub async fn listen_task(stack: embassy_net::Stack<'static>, mut app: impl apps::App, port: u16) {
|
||||
// loop {
|
||||
// info!("team:{:?}", team);
|
||||
// Timer::after_millis(0).await;
|
||||
// }
|
||||
let mut rx_buffer = [0; 1024];
|
||||
let mut tx_buffer = [0; 2048];
|
||||
let mut buf = [0; 1024];
|
||||
@ -84,9 +80,6 @@ pub async fn listen_task(stack: embassy_net::Stack<'static>, mut app: impl apps:
|
||||
}
|
||||
};
|
||||
|
||||
// info!("\n{:?}\n", headers);
|
||||
// Timer::after_micros(100).await;
|
||||
|
||||
let mut hl = headers.lines();
|
||||
let (request_type, path) = match hl.next() {
|
||||
None => {
|
||||
@ -147,7 +140,6 @@ pub async fn listen_task(stack: embassy_net::Stack<'static>, mut app: impl apps:
|
||||
host,
|
||||
path,
|
||||
);
|
||||
Timer::after_micros(100).await;
|
||||
|
||||
head_buf.clear();
|
||||
let res_content: Result<Option<Content>, core::fmt::Error> = try {
|
||||
@ -182,24 +174,14 @@ pub async fn listen_task(stack: embassy_net::Stack<'static>, mut app: impl apps:
|
||||
Upgrade: websocket\r\n\
|
||||
Connection: Upgrade\r\n\
|
||||
Sec-WebSocket-Accept: {}\r\n\r\n",
|
||||
// Sec-WebSocket-Protocol: chat\r\n
|
||||
Into::<&str>::into(HttpResCode::SwitchingProtocols),
|
||||
accept
|
||||
)?;
|
||||
None
|
||||
}
|
||||
} else {
|
||||
let (code, res_type, res_content) = match path {
|
||||
"/htmx.js" => (
|
||||
HttpResCode::Ok,
|
||||
"javascript",
|
||||
#[cfg(debug_assertions)]
|
||||
Some(include_str!("../static/htmx.js").into()),
|
||||
#[cfg(not(debug_assertions))]
|
||||
Some(include_bytes!("../static/htmx.min.js").into()),
|
||||
),
|
||||
_ => app.handle_request(path, request_type, content).await,
|
||||
};
|
||||
let (code, res_type, res_content) =
|
||||
app.handle_request(path, request_type, content).await;
|
||||
|
||||
write!(&mut head_buf, "{}", Into::<&str>::into(code))?;
|
||||
if let Some(ref c) = res_content {
|
||||
@ -225,9 +207,6 @@ pub async fn listen_task(stack: embassy_net::Stack<'static>, mut app: impl apps:
|
||||
}
|
||||
};
|
||||
|
||||
info!("\n{}\n", unwrap(from_utf8(&head_buf)).await);
|
||||
Timer::after_micros(1000).await;
|
||||
|
||||
let w: Result<(), embassy_net::tcp::Error> = try {
|
||||
socket.write_all(&head_buf).await?;
|
||||
if let Some(ref c) = res_content {
|
||||
@ -248,8 +227,6 @@ pub async fn listen_task(stack: embassy_net::Stack<'static>, mut app: impl apps:
|
||||
}
|
||||
}
|
||||
if let Some(path) = ws_path {
|
||||
info!("handle ws");
|
||||
Timer::after_micros(200).await;
|
||||
app.handle_ws(
|
||||
&path,
|
||||
Ws::new(&mut socket, &mut buf, &mut head_buf, app.socket_name()),
|
||||
@ -297,7 +274,6 @@ impl Into<&str> for HttpResCode {
|
||||
|
||||
async fn compute_ws_accept(key: &str) -> Result<String<28>, EncodeSliceError> {
|
||||
let mut res = Vec::<u8, 28>::new();
|
||||
Timer::after_micros(10).await;
|
||||
res.extend_from_slice(&[0; 28]).unwrap();
|
||||
let mut hasher = Sha1::new();
|
||||
hasher.update(key.as_bytes());
|
||||
|
@ -1,7 +1,7 @@
|
||||
use core::str::from_utf8;
|
||||
|
||||
use embassy_net::tcp::{TcpReader, TcpSocket, TcpWriter};
|
||||
use embassy_time::{Instant, Timer};
|
||||
use embassy_time::Instant;
|
||||
use embedded_io_async::{ErrorType, ReadReady, Write};
|
||||
use heapless::Vec;
|
||||
use log::{info, warn};
|
||||
@ -58,7 +58,6 @@ impl<'a, const HEAD_BUF_SIZE: usize> WsTx<'a, HEAD_BUF_SIZE> {
|
||||
.extend_from_slice(&(msg.len() as u16).to_le_bytes()),
|
||||
)
|
||||
.await;
|
||||
// self.head_buf.extend_from_slice(msg.as_bytes()).unwrap();
|
||||
}
|
||||
let w: Result<(), <TcpSocket<'_> as ErrorType>::Error> = try {
|
||||
self.socket.write_all(&self.head_buf).await?;
|
||||
@ -66,7 +65,6 @@ impl<'a, const HEAD_BUF_SIZE: usize> WsTx<'a, HEAD_BUF_SIZE> {
|
||||
};
|
||||
w.map_err(|e| {
|
||||
warn!("write error: {:?}", e);
|
||||
()
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -99,7 +97,7 @@ impl<'a, const BUF_SIZE: usize, const HEAD_BUF_SIZE: usize> Ws<'a, BUF_SIZE, HEA
|
||||
name,
|
||||
}
|
||||
}
|
||||
// Do this often to respond to pings
|
||||
/// Do this often to respond to pings
|
||||
pub async fn rcv(&mut self) -> Result<Option<WsMsg>, ()> {
|
||||
let n = match self.rx.msg_in_buf.take() {
|
||||
Some(n) => {
|
||||
@ -108,12 +106,12 @@ impl<'a, const BUF_SIZE: usize, const HEAD_BUF_SIZE: usize> Ws<'a, BUF_SIZE, HEA
|
||||
if unwrap(self.rx.socket.read_ready()).await {
|
||||
let n_rcv = match self.rx.socket.read(&mut self.rx.buf[n.1..]).await {
|
||||
Ok(0) => {
|
||||
info!("read EOF");
|
||||
warn!("read EOF");
|
||||
return Err(());
|
||||
}
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
info!("Socket {}: read error: {:?}", self.name, e);
|
||||
warn!("Socket {}: read error: {:?}", self.name, e);
|
||||
return Err(());
|
||||
}
|
||||
};
|
||||
@ -126,12 +124,12 @@ impl<'a, const BUF_SIZE: usize, const HEAD_BUF_SIZE: usize> Ws<'a, BUF_SIZE, HEA
|
||||
if unwrap(self.rx.socket.read_ready()).await {
|
||||
match self.rx.socket.read(self.rx.buf).await {
|
||||
Ok(0) => {
|
||||
info!("read EOF");
|
||||
warn!("read EOF");
|
||||
return Err(());
|
||||
}
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
info!("Socket {}: read error: {:?}", self.name, e);
|
||||
warn!("Socket {}: read error: {:?}", self.name, e);
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
@ -142,11 +140,11 @@ impl<'a, const BUF_SIZE: usize, const HEAD_BUF_SIZE: usize> Ws<'a, BUF_SIZE, HEA
|
||||
};
|
||||
|
||||
if self.rx.buf[0] & 0b1000_0000 == 0 {
|
||||
info!("Fragmented ws messages are not supported!");
|
||||
warn!("Fragmented ws messages are not supported!");
|
||||
return Err(());
|
||||
}
|
||||
if self.rx.buf[0] & 0b0111_0000 != 0 {
|
||||
info!(
|
||||
warn!(
|
||||
"Reserved ws bits are set : {}",
|
||||
(self.rx.buf[0] >> 4) & 0b0111
|
||||
);
|
||||
@ -164,14 +162,14 @@ impl<'a, const BUF_SIZE: usize, const HEAD_BUF_SIZE: usize> Ws<'a, BUF_SIZE, HEA
|
||||
l => (l as u64, 2),
|
||||
};
|
||||
if length > 512 {
|
||||
info!("ws payload bigger than 512!");
|
||||
warn!("ws payload bigger than 512!");
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let content = if self.rx.buf[1] & 0b1000_0000 != 0 {
|
||||
// masked message
|
||||
if n_after_length + 4 + length as usize > n {
|
||||
info!("ws payload smaller than length");
|
||||
warn!("ws payload smaller than length");
|
||||
return Err(());
|
||||
}
|
||||
let mask_key: [u8; 4] = self.rx.buf[n_after_length..n_after_length + 4]
|
||||
@ -192,7 +190,7 @@ impl<'a, const BUF_SIZE: usize, const HEAD_BUF_SIZE: usize> Ws<'a, BUF_SIZE, HEA
|
||||
&self.rx.buf[n_after_length + 4..n_after_length + 4 + length as usize]
|
||||
} else {
|
||||
if n_after_length + length as usize > n {
|
||||
info!("ws payload smaller than length");
|
||||
warn!("ws payload smaller than length");
|
||||
return Err(());
|
||||
}
|
||||
if n_after_length + (length as usize) < n {
|
||||
@ -220,7 +218,7 @@ impl<'a, const BUF_SIZE: usize, const HEAD_BUF_SIZE: usize> Ws<'a, BUF_SIZE, HEA
|
||||
// Pong
|
||||
10 => Ok(Some(WsMsg::Pong(&content))),
|
||||
c => {
|
||||
info!("Unknown ws op code (ignoring) : {}", c);
|
||||
warn!("Unknown ws op code (ignoring) : {}", c);
|
||||
Ok(Some(WsMsg::Unknown(c, &content)))
|
||||
}
|
||||
}
|
||||
|
1
static/index.min.html
Normal file
1
static/index.min.html
Normal file
@ -0,0 +1 @@
|
||||
<!doctype html><html><body><h1>Apps</h1><ul><li><a href="/ttt?team=0">Tic Tac Toe</a>(team blue)</li><li><a href="/ttt?team=1">Tic Tac Toe</a>(team red)</li></ul></body></html>
|
1
static/ttt.min.html
Normal file
1
static/ttt.min.html
Normal file
@ -0,0 +1 @@
|
||||
<!doctype html><head><style type="text/css"> body { #grid { .cell { border: 1px dotted black; padding: 33%; } .cell[team="0"] { background-color: dodgerblue; } .cell[team="1"] { background-color: firebrick; } display: grid; border: 1px solid black; grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr; } } </style><script src="/ttt.js" defer></script></head><html><body><h1>TicTacToe</h1><h3 id="team"></h3><h3 id="winner"></h3><div id="grid"></div></body></html>
|
1
static/ttt.min.js
vendored
Normal file
1
static/ttt.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
if(0!=team&&1!=team)throw"team is not 0 or 1! team="+team;const teams=[{name:"blue",color:"dodgerblue",port:"8080"},{name:"red",color:"firebrick",port:"8081"}];document.getElementById("team").innerHTML='Team : <span style="color:'+teams[team].color+'">'+teams[team].name+"</span>";const ws=new WebSocket("ws://192.254.0.2:"+teams[team].port+"/"+teams[team].name);ws.onmessage=e=>{if("string"==typeof e.data){let t=JSON.parse(e.data),n=[];for(let e=0;e<9;e++){let a,r=t.board[e];a=t.turn==team&&null===r?"button":"div";let m=document.createElement(a);m.classList.add("cell"),"button"===a&&m.addEventListener("click",(t=>{ws.send(new Uint8Array([e]))})),m.setAttribute("team",r),n.push(m)}document.getElementById("grid").replaceChildren(...n),null==t.turn?null==t.winner?document.getElementById("winner").innerHTML="Draw!":document.getElementById("winner").innerHTML='Winner : <span style="color:'+teams[t.winner].color+'">'+teams[t.winner].name+"</span>":document.getElementById("winner").innerHTML=""}};
|
Loading…
Reference in New Issue
Block a user