Skip to content

Commit

Permalink
Docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dirbaio committed Aug 24, 2023
1 parent 2e73bb7 commit 647d7b1
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 20 deletions.
9 changes: 0 additions & 9 deletions .vscode/settings.json

This file was deleted.

3 changes: 2 additions & 1 deletion examples/src/bin/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use clap::Parser;
use std::io::{Read, Write};
use std::path::Path;

use ppproto::{Config, PPPoS, PPPoSAction};
use ppproto::pppos::{PPPoS, PPPoSAction};
use ppproto::Config;
use serial_port::SerialPort;

#[derive(Parser)]
Expand Down
3 changes: 2 additions & 1 deletion examples/src/bin/smoltcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ use smoltcp::socket::{tcp, udp};
use smoltcp::time::{Duration, Instant};
use smoltcp::wire::IpCidr;

use ppproto::{Config, PPPoS, PPPoSAction};
use ppproto::pppos::{PPPoS, PPPoSAction};
use ppproto::Config;
use serial_port::SerialPort;

#[derive(clap::Parser)]
Expand Down
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![allow(non_upper_case_globals)]
#![doc = include_str!("../README.md")]

// This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt;
Expand All @@ -8,8 +11,8 @@ pub mod pppos;
mod wire;

pub use ppp::{Config, Ipv4Address, Ipv4Status, Phase, Status};
pub use pppos::{BufferFullError, PPPoS, PPPoSAction};

/// Invalid state error.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct InvalidStateError;
8 changes: 8 additions & 0 deletions src/ppp/ipv4cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ use num_enum::{FromPrimitive, IntoPrimitive};
use super::option_fsm::{Protocol, Verdict};
use crate::wire::ProtocolType;

/// IPv4 address.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Ipv4Address(pub [u8; 4]);

impl Ipv4Address {
/// The unspecified address `0.0.0.0`.
pub const UNSPECIFIED: Self = Self([0; 4]);

/// Return whether this address is the unspecified address `0.0.0.0`.
pub fn is_unspecified(&self) -> bool {
*self == Self::UNSPECIFIED
}
Expand Down Expand Up @@ -64,11 +68,15 @@ impl IpOption {
}
}

/// Status of the IPv4 connection.
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Ipv4Status {
/// Our adress
pub address: Option<Ipv4Address>,
/// The peer's address
pub peer_address: Option<Ipv4Address>,
/// DNS servers provided by the peer.
pub dns_servers: [Option<Ipv4Address>; 2],
}

Expand Down
15 changes: 14 additions & 1 deletion src/ppp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,41 @@ use crate::wire::{Packet, ProtocolType};

pub use self::ipv4cp::{Ipv4Address, Ipv4Status};

/// PPP configuration.
pub struct Config<'a> {
/// Username for PAP.
pub username: &'a [u8],
/// Password for PAP.
pub password: &'a [u8],
}

/// Phase of the PPP connection.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Phase {
/// Dead, not connected.
Dead,
/// Establishing initial connection.
Establish,
/// Authenticating with e.g. PAP.
Auth,
/// Negotiating network parameters, with e.g. IPv4CP
Network,
/// Connection is open, all layers are setup.
Open,
}

/// Status of the PPP connection.
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Status {
/// Phase
pub phase: Phase,
/// IPv4 configuration obtained from IPv4CP. None if IPv4CP is not up.
pub ipv4: Option<Ipv4Status>,
}

