43
44
#include "numbercategory.h"
44
45
#include "phonedirectorymodel.h"
45
46
#include "phonenumber.h"
46
#include "videorenderer.h"
47
#include "video/videorenderer.h"
47
48
#include "tlsmethodmodel.h"
48
49
#include "audiosettingsmodel.h"
50
#include "contactmodel.h"
52
//Track where state changes are performed on finished (over, error, failed) calls
53
//while not really problematic, it is technically wrong
54
#define Q_ASSERT_IS_IN_PROGRESS Q_ASSERT(state() != Call::State::OVER);
55
#define FORCE_ERROR_STATE() {qDebug() << "Fatal error on " << this << __FILE__ << __LINE__;\
56
changeCurrentState(Call::State::ERROR);}
50
58
const TypedStateMachine< TypedStateMachine< Call::State , Call::Action> , Call::State> Call::actionPerformedStateMap =
52
// ACCEPT REFUSE TRANSFER HOLD RECORD /**/
53
/*INCOMING */ {{Call::State::INCOMING , Call::State::INCOMING , Call::State::ERROR , Call::State::INCOMING , Call::State::INCOMING }},/**/
54
/*RINGING */ {{Call::State::ERROR , Call::State::RINGING , Call::State::ERROR , Call::State::ERROR , Call::State::RINGING }},/**/
55
/*CURRENT */ {{Call::State::ERROR , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::CURRENT }},/**/
56
/*DIALING */ {{Call::State::DIALING , Call::State::OVER , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
57
/*HOLD */ {{Call::State::ERROR , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::HOLD }},/**/
58
/*FAILURE */ {{Call::State::ERROR , Call::State::FAILURE , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
59
/*BUSY */ {{Call::State::ERROR , Call::State::BUSY , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
60
/*TRANSFER */ {{Call::State::TRANSFERRED, Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::TRANSFERRED }},/**/
61
/*TRANSF_HOLD */ {{Call::State::TRANSF_HOLD, Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::TRANSF_HOLD }},/**/
62
/*OVER */ {{Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
63
/*ERROR */ {{Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
64
/*CONF */ {{Call::State::ERROR , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::CURRENT }},/**/
65
/*CONF_HOLD */ {{Call::State::ERROR , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::HOLD }},/**/
60
// ACCEPT REFUSE TRANSFER HOLD RECORD /**/
61
/*INCOMING */ {{Call::State::INCOMING , Call::State::INCOMING , Call::State::ERROR , Call::State::INCOMING , Call::State::INCOMING }},/**/
62
/*RINGING */ {{Call::State::ERROR , Call::State::RINGING , Call::State::ERROR , Call::State::ERROR , Call::State::RINGING }},/**/
63
/*CURRENT */ {{Call::State::ERROR , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::CURRENT }},/**/
64
/*DIALING */ {{Call::State::INITIALIZATION, Call::State::OVER , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
65
/*HOLD */ {{Call::State::ERROR , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::HOLD }},/**/
66
/*FAILURE */ {{Call::State::ERROR , Call::State::OVER , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
67
/*BUSY */ {{Call::State::ERROR , Call::State::BUSY , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
68
/*TRANSFER */ {{Call::State::TRANSFERRED , Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::TRANSFERRED }},/**/
69
/*TRANSF_HOLD */ {{Call::State::TRANSF_HOLD , Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::TRANSF_HOLD }},/**/
70
/*OVER */ {{Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
71
/*ERROR */ {{Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
72
/*CONF */ {{Call::State::ERROR , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::CURRENT }},/**/
73
/*CONF_HOLD */ {{Call::State::ERROR , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::HOLD }},/**/
74
/*INIT */ {{Call::State::INITIALIZATION, Call::State::OVER , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
74
83
/*CURRENT */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord }},/**/
75
84
/*DIALING */ {{&Call::call , &Call::cancel , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
76
85
/*HOLD */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::unhold , &Call::setRecord }},/**/
77
/*FAILURE */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
86
/*FAILURE */ {{&Call::nothing , &Call::remove , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
78
87
/*BUSY */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
79
88
/*TRANSFERT */ {{&Call::transfer , &Call::hangUp , &Call::transfer , &Call::hold , &Call::setRecord }},/**/
80
89
/*TRANSFERT_HOLD */ {{&Call::transfer , &Call::hangUp , &Call::transfer , &Call::unhold , &Call::setRecord }},/**/
101
111
/*ERROR */ {{Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
102
112
/*CONF */ {{Call::State::CURRENT , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
103
113
/*CONF_HOLD */ {{Call::State::HOLD , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
114
/*INIT */ {{Call::State::RINGING , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
106
117
const TypedStateMachine< TypedStateMachine< function , Call::DaemonState > , Call::State > Call::stateChangedFunctionMap =
108
119
// RINGING CURRENT BUSY HOLD HUNGUP FAILURE /**/
109
/*INCOMING */ {{&Call::nothing , &Call::start , &Call::startWeird , &Call::startWeird , &Call::startStop , &Call::start }},/**/
110
/*RINGING */ {{&Call::nothing , &Call::start , &Call::start , &Call::start , &Call::startStop , &Call::start }},/**/
120
/*INCOMING */ {{&Call::nothing , &Call::start , &Call::startWeird , &Call::startWeird , &Call::startStop , &Call::failure }},/**/
121
/*RINGING */ {{&Call::nothing , &Call::start , &Call::start , &Call::start , &Call::startStop , &Call::failure }},/**/
111
122
/*CURRENT */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
112
123
/*DIALING */ {{&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::warning }},/**/
113
124
/*HOLD */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
119
130
/*ERROR */ {{&Call::error , &Call::error , &Call::error , &Call::error , &Call::stop , &Call::error }},/**/
120
131
/*CONF */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
121
132
/*CONF_HOLD */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
133
/*INIT */ {{&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::warning }},/**/
136
const TypedStateMachine< Call::LifeCycleState , Call::State > Call::metaStateMap =
138
/* * Life cycle meta-state **/
139
/*INCOMING */ Call::LifeCycleState::INITIALIZATION ,/**/
140
/*RINGING */ Call::LifeCycleState::INITIALIZATION ,/**/
141
/*CURRENT */ Call::LifeCycleState::PROGRESS ,/**/
142
/*DIALING */ Call::LifeCycleState::INITIALIZATION ,/**/
143
/*HOLD */ Call::LifeCycleState::PROGRESS ,/**/
144
/*FAILURE */ Call::LifeCycleState::FINISHED ,/**/
145
/*BUSY */ Call::LifeCycleState::FINISHED ,/**/
146
/*TRANSFERT */ Call::LifeCycleState::PROGRESS ,/**/
147
/*TRANSFERT_HOLD */ Call::LifeCycleState::PROGRESS ,/**/
148
/*OVER */ Call::LifeCycleState::FINISHED ,/**/
149
/*ERROR */ Call::LifeCycleState::FINISHED ,/**/
150
/*CONF */ Call::LifeCycleState::PROGRESS ,/**/
151
/*CONF_HOLD */ Call::LifeCycleState::PROGRESS ,/**/
152
/*INIT */ Call::LifeCycleState::INITIALIZATION ,/**/
155
const TypedStateMachine< TypedStateMachine< bool , Call::LifeCycleState > , Call::State > Call::metaStateTransitionValidationMap =
157
/* * INITIALIZATION PROGRESS FINISHED **/
158
/*INCOMING */ {{ true , false , false }},/**/
159
/*RINGING */ {{ true , false , false }},/**/
160
/*CURRENT */ {{ true , true , false }},/**/
161
/*DIALING */ {{ true , false , false }},/**/
162
/*HOLD */ {{ true , true , false }},/**/
163
/*FAILURE */ {{ true , true , false }},/**/
164
/*BUSY */ {{ true , false , false }},/**/
165
/*TRANSFERT */ {{ false , true , false }},/**/
166
/*TRANSFERT_HOLD */ {{ false , true , false }},/**/
167
/*OVER */ {{ true , true , true }},/**/
168
/*ERROR */ {{ true , true , false }},/**/
169
/*CONF */ {{ true , false , false }},/**/
170
/*CONF_HOLD */ {{ true , false , false }},/**/
171
/*INIT */ {{ true , false , false }},/**/
173
/*^^ A call _can_ be created on hold (conference) and as over (peer hang up before pickup)
174
the progress->failure one is an implementation bug*/
124
177
QDebug LIB_EXPORT operator<<(QDebug dbg, const Call::State& c)
126
179
dbg.nospace() << QString(Call::toHumanStateName(c));
136
189
QDebug LIB_EXPORT operator<<(QDebug dbg, const Call::Action& c)
138
dbg.nospace() << static_cast<int>(c);
192
case Call::Action::ACCEPT:
193
dbg.nospace() << "ACCEPT";
194
case Call::Action::REFUSE:
195
dbg.nospace() << "REFUSE";
196
case Call::Action::TRANSFER:
197
dbg.nospace() << "TRANSFER";
198
case Call::Action::HOLD:
199
dbg.nospace() << "HOLD";
200
case Call::Action::RECORD:
201
dbg.nospace() << "RECORD";
202
case Call::Action::__COUNT:
203
dbg.nospace() << "COUNT";
206
dbg.nospace() << '(' << static_cast<int>(c) << ')';
139
207
return dbg.space();
142
AbstractContactBackend* Call::m_pContactBackend = nullptr;
143
Call* Call::m_sSelectedCall = nullptr;
145
void Call::setContactBackend(AbstractContactBackend* be)
147
m_pContactBackend = be;
150
AbstractContactBackend* Call::contactBackend ()
152
return m_pContactBackend;
156
211
Call::Call(Call::State startState, const QString& callId, const QString& peerName, PhoneNumber* number, Account* account)
157
: QObject(CallModel::instance()), m_isConference(false),m_pStopTimeStamp(0),
212
: QObject(CallModel::instance()),m_pStopTimeStamp(0),
158
213
m_pImModel(nullptr),m_pTimer(nullptr),m_Recording(false),m_Account(nullptr),
159
214
m_PeerName(peerName),m_pPeerPhoneNumber(number),m_HistoryConst(HistoryTimeCategoryModel::HistoryConst::Never),
160
215
m_CallId(callId),m_CurrentState(startState),m_pStartTimeStamp(0),m_pDialNumber(nullptr),m_pTransferNumber(nullptr),
161
m_History(false),m_Missed(false),m_Direction(Call::Direction::OUTGOING)
216
m_History(false),m_Missed(false),m_Direction(Call::Direction::OUTGOING),m_pBackend(nullptr),m_Type(Call::Type::CALL)
163
218
m_Account = account;
164
219
Q_ASSERT(!callId.isEmpty());
183
238
Call::Call(const QString& confId, const QString& account): QObject(CallModel::instance()),
184
m_pStopTimeStamp(0),m_pStartTimeStamp(0),m_pImModel(nullptr),m_ConfId(confId),
239
m_pStopTimeStamp(0),m_pStartTimeStamp(0),m_pImModel(nullptr),
185
240
m_Account(AccountListModel::instance()->getAccountById(account)),m_CurrentState(Call::State::CONFERENCE),
186
m_pTimer(nullptr), m_isConference(false),m_pPeerPhoneNumber(nullptr),m_pDialNumber(nullptr),m_pTransferNumber(nullptr),
241
m_pTimer(nullptr),m_pPeerPhoneNumber(nullptr),m_pDialNumber(nullptr),m_pTransferNumber(nullptr),
187
242
m_HistoryConst(HistoryTimeCategoryModel::HistoryConst::Never),m_History(false),m_Missed(false),
188
m_Direction(Call::Direction::OUTGOING)
243
m_Direction(Call::Direction::OUTGOING),m_pBackend(nullptr), m_CallId(confId),
244
m_Type((!confId.isEmpty())?Call::Type::CONFERENCE:Call::Type::CALL)
190
246
setObjectName("Conf:"+confId);
191
m_isConference = !m_ConfId.isEmpty();
192
247
m_pUserActionModel = new UserActionModel(this);
194
if (m_isConference) {
249
if (type() == Call::Type::CONFERENCE) {
196
251
::time(&curTime);
197
252
setStartTimeStamp(curTime);
198
m_pTimer = new QTimer(this);
199
m_pTimer->setInterval(1000);
200
connect(m_pTimer,SIGNAL(timeout()),this,SLOT(updated()));
202
254
CallManagerInterface& callManager = DBus::CallManager::instance();
203
MapStringString details = callManager.getConferenceDetails(m_ConfId) ;
204
m_CurrentState = confStatetoCallState(details["CONF_STATE"]);
255
MapStringString details = callManager.getConferenceDetails(id()) ;
256
m_CurrentState = confStatetoCallState(details[ConfDetailsMapFields::CONF_STATE]);
205
257
emit stateChanged();
317
366
Call* Call::buildHistoryCall(const QMap<QString,QString>& hc)
319
368
const QString& callId = hc[ Call::HistoryMapFields::CALLID ] ;
320
time_t startTimeStamp = hc[ Call::HistoryMapFields::TIMESTAMP_START ].toUInt() ;
321
time_t stopTimeStamp = hc[ Call::HistoryMapFields::TIMESTAMP_STOP ].toUInt() ;
322
const QString& accId = hc[ Call::HistoryMapFields::ACCOUNT_ID ] ;
323
369
const QString& name = hc[ Call::HistoryMapFields::DISPLAY_NAME ] ;
324
370
const QString& number = hc[ Call::HistoryMapFields::PEER_NUMBER ] ;
325
371
const QString& type = hc[ Call::HistoryMapFields::STATE ] ;
326
372
const QString& direction = hc[ Call::HistoryMapFields::DIRECTION ] ;
327
const bool missed = hc[ Call::HistoryMapFields::MISSED ] == "true";
373
const bool missed = hc[ Call::HistoryMapFields::MISSED ] == "1";
374
time_t startTimeStamp = hc[ Call::HistoryMapFields::TIMESTAMP_START ].toUInt() ;
375
time_t stopTimeStamp = hc[ Call::HistoryMapFields::TIMESTAMP_STOP ].toUInt() ;
376
QString accId = hc[ Call::HistoryMapFields::ACCOUNT_ID ] ;
378
if (accId.isEmpty()) {
379
qWarning() << "An history call has an invalid account identifier";
380
accId = QString(Account::ProtocolName::IP2IP);
383
//Try to assiciate a contact now, the real contact object is probably not
384
//loaded yet, but we can get a placeholder for now
385
// const QString& contactUsed = hc[ Call::HistoryMapFields::CONTACT_USED ]; //TODO
386
const QString& contactUid = hc[ Call::HistoryMapFields::CONTACT_UID ];
388
Contact* ct = nullptr;
389
if (!hc[ Call::HistoryMapFields::CONTACT_UID].isEmpty())
390
ct = ContactModel::instance()->getPlaceHolder(contactUid.toAscii());
329
392
Account* acc = AccountListModel::instance()->getAccountById(accId);
330
PhoneNumber* nb = PhoneDirectoryModel::instance()->getNumber(number,acc);
393
PhoneNumber* nb = PhoneDirectoryModel::instance()->getNumber(number,ct,acc);
331
395
Call* call = new Call(Call::State::OVER, callId, (name == "empty")?QString():name, nb, acc );
333
397
call->m_pStopTimeStamp = stopTimeStamp ;
334
398
call->m_History = true;
335
399
call->setStartTimeStamp(startTimeStamp);
337
400
call->m_HistoryState = historyStateFromType(type);
338
401
call->m_Account = AccountListModel::instance()->getAccountById(accId);
768
844
m_Account = account;
847
/// Set the backend to save this call to. It is currently impossible to migrate.
848
void Call::setBackend(AbstractHistoryBackend* backend)
850
m_pBackend = backend;
771
853
/*****************************************************************************
775
857
****************************************************************************/
777
///The call state just changed
859
///The call state just changed (by the daemon)
778
860
Call::State Call::stateChanged(const QString& newStateName)
780
Call::State previousState = m_CurrentState;
781
if (!m_isConference) {
862
const Call::State previousState = m_CurrentState;
863
if (type() != Call::Type::CONFERENCE) {
782
864
Call::DaemonState dcs = toDaemonCallState(newStateName);
783
if (dcs == Call::DaemonState::COUNT || m_CurrentState == Call::State::COUNT) {
865
if (dcs == Call::DaemonState::__COUNT || m_CurrentState == Call::State::__COUNT) {
784
866
qDebug() << "Error: Invalid state change";
785
867
return Call::State::FAILURE;
869
// if (previousState == stateChangedStateMap[m_CurrentState][dcs]) {
871
// qDebug() << "Trying to change state with the same state" << previousState;
873
// return previousState;
877
//Validate if the transition respect the expected life cycle
878
if (!metaStateTransitionValidationMap[stateChangedStateMap[m_CurrentState][dcs]][lifeCycleState()]) {
879
qWarning() << "Unexpected state transition from" << state() << "to" << stateChangedStateMap[m_CurrentState][dcs];
789
882
changeCurrentState(stateChangedStateMap[m_CurrentState][dcs]);
791
884
catch(Call::State& state) {
792
885
qDebug() << "State change failed (stateChangedStateMap)" << state;
793
m_CurrentState = Call::State::ERROR;
796
887
return m_CurrentState;
798
889
catch(Call::DaemonState& state) {
799
890
qDebug() << "State change failed (stateChangedStateMap)" << state;
800
m_CurrentState = Call::State::ERROR;
803
892
return m_CurrentState;
806
895
qDebug() << "State change failed (stateChangedStateMap) other";;
807
m_CurrentState = Call::State::ERROR;
810
897
return m_CurrentState;
821
908
catch(Call::State& state) {
822
909
qDebug() << "State change failed (stateChangedFunctionMap)" << state;
823
m_CurrentState = Call::State::ERROR;
826
911
return m_CurrentState;
828
913
catch(Call::DaemonState& state) {
829
914
qDebug() << "State change failed (stateChangedFunctionMap)" << state;
830
m_CurrentState = Call::State::ERROR;
833
916
return m_CurrentState;
836
919
qDebug() << "State change failed (stateChangedFunctionMap) other";;
837
m_CurrentState = Call::State::ERROR;
840
921
return m_CurrentState;
844
925
//Until now, it does not worth using stateChangedStateMap, conferences are quite simple
845
m_CurrentState = confStatetoCallState(newStateName);
926
//update 2014: Umm... wrong
927
m_CurrentState = confStatetoCallState(newStateName); //TODO don't do this
846
928
emit stateChanged();
848
if ((m_CurrentState == Call::State::HOLD || m_CurrentState == Call::State::CURRENT) && !m_pTimer) {
849
m_pTimer = new QTimer(this);
850
m_pTimer->setInterval(1000);
851
connect(m_pTimer,SIGNAL(timeout()),this,SLOT(updated()));
854
930
if (m_CurrentState != Call::State::DIALING && m_pDialNumber) {
855
931
if (!m_pPeerPhoneNumber)
856
932
m_pPeerPhoneNumber = PhoneDirectoryModel::instance()->fromTemporary(m_pDialNumber);
893
973
catch(Call::State& state) {
894
974
qDebug() << "State change failed (actionPerformedFunctionMap)" << state;
895
m_CurrentState = Call::State::ERROR;
898
976
return Call::State::ERROR;
900
978
catch(Call::Action& action) {
901
979
qDebug() << "State change failed (actionPerformedFunctionMap)" << action;
902
m_CurrentState = Call::State::ERROR;
905
981
return Call::State::ERROR;
908
984
qDebug() << "State change failed (actionPerformedFunctionMap) other";;
909
m_CurrentState = Call::State::ERROR;
912
986
return m_CurrentState;
914
qDebug() << "Calling action " << action << " on call with state " << previousState << ". Become " << m_CurrentState;
988
qDebug() << "Calling action " << action << " on " << id() << " with state " << previousState << ". Become " << m_CurrentState;
915
989
return m_CurrentState;
916
990
} //actionPerformed
992
///Change the state, do not abuse of this, but it is necessary for error cases
919
993
void Call::changeCurrentState(Call::State newState)
921
if (newState == Call::State::COUNT) {
995
if (newState == Call::State::__COUNT) {
922
996
qDebug() << "Error: Call reach invalid state";
923
m_CurrentState = Call::State::ERROR;
979
1055
https://projects.savoirfairelinux.com/projects/sflphone/issues");
1058
///Change history state to failure
1059
void Call::failure()
1062
//This is how it always was done
1063
//The main point is to leave the call in the CallList
982
1067
///Accept the call
983
1068
void Call::accept()
1070
Q_ASSERT_IS_IN_PROGRESS
985
1072
CallManagerInterface & callManager = DBus::CallManager::instance();
986
qDebug() << "Accepting call. callId : " << m_CallId << "ConfId:" << m_ConfId;
1073
qDebug() << "Accepting call. callId : " << m_CallId << "ConfId:" << id();
987
1074
Q_NOREPLY callManager.accept(m_CallId);
989
1076
::time(&curTime);
990
1077
setStartTimeStamp(curTime);
991
1078
this->m_HistoryState = LegacyHistoryState::INCOMING;
992
1079
m_Direction = Call::Direction::INCOMING;
994
m_pTimer = new QTimer(this);
995
m_pTimer->setInterval(1000);
996
connect(m_pTimer,SIGNAL(timeout()),this,SLOT(updated()));
1001
1082
///Refuse the call
1002
1083
void Call::refuse()
1004
1085
CallManagerInterface & callManager = DBus::CallManager::instance();
1005
qDebug() << "Refusing call. callId : " << m_CallId << "ConfId:" << m_ConfId;
1006
Q_NOREPLY callManager.refuse(m_CallId);
1086
qDebug() << "Refusing call. callId : " << m_CallId << "ConfId:" << id();
1087
const bool ret = callManager.refuse(m_CallId);
1007
1088
time_t curTime;
1008
1089
::time(&curTime);
1009
1090
setStartTimeStamp(curTime);
1010
1091
this->m_HistoryState = Call::LegacyHistoryState::MISSED;
1011
1092
m_Missed = true;
1094
//If the daemon crashed then re-spawned when a call is ringing, this happen.
1014
1099
///Accept the transfer
1015
1100
void Call::acceptTransf()
1102
Q_ASSERT_IS_IN_PROGRESS
1017
1104
if (!m_pTransferNumber) {
1018
1105
qDebug() << "Trying to transfer to no one";
1021
1108
CallManagerInterface & callManager = DBus::CallManager::instance();
1022
qDebug() << "Accepting call and transferring it to number : " << m_pTransferNumber->uri() << ". callId : " << m_CallId << "ConfId:" << m_ConfId;
1109
qDebug() << "Accepting call and transferring it to number : " << m_pTransferNumber->uri() << ". callId : " << m_CallId << "ConfId:" << id();
1023
1110
callManager.accept(m_CallId);
1024
1111
Q_NOREPLY callManager.transfer(m_CallId, m_pTransferNumber->uri());
1074
1174
///Cancel this call
1075
1175
void Call::cancel()
1177
//This one can be over if the peer server failed to comply with the correct sequence
1077
1178
CallManagerInterface & callManager = DBus::CallManager::instance();
1078
qDebug() << "Canceling call. callId : " << m_CallId << "ConfId:" << m_ConfId;
1179
qDebug() << "Canceling call. callId : " << m_CallId << "ConfId:" << id();
1079
1180
emit dialNumberChanged(QString());
1080
Q_NOREPLY callManager.hangUp(m_CallId);
1181
// Q_NOREPLY callManager.hangUp(m_CallId);
1182
if (!callManager.hangUp(m_CallId)) {
1183
qWarning() << "HangUp failed, the call was probably already over";
1184
changeCurrentState(Call::State::OVER);
1084
1189
void Call::hold()
1191
Q_ASSERT_IS_IN_PROGRESS
1086
1193
CallManagerInterface & callManager = DBus::CallManager::instance();
1087
qDebug() << "Holding call. callId : " << m_CallId << "ConfId:" << m_ConfId;
1088
if (!isConference())
1194
qDebug() << "Holding call. callId : " << m_CallId << "ConfId:" << id();
1195
if (type() != Call::Type::CONFERENCE)
1089
1196
Q_NOREPLY callManager.hold(m_CallId);
1091
Q_NOREPLY callManager.holdConference(m_ConfId);
1198
Q_NOREPLY callManager.holdConference(id());
1094
1201
///Start the call
1095
1202
void Call::call()
1204
Q_ASSERT_IS_IN_PROGRESS
1097
1206
CallManagerInterface& callManager = DBus::CallManager::instance();
1098
1207
qDebug() << "account = " << m_Account;
1099
1208
if(!m_Account) {
1101
1210
this->m_Account = AccountListModel::currentAccount();
1103
1212
//Calls to empty URI should not be allowed, sflphoned will go crazy
1104
if (m_pDialNumber->uri().isEmpty()) {
1213
if ((!m_pDialNumber) || m_pDialNumber->uri().isEmpty()) {
1105
1214
qDebug() << "Trying to call an empty URI";
1106
m_CurrentState = Call::State::FAILURE;
1215
changeCurrentState(Call::State::FAILURE);
1216
if (!m_pDialNumber) {
1108
1217
emit dialNumberChanged(QString());
1220
delete m_pDialNumber;
1221
m_pDialNumber = nullptr;
1109
1223
setPeerName(tr("Failure"));
1110
1224
emit stateChanged();
1111
1225
emit changed();
1112
delete m_pDialNumber;
1113
m_pDialNumber = nullptr;
1116
1228
else if(m_Account) {
1117
qDebug() << "Calling " << peerPhoneNumber()->uri() << " with account " << m_Account << ". callId : " << m_CallId << "ConfId:" << m_ConfId;
1229
qDebug() << "Calling " << peerPhoneNumber()->uri() << " with account " << m_Account << ". callId : " << m_CallId << "ConfId:" << id();
1118
1230
callManager.placeCall(m_Account->id(), m_CallId, m_pDialNumber->uri());
1119
1231
this->m_pPeerPhoneNumber = PhoneDirectoryModel::instance()->getNumber(m_pDialNumber->uri(),account());
1120
if (m_pContactBackend) {
1232
if (ContactModel::instance()->hasBackends()) {
1121
1233
if (peerPhoneNumber()->contact())
1122
1234
m_PeerName = peerPhoneNumber()->contact()->formattedName();