How to create programmatically an A2DP connection or how can I emulate an Android phone to be an A2DP sink?

12,008

You cannot do it over RFCOMM / SPP - Connecting to A2DP UUID is not enough - the Profile connection / profile level protocol procedures need to be done to implement A2DP - more over A2DP directly works over L2CAP protocol (and does not require RFCOMM).

You may-not be able to do it manually between 2 phones also because to stream one device needs to be A2DP sink and other other A2DP source, Phones are typically only Source devices (Source of the stream that can stream to sink devices) , Sinks are Headsets or Bluetooth speakers.

Share:
12,008
Admin
Author by

Admin

Updated on June 05, 2022

Comments

  • Admin
    Admin almost 2 years

    I have two android phones (Samsung Galaxy Tab and HTC Desire). Both 2.2. The Galaxy Tab should be an A2DP sink and the Desire the source. My aim is to route the sound of the Desire to the Galaxy. I just saw in the API that it is possible to establish a RFCOMM connection. But I want to establish an A2DP connection. My requirements to the solution is that none of the phones should be rooted.

    I found in the source code the Bluetooth UUID class. And I tried to open a A2DP Connection with the UUIDs.

    This is the code of the server side:

    private class AcceptThread extends Thread {
      public AcceptThread() {
           try {
           BluetoothServerSocket mmServerSocket = btAdapter.listenUsingRfcommWithServiceRecord("Audio Sink", UUID.fromString("0000110B-0000-1000-8000-00805F9B34FB")); // UUID of Audio sink
           mmServerSocket = btAdapter.listenUsingRfcommWithServiceRecord(
        "AVCRP Controller", UUID.fromString("0000110E-0000-1000-8000-00805F9B34FB")); // UUID of AVCRP Controller                
    
        } catch (IOException e) {
        }
    }
    
       public void run() {
    // Keep listening until exception occurs or a socket is returned
    while (true) {
    try {
             socket = mmServerSocket.accept();
    
    } catch (IOException e) {
        break;
    }
    // If a connection was accepted
    if (socket != null) {
        try {
        mmServerSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
        }
    

    Code of the client side:

    Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
    tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
    

    I could pair both devices and could create a connection. If I go to the bluetooth settings of the Desire and long press on the Galaxy Tab, I have the menu OPTIONS. I can see the media profile. Then if tried to check the connection box to connect the device with the selected profiles I get following log:

    04-11 17:21:18.994: DEBUG/DTUN_HCID4(1233):         dtun_client_get_remote_services()
    04-11 17:21:18.994: INFO/DTUN_HCID4(1233): dtun_client_get_remote_services: Get remote services on 
    04-11 17:21:18.994: INFO/DTUN_CLNT(1233):     Client calling DTUN_METHOD_DM_GET_REMOTE_SERVICES (id 5)
    04-11 17:21:18.994: INFO/(1220): DTUN_ReceiveCtrlMsg: [DTUN] Received message [BTLIF_DTUN_METHOD_CALL] 4354
    04-11 17:21:18.994: INFO/(1220): handle_method_call: handle_method_call :: received DTUN_METHOD_DM_GET_REMOTE_SERVICES (id 5), len 6
    04-11 17:21:18.994: ERROR/BTLD(1220): ****************search UUID = 1108***********
    04-11 17:21:18.994: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:19.005: INFO//system/bin/btld(1219):         btapp_dm_GetRemoteServices()
    04-11 17:21:19.005: INFO//system/bin/btld(1219): ##### USerial_Ioctl: BT_Wake, 0x8003 ####
    04-11 17:21:19.125: WARN/BTLD(1220): process_service_search_attr_rsp
    04-11 17:21:19.144: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:19.155: ERROR/BTLD(1220): ****************search UUID = 111e***********
    04-11 17:21:19.155: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:19.287: WARN/BTLD(1220): process_service_search_attr_rsp
    04-11 17:21:19.287: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:19.336: ERROR/BTLD(1220): ****************search UUID = 110b***********
    04-11 17:21:19.336: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:19.474: WARN/BTLD(1220): process_service_search_attr_rsp
    04-11 17:21:19.474: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:19.534: INFO/BTL-IFS(1220): send_ctrl_msg: [BTL_IFS CTRL] send BTLIF_DTUN_SIGNAL_EVT (CTRL) 14 pbytes (hdl 15)
    04-11 17:21:19.534: INFO/DTUN_HCID4(1233): dtun_dm_sig_rmt_services: success=1, service=00040040
    04-11 17:21:19.534: DEBUG/DTUN_HCID4(1233): Adding UUID 0000111E-0000-1000-8000-00805F9B34FB
    04-11 17:21:19.534: DEBUG/DEVICE(1233): Just add the profiles for /org/bluez/1233/hci0/dev_xx_xx_xx_xx_xx_xx
    04-11 17:21:19.534: INFO/DTUN_HCID4(1233): Adding uuid 0000111E-0000-1000-8000-00805F9B34FB
    04-11 17:21:19.534: DEBUG/DTUN_HCID4(1233): Adding UUID 0000110B-0000-1000-8000-00805F9B34FB
    04-11 17:21:19.534: DEBUG/DEVICE(1233): Just add the profiles for /org/bluez/1233/hci0/dev_xx_xx_xx_x_xx_xx
    04-11 17:21:19.534: INFO/DTUN_HCID4(1233): Adding uuid 0000110B-0000-1000-8000-00805F9B34FB
    04-11 17:21:19.534: INFO/DTUN_HCID4(1233): Calling sink_init
    04-11 17:21:19.534: DEBUG/ADAPTER(1233): adapter_get_device(Xx:xx:xx:xx:xx:xx)
    04-11 17:21:19.534: DEBUG/DEVICE(1233): btd_device_ref(0xfa10): ref=2
    04-11 17:21:19.534: INFO/DTUN_HCID4(1233): sink_init
    04-11 17:21:19.534: DEBUG/DTUN_HCID4(1233): Registered interface org.bluez.AudioSink on path /org/bluez/1233/hci0/dev_xx_xx_xx_xx_xx_xx
    04-11 17:21:19.544: ERROR/BluetoothEventLoop.cpp(96): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/1233/hci0/dev_xx_xx_xx_xx_xx_xx
    04-11 17:21:19.544: DEBUG/BluetoothService(96): updateDeviceServiceChannelCache(xx:xx:xx:xx:xx:xx)
    04-11 17:21:19.554: INFO/DEVICE(1233): pattern = 0000111e-0000-1000-8000-00805f9b34fb, id = 4
    04-11 17:21:19.564: DEBUG/BluetoothService(96):     uuid(system): 0000111e-0000-1000-8000-00805f9b34fb 4382
    04-11 17:21:19.574: VERBOSE/BluetoothEventRedirector(492): Received android.bleutooth.device.action.UUID
    04-11 17:21:19.700: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:20.615: INFO//system/bin/btld(1219): ##### USerial_Ioctl: BT_Sleep, 0x8004 ####
    04-11 17:21:24.634: DEBUG/dalvikvm(594): GC_EXPLICIT freed 46 objects / 2320 bytes in 50ms
    04-11 17:21:24.675: INFO/System.out(1336): public android.bluetooth.BluetoothA2dp(android.content.Context)
    04-11 17:21:24.684: DEBUG/BluetoothA2dpService(96): connectSink(xx:xx:xx:xx:xx:xx)
    04-11 17:21:24.684: INFO/BluetoothA2dpService(96): checkSinkSuspendState() : state = 1 prevState = 0
    04-11 17:21:24.684: INFO/BluetoothA2dpService(96): checkSinkSuspendState() : mTargetA2dpState = -1
    04-11 17:21:24.684: INFO/BluetoothA2dpService(96): checkSinkSuspendState() : initialStart = false initialSuspend = false
    04-11 17:21:24.694: VERBOSE/BluetoothEventRedirector(492): Received android.bluetooth.a2dp.action.SINK_STATE_CHANGED
    04-11 17:21:24.694: DEBUG/CachedBluetoothDevice(492): onProfileStateChanged:[]
    04-11 17:21:24.705: DEBUG/BluetoothA2dpService(96): A2DP state : device: BC:47:60:0F:4B:F3 State:0->1
    04-11 17:21:24.705: INFO/DTUN_CLNT(1233):     Client calling DTUN_METHOD_AM_AV_OPEN (id 20)
    04-11 17:21:24.705: INFO/(1220): DTUN_ReceiveCtrlMsg: [DTUN] Received message [BTLIF_DTUN_METHOD_CALL] 4354
    04-11 17:21:24.705: INFO/(1220): handle_method_call: handle_method_call :: received DTUN_METHOD_AM_AV_OPEN (id 20), len 6
    04-11 17:21:24.705: ERROR/BTLD(1220): reset flags
    04-11 17:21:24.705: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:24.705: DEBUG/DTUN_HCID4(1233): stream creation in progress
    04-11 17:21:24.714: INFO//system/bin/btld(1219): ##### USerial_Ioctl: BT_Wake, 0x8003 ####
    04-11 17:21:24.958: WARN/BTLD(1220): process_service_search_attr_rsp
    04-11 17:21:25.017: WARN/BTLD(1220): ccb timer ticks: 0
    04-11 17:21:25.227: ERROR/BTLD(1220): bta_av_rc_create ACP handle exist for shdl:0
    04-11 17:21:25.325: WARN/BTLD(1220): bta_dm_rm_cback:0, status:1
    04-11 17:21:25.325: WARN/BTLD(1220): bta_dm_act no entry for connected service cbs
    04-11 17:21:25.325: INFO/BTL-IFS(1220): send_ctrl_msg: [BTL_IFS CTRL] send BTLIF_DTUN_SIGNAL_EVT (CTRL) 44 pbytes (hdl 15)
    04-11 17:21:25.325: WARN/BTLD(1220): btui_av_callback(BTA_AV_OPEN_EVT::FAILED (page-timeout or protocol)::status: 3
    04-11 17:21:25.325: INFO/DTUN_HCID4(1233): pending
    04-11 17:21:25.325: INFO/DTUN_HCID4(1233): orig_msg = e588
    04-11 17:21:25.325: ERROR/BluetoothA2dpService.cpp(96): onConnectSinkResult: D-Bus error: org.bluez.Error.Failed (Stream connection failed)
    04-11 17:21:25.325: INFO/BluetoothA2dpService(96): checkSinkSuspendState() : state = 0 prevState = 1
    04-11 17:21:25.325: INFO/BluetoothA2dpService(96): checkSinkSuspendState() : mTargetA2dpState = -1
    04-11 17:21:25.325: INFO/BluetoothA2dpService(96): checkSinkSuspendState() : initialStart = false initialSuspend = false
    04-11 17:21:25.334: VERBOSE/BluetoothEventRedirector(492): Received android.bluetooth.a2dp.action.SINK_STATE_CHANGED
    04-11 17:21:25.334: INFO/BluetoothEventRedirector(492): Failed to connect BT A2DP
    04-11 17:21:25.334: DEBUG/CachedBluetoothDevice(492): onProfileStateChanged:[]
    04-11 17:21:25.334: DEBUG/BluetoothA2dpService(96): A2DP state : device: BC:47:60:0F:4B:F3 State:1->0
    04-11 17:21:25.925: INFO//system/bin/btld(1219): ##### USerial_Ioctl: BT_Sleep, 0x8004 ####
    04-11 17:21:26.775: WARN/BTLD(1220): ccb timer ticks: 2147483648
    04-11 17:21:26.785: INFO//system/bin/btld(1219): ##### USerial_Ioctl: BT_Wake, 0x8003 ####
    04-11 17:21:27.725: INFO//system/bin/btld(1219): ##### USerial_Ioctl: BT_Sleep, 0x8004 ####
    

    Does anyone know what I am doing wrong? A general question is it possible to connect two Android phones via Bluetooth and stream from one phone to the other? Do you have any alternative approaches?

    Thanks

  • Admin
    Admin about 13 years
    Is there an unofficial way to extends my device to support A2DP sink. I just read that Bluez supports A2DP sink. So theoretically my device could be an A2DP sink or do I need some special hardware to extend this function? Or is it sufficient to maybe enable Sink support in the audio.conf file?
  • Dennis Mathews
    Dennis Mathews about 13 years
    yes you can extend Android by integrating with A2DP sink from BlueZ - I dont think it needs special hardware.
  • Admin
    Admin about 13 years
    How can I do this? If I want to extend my Samsung Galaxy Tab, then I should get the source to get the bluez files? Afterthat I have to change something somewhere in the bluez stack to activate A2DP sink and then put my customized code on the galaxy tab? Am I right or am I totally wrong? Do I have to write a driver for that? I have no idea how to integrate A2DP in the Galaxy Bluez Stack. Can you give me some hints, please? Thanks
  • JRC
    JRC over 10 years
    @DennisMathews, is it possible to connect to multiple a2dp sinks from android? and play same content to all sinks?