im trying to control a bluetooth bracelet with vibration function via HFP (hands free profile) in Android. I've been able to connect to the bracelet and access the input- and outputstream.
My goal is to simulate an incoming call so that the bluetooth bracelet starts vibrating (which seems to be the only way to do that). To do this, im using AT commands. In the bluetooth specs at https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=238193 on page 22 you can see the handshake to establish service level connection.
I need to establish this connection to use the "+CIEV" command (see handshake page 48).
But when my bracelet returns the command "AT+CIND=?" I dont know how to respond. I can't find any hints on how to answer with the "CIND:" command. Also I dont know how to send the acknowledgement (is it just "OK"?).
That might even be the completely wrong way to do this. Every suggestion is appreciated. I only found one post on stackoverflow that helped me in some way, rest of the posts I found were unanswered.
By the way, im using a smartphone with Android 4.1.2. The bracelet supports HFP and HSP. Thanks in advance.
UPDATE 10/29/2014
===== Connection through RFCOMM Socket established at this point =====
// read AT+BRSF=0 from device
byte[] buffer = new byte[200];
mBluetoothSocket.getInputStream().read(buffer);
Log.d(TAG, new String(buffer).trim());
//write answer BRSF: ...
mBluetoothSocket.getOutputStream().write("+BRSF=20\r".getBytes());
mBluetoothSocket.getOutputStream().write("OK\r".getBytes());
// read AT+CIND=? command
buffer = new byte[200];
mBluetoothSocket.getInputStream().read(buffer);
Log.d(TAG, new String(buffer).trim());
//write answer CIND: ...
mBluetoothSocket.getOutputStream().write("+CIND: (\"battchg\",(0-5)),(\"signal\",(0-5)),
(\"service\",(0,1)),(\"call\",(0,1)),(\"callsetup\",(0-3)),
(\"callheld\",(0-2)),(\"roam\",(0,1))".getBytes());
mBluetoothSocket.getOutputStream().write("OK".getBytes());
// read AT+CIND?
buffer = new byte[200];
mBluetoothSocket.getInputStream().read(buffer);
Log.d(TAG, new String(buffer).trim());
Following the procedure of the protocol, I should receive the "AT+CIND?" command and then I could send the command "+CIND: 5,5,1,0,0,0,0", but...I dont receive the "AT+CIND?" command. Actually im not receiving anything. Am I missing something? Sending an "OK" doesnt change anything btw...
I was fiddeling with exaclty the same problem. After days of trial and error, I finally got it to work.
I think it depends on the speed at wich you answer the HF's commands, as well as on the correct line-endings ("COMMAND").
Here is my DroidScript which works. It's not cleaned up, but it works.
https://gist.github.com/t-oster/68a568ac4c4e133f67ac
Also, the one example I found that seemed to almost work, it's expecting the responses to be top and tailed with crlf:
"\r\n+BRSF=20\r\n"
"\r\nOK\r\n"
Still struggling with the rest of it myself.
refer to bluetooth hfp 1.5 spec in which you can understand CIEV response
normally when not in any call setup, response can be +CIND = 1,0,0,0,5,0,5
Note these values are based on the hfp spec, on incoming call return +CIEV: ,
ind- indicator for callsetup and value as 1 and then RING commands to the bracelet
My BLE application requires computation on the server side (BLE chip) which takes time and results with disconnection.
Th flow is like this:
1- Android phone writes the characteristic value to the BLE chip.
2- The chip evaluates this value and starts computation.
3- The connection is lost soon after the computation has started.
What solution can I apply to prevent the disconnecton? I have two solutions in my mind:
1- Changing the connection interval: Currently Android uses 7.5 msec as connection interval. Since the computation on BLE chip takes time, packets are not sent or received during the computation. Increasing the connection interval will decrease the number of lost packets. However there is no guarantee that Android phone will accept the new connection parameters.
2- Running the computation in a separate thread: I dont think that BLE chips' SDK support multi-threading such that while there is a computation process going on, it will keep receiving and sending packets and prevent the disconnection. I use CSR chip and I think it doesnt support.
Please correct me if I am wrong at my points.
Do you have any other suggestions to solve the issue?
Thanks in advance.
Thank you for the answers. I found out what the problem is after spending hours.
First of all, when Android gives error 133 or 129, it is most probably because of the remote device.
At the beginning I thought that the problem occurred because of the supervision timeout. Then I re-configured the connection parameters of the CSR chip but it didn't help.
There is a problem about CSR app development with xIDE (IDE of CSR). When there is run-time-error due to index overshoot or accessing some invalid pointers, then you would not receive any errors in xIDE. I finally found out the array problem and fixed it. Now it works perfect.
Thanks a lot!
I don't know exactly if what i going to explain it's feasible under Android because I used BLE only with a low level applications, anyway if your problems are the connection parameters you can try to change the Slave_Latency.
It should be usefull since playing with this parameter, you can change the number of connection intervals in which the Central device can wait until it considers the connection lost.
The following equation is usefull to derive the connection parameters:
Effective_Connection_Interval = (Connection_Interval)*(1+(Slave_Latency))
Remember that can exists some kind of Supervision_Timeout that can collide with your Effective_Connection_Interval
I am stuck at a place where my Android Phone(Samsung Galaxy) has to open 2(or more) connections to my PC(server) which is a paired device. For this purpose, I start SDP server on PC with UUID : 00001101-0000-1000-8000-00805F9B34FB and channel 2, after the first connection I unregister the SDP service on the PC and register it again on channel 3(and same UUID) and expect my android phone to 'connect' to it for establishing the second bluetooth connection. The second one fails.
The problem as I have figured out is that because of the pairing, the channel num and UUID of the device for the 'BluetoothSocket.connect' are serviced from cache and are not being updated, so my SDP change in channel num on the server side is not visible here as it still tries to connect to channel 2(old one).
A workaround of this problem(found after a lot of frustrating attempts) might be to change the android.server.BluetoothService.java file, by introducing
updateDeviceServiceChannelCache(addr) before returning in the getRemoteServiceChannel() and fetchRemoteUuids() so as to update the channel number at each func call.
The above solution may well be wrong, please pardon me for that. If it is correct please suggest any further changes and how to make this change permanent in eclipse, or in other case(wrong solution), the right way of doing this.
Note: I have android 2.3.5 and the requests from the device are actually from the browser that I forward to the PC. I want them on separate channels.
thanks.
when opening a bluetooth rfcomm socket via the UUID method ( the other method ( using reflection ) in here http://code.google.com/p/android/issues/detail?id=5427 ) - I sometimes get the following error ( after successfull connections ) and the socket is not opened:
E/BluetoothService(21847): Received ACTION_UPDATE_SERVICE_CACHE00:0B:CE:01:2E:00
D/BluetoothService(21847): updateDeviceServiceChannelCache(00:0B:CE:01:2E:00)
D/BluetoothService(21847): Cleaning up failed UUID channel lookup: 00:0B:CE:01:2E:00 00001101-0000-1000-8000-00805f9b34fb
had no luck with google on this one - has anyone here a clue whats going on and how to prevent that?
Update:
for people running into the same problem - possible solutions:
advice the users to reboot the device if we run into that state (
very bad UX )
use the reflection method ( dirty but works most of the time )
I am still open for new Ideas ;-)
I stick to #2 at the moment - but waiting for a better solution.
It seems that the message is the consequence, not the reason. If a serial port emulation service is not found on device the connection will obviously fail.
Update
After reviewing code everything seems ok. So my questions are: Do the random errors occur with same device o with different devices? If the occur with different devices, the devices might have not registered the SerialPort service. Is device previously paired? In case of the error ocurring randomly with same device? Are you using the connection class concurrently? You have not protected the methods against concurrent access. You have not protected either against succesive connects. If you try to read/close a stream after a second connect it will fail (the socket object has changed).
It seems ok. The random error occurs with same device? If this is the case, are you using concurrent use of that class? In first case
Currently Iam using backport.android.bluetooth2.jar file for bluetooth programming with Android 1.5.Whenever device pairing fails it populates alert dialog for passKey and if i give passkey then in my log iam getting below error
07-21 12:25:52.419: WARN/BluetoothDeviceService(948): setPin(00:0E:6D:BA:89:F3) called but no native data available, ignoring. Maybe the PasskeyAgent Request was cancelled by the remote device or by bluez.
For successfully pair my BT device I always rebooting my tablet and manually pair the device with Settings options.So at last i realised to give this passKey programmatically but i haven't found any method for this.But in google opensource i found one method that is commented with #hide setPassKey(String Address,int passKey) in BluetoothDevice.java of backport.android.bluetooth2.jar .This will n't appear in my jar file.If any way is there for pairing the unbounded device please give reply ASAP?
In the AndroidBluetoothAPI_0.3.jar file following methods are available i,e: pair(address) and setPin() for setting the pin programmatically and connecting the BT device.For finding the signal strength method is available in this api.Below is the code project link
http://code.google.com/p/android-bluetooth/downloads/detail?name=AndroidBluetoothAPI_0.3.jar&can=2&q=