diff --git a/fscomm/call.cpp b/fscomm/call.cpp index 1fa8775e32..a13f01712e 100644 --- a/fscomm/call.cpp +++ b/fscomm/call.cpp @@ -32,7 +32,9 @@ #include Call::Call() -{} +{ + _answeredEpoch = 0; +} switch_status_t Call::toggleRecord(bool startRecord) { @@ -70,6 +72,23 @@ void Call::sendDTMF(QString digit) QTime Call::getCurrentStateTime() { - int now = QDateTime::fromTime_t(_answered_epoch).secsTo(QDateTime::currentDateTime()); + qulonglong time = 0; + + if (_state == FSCOMM_CALL_STATE_ANSWERED) + { + time = _answeredEpoch; + } + else if(_state == FSCOMM_CALL_STATE_RINGING) + { + if (_direction == FSCOMM_CALL_DIRECTION_INBOUND) + { + /* TODO: DOESNT WORK - How do I get what time it started to ring? */ + _channel.data()->getProgressEpoch() == 0 ? time = _channel.data()->getProgressMediaEpoch() : time = _channel.data()->getProgressEpoch(); + } + else + _otherLegChannel.data()->getProgressEpoch() == 0 ? time = _otherLegChannel.data()->getProgressMediaEpoch() : time = _otherLegChannel.data()->getProgressEpoch(); + } + + int now = QDateTime::fromTime_t(time).secsTo(QDateTime::currentDateTime()); return QTime::fromString(QString::number(now), "s"); } diff --git a/fscomm/call.h b/fscomm/call.h index 5662a75876..891bb17f54 100644 --- a/fscomm/call.h +++ b/fscomm/call.h @@ -72,7 +72,7 @@ public: bool isActive() { return _isActive == true; } switch_status_t toggleRecord(bool); void sendDTMF(QString digit); - void setAnsweredEpoch(qulonglong time) { _answered_epoch = time/1000000; } + void setAnsweredEpoch(qulonglong time) { _answeredEpoch = time/1000000; } QTime getCurrentStateTime(); private: @@ -85,7 +85,7 @@ private: bool _isActive; QString _recording_filename; fscomm_call_state_t _state; - qulonglong _answered_epoch; + qulonglong _answeredEpoch; }; Q_DECLARE_METATYPE(Call) diff --git a/fscomm/channel.cpp b/fscomm/channel.cpp index 75f1aaf29e..ca056854c2 100644 --- a/fscomm/channel.cpp +++ b/fscomm/channel.cpp @@ -3,4 +3,6 @@ Channel::Channel(QString uuid): _uuid(uuid) { + _progressEpoch = 0; + _progressMediaEpoch = 0; } diff --git a/fscomm/channel.h b/fscomm/channel.h index 2dc744261e..b97126cda7 100644 --- a/fscomm/channel.h +++ b/fscomm/channel.h @@ -16,14 +16,22 @@ public: void setDestinatinonNumber(QString destinationNumber) { _destinationNumber = destinationNumber; } QString getDestinationNumber() { return _destinationNumber; } - int getPaCallId() { return _pa_call_id; } + int getPaCallId() { return _paCallId; } + void setPaCallId(int paCallId) { _paCallId = paCallId;} + + void setProgressEpoch(qulonglong time) { _progressEpoch = time/1000000; } + qulonglong getProgressEpoch() { return _progressEpoch; } + void setProgressMediaEpoch(qulonglong time) { _progressMediaEpoch = time/1000000; } + qulonglong getProgressMediaEpoch() { return _progressMediaEpoch; } private: QString _uuid; QString _cidName; QString _cidNumber; QString _destinationNumber; - int _pa_call_id; + int _paCallId; + qulonglong _progressEpoch; + qulonglong _progressMediaEpoch; }; Q_DECLARE_METATYPE(Channel) diff --git a/fscomm/fshost.cpp b/fscomm/fshost.cpp index 609f7e9351..3d7984fcdc 100644 --- a/fscomm/fshost.cpp +++ b/fscomm/fshost.cpp @@ -168,11 +168,11 @@ void FSHost::run(void) } } -void FSHost::generalEventHandler(switch_event_t *event) +void FSHost::generalEventHandler(QSharedPointerevent) { - QString uuid = switch_event_get_header_nil(event, "Unique-ID"); + QString uuid = switch_event_get_header_nil(event.data(), "Unique-ID"); - switch(event->event_id) { + switch(event.data()->event_id) { case SWITCH_EVENT_CHANNEL_CREATE: /*1A - 17B*/ { eventChannelCreate(event, uuid); @@ -218,6 +218,11 @@ void FSHost::generalEventHandler(switch_event_t *event) eventCallUpdate(event, uuid); break; } + case SWITCH_EVENT_CHANNEL_PROGRESS: + { + eventChannelProgress(event, uuid); + break; + } case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA:/*26B*/ { eventChannelProgressMedia(event, uuid); @@ -256,63 +261,63 @@ void FSHost::generalEventHandler(switch_event_t *event) } case SWITCH_EVENT_CUSTOM:/*5A*/ { - if (strcmp(event->subclass_name, "sofia::gateway_state") == 0) + if (strcmp(event.data()->subclass_name, "sofia::gateway_state") == 0) { - QString state = switch_event_get_header_nil(event, "State"); - QString gw = switch_event_get_header_nil(event, "Gateway"); + QString state = switch_event_get_header_nil(event.data(), "State"); + QString gw = switch_event_get_header_nil(event.data(), "Gateway"); QSharedPointer acc = _accounts.value(gw); if (acc.isNull()) return; if (state == "TRYING") { - acc.data()->setStatusPhrase(switch_event_get_header_nil(event, "Phrase")); + acc.data()->setStatusPhrase(switch_event_get_header_nil(event.data(), "Phrase")); acc.data()->setState(FSCOMM_GW_STATE_TRYING); emit accountStateChange(acc); } else if (state == "REGISTER") { - acc.data()->setStatusPhrase(switch_event_get_header_nil(event, "Phrase")); + acc.data()->setStatusPhrase(switch_event_get_header_nil(event.data(), "Phrase")); acc.data()->setState(FSCOMM_GW_STATE_REGISTER); emit accountStateChange(acc); } else if (state == "REGED") { - acc.data()->setStatusPhrase(switch_event_get_header_nil(event, "Phrase")); + acc.data()->setStatusPhrase(switch_event_get_header_nil(event.data(), "Phrase")); acc.data()->setState(FSCOMM_GW_STATE_REGED); emit accountStateChange(acc); } else if (state == "UNREGED") { - acc.data()->setStatusPhrase(switch_event_get_header_nil(event, "Phrase")); + acc.data()->setStatusPhrase(switch_event_get_header_nil(event.data(), "Phrase")); acc.data()->setState(FSCOMM_GW_STATE_UNREGED); emit accountStateChange(acc); } else if (state == "UNREGISTER") { - acc.data()->setStatusPhrase(switch_event_get_header_nil(event, "Phrase")); + acc.data()->setStatusPhrase(switch_event_get_header_nil(event.data(), "Phrase")); acc.data()->setState(FSCOMM_GW_STATE_UNREGISTER); emit accountStateChange(acc); } else if (state =="FAILED") { - acc.data()->setStatusPhrase(switch_event_get_header_nil(event, "Phrase")); + acc.data()->setStatusPhrase(switch_event_get_header_nil(event.data(), "Phrase")); acc.data()->setState(FSCOMM_GW_STATE_FAILED); emit accountStateChange(acc); } else if (state == "FAIL_WAIT") { acc.data()->setState(FSCOMM_GW_STATE_FAIL_WAIT); emit accountStateChange(acc); } else if (state == "EXPIRED") { - acc.data()->setStatusPhrase(switch_event_get_header_nil(event, "Phrase")); + acc.data()->setStatusPhrase(switch_event_get_header_nil(event.data(), "Phrase")); acc.data()->setState(FSCOMM_GW_STATE_EXPIRED); emit accountStateChange(acc); } else if (state == "NOREG") { - acc.data()->setStatusPhrase(switch_event_get_header_nil(event, "Phrase")); + acc.data()->setStatusPhrase(switch_event_get_header_nil(event.data(), "Phrase")); acc.data()->setState(FSCOMM_GW_STATE_NOREG); emit accountStateChange(acc); } } - else if (strcmp(event->subclass_name, "sofia::gateway_add") == 0) + else if (strcmp(event.data()->subclass_name, "sofia::gateway_add") == 0) { - QString gw = switch_event_get_header_nil(event, "Gateway"); + QString gw = switch_event_get_header_nil(event.data(), "Gateway"); Account * accPtr = new Account(gw); QSharedPointer acc = QSharedPointer(accPtr); acc.data()->setState(FSCOMM_GW_STATE_NOAVAIL); _accounts.insert(gw, acc); emit newAccount(acc); } - else if (strcmp(event->subclass_name, "sofia::gateway_delete") == 0) + else if (strcmp(event.data()->subclass_name, "sofia::gateway_delete") == 0) { - QSharedPointer acc = _accounts.take(switch_event_get_header_nil(event, "Gateway")); + QSharedPointer acc = _accounts.take(switch_event_get_header_nil(event.data(), "Gateway")); if (!acc.isNull()) emit delAccount(acc); } @@ -324,8 +329,8 @@ void FSHost::generalEventHandler(switch_event_t *event) } case SWITCH_EVENT_MODULE_LOAD: { - QString modType = switch_event_get_header_nil(event, "type"); - QString modKey = switch_event_get_header_nil(event, "key"); + QString modType = switch_event_get_header_nil(event.data(), "type"); + QString modKey = switch_event_get_header_nil(event.data(), "key"); emit loadedModule(modType, modKey); break; } @@ -334,38 +339,41 @@ void FSHost::generalEventHandler(switch_event_t *event) } } -void FSHost::eventChannelCreate(switch_event_t *event, QString uuid) +void FSHost::eventChannelCreate(QSharedPointerevent, QString uuid) { Channel *channelPtr = new Channel(uuid); QSharedPointerchannel(channelPtr); _channels.insert(uuid, channel); } -void FSHost::eventChannelAnswer(switch_event_t *event, QString uuid) +void FSHost::eventChannelAnswer(QSharedPointerevent, QString uuid) { - _channels.value(uuid).data()->setDestinatinonNumber(switch_event_get_header_nil(event, "Caller-Destination-Number")); + _channels.value(uuid).data()->setDestinatinonNumber(switch_event_get_header_nil(event.data(), "Caller-Destination-Number")); if (_active_calls.contains(uuid)) { - _active_calls.value(uuid).data()->setAnsweredEpoch(QString(switch_event_get_header_nil(event, "Caller-Channel-Answered-Time")).toULongLong()); + _active_calls.value(uuid).data()->setAnsweredEpoch(QString(switch_event_get_header_nil(event.data(), "Caller-Channel-Answered-Time")).toULongLong()); + _active_calls.value(uuid).data()->setState(FSCOMM_CALL_STATE_ANSWERED); emit answered(_active_calls.value(uuid)); } } -void FSHost::eventChannelState(switch_event_t *event, QString uuid) +void FSHost::eventChannelState(QSharedPointerevent, QString uuid) {} -void FSHost::eventChannelExecute(switch_event_t *event, QString uuid) +void FSHost::eventChannelExecute(QSharedPointerevent, QString uuid) {} -void FSHost::eventChannelExecuteComplete(switch_event_t *event, QString uuid) -{} -void FSHost::eventChannelOutgoing(switch_event_t *event, QString uuid) +void FSHost::eventChannelExecuteComplete(QSharedPointerevent, QString uuid) +{ + _channels.value(uuid).data()->setPaCallId(atoi(switch_event_get_header_nil(event.data(), "variable_pa_call_id"))); +} +void FSHost::eventChannelOutgoing(QSharedPointerevent, QString uuid) { /* Checks if this is an inbound or outbound call */ /** Outbound call */ - if ( strcmp(switch_event_get_header_nil(event, "Caller-Source"), "mod_portaudio") == 0 ) + if ( strcmp(switch_event_get_header_nil(event.data(), "Caller-Source"), "mod_portaudio") == 0 ) { Call *callPtr = new Call(); callPtr->setCallDirection(FSCOMM_CALL_DIRECTION_OUTBOUND); callPtr->setChannel(_channels.value(uuid)); - callPtr->setOtherLegChannel(_channels.value(switch_event_get_header_nil(event, "Other-Leg-Unique-ID"))); + callPtr->setOtherLegChannel(_channels.value(switch_event_get_header_nil(event.data(), "Other-Leg-Unique-ID"))); QSharedPointer call(callPtr); _active_calls.insert(uuid, call); call.data()->setState(FSCOMM_CALL_STATE_TRYING); @@ -377,44 +385,58 @@ void FSHost::eventChannelOutgoing(switch_event_t *event, QString uuid) Call *callPtr = new Call(); callPtr->setCallDirection(FSCOMM_CALL_DIRECTION_INBOUND); - callPtr->setChannel(_channels.value(switch_event_get_header_nil(event, "Other-Leg-Unique-ID"))); + callPtr->setChannel(_channels.value(switch_event_get_header_nil(event.data(), "Other-Leg-Unique-ID"))); callPtr->setOtherLegChannel(_channels.value(uuid)); QSharedPointer call(callPtr); - _active_calls.insert(switch_event_get_header_nil(event, "Other-Leg-Unique-ID"), call); + _active_calls.insert(switch_event_get_header_nil(event.data(), "Other-Leg-Unique-ID"), call); call.data()->setState(FSCOMM_CALL_STATE_RINGING); emit ringing(call); - qDebug() << _channels.value(uuid).data()->getCidName() << _channels.value(uuid).data()->getCidNumber(); } } -void FSHost::eventChannelOriginate(switch_event_t *event, QString uuid) +void FSHost::eventChannelOriginate(QSharedPointerevent, QString uuid) {} -void FSHost::eventChannelProgressMedia(switch_event_t *event, QString uuid) +void FSHost::eventChannelProgress(QSharedPointerevent, QString uuid) {} -void FSHost::eventChannelBridge(switch_event_t *event, QString uuid) -{} -void FSHost::eventChannelHangup(switch_event_t *event, QString uuid) +void FSHost::eventChannelProgressMedia(QSharedPointerevent, QString uuid) +{ + _channels.value(uuid).data()->setProgressEpoch(QString(switch_event_get_header_nil(event.data(), "Caller-Channel-Progress-Time")).toULongLong()); + if (_active_calls.contains(uuid)) + { + _active_calls.value(uuid).data()->setState(FSCOMM_CALL_STATE_RINGING); + emit ringing(_active_calls.value(uuid)); + } +} +void FSHost::eventChannelBridge(QSharedPointerevent, QString uuid) +{ + QString time; + time = switch_event_get_header_nil(event.data(), "Caller-Channel-Progress-Time"); + if (time.toULongLong() > 0) _channels.value(uuid).data()->setProgressEpoch(time.toULongLong()); + time = switch_event_get_header_nil(event.data(), "Caller-Channel-Progress-Media-Time"); + if (time.toULongLong() > 0) _channels.value(uuid).data()->setProgressMediaEpoch(time.toULongLong()); +} +void FSHost::eventChannelHangup(QSharedPointerevent, QString uuid) { if (_active_calls.contains(uuid)) { emit hungup(_active_calls.take(uuid)); } } -void FSHost::eventChannelUnbridge(switch_event_t *event, QString uuid) +void FSHost::eventChannelUnbridge(QSharedPointerevent, QString uuid) {} -void FSHost::eventChannelHangupComplete(switch_event_t *event, QString uuid) +void FSHost::eventChannelHangupComplete(QSharedPointerevent, QString uuid) {} -void FSHost::eventChannelDestroy(switch_event_t *event, QString uuid) +void FSHost::eventChannelDestroy(QSharedPointerevent, QString uuid) { _channels.take(uuid); } -void FSHost::eventCodec(switch_event_t *event, QString uuid) +void FSHost::eventCodec(QSharedPointerevent, QString uuid) { - _channels.value(uuid).data()->setCidName(switch_event_get_header_nil(event, "Caller-Caller-ID-Name")); - _channels.value(uuid).data()->setCidNumber(switch_event_get_header_nil(event, "Caller-Caller-ID-Number")); + _channels.value(uuid).data()->setCidName(switch_event_get_header_nil(event.data(), "Caller-Caller-ID-Name")); + _channels.value(uuid).data()->setCidNumber(switch_event_get_header_nil(event.data(), "Caller-Caller-ID-Number")); } -void FSHost::eventCallUpdate(switch_event_t *event, QString uuid) +void FSHost::eventCallUpdate(QSharedPointerevent, QString uuid) {} -void FSHost::eventRecvInfo(switch_event_t *event, QString uuid) +void FSHost::eventRecvInfo(QSharedPointerevent, QString uuid) {} void FSHost::minimalModuleLoaded(QString modType, QString modKey) @@ -489,11 +511,11 @@ QSharedPointer FSHost::getCurrentActiveCall() return QSharedPointer(); } -void FSHost::printEventHeaders(switch_event_t *event) +void FSHost::printEventHeaders(QSharedPointerevent) { switch_event_header_t *hp; - qDebug() << QString("Received event: %1(%2)").arg(switch_event_name(event->event_id), switch_event_get_header_nil(event, "Event-Subclass")); - for (hp = event->headers; hp; hp = hp->next) { + qDebug() << QString("Received event: %1(%2)").arg(switch_event_name(event.data()->event_id), switch_event_get_header_nil(event.data(), "Event-Subclass")); + for (hp = event.data()->headers; hp; hp = hp->next) { qDebug() << hp->name << "=" << hp->value; } qDebug() << "\n\n"; diff --git a/fscomm/fshost.h b/fscomm/fshost.h index da5948a773..980ed092d4 100644 --- a/fscomm/fshost.h +++ b/fscomm/fshost.h @@ -44,7 +44,7 @@ Q_OBJECT public: explicit FSHost(QObject *parent = 0); switch_status_t sendCmd(const char *cmd, const char *args, QString *res); - void generalEventHandler(switch_event_t *event); + void generalEventHandler(QSharedPointerevent); QSharedPointer getCallByUUID(QString uuid) { return _active_calls.value(uuid); } QSharedPointer getCurrentActiveCall(); QList > getAccounts() { return _accounts.values(); } @@ -84,28 +84,29 @@ private slots: private: /* Helper methods */ void createFolders(); - void printEventHeaders(switch_event_t *event); + void printEventHeaders(QSharedPointerevent); /*FSM State handlers*/ /** Channel Related*/ - void eventChannelCreate(switch_event_t *event, QString uuid); - void eventChannelAnswer(switch_event_t *event, QString uuid); - void eventChannelState(switch_event_t *event, QString uuid); - void eventChannelExecute(switch_event_t *event, QString uuid); - void eventChannelExecuteComplete(switch_event_t *event, QString uuid); - void eventChannelOutgoing(switch_event_t *event, QString uuid); - void eventChannelOriginate(switch_event_t *event, QString uuid); - void eventChannelProgressMedia(switch_event_t *event, QString uuid); - void eventChannelBridge(switch_event_t *event, QString uuid); - void eventChannelHangup(switch_event_t *event, QString uuid); - void eventChannelUnbridge(switch_event_t *event, QString uuid); - void eventChannelHangupComplete(switch_event_t *event, QString uuid); - void eventChannelDestroy(switch_event_t *event, QString uuid); + void eventChannelCreate(QSharedPointer event, QString uuid); + void eventChannelAnswer(QSharedPointer event, QString uuid); + void eventChannelState(QSharedPointerevent, QString uuid); + void eventChannelExecute(QSharedPointerevent, QString uuid); + void eventChannelExecuteComplete(QSharedPointerevent, QString uuid); + void eventChannelOutgoing(QSharedPointerevent, QString uuid); + void eventChannelOriginate(QSharedPointerevent, QString uuid); + void eventChannelProgress(QSharedPointerevent, QString uuid); + void eventChannelProgressMedia(QSharedPointerevent, QString uuid); + void eventChannelBridge(QSharedPointerevent, QString uuid); + void eventChannelHangup(QSharedPointerevent, QString uuid); + void eventChannelUnbridge(QSharedPointerevent, QString uuid); + void eventChannelHangupComplete(QSharedPointerevent, QString uuid); + void eventChannelDestroy(QSharedPointerevent, QString uuid); /** Others*/ - void eventCodec(switch_event_t *event, QString uuid); - void eventCallUpdate(switch_event_t *event, QString uuid); - void eventRecvInfo(switch_event_t *event, QString uuid); + void eventCodec(QSharedPointerevent, QString uuid); + void eventCallUpdate(QSharedPointerevent, QString uuid); + void eventRecvInfo(QSharedPointerevent, QString uuid); /* Structures to keep track of things */ QHash > _active_calls; @@ -125,9 +126,9 @@ static void eventHandlerCallback(switch_event_t *event) { switch_event_t *clone = NULL; if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) { - g_FSHost.generalEventHandler(clone); + QSharedPointer e(clone); + g_FSHost.generalEventHandler(e); } - switch_safe_free(clone); } #endif // FSHOST_H diff --git a/fscomm/mainwindow.cpp b/fscomm/mainwindow.cpp index e75613ac2f..38892c6add 100644 --- a/fscomm/mainwindow.cpp +++ b/fscomm/mainwindow.cpp @@ -133,7 +133,7 @@ void MainWindow::updateCallTimers() QSharedPointer call = g_FSHost.getCallByUUID(item->data(Qt::UserRole).toString()); QTime time = call.data()->getCurrentStateTime(); item->setText(time.toString("hh:mm:ss")); - item->setTextAlignment(Qt::AlignRight); + item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); } } @@ -267,7 +267,6 @@ void MainWindow::makeCall() switch_core_set_variable("fscomm_caller_id_name", cidName.toAscii().data()); switch_core_set_variable("fscomm_caller_id_num", cidNum.toAscii().data()); - qDebug() << "Name:" << cidName << "Num:" << cidNum; } if (ok && !dialstring.isEmpty()) @@ -396,12 +395,18 @@ void MainWindow::ringing(QSharedPointer call) if (item->data(Qt::UserRole).toString() == call.data()->getUuid()) { item->setText(tr("Ringing")); - ui->textEdit->setText(QString("Call from %1 (%2)").arg(call.data()->getCidName(), call.data()->getCidNumber())); + if (call.data()->getDirection() == FSCOMM_CALL_DIRECTION_INBOUND) + ui->textEdit->setText(QString("Call from %1 (%2)").arg(call.data()->getCidName(), call.data()->getCidNumber())); + else + ui->textEdit->setText(QString("Call to %1 is ringing.").arg(call.data()->getDestinationNumber())); return; } } - ui->textEdit->setText(QString("Call from %1 (%2)").arg(call.data()->getCidName(), call.data()->getCidNumber())); + if (call.data()->getDirection() == FSCOMM_CALL_DIRECTION_INBOUND) + ui->textEdit->setText(QString("Call from %1 (%2)").arg(call.data()->getCidName(), call.data()->getCidNumber())); + else + ui->textEdit->setText(QString("Call to %1 is ringing.").arg(call.data()->getDestinationNumber())); ui->tableCalls->setRowCount(ui->tableCalls->rowCount()+1); QTableWidgetItem *item0 = new QTableWidgetItem(QString("%1 (%2)").arg(call.data()->getCidName(), call.data()->getCidNumber())); @@ -521,7 +526,7 @@ void MainWindow::hungup(QSharedPointer call) } else { - ui->textEdit->setText(tr("Call with %1 hungup.").arg(call.data()->getCidNumber())); + ui->textEdit->setText(tr("Call with %1 hungup.").arg(call.data()->getDestinationNumber())); } /* TODO: Will cause problems if 2 calls are received at the same time */ ui->recoredCallBtn->setEnabled(false);