View Full Version : Bluetooth programming question

Jan 16, 2012, 04:26 AM
I don't know if this really is a Mac specific question but since that's the system I'm programming in I'll ask anyway :-)

I'm writing a program that connects to a mobile phone (For now just Sony Ericsson dumbphones) through Bluetooth (Connects through a RFCOMM channel) and then sends AT-commands to control this phone. The purpose of this program is that people with disabilities that might have trouble working a mobile can use this program to perform calls, receive calls and modify a contact list.

The user interface is written in wxWidgets since it's supposed to be as cross platform as possible, and the phone manager is written in Objective-C++ using the OS X Bluetooth stack.

My problem now is that when a user calls a number and the number is busy, I'm not getting a BUSY reply back from the phone as the Sony Ericsson developer guide says should happen. Other messages from the phone gets received, like RING when an incoming call happens, or +CLIP when returning the number of the caller.

Here is the function responsible for reading incoming data:

-(void) rfcommChannelData:(IOBluetoothRFCOMMChannel *)rfcommChannel data:(void *)dataPtr length:(size_t)length {

* Fetch data
char buf[256];

strncpy(buf, (char*)dataPtr, length);
buf[length] = '\0';

std::string cppbuf(buf);
cppbuf = cppbuf.substr(2, length-2);

* Incoming call
if(cppbuf.substr(0,4).compare("RING") == 0) {
NSLog(@"Incoming call!");
// Fetch incoming number
char ATCommand[40];
strcpy(ATCommand, "AT+CLIP=1\r\n");
[self sendrfcommData:ATCommand];

* Number request reply
} else if(cppbuf.substr(0,7).compare("+CLIP: ") == 0) {
* Incoming reply has syntax "+CLIP: "<number>",...
* To find the number, we first look up index for space
* and increment that value by 2. We then look up index for the
* first comma, and decrease that value by 1.
* The number is now the substring starting at startindex
* with length (endIndex - startIndex).

int startIndex = cppbuf.find(" ");
int endIndex = cppbuf.find(",");

if(!call_window_shown) {
call_window_shown = TRUE;
incoming_call_func(incoming_call_object, cppbuf.substr(startIndex, endIndex-startIndex));

* User hung up
} else if(cppbuf.substr(0,5).compare("+CHUP") == 0) {
NSLog(@"Hanging up");
call_window_shown = FALSE;

* Busy reply
} else if(cppbuf.substr(0,4).compare("BUSY") == 0) {
call_window_shown = FALSE;

* Aborted call
} else if(cppbuf.substr(0,10).compare("NO CARRIER") == 0) {
NSLog(@"No carrier!");
call_window_shown = FALSE;
} else
std::cout << "Unhandled incoming data: " << cppbuf << std::endl;

As I mentioned, the RING (From phone), +CLIP (From phone), and +CHUP (From user interface) messages all gets read correctly, but when the called number is busy no BUSY reply is ever sent. I've tried printing the incoming data before any of the if-statements but BUSY is never received.

If anyone can see something wrong with this code or have any ideas, please let me know. I've been scratching my head for days trying to figure out why this issue exists.

Dangerous Theory
Jan 19, 2012, 02:23 AM
Does NO CARRIER/Aborted call work? If so, then it's going to be an issue with the first line for BUSY, as they call the same function. If not, then it would appear that the aborted call function is broken.

Jan 24, 2012, 05:47 AM
Well my problem is that the rfcommChannelData function never recieves a BUSY or NO CARRIER. That is, the string comparison if(cppbuf.substr(0,4).compare("BUSY") == 0) is never true so the function call aborted_call_func(aborted_call_object); for BUSY or NO CARRIER is never done.

Like I mentioned, I've printed the incoming data at the top of rfcommChannelData before it is processed by the switch/case, and even though I call a busy number, the phone never sends BUSY back through the rfcomm channel.

Jan 24, 2012, 09:25 AM
From your posts, it sounds like the Sony Ericsson developer guide could be wrong and the phone is not sending the proper data back. What is sent back from the phone when you call a busy signal?

Since you are calling the same function for BUSY and NO CARRIER, can you just combine those two conditions into the else statement

NSLog(@"Busy or No carrier!");
call_window_shown = FALSE;

Jan 26, 2012, 09:37 AM
Yeah I'm starting to think the developer guide might be wrong or is leaving some info out. When I call a busy number, instead of getting a BUSY message from the phone I get nothing. I've tested this by in rfcommChannelData printing dataPtr (After casting it to char*) before any processing takes place.

What happens is that there is no incoming data at all when the line is busy. Quite strange, but as you say maybe the developer guide is wrong or missing some info. I'll see if I can connect to the phone with minicom or something similar and see what kind of messages I get from it.