1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
#[cfg(windows)]
extern crate pcan_basic_sys;
#[cfg(unix)]
extern crate socketcan;

mod can_message;
mod can_network;
#[cfg(windows)]
mod can_pcan;
mod can_socketcan;
mod can_udp;
mod multican;

pub use self::can_message::CanMessage;
pub use self::can_network::CanNetwork;
#[cfg(windows)]
pub use self::can_pcan::PcanNetwork;
pub use self::can_socketcan::SocketCanNetwork;
pub use self::can_udp::UdpNetwork;
pub use self::multican::MultiCan;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CanConfig {
    /// Bus identifier, can be set to any value.  Use to specify the tx/rs bus for a CanMessage
    pub id: u8,
    /// Bus type - udp, socketcan, pcan
    pub kind: CanBusType,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum CanBusType {
    SocketCan,
    VirtualSocketCan,
    Pcan,
    Udp,
}

/// Initializes a group of CAN adapters from the specified configuration
///
/// Typical entry point for this library.  CanConfig can be read from a config file
/// or created manually.  Not required to create a multican instance, but useful.
///
/// Note that this function contains some sane defaults, but you may need to
/// customize things like the can network prefix.  If this is the case, construct
/// your adaters manuall and use add_adapter
///
/// # Example
///
/// ```
/// // Set up adapters
/// let cfg = read_config("myfile.toml");
/// let mut network = multican::from_config(cfg);
/// for m in network.recv() {
///     println!("RX: {:?}", m);
/// }
/// ```
pub fn from_config(config: Vec<CanConfig>) -> MultiCan {
    let mut mc = MultiCan::new();
    for net_config in config {
        match net_config.kind {
            CanBusType::SocketCan => {
                #[cfg(unix)]
                {
                    mc.add_adapter(
                        net_config.id,
                        Box::new(SocketCanNetwork::new(net_config.id, "can")),
                    );
                }
                #[cfg(windows)]
                {
                    panic!("Can't use SocketCAN on Windows");
                }
            }
            CanBusType::VirtualSocketCan => {
                #[cfg(unix)]
                {
                    mc.add_adapter(
                        net_config.id,
                        Box::new(SocketCanNetwork::new(net_config.id, "vcan")),
                    );
                }
                #[cfg(windows)]
                {
                    panic!("Can't use SocketCAN on Windows");
                }
            }
            CanBusType::Pcan => {
                #[cfg(unix)]
                {
                    panic!("Can't use PCAN on unix");
                }
                #[cfg(windows)]
                {
                    mc.add_adapter(net_config.id, Box::new(PcanNetwork::new()));
                }
            }
            CanBusType::Udp => {
                mc.add_adapter(net_config.id, Box::new(UdpNetwork::new(net_config.id)));
            }
        };
    }
    mc
}