I am writing an application implementing the HF side of the Bluetooth Hands-free Protocol, and I need some advice as to how you are supposed to debug the SCO connections.
From my assumption and observation, the AG only establishes an SCO connection once a call has been answered (or when one is incoming due to In-band ringtone). This is hard to debug as I don't have a second mobile phone to call myself.
Is there some way to make the phone establish an SCO link without using some service to call the device, or without calling someone yourself?
I know that the HF can ask the AG to establish an SCO link through AT+BCC, but once the socket is open, the AG closes it fairly quickly, which doesn't happen when the AG opens the link on its own.
My approach thus far was an online service that calls me on my mobile phone, but that service only allows 5 calls a day, which I most of the time easily exceed.
The device is an Android phone.
Related
I am trying to make an app, that when it sees a specific bluetooth device to connect to it and send a command and before loose that connection to send another command.
The device is standard bluetooth serial device.
Is there a way to check when i am going to loose the connection?
No unfortunately Bluetooth doesn't work this way. You are usually notified that the remote device disconnected and you can even get the disconnection reason (e.g. BT_HCI_REMOTE_USER_TERMINATED_CONNECTION), but by then it is already too late and the link between your device and the remote device is already lost. Generally speaking, the way a disconnection works is that there are empty Bluetooth packets sent back and forth between the two devices (similar to an ACK) to indicate that the link is alive. If that packet does not arrive after a certain timeout, the BLE stack throws an event to the application notifying it that the connection has been lost (i.e. a disconnection event).
If you are using Bluetooth Low Energy, and if you are in control of both devices (your one and the remote one), then you could implement additional communication on the advertising channels. This is not as efficient as performing the communication through a connection, but you can advertise this additional command upon disconnection, and the remote device would scan for this new command upon disconnection as well.
I hope this helps.
I am new to Bluetooth, but have been working for a month or so on a Android Client that connects to a BLE peripheral to write data to a characteristic.
My BLE peripheral is a nrf52832 (Nordic) device and I have loaded the BLE_SM (security manager) example project so that I can use bonding/pairing for secure communications.
My Android code pairs/bonds successfully to the peripheral, but from what I can see the peripheral now stops advertising. I'm not sure if this is normal or it's because I received a gap.onDisconnection event of type REMOTE_USER_TERMINATED_CONNECTION.
Irrespective I am bonded so you would think I could now not need to scan anymore for the device and could just call device.connectGatt(), but it is not working and my callback gets a GATT STATE_DISCONNECTED event.
I read in another post that had pasted the following from Nordic (Tutorial):
It is not possible to connect to a peripheral which is not
advertising, even though one knows its address from before. This is
because the peripheral will only turn on the receiver for a set amount
of time after transmitting an advertisement. This time is used to
listen for connection requests and scan requests.
If this is in fact true, it seems I would be unable to stop the peripheral continually advertising, which is not helpful if I am trying to reduce the peripheral's power consumption.
The citation is 100% true. Connection setup has nothing to do with if the device is bonded or not (assuming you don't use directed advertising). If the peripheral is neither connected nor advertising, the radio is completely off and therefore a central can't connect.
If you want to minimize power consumption, make sure you don't advertise when you don't need to. Depending on your use case, can you have anything triggering advertising? For example a button or a sensor event?
If you need to advertise all the time, you can try use a longer advertising interval to save battery, but this will increase discovery and connection setup time.
Overview
I'm currently working on an android app that supports VoIP calls (using webrtc). Everything's working perfectly, but now I'm trying to add support for bluetooth headsets. I want the calls to be answered/hangup automatically (without the user touching the device's screen) if:
The user has a bluetooth headset connected to his device
The Answer/Hangup button was pressed
Problem
I'm still struggling to make this work. I've read all related stack overflow questions (like this and this), but still no luck.
What I've tried:
Obtain the bluetooth profile proxy using bluetoothAdapter.getProfileProxy(context, serviceListener, BluetoothProfile.HEADSET).
On the service listener (a BluetoothProfile.ServiceListener) check if the obtained BluetoothHeadset has a connected bluetooth device. If true, register a BroadcastReceiver with an IntentFilter that has the actions android.intent.action.MEDIA_BUTTON, android.media.ACTION_SCO_AUDIO_STATE_UPDATED and android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED and call audioManager.startBluetoothSco().
I'm only receiving broadcasts for the android.media.ACTION_SCO_AUDIO_STATE_UPDATED action. What's wrong with my approach?
Any help would be appreciated.
I have not developed VoIP apps, so I am not sure about correct sequence of events and control calls in this case. Not sure that this can help, just some notes from Bluetooth point of view. Intents BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED (android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED) are about BluetoothHeadset's RFCOMM connection, it is kept alive if Handsfree/Headset profile is enabled for specific Handsfree unit and Handsfree unit is in use. You need these intents to detect if you need to look after BluetoothHeadset state or not, so you will not receive them during calls.
You can also register a receiver for BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED intents (android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED). In BluetoothHeadset source and accordingly in Android documentation it described as "Audio Connection state of the A2DP profile", but this is wrong. This is state of Handsfree/Headset physical audio SCO connection. This connection is active during voice calls, Bluetooth voice recognition and ringing (if In Band Ringing feature is supported and enabled). I do not remember how BluetoothHeadset audio state concerns AudioManager's SCO state.
I have: 1) An embedded device with a Bluetooth connector that I use with BlueZ, and 2) I have an Android phone that I am writing an application on.
Goal: I want to make sure that when these two devices are near each other, they quickly detect each other and establish communication. Unfortunately, I'm running in to complications of what is feasible on Android and power efficient.
Initial Design: Originally, I've been thinking and implementing the following --
Embedded Device: Constantly in discoverable mode, creates a service with an RFCOMM server running to accept multiple connections.
Android Phone: Listen for Broadcast intents that would tell me when the embedded device (discoverable) is nearby, and then create an RFCOMM client socket to it.
The difficulty I am having with this design is that I do not get intents when I would expect them. Even if I turn the embedded device on and cycle the Android phone's Bluetooth adapter to off/on ... none of these Broadcast intents are received:
BluetoothDevice.ACTION_FOUND
BluetoothDevice.ACTION_ACL_CONNECTED
BluetoothDevice.ACTION_BOND_STATE_CHANGED
The only thing that seems to work is to periodically either have the phone try to connect to the Bluetooth device's RFCOMM socket, or to periodically trigger Bluetooth scans (both power inefficient). This will trigger ACTION_FOUND and ACTION_ACL_CONNECTED. If i shutdown the embedded device, I will receive ACTION_ACL_DISCONNECTED. The issue, again, is that none of these are received if I do not explicitly have the phone try to initiate a socket connection. This is bad for power efficiency on the phone.
Do I have this logic backwards? Should the embedded device keep track of Bluetooth MAC addresses that it has paired with and be the RFCOMM client, whereas the Android application creates a service and is the RFCOMM server just hanging around and waiting for a connection? This seems logically backwards, though... I wouldn't think the Android phone would create a service or be the server to make this happen.
If I go in to my car, it almost immediately manages to establish a connection with my phone. So, I know this is possible!
The concrete questions I have are two-fold: 1) Is there something I am doing wrong with my "initial design" to make it more effective, and 2) Is the 2nd logic I propose what things like cars use to establish quick communication and poll frequently? (since the battery power of the car is not a concern...)
i have 2 devices that are in same wifi network and are connected. Now, i want to listen whenever the device gets disconnected or reconnects. I dont want to listen to wifi connectivity with device but the connectivity between 2 devices in same wifi network.
How can we do that ?
Its certainly possible by using Android's peer to peer connection.
This is from the above link.
The WifiP2pManager.ActionListener implemented in this snippet only
notifies you when the initiation succeeds or fails. To listen for
changes in connection state, implement the
WifiP2pManager.ConnectionInfoListener interface. Its
onConnectionInfoAvailable() callback will notify you when the state of
the connection changes. In cases where multiple devices are going to
be connected to a single device (like a game with 3 or more players,
or a chat app), one device will be designated the "group owner".
We can communicate between 2 phones in the same using regular Socket's.
Server Side Link
Client Side Link
If you have a large amount of data to transfer, internet sockets have a greater data capacity and will be faster. The other advantage is that there is no such thing as "out of range". You can connect the two devices wherever internet is available.
So a UDP broadcast would seem like a good option. I.e where 2 devices with same app are running and a packet is broadcasted from one device on a particular socket, where as the other side the app listens on that socket.