FileDocCategorySizeDatePackage
SSDPCore.javaAPI DocAzureus 3.0.3.412416Wed Apr 19 06:02:32 BST 2006com.aelitis.net.upnp.impl.ssdp

SSDPCore

public class SSDPCore extends Object implements UPnPSSDP, com.aelitis.net.udp.mc.MCGroupAdapter
author
parg

Fields Summary
private static final String
HTTP_VERSION
private static final String
NL
private static Map
singletons
private static org.gudy.azureus2.core3.util.AEMonitor
class_mon
private com.aelitis.net.udp.mc.MCGroup
mc_group
private UPnPSSDPAdapter
adapter
private String
group_address_str
private int
group_port
private boolean
first_response
private List
listeners
private org.gudy.azureus2.plugins.utils.UTTimer
timer
protected org.gudy.azureus2.core3.util.AEMonitor
this_mon
Constructors Summary
public SSDPCore(UPnPSSDPAdapter _adapter, String _group_address, int _group_port, int _control_port, String[] _selected_interfaces)


	
	
	
				
						
							
							
					 
	
		 
		
		adapter	= _adapter;

		group_address_str	= _group_address;
		group_port			= _group_port;
		
		try{
			mc_group = MCGroupFactory.getSingleton( this, _group_address, group_port, _control_port, _selected_interfaces );
			
		}catch( Throwable e ){
						
			throw( new UPnPException( "Failed to initialise SSDP", e ));
		}
	
Methods Summary
public voidaddListener(UPnPSSDPListener l)

		listeners.add( l );
	
public intgetControlPort()

		return( mc_group.getControlPort());
	
protected java.lang.StringgetServerName()

		return( System.getProperty( "os.name" ) + "/" + System.getProperty("os.version") + " UPnP/1.0 " +
				Constants.AZUREUS_NAME + "/" + Constants.AZUREUS_VERSION );
	
public static com.aelitis.net.upnp.impl.ssdp.SSDPCoregetSingleton(UPnPSSDPAdapter adapter, java.lang.String group_address, int group_port, int control_port, java.lang.String[] selected_interfaces)


	  
	
				
						
							
							
					 
	
		 
	
		try{
			class_mon.enter();
		
			String	key = group_address + ":" + group_port;// + ":" + control_port;
			
			SSDPCore	singleton = (SSDPCore)singletons.get( key );
			
			if ( singleton == null ){
				
				singleton = new SSDPCore( adapter, group_address, group_port, control_port, selected_interfaces );
				
				singletons.put( key, singleton );
			}
			
			return( singleton );
			
		}finally{
			
			class_mon.exit();
		}
	
protected voidinformNotify(java.net.NetworkInterface network_interface, java.net.InetAddress local_address, java.net.InetAddress originator, java.lang.String usn, java.net.URL location, java.lang.String nt, java.lang.String nts)

		for (int i=0;i<listeners.size();i++){
			
			try{
				((UPnPSSDPListener)listeners.get(i)).receivedNotify(network_interface,local_address,originator,usn,location,nt,nts);
				
			}catch( Throwable e ){
				
				adapter.log(e);
			}
		}
	
protected voidinformResult(java.net.NetworkInterface network_interface, java.net.InetAddress local_address, java.net.InetAddress originator, java.lang.String usn, java.net.URL location, java.lang.String st, java.lang.String al)

		for (int i=0;i<listeners.size();i++){
			
			try{
				((UPnPSSDPListener)listeners.get(i)).receivedResult(network_interface,local_address,originator,usn,location,st,al);
				
			}catch( Throwable e ){
				
				adapter.log(e);
			}
		}
	
protected java.lang.String[]informSearch(java.net.NetworkInterface network_interface, java.net.InetAddress local_address, java.net.InetAddress originator, java.lang.String st)

		for (int i=0;i<listeners.size();i++){
			
			try{
				String[]	res = ((UPnPSSDPListener)listeners.get(i)).receivedSearch(network_interface,local_address,originator,st );
				
				if ( res != null ){
					
					return( res );
				}
			}catch( Throwable e ){
				
				adapter.log(e);
			}
		}
		
		return( null );
	
public voidinterfaceChanged(java.net.NetworkInterface network_interface)

		for (int i=0;i<listeners.size();i++){
			
			try{
				((UPnPSSDPListener)listeners.get(i)).interfaceChanged(network_interface);
				
			}catch( Throwable e ){
				
				adapter.log(e);
			}
		}	
	
public voidlog(java.lang.Throwable e)

		adapter.log( e );
	
public voidnotify(java.lang.String NT, java.lang.String NTS, java.lang.String UUID, java.lang.String url)

		/*
		NOTIFY * HTTP/1.1
		HOST: 239.255.255.250:1900
		CACHE-CONTROL: max-age=3600
		LOCATION: http://192.168.0.1:49152/gateway.xml
		NT: urn:schemas-upnp-org:service:WANIPConnection:1
		NTS: ssdp:byebye
		SERVER: Linux/2.4.17_mvl21-malta-mips_fp_le, UPnP/1.0, Intel SDK for UPnP devices /1.2
		USN: uuid:ab5d9077-0710-4373-a4ea-5192c8781666::urn:schemas-upnp-org:service:WANIPConnection:1
		*/
		
		if ( url.startsWith("/")){
			
			url = url.substring(1);
		}
		
		String	str =
			"NOTIFY * HTTP/" + HTTP_VERSION + NL +  
			"HOST: " + group_address_str + ":" + group_port + NL +
			"CACHE-CONTROL: max-age=3600" + NL +
			"LOCATION: http://%AZINTERFACE%:" + mc_group.getControlPort() + "/" + url + NL +
			"NT: " + NT + NL + 
			"NTS: " + NTS + NL + 
			"SERVER: " + getServerName() + NL +
			"USN: " + (UUID==null?"":(UUID + "::")) + NT + NL + NL; 
		
		try{

			mc_group.sendToGroup( str );
			
		}catch( Throwable e ){
		}
	
