package com.genuitec.piplug.daemon;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.Collections;

import org.junit.Assert;
import org.junit.Test;

public class DaemonTests {

    private static final int DAEMON_PORT = 4392;

    private static final class SendDiscoveryThread extends Thread {

	protected DatagramSocket socket;
	protected boolean received;
	protected byte[] bytesToSend;

	public SendDiscoveryThread(DatagramSocket socket, byte[] bytesToSend) {
	    this.socket = socket;
	    this.received = false;
	    this.bytesToSend = bytesToSend;
	}

	public void run() {
	    while (!received) {
		// re-send every quarter second
		try {
		    Thread.sleep(250);
		} catch (Exception ignore) {
		}

		// broadcast on all the networks connected
		try {
		    for (NetworkInterface nic : Collections
			    .list(NetworkInterface.getNetworkInterfaces())) {
			for (InterfaceAddress ip : nic.getInterfaceAddresses()) {
			    if (ip.getBroadcast() == null) {
				continue;
			    }
			    try {
				DatagramPacket dp = new DatagramPacket(
					bytesToSend, 0, bytesToSend.length,
					ip.getBroadcast(), DAEMON_PORT);
				socket.send(dp);
			    } catch (Exception e) {
				// best effort
			    }
			}
		    }
		} catch (Exception ignore) {
		    // best effort
		}
	    }
	}
    }

    @Test
    public void discovery() throws IOException {

	byte[] bytesToSend = "find-piplug-server".getBytes("UTF-8");
	String expectedToReceive = "piplug-server";

	DatagramSocket client = new DatagramSocket();
	client.setBroadcast(true);

	System.out.println("Looking for PiPlug plug-in daemon...");

	SendDiscoveryThread thread = new SendDiscoveryThread(client,
		bytesToSend);
	thread.start();
	try {
	    // wait for a server to respond
	    client.setSoTimeout(30000); // wait 30 seconds for a server
	    byte[] buffer = new byte[16384];
	    DatagramPacket dp = new DatagramPacket(buffer, 0,
		    bytesToSend.length);
	    client.receive(dp);
	    String received = new String(buffer, dp.getOffset(),
		    dp.getLength(), "UTF-8");
	    Assert.assertEquals(expectedToReceive, received);

	    System.out.println("Discovered server at " + dp.getAddress() + ":"
		    + dp.getPort());
	} finally {
	    thread.received = true;
	}
    }
}

@@ -118,24 +118,53 @@
 gramSocket;%0A
+import java.net.InetAddress;%0A
 import java.
@@ -1152,16 +1152,110 @@
   try %7B%0A
+%09%09%09%09System.out%0A%09%09%09%09%09.println(%22Broadcasting discovery request to %22%0A%09%09%09%09%09%09+ ip.getBroadcast());%0A
 %09%09%09%09Data
@@ -1449,16 +1449,605 @@
 %09%09    %7D%0A
+%09%09%09    if (ip.getAddress().getAddress()%5B0%5D != ip%0A%09%09%09%09    .getBroadcast().getAddress()%5B0%5D) %7B%0A%09%09%09%09try %7B%0A%09%09%09%09    byte%5B%5D addr = ip.getAddress().getAddress();%0A%09%09%09%09    addr%5B3%5D = (byte) 255;%0A%09%09%09%09    InetAddress otherBroadcast = InetAddress%0A%09%09%09%09%09    .getByAddress(addr);%0A%09%09%09%09    System.out%0A%09%09%09%09%09    .println(%22Broadcasting discovery request to %22%0A%09%09%09%09%09%09    + otherBroadcast);%0A%09%09%09%09    DatagramPacket dp = new DatagramPacket(%0A%09%09%09%09%09    bytesToSend, 0, bytesToSend.length,%0A%09%09%09%09%09    otherBroadcast, DAEMON_PORT);%0A%09%09%09%09    socket.send(dp);%0A%09%09%09%09%7D catch (Exception e) %7B%0A%09%09%09%09    // best effort%0A%09%09%09%09%7D%0A%09%09%09    %7D%0A
 %09%09%09%7D%0A%09%09 

Use fallback broadcast address