mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 01:27:34 -05:00
Resolves significant memory usage issue - updates Airspy and HackRF with
the recent changes applied to RTL2832 Tuner controller for processing of libusb transfer buffers.
This commit is contained in:
@@ -262,7 +262,30 @@ public class AirspyTunerController extends TunerController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static String getTransferStatus( int status )
|
||||||
|
{
|
||||||
|
switch( status )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "TRANSFER COMPLETED (0)";
|
||||||
|
case 1:
|
||||||
|
return "TRANSFER ERROR (1)";
|
||||||
|
case 2:
|
||||||
|
return "TRANSFER TIMED OUT (2)";
|
||||||
|
case 3:
|
||||||
|
return "TRANSFER CANCELLED (3)";
|
||||||
|
case 4:
|
||||||
|
return "TRANSFER STALL (4)";
|
||||||
|
case 5:
|
||||||
|
return "TRANSFER NO DEVICE (5)";
|
||||||
|
case 6:
|
||||||
|
return "TRANSFER OVERFLOW (6)";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN TRANSFER STATUS (" + status + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void apply( TunerConfiguration config ) throws SourceException
|
public void apply( TunerConfiguration config ) throws SourceException
|
||||||
{
|
{
|
||||||
if( config instanceof AirspyTunerConfiguration )
|
if( config instanceof AirspyTunerConfiguration )
|
||||||
@@ -1192,18 +1215,21 @@ public class AirspyTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void addListener( Listener<ComplexBuffer> listener )
|
public void addListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.addListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
|
mComplexBufferBroadcaster.addListener( listener );
|
||||||
|
|
||||||
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
||||||
{
|
{
|
||||||
mBufferProcessor = new BufferProcessor();
|
mBufferProcessor = new BufferProcessor();
|
||||||
|
|
||||||
Thread thread = new Thread( mBufferProcessor );
|
Thread thread = new Thread( mBufferProcessor );
|
||||||
thread.setDaemon( true );
|
thread.setDaemon( true );
|
||||||
thread.setName( "Airspy Buffer Processor" );
|
thread.setName( "Airspy Buffer Processor" );
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1212,12 +1238,15 @@ public class AirspyTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void removeListener( Listener<ComplexBuffer> listener )
|
public void removeListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.removeListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
if( !mComplexBufferBroadcaster.hasListeners() )
|
mComplexBufferBroadcaster.removeListener( listener );
|
||||||
{
|
|
||||||
mBufferProcessor.stop();
|
if( !mComplexBufferBroadcaster.hasListeners() )
|
||||||
}
|
{
|
||||||
|
mBufferProcessor.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1227,8 +1256,11 @@ public class AirspyTunerController extends TunerController
|
|||||||
public class BufferProcessor implements Runnable, TransferCallback
|
public class BufferProcessor implements Runnable, TransferCallback
|
||||||
{
|
{
|
||||||
private ScheduledFuture<?> mSampleDispatcherTask;
|
private ScheduledFuture<?> mSampleDispatcherTask;
|
||||||
private CopyOnWriteArrayList<Transfer> mTransfers;
|
private LinkedTransferQueue<Transfer> mAvailableTransfers;
|
||||||
|
private LinkedTransferQueue<Transfer> mTransfersInProgress = new LinkedTransferQueue<>();
|
||||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||||
|
private ByteBuffer mLibUsbHandlerStatus;
|
||||||
|
private boolean mCancel = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
@@ -1237,33 +1269,64 @@ public class AirspyTunerController extends TunerController
|
|||||||
{
|
{
|
||||||
prepareTransfers();
|
prepareTransfers();
|
||||||
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
|
||||||
mLog.error( "error submitting transfer [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
||||||
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
||||||
20, TimeUnit.MILLISECONDS );
|
20, TimeUnit.MILLISECONDS );
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus = ByteBuffer.allocateDirect( 4 );
|
||||||
|
|
||||||
|
List<Transfer> transfers = new ArrayList<>();
|
||||||
|
|
||||||
|
mCancel = false;
|
||||||
|
|
||||||
while( mRunning.get() )
|
while( mRunning.get() )
|
||||||
{
|
{
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
mAvailableTransfers.drainTo( transfers );
|
||||||
|
|
||||||
|
for( Transfer transfer: transfers )
|
||||||
|
{
|
||||||
|
int result = LibUsb.submitTransfer( transfer );
|
||||||
|
|
||||||
|
if( result == LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mTransfersInProgress.add( transfer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.error( "error submitting transfer [" +
|
||||||
|
LibUsb.errorName( result ) + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||||
null, USB_TIMEOUT_MS, completed.asIntBuffer() );
|
null, USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
if( result != LibUsb.SUCCESS )
|
||||||
{
|
{
|
||||||
mLog.error( "error handling events for libusb" );
|
mLog.error( "error handling events for libusb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transfers.clear();
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mCancel )
|
||||||
|
{
|
||||||
|
for( Transfer transfer: mTransfersInProgress )
|
||||||
|
{
|
||||||
|
LibUsb.cancelTransfer( transfer );
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = LibUsb.handleEventsTimeoutCompleted( null,
|
||||||
|
USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
|
if( result != LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mLog.error( "error handling events for libusb" );
|
||||||
|
}
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1273,10 +1336,10 @@ public class AirspyTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void stop()
|
public void stop()
|
||||||
{
|
{
|
||||||
|
mCancel = true;
|
||||||
|
|
||||||
if( mRunning.compareAndSet( true, false ) )
|
if( mRunning.compareAndSet( true, false ) )
|
||||||
{
|
{
|
||||||
cancel();
|
|
||||||
|
|
||||||
if( mSampleDispatcherTask != null )
|
if( mSampleDispatcherTask != null )
|
||||||
{
|
{
|
||||||
mSampleDispatcherTask.cancel( true );
|
mSampleDispatcherTask.cancel( true );
|
||||||
@@ -1296,66 +1359,39 @@ public class AirspyTunerController extends TunerController
|
|||||||
@Override
|
@Override
|
||||||
public void processTransfer( Transfer transfer )
|
public void processTransfer( Transfer transfer )
|
||||||
{
|
{
|
||||||
if( transfer.status() == LibUsb.TRANSFER_COMPLETED )
|
mTransfersInProgress.remove( transfer );
|
||||||
{
|
|
||||||
ByteBuffer buffer = transfer.buffer();
|
|
||||||
|
|
||||||
byte[] data = new byte[ transfer.actualLength() ];
|
|
||||||
|
|
||||||
buffer.get( data );
|
|
||||||
|
|
||||||
buffer.rewind();
|
|
||||||
|
|
||||||
mFilledBuffers.add( data );
|
|
||||||
|
|
||||||
if( !isRunning() )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( transfer.status() )
|
switch( transfer.status() )
|
||||||
{
|
{
|
||||||
case LibUsb.TRANSFER_COMPLETED:
|
case LibUsb.TRANSFER_COMPLETED:
|
||||||
/* resubmit the transfer */
|
case LibUsb.TRANSFER_STALL:
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
if( transfer.actualLength() > 0 )
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
{
|
||||||
mLog.error( "couldn't resubmit buffer transfer to tuner" );
|
ByteBuffer buffer = transfer.buffer();
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
byte[] data = new byte[ transfer.actualLength() ];
|
||||||
|
|
||||||
|
buffer.get( data );
|
||||||
|
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
if( isRunning() )
|
||||||
|
{
|
||||||
|
mFilledBuffers.add( data );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LibUsb.TRANSFER_CANCELLED:
|
case LibUsb.TRANSFER_CANCELLED:
|
||||||
/* free the transfer and remove it */
|
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unexpected error */
|
/* unexpected error */
|
||||||
mLog.error( "transfer error" );
|
mLog.error( "transfer error [" +
|
||||||
|
getTransferStatus( transfer.status() ) +
|
||||||
|
"] transferred actual: " + transfer.actualLength() );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void cancel()
|
|
||||||
{
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
|
||||||
null, USB_TIMEOUT_MS, completed.asIntBuffer() );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
mAvailableTransfers.add( transfer );
|
||||||
{
|
}
|
||||||
mLog.error( "error handling usb events during cancel [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares (allocates) a set of transfer buffers for use in
|
* Prepares (allocates) a set of transfer buffers for use in
|
||||||
@@ -1363,30 +1399,28 @@ public class AirspyTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
private void prepareTransfers() throws LibUsbException
|
private void prepareTransfers() throws LibUsbException
|
||||||
{
|
{
|
||||||
mTransfers = new CopyOnWriteArrayList<Transfer>();
|
if( mAvailableTransfers == null )
|
||||||
|
|
||||||
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
|
||||||
{
|
{
|
||||||
Transfer transfer = LibUsb.allocTransfer();
|
mAvailableTransfers = new LinkedTransferQueue<>();
|
||||||
|
|
||||||
|
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
||||||
|
{
|
||||||
|
Transfer transfer = LibUsb.allocTransfer();
|
||||||
|
|
||||||
if( transfer == null )
|
if( transfer == null )
|
||||||
{
|
{
|
||||||
throw new LibUsbException( "couldn't allocate transfer",
|
throw new LibUsbException( "couldn't allocate transfer",
|
||||||
LibUsb.ERROR_NO_MEM );
|
LibUsb.ERROR_NO_MEM );
|
||||||
}
|
}
|
||||||
|
|
||||||
final ByteBuffer buffer =
|
final ByteBuffer buffer =
|
||||||
ByteBuffer.allocateDirect( mBufferSize );
|
ByteBuffer.allocateDirect( mBufferSize );
|
||||||
|
|
||||||
LibUsb.fillBulkTransfer( transfer,
|
LibUsb.fillBulkTransfer( transfer, mDeviceHandle, USB_ENDPOINT,
|
||||||
mDeviceHandle,
|
buffer, BufferProcessor.this, "Buffer", USB_TIMEOUT_MS );
|
||||||
USB_ENDPOINT,
|
|
||||||
buffer,
|
mAvailableTransfers.add( transfer );
|
||||||
BufferProcessor.this,
|
}
|
||||||
"Buffer #" + x,
|
|
||||||
USB_TIMEOUT_MS );
|
|
||||||
|
|
||||||
mTransfers.add( transfer );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.LinkedTransferQueue;
|
import java.util.concurrent.LinkedTransferQueue;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
@@ -91,7 +92,7 @@ public class HackRFTunerController extends TunerController
|
|||||||
private final static Logger mLog =
|
private final static Logger mLog =
|
||||||
LoggerFactory.getLogger( HackRFTunerController.class );
|
LoggerFactory.getLogger( HackRFTunerController.class );
|
||||||
|
|
||||||
public final static long TIMEOUT_US = 1000000l; //uSeconds
|
public final static long USB_TIMEOUT_MS = 1000000l; //uSeconds
|
||||||
public static final byte USB_ENDPOINT = (byte)0x81;
|
public static final byte USB_ENDPOINT = (byte)0x81;
|
||||||
public static final byte USB_INTERFACE = (byte)0x0;
|
public static final byte USB_INTERFACE = (byte)0x0;
|
||||||
|
|
||||||
@@ -394,7 +395,7 @@ public class HackRFTunerController extends TunerController
|
|||||||
(short)value,
|
(short)value,
|
||||||
(short)index,
|
(short)index,
|
||||||
buffer,
|
buffer,
|
||||||
TIMEOUT_US );
|
USB_TIMEOUT_MS );
|
||||||
|
|
||||||
if( transferred < 0 )
|
if( transferred < 0 )
|
||||||
{
|
{
|
||||||
@@ -467,7 +468,7 @@ public class HackRFTunerController extends TunerController
|
|||||||
(short)value,
|
(short)value,
|
||||||
(short)index,
|
(short)index,
|
||||||
buffer,
|
buffer,
|
||||||
TIMEOUT_US );
|
USB_TIMEOUT_MS );
|
||||||
|
|
||||||
if( transferred < 0 )
|
if( transferred < 0 )
|
||||||
{
|
{
|
||||||
@@ -886,18 +887,21 @@ public class HackRFTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void addListener( Listener<ComplexBuffer> listener )
|
public void addListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.addListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
|
mComplexBufferBroadcaster.addListener( listener );
|
||||||
|
|
||||||
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
||||||
{
|
{
|
||||||
mBufferProcessor = new BufferProcessor();
|
mBufferProcessor = new BufferProcessor();
|
||||||
|
|
||||||
Thread thread = new Thread( mBufferProcessor );
|
Thread thread = new Thread( mBufferProcessor );
|
||||||
thread.setDaemon( true );
|
thread.setDaemon( true );
|
||||||
thread.setName( "HackRF Sample Processor" );
|
thread.setName( "HackRF Sample Processor" );
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -906,12 +910,15 @@ public class HackRFTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void removeListener( Listener<ComplexBuffer> listener )
|
public void removeListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.removeListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
if( !mComplexBufferBroadcaster.hasListeners() )
|
mComplexBufferBroadcaster.removeListener( listener );
|
||||||
{
|
|
||||||
mBufferProcessor.stop();
|
if( !mComplexBufferBroadcaster.hasListeners() )
|
||||||
}
|
{
|
||||||
|
mBufferProcessor.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -921,45 +928,77 @@ public class HackRFTunerController extends TunerController
|
|||||||
public class BufferProcessor implements Runnable, TransferCallback
|
public class BufferProcessor implements Runnable, TransferCallback
|
||||||
{
|
{
|
||||||
private ScheduledFuture<?> mSampleDispatcherTask;
|
private ScheduledFuture<?> mSampleDispatcherTask;
|
||||||
private CopyOnWriteArrayList<Transfer> mTransfers;
|
private LinkedTransferQueue<Transfer> mAvailableTransfers;
|
||||||
|
private LinkedTransferQueue<Transfer> mTransfersInProgress = new LinkedTransferQueue<>();
|
||||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||||
|
private ByteBuffer mLibUsbHandlerStatus;
|
||||||
|
private boolean mCancel = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
if( mRunning.compareAndSet( false, true ) )
|
if( mRunning.compareAndSet( false, true ) )
|
||||||
{
|
{
|
||||||
mLog.info( "starting HackRF sample fetch thread" );
|
|
||||||
|
|
||||||
prepareTransfers();
|
prepareTransfers();
|
||||||
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
|
||||||
mLog.error( "error submitting transfer [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
||||||
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
||||||
20, TimeUnit.MILLISECONDS );
|
20, TimeUnit.MILLISECONDS );
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus = ByteBuffer.allocateDirect( 4 );
|
||||||
|
|
||||||
|
List<Transfer> transfers = new ArrayList<>();
|
||||||
|
|
||||||
|
mCancel = false;
|
||||||
|
|
||||||
while( mRunning.get() )
|
while( mRunning.get() )
|
||||||
{
|
{
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
mAvailableTransfers.drainTo( transfers );
|
||||||
|
|
||||||
|
for( Transfer transfer: transfers )
|
||||||
|
{
|
||||||
|
int result = LibUsb.submitTransfer( transfer );
|
||||||
|
|
||||||
|
if( result == LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mTransfersInProgress.add( transfer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.error( "error submitting transfer [" +
|
||||||
|
LibUsb.errorName( result ) + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||||
null, TIMEOUT_US, completed.asIntBuffer() );
|
null, USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
if( result != LibUsb.SUCCESS )
|
||||||
{
|
{
|
||||||
mLog.error( "error handling events for libusb" );
|
mLog.error( "error handling events for libusb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transfers.clear();
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mCancel )
|
||||||
|
{
|
||||||
|
for( Transfer transfer: mTransfersInProgress )
|
||||||
|
{
|
||||||
|
LibUsb.cancelTransfer( transfer );
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||||
|
null, USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
|
if( result != LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mLog.error( "error cancelling transfers in progress" );
|
||||||
|
}
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -969,12 +1008,10 @@ public class HackRFTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void stop()
|
public void stop()
|
||||||
{
|
{
|
||||||
|
mCancel = true;
|
||||||
|
|
||||||
if( mRunning.compareAndSet( true, false ) )
|
if( mRunning.compareAndSet( true, false ) )
|
||||||
{
|
{
|
||||||
mLog.info( "stopping HackRF sample fetch thread" );
|
|
||||||
|
|
||||||
cancel();
|
|
||||||
|
|
||||||
if( mSampleDispatcherTask != null )
|
if( mSampleDispatcherTask != null )
|
||||||
{
|
{
|
||||||
mSampleDispatcherTask.cancel( true );
|
mSampleDispatcherTask.cancel( true );
|
||||||
@@ -994,41 +1031,29 @@ public class HackRFTunerController extends TunerController
|
|||||||
@Override
|
@Override
|
||||||
public void processTransfer( Transfer transfer )
|
public void processTransfer( Transfer transfer )
|
||||||
{
|
{
|
||||||
if( transfer.status() == LibUsb.TRANSFER_COMPLETED )
|
mTransfersInProgress.remove( transfer );
|
||||||
{
|
|
||||||
ByteBuffer buffer = transfer.buffer();
|
|
||||||
|
|
||||||
byte[] data = new byte[ transfer.actualLength() ];
|
|
||||||
|
|
||||||
buffer.get( data );
|
|
||||||
|
|
||||||
buffer.rewind();
|
|
||||||
|
|
||||||
mFilledBuffers.add( data );
|
|
||||||
|
|
||||||
if( !isRunning() )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( transfer.status() )
|
switch( transfer.status() )
|
||||||
{
|
{
|
||||||
case LibUsb.TRANSFER_COMPLETED:
|
case LibUsb.TRANSFER_COMPLETED:
|
||||||
/* resubmit the transfer */
|
case LibUsb.TRANSFER_STALL:
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
if( transfer.actualLength() > 0 )
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
{
|
||||||
mLog.error( "couldn't resubmit buffer transfer to tuner" );
|
ByteBuffer buffer = transfer.buffer();
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
byte[] data = new byte[ transfer.actualLength() ];
|
||||||
|
|
||||||
|
buffer.get( data );
|
||||||
|
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
if( isRunning() )
|
||||||
|
{
|
||||||
|
mFilledBuffers.add( data );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LibUsb.TRANSFER_CANCELLED:
|
case LibUsb.TRANSFER_CANCELLED:
|
||||||
/* free the transfer and remove it */
|
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unexpected error */
|
/* unexpected error */
|
||||||
@@ -1036,26 +1061,9 @@ public class HackRFTunerController extends TunerController
|
|||||||
getTransferStatus( transfer.status() ) +
|
getTransferStatus( transfer.status() ) +
|
||||||
"] transferred actual: " + transfer.actualLength() );
|
"] transferred actual: " + transfer.actualLength() );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void cancel()
|
|
||||||
{
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
|
||||||
null, TIMEOUT_US, completed.asIntBuffer() );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
mAvailableTransfers.add( transfer );
|
||||||
{
|
}
|
||||||
mLog.error( "error handling usb events during cancel [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares (allocates) a set of transfer buffers for use in
|
* Prepares (allocates) a set of transfer buffers for use in
|
||||||
@@ -1063,30 +1071,28 @@ public class HackRFTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
private void prepareTransfers() throws LibUsbException
|
private void prepareTransfers() throws LibUsbException
|
||||||
{
|
{
|
||||||
mTransfers = new CopyOnWriteArrayList<Transfer>();
|
if( mAvailableTransfers == null )
|
||||||
|
|
||||||
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
|
||||||
{
|
{
|
||||||
Transfer transfer = LibUsb.allocTransfer();
|
mAvailableTransfers = new LinkedTransferQueue<>();
|
||||||
|
|
||||||
|
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
||||||
|
{
|
||||||
|
Transfer transfer = LibUsb.allocTransfer();
|
||||||
|
|
||||||
if( transfer == null )
|
if( transfer == null )
|
||||||
{
|
{
|
||||||
throw new LibUsbException( "couldn't allocate transfer",
|
throw new LibUsbException( "couldn't allocate transfer",
|
||||||
LibUsb.ERROR_NO_MEM );
|
LibUsb.ERROR_NO_MEM );
|
||||||
}
|
}
|
||||||
|
|
||||||
final ByteBuffer buffer =
|
final ByteBuffer buffer =
|
||||||
ByteBuffer.allocateDirect( mBufferSize );
|
ByteBuffer.allocateDirect( mBufferSize );
|
||||||
|
|
||||||
LibUsb.fillBulkTransfer( transfer,
|
LibUsb.fillBulkTransfer( transfer, mDeviceHandle,USB_ENDPOINT,
|
||||||
mDeviceHandle,
|
buffer, BufferProcessor.this, "Buffer", USB_TIMEOUT_MS );
|
||||||
USB_ENDPOINT,
|
|
||||||
buffer,
|
mAvailableTransfers.add( transfer );
|
||||||
BufferProcessor.this,
|
}
|
||||||
"Buffer #" + x,
|
|
||||||
TIMEOUT_US );
|
|
||||||
|
|
||||||
mTransfers.add( transfer );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import java.text.DecimalFormat;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.concurrent.LinkedTransferQueue;
|
import java.util.concurrent.LinkedTransferQueue;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -72,7 +71,7 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
public final static int TWO_TO_22_POWER = 4194304;
|
public final static int TWO_TO_22_POWER = 4194304;
|
||||||
|
|
||||||
public final static byte USB_INTERFACE = (byte)0x0;
|
public final static byte USB_INTERFACE = (byte)0x0;
|
||||||
public final static byte BULK_ENDPOINT_IN = (byte)0x81;
|
public final static byte USB_BULK_ENDPOINT = (byte)0x81;
|
||||||
public final static byte CONTROL_ENDPOINT_IN =
|
public final static byte CONTROL_ENDPOINT_IN =
|
||||||
(byte)( LibUsb.ENDPOINT_IN | LibUsb.REQUEST_TYPE_VENDOR );
|
(byte)( LibUsb.ENDPOINT_IN | LibUsb.REQUEST_TYPE_VENDOR );
|
||||||
public final static byte CONTROL_ENDPOINT_OUT =
|
public final static byte CONTROL_ENDPOINT_OUT =
|
||||||
@@ -1387,7 +1386,6 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
private ScheduledFuture<?> mSampleDispatcherTask;
|
private ScheduledFuture<?> mSampleDispatcherTask;
|
||||||
private LinkedTransferQueue<Transfer> mAvailableTransfers;
|
private LinkedTransferQueue<Transfer> mAvailableTransfers;
|
||||||
private LinkedTransferQueue<Transfer> mTransfersInProgress = new LinkedTransferQueue<>();
|
private LinkedTransferQueue<Transfer> mTransfersInProgress = new LinkedTransferQueue<>();
|
||||||
private CopyOnWriteArrayList<Transfer> mTransfers;
|
|
||||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||||
private ThreadPoolManager mThreadPoolManager;
|
private ThreadPoolManager mThreadPoolManager;
|
||||||
private ByteBuffer mLibUsbHandlerStatus;
|
private ByteBuffer mLibUsbHandlerStatus;
|
||||||
@@ -1577,7 +1575,7 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
final ByteBuffer buffer =
|
final ByteBuffer buffer =
|
||||||
ByteBuffer.allocateDirect( mBufferSize );
|
ByteBuffer.allocateDirect( mBufferSize );
|
||||||
|
|
||||||
LibUsb.fillBulkTransfer( transfer, mDeviceHandle, BULK_ENDPOINT_IN,
|
LibUsb.fillBulkTransfer( transfer, mDeviceHandle, USB_BULK_ENDPOINT,
|
||||||
buffer, BufferProcessor.this, "Buffer", TIMEOUT_US );
|
buffer, BufferProcessor.this, "Buffer", TIMEOUT_US );
|
||||||
|
|
||||||
mAvailableTransfers.add( transfer );
|
mAvailableTransfers.add( transfer );
|
||||||
|
|||||||
Reference in New Issue
Block a user