Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Bluetooth Server socket will be blocked on accept() if it processes more than one conntion

I have studied the android bluetooth example.
What I'm confused is that other devices has sent a connection request, and the server is just blocked so long without accepted if previous connection exsited.

Is it possible for an android device which can perform a server socket and accept many connections rather than just one connection? Is there any reason might cause the server which is blocked by accept(), for example, incorrect UUID, or something like that?

I do the operation as follows,

  1. For first connection, create the server socket and wait for the connection
  2. client B send the connection request
  3. server socket accept
  4. process the i/o stream
  5. use the same serversocket to wait for the connection again (I don't close the serversocket)
  6. client C send the connection request
  7. server socket is blocked, blocked, blocked, rather than accepted...

Because the first connection is successful, and I don't change the UUID on second connection. So I think the UUID is not the key. When first connection is established, server socket will wait for another connection. Sadly, it just waits and blocked, not accepts as first connection.

public void run() {
    if (D) Log.d(TAG, "BEGIN ServerSocketThread" + this);
    BluetoothSocket socket = null;
    while(true) {
        try {
            Log.i(TAG, "[ServerSocketThread] Enter while loop");
            socket = mmServerSocket.accept();                                     
            Log.i(TAG, "[ServerSocketThread] Got client socket");                    
        } catch (IOException e) {
            Log.e(TAG, "accept() failed", e);
            break;
        }

        if (socket!=null) {
            synchronized (BluetoothConnService.this) {                       
                Log.i(TAG, "[ServerSocketThread] "+socket.getRemoteDevice()+" is connected.");
                ConnectedThread tmpThread = new ConnectedThread(socket); 
                tmpThread.start();
                break;
            }
        }

    }   
    BluetoothConnService.this.startSession();
}

It is a part of the server socket thread. Whenever I want to make a second connection, the logcat shows it will stop after the log "[ServerSocketThread] Enter while loop." It seems the operation is blocked on accept(), but the serversocket didn't throws the IOException for mmServerSocket.accept().

I have no idea why the socket neither be accepted nor throws exception, just blocked there, if I want to make a second connection. I'm appreciated if any possible reason or any suggestion.

Here is some catlog when I run the application. I hope it is helpful for identify the problem.

Part A : It is a successful connection and a first connection

12-12 22:42:05.358: DEBUG/BluetoothSppPort(889): Creating a BluetoothSpp proxy object
12-12 22:42:05.378: DEBUG/BluetoothSppService(122): createPort called!
12-12 22:42:05.378: DEBUG/BluetoothSppService(122): createPort checking uuid
12-12 22:42:05.388: DEBUG/BluetoothSppService(122): createPort UUID=00001101-0000-1000-8000-00805f9b34fb auth=true encrypt=true
12-12 22:42:05.388: DEBUG/BluetoothSppService(122): createPort enforcing bluetooth perm
12-12 22:42:05.388: DEBUG/BluetoothSppService(122): createPort creating a jbtlspp object
12-12 22:42:05.388: DEBUG/BluetoothSppService(122): createPort checking if the btl spp object is valid
12-12 22:42:05.388: DEBUG/BluetoothSppService(122): createPort try to create an spp container
12-12 22:42:05.388: DEBUG/BluetoothSppService(122): createPort try to create security params
12-12 22:42:05.388: DEBUG/BluetoothSppService(122): createPort Set Security L2
12-12 22:42:05.388: DEBUG/BluetoothSppService(122): createPort spp port create
12-12 22:42:05.418: DEBUG/JBtlSpp(122): create: Entered
12-12 22:42:05.418: DEBUG/JBtlSpp(122): Calling NativeJBtlSpp_Create
12-12 22:42:05.418: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Create: Entered
12-12 22:42:05.418: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Create: Calling BTL_SPP_Remote_Create
12-12 22:42:05.598: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Create: BTL_SPP_Remote_Create returned 0, context:f
12-12 22:42:05.598: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Create: Setting context value in jContext out parm
12-12 22:42:05.598: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Create: Calling Java setValue(0xf) in context's class
12-12 22:42:05.598: DEBUG/JBtlProfileContext(122): setValue: setValue called, value:15
12-12 22:42:05.598: DEBUG/JBtlSppNative(122): create_spp_port_data: will use context struct 0 for the port 15
12-12 22:42:05.608: DEBUG/JBtlSppNative(122): create_spp_port_data: spp port context 0 added
12-12 22:42:05.608: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Create:Exiting Successfully
12-12 22:42:05.778: DEBUG/JBtlSpp(122): After NativeJBtlSpp_Create, status=SUCCESS, Context = 15
12-12 22:42:05.778: DEBUG/JBtlRbtlServices(122): addUser: Entered, userRefCount = 1
12-12 22:42:05.778: DEBUG/BluetoothSppService(122): port create returned status SUCCESS
12-12 22:42:05.778: DEBUG/JBtlSpp(122): enable: Entered
12-12 22:42:05.778: DEBUG/JBtlSpp(122): enable: UUID=00001101-0000-1000-8000-00805f9b34fb
12-12 22:42:05.778: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Enable: Entered
12-12 22:42:05.978: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Enable: BTL_SPP_Enable returned 0
12-12 22:42:05.978: DEBUG/JBtlSppNative(122): NativeJBtlSpp_Enable:Exiting
12-12 22:42:05.978: DEBUG/JBtlSpp(122): After NativeJBtlSpp_Enable, status=SUCCESS
12-12 22:42:05.978: DEBUG/JBtlSpp(122): enable: Exiting
12-12 22:42:05.978: DEBUG/BluetoothSppService(122): port enable returned status SUCCESS
12-12 22:42:57.678: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_OPEN_IND: Entered
12-12 22:42:57.678: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_OPEN_IND: Exiting
12-12 22:42:57.678: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_OPEN: Entered
12-12 22:42:57.678: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_OPEN: status: 0 context:15
12-12 22:42:57.708: DEBUG/JBtlSpp(122): nativeCb_open: Entered from 00:10:60:56:83:28
12-12 22:42:57.718: DEBUG/JBtlSpp(122): nativeCb_open: Calling callback
12-12 22:42:57.718: DEBUG/BluetoothSppService(122): connected called!
12-12 22:42:57.718: DEBUG/BluetoothSocket(889): SppPort connected()
12-12 22:42:57.718: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_OPEN: Exiting
12-12 22:42:57.718: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_MODEM_STATUS_IND: Entered
12-12 22:42:57.718: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_MODEM_STATUS_IND: Exiting

Part B : It is second connection, and it lets the serversocket blocked without accepted.

It looks like that it didn't run the BluetoothSppService like part A. But BluetoothSppService is lower layer on andorid framework, therefore I don't know how to handle.

12-12 22:43:29.158: DEBUG/(122): signal_BTEVENT_LINK_CONNECT_IND: Entered
12-12 22:43:29.168: DEBUG/(122): signal_BTEVENT_LINK_CONNECT_IND: context: 1, errCode: 0
12-12 22:43:29.168: DEBUG/(122): signal_BTEVENT_LINK_CONNECT_IND: Calling Java Link Connect Indication callback
12-12 22:43:29.178: DEBUG/JBtlBmg(122): nativeLinkConnectInd
12-12 22:43:29.218: DEBUG/BluetoothService(122): Callback - linkConnectInd, btErrCode = NO_ERROR, bdAddr = C0:E4:22:18:ED:C1
12-12 22:43:29.258: DEBUG/JBtlBmg(122): getKnownDeviceInfo: Entered
12-12 22:43:29.258: DEBUG/JBtlBmg(122): getKnownDeviceInfo: Calling NativeJBtlBmg_GetKnownDeviceInfo
12-12 22:43:29.258: DEBUG/(122): NativeJBtlBmg_GetKnownDeviceInfo: Entered
12-12 22:43:29.258: DEBUG/(122): NativeJBtlBmg_GetKnownDeviceInfo: Calling BTL_BMG_GetKnownDeviceInfo
12-12 22:43:29.268: DEBUG/JBtlBmgJniKnownDeviceInfo(122): setValues: Entered
12-12 22:43:29.268: DEBUG/(122): NativeJBtlBmg_GetKnownDeviceInfo:Exiting
12-12 22:43:29.268: DEBUG/JBtlBmg(122): getKnownDeviceInfo: After NativeJBtlBmg_GetKnownDeviceInfo, status=SUCCESS
12-12 22:43:29.278: DEBUG/JBtlBmg(122): getKnownDeviceInfo: Exiting
12-12 22:43:29.278: DEBUG/BluetoothService(122): onRemoteDeviceConnected, device C0:E4:22:18:ED:C1 is Paired
12-12 22:43:29.278: DEBUG/BluetoothService(122): Sending ACTION_ACL_CONNECTED intent, address = C0:E4:22:18:ED:C1
12-12 22:43:29.278: DEBUG/BluetoothA2dpService(122): Received intent with action: android.bluetooth.device.action.ACL_CONNECTED
12-12 22:43:29.298: DEBUG/(122): signal_BTEVENT_LINK_CONNECT_IND: Exiting
12-12 22:43:29.988: DEBUG/(122): signal_BTEVENT_LINK_DISCONNECT: Entered
12-12 22:43:29.988: DEBUG/(122): signal_BTEVENT_LINK_DISCONNECT: context: 1, errCode: 19
12-12 22:43:29.988: DEBUG/(122): signal_BTEVENT_LINK_DISCONNECT: Calling Java Link Disconnect callback
12-12 22:43:29.988: DEBUG/JBtlBmg(122): nativeLinkDisconnect
12-12 22:43:29.998: DEBUG/BluetoothService(122): Callback - linkDisconnect, btErrCode = USER_TERMINATED, bdAddr = C0:E4:22:18:ED:C1, status = NO_ERROR
12-12 22:43:30.018: DEBUG/BluetoothService(122): Sending ACTION_ACL_DISCONNECTED intent, address = C0:E4:22:18:ED:C1

Part C: If I disconnted the previous existed connection, it will run as follows. And then run the part A. So I can establish a conntion again.

Creating a BluetoothSpp proxy object, and perform BluetoothSppService.

12-12 22:45:45.758: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_MODEM_STATUS_IND: Entered
12-12 22:45:45.758: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_MODEM_STATUS_IND: Exiting
12-12 22:45:45.788: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_CLOSE_IND: Entered
12-12 22:45:45.788: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_CLOSE_IND: Exiting
12-12 22:45:45.798: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_CLOSED: Entered
12-12 22:45:45.798: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_CLOSED: status: 0 context:15
12-12 22:45:45.798: DEBUG/JBtlSpp(122): nativeCb_closed: Entered
12-12 22:45:45.798: DEBUG/BluetoothSppService(122): close called!
12-12 22:45:45.798: DEBUG/JBtlSppNative(122): signal_SPP_EVENT_CLOSED: Exiting
12-12 22:45:46.158: DEBUG/JBtlSppNative(122): NativeJBtlSpp_ReadNative:Exiting with 1

It seems the logcat should like part A, the conntion can be established. I doubted the reason why the server socket was blocked without accept is that these operations are handled by the lower level of android platform. But I don't know how to get or how to perform this service, such as BluetoothSppService, JBtlSppNative, JBtlBmg, etc.

Do you have any experience with that?
If yes, I'm appreciated if you can share with me. Or give me some hints or suggestions about how to let the device can accept another connection if pervious connection has existed.

like image 818
Fiona Avatar asked Dec 13 '10 03:12

Fiona


People also ask

How to connect Bluetooth socket in android?

To create a BluetoothSocket for connecting to a known device, use BluetoothDevice. createRfcommSocketToServiceRecord() . Then call connect() to attempt a connection to the remote device. This call will block until a connection is established or the connection fails.

What is the purpose of the Bluetooth server socket?

The interface for Bluetooth Sockets is similar to that of TCP sockets: Socket and ServerSocket . On the server side, use a BluetoothServerSocket to create a listening server socket. When a connection is accepted by the BluetoothServerSocket , it will return a new BluetoothSocket to manage the connection.

Does android support Bluetooth spp?

Android allows communication with Bluetooth devices which have SPP.

Is ServerSocket accept blocking?

accept() is a blocking one. There must be a smart way to get around this.


1 Answers

Sorry, unlike TCP Sockets, Bluetooth Welcome Server Sockets are meant to accept only a single client.

From Google:

Unlike TCP/IP, RFCOMM only allows one connected client per channel at a time, so in most cases it makes sense to call close() on the BluetoothServerSocket immediately after accepting a connected socket.

like image 92
Behnam Avatar answered Oct 06 '22 04:10

Behnam