package Slim::Networking::mDNS; # $Id: mDNS.pm 13204 2007-09-22 16:50:16Z andy $ # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License, # version 2. use strict; use base qw(Class::Data::Inheritable); #use FindBin qw($Bin); #use File::Slurp; #use File::Spec::Functions qw(:ALL); #use Proc::Background; use Net::Rendezvous::Publish; use Slim::Utils::Log; use Slim::Utils::Misc; use Slim::Utils::Prefs; use Slim::Utils::OSDetect; { my $class = __PACKAGE__; for my $accessor (qw(isInitialized publisher)) { $class->mk_classdata($accessor); } $class->isInitialized(0); } my $log = logger('network.mdns'); my $prefs = preferences('server'); my %services = (); my @advertisement = (); sub init { my $class = shift; if (Slim::Utils::OSDetect::OS() eq 'win') { $log->debug("Skipping initialization on Windows."); return 0; } $log->info("Initializing.."); $class->publisher( Net::Rendezvous::Publish->new( backend => 'Net::Rendezvous::Publish::Backend::Avahi')); if (! $class->publisher) { $log->error("Error: Filed to create responder"); return 0; } $class->isInitialized(1); return 1; } sub addService { my ($class, $service, $port) = @_; if (!$class->isInitialized) { return if !$class->init; } my $name = $prefs->get('mDNSname'); if (!$name) { $log->info("Blank name, skipping service: $service - TXT - $port"); } else { $log->info("Adding service: $name - $service - TXT - $port"); $services{$service} = [ $name, $port ]; } } sub removeService { my ($class, $service) = @_; if (!$class->isInitialized) { return if !$class->init; } $log->info("Removing service: $service"); delete $services{$service}; } sub startAdvertising { my $class = shift; if (!$class->isInitialized) { return if !$class->init; } $log->info("Building configuration."); if (!$class->isInitialized) { return if !$class->init; } # Remove any existing services $class->stopAdvertising; # Publish the service information while (my ($service, $data) = each %services) { my ($name, $port) = @$data; $log->info("Publishing service: $name $service $port"); push @advertisement, $class->publisher->publish( name => $name, type => $service, port => $port, txt => "TXT", ); } } sub stopAdvertising { my $class = shift; if (!$class->isInitialized) { return if !$class->init; } $log->info("Shutting down.."); while (@advertisement) { shift(@advertisement)->stop; } } 1; __END__