use serde::{Deserialize, Serialize};
use std::io;
use std::net::UdpSocket;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MagicPacket {
pub mac: String,
pub ip: Option<String>,
pub port: Option<i32>,
pub title: Option<String>,
pub r#type: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MagicPacketSend {
is_send: bool,
magic_packet: MagicPacket,
}
impl MagicPacket {
fn create_magic_packet(mac: &str) -> io::Result<Vec<u8>> {
let mut packet = Vec::new();
packet.extend([0xFF; 6]);
let mac_bytes = mac
.split(':')
.map(|byte| u8::from_str_radix(byte, 16))
.collect::<Result<Vec<u8>, _>>()
.unwrap();
for _ in 0..16 {
packet.extend(&mac_bytes);
}
Ok(packet)
}
pub async fn send(&self) -> MagicPacketSend {
let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
socket.set_broadcast(true).unwrap();
let broadcast_address = format!(
"{}:{}",
self.ip.clone().unwrap_or("255.255.255.255".to_string()),
self.port.unwrap_or(9)
);
let magic_packet = Self::create_magic_packet(&self.mac).unwrap();
socket.send_to(&magic_packet, broadcast_address).unwrap();
MagicPacketSend {
is_send: true,
magic_packet: self.clone(),
}
}
}