public voidreceived(java.net.NetworkInterface network_interface, java.net.InetAddress local_address, java.net.InetSocketAddress originator, byte[] packet_data, int length)

		String	str = new String( packet_data, 0,length );
				
		if ( first_response ){
			
			first_response	= false;
			
			adapter.trace( "UPnP:SSDP: first response:\n" + str );
		}
		
				// example notify event
			/*
			NOTIFY * HTTP/1.1
			HOST: 239.255.255.250:1900
			CACHE-CONTROL: max-age=3600
			LOCATION: http://192.168.0.1:49152/gateway.xml
			NT: urn:schemas-upnp-org:service:WANIPConnection:1
			NTS: ssdp:byebye
			SERVER: Linux/2.4.17_mvl21-malta-mips_fp_le, UPnP/1.0, Intel SDK for UPnP devices /1.2
			USN: uuid:ab5d9077-0710-4373-a4ea-5192c8781666::urn:schemas-upnp-org:service:WANIPConnection:1
			*/
			
		// System.out.println( str );
		
		List	lines = new ArrayList();
		
		int	pos = 0;
		
		while(true){
			
			int	p1 = str.indexOf( NL, pos );
			
			String	line;
			
			if ( p1 == -1 ){
			
				line = str.substring(pos);
			}else{
				
				line = str.substring(pos,p1);
				
				pos	= p1+1;
			}
			
			lines.add( line.trim());
			
			if ( p1 == -1 ){
				
				break;
			}
		}
		
		if ( lines.size() == 0 ){
			
			adapter.trace( "SSDP::receive packet - 0 line reply" );
			
			return;
		}
		
		String	header = (String)lines.get(0);
		
			// Gudy's  Root: http://192.168.0.1:5678/igd.xml, uuid:upnp-InternetGatewayDevice-1_0-12345678900001::upnp:rootdevice, upnp:rootdevice
			// Parg's  Root: http://192.168.0.1:49152/gateway.xml, uuid:824ff22b-8c7d-41c5-a131-44f534e12555::upnp:rootdevice, upnp:rootdevice

		URL		location	= null;
		String	usn			= null;
		String	nt			= null;
		String	nts			= null;
		String	st			= null;
		String	al			= null;
		String	mx			= null;
		
		for (int i=1;i<lines.size();i++){
			
			String	line = (String)lines.get(i);
			
			int	c_pos = line.indexOf(":");
			
			if ( c_pos == -1 ){
				continue;
			}
			
			String	key	= line.substring( 0, c_pos ).trim().toUpperCase();
			String 	val = line.substring( c_pos+1 ).trim();
			
			if ( key.equals("LOCATION" )){
				
				try{
					location	= new URL( val );
					
				}catch( MalformedURLException e ){
					
					adapter.log( e );
				}			
			}else if ( key.equals( "NT" )){
				
				nt	= val;
				
			}else if ( key.equals( "USN" )){
				
				usn	= val;
				
			}else if ( key.equals( "NTS" )){
				
				nts	= val;
				
			}else if ( key.equals( "ST" )){
				
				st	= val;
				
			}else if ( key.equals( "AL" )){
				
				al	= val;
				
			}else if ( key.equals( "MX" )){
				
				mx	= val;
			}
		}
			
		if ( header.startsWith("M-SEARCH")){

			if ( st != null ){
				
				/*
				HTTP/1.1 200 OK
				CACHE-CONTROL: max-age=600
				DATE: Tue, 20 Dec 2005 13:07:31 GMT
				EXT:
				LOCATION: http://192.168.1.1:2869/gatedesc.xml
				SERVER: Linux/2.4.17_mvl21-malta-mips_fp_le UPnP/1.0 
				ST: upnp:rootdevice
				USN: uuid:UUID-InternetGatewayDevice-1234::upnp:rootdevice
				*/
				
				String[]	response = informSearch( network_interface, local_address, originator.getAddress(), st );
				
				if ( response != null ){
					
					String	UUID 	= response[0];
					String	url		= response[1];
					
					if ( url.startsWith("/")){
						url = url.substring(1);
					}
					
					String	data = 
						"HTTP/1.1 200 OK" + NL +
						"LOCATION: http://" + local_address.getHostAddress() + ":" + mc_group.getControlPort() + "/" + url + NL +
						"EXT:" + NL + 
						"USN: " + UUID + "::" + st + NL + 
						"SERVER: Azureus (UPnP/1.0)" + NL +
						"CACHE-CONTROL: max-age=3600" + NL +
						"ST: " + st + NL + 
						"Content-Length: 0" + NL + NL;
										
					final byte[]	data_bytes = data.getBytes();
					
					if ( timer == null ){
						
						timer	= adapter.createTimer( "SSDPCore:MX" );
					}
					
					int	delay = 0;
					
					if ( mx != null ){
						
						try{
							
							delay = Integer.parseInt( mx ) * 1000;
							
							delay = (int)(Math.random()*delay);
							
						}catch( Throwable e ){
						}
					}
					
					final Runnable task =
						new Runnable()
						{
							public void
							run()
							{
								try{
									mc_group.sendToMember( originator, data_bytes );
									
								}catch( Throwable e ){
									
									adapter.log(e);
								}	
							}
						};
												
					if ( delay == 0 ){
						
						task.run();
						
					}else{
						
						timer.addEvent( 
								SystemTime.getCurrentTime() + delay,
								new UTTimerEventPerformer()
								{
									public void
									perform(
										UTTimerEvent		event )
									{
										task.run();
									}
								});
					}
				}
			}else{
				
				adapter.trace( "SSDP::receive M-SEARCH - bad header:" + header );
			}
		}else if ( header.startsWith( "NOTIFY" )){
			
				// location is null for byebye
			
			if ( nt != null && nts != null ){
			
				informNotify( network_interface, local_address, originator.getAddress(), usn, location, nt, nts );
				
			}else{
				
				adapter.trace( "SSDP::receive NOTIFY - bad header:" + header );
			}
		}else if ( header.startsWith( "HTTP") && header.indexOf( "200") != -1 ){
			
			if ( location != null && st != null ){
		
				informResult( network_interface, local_address, originator.getAddress(), usn, location, st, al  );
				
			}else{
				
				adapter.trace( "SSDP::receive HTTP - bad header:" + header );
			}			
		}else{
			
			adapter.trace( "SSDP::receive packet - bad header:" + header );
		}
	
public voidremoveListener(UPnPSSDPListener l)

		listeners.remove(l);
	
public voidsearch(java.lang.String ST)

		String	str =
			"M-SEARCH * HTTP/" + HTTP_VERSION + NL +  
			"ST: " + ST + NL +
			"MX: 3" + NL +
			"MAN: \"ssdp:discover\"" + NL + 
			"HOST: " + group_address_str + ":" + group_port + NL + NL;
		
		sendMC( str );
	
protected voidsendMC(java.lang.String str)

		byte[]	data = str.getBytes();
		
		try{

			mc_group.sendToGroup( data );
			
		}catch( Throwable e ){
		}
	
public voidtrace(java.lang.String str)

		adapter.log( str );