upnpimpl.java
来自「Azureus is a powerful, full-featured, cr」· Java 代码 · 共 738 行 · 第 1/2 页
JAVA
738 行
/*
* Created on 14-Jun-2004
* Created by Paul Gardner
* Copyright (C) 2004 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SARL au capital de 30,000 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.aelitis.net.upnp.impl;
/**
* @author parg
*
*/
import java.util.*;
import java.net.*;
import java.io.*;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.logging.*;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderAdapter;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderException;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderFactory;
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocument;
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentException;
import com.aelitis.net.upnp.*;
import com.aelitis.net.upnp.impl.device.*;
import com.aelitis.net.upnp.services.UPnPWANConnectionPortMapping;
import com.aelitis.net.upnp.services.UPnPWANIPConnection;
public class
UPnPImpl
extends ResourceDownloaderAdapter
implements UPnP, SSDPListener
{
public static final boolean USE_HTTP_CONNECTION = true;
public static final String NL = "\r\n";
protected static UPnPImpl singleton;
protected static AEMonitor class_mon = new AEMonitor( "UPnP:class" );
public static UPnP
getSingleton(
PluginInterface plugin_interface )
throws UPnPException
{
try{
class_mon.enter();
if ( singleton == null ){
singleton = new UPnPImpl( plugin_interface );
}
return( singleton );
}finally{
class_mon.exit();
}
}
protected PluginInterface plugin_interface;
protected LoggerChannel log;
protected SSDP ssdp;
protected Map root_locations = new HashMap();
protected List log_listeners = new ArrayList();
protected List log_history = new ArrayList();
protected List rd_listeners = new ArrayList();
protected AEMonitor rd_listeners_mon = new AEMonitor( "UPnP:L" );
protected int trace_index = 0;
protected AEMonitor this_mon = new AEMonitor( "UPnP" );
protected
UPnPImpl(
PluginInterface _plugin_interface )
throws UPnPException
{
plugin_interface = _plugin_interface;
log = plugin_interface.getLogger().getChannel("UPnP Core");
ssdp = SSDPFactory.create( this );
ssdp.addListener(this);
ssdp.start();
}
public void
rootDiscovered(
InetAddress local_address,
URL location )
{
UPnPRootDeviceImpl root_device = (UPnPRootDeviceImpl)root_locations.get( location.getHost());
if ( root_device != null ){
// device is still there with same IP, however
// 1) port of UPnP device might have changed (it does on mine when enabling/disabling UPnP)
// 2) our local IP might have changed (DHCP reassignment)
if ( root_device.getLocation().equals( location ) &&
root_device.getLocalAddress().equals( local_address )){
// everythings the same, nothing to do
return;
}
// something changed, resetablish everything
root_locations.remove( location.getHost());
root_device.destroy( true );
}
log( "UPnP: root discovered = " + location + ", local = " + local_address.toString() );
try{
root_device = new UPnPRootDeviceImpl( this, local_address, location );
List listeners;
try{
rd_listeners_mon.enter();
root_locations.put( location.getHost(), root_device );
listeners = new ArrayList( rd_listeners );
}finally{
rd_listeners_mon.exit();
}
for (int i=0;i<listeners.size();i++){
((UPnPListener)listeners.get(i)).rootDeviceFound( root_device );
}
}catch( UPnPException e ){
log( e.toString());
}
}
public void
rootAlive(
URL location )
{
UPnPRootDeviceImpl root_device = (UPnPRootDeviceImpl)root_locations.get( location.getHost());
if ( root_device == null ){
ssdp.searchNow();
}
}
public void
rootLost(
InetAddress local_address,
URL location )
{
UPnPRootDeviceImpl root_device;
try{
rd_listeners_mon.enter();
root_device = (UPnPRootDeviceImpl)root_locations.remove( location.getHost());
}finally{
rd_listeners_mon.exit();
}
if ( root_device == null ){
return;
}
log( "UPnP: root lost = " + location +", local = " + local_address.toString() );
root_device.destroy( false );
}
public void
reset()
{
log( "UPnP: reset" );
List roots;
try{
rd_listeners_mon.enter();
roots = new ArrayList(root_locations.values());
root_locations.clear();
}finally{
rd_listeners_mon.exit();
}
for (int i=0;i<roots.size();i++){
((UPnPRootDeviceImpl)roots.get(i)).destroy( true );
}
ssdp.searchNow();
}
public SimpleXMLParserDocument
parseXML(
InputStream _is )
throws SimpleXMLParserDocumentException, IOException
{
// ASSUME UTF-8
ByteArrayOutputStream baos = null;
try{
baos = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[8192];
while(true){
int len = _is.read( buffer );
if ( len <= 0 ){
break;
}
baos.write( buffer, 0, len );
}
}finally{
baos.close();
}
byte[] bytes_in = baos.toByteArray();
InputStream is = new ByteArrayInputStream( bytes_in );
// Gudy's router was returning trailing nulls which then stuffed up the
// XML parser. Hence this code to try and strip them
try{
StringBuffer data = new StringBuffer(1024);
LineNumberReader lnr = new LineNumberReader( new InputStreamReader( is, "UTF-8" ));
while( true ){
String line = lnr.readLine();
if ( line == null ){
break;
}
data.append( line.trim() + "\n" );
}
String data_str = data.toString();
log.log( "UPnP:Response:" + data_str );
return( plugin_interface.getUtilities().getSimpleXMLParserDocumentFactory().create( data_str ));
}catch( Throwable e ){
try{
FileOutputStream trace = new FileOutputStream( getTraceFile());
trace.write( bytes_in );
trace.close();
}catch( Throwable f ){
Debug.printStackTrace( f );
}
if ( e instanceof SimpleXMLParserDocumentException ){
throw((SimpleXMLParserDocumentException)e);
}
throw( new SimpleXMLParserDocumentException(e ));
}
}
public SimpleXMLParserDocument
downloadXML(
URL url )
throws UPnPException
{
ResourceDownloaderFactory rdf = plugin_interface.getUtilities().getResourceDownloaderFactory();
ResourceDownloader rd = rdf.getRetryDownloader( rdf.create( url ), 3 );
rd.addListener( this );
try{
InputStream data = rd.download();
return( parseXML( data ));
}catch( Throwable e ){
log( e );
if (e instanceof UPnPException ){
throw((UPnPException)e);
}
throw( new UPnPException( "Root device location '" + url + "' - data read failed", e ));
}
}
public SimpleXMLParserDocument
performSOAPRequest(
UPnPService service,
String soap_action,
String request )
throws SimpleXMLParserDocumentException, UPnPException, IOException
{
log.log( "UPnP:Request:" + request );
URL control = service.getControlURL();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?