~boiko/telepathy-ofono/update_tp_qt

6 by Tiago Salem Herrmann
add copyright headers
1
/**
19 by Tiago Salem Herrmann
fix copyright year
2
 * Copyright (C) 2013 Canonical, Ltd.
6 by Tiago Salem Herrmann
add copyright headers
3
 *
24.1.2 by Ricardo Salveti de Araujo
* Packaging cleanup
4
 * This program is free software: you can redistribute it and/or modify it under
5
 * the terms of the GNU Lesser General Public License version 3, as published by
6
 * the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10
 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 * Lesser General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU Lesser General Public License
6 by Tiago Salem Herrmann
add copyright headers
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24.1.2 by Ricardo Salveti de Araujo
* Packaging cleanup
15
 *
16
 * Authors: Tiago Salem Herrmann <tiago.herrmann@canonical.com>
6 by Tiago Salem Herrmann
add copyright headers
17
 */
18
2 by Tiago Salem Herrmann
- add call channel support
19
#include "ofonocallchannel.h"
45.1.5 by David Henningsson
Also call PulseAudio's mic mute function.
20
#ifdef USE_PULSEAUDIO
21
#include "qpulseaudioengine.h"
22
#endif
23
2 by Tiago Salem Herrmann
- add call channel support
24
25
oFonoCallChannel::oFonoCallChannel(oFonoConnection *conn, QString phoneNumber, uint targetHandle, QString voiceObj, QObject *parent):
26
    OfonoVoiceCall(voiceObj),
13 by Tiago Salem Herrmann
set status to no-answer for missed calls
27
    mIncoming(false),
28
    mRequestedHangup(false),
2 by Tiago Salem Herrmann
- add call channel support
29
    mConnection(conn),
30
    mPhoneNumber(phoneNumber),
58.1.1 by Tiago Salem Herrmann
check if the previous sendTones() succeeded before sending more tones
31
    mTargetHandle(targetHandle),
60.3.1 by Tiago Salem Herrmann
add initial multi party call support
32
    mDtmfLock(false),
33
    mMultiparty(false)
58.1.1 by Tiago Salem Herrmann
check if the previous sendTones() succeeded before sending more tones
34
    
2 by Tiago Salem Herrmann
- add call channel support
35
{
36
    Tp::BaseChannelPtr baseChannel = Tp::BaseChannel::create(mConnection, TP_QT_IFACE_CHANNEL_TYPE_CALL, targetHandle, Tp::HandleTypeContact);
37
    Tp::BaseChannelCallTypePtr callType = Tp::BaseChannelCallType::create(baseChannel.data(),
38
                                                                          true,
39
                                                                          Tp::StreamTransportTypeUnknown,
40
                                                                          true,
41
                                                                          false, "","");
42
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(callType));
43
44
    mHoldIface = Tp::BaseChannelHoldInterface::create();
45
    mHoldIface->setSetHoldStateCallback(Tp::memFun(this,&oFonoCallChannel::onHoldStateChanged));
46
47
    mMuteIface = Tp::BaseCallMuteInterface::create();
48
    mMuteIface->setSetMuteStateCallback(Tp::memFun(this,&oFonoCallChannel::onMuteStateChanged));
49
91.3.2 by Tiago Salem Herrmann
move SpeakerInterface to AudioOutputsInterface
50
    mAudioOutputsIface = BaseChannelAudioOutputsInterface::create();
51
    mAudioOutputsIface->setSetActiveAudioOutputCallback(Tp::memFun(this,&oFonoCallChannel::onSetActiveAudioOutput));
10 by Tiago Salem Herrmann
add speaker interface
52
60.3.1 by Tiago Salem Herrmann
add initial multi party call support
53
    mSplittableIface = Tp::BaseChannelSplittableInterface::create();
54
    mSplittableIface->setSplitCallback(Tp::memFun(this,&oFonoCallChannel::onSplit));
55
2 by Tiago Salem Herrmann
- add call channel support
56
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mHoldIface));
57
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mMuteIface));
91.3.2 by Tiago Salem Herrmann
move SpeakerInterface to AudioOutputsInterface
58
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mAudioOutputsIface));
60.3.1 by Tiago Salem Herrmann
add initial multi party call support
59
    baseChannel->plugInterface(Tp::AbstractChannelInterfacePtr::dynamicCast(mSplittableIface));
2 by Tiago Salem Herrmann
- add call channel support
60
61
    mBaseChannel = baseChannel;
62
    mCallChannel = Tp::BaseChannelCallTypePtr::dynamicCast(mBaseChannel->interface(TP_QT_IFACE_CHANNEL_TYPE_CALL));
63
64
    mCallChannel->setHangupCallback(Tp::memFun(this,&oFonoCallChannel::onHangup));
65
    mCallChannel->setAcceptCallback(Tp::memFun(this,&oFonoCallChannel::onAccept));
66
5 by Tiago Salem Herrmann
- rename some methods
67
    // init must be called after initialization, otherwise we will have no object path registered.
2 by Tiago Salem Herrmann
- add call channel support
68
    QTimer::singleShot(0, this, SLOT(init()));
107.2.2 by Ricardo Salveti de Araujo
Better handling PA_DISABLED
69
70
#ifdef USE_PULSEAUDIO
71
    QByteArray pulseAudioDisabled = qgetenv("PA_DISABLED");
72
    mHasPulseAudio = true;
73
    if (!pulseAudioDisabled.isEmpty())
74
        mHasPulseAudio = false;
75
#endif
2 by Tiago Salem Herrmann
- add call channel support
76
}
77
60.3.1 by Tiago Salem Herrmann
add initial multi party call support
78
Tp::CallState oFonoCallChannel::callState()
79
{
80
    return (Tp::CallState)mCallChannel->callState();
81
}
82
83
void oFonoCallChannel::onSplit(Tp::DBusError *error)
84
{
85
    mConnection->voiceCallManager()->privateChat(path());
86
}
87
91.3.2 by Tiago Salem Herrmann
move SpeakerInterface to AudioOutputsInterface
88
void oFonoCallChannel::onSetActiveAudioOutput(const QString &id, Tp::DBusError *error)
10 by Tiago Salem Herrmann
add speaker interface
89
{
101.1.2 by Tiago Salem Herrmann
Hook qpulseaudioengine to the new AudioOutputs interface
90
#ifdef USE_PULSEAUDIO
91
    // fallback to earpiece/headset
92
    AudioMode mode = AudioModeWiredOrEarpiece;
93
    if (id == "bluetooth") {
94
        mode = AudioModeBluetooth;
95
    } else if (id == "speaker") {
96
        mode = AudioModeSpeaker;
97
    }
107.2.2 by Ricardo Salveti de Araujo
Better handling PA_DISABLED
98
    if (mHasPulseAudio)
99
        QPulseAudioEngine::instance()->setCallMode(QPulseAudioEngine::CallActive, mode);
101.1.2 by Tiago Salem Herrmann
Hook qpulseaudioengine to the new AudioOutputs interface
100
#endif
10 by Tiago Salem Herrmann
add speaker interface
101
}
102
5 by Tiago Salem Herrmann
- rename some methods
103
void oFonoCallChannel::onHangup(uint reason, const QString &detailedReason, const QString &message, Tp::DBusError *error)
2 by Tiago Salem Herrmann
- add call channel support
104
{
5 by Tiago Salem Herrmann
- rename some methods
105
    // TODO: use the parameters sent by telepathy
13 by Tiago Salem Herrmann
set status to no-answer for missed calls
106
    mRequestedHangup = true;
2 by Tiago Salem Herrmann
- add call channel support
107
    hangup();
108
}
109
110
void oFonoCallChannel::onAccept(Tp::DBusError*)
111
{
4 by Tiago Salem Herrmann
implement support for background calls
112
    if (this->state() == "waiting") {
113
        mConnection->voiceCallManager()->holdAndAnswer();
114
    } else {
115
        answer();
116
    }
2 by Tiago Salem Herrmann
- add call channel support
117
}
118
119
void oFonoCallChannel::init()
120
{
13 by Tiago Salem Herrmann
set status to no-answer for missed calls
121
    mIncoming = this->state() == "incoming" || this->state() == "waiting";
60.3.1 by Tiago Salem Herrmann
add initial multi party call support
122
    mMultiparty = this->multiparty();
13 by Tiago Salem Herrmann
set status to no-answer for missed calls
123
    mPreviousState = this->state();
2 by Tiago Salem Herrmann
- add call channel support
124
    mObjPath = mBaseChannel->objectPath();
125
126
    Tp::CallMemberMap memberFlags;
127
    Tp::HandleIdentifierMap identifiers;
128
    QVariantMap stateDetails;
129
    Tp::CallStateReason reason;
130
131
    identifiers[mTargetHandle] = mPhoneNumber;
132
    reason.actor =  0;
133
    reason.reason = Tp::CallStateChangeReasonProgressMade;
134
    reason.message = "";
135
    reason.DBusReason = "";
13 by Tiago Salem Herrmann
set status to no-answer for missed calls
136
    if (mIncoming) {
2 by Tiago Salem Herrmann
- add call channel support
137
        memberFlags[mTargetHandle] = 0;
138
    } else {
139
        memberFlags[mTargetHandle] = Tp::CallMemberFlagRinging;
140
    }
141
142
    mCallChannel->setCallState(Tp::CallStateInitialising, 0, reason, stateDetails);
143
3 by Tiago Salem Herrmann
add dtmf support
144
    mCallContent = Tp::BaseCallContent::create(baseChannel()->dbusConnection(), baseChannel().data(), "audio", Tp::MediaStreamTypeAudio, Tp::MediaStreamDirectionNone);
145
146
    mDTMFIface = Tp::BaseCallContentDTMFInterface::create();
147
    mCallContent->plugInterface(Tp::AbstractCallContentInterfacePtr::dynamicCast(mDTMFIface));
148
    mCallChannel->addContent(mCallContent);
149
150
    mDTMFIface->setStartToneCallback(Tp::memFun(this,&oFonoCallChannel::onDTMFStartTone));
151
    mDTMFIface->setStopToneCallback(Tp::memFun(this,&oFonoCallChannel::onDTMFStopTone));
2 by Tiago Salem Herrmann
- add call channel support
152
153
    mCallChannel->setMembersFlags(memberFlags, identifiers, Tp::UIntList(), reason);
154
155
    mCallChannel->setCallState(Tp::CallStateInitialised, 0, reason, stateDetails);
156
    QObject::connect(mBaseChannel.data(), SIGNAL(closed()), this, SLOT(deleteLater()));
157
    QObject::connect(mConnection->callVolume(), SIGNAL(mutedChanged(bool)), SLOT(onOfonoMuteChanged(bool)));
5 by Tiago Salem Herrmann
- rename some methods
158
    QObject::connect(this, SIGNAL(stateChanged(QString)), SLOT(onOfonoCallStateChanged(QString)));
91.3.2 by Tiago Salem Herrmann
move SpeakerInterface to AudioOutputsInterface
159
    QObject::connect(mConnection, SIGNAL(activeAudioOutputChanged(QString)), mAudioOutputsIface.data(), SLOT(setActiveAudioOutput(QString)));
160
    QObject::connect(mConnection, SIGNAL(audioOutputsChanged(AudioOutputList)), mAudioOutputsIface.data(), SLOT(setAudioOutputs(AudioOutputList)));
58.1.1 by Tiago Salem Herrmann
check if the previous sendTones() succeeded before sending more tones
161
    QObject::connect(mConnection->voiceCallManager(), SIGNAL(sendTonesComplete(bool)), SLOT(onDtmfComplete(bool)));
60.3.1 by Tiago Salem Herrmann
add initial multi party call support
162
    QObject::connect(this, SIGNAL(multipartyChanged(bool)), this, SLOT(onMultipartyChanged(bool)));
75.1.1 by Tiago Salem Herrmann
use DisconnectReason() to decide if the call is missed
163
    
164
    QObject::connect(this, SIGNAL(disconnectReason(const QString &)), this, SLOT(onDisconnectReason(const QString &)));
34.1.1 by Tiago Salem Herrmann
use audioflinger and implement speaker mode
165
101.1.2 by Tiago Salem Herrmann
Hook qpulseaudioengine to the new AudioOutputs interface
166
    mAudioOutputsIface->setAudioOutputs(mConnection->audioOutputs());
91.3.2 by Tiago Salem Herrmann
move SpeakerInterface to AudioOutputsInterface
167
    mAudioOutputsIface->setActiveAudioOutput(mConnection->activeAudioOutput());
2 by Tiago Salem Herrmann
- add call channel support
168
}
169
75.1.1 by Tiago Salem Herrmann
use DisconnectReason() to decide if the call is missed
170
void oFonoCallChannel::onDisconnectReason(const QString &reason) {
171
    mRequestedHangup = reason == "local";
172
}
173
60.3.1 by Tiago Salem Herrmann
add initial multi party call support
174
void oFonoCallChannel::onMultipartyChanged(bool multiparty)
175
{
176
    // if previous state was multparty then split
177
    if (multiparty) {
178
        Q_EMIT merged();
179
    } else {
180
        Q_EMIT splitted();
181
    }
182
    mMultiparty = multiparty;
183
}
184
2 by Tiago Salem Herrmann
- add call channel support
185
void oFonoCallChannel::onOfonoMuteChanged(bool mute)
186
{
187
    Tp::LocalMuteState state = mute ? Tp::LocalMuteStateMuted : Tp::LocalMuteStateUnmuted;
188
    mMuteIface->setMuteState(state);
189
}
190
191
void oFonoCallChannel::onHoldStateChanged(const Tp::LocalHoldState &state, const Tp::LocalHoldStateReason &reason, Tp::DBusError *error)
192
{
193
    if (state == Tp::LocalHoldStateHeld && this->state() == "active") {
124.2.1 by Tiago Salem Herrmann
set holdState and holdStateReason accordingly
194
        QObject::connect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
2 by Tiago Salem Herrmann
- add call channel support
195
        mConnection->voiceCallManager()->swapCalls();
124.2.2 by Tiago Salem Herrmann
set pending hold state
196
        mHoldIface->setHoldState(Tp::LocalHoldStatePendingHold, Tp::LocalHoldStateReasonRequested);
2 by Tiago Salem Herrmann
- add call channel support
197
    } else if (state == Tp::LocalHoldStateUnheld && this->state() == "held") {
124.2.1 by Tiago Salem Herrmann
set holdState and holdStateReason accordingly
198
        QObject::connect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
2 by Tiago Salem Herrmann
- add call channel support
199
        mConnection->voiceCallManager()->swapCalls();
124.2.2 by Tiago Salem Herrmann
set pending hold state
200
        mHoldIface->setHoldState(Tp::LocalHoldStatePendingUnhold, Tp::LocalHoldStateReasonRequested);
2 by Tiago Salem Herrmann
- add call channel support
201
    }
202
}
203
124.2.1 by Tiago Salem Herrmann
set holdState and holdStateReason accordingly
204
void oFonoCallChannel::onSwapCallsComplete(bool success)
205
{
206
    Tp::LocalHoldState holdState = this->state() == "active" ? Tp::LocalHoldStateUnheld : Tp::LocalHoldStateHeld;
207
    Tp::LocalHoldStateReason reason = success ? Tp::LocalHoldStateReasonRequested : Tp::LocalHoldStateReasonResourceNotAvailable;
208
    QObject::disconnect(mConnection->voiceCallManager(), SIGNAL(swapCallsComplete(bool)), this, SLOT(onSwapCallsComplete(bool)));
209
    mHoldIface->setHoldState(holdState, reason);
210
}
211
2 by Tiago Salem Herrmann
- add call channel support
212
void oFonoCallChannel::onMuteStateChanged(const Tp::LocalMuteState &state, Tp::DBusError *error)
213
{
214
    if (state == Tp::LocalMuteStateMuted) {
215
        mConnection->callVolume()->setMuted(true);
45.1.5 by David Henningsson
Also call PulseAudio's mic mute function.
216
#ifdef USE_PULSEAUDIO
107.2.2 by Ricardo Salveti de Araujo
Better handling PA_DISABLED
217
        if (mHasPulseAudio)
64.2.5 by Tiago Salem Herrmann
add env variable to disable pulseaudio
218
            QPulseAudioEngine::instance()->setMicMute(true);
45.1.5 by David Henningsson
Also call PulseAudio's mic mute function.
219
#endif
2 by Tiago Salem Herrmann
- add call channel support
220
    } else if (state == Tp::LocalMuteStateUnmuted) {
221
        mConnection->callVolume()->setMuted(false);
45.1.5 by David Henningsson
Also call PulseAudio's mic mute function.
222
#ifdef USE_PULSEAUDIO
107.2.2 by Ricardo Salveti de Araujo
Better handling PA_DISABLED
223
        if (mHasPulseAudio)
64.2.5 by Tiago Salem Herrmann
add env variable to disable pulseaudio
224
            QPulseAudioEngine::instance()->setMicMute(false);
45.1.5 by David Henningsson
Also call PulseAudio's mic mute function.
225
#endif
2 by Tiago Salem Herrmann
- add call channel support
226
    }
227
}
228
58.1.1 by Tiago Salem Herrmann
check if the previous sendTones() succeeded before sending more tones
229
void oFonoCallChannel::sendNextDtmf()
230
{
231
    if (mDtmfLock) {
232
        return;
233
    }
58.1.3 by Tiago Salem Herrmann
invalidate the pending dtmf strings if the call status is changed
234
    if (!mDtmfPendingStrings.isEmpty()) {
235
        mDtmfLock = true;
236
        mConnection->voiceCallManager()->sendTones(mDtmfPendingStrings.front());
237
    }
58.1.1 by Tiago Salem Herrmann
check if the previous sendTones() succeeded before sending more tones
238
}
239
240
void oFonoCallChannel::onDtmfComplete(bool success)
241
{
105.1.1 by Tiago Salem Herrmann
don not process dtmf response if the channel is not active
242
    // this might be a response for another channel
243
    if (mCallChannel->callState() != Tp::CallStateActive) {
244
        return;
245
    }
58.1.1 by Tiago Salem Herrmann
check if the previous sendTones() succeeded before sending more tones
246
    mDtmfLock = false;
247
    if (success) {
105.1.1 by Tiago Salem Herrmann
don not process dtmf response if the channel is not active
248
       if (mDtmfPendingStrings.count() > 0) {
249
           mDtmfPendingStrings.removeFirst();
250
       }
58.1.1 by Tiago Salem Herrmann
check if the previous sendTones() succeeded before sending more tones
251
       if (mDtmfPendingStrings.isEmpty()) {
252
           return;
253
       }
254
       sendNextDtmf();
255
    } else {
256
        QTimer::singleShot(1000, this, SLOT(sendNextDtmf()));
257
    }
258
}
259
3 by Tiago Salem Herrmann
add dtmf support
260
void oFonoCallChannel::onDTMFStartTone(uchar event, Tp::DBusError *error)
261
{
262
    QString finalString;
263
    if (event == 10) {
264
        finalString = "*";
265
    } else if (event == 11) {
266
        finalString = "#";
267
    } else {
268
        finalString = QString::number(event);
269
    }
5 by Tiago Salem Herrmann
- rename some methods
270
3 by Tiago Salem Herrmann
add dtmf support
271
    qDebug() << "start tone" << finalString;
58.1.1 by Tiago Salem Herrmann
check if the previous sendTones() succeeded before sending more tones
272
    // we can't append to the first item in the queue as it is being sent and 
273
    // we dont know yet if it will succeed or not.
274
    if (mDtmfPendingStrings.count() > 1) {
275
        mDtmfPendingStrings[1] += finalString;
276
    } else {
277
        mDtmfPendingStrings << finalString;
278
    }
279
    sendNextDtmf();
3 by Tiago Salem Herrmann
add dtmf support
280
}
281
282
void oFonoCallChannel::onDTMFStopTone(Tp::DBusError *error)
283
{
284
}
285
2 by Tiago Salem Herrmann
- add call channel support
286
oFonoCallChannel::~oFonoCallChannel()
287
{
288
    qDebug() << "call channel closed";
289
    // TODO - for some reason the object is not being removed
290
    mConnection->dbusConnection().unregisterObject(mObjPath, QDBusConnection::UnregisterTree);
291
}
292
293
Tp::BaseChannelPtr oFonoCallChannel::baseChannel()
294
{
295
    return mBaseChannel;
296
}
297
5 by Tiago Salem Herrmann
- rename some methods
298
void oFonoCallChannel::onOfonoCallStateChanged(const QString &state)
2 by Tiago Salem Herrmann
- add call channel support
299
{
300
    Tp::CallStateReason reason;
301
    QVariantMap stateDetails;
302
    reason.actor =  0;
13 by Tiago Salem Herrmann
set status to no-answer for missed calls
303
    reason.reason = Tp::CallStateChangeReasonUserRequested;
2 by Tiago Salem Herrmann
- add call channel support
304
    reason.message = "";
305
    reason.DBusReason = "";
58.1.3 by Tiago Salem Herrmann
invalidate the pending dtmf strings if the call status is changed
306
    // we invalidate the pending dtmf strings if the call status is changed
307
    mDtmfPendingStrings.clear();
308
    mDtmfLock = false;
2 by Tiago Salem Herrmann
- add call channel support
309
    if (state == "disconnected") {
310
        qDebug() << "disconnected";
60.1.1 by Tiago Salem Herrmann
set NoAnswer also for waiting calls
311
        if (mIncoming && (mPreviousState == "incoming" || mPreviousState == "waiting") && !mRequestedHangup) {
13 by Tiago Salem Herrmann
set status to no-answer for missed calls
312
            reason.reason = Tp::CallStateChangeReasonNoAnswer;
313
        }
2 by Tiago Salem Herrmann
- add call channel support
314
        mCallChannel->setCallState(Tp::CallStateEnded, 0, reason, stateDetails);
60.3.5 by Tiago Salem Herrmann
add tests for conference calls
315
        Q_EMIT closed();
3 by Tiago Salem Herrmann
add dtmf support
316
        mBaseChannel->close();
2 by Tiago Salem Herrmann
- add call channel support
317
    } else if (state == "active") {
318
        qDebug() << "active";
319
        mHoldIface->setHoldState(Tp::LocalHoldStateUnheld, Tp::LocalHoldStateReasonNone);
60.3.4 by Tiago Salem Herrmann
handle conference call status (active/on hold)
320
        if (mMultiparty) {
321
            Q_EMIT multipartyCallActive();
322
        }
101.1.4 by Tiago Salem Herrmann
call enable_earpiece() on incoming calls, and only if this is the only call
323
        if (mPreviousState == "incoming") {
324
            mConnection->updateAudioRouteToEarpiece();
325
        }
22.1.1 by Tiago Salem Herrmann
unmute ofono modem when calls become active
326
        if (mPreviousState == "dialing" || mPreviousState == "alerting" || 
327
                mPreviousState == "incoming") {
328
            mConnection->callVolume()->setMuted(false);
23.1.1 by Tiago Salem Herrmann
Set calls to "accepted" so logger can set the right duration (LP: #1185078).
329
            mCallChannel->setCallState(Tp::CallStateAccepted, 0, reason, stateDetails);
22.1.1 by Tiago Salem Herrmann
unmute ofono modem when calls become active
330
        }
23.1.1 by Tiago Salem Herrmann
Set calls to "accepted" so logger can set the right duration (LP: #1185078).
331
        mCallChannel->setCallState(Tp::CallStateActive, 0, reason, stateDetails);
2 by Tiago Salem Herrmann
- add call channel support
332
    } else if (state == "held") {
333
        mHoldIface->setHoldState(Tp::LocalHoldStateHeld, Tp::LocalHoldStateReasonNone);
60.3.4 by Tiago Salem Herrmann
handle conference call status (active/on hold)
334
        if (mMultiparty) {
335
            Q_EMIT multipartyCallHeld();
336
        }
2 by Tiago Salem Herrmann
- add call channel support
337
        qDebug() << "held";
338
    } else if (state == "dialing") {
339
        qDebug() << "dialing";
340
    } else if (state == "alerting") {
341
        qDebug() << "alerting";
342
    } else if (state == "incoming") {
343
        qDebug() << "incoming";
344
    } else if (state == "waiting") {
345
        qDebug() << "waiting";
346
    }
34.1.2 by Tiago Salem Herrmann
enable speaker phone mode on incoming calls.
347
    // always update the audio route when call state changes
348
    mConnection->updateAudioRoute();
13 by Tiago Salem Herrmann
set status to no-answer for missed calls
349
    mPreviousState = state;
2 by Tiago Salem Herrmann
- add call channel support
350
}