aboutsummaryrefslogtreecommitdiff
path: root/examples/nrf9160
diff options
context:
space:
mode:
authorUlf Lilleengen <[email protected]>2024-09-04 12:58:33 +0200
committerUlf Lilleengen <[email protected]>2024-09-04 12:58:33 +0200
commitb76b7ca9f5d64e83f7f69a6f7d97ba605ab2af7f (patch)
tree9577beb7c10d467a92d06ac7e96c662c84f74e39 /examples/nrf9160
parentaabdd45424ae71550be542a3a62872b33a4e0717 (diff)
Use at-commands crate and support DNS
* Use at-commands for building and parsing AT commands which has better error handling. * Retrieve DNS servers * Retrieve gateway * Update example to configure embassy-net with retrieved parameters.
Diffstat (limited to 'examples/nrf9160')
-rw-r--r--examples/nrf9160/Cargo.toml1
-rw-r--r--examples/nrf9160/src/bin/modem_tcp_client.rs78
2 files changed, 22 insertions, 57 deletions
diff --git a/examples/nrf9160/Cargo.toml b/examples/nrf9160/Cargo.toml
index fc24e99d2..9aeb99317 100644
--- a/examples/nrf9160/Cargo.toml
+++ b/examples/nrf9160/Cargo.toml
@@ -14,6 +14,7 @@ embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defm
14defmt = "0.3" 14defmt = "0.3"
15defmt-rtt = "0.4" 15defmt-rtt = "0.4"
16 16
17heapless = "0.8"
17cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 18cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
18cortex-m-rt = "0.7.0" 19cortex-m-rt = "0.7.0"
19panic-probe = { version = "0.3", features = ["print-defmt"] } 20panic-probe = { version = "0.3", features = ["print-defmt"] }
diff --git a/examples/nrf9160/src/bin/modem_tcp_client.rs b/examples/nrf9160/src/bin/modem_tcp_client.rs
index 817ad17c7..f80861693 100644
--- a/examples/nrf9160/src/bin/modem_tcp_client.rs
+++ b/examples/nrf9160/src/bin/modem_tcp_client.rs
@@ -5,9 +5,10 @@ use core::mem::MaybeUninit;
5use core::net::IpAddr; 5use core::net::IpAddr;
6use core::ptr::addr_of_mut; 6use core::ptr::addr_of_mut;
7use core::str::FromStr; 7use core::str::FromStr;
8use core::{slice, str}; 8use core::slice;
9 9
10use defmt::{assert, info, warn, unwrap}; 10use defmt::{assert, info, warn, unwrap};
11use heapless::Vec;
11use embassy_executor::Spawner; 12use embassy_executor::Spawner;
12use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources}; 13use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources};
13use embassy_net_nrf91::{Runner, State, context}; 14use embassy_net_nrf91::{Runner, State, context};
@@ -146,10 +147,23 @@ async fn main(spawner: Spawner) {
146 }; 147 };
147 let addr = Ipv4Address(addr.octets()); 148 let addr = Ipv4Address(addr.octets());
148 149
150 let gateway = if let Some(IpAddr::V4(addr)) = status.gateway {
151 Some(Ipv4Address(addr.octets()))
152 } else {
153 None
154 };
155
156 let mut dns_servers = Vec::new();
157 for dns in status.dns {
158 if let IpAddr::V4(ip) = dns {
159 unwrap!(dns_servers.push(Ipv4Address(ip.octets())));
160 }
161 }
162
149 stack.set_config_v4(embassy_net::ConfigV4::Static(embassy_net::StaticConfigV4 { 163 stack.set_config_v4(embassy_net::ConfigV4::Static(embassy_net::StaticConfigV4 {
150 address: Ipv4Cidr::new(addr, 32), 164 address: Ipv4Cidr::new(addr, 32),
151 gateway: None, 165 gateway,
152 dns_servers: Default::default(), 166 dns_servers,
153 })); 167 }));
154 168
155 let mut rx_buffer = [0; 4096]; 169 let mut rx_buffer = [0; 4096];
@@ -159,15 +173,16 @@ async fn main(spawner: Spawner) {
159 socket.set_timeout(Some(Duration::from_secs(10))); 173 socket.set_timeout(Some(Duration::from_secs(10)));
160 174
161 info!("Connecting..."); 175 info!("Connecting...");
162 let host_addr = embassy_net::Ipv4Address::from_str("83.51.182.206").unwrap(); 176 let host_addr = embassy_net::Ipv4Address::from_str("45.79.112.203").unwrap();
163 if let Err(e) = socket.connect((host_addr, 8000)).await { 177 if let Err(e) = socket.connect((host_addr, 4242)).await {
164 warn!("connect error: {:?}", e); 178 warn!("connect error: {:?}", e);
179 Timer::after_secs(1).await;
165 continue; 180 continue;
166 } 181 }
167 info!("Connected to {:?}", socket.remote_endpoint()); 182 info!("Connected to {:?}", socket.remote_endpoint());
168 183
169 let msg = b"Hello world!\n"; 184 let msg = b"Hello world!\n";
170 loop { 185 for _ in 0..10 {
171 if let Err(e) = socket.write_all(msg).await { 186 if let Err(e) = socket.write_all(msg).await {
172 warn!("write error: {:?}", e); 187 warn!("write error: {:?}", e);
173 break; 188 break;
@@ -177,54 +192,3 @@ async fn main(spawner: Spawner) {
177 } 192 }
178 } 193 }
179} 194}
180
181fn is_whitespace(char: u8) -> bool {
182 match char {
183 b'\r' | b'\n' | b' ' => true,
184 _ => false,
185 }
186}
187
188fn is_separator(char: u8) -> bool {
189 match char {
190 b',' | b'\r' | b'\n' | b' ' => true,
191 _ => false,
192 }
193}
194
195fn split_field<'a>(data: &mut &'a [u8]) -> &'a [u8] {
196 while !data.is_empty() && is_whitespace(data[0]) {
197 *data = &data[1..];
198 }
199
200 if data.is_empty() {
201 return &[];
202 }
203
204 if data[0] == b'"' {
205 let data2 = &data[1..];
206 let end = data2.iter().position(|&x| x == b'"').unwrap_or(data2.len());
207 let field = &data2[..end];
208 let mut rest = &data2[data2.len().min(end + 1)..];
209 if rest.first() == Some(&b'\"') {
210 rest = &rest[1..];
211 }
212 while !rest.is_empty() && is_separator(rest[0]) {
213 rest = &rest[1..];
214 }
215 *data = rest;
216 field
217 } else {
218 let end = data.iter().position(|&x| is_separator(x)).unwrap_or(data.len());
219 let field = &data[0..end];
220 let rest = &data[data.len().min(end + 1)..];
221 *data = rest;
222 field
223 }
224}
225
226fn pop_prefix(data: &mut &[u8], prefix: &[u8]) {
227 assert!(data.len() >= prefix.len());
228 assert!(&data[..prefix.len()] == prefix);
229 *data = &data[prefix.len()..];
230}