package fr.phelep.java.squeezebox;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
public class SqueezeboxServerDiscoverer {
private static final int DISCOVERY_PORT = 3483;
private static final int TIMEOUT_MS = 2500;
private static final String DISCOVERY_PACKET = "eIPAD\0NAME\0JSON\0VERS\0";
private int ipAddress;
private int netmask;
private DatagramSocket socket;
private ArrayList<SqueezeboxServer> servers = new ArrayList<SqueezeboxServer>();
public SqueezeboxServerDiscoverer( int ipAddress, int netmask ) throws IOException {
this.ipAddress = ipAddress;
this.netmask = netmask;
this.socket = new DatagramSocket(DISCOVERY_PORT);
this.socket.setBroadcast(true);
this.socket.setSoTimeout(TIMEOUT_MS);
this.sendDiscoveryRequest();
this.listenForResponses();
this.socket.close();
}
private void sendDiscoveryRequest() throws IOException {
DatagramPacket packet = new DatagramPacket(DISCOVERY_PACKET.getBytes(),
DISCOVERY_PACKET.length(), getBroadcastAddress(), DISCOVERY_PORT);
this.socket.send(packet);
}
private InetAddress getBroadcastAddress() throws IOException {
int broadcast = (this.ipAddress & this.netmask) | ~this.netmask;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
return InetAddress.getByAddress(quads);
}
private void listenForResponses() throws IOException {
byte[] buf = new byte[256];
try {
while (true) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
this.socket.receive(packet);
buf = packet.getData();
int i = 1;
int l;
String t;
String v;
if( (char)buf[0] == 'E' ) {
String ipAddress = packet.getAddress().getHostAddress();
String version = null;
String name = null;
int port = -1;
while( i< packet.getLength() ) {
t = new String(buf,i,4);
l = (int) buf[i+4];
v = new String(buf,i+5,l);
i = i + 5 + l;
if( t.equals("JSON") ) {
port = Integer.parseInt(v);
} else if( t.equals("NAME" ) ) {
name = v;
} else if( t.equals("VERS") ) {
version = v;
}
}
if( port > 0 ) {
this.servers.add(new SqueezeboxServer(ipAddress, port, name, version));
}
}
}
} catch (SocketTimeoutException e) {
// Should handle this sometime
}
}
public int serversCount() {
return this.servers.size();
}
public SqueezeboxServer getServer(int index) {
return this.servers.get(index);
}
}