Merge pull request 'corrige un bug de détection des servers online' (#38) from push-vnqkompntkws into main
All checks were successful
Build and Push Docker Image / build (push) Successful in 28m35s
All checks were successful
Build and Push Docker Image / build (push) Successful in 28m35s
Reviewed-on: https://gargoton.petite-maison-orange.fr/eric/pmomusic/pulls/38
This commit was merged in pull request #38.
This commit is contained in:
@@ -12,7 +12,8 @@ pub struct UpnpDiscoveryManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UpnpDiscoveryManager {
|
impl UpnpDiscoveryManager {
|
||||||
pub fn new(device_registry: Arc<RwLock<DeviceRegistry>>,
|
pub fn new(
|
||||||
|
device_registry: Arc<RwLock<DeviceRegistry>>,
|
||||||
udn_cache: Arc<Mutex<UDNRegistry>>,
|
udn_cache: Arc<Mutex<UDNRegistry>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -42,10 +43,15 @@ impl UpnpDiscoveryManager {
|
|||||||
|
|
||||||
if let Some(udn) = extract_udn_from_usn(&usn) {
|
if let Some(udn) = extract_udn_from_usn(&usn) {
|
||||||
if alive {
|
if alive {
|
||||||
// ✅ Check cache
|
// Check if we should fetch the full device description
|
||||||
if UDNRegistry::should_fetch(self.udn_cache.clone(), &udn, max_age as u64) {
|
let should_fetch =
|
||||||
// ✅ Fetch + parse
|
UDNRegistry::should_fetch(self.udn_cache.clone(), &udn, max_age as u64);
|
||||||
if let Ok(info) = ParsedDeviceDescription::new(&udn, &location, &server_header,5) {
|
|
||||||
|
if should_fetch {
|
||||||
|
// Fetch + parse the device description
|
||||||
|
if let Ok(info) =
|
||||||
|
ParsedDeviceDescription::new(&udn, &location, &server_header, 5)
|
||||||
|
{
|
||||||
if let Some(renderer_info) = info.build_renderer() {
|
if let Some(renderer_info) = info.build_renderer() {
|
||||||
if let Ok(mut reg) = self.device_registry.write() {
|
if let Ok(mut reg) = self.device_registry.write() {
|
||||||
reg.push_renderer(&renderer_info, max_age);
|
reg.push_renderer(&renderer_info, max_age);
|
||||||
@@ -56,6 +62,13 @@ impl UpnpDiscoveryManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Even if we don't fetch, we MUST update last_seen to prevent timeout
|
||||||
|
// This is critical: SSDP Alive messages arrive more frequently than max_age/2,
|
||||||
|
// and we need to acknowledge them to keep the device online
|
||||||
|
if let Ok(mut reg) = self.device_registry.write() {
|
||||||
|
reg.refresh_device_presence(&udn, max_age);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Ok(mut reg) = self.device_registry.write() {
|
if let Ok(mut reg) = self.device_registry.write() {
|
||||||
@@ -64,11 +77,8 @@ impl UpnpDiscoveryManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn extract_udn_from_usn(usn: &str) -> Option<String> {
|
fn extract_udn_from_usn(usn: &str) -> Option<String> {
|
||||||
let lower = usn.trim().to_ascii_lowercase();
|
let lower = usn.trim().to_ascii_lowercase();
|
||||||
if let Some(idx) = lower.find("uuid:") {
|
if let Some(idx) = lower.find("uuid:") {
|
||||||
|
|||||||
@@ -130,46 +130,46 @@ impl MusicRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the protocol.
|
/// Returns the protocol.
|
||||||
fn protocol(&self) -> RendererProtocol {
|
pub fn protocol(&self) -> RendererProtocol {
|
||||||
self.info.protocol()
|
self.info.protocol()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_upnp(&self) -> bool {
|
pub fn is_upnp(&self) -> bool {
|
||||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||||
MusicRendererBackend::Upnp(_) => true,
|
MusicRendererBackend::Upnp(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_openhome(&self) -> bool {
|
pub fn is_openhome(&self) -> bool {
|
||||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||||
MusicRendererBackend::OpenHome(_) => true,
|
MusicRendererBackend::OpenHome(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_linkplay(&self) -> bool {
|
pub fn is_linkplay(&self) -> bool {
|
||||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||||
MusicRendererBackend::LinkPlay(_) => true,
|
MusicRendererBackend::LinkPlay(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_arylictcp(&self) -> bool {
|
pub fn is_arylictcp(&self) -> bool {
|
||||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||||
MusicRendererBackend::ArylicTcp(_) => true,
|
MusicRendererBackend::ArylicTcp(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_chromecast(&self) -> bool {
|
pub fn is_chromecast(&self) -> bool {
|
||||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||||
MusicRendererBackend::Chromecast(_) => true,
|
MusicRendererBackend::Chromecast(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_hybridupnparylic(&self) -> bool {
|
pub fn is_hybridupnparylic(&self) -> bool {
|
||||||
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
match &*self.backend.lock().expect("Backend mutex poisoned") {
|
||||||
MusicRendererBackend::HybridUpnpArylic { .. } => true,
|
MusicRendererBackend::HybridUpnpArylic { .. } => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|||||||
@@ -257,6 +257,41 @@ impl DeviceRegistry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Updates the last_seen timestamp for a device without fetching its full description.
|
||||||
|
///
|
||||||
|
/// This is critical for keeping devices online when SSDP Alive messages arrive
|
||||||
|
/// more frequently than the UDN cache refresh interval (max_age/2).
|
||||||
|
pub fn refresh_device_presence(&mut self, udn: &str, max_age: u32) {
|
||||||
|
let lookup = udn.to_ascii_lowercase();
|
||||||
|
|
||||||
|
if let Some(id) = self.udn_index.get(&lookup) {
|
||||||
|
if let Some(device) = self.devices.get(id) {
|
||||||
|
let was_online = device.is_online();
|
||||||
|
device.has_been_seen_now(max_age);
|
||||||
|
|
||||||
|
// If device was offline and came back online, broadcast Online event
|
||||||
|
if !was_online {
|
||||||
|
if device.is_a_music_renderer() {
|
||||||
|
if let Ok(renderer) = device.as_music_renderer() {
|
||||||
|
self.renderer_bus.broadcast(RendererEvent::Online {
|
||||||
|
id: id.clone(),
|
||||||
|
info: renderer.info().basic_info(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if device.is_a_music_server() {
|
||||||
|
if let Ok(server) = device.as_music_server() {
|
||||||
|
self.server_bus.broadcast(MediaServerEvent::Online {
|
||||||
|
server_id: id.clone(),
|
||||||
|
info: server.basic_info(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn device_says_byebye(&mut self, udn: &str) {
|
pub fn device_says_byebye(&mut self, udn: &str) {
|
||||||
let lookup = udn.to_ascii_lowercase();
|
let lookup = udn.to_ascii_lowercase();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user