Skip to content

Commit 0f60d38

Browse files
committed
feat: more error handling
1 parent f01fc9f commit 0f60d38

File tree

4 files changed

+104
-59
lines changed

4 files changed

+104
-59
lines changed

src/main.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
#![feature(asm_experimental_arch)]
55

66
extern crate alloc;
7-
use alloc::string::String;
7+
use alloc::string::{String, ToString};
88
use alloc::{rc::Rc, vec::Vec};
99
use consts::{LOG_SEND_INTERVAL_MS, PRINT_HEAP_INTERVAL_MS};
10-
use core::str::FromStr;
1110
use embassy_executor::Spawner;
1211
use embassy_sync::signal::Signal;
1312
use embassy_time::{Instant, Timer};
@@ -92,7 +91,8 @@ async fn main(spawner: Spawner) {
9291
}
9392
}
9493

95-
let nvs = esp_hal_wifimanager::Nvs::new_from_part_table().unwrap();
94+
let nvs =
95+
esp_hal_wifimanager::Nvs::new_from_part_table().expect("Wrong partition configuration!");
9696

9797
set_brownout_detection(false);
9898
let rng = esp_hal::rng::Rng::new(peripherals.RNG);
@@ -194,7 +194,7 @@ async fn main(spawner: Spawner) {
194194
.with_frequency(100.kHz())
195195
.with_timeout(esp_hal::i2c::master::BusTimeout::Maximum),
196196
)
197-
.unwrap()
197+
.expect("I2C new failed")
198198
.with_sda(peripherals.GPIO21)
199199
.with_scl(peripherals.GPIO22);
200200

@@ -252,13 +252,8 @@ async fn main(spawner: Spawner) {
252252
wm_settings.esp_restart_after_connection = true;
253253
}
254254

