📄 kcallwidget.cpp
字号:
#include <stdlib.h>#include <sys/ioctl.h>#include <sys/soundcard.h>#include <sys/stat.h>#include <sys/time.h>#include <signal.h>#include <time.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <unistd.h>#include <fcntl.h>#include <math.h>#include <qbuttongroup.h>#include <qdatetime.h>#include <qdir.h>#include <qgrid.h>#include <qhbox.h>#include <qlabel.h>#include <qlayout.h>#include <qlineedit.h>#include <qmessagebox.h>#include <qpushbutton.h>#include <qsettings.h>#include <qtextedit.h>#include <qtimer.h>#include <qvbox.h>#include <qsound.h>#include "dspearly.h"#include "kcallwidget.h"#include "kphone.h"#include "kstatics.h"#include "kphoneview.h" #include "ksipauthentication.h"#include "sessioncontrol.h"#include "callaudio.h"#include "../dissipate2/mimecontenttype.h"#include "../dissipate2/sdpbuild.h"#include "../dissipate2/sipcall.h"#include "../dissipate2/sipmessage.h"#include "../dissipate2/siptransaction.h"#include "../dissipate2/sipuser.h"#include "../dissipate2/udpmessagesocket.h"KCallWidget::KCallWidget( KSipAuthentication *auth, SessionControl *sessioncontrol, SipCall *initcall, CallAudio *au, QWidget *parent, KPhoneView *Vater, KCallWidget *trfrom, int wNr, const char *name ) : QDialog( parent, name, FALSE, WStyle_NoBorder), call( initcall ) //WStyle_DialogBorder{ sipauthentication = auth; missedCalls.setAutoDelete( true ); receivedCalls.setAutoDelete( true ); dialledCalls.setAutoDelete( true ); hided = false; phoneBook = 0; curstate = PreDial; member = 0; shortTransfer=false; referdialog= 0; createKeypad(); audio = au; sessionC = sessioncontrol; papa=Vater; referedFrom=trfrom; referedNr= wNr; refnoti="none"; forceHold=false; dirFlag = "";// i or o KWsocket=0; call->setCurPid(0); redirTo=RdHoldNo; myNumber=papa->cntWidget(); MyIdentity(); referTo=""; dtmfSize = 0; dtmfStr = ""; doTransfer = false; preventSessionStart=false; earlyMedia = earlyNo; ringtonepid = 0; debug=KStatics::debugLevel; if(debug >=2) printf (":::::KCallWidget start Nummer %d\n",myNumber);//+++++++++++ the timer ringCount = 0; ringTimer = new QTimer(); connect( ringTimer, SIGNAL( timeout() ), this, SLOT( ringTimeout() ) ); notiTime=sessionC->getNotiExpires(); notiTimer = new QTimer(); connect( notiTimer, SIGNAL( timeout() ), this, SLOT( hangupCall() ) ); acceptCallTimer = new QTimer(); connect( acceptCallTimer, SIGNAL( timeout() ), this, SLOT( acceptCallTimeout() ) ); referTime = 500; referTimer = new QTimer(); connect( referTimer, SIGNAL( timeout() ), this, SLOT( handleRefer() ) );//+++++++++++++++ the dial field QVBoxLayout *vbox = new QVBoxLayout( this ); vbox->setMargin( 3 ); vbox->setSpacing( 3 ); QGridLayout *headergrid = new QGridLayout( 2, 3 ); headergrid->setSpacing( 2 ); vbox->insertLayout( 0, headergrid ); // Remote (person we're calling) QLabel *remotelabel = new QLabel( "Remote:", this ); remotelabel->setFixedWidth( remotelabel->fontMetrics().width( "Remote: " ) ); headergrid->addWidget( remotelabel, 0, 0 ); remote = new QComboBox( true, this ); remote->setAutoCompletion( true ); headergrid->addWidget( remote, 0, 1 ); // Remember to give remote completion int count = 0; QString s; QString remoteuri; QSettings settings; QString p = KStatics::dBase + getUserPrefix() + "CallRegister";/* QString label = p + "/Dialled" + s.setNum( count ); remoteuri = settings.readEntry( label, "" ); while( !remoteuri.isEmpty() && count < 20 ) { remote->insertItem( remoteuri ); label = p + "/Dialled" + s.setNum( ++count ); remoteuri = settings.readEntry( label, "" ); } */ QPushButton *loadUri = new QPushButton( "", this ); QIconSet icon; icon.setPixmap(SHARE_DIR "/icons/phonebook.png", QIconSet::Automatic ); loadUri->setIconSet( icon ); loadUri->setFixedWidth( loadUri->fontMetrics().maxWidth() * 2 ); connect( loadUri, SIGNAL( clicked() ), this, SLOT( getUri() ) ); headergrid->addWidget( loadUri, 0, 2 );//+++++++++++++++ Status Fields QHBox *statline = new QHBox( this ); statline->setSpacing( 5 ); vbox->insertWidget( 1, statline ); QLabel *statlabel = new QLabel( "CallStatus:", statline ); statlabel->setFixedWidth( remotelabel->width() ); curstat = new QLabel( statline ); QLabel *astatlabel = new QLabel( "AudioStatus:", statline ); astatlabel->setFixedWidth( remotelabel->width() ); curaudiostat = new QLabel( statline ); QLabel *aloadlabel = new QLabel( "Payload:", statline ); aloadlabel->setFixedWidth( remotelabel->width() ); curload = new QLabel( statline );//+++++++++++++++ Info Fields QHBox *infoline = new QHBox( this ); infoline->setSpacing( 5 ); vbox->insertWidget( 2, infoline ); QLabel *infolabel = new QLabel( infoline ); infostat = new QLabel( infoline ); infostat->setText(" No News"); infolabel->setText("Last Refer Info:");//+++++++++++++++++++ The action buttons QGrid *buttonbox = new QGrid(3, this ); //3 = #buttons per line buttonbox->setSpacing( 1 ); vbox->insertWidget( 3, buttonbox ); dial = new QPushButton( "Dial", buttonbox ); connect( dial, SIGNAL( clicked() ), this, SLOT(dialClicked() ) ); dial->setEnabled( true ); dial->setFocus(); rstbutton = new QPushButton( "Remote Start", buttonbox ); connect( rstbutton, SIGNAL( clicked() ),this, SLOT( rdialClicked())); rstbutton->setEnabled( true ); hangup = new QPushButton( "Hangup", buttonbox ); connect( hangup, SIGNAL( clicked() ), this, SLOT( hangupCall() ) ); hangup->setEnabled( false ); holdbutton = new QPushButton( "Hold", buttonbox ); connect( holdbutton, SIGNAL( clicked() ), this, SLOT( holdCall() ) ); holdbutton->setEnabled( false ); transferbutton = new QPushButton( "Transfer", buttonbox ); connect( transferbutton, SIGNAL( clicked() ), this, SLOT( showTransferDialog() ) ); transferbutton->setEnabled( false ); referbutton = new QPushButton( "Refer", buttonbox ); connect( referbutton, SIGNAL( clicked() ), this, SLOT( showReferDialog() ) ); referbutton->setEnabled( false ); crnbutton = new QPushButton( "+/-Video", buttonbox ); connect( crnbutton, SIGNAL( clicked() ),this, SLOT( renegCodec())); crnbutton->setEnabled( false ); hidebutton = new QPushButton( "Hide", buttonbox ); connect( hidebutton, SIGNAL( clicked() ), this, SLOT( hideCall() ) ); morebutton = new QPushButton( "DTMF", buttonbox ); morebutton->setToggleButton(true); morebutton->setOn( false ); connect( morebutton, SIGNAL( toggled(bool) ), this, SLOT( showExtension(bool)));//+++++++++++++++++++++++++++++ read the CallRegister QDateTime dt; int year,month,day,hour,min,sec; count = 0; QString label; p = KStatics::dBase + getUserPrefix() + "CallRegister"; label.setNum( count ); label = p + "/Received" + label; s = settings.readEntry( label, "" ); while( !s.isEmpty() ) { year = s.left( s.find( '.' ) ).toInt(); s = s.mid( s.find( '.' ) + 1 ); month = s.left( s.find( '.' ) ).toInt(); s = s.mid( s.find( '.' ) + 1 ); day = s.left( s.find( '-' ) ).toInt(); s = s.mid( s.find( '-' ) + 1 ); hour = s.left( s.find( ':' ) ).toInt(); s = s.mid( s.find( ':' ) + 1 ); min = s.left( s.find( ':' ) ).toInt(); s = s.mid( s.find( ':' ) + 1 ); sec = s.left( s.find( '[' ) ).toInt(); dt.setDate( QDate( year, month, day ) ); dt.setTime( QTime( hour, min, sec ) ); s = s.left( s.find( ']' ) ); s = s.mid( s.find( '[' ) + 1 ); incomingCall = new IncomingCall( s, dt ); receivedCalls.append( incomingCall ); label.setNum( ++count ); label = p + "/Received" + label; s = settings.readEntry( label, "" ); } count = 0; label.setNum( count ); label = p + "/Missed" + label; s = settings.readEntry( label, "" ); while( !s.isEmpty() ) { year = s.left( s.find( '.' ) ).toInt(); s = s.mid( s.find( '.' ) + 1 ); month = s.left( s.find( '.' ) ).toInt(); s = s.mid( s.find( '.' ) + 1 ); day = s.left( s.find( '-' ) ).toInt(); s = s.mid( s.find( '-' ) + 1 ); hour = s.left( s.find( ':' ) ).toInt(); s = s.mid( s.find( ':' ) + 1 ); min = s.left( s.find( ':' ) ).toInt(); s = s.mid( s.find( ':' ) + 1 ); sec = s.left( s.find( '[' ) ).toInt(); dt.setDate( QDate( year, month, day ) ); dt.setTime( QTime( hour, min, sec ) ); s = s.left( s.find( ']' ) ); s = s.mid( s.find( '[' ) + 1 ); incomingCall = new IncomingCall( s, dt ); missedCalls.append( incomingCall ); label.setNum( ++count ); label = p + "/Missed" + label; s = settings.readEntry( label, "" ); } count = 0; label.setNum( count ); label = p + "/Dialled" + label; s = settings.readEntry( label, "" ); while( !s.isEmpty() ) { year = s.left( s.find( '.' ) ).toInt(); s = s.mid( s.find( '.' ) + 1 ); month = s.left( s.find( '.' ) ).toInt(); s = s.mid( s.find( '.' ) + 1 ); day = s.left( s.find( '-' ) ).toInt(); s = s.mid( s.find( '-' ) + 1 ); hour = s.left( s.find( ':' ) ).toInt(); s = s.mid( s.find( ':' ) + 1 ); min = s.left( s.find( ':' ) ).toInt(); s = s.mid( s.find( ':' ) + 1 ); sec = s.left( s.find( '[' ) ).toInt(); dt.setDate( QDate( year, month, day ) ); dt.setTime( QTime( hour, min, sec ) ); s = s.left( s.find( ']' ) ); s = s.mid( s.find( '[' ) + 1 ); remote->insertItem( s ); incomingCall = new IncomingCall( s, dt ); dialledCalls.append( incomingCall ); label.setNum( ++count ); label = p + "/Dialled" + label; s = settings.readEntry( label, "" ); } QString sx, ssx, s1x, s2x, s3x; QTime t; QDate d; QDateTime t1=QDateTime::currentDateTime(); t = t1.time(); d = t1.date(); ssx = s1x.setNum( d.year() ) + "." + s2x.setNum( d.month() ) + "." + s3x.setNum( d.day() ) + "-" + t.toString() + "[" + "die URI" + "]";//Der SdpMessage-Container sdpS = new SdpBuild (sessionC, call);//If we are the refered A-Side, so to send Notification set a sigslot to old B-Side if(referedFrom) { connect(this,SIGNAL(sigTrNotify(QString)),referedFrom,SLOT(sendTrNotify(QString))); }// showExtension(true); setCS( "Start" ); //early media dspe = new DspEarly(); // Start Call Handling switchCall( initcall );}KCallWidget::~KCallWidget( void ){ if(debug >= 2) printf("\nR:::::KCallWidget end Nummer %d\n",myNumber); if(sdpS) delete sdpS; delete notiTimer; delete referTimer; delete ringTimer; delete acceptCallTimer; missedCalls.clear(); receivedCalls.clear(); dialledCalls.clear(); if( phoneBook ) { delete phoneBook; } if (keypad) { delete keypad; } if( call ) { delete call; call = 0; } if(audio) { audio->clearMe(myNumber); } if(KWsocket) { delete KWsocket; KWsocket = 0; } if(dspe) { delete dspe; dspe = 0; } if(referdialog) { delete referdialog; referdialog = 0; }}void KCallWidget::switchCall( SipCall *newcall ){ int callT=0, loadT=0; bool srtpErr = false; if(debug >= 2) printf( "=====KCallWidget:switchCall\n"); stopRinging(); call = newcall; dial->setText( "Dial" ); hangup->setText( "Hangup" ); if( member ) disconnect( member, 0, this, 0 ); member = call->getMemberList().toFirst();/* INCOMING CALL */ if( member ) { loadT = sdpS->checkCodec(false,member,isForceHold(),&srtpErr); callT = call->saveLoadType(loadT); if(debug >= 2) printf( "=====KCallWidget: Switching calls: incoming LoadType=%d CallType=%d\n",loadT,callT ); if(loadT==0){ // no PayLoad good bye curaudiostat->setText("no Audio"); curload->setText("No valid Session"); member->notAcceptableHere(); //QMessageBox::information( this, "Accept Call","Accepted codec not found." ); return; } dirFlag = "i"; if( member->getState() == SipCallMember::state_Disconnected ) { forceDisconnect(); return; } if( member->getState() == SipCallMember::state_Redirected ) { handleRedirect(); return; } setCS( member->getLocalStatusDescription() ); connect( member, SIGNAL( statusUpdated( SipCallMember * ) ), this, SLOT( callMemberStatusUpdated() ) ); setCaption( getUserPrefix() + QString( "Call: " ) + call->getCallId() ); if( call->getSubject() == "Incoming call" ) { setCaption( getUserPrefix() + QString( "I: " ) + call->getCallId() ); if( callT == SipCall::videoCall ) { setLT("video"); } else if( callT == SipCall::StandardCall ){ setLT("audio"); }else if( callT == SipCall::auviCall ) { setLT("audio+video"); } else if( call->isExtCall() ) { int l=loadT-SipCall::extCall1+1; setLT("ext: " + QString::number(l)+ sessionC->theVectorId((l))); } QString ss = member->getUri().uri(); QDateTime t = QDateTime::currentDateTime(); incomingCall = new IncomingCall( ss, t ); missedCalls.append( incomingCall ); updateCallRegister(); setCS( member->getLocalStatusDescription() ); informPhoneView(UPDATEWLIST,myNumber); // Ringing tone QSettings settings; QString p = KStatics::dBase+ getUserPrefix()+"/General/"; isRingingTone = sessionC ->getRinging(); ringCount = 0; ringTimer->start( ringTime_1, TRUE ); }// Modify Result if CLIR indicated ( sip:-) QString ss1 = member->getUri().uri(); if(ss1.contains("sip:-")) ss1 = "hallo from a stranger"; remote->setEditText(ss1); setCon(ss1); subject = call->getSubject(); hangup->setEnabled( true ); hangup->setFocus(); rstbutton->setEnabled( false ); dial->setEnabled( false ); rstbutton->setEnabled( false ); if( member->getState() == SipCallMember::state_InviteRequested ) { curstate = Calling; } else if( member->getState() == SipCallMember::state_RequestingInvite ) { dial->setText( "Accept" ); hangup->setText( "Reject" ); dial->setEnabled( true ); curstate = Called; } else { curstate = Connected; } // start the remoely triggered application if(call->isRemoteStart()) { if(sessionC->isRemoteStartAllowed(callT)){ emit clickDial( ); } else { forceDisconnect(); } }/* OUTGOING CALL */ } else { callT=(int)call->getCallType(); loadT = callT; curstat->setText( QString::null ); dirFlag = "o"; if(debug >= 2) printf( "=====KCallWidget: Switching calls: outgoing CallType = %d\n" , callT); setCaption( getUserPrefix() + QString( "O: " ) + call->getCallId() ); if( call->isExtCall()){ if( sessionC->isRemoteStartAllowed(callT) ) { rstbutton->setEnabled( true ); } else { rstbutton->setEnabled( false ); } } subject = call->getSubject(); remote->setEditText( QString::null ); dial->setEnabled( true ); dial->setFocus(); hangup->setEnabled( false ); curstate = PreDial; } }void KCallWidget::clickDial(){ dialClicked();}void KCallWidget::pleaseDial( const SipUri &dialuri ){ remote->setEditText( dialuri.reqUri() ); dialClicked();}void KCallWidget::rdialClicked( void ){ call->setRemoteStart(true); dialClicked();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -