Android USB- "could not find endpoint" - android

I'm a beginner android programmer who is trying to set up some USB functionality with my tablet and a device. My program uses an Intent filter to find the device. I took the Android's MissileLauncherActivity.java example and rewrote it. I am getting a "could not find endpoint" error in logcat. Is there something wrong with my code, or could it be my device? LogCat is finding the error in the setDevice method where it is trying to find the OUT endpoint. Here is the code:
public class UsbTestActivity extends Activity implements Runnable {
private UsbManager mUsbManager;
private UsbDevice mDevice;
private UsbDeviceConnection mConnection;
private UsbEndpoint mEndpointIntr;
private static final String TAG = "UsbTestActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
}
#Override
public void onPause(){
super.onPause();
}
#Override
public void onResume(){
super.onResume();
Intent intent = getIntent();
Log.d(TAG, "intent: " + intent);
String action = intent.getAction();
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
setDevice(device);
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
if (mDevice != null && mDevice.equals(device)) {
setDevice(null);
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
public void setDevice(UsbDevice device){
Log.d(TAG, "setDevice " + device);
if (device.getInterfaceCount() != 1) {
Log.e(TAG, "could not find interface");
return;
}
UsbInterface intf = device.getInterface(0);
// device should have one endpoint
if (intf.getEndpointCount() != 1) {
Log.e(TAG, "could not find endpoint");
return;
}
System.out.println("Got endpoint");
// endpoint should be of type interrupt
UsbEndpoint ep = intf.getEndpoint(0);
if (ep.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
Log.e(TAG, "endpoint is not interrupt type");
return;
}
mDevice = device;
mEndpointIntr = ep;
if (device != null) {
UsbDeviceConnection connection = mUsbManager.openDevice(device);
if (connection != null && connection.claimInterface(intf, true)) {
Log.d(TAG, "open SUCCESS");
mConnection = connection;
Thread thread = new Thread(this);
thread.start();
} else {
Log.d(TAG, "open FAIL");
mConnection = null;
}
}
}
private void sendCommand(int control) {
synchronized (this) {
if (mConnection != null) {
byte[] message = new byte[1];
message[0] = (byte)control;
// Send command via a control request on endpoint zero
if(mConnection.controlTransfer(0x21, 0x9, 0x200, 0, message, message.length, 0) > 0){
Log.d(TAG, "Sending Failed");
}
}
}
}
public void run() {
ByteBuffer buffer = ByteBuffer.allocate(1);
UsbRequest request = new UsbRequest();
request.initialize(mConnection, mEndpointIntr);
byte status = -1;
while (true) {
// queue a request on the interrupt endpoint
request.queue(buffer, 1);
// send poll status command
if (mConnection.requestWait() == request) {
byte newStatus = buffer.get(0);
if (newStatus != status) {
Log.d(TAG, "got status " + newStatus);
status = newStatus;
sendCommand(7);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
} else {
Log.e(TAG, "requestWait failed, exiting");
break;
}
}
}
}

// device should have one endpoint
if (intf.getEndpointCount() != 1) {
Log.e(TAG, "could not find endpoint");
return;
}
Looks like you are trying to work with a USB HID device and its OUT endpoint. But HID mandates the IN endpoint to be present - so getEndpointCount() will most likely return 2 instead of one. You will need to check which is the IN and which is OUT.

Related

Reading value of characteristic after connecting to service Bluetooth Low Energy Android

after the connection is established I want to read the value from the characteristic and save the value in a byte array.
Here is my function for the reading inside my BluetoothLeService:
public byte[] readWhiteAndIntensityCharacteristic() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return null;
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString(UuidAdresssService));
if (mCustomService == null) {
Log.w(TAG, "Custom BLE Service not found");
return null;
}
/*get the read characteristic from the service*/
BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(UUID.fromString(UuidAdresssWhiteAndIntensityCharastic));
byte[] messageByte = mReadCharacteristic.getValue();
if (messageByte != null && messageByte.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(messageByte.length);
for (byte byteChar : messageByte)
stringBuilder.append(String.format("%02X", byteChar));
s = "0x" + stringBuilder.toString();
Log.v("Scan Activity", s);
if (mBluetoothGatt.readCharacteristic(mReadCharacteristic) == false) {
Log.w(TAG, "Failed to read characteristic");
}
}
return messageByte;
}
This function get called inside my DeviceControlActivity:
public void getStartUpValue(){
Log.w(TAG, "Reading completed");}
if(mBluetoothLeService.readWhiteAndIntensityCharacteristic() == null)
{
Log.w(TAG, "FAILED Reading value failed");
}
startValue = mBluetoothLeService.readWhiteAndIntensityCharacteristic();
Log.w(TAG, "Reading completed");
}
I call the getStartUpValue function after the connection is established.
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the user interface.
mBluetoothLeService.getSupportedGattServices();
getStartUpValue();
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
The reading is failing everytime but sending values to the characteristic is no problem.
How can I fix this problem?
The solution is: mBluetoothGatt.readCharacteristic(mReadCharacteristic)
After the reading is finished a callback will be called.
Thanks to Andrew Vovk

BluetoothSocket not connecting to target device

I'm trying to connect my device to another one via Bluetooth, but when I select the device I want to connect with, I get an IOException saying
read failed, socket might closed or timeout, read ret: -1
Just to illustrate how my app works, I have a RecyclerView populated with the devices my Bluetooth scan has found, then when I click an item the app is supposed to connect with that device.
Below is my the code for my connection thread:
private val MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb")
private lateinit var device: BluetoothDevice
private lateinit var onDeviceActionListener: OnDeviceActionListener
private lateinit var socket: BluetoothSocket
fun init(device: BluetoothDevice,
onDeviceActionListener: OnDeviceActionListener): ConnectionThread {
this.device = device
this.onDeviceActionListener = onDeviceActionListener
try {
socket = device.createRfcommSocketToServiceRecord(MY_UUID)
} catch (e: IOException) {
Log.e(TAG, "Error creating socket", e)
}
return this
}
override fun run() {
try {
socket.connect()
} catch (openException: IOException) {
Log.e(TAG, "Error opening connection. Trying to close...", openException)
try {
socket.close()
} catch (closeException: IOException) {
Log.e(TAG, "Error closing socket", closeException)
}
return
}
onDeviceActionListener.onDeviceConnect(device)
}
My guess is there is something wrong with my UUID. I've tried some other values but still didn't work.
Any help will be much appreciated.
Well, I don't see exactly what you are doing wrong here. However, I have done quite a bit of Bluetooth work. More recently just focused in BLE. You should be able to discover your nearby BT devices and see their UUIDs.
I have written a helper class about 3 years ago so it's a little old, but should be mostly the same code. Happy to share it with you if it helps.
public class BluetoothConnector {
private static final String TAG = Globals.SEARCH_STRING + BluetoothConnector.class.getSimpleName();
private static final String DEFAULT_SERVER_NAME_FOR_APP = "tn_bt_default_server";
private static final int DEFAULT_DISCOVERABLE_DURATION_MS = 30000;
private static final UUID DEFAULT_UUID = UUID.fromString("6534c201-039c-4e4f-89f9-5ca8cfeb9667");
public static final int ENABLE_DISCOVER_INTENT = 1002;
protected boolean mIsToastEnabled = false; //Access from calling class to enable toasting of progress to screen if necessary
private Handler mUIHandler;
private static ServerSocketThread mServerSocketThread;
private static ClientSocketThread mClientSocketThread;
private ManageConnectionThread mManageConnectionThread;
private Context mContext;
private IBluetoothDataListener mBluetoothDataListener;
public final Object ServerSocketLock = new Object();
public final Object ClientSocketLock = new Object();
public final Object ManageConnectionLock = new Object();
public BluetoothConnector(Context context, IBluetoothDataListener listener){
this(context, new Handler(Looper.getMainLooper()), listener);
}
public BluetoothConnector(Context context, Handler UIHandler, IBluetoothDataListener listener){
Log.v(TAG, "BluetoothConnector(context=" + context + ", Handler=" + UIHandler.getClass().getSimpleName() + ", IBluetoothDataListener=" + listener.getClass().getSimpleName());
mContext = context;
mUIHandler = UIHandler;
mBluetoothDataListener = listener;
}
public void makeThisDeviceDiscoverable(Activity callingActivity){
makeThisDeviceDiscoverable(callingActivity, BluetoothAdapter.getDefaultAdapter(), DEFAULT_DISCOVERABLE_DURATION_MS);
}
public void makeThisDeviceDiscoverable(Activity callingActivity, BluetoothAdapter adapter){
makeThisDeviceDiscoverable(callingActivity, adapter, DEFAULT_DISCOVERABLE_DURATION_MS);
}
public void makeThisDeviceDiscoverable(Activity callingActivity, int durationInMs){
makeThisDeviceDiscoverable(callingActivity, BluetoothAdapter.getDefaultAdapter(), durationInMs);
}
public void makeThisDeviceDiscoverable(Activity callingActivity, BluetoothAdapter adapter, int durationInMs) {
Log.v(TAG, "makeThisDeviceDiscoverable(callingActivity=" + callingActivity.getClass().getSimpleName() + ", BluetoothAdapter=" + (adapter == null ? "null" : adapter.getName()) + ", duration=" + String.valueOf(durationInMs));
if(adapter == null){
Log.v(TAG, "adapter is null");
}else if(adapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Log.v(TAG, "Launching Activity to request Discoverable Permission");
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, durationInMs);
callingActivity.startActivityForResult(discoverableIntent, ENABLE_DISCOVER_INTENT);
}else{
Log.v(TAG, "adapter is already in SCAN MODE");
}
}
public void awaitConnectionFromDevice(){
awaitConnectionFromDevice(DEFAULT_UUID, BluetoothAdapter.getDefaultAdapter());
}
public void awaitConnectionFromDevice(UUID commonKey){
awaitConnectionFromDevice(commonKey, BluetoothAdapter.getDefaultAdapter());
}
public void awaitConnectionFromDevice(BluetoothAdapter adapter){
awaitConnectionFromDevice(DEFAULT_UUID, adapter);
}
public void awaitConnectionFromDevice(UUID commonKey, BluetoothAdapter adapter){
Log.v(TAG, "awaitConnectionFromDevice for UUID: " + String.valueOf(commonKey) + ", BluetoothAdapter=" + (adapter == null ? "null" : adapter.getName()));
cancelDiscovery();
synchronized (ServerSocketLock){
if(mServerSocketThread != null){
Log.v(TAG, "Server Socket Thread was not null so canceling current Thread");
mServerSocketThread.cancel();
}
Log.v(TAG, "Attempting to Start new ServerThread");
mServerSocketThread = new ServerSocketThread(commonKey, adapter);
mServerSocketThread.start();
}
}
public void cancelAwaitingConnectionFromDevice(){
Log.v(TAG, "cancelAwaitingConnectionFromDevice");
synchronized (ServerSocketLock){
if(mServerSocketThread != null){
mServerSocketThread.cancel();
mServerSocketThread = null;
Log.v(TAG, "canceling Server Socket Thread");
}else{
Log.v(TAG, "Server Socket null, so not canceling");
}
}
}
public void startDiscovery() {
startDiscovery(BluetoothAdapter.getDefaultAdapter());
}
public void startDiscovery(BluetoothAdapter adapter){
Log.v(TAG, "startDiscovery to find list of devices in range");
adapter.startDiscovery();
}
public void cancelDiscovery() {
cancelDiscovery(BluetoothAdapter.getDefaultAdapter());
}
public void cancelDiscovery(BluetoothAdapter adapter){
Log.v(TAG, "cancelDiscovery");
adapter.cancelDiscovery();
}
public void connectToDevice(BluetoothDevice device){
connectToDevice(device, DEFAULT_UUID);
}
public void connectToDevice(BluetoothDevice device, UUID commonKey){
Log.v(TAG, "connectToDevice(BluetoothDevice=" + (device == null ? "null" : device.getName()) + ", UUID=" + String.valueOf(commonKey));
synchronized (ClientSocketLock){
if(mClientSocketThread != null){
Log.v(TAG, "Client Socket Thread was not null so canceling current Thread");
mClientSocketThread.cancel();
}else{
Log.v(TAG, "Client Socket Thread is NULL so not canceling");
}
Log.v(TAG, "ClientSocketThread Starting");
mClientSocketThread = new ClientSocketThread(device, commonKey);
mClientSocketThread.start();
}
}
public BluetoothDevice getBluetoothDeviceByMac(String mac){
Log.v(TAG, "getBluetoothDeviceByMac(mac=" + mac);
return getBluetoothDeviceByMac(mac, BluetoothAdapter.getDefaultAdapter());
}
public BluetoothDevice getBluetoothDeviceByMac(String mac, BluetoothAdapter adapter) {
Log.v(TAG, "getBluetoothDeviceByMac(mac=" + mac + ", BluetoothAdapter=" + (adapter == null ? "null" : adapter.getName()));
return adapter.getRemoteDevice(mac);
}
public ArrayList<KeyValueModel> getPairedDevices(){
return getPairedDevices(BluetoothAdapter.getDefaultAdapter());
}
public ArrayList<KeyValueModel> getPairedDevices(BluetoothAdapter adapter){
ArrayList<KeyValueModel> bondedDevices = new ArrayList<KeyValueModel>();
Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices();
Log.v(TAG, "getPairedDevices Found " + pairedDevices.size() + " number of paired devices");
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
bondedDevices.add(new KeyValueModel(device.getAddress(), device.getName()));
}
}
return bondedDevices;
}
public static void unpairDevice(BluetoothDevice device){
Log.v(TAG, "unpairDevice");
try{
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
method.invoke(device, (Object[]) null);
}catch (Exception ex){
Log.e(TAG, "Error Unpairing Device: " + ex.getMessage());
}
}
public boolean sendDataToConnectedDevice(byte[] data){
Log.v(TAG, "sendDataToConnectedDevice");
synchronized (ManageConnectionLock){
mManageConnectionThread.write(data);
return true;
}
}
public void setBluetoothDataListener(IBluetoothDataListener listener){
mBluetoothDataListener = listener;
}
public boolean getIsConnected(){
synchronized (ManageConnectionLock) {
return mManageConnectionThread != null && mManageConnectionThread.isAlive();
}
}
private void startManageConnectionThread(BluetoothSocket socket){
Log.v(TAG, "startManageConnectionThread for Socket: " + (socket == null ? "null" : socket.getClass().getSimpleName()));
synchronized (ManageConnectionLock) {
mManageConnectionThread = new ManageConnectionThread(socket);
mManageConnectionThread.start();
}
}
private void handleDataReceivedFromConnectedDevice(final byte[] bytes){
Log.v(TAG, "handleDataReceivedFromConnectedDevice");
Log.v(TAG, "bytes to Listener: " + new String(bytes));
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if (mBluetoothDataListener != null) {
mBluetoothDataListener.onReceivedPayloadFromConnectedDevice(bytes);
}
}
});
}else{
Log.v(TAG, "UIHandler was null so skipped sending payload to listener");
}
}
private void handleConnected(){
Log.e(TAG, "handleConnected");
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onConnectedToTargetDevice();
}
}
});
}else{
Log.v(TAG, "UIHandler was null so skipped sending payload to listener");
}
}
private void handleDisconnected(){
Log.e(TAG, "handleDisconnected");
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onDisconnectedFromTargetDevice();
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void handleFailedToConnectAsServer(final Exception ex){
Log.e(TAG, "handleFailedToConnectAsServer ex: " + ex.getMessage());
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onFailedToReceiveConnectionFromTargetDevice(ex);
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void handleFailedToConnectAsClient(final Exception ex){
Log.e(TAG, "handleFailedToConnectAsClient ex: " + ex.getMessage());
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onFailedToConnectToTargetDevice(ex);
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void handleErrorInRetrievingData(final Exception ex){
Log.e(TAG, "handleErrorInRetrievingData ex: " + ex.getMessage());
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onErrorReceivingPayloadFromConnectedDevice(ex);
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void handleFailedToSendDataToConnectedDevice(final Exception ex){
Log.e(TAG, "handleFailedToSendDataToConnectedDevice ex: " + ex.getMessage());
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onFailedToSendDataToConnectedDevice(ex);
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void toastMessage(final String value){
if(!mIsToastEnabled || mUIHandler == null) {
return;
}
mUIHandler.post(new Runnable() {
#Override
public void run() {
try{
Toast.makeText(mContext, value, Toast.LENGTH_SHORT).show();
}catch(Exception ex){
Log.v(TAG, "Error Toasting, possibly bad handler, or context: " + ex.getMessage());
}
}
});
}
private class ServerSocketThread extends Thread{
private final String TAG = Globals.SEARCH_STRING + ServerSocketThread.class.getSimpleName();
private final BluetoothServerSocket mServerSocket;
public ServerSocketThread(UUID commonKey, BluetoothAdapter adapter) {
Log.v(TAG, "ServerSocketThread Constructor");
BluetoothServerSocket tmp = null;
try {
Log.v(TAG, "listening for RFComas Server: " + DEFAULT_SERVER_NAME_FOR_APP + ", and commonKey: " + String.valueOf(commonKey));
// MY_UUID is the app's UUID string, also used by the client code
tmp = adapter.listenUsingRfcommWithServiceRecord(DEFAULT_SERVER_NAME_FOR_APP, commonKey);
toastMessage("Listening for RFComm As Server on UUID: " + String.valueOf(commonKey));
} catch (IOException e) {
Log.e(TAG, "Error creating ServerSocket: " + e.getMessage());
toastMessage("Error Creating ServerSocket: " + e.getMessage());
}
mServerSocket = tmp;
}
public void run() {
Log.v(TAG, "ServerSocket run");
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (mServerSocket != null) {
try {
Log.v(TAG, "ServerSocket.accept()");
toastMessage("ServerSocket.accept()");
//Waits for Client Connection to pass Socket, then we close down
socket = mServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "ServerSocket.accept() Error: " + e.getMessage());
toastMessage("ServerSocket.accept() Error: " + e.getMessage());
handleFailedToConnectAsServer(e);
break;
}
// If a connection was accepted we don't need to keep server listening, so close unless multiple client/server connections is desired
if (socket != null) {
try{
Log.v(TAG, "ServerSocket Accepted Client Socket, Begin Listening Connect Thread");
toastMessage("ServerSocket Accepted Client Socket, Begin Listening Connect Thread");
// Do work to manage the connection (in a separate thread)
startManageConnectionThread(socket);
//mServerSocket.close();
}catch(Exception ex){
Log.e(TAG, "Exception closing Server Socket");
}
//break; //Add in Break if you want to shut down listening for connections
}else{
Log.v(TAG, "Socket wasn't accepted");
toastMessage("Socket wasn't accepted");
handleFailedToConnectAsServer(new Exception("Socket is Null"));
}
}
Log.v(TAG, "Exiting Server Accept Thread");
}
public void cancel() {
try {
Log.v(TAG, "ServerSocketThread Canceled");
mServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "ServerSocketThread Error: " + e.getMessage());
}
}
}
private class ClientSocketThread extends Thread{
private BluetoothSocket mSocket;
private final BluetoothDevice mDevice;
public ClientSocketThread(BluetoothDevice device, UUID commonKey) {
Log.v(TAG, "ClientSocketThread Constructor");
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
Log.v(TAG, "Client creating RFComm Socket to Server with UUID: " + String.valueOf(commonKey));
toastMessage("Client creating RFComm Socket to Server with UUID: " + String.valueOf(commonKey));
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(commonKey);
} catch (IOException e) {
Log.e(TAG, "Error creating Client Socket: " + e.getMessage());
toastMessage("Creating Socket Exception: " + e.getMessage());
handleFailedToConnectAsClient(e);
}
mSocket = tmp;
}
public void run() {
try {
if(mSocket == null){
Log.e(TAG, "Error Client Socket is Null, Canceling Client Thread");
return;
}
Log.v(TAG, "Client Connecting");
// Connect to the server, or timeout eventually
toastMessage("Client Connecting");
mSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and try the fallback method of reflection with port to connect
try {
Log.e("", "trying fallback...");
toastMessage("Client Connection Failed Exception: " + connectException.getMessage());
mSocket = (BluetoothSocket) mDevice.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(mDevice, 1);
toastMessage("Client Connect Again Attempt 2, but with fall back Reflection and port");
Log.v(TAG, "Client Connect Again Attempt 2, but with fall back Reflection and port");
mSocket.connect();
Log.e("", "Connected");
toastMessage("Client Connected");
} catch (Exception ex) {
Log.e("", "Couldn't establish Bluetooth connection!");
toastMessage("Client Couldn't Establish Connection to Server: " + ex.getMessage());
handleFailedToConnectAsClient(ex);
return;
}
}
// Do work to manage the connection (in a separate thread)
startManageConnectionThread(mSocket);
}
public void cancel() {
try {
Log.v(TAG, "Client Socket cancel");
mSocket.close();
} catch (IOException e) {
Log.e(TAG, "Error Closing Socket");
}
}
}
private class ManageConnectionThread extends Thread {
/////////////
// MEMBERS //
/////////////
private final String TAG = Globals.SEARCH_STRING + ManageConnectionThread.class.getSimpleName();
private final BluetoothSocket mSocket;
private final InputStream mInStream;
private final OutputStream mOutStream;
//////////////////
// CONSTRUCTOR //
//////////////////
public ManageConnectionThread(BluetoothSocket socket) {
mSocket = socket;
handleConnected();
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
try {
Log.v(TAG, "ManageConnectionThread Constructor");
Log.v(TAG, "Connected to Socket = " + String.valueOf(socket.isConnected()));
toastMessage("Listening for input or output Stream");
Log.v(TAG, "Get InputStream");
tmpIn = socket.getInputStream();
Log.v(TAG, "Get OutputStream");
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error getting Socket Streams: " + e.getMessage());
toastMessage("Connect Thread: Error: " + e.getMessage());
handleErrorInRetrievingData(e);
}
mInStream = tmpIn;
mOutStream = tmpOut;
}
///////////////
// OVERRIDES //
///////////////
public void run() {
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
byte[] data = new byte[16384];
int nRead;
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while ((nRead = mInStream.read(data, 0, data.length)) != -1) {
//Log.v(TAG, "bytes Read: " + String.valueOf(nRead));
buffer.write(data, 0, nRead);
//TODO Find better way to find End Of Message rather than looking for }
String temp = new String(buffer.toByteArray());
//Log.v(TAG, "current Data: " + temp);
if(temp.contains("}")){
Log.v(TAG, "bytes reading complete");
handleDataReceivedFromConnectedDevice(buffer.toByteArray());
buffer.flush();
buffer = new ByteArrayOutputStream();
}else{
Log.v(TAG, "More bytes Available");
}
}
} catch (IOException e) {
Log.e(TAG, "Error reading inputStream");
handleErrorInRetrievingData(e);
break;
}
}
Log.v(TAG, "Exiting Managed Connection Thread");
handleDisconnected();
}
/////////////
// METHODS //
/////////////
public void write(byte[] bytes) {
try {
Log.v(TAG, "ManageConnectionThread write(bytes)");
mOutStream.write(bytes);
} catch (IOException e) {
Log.e(TAG, "Error Writing Stream: " + e.getMessage());
handleFailedToSendDataToConnectedDevice(e);
}
}
public void cancel() {
try {
Log.v(TAG, "ManageConnectionThread cancel");
handleDisconnected();
mSocket.close();
} catch (IOException e) {
Log.e(TAG, "Error Closing BluetoothSocket: " + e.getMessage());
}
}
}
public interface IBluetoothDataListener{
//////////////////////
// OVERRIDE METHODS //
//////////////////////
void onReceivedPayloadFromConnectedDevice(byte[] payload);
void onErrorReceivingPayloadFromConnectedDevice(Exception ex);
void onFailedToConnectToTargetDevice(Exception ex);
void onFailedToReceiveConnectionFromTargetDevice(Exception ex);
void onFailedToSendDataToConnectedDevice(Exception ex);
void onConnectedToTargetDevice();
void onDisconnectedFromTargetDevice();
}
}
Then of course you will want to make sure you have your broadcast receivers setup:
<receiver
android:name=".receivers.BluetoothChangedReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
<action android:name="android.bluetooth.adapter.action.SCAN_MODE_CHANGED" />
<action android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
<action android:name="android.bluetooth.adapter.action.DISCOVERY_FINISHED" />
<action android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
<action android:name="android.bluetooth.device.action.FOUND" />
<action android:name="android.bluetooth.device.action.DISAPPEARED" />
</intent-filter>
</receiver>
<receiver
android:name=".receivers.BluetoothDeviceReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.bluetooth.device.action.FOUND" />
<action android:name="android.bluetooth.device.action.DISAPPEARED" />
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
<action android:name="android.bluetooth.device.action.ACTION_ACL_DISCONNECT_REQUESTED" />
<action android:name="android.bluetooth.device.action.BOND_STATE_CHANGED" />
<action android:name="android.bluetooth.device.action.UUID" />
</intent-filter>
</receiver>

How to retrieve packet in a VpnService

I have the following implementation of ToyVpnService which I got frome here
public class ToyVpnService extends VpnService implements Handler.Callback, Runnable {
private static final String TAG = "ToyVpnService";
private Handler mHandler;
private Thread mThread;
private ParcelFileDescriptor mInterface;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The handler is only used to show messages.
if (mHandler == null) {
mHandler = new Handler(this);
}
// Stop the previous session by interrupting the thread.
if (mThread != null) {
mThread.interrupt();
}
// Start a new session by creating a new thread.
mThread = new Thread(this, "ToyVpnThread");
mThread.start();
return START_STICKY;
}
#Override
public void onDestroy() {
if (mThread != null) {
mThread.interrupt();
}
}
#Override
public boolean handleMessage(Message message) {
if (message != null) {
Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show();
}
return true;
}
#Override
public synchronized void run() {
Log.i(TAG, "running vpnService");
try {
runVpnConnection();
} catch (Exception e) {
e.printStackTrace();
//Log.e(TAG, "Got " + e.toString());
} finally {
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
mInterface = null;
mHandler.sendEmptyMessage(R.string.disconnected);
Log.i(TAG, "Exiting");
}
}
private boolean runVpnConnection() throws Exception {
configure();
FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
// Allocate the buffer for a single packet.
ByteBuffer packet = ByteBuffer.allocate(32767);
// We keep forwarding packets till something goes wrong.
while (true) {
// Assume that we did not make any progress in this iteration.
boolean idle = true;
// Read the outgoing packet from the input stream.
int length = in.read(packet.array());
if (length > 0) {
Log.i(TAG, "************new packet");
System.exit(-1);
while (packet.hasRemaining()) {
Log.i(TAG, "" + packet.get());
//System.out.print((char) packet.get());
}
packet.limit(length);
// tunnel.write(packet);
packet.clear();
// There might be more outgoing packets.
idle = false;
}
Thread.sleep(50);
}
}
public String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
Log.i(TAG, "****** INET ADDRESS ******");
Log.i(TAG, "address: " + inetAddress.getHostAddress());
Log.i(TAG, "hostname: " + inetAddress.getHostName());
Log.i(TAG, "address.toString(): " + inetAddress.getHostAddress().toString());
if (!inetAddress.isLoopbackAddress()) {
//IPAddresses.setText(inetAddress.getHostAddress().toString());
Log.i(TAG, "IS NOT LOOPBACK ADDRESS: " + inetAddress.getHostAddress().toString());
return inetAddress.getHostAddress().toString();
} else {
Log.i(TAG, "It is a loopback address");
}
}
}
} catch (SocketException ex) {
String LOG_TAG = null;
Log.e(LOG_TAG, ex.toString());
}
return null;
}
private void configure() throws Exception {
// If the old interface has exactly the same parameters, use it!
if (mInterface != null) {
Log.i(TAG, "Using the previous interface");
return;
}
// Configure a builder while parsing the parameters.
Builder builder = new Builder();
builder.setMtu(1500);
builder.addAddress(getLocalIpAddress(), 24);
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
mInterface = builder.establish();
}
}
It seems to be receiving packets but I have no idea on how to read the data in the paclkets. the code seems to be incomplete (hence the tunnel.write(packet) that's commented out cause there isn't a variable tunnel). Is this the right way? or is there a better way of doing this?

android usb UsbDeviceConnection.bulkTransfer returns -1

I am trying to send commands to a POS printer from my android tablet. I have been able to get the basic connections wroking but now when I try to send data to the printer, the bulkTransfer returns -1. Please help me understand what is going on. The following is a modified broadcast receiver taken from the android site where I do all the data transfer.
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
if(device.getVendorId() != 1659)
return;
UsbInterface intf = device.getInterface(0);
UsbEndpoint endpoint = intf.getEndpoint(0);
int direction = endpoint.getDirection();
UsbDeviceConnection connection = mUsbManager.openDevice(device);
connection.claimInterface(intf, forceClaim);
bytes = new byte[]{27, 64};
//**This returns -1 always**
int ret = connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT);
if(ret < 0)
{
Log.d("WTF", "Error happened!");
}
else if(ret == 0)
{
Log.d("WTF", "No data transferred!");
}
else
{
Log.d("WTF", "success!");
}
}
}
else {
Log.d(TAG, "permission denied for device " + device);
}
}
}
}
};

communication between android and fpga board

I am trying to transfer data from my android device to FPGA board. The android device supports the USB host mode and the connected FPGA board uses RS_232 port. So I got a USB-RS232 converter device(CP210x) for the connection. I coded the transfer as mentioned on this page: http://developer.android.com/guide/topics/connectivity/usb/host.html My code is:
public class MainActivity extends Activity
implements View.OnClickListener, Runnable {
private static final String TAG = "TransferData";
private Button sendB;
private UsbManager mUsbManager;
private UsbDevice mDevice;
private UsbDeviceConnection mConnection;
private UsbEndpoint mEndpointIntr;
private static final char DATA = 'A';
static UsbDevice device;
static int TIMEOUT = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendB = (Button)findViewById(R.id.send);
sendB.setOnClickListener(this);
mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
Log.d(TAG, "intent: " + intent);
String action = intent.getAction();
device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
setDevice(device);
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
if (mDevice != null && mDevice.equals(device)) {
setDevice(null);
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
private void setDevice(UsbDevice device) {
Log.d(TAG, "setDevice " + device);
if (device.getInterfaceCount() != 1) {
Log.e(TAG, "could not find interface");
return;
}
else Log.w(TAG, "found interface");
UsbInterface intf = device.getInterface(0);
// device should have one endpoint
if (intf.getEndpointCount() == 0) {
Log.e(TAG, "could not find endpoint");
return;
}
else Log.w(TAG, "found endpoint");
// endpoint should be of type interrupt
Log.w("endpoint", "" + intf.getEndpointCount());
UsbEndpoint ep = intf.getEndpoint(1);
if (ep.getType() != UsbConstants.USB_ENDPOINT_XFER_BULK) {
Log.e(TAG, "endpoint is not interrupt type");
return;
}
else Log.w(TAG, "endpoint is interrupt");
mDevice = device;
mEndpointIntr = ep;
if (device != null) {
UsbDeviceConnection connection = mUsbManager.openDevice(device);
if (connection != null && connection.claimInterface(intf, true)) {
Log.d(TAG, "open SUCCESS");
mConnection = connection;
Thread thread = new Thread(this);
thread.start();
} else {
Log.d(TAG, "open FAIL");
mConnection = null;
}
}
}
private void sendCommand(char control) {
if (mConnection != null) {
byte[] message = new byte[1];
message[0] = (byte)control;
// Send command via a control request on endpoint zero
UsbInterface intf = device.getInterface(0);
UsbEndpoint endpoint = intf.getEndpoint(1);
mConnection.claimInterface(intf,true);
int res = mConnection.bulkTransfer(endpoint, message, message.length, TIMEOUT);
Log.w("data sent","result " + res);
}
}
public void onClick(View v) {
if (v == sendB) {
sendCommand(DATA);
}
}
#Override
public void run() {
ByteBuffer buffer = ByteBuffer.allocate(1);
UsbRequest request = new UsbRequest();
request.initialize(mConnection, mEndpointIntr);
byte status = -1;
request.queue(buffer, 1);
// send poll status command
sendCommand(DATA);
// wait for status event
if (mConnection.requestWait() == request) {
byte newStatus = buffer.get(0);
if (newStatus != status) {
Log.d(TAG, "got status " + newStatus);
status = newStatus;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
} else {
Log.e(TAG, "requestWait failed, exiting");
}
}
I get success in opening device and I get send result as 1. But no data received is reflected as the FPGA board. What am I doing wromg?
Try to switch RX with TX on FPGA. Did other communcation work with this connection?
Is there a design on the FPGA which will serve the UART?

Categories

Resources