CallManager.cpp 8.67 KB
#include "JusCallPch.h"

#include "../mainapp.h"
RCallManager *RCallManager::m_psRCallManager = ZNULL;
RCallManager::RCallManager(QObject *parent)
    : QObject(parent)
    , m_pRSession(NULL)
    , m_pSessVoice(NULL)
    , m_pSessVideo(NULL)
    , m_qsMicphone()
    , m_qsSpeaker()
    , m_qsCamera()
    , m_bAudioStarted(false)
{
	m_psRCallManager = this;
}

RCallManager *RCallManager::Instance()
{
    if (!m_psRCallManager) 
		m_psRCallManager = new RCallManager;

    return m_psRCallManager;
}

bool RCallManager::init()
{
    initCallback();
    return true;
}

int RCallManager::getSessId()
{
    if (!m_pRSession)
        return -1;

    return (int)m_pRSession->sessId();
}


void RCallManager::setMicphone(const QString &id)
{
    m_qsMicphone = id;
}

QString RCallManager::getMicphone()
{
    return m_qsMicphone;
}

void RCallManager::setSpeaker(const QString &id)
{
    m_qsSpeaker = id;
}

QString RCallManager::getSpeaker()
{
    return m_qsSpeaker;
}

void RCallManager::setCamera(const QString &id)
{
    m_qsCamera = id;
}

QString RCallManager::getCamera()
{
    return m_qsCamera;
}

bool RCallManager::startSess(const QString & qsPhone, bool bVideo)
{
    RClient::printLog(__FUNCTION__);

    // check for duplication
    if (m_pRSession) return false;

    // open audio device for first session
    if (!startAudioDevice())
    {
        RMessageBox *pMessageBox = new RMessageBox(0, tr("Error"));
        pMessageBox->addButton(tr("OK"), RMessageBox::AcceptRole);
        pMessageBox->setText(tr("Failed to open audio device"));
        pMessageBox->exec();
        return false;
    }

    m_pRSession = new RSession(qsPhone);

    if (hasAudio())
    {
        RMessageBox *pMessageBox = new RMessageBox(0, tr("Message"));
        pMessageBox->addButton(tr("OK"), RMessageBox::AcceptRole);
        pMessageBox->setText(tr("Busy"));
        pMessageBox->exec();
        stopAudioDevice();
        return false;
    }
	if (!bVideo || hasVideo())
		m_pRSession->audioCall();
	else
		m_pRSession->videoCall();
    m_pRSession->show();
    m_pRSession->moveMediaToLog();

    // play ring
    Mtc_RingPlay(EN_MTC_RING_RING, MTC_RING_FOREVER);

    return true;
}

void RCallManager::rmvSession(RSession *)
{
    m_pRSession = ZNULL;

    // close device after all session removed
    stopAudioDevice();
}

void RCallManager::endAllSess()
{
    if (m_pRSession) 
        m_pRSession->close();
}

bool RCallManager::hasAudio()

{
    return m_pRSession ? m_pRSession->hasAudio() : false;
}

bool RCallManager::hasVideo()

{
    return m_pRSession ? m_pRSession->hasVideo() : false;
}

void RCallManager::onServiceEvent(const QString &name, size_t, const Notification &_info)
{
    Notification info = (Notification &)_info;
    unsigned int iCallId = (unsigned int)info.getIntValue(MtcCallIdKey);

    if (name == MtcCallIncomingNotification)
    {
        MtcCallInComing(iCallId);
        QJsonDocument myjsonDoc1 = QJsonDocument::fromJson(info.getStringValue(MtcCallUserDataKey).toLatin1());
        emit CallIncoming(QString::fromLatin1(Mtc_CallGetPeerDisplayName(iCallId)),myjsonDoc1.object().find("avatar_s").value().toString());
    }
    else if (name == MtcCallOutgoingNotification)
    {
        MtcCallOutgoing(iCallId);
    }
    else if (name == MtcCallAlertedNotification)
    {
        unsigned int iType = (unsigned int)info.getIntValue(MtcCallAlertTypeKey);
        MtcCallAlerted(iCallId, iType);
    }
    else if (name == MtcCallConnectingNotification)
    {
        MtcCallConnecting(iCallId);
    }
    else if (name == MtcCallTalkingNotification)
    {
        MtcCallTalking(iCallId);
    }
    else if (name == MtcCallTermedNotification
        || name == MtcCallDidTermNotification)
    {
        if (m_pRSession && (m_pRSession->sessId() == iCallId))
        {
            unsigned int iStatusCode = (unsigned int)info.getIntValue(MtcCallStatusCodeKey);
            QString reason = info.getStringValue(MtcCallDescriptionKey);
            MtcCallTermed(iCallId, iStatusCode, reason.toUtf8());
            qDebug("CMQ CallOutgoing...3 %s\n",Mtc_CallGetSipCallId(iCallId));
            emit CallOutgoing(QString::fromLatin1(Mtc_CallGetSipCallId(iCallId)));
        }
    }
}

void RCallManager::initCallback()
{
    if (!connect((MainApp *)qApp, SIGNAL(serviceEvent(const QString &, size_t, const Notification &)),
        SLOT(onServiceEvent(const QString &, size_t, const Notification &))))
    {
        RClient::printLog("initCallback connect failed");
        return;
    }
}

bool RCallManager::startAudioDevice()
{
    if (m_bAudioStarted) return true;

    if(m_qsMicphone.size() > 1)
    {
        if (Zmf_AudioInputStart(m_qsMicphone.toUtf8().data(), 32000, 1,
            ZmfAecAuto, ZmfAgcAuto) != 0)
            return false;
    }

    if(m_qsSpeaker.size() > 1)
    {
        if (Zmf_AudioOutputStart(m_qsSpeaker.toUtf8().data(), 32000, 1) != 0)
        {
            Zmf_AudioInputStopAll();
            return false;
        }
    }

    m_bAudioStarted = true;

    return true;
}

void RCallManager::stopAudioDevice()
{
    if (m_bAudioStarted)
    {
        Zmf_AudioInputStopAll();
        Zmf_AudioOutputStopAll();
        m_bAudioStarted = false;
    }
}

void RCallManager::showRefreshOk()
{
}

void RCallManager::showCallInComing(unsigned int dwSessId)
{
	if (m_pRSession && (m_pRSession->sessId() != dwSessId))
    {
        // only support one session now
		Mtc_CallTerm(dwSessId, EN_MTC_CALL_TERM_STATUS_BUSY, ZNULL);
        return;
    }   

    // open audio device for first session
    if (!startAudioDevice())
    {
        RMessageBox *pMessageBox = new RMessageBox(0, tr("Error"));
        pMessageBox->addButton(tr("OK"), RMessageBox::AcceptRole);
        pMessageBox->setText(tr("Failed to open audio device"));
        pMessageBox->exec();

        // terminate call
        Mtc_CallTerm(dwSessId, EN_MTC_CALL_TERM_STATUS_ERROR_TEMP_UNAVAIL,
            "Failed to open audio device.");
        return;
    }

	ZCHAR *pcUri, *pcName;
	Mtc_CallGetPeerUri(dwSessId, &pcName, &pcUri);
	QString qsPhone = QString::fromUtf8(pcName);

	if (!m_pRSession)
		m_pRSession = new RSession(qsPhone);
    else if (m_pRSession->currentPhone() != qsPhone)
        m_pRSession->setCurPhone(qsPhone);

	ZINT enSessMode;
	if (Mtc_CallPeerOfferVideo(dwSessId))
		enSessMode = EN_UI_SESS_MODE_VIDEO;
	else
		enSessMode = EN_UI_SESS_MODE_AUDIO;
	m_pRSession->showSessIncoming(dwSessId, enSessMode);
    m_pRSession->show();
    if (m_pRSession->logShowing())
        m_pRSession->moveMediaToLog();

    // play ring
    Mtc_RingPlay(EN_MTC_RING_RING, MTC_RING_FOREVER);

    // alert peer
    Mtc_CallAlert(dwSessId, (ZCOOKIE)m_pRSession, EN_MTC_CALL_ALERT_RING, ZFALSE);
}

void RCallManager::showCallOutgoing(unsigned int dwSessId)
{
	if (!m_pRSession || m_pRSession->sessId() != dwSessId)
		return;

	m_pRSession->showSessOutgoing();
}

void RCallManager::showCallAlerted(unsigned int dwSessId)
{
	if (!m_pRSession || m_pRSession->sessId() != dwSessId)
		return;

	m_pRSession->showSessAlerted();
}

void RCallManager::showCallConnecting(unsigned int dwSessId)
{
    if (!m_pRSession || m_pRSession->sessId() != dwSessId)
        return;

    m_pRSession->showSessConnecting();

    // stop ring playing
    Mtc_RingStop(ZMAXUINT);
}

void RCallManager::showCallTalking(unsigned int dwSessId)
{
	if (!m_pRSession || m_pRSession->sessId() != dwSessId)
		return;

	m_pRSession->showSessTalking();
}

void RCallManager::showCallTermed(unsigned int dwSessId)
{
	if (!m_pRSession || m_pRSession->sessId() != dwSessId)
		return;

	m_pRSession->showSessTermed();

    // stop ring playing
    Mtc_RingStop(ZMAXUINT);

    // play ring for terminated
    Mtc_RingPlay(EN_MTC_RING_TERM, MTC_RING_TERM_LEN);
}

void RCallManager::MtcCallInComing(unsigned int dwSessId)
{
    RClient::printLog("%s %d", __FUNCTION__, dwSessId);
    m_psRCallManager->showCallInComing(dwSessId);
}

void RCallManager::MtcCallOutgoing(unsigned int dwSessId)
{
    RClient::printLog("%s %d", __FUNCTION__, dwSessId);
    m_psRCallManager->showCallOutgoing(dwSessId);
}

void RCallManager::MtcCallAlerted(unsigned int dwSessId, unsigned int dwAlertType)
{
    RClient::printLog("%s %d %d", __FUNCTION__, dwSessId, dwAlertType);
    m_psRCallManager->showCallAlerted(dwSessId);
}

void RCallManager::MtcCallConnecting(unsigned int dwSessId)
{
    RClient::printLog("%s %d", __FUNCTION__, dwSessId);
    m_psRCallManager->showCallConnecting(dwSessId);
}

void RCallManager::MtcCallTalking(unsigned int dwSessId)
{
    RClient::printLog("%s %d", __FUNCTION__, dwSessId);
    m_psRCallManager->showCallTalking(dwSessId);
}

void RCallManager::MtcCallTermed(unsigned int dwSessId, unsigned int dwStatCode, 
    ZCONST ZCHAR *)
{
    RClient::printLog("%s %d %d", __FUNCTION__, dwSessId, dwStatCode);
    m_psRCallManager->showCallTermed(dwSessId);
}