📄 kcallwidget.cpp
字号:
}void KCallWidget::dialClicked( void ){ QString auxPort = ""; QString MyPort = ""; QString MyAuPort = ""; QString Mask=""; int callT; callT=call->getCallType(); if(debug >= 2) printf("KCallWidget::dialClicked callType=%d",callT); // Permissions for Hold and Refer sessionC->setPermFlags(callT); bool cFlag=sessionC->activeOnly(callT); call->onlyMeActive(cFlag); if(!sessionC->isHoldAllowed(callT)){ call->setHoldMaster(true); } if(sessionC->isTransferAllowed(callT) ) { call->setTransAllowed(true); } else { call->setTransAllowed(false); } int ac=papa->countActiveCalls(); if( ac >= 1) { //some other blocking session active if( cFlag || call->withAudioCall()) { //generalized with Flag or audio if(debug >= 2) printf(" Someone blocks the Audio\n "); QMessageBox::critical(this, "Dial","Someone blocks the Audio.\n Clear this and redial, please"); return; } } hide(); if( curstate == Called ) { // accept clicked, incoming Call missedCalls.setAutoDelete( false ); missedCalls.remove( incomingCall ); missedCalls.setAutoDelete( true ); receivedCalls.append( incomingCall ); updateCallRegister(); if(debug >= 2) printf("accept incoming Call\n "); acceptCall(); return; }//check if we have not spezified a remote yet if( remote->currentText().length() == 0 ) { QMessageBox::critical( this, "Error: No Destination", "You must specify someone to call." ); if(debug >= 2) printf(" Error: No Destination\n "); return; }//transform the input to a SIP-URI, extract a possible DTMF-String QString strRemoteUri; QString s = remote->currentText(); int dtmfPos = s.find(","); int Usize=s.length(); if (dtmfPos>0) { dtmfSize = Usize-dtmfPos-1; dtmfStr = s.right(dtmfSize); s = s.left(dtmfPos); } if( s.contains( '[' ) && s.contains( ']' ) ) { strRemoteUri = s.mid( s.find( '[' ) + 1, s.find( ']' ) - s.find( '[' ) - 1 ); } else { if( s.left( 4 ).lower() != "tel:" ) { if( s.left( 4 ).lower() != "sip:" ) { s = "sip:" + s; } if( !s.contains( '@' ) ) { s = s + "@" + call->getHostname(); } } strRemoteUri = s; } if(debug >= 2) printf(" Uri = %s\n ", s.latin1()); //check if we are calling ourself if(cmpUri(s,thatsMe)) { hangupCall(); return; } for( int i = 0; i < remote->count(); i++ ) { if( remote->text( i ).compare( strRemoteUri ) == 0 ) { remote->removeItem( i ); } } remote->insertItem( strRemoteUri, 0 ); remote->setCurrentItem( 0 ); QSettings settings;//update CallRegister QDateTime t = QDateTime::currentDateTime(); incomingCall = new IncomingCall( strRemoteUri, t ); dialledCalls.append( incomingCall ); updateCallRegister();// our callmember SipUri remoteuri( strRemoteUri ); member = new SipCallMember( call, remoteuri ); connect( member, SIGNAL( statusUpdated( SipCallMember * ) ), this, SLOT( callMemberStatusUpdated() ) ); QString ss = member->getUri().uri(); setCon(ss); //Invite schnitzen! if ( call->withAudioCall() ) { MyAuPort = QString::number(audio->audioOut(sdpS,myNumber )); sdpS->setAudioHomePort(MyAuPort); } if( call->withExtCall() ){ getExtSocket(callT); MyPort = QString::number(KWsocket->getPortNumber()); sdpS->setExtHomePort(MyPort); if(sessionC->isStun() ) { auxPort=QString::number(getStunPort()); } else { auxPort = MyPort; } sdpS->setSExtHomePort(auxPort); } if(!member->requestInvite( sdpS->prepInviteString( call->getCallType() ,MyAuPort,auxPort), MimeContentType( "application/sdp" ) )) { detachFromCall(call); setHide(); informPhoneView(UPDATEWLIST,myNumber); } setLoadText (call->getCallType());//Common Handling rstbutton->setEnabled( false ); dial->setEnabled( false ); hangup->setEnabled( true ); curstate = Calling; setCS( member->getLocalStatusDescription() ); informPhoneView(UPDATEWLIST,myNumber);// we initiated a new call}void KCallWidget::stopRinging(void) {// kill ringtone child process if user accepts or declines the callifif(debug >= 2)printf ("===== KCallWidget::stopRinging\n" ); ringTimer->stop(); if(ringtonepid ) { kill( ringtonepid, SIGKILL ); ringtonepid = 0; }}void KCallWidget::ringTimeout( void ) {if(debug >= 2)printf ("===== KCallWidget::ringTimeout \n" );setCS( member->getLocalStatusDescription() );informPhoneView(UPDATEWLIST,myNumber); //for an incoming call the earliest time to do this bool ok; int auaring = 2000000; //almost foreverint cfnaring = 2000000; //almost foreverif(sessionC->getAua()) auaring = sessionC->getAuacnt().toInt(&ok,10);//get the real value, if activatedif(sessionC->getCFNA()) cfnaring = sessionC->getCallForwardNAcnt().toInt(&ok,10);//get the real value, if activatedif( (ringCount < cfnaring ) && (ringCount < auaring) ) { ringCount++; if((ringtonepid == 0) && (isRingingTone == 1) ) { QString xSP = sessionC->getRingtoneP(); QString xSA = sessionC->getRingtoneapp(); QString xSF = sessionC->getRingtonefile(); QString xSD = sessionC->getRingtonedevice(); xSA.replace( "\n" , ""); xSP.replace( "\n" , ""); xSP.replace( "_" , " "); xSF.replace( "\n" , ""); xSD.replace( "\n" , ""); QString xSAmod = xSA; if( xSAmod.contains( "/" ) ) { xSAmod = xSAmod.mid( xSAmod.findRev( '/' ) + 1 ); } QString xSPmod = xSP; if(xSPmod.contains("%F")) { xSPmod.replace( "%F" , xSF); } if(xSPmod.contains("%D")) { xSPmod.replace( "%D" , xSD); } ringtonepid = fork (); if (!ringtonepid) { // in child process if(debug >= 2)printf ("===== KCallWidget::ringTimeout (%s) (%s) !\n",xSAmod.latin1(),xSPmod.latin1()); execlp( xSA.latin1(), xSAmod.latin1(),xSPmod.latin1(),(char*)NULL); exit(1); } } ringTimer->start( ringTime_3, TRUE );} else { if(ringCount == sessionC->getCallForwardNAcnt().toInt(&ok,10)) { if(sessionC->getCFNA()) { if(debug >= 2) printf("===== KCallWidget::ringTimeout CFNA\n"); member->forwardCall("Contact: <" + sessionC->getCallForwardNAUri() + ">\r\n"); forceDisconnect(); return; } } if (ringCount == sessionC->getAuacnt().toInt(&ok,10) ) { if(sessionC->getAua()) { if(debug >= 2) printf("===== KCallWidget::ringTimeout AA\n"); emit clickDial( ); return; } } hangupCall(); return; }}void KCallWidget::acceptCall( void ){ stopRinging(); acceptCallTimer->start( acceptTime, true );}void KCallWidget::acceptCallTimeout( void ){ QString auxPort =""; QString MyPort =""; QString MyAuPort = ""; bool srtpErr=false; int loadT; loadT = sdpS->checkCodec(false,member,isForceHold(), &srtpErr); int callT=call->saveLoadType(loadT); call->onlyMeActive(sessionC->activeOnly(callT)); if( papa->countActiveCalls() > 1) { //someone else active if( sessionC->activeOnly(callT) || call->withAudioCall()) {//generalized with Flag or audio QMessageBox::critical(this,"Dial", "Someone blocks the Audio. \n Clear this and redial, please"); return; } } if( isRingingTone ) { ::close( audio_fd ); } sessionC->setPermFlags(callT); call->onlyMeActive(sessionC->activeOnly(callT)); if(sessionC->isHoldAllowed(callT)){ } else { call->setHoldMaster(true); call->setNoHold(true); } if(sessionC->isTransferAllowed(callT) ) { transferbutton->setEnabled( true ); referbutton->setEnabled( true ); call->setTransAllowed(true); } else { call->setTransAllowed(false); } // Prepare 200 ok if( call->loadCall()) { dial->setText( "Dial" ); hangup->setText( "Hangup" ); dial->setEnabled( false ); hangup->setEnabled( true ); if (call->withAudioCall()) { MyAuPort = QString::number(audio->audioOut(sdpS,myNumber )); sdpS->setAudioHomePort(MyAuPort); } if(loadT != (int)SipCall::GarKeinCall) { QSettings settings; getExtSocket(callT); MyPort = QString::number(KWsocket->getPortNumber()); sdpS->setExtHomePort(MyPort); if(sessionC->isStun() ) { auxPort=QString::number(getStunPort()); } else { auxPort = MyPort; } sdpS->setSExtHomePort(auxPort); } member->acceptInvite( sdpS->prepAcceptString( loadT,MyAuPort,auxPort,false) , MimeContentType( "application/sdp" ) ); setLoadText(loadT); } else { setLT("no valid session"); member->notAcceptableHere(); if(debug >= 2) printf("=====KCallWidget acceptCall: member->notAcceptableHere \n"); // QMessageBox::information( this, "Accept Call","Accepted codec not found." ); } }void KCallWidget::clickHangup(){ hangupCall();}void KCallWidget::holdCall( void ) { if(debug >= 2) printf("=====KCallWidget toggle hold\n"); preventSessionStart=false; int callT= (int)call->getCallType(); if(debug >= 2) printf("=====KCallWidget "); if( call->isHeld()) { //Call on Hold ? printf(" on Hold\n" ); if( call->getHoldMaster()){ printf(" hold Master" ); call->onlyMeActive(sessionC->activeOnly(callT)); if( papa->countActiveCalls() == 0) { //someone else active if(debug >= 2) printf("request Retrieve\n" ); doRetrieve(); } else if( !sessionC->activeOnly(callT) ) {//generalized with Flag or audio if(debug >= 2) printf("request Retrieve\n" ); doRetrieve(); } } } else { if(!sessionC->isHoldAllowed(call->getCallType())) return; if(debug >= 2) printf(" request Hold \n"); doHold(); } hide();}void KCallWidget::doHold( void ) { holdbutton->setText( "Retrieve" ); crnbutton->setEnabled( false ); call->setHoldMaster(true); call->setHoldCall(SipCall::callHold); doForceHold(true); member->requestReInvite( sdpS->prepAcceptString( call->getCallType() ,sdpS->getAudioHomePort() ,sdpS->getSExtHomePort() ,true) ,MimeContentType( "application/sdp" ) ); setCS( "Call on Hold" ); informPhoneView(UPDATEWLIST,myNumber);}void KCallWidget::doRetrieve( void ) {crnbutton->setEnabled( false );QString MyPort = "";QString MyAuPort = "";holdbutton->setText( "Hold" );call->setHoldMaster(false);doForceHold(false);if ( call->withAudioCall() ) { MyAuPort = QString::number(audio->audioOut(sdpS,myNumber )); sdpS->setAudioHomePort(MyAuPort); }if( call->withExtCall() ){ getExtSocket(call->getCallType()); MyPort = QString::number(KWsocket->getPortNumber()); sdpS->setExtHomePort(MyPort); } member->requestReInvite( sdpS->prepAcceptString( call->getCallType() ,sdpS->getAudioHomePort() ,sdpS->getSExtHomePort() ,false) ,MimeContentType( "application/sdp" ) ) ; }void KCallWidget::handleRedirect( void ){ if(debug >= 2) printf( "=====KCallWidget: Handling redirect...\n" ); preventSessionStart=false; QValueList<SipUri>::Iterator it; SipUriList urilist = member->getRedirectList(); while ( urilist.getListLength() > 0 ) { SipUri redirto = urilist.getPriorContact(); if(cmpUri(redirto.reqUri(),thatsMe)) { forceDisconnect(); return; } QMessageBox mb( "Redirect", "Call redirected to: \n" + redirto.reqUri() + "\n\n" + "Do you want to proceed ? ", QMessageBox::Information, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape ); switch( mb.exec() ) { case QMessageBox::No: continue; case QMessageBox::Cancel: forceDisconnect(); return; } int ctSave; ctSave=(int)call->getCallType(); detachFromCall(call); if( member ) disconnect( member, 0, this, 0 ); member = 0; if( call ) delete call; call = 0; // Hier muessen ALLE relevanten Parameter uebergeben werden!! redirectCall( redirto, subject, ctSave, 0, 0); setHide(); return; } forceDisconnect();}void KCallWidget::handleRefer( void ){ preventSessionStart=false; infostat->setText(" No News"); int ctSave; ctSave=(int)call->getCallType(); if(debug >= 2) printf( "=====KCallWidget: Handling Refer...%d\n",ctSave ); if(redirTo==RdHoldNo) { redirto = member->getRedirectList().getHead(); referTo=redirto.reqUri(); } if(cmpUri(thatsMe,redirto.reqUri())) { sendTrNotify("405 Method not Allowed"); hide(); return; } if( sessionC->activeOnly(ctSave) || call->withAudioCall() ) { //put the call on hold, first if(!call->isHeld()) { redirTo=RdHoldActive; doHold(); return; } } QMessageBox mb( "Refer", "Attempt to establish a new session to: \n" + redirto.reqUri() + "\n\n" + "Do you want to proceed ? ",QMessageBox::Information, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, 0 ); if( mb.exec() == QMessageBox::Yes ) { //inform KPhoneView redirectCall( redirto, subject,ctSave,this,myNumber ); member->setState(SipCallMember::state_Connected); } else { member->setState(SipCallMember::state_Connected); }}void KCallWidget::sendTrNotify(QString cause) { QString theNoti; if(debug >= 2) printf("=====KCallWidget::sendTrNotify cause=%s ich=%d \n",cause.latin1(), myNumber); theNoti="SIP/2.0 " + cause + "\r\n"; if(call->isHeld()) { if( call->getHoldMaster() ) setCS( "Connected Hold" ); else setCS( "Connected Held" ); } else { setCS( "Connected" ); } informPhoneView(UPDATEWLIST,myNumber); infostat->setText(theNoti); member->requestRNotify(theNoti,MimeContentType( "message/sipfrag;version=2.0"));}void KCallWidget::showTransferDialog( void ) { if(debug >= 2) printf("=====KCallWidget showTransferDialog\n"); doTransfer = true;showDialog();}void KCallWidget::showReferDialog( void ) { if(debug >= 2) printf("=====KCallWidget showReferDialog\n");doTransfer = false;showDialog();}void KCallWidget::showDialog( void ){ infostat->setText(" No News"); if(member->getState() == SipCallMember::state_r202 ) return; if(call->blockCall() || call->withAudioCall()) {//XX if(!call->isHeld()) { redirTo=RdHoldForward; doHold(); return; } } if( !referdialog ) { referdialog = new KReferDialog(papa,myNumber,getUserPrefix()); connect( referdialog, SIGNAL( newSessionRefer( const QString & ) ), this, SLOT( newSessionRefer( const QString & ) ) ); } shortTransfer=false; referdialog->show();}void KCallWidget::newSessionRefer( const QString &referto ){if(debug >= 2) printf("=====KCallWidget newSessionRefer\n");// Ignore this button if there is no call setup yet. if( curstate != Connected ) { return; } if( call->getCallStatus() != SipCall::callDead ) { QString s = ""; s+=referto; if( s.left( 4 ).lower() != "tel:" ) { if( s.left( 4 ).lower() != "sip:" ) { s = "sip:" + s; } if( !s.contains( '@' ) ) { s = s + "@" + member->getUri().getHostname(); } } if(cmpUri(s,member->getUri().uri()) || cmpUri(s,thatsMe)) { hide(); return; } redirTo=RdHoldPassive; referTo=s; member->requestRefer( shortTransfer, SipUri( s ) ); notiTimer->start(notiTime,TRUE); return; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -