Skip to content

Commit

Permalink
Fix TlsSocket and module restart with EDM
Browse files Browse the repository at this point in the history
  • Loading branch information
MathiasKoch committed Jan 18, 2024
1 parent 7693866 commit 6c31682
Show file tree
Hide file tree
Showing 15 changed files with 109 additions and 150 deletions.
13 changes: 4 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ atat = { version = "0.21", features = ["derive", "bytes"] }
heapless = { version = "^0.8", features = ["serde"] }
no-std-net = { version = "0.6", features = ["serde"] }
serde = { version = "^1", default-features = false, features = ["derive"] }
ublox-sockets = { version = "0.5", features = ["edm"], optional = true }
# ublox-sockets = { version = "0.5", features = ["edm"], optional = true }
ublox-sockets = { git = "https://github.com/BlackbirdHQ/ublox-sockets", rev = "9f7fe54", features = ["edm"], optional = true }
postcard = "1.0.4"
portable-atomic = "1.5"

Expand Down Expand Up @@ -78,11 +79,5 @@ exclude = ["examples"]


[patch.crates-io]
atat = { path = "../atat/atat" }
ublox-sockets = { path = "../ublox-sockets" }
no-std-net = { path = "../no-std-net" }

embassy-time = { path = "../embassy/embassy-time" }
embassy-sync = { path = "../embassy/embassy-sync" }
embassy-futures = { path = "../embassy/embassy-futures" }
embassy-net-driver = { path = "../embassy/embassy-net-driver" }
no-std-net = { git = "https://github.com/rushmorem/no-std-net", branch = "issue-15" }
atat = { path = "../atat/atat" }
50 changes: 45 additions & 5 deletions src/asynch/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@ use core::task::Poll;
use atat::asynch::AtatClient;
use embassy_time::{with_timeout, Duration};

use crate::command::gpio::{
types::{GPIOId, GPIOValue},
WriteGPIO,
};
use crate::command::network::SetNetworkHostName;
use crate::command::security::types::SecurityDataType;
use crate::command::security::SendSecurityDataImport;
use crate::command::wifi::types::{
Authentication, StatusId, WifiStationAction, WifiStationConfig, WifiStatus, WifiStatusVal,
};
use crate::command::wifi::{ExecWifiStationAction, GetWifiStatus, SetWifiStationConfig};
use crate::command::OnOff;
use crate::command::{
gpio::{
types::{GPIOId, GPIOValue},
WriteGPIO,
},
security::PrepareSecurityDataImport,
};
use crate::error::Error;

use super::state::LinkState;
Expand Down Expand Up @@ -223,7 +228,7 @@ impl<'a, AT: AtatClient> Control<'a, AT> {
})
.await?;

with_timeout(Duration::from_secs(10), self.wait_for_join(ssid))
with_timeout(Duration::from_secs(20), self.wait_for_join(ssid))
.await
.map_err(|_| Error::Timeout)??;

Expand Down Expand Up @@ -275,4 +280,39 @@ impl<'a, AT: AtatClient> Control<'a, AT> {
self.at.send_edm(WriteGPIO { id, value }).await?;
Ok(())
}

// FIXME: This could probably be improved
pub async fn import_credentials(
&mut self,
data_type: SecurityDataType,
name: &str,
data: &[u8],
md5_sum: Option<&str>,
) -> Result<(), atat::Error> {
assert!(name.len() < 16);

info!("Importing {:?} bytes as {:?}", data.len(), name);

self.at
.send_edm(PrepareSecurityDataImport {
data_type,
data_size: data.len(),
internal_name: name,
password: None,
})
.await?;

let import_data = self
.at
.send_edm(SendSecurityDataImport {
data: atat::serde_bytes::Bytes::new(data),
})
.await?;

if let Some(hash) = md5_sum {
assert_eq!(import_data.md5_string.as_str(), hash);
}

Ok(())
}
}
63 changes: 30 additions & 33 deletions src/asynch/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ use super::state::{self, LinkState};
use crate::{
command::{
edm::{urc::EdmEvent, SwitchToEdmCommand},
general::SoftwareVersion,
network::{
responses::NetworkStatusResponse,
types::{InterfaceType, NetworkStatus, NetworkStatusParameter},
urc::{NetworkDown, NetworkUp},
GetNetworkStatus,
},
system::{
types::{EchoOn},
RebootDCE, SetEcho, StoreCurrentConfig,
types::{BaudRate, ChangeAfterConfirm, EchoOn, FlowControl, Parity, StopBits},
RebootDCE, SetEcho, SetRS232Settings, StoreCurrentConfig,
},
wifi::{
types::DisconnectReason,
Expand Down Expand Up @@ -88,26 +89,21 @@ impl<
// <change_after_confirm> parameter. Instead, the <change_after_confirm>
// parameter must be set to 0 and the serial settings will take effect
// when the module is reset.
// let baud_rate = BaudRate::B3000000;
// self.at
// .send_edm(SetRS232Settings {
// baud_rate,
// flow_control: FlowControl::On,
// data_bits: 8,
// stop_bits: StopBits::One,
// parity: Parity::None,
// change_after_confirm: ChangeAfterConfirm::StoreAndReset,
// })
// .await?;

// self.restart(true).await?;

// self.at
// .0
// .lock()
// .await
// .set_baudrate(baud_rate as u32)
// .map_err(|_| Error::BaudDetection)?;
let baud_rate = BaudRate::B115200;
self.at
.send_edm(SetRS232Settings {
baud_rate,
flow_control: FlowControl::On,
data_bits: 8,
stop_bits: StopBits::One,
parity: Parity::None,
change_after_confirm: ChangeAfterConfirm::StoreAndReset,
})
.await?;

self.restart(true).await?;

self.at.send_edm(SoftwareVersion).await?;

// Move to control
// if let Some(size) = self.config.tls_in_buffer_size {
Expand All @@ -133,7 +129,7 @@ impl<
let fut = async {
loop {
match self.urc_subscription.next_message_pure().await {
EdmEvent::ATEvent(Urc::StartUp) | EdmEvent::StartUp => return,
EdmEvent::ATEvent(Urc::StartUp) => return,
_ => {}
}
}
Expand Down Expand Up @@ -163,36 +159,37 @@ impl<

self.at.send_edm(RebootDCE).await?;

Timer::after(Duration::from_millis(3500)).await;
self.wait_startup(Duration::from_secs(10)).await?;

info!("Module started again");
self.enter_edm(Duration::from_secs(4)).await?;

Ok(())
}

pub async fn enter_edm(&mut self, timeout: Duration) -> Result<(), Error> {
info!("Entering EDM mode");

// Switch to EDM on Init. If in EDM, fail and check with autosense
let fut = async {
loop {
// Ignore AT results until we are successful in EDM mode
self.at.send(SwitchToEdmCommand).await.ok();

if let Ok(EdmEvent::StartUp) = with_timeout(
Duration::from_millis(300),
self.urc_subscription.next_message_pure(),
)
.await
{
if let Ok(_) = self.at.send(SwitchToEdmCommand).await {
// After executing the data mode command or the extended data
// mode command, a delay of 50 ms is required before start of
// data transmission.
Timer::after(Duration::from_millis(50)).await;
break;
}
Timer::after(Duration::from_millis(10)).await;
}
};

with_timeout(timeout, fut)
.await
.map_err(|_| Error::Timeout)?;

self.at.send_edm(SetEcho { on: EchoOn::Off }).await?;
self.at.send_edm(SetEcho { on: EchoOn::On }).await?;

Ok(())
}
Expand Down
10 changes: 2 additions & 8 deletions src/asynch/ublox_stack/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,12 @@ impl<'a> DnsSocket<'a> {
s.waker.wake();
}



poll_fn(|cx| {
let mut s = self.stack.borrow_mut();
let query = s.dns_table.get_mut(&name_string).unwrap();
match query.state {
DnsState::Resolved(ip) => {
Poll::Ready(Ok(ip))
}
DnsState::Error(_e) => {
Poll::Ready(Err(Error::Failed))
}
DnsState::Resolved(ip) => Poll::Ready(Ok(ip)),
DnsState::Error(_e) => Poll::Ready(Err(Error::Failed)),
_ => {
query.waker.register(cx.waker());
Poll::Pending
Expand Down
77 changes: 3 additions & 74 deletions src/asynch/ublox_stack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ use crate::command::edm::EdmDataCommand;
use crate::command::ping::types::PingError;
use crate::command::ping::urc::{PingErrorResponse, PingResponse};
use crate::command::ping::Ping;
use crate::command::security::types::SecurityDataType;
use crate::command::security::{PrepareSecurityDataImport, SendSecurityDataImport};
use crate::command::Urc;
use crate::peer_builder::{PeerUrlBuilder, SecurityCredentials};

Expand Down Expand Up @@ -81,7 +79,7 @@ struct SocketStack {
waker: WakerRegistration,
dns_table: DnsTable,
dropped_sockets: heapless::Vec<PeerHandle, 3>,
credential_map: heapless::FnvIndexMap<SocketHandle, SecurityCredentials, 3>,
credential_map: heapless::FnvIndexMap<SocketHandle, SecurityCredentials, 2>,
}

impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAPACITY> {
Expand Down Expand Up @@ -170,76 +168,6 @@ impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAP
}
}

// FIXME: This could probably be improved
pub async fn import_credentials(
&self,
root_ca: (&str, &[u8]),
cert: (&str, &[u8]),
priv_key: (&str, &[u8]),
) -> Result<(), atat::Error> {
let mut device = self.device.borrow_mut();

assert!(root_ca.0.len() < 16);
assert!(cert.0.len() < 16);
assert!(priv_key.0.len() < 16);

device
.at
.send_edm(PrepareSecurityDataImport {
data_type: SecurityDataType::TrustedRootCA,
data_size: root_ca.1.len(),
internal_name: root_ca.0,
password: None,
})
.await?;

device
.at
.send_edm(SendSecurityDataImport {
data: atat::serde_bytes::Bytes::new(root_ca.1),
})
.await?;

device
.at
.send_edm(PrepareSecurityDataImport {
data_type: SecurityDataType::ClientCertificate,
data_size: cert.1.len(),
internal_name: cert.0,
password: None,
})
.await?;

device
.at
.send_edm(SendSecurityDataImport {
data: atat::serde_bytes::Bytes::new(cert.1),
})
.await?;

device
.at
.send_edm(PrepareSecurityDataImport {
data_type: SecurityDataType::ClientPrivateKey,
data_size: priv_key.1.len(),
internal_name: priv_key.0,
password: None,
})
.await?;

device
.at
.send_edm(SendSecurityDataImport {
data: atat::serde_bytes::Bytes::new(priv_key.1),
})
.await?;

// FIXME:
// self.socket.borrow_mut().credential_map.insert(key, value);

Ok(())
}

/// Make a query for a given name and return the corresponding IP addresses.
// #[cfg(feature = "dns")]
pub async fn dns_query(
Expand Down Expand Up @@ -426,7 +354,8 @@ impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAP
builder.address(&addr)
};

if let Some(creds) = credential_map.remove(&handle) {
if let Some(creds) = credential_map.get(&handle) {
info!("Found credentials {} for {}", creds, handle);
builder.creds(creds);
}

Expand Down
2 changes: 0 additions & 2 deletions src/asynch/ublox_stack/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,8 +619,6 @@ pub mod client {
use core::mem::MaybeUninit;
use core::ptr::NonNull;



use crate::asynch::ublox_stack::dns::DnsSocket;

use super::*;
Expand Down
8 changes: 8 additions & 0 deletions src/asynch/ublox_stack/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ impl<'a> TlsSocket<'a> {
let TcpIo { stack, handle } = tcp_socket.io;

let s = &mut *stack.borrow_mut();
info!("Associating credentials {} with {}", credentials, handle);
s.credential_map.insert(handle, credentials);

Self { inner: tcp_socket }
Expand Down Expand Up @@ -217,6 +218,13 @@ impl<'a> TlsSocket<'a> {
}
}

impl<'a> Drop for TlsSocket<'a> {
fn drop(&mut self) {
let mut stack = self.inner.io.stack.borrow_mut();
stack.credential_map.remove(&self.inner.io.handle);
}
}

mod embedded_io_impls {
use super::*;

Expand Down
1 change: 0 additions & 1 deletion src/asynch/ublox_stack/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use core::cell::RefCell;

use core::mem;


use atat::asynch::AtatClient;
use embedded_nal_async::SocketAddr;
use ublox_sockets::{udp, SocketHandle, UdpState};
Expand Down
3 changes: 1 addition & 2 deletions src/command/custom_digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ impl Digester for EdmDigester {
};
(return_val, edm_len)
}
PayloadType::StartEvent => (DigestResult::Urc(&buf[..edm_len]), edm_len),
// PayloadType::StartEvent => (DigestResult::Response(Ok(&buf[..edm_len])), edm_len),
PayloadType::StartEvent => (DigestResult::Response(Ok(&buf[..edm_len])), edm_len),
PayloadType::ATEvent
| PayloadType::ConnectEvent
| PayloadType::DataEvent
Expand Down
Loading

0 comments on commit 6c31682

Please sign in to comment.