prns-runtime-embassy 0.3.6

Embassy host runtime for Personal Reticulum
Documentation
use embassy_futures::block_on;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel;

use crate::interfaces::{InterfaceId, PacketPhyStats};
use crate::manifold::grant::{GrantConsumer, GrantProducer};
use crate::manifold::interface_seam::{InterfaceSeam, OutboundDisposition};

use super::super::leaked_grant_lane;
use super::EmbassyInterfaceSeam;

#[test]
fn packet_phy_crosses_the_embassy_ingress_seam_with_its_frame() {
    const FRAME: usize = 64;

    let interface = InterfaceId::new([0xA1; 8]);
    let (inbound, mut manifold_inbound) = leaked_grant_lane::<FRAME>(1);
    let (_manifold_outbound, outbound) = leaked_grant_lane::<FRAME>(1);
    let notify = Channel::<CriticalSectionRawMutex, InterfaceId, 1>::new();
    let packet_phy = PacketPhyStats {
        rssi: Some(crate::interfaces::RssiDbm::new(-87)),
        snr: Some(crate::interfaces::SnrQuarterDb::new(-9)),
        quality: crate::interfaces::SignalQualityTenthsPercent::new(875),
    };
    let mut seam =
        EmbassyInterfaceSeam::new(interface, inbound, notify.sender(), outbound, |bytes| {
            bytes.fill(0)
        });

    block_on(seam.next_inbound_with_phy(b"observed", packet_phy));

    let retained = manifold_inbound
        .try_peek()
        .expect("the committed frame reaches the manifold lane");
    assert_eq!(
        (retained.frame(), retained.packet_phy),
        (b"observed".as_slice(), packet_phy)
    );
    assert_eq!(notify.receiver().try_receive(), Ok(interface));

    manifold_inbound.release();
    block_on(seam.next_inbound(b"plain"));

    let retained = manifold_inbound
        .try_peek()
        .expect("the next committed frame reaches the manifold lane");
    assert_eq!(
        (retained.frame(), retained.packet_phy),
        (b"plain".as_slice(), PacketPhyStats::default())
    );
}

#[test]
fn accepted_outbound_custody_releases_lane_storage_before_completion() {
    const FRAME: usize = 64;

    let interface = InterfaceId::new([0xA2; 8]);
    let (inbound, _manifold_inbound) = leaked_grant_lane::<FRAME>(1);
    let (mut manifold_outbound, outbound) = leaked_grant_lane::<FRAME>(1);
    let notify = Channel::<CriticalSectionRawMutex, InterfaceId, 1>::new();
    let mut seam =
        EmbassyInterfaceSeam::new(interface, inbound, notify.sender(), outbound, |bytes| {
            bytes.fill(0)
        });

    manifold_outbound
        .try_grant()
        .expect("the first outbound slot is free")
        .fill_for(interface, b"first");
    manifold_outbound.commit();
    assert_eq!(block_on(seam.next_outbound()), b"first");

    seam.accept_outbound_custody();
    manifold_outbound
        .try_grant()
        .expect("accepted custody frees the slot before radio completion")
        .fill_for(interface, b"second");
    manifold_outbound.commit();
    assert_eq!(block_on(seam.next_outbound()), b"second");

    seam.complete_outbound(OutboundDisposition::Sent);
    assert!(
        manifold_outbound.try_grant().is_some(),
        "final completion releases whichever frame is currently borrowed"
    );
}