255-
{
256-
let mut ota = esp_hal_ota::Ota::new(FlashStorage::new()).unwrap();
257-
ota.ota_mark_app_valid().unwrap();
258-
}
259-
260255
let timg0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG0);
261-
let mut wifi_res = esp_hal_wifimanager::init_wm(
256+
let wifi_res = esp_hal_wifimanager::init_wm(
262257
wm_settings,
263258
&spawner,
264259
&nvs,
@@ -269,28 +264,33 @@ async fn main(spawner: Spawner) {
269264
peripherals.BT,
270265
Some(wifi_setup_sig),
271266
)
272-
.await
273-
.unwrap();
267+
.await;
274268

275-
let conn_settings: Option<ConnSettings> = wifi_res
269+
let Ok(mut wifi_res) = wifi_res else {
270+
log::error!("WifiManager failed!!! Restarting in 1s!");
271+
Timer::after_millis(1000).await;
272+
esp_hal::reset::software_reset();
273+
return;
274+
};
275+
276+
let conn_settings: ConnSettings = wifi_res
276277
.data
277278
.take()
278-
.and_then(|d| serde_json::from_value(d).ok());
279+
.and_then(|d| serde_json::from_value(d).ok())
280+
.unwrap_or_default();
279281

280-
let ws_url = if conn_settings.is_none()
281-
|| conn_settings.as_ref().unwrap().mdns
282-
|| conn_settings.as_ref().unwrap().ws_url.is_none()
283-
{
282+
let ws_url = if conn_settings.mdns || conn_settings.ws_url.is_none() {
284283
log::info!("Start mdns lookup...");
285284
global_state.state.lock().await.scene = Scene::MdnsWait;
286285
let mdns_res = mdns::mdns_query(wifi_res.sta_stack).await;
287286
log::info!("Mdns result: {:?}", mdns_res);
288287

289-
alloc::string::String::from_str(&mdns_res.expect("MDNS HOW?")).unwrap()
288+
mdns_res.to_string()
290289
} else {
291-
conn_settings.unwrap().ws_url.unwrap()
290+
conn_settings.ws_url.expect("Cant fail")
292291
};
293292

293+
utils::backtrace_store::read_saved_backtrace().await;
294294
_ = spawner.spawn(ws::ws_task(
295295
wifi_res.sta_stack,
296296
ws_url,
@@ -307,7 +307,15 @@ async fn main(spawner: Spawner) {
307307
.parse_saved_state(saved_state);
308308
}
309309

310-
utils::backtrace_store::read_saved_backtrace().await;
310+
// only mark ota valid after wifi connection!
311+
{
312+
if let Ok(mut ota) = esp_hal_ota::Ota::new(FlashStorage::new()) {
313+
let res = ota.ota_mark_app_valid();
314+
if let Err(e) = res {
315+
log::error!("Ota mark app valid failed: {e:?}");
316+
}
317+
}
318+
}
311319

312320
let mut heap_start = Instant::now();
313321
loop {

src/mdns.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use esp_hal_mdns::MdnsQuery;
77

88
use crate::consts::MDNS_RESEND_INTERVAL;
99

10-
pub async fn mdns_query(stack: Stack<'static>) -> Option<heapless::String<255>> {
10+
pub async fn mdns_query(stack: Stack<'static>) -> heapless::String<255> {
1111
let mut rx_buffer = [0; 1024];
1212
let mut tx_buffer = [0; 1024];
1313
let mut rx_meta = [PacketMetadata::EMPTY; 16];
@@ -41,8 +41,8 @@ pub async fn mdns_query(stack: Stack<'static>) -> Option<heapless::String<255>>
4141
if let Ok((n, _endpoint)) = res {
4242
let resp = mdns.parse_mdns_query(&data_buf[..n], Some("ws"));
4343

44-
if resp.2.is_some() {
45-
tmp = resp.2;
44+
if let Some(value) = resp.2 {
45+
tmp = value;
4646
break;
4747
}
4848
}

src/structs.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ pub struct ConnSettings {
1010
pub ws_url: Option<String>,
1111
}
1212

13+
impl Default for ConnSettings {
14+
fn default() -> Self {
15+
Self {
16+
mdns: true,
17+
ws_url: None,
18+
}
19+
}
20+
}
21+
1322
#[derive(Serialize, Deserialize, Debug, Clone)]
1423
pub struct TimerPacket {
1524
#[serde(skip_serializing_if = "Option::is_none")]

src/ws.rs

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,58 @@ static TAGGED_RETURN: PubSubChannel<CriticalSectionRawMutex, (u64, TimerPacket),
2323

2424
#[embassy_executor::task]
2525
pub async fn ws_task(stack: Stack<'static>, ws_url: String, global_state: GlobalState) {
26-
let ws_url = WsUrl::from_str(&ws_url).unwrap();
27-
28-
let mut rx_buffer = [0; 8192];
29-
let mut tx_buffer = [0; 8192];
26+
let ws_url = WsUrl::from_str(&ws_url).expect("Ws url parse error");
3027

28+
let mut rx_buf = [0; 8192];
29+
let mut tx_buf = [0; 8192];
3130
let mut ws_rx_buf = alloc::vec![0; 8192];
3231
let mut ws_tx_buf = alloc::vec![0; 8192];
3332

3433
// tls buffers
35-
let mut read_record_buffer = alloc::vec::Vec::new();
36-
let mut write_record_buffer = alloc::vec::Vec::new();
34+
let mut ssl_rx_buf = alloc::vec::Vec::new();
35+
let mut ssl_tx_buf = alloc::vec::Vec::new();
3736

3837
#[cfg(feature = "esp32c3")]
3938
if ws_url.secure {
40-
read_record_buffer.resize(16640, 0);
41-
write_record_buffer.resize(16640, 0);
39+
ssl_rx_buf.resize(16640, 0);
40+
ssl_tx_buf.resize(16640, 0);
41+
}
42+
43+
loop {
44+
let res = ws_loop(
45+
&global_state,
46+
&ws_url,
47+
stack,
48+
&mut rx_buf,
49+
&mut tx_buf,
50+
&mut ws_rx_buf,
51+
&mut ws_tx_buf,
52+
&mut ssl_rx_buf,
53+
&mut ssl_tx_buf,
54+
)
55+
.await;
56+
57+
if let Err(e) = res {
58+
log::error!("Ws_loop errored! {e:?}");
59+
}
60+
61+
Timer::after_millis(500).await;
4262
}
63+
}
4364

65+
// TODO: maybe make less args?
66+
#[allow(clippy::too_many_arguments)]
67+
async fn ws_loop(
68+
global_state: &GlobalState,
69+
ws_url: &WsUrl<'_>,
70+
stack: Stack<'static>,
71+
rx_buf: &mut [u8],
72+
tx_buf: &mut [u8],
73+
ws_rx_buf: &mut [u8],
74+
ws_tx_buf: &mut [u8],
75+
ssl_rx_buf: &mut [u8],
76+
ssl_tx_buf: &mut [u8],
77+
) -> Result<(), ()> {
4478
loop {
4579
{
4680
global_state.state.lock().await.server_connected = Some(false);
@@ -53,25 +87,25 @@ pub async fn ws_task(stack: Stack<'static>, ws_url: String, global_state: Global
5387
let res = dns_resolver
5488
.query(ws_url.ip, embassy_net::dns::DnsQueryType::A)
5589
.await;
56-
if let Err(e) = res {
57-
log::error!("[WS]Dns resolver error: {e:?}");
90+
91+
let Ok(res) = res else {
92+
log::error!(
93+
"[WS]Dns resolver error: {:?}",
94+
res.expect_err("Shouldnt fail")
95+
);
5896
Timer::after_millis(1000).await;
5997
continue;
60-
}
98+
};
6199

62-
let res = res.unwrap();
63-
let first = res.first();
64-
if first.is_none() {
100+
let Some(IpAddress::Ipv4(addr)) = res.first() else {
65101
log::error!("[WS]Dns resolver empty vec");
66102
Timer::after_millis(1000).await;
67103
continue;
68-
}
69-
70-
let IpAddress::Ipv4(addr) = first.unwrap();
104+
};
71105
*addr
72106
};
73107

74-
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
108+
let mut socket = TcpSocket::new(stack, rx_buf, tx_buf);
75109
socket.set_timeout(Some(embassy_time::Duration::from_secs(15)));
76110

77111
let remote_endpoint = (ip, ws_url.port);
@@ -83,14 +117,14 @@ pub async fn ws_task(stack: Stack<'static>, ws_url: String, global_state: Global
83117
}
84118

85119
let mut socket = if ws_url.secure {
86-
let mut tls =
87-
TlsConnection::new(socket, &mut read_record_buffer, &mut write_record_buffer);
120+
let mut tls = TlsConnection::new(socket, ssl_rx_buf, ssl_tx_buf);
88121

89122
let config: TlsConfig<'_, Aes128GcmSha256> =
90123
TlsConfig::new().with_server_name(ws_url.host);
91124
tls.open::<OsRng, NoVerify>(TlsContext::new(&config, &mut OsRng))
92125
.await
93-
.expect("error establishing TLS connection");
126+
.map_err(|_| ())?;
127+
94128
WsSocket::Tls(tls)
95129
} else {
96130
WsSocket::Raw(socket)
@@ -101,8 +135,8 @@ pub async fn ws_task(stack: Stack<'static>, ws_url: String, global_state: Global
101135
}
102136

103137
log::info!("connected!");
104-
let mut tx_framer = WsTxFramer::new(true, &mut ws_tx_buf);
105-
let mut rx_framer = WsRxFramer::new(&mut ws_rx_buf);
138+
let mut tx_framer = WsTxFramer::new(true, ws_tx_buf);
139+
let mut rx_framer = WsRxFramer::new(ws_rx_buf);
106140

107141
let path = alloc::format!(
108142
"{}?id={}&ver={}&chip={}&firmware={}",
@@ -116,10 +150,10 @@ pub async fn ws_task(stack: Stack<'static>, ws_url: String, global_state: Global
116150
socket
117151
.write_all(tx_framer.generate_http_upgrade(ws_url.host, &path, None))
118152
.await
119-
.unwrap();
153+
.map_err(|_| ())?;
120154

121155
loop {
122-
let n = socket.read(rx_framer.mut_buf()).await.unwrap();
156+
let n = socket.read(rx_framer.mut_buf()).await.map_err(|_| ())?;
123157
let res = rx_framer.process_http_response(n);
124158

125159
if let Some(code) = res {
@@ -141,8 +175,8 @@ pub async fn ws_task(stack: Stack<'static>, ws_url: String, global_state: Global
141175
)
142176
.await;
143177

144-
if res.is_err() {
145-
log::error!("ws: reader or writer err!");
178+
if let Err(e) = res {
179+
log::error!("ws_rw_error: {e:?}");
146180
Timer::after_millis(WS_RETRY_MS).await;
147181
break;
148182
}
@@ -164,22 +198,16 @@ async fn ws_rw(
164198
let read_fut = tls.read(framer_rx.mut_buf());
165199
let write_fut = recv.receive();
166200

167-
let res = match embassy_futures::select::select(read_fut, write_fut).await {
201+
let n = match embassy_futures::select::select(read_fut, write_fut).await {
168202
embassy_futures::select::Either::First(read_res) => read_res,
169203
embassy_futures::select::Either::Second(write_frame) => {
170204
let data = framer_tx.frame(write_frame.into_ref());
171205
tls.write_all(data).await.map_err(|_| ())?;
172206

173207
continue;
174208
}
175-
};
176-
177-
if let Err(e) = res {
178-
log::error!("ws_read: {e:?}");
179-
return Err(());
180-
}
209+
}?;
181210

182-
let n = res.unwrap();
183211
if n == 0 {
184212
log::warn!("read_n: 0");
185213
return Err(());

0 commit comments

Comments
 (0)