simple_ssdp_client/
mod.rs1use std::net::{Ipv4Addr, SocketAddr, UdpSocket};
2use std::str;
3mod parser;
4
5pub struct ResponseHeaders {
6 pub server: String,
7 pub location: String,
8}
9
10fn create_socket(add: &str) -> UdpSocket {
11 match UdpSocket::bind(add) {
12 Ok(s) => return s,
13 Err(e) => panic!("couldn't bind socket: {}", e)
14 };
15}
16
17pub struct SimpleServiceDiscoveryClient {
18 socket: UdpSocket,
19}
20
21pub const SSDP_SEARCH_PAYLOAD: &'static str = "\
22 M-SEARCH * HTTP/1.1\n\
23 Host: 239.255.255.250:1900\n\
24 Man: \"ssdp:discover\"\n\
25 ST: ssdp:all\n\
26 MX: 5";
27
28impl SimpleServiceDiscoveryClient {
29
30 fn broadcast_search(&self) {
31
32 match self.socket.send_to(SSDP_SEARCH_PAYLOAD.as_bytes(), SocketAddr::from(([239, 255, 255, 250], 1900))) {
33 Ok(_) => {
34}
36
37 Err(error) => {
38 println!("woops {}", error)
39 }
40 }
41 }
42
43 fn join_multicast_v4(&self, multiaddr: &Ipv4Addr) {
44 self.socket.join_multicast_v4(multiaddr, &Ipv4Addr::new(0, 0, 0, 0)).expect("to join multicast");
45 }
46
47
48 fn listen(&self, mut f: impl FnMut(&ResponseHeaders)) {
49
50 let mut buf = [0; 9000];
51 loop {
52 match self.socket.recv_from(&mut buf) {
53 Ok((_smt, _src)) => {
54 let body = str::from_utf8(&buf).unwrap_or("").trim();
55
56 let lines = body.split("\r\n");
57 let mut server= String::new();
58 let mut location= String::new();
59 for line in lines {
60 match parser::extract(line, "Server: ") {
61 Some(result) => {
62 server = result
63 }
64 None => {}
65 }
66 match parser::extract(line, "Location: ") {
67 Some(result) => {
68 location = result
69 }
70 None => {}
71 }
72 }
73 let response_headers = ResponseHeaders {server, location };
74 f(&response_headers);
75
76 },
77 Err(e) => {
78 println!("couldn't recieve a datagram: {}", e);
79 }
80 }
81 }
82 }
83}
84
85pub fn create_client() -> SimpleServiceDiscoveryClient {
86 let client = SimpleServiceDiscoveryClient {
87 socket: create_socket("0.0.0.0:1900")
88 };
89 return client;
90}
91
92pub fn listen(f: impl FnMut(&ResponseHeaders)) {
93 let client = create_client();
94 client.broadcast_search();
95 client.join_multicast_v4(&Ipv4Addr::new(239, 255, 255, 250));
96 client.listen(f);
97}