2727/* Implementation *************************************************************/
2828CClient::CClient ( const quint16 iPortNumber,
2929 const quint16 iQosNumber,
30- const QString& strConnOnStartupAddress,
3130 const QString& strMIDISetup,
3231 const bool bNoAutoJackConnect,
3332 const QString& strNClientName,
@@ -184,13 +183,6 @@ CClient::CClient ( const quint16 iPortNumber,
184183 // start the socket (it is important to start the socket after all
185184 // initializations and connections)
186185 Socket.Start ();
187-
188- // do an immediate start if a server address is given
189- if ( !strConnOnStartupAddress.isEmpty () )
190- {
191- SetServerAddr ( strConnOnStartupAddress );
192- Start ();
193- }
194186}
195187
196188CClient::~CClient ()
@@ -337,7 +329,7 @@ void CClient::CreateServerJitterBufferMessage()
337329void CClient::OnCLPingReceived ( CHostAddress InetAddr, int iMs )
338330{
339331 // make sure we are running and the server address is correct
340- if ( IsRunning () && ( InetAddr == Channel.GetAddress () ) )
332+ if ( Channel. IsEnabled () && ( InetAddr == Channel.GetAddress () ) )
341333 {
342334 // take care of wrap arounds (if wrapping, do not use result)
343335 const int iCurDiff = EvaluatePingMessage ( iMs );
@@ -474,26 +466,6 @@ void CClient::StartDelayTimer()
474466 }
475467}
476468
477- bool CClient::SetServerAddr ( QString strNAddr )
478- {
479- CHostAddress HostAddress;
480- #ifdef CLIENT_NO_SRV_CONNECT
481- if ( NetworkUtil ().ParseNetworkAddress ( strNAddr, HostAddress, bEnableIPv6 ) )
482- #else
483- if ( NetworkUtil ().ParseNetworkAddressWithSrvDiscovery ( strNAddr, HostAddress, bEnableIPv6 ) )
484- #endif
485- {
486- // apply address to the channel
487- Channel.SetAddress ( HostAddress );
488-
489- return true ;
490- }
491- else
492- {
493- return false ; // invalid address
494- }
495- }
496-
497469bool CClient::GetAndResetbJitterBufferOKFlag ()
498470{
499471 // get the socket buffer put status flag and reset it
@@ -626,12 +598,16 @@ QString CClient::SetSndCrdDev ( const QString strNewDev )
626598 Sound.Start ();
627599 }
628600
629- // in case of an error inform the GUI about it
630601 if ( !strError.isEmpty () )
631602 {
632- emit SoundDeviceChanged ( strError );
603+ // due to error, disconnect
604+ Disconnect ();
633605 }
634606
607+ // in case of an error, this will inform the GUI about it
608+
609+ emit SoundDeviceChanged ();
610+
635611 return strError;
636612}
637613
@@ -758,8 +734,18 @@ void CClient::OnSndCrdReinitRequest ( int iSndCrdResetType )
758734 }
759735 MutexDriverReinit.unlock ();
760736
737+ if ( !strError.isEmpty () )
738+ {
739+ #ifndef HEADLESS
740+ QMessageBox::critical ( 0 , APP_NAME, strError, tr ( " Ok" ) );
741+ #else
742+ qCritical () << qUtf8Printable ( strError );
743+ exit ( 1 );
744+ #endif
745+ }
746+
761747 // inform GUI about the sound card device change
762- emit SoundDeviceChanged ( strError );
748+ emit SoundDeviceChanged ( );
763749}
764750
765751void CClient::OnHandledSignal ( int sigNum )
@@ -773,11 +759,8 @@ void CClient::OnHandledSignal ( int sigNum )
773759 {
774760 case SIGINT:
775761 case SIGTERM:
776- // if connected, terminate connection (needed for headless mode)
777- if ( IsRunning () )
778- {
779- Stop ();
780- }
762+ // if connected, terminate connection
763+ Disconnect ();
781764
782765 // this should trigger OnAboutToQuit
783766 QCoreApplication::instance ()->exit ();
@@ -862,50 +845,88 @@ void CClient::OnClientIDReceived ( int iChanID )
862845 emit ClientIDReceived ( iChanID );
863846}
864847
865- void CClient::Start ( )
848+ bool CClient::Connect ( QString strServerAddress, QString strServerName )
866849{
867- // init object
868- Init ();
850+ if ( !Channel.IsEnabled () )
851+ {
852+ CHostAddress HostAddress;
853+
854+ if ( NetworkUtil ().ParseNetworkAddress ( strServerAddress, HostAddress, bEnableIPv6 ) )
855+ {
856+ // init object
857+ Init ();
858+ // apply address to the channel
859+ Channel.SetAddress ( HostAddress );
869860
870- // enable channel
871- Channel.SetEnable ( true );
861+ // enable channel
862+ Channel.SetEnable ( true );
872863
873- // start audio interface
874- Sound.Start ();
864+ // start audio interface
865+ Sound.Start ();
866+
867+ // Notify ClientDlg
868+ emit Connecting ( strServerName );
869+
870+ return true ;
871+ }
872+ }
873+
874+ return false ;
875875}
876876
877- void CClient::Stop ()
877+ bool CClient::Disconnect ()
878878{
879- // stop audio interface
880- Sound.Stop ();
881-
882- // disable channel
883- Channel.SetEnable ( false );
884-
885- // wait for approx. 100 ms to make sure no audio packet is still in the
886- // network queue causing the channel to be reconnected right after having
887- // received the disconnect message (seems not to gain much, disconnect is
888- // still not working reliably)
889- QTime DieTime = QTime::currentTime ().addMSecs ( 100 );
890- while ( QTime::currentTime () < DieTime )
891- {
892- // exclude user input events because if we use AllEvents, it happens
893- // that if the user initiates a connection and disconnection quickly
894- // (e.g. quickly pressing enter five times), the software can get into
895- // an unknown state
896- QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 );
897- }
898-
899- // Send disconnect message to server (Since we disable our protocol
900- // receive mechanism with the next command, we do not evaluate any
901- // respond from the server, therefore we just hope that the message
902- // gets its way to the server, if not, the old behaviour time-out
903- // disconnects the connection anyway).
904- ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress () );
905-
906- // reset current signal level and LEDs
907- bJitterBufferOK = true ;
908- SignalLevelMeter.Reset ();
879+ if ( Channel.IsEnabled () )
880+ {
881+ // start disconnection
882+ Channel.Disconnect ();
883+
884+ // Channel.Disconnect() should automatically disable Channel as soon as disconnected.
885+ // Note that this only works if Sound is Active !
886+
887+ QTime DieTime = QTime::currentTime ().addMSecs ( 500 );
888+ while ( ( QTime::currentTime () < DieTime ) && Channel.IsEnabled () )
889+ {
890+ // exclude user input events because if we use AllEvents, it happens
891+ // that if the user initiates a connection and disconnection quickly
892+ // (e.g. quickly pressing enter five times), the software can get into
893+ // an unknown state
894+ QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 );
895+ }
896+
897+ // Now stop the audio interface
898+ Sound.Stop ();
899+
900+ // in case we timed out, log warning and make sure Channel is disabled
901+ if ( Channel.IsEnabled () )
902+ {
903+ Channel.SetEnable ( false );
904+ }
905+
906+ // Send disconnect message to server (Since we disable our protocol
907+ // receive mechanism with the next command, we do not evaluate any
908+ // respond from the server, therefore we just hope that the message
909+ // gets its way to the server, if not, the old behaviour time-out
910+ // disconnects the connection anyway).
911+ ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress () );
912+
913+ // reset current signal level and LEDs
914+ bJitterBufferOK = true ;
915+ SignalLevelMeter.Reset ();
916+
917+ emit Disconnected ();
918+
919+ return true ;
920+ }
921+ else
922+ {
923+ // make sure sound is stopped too
924+ Sound.Stop ();
925+
926+ emit Disconnected ();
927+
928+ return false ;
929+ }
909930}
910931
911932void CClient::Init ()
@@ -921,7 +942,7 @@ void CClient::Init()
921942 bFraSiFactSafeSupported = true ;
922943#else
923944 bFraSiFactPrefSupported = ( Sound.Init ( iFraSizePreffered ) == iFraSizePreffered );
924- bFraSiFactDefSupported = ( Sound.Init ( iFraSizeDefault ) == iFraSizeDefault );
945+ bFraSiFactDefSupported = ( Sound.Init ( iFraSizeDefault ) == iFraSizeDefault );
925946 bFraSiFactSafeSupported = ( Sound.Init ( iFraSizeSafe ) == iFraSizeSafe );
926947#endif
927948
0 commit comments