android usb host asynchronous interrupt transfer - android

public boolean OpenDevice() {
_usbManager = (UsbManager) _context.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = _usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
_usbDevice = null;
// Iterate all the available devices and find ours.
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next();
if (device.getProductId() == _productId && device.getVendorId() == _vendorId) {
_usbDevice = device;
_deviceName = _usbDevice.getDeviceName();
}
}
if (_usbDevice == null) {
Toast.makeText(_context,"Cannot find the device. Did you forgot to plug it?",Toast.LENGTH_SHORT).show();
return false;
}
// Create and intent and request a permission.
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(_context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
_context.registerReceiver(mUsbReceiver, filter);
_usbManager.requestPermission(_usbDevice, mPermissionIntent);
UsbInterface writeIntf = _usbDevice.getInterface(0);
epOUT=writeIntf.getEndpoint(1);
epIN=writeIntf.getEndpoint(0);
mUsbDeviceConnection=_usbManager.openDevice(_usbDevice);
mUsbDeviceConnection.claimInterface(writeIntf, true);
Toast.makeText(_context,"Found the device",Toast.LENGTH_SHORT).show();
return true;
}
public byte[] read(UsbRequest outRequest) throws UsbException {
if (mUsbDeviceConnection == null) {
throw new UsbException("no connection available");
}
ByteBuffer buffer = ByteBuffer.allocate(MAX_PACKAGE_SIZE);
if (outRequest.equals(mUsbDeviceConnection.requestWait())) {
UsbRequest inRequest = new UsbRequest();
inRequest.initialize(mUsbDeviceConnection, epIN);
if (inRequest.queue(buffer, MAX_PACKAGE_SIZE)) {
mUsbDeviceConnection.requestWait();
return buffer.array();
}
}
return null;
}
public UsbRequest write(byte[] command) throws UsbException {
if (mUsbDeviceConnection == null) {
throw new UsbException("no connection available");
}
ByteBuffer buffer = ByteBuffer.allocate(1);
UsbRequest outRequest = new UsbRequest();
outRequest.initialize(mUsbDeviceConnection, epOUT);
buffer.put(command);
outRequest.queue(buffer, 1);
return outRequest;
}
public byte[] sendCommand(byte[] command) throws UsbException {
UsbRequest request = write(command);
_textInfo.setText(_textInfo.getText()+"\n" +request );
return read(request);
}
I am trying to push some command at endPointOut and trying to receive data from endPointIN but when i am trying to read using mUsbDeviceConnection.requestWait() application is not responding
following code that how i am trying to call these function
byte b=(byte)'x';
byte command[] = {b};
byte[] result= hidBr.sendCommand(command);
I am getting a blank array

Related

Android: MediaCodec: dequeueBuffer failed: BAD_VALUE(-22)

i'm trying to decode data that i send through TCP.
I successfully managed to fill in the decoder.
But when i try to get the output to render it on a surfaceView. i get this error:
dequeueBuffer failed: BAD_VALUE(-22)
Also, outputBufferIdde is always equal to -1 (try again later)
this is my code :
try {
serverSocket = new ServerSocket(2968);
Log.d(TAG,"server accept");
Socket client = serverSocket.accept();
InputStream inputStream = client.getInputStream();
inputBuffersde = decodec.getInputBuffers();
Log.d(TAG, "encodeDecode 1");
DecoderRunnable decoderRunnable=new DecoderRunnable(decodec,infode);
new Thread(decoderRunnable).start();
while (true) {
dataSizes=new byte[4];
inputStream.read(dataSizes,0,4);
dataSize=ByteBuffer.wrap(dataSizes).getInt();
Log.d(TAG,"size: "+dataSize);
totalLen=0;
data= new byte[dataSize];
for(;totalLen<dataSize;) {
len=inputStream.read(data, totalLen, dataSize-totalLen);
totalLen+=len;
Log.d(TAG,"totalLen: "+totalLen+" ,len: "+len);
}
int inputBufferIdde = decodec.dequeueInputBuffer(5000);
Log.d(TAG,"inputBufferIdde: "+inputBufferIdde);
if (inputBufferIdde >= 0) {
Log.d(TAG,"inputBufferIdde: "+inputBufferIdde);
inputBuffersde[inputBufferIdde].clear();
inputBuffersde[inputBufferIdde].rewind();
inputBuffersde[inputBufferIdde].put(data);
decodec.queueInputBuffer(inputBufferIdde, 0, inputBuffersde[inputBufferIdde].position(), System.nanoTime(), 0);
}
}
} catch(IOException e){
e.printStackTrace();
}
DecoderRunnable looks like this :
public DecoderRunnable(MediaCodec decodec, MediaCodec.BufferInfo infode) {
this.decodec = decodec;
this.infode = infode;
}
#Override
public void run() {
while(true){
int outputBufferIdde = decodec.dequeueOutputBuffer(infode, 5000);
Log.d(TAG, "outputBufferIdde : " + outputBufferIdde);
if (outputBufferIdde >= 0) {
Log.d(TAG, "encodeDecode 7");
decodec.releaseOutputBuffer(outputBufferIdde, true);
}
}
}
Can someone help me?

Android USB Accessory to Host Communication Truncation

This is my first experience working with USB communication and an android app.
I'm using https://github.com/felHR85/UsbSerial to create a application that will allow tablets/phones to use USB OTG to act as a host and communicate with an accessory. I have gotten to the point where I'm using the SerialInputStreams and SerialOutputStreams to send and receive with the device.
This is about the maximum packet size a USB can send being 64 bytes with the cable I'm using. On my application, the accessory is sending data that is larger than 64 bytes. If the accessory does not have code that sends the data over in 64 byte packages, but instead all of it at once. Will any data that comes after 64 bytes be lost?
I'm receiving the first 64 bytes of the message from the accessory to the host and then host times out as it doesn't receive the full message and resends to the accessory. The first 64 bytes of the message are always what show up, that way I know the other parts of the message aren't waiting to be polled.
EDIT
The device I'm connecting to is a datalogger that is taken as a CDC device. I know that the connection I'm using has a maximum packet size of 64.
The USBConnectActivity happens whenever a usb device is attached and passes the filter that I have set up, and the interface and endpoints are correct.
public class USBConnectActivity extends Activity
{
public UsbDevice device = null;
public UsbManager manager = null;
public UsbDeviceConnection usbDeviceConnection = null;
public UsbSerialDevice serialPort = null;
public String deviceID = "";
public boolean isUSBConnected = false;
private PendingIntent mPermissionIntent;
private final String ACTION_USB_PERMISSION =
"com.android.example.USB_PERMISSION";
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
stopUsbConnection();
unregisterReceiver(usbReceiver);
}
if(ACTION_USB_PERMISSION.equals(action))
{
setupCom();
}
}
};
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
USBConnection.getInstance().setManager(manager);
mPermissionIntent = PendingIntent.getBroadcast(
this,0,new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter mfilter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(usbReceiver,mfilter);
IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(usbReceiver, filter);
findDevice(mPermissionIntent);
finish();
}
private void findDevice(PendingIntent i)
{
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
boolean found = false;
UsbDevice xDevice = null;
while (deviceIterator.hasNext()) {
UsbDevice tDevice = deviceIterator.next();
// Loop through the interfaces of the attached USB device
for (int count = 0; count < tDevice.getInterfaceCount(); count++) {
if (found) break;
// Use temp variables to check and then match with the private variables
UsbInterface inter = tDevice.getInterface(count);
UsbEndpoint tOut = null;
UsbEndpoint tIn = null;
if (inter.getEndpointCount() >= 2) {
for (int end_count = 0; end_count < inter.getEndpointCount(); end_count++) {
UsbEndpoint end = inter.getEndpoint(end_count);
if (end.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (end.getDirection() == UsbConstants.USB_DIR_OUT) tOut = end;
else if (end.getDirection() == UsbConstants.USB_DIR_IN) tIn = end;
}
}
}
if (tOut != null && tIn != null) {
device = tDevice; manager.requestPermission(device, i); found = true;
isUSBConnected = true;
USBConnection.getInstance().setDevice(device);
USBConnection.getInstance().attach();
}
}
}
if(usbDeviceConnection == null) setupCom();
}
#Override
protected void onStop()
{
super.onStop();
unregisterReceiver(usbReceiver);
}
private void setupCom()
{
deviceID = device.getDeviceName();
if(usbDeviceConnection == null) usbDeviceConnection = manager.openDevice(device);
if(serialPort == null)
{
serialPort = UsbSerialDevice.createUsbSerialDevice(device, usbDeviceConnection);
if(serialPort != null && serialPort.open())
{
serialPort.setBaudRate(115200);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
USBConnection.getInstance().setSerialPort(serialPort);
USBConnection.getInstance().setUsbDeviceConnection(usbDeviceConnection);
}
}
}
private void stopUsbConnection(){
manager = null;
device = null;
isUSBConnected = false;
USBConnection.getInstance().detach();
deviceID = "";
try
{
if(serialPort != null)
serialPort.close();
if(usbDeviceConnection != null)
usbDeviceConnection.close();
}
finally
{
serialPort = null;
usbDeviceConnection = null;
}
}
}
This class holds all the USB info
public class USBConnection
{
// USB information
public boolean isConnected;
public UsbDevice device;
public UsbManager manager;
public UsbSerialDevice serialPort;
public UsbDeviceConnection usbDeviceConnection;
public String deviceName;
public boolean waitForReading;
private static USBConnection instance;
public static USBConnection getInstance()
{
if(instance == null)
instance = new USBConnection();
return instance;
}
public void setDevice(UsbDevice device_)
{
device = device_;
deviceName = device.getDeviceName();
}
public void setManager(UsbManager manager_)
{
manager = manager_;
}
public void attach()
{
isConnected = true;
}
public void detach()
{
isConnected = false;
}
public void setSerialPort(UsbSerialDevice serialPort_)
{
serialPort = serialPort_;
}
public void setUsbDeviceConnection(UsbDeviceConnection usbDeviceConnection_)
{
usbDeviceConnection = usbDeviceConnection_;
}
public void writing() {
waitForReading = true;
}
public void reading(){
waitForReading = false;
}
public boolean waitingForRead()
{
return waitForReading;
}
}
This is the code I use to set up the input and output streams
else if(USBConnection.getInstance().isConnected) // check if usb is connected
{
manager = USBConnection.getInstance().manager;
device = USBConnection.getInstance().device;
// Attempt at setting up a USB input and output stream
if (manager != null) {
if(usbDeviceConnection == null) usbDeviceConnection = manager.openDevice(device);
if(serialPort == null)
{
serialPort = UsbSerialDevice.createUsbSerialDevice(device, usbDeviceConnection);
if(serialPort != null && serialPort.open())
{
serialPort.setBaudRate(115200);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
input = new SerialInputStream(serialPort);
output = new SerialOutputStream(serialPort);
Log.d("Direct", "Connected to the USB socket");
}
}
}
} // else there is no usb connected
This is in felHR85 UsbSerialDevice, in his ReadThread, and what is commented out is what I included thinking it would grab the data if it was larger than 64 bytes
int numberBytes, bytes;
if(inEndpoint != null) {
bytes = numberBytes = connection.bulkTransfer(inEndpoint, serialBuffer.getBufferCompatible(),
SerialBuffer.DEFAULT_READ_BUFFER_SIZE, 100);
}/*while(numberBytes >= 64) {
numberBytes = connection.bulkTransfer(inEndpoint, serialBuffer.getBufferCompatible(), bytes,
124, 100);
bytes += numberBytes;
Log.i("Bytes", " : " + bytes);
}*/
else
bytes = numberBytes = 0;
This is in his WriteThread
while(working.get())
{
byte[] data = serialBuffer.getWriteBuffer();
if(data.length > 0)
connection.bulkTransfer(outEndpoint, data, data.length, USB_TIMEOUT);
}
EDIT
This solved my problem but I'm still not sure what the answer is to my original question
if(serialPort == null)
{
usbDeviceConnection.claimInterface(USBConnection.getInstance().usbInterface, true);
usbDeviceConnection.controlTransfer(64,0,1,0,null,0,0); // clear tx
usbDeviceConnection.controlTransfer(64,0,2,0,null,0,0); // clear rx
serialPort = UsbSerialDevice.createUsbSerialDevice(device, usbDeviceConnection);
Please put up your code. Please specify any device that you are using as accessory(Arduino, FPGA, etc) so that finding solution becomes easier. It is difficult to tell what is going wrong. I suggest you to do the following -
1)Check the device descriptor of the accessory where it is clearly mentioned the maximum bytes the USB endpoint can transfer at a time. Here I have it for my Arduino Uno
2)I request you to go through this instead of using a library.
3)There is a DTR signal which must be sent form host to accessory to indicate that data transfer is complete; so that the next data can be sent.Check this
4)You should be using a ring buffer for the receiving stream so that the data is not lost.

Difference between Reading a characteristic and setting up notifications

Hi I am working on a Bluetooth low energy in my android app
I am able to read the characteristics whenever I call my readCharacter() in app
but I want to enable a notification such that when ever there is data available I can read.
Currently I am using the method below.
private byte[] readCharacteristic(){
if(!isReadEnabled){
enableTXNotification();
isReadEnabled = true;
}
byte[] arr = new byte[CHUCK_SIZE];
BluetoothGattService RxService = mBluetoothGatt.getService(RX_SERVICE_UUID);
if(RxService == null){
broadcastUpdate(BLUETOOTH_EVENT_SERVICES_NOT_SUPPORTED);
return arr;
}
BluetoothGattCharacteristic TxChar = RxService.getCharacteristic(TX_CHAR_UUID);
if(TxChar == null){
broadcastUpdate(BLUETOOTH_EVENT_SERVICES_NOT_SUPPORTED);
return arr;
}
arr = TxChar.getValue();
Log.d(TAG,Arrays.toString(arr));
return arr;
}
And this is my enableTXNotification():
private void enableTXNotification(){
if (mBluetoothGatt == null) {
broadcastUpdate(BLUETOOTH_EVENT_SERVICES_NOT_SUPPORTED);
return;
}
BluetoothGattService RxService = mBluetoothGatt.getService(RX_SERVICE_UUID);
if (RxService == null) {
broadcastUpdate(BLUETOOTH_EVENT_SERVICES_NOT_SUPPORTED);
return;
}
BluetoothGattCharacteristic TxChar = RxService.getCharacteristic(TX_CHAR_UUID);
if (TxChar == null) {
broadcastUpdate(BLUETOOTH_EVENT_SERVICES_NOT_SUPPORTED);
return;
}
mBluetoothGatt.setCharacteristicNotification(TxChar,true);
BluetoothGattDescriptor descriptor = TxChar.getDescriptor(CCCD);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
So my question is what is the difference between Enabling notification and Reading characteristic?
How can I get notification whenever data is available

Unable to read data from USB hid device with android in host mode

I'am able to connect to device and ask device specifications:
specs:
Model: /dev/bus/usb/001/002
ID: 1002
Class: 0
Protocol: 0
Vendor ID 1155
Product ID: 22352
Interface count: 1
---------------------------------------
***** *****
Interface index: 0
Interface ID: 0
Inteface class: 3 USB_CLASS_HID
Interface protocol: 0
Endpoint count: 2
++++ ++++ ++++
Endpoint index: 0
Attributes: 3
Direction: 128 (device to host)
Number: 1
Interval: 1
Packet size: 64
Type: 3 USB_ENDPOINT_XFER_INT (interrupt endpoint)
++++ ++++ ++++
Endpoint index: 1
Attributes: 3
Direction: 0 (host to device)
Number: 1
Interval: 1
Packet size: 64
Type: 3 USB_ENDPOINT_XFER_INT (interrupt endpoint)
No more devices connected.
I'am also able to send data from host to device, using this method:
int bufferDataLength = mEndpointOut.getMaxPacketSize();
ByteBuffer buffer = ByteBuffer.allocate(bufferDataLength + 1);
UsbRequest request = new UsbRequest();
buffer.put(DataToSend);
request.initialize(mDeviceConnection, mEndpointOut);
request.queue(buffer, bufferDataLength);
try
{
if (request.equals(mDeviceConnection.requestWait()))
{
// Read an analyze the incoming data here
byte[] byteBuffer = new byte[buffer.remaining()];
buffer.get(byteBuffer, 0, buffer.remaining());
return true;
}
}
catch (Exception ex)
{
Log.e(TAG, "Error sending data: " + ex.toString());
}
return false;
But i'am not able to read from device, i've tested several methods without success..
for example this doesn't work:
int bufferDataLength = mEndpointIn.getMaxPacketSize();
ByteBuffer buffer = ByteBuffer.allocate(bufferDataLength + 1);
//Make a request
UsbRequest request = new UsbRequest();
request.initialize(mDeviceConnection, mEndpointIn);
ByteBuffer buffer = ByteBuffer.allocate(bufferDataLength);
//For IN endpoints, data is read into the buffer
request.queue(buffer, bufferDataLength);
//This blocks until the request is successful
//Make sure the request that finished is the one you need
if (mDeviceConnection.requestWait() == request) {
// Read an analyze the incoming data here
byte[] byteBuffer = new byte[buffer.remaining()];
buffer.get(byteBuffer, 0, buffer.remaining());
}
Suggestions?
I resolved my problems using this class, i'm answering to my my question hoping it can help someone else:
/**
* This class is used for talking to hid of the dongle, connecting, disconnencting and enumerating the devices.
* #author gai
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public class HidBridge {
private Context _context;
private int _productId;
private int _vendorId;
//private HidBridgeLogSupporter _logSupporter = new HidBridgeLogSupporter();
private static final String ACTION_USB_PERMISSION =
"com.example.company.app.testhid.USB_PERMISSION";
// Locker object that is responsible for locking read/write thread.
private final Object _locker = new Object();
private Thread _readingThread = null;
private boolean _runReadingThread = false;
private String _deviceName;
private UsbManager _usbManager;
private UsbDevice _usbDevice;
// The queue that contains the read data.
private Queue<byte[]> _receivedQueue;
/**
* Creates a hid bridge to the dongle. Should be created once.
* #param context is the UI context of Android.
* #param productId of the device.
* #param vendorId of the device.
*/
public HidBridge(Context context, int productId, int vendorId) {
_context = context;
_productId = productId;
_vendorId = vendorId;
_receivedQueue = new LinkedList<byte[]>();
}
/**
* Searches for the device and opens it if successful
* #return true, if connection was successful
*/
public boolean OpenDevice() {
_usbManager = (UsbManager) _context.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = _usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
_usbDevice = null;
// Iterate all the available devices and find ours.
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next();
if (device.getProductId() == _productId && device.getVendorId() == _vendorId) {
_usbDevice = device;
_deviceName = _usbDevice.getDeviceName();
}
}
if (_usbDevice == null) {
Log("Cannot find the device. Did you forgot to plug it?");
Log(String.format("\t I search for VendorId: %s and ProductId: %s", _vendorId, _productId));
return false;
}
// Create and intent and request a permission.
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(_context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
_context.registerReceiver(mUsbReceiver, filter);
_usbManager.requestPermission(_usbDevice, mPermissionIntent);
Log("Found the device");
return true;
}
/**
* Closes the reading thread of the device.
*/
public void CloseTheDevice() {
try
{
StopReadingThread();
_context.unregisterReceiver(mUsbReceiver);
}
catch(RuntimeException e)
{
Log("Error happend while closing device. Usb reciver not connected.");
}
}
/**
* Starts the thread that continuously reads the data from the device.
* Should be called in order to be able to talk with the device.
*/
public void StartReadingThread() {
if (_readingThread == null) {
_runReadingThread = true;
_readingThread = new Thread(readerReceiver);
_readingThread.start();
} else {
Log("Reading thread already started");
}
}
/**
* Stops the thread that continuously reads the data from the device.
* If it is stopped - talking to the device would be impossible.
*/
public void StopReadingThread() {
if (_readingThread != null) {
// Just kill the thread. It is better to do that fast if we need that asap.
_runReadingThread = false;
_readingThread = null;
} else {
Log("No reading thread to stop");
}
}
/**
* Write data to the usb hid. Data is written as-is, so calling method is responsible for adding header data.
* #param bytes is the data to be written.
* #return true if succeed.
*/
public boolean WriteData(byte[] bytes) {
try
{
// Lock that is common for read/write methods.
synchronized (_locker) {
UsbInterface writeIntf = _usbDevice.getInterface(0);
UsbEndpoint writeEp = writeIntf.getEndpoint(1);
UsbDeviceConnection writeConnection = _usbManager.openDevice(_usbDevice);
// Lock the usb interface.
writeConnection.claimInterface(writeIntf, true);
// Write the data as a bulk transfer with defined data length.
int r = writeConnection.bulkTransfer(writeEp, bytes, bytes.length, 0);
if (r != -1) {
Log(String.format("Written %s bytes to the dongle. Data written: %s", r, composeString(bytes)));
} else {
Log("Error happened while writing data. No ACK");
}
// Release the usb interface.
writeConnection.releaseInterface(writeIntf);
writeConnection.close();
}
} catch(NullPointerException e)
{
Log("Error happend while writing. Could not connect to the device or interface is busy?");
Log.e("HidBridge", Log.getStackTraceString(e));
return false;
}
return true;
}
/**
* #return true if there are any data in the queue to be read.
*/
public boolean IsThereAnyReceivedData() {
synchronized(_locker) {
return !_receivedQueue.isEmpty();
}
}
/**
* Queue the data from the read queue.
* #return queued data.
*/
public byte[] GetReceivedDataFromQueue() {
synchronized(_locker) {
return _receivedQueue.poll();
}
}
// The thread that continuously receives data from the dongle and put it to the queue.
private Runnable readerReceiver = new Runnable() {
public void run() {
if (_usbDevice == null) {
Log("No device to read from");
return;
}
UsbEndpoint readEp;
UsbDeviceConnection readConnection = null;
UsbInterface readIntf = null;
boolean readerStartedMsgWasShown = false;
// We will continuously ask for the data from the device and store it in the queue.
while (_runReadingThread) {
// Lock that is common for read/write methods.
synchronized (_locker) {
try
{
if (_usbDevice == null) {
OpenDevice();
Log("No device. Recheking in 10 sec...");
Sleep(10000);
continue;
}
readIntf = _usbDevice.getInterface(0);
readEp = readIntf.getEndpoint(0);
if (!_usbManager.getDeviceList().containsKey(_deviceName)) {
Log("Failed to connect to the device. Retrying to acquire it.");
OpenDevice();
if (!_usbManager.getDeviceList().containsKey(_deviceName)) {
Log("No device. Recheking in 10 sec...");
Sleep(10000);
continue;
}
}
try
{
readConnection = _usbManager.openDevice(_usbDevice);
if (readConnection == null) {
Log("Cannot start reader because the user didn't gave me permissions or the device is not present. Retrying in 2 sec...");
Sleep(2000);
continue;
}
// Claim and lock the interface in the android system.
readConnection.claimInterface(readIntf, true);
}
catch (SecurityException e) {
Log("Cannot start reader because the user didn't gave me permissions. Retrying in 2 sec...");
Sleep(2000);
continue;
}
// Show the reader started message once.
if (!readerStartedMsgWasShown) {
Log("!!! Reader was started !!!");
readerStartedMsgWasShown = true;
}
// Read the data as a bulk transfer with the size = MaxPacketSize
int packetSize = readEp.getMaxPacketSize();
byte[] bytes = new byte[packetSize];
int r = readConnection.bulkTransfer(readEp, bytes, packetSize, 50);
if (r >= 0) {
byte[] trancatedBytes = new byte[r - 1]; // Truncate bytes in the honor of r
int i=0;
for (byte b : bytes) {
if (i > 0)
trancatedBytes[i - 1] = b;
i++;
}
_receivedQueue.add(trancatedBytes); // Store received data
Log(String.format("Message received of lengths %s and content: %s", r, composeString(bytes)));
}
// Release the interface lock.
readConnection.releaseInterface(readIntf);
readConnection.close();
}
catch (NullPointerException e) {
Log("Error happened while reading. No device or the connection is busy");
Log.e("HidBridge", Log.getStackTraceString(e));
}
catch (ThreadDeath e) {
if (readConnection != null) {
readConnection.releaseInterface(readIntf);
readConnection.close();
}
throw e;
}
}
// Sleep for 10 ms to pause, so other thread can write data or anything.
// As both read and write data methods lock each other - they cannot be run in parallel.
// Looks like Android is not so smart in planning the threads, so we need to give it a small time
// to switch the thread context.
Sleep(10);
}
}
};
private void Sleep(int milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
//call method to set up device communication
}
}
else {
Log.d("TAG", "permission denied for the device " + device);
}
}
}
}
};
/**
* Logs the message from HidBridge.
* #param message to log.
*/
private void Log(String message) {
//LogHandler logHandler = LogHandler.getInstance();
//logHandler.WriteMessage("HidBridge: " + message, LogHandler.GetNormalColor());
Log.i("HidBridge: ", message);
}
/**
* Composes a string from byte array.
*/
private String composeString(byte[] bytes) {
StringBuilder builder = new StringBuilder();
for (byte b: bytes) {
builder.append(b);
builder.append(" ");
}
return builder.toString();
}
}

How to send and receive Voice Stream using RTP

I am new in SIP call using RTP, now I am trying to send and receive
voice streams using RTP for sip call. I am done with connecting
two emulators and able to send INVITE and INVITE-ACK using jain sip.
After I got an Ack I want to start RTP for media streaming, I use the RtpPacket
function to send and receive
I use RtpFunction to send media with all RTP header like this:
byte Version;
boolean Padding;
boolean Extension;
byte CC;
boolean Marker;
byte PayloadType;
short SequenceNumber;
int TimeStamp;
Please give some ideas and actual links where I can find an answer.
This can be achieved in a simpler manner
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audio.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioGroup = new AudioGroup();
audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
audioStream = new AudioStream(InetAddress.getByAddress(getLocalIPAddress()));
audioStream.setCodec(AudioCodec.PCMU);
audioStream.setMode(RtpStream.MODE_NORMAL);
audioStream.associate(InetAddress.getByName(SipStackAndroid.getRemoteIp()), REMOTE_PORT);
audioStream.join(audioGroup);
We send and receive RTP data using RTPpacket.
import javax.media.rtp.*;
import javax.media.rtp.rtcp.*;
import javax.media.rtp.event.*;
import javax.media.*;
import javax.media.protocol.*;
import java.net.InetAddress;
import javax.media.format.AudioFormat;
import com.sun.media.ui.*;
import java.util.Vector;
public class RTPSourceStream < RTPPlayerWindow > implements ReceiveStreamListener,
ControllerListener {
#SuppressWarnings("rawtypes")
Vector playerlist = new Vector();
#SuppressWarnings("deprecation")
SessionManager mgr = null;
boolean terminatedbyClose = false;
#SuppressWarnings("deprecation")
public SessionManager createManager(String address,
String sport,
String sttl,
boolean listener,
boolean sendlistener) {
return createManager(address,
new Integer(sport).intValue(),
new Integer(sttl).intValue(),
listener,
sendlistener);
}
#SuppressWarnings("deprecation")
public SessionManager createManager(String address,
int port,
int ttl,
boolean listener,
boolean sendlistener) {
mgr = (SessionManager) new com.sun.media.rtp.RTPSessionMgr();
if (mgr == null) return null;
mgr.addFormat(new AudioFormat(AudioFormat.DVI_RTP, 44100, 4, 1), 18);
if (listener) mgr.addReceiveStreamListener(this);
// if (sendlistener) new RTPSendStreamWindow(mgr);
// ask RTPSM to generate the local participants CNAME
String cname = mgr.generateCNAME();
String username = null;
try {
username = System.getProperty("user.name");
} catch (SecurityException e) {
username = "jmf-user";
}
// create our local Session Address
SessionAddress localaddr = new SessionAddress();
try {
InetAddress destaddr = InetAddress.getByName(address);
SessionAddress sessaddr = new SessionAddress(destaddr,
port,
destaddr,
port + 1);
SourceDescription[] userdesclist = new SourceDescription[] {
new SourceDescription(SourceDescription
.SOURCE_DESC_EMAIL,
"jmf-user#sun.com",
1,
false),
new SourceDescription(SourceDescription
.SOURCE_DESC_CNAME,
cname,
1,
false),
new
SourceDescription(SourceDescription.SOURCE_DESC_TOOL, "JMF RTP Player v2.0",
1,
false)
};
mgr.initSession(localaddr,
userdesclist,
0.05,
0.25);
mgr.startSession(sessaddr, ttl, null);
} catch (Exception e) {
System.err.println(e.getMessage());
return null;
}
return mgr;
}
public void update(ReceiveStreamEvent event) {
Player newplayer = null;
RTPPacket playerWindow = null;
// find the sourceRTPSM for this event
SessionManager source = (SessionManager) event.getSource();
// create a new player if a new recvstream is detected
if (event instanceof NewReceiveStreamEvent) {
String cname = "Java Media Player";
ReceiveStream stream = null;
try {
// get a handle over the ReceiveStream
stream = ((NewReceiveStreamEvent) event)
.getReceiveStream();
Participant part = stream.getParticipant();
if (part != null) cname = part.getCNAME();
// get a handle over the ReceiveStream datasource
DataSource dsource = stream.getDataSource();
// create a player by passing datasource to the
// Media Manager
newplayer = Manager.createPlayer(dsource);
System.out.println("created player " + newplayer);
} catch (Exception e) {
System.err.println("NewReceiveStreamEvent exception " +
e.getMessage());
return;
}
if (newplayer == null) return;
playerlist.addElement(newplayer);
newplayer.addControllerListener(this);
// send this player to player GUI
playerWindow = new RTPPacket(newplayer, cname);
}
}
public void controllerUpdate(ControllerEvent evt) {
// get a handle over controller, remove it from the player
// list.
// if player list is empty, close the sesssion manager.
if ((evt instanceof ControllerClosedEvent) ||
(evt instanceof ControllerErrorEvent) ||
(evt instanceof DeallocateEvent)) {
Player p = (Player) evt.getSourceController();
if (!terminatedbyClose) {
if (playerlist.contains(p))
playerlist.removeElement(p);
if ((playerlist.size() == 0) && (mgr != null))
mgr.closeSession("All players are closed");
}
}
}
public void closeManager() {
terminatedbyClose = true;
// first close all the players
for (int i = 0; i < playerlist.size(); i++) {
((Player) playerlist.elementAt(i)).close();
}
if (mgr != null) {
mgr.closeSession("RTP Session Terminated");
mgr = null;
}
}
class RTPPacket extends RTPSourceStream {
public RTPPacket(Player newplayer, String cname) {
// TODO Auto-generated constructor stub
}
}
}

Categories

Resources