diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp index 041181db39407afebfc2e400a658076f4897fb1d..81832e9a4d5b65967378240c70560bfa32044ade 100644 --- a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp +++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp @@ -47,6 +47,14 @@ std::ofstream rtpResampled ("testRtpOutputResampled.raw", std::ifstream::binary) std::ofstream rtpNotResampled("testRtpOutput.raw", std::ifstream::binary); #endif +DTMFEvent::DTMFEvent(int digit) : payload(), newevent(true), length(1000) +{ + payload.event = digit; + payload.ebit = false; // end of event bit + payload.rbit = false; // reserved bit + payload.duration = 1; // duration for this event +} + AudioRtpRecord::AudioRtpRecord() : audioCodec_(0) , audioCodecMutex_() @@ -131,7 +139,8 @@ void AudioRtpRecordHandler::initNoiseSuppress() void AudioRtpRecordHandler::putDtmfEvent(int digit) { - audioRtpRecord_.dtmfQueue_.push_back(digit); + DTMFEvent dtmf(digit); + audioRtpRecord_.dtmfQueue_.push_back(dtmf); } int AudioRtpRecordHandler::processDataEncode() diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.h b/daemon/src/audio/audiortp/audio_rtp_record_handler.h index 3f3a7ec649c69c5fdf2cb76e354580e1299c36f3..1f8c4c13bf0dc45c6ddfc62f85d1d2a026b716b0 100644 --- a/daemon/src/audio/audiortp/audio_rtp_record_handler.h +++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.h @@ -67,6 +67,13 @@ timeval2microtimeout(const timeval& t) return ((t.tv_sec * 1000000ul) + t.tv_usec); } +struct DTMFEvent { + DTMFEvent(int digit); + ost::RTPPacket::RFC2833Payload payload; + bool newevent; + int length; +}; + /** * Class meant to store internal data in order to encode/decode, * resample, process, and packetize audio streams. This class should not be @@ -90,7 +97,7 @@ class AudioRtpRecord { int codecSampleRate_; int codecFrameSize_; int converterSamplingRate_; - std::list<int> dtmfQueue_; + std::list<DTMFEvent> dtmfQueue_; SFLDataFormat fadeFactor_; NoiseSuppress *noiseSuppressEncode_; NoiseSuppress *noiseSuppressDecode_; @@ -138,7 +145,7 @@ class AudioRtpRecordHandler { return audioRtpRecord_.hasDynamicPayloadType_; } - int DtmfPending() const { + bool hasDTMFPending() const { return not audioRtpRecord_.dtmfQueue_.empty(); } diff --git a/daemon/src/audio/audiortp/audio_rtp_session.cpp b/daemon/src/audio/audiortp/audio_rtp_session.cpp index 6d70bcd0c6d9fb7040e010c29e66b3a2a201fc07..b2a1d7e2677dcf9e6398da5461f8a4a27194d26a 100644 --- a/daemon/src/audio/audiortp/audio_rtp_session.cpp +++ b/daemon/src/audio/audiortp/audio_rtp_session.cpp @@ -110,25 +110,13 @@ void AudioRtpSession::setSessionMedia(AudioCodec &audioCodec) } } -void AudioRtpSession::incrementTimestampForDTMF() -{ - timestamp_ += timestampIncrement_; -} - void AudioRtpSession::sendDtmfEvent() { - ost::RTPPacket::RFC2833Payload payload; - - payload.event = audioRtpRecord_.dtmfQueue_.front(); - payload.ebit = false; // end of event bit - payload.rbit = false; // reserved bit - payload.duration = 1; // duration for this event - - audioRtpRecord_.dtmfQueue_.pop_front(); - - DEBUG("Send RTP Dtmf (%d)", payload.event); + DTMFEvent &dtmf(audioRtpRecord_.dtmfQueue_.front()); + DEBUG("Send RTP Dtmf (%d)", dtmf.payload.event); - incrementTimestampForDTMF(); + const int increment = getIncrementForDTMF(); + timestamp_ += increment; // discard equivalent size of audio processDataEncode(); @@ -136,13 +124,29 @@ void AudioRtpSession::sendDtmfEvent() // change Payload type for DTMF payload queue_.setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) getDtmfPayloadType(), 8000)); - queue_.setMark(true); - queue_.sendImmediate(timestamp_, (const unsigned char *)(&payload), sizeof(payload)); - queue_.setMark(false); + // Set marker in case this is a new Event + if (dtmf.newevent) + queue_.setMark(true); + queue_.sendImmediate(timestamp_, (const unsigned char *) (& (dtmf.payload)), sizeof (ost::RTPPacket::RFC2833Payload)); - // get back the payload to audio + // This is no longer a new event + if (dtmf.newevent) { + dtmf.newevent = false; + queue_.setMark(false); + } + + // restore the payload to audio const ost::StaticPayloadFormat pf(static_cast<ost::StaticPayloadType>(getCodecPayloadType())); queue_.setPayloadFormat(pf); + + // decrease length remaining to process for this event + dtmf.length -= increment; + dtmf.payload.duration++; + // next packet is going to be the last one + if ((dtmf.length - increment) < increment) + dtmf.payload.ebit = true; + if (dtmf.length < increment) + audioRtpRecord_.dtmfQueue_.pop_front(); } @@ -253,4 +257,9 @@ bool AudioRtpSession::onRTPPacketRecv(ost::IncomingRTPPkt&) return true; } +int AudioRtpSession::getIncrementForDTMF() const +{ + return timestampIncrement_; +} + } diff --git a/daemon/src/audio/audiortp/audio_rtp_session.h b/daemon/src/audio/audiortp/audio_rtp_session.h index c6baca3f29fd81b9899922e6b1aef87a767a0478..5a71779f31d7e6349d48a832fd52b9f3c0ec2527 100644 --- a/daemon/src/audio/audiortp/audio_rtp_session.h +++ b/daemon/src/audio/audiortp/audio_rtp_session.h @@ -66,6 +66,8 @@ class AudioRtpSession : public AudioRtpRecordHandler { */ void updateDestinationIpAddress(); + virtual int getIncrementForDTMF() const; + protected: /** * Set the audio codec for this RTP session @@ -122,11 +124,6 @@ class AudioRtpSession : public AudioRtpRecordHandler { */ void receiveSpeakerData(); - /** - * Increment timestamp for DTMF event - */ - virtual void incrementTimestampForDTMF(); - // Main destination address for this rtp session. // Stored in case or reINVITE, which may require to forget // this destination and update a new one. diff --git a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp index 559c6578057742790ffefa2d951045834d7fd22b..3628a3cecf9c0f5372cb8ada8d87dc95e1056676 100644 --- a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp +++ b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp @@ -70,7 +70,7 @@ void AudioSymmetricRtpSession::AudioRtpThread::run() while (running_) { // Send session - if (rtpSession_.DtmfPending()) + if (rtpSession_.hasDTMFPending()) rtpSession_.sendDtmfEvent(); else rtpSession_.sendMicData(); diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.cpp b/daemon/src/audio/audiortp/audio_zrtp_session.cpp index 72570544b90fec53c5ec7b684147f098608ddd24..5b41a5c4d2eacd9fdb28ca83fc5817320a29f6ff 100644 --- a/daemon/src/audio/audiortp/audio_zrtp_session.cpp +++ b/daemon/src/audio/audiortp/audio_zrtp_session.cpp @@ -133,7 +133,7 @@ void AudioZrtpSession::run() timeout = getSchedulingTimeout(); // Send session - if (DtmfPending()) + if (hasDTMFPending()) sendDtmfEvent(); else sendMicData(); @@ -162,9 +162,9 @@ void AudioZrtpSession::run() DEBUG("Left main loop for call %s", call_.getCallId().c_str()); } -void AudioZrtpSession::incrementTimestampForDTMF() +int AudioZrtpSession::getIncrementForDTMF() const { - timestamp_ += 160; + return 160; } void AudioZrtpSession::setSessionMedia(AudioCodec &audioCodec) diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.h b/daemon/src/audio/audiortp/audio_zrtp_session.h index 65a86fa352e3fe24d559c4b10bc51364b694afea..d056d021ca01a4d647503532bd9f70a55882d71c 100644 --- a/daemon/src/audio/audiortp/audio_zrtp_session.h +++ b/daemon/src/audio/audiortp/audio_zrtp_session.h @@ -71,8 +71,8 @@ class AudioZrtpSession : void sendMicData(); void initializeZid(); std::string zidFilename_; - void incrementTimestampForDTMF(); void setSessionMedia(AudioCodec &codec); + virtual int getIncrementForDTMF() const; }; } diff --git a/kde/src/CallView.cpp b/kde/src/CallView.cpp index a71aa41d9c47da7ba3df43cca3ffebc89f7124c7..20829835d60849f10882f89883a992253c81f5e7 100644 --- a/kde/src/CallView.cpp +++ b/kde/src/CallView.cpp @@ -89,7 +89,6 @@ CallView::CallView(QWidget* parent) : QTreeWidget(parent),m_pActiveOverlay(0),m_ addConference(active); } - qDebug() << "\n\n\nHERE"; //User Interface even // SENDER SIGNAL RECEIVER SLOT / /**/connect(this , SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int) ) , this, SLOT( itemDoubleClicked(QTreeWidgetItem*,int)) ); @@ -180,7 +179,7 @@ bool CallView::callToCall(QTreeWidgetItem *parent, int index, const QMimeData *d else if ((parent->parent()) || (parent->childCount())) { kDebug() << "Call dropped on a conference"; - if ((SFLPhone::model()->getIndex(encodedCallId)->childCount()) && (!parent->childCount())) { + if (SFLPhone::model()->getIndex(encodedCallId)->childCount() && (SFLPhone::model()->getIndex(encodedCallId)->childCount()) && (!parent->childCount())) { kDebug() << "Conference dropped on a call (doing nothing)"; return true; } @@ -215,7 +214,7 @@ bool CallView::callToCall(QTreeWidgetItem *parent, int index, const QMimeData *d SFLPhone::model()->addParticipant(SFLPhone::model()->getCall(call1),SFLPhone::model()->getCall(call2)); return true; } - else if ((SFLPhone::model()->getIndex(encodedCallId)->childCount()) && (!parent->childCount())) { + else if (SFLPhone::model()->getIndex(encodedCallId) && (SFLPhone::model()->getIndex(encodedCallId)->childCount()) && (!parent->childCount())) { kDebug() << "Call dropped on it's own conference (doing nothing)"; return true; } @@ -383,6 +382,7 @@ void CallView::transfer() m_pCallPendingTransfer = 0; m_pTransferLE->clear(); + m_pTransferOverlay->setVisible(false); } @@ -414,14 +414,13 @@ bool CallView::haveOverlay() ///Remove the active overlay void CallView::hideOverlay() { - if (m_pActiveOverlay) + if (m_pActiveOverlay){ + disconnect(m_pCallPendingTransfer,SIGNAL(changed()),this,SLOT(hideOverlay())); m_pActiveOverlay->setVisible(false); - m_pActiveOverlay = 0; - - if (m_pCallPendingTransfer && m_pCallPendingTransfer->getState() == CALL_STATE_TRANSFER ) { - m_pCallPendingTransfer->actionPerformed(CALL_ACTION_TRANSFER); } + m_pActiveOverlay = 0; + m_pCallPendingTransfer = 0; } //hideOverlay @@ -489,6 +488,8 @@ QTreeWidgetItem* CallView::extractItem(const QString& callId) ///Extract an item from the TreeView and return it, the item is -not- deleted QTreeWidgetItem* CallView::extractItem(QTreeWidgetItem* item) { + if (!item) + return nullptr; QTreeWidgetItem* parentItem = item->parent(); if (parentItem) { @@ -514,7 +515,7 @@ CallTreeItem* CallView::insertItem(QTreeWidgetItem* item, Call* parent) ///Insert a TreeView item in the TreeView as child of parent or as a top level item, also restore the item Widget CallTreeItem* CallView::insertItem(QTreeWidgetItem* item, QTreeWidgetItem* parent) { - if (!dynamic_cast<QTreeWidgetItem*>(item) && !dynamic_cast<QTreeWidgetItem*>(parent)) + if (!dynamic_cast<QTreeWidgetItem*>(item) && SFLPhone::model()->getCall(item) && !dynamic_cast<QTreeWidgetItem*>(parent)) return nullptr; if (!item) { @@ -620,8 +621,8 @@ void CallView::itemClicked(QTreeWidgetItem* item, int column) { ///Add a new conference, get the call list and update the interface as needed Call* CallView::addConference(Call* conf) { - kDebug() << "\n\n\nConference created"; - Call* newConf = conf;//SFLPhone::model()->addConference(confID);//TODO ELV? + kDebug() << "Conference created"; + Call* newConf = conf; QTreeWidgetItem* confItem = new QTreeWidgetItem(); SFLPhone::model()->updateIndex(conf,confItem); diff --git a/kde/src/lib/Call.cpp b/kde/src/lib/Call.cpp index ede7b5399c0109e093dcb946d7be19eb4531cca7..809c24418375b89bd163519aa1d1fdaa8274b737 100644 --- a/kde/src/lib/Call.cpp +++ b/kde/src/lib/Call.cpp @@ -56,8 +56,8 @@ const function Call::actionPerformedFunctionMap[11][5] = /*HOLD */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::unhold , &Call::setRecord },/**/ /*FAILURE */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::nothing },/**/ /*BUSY */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::nothing },/**/ -/*TRANSFERT */ {&Call::transfer , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord },/**/ -/*TRANSFERT_HOLD */ {&Call::transfer , &Call::hangUp , &Call::nothing , &Call::unhold , &Call::setRecord },/**/ +/*TRANSFERT */ {&Call::transfer , &Call::hangUp , &Call::transfer , &Call::hold , &Call::setRecord },/**/ +/*TRANSFERT_HOLD */ {&Call::transfer , &Call::hangUp , &Call::transfer , &Call::unhold , &Call::setRecord },/**/ /*OVER */ {&Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing },/**/ /*ERROR */ {&Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing } /**/ };// @@ -712,7 +712,7 @@ void Call::call() void Call::transfer() { CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance(); - qDebug() << "Transferring call to number : " << m_TransferNumber << ". callId : " << m_CallId; + qDebug() << "\n\n\nTransferring call to number : " << m_TransferNumber << ". callId : " << m_CallId << "\n\n\n"; callManager.transfer(m_CallId, m_TransferNumber); this->m_pStopTime = new QDateTime(QDateTime::currentDateTime()); } diff --git a/kde/src/lib/CallModel.cpp b/kde/src/lib/CallModel.cpp index 7a466f05e35285d708804de8d1e4708962806014..76db9efe2a6c0b9019bc9314d59ebf29071a86e3 100644 --- a/kde/src/lib/CallModel.cpp +++ b/kde/src/lib/CallModel.cpp @@ -136,7 +136,6 @@ Call* CallModelBase::addCall(Call* call, Call* parent) Call* CallModelBase::addConferenceS(Call* conf) { - qDebug() << "-----Emitting conference" << conf->getConfId(); emit conferenceCreated(conf); return conf; } diff --git a/kde/src/lib/CallModel.hpp b/kde/src/lib/CallModel.hpp index 39e910f5bc265ab05499a31bd18eb4d2bc22f29d..b456f551f2eaceae36027d6d3d0c95aca260af31 100644 --- a/kde/src/lib/CallModel.hpp +++ b/kde/src/lib/CallModel.hpp @@ -322,8 +322,7 @@ CALLMODEL_TEMPLATE void CALLMODEL_T::transfer(Call* toTransfer, QString target) { qDebug() << "Transferring call " << toTransfer->getCallId() << "to" << target; toTransfer->setTransferNumber(target); - toTransfer->changeCurrentState(CALL_STATE_TRANSFER); - toTransfer->actionPerformed(CALL_ACTION_ACCEPT); + toTransfer->actionPerformed(CALL_ACTION_TRANSFER); toTransfer->changeCurrentState(CALL_STATE_OVER); } //transfer @@ -345,7 +344,7 @@ CALLMODEL_TEMPLATE Call* CALLMODEL_T::addConference(const QString & confID) qDebug() << "This conference (" + confID + ") contain no call"; return 0; } - + if (!m_sPrivateCallList_callId[callList[0]]) { qDebug() << "Invalid call"; return 0; diff --git a/kde/src/widgets/CallTreeItem.cpp b/kde/src/widgets/CallTreeItem.cpp index c62b65c2c14afe22a4acee577c0ea11a8f91fd1d..09eaa12276a6296149acfaa39891875d686e716d 100644 --- a/kde/src/widgets/CallTreeItem.cpp +++ b/kde/src/widgets/CallTreeItem.cpp @@ -228,7 +228,7 @@ void CallTreeItem::updated() else { //kDebug() << "Updating item of call of state OVER. Doing nothing."; } - if (state == CALL_STATE_TRANSFER) { + if (state == CALL_STATE_TRANSFER || state == CALL_STATE_TRANSF_HOLD) { kDebug() << "emmiting tranfer signal"; emit askTransfer(m_pItemCall); }