📄 kcallwidget.cpp
字号:
void KCallWidget::renegCodec( void ){ int callT=0, loadT=0; preventSessionStart=false; QString MyPort = ""; QString MyAuPort = ""; if(debug >= 2) printf("=====KCallWidget renegCodec \n"); callT = loadT = call->getCallType(); // Codec renegotiation is only used to switch video on and off at this time if (call->withAudioCall()) { // add video if (callT == SipCall::StandardCall) { call->setCallType(SipCall::auviCall); } // subtract video if (callT == SipCall::auviCall) { call->setCallType(SipCall::StandardCall); } detachFromCall(call); //new port MyAuPort = QString::number(audio->audioOut(sdpS,myNumber )); sdpS->setAudioHomePort(MyAuPort); // new video port if((loadT == SipCall::auviCall)) { getExtSocket(callT); MyPort = QString::number(KWsocket->getPortNumber()); sdpS->setExtHomePort(MyPort); } if (loadT == SipCall::StandardCall){ member->requestReInvite( sdpS->prepInviteString((int)SipCall::StandardCall,MyAuPort,MyPort) ,MimeContentType( "application/sdp" ) ); } else if (loadT == SipCall::auviCall){ member->requestReInvite( sdpS->prepInviteString((int)SipCall::auviCall,MyAuPort,MyPort) ,MimeContentType( "application/sdp" ) ); } }}void KCallWidget::callMemberStatusUpdated( void ){bool srtpErr=false;QString MyPort = "";QString MyAuPort = "";QString auxPort = "";int loadT=SipCall::GarKeinCall; if(debug >= 2) printf("=====KCallWidget callMemberStatusUpdated memberState= %d mynumber = %d ",(int) member->getState(),myNumber );// ---------------------Member State Disconnecting if( member->getState() == SipCallMember::state_Disconnecting ) { if ( member->getCallMemberType() == SipCallMember::Disc) sipauthentication->authRequest(member,getUserPrefix()); if(debug >= 2) printf("state_Disconnecing %d\n", member->getCallMemberType());}// ---------------------Member State Disconnectedelse if( member->getState() == SipCallMember::state_Disconnected ) { if(debug >= 2) printf("state_Disconnected\n"); if( member->getLocalStatusDescription().left( 2 ) == "!!" ) { if(referedFrom && papa->isExistingWidget(referedNr)) { papa->testWidgetList( ); emit sigTrNotify(QString::number(member->getLocalStatusCode()) + " " + member->getLocalStatusDescription().remove(0,2)); if(debug >= 2) printf("=====KCallWidget callMemberStatusUpdated buddy we may emit \n"); } setCS( "Call Failed") ; informPhoneView(UPDATEWLIST,myNumber); QMessageBox::critical( this, "Alert",member->getLocalStatusDescription().remove(0,2)); setHide(); } else { setCS( member->getLocalStatusDescription() ); informPhoneView(UPDATEWLIST,myNumber); }/* Use This if you want to inspect all release causes setCS( member->getLocalStatusDescription() ); QMessageBox::critical( this, "Alert", member->getLocalStatusDescription()); setHide();*/ forceDisconnect();// ---------------------Member State Redirected } else if( member->getState() == SipCallMember::state_Redirected ) { if(debug >= 2) printf(" state_Redirected: "); setCS( member->getLocalStatusDescription() ); informPhoneView(UPDATEWLIST,myNumber); if(debug >= 2) printf(" handleRedirect\n"); handleRedirect();// ---------------------Member State Refer } else if( member->getState() == SipCallMember::state_Refer ) { if(debug >= 2) printf(" state_Refer: handleRefer\n"); member->setState( SipCallMember::state_Refer_handling ); setCS( member->getLocalStatusDescription() ); informPhoneView(UPDATEWLIST,myNumber); handleRefer(); // ---------------------Member State Connected } else if( member->getState() == SipCallMember::state_Connected ) { hide(); if(debug >= 2) printf(" state_Connected "); if( (earlyMedia == earlyCaller) ){// stop rtp and clear resources if(dspe) delete dspe; dspe=0; if(debug >= 2) printf(" earlySBC stopped \n"); earlyMedia=earlyNo; } if(sessionC->isHoldAllowed(call->getCallType())){ holdbutton->setEnabled( true ); } if(sessionC->isTransferAllowed(call->getCallType()) ) { transferbutton->setEnabled( true ); referbutton->setEnabled( true ); } dial->setEnabled( false );rstbutton->setEnabled( false );hangup->setEnabled( true ); int loadT = sdpS->checkCodec(false,member,isForceHold(),&srtpErr); if (srtpErr) { hangupCall(); return; } if(loadT == (int)SipCall::putMeOnHold ) { //peer attempt to put us on hold if( call->getHoldMaster() ) setCS( "Connected Hold" ); else setCS( "Connected Held" ); informPhoneView(UPDATEWLIST,myNumber); if(redirTo==RdHoldActive) { //Hold SubCycle started by handleRefer if(debug >= 2) printf(" RdHoldActive\n" ); redirTo=RdHoldNo; if(call->getNoHold()){ hangupCall(); return; } doPayload(loadT); referTimer->start(referTime,TRUE); // we wait for a notification patiently, before we released the call return; } else if(redirTo==RdHoldPassive) { //Hold SubCycle started by peer, i.e. the passive side if(debug >= 2) printf(" RdHoldPassive\n" ); member->setState(SipCallMember::state_r202); redirTo=RdHoldNo; } } else { call->saveLoadType (loadT); setCS( member->getLocalStatusDescription() ); informPhoneView(UPDATEWLIST,myNumber); if(referedFrom && papa->isExistingWidget(referedNr)) { emit sigTrNotify("200 OK"); if(referedFrom) { disconnect(this,0,referedFrom,0); } referedFrom=0; referedNr=0; } } //Notify the Original A-Side curstate = Connected; setLoadText(loadT); informPhoneView(UPDATEWLIST,myNumber); if(call->loadCall()) { crnbutton->setEnabled( true ) ; } else { crnbutton->setEnabled( false); } if(loadT){ doPayload(loadT); if(redirTo==RdHoldForward) { // we started refer and had to put the call on hold first redirTo=RdHoldNo; showDialog(); return; } if (dtmfSize >0) sendDTMFSeq(); } else { setLT("no valid session"); informPhoneView(UPDATEWLIST,myNumber); member->notAcceptableHere(); return; }// ---------------------Member State state_InviteRequested} else if( member->getState() == SipCallMember::state_InviteRequested ) { if(debug >= 2) printf(" state_InviteRequested\n"); //Notify the Original A-Side if(referedFrom && papa->isExistingWidget(referedNr)) { emit sigTrNotify("100 Trying"); } setCS( "Trying" ); informPhoneView(UPDATEWLIST,myNumber); if ( member->getCallMemberType() == SipCallMember::Invite) sipauthentication->authRequest(member,getUserPrefix());// ---------------------Member State RequestingReInvite } else if( member->getState() == SipCallMember::state_ReInviteRequested ) { if(debug >= 2) printf(" state_ReInviteRequested curstate = %d\n",curstate); if ( member->getCallMemberType() == SipCallMember::Invite) sipauthentication->authRequest(member,getUserPrefix());} else if( member->getState() == SipCallMember::state_RequestingReInvite ) { if(debug >= 2) printf(" state_RequestingReInvite curstate = %d\n",curstate); // Hold and retrieve for the called leg loadT = sdpS->checkCodec(true, member, isForceHold(), &srtpErr); if (loadT == SipCall::noChange) { preventSessionStart=true; //nothing to be done, as the load did not change // but we answer gently member->acceptInvite( sdpS->prepAcceptString( sdpS->getRealLoad() ,sdpS->getAudioHomePort(),sdpS->getSExtHomePort() ,false), MimeContentType( "application/sdp" ) ); return; } //we are on hold or received a renegotiate request : accept new INVITE // no codec at all if(loadT == SipCall::GarKeinCall) { if(debug >= 2) printf("=====KCallWidget callMemberStatusUpdated connected something inacceptable\n"); setLT("no valid session"); informPhoneView(UPDATEWLIST,myNumber); member->notAcceptableHere(); QMessageBox::information( this, "Can't accept call", "No accepted codec found." ); // retrieve or new media } else if(loadT< SipCall::putMeOnHold) { int callT = call->saveLoadType(loadT); // save the new CallState // if we are on hold, specific handling follows if( call->isHeld()) { //Call on Hold ? // Check if the resouurces are free call->onlyMeActive(sessionC->activeOnly(callT)); if( papa->countActiveCalls() > 0) { //someone else active if( sessionC->activeOnly(callT) || call->withAudioCall()) {//generalized with Flag or audio QMessageBox::information( this, "Can't accept call", "No resources" ); member->notAcceptableHere(); return; } } //Only Hold initiator may retrieve if(call->getHoldMaster() ){ member->acceptInvite( sdpS->prepAcceptString( call->getCallType() ,sdpS->getAudioHomePort() ,sdpS->getSExtHomePort() ,true), MimeContentType( "application/sdp" ) ); return; } } // we clean our payload if not yet done if( !call->isHeld() ) { detachFromCall(call); } call->setHoldCall(SipCall::callActive); //allow later holds setCS( member->getLocalStatusDescription() ); informPhoneView(UPDATEWLIST,myNumber); if ( call->withAudioCall() ) { // get new audio resources MyAuPort = QString::number(audio->audioOut(sdpS,myNumber )); sdpS->setAudioHomePort(MyAuPort); } if( call->withExtCall() ) { getExtSocket(call->getCallType()); MyPort = QString::number(KWsocket->getPortNumber()); sdpS->setExtHomePort(MyPort); if(sessionC->isStun() ) { auxPort=QString::number(getStunPort()); } else { auxPort = MyPort; } sdpS->setSExtHomePort(auxPort); } // send invite member->acceptInvite( sdpS->prepAcceptString( loadT ,MyAuPort,auxPort ,false), MimeContentType( "application/sdp" ) ); setLoadText(loadT); } else { // we are asked to put the call on hold if(call->getNoHold()) { //Hold forbidden ? QMessageBox::critical(this,"Hold", "Feature Call Hold not allowed,\n Call released."); member->notAcceptableHere(); return; } if(debug >= 2) printf(" accept Hold\n"); call->setHoldCall(SipCall::callHold); //we are a hold call crnbutton->setEnabled( false ); member->acceptInvite( sdpS->prepAcceptString( call->getCallType() ,sdpS->getAudioHomePort() ,sdpS->getSExtHomePort() ,true), MimeContentType( "application/sdp" ) ); if(redirTo==RdHoldActive) { //Hold SubCycle started by handleRefer if(debug >= 2) printf(" RdHoldActive\n" ); redirTo=RdHoldNo; detachFromCall(call); referTimer->start(referTime,TRUE); return; } else if(redirTo==RdHoldPassive) { //Hold SubCycle passive side if(debug >= 2) printf(" RdHoldPassive\n" ); member->setState(SipCallMember::state_r202); redirTo=RdHoldNo; } detachFromCall(call); }// ---------------------Member State r202} else if( member->getState() == SipCallMember::state_r202 ) { refnoti=call->getRefNoti(); if(debug >= 2) printf(" state r202, refnoti= %s\n",refnoti.latin1()); if( (call->loadCall()) && (refnoti != QString::null) ) { //we received a NOTIFY refer infostat->setText(refnoti); if(refnoti.contains("200")) { // New Session established, we may say good by (CT) or keep the session notiTimer->stop(); if(doTransfer) { if(debug >= 2) printf(" doTransfer\n"); doTransfer=false; hangupCall(); return; } QMessageBox mb( "Refer", "Session established You like to release? ",QMessageBox::Information, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, 0 ); if( mb.exec() == QMessageBox::Yes ) { hangupCall(); } else { if(call->isHeld()) { if( call->getHoldMaster() ) setCS( "Connected Hold" ); else setCS( "Connected Held" ); } else { setCS( "Connected" ); } informPhoneView(UPDATEWLIST,myNumber); hideCall(); return; } } else if(refnoti.contains("100") || refnoti.contains("180")){ // good Start //refresh notiTimer notiTimer->stop(); notiTimer->start(notiTime,TRUE); setCS( "CT ongoing" ); informPhoneView(UPDATEWLIST,myNumber); } else { if (notiTimer->isActive()) notiTimer->stop(); call->setRefNoti(QString::null); refnoti="none"; member->setState(SipCallMember::state_Connected); if(call->isHeld()) { if( call->getHoldMaster() ) setCS( "Connected Hold" ); else setCS( "Connected Held" ); } else { setCS( "Connected" ); } informPhoneView(UPDATEWLIST,myNumber); hideCall(); return; } } if(debug >= 2) printf(" state r202 nothing to do\n"); dial->setEnabled( false ); rstbutton->setEnabled( false ); hangup->setEnabled( true );// ---------------------Early dialog} else if( member->getState() == SipCallMember::state_EarlyDialog ) { int loadT = sdpS->checkCodec(false,member,false, &srtpErr); // check the 183 SDP-description if(debug >= 2)printf(" EarlyDialog %s loadT=%d",member->getLocalStatusDescription().latin1(),loadT); if ( (loadT > 0) && (earlyMedia == earlyNo) ) { //member->getLocalStatusDescription().contains("Bogus Session in progress") ) { earlyMedia=earlyCaller; if ( !call->withAudioCall() ) {//init audio for non-audio calls if(debug >= 2)printf(" ext Call\n"); dspe->startExt(sdpS->getRtpCodec(), sdpS->getRtpCodecNum(), KWsocket->getFileDescriptor(), sdpS->getExtHost(), sdpS->getAudioPort(), Sip::getLocalAddress(), sdpS->getExtHomePort() ); } else { if(debug >= 2)printf(" audio call \n"); //start rtp stream dspe->start(sdpS->getRtpCodec(), sdpS->getRtpCodecNum(), audio->getSocket(), sdpS->getExtHost(), sdpS->getAudioPort() ); } }// ---------------------The rest} else { if(debug >= 2) printf(" the rest %s\n",member->getLocalStatusDescription().latin1());}}void KCallWidget::createKeypad(void){ QGrid* grid; setOrientation(Qt::Vertical); grid = new QGrid(3); grid->setMargin(5);//30 grid->setLineWidth(1); grid->setFrameStyle(3); keypad = new QButtonGroup(3,Qt::Vertical); keypad->insert(new QPushButton("1 ", grid)); keypad->insert(new QPushButton("2 ABC", grid)); keypad->insert(new QPushButton("3 DEF", grid)); keypad->insert(new QPushButton("4 GHI", grid)); keypad->insert(new QPushButton("5 JKL", grid)); keypad->insert(new QPushButton("6 MNO", grid)); keypad->insert(new QPushButton("7 PQRS", grid)); keypad->insert(new QPushButton("8 TUV", grid)); keypad->insert(new QPushButton("9 WXYZ", grid)); keypad->insert(new QPushButton("* ", grid)); keypad->insert(new QPushButton("0 ", grid)); keypad->insert(new QPushButton("# ", grid)); connect(keypad, SIGNAL( pressed(int) ), this, SLOT( keypadPressed(int) )); connect(keypad, SIGNAL( released(int) ), this, SLOT( keypadReleased(int) )); setExtension(grid); //showExtension(true);}void KCallWidget::keypadPressed( int id ){ int tone = 0; switch(id) { case 0: tone = 1; break; case 1: tone = 2; break; case 2: tone = 3; break; case 3: tone = 4; break; case 4: tone = 5; break; case 5: tone = 6; break; case 6: tone = 7; break; case 7: tone = 8; break; case 8: tone = 9; break; case 9: tone = 10;break; case 10:tone = 0; break; case 11:tone = 11;break; } if (audio) { audio->startDTMF(tone); }}void KCallWidget::keypadReleased( int id ){ if (audio) audio->stopDTMF();}void KCallWidget::setRemote( QString newremote ){ remote->setEditText( newremote );}SipCall *KCallWidget::getCall(){ return call;}void KCallWidget::setLoadText (int load) {QString loadtext;int l;switch (load) { case (int)SipCall::extCall1 : case (int)SipCall::extCall2 : case (int)SipCall::extCall3 : case (int)SipCall::extCall4 : l=load-SipCall::extCall1+1; setLT ( "ext: " + QString::number(l)+ " " +sessionC->theVectorId(l) ); break; case (int)SipCall::StandardCall : loadtext = "audio:" + sdpS->getPrefCodec(); setLT(loadtext); break; case (int)SipCall::videoCall : loadtext = "video:" + sdpS->getVidPrefCodec(); setLT(loadtext); break; case (int)SipCall::auviCall : loadtext = "a+v:" + sdpS->getPrefCodec() + " " + sdpS->getVidPrefCodec(); setLT(loadtext); }}void KCallWidget::audioOutputDead( void ){ if(debug >= 2) printf( "=====KCallWidget: Broken output pipe, disconnecting unpolitely\n" ); forceDisconnect();}void KCallWidget::getUri( void ){ QSettings settings; QString p = KStatics::dBase + getUserPrefix() + "/Local"; QString xmlFile = settings.readEntry( p + "/PhoneBook", "" ); if( xmlFile.isEmpty() ) { if( getUserPrefix().isEmpty() ) { xmlFile = QDir::homeDirPath() + "/." + KStatics::xBase + "-phonebook.xml"; } else { xmlFile = QDir::homeDirPath() + "/." + KStatics::xBase + "_" + getUserPrefix() + "phonebook.xml"; } } QStringList r; if( !phoneBook ) { phoneBook = new PhoneBook(xmlFile, this, getUserPrefix() + "Phone Book", receivedCalls, missedCalls, dialledCalls, r ); } phoneBook->exec(); remote->setEditText( phoneBook->getUri() ); ((KPhoneView *)parentWidget())->updateContacts( xmlFile );}void KCallWidget::updateCallRegister( void ){ QString s, ss, s1, s2, s3; QTime t; QDate d; QString label; IncomingCall *c; IncomingCall *first; int count = 0; QSettings settings; QString p = KStatics::dBase + getUserPrefix() + "CallRegister/";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -