1
votes

I'm having problems connecting to a WML-C46 AH Bluetooth Chip using an insecure RFCOMM connection. I wrote an android app with just the relevant code to show you my problem.

The App

The app has just one button. If you click on this button a bluetooth device discovery is started. After the discovery has finished the app connects to the bluetooth device (I'm using just one bluetooth device for testing, so it can't find any other devices). It then opens an inputstream to read the data of this device. If the connection breaks (ioexception is thrown) or the button is clicked again, the connection is shut down (closing all threads, sockets and streams). If you click on the button again a new device discovery is started and so on...

The Problem

The connection doesn't work properly. The data inputstream seems to be a little bit laggy and sometimes the connection breaks without any observable reason (IOException: Software caused connection abort or IOException: Try again). It's pretty much a simplified version of the android bluetooth chat sample which uses device discovery instead of paired devices and just one activity.

The Code

public class MainActivity extends Activity implements View.OnClickListener {

    BluetoothDevice btDevice;
    BluetoothSocket btSocket;
    InputStream inStream;
    OutputStream outStream;
    Object lock = new Object();
    boolean connected = false;
    boolean canceled = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        getApplicationContext().registerReceiver(btReceiver, filter);
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        getApplicationContext().registerReceiver(btReceiver, filter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onClick(View arg0) {
        if (!connected) {
            connected = true;
            canceled = false;

            new Thread(new Runnable() {
                @Override
                public void run() {
                    BluetoothAdapter btAdapter = BluetoothAdapter
                            .getDefaultAdapter();

                    try {
                        if (btAdapter.isDiscovering())
                            btAdapter.cancelDiscovery();
                        btAdapter.startDiscovery();

                        // block until device discovery has finished
                        synchronized (lock) {
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                Log.d("EXCEPTION", "", e);
                            }
                        }

                        btSocket = btDevice.createInsecureRfcommSocketToServiceRecord(UUID
                                .fromString("00001101-0000-1000-8000-00805F9B34FB"));
                        btSocket.connect();

                        inStream = btSocket.getInputStream();
                        outStream = btSocket.getOutputStream();

                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                while (!canceled) {
                                    try {
                                        int in;
                                        while ((in = inStream.read()) != -1) {
                                            Log.d("Received new byte: ", in
                                                    + "");
                                        }
                                    } catch (IOException e) {
                                        Log.d("EXCEPTION IN LISTENER", "", e);
                                        disconnect();
                                    }
                                }
                            }
                        }).start();
                    } catch (IOException e) {
                        Log.d("", "", e);
                    }
                }
            }).start();
        } else {
            disconnect();
        }
    }

    private void disconnect() {
        connected = false;
        canceled = true;

        try {
            btSocket.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }
        try {
            inStream.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }
        try {
            outStream.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }

        btDevice = null;
        btSocket = null;
        inStream = null;
        outStream = null;
    }

    private final BroadcastReceiver btReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            try {
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    synchronized (lock) {
                        lock.notifyAll();
                    }
                }
            } catch (Exception e) {
                Log.d(this.getClass().getName(), "", e);
            }
        }
    };
}

I'm only using blocking methods or do the blocking by myself. So the connection establishment works pretty procedural. I've probably lost the connection flow of the android example when I adapted it but I can't find the problem.

The Output

Establishing the connection:

01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketNative
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): ...fd 47 created (RFCOMM, lm = 0)
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketFromFdNative
01-16 16:52:46.257: D/BluetoothUtils(6961): isSocketAllowedBySecurityPolicy start : device null
01-16 16:52:47.171: V/BluetoothSocket.cpp(6961): connectNative
01-16 16:52:47.570: V/BluetoothSocket.cpp(6961): ...connect(47, RFCOMM) = 0 (errno 115)

Connection breaks:

01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): java.io.IOException: Software caused connection abort
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothSocket.readNative(Native Method)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:388)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:60)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at com.example.bttest.MainActivity$2$1.run(MainActivity.java:100)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at java.lang.Thread.run(Thread.java:856)

Thanks!

1

1 Answers

0
votes

Found the problem. The bluetooth device didn't work as expected and shut the connection down after some seconds. The code however works just fine.