pub struct PPP<'a> {
pub(crate) struct PPP<'a> {
phase: Phase,
pub(crate) lcp: OptionFsm<LCP>,
pub(crate) pap: PAP<'a>,
Expand All @@ -54,6 +66,7 @@ impl<'a> PPP<'a> {

pub fn status(&self) -> Status {
Status {
phase: self.phase,
ipv4: if self.ipv4cp.state() == State::Opened {
Some(self.ipv4cp.proto().status())
} else {
Expand Down
1 change: 1 addition & 0 deletions src/pppos/frame_writer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::crc::crc16;

/// Given buffer is too small.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct BufferFullError;
Expand Down
44 changes: 37 additions & 7 deletions src/pppos/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! PPP over Serial

mod crc;
mod frame_reader;
mod frame_writer;
Expand All @@ -14,19 +16,35 @@ use crate::{Config, Status};

pub use self::frame_writer::BufferFullError;

/// Return value from [`PPPoS::poll()`].
pub enum PPPoSAction<B> {
/// No action needed to take.
None,
/// An IP packet was received.
///
/// The packet is located in `buffer[range]`, you must pass it to higher layers for processing.
///
/// When this happens, the PPPoS gives you back ownership over the RX buffer. You must put a
/// buffer back with [`PPPoS::put_rx_buf`] before calling `poll()` or `consume()`.
Received(B, Range<usize>),
/// PPP wants to transmit some data.
///
/// You must transmit `tx_buf[..n]` over the serial connection.
Transmit(usize),
}

/// Main PPPoS struct.
pub struct PPPoS<'a, B: AsMutSlice<Element = u8>> {
frame_reader: FrameReader,
rx_buf: Option<B>,
ppp: PPP<'a>,
}

impl<'a, B: AsMutSlice<Element = u8>> PPPoS<'a, B> {
/// Create a new PPPoS
///
/// The PPPoS is created in phase [`Dead`](crate::Phase::Dead), i.e. not connected. You must
/// call [`open()`](Self::open) to get it to start connecting.
pub fn new(config: Config<'a>) -> Self {
Self {
frame_reader: FrameReader::new(),
Expand All @@ -35,18 +53,30 @@ impl<'a, B: AsMutSlice<Element = u8>> PPPoS<'a, B> {
}
}

/// Get the status of the PPPoS connection.
pub fn status(&self) -> Status {
self.ppp.status()
}

/// Start opening the PPPoS connection.
///
/// This will kick off the PPP state machine.
///
/// Returns an error if it's not in phase [`Dead`](crate::Phase::Dead).
pub fn open(&mut self) -> Result<(), crate::InvalidStateError> {
self.ppp.open()
}

/// Get whether there's a buffer available for RXing.
pub fn has_rx_buf(&self) -> bool {
self.rx_buf.is_some()
}

/// Make a buffer available for RXing.
///
/// # Panics
///
/// Panics if there's already a buffer (i.e. if [`has_rx_buf()`](Self::has_rx_buf) returns `true`).
pub fn put_rx_buf(&mut self, rx_buf: B) {
if self.rx_buf.is_some() {
panic!("called put_rx_buf when we already have a buffer.")
Expand All @@ -57,11 +87,8 @@ impl<'a, B: AsMutSlice<Element = u8>> PPPoS<'a, B> {

/// Process received data and generate data to be send.
///
/// Action::Received is returned when an IP packet is received. You must then pass the packet
/// to higher layers for processing.
///
/// You must provide buffer space for data to be transmitted, and transmit the returned slice
/// over the serial connection if Action::Transmit is returned.
/// The return value tells you what action to take. See [`PPPoSAction`] documentation
/// for details.
pub fn poll(&mut self, tx_buf: &mut [u8]) -> PPPoSAction<B> {
let mut w = FrameWriter::new(tx_buf);

Expand Down Expand Up @@ -107,8 +134,11 @@ impl<'a, B: AsMutSlice<Element = u8>> PPPoS<'a, B> {

/// Send an IP packet.
///
/// You must provide buffer space for the data to be transmitted, and transmit the returned
/// slice over the serial connection.
/// You must provide enough buffer space for the data to be transmitted. This function
/// returns the size of the encoded packet `n`, you must transmit `tx_buf[..n]` over the
/// serial connection.
///
/// Returns `BufferFullError` if `tx_buf` is too small.
pub fn send(&mut self, pkt: &[u8], tx_buf: &mut [u8]) -> Result<usize, BufferFullError> {
// TODO check IPv4CP is up

Expand Down

0 comments on commit 647d7b1

Please sign in to comment.