Skip to content

Commit

Permalink
Simplify underlying encoding mechanisms
Browse files Browse the repository at this point in the history
  • Loading branch information
dflemstr committed Aug 23, 2020
1 parent ed09d22 commit 7c593ad
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 49 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ categories = ["embedded", "hardware-support", "no-std"]
arrayvec = { version = "0.5.1", default-features = false }
byteorder = { version = "1.3.4", default-features = false }
embedded-hal = { version = "0.2.3", features = ["unproven"] }
itertools = { version = "0.9.0", default-features = false }
log = { version = "0.4.8", default-features = false }
nb = { version = "0.1.2", default-features = false }
no-std-net = { version = "0.3.0", default-features = false }
Expand Down
40 changes: 40 additions & 0 deletions src/encoding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
pub fn recv_len<S>(spi: &mut S, long: bool) -> Result<usize, S::Error>
where
S: embedded_hal::spi::FullDuplex<u8>,
{
use super::full_duplex::FullDuplexExt as _;
use byteorder::ByteOrder as _;

let len = if long {
let mut buf = [0; 2];
buf[0] = spi.recv_exchange()?;
buf[1] = spi.recv_exchange()?;
byteorder::BigEndian::read_u16(&buf) as usize
} else {
spi.recv_exchange()? as usize
};

Ok(len)
}

pub fn send_len<S>(spi: &mut S, long: bool, len: usize) -> Result<(), S::Error>
where
S: embedded_hal::spi::FullDuplex<u8>,
{
use super::full_duplex::FullDuplexExt as _;
use byteorder::ByteOrder as _;
use core::convert::TryFrom;

if long {
let len = u16::try_from(len).unwrap();
let mut buf = [0; 2];
byteorder::BigEndian::write_u16(&mut buf, len);
spi.send_exchange(buf[0])?;
spi.send_exchange(buf[1])?;
} else {
let len = u8::try_from(len).unwrap();
spi.send_exchange(len)?;
}

Ok(())
}
1 change: 1 addition & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub enum Error<E> {
SetDnsConfig,
SetHostname,
Disconnect,
ReqHostByName,
StartScanNetworks,
StartClientByIp,
StopClient,
Expand Down
33 changes: 31 additions & 2 deletions src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ where

pub fn get_scanned_network_rssi(&mut self, network: u8) -> Result<i32, error::Error<T::Error>> {
let send_params = (network,);
let mut recv_params = (param::Scalar::be(0u32),);
let mut recv_params = (param::Scalar::le(0u32),);

self.handle_cmd(
command::Command::GetIdxRssiCmd,
Expand Down Expand Up @@ -174,6 +174,35 @@ where
Ok(channel)
}

pub fn request_host_by_name(&mut self, hostname: &str) -> Result<(), error::Error<T::Error>> {
let send_params = (param::NullTerminated::new(hostname.as_bytes()),);
let mut recv_params = (0u8,);

self.handle_cmd(
command::Command::ReqHostByNameCmd,
&send_params,
&mut recv_params,
)?;

let (status,) = recv_params;

if status == 1 {
Ok(())
} else {
Err(error::Error::ReqHostByName)
}
}

pub fn get_host_by_name(&mut self) -> Result<no_std_net::Ipv4Addr, error::Error<T::Error>> {
let mut recv_params = (param::Scalar::be(0u32),);

self.handle_cmd(command::Command::GetHostByNameCmd, &(), &mut recv_params)?;

let (ip,) = recv_params;

Ok(ip.into_inner().into())
}

pub fn get_network_data(&mut self) -> Result<types::NetworkData, error::Error<T::Error>> {
let send_params = (0u8,);
let mut recv_params = (
Expand Down Expand Up @@ -558,7 +587,7 @@ where
socket: types::Socket,
data: &[u8],
) -> Result<usize, error::Error<T::Error>> {
let send_params = (socket.0, &data);
let send_params = (socket.0, data);
let mut recv_params = (param::Scalar::le(0u16),);

self.handle_long_send_cmd(
Expand Down
61 changes: 47 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use core::marker;
use core::time;

mod command;
mod encoding;
mod error;
mod full_duplex;
mod handler;
Expand All @@ -14,6 +15,8 @@ pub mod types;

pub use error::Error;

const BUFFER_CAPACITY: usize = 4096;

#[derive(Debug)]
pub struct Wifi<T> {
handler: handler::Handler<T>,
Expand All @@ -23,6 +26,8 @@ pub struct Wifi<T> {
#[derive(Debug)]
pub struct Client<T> {
socket: types::Socket,
buffer_offset: usize,
buffer: arrayvec::ArrayVec<[u8; BUFFER_CAPACITY]>,
phantom: marker::PhantomData<T>,
}

Expand Down Expand Up @@ -119,21 +124,19 @@ where
.get_scanned_networks()?
.into_iter()
.enumerate()
.map(move |(_i, ssid)| {
/*
.map(move |(i, ssid)| {
let i = i as u8;
let rssi = self.handler.get_scanned_network_rssi(spi, i)?;
let encryption_type = self.handler.get_scanned_network_encryption_type(spi, i)?;
let bssid = self.handler.get_scanned_network_bssid(spi, i)?;
let channel = self.handler.get_scanned_network_channel(spi, i)?;
*/
let rssi = self.handler.get_scanned_network_rssi(i)?;
let encryption_type = self.handler.get_scanned_network_encryption_type(i)?;
let bssid = self.handler.get_scanned_network_bssid(i)?;
let channel = self.handler.get_scanned_network_channel(i)?;

Ok(types::ScannedNetwork {
ssid,
rssi: 0,
encryption_type: types::EncryptionType::Auto,
bssid: [0; 6],
channel: 0,
rssi,
encryption_type,
bssid,
channel,
})
}))
}
Expand All @@ -154,10 +157,25 @@ where
self.handler.get_current_encryption_type()
}

pub fn resolve(
&mut self,
hostname: &str,
) -> Result<no_std_net::Ipv4Addr, error::Error<T::Error>> {
self.handler.request_host_by_name(hostname)?;
self.handler.get_host_by_name()
}

pub fn new_client(&mut self) -> Result<Client<T>, error::Error<T::Error>> {
let socket = self.handler.get_socket()?;
let buffer_offset = 0;
let buffer = arrayvec::ArrayVec::new();
let phantom = marker::PhantomData;
Ok(Client { socket, phantom })
Ok(Client {
socket,
buffer_offset,
buffer,
phantom,
})
}
}

Expand Down Expand Up @@ -208,8 +226,23 @@ where
wifi: &mut Wifi<T>,
data: &mut [u8],
) -> Result<usize, error::Error<T::Error>> {
let len = data.len().min(u16::max_value() as usize);
wifi.handler.get_data_buf(self.socket, &mut data[..len])
if self.buffer_offset >= self.buffer.len() {
self.buffer.clear();
self.buffer
.try_extend_from_slice(&[0; BUFFER_CAPACITY])
.unwrap();
let recv_len = wifi
.handler
.get_data_buf(self.socket, self.buffer.as_mut())?;
self.buffer.truncate(recv_len);
self.buffer_offset = 0;
log::debug!("fetched new buffer of len {}", self.buffer.len());
}

let len = data.len().min(self.buffer.len() - self.buffer_offset);
data[..len].copy_from_slice(&self.buffer[self.buffer_offset..self.buffer_offset + len]);
self.buffer_offset += len;
Ok(len)
}

pub fn recv_exact(
Expand Down
28 changes: 3 additions & 25 deletions src/param.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::full_duplex::FullDuplexExt as _;
use crate::encoding;
use core::marker;

pub trait SendParam {
Expand All @@ -16,20 +17,7 @@ pub trait SendParam {
where
S: embedded_hal::spi::FullDuplex<u8>,
{
use byteorder::ByteOrder;
use core::convert::TryFrom;

if long {
let len = u16::try_from(self.len()).unwrap();
let mut buf = [0; 2];
byteorder::BigEndian::write_u16(&mut buf, len);
spi.send_exchange(buf[0])?;
spi.send_exchange(buf[1])?;
} else {
let len = u8::try_from(self.len()).unwrap();
spi.send_exchange(len)?;
}

encoding::send_len(spi, long, self.len())?;
self.send(spi)
}
}
Expand All @@ -43,17 +31,7 @@ pub trait RecvParam {
where
S: embedded_hal::spi::FullDuplex<u8>,
{
use byteorder::ByteOrder;

let len = if long {
let mut buf = [0; 2];
buf[0] = spi.recv_exchange()?;
buf[1] = spi.recv_exchange()?;
byteorder::BigEndian::read_u16(&buf) as usize
} else {
spi.recv_exchange()? as usize
};

let len = encoding::recv_len(spi, long)?;
self.recv(spi, len)
}
}
Expand Down
10 changes: 2 additions & 8 deletions src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,20 @@ impl SendParams for () {
0
}

fn send<S>(&self, spi: &mut S, long: bool) -> Result<(), S::Error>
fn send<S>(&self, spi: &mut S, _long: bool) -> Result<(), S::Error>
where
S: embedded_hal::spi::FullDuplex<u8>,
{
if long {
spi.send_exchange(0)?;
}
spi.send_exchange(0)?;
Ok(())
}
}

impl RecvParams for () {
fn recv<S>(&mut self, spi: &mut S, long: bool) -> Result<(), S::Error>
fn recv<S>(&mut self, spi: &mut S, _long: bool) -> Result<(), S::Error>
where
S: embedded_hal::spi::FullDuplex<u8>,
{
if long {
assert_eq!(0, spi.recv_exchange()?);
}
assert_eq!(0, spi.recv_exchange()?);
Ok(())
}
Expand Down
45 changes: 45 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::fmt;

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Config<'a> {
Station(StationConfig<'a>),
Expand Down Expand Up @@ -107,3 +109,46 @@ pub struct RemoteData {
pub ip: no_std_net::Ipv4Addr,
pub port: u32,
}

impl fmt::Display for ScannedNetwork {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use itertools::Itertools;
if let Ok(ssid) = core::str::from_utf8(&self.ssid[..]) {
write!(
f,
"{:32} {:>8} {:3}dBm ch {:<2} [{:02x}]",
ssid,
self.encryption_type,
self.rssi,
self.channel,
self.bssid.iter().format(":")
)
} else {
write!(
f,
"{:64x} {:>8} {:3}dBm ch {:<2} [{:02x}]",
self.ssid.iter().format(""),
self.encryption_type,
self.rssi,
self.channel,
self.bssid.iter().format(":")
)
}
}
}

impl fmt::Display for EncryptionType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let string = match *self {
EncryptionType::Invalid => "???",
EncryptionType::Auto => "Auto",
EncryptionType::OpenSystem => "Open",
EncryptionType::SharedKey => "PSK",
EncryptionType::Wpa => "WPA",
EncryptionType::Wpa2 => "WPA2",
EncryptionType::WpaPsk => "WPA PSK",
EncryptionType::Wpa2Psk => "WPA2 PSK",
};
f.pad(string)
}
}

0 comments on commit 7c593ad

Please sign in to comment.