Go to the documentation of this file.00001 package ros.zeroconf.jmdns;
00002
00003 import java.io.IOException;
00004 import java.lang.Thread;
00005 import java.lang.Boolean;
00006 import java.net.InetAddress;
00007 import java.net.Inet4Address;
00008 import java.net.Inet6Address;
00009 import java.net.NetworkInterface;
00010 import java.util.Arrays;
00011 import java.util.Iterator;
00012 import java.util.HashMap;
00013 import java.util.HashSet;
00014 import java.util.List;
00015 import java.util.ArrayList;
00016 import java.util.Map;
00017 import java.util.Set;
00018 import javax.jmdns.JmmDNS;
00019 import javax.jmdns.NetworkTopologyEvent;
00020 import javax.jmdns.NetworkTopologyListener;
00021 import javax.jmdns.ServiceEvent;
00022 import javax.jmdns.ServiceInfo;
00023 import javax.jmdns.ServiceListener;
00024 import javax.jmdns.ServiceTypeListener;
00025 import org.ros.message.zeroconf_comms.DiscoveredService;
00026
00041 public class Zeroconf implements ServiceListener, ServiceTypeListener, NetworkTopologyListener {
00042
00043 private class DefaultLogger implements ZeroconfLogger {
00044 public void println(String msg) {}
00045 }
00046
00047 JmmDNS jmmdns;
00048 Set<String> listeners;
00049 Set<ServiceInfo> services;
00050 ZeroconfLogger logger;
00051 Map<String, ZeroconfDiscoveryHandler> listener_callbacks;
00052 ZeroconfDiscoveryHandler default_listener_callback;
00053
00054 public Zeroconf() {
00055
00056
00057
00058 this.jmmdns = JmmDNS.Factory.getInstance();
00059 this.listeners = new HashSet<String>();
00060 this.services = new HashSet<ServiceInfo>();
00061 this.logger = new DefaultLogger();
00062 this.listener_callbacks = new HashMap<String, ZeroconfDiscoveryHandler>();
00063 this.default_listener_callback = null;
00064
00065
00066
00067
00068
00069 this.jmmdns.addNetworkTopologyListener(this);
00070 }
00071
00072 public Zeroconf(ZeroconfLogger logger) {
00073
00074
00075
00076 this.jmmdns = JmmDNS.Factory.getInstance();
00077 this.listeners = new HashSet<String>();
00078 this.services = new HashSet<ServiceInfo>();
00079 this.logger = logger;
00080 this.listener_callbacks = new HashMap<String, ZeroconfDiscoveryHandler>();
00081 this.default_listener_callback = null;
00082
00083
00084
00085
00086
00087 this.jmmdns.addNetworkTopologyListener(this);
00088 }
00089
00090
00091
00092
00093 public void setDefaultDiscoveryCallback(ZeroconfDiscoveryHandler listener_callback) {
00094 this.default_listener_callback = listener_callback;
00095 }
00096 public void addListener(String service_type, String domain) {
00097 addListener(service_type, domain, this.default_listener_callback);
00098 }
00105 public void addListener(String service_type, String domain, ZeroconfDiscoveryHandler listener_callback) {
00106 String service = service_type + "." + domain + ".";
00107 logger.println("Activating listener: " + service);
00108 listeners.add(service);
00109 if ( listener_callback != null ) {
00110 listener_callbacks.put(service, listener_callback);
00111 }
00112
00113 jmmdns.addServiceListener(service, this);
00114 }
00115
00119 public void removeListener(String service_type, String domain) {
00120 String listener_to_remove = service_type + "." + domain + ".";
00121 for ( Iterator<String> listener = listeners.iterator(); listener.hasNext(); ) {
00122 String this_listener = listener.next().toString();
00123 if ( this_listener.equals(listener_to_remove) ) {
00124 logger.println("Deactivating listener: " + this_listener);
00125 listener.remove();
00126
00127 jmmdns.removeServiceListener(listener_to_remove, this);
00128 break;
00129 }
00130 }
00131 listener_callbacks.remove(listener_to_remove);
00132 }
00145 public void addService(String name, String type, String domain, int port, String description) {
00146 String full_service_type = type + "." + domain + ".";
00147 logger.println("Registering service: " + full_service_type);
00148 String service_key = "description";
00149 HashMap<String, byte[]> properties = new HashMap<String, byte[]>();
00150 properties.put(service_key,description.getBytes());
00151 ServiceInfo service_info = ServiceInfo.create(full_service_type, name, port, 0, 0, true, properties);
00152
00153 if ( services.add(service_info) ) {
00154 try {
00155 jmmdns.registerService(service_info);
00156 } catch (IOException e) {
00157 e.printStackTrace();
00158 }
00159 }
00160
00161
00162
00163
00164 }
00165
00172 public List<DiscoveredService> listDiscoveredServices() {
00173 List<ServiceInfo> service_infos = new ArrayList<ServiceInfo>();
00174 for(String service : listeners ) {
00175 service_infos.addAll(Arrays.asList(this.jmmdns.list(service)));
00176 }
00177
00178
00179
00180
00181 List<DiscoveredService> discovered_services = new ArrayList<DiscoveredService>();
00182 for(ServiceInfo service_info : service_infos ) {
00183 Boolean service_found = false;
00184 for ( DiscoveredService discovered_service : discovered_services ) {
00185 if ( service_info.getQualifiedName().equals(discovered_service.name+"."+discovered_service.type+"."+discovered_service.domain+".") ) {
00186 for ( InetAddress inet_address : service_info.getInetAddresses() ) {
00187 if ( inet_address instanceof Inet4Address) {
00188 Boolean address_found = false;
00189 for ( String unique_address : discovered_service.ipv4_addresses ) {
00190 if ( inet_address.getHostAddress().equals(unique_address) ) {
00191 address_found = true;
00192 break;
00193 }
00194 }
00195 if ( !address_found ) {
00196 discovered_service.ipv4_addresses.add(inet_address.getHostAddress());
00197 }
00198 } else {
00199 Boolean address_found = false;
00200 for ( String unique_address : discovered_service.ipv6_addresses ) {
00201 if ( inet_address.getHostAddress().equals(unique_address) ) {
00202 address_found = true;
00203 break;
00204 }
00205 }
00206 if ( !address_found ) {
00207 discovered_service.ipv6_addresses.add(inet_address.getHostAddress());
00208 }
00209 }
00210 }
00211 service_found = true;
00212 break;
00213 }
00214 }
00215 if ( !service_found ) {
00216 discovered_services.add(toDiscoveredService(service_info));
00217 }
00218
00219 }
00220 return discovered_services;
00221 }
00222
00227 public void removeAllServices() {
00228 logger.println("Removing all services");
00229 jmmdns.unregisterAllServices();
00230 services.clear();
00231 }
00232
00233 public void shutdown() throws IOException {
00234 removeAllServices();
00235 logger.println("Shutdown");
00236 jmmdns.close();
00237 }
00238
00239
00240
00241
00242 @Override
00243 public void serviceAdded(ServiceEvent event) {
00244 final ServiceInfo service_info = event.getInfo();
00245
00246
00247 jmmdns.getServiceInfos(service_info.getType(), service_info.getName(), true);
00248 ZeroconfDiscoveryHandler callback = listener_callbacks.get(service_info.getType());
00249 if ( callback != null ) {
00250 callback.serviceAdded(toDiscoveredService(service_info));
00251 } else {
00252 logger.println("[+] Service : " + service_info.getQualifiedName());
00253 }
00254 }
00255
00256 @Override
00257 public void serviceRemoved(ServiceEvent event) {
00258 final String name = event.getName();
00259 final ServiceInfo service_info = event.getInfo();
00260 ZeroconfDiscoveryHandler callback = listener_callbacks.get(service_info.getType());
00261 if ( callback != null ) {
00262 callback.serviceRemoved(toDiscoveredService(service_info));
00263 } else {
00264 logger.println("[-] Service : " + name);
00265 }
00266 }
00267
00268 @Override
00277 public void serviceResolved(ServiceEvent event) {
00278 final ServiceInfo service_info = event.getInfo();
00279 ZeroconfDiscoveryHandler callback = listener_callbacks.get(service_info.getType());
00280 if ( callback != null ) {
00281 callback.serviceResolved(toDiscoveredService(service_info));
00282 } else {
00283 logger.println("[=] Resolved : " + service_info.getQualifiedName());
00284 logger.println(" Port : " + service_info.getPort() );
00285 for ( int i = 0; i < service_info.getInetAddresses().length; ++i ) {
00286 logger.println(" Address : " + service_info.getInetAddresses()[i].getHostAddress() );
00287 }
00288 }
00289 }
00290
00291 @Override
00292 public void serviceTypeAdded(ServiceEvent event) {
00293
00294
00295 }
00296
00297 @Override
00298 public void subTypeForServiceTypeAdded(ServiceEvent event) {
00299
00300 }
00301
00302
00303
00304
00305 @Override
00306 public void inetAddressAdded(NetworkTopologyEvent event) {
00307 try {
00308 logger.println("[+] NetworkInterface: " + event.getInetAddress().getHostAddress() + " [" + NetworkInterface.getByInetAddress(event.getInetAddress()).getDisplayName() + "]");
00309 } catch (IOException e) {
00310 e.printStackTrace();
00311 }
00312 try {
00313 event.getDNS().addServiceTypeListener(this);
00314 for(String listener : listeners ) {
00315 logger.println(" Adding service listener '" + listener + "'");
00316 event.getDNS().addServiceListener(listener, this);
00317 }
00318 for (ServiceInfo service : services ) {
00319 logger.println("Publishing Service on " + event.getInetAddress().getHostAddress());
00320 logger.println(" Name : " + service.getName() );
00321 logger.println(" Type : " + service.getType() );
00322 logger.println(" Port : " + service.getPort() );
00323 event.getDNS().registerService(service.clone());
00324 }
00325 } catch (IOException e) {
00326 e.printStackTrace();
00327 }
00328 }
00329
00330 @Override
00331 public void inetAddressRemoved(NetworkTopologyEvent event) {
00332 String event_address_str = event.getInetAddress().getHostAddress();
00333
00334
00335
00336 logger.println("[-] NetworkInterface: " + event_address_str);
00337
00338
00339
00340
00341
00342 event.getDNS().removeServiceTypeListener(this);
00343 for(String listener : listeners ) {
00344 logger.println(" Removing service listener '" + listener + "'");
00345 event.getDNS().removeServiceListener(listener, this);
00346 }
00347 for (ServiceInfo service : services ) {
00348 logger.println("Unpublishing Service:");
00349 logger.println(" Name : " + service.getName() );
00350 logger.println(" Type : " + service.getType() );
00351 logger.println(" Port : " + service.getPort() );
00352 event.getDNS().unregisterService(service);
00353 }
00354 }
00355
00356
00357
00358
00359 public void display(DiscoveredService discovered_service) {
00360 logger.println("Discovered Service:");
00361 logger.println(" Name : " + discovered_service.name );
00362 logger.println(" Type : " + discovered_service.type );
00363 logger.println(" Port : " + discovered_service.port );
00364 for ( String address : discovered_service.ipv4_addresses ) {
00365 logger.println(" Address: " + address );
00366 }
00367 for ( String address : discovered_service.ipv6_addresses ) {
00368 logger.println(" Address: " + address );
00369 }
00370 }
00371
00372 public String toString(DiscoveredService discovered_service) {
00373 String result = "Service Info:\n";
00374 result += " Name : " + discovered_service.name + "\n";
00375 result += " Type : " + discovered_service.type + "\n";
00376 result += " Port : " + discovered_service.port + "\n";
00377 for ( String address : discovered_service.ipv4_addresses ) {
00378 result += " Address: " + address + "\n";
00379 }
00380 for ( String address : discovered_service.ipv6_addresses ) {
00381 result += " Address: " + address + "\n";
00382 }
00383 return result;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 private DiscoveredService toDiscoveredService(ServiceInfo service_info) {
00414 DiscoveredService discovered_service = new DiscoveredService();
00415 discovered_service.name = service_info.getName();
00416 String[] type_domain_str = service_info.getType().split("\\.");
00417 discovered_service.type = type_domain_str[0] + "." + type_domain_str[1];
00418 discovered_service.domain = service_info.getDomain();
00419 discovered_service.hostname = service_info.getServer();
00420 discovered_service.port = service_info.getPort();
00421 for ( InetAddress inet_address : service_info.getInetAddresses() ) {
00422 if ( inet_address instanceof Inet4Address) {
00423 discovered_service.ipv4_addresses.add(inet_address.getHostAddress());
00424 } else {
00425 discovered_service.ipv6_addresses.add(inet_address.getHostAddress());
00426 }
00427 }
00428 return discovered_service;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 }