Skip to content

Commit

Permalink
Bug 860166 - Revice AT command handler for Headset profile (HSP), r=gyeh
Browse files Browse the repository at this point in the history
  • Loading branch information
eric30 committed Apr 19, 2013
1 parent 355ed7a commit c9bb10b
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 37 deletions.
58 changes: 42 additions & 16 deletions dom/bluetooth/BluetoothHfpManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
nsAutoPtr<UnixSocketRawData>& aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aSocket);

nsAutoCString msg((const char*)aMessage->mData.get(), aMessage->mSize);
msg.StripWhitespace();
Expand Down Expand Up @@ -886,23 +887,46 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,

mCCWA = atCommandValues[0].EqualsLiteral("1");
} else if (msg.Find("AT+CKPD") != -1) {
// For Headset Profile (HSP)
switch (mCurrentCallArray[mCurrentCallIndex].mState) {
case nsITelephonyProvider::CALL_STATE_INCOMING:
NotifyDialer(NS_LITERAL_STRING("ATA"));
break;
case nsITelephonyProvider::CALL_STATE_CONNECTED:
case nsITelephonyProvider::CALL_STATE_DIALING:
case nsITelephonyProvider::CALL_STATE_ALERTING:
NotifyDialer(NS_LITERAL_STRING("CHUP"));
break;
case nsITelephonyProvider::CALL_STATE_DISCONNECTED:
NotifyDialer(NS_LITERAL_STRING("BLDN"));
break;
default:
NS_WARNING("Not handling state changed");
break;
BluetoothScoManager* sco = BluetoothScoManager::Get();
if (!sco) {
NS_WARNING("Couldn't get BluetoothScoManager instance");
goto respond_with_ok;
}

if (!sStopSendingRingFlag) {
// Bluetooth HSP spec 4.2.2
// There is an incoming call, notify Dialer to pick up the phone call
// and SCO will be established after we get the CallStateChanged event
// indicating the call is answered successfully.
NotifyDialer(NS_LITERAL_STRING("ATA"));
} else {
if (!sco->IsConnected()) {
// Bluetooth HSP spec 4.3
// If there's no SCO, set up a SCO link.
nsAutoString address;
mSocket->GetAddress(address);
sco->Connect(address);
} else if (!mFirstCKPD) {
// Bluetooth HSP spec 4.5
// There are two ways to release SCO: sending CHUP to dialer or closing
// SCO socket directly. We notify dialer only if there is at least one
// active call.
if (mCurrentCallArray.Length() > 1) {
NotifyDialer(NS_LITERAL_STRING("CHUP"));
} else {
sco->Disconnect();
}
} else {
// Three conditions have to be matched to come in here:
// (1) Not sending RING indicator
// (2) A SCO link exists
// (3) This is the very first AT+CKPD=200 of this session
// It is the case of Figure 4.3, Bluetooth HSP spec. Do nothing.
NS_WARNING("AT+CKPD=200: Do nothing");
}
}

mFirstCKPD = false;
} else if (msg.Find("AT+CNUM") != -1) {
if (!mMsisdn.IsEmpty()) {
nsAutoCString message("+CNUM: ,\"");
Expand Down Expand Up @@ -1373,6 +1397,8 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket)
mRunnable.forget();
}

mFirstCKPD = true;

// Cache device path for NotifySettings() since we can't get socket address
// when a headset disconnect with us
mSocket->GetAddress(mDevicePath);
Expand Down
1 change: 1 addition & 0 deletions dom/bluetooth/BluetoothHfpManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class BluetoothHfpManager : public BluetoothSocketObserver
bool mCLIP;
bool mCMEE;
bool mCMER;
bool mFirstCKPD;
int mNetworkSelectionMode;
bool mReceiveVgsFlag;
nsString mDevicePath;
Expand Down
45 changes: 24 additions & 21 deletions dom/bluetooth/BluetoothScoManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,14 @@ BluetoothScoManager::NotifyAudioManager(const nsAString& aAddress)
do_GetService("@mozilla.org/observer-service;1");
NS_ENSURE_TRUE_VOID(obs);

nsCOMPtr<nsIAudioManager> am =
do_GetService("@mozilla.org/telephony/audiomanager;1");
NS_ENSURE_TRUE_VOID(am);

if (aAddress.IsEmpty()) {
if (NS_FAILED(obs->NotifyObservers(nullptr, BLUETOOTH_SCO_STATUS_CHANGED, nullptr))) {
NS_WARNING("Failed to notify bluetooth-sco-status-changed observsers!");
return;
}
} else {
if (NS_FAILED(obs->NotifyObservers(nullptr, BLUETOOTH_SCO_STATUS_CHANGED, aAddress.BeginReading()))) {
NS_WARNING("Failed to notify bluetooth-sco-status-changed observsers!");
return;
}
const PRUnichar* addr =
aAddress.IsEmpty() ? nullptr : aAddress.BeginReading();

if (NS_FAILED(obs->NotifyObservers(nullptr,
BLUETOOTH_SCO_STATUS_CHANGED,
addr))) {
NS_WARNING("Failed to notify bluetooth-sco-status-changed observsers!");
return;
}
}

Expand Down Expand Up @@ -199,19 +193,17 @@ BluetoothScoManager::Connect(const nsAString& aDeviceAddress)
return false;
}

if (mSocket->GetConnectionStatus() ==
SocketConnectionStatus::SOCKET_CONNECTED) {
NS_WARNING("Sco socket has been connected");
SocketConnectionStatus status = mSocket->GetConnectionStatus();
if (status == SocketConnectionStatus::SOCKET_CONNECTED ||
status == SocketConnectionStatus::SOCKET_CONNECTING) {
NS_WARNING("SCO connection exists or is being established");
return false;
}

mSocket->Disconnect();

BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("BluetoothService not available!");
return false;
}
NS_ENSURE_TRUE(bs, false);

nsresult rv = bs->GetScoSocket(aDeviceAddress,
true,
Expand Down Expand Up @@ -288,3 +280,14 @@ BluetoothScoManager::OnDisconnect(BluetoothSocket* aSocket)
NotifyAudioManager(address);
}
}

bool
BluetoothScoManager::IsConnected()
{
if (mSocket) {
return mSocket->GetConnectionStatus() ==
SocketConnectionStatus::SOCKET_CONNECTED;
}

return false;
}
1 change: 1 addition & 0 deletions dom/bluetooth/BluetoothScoManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class BluetoothScoManager : public BluetoothSocketObserver
bool Connect(const nsAString& aDeviceObjectPath);
void Disconnect();
bool Listen();
bool IsConnected();

private:
friend class BluetoothScoManagerObserver;
Expand Down

0 comments on commit c9bb10b

Please sign in to comment.