aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-net-nrf91/src/context.rs48
-rw-r--r--examples/nrf9160/src/bin/modem_tcp_client.rs6
2 files changed, 30 insertions, 24 deletions
diff --git a/embassy-net-nrf91/src/context.rs b/embassy-net-nrf91/src/context.rs
index b532dca14..9c67cbc9f 100644
--- a/embassy-net-nrf91/src/context.rs
+++ b/embassy-net-nrf91/src/context.rs
@@ -1,38 +1,46 @@
1//! Helper utility to configure a specific modem context.
1use core::net::IpAddr; 2use core::net::IpAddr;
2use heapless::String;
3use core::str::FromStr; 3use core::str::FromStr;
4use core::fmt::Write;
5use heapless::Vec; 4use heapless::Vec;
6use at_commands::{builder::CommandBuilder, parser::CommandParser}; 5use at_commands::{builder::CommandBuilder, parser::CommandParser};
7 6
8/// Provides a higher level API for configuring and reading information for a given 7/// Provides a higher level API for controlling a given context.
9/// context id.
10pub struct Control<'a> { 8pub struct Control<'a> {
11 control: crate::Control<'a>, 9 control: crate::Control<'a>,
12 cid: u8, 10 cid: u8,
13} 11}
14 12
13/// Configuration for a given context
15pub struct Config<'a> { 14pub struct Config<'a> {
16 pub gateway: &'a str, 15 /// Desired APN address.
16 pub apn: &'a str,
17 /// Desired authentication protocol.
17 pub auth_prot: AuthProt, 18 pub auth_prot: AuthProt,
19 /// Credentials.
18 pub auth: Option<(&'a str, &'a str)>, 20 pub auth: Option<(&'a str, &'a str)>,
19} 21}
20 22
23/// Authentication protocol.
21#[repr(u8)] 24#[repr(u8)]
22pub enum AuthProt { 25pub enum AuthProt {
26 /// No authentication.
23 None = 0, 27 None = 0,
28 /// PAP authentication.
24 Pap = 1, 29 Pap = 1,
30 /// CHAP authentication.
25 Chap = 2, 31 Chap = 2,
26} 32}
27 33
34/// Error returned by control.
28#[derive(Clone, Copy, PartialEq, Debug)] 35#[derive(Clone, Copy, PartialEq, Debug)]
29#[cfg_attr(feature = "defmt", derive(defmt::Format))] 36#[cfg_attr(feature = "defmt", derive(defmt::Format))]
30pub enum Error { 37pub enum Error {
38 /// Not enough space for command.
31 BufferTooSmall, 39 BufferTooSmall,
32 AtCommand, 40 /// Error parsing response from modem.
33 AtParseError, 41 AtParseError,
42 /// Error parsing IP addresses.
34 AddrParseError, 43 AddrParseError,
35 Format,
36} 44}
37 45
38impl From<at_commands::parser::ParseError> for Error { 46impl From<at_commands::parser::ParseError> for Error {
@@ -41,17 +49,16 @@ impl From<at_commands::parser::ParseError> for Error {
41 } 49 }
42} 50}
43 51
44impl From<core::fmt::Error> for Error { 52/// Status of a given context.
45 fn from(_: core::fmt::Error) -> Self {
46 Self::Format
47 }
48}
49
50#[derive(PartialEq, Debug)] 53#[derive(PartialEq, Debug)]
51pub struct Status { 54pub struct Status {
55 /// Attached to APN or not.
52 pub attached: bool, 56 pub attached: bool,
57 /// IP if assigned.
53 pub ip: Option<IpAddr>, 58 pub ip: Option<IpAddr>,
59 /// Gateway if assigned.
54 pub gateway: Option<IpAddr>, 60 pub gateway: Option<IpAddr>,
61 /// DNS servers if assigned.
55 pub dns: Vec<IpAddr, 2>, 62 pub dns: Vec<IpAddr, 2>,
56} 63}
57 64
@@ -66,16 +73,14 @@ impl defmt::Format for Status {
66} 73}
67 74
68impl<'a> Control<'a> { 75impl<'a> Control<'a> {
76 /// Create a new instance of a control handle for a given context.
77 ///
78 /// Will wait for the modem to be initialized if not.
69 pub async fn new(control: crate::Control<'a>, cid: u8) -> Self { 79 pub async fn new(control: crate::Control<'a>, cid: u8) -> Self {
70 control.wait_init().await; 80 control.wait_init().await;
71 Self { control, cid } 81 Self { control, cid }
72 } 82 }
73 83
74 /// Bypass modem configurator
75 pub async fn at_command(&self, req: &[u8], resp: &mut [u8]) -> usize {
76 self.control.at_command(req, resp).await
77 }
78
79 /// Configures the modem with the provided config. 84 /// Configures the modem with the provided config.
80 pub async fn configure(&self, config: Config<'_>) -> Result<(), Error> { 85 pub async fn configure(&self, config: Config<'_>) -> Result<(), Error> {
81 let mut cmd: [u8; 256] = [0; 256]; 86 let mut cmd: [u8; 256] = [0; 256];
@@ -85,7 +90,7 @@ impl<'a> Control<'a> {
85 .named("+CGDCONT") 90 .named("+CGDCONT")
86 .with_int_parameter(self.cid) 91 .with_int_parameter(self.cid)
87 .with_string_parameter("IP") 92 .with_string_parameter("IP")
88 .with_string_parameter(config.gateway) 93 .with_string_parameter(config.apn)
89 .finish().map_err(|_| Error::BufferTooSmall)?; 94 .finish().map_err(|_| Error::BufferTooSmall)?;
90 let n = self.control.at_command(op, &mut buf).await; 95 let n = self.control.at_command(op, &mut buf).await;
91 CommandParser::parse(&buf[..n]).expect_identifier(b"OK").finish()?; 96 CommandParser::parse(&buf[..n]).expect_identifier(b"OK").finish()?;
@@ -112,6 +117,7 @@ impl<'a> Control<'a> {
112 Ok(()) 117 Ok(())
113 } 118 }
114 119
120 /// Read current connectivity status for modem.
115 pub async fn status(&self) -> Result<Status, Error> { 121 pub async fn status(&self) -> Result<Status, Error> {
116 let mut cmd: [u8; 256] = [0; 256]; 122 let mut cmd: [u8; 256] = [0; 256];
117 let mut buf: [u8; 256] = [0; 256]; 123 let mut buf: [u8; 256] = [0; 256];
@@ -134,7 +140,7 @@ impl<'a> Control<'a> {
134 .with_int_parameter(self.cid) 140 .with_int_parameter(self.cid)
135 .finish().map_err(|_| Error::BufferTooSmall)?; 141 .finish().map_err(|_| Error::BufferTooSmall)?;
136 let n = self.control.at_command(op, &mut buf).await; 142 let n = self.control.at_command(op, &mut buf).await;
137 let (_, ip1, ip2, ) = CommandParser::parse(&buf[..n]) 143 let (_, ip1, _ip2, ) = CommandParser::parse(&buf[..n])
138 .expect_identifier(b"+CGPADDR: ") 144 .expect_identifier(b"+CGPADDR: ")
139 .expect_int_parameter() 145 .expect_int_parameter()
140 .expect_optional_string_parameter() 146 .expect_optional_string_parameter()
@@ -154,7 +160,7 @@ impl<'a> Control<'a> {
154 .with_int_parameter(self.cid) 160 .with_int_parameter(self.cid)
155 .finish().map_err(|_| Error::BufferTooSmall)?; 161 .finish().map_err(|_| Error::BufferTooSmall)?;
156 let n = self.control.at_command(op, &mut buf).await; 162 let n = self.control.at_command(op, &mut buf).await;
157 let (_cid, _bid, _apn, _mask, gateway, dns1, dns2, _, _, _, _, mtu) = CommandParser::parse(&buf[..n]) 163 let (_cid, _bid, _apn, _mask, gateway, dns1, dns2, _, _, _, _, _mtu) = CommandParser::parse(&buf[..n])
158 .expect_identifier(b"+CGCONTRDP: ") 164 .expect_identifier(b"+CGCONTRDP: ")
159 .expect_int_parameter() 165 .expect_int_parameter()
160 .expect_optional_int_parameter() 166 .expect_optional_int_parameter()
diff --git a/examples/nrf9160/src/bin/modem_tcp_client.rs b/examples/nrf9160/src/bin/modem_tcp_client.rs
index f80861693..55ab2a707 100644
--- a/examples/nrf9160/src/bin/modem_tcp_client.rs
+++ b/examples/nrf9160/src/bin/modem_tcp_client.rs
@@ -7,7 +7,7 @@ use core::ptr::addr_of_mut;
7use core::str::FromStr; 7use core::str::FromStr;
8use core::slice; 8use core::slice;
9 9
10use defmt::{assert, info, warn, unwrap}; 10use defmt::{info, warn, unwrap};
11use heapless::Vec; 11use heapless::Vec;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources}; 13use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources};
@@ -93,7 +93,7 @@ async fn main(spawner: Spawner) {
93 93
94 static mut TRACE_BUF: [u8; 4096] = [0u8; 4096]; 94 static mut TRACE_BUF: [u8; 4096] = [0u8; 4096];
95 let mut config = uarte::Config::default(); 95 let mut config = uarte::Config::default();
96 config.baudrate = Baudrate::BAUD1M; 96 config.baudrate = Baudrate::BAUD115200;
97 let trace_writer = TraceWriter(BufferedUarteTx::new( 97 let trace_writer = TraceWriter(BufferedUarteTx::new(
98 //let trace_uart = BufferedUarteTx::new( 98 //let trace_uart = BufferedUarteTx::new(
99 unsafe { peripherals::SERIAL0::steal() }, 99 unsafe { peripherals::SERIAL0::steal() },
@@ -128,7 +128,7 @@ async fn main(spawner: Spawner) {
128 let control = context::Control::new(control, 0).await; 128 let control = context::Control::new(control, 0).await;
129 129
130 unwrap!(control.configure(context::Config { 130 unwrap!(control.configure(context::Config {
131 gateway: "iot.nat.es", 131 apn: "iot.nat.es",
132 auth_prot: context::AuthProt::Pap, 132 auth_prot: context::AuthProt::Pap,
133 auth: Some(("orange", "orange")), 133 auth: Some(("orange", "orange")),
134 }).await); 134 }).await);