package org.hwo.beacon; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Date; import java.util.Hashtable; import java.util.Properties; import java.util.Timer; import java.util.TimerTask; import java.util.UUID; public class Beacon { public class BeaconSender { private Properties properties; private InetAddress inetAddress; private Long lastBeacon; public BeaconSender() { properties = new Properties(); lastBeacon = 0l; } public InetAddress getInetAddress() { return inetAddress; } public void setInetAddress(InetAddress inetAddress) { this.inetAddress = inetAddress; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } public Long getLastBeacon() { return lastBeacon; } public void setLastBeacon(Long lastBeacon) { this.lastBeacon = lastBeacon; } @Override public String toString() { return String.format("%s", getProperties().getProperty("beacon.name")); } } public static void main(String[] args) { int mode = 0; for (String arg:args) { if (arg.equals("-s")) mode = 1; } Beacon beacon = new Beacon(44999); beacon.setBeaconName("Test beacon"); if (mode == 1) { beacon.start(); System.console().printf("Press Enter to exit!"); System.console().readLine(); System.console().printf("exiting..."); beacon.exit(); } else { beacon.ping(); } } private int port; private boolean exit; private DatagramSocket socket; private Properties properties; private Integer intervall; private String beaconName; private UUID uuid; private boolean serverOnly; private boolean clientOnly; private Thread thread; private Hashtable beaconSenders; public Beacon(int port) { this.port = port; this.socket = null; this.properties = new Properties(); this.intervall = 5000; this.beaconSenders = new Hashtable(); this.uuid = UUID.randomUUID(); try { this.beaconName = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { this.beaconName = "Unkown Host"; } } public void setServerOnly(boolean serverOnly) { this.serverOnly = serverOnly; } public boolean isServerOnly() { return serverOnly; } public void setClientOnly(boolean clientOnly) { this.clientOnly = clientOnly; } public boolean isClientOnly() { return clientOnly; } public boolean isAlive(){ return this.thread != null; } public synchronized void start() { if (thread == null) { thread = new Thread(new Runnable() { @Override public void run() { Beacon.this.run(); } }); thread.start(); } } public synchronized void exit() { if (thread != null){ exit = true; socket.close(); try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } thread = null; } } public boolean getExit() { return exit; } public void setExit(Boolean exit){ this.exit = exit; } public void run() { Timer pingTimer = new Timer(); if (!clientOnly){ pingTimer.schedule(new TimerTask() { @Override public void run() { ping(); } }, intervall, intervall); } try { if (serverOnly) socket = new DatagramSocket(); else socket = new DatagramSocket(this.port); DatagramPacket packet = new DatagramPacket(new byte[1500], 1500); while (!getExit()) { try { socket.receive(packet); ByteArrayInputStream bis = new ByteArrayInputStream(packet.getData(),0,packet.getLength()); BeaconSender bs = beaconSenders.get(packet.getAddress().getHostAddress()); if (bs == null) { bs = new BeaconSender(); bs.setInetAddress(packet.getAddress()); } bs.setLastBeacon((new Date()).getTime()); bs.getProperties().load(bis); if (bs.getProperties().getProperty("beacon.uuid").equals(uuid.toString())) { System.err.println("Received Local Echo."); } else { System.err.println(String.format("Beacon from %s",packet.getAddress().getHostAddress())); System.err.println(String.format("Beacon: %s", bs.getProperties().getProperty("beacon.name"))); beaconSenders.put(packet.getAddress().getHostAddress(), bs); }; } catch (IOException e) { } } } catch (SocketException e) { e.printStackTrace(); } pingTimer.cancel(); } public BeaconSender getSenderByUUID(UUID uuid){ for (BeaconSender sender: this.beaconSenders.values()){ if (UUID.fromString(sender.getProperties().getProperty("beacon.uuid")).equals(uuid)) return sender; } return null; } public BeaconSender getSenderByName(String beaconName){ for (BeaconSender sender: this.beaconSenders.values()){ if (sender.getProperties().getProperty("beacon.name").equals(beaconName)) return sender; } return null; } public void ping() { DatagramSocket sock = socket; try { if (sock == null) sock = new DatagramSocket(); } catch (SocketException e1) { e1.printStackTrace(); } properties.setProperty("beacon.name", beaconName); properties.setProperty("beacon.uuid", uuid.toString()); try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); properties.store(bos, null); byte[] bytes = bos.toByteArray(); DatagramPacket packet = new DatagramPacket(bytes,bytes.length); packet.setPort(this.port); packet.setAddress(InetAddress.getByName("255.255.255.255")); sock.send(packet); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } public Integer getIntervall() { return intervall; } public void setIntervall(Integer intervall) { this.intervall = intervall; } public Hashtable getBeaconSenders() { return beaconSenders; } public void setBeaconSenders(Hashtable beaconSenders) { this.beaconSenders = beaconSenders; } public String getBeaconName() { return beaconName; } public void setBeaconName(String beaconName) { this.beaconName = beaconName; } }