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