package de.tum.in.www1.jReto.module.wlan;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executor;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceInfo;
import javax.jmdns.ServiceListener;
import de.tum.in.www1.jReto.module.api.Browser;
import de.tum.in.www1.jReto.niotools.Dispatcher;
public class WlanBrowser implements Browser, ServiceListener {
private Browser.Handler handler;
private Executor executor;
private Dispatcher dispatcher;
private boolean browsing;
private JmDNS bonjourBrowser;
private String networkType;
private Map<String, WlanAddress> addresses;
public WlanBrowser(Executor executor, Dispatcher dispatcher, String networkType) {
if (executor == null) throw new IllegalArgumentException("dispatcher may not be null");
if (networkType == null) throw new IllegalArgumentException("networkType may not be null");
this.executor = executor;
this.dispatcher = dispatcher;
this.networkType = networkType;
this.addresses = new HashMap<String, WlanAddress>();
}
@Override
public void setBrowserHandler(Browser.Handler handler) {
this.handler = handler;
}
@Override
public Browser.Handler getBrowserHandler() {
return handler;
}
@Override
public boolean isBrowsing() {
return this.browsing;
}
@Override
public void startBrowsing() {
String serviceType = "_" + this.networkType + "wlan._tcp.local.";
try {
this.bonjourBrowser = JmDNS.create("RetoWlanBrowser");
this.bonjourBrowser.addServiceListener(serviceType, this);
this.browsing = true;
this.handler.onBrowsingStarted(this);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void stopBrowsing() {
String serviceType = "_" + this.networkType + "wlan._tcp.local.";
this.browsing = false;
this.bonjourBrowser.removeServiceListener(serviceType, this);
try {
this.bonjourBrowser.close();
this.handler.onBrowsingStopped(this, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
this.bonjourBrowser = null;
}
}
@Override
public void serviceResolved(ServiceEvent event) {
ServiceInfo info = event.getDNS().getServiceInfo(event.getType(), event.getName());
this.onDiscoveredService(info);
}
@Override
public void serviceRemoved(final ServiceEvent event) {
System.out.println("Removed service: " + event.getInfo().getName());
this.executor.execute(new Runnable() {
@Override
public void run() {
String identifier = event.getInfo().getName();
WlanAddress address = WlanBrowser.this.addresses.get(identifier);
WlanBrowser.this.addresses.remove(identifier);
WlanBrowser.this.handler.onAddressRemoved(WlanBrowser.this, address, UUID.fromString(identifier));
}
});
}
@Override
public void serviceAdded(ServiceEvent event) {
this.bonjourBrowser.requestServiceInfo(event.getType(), event.getName(), 5000);
}
private void onDiscoveredService(final ServiceInfo info) {
if (info.getInetAddresses() == null) {
return;
}
final WlanAddress address = new WlanAddress(this.dispatcher, info.getInetAddresses()[0], info.getPort());
this.addresses.put(info.getName(), address);
this.executor.execute(new Runnable() {
public void run() {
WlanBrowser.this.handler.onAddressDiscovered(WlanBrowser.this, address, UUID.fromString(info.getName()));
}
});
}
}