#![cfg_attr(rustfmt, rustfmt_skip)]
extern crate sacn;
extern crate uuid;
extern crate socket2;
use std::io::Read;
use std::{array, thread};
use std::thread::sleep;
use std::sync::mpsc;
use std::sync::mpsc::{Sender, SyncSender, Receiver, RecvTimeoutError};
use std::time::{Duration, Instant};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::iter;
use std::convert::TryInto; use std::str;
use sacn::source::SacnSource;
use sacn::receive::{SacnReceiver, DMXData, htp_dmx_merge};
use sacn::packet::*;
use sacn::error::errors::*;
use uuid::Uuid;
use socket2::{Socket, Domain, Type};
pub const TEST_NETWORK_INTERFACE_IPV4: [&'static str; 3] = ["192.168.0.6", "192.168.0.7", "192.168.0.8"];
pub const TEST_DATA_PARTIAL_CAPACITY_UNIVERSE: [u8; 313] = [0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
];
pub const TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE: [u8; 513] = [1,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
];
pub const TEST_DATA_SINGLE_UNIVERSE: [u8; 513] = [0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
];
pub const TEST_DATA_MULTIPLE_ALTERNATIVE_STARTCODE_UNIVERSE: [u8; 714] = [1,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
3,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
];
pub const TEST_DATA_MULTIPLE_UNIVERSE: [u8; 714] = [0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
];
pub const TEST_DATA_FULL_CAPACITY_MULTIPLE_UNIVERSE: [u8; 1026] = [0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
];
#[test]
#[ignore]
fn test_send_single_universe_multiple_receivers_multicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread1_tx = tx.clone();
let thread2_tx = tx.clone();
let universe = 1;
let rcv_thread1 = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
thread1_tx.send(Ok(Vec::new())).unwrap();
thread1_tx.send(dmx_recv.recv(None)).unwrap();
});
let rcv_thread2 = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
thread2_tx.send(Ok(Vec::new())).unwrap();
thread2_tx.send(dmx_recv.recv(None)).unwrap();
});
rx.recv().unwrap().unwrap(); rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe).unwrap();
src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), None, None).unwrap();
let received_result1: Result<Vec<DMXData>> = rx.recv().unwrap();
let received_result2: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread1.join().unwrap();
rcv_thread2.join().unwrap();
assert!(!received_result1.is_err(), "Failed: Error when receiving data");
let received_data1: Vec<DMXData> = received_result1.unwrap();
assert_eq!(received_data1.len(), 1); let received_universe1: DMXData = received_data1[0].clone();
assert_eq!(received_universe1.universe, universe); assert_eq!(received_universe1.values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
assert!(!received_result2.is_err(), "Failed: Error when receiving data");
let received_data2: Vec<DMXData> = received_result2.unwrap();
assert_eq!(received_data2.len(), 1); let received_universe2: DMXData = received_data2[0].clone();
assert_eq!(received_universe2.universe, universe); assert_eq!(received_universe2.values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
}
#[test]
#[ignore]
fn test_send_across_universe_multiple_receivers_sync_multicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread1_tx = tx.clone();
let thread2_tx = tx.clone();
let universe1 = 1;
let universe2 = 2;
let sync_uni = 3;
let rcv_thread1 = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe1]).unwrap();
dmx_recv.listen_universes(&[sync_uni]).unwrap();
thread1_tx.send(Ok(Vec::new())).unwrap();
thread1_tx.send(dmx_recv.recv(None)).unwrap();
});
let rcv_thread2 = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe2]).unwrap();
dmx_recv.listen_universes(&[sync_uni]).unwrap();
thread2_tx.send(Ok(Vec::new())).unwrap();
thread2_tx.send(dmx_recv.recv(None)).unwrap();
});
rx.recv().unwrap().unwrap(); rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe1).unwrap();
src.register_universe(universe2).unwrap();
src.register_universe(sync_uni).unwrap();
src.send(&[universe1], &TEST_DATA_MULTIPLE_UNIVERSE[..513], Some(priority), None, Some(sync_uni)).unwrap();
src.send(&[universe2], &TEST_DATA_MULTIPLE_UNIVERSE[513..], Some(priority), None, Some(sync_uni)).unwrap();
const WAIT_RECV_TIMEOUT: u64 = 2;
let attempt_recv = rx.recv_timeout(Duration::from_secs(WAIT_RECV_TIMEOUT));
match attempt_recv {
Ok(_) => {
assert!(false, "Receivers received without waiting for sync");
},
Err(e) => assert_eq!(e, RecvTimeoutError::Timeout)
}
src.send_sync_packet(sync_uni, None).unwrap();
let received_result1: Vec<DMXData> = rx.recv().unwrap().unwrap();
let received_result2: Vec<DMXData> = rx.recv().unwrap().unwrap();
rcv_thread1.join().unwrap();
rcv_thread2.join().unwrap();
assert_eq!(received_result1.len(), 1); assert_eq!(received_result2.len(), 1);
let mut results = vec![received_result1[0].clone(), received_result2[0].clone()];
results.sort_unstable();
assert_eq!(results[0].universe, universe1); assert_eq!(results[1].universe, universe2);
assert_eq!(results[0].values, TEST_DATA_MULTIPLE_UNIVERSE[..513].to_vec());
assert_eq!(results[1].values, TEST_DATA_MULTIPLE_UNIVERSE[513..].to_vec());
}
#[test]
#[ignore]
fn test_send_recv_single_universe_unicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
let universe = 1;
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
thread_tx.send(dmx_recv.recv(None)).unwrap();
});
let _ = rx.recv().unwrap();
let ip: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe).unwrap();
let dst_ip: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT);
let _ = src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
let received_result: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!received_result.is_err(), "Failed: Error when receiving data");
let received_data: Vec<DMXData> = received_result.unwrap();
assert_eq!(received_data.len(), 1);
let received_universe: DMXData = received_data[0].clone();
assert_eq!(received_universe.universe, universe);
assert_eq!(received_universe.values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
}
#[test]
#[ignore]
fn test_send_recv_single_universe_multicast_ipv4(){
const UNIVERSE: u16 = 1;
const PRIORITY: u8 = 100;
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[UNIVERSE]).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
let result = dmx_recv.recv(None);
thread_tx.send(result).unwrap();
});
rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
src.register_universe(UNIVERSE).unwrap();
src.send(&[UNIVERSE], &TEST_DATA_SINGLE_UNIVERSE, Some(PRIORITY), None, None).unwrap();
let received_result: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!received_result.is_err(), "Failed: Error when receiving data");
let received_data: Vec<DMXData> = received_result.unwrap();
assert_eq!(received_data.len(), 1);
let received_universe: DMXData = received_data[0].clone();
assert_eq!(received_universe.priority, PRIORITY, "Received priority doesn't match expected");
assert_eq!(received_universe.universe, UNIVERSE, "Received universe doesn't match expected");
assert_eq!(received_universe.values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
}
#[test]
#[ignore]
fn test_send_recv_single_universe_overflow_sequence_number_multicast_ipv4(){
const DATA_PACKETS_TO_SEND: usize = 260;
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
let universe = 1;
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
for _ in 0 .. DATA_PACKETS_TO_SEND {
thread_tx.send(dmx_recv.recv(None)).unwrap();
}
});
rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
src.register_universe(universe).unwrap();
for i in 0 .. DATA_PACKETS_TO_SEND {
src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE[0 .. i + 1], None, None, None).unwrap(); let received_data: Vec<DMXData> = rx.recv().unwrap().unwrap(); assert_eq!(received_data.len(), 1); let received_universe: DMXData = received_data[0].clone();
assert_eq!(received_universe.universe, universe);
assert_eq!(received_universe.values, TEST_DATA_SINGLE_UNIVERSE[0 .. i + 1].to_vec(), "Received payload values don't match sent!");
}
rcv_thread.join().unwrap();
}
#[test]
#[ignore]
fn test_send_recv_diff_priority_same_universe_multicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
let universe = 1;
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
thread_tx.send(dmx_recv.recv(None)).unwrap();
});
rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 110;
let priority_2 = 109;
src.register_universe(universe).unwrap();
src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), None, Some(universe)).unwrap(); src.send(&[universe], &TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE, Some(priority_2), None, Some(universe)).unwrap(); src.send_sync_packet(universe, None).unwrap();
let received_result: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!received_result.is_err(), "Failed: Error when receiving data");
let received_data: Vec<DMXData> = received_result.unwrap();
assert_eq!(received_data.len(), 1);
let received_universe: DMXData = received_data[0].clone();
assert_eq!(received_universe.universe, universe);
assert_eq!(received_universe.values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
}
#[test]
#[ignore]
fn test_send_recv_two_packets_same_priority_same_universe_multicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
let universe = 1;
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
thread_tx.send(dmx_recv.recv(None)).unwrap();
});
rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 110;
src.register_universe(universe).unwrap();
src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), None, Some(universe)).unwrap(); src.send(&[universe], &TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE, Some(priority), None, Some(universe)).unwrap(); src.send_sync_packet(universe, None).unwrap();
let received_result: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!received_result.is_err(), "Failed: Error when receiving data");
let received_data: Vec<DMXData> = received_result.unwrap();
assert_eq!(received_data.len(), 1);
let received_universe: DMXData = received_data[0].clone();
assert_eq!(received_universe.universe, universe);
assert_eq!(received_universe.values, TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
}
#[test]
#[ignore]
fn test_send_recv_sync_then_nosync_packet_same_universe_multicast_ipv4() {
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
let universe = 1;
const TIMEOUT: Option<Duration> = Some(Duration::from_secs(2));
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
thread_tx.send(dmx_recv.recv(None)).unwrap();
thread_tx.send(dmx_recv.recv(TIMEOUT)).unwrap(); });
rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
src.register_universe(universe).unwrap();
src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE, None, None, Some(universe)).unwrap(); src.send(&[universe], &TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE, None, None, None).unwrap();
src.send_sync_packet(universe, None).unwrap();
let first_received_result: Result<Vec<DMXData>> = rx.recv().unwrap();
let second_received_result: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!first_received_result.is_err(), "Unexpected error when receiving first lot of data");
let received_data: Vec<DMXData> = first_received_result.unwrap();
assert_eq!(received_data.len(), 1); let received_universe: DMXData = received_data[0].clone();
assert_eq!(received_universe.universe, universe); assert_eq!(received_universe.values, TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
match second_received_result {
Err(e) => {
match e {
SacnError::Io(s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock => {
assert!(true, "Timed out as expected meaning waiting data was successfully discarded");
},
std::io::ErrorKind::TimedOut => {
assert!(true, "Timed out as expected meaning waiting data was successfully discarded");
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
}
Ok(_) => {
assert!(false, "Second receive attempt didn't timeout as expected, indicates that the synchronised data packet wasn't discarded as expected");
}
}
}
#[test]
#[ignore]
fn test_send_recv_two_universe_multicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
let universes = [1, 2];
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&universes).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
thread_tx.send(dmx_recv.recv(None)).unwrap(); thread_tx.send(dmx_recv.recv(None)).unwrap();
});
rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
src.register_universes(&universes).unwrap();
src.send(&universes, &TEST_DATA_MULTIPLE_UNIVERSE, None, None, None).unwrap();
let received_result: Result<Vec<DMXData>> = rx.recv().unwrap();
let received_result_2: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!received_result.is_err(), "Failed: Error when receiving 1st universe of data");
assert!(!received_result_2.is_err(), "Failed: Error when receiving 2nd universe of data");
let received_data: Vec<DMXData> = received_result.unwrap();
let received_data_2: Vec<DMXData> = received_result_2.unwrap();
assert_eq!(received_data.len(), 1); assert_eq!(received_data_2.len(), 1);
assert_eq!(received_data[0].universe, universes[0]); assert_eq!(received_data_2[0].universe, universes[1]);
assert_eq!(received_data[0].values, TEST_DATA_MULTIPLE_UNIVERSE[..513].to_vec());
assert_eq!(received_data_2[0].values, TEST_DATA_MULTIPLE_UNIVERSE[513..].to_vec());
}
#[test]
#[ignore]
fn test_send_recv_single_universe_alternative_startcode_multicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
let universe = 1;
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
thread_tx.send(dmx_recv.recv(None)).unwrap();
});
rx.recv().unwrap().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe).unwrap();
src.send(&[universe], &TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE, Some(priority), None, None).unwrap();
let received_result: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!received_result.is_err(), "Failed: Error when receiving data");
let received_data: Vec<DMXData> = received_result.unwrap();
assert_eq!(received_data.len(), 1);
let received_universe: DMXData = received_data[0].clone();
assert_eq!(received_universe.universe, universe);
assert_eq!(received_universe.values, TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
}
#[test]
#[ignore]
fn test_send_recv_across_universe_multicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
const UNIVERSES: [u16; 2] = [2, 3];
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(Ipv4Addr::new(0,0,0,0).into(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&UNIVERSES).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
thread_tx.send(dmx_recv.recv(None)).unwrap(); });
let _ = rx.recv().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universes(&UNIVERSES).unwrap();
src.send(&UNIVERSES, &TEST_DATA_MULTIPLE_UNIVERSE, Some(priority), None, Some(UNIVERSES[0])).unwrap();
sleep(Duration::from_millis(500)); src.send_sync_packet(UNIVERSES[0], None).unwrap();
let sync_pkt_res: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!sync_pkt_res.is_err(), "Failed: Error when receiving packets");
let mut received_data: Vec<DMXData> = sync_pkt_res.unwrap();
received_data.sort();
assert_eq!(received_data.len(), 2);
assert_eq!(received_data[0].universe, 2);
assert_eq!(received_data[0].sync_uni, 2);
assert_eq!(received_data[0].values, TEST_DATA_MULTIPLE_UNIVERSE[..UNIVERSE_CHANNEL_CAPACITY].to_vec(), "Universe 1 received payload values don't match sent!");
assert_eq!(received_data[1].universe, 3);
assert_eq!(received_data[1].sync_uni, 2);
assert_eq!(received_data[1].values, TEST_DATA_MULTIPLE_UNIVERSE[UNIVERSE_CHANNEL_CAPACITY..].to_vec(), "Universe 2 received payload values don't match sent!");
}
#[test]
#[ignore]
fn test_send_recv_across_universe_unicast_ipv4(){
let (tx, rx): (Sender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::channel();
let thread_tx = tx.clone();
const UNIVERSES: [u16; 2] = [2, 3];
let rcv_thread = thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(Ipv4Addr::new(127,0,0,1).into(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&UNIVERSES).unwrap();
thread_tx.send(Ok(Vec::new())).unwrap();
thread_tx.send(dmx_recv.recv(None)).unwrap(); });
let _ = rx.recv().unwrap();
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universes(&UNIVERSES).unwrap();
let _ = src.send(&UNIVERSES, &TEST_DATA_MULTIPLE_UNIVERSE, Some(priority), Some(SocketAddr::new(Ipv4Addr::new(127,0,0,1).into(), ACN_SDT_MULTICAST_PORT).into()), Some(UNIVERSES[0])).unwrap();
sleep(Duration::from_millis(500)); src.send_sync_packet(UNIVERSES[0], Some(SocketAddr::new(Ipv4Addr::new(127,0,0,1).into(), ACN_SDT_MULTICAST_PORT).into())).unwrap();
let sync_pkt_res: Result<Vec<DMXData>> = rx.recv().unwrap();
rcv_thread.join().unwrap();
assert!(!sync_pkt_res.is_err(), "Failed: Error when receiving packets");
let mut received_data: Vec<DMXData> = sync_pkt_res.unwrap();
received_data.sort();
assert_eq!(received_data.len(), 2);
assert_eq!(received_data[0].universe, 2);
assert_eq!(received_data[0].sync_uni, 2);
assert_eq!(received_data[0].values, TEST_DATA_MULTIPLE_UNIVERSE[..UNIVERSE_CHANNEL_CAPACITY].to_vec(), "Universe 1 received payload values don't match sent!");
assert_eq!(received_data[1].universe, 3);
assert_eq!(received_data[1].sync_uni, 2);
assert_eq!(received_data[1].values, TEST_DATA_MULTIPLE_UNIVERSE[UNIVERSE_CHANNEL_CAPACITY..].to_vec(), "Universe 2 received payload values don't match sent!");
}
#[test]
#[ignore]
fn test_two_senders_one_recv_different_universes_multicast_ipv4(){
let universe_1 = 1;
let universe_2 = 2;
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(Ipv4Addr::new(0,0,0,0).into(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe_1]).unwrap();
dmx_recv.listen_universes(&[universe_2]).unwrap();
let snd_thread_1 = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe_1).unwrap();
let _ = src.send(&[universe_1], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), None, None).unwrap();
});
let snd_thread_2 = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), ACN_SDT_MULTICAST_PORT + 2);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe_2).unwrap();
let _ = src.send(&[universe_2], &TEST_DATA_PARTIAL_CAPACITY_UNIVERSE, Some(priority), None, None).unwrap();
});
let res1: Vec<DMXData> = dmx_recv.recv(None).unwrap();
let res2: Vec<DMXData> = dmx_recv.recv(None).unwrap();
snd_thread_1.join().unwrap();
snd_thread_2.join().unwrap();
assert_eq!(res1.len(), 1);
assert_eq!(res2.len(), 1);
let mut res = vec![res1[0].clone(), res2[0].clone()];
res.sort_unstable();
assert_eq!(res[0].universe, universe_1);
assert_eq!(res[1].universe, universe_2);
assert_eq!(res[0].values, TEST_DATA_SINGLE_UNIVERSE.to_vec());
assert_eq!(res[1].values, TEST_DATA_PARTIAL_CAPACITY_UNIVERSE.to_vec());
}
#[test]
#[ignore]
fn test_two_senders_one_recv_same_universe_no_sync_multicast_ipv4(){
let universe = 1;
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(Ipv4Addr::new(0,0,0,0).into(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
let snd_thread_1 = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe).unwrap();
let _ = src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), None, None).unwrap();
});
let snd_thread_2 = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), ACN_SDT_MULTICAST_PORT + 2);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe).unwrap();
let _ = src.send(&[universe], &TEST_DATA_PARTIAL_CAPACITY_UNIVERSE, Some(priority), None, None).unwrap();
});
let res1: Vec<DMXData> = dmx_recv.recv(None).unwrap();
let res2: Vec<DMXData> = dmx_recv.recv(None).unwrap();
snd_thread_1.join().unwrap();
snd_thread_2.join().unwrap();
assert_eq!(res1.len(), 1);
assert_eq!(res2.len(), 1);
let res = vec![res1[0].clone(), res2[0].clone()];
assert_eq!(res[0].universe, universe);
assert_eq!(res[1].universe, universe);
if res[0].values == TEST_DATA_SINGLE_UNIVERSE.to_vec() {
assert_eq!(res[1].values, TEST_DATA_PARTIAL_CAPACITY_UNIVERSE.to_vec());
} else {
assert_eq!(res[0].values, TEST_DATA_PARTIAL_CAPACITY_UNIVERSE.to_vec());
assert_eq!(res[1].values, TEST_DATA_SINGLE_UNIVERSE.to_vec());
}
}
#[test]
#[ignore]
fn test_two_senders_one_recv_same_universe_custom_merge_fn_sync_multicast_ipv4(){
let (tx, rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let snd_tx = tx.clone();
let universe = 1;
let sync_uni = 2;
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe, sync_uni]).unwrap();
dmx_recv.set_merge_fn(htp_dmx_merge).unwrap();
let snd_thread_1 = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe).unwrap();
src.register_universe(sync_uni).unwrap();
src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), None, Some(sync_uni)).unwrap();
snd_tx.send(()).unwrap();
});
let snd_thread_2 = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[2].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 2);
let mut src = SacnSource::with_ip("Source 2", ip).unwrap();
let priority = 100;
src.register_universe(universe).unwrap();
src.register_universe(sync_uni).unwrap();
src.send(&[universe], &TEST_DATA_PARTIAL_CAPACITY_UNIVERSE, Some(priority), None, Some(sync_uni)).unwrap();
rx.recv().unwrap(); src.send_sync_packet(sync_uni, None).unwrap();
});
let res1: Vec<DMXData> = dmx_recv.recv(None).unwrap();
snd_thread_1.join().unwrap();
snd_thread_2.join().unwrap();
assert_eq!(res1.len(), 1);
assert_eq!(res1[0].values, htp_dmx_merge(&DMXData {
universe: universe,
values: TEST_DATA_SINGLE_UNIVERSE.to_vec(),
sync_uni: sync_uni,
priority: 100,
src_cid: None,
preview: false,
recv_timestamp: Instant::now()
},
&DMXData {
universe: universe,
values: TEST_DATA_PARTIAL_CAPACITY_UNIVERSE.to_vec(),
sync_uni: sync_uni,
priority: 100,
src_cid: None,
preview: false,
recv_timestamp: Instant::now()
},).unwrap().values);
}
#[test]
#[ignore]
fn test_two_senders_two_recv_multicast_ipv4(){
const SND_THREADS: usize = 2;
const RCV_THREADS: usize = 2;
const SND_DATA_LEN: usize = 100;
let mut snd_data: Vec<Vec<u8>> = Vec::new();
for i in 1 .. SND_THREADS + 1 {
let mut d: Vec<u8> = Vec::new();
for _k in 0 .. SND_DATA_LEN {
d.push(i as u8);
}
snd_data.push(d);
}
let mut snd_threads = Vec::new();
let mut rcv_threads = Vec::new();
let (rcv_tx, rcv_rx): (SyncSender<Vec<Result<Vec<DMXData>>>>, Receiver<Vec<Result<Vec<DMXData>>>>) = mpsc::sync_channel(0);
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
assert!(RCV_THREADS <= TEST_NETWORK_INTERFACE_IPV4.len(), "Number of test network interface ips less than number of recv threads!");
const BASE_UNIVERSE: u16 = 2;
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
let data = snd_data[i].clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(&format!("Source {}", i), ip).unwrap();
let priority = 100;
let universe: u16 = (i as u16) + BASE_UNIVERSE;
src.register_universe(universe).unwrap();
tx.send(()).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
}));
}
for i in 0 .. RCV_THREADS {
let tx = rcv_tx.clone();
rcv_threads.push(thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[i].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
for i in (BASE_UNIVERSE as u16) .. ((SND_THREADS as u16) + (BASE_UNIVERSE as u16)) {
dmx_recv.listen_universes(&[i]).unwrap();
}
let mut res: Vec<Result<Vec<DMXData>>> = Vec::new();
tx.send(Vec::new()).unwrap();
for _i in 0 .. SND_THREADS { res.push(dmx_recv.recv(None)); }
tx.send(res).unwrap();
}));
assert_eq!(rcv_rx.recv().unwrap().len(), 0); }
for _i in 0 .. SND_THREADS {
snd_rx.recv().unwrap(); }
for _i in 0 .. RCV_THREADS {
let res: Vec<Result<Vec<DMXData>>> = rcv_rx.recv().unwrap();
assert_eq!(res.len(), SND_THREADS);
let mut rcv_dmx_datas: Vec<DMXData> = Vec::new();
for r in res {
let data: Vec<DMXData> = r.unwrap(); assert_eq!(data.len(), 1); rcv_dmx_datas.push(data[0].clone());
}
rcv_dmx_datas.sort_unstable();
for k in 0 .. SND_THREADS {
assert_eq!(rcv_dmx_datas[k].universe, ((k as u16) + BASE_UNIVERSE));
assert_eq!(rcv_dmx_datas[k].values, snd_data[k], "Received payload values don't match sent!");
}
}
for s in snd_threads {
s.join().unwrap();
}
for r in rcv_threads {
r.join().unwrap();
}
}
#[test]
#[ignore]
fn test_three_senders_two_recv_multicast_ipv4(){
const SND_THREADS: usize = 3;
const RCV_THREADS: usize = 2;
const SND_DATA_LEN: usize = 100;
let mut snd_data: Vec<Vec<u8>> = Vec::new();
for i in 1 .. SND_THREADS + 1 {
let mut d: Vec<u8> = Vec::new();
for _k in 0 .. SND_DATA_LEN {
d.push(i as u8);
}
snd_data.push(d);
}
let mut snd_threads = Vec::new();
let mut rcv_threads = Vec::new();
let (rcv_tx, rcv_rx): (SyncSender<Vec<Result<Vec<DMXData>>>>, Receiver<Vec<Result<Vec<DMXData>>>>) = mpsc::sync_channel(0);
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
assert!(RCV_THREADS <= TEST_NETWORK_INTERFACE_IPV4.len(), "Number of test network interface ips less than number of recv threads!");
const BASE_UNIVERSE: u16 = 2;
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
let data = snd_data[i].clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(&format!("Source {}", i), ip).unwrap();
let priority = 100;
let universe: u16 = (i as u16) + BASE_UNIVERSE;
src.register_universe(universe).unwrap();
tx.send(()).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
}));
}
for i in 0 .. RCV_THREADS {
let tx = rcv_tx.clone();
rcv_threads.push(thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[i].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
for i in (BASE_UNIVERSE as u16) .. ((SND_THREADS as u16) + (BASE_UNIVERSE as u16)) {
dmx_recv.listen_universes(&[i]).unwrap();
}
let mut res: Vec<Result<Vec<DMXData>>> = Vec::new();
tx.send(Vec::new()).unwrap();
for _i in 0 .. SND_THREADS { res.push(dmx_recv.recv(None)); }
tx.send(res).unwrap();
}));
assert_eq!(rcv_rx.recv().unwrap().len(), 0); }
for _i in 0 .. SND_THREADS {
snd_rx.recv().unwrap(); }
for _i in 0 .. RCV_THREADS {
let res: Vec<Result<Vec<DMXData>>> = rcv_rx.recv().unwrap();
assert_eq!(res.len(), SND_THREADS);
let mut rcv_dmx_datas: Vec<DMXData> = Vec::new();
for r in res {
let data: Vec<DMXData> = r.unwrap(); assert_eq!(data.len(), 1); rcv_dmx_datas.push(data[0].clone());
}
rcv_dmx_datas.sort_unstable();
for k in 0 .. SND_THREADS {
assert_eq!(rcv_dmx_datas[k].universe, ((k as u16) + BASE_UNIVERSE));
assert_eq!(rcv_dmx_datas[k].values, snd_data[k], "Received payload values don't match sent!");
}
}
for s in snd_threads {
s.join().unwrap();
}
for r in rcv_threads {
r.join().unwrap();
}
}
#[test]
#[ignore]
fn test_two_senders_three_recv_multicast_ipv4(){
const SND_THREADS: usize = 2;
const RCV_THREADS: usize = 3;
const SND_DATA_LEN: usize = 100;
let mut snd_data: Vec<Vec<u8>> = Vec::new();
for i in 1 .. SND_THREADS + 1 {
let mut d: Vec<u8> = Vec::new();
for _k in 0 .. SND_DATA_LEN {
d.push(i as u8);
}
snd_data.push(d);
}
let mut snd_threads = Vec::new();
let mut rcv_threads = Vec::new();
let (rcv_tx, rcv_rx): (SyncSender<Vec<Result<Vec<DMXData>>>>, Receiver<Vec<Result<Vec<DMXData>>>>) = mpsc::sync_channel(0);
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
assert!(RCV_THREADS <= TEST_NETWORK_INTERFACE_IPV4.len(), "Number of test network interface ips less than number of recv threads!");
const BASE_UNIVERSE: u16 = 2;
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
let data = snd_data[i].clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(&format!("Source {}", i), ip).unwrap();
let priority = 100;
let universe: u16 = (i as u16) + BASE_UNIVERSE;
src.register_universe(universe).unwrap();
tx.send(()).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
}));
}
for i in 0 .. RCV_THREADS {
let tx = rcv_tx.clone();
rcv_threads.push(thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[i].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
for i in (BASE_UNIVERSE as u16) .. ((SND_THREADS as u16) + (BASE_UNIVERSE as u16)) {
dmx_recv.listen_universes(&[i]).unwrap();
}
let mut res: Vec<Result<Vec<DMXData>>> = Vec::new();
tx.send(Vec::new()).unwrap();
for _i in 0 .. SND_THREADS { res.push(dmx_recv.recv(None)); }
tx.send(res).unwrap();
}));
assert_eq!(rcv_rx.recv().unwrap().len(), 0); }
for _i in 0 .. SND_THREADS {
snd_rx.recv().unwrap(); }
for _i in 0 .. RCV_THREADS {
let res: Vec<Result<Vec<DMXData>>> = rcv_rx.recv().unwrap();
assert_eq!(res.len(), SND_THREADS);
let mut rcv_dmx_datas: Vec<DMXData> = Vec::new();
for r in res {
let data: Vec<DMXData> = r.unwrap(); assert_eq!(data.len(), 1); rcv_dmx_datas.push(data[0].clone());
}
rcv_dmx_datas.sort_unstable();
for k in 0 .. SND_THREADS {
assert_eq!(rcv_dmx_datas[k].universe, ((k as u16) + BASE_UNIVERSE));
assert_eq!(rcv_dmx_datas[k].values, snd_data[k], "Received payload values don't match sent!");
}
}
for s in snd_threads {
s.join().unwrap();
}
for r in rcv_threads {
r.join().unwrap();
}
}
#[test]
#[ignore]
fn test_three_senders_three_recv_multicast_ipv4(){
const SND_THREADS: usize = 3;
const RCV_THREADS: usize = 3;
const SND_DATA_LEN: usize = 100;
let mut snd_data: Vec<Vec<u8>> = Vec::new();
for i in 1 .. SND_THREADS + 1 {
let mut d: Vec<u8> = Vec::new();
for _k in 0 .. SND_DATA_LEN {
d.push(i as u8);
}
snd_data.push(d);
}
let mut snd_threads = Vec::new();
let mut rcv_threads = Vec::new();
let (rcv_tx, rcv_rx): (SyncSender<Vec<Result<Vec<DMXData>>>>, Receiver<Vec<Result<Vec<DMXData>>>>) = mpsc::sync_channel(0);
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
assert!(RCV_THREADS <= TEST_NETWORK_INTERFACE_IPV4.len(), "Number of test network interface ips less than number of recv threads!");
const BASE_UNIVERSE: u16 = 2;
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
let data = snd_data[i].clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(&format!("Source {}", i), ip).unwrap();
let priority = 100;
let universe: u16 = (i as u16) + BASE_UNIVERSE;
src.register_universe(universe).unwrap();
tx.send(()).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
}));
}
for i in 0 .. RCV_THREADS {
let tx = rcv_tx.clone();
rcv_threads.push(thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[i].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
for i in (BASE_UNIVERSE as u16) .. ((SND_THREADS as u16) + (BASE_UNIVERSE as u16)) {
dmx_recv.listen_universes(&[i]).unwrap();
}
let mut res: Vec<Result<Vec<DMXData>>> = Vec::new();
tx.send(Vec::new()).unwrap();
for _i in 0 .. SND_THREADS { res.push(dmx_recv.recv(None)); }
tx.send(res).unwrap();
}));
assert_eq!(rcv_rx.recv().unwrap().len(), 0); }
for _i in 0 .. SND_THREADS {
snd_rx.recv().unwrap(); }
for _i in 0 .. RCV_THREADS {
let res: Vec<Result<Vec<DMXData>>> = rcv_rx.recv().unwrap();
assert_eq!(res.len(), SND_THREADS);
let mut rcv_dmx_datas: Vec<DMXData> = Vec::new();
for r in res {
let data: Vec<DMXData> = r.unwrap(); assert_eq!(data.len(), 1); rcv_dmx_datas.push(data[0].clone());
}
rcv_dmx_datas.sort_unstable();
for k in 0 .. SND_THREADS {
assert_eq!(rcv_dmx_datas[k].universe, ((k as u16) + BASE_UNIVERSE));
assert_eq!(rcv_dmx_datas[k].values, snd_data[k], "Received payload values don't match sent!");
}
}
for s in snd_threads {
s.join().unwrap();
}
for r in rcv_threads {
r.join().unwrap();
}
}
#[test]
#[ignore]
fn test_universe_discovery_one_universe_one_source_ipv4(){
const SND_THREADS: usize = 1;
const BASE_UNIVERSE: u16 = 2;
const UNIVERSE_COUNT: usize = 1;
const SOURCE_NAMES: [&'static str; 1] = ["Source 1"];
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let mut snd_threads = Vec::new();
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(SOURCE_NAMES[i], ip).unwrap();
let mut universes: Vec<u16> = Vec::new();
for j in 0 .. UNIVERSE_COUNT {
universes.push(((i + j) as u16) + BASE_UNIVERSE);
}
src.register_universes(&universes).unwrap();
tx.send(()).unwrap(); }));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
loop {
let result = dmx_recv.recv(Some(Duration::from_secs(2)));
match result {
Err(e) => {
match e {
SacnError::Io(ref s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock => {
},
std::io::ErrorKind::TimedOut => {},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
Ok(_) => {
assert!(false, "No data should have been passed up!");
}
}
let discovered = dmx_recv.get_discovered_sources();
if discovered.len() > 0 {
assert_eq!(discovered.len(), 1);
assert_eq!(discovered[0].name, SOURCE_NAMES[0]);
let universes = discovered[0].get_all_universes();
assert_eq!(universes.len(), UNIVERSE_COUNT);
for j in 0 .. UNIVERSE_COUNT {
assert_eq!(universes[j], (j as u16) + BASE_UNIVERSE);
}
break;
}
}
snd_rx.recv().unwrap();
for s in snd_threads {
s.join().unwrap();
}
}
#[test]
#[ignore]
fn test_universe_discovery_interval_ipv4(){
const SND_THREADS: usize = 1;
const BASE_UNIVERSE: u16 = 1;
const SOURCE_NAMES: [&'static str; 1] = ["Source 1"];
const INTERVAL_EXPECTED_MILLIS: u128 = E131_UNIVERSE_DISCOVERY_INTERVAL.as_millis(); const INTERVAL_TOLERANCE_MILLIS: u128 = 1000;
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let mut snd_threads = Vec::new();
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
tx.send(()).unwrap();
let mut src = SacnSource::with_ip(SOURCE_NAMES[i], ip).unwrap();
src.register_universes(&[BASE_UNIVERSE]).unwrap();
tx.send(()).unwrap(); }));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.set_announce_source_discovery(true);
snd_rx.recv().unwrap();
let mut interval_start = Instant::now();
match dmx_recv.recv(None) {
Err(e) => {
match e {
SacnError::SourceDiscovered(_) => {
interval_start = Instant::now();
}
k => {
assert!(false, "Unexpected error kind, {:?}", k);
}
}
}
Ok(d) => {
assert!(false, "No data expected, {:?}", d);
}
}
match dmx_recv.recv(None) {
Err(e) => {
match e {
SacnError::SourceDiscovered(_) => {
let interval = interval_start.elapsed();
let interval_millis = interval.as_millis();
assert!(interval_millis > (INTERVAL_EXPECTED_MILLIS - INTERVAL_TOLERANCE_MILLIS), "Discovery interval is shorter than expected, {} ms", interval_millis);
assert!(interval_millis < (INTERVAL_EXPECTED_MILLIS + INTERVAL_TOLERANCE_MILLIS), "Discovery interval is longer than expected, {} ms", interval_millis);
}
k => {
assert!(false, "Unexpected error kind, {:?}", k);
}
}
}
Ok(d) => {
assert!(false, "No data expected, {:?}", d);
}
}
snd_rx.recv().unwrap(); }
#[test]
#[ignore]
fn test_universe_discovery_interval_with_updates_ipv4(){
const SND_THREADS: usize = 1;
const BASE_UNIVERSE: u16 = 1;
const SOURCE_NAMES: [&'static str; 1] = ["Source 1"];
const INTERVAL_EXPECTED_MILLIS: u128 = E131_UNIVERSE_DISCOVERY_INTERVAL.as_millis(); const INTERVAL_TOLERANCE_MILLIS: u128 = 1000; const SENDER_REGISTER_DELAY: Duration = Duration::from_secs(1); const UNIVERSES_TO_REGISTER: usize = 5;
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let mut snd_threads = Vec::new();
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
tx.send(()).unwrap();
let mut src = SacnSource::with_ip(SOURCE_NAMES[i], ip).unwrap();
for _ in 0 .. UNIVERSES_TO_REGISTER {
src.register_universes(&[BASE_UNIVERSE]).unwrap();
sleep(SENDER_REGISTER_DELAY);
}
tx.send(()).unwrap(); }));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.set_announce_source_discovery(true);
snd_rx.recv().unwrap();
let mut interval_start = Instant::now();
match dmx_recv.recv(None) {
Err(e) => {
match e {
SacnError::SourceDiscovered(_) => {
interval_start = Instant::now();
}
k => {
assert!(false, "Unexpected error kind, {:?}", k);
}
}
}
Ok(d) => {
assert!(false, "No data expected, {:?}", d);
}
}
match dmx_recv.recv(None) {
Err(e) => {
match e {
SacnError::SourceDiscovered(_) => {
let interval = interval_start.elapsed();
let interval_millis = interval.as_millis();
assert!(interval_millis > (INTERVAL_EXPECTED_MILLIS - INTERVAL_TOLERANCE_MILLIS), "Discovery interval is shorter than expected, {} ms", interval_millis);
assert!(interval_millis < (INTERVAL_EXPECTED_MILLIS + INTERVAL_TOLERANCE_MILLIS), "Discovery interval is longer than expected, {} ms", interval_millis);
}
k => {
assert!(false, "Unexpected error kind, {:?}", k);
}
}
}
Ok(d) => {
assert!(false, "No data expected, {:?}", d);
}
}
snd_rx.recv().unwrap(); }
#[test]
#[ignore]
fn test_universe_discovery_multiple_universe_one_source_ipv4(){
const SND_THREADS: usize = 1;
const BASE_UNIVERSE: u16 = 2;
const UNIVERSE_COUNT: usize = 5;
const SOURCE_NAMES: [&'static str; 1] = ["Source 1"];
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let mut snd_threads = Vec::new();
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(SOURCE_NAMES[i], ip).unwrap();
let mut universes: Vec<u16> = Vec::new();
for j in 0 .. UNIVERSE_COUNT {
universes.push(((i + j) as u16) + BASE_UNIVERSE);
}
src.register_universes(&universes).unwrap();
tx.send(()).unwrap(); }));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
loop {
let result = dmx_recv.recv(Some(Duration::from_secs(2)));
match result {
Err(e) => {
match e {
SacnError::Io(ref s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock => {
},
std::io::ErrorKind::TimedOut => {},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
Ok(_) => {
assert!(false, "No data should have been passed up!");
}
}
let discovered = dmx_recv.get_discovered_sources();
if discovered.len() > 0 {
assert_eq!(discovered.len(), 1);
assert_eq!(discovered[0].name, SOURCE_NAMES[0]);
let universes = discovered[0].get_all_universes();
assert_eq!(universes.len(), UNIVERSE_COUNT);
for j in 0 .. UNIVERSE_COUNT {
assert_eq!(universes[j], (j as u16) + BASE_UNIVERSE);
}
break;
}
}
snd_rx.recv().unwrap();
for s in snd_threads {
s.join().unwrap();
}
}
#[test]
#[ignore]
fn test_universe_discovery_multiple_pages_one_source_ipv4(){
const SND_THREADS: usize = 1;
const BASE_UNIVERSE: u16 = 2;
const UNIVERSE_COUNT: usize = 600;
const SOURCE_NAMES: [&'static str; 1] = ["Source 1"];
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let mut snd_threads = Vec::new();
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(SOURCE_NAMES[i], ip).unwrap();
src.set_is_sending_discovery(false);
let mut universes: Vec<u16> = Vec::new();
for j in 0 .. UNIVERSE_COUNT {
universes.push(((i + j) as u16) + BASE_UNIVERSE);
}
src.register_universes(&universes).unwrap();
src.set_is_sending_discovery(true);
tx.send(()).unwrap(); }));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
loop {
let result = dmx_recv.recv(Some(Duration::from_secs(2)));
match result {
Err(e) => {
match e {
SacnError::Io(ref s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock => {
},
std::io::ErrorKind::TimedOut => {},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
Ok(_) => {
assert!(false, "No data should have been passed up!");
}
}
let discovered = dmx_recv.get_discovered_sources();
if discovered.len() > 0 {
assert_eq!(discovered.len(), 1);
assert_eq!(discovered[0].name, SOURCE_NAMES[0]);
let universes = discovered[0].get_all_universes();
assert_eq!(universes.len(), UNIVERSE_COUNT);
for j in 0 .. UNIVERSE_COUNT {
assert_eq!(universes[j], (j as u16) + BASE_UNIVERSE);
}
break;
}
}
snd_rx.recv().unwrap();
for s in snd_threads {
s.join().unwrap();
}
}
#[test]
#[ignore]
fn test_universe_discovery_no_universes_ipv4(){
const SND_THREADS: usize = 1;
const SOURCE_NAMES: [&'static str; 1] = ["Source 1"];
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let mut snd_threads = Vec::new();
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
tx.send(()).unwrap();
let mut src = SacnSource::with_ip(SOURCE_NAMES[i], ip).unwrap();
src.set_is_sending_discovery(true);
tx.send(()).unwrap(); }));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.set_announce_source_discovery(true);
snd_rx.recv().unwrap();
match dmx_recv.recv(None) {
Err(e) => {
match e {
SacnError::SourceDiscovered(src_name) => {
assert_eq!(src_name, SOURCE_NAMES[0], "Name of source discovered doesn't match expected");
let sources = dmx_recv.get_discovered_sources();
assert_eq!(sources.len(), 1, "Number of sources discovered doesn't match expected (1)");
assert_eq!(sources[0].get_all_universes(), Vec::new(), "Number of universes on source is greater than expected (0)");
}
k => {
assert!(false, "Unexpected error kind, {:?}", k);
}
}
}
Ok(d) => {
assert!(false, "No data expected, {:?}", d);
}
}
snd_rx.recv().unwrap(); }
#[test]
#[ignore]
fn test_receiver_sources_exceeded_3() {
const SND_THREADS: usize = 3;
const RCV_THREADS: usize = 1;
const SRC_LIMIT: Option<usize> = Some(2);
const TIMEOUT: Option<Duration> = Some(Duration::from_secs(3));
let mut snd_threads = Vec::new();
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0); let (finish_snd_tx, finish_snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
assert!(RCV_THREADS <= TEST_NETWORK_INTERFACE_IPV4.len(), "Number of test network interface ips less than number of recv threads!");
const BASE_UNIVERSE: u16 = 2;
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
let fin_tx = finish_snd_tx.clone();
let data = [1, 2, 3];
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(&format!("Source {}", i), ip).unwrap();
let priority = 100;
let universe: u16 = (i as u16) + BASE_UNIVERSE;
src.register_universe(universe).unwrap();
tx.send(()).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
fin_tx.send(()).unwrap(); }));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), SRC_LIMIT).unwrap();
for i in (BASE_UNIVERSE as u16) .. ((SND_THREADS as u16) + (BASE_UNIVERSE as u16)) {
dmx_recv.listen_universes(&[i]).unwrap();
}
for _ in 0 .. SND_THREADS {
snd_rx.recv().unwrap(); }
dmx_recv.recv(TIMEOUT).unwrap();
dmx_recv.recv(TIMEOUT).unwrap();
match dmx_recv.recv(TIMEOUT) {
Err(e) => {
match e {
SacnError::SourcesExceededError(_) => {
assert!(true, "Expected error returned");
}
_ => {
assert!(false, "Unexpected error type returned");
}
}
}
Ok(_) => {
assert!(false, "Recv was successful even though source limit was exceeded");
}
}
for _ in 0 .. SND_THREADS {
finish_snd_rx.recv().unwrap();
}
for _ in 0 .. SND_THREADS {
snd_threads.pop().unwrap().join().unwrap();
}
}
#[test]
#[ignore]
fn test_receiver_source_limit_2() {
const SND_THREADS: usize = 2;
const RCV_THREADS: usize = 1;
const SRC_LIMIT: Option<usize> = Some(2);
let mut snd_threads = Vec::new();
let (snd_tx, snd_rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
assert!(RCV_THREADS <= TEST_NETWORK_INTERFACE_IPV4.len(), "Number of test network interface ips less than number of recv threads!");
const BASE_UNIVERSE: u16 = 2;
for i in 0 .. SND_THREADS {
let tx = snd_tx.clone();
let data = [1, 2, 3];
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(&format!("Source {}", i), ip).unwrap();
let priority = 100;
let universe: u16 = (i as u16) + BASE_UNIVERSE;
src.register_universe(universe).unwrap();
tx.send(()).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
}));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), SRC_LIMIT).unwrap();
for i in (BASE_UNIVERSE as u16) .. ((SND_THREADS as u16) + (BASE_UNIVERSE as u16)) {
dmx_recv.listen_universes(&[i]).unwrap();
}
for _i in 0 .. SND_THREADS {
snd_rx.recv().unwrap(); }
dmx_recv.recv(None).unwrap();
dmx_recv.recv(None).unwrap();
dmx_recv.recv(None).unwrap();
dmx_recv.recv(None).unwrap();
}
#[test]
#[ignore]
fn test_receiver_source_limit_2_termination_check() {
const SND_THREADS: usize = 2;
const SRC_LIMIT: Option<usize> = Some(2);
const RECV_TIMEOUT: Option<Duration> = Some(Duration::from_secs(5));
let mut snd_threads = Vec::new();
let sender_channels: [(SyncSender<()>, Receiver<()>); SND_THREADS] = array::from_fn(|_| mpsc::sync_channel(0));
const BASE_UNIVERSE: u16 = 2;
for i in 0 .. SND_THREADS {
let tx = sender_channels[i].0.clone();
let data = [1, 2, 3];
snd_threads.push(thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (i as u16));
let mut src = SacnSource::with_ip(&format!("Source {}", i), ip).unwrap();
let priority = 100;
let universe: u16 = (i as u16) + BASE_UNIVERSE;
src.register_universe(universe).unwrap();
tx.send(()).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
src.send(&[universe], &data, Some(priority), None, None).unwrap();
if i == 0 { tx.send(()).unwrap();
}
}));
}
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT), SRC_LIMIT).unwrap();
for i in (BASE_UNIVERSE as u16) .. ((SND_THREADS as u16) + (BASE_UNIVERSE as u16)) {
dmx_recv.listen_universes(&[i]).unwrap();
}
for (_, snd_rx) in &sender_channels {
snd_rx.recv().unwrap();
}
dmx_recv.recv(RECV_TIMEOUT).expect("dmx_recv.recv() #1 failed.");
dmx_recv.recv(RECV_TIMEOUT).expect("dmx_recv.recv() #2 failed.");
dmx_recv.recv(RECV_TIMEOUT).expect("dmx_recv.recv() #3 failed.");
dmx_recv.recv(RECV_TIMEOUT).expect("dmx_recv.recv() #4 failed.");
let second_thread = snd_threads.remove(1);
second_thread.join().unwrap();
let data = [1, 2, 3];
let new_src_thread = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1 + (3 as u16));
let mut src = SacnSource::with_ip(&format!("Source {}", 3), ip).unwrap();
src.register_universe(BASE_UNIVERSE).unwrap();
src.send(&[BASE_UNIVERSE], &data, None, None, None).unwrap();
src.send(&[BASE_UNIVERSE], &data, None, None, None).unwrap();
});
dmx_recv.recv(RECV_TIMEOUT).expect("dmx_recv.recv() #5 failed.");
dmx_recv.recv(RECV_TIMEOUT).expect("dmx_recv.recv() #6 failed.");
sender_channels[0].1.recv().unwrap();
let first_thread = snd_threads.remove(0);
first_thread.join().unwrap();
new_src_thread.join().unwrap();
}
#[test]
#[ignore]
fn test_preview_data_2_receiver_1_sender() {
const RCV_THREADS: usize = 2;
const UNIVERSE: u16 = 1;
const NORMAL_DATA: [u8; 4] = [0, 1, 2, 3];
const PREVIEW_DATA: [u8; 4] = [9, 10, 11, 12];
const TIMEOUT: Option<Duration> = Some(Duration::from_secs(3));
let mut rcv_threads = Vec::new();
let (rcv_tx, rcv_rx): (SyncSender<Result<Vec<DMXData>>>, Receiver<Result<Vec<DMXData>>>) = mpsc::sync_channel(0);
assert!(RCV_THREADS <= TEST_NETWORK_INTERFACE_IPV4.len(), "Number of test network interface ips less than number of recv threads!");
for i in 0 .. RCV_THREADS {
let tx = rcv_tx.clone();
rcv_threads.push(thread::spawn(move || {
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[i].parse().unwrap()), ACN_SDT_MULTICAST_PORT), None).unwrap();
if i == 0 {
dmx_recv.set_process_preview_data(true); }
dmx_recv.listen_universes(&[UNIVERSE]).unwrap();
tx.send(Ok(Vec::new())).unwrap();
let result = dmx_recv.recv(None).unwrap();
assert_eq!(result.len(), 1);
let data = &result[0];
assert_eq!(data.universe, UNIVERSE);
assert_eq!(data.values, NORMAL_DATA);
assert_eq!(data.preview, false);
if i == 0 {
let preview_result = dmx_recv.recv(None).unwrap();
assert_eq!(preview_result.len(), 1);
let preview_data = &preview_result[0];
assert_eq!(preview_data.universe, UNIVERSE);
assert_eq!(preview_data.values, PREVIEW_DATA);
assert_eq!(preview_data.preview, true);
} else {
match dmx_recv.recv(TIMEOUT) {
Err(e) => {
match e {
SacnError::Io(ref s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock => {
},
std::io::ErrorKind::TimedOut => {},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
Ok(_) => {
assert!(false, "Non-preview receiver received preview data");
}
}
}
}));
}
for _ in 0 .. RCV_THREADS {
rcv_rx.recv().unwrap().unwrap();
}
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
src.register_universe(UNIVERSE).unwrap();
src.send(&[UNIVERSE], &NORMAL_DATA, None, None, None).unwrap();
src.set_preview_mode(true).unwrap();
src.send(&[UNIVERSE], &PREVIEW_DATA, None, None, None).unwrap();
for r in rcv_threads {
r.join().unwrap();
}
}
#[test]
#[ignore]
fn test_source_1_universe_timeout(){
let acceptable_lower_bound: Duration = E131_NETWORK_DATA_LOSS_TIMEOUT - Duration::from_millis(50);
let acceptable_upper_bound: Duration = 2 * E131_NETWORK_DATA_LOSS_TIMEOUT + Duration::from_millis(50);
let (tx, rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let thread_tx = tx.clone();
let universe = 1;
let snd_thread = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universe(universe).unwrap();
let dst_ip: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT);
thread_tx.send(()).unwrap();
src.send(&[universe], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
thread_tx.send(()).unwrap();
});
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe]).unwrap();
dmx_recv.set_announce_timeout(true);
rx.recv().unwrap();
let received_data: Vec<DMXData> = dmx_recv.recv(None).unwrap();
assert_eq!(received_data.len(), 1); assert_eq!(received_data[0].universe, universe); assert_eq!(received_data[0].values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
let start_time: Instant = Instant::now();
match dmx_recv.recv(Some(acceptable_upper_bound)) { Err(e) => {
match e {
SacnError::UniverseTimeout(_src_cid, timedout_uni) => {
if start_time.elapsed() < acceptable_lower_bound{
assert!(false, "Timeout came quicker than expected");
}
assert_eq!(timedout_uni, universe, "Timed out universe doesn't match expected");
assert!(true, "Universe timed out as expected");
}
SacnError::Io(s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut => {
assert!(false, "Timeout took too long to come through");
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
}
Ok(x) => {
assert!(false, "Data received unexpectedly as none sent! {:?}", x);
}
}
rx.recv().unwrap(); snd_thread.join().unwrap();
}
#[test]
#[ignore]
fn test_source_2_universe_1_timeout(){
let acceptable_lower_bound: Duration = E131_NETWORK_DATA_LOSS_TIMEOUT - Duration::from_millis(50);
let acceptable_upper_bound: Duration = 2 * E131_NETWORK_DATA_LOSS_TIMEOUT + Duration::from_millis(50);
let (tx, rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let thread_tx = tx.clone();
let universe_no_timeout = 1;
let universe_timeout = 2;
let snd_thread = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universes(&[universe_no_timeout, universe_timeout]).unwrap();
let dst_ip: SocketAddr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT);
thread_tx.send(()).unwrap();
src.send(&[universe_no_timeout], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
src.send(&[universe_timeout], &TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
sleep(Duration::from_secs(1));
src.send(&[universe_no_timeout], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
sleep(Duration::from_secs(1));
src.send(&[universe_no_timeout], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
sleep(Duration::from_secs(1));
src.send(&[universe_no_timeout], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
sleep(Duration::from_secs(1));
src.send(&[universe_no_timeout], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
thread_tx.send(()).unwrap();
});
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(Ipv4Addr::LOCALHOST.into(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[universe_no_timeout, universe_timeout]).unwrap();
dmx_recv.set_announce_timeout(true);
rx.recv().unwrap();
let received_data: Vec<DMXData> = dmx_recv.recv(None).unwrap();
assert_eq!(received_data.len(), 1);
if received_data[0].universe == universe_no_timeout {
assert_eq!(received_data[0].values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
let received_data: Vec<DMXData> = dmx_recv.recv(None).unwrap();
assert_eq!(received_data.len(), 1); if received_data[0].universe == universe_timeout {
assert_eq!(received_data[0].values, TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
} else {
assert!(false, "Data packet from unexpected universe received");
}
} else if received_data[0].universe == universe_timeout {
assert_eq!(received_data[0].values, TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
let received_data: Vec<DMXData> = dmx_recv.recv(None).unwrap();
assert_eq!(received_data.len(), 1); if received_data[0].universe == universe_no_timeout {
assert_eq!(received_data[0].values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Received payload values don't match sent!");
} else {
assert!(false, "Data packet from unexpected universe received");
}
} else {
assert!(false, "Data packet from unexpected universe received");
}
let start_time: Instant = Instant::now();
loop { match dmx_recv.recv(Some(acceptable_upper_bound)) { Err(e) => {
match e {
SacnError::UniverseTimeout(_src_cid, universe) => {
if start_time.elapsed() < acceptable_lower_bound{
assert!(false, "Timeout came quicker than expected");
}
assert_eq!(universe, universe_timeout, "Unexpected universe timed out");
assert!(true, "Universe timed out as expected");
match dmx_recv.recv(Some(Duration::from_millis(0))) {
Err(e) => {
match e {
SacnError::Io(s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut => {
assert!(true, "Other universe hasn't timedout as expected");
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
}
Ok(x) => {
assert!(false, "Data received unexpectedly as none sent! {:?}", x);
}
}
break;
}
SacnError::Io(s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut => {
assert!(false, "Timeout took too long to come through: {:?}", start_time.elapsed());
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
}
Ok(p) => { assert_eq!(p.len(), 1, "Data packet universe count doesn't match expected");
assert_eq!(p[0].universe, universe_no_timeout, "Data packet universe doesn't match expected");
assert_eq!(p[0].values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Data packet values don't match expected");
}
}
}
rx.recv().unwrap(); snd_thread.join().unwrap();
}
#[test]
#[ignore]
fn test_send_recv_wrong_multicast_universe(){
const TIMEOUT: Option<Duration> = Some(Duration::from_secs(3));
let (tx, rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let thread_tx = tx.clone();
let multicast_universe = 1;
let actual_universe = 2;
let snd_thread = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap(), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
let priority = 100;
src.register_universes(&[multicast_universe, actual_universe]).unwrap();
let dst_ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(239, 255, 0, 1)), ACN_SDT_MULTICAST_PORT);
thread_tx.send(()).unwrap();
src.send(&[actual_universe], &TEST_DATA_SINGLE_UNIVERSE, Some(priority), Some(dst_ip), None).unwrap();
});
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[multicast_universe, actual_universe]).unwrap();
rx.recv().unwrap();
let received_data: Vec<DMXData> = dmx_recv.recv(TIMEOUT).unwrap();
assert_eq!(received_data.len(), 1, "Data packet universe count doesn't match expected");
assert_eq!(received_data[0].universe, actual_universe, "Packet universe doesn't match expected");
assert_eq!(received_data[0].values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Data packet values don't match expected");
snd_thread.join().unwrap();
}
#[test]
#[ignore]
fn test_send_recv_multiple_sync_universes(){
const TIMEOUT: Option<Duration> = Some(Duration::from_secs(3));
let (tx, rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let thread_tx = tx.clone();
let universes = [1, 2, 3];
let snd_thread = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap(), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
src.register_universes(&universes).unwrap();
thread_tx.send(()).unwrap();
src.send(&[universes[0]], &TEST_DATA_SINGLE_UNIVERSE, None, None, Some(universes[1])).unwrap();
src.send(&[universes[1]], &TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE, None, None, Some(universes[2])).unwrap();
src.send(&[universes[2]], &TEST_DATA_PARTIAL_CAPACITY_UNIVERSE, None, None, Some(universes[2])).unwrap();
src.send_sync_packet(universes[1], None).unwrap(); src.send_sync_packet(universes[2], None).unwrap(); });
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&universes).unwrap();
rx.recv().unwrap();
let received_data: Vec<DMXData> = dmx_recv.recv(TIMEOUT).unwrap();
assert_eq!(received_data.len(), 1, "First set of data universe count doesn't match expected");
assert_eq!(received_data[0].universe, universes[0], "Packet universe doesn't match expected");
assert_eq!(received_data[0].values, TEST_DATA_SINGLE_UNIVERSE.to_vec(), "Data packet values don't match expected");
let received_data2: Vec<DMXData> = dmx_recv.recv(TIMEOUT).unwrap();
assert_eq!(received_data2.len(), 2, "Second set of data universe count doesn't match expected");
if received_data2[0].universe == universes[1] { assert_eq!(received_data2[0].values, TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE.to_vec(), "Second set of data part 1 packet values don't match expected");
assert_eq!(received_data2[1].universe, universes[2], "Second set of data universes don't match expected");
assert_eq!(received_data2[1].values, TEST_DATA_PARTIAL_CAPACITY_UNIVERSE.to_vec(), "Second set of data part 2 packet values don't match expected");
} else if received_data2[0].universe == universes[2] {
assert_eq!(received_data2[0].values, TEST_DATA_PARTIAL_CAPACITY_UNIVERSE.to_vec(), "Second set of data part 1 packet values don't match expected");
assert_eq!(received_data2[1].universe, universes[1], "Second set of data universes don't match expected");
assert_eq!(received_data2[1].values, TEST_DATA_SINGLE_ALTERNATIVE_STARTCODE_UNIVERSE.to_vec(), "Second set of data part 2 packet values don't match expected");
} else {
assert!(false, "Unexpected universe of data received");
}
snd_thread.join().unwrap();
}
#[test]
#[ignore]
fn test_send_sync_timeout(){
const TIMEOUT: Option<Duration> = Some(Duration::from_secs(5));
let sender_wait_period: Duration = E131_NETWORK_DATA_LOSS_TIMEOUT + Duration::from_millis(100);
let (tx, rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let thread_tx = tx.clone();
let data_universe = 1;
let sync_universe = 2;
let snd_thread = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap(), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_ip("Source", ip).unwrap();
src.register_universes(&[data_universe, sync_universe]).unwrap();
thread_tx.send(()).unwrap();
src.send(&[data_universe], &TEST_DATA_SINGLE_UNIVERSE, None, None, Some(sync_universe)).unwrap();
sleep(sender_wait_period);
src.send_sync_packet(sync_universe, None).unwrap();
});
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&[data_universe, sync_universe]).unwrap();
rx.recv().unwrap();
match dmx_recv.recv(TIMEOUT) {
Err(e) => {
match e {
SacnError::Io(s) => {
match s.kind() {
std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut => {
assert!(true, "Timed out as expected meaning synchronised data packet timed out as expected");
},
_ => {
assert!(false, "Unexpected error returned");
}
}
},
_ => {
assert!(false, "Unexpected error returned");
}
}
}
Ok(p) => {
assert!(false, "Received data unexpectedly: {:?}", p);
}
}
snd_thread.join().unwrap();
}
#[test]
#[ignore]
fn test_ansi_e131_appendix_b_runthrough_ipv4() {
const SYNC_PACKET_COUNT: usize = 5;
const DATA_PACKETS_PER_SYNC_PACKET: usize = 2;
const PAUSE_PERIOD: Duration = Duration::from_millis(100);
let (tx, rx): (SyncSender<()>, Receiver<()>) = mpsc::sync_channel(0);
let thread_tx = tx.clone();
let data_universes = [1, 2];
let sync_universe = 7962;
let priority = 100;
let source_name = "Source_A";
let data = [0x00, 0xe, 0x0, 0xc, 0x1, 0x7, 0x1, 0x4, 0x8, 0x0, 0xd, 0xa, 0x7, 0xa];
let data2 = [0x00, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xa];
let src_cid: Uuid = Uuid::from_bytes([0xef, 0x07, 0xc8, 0xdd, 0x00, 0x64, 0x44, 0x01, 0xa3, 0xa2, 0x45, 0x9e, 0xf8, 0xe6, 0x14, 0x3e].try_into().unwrap());
let snd_thread = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap(), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_cid_ip(source_name, src_cid, ip).unwrap();
src.register_universes(&data_universes).unwrap();
src.register_universe(sync_universe).unwrap();
thread_tx.send(()).unwrap();
for _ in 0 .. SYNC_PACKET_COUNT {
src.send(&[data_universes[0]], &data, Some(priority), None, Some(sync_universe)).unwrap();
src.send(&[data_universes[1]], &data2, Some(priority), None, Some(sync_universe)).unwrap();
sleep(PAUSE_PERIOD);
src.send_sync_packet(sync_universe, None).unwrap();
}
src.send(&[data_universes[0]], &data, Some(priority), None, None).unwrap();
src.send(&[data_universes[1]], &data2, Some(priority), None, None).unwrap();
});
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.listen_universes(&data_universes).unwrap();
rx.recv().unwrap();
for _ in 0 .. SYNC_PACKET_COUNT {
match dmx_recv.recv(None) {
Ok(p) => {
assert_eq!(p.len(), DATA_PACKETS_PER_SYNC_PACKET);
if p[0].universe == data_universes[0] {
assert_eq!(p[0].values, data, "Unexpected data within first data packet of a set of synchronised packets");
assert_eq!(p[1].universe, data_universes[1], "Unrecognised universe as second data packet in set of synchronised packets");
assert_eq!(p[1].values, data2, "Unexpected data within second data packet of a set of synchronised packets");
} else if p[0].universe == data_universes[1] {
assert_eq!(p[0].values, data2, "Unexpected data within first data packet of a set of synchronised packets");
assert_eq!(p[1].universe, data_universes[0], "Unrecognised universe as second data packet in set of synchronised packets");
assert_eq!(p[1].values, data, "Unexpected data within second data packet of a set of synchronised packets");
} else {
assert!(false, "Unrecognised universe within data packet");
}
}
Err(e) => {
assert!(false, "Unexpected error returned: {:?}", e);
}
}
}
let rcv_data = dmx_recv.recv(None).unwrap();
assert_eq!(rcv_data.len(), 1);
assert_eq!(rcv_data[0].universe, data_universes[0]);
assert_eq!(rcv_data[0].values, data);
let rcv_data2 = dmx_recv.recv(None).unwrap();
assert_eq!(rcv_data2.len(), 1);
assert_eq!(rcv_data2[0].universe, data_universes[1]);
assert_eq!(rcv_data2[0].values, data2);
snd_thread.join().unwrap();
}
#[test]
#[ignore]
fn test_discover_recv_sync_runthrough_ipv4() {
const SYNC_PACKET_COUNT: usize = 250;
const DATA_PACKETS_PER_SYNC_PACKET: usize = 2;
const PAUSE_PERIOD: Duration = Duration::from_millis(50);
const INTERVAL: Duration = Duration::from_millis(100);
const DATA_UNIVERSES: [u16; 2] = [1, 2];
const SYNC_UNIVERSE: u16 = 4;
const SOURCE_NAME: &str = "Test Source";
const DATA: [u8; 16] = [0x00, 0xe, 0x0, 0xc, 0x1, 0x7, 0x1, 0x4, 0x8, 0x0, 0xd, 0xa, 0x7, 0xa, 0x9, 0x8];
const DATA2: [u8; 16] =[0x00, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xa, 0x9, 0x8];
let src_cid: Uuid = Uuid::from_bytes([0xef, 0x07, 0xc8, 0xdd, 0x00, 0x64, 0x44, 0x01, 0xa3, 0xa2, 0x45, 0x9e, 0xf8, 0xe6, 0x14, 0x3e].try_into().unwrap());
let snd_thread = thread::spawn(move || {
let ip: SocketAddr = SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap(), ACN_SDT_MULTICAST_PORT + 1);
let mut src = SacnSource::with_cid_ip(SOURCE_NAME, src_cid, ip).unwrap();
src.register_universes(&DATA_UNIVERSES).unwrap();
src.register_universe(SYNC_UNIVERSE).unwrap();
for _ in 0 .. SYNC_PACKET_COUNT {
src.send(&[DATA_UNIVERSES[0]], &DATA, None, None, Some(SYNC_UNIVERSE)).unwrap();
src.send(&[DATA_UNIVERSES[1]], &DATA2, None, None, Some(SYNC_UNIVERSE)).unwrap();
sleep(PAUSE_PERIOD);
src.send_sync_packet(SYNC_UNIVERSE, None).unwrap();
sleep(INTERVAL);
}
});
let mut dmx_recv = SacnReceiver::with_ip(SocketAddr::new(TEST_NETWORK_INTERFACE_IPV4[1].parse().unwrap(), ACN_SDT_MULTICAST_PORT), None).unwrap();
dmx_recv.set_announce_source_discovery(true);
let universes: Vec<u16> = match dmx_recv.recv(None) {
Err(e) => {
match e {
SacnError::SourceDiscovered(_name) => {
let discovered_sources = dmx_recv.get_discovered_sources();
assert_eq!(discovered_sources.len(), 1);
dmx_recv.set_announce_source_discovery(false);
dmx_recv.set_announce_stream_termination(true);
discovered_sources[0].get_all_universes()
}
_ => {
panic!("Unexpected error");
}
}
}
Ok(_) => {
panic!("Unexpected data packet before any data universes registered");
}
};
dmx_recv.listen_universes(&universes).unwrap();
loop {
match dmx_recv.recv(None) {
Err(e) => {
match e {
SacnError::UniverseTerminated(_src_cid, _universe) => {
break;
}
_ => {
assert!(false, "Unexpected error returned");
}
}
}
Ok(rcv_data) => {
assert_eq!(rcv_data.len(), DATA_PACKETS_PER_SYNC_PACKET);
if rcv_data[0].universe == DATA_UNIVERSES[0] {
assert_eq!(rcv_data[0].values, DATA, "Unexpected data within first data packet of a set of synchronised packets");
assert_eq!(rcv_data[1].universe, DATA_UNIVERSES[1], "Unrecognised universe as second data packet in set of synchronised packets");
assert_eq!(rcv_data[1].values, DATA2, "Unexpected data within second data packet of a set of synchronised packets");
} else if rcv_data[0].universe == DATA_UNIVERSES[1] {
assert_eq!(rcv_data[0].values, DATA2, "Unexpected data within first data packet of a set of synchronised packets");
assert_eq!(rcv_data[1].universe, DATA_UNIVERSES[0], "Unrecognised universe as second data packet in set of synchronised packets");
assert_eq!(rcv_data[1].values, DATA, "Unexpected data within second data packet of a set of synchronised packets");
} else {
assert!(false, "Unrecognised universe within data packet");
}
}
}
}
snd_thread.join().unwrap();
}
fn generate_data_packet_raw(cid: [u8; 16], universe: u16, source_name: String, priority: u8, seq_num: u8, options: u8, dmx_data: Vec<u8>) -> Vec<u8> {
assert!(universe >= E131_MIN_MULTICAST_UNIVERSE && universe <= E131_MAX_MULTICAST_UNIVERSE, "Generated data packet universe out of range");
assert!(priority <= E131_MAX_PRIORITY, "Generated data packet priority too high");
assert!(dmx_data.len() <= UNIVERSE_CHANNEL_CAPACITY);
assert_eq!(source_name.len(), 64);
let mut packet = Vec::new();
packet.extend("\x00\x10".bytes());
packet.extend("\x00\x00".bytes());
packet.extend("\x41\x53\x43\x2d\x45\x31\x2e\x31\x37\x00\x00\x00".bytes());
packet.push(0b01110001);
packet.push(0b01101101);
packet.extend("\x00\x00\x00\x04".bytes());
packet.extend(&cid);
packet.push(0b01110001);
packet.push(0b01010111);
packet.extend("\x00\x00\x00\x02".bytes());
packet.extend(source_name.bytes());
packet.push(priority);
packet.extend("\x00\x00".bytes());
packet.push(seq_num);
packet.push(options);
let universe_bytes = universe.to_be_bytes();
packet.push(universe_bytes[0]);
packet.push(universe_bytes[1]);
packet.push(0b01110001);
packet.push(0b00001010);
packet.push(0x02);
packet.push(0xa1);
packet.extend("\x00\x00".bytes());
packet.extend("\x00\x01".bytes());
packet.push(0b1);
packet.push(0b00000000);
packet.extend(&dmx_data);
packet
}
fn generate_sync_packet_raw(cid: [u8; 16], sync_addr: u16, seq_num: u8) -> Vec<u8> {
let mut sync_packet = Vec::new();
sync_packet.extend("\x00\x10".bytes());
sync_packet.extend("\x00\x00".bytes());
sync_packet.extend("\x41\x53\x43\x2d\x45\x31\x2e\x31\x37\x00\x00\x00".bytes());
sync_packet.push(0b01110000);
sync_packet.push(0b00100001);
sync_packet.extend("\x00\x00\x00\x08".bytes());
sync_packet.extend(&cid);
sync_packet.push(0b01110000);
sync_packet.push(0b00001011);
sync_packet.extend("\x00\x00\x00\x01".bytes());
sync_packet.push(seq_num);
let sync_addr_bytes = sync_addr.to_be_bytes();
sync_packet.push(sync_addr_bytes[0]);
sync_packet.push(sync_addr_bytes[1]);
sync_packet.push(0);
sync_packet.push(0);
sync_packet
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
#[ignore]
fn test_data_packet_transmit_format() {
const CID: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const OPTIONS: u8 = 0; const PRIORITY: u8 = 150;
let universe: u16 = 1;
let source_name = "SourceName".to_string() +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0";
let sequence = 0;
let mut dmx_data: Vec<u8> = Vec::new();
dmx_data.push(0); dmx_data.extend(iter::repeat(100).take(255));
let packet = generate_data_packet_raw(CID, universe, source_name.clone(), PRIORITY, sequence, OPTIONS, dmx_data.clone());
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), ACN_SDT_MULTICAST_PORT + 1);
let mut source = SacnSource::with_cid_ip(&source_name.clone(), Uuid::from_bytes(CID), ip).unwrap();
source.set_preview_mode(false).unwrap();
source.set_multicast_loop_v4(true).unwrap();
let mut recv_socket = Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap();
let addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT);
recv_socket.bind(&addr.into()).unwrap();
recv_socket.join_multicast_v4(&Ipv4Addr::new(239, 255, 0, 1), &Ipv4Addr::new(0, 0, 0, 0))
.unwrap();
let mut recv_buf = [0; 1024];
source.register_universes(&[universe]).unwrap();
source.send(&[universe], &dmx_data, Some(PRIORITY), None, None).unwrap();
let amt = recv_socket.read(&mut recv_buf).unwrap();
assert_eq!(&packet[..], &recv_buf[0..amt]);
}
#[test]
#[ignore]
fn test_terminate_packet_transmit_format() {
let cid = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT + 1);
let mut source = SacnSource::with_cid_ip(&"Source", Uuid::from_bytes(cid), ip).unwrap();
source.set_multicast_loop_v4(true).unwrap();
let mut recv_socket = Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap();
let addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT);
recv_socket.bind(&addr.into()).unwrap();
recv_socket
.join_multicast_v4(&Ipv4Addr::new(239, 255, 0, 1), &Ipv4Addr::new(0, 0, 0, 0))
.unwrap();
let mut recv_buf = [0; 1024];
let start_code: u8 = 0;
source.register_universes(&[1]).unwrap();
source.terminate_stream(1, start_code).unwrap();
for _ in 0..2 {
recv_socket.read(&mut recv_buf).unwrap();
assert_eq!(
match AcnRootLayerProtocol::parse(&recv_buf).unwrap().pdu.data {
E131RootLayerData::DataPacket(data) => data.stream_terminated,
_ => panic!(),
},
true
)
}
}
#[test]
#[ignore]
fn test_sync_packet_transmit_format() {
const CID: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const SYNC_ADDR: u16 = 1;
const E131_SYNC_PACKET_LENGTH: usize = 49;
const SEQUENCE_NUM: u8 = 0;
let sync_packet = generate_sync_packet_raw(CID, SYNC_ADDR, SEQUENCE_NUM);
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT + 1);
let mut source = SacnSource::with_cid_ip(&"Source", Uuid::from_bytes(CID), ip).unwrap();
source.set_multicast_loop_v4(true).unwrap();
let mut recv_socket = Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap();
let addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT);
recv_socket.bind(&addr.into()).unwrap();
recv_socket
.join_multicast_v4(&Ipv4Addr::new(239, 255, 0, 1), &Ipv4Addr::new(0, 0, 0, 0))
.unwrap();
let mut recv_buf = [0; E131_SYNC_PACKET_LENGTH];
source.register_universes(&[SYNC_ADDR]).unwrap();
source.send_sync_packet(SYNC_ADDR, None).unwrap();
recv_socket.read(&mut recv_buf).unwrap();
assert_eq!(recv_buf[..], sync_packet[..], "Sync packet sent by source doesn't match expected format");
}
#[test]
#[ignore]
fn test_discovery_packet_transmit_format() {
const CID: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const SOURCE_NAME: [u8; 64] = [b'C', b'o', b'n', b't', b'r', b'o', b'l', b'l', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0];
const UNIVERSES: [u8; 6] = [0x0, 0x1 , 0x0, 0x2, 0x0, 0x3];
const DISCOVERY_PACKET_LENGTH_EXPECTED: usize = 120 + UNIVERSES.len();
const PAGE: u8 = 0;
const LAST_PAGE: u8 = 0;
let mut discovery_packet = Vec::new();
discovery_packet.extend("\x00\x10".bytes());
discovery_packet.extend("\x00\x00".bytes());
discovery_packet.extend("\x41\x53\x43\x2d\x45\x31\x2e\x31\x37\x00\x00\x00".bytes());
discovery_packet.push(0b01110000);
discovery_packet.push(0b01101110);
discovery_packet.extend("\x00\x00\x00\x08".bytes());
discovery_packet.extend(&CID);
discovery_packet.push(0b01110000);
discovery_packet.push(0b01011000);
discovery_packet.extend("\x00\x00\x00\x02".bytes());
discovery_packet.extend(SOURCE_NAME.iter());
discovery_packet.push(0);
discovery_packet.push(0);
discovery_packet.push(0);
discovery_packet.push(0);
discovery_packet.push(0b01110000);
discovery_packet.push(0b00001110);
discovery_packet.extend("\x00\x00\x00\x01".bytes());
discovery_packet.push(PAGE);
discovery_packet.push(LAST_PAGE);
discovery_packet.extend(UNIVERSES.iter());
assert_eq!(discovery_packet.len(), DISCOVERY_PACKET_LENGTH_EXPECTED, "Example discovery packet length doesn't match expected");
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT + 1);
let mut source = SacnSource::with_cid_ip(&str::from_utf8(&SOURCE_NAME).unwrap(), Uuid::from_bytes(CID), ip).unwrap();
source.set_multicast_loop_v4(true).unwrap();
let mut recv_socket = Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap();
let addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT);
recv_socket.bind(&addr.into()).unwrap();
let address = universe_to_ipv4_multicast_addr(E131_DISCOVERY_UNIVERSE).unwrap().as_socket_ipv4();
recv_socket
.join_multicast_v4(&address.unwrap().ip(), &Ipv4Addr::new(0, 0, 0, 0))
.unwrap();
let mut recv_buf = [0; DISCOVERY_PACKET_LENGTH_EXPECTED];
source.register_universes(&[
u16::from_be_bytes(UNIVERSES[0..2].try_into().unwrap()),
u16::from_be_bytes(UNIVERSES[2..4].try_into().unwrap()),
u16::from_be_bytes(UNIVERSES[4..6].try_into().unwrap())
]).unwrap();
recv_socket.read(&mut recv_buf).unwrap();
assert_eq!(recv_buf[..], discovery_packet[..], "Discovery packet sent by source doesn't match expected format");
}
#[test]
#[ignore]
fn test_sync_packet_transmit_seq_numbers() {
const CID: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const UNIVERSE: u16 = 1;
const E131_SYNC_PACKET_LENGTH: usize = 49;
const SEQUENCE_NUM: u8 = 0;
let mut sync_packet = Vec::new();
sync_packet.extend("\x00\x10".bytes());
sync_packet.extend("\x00\x00".bytes());
sync_packet.extend("\x41\x53\x43\x2d\x45\x31\x2e\x31\x37\x00\x00\x00".bytes());
sync_packet.push(0b01110000);
sync_packet.push(0b00100001);
sync_packet.extend("\x00\x00\x00\x08".bytes());
sync_packet.extend(&CID);
sync_packet.push(0b01110000);
sync_packet.push(0b00001011);
sync_packet.extend("\x00\x00\x00\x01".bytes());
sync_packet.push(SEQUENCE_NUM);
sync_packet.push(0);
sync_packet.push(1);
sync_packet.push(0);
sync_packet.push(0);
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT + 1);
let mut source = SacnSource::with_cid_ip(&"Source", Uuid::from_bytes(CID), ip).unwrap();
source.set_multicast_loop_v4(true).unwrap();
let mut recv_socket = Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap();
let addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT);
recv_socket.bind(&addr.into()).unwrap();
recv_socket
.join_multicast_v4(&Ipv4Addr::new(239, 255, 0, 1), &Ipv4Addr::new(0, 0, 0, 0))
.unwrap();
let mut recv_buf = [0; E131_SYNC_PACKET_LENGTH];
source.register_universes(&[UNIVERSE]).unwrap();
source.send_sync_packet(UNIVERSE, None).unwrap();
recv_socket.read(&mut recv_buf).unwrap();
assert_eq!(recv_buf[..], sync_packet[..], "Sync packet sent by source doesn't match expected format");
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
#[ignore]
fn test_track_data_packet_seq_numbers() {
const CID: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const OPTIONS: u8 = 0; const PRIORITY: u8 = 150;
let source_name = "SourceName".to_string() +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0";
let mut dmx_data: Vec<u8> = Vec::new();
dmx_data.push(0); dmx_data.extend(iter::repeat(100).take(255));
const START_SEQ_NUM: usize = 0;
const DATA_PACKETS_TO_SEND: usize = 300;
const UNIVERSES: [u16; 5] = [1, 3, 5, 7, 9];
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), ACN_SDT_MULTICAST_PORT + 1);
let mut source = SacnSource::with_cid_ip(&source_name.clone(), Uuid::from_bytes(CID), ip).unwrap();
source.set_multicast_loop_v4(true).unwrap();
source.register_universes(&UNIVERSES).unwrap();
source.set_is_sending_discovery(false);
let mut recv_socket = Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap();
let addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT);
recv_socket.bind(&addr.into()).unwrap();
for u in UNIVERSES.iter() {
let address = universe_to_ipv4_multicast_addr(*u).unwrap().as_socket_ipv4();
recv_socket
.join_multicast_v4(&address.unwrap().ip(), &Ipv4Addr::new(0, 0, 0, 0))
.unwrap();
}
for s in START_SEQ_NUM .. START_SEQ_NUM + DATA_PACKETS_TO_SEND {
let expected_seq_num: u8 = (s % 256).try_into().unwrap();
for u in UNIVERSES.iter() {
let expected_packet = generate_data_packet_raw(CID, *u, source_name.clone(), PRIORITY, expected_seq_num, OPTIONS, dmx_data.clone());
source.send(&[*u], &dmx_data, Some(PRIORITY), None, None).unwrap();
let mut recv_buf = [0; 1024];
let amt = recv_socket.read(&mut recv_buf).unwrap();
assert_eq!(&recv_buf[0..amt], &expected_packet[..]);
}
}
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
#[ignore]
fn test_track_sync_packet_seq_numbers() {
const CID: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
let source_name = "SourceName".to_string() +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0";
const START_SEQ_NUM: usize = 0;
const SYNC_PACKETS_TO_SEND: usize = 300;
const SYNC_ADDRESSES: [u16; 5] = [1, 3, 5, 7, 9];
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), ACN_SDT_MULTICAST_PORT + 1);
let mut source = SacnSource::with_cid_ip(&source_name.clone(), Uuid::from_bytes(CID), ip).unwrap();
source.set_multicast_loop_v4(true).unwrap();
source.register_universes(&SYNC_ADDRESSES).unwrap();
source.set_is_sending_discovery(false);
let mut recv_socket = Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap();
let addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), ACN_SDT_MULTICAST_PORT);
recv_socket.bind(&addr.into()).unwrap();
for u in SYNC_ADDRESSES.iter() {
let address = universe_to_ipv4_multicast_addr(*u).unwrap().as_socket_ipv4();
recv_socket
.join_multicast_v4(&address.unwrap().ip(), &Ipv4Addr::new(0, 0, 0, 0))
.unwrap();
}
for s in START_SEQ_NUM .. START_SEQ_NUM + SYNC_PACKETS_TO_SEND {
let expected_seq_num: u8 = (s % 256).try_into().unwrap();
for a in SYNC_ADDRESSES.iter() {
let expected_packet = generate_sync_packet_raw(CID, *a, expected_seq_num);
source.send_sync_packet(*a, None).unwrap();
let mut recv_buf = [0; 1024];
let amt = recv_socket.read(&mut recv_buf).unwrap();
assert_eq!(&recv_buf[0..amt], &expected_packet[..]);
}
}
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
#[ignore]
#[cfg(target_os = "linux")]
fn test_sync_packet_multicast_address() {
const CID: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
let source_name = "SourceName".to_string() +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0\0\0\0\0\0\0" +
"\0\0\0\0";
const START_SEQ_NUM: usize = 0;
const SYNC_PACKETS_TO_SEND: usize = 250;
const SYNC_ADDRESSES: [u16; 3] = [1, 2, 63999];
let ip: SocketAddr = SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT + 1);
let mut source = SacnSource::with_cid_ip(&source_name.clone(), Uuid::from_bytes(CID), ip).unwrap();
source.set_multicast_loop_v4(true).unwrap();
source.register_universes(&SYNC_ADDRESSES).unwrap();
source.set_is_sending_discovery(false);
let mut recv_sockets: Vec<Socket> = Vec::new();
let mut i = 0;
for sync_addr in SYNC_ADDRESSES.iter() {
recv_sockets.push(Socket::new(Domain::IPV4, Type::DGRAM, None).unwrap());
let multicast_addr = universe_to_ipv4_multicast_addr(*sync_addr).unwrap();
recv_sockets[i].bind(&multicast_addr).unwrap();
recv_sockets[i]
.join_multicast_v4(&multicast_addr.as_socket_ipv4().unwrap().ip(), &TEST_NETWORK_INTERFACE_IPV4[i].parse().unwrap())
.unwrap();
i = i + 1;
}
for s in START_SEQ_NUM .. START_SEQ_NUM + SYNC_PACKETS_TO_SEND {
let expected_seq_num: u8 = (s % 256).try_into().unwrap();
let mut i = 0;
for sync_addr in SYNC_ADDRESSES.iter() {
let expected_packet = generate_sync_packet_raw(CID, *sync_addr, expected_seq_num);
source.send_sync_packet(*sync_addr, None).unwrap();
let mut recv_buf = [0; 1024];
let amt = recv_sockets[i].read(&mut recv_buf).unwrap();
assert_eq!(&recv_buf[0..amt], &expected_packet[..]);
i = i + 1;
}
}
}
#[test]
#[ignore]
fn test_register_terminate_universe() {
let mut src = SacnSource::with_cid_ip("Test name", Uuid::new_v4(), SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT)).unwrap();
let universe = 1;
src.register_universe(universe).unwrap();
assert_eq!(src.universes().unwrap(), vec!(1), "Universe not registered correctly");
src.terminate_stream(universe, 0).unwrap();
assert_eq!(src.universes().unwrap(), Vec::new(), "Universe not registered correctly");
}
#[test]
#[ignore]
fn test_terminate_universe_no_register() {
let mut src = SacnSource::with_cid_ip("Test name", Uuid::new_v4(), SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT)).unwrap();
let universe = 1;
match src.terminate_stream(universe, 0) {
Err(e) => {
match e {
SacnError::UniverseNotRegistered(_) => {
assert!(true, "Expected error returned");
},
_ => {
assert!(false, "Unexpected error returned");
}
}
}
_ => {
assert!(false, "Src terminated stream that wasn't registered!");
}
}
}
#[test]
#[ignore]
fn test_send_empty() {
const UNIVERSE: u16 = 1;
let mut src = SacnSource::with_cid_ip("Test name", Uuid::new_v4(), SocketAddr::new(IpAddr::V4(TEST_NETWORK_INTERFACE_IPV4[0].parse().unwrap()), ACN_SDT_MULTICAST_PORT)).unwrap();
src.register_universe(UNIVERSE).unwrap();
match src.send(&[UNIVERSE], &[], None, None, None) {
Err(e) => {
match e {
SacnError::DataArrayEmpty() => {
assert!(true, "Expected error returned");
},
_ => {
assert!(false, "Unexpected error returned");
}
}
}
_ => {
assert!(false, "Empty data accepted to send incorrectly");
}
}
}