Skip to content

Commit 3ead44b

Browse files
authored
Merge pull request #25 from Jim-Hodapp-Coaching/leave_a_wifi_network
Leave a previously joined WiFi network (non-enterprise)
2 parents 12d37a8 + e5ac205 commit 3ead44b

File tree

4 files changed

+91
-11
lines changed

4 files changed

+91
-11
lines changed

examples/join.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
//! # ESP32-WROOM-RP Pico Wireless Example
22
//!
33
//! This application demonstrates how to use the ESP32-WROOM-RP crate to request that
4-
//! a remote ESP32 WiFi target connects to a particular SSID given a passphrase.
4+
//! a remote ESP32 WiFi target connects to a particular SSID given a passphrase
5+
//! and then leaves (disconnects) that same network.
56
//!
67
//! See the `Cargo.toml` file for Copyright and license details.
78
@@ -99,7 +100,7 @@ fn main() -> ! {
99100
&mut pac.RESETS,
100101
);
101102

102-
defmt::info!("ESP32-WROOM-RP get NINA firmware version example");
103+
defmt::info!("ESP32-WROOM-RP join/leave WiFi network");
103104

104105
// These are implicitly used by the spi driver if they are in the correct mode
105106
let spi_miso = pins.gpio16.into_mode::<hal::gpio::FunctionSpi>();
@@ -144,6 +145,13 @@ fn main() -> ! {
144145

145146
if byte == 3 {
146147
defmt::info!("Connected to Network: {:?}", ssid);
148+
149+
defmt::info!("Sleeping for 5 seconds before disconnecting...");
150+
delay.delay_ms(5000).ok().unwrap();
151+
152+
wifi.leave().ok().unwrap();
153+
} else if byte == 6 {
154+
defmt::info!("Disconnected from Network: {:?}", ssid);
147155
}
148156
}
149157
Err(e) => {

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ where
190190
self.protocol_handler.set_passphrase(ssid, passphrase)
191191
}
192192

193+
fn leave(&mut self) -> Result<(), Error> {
194+
self.protocol_handler.disconnect()
195+
}
196+
193197
fn get_connection_status(&mut self) -> Result<u8, self::Error> {
194198
self.protocol_handler.get_conn_status()
195199
}

src/protocol.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ pub enum NinaCommand {
1212
GetFwVersion = 0x37u8,
1313
SetPassphrase = 0x11u8,
1414
GetConnStatus = 0x20u8,
15+
Disconnect = 0x30u8,
1516
}
1617

1718
pub trait NinaParam {
1819
// Length of parameter in bytes
1920
type LengthAsBytes: IntoIterator<Item = u8>;
2021

2122
fn new(data: &str) -> Self;
23+
fn from_bytes(bytes: &[u8]) -> Self;
2224

2325
fn data(&mut self) -> &[u8];
2426

@@ -60,6 +62,15 @@ impl NinaParam for NinaByteParam {
6062
}
6163
}
6264

65+
fn from_bytes(bytes: &[u8]) -> Self {
66+
let mut data_as_bytes: Vec<u8, 1> = Vec::new();
67+
data_as_bytes.extend_from_slice(bytes);
68+
Self {
69+
length: data_as_bytes.len() as u8,
70+
data: data_as_bytes,
71+
}
72+
}
73+
6374
fn data(&mut self) -> &[u8] {
6475
self.data.as_slice()
6576
}
@@ -80,6 +91,15 @@ impl NinaParam for NinaWordParam {
8091
}
8192
}
8293

94+
fn from_bytes(bytes: &[u8]) -> Self {
95+
let mut data_as_bytes: Vec<u8, 2> = Vec::new();
96+
data_as_bytes.extend_from_slice(bytes);
97+
Self {
98+
length: data_as_bytes.len() as u8,
99+
data: data_as_bytes,
100+
}
101+
}
102+
83103
fn data(&mut self) -> &[u8] {
84104
self.data.as_slice()
85105
}
@@ -100,6 +120,15 @@ impl NinaParam for NinaSmallArrayParam {
100120
}
101121
}
102122

123+
fn from_bytes(bytes: &[u8]) -> Self {
124+
let mut data_as_bytes: Vec<u8, MAX_NINA_PARAM_LENGTH> = Vec::new();
125+
data_as_bytes.extend_from_slice(bytes);
126+
Self {
127+
length: data_as_bytes.len() as u8,
128+
data: data_as_bytes,
129+
}
130+
}
131+
103132
fn data(&mut self) -> &[u8] {
104133
self.data.as_slice()
105134
}
@@ -120,6 +149,15 @@ impl NinaParam for NinaLargeArrayParam {
120149
}
121150
}
122151

152+
fn from_bytes(bytes: &[u8]) -> Self {
153+
let mut data_as_bytes: Vec<u8, MAX_NINA_PARAM_LENGTH> = Vec::new();
154+
data_as_bytes.extend_from_slice(bytes);
155+
Self {
156+
length: data_as_bytes.len() as u16,
157+
data: data_as_bytes,
158+
}
159+
}
160+
123161
fn data(&mut self) -> &[u8] {
124162
self.data.as_slice()
125163
}
@@ -137,6 +175,7 @@ pub trait ProtocolInterface {
137175
fn reset<D: DelayUs>(&mut self, delay: &mut D);
138176
fn get_fw_version(&mut self) -> Result<FirmwareVersion, self::Error>;
139177
fn set_passphrase(&mut self, ssid: &str, passphrase: &str) -> Result<(), Error>;
178+
fn disconnect(&mut self) -> Result<(), self::Error>;
140179
fn get_conn_status(&mut self) -> Result<u8, self::Error>;
141180

142181
fn send_cmd(&mut self, cmd: NinaCommand, num_params: u8) -> Result<(), self::Error>;
@@ -147,7 +186,7 @@ pub trait ProtocolInterface {
147186
) -> Result<[u8; ARRAY_LENGTH_PLACEHOLDER], self::Error>;
148187
fn send_end_cmd(&mut self) -> Result<(), self::Error>;
149188

150-
fn get_param(&mut self) -> Result<u8, self::Error>;
189+
fn get_byte(&mut self) -> Result<u8, self::Error>;
151190
fn wait_for_byte(&mut self, wait_byte: u8) -> Result<bool, self::Error>;
152191
fn check_start_cmd(&mut self) -> Result<bool, self::Error>;
153192
fn read_and_check_byte(&mut self, check_byte: u8) -> Result<bool, self::Error>;

src/spi.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
use super::gpio::EspControlInterface;
44
use super::protocol::{
5-
NinaCommand, NinaParam, NinaProtocolHandler, NinaSmallArrayParam, ProtocolInterface,
5+
NinaByteParam, NinaCommand, NinaParam, NinaProtocolHandler, NinaSmallArrayParam,
6+
ProtocolInterface,
67
};
78
use super::{Error, FirmwareVersion, WifiCommon, ARRAY_LENGTH_PLACEHOLDER};
89

@@ -51,11 +52,16 @@ where
5152
self.common.firmware_version()
5253
}
5354

54-
/// Joins a WiFi network given an SSID and a Passphrase
55+
/// Joins a WiFi network given an SSID and a Passphrase.
5556
pub fn join(&mut self, ssid: &str, passphrase: &str) -> Result<(), Error> {
5657
self.common.join(ssid, passphrase)
5758
}
5859

60+
/// Disconnects from a joined WiFi network.
61+
pub fn leave(&mut self) -> Result<(), Error> {
62+
self.common.leave()
63+
}
64+
5965
pub fn get_connection_status(&mut self) -> Result<u8, Error> {
6066
self.common.get_connection_status()
6167
}
@@ -118,6 +124,29 @@ where
118124
Ok(())
119125
}
120126

127+
fn disconnect(&mut self) -> Result<(), self::Error> {
128+
self.control_pins.wait_for_esp_select();
129+
130+
self.send_cmd(NinaCommand::Disconnect, 1).ok().unwrap();
131+
132+
let dummy_param = NinaByteParam::from_bytes(&[ControlByte::Dummy as u8]);
133+
self.send_param(dummy_param);
134+
135+
self.send_end_cmd();
136+
137+
// Pad byte stream to multiple of 4
138+
self.get_byte().ok().unwrap();
139+
self.get_byte().ok().unwrap();
140+
141+
self.control_pins.esp_deselect();
142+
self.control_pins.wait_for_esp_select();
143+
144+
self.wait_response_cmd(NinaCommand::Disconnect, 1);
145+
146+
self.control_pins.esp_deselect();
147+
Ok(())
148+
}
149+
121150
fn get_conn_status(&mut self) -> Result<u8, self::Error> {
122151
self.control_pins.wait_for_esp_select();
123152

@@ -171,7 +200,7 @@ where
171200
//return Err(SPIError::Misc);
172201
}
173202

174-
let num_params_to_read = self.get_param()? as usize;
203+
let num_params_to_read = self.get_byte()? as usize;
175204

176205
if num_params_to_read > 8 {
177206
return Ok([0x31, 0x2e, 0x37, 0x2e, 0x34, 0x0, 0x0, 0x0]);
@@ -180,7 +209,7 @@ where
180209

181210
let mut params: [u8; ARRAY_LENGTH_PLACEHOLDER] = [0; 8];
182211
for i in 0..num_params_to_read {
183-
params[i] = self.get_param().ok().unwrap()
212+
params[i] = self.get_byte().ok().unwrap()
184213
}
185214

186215
self.read_and_check_byte(ControlByte::End as u8)?;
@@ -194,7 +223,7 @@ where
194223
Ok(())
195224
}
196225

197-
fn get_param(&mut self) -> Result<u8, self::Error> {
226+
fn get_byte(&mut self) -> Result<u8, self::Error> {
198227
// Blocking read, don't return until we've read a byte successfully
199228
loop {
200229
let word_out = &mut [ControlByte::Dummy as u8];
@@ -214,7 +243,7 @@ where
214243
let mut timeout: u16 = 1000u16;
215244

216245
loop {
217-
match self.get_param() {
246+
match self.get_byte() {
218247
Ok(byte_read) => {
219248
if byte_read == ControlByte::Error as u8 {
220249
return Ok(false);
@@ -239,7 +268,7 @@ where
239268
}
240269

241270
fn read_and_check_byte(&mut self, check_byte: u8) -> Result<bool, self::Error> {
242-
match self.get_param() {
271+
match self.get_byte() {
243272
Ok(byte_out) => {
244273
return Ok(byte_out == check_byte);
245274
}
@@ -267,7 +296,7 @@ where
267296

268297
fn pad_to_multiple_of_4(&mut self, mut command_size: u16) {
269298
while command_size % 4 == 0 {
270-
self.get_param().ok().unwrap();
299+
self.get_byte().ok().unwrap();
271300
command_size += 1;
272301
}
273302
}

0 commit comments

Comments
 (0)