nrf_modem/embassy_net_modem/
mod.rs1use core::cell::RefCell;
6use core::mem::MaybeUninit;
7
8use embassy_futures::select::{select, Either};
9use embassy_net_driver_channel as ch;
10use embassy_time::Timer;
11
12pub mod context;
13
14use crate::socket::Socket;
15const MTU: usize = 1500;
16
17pub type NetDriver<'a> = ch::Device<'a, MTU>;
21
22pub async fn new<'a>(state: &'a mut State) -> (NetDriver<'a>, Control<'a>, Runner<'a>) {
24 let state_inner = &*state
25 .inner
26 .write(RefCell::new(StateInner { net_socket: None }));
27
28 let control = Control { state: state_inner };
29
30 let (ch_runner, device) = ch::new(&mut state.ch, ch::driver::HardwareAddress::Ip);
31 let state_ch = ch_runner.state_runner();
32 state_ch.set_link_state(ch::driver::LinkState::Up);
33
34 let runner = Runner {
35 ch: ch_runner,
36 state: state_inner,
37 };
38
39 (device, control, runner)
40}
41
42pub struct State {
44 ch: ch::State<MTU, 4, 4>,
45 inner: MaybeUninit<RefCell<StateInner>>,
46}
47
48impl State {
49 pub const fn new() -> Self {
51 Self {
52 ch: ch::State::new(),
53 inner: MaybeUninit::uninit(),
54 }
55 }
56}
57
58impl Default for State {
59 fn default() -> Self {
60 Self::new()
61 }
62}
63
64struct StateInner {
65 net_socket: Option<Socket>,
66}
67
68pub struct Control<'a> {
72 state: &'a RefCell<StateInner>,
73}
74
75pub(crate) const CAP_SIZE: usize = 256;
76
77impl<'a> Control<'a> {
78 async fn open_raw_socket(&self) {
80 let socket = Socket::create(
81 crate::socket::SocketFamily::Raw,
82 crate::socket::SocketType::Raw,
83 crate::socket::SocketProtocol::IP,
84 )
85 .await
86 .unwrap();
87 self.state.borrow_mut().net_socket = Some(socket);
88 }
89
90 async fn close_raw_socket(&self) {
91 let sock = self.state.borrow_mut().net_socket.take();
92 if let Some(s) = sock {
93 s.deactivate().await.unwrap();
94 }
95 }
96 pub async fn at_command(&self, commad: &[u8]) -> arrayvec::ArrayString<CAP_SIZE> {
100 crate::send_at(core::str::from_utf8(commad).unwrap())
101 .await
102 .unwrap()
103 }
104}
105
106pub struct Runner<'a> {
108 ch: ch::Runner<'a, MTU>,
109 state: &'a RefCell<StateInner>,
110}
111
112impl<'a> Runner<'a> {
113 pub async fn run(mut self) -> ! {
117 loop {
118 let (_, mut rx_chan, mut tx_chan) = self.ch.borrow_split();
119 let net_socket = self.state.borrow_mut().net_socket.take();
120
121 let mut rx_buf = [0; 2048];
122
123 let token: crate::CancellationToken = Default::default();
124
125 if let Some(socket) = net_socket {
126 let rx_fut = async {
127 let size = socket
128 .receive_with_cancellation(&mut rx_buf, &token)
129 .await
130 .unwrap();
131 let buf = rx_chan.rx_buf().await;
132 (size, buf)
133 };
134 let tx_fut = tx_chan.tx_buf();
135 match select(rx_fut, tx_fut).await {
136 Either::First((size, buf)) => {
137 if size > 0 {
138 buf[..size].copy_from_slice(&rx_buf[..size]);
140 rx_chan.rx_done(size);
141 }
142 }
143 Either::Second(buf) => {
144 let size = buf.len();
145 let mut remaining = size;
146 while remaining > 0 {
147 let size = socket
148 .write_with_cancellation(&buf[size - remaining..], &token)
149 .await
150 .unwrap();
151 remaining -= size;
152 }
153 tx_chan.tx_done();
154 }
155 }
156
157 self.state.borrow_mut().net_socket.replace(socket);
158 } else {
159 Timer::after_millis(100).await
160 }
161 }
162 }
163}