diff --git a/README.md b/README.md index 14cb4d6..f61544f 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,15 @@ use futures::prelude::*; use std::time::Duration; use ssdp_client::SearchTarget; -let search_target = SearchTarget::RootDevice; -let mut responses = ssdp_client::search(&search_target, Duration::from_secs(3), 2, None).await?; - -while let Some(response) = responses.next().await { - println!("{:?}", response?); +#[tokio::main] +async fn mian() { + let search_target = SearchTarget::RootDevice; + let bind_addr = ([192, 168, 1, 10], 1900).into(); + let mut responses = ssdp_client::search(&search_target, Duration::from_secs(3), 2, None, bind_addr).await?; + + while let Some(response) = responses.next().await { + println!("{:?}", response?); + } } ``` diff --git a/examples/search.rs b/examples/search.rs index fab55f6..c29ee19 100644 --- a/examples/search.rs +++ b/examples/search.rs @@ -1,12 +1,22 @@ use futures::prelude::*; use ssdp_client::URN; use std::time::Duration; +use std::net::{SocketAddrV6, Ipv6Addr}; #[tokio::main] async fn main() -> Result<(), ssdp_client::Error> { let search_target = URN::device("schemas-upnp-org", "ZonePlayer", 1).into(); - let timeout = Duration::from_secs(3); - let mut responses = ssdp_client::search(&search_target, timeout, 2, None).await?; + let timeout = Duration::from_secs(10); + // ipv4 + // let bind_addr = ([192, 168, 1, 10], 1900).into(); + // ipv6 + let bind_addr = SocketAddrV6::new( + Ipv6Addr::new(0xfe80, 0, 0, 0, 0x64a3, 0x40ff, 0xfe0b, 0x77a3), + 1900, // port + 0, // stream info: 0 + 4 // iface index: 4 + ).into(); + let mut responses = ssdp_client::search(&search_target, timeout, 2, None, bind_addr).await.expect("asjdlksaj"); while let Some(response) = responses.next().await { let response = response?; diff --git a/src/lib.rs b/src/lib.rs index a84787c..75b8290 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,7 +21,7 @@ //! use ssdp_client::SearchTarget; //! //! let search_target = SearchTarget::RootDevice; -//! let mut responses = ssdp_client::search(&search_target, Duration::from_secs(3), 2, None).await?; +//! let mut responses = ssdp_client::search(&search_target, Duration::from_secs(3), 2, None, ([0, 0, 0, 0], 0).into()).await?; //! //! while let Some(response) = responses.next().await { //! println!("{:?}", response?); diff --git a/src/search.rs b/src/search.rs index 7146c5b..6a212f5 100644 --- a/src/search.rs +++ b/src/search.rs @@ -4,7 +4,6 @@ use futures_core::stream::Stream; use genawaiter::sync::{Co, Gen}; use std::{collections::HashMap, net::SocketAddr, time::Duration}; use tokio::net::UdpSocket; - const INSUFFICIENT_BUFFER_MSG: &str = "buffer size too small, udp packets lost"; const DEFAULT_SEARCH_TTL: u32 = 2; @@ -67,14 +66,23 @@ pub async fn search( timeout: Duration, mx: usize, ttl: Option, + bind_addr: SocketAddr ) -> Result>, Error> { - let bind_addr: SocketAddr = get_bind_addr().await?; - let broadcast_address: SocketAddr = ([239, 255, 255, 250], 1900).into(); + let broadcast_address: SocketAddr = if bind_addr.is_ipv4() { + ([239, 255, 255, 250], 1900).into() + } else { + ([0xff02, 0, 0, 0, 0, 0, 0, 0xc], 1900).into() + }; - let socket = UdpSocket::bind(&bind_addr).await?; - socket - .set_multicast_ttl_v4(ttl.unwrap_or(DEFAULT_SEARCH_TTL)) - .ok(); + let socket = UdpSocket::bind(&bind_addr).await.expect("error addr"); + if bind_addr.is_ipv4() { + socket + .set_multicast_ttl_v4(ttl.unwrap_or(DEFAULT_SEARCH_TTL)) + .ok(); + } else { + socket.set_multicast_loop_v6(true).ok(); + socket.set_ttl(ttl.unwrap_or(DEFAULT_SEARCH_TTL)).ok(); + } let msg = format!( "M-SEARCH * HTTP/1.1\r @@ -83,7 +91,7 @@ Man:\"ssdp:discover\"\r ST: {search_target}\r MX: {mx}\r\n\r\n" ); - socket.send_to(msg.as_bytes(), &broadcast_address).await?; + socket.send_to(msg.as_bytes(), &broadcast_address).await.expect("msg"); Ok(Gen::new(move |co| socket_stream(socket, timeout, co))) }