Skip to content

Commit

Permalink
Fix internal-network-stack compiling
Browse files Browse the repository at this point in the history
  • Loading branch information
MathiasKoch committed Jul 1, 2024
1 parent 967d75f commit bfdc248
Show file tree
Hide file tree
Showing 24 changed files with 182 additions and 1,201 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"rust-analyzer.linkedProjects": [],
"rust-analyzer.cargo.features": [
"odin_w2xx",
// "internal-network-stack"
"ppp"
],
"rust-analyzer.server.extraEnv": {
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ name = "ublox_short_range"
doctest = false

[dependencies]
atat = { version = "0.22", features = ["derive", "bytes"] }
atat = { version = "0.23", features = ["derive", "bytes"] }

heapless = { version = "^0.8", features = ["serde"] }
no-std-net = { version = "0.6", features = ["serde"] }
Expand Down
1 change: 0 additions & 1 deletion Design_diagram.drawio

This file was deleted.

Binary file removed Design_diagram.png
Binary file not shown.
26 changes: 11 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

A driver crate for AT-command based serial ublox short range modules, built on top of [atat].
The driver aims to be compatible with the ublox short range modules:

- odin_w2xx
- nina_w1xx
- nina_b1xx
Expand All @@ -22,20 +23,16 @@ The driver aims to be compatible with the ublox short range modules:
[atat]: https://crates.io/crates/atat

## Documentation
Design diagram:
![design diagram](./Design_diagram.png "Design diagram")


Relevant docs:

- https://www.u-blox.com/en/docs/UBX-14044127
- https://www.u-blox.com/en/docs/UBX-14044126
- https://www.u-blox.com/en/docs/UBX-16024251

Relevant repos:
- https://github.com/u-blox/u-connectXpress-host-library
- https://github.com/particle-iot/device-os
- https://github.com/u-blox/ubxlib

- https://github.com/u-blox/ubxlib

## Tests

Expand All @@ -51,12 +48,12 @@ The samples can be built using `cargo build -p linux_example --target x86_64-unk
## Features

- device selection (must select one, and only one!):
- `odin_w2xx`
- `nina_w1xx`
- `nina_b1xx`
- `anna_b1xx`
- `nina_b2xx`
- `nina_b3xx`
- `odin_w2xx`
- `nina_w1xx`
- `nina_b1xx`
- `anna_b1xx`
- `nina_b2xx`
- `nina_b3xx`
- `socket-tcp`: Enabled by default. Adds TCP socket capabilities, and implements [`TcpStack`] trait.
- `socket-udp`: Enabled by default. Adds UDP socket capabilities, and implements [`UdpStack`] trait.
- `defmt-default`: Disabled by default. Add log statements on trace (dev) or info (release) log levels to aid debugging.
Expand All @@ -66,13 +63,12 @@ The samples can be built using `cargo build -p linux_example --target x86_64-unk
- `defmt-warn`: Disabled by default. Add log statements on warn log levels to aid debugging.
- `defmt-error`: Disabled by default. Add log statements on error log levels to aid debugging.


## License

Licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.
Expand All @@ -83,8 +79,8 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.


<!-- Badges -->

[no-std-badge]: https://img.shields.io/badge/no__std-yes-blue
[test]: https://github.com/BlackbirdHQ/ublox-short-range-rs/workflows/Test/badge.svg
[codecov-badge]: https://codecov.io/gh/BlackbirdHQ/ublox-short-range-rs/branch/master/graph/badge.svg
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[toolchain]
channel = "1.75"
channel = "1.79"
components = [ "rust-src", "rustfmt", "llvm-tools" ]
targets = [
"thumbv6m-none-eabi",
Expand Down
6 changes: 3 additions & 3 deletions src/asynch/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
#[cfg(feature = "ppp")]
mod at_udp_socket;
pub mod control;
pub mod network;
mod resources;
pub mod runner;
#[cfg(feature = "ublox-sockets")]
#[cfg(feature = "internal-network-stack")]
pub mod ublox_stack;

pub(crate) mod state;

pub use resources::Resources;
pub use runner::Runner;
pub use state::LinkState;

#[cfg(feature = "internal-network-stack")]
mod internal_stack;
use embedded_io_async::{BufRead, Error as _, ErrorKind, Read, Write};

#[cfg(feature = "edm")]
Expand Down
11 changes: 11 additions & 0 deletions src/asynch/ublox_stack/device.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use core::cell::RefCell;

use atat::UrcChannel;

use crate::asynch::{control::ProxyClient, runner::URC_SUBSCRIBERS, state, UbloxUrc};

pub struct Device<'a, const INGRESS_BUF_SIZE: usize, const URC_CAPACITY: usize> {
pub(crate) state_ch: state::Runner<'a>,
pub(crate) at_client: RefCell<ProxyClient<'a, INGRESS_BUF_SIZE>>,
pub(crate) urc_channel: &'a UrcChannel<UbloxUrc, URC_CAPACITY, URC_SUBSCRIBERS>,
}
5 changes: 2 additions & 3 deletions src/asynch/ublox_stack/dns.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use core::{cell::RefCell, future::poll_fn, task::Poll};

use atat::asynch::AtatClient;
use embassy_sync::waitqueue::WakerRegistration;
use embedded_nal_async::AddrType;
use no_std_net::IpAddr;
Expand Down Expand Up @@ -115,8 +114,8 @@ pub struct DnsSocket<'a> {

impl<'a> DnsSocket<'a> {
/// Create a new DNS socket using the provided stack.
pub fn new<AT: AtatClient, const URC_CAPACITY: usize>(
stack: &'a UbloxStack<AT, URC_CAPACITY>,
pub fn new<const INGRESS_BUF_SIZE: usize, const URC_CAPACITY: usize>(
stack: &'a UbloxStack<INGRESS_BUF_SIZE, URC_CAPACITY>,
) -> Self {
Self {
stack: &stack.socket,
Expand Down
105 changes: 47 additions & 58 deletions src/asynch/ublox_stack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,37 @@ pub mod tls;
#[cfg(feature = "socket-udp")]
pub mod udp;

mod device;
pub mod dns;
mod peer_builder;

pub use device::Device;

use core::cell::RefCell;
use core::future::poll_fn;
use core::ops::{DerefMut, Rem};
use core::task::Poll;

use crate::asynch::state::Device;
use crate::command::data_mode::responses::ConnectPeerResponse;
use crate::command::data_mode::urc::PeerDisconnected;
use crate::command::data_mode::{ClosePeerConnection, ConnectPeer};
use crate::command::edm::types::{DataEvent, Protocol};
use crate::command::edm::urc::EdmEvent;
use crate::command::edm::EdmDataCommand;
use crate::command::edm::{EdmAtCmdWrapper, EdmDataCommand};
use crate::command::ping::types::PingError;
use crate::command::ping::urc::{PingErrorResponse, PingResponse};
use crate::command::ping::Ping;
use crate::command::Urc;
use crate::peer_builder::{PeerUrlBuilder, SecurityCredentials};
use peer_builder::{PeerUrlBuilder, SecurityCredentials};

use self::dns::{DnsSocket, DnsState, DnsTable};

use super::state::{self, LinkState};
use super::AtHandle;
use super::control::ProxyClient;

use atat::asynch::AtatClient;
use embassy_futures::select;
use embassy_sync::waitqueue::WakerRegistration;
use embassy_time::{Duration, Ticker};
use embedded_nal_async::SocketAddr;
use futures::pin_mut;
use no_std_net::IpAddr;
use portable_atomic::{AtomicBool, AtomicU8, Ordering};
use ublox_sockets::{
Expand Down Expand Up @@ -68,25 +68,26 @@ impl<const SOCK: usize> StackResources<SOCK> {
}
}

pub struct UbloxStack<AT: AtatClient + 'static, const URC_CAPACITY: usize> {
pub struct UbloxStack<const INGRESS_BUF_SIZE: usize, const URC_CAPACITY: usize> {
socket: RefCell<SocketStack>,
device: RefCell<state::Device<'static, AT, URC_CAPACITY>>,
device: Device<'static, INGRESS_BUF_SIZE, URC_CAPACITY>,
last_tx_socket: AtomicU8,
should_tx: AtomicBool,
link_up: AtomicBool,
}

struct SocketStack {
pub(crate) struct SocketStack {
sockets: SocketSet<'static>,
waker: WakerRegistration,
dns_table: DnsTable,
dropped_sockets: heapless::Vec<PeerHandle, 3>,
credential_map: heapless::FnvIndexMap<SocketHandle, SecurityCredentials, 2>,
}

impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAPACITY> {
impl<const INGRESS_BUF_SIZE: usize, const URC_CAPACITY: usize>
UbloxStack<INGRESS_BUF_SIZE, URC_CAPACITY>
{
pub fn new<const SOCK: usize>(
device: state::Device<'static, AT, URC_CAPACITY>,
device: Device<'static, INGRESS_BUF_SIZE, URC_CAPACITY>,
resources: &'static mut StackResources<SOCK>,
) -> Self {
let sockets = SocketSet::new(&mut resources.sockets[..]);
Expand All @@ -101,16 +102,23 @@ impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAP

Self {
socket: RefCell::new(socket),
device: RefCell::new(device),
device,
last_tx_socket: AtomicU8::new(0),
link_up: AtomicBool::new(false),
should_tx: AtomicBool::new(false),
}
}

pub async fn run(&self) -> ! {
let mut tx_buf = [0u8; MAX_EGRESS_SIZE];

let Device {
urc_channel,
state_ch,
at_client,
} = &self.device;

let mut urc_subscription = urc_channel.subscribe().unwrap();

loop {
// FIXME: It feels like this can be written smarter/simpler?
let should_tx = poll_fn(|cx| match self.should_tx.load(Ordering::Relaxed) {
Expand All @@ -126,46 +134,21 @@ impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAP
});

let ticker = Ticker::every(Duration::from_millis(100));
pin_mut!(ticker);

let mut device = self.device.borrow_mut();
let Device {
ref mut urc_subscription,
ref mut shared,
ref mut at,
} = device.deref_mut();
futures_util::pin_mut!(ticker);

match select::select4(
match select::select3(
urc_subscription.next_message_pure(),
should_tx,
ticker.next(),
poll_fn(
|cx| match (self.link_up.load(Ordering::Relaxed), shared.link_state(cx)) {
(true, LinkState::Down) => Poll::Ready(LinkState::Down),
(false, LinkState::Up) => Poll::Ready(LinkState::Up),
_ => Poll::Pending,
},
),
)
.await
{
select::Either4::First(event) => {
select::Either3::First(event) => {
Self::socket_rx(event, &self.socket);
}
select::Either4::Second(_) | select::Either4::Third(_) => {
select::Either3::Second(_) | select::Either3::Third(_) => {
if let Some(ev) = self.tx_event(&mut tx_buf) {
Self::socket_tx(ev, &self.socket, at).await;
}
}
select::Either4::Fourth(new_state) => {
// Update link up
let old_link_up = self.link_up.load(Ordering::Relaxed);
let new_link_up = new_state == LinkState::Up;
self.link_up.store(new_link_up, Ordering::Relaxed);

// Print when changed
if old_link_up != new_link_up {
info!("link_up = {:?}", new_link_up);
Self::socket_tx(ev, &self.socket, &at_client).await;
}
}
}
Expand Down Expand Up @@ -325,13 +308,14 @@ impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAP
}

// Make sure to give all sockets an even opportunity to TX
let skip = self
.last_tx_socket
.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |v| {
let next = v + 1;
Some(next.rem(s.sockets.sockets.len() as u8))
})
.unwrap();
// let skip = self
// .last_tx_socket
// .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |v| {
// let next = v + 1;
// Some(next.rem(s.sockets.sockets.len() as u8))
// })
// .unwrap();
let skip = 0;

let SocketStack {
sockets,
Expand Down Expand Up @@ -416,11 +400,14 @@ impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAP
async fn socket_tx<'data>(
ev: TxEvent<'data>,
socket: &RefCell<SocketStack>,
at: &mut AtHandle<'_, AT>,
at_client: &RefCell<ProxyClient<'_, INGRESS_BUF_SIZE>>,
) {
use atat::asynch::AtatClient;

let mut at = at_client.borrow_mut();
match ev {
TxEvent::Connect { socket_handle, url } => {
match at.send_edm(ConnectPeer { url: &url }).await {
match at.send(&EdmAtCmdWrapper(ConnectPeer { url: &url })).await {
Ok(ConnectPeerResponse { peer_handle }) => {
let mut s = socket.borrow_mut();
let tcp = s
Expand All @@ -436,22 +423,24 @@ impl<AT: AtatClient + 'static, const URC_CAPACITY: usize> UbloxStack<AT, URC_CAP
}
TxEvent::Send { edm_channel, data } => {
warn!("Sending {} bytes on {}", data.len(), edm_channel);
at.send(EdmDataCommand {
at.send(&EdmDataCommand {
channel: edm_channel,
data,
})
.await
.ok();
}
TxEvent::Close { peer_handle } => {
at.send_edm(ClosePeerConnection { peer_handle }).await.ok();
at.send(&EdmAtCmdWrapper(ClosePeerConnection { peer_handle }))
.await
.ok();
}
TxEvent::Dns { hostname } => {
match at
.send_edm(Ping {
.send(&EdmAtCmdWrapper(Ping {
hostname: &hostname,
retry_num: 1,
})
}))
.await
{
Ok(_) => {}
Expand Down
File renamed without changes.
Loading

0 comments on commit bfdc248

Please sign in to comment.