summaryrefslogtreecommitdiffstats
path: root/contrib/plugins/RioPlayer/ssdp.pl
blob: d2023d4720a9a4b5cd524cb9554aa677d2a5aec7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/perl -T -w

#
# UDP server for auto-configuration of Dell Audio Radio.
#
# Listens on UDP port 21075 for SSDP requests and 
# replies to point the client box to the appropriate
# server.
#
# Typically put this is /etc/ssdp.pl and run it from
# /etc/rc.d/rc.local (or equiv).  This runs as a 
# daemon and consumes few resources.  The client box
# sends out a couple of requests when it powers up 
# and none otherwise.
#

use strict;
use POSIX;
use IO::Socket;

$ENV{PATH} = "/usr/bin:/bin:/usr/local/bin";
$ENV{BASH_ENV} = "/root/.bashrc";

sub mlog($) {
    my $msg = shift;
    system("logger -t SSDP \"$msg\"");
}

sub mdie($) {
    my $msg = shift;
    mlog $msg;
    exit 1;
}

sub sig_handle($) {
    mdie "SSDP server exit on signal";
}

# $mserve_ip must be a dotted-quad unless you modify the client
# NFS image to include /etc/resolv.conf.
#
my $ssdp_port   = 21075;
my $mserve_ip   = "10.60.60.16"; 		# web and NFS server IP address
my $mserve_port = "80";				# web server port

#
# The box makes two different requests.  One comes from the kernel
# during initial booting, the second comes from the player application
# after the second boot when the player starts.
#
# The respones are different for Linux.  If there is a port number
# on the first "linux" request then the client box will use that port
# for portmapper lookups, which is generally bad when talking to 
# another linux box.
#
# The second "player" response includes a port number that indicates
# the port number to use for HTTP music related requests.  I use
# port 81 and setup a virtual server in Apache to respond to music
# requests, but you may want to do this differently.
#
my $player_request = "^upnp:uuid:1D274DB0-F053-11d3-BF72-0050DA689B2F";
my $linux_request  = "^upnp:uuid:1D274DB1-F053-11d3-BF72-0050DA689B2F";

my (
    $pid,          # PID of server
    $server,       # Handle for server socket
    $him,          # peer making UDP request
    $datagram,     # Packet from client
);

#
# Cruft to become a daemon
#
$pid = fork;
exit if $pid;
mlog "SSDP server started";
mdie "Could not fork: $!" unless defined($pid);
POSIX::setsid() or mdie "Cannot start new session: $!";
$SIG{INT}  = \&sig_handle;
$SIG{TERM} = \&sig_handle;
$SIG{HUP}  = \&sig_handle;
$0 = "ssdp";

#
# Get a socket to be a UDP server
$server = IO::Socket::INET->new(LocalPort => $ssdp_port,
                                Proto     => "udp")
    or mdie "Couldn't be a udp server on port $ssdp_port : $@\n";

#
# Wait for requests and respond if appropriate
#
while ($him = $server->recv($datagram, 256, 0)) {
    my ($port, $iaddr) = sockaddr_in($server->peername);
    my $peer = inet_ntoa($iaddr);
    $datagram =~ s/\n//g;
    if ($datagram =~ $linux_request) {
	mlog "Linux request from $peer.";
        $server->send("http://$mserve_ip/descriptor.xml\n");         
    } 
    if ($datagram =~ $player_request) {
	mlog "Player request from $peer.";
        $server->send("http://$mserve_ip:$mserve_port/descriptor.xml\n"); 
    }
}