Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrapping EthernetInterface #5

Closed
little-dude opened this issue Feb 5, 2017 · 2 comments
Closed

Wrapping EthernetInterface #5

little-dude opened this issue Feb 5, 2017 · 2 comments

Comments

@little-dude
Copy link
Contributor

Hi,

I'm trying to wrap smoltcp::iface::EthernetInterface like so:

extern crate smoltcp;
use std::fs::File;
use std::io::{self, Read, Write};

struct Device {
    network: File,
}

struct TxBuffer {
    buffer: Vec<u8>,
    network: File,
}

impl AsRef<[u8]> for TxBuffer {
    fn as_ref(&self) -> &[u8] { self.buffer.as_ref() }
}

impl AsMut<[u8]> for TxBuffer {
    fn as_mut(&mut self) -> &mut [u8] { self.buffer.as_mut() }
}

impl Drop for TxBuffer {
    fn drop(&mut self) { self.network.write(&mut self.buffer[..]).unwrap(); }
}

impl smoltcp::phy::Device for Device {
    type RxBuffer = Vec<u8>;
    type TxBuffer = TxBuffer;

    fn mtu(&self) -> usize { 1536 }

    fn receive(&mut self) -> Result<Self::RxBuffer, smoltcp::Error> {
        let mut buffer = vec![0; self.mtu()];
        let size = self.network.read(&mut buffer[..])?;
        buffer.resize(size, 0);
        Ok(buffer)
    }

    fn transmit(&mut self, length: usize) -> Result<Self::TxBuffer, smoltcp::Error> {
        Ok(TxBuffer {
            network:  self.network.try_clone()?,
            buffer: vec![0; length]
        })
    }
}

pub struct EthernetDevice<'a, 'b, 'c>(smoltcp::iface::EthernetInterface<'a, 'b, 'c, Device>);

impl<'a, 'b, 'c> EthernetDevice <'a, 'b, 'c> {
    pub fn new(network: File) -> Self {
        let device = Box::new(Device { network: network });
        let arp_cache = Box::new(smoltcp::iface::SliceArpCache::new(vec![Default::default(); 8])) as Box<smoltcp::iface::ArpCache>;
        let hardware_addr = smoltcp::wire::EthernetAddress([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
        let ip_addresses = [smoltcp::wire::IpAddress::v4(192, 168, 0, 2)];
        EthernetDevice(smoltcp::iface::EthernetInterface::new(device, arp_cache, hardware_addr, ip_addresses))
    }
    // more stuff
}

This does not work:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
  --> new.rs:56:9
   |
56 |         EthernetDevice(smoltcp::iface::EthernetInterface::new(device, arp_cache, hardware_addr, ip_addresses))
   |         ^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime 'b as defined on the body at 51:38...
  --> new.rs:51:39
   |
51 |       pub fn new(network: File) -> Self {
   |  _______________________________________^ starting here...
52 | |         let device = Box::new(Device { network: network });
53 | |         let arp_cache = Box::new(smoltcp::iface::SliceArpCache::new(vec![Default::default(); 8])) as Box<smoltcp::iface::ArpCache>;
54 | |         let hardware_addr = smoltcp::wire::EthernetAddress([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
55 | |         let ip_addresses = [smoltcp::wire::IpAddress::v4(192, 168, 0, 2)];
56 | |         EthernetDevice(smoltcp::iface::EthernetInterface::new(device, arp_cache, hardware_addr, ip_addresses))
57 | |     }
   | |_____^ ...ending here
note: ...so that expression is assignable (expected EthernetDevice<'a, 'b, 'c>, found EthernetDevice<'_, '_, '_>)
  --> new.rs:56:9
   |
56 |         EthernetDevice(smoltcp::iface::EthernetInterface::new(device, arp_cache, hardware_addr, ip_addresses))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `smoltcp::iface::Cache` will meet its required lifetime bounds
  --> new.rs:56:24
   |
56 |         EthernetDevice(smoltcp::iface::EthernetInterface::new(device, arp_cache, hardware_addr, ip_addresses))
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I know this is not a smoltcp issue, but I have really don't know how to make the compiler happy here, so I was hoping you would be able to suggest something? Or am I trying to do something fundamentally wrong?

@whitequark
Copy link
Contributor

Given that you use Box and Vec everywhere, replace 'a 'b 'c with 'static.

@little-dude
Copy link
Contributor Author

Ahh thanks, it makes sense. This compiles fine:

pub struct EthernetDevice(smoltcp::iface::EthernetInterface<'static, 'static, 'static, Device>);

impl EthernetDevice {
    pub fn new(network: File) -> Self {
        let device = Box::new(Device { network: network });
        let arp_cache = Box::new(smoltcp::iface::SliceArpCache::new(vec![Default::default(); 8])) as Box<smoltcp::iface::ArpCache>;
        let hardware_addr = smoltcp::wire::EthernetAddress([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
        let ip_addresses = [smoltcp::wire::IpAddress::v4(192, 168, 0, 2)];
        EthernetDevice(smoltcp::iface::EthernetInterface::new(device, arp_cache, hardware_addr, ip_addresses))
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants