diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.h b/sflphone-common/src/audio/audiortp/AudioRtpSession.h index cb0578beaa7a12d70b5efd781fd3fd29b07afcdb..7ecfe5ecb9cb81bac9e042c62f6e531bb4f28da5 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.h @@ -249,7 +249,7 @@ namespace sfl { template <typename D> AudioRtpSession<D>::~AudioRtpSession() { - _debug ("Rtp: Delete AudioRtpSession instance"); + _debug ("RTP: Delete AudioRtpSession instance"); try { terminate(); @@ -273,11 +273,9 @@ namespace sfl { void AudioRtpSession<D>::initBuffers() { // Set sampling rate, main buffer choose the highest one - // _audiolayer->getMainBuffer()->setInternalSamplingRate(_codecSampleRate); _manager->getAudioDriver()->getMainBuffer()->setInternalSamplingRate(_codecSampleRate); // may be different than one already setted - // converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate(); _converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); // initialize SampleRate converter using AudioLayer's sampling rate @@ -311,28 +309,33 @@ namespace sfl { { assert(_ca); + _debug("RTP: Get audio codec for call %s", _ca->getCallId().c_str()); + AudioCodecType pl = (AudioCodecType)_ca->getLocalSDP()->get_session_media()->getPayload(); _audiocodec = _manager->getCodecDescriptorMap().instantiateCodec(pl); - if (_audiocodec == NULL) { - _debug ("No audiocodec, can't init RTP media"); + if (!_audiocodec) { + _error ("RTP: Error: No audiocodec, can't init RTP media"); throw AudioRtpSessionException(); } - _debug ("Init audio RTP session: codec payload %i", _audiocodec->getPayload()); + _debug ("RTP: Init codec payload %i", _audiocodec->getPayload()); _codecSampleRate = _audiocodec->getClockRate(); _codecFrameSize = _audiocodec->getFrameSize(); + _debug("RTP: Codec sampling rate: %d", _codecSampleRate); + _debug("RTP: Codec frame size: %d", _codecFrameSize); + //TODO: figure out why this is necessary. if (_audiocodec->getPayload() == 9) { - _debug ("Setting payload format to G722"); + _debug ("RTP: Setting payload format to G722"); static_cast<D*>(this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate())); } else if (_audiocodec->hasDynamicPayload()) { - _debug ("Setting a dynamic payload format"); + _debug ("RTP: Setting a dynamic payload format"); static_cast<D*>(this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate())); } else if (!_audiocodec->hasDynamicPayload() && _audiocodec->getPayload() != 9) { - _debug ("Setting a static payload format"); + _debug ("RTP: Setting a static payload format"); static_cast<D*>(this)->setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) _audiocodec->getPayload())); } } @@ -341,7 +344,7 @@ namespace sfl { void AudioRtpSession<D>::setDestinationIpAddress(void) { if (_ca == NULL) { - _warn ("Rtp: Sipcall is gone."); + _error ("RTP: Sipcall is gone."); throw AudioRtpSessionException(); } @@ -351,7 +354,7 @@ namespace sfl { _remote_ip = ost::InetHostAddress(_ca->getLocalSDP()->get_remote_ip().c_str()); if (!_remote_ip) { - _warn("Rtp: Target IP address (%s) is not correct!", + _warn("RTP: Target IP address (%s) is not correct!", _ca->getLocalSDP()->get_remote_ip().data()); return; } @@ -363,7 +366,7 @@ namespace sfl { _ca->getLocalSDP()->get_remote_ip().data(), _remote_port); if (! static_cast<D*>(this)->addDestination (_remote_ip, _remote_port)) { - _warn("Rtp: Can't add new destination to session!"); + _warn("RTP: Can't add new destination to session!"); return; } } @@ -375,7 +378,7 @@ namespace sfl { // This method remove the current destination entry if(!static_cast<D*>(this)->forgetDestination(_remote_ip, _remote_port, _remote_port+1)) - _warn("Rtp: Could not remove previous destination"); + _warn("RTP: Could not remove previous destination"); // new destination is stored in call // we just need to recall this method @@ -619,7 +622,7 @@ namespace sfl { template <typename D> int AudioRtpSession<D>::startRtpThread () { - _debug("Starting main thread"); + _debug("RTP: Starting main thread"); return start(_mainloopSemaphore); } @@ -630,48 +633,50 @@ namespace sfl { setSessionTimeouts(); setSessionMedia(); - initBuffers(); + initBuffers(); - // Timestamp must be initialized randomly - _timestamp = static_cast<D*>(this)->getCurrentTimestamp(); + // Timestamp must be initialized randomly + _timestamp = static_cast<D*>(this)->getCurrentTimestamp(); int sessionWaiting; int threadSleep = 0; - if (_codecSampleRate != 0) - { threadSleep = (_codecFrameSize * 1000) / _codecSampleRate; } - else - { threadSleep = _layerFrameSize; } + if (_codecSampleRate != 0){ + threadSleep = (_codecFrameSize * 1000) / _codecSampleRate; + } + else { + threadSleep = _layerFrameSize; + } TimerPort::setTimer (threadSleep); if (_audiolayer == NULL) { - _debug("For some unknown reason, audiolayer is null, just as \ - we were about to start the audio stream"); + _error("RTP: Error: Audiolayer is null, cannot start the audio stream"); throw AudioRtpSessionException(); } - _ca->setRecordingSmplRate(_audiocodec->getClockRate()); + _ca->setRecordingSmplRate(_audiocodec->getClockRate()); - // Start audio stream (if not started) AND flush all buffers (main and urgent) - _manager->getAudioDriver()->startStream(); + // Start audio stream (if not started) AND flush all buffers (main and urgent) + _manager->getAudioDriver()->startStream(); static_cast<D*>(this)->startRunning(); - _debug ("Entering RTP mainloop for callid %s",_ca->getCallId().c_str()); + _debug ("RTP: Entering mainloop for call %s",_ca->getCallId().c_str()); while (!testCancel()) { - // ost::MutexLock lock(*(_manager->getAudioLayerMutex())); + // ost::MutexLock lock(*(_manager->getAudioLayerMutex())); - _manager->getAudioLayerMutex()->enter(); + _manager->getAudioLayerMutex()->enter(); - // converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate(); - _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); + // converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate(); + _converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); - // Send session - sessionWaiting = static_cast<D*>(this)->isWaiting(); + sessionWaiting = static_cast<D*>(this)->isWaiting(); + + // Send session if(_eventQueue.size() > 0) { sendDtmfEvent(_eventQueue.front()); } @@ -698,7 +703,7 @@ namespace sfl { TimerPort::incTimer (threadSleep); } - _debug ("Left RTP main loop for callid %s",_ca->getCallId().c_str()); + _debug ("RTP: Left main loop for call%s", _ca->getCallId().c_str()); } } diff --git a/sflphone-common/src/audio/codecs/Makefile.am b/sflphone-common/src/audio/codecs/Makefile.am index 230ee7bbc0dce19ecfd5f02f18236afefb84965d..e338dc3fb5f898a86039e174c6705370fc20b91a 100644 --- a/sflphone-common/src/audio/codecs/Makefile.am +++ b/sflphone-common/src/audio/codecs/Makefile.am @@ -49,7 +49,7 @@ CELT_LIB = libcodec_celt.so libcodec_celt_so_SOURCES = celtcodec.cpp libcodec_celt_so_CFLAGS = -fPIC -g -Wall libcodec_celt_so_CXXFLAGS = -fPIC -g -Wall -libcodec_celt_so_LDFLAGS = --shared -lc -lcelt $(CELT_NIMP) +libcodec_celt_so_LDFLAGS = --shared -lc -lcelt0 $(CELT_NIMP) INSTALL_CELT_RULE = install-libcodec_celt_so endif diff --git a/sflphone-common/src/audio/codecs/celtcodec.cpp b/sflphone-common/src/audio/codecs/celtcodec.cpp index 8787bd6b6b3f7c8bfeec6fbf31464de24e31816c..f68fce20578cd20b526771baddd64d0f58b7271b 100644 --- a/sflphone-common/src/audio/codecs/celtcodec.cpp +++ b/sflphone-common/src/audio/codecs/celtcodec.cpp @@ -26,27 +26,59 @@ class Celt : public AudioCodec { public: - Celt (int payload=0) - : AudioCodec (payload, "celt") { - _clockRate = 44100; - _frameSize = 512; // fixed frameSize, TODO: support variable size from 64 to 512 + Celt (int payload=0) : AudioCodec (payload, "celt") { + + _clockRate = 32000; + _frameSize = 512; // fixed frameSize, TODO: support variable size from 64 to 512 _channel = 1; _bitrate = 0; _bandwidth = 0; + initCelt(); + } Celt (const Celt&); Celt& operator= (const Celt&); void initCelt() { - printf ("init celt"); + printf ("Celt: Init Celt codec"); + + int error = 0; + + _mode = celt_mode_create (_clockRate, _frameSize, &error); + + if(error != CELT_OK) { + switch(error) { + case CELT_BAD_ARG: + printf("Celt: Error: An (or more) invalid argument (e.g. out of range)\n"); + break; + case CELT_INVALID_MODE: + printf("Celt: Error: The mode struct passed is invalid\n"); + break; + case CELT_INTERNAL_ERROR: + printf("Celt: Error: An internal error was detected\n"); + break; + case CELT_CORRUPTED_DATA: + printf("Celt: Error: The data passed (e.g. compressed data to decoder) is corrupted\n"); + break; + case CELT_UNIMPLEMENTED: + printf("Celt: Error: Invalid/unsupported request numbe\n"); + break; + case CELT_INVALID_STATE: + printf("Celt: Error: An encoder or decoder structure is invalid or already freed\n"); + break; + case CELT_ALLOC_FAIL: + printf("Celt: Error: Memory allocation has failed\n"); + break; + default: + printf("Celt: Error"); + } - mode = celt_mode_create (_clockRate, _channel, _frameSize, NULL); - // celt_mode_info(mode, CELT_GET_LOOKAHEAD, &skip); + } - if (mode == NULL) { - printf ("failed to create a mode"); + if (_mode == NULL) { + printf ("Celt: Error: Failed to create Celt mode"); } // bytes_per_packet = 1024; @@ -58,11 +90,12 @@ class Celt : public AudioCodec // celt_mode_info(mode, CELT_GET_FRAME_SIZE, &frame_size); // celt_mode_info(mode, CELT_GET_NB_CHANNELS, &_channel); - enc = celt_encoder_create (mode); + _enc = celt_encoder_create (_mode, _channel, &error); - dec = celt_decoder_create (mode); + _dec = celt_decoder_create (_mode, _channel, &error); - celt_encoder_ctl (enc,CELT_SET_COMPLEXITY (10)); + celt_encoder_ctl (_enc, CELT_SET_COMPLEXITY (10)); + celt_decoder_ctl(_dec, CELT_SET_COMPLEXITY (10)); } @@ -72,32 +105,34 @@ class Celt : public AudioCodec void terminateCelt() { - celt_encoder_destroy (enc); - celt_decoder_destroy (dec); + celt_encoder_destroy (_enc); + celt_decoder_destroy (_dec); + + celt_mode_destroy(_mode); } virtual int codecDecode (short *dst, unsigned char *src, unsigned int size) { int err = 0; - err = celt_decode (dec, src, size, (celt_int16_t*) dst); - return _frameSize * sizeof (celt_int16_t); + err = celt_decode (_dec, src, size, (celt_int16*) dst); + return _frameSize * sizeof (celt_int16); } virtual int codecEncode (unsigned char *dst, short *src, unsigned int size) { int len = 0; - len = celt_encode (enc, (celt_int16_t *) src, (celt_int16_t *) src, dst, 512); + len = celt_encode (_enc, (celt_int16*) src, (celt_int16 *) src, dst, 512); // returns the number of bytes writen return len; } private: - CELTMode *mode; + CELTMode *_mode; - CELTEncoder *enc; - CELTDecoder *dec; + CELTEncoder *_enc; + CELTDecoder *_dec; - celt_int32_t _celt_frame_size; - celt_int32_t skip; + celt_int32 _celt_frame_size; + celt_int32 skip; }; diff --git a/sflphone-common/src/audio/codecs/speexcodec_nb.cpp b/sflphone-common/src/audio/codecs/speexcodec_nb.cpp index a2603fc8271e1430ca664edce67d07e3205b3ad4..9099dca71fbc7a69d71982394794c59f1d95492e 100644 --- a/sflphone-common/src/audio/codecs/speexcodec_nb.cpp +++ b/sflphone-common/src/audio/codecs/speexcodec_nb.cpp @@ -39,7 +39,7 @@ class Speex : public AudioCodec _clockRate = 8000; _frameSize = 160; // samples, 20 ms at 8kHz _channel = 1; - _bitrate = 0; + _bitrate = 24; _bandwidth = 0; initSpeex(); } diff --git a/sflphone-common/src/audio/codecs/speexcodec_wb.cpp b/sflphone-common/src/audio/codecs/speexcodec_wb.cpp index 9d3b618674d016fdd939b08e30e833aa70d47bf0..28e099791f511dd838fdedc5c37dd4e4f20d4265 100644 --- a/sflphone-common/src/audio/codecs/speexcodec_wb.cpp +++ b/sflphone-common/src/audio/codecs/speexcodec_wb.cpp @@ -39,7 +39,7 @@ class Speex : public AudioCodec _clockRate = 16000; _frameSize = 320; // 20 ms at 16 kHz _channel = 1; - _bitrate = 0; + _bitrate = 42; _bandwidth = 0; initSpeex(); } diff --git a/sflphone-common/src/dbus/callmanager.cpp b/sflphone-common/src/dbus/callmanager.cpp index 1c30ef975528dab36b6ed6840dd2bbac18cd7af5..36b5aa87a958aacb1c29046f11dfb860fe278f6e 100644 --- a/sflphone-common/src/dbus/callmanager.cpp +++ b/sflphone-common/src/dbus/callmanager.cpp @@ -77,14 +77,14 @@ CallManager::placeCallFirstAccount (const std::string& callID, void CallManager::refuse (const std::string& callID) { - _debug ("CallManager::refuse received"); + _debug ("CallManager: refuse received"); Manager::instance().refuseCall (callID); } void CallManager::accept (const std::string& callID) { - _debug ("CallManager::accept received"); + _debug ("CallManager: accept received"); Manager::instance().answerCall (callID); } diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 5fc21e09a700677d936f2996c0ddfda3288727f8..2bb011d6420cb011e9a9df4e92e7f8daf81a1b5c 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -376,7 +376,9 @@ bool ManagerImpl::answerCall (const CallID& call_id) { //THREAD=Main bool ManagerImpl::hangupCall (const CallID& call_id) { - _debug ("ManagerImpl::hangupCall(%s)", call_id.c_str()); + + _info("Manager: Hangup call %s", call_id.c_str()); + PulseLayer *pulselayer; AccountID account_id; bool returnValue = true; @@ -387,7 +389,7 @@ bool ManagerImpl::hangupCall (const CallID& call_id) { stopTone(); /* Broadcast a signal over DBus */ - _debug (" hangupCall: Send DBUS call state change (HUNGUP) for id %s", call_id.c_str()); + _debug ("Manager: Send DBUS call state change (HUNGUP) for id %s", call_id.c_str()); if (_dbus) _dbus->getCallManager()->callStateChanged(call_id, "HUNGUP"); @@ -419,7 +421,7 @@ bool ManagerImpl::hangupCall (const CallID& call_id) { if (account_id == AccountNULL) { - _debug ("! Manager Hangup Call: Call doesn't exists"); + _error ("Manager: Error: account id is NULL in hangup"); returnValue = false; } else { @@ -434,7 +436,7 @@ bool ManagerImpl::hangupCall (const CallID& call_id) { // stop streams if (audiolayer && (nbCalls <= 0)) { - _debug (" hangupCall: stop audio stream, ther is only %i call(s) remaining", nbCalls); + _debug ("Manager: stop audio stream, ther is only %i call(s) remaining", nbCalls); audiolayer->stopStream(); } @@ -446,7 +448,8 @@ bool ManagerImpl::hangupCall (const CallID& call_id) { } bool ManagerImpl::hangupConference (const ConfID& id) { - _debug ("ManagerImpl::hangupConference()"); + + _debug ("Manager: Hangup conference %s", id.c_str()); Conference *conf; ConferenceMap::iterator iter_conf = _conferencemap.find(id); @@ -463,7 +466,7 @@ bool ManagerImpl::hangupConference (const ConfID& id) { ParticipantSet::iterator iter_participant = participants.begin(); while (iter_participant != participants.end()) { - _debug ("ManagerImpl::hangupConference participant %s", (*iter_participant).c_str()); + _debug ("Manager: Hangup onference participant %s", (*iter_participant).c_str()); hangupCall(*iter_participant); @@ -483,6 +486,8 @@ bool ManagerImpl::cancelCall (const CallID& id) { AccountID accountid; bool returnValue; + _debug("Manager: Cancel call"); + stopTone(); /* Direct IP to IP call */ @@ -518,13 +523,12 @@ bool ManagerImpl::onHoldCall (const CallID& call_id) { AccountID account_id; bool returnValue; - _debug ("ManagerImpl::onHoldCall(%s)", call_id.c_str()); + _debug ("Manager: Put call %s on hold", call_id.c_str()); stopTone(); CallID current_call_id = getCurrentCallId(); - _debug (" onHoldCall: try to put call %s on hold", call_id.c_str()); /* Direct IP to IP call */ @@ -537,7 +541,7 @@ bool ManagerImpl::onHoldCall (const CallID& call_id) { account_id = getAccountFromCall(call_id); if (account_id == AccountNULL) { - _debug (" onHoldCall: Account ID %s or callid %s doesn't exists", account_id.c_str(), call_id.c_str()); + _debug ("Manager: Account ID %s or callid %s doesn't exists in call onHold", account_id.c_str(), call_id.c_str()); return false; } @@ -568,7 +572,7 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) { is_rec = false; - _debug ("ManagerImpl::offHoldCall(%s)", call_id.c_str()); + _debug ("Manager: Put call %s off hold", call_id.c_str()); stopTone(); @@ -580,11 +584,9 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) { // if this is not a conferenceand this and is not a conference participant if (!isConference(current_call_id) && !participToConference( current_call_id)) { - _debug (" offHoldCall: put current call (%s) on hold", current_call_id.c_str()); onHoldCall(current_call_id); } else if (isConference(current_call_id) && !participToConference( call_id)) { - _debug (" offHoldCall Put current conference (%s) on hold", current_call_id.c_str()); detachParticipant(default_id, current_call_id); } } @@ -603,11 +605,11 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) { account_id = getAccountFromCall(call_id); if (account_id == AccountNULL) { - _debug ("Manager OffHold Call: Call doesn't exists"); + _warn ("Manager: Error: Call doesn't exists in off hold"); return false; } - _debug ("Setting OFFHOLD, Account %s, callid %s", account_id.c_str(), call_id.c_str()); + _debug ("Manager: Setting offhold, Account %s, callid %s", account_id.c_str(), call_id.c_str()); is_rec = getAccountLink(account_id)->getCall(call_id)->isRecording(); returnValue = getAccountLink(account_id)->offhold(call_id); @@ -636,12 +638,6 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) { _audiodriver->flushMain(); } - // codecName = getCurrentCodecName (call_id); - // _debug("ManagerImpl::hangupCall(): broadcast codec name %s ",codecName.c_str()); - - // if (_dbus) _dbus->getCallManager()->currentSelectedCodec (call_id,codecName.c_str()); - - return returnValue; } @@ -650,39 +646,18 @@ bool ManagerImpl::transferCall (const CallID& call_id, const std::string& to) { AccountID accountid; bool returnValue; - _info("Manager: Transfer Call\n"); - - stopTone(); + _info("Manager: Transfer call %s\n", call_id.c_str()); CallID current_call_id = getCurrentCallId(); - if (participToConference(call_id)) { - - _info("Manager: Particip to a conference\n"); - - Conference *conf = getConferenceFromCallID(call_id); - - if (conf != NULL) { - // remove this participant - removeParticipant(call_id); - - processRemainingParticipant(current_call_id, conf); - } - } else { - - // we are not participating to a conference, current call switched to "" - if (!isConference(current_call_id)) - switchCall(""); - } - - /* Direct IP to IP call */ + // Direct IP to IP call if (getConfigFromCall(call_id) == Call::IPtoIP) { - returnValue - = SIPVoIPLink::instance(AccountNULL)-> transfer(call_id, to); + returnValue = SIPVoIPLink::instance(AccountNULL)-> transfer(call_id, to); } - /* Classic call, attached to an account */ + // Classic call, attached to an account else { - accountid = getAccountFromCall(call_id); + + accountid = getAccountFromCall(call_id); if (accountid == AccountNULL) { _warn ("Manager: Call doesn't exists"); @@ -691,9 +666,9 @@ bool ManagerImpl::transferCall (const CallID& call_id, const std::string& to) { returnValue = getAccountLink(accountid)->transfer(call_id, to); - removeCallAccount(call_id); } + // remove waiting call in case we make transfer without even answer removeWaitingCall(call_id); return returnValue; @@ -721,6 +696,8 @@ bool ManagerImpl::refuseCall (const CallID& id) { AccountID accountid; bool returnValue; + _debug("Manager: Refuse call %s", id.c_str()); + CallID current_call_id = getCurrentCallId(); stopTone(); @@ -730,12 +707,14 @@ bool ManagerImpl::refuseCall (const CallID& id) { // AudioLayer* audiolayer = getAudioDriver(); if (nbCalls <= 1) { - _debug (" hangupCall: stop audio stream, ther is only %i call(s) remaining", nbCalls); + _debug ("Manager: Stop audio stream, ther is only %i call(s) remaining", nbCalls); AudioLayer* audiolayer = getAudioDriver(); audiolayer->stopStream(); } + _debug("OK"); + /* Direct IP to IP call */ if (getConfigFromCall(id) == Call::IPtoIP) { @@ -747,7 +726,7 @@ bool ManagerImpl::refuseCall (const CallID& id) { accountid = getAccountFromCall(id); if (accountid == AccountNULL) { - _debug ("! Manager OffHold Call: Call doesn't exists"); + _warn ("Manager: Call doesn't exists"); return false; } @@ -755,6 +734,7 @@ bool ManagerImpl::refuseCall (const CallID& id) { removeCallAccount(id); } + _debug("OK"); // if the call was outgoing or established, we didn't refuse it // so the method did nothing @@ -763,9 +743,6 @@ bool ManagerImpl::refuseCall (const CallID& id) { if (_dbus) _dbus->getCallManager()->callStateChanged(id, "HUNGUP"); - - // if(current_call_id.compare("") != 0) - // switchCall (""); } return returnValue; @@ -1545,18 +1522,24 @@ bool ManagerImpl::incomingCallWaiting () { } void ManagerImpl::addWaitingCall (const CallID& id) { + ost::MutexLock m(_waitingCallMutex); _waitingCall.insert(id); _nbIncomingWaitingCall++; + + _info("Manager: Add waiting call %s (%d calls)", id.c_str(), _nbIncomingWaitingCall); } void ManagerImpl::removeWaitingCall (const CallID& id) { + ost::MutexLock m(_waitingCallMutex); // should return more than 1 if it erase a call if (_waitingCall.erase(id)) { _nbIncomingWaitingCall--; } + + _info("Manager: Remove waiting call %s (%d calls)", id.c_str(), _nbIncomingWaitingCall); } bool ManagerImpl::isWaitingCall (const CallID& id) { @@ -1574,29 +1557,29 @@ bool ManagerImpl::isWaitingCall (const CallID& id) { //////////////////////////////////////////////////////////////////////////////// // SipEvent Thread bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId) { - PulseLayer *pulselayer; + std::string from, number, display_name, display; + if(!call) + _error("Manager: Error: no call at this point"); + stopTone(); - _debug ("Incoming call %s for account %s", call->getCallId().data(), accountId.c_str()); + _debug ("Manager: Incoming call %s for account %s", call->getCallId().data(), accountId.c_str()); associateCallToAccount(call->getCallId(), accountId); // If account is null it is an ip to ip call - if (accountId == AccountNULL) { - associateConfigToCall(call->getCallId(), Call::IPtoIP); - } else { + } + else { // strip sip: which is not required and bring confusion with ip to ip calls // when placing new call from history (if call is IAX, do nothing) std::string peerNumber = call->getPeerNumber(); int startIndex = peerNumber.find("sip:"); - // if "sip:" is found => it is not an IAX call - if (startIndex != (int) string::npos) { std::string strippedPeerNumber = peerNumber.substr(startIndex + 4); call->setPeerNumber(strippedPeerNumber); @@ -1604,32 +1587,23 @@ bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId) { } - _debug ("ManagerImpl::incomingCall :: hasCurrentCall() %i ", hasCurrentCall()); - if (!hasCurrentCall()) { + _debug ("Manager: Has no current call"); call->setConnectionState(Call::Ringing); ringtone(); - // switchCall (call->getCallId()); } - - /* - else { - addWaitingCall(call->getCallId()); - } - */ + else { + _debug ("Manager: has current call"); + } addWaitingCall(call->getCallId()); from = call->getPeerName(); - number = call->getPeerNumber(); - display_name = call->getDisplayName(); - // _debug( "incomingCall from: %s, number: %s, display_name: %s", from.c_str(), number.c_str(), display_name.c_str()); - if (from != "" && number != "") { from.append(" <"); from.append(number); @@ -1640,33 +1614,15 @@ bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId) { from.append(">"); } - /* - CallIDSet::iterator iter = _waitingCall.begin(); - while (iter != _waitingCall.end()) { - CallID ident = *iter; - _debug("ManagerImpl::incomingCall :: CALL iteration: %s ",ident.c_str()); - ++iter; - } - */ - /* Broadcast a signal over DBus */ - _debug ("From: %s, Number: %s, DisplayName: %s", from.c_str(), number.c_str(), display_name.c_str()); + _debug ("Manager: From: %s, Number: %s, Display Name: %s", from.c_str(), number.c_str(), display_name.c_str()); display = display_name; - display.append(" "); - display.append(from); if (_dbus) - _dbus->getCallManager()->incomingCall(accountId, call->getCallId(), - display.c_str()); - - //if (_dbus) _dbus->getCallManager()->callStateChanged(call->getCallId(), "INCOMING"); - - if (_audiodriver->getLayerType() == PULSEAUDIO) { - pulselayer = dynamic_cast<PulseLayer *> (getAudioDriver()); - } + _dbus->getCallManager()->incomingCall(accountId, call->getCallId(), display.c_str()); return true; } @@ -1943,7 +1899,8 @@ void ManagerImpl::ringback () { * Multi Thread */ void ManagerImpl::ringtone () { - _debug ("ManagerImpl::ringtone"); + + _debug ("Manager: Start ringtone"); std::string ringchoice; AudioLayer *audiolayer; AudioCodec *codecForTone; @@ -1952,7 +1909,7 @@ void ManagerImpl::ringtone () { if (isRingtoneEnabled()) { - _debug (" Tone is enabled"); + _debug ("Manager: Tone is enabled"); //TODO Comment this because it makes the daemon crashes since the main thread //synchronizes the ringtone thread. @@ -1967,10 +1924,12 @@ void ManagerImpl::ringtone () { audiolayer = getAudioDriver(); - layer = audiolayer->getLayerType(); - - if (audiolayer == 0) + if (!audiolayer) { + _error("Manager: Error: no audio layer in ringtone"); return; + } + + layer = audiolayer->getLayerType(); samplerate = audiolayer->getSampleRate(); @@ -3937,7 +3896,6 @@ bool ManagerImpl::removeCallAccount (const CallID& callID) { if (_callAccountMap.erase(callID)) { return true; } - return false; } @@ -4096,18 +4054,19 @@ ManagerImpl::getAccount (const AccountID& accountID) { AccountID ManagerImpl::getAccountIdFromNameAndServer ( const std::string& userName, const std::string& server) { + AccountMap::iterator iter; SIPAccount *account; - _debug ("getAccountIdFromNameAndServer : username = %s , server = %s", userName.c_str(), server.c_str()); + + _info ("Manager : username = %s , server = %s", userName.c_str(), server.c_str()); // Try to find the account id from username and server name by full match for (iter = _accountMap.begin(); iter != _accountMap.end(); ++iter) { - _debug ("for : account = %s", iter->first.c_str()); account = dynamic_cast<SIPAccount *> (iter->second); if (account != NULL) { if (account->fullMatch(userName, server)) { - _debug ("Matching accountId in request is a fullmatch"); + _debug ("Manager: Matching account id in request is a fullmatch %s@%s", userName.c_str(), server.c_str()); return iter->first; } } @@ -4119,7 +4078,7 @@ AccountID ManagerImpl::getAccountIdFromNameAndServer ( if (account != NULL) { if (account->hostnameMatch(server)) { - _debug ("Matching accountId in request with hostname"); + _debug ("Manager: Matching account id in request with hostname %s", server.c_str()); return iter->first; } } @@ -4131,12 +4090,14 @@ AccountID ManagerImpl::getAccountIdFromNameAndServer ( if (account != NULL) { if (account->userMatch(userName)) { - _debug ("Matching accountId in request with username"); + _debug ("Manager: Matching account id in request with username %s", userName.c_str()); return iter->first; } } } + _debug ("Manager: Username %s or server %s doesn't match any account, using IP2IP", userName.c_str(), server.c_str()); + // Failed again! return AccountNULL return AccountNULL; } @@ -4260,7 +4221,7 @@ bool ManagerImpl::associateConfigToCall (const CallID& callID, if (getConfigFromCall(callID) == CallConfigNULL) { // nothing with the same ID _callConfigMap[callID] = config; - _debug ("Associate Call %s with config %i", callID.data(), config); + _debug ("Manager: Associate call %s with config %i", callID.c_str(), config); return true; } else { return false; diff --git a/sflphone-common/src/sip/sipcall.cpp b/sflphone-common/src/sip/sipcall.cpp index d1e22660c64e97650684a27048114b875de382e2..9ed7f7a90e42b3651fdd67fddde9972fbd9a7565 100644 --- a/sflphone-common/src/sip/sipcall.cpp +++ b/sflphone-common/src/sip/sipcall.cpp @@ -33,17 +33,19 @@ SIPCall::SIPCall (const CallID& id, Call::CallType type, pj_pool_t *pool) : Call , _invSession (NULL) , _local_sdp (0) { + _debug ("SIPCall: Create new call %s", id.c_str()); + _local_sdp = new Sdp (pool); - _debug ("SIPCALL::Constructor for this class is called "); } SIPCall::~SIPCall() { + _debug ("SIPCall: Delete call"); + delete _audiortp; _audiortp = 0; delete _local_sdp; _local_sdp = 0; - _debug ("SIPCALL::Destructor for this class is called "); } diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index 2309c86923288825ba59aed8ce1b1ab8a04c50ff..36901c1e779c2b67730b6dcbd4f4cd965a8f3658 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -352,6 +352,7 @@ SIPVoIPLink::terminateSIPCall() void SIPVoIPLink::terminateOneCall (const CallID& id) { + _debug("UserAgent: Terminate call %s", id.c_str()); SIPCall *call = getSIPCall (id); @@ -396,7 +397,7 @@ std::string SIPVoIPLink::getInterfaceAddrFromName(std::string ifaceName) { struct in_addr *addr_in; if((fd = socket (AF_INET, SOCK_DGRAM,0)) < 0) - _debug("UserAgent: getInterfaceAddrFromName error could not open socket\n"); + _error("UserAgent: Error: could not open socket"); memset (&ifr, 0, sizeof (struct ifreq)); @@ -404,7 +405,7 @@ std::string SIPVoIPLink::getInterfaceAddrFromName(std::string ifaceName) { ifr.ifr_addr.sa_family = AF_INET; if((err = ioctl(fd, SIOCGIFADDR, &ifr)) < 0) - _debug("UserAgent: getInterfaceAddrFromName use default interface (0.0.0.0)\n"); + _debug("UserAgent: Use default interface (0.0.0.0)"); saddr_in = (struct sockaddr_in *)&ifr.ifr_addr; addr_in = &(saddr_in->sin_addr); @@ -974,15 +975,15 @@ SIPVoIPLink::peerHungup (const CallID& id) bool SIPVoIPLink::cancel (const CallID& id) { + _info ("UserAgent: Cancel call %s", id.c_str()); + SIPCall* call = getSIPCall (id); - if (call==0) { - _debug ("! SIP Error: Call doesn't exist"); + if (!call) { + _warn("UserAgent: Error: Call doesn't exist"); return false; } - _debug ("- SIP Action: Cancel call %s [cid: %3d]", id.data(), call->getCid()); - terminateOneCall (id); removeCall (id); @@ -1203,17 +1204,18 @@ SIPVoIPLink::refuse (const CallID& id) pj_status_t status; pjsip_tx_data *tdata; + _debug("UserAgent: Refuse call %s", id.c_str()); call = getSIPCall (id); if (call==0) { - _debug ("Call doesn't exist"); + _error ("UserAgent: Error: Call doesn't exist"); return false; } // can't refuse outgoing call or connected if (!call->isIncoming() || call->getConnectionState() == Call::Connected) { - _debug ("It's not an incoming call, or it's already answered"); + _debug ("UserAgent: Call %s is not in state incoming, or is already answered"); return false; } @@ -1232,6 +1234,8 @@ SIPVoIPLink::refuse (const CallID& id) terminateOneCall (id); + _debug("UserAgent: Refuse call completed"); + return true; } @@ -1395,25 +1399,18 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) // Creates URI std::string fromUri; - std::string toUri; - std::string contactUri; fromUri = account->getFromUri(); - toUri = call->getPeerNumber(); // expecting a fully well formed sip uri std::string address = findLocalAddressFromUri (toUri, account->getAccountTransport ()); - int port = findLocalPortFromUri (toUri, account->getAccountTransport ()); std::stringstream ss; - std::string portStr; - ss << port; - ss >> portStr; contactUri = account->getContactHeader (address, portStr); @@ -1424,15 +1421,12 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) contactUri.c_str()); pj_str_t pjFrom; - pj_cstr (&pjFrom, fromUri.c_str()); pj_str_t pjContact; - pj_cstr (&pjContact, contactUri.c_str()); pj_str_t pjTo; - pj_cstr (&pjTo, toUri.c_str()); // Create the dialog (UAC) @@ -1476,7 +1470,6 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) // decrement transport's ref count // pjsip_transport_dec_ref(account->getAccountTransport()); - status = pjsip_inv_send_msg (inv, tdata); if (status != PJ_SUCCESS) { @@ -1499,7 +1492,7 @@ void SIPVoIPLink::SIPCallServerFailure (SIPCall *call) { if (call != 0) { - _debug ("Server error!"); + _error ("UserAgent: Error: Server error!"); CallID id = call->getCallId(); Manager::instance().callFailure (id); terminateOneCall (id); @@ -2987,7 +2980,7 @@ void set_voicemail_info (AccountID account, pjsip_msg_body *body) void SIPVoIPLink::handle_reinvite (SIPCall *call) { - _debug ("UserAgent: handle_reinvite"); + _debug ("UserAgent: Handle reinvite"); /* // Close the previous RTP session call->getAudioRtp()->stop (); @@ -3010,7 +3003,7 @@ void SIPVoIPLink::handle_reinvite (SIPCall *call) // This callback is called when the invite session state has changed void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) { - _debug ("call_on_state_changed to state %s", invitationStateMap[inv->state]); + _debug ("UserAgent: Call state changed to %s", invitationStateMap[inv->state]); pjsip_rx_data *rdata; pj_status_t status; @@ -3055,7 +3048,6 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE; switch (call->getInvSession()->state) { - // switch (inv->state) { case PJSIP_INV_STATE_NULL: @@ -3094,9 +3086,7 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) pjsip_tx_data *tdata; pj_status_t status; - status = pjsip_xfer_notify (call->getXferSub(), - ev_state, st_code, - NULL, &tdata); + status = pjsip_xfer_notify (call->getXferSub(), ev_state, st_code, NULL, &tdata); if (status != PJ_SUCCESS) { _debug ("UserAgent: Unable to create NOTIFY -- %d", status); @@ -3155,45 +3145,35 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) _debug ("State: %s. Cause: %.*s", invitationStateMap[inv->state], (int) inv->cause_text.slen, inv->cause_text.ptr); + accId = Manager::instance().getAccountFromCall (call->getCallId()); + link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId)); + + // Make sure link is valid + assert(link); + switch (inv->cause) { - /* The call terminates normally - BYE / CANCEL */ + // The call terminates normally - BYE / CANCEL case PJSIP_SC_OK: - case PJSIP_SC_REQUEST_TERMINATED: - accId = Manager::instance().getAccountFromCall (call->getCallId()); - link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId)); - - if (link) { - link->SIPCallClosed (call); - } - + link->SIPCallClosed (call); break; - case PJSIP_SC_NOT_FOUND: /* peer not found */ - - case PJSIP_SC_DECLINE: /* We have been ignored */ + case PJSIP_SC_DECLINE: + _debug("UserAgent: Call %s is declined", call->getCallId().c_str()); + if (inv->role == PJSIP_ROLE_UAC) + link->SIPCallServerFailure (call); + break; + case PJSIP_SC_NOT_FOUND: /* peer not found */ case PJSIP_SC_REQUEST_TIMEOUT: /* request timeout */ - case PJSIP_SC_NOT_ACCEPTABLE_HERE: /* no compatible codecs */ - case PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE: - case PJSIP_SC_UNSUPPORTED_MEDIA_TYPE: - case PJSIP_SC_UNAUTHORIZED: - case PJSIP_SC_FORBIDDEN: - case PJSIP_SC_REQUEST_PENDING: - accId = Manager::instance().getAccountFromCall (call->getCallId()); - link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId)); - - if (link) { - link->SIPCallServerFailure (call); - } - + link->SIPCallServerFailure (call); break; default: @@ -3207,7 +3187,7 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) // This callback is called after SDP offer/answer session has completed. void call_on_media_update (pjsip_inv_session *inv, pj_status_t status) { - _debug ("UserAgent: Call on media update"); + _debug ("UserAgent: Call media update"); const pjmedia_sdp_session *local_sdp; const pjmedia_sdp_session *remote_sdp; @@ -3337,8 +3317,9 @@ void call_on_forked (pjsip_inv_session *inv, pjsip_event *e) void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e) { - _debug("UserAgent: Transaction changed to state %s", transactionStateMap[tsx->state]); + assert(tsx); + _debug("UserAgent: Transaction changed to state %s", transactionStateMap[tsx->state]); if (tsx->role==PJSIP_ROLE_UAS && tsx->state==PJSIP_TSX_STATE_TRYING && pjsip_method_cmp (&tsx->method, &pjsip_refer_method) ==0) { @@ -3348,10 +3329,14 @@ void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_ if (e && e->body.rx_msg.rdata) { + + _debug("Event"); pjsip_tx_data* t_data; pjsip_rx_data* r_data = e->body.rx_msg.rdata; - if (r_data->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) { + if (r_data && r_data->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) { + + _debug("R_data"); std::string method_info = "INFO"; std::string method_notify = "NOTIFY"; @@ -3373,6 +3358,8 @@ void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_ } } } + + _debug("OK: ransaction changed to state"); } void regc_cb (struct pjsip_regc_cbparam *param) @@ -3502,18 +3489,18 @@ mod_on_rx_request (pjsip_rx_data *rdata) std::string method_name; std::string request; + + _info("UserAgent: Receiving REQUEST using transport: %s %s (refcnt=%d)", + rdata->tp_info.transport->obj_name, + rdata->tp_info.transport->info, + (int)pj_atomic_get(rdata->tp_info.transport->ref_cnt)); + // No need to go any further on incoming ACK if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) { _info("UserAgent: received an ACK"); return true; } - // Handle the incoming call invite in this function - _info("UserAgent: Receiving REQUEST using transport: %s %s (refcnt=%d)", - rdata->tp_info.transport->obj_name, - rdata->tp_info.transport->info, - (int)pj_atomic_get(rdata->tp_info.transport->ref_cnt)); - /* First, let's got the username and server name from the invite. * We will use them to detect which account is the callee. */ @@ -3523,13 +3510,10 @@ mod_on_rx_request (pjsip_rx_data *rdata) userName = std::string (sip_uri->user.ptr, sip_uri->user.slen); server = std::string (sip_uri->host.ptr, sip_uri->host.slen); - _debug ("UserAgent: mod_on_rx_request: %s@%s", userName.c_str(), server.c_str()); - // Get the account id of callee from username and server account_id = Manager::instance().getAccountIdFromNameAndServer (userName, server); /* If we don't find any account to receive the call */ - if (account_id == AccountNULL) { _debug ("UserAgent: Username %s doesn't match any account, using IP2IP!",userName.c_str()); } @@ -3562,7 +3546,7 @@ mod_on_rx_request (pjsip_rx_data *rdata) displayName = std::string (""); } - _debug ("UserAgent: The receiver is : %s@%s", userName.data(), server.data()); + _debug ("UserAgent: The receiver is: %s@%s", userName.data(), server.data()); _debug ("UserAgent: The callee account id is %s", account_id.c_str()); /* Now, it is the time to find the information of the caller */ @@ -3580,6 +3564,7 @@ mod_on_rx_request (pjsip_rx_data *rdata) // Get the server voicemail notification // Catch the NOTIFY message if (rdata->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) { + method_name = "NOTIFY"; // Retrieve all the message. Should contains only the method name but ... request = rdata->msg_info.msg->line.req.method.name.ptr; @@ -3616,10 +3601,10 @@ mod_on_rx_request (pjsip_rx_data *rdata) get_remote_sdp_from_offer (rdata, &r_sdp); if(account->getActiveCodecs().empty()) { - _warn ("UserAgent: Error: No active codec"); - pj_strdup2 (_pool, &reason, "no active codec"); + _warn ("UserAgent: Error: No active codec"); + pj_strdup2 (_pool, &reason, "no active codec"); pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_NOT_ACCEPTABLE_HERE , - &reason, NULL, NULL); + &reason, NULL, NULL); return true; } @@ -3658,13 +3643,14 @@ mod_on_rx_request (pjsip_rx_data *rdata) id = Manager::instance().getNewCallID(); call = new SIPCall (id, Call::Incoming, _pool); - /* If an error occured at the call creation */ + + // If an error occured at the call creation if (!call) { _warn("UserAgent: Error: Unable to create an incoming call"); - pj_strdup2 (_pool, &reason, "unable to create an incoming call"); + pj_strdup2 (_pool, &reason, "unable to create an incoming call"); pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, &reason, NULL, NULL); - return false; + return false; } std::string addrToUse, addrSdp ="0.0.0.0"; @@ -3676,17 +3662,17 @@ mod_on_rx_request (pjsip_rx_data *rdata) // May use the published address as well addrToUse = SIPVoIPLink::instance("")->getInterfaceAddrFromName(account->getLocalInterface ()); - account->isStunEnabled () ? addrSdp = account->getPublishedAddress () : addrSdp = addrToUse; - // Set the appropriate transport to have the right VIA header - link->init_transport_selector (account->getAccountTransport (), &tp); + account->isStunEnabled () ? addrSdp = account->getPublishedAddress () : addrSdp = addrToUse; + // Set the appropriate transport to have the right VIA header + link->init_transport_selector (account->getAccountTransport (), &tp); - if(account->getAccountTransport()) { + if(account->getAccountTransport()) { - _debug("UserAgent: Process INVITE request using transport: %s %s (refcnt=%i)", - account->getAccountTransport()->obj_name, - account->getAccountTransport()->info, - (int)pj_atomic_get(account->getAccountTransport()->ref_cnt)); - } + _debug("UserAgent: SIP transport for this account: %s %s (refcnt=%i)", + account->getAccountTransport()->obj_name, + account->getAccountTransport()->info, + (int)pj_atomic_get(account->getAccountTransport()->ref_cnt)); + } } @@ -3707,22 +3693,6 @@ mod_on_rx_request (pjsip_rx_data *rdata) call->initRecFileName(); - // Notify UI there is an incoming call - - _debug ("UserAgent: Add call to account link"); - - if (Manager::instance().incomingCall (call, account_id)) { - // Add this call to the callAccountMap in ManagerImpl - Manager::instance().getAccountLink (account_id)->addCall (call); - } else { - // Fail to notify UI - delete call; call = NULL; - _warn ("UserAgent: Fail to notify UI!"); - pj_strdup2 (_pool, &reason, "fail to notify ui"); - pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, - &reason, NULL, NULL); - return false; - } // Have to do some stuff with the SDP // Set the codec map, IP, peer number and so on... for the SIPCall object @@ -3758,7 +3728,7 @@ mod_on_rx_request (pjsip_rx_data *rdata) pj_strdup2 (_pool, &reason, "fail to create uas dialog"); pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, &reason, NULL, NULL); - return true; + return false; } // Specify media capability during invite session creation @@ -3772,7 +3742,8 @@ mod_on_rx_request (pjsip_rx_data *rdata) // Associate the call in the invite session inv->mod_data[_mod_ua.id] = call; - // Send a 180/Ringing response + // Send a 180 Ringing response + _info ("UserAgent: Send a 180 Ringing response"); status = pjsip_inv_initial_answer (inv, rdata, PJSIP_SC_RINGING, NULL, NULL, &tdata); PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1); @@ -3787,6 +3758,20 @@ mod_on_rx_request (pjsip_rx_data *rdata) // Update the connection state call->setConnectionState (Call::Ringing); + _debug ("UserAgent: Add call to account link"); + if (Manager::instance().incomingCall (call, account_id)) { + // Add this call to the callAccountMap in ManagerImpl + Manager::instance().getAccountLink (account_id)->addCall (call); + } else { + // Fail to notify UI + delete call; call = NULL; + _warn ("UserAgent: Fail to notify UI!"); + pj_strdup2 (_pool, &reason, "fail to notify ui"); + pjsip_endpt_respond_stateless (_endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, + &reason, NULL, NULL); + return false; + } + /* Done */ return true; diff --git a/sippxml/ip2ip_uac_send_hangup.xml b/sippxml/ip2ip_uac_send_hangup.xml index 49cc63fca06e2cd1f2a40f1f65929de436da7d6b..8b801eb49438bb553a448f28e2c410f86c34a234 100644 --- a/sippxml/ip2ip_uac_send_hangup.xml +++ b/sippxml/ip2ip_uac_send_hangup.xml @@ -95,6 +95,4 @@ <recv response="200"> </recv> - <pause milliseconds="1000"/> - </scenario> diff --git a/sippxml/ip2ip_uac_send_peer_hungup.xml b/sippxml/ip2ip_uac_send_peer_hungup.xml index 4e811e38262f10680417f9415e960e33585b26ee..048b0d8a062521288ed6afc5c21934a2232dd30a 100644 --- a/sippxml/ip2ip_uac_send_peer_hungup.xml +++ b/sippxml/ip2ip_uac_send_peer_hungup.xml @@ -89,6 +89,4 @@ ]]> </send> - <pause milliseconds="1000"/> - </scenario> diff --git a/sippxml/testsuiteuac.sh b/sippxml/testsuiteuac.sh index 1ed0db416504d9abc8288a3a56e8b848d0e46263..9e993dfeb80926a0b7131add92bc4d657ab89726 100644 --- a/sippxml/testsuiteuac.sh +++ b/sippxml/testsuiteuac.sh @@ -62,29 +62,7 @@ function test_ip2ip_recv_hangup { # sleep 1; # start sipp client and send calls - sipp -sf ip2ip_uac_send_peer_hungup.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} -l 1 -m 10 - - # kill every one - # bashtrap -} - - -# SCENARIO 1 Test 4 -function test_ip2ip_recv_peer_hungup { - - # start sflphoned - # /usr/lib/sflphone/sflphoned& - - # wait some time to make sure sflphoned is started - # sleep 1; - - # python ../tools/pysflphone/pysflphone_testdbus.py & - - # wait some time to make sure client is bound - # sleep 1; - - # start sipp client and send calls - sipp -sf ip2ip_uac_send_hangup.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} -l 1 -m 10 + sipp -sf ip2ip_uac_send_peer_hungup.xmlip2ip_uac_send_hangup.xml ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} -l 1 -m 10 # kill every one # bashtrap @@ -230,6 +208,26 @@ function test_account_send_transfer { } +# SCENARIO 5 Test 1 +function test_ip2ip_send_refused { + + # start sflphoned + # /usr/lib/sflphone/sflphoned& + + # start sipp server to receive calls from sflphone and then hangup + sipp -sf ip2ip_uac_send_refused.xml ${REMOTEADDR_lo} -s ${REMOTEADDR_lo} -i ${LOCALIP_lo} -p ${LOCALPORT} -l 1 + + # wait some time to make sure sflphoned is started + # sleep 1; + + # run python client and script to make calls + # python ../tools/pysflphone/pysflphone_testdbus.py & + + # kill every one + bashtrap +} + + # function called if CTRL-C detected bashtrap() { @@ -288,7 +286,7 @@ bashtrap() # - Put this call on HOLD # - Off HOLD this call # - Hangup -test_ip2ip_send_hold_offhold +# test_ip2ip_send_hold_offhold @@ -297,4 +295,11 @@ test_ip2ip_send_hold_offhold # Test 1: - Send an IP2IP call # - Transfer this call to another sipp instance # - Hangup -# test_account_send_transfer \ No newline at end of file +# test_account_send_transfer + + +#SCENARIO 5: Refuse call (IP2IP) + +# Test 1: - Receive a call +# - Refuse (hangup without answer) +test_ip2ip_send_refused \ No newline at end of file diff --git a/tools/pysflphone/pysflphone_testdbus.py b/tools/pysflphone/pysflphone_testdbus.py index a1c909c531fb3a2b73306c59466039e26bbcefb1..933f8736c9ab8e57183006a92069910119ff66d2 100644 --- a/tools/pysflphone/pysflphone_testdbus.py +++ b/tools/pysflphone/pysflphone_testdbus.py @@ -21,21 +21,29 @@ PHONE1="27182" PHONE2="31416" PHONE3="14142" + # Define function callback to emulate UA behavior on -# recieving a call +# recieving a call (peer hangup)) def acceptOnIncomingCall(sflphone): - time.sleep(0.2) + sflphone.Accept(sflphone.currentCallId) + # Define function callback to emulate UA behavior on # receiving a call and hanging up def acceptOnIncomingCallHangup(sflphone): - time.sleep(0.2) - sflphone.Accept(sflphone.currentCallId) - time.sleep(0.5) + + sflphone.Accept(sflphone.currentCallId) sflphone.HangUp(sflphone.currentCallId) +# Define function callback to emulate UA behavior on +# refusing a call +def refuseOnIncomingCall(sflphone): + # time.sleep(0.5) + sflphone.Refuse(sflphone.currentCallId) + + class SflPhoneTests(): def __init__(self, sfl): @@ -230,6 +238,17 @@ class SflPhoneTests(): i = i+1 + # SCENARIO 5 Test 1 + def test_ip2ip_recv_refuse(self): + """Receive an incoming IP2IP call, refuse it""" + + # Add callback for this test + self.sflphone.onIncomingCall_cb = refuseOnIncomingCall + + # Start Glib mainloop + self.sflphone.start() + + # Open sflphone and connect to sflphoned through dbus sflphone = SflPhoneCtrlSimple(True) @@ -291,7 +310,7 @@ sflphone.setFirstRegisteredAccount(); # - Put this call on HOLD # - Off HOLD this call # - Hangup -testsuite.test_ip2ip_send_hold_offhold() +# testsuite.test_ip2ip_send_hold_offhold() @@ -301,3 +320,11 @@ testsuite.test_ip2ip_send_hold_offhold() # - Transfer this call to another sipp instance # - Hangup # testsuite.test_account_send_transfer() + + + +# SCENARIO 5: IP2IP Call, Refuse + +# Test 1: - Receive an incoming call +# - Hangup without answer +testsuite.test_ip2ip_recv_refuse() diff --git a/tools/pysflphone/sflphonectrlsimple.py b/tools/pysflphone/sflphonectrlsimple.py index a19d4ab0901f4b28fb2081d3f68fc58a5419b2e1..491e105e8256fb6314c80b95b081fb0d5c7f75fc 100755 --- a/tools/pysflphone/sflphonectrlsimple.py +++ b/tools/pysflphone/sflphonectrlsimple.py @@ -66,6 +66,7 @@ class SflPhoneCtrlSimple(Thread): self.registered = False self.register() self.currentCallId = "" + self.loop = MainLoop() self.test = test @@ -534,11 +535,12 @@ class SflPhoneCtrlSimple(Thread): def Refuse(self, callid): """Refuse an incoming call identified by a CallID""" - if not self.account: - self.setFirstRegisteredAccount() + print "Refuse call " + callid + # if not self.account: + # self.setFirstRegisteredAccount() - if not self.isAccountRegistered(): - raise SflPhoneError("Can't refuse a call without a registered account") + # if not self.isAccountRegistered(): + # raise SflPhoneError("Can't refuse a call without a registered account") if callid is None or callid == "": raise SflPhoneError("Invalid callID") @@ -548,6 +550,7 @@ class SflPhoneCtrlSimple(Thread): def Accept(self, callid): """Accept an incoming call identified by a CallID""" + print "Accept call " + callid if not self.account: self.setFirstRegisteredAccount() @@ -603,4 +606,9 @@ class SflPhoneCtrlSimple(Thread): return callid def run(self): - self.loop.run() + gobject.threads_init() + # self.loop.run() + context = self.loop.get_context() + + while 1: + context.iteration(True)