This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Using Android phone as Headset

Hi,

I am trying to convert Galaxy Nexus device into a headset. I was able to successfully send/receive commands to perform Handsfree actions like Answer call, end call, etc with the connected phone.


But only thing that's missing is the Voice. I tried connecting it to SCO via Socket but I do not receive any audio data.

I am unable to figure out if the Bluetooth hardware supports routing audio to speaker or not.

This is my audio.conf file:

# Configuration file for the audio service

# This section contains options which are not specific to any
# particular interface
# NOTE: Enable=Sink means that bluetoothd exposes Sink interface for remote
# devices, and the local device is a Source
[General]
Enable=Media,Control,Source,Gateway,Headset
#Control,Headset,Gateway,Source,Control
#Disable=Headset,Gateway,Source

# Switch to master role for incoming connections (defaults to true)
Master=true

# If we want to disable support for specific services
# Defaults to supporting all implemented services
#Disable=Control,Source

# SCO routing. Either PCM or HCI (in which case audio is routed to/from ALSA)
# Defaults to HCI
#SCORouting=PCM

# Automatically connect both A2DP and HFP/HSP profiles for incoming
# connections. Some headsets that support both profiles will only connect the
# other one automatically so the default setting of true is usually a good
# idea.
AutoConnect=true

# Headset interface specific options (i.e. options which affect how the audio
# service interacts with remote headset devices)
[Headset]

# Set to true to support HFP (in addition to HSP only which is the default)
# Defaults to false
HFP=true

# Maximum number of connected HSP/HFP devices per adapter. Defaults to 1
MaxConnections=10

# Set to true to enable use of fast connectable mode (faster page scanning)
# for HFP when incomming call starts. Default settings are restored after
# call is answered or rejected. Page scan interval is much shorter and page
# scan type changed to interlaced. Such allows faster connection initiated
# by a headset.
FastConnectable=false

# Just an example of potential config options for the other interfaces
[A2DP]
SBCSources=1
MPEG12Sources=0

[AVRCP]
InputDeviceName=AVRCP
MetaDataEnable=true

#[WBspeech]
#for wide band speech hci commands arguments
#WBSEnable = false
#I2sEnable = 0x01
#IsMaster = 0x00
#ClockRate = 0x02
#PcmInterfaceRate = 0x00

I tried two solutions:

1. Directly connect to SCO socket using the Low level socket APIs. I am able to establish connection to SCO Socket but it's not returning any data if I do read/write on that Socket. I establish connection only after picking up a phone call with the devices connected already.

2. Use DBuS APIs for BlueZ and perform tasks as mentioned in Slide #7. http://download.tizen.org/misc/media/conference2012/wednesday/bayview/2012-05-09-0900-0940-bluez-_plugging_the_unpluggable.pdf

But I am unable to access any SCO audio data.

Hcidump shows that my Headset emulated Android phone is able to receive the data, but how can I capture this data and route it to speaker ??

shell@android:/ # hcidump
HCI sniffer - Bluetooth packet analyzer ver 2.0
device: hci0 snap_len: 1028 filter: 0xffffffff
< HCI Command: Setup Synchronous Connection (0x01|0x0028) plen 17
    handle 12 voice setting 0x0060 ptype 0x003f
> HCI Event: Command Status (0x0f) plen 4
    Setup Synchronous Connection (0x01|0x0028) status 0x00 ncmd 1
> HCI Event: Synchronous Connect Complete (0x2c) plen 17
    status 0x00 handle 6 bdaddr 5C:3C:27:BA:4C:DC type eSCO
    Air mode: CVSD
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< ACL data: handle 12 flags 0x00 dlen 16
    L2CAP(d): cid 0x0041 len 12 [psm 0]
< SCO data: handle 6 flags 0x00 dlen 22
> ACL data: handle 12 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 0]
< SCO data: handle 6 flags 0x00 dlen 22
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 12 packets 1
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
< SCO data: handle 6 flags 0x00 dlen 22
> HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 6 reason 0x13
    Reason: Remote User Terminated Connection
> HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 12 reason 0x13
    Reason: Remote User Terminated Connection

  • Hi,

    The PCM configurations should be changed.

    and are taking care of routing the audio to the speaker?

  • Hi Sudeep,


    Thanks for response. Can you please be little more elaborate.


    Unless until I get handle to SCO data, I cannot route the data to Speaker.

    Everytime I do a ioctl command, I get number of bytes available as 0, and recv function does not return any data in the buffer.

    Similarly send function does not work as well. I am unable to write any data to SCO socket, it throws an IO Exception with a message "This operation is not supported"

    Please advice.

  • Hi,

    Did you change the UUID of WL7 to HF? Is you device only recognize as HF device? Is AG still active?

    Are you sending any data and is it being received from the controller side. Have you checked the sniffer logs.?

    Are you reading the data from the PCM lines? are you decoding this data using your external codec?

    Now are you routing the audio to the speaker?

    and don't use the android subsystem for bluetooth, Directly read it from the stack? As far as I know android does not allow this. 

  • Hi Sudeep,

    If you have read the question, I have posted that I am able to make my device emulated as headset, it is controlling the AG as well.

    The sniffer tool on HF side receives the SCO data as well. I tested this by making an actual call from AG phone.

    I am trying to read the data from SCO Socket. Steps for connecting SCO on HF:

    1. Create a SCO Socket using low-level socket() function in C.
    2. Bind the socket to local BT Address. (ie local adapter)
    3. Connect to the AG, as AG goes into listen mode once call is started.
    4. Then try to receive data using recv() function in C.

    I am stuck at #4 where the audio packets are not coming from Socket.

    So unless I get the data, I cannot use Codec to convert the encoded data nor I can route data to Speaker.

  • Hi,

    After the step three 

    Are you sending any data and is it being received from the controller side. Have you checked the sniffer logs.?

    Are you reading the data from the PCM lines? You will receive the data on PCM lines, from where you need to read it?

    If I am not wrong you are trying to do SCO over HCI, correct? 

  • Hi Sudeep,

    Thanks again. This is the pseudo code I have for reading...

    int sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
    	ALOGI("Socket %d", sk);
    
    	if (sk < 0) {
    		ALOGI("A Socket is NULL");
    		return -1;
    	}
    	
    //.... perform all checks and initialize the buffer array.
    // use read() function to read the data from socket	
      ret = read(sk, &buffer[0], buf_len);
    	

    This is the code for sending data...

    int sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
    	ALOGI("Socket %d", sk);
    
    	if (sk < 0) {
    		ALOGI("A Socket is NULL");
    		return -1;
    	}
    	
    //.... perform all checks and initialize the buffer array.
    // use send() function to send the data from socket	
      ret =  send(sk, &b[offset], length, -1);
    	

    Both read and send are not fetching / sending any data from SCO socket.

    I tried both configurations by changing SCORouting in audio.conf to PCM and HCI.

    Neither worked for me as of today.

  • Hi,

    Voice over HCI is not recommend it as the first option. The recommended settings are below:

    HCI_Write_Default_Erroneous_Data_Reporting 0x0c5b, 0x01

    HCI_VS_Write_SCO_Configuration 0xFE10, 1, 120, 720, 1 

    see: http://processors.wiki.ti.com/index.php/WL18xx_Bluetooth_RF_Testing#Conversion_of_HCI_cmds_to_HCITool_Tool_format

    also see the links below related to the voice over PCM which might help

    http://e2e.ti.com/support/low_power_rf/f/307/t/104349.aspx?pi267162=1 

    http://e2e.ti.com/support/low_power_rf/f/307/p/245418/858623.aspx#858623