-
Notifications
You must be signed in to change notification settings - Fork 238
Fix connection status issue (#2519) #3364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
38fb414
a5af8cc
535f781
21815c1
d7b4b8b
66edab5
49402c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,7 @@ CChannel::CChannel ( const bool bNIsServer ) : | |
| bIsEnabled ( false ), | ||
| bIsServer ( bNIsServer ), | ||
| bIsIdentified ( false ), | ||
| bDisconnectAndDisable ( false ), | ||
| iAudioFrameSizeSamples ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ), | ||
| SignalLevelMeter ( false, 0.5 ) // server mode with mono out and faster smoothing | ||
| { | ||
|
|
@@ -125,7 +126,8 @@ void CChannel::SetEnable ( const bool bNEnStat ) | |
| QMutexLocker locker ( &Mutex ); | ||
|
|
||
| // set internal parameter | ||
| bIsEnabled = bNEnStat; | ||
| bIsEnabled = bNEnStat; | ||
| bDisconnectAndDisable = false; | ||
|
|
||
| // The support for the packet sequence number must be reset if the client | ||
| // disconnects from a server since we do not yet know if the next server we | ||
|
|
@@ -506,11 +508,24 @@ void CChannel::Disconnect() | |
| // we only have to disconnect the channel if it is actually connected | ||
| if ( IsConnected() ) | ||
| { | ||
| // for a Client, block further audio data and disable the channel as soon as Disconnect() is called | ||
| // TODO: Add reasoning from #2550 | ||
|
|
||
| bDisconnectAndDisable = !bIsServer; | ||
|
|
||
| // set time out counter to a small value > 0 so that the next time a | ||
| // received audio block is queried, the disconnection is performed | ||
| // (assuming that no audio packet is received in the meantime) | ||
| iConTimeOut = 1; // a small number > 0 | ||
| } | ||
| else if ( !bIsServer ) | ||
| { | ||
| // For clients (?) set defaults | ||
|
|
||
| bDisconnectAndDisable = false; | ||
| bIsEnabled = false; | ||
| iConTimeOut = 0; | ||
| } | ||
| } | ||
|
|
||
| void CChannel::PutProtocolData ( const int iRecCounter, const int iRecID, const CVector<uint8_t>& vecbyMesBodyData, const CHostAddress& RecHostAddr ) | ||
|
|
@@ -534,7 +549,7 @@ EPutDataStat CChannel::PutAudioData ( const CVector<uint8_t>& vecbyData, const i | |
| // Only process audio data if: | ||
| // - for client only: the packet comes from the server we want to talk to | ||
| // - the channel is enabled | ||
| if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() ) | ||
| if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() && !bDisconnectAndDisable ) | ||
| { | ||
| MutexSocketBuf.lock(); | ||
| { | ||
|
|
@@ -622,6 +637,11 @@ EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData, const int iNumByte | |
| eGetStatus = GS_CHAN_NOW_DISCONNECTED; | ||
| iConTimeOut = 0; // make sure we do not have negative values | ||
|
|
||
| if ( bDisconnectAndDisable ) | ||
| { | ||
| bDisconnectAndDisable = false; | ||
| bIsEnabled = false; | ||
| } | ||
| // reset network transport properties | ||
| ResetNetworkTransportProperties(); | ||
| } | ||
|
|
@@ -643,6 +663,13 @@ EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData, const int iNumByte | |
| { | ||
| // channel is disconnected | ||
| eGetStatus = GS_CHAN_NOT_CONNECTED; | ||
|
|
||
| if ( bDisconnectAndDisable ) | ||
ann0see marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| bDisconnectAndDisable = false; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ??! So these get set to the same values whether |
||
| bIsEnabled = false; | ||
| iConTimeOut = 0; | ||
| } | ||
| } | ||
| } | ||
| MutexSocketBuf.unlock(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,7 +76,7 @@ class CChannel : public QObject | |
|
|
||
| void PrepAndSendPacket ( CHighPrioSocket* pSocket, const CVector<uint8_t>& vecbyNPacket, const int iNPacketLen ); | ||
|
|
||
| void ResetTimeOutCounter() { iConTimeOut = iConTimeOutStartVal; } | ||
| void ResetTimeOutCounter() { iConTimeOut = bDisconnectAndDisable ? 1 : iConTimeOutStartVal; } | ||
|
||
| bool IsConnected() const { return iConTimeOut > 0; } | ||
| void Disconnect(); | ||
|
|
||
|
|
@@ -216,6 +216,7 @@ class CChannel : public QObject | |
| bool bIsEnabled; | ||
| bool bIsServer; | ||
| bool bIsIdentified; | ||
| bool bDisconnectAndDisable; | ||
|
|
||
| int iNetwFrameSizeFact; | ||
| int iNetwFrameSize; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,7 +27,6 @@ | |
| /* Implementation *************************************************************/ | ||
| CClient::CClient ( const quint16 iPortNumber, | ||
| const quint16 iQosNumber, | ||
| const QString& strConnOnStartupAddress, | ||
| const QString& strMIDISetup, | ||
| const bool bNoAutoJackConnect, | ||
| const QString& strNClientName, | ||
|
|
@@ -184,13 +183,6 @@ CClient::CClient ( const quint16 iPortNumber, | |
| // start the socket (it is important to start the socket after all | ||
| // initializations and connections) | ||
| Socket.Start(); | ||
|
|
||
| // do an immediate start if a server address is given | ||
| if ( !strConnOnStartupAddress.isEmpty() ) | ||
| { | ||
| SetServerAddr ( strConnOnStartupAddress ); | ||
| Start(); | ||
| } | ||
ann0see marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| CClient::~CClient() | ||
|
|
@@ -337,7 +329,7 @@ void CClient::CreateServerJitterBufferMessage() | |
| void CClient::OnCLPingReceived ( CHostAddress InetAddr, int iMs ) | ||
| { | ||
| // make sure we are running and the server address is correct | ||
| if ( IsRunning() && ( InetAddr == Channel.GetAddress() ) ) | ||
| if ( Channel.IsEnabled() && ( InetAddr == Channel.GetAddress() ) ) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't about the channel being enabled. It's about whether the client is running. It's a different intent.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the initial PR confused active channel and active client: #2550 (comment) This difference needs documentation. IMO: Add (like for JSON-RPC) respective technical documentation before the respective methods. As end goal: Write them for every function, for now: Write docs while changing. |
||
| { | ||
| // take care of wrap arounds (if wrapping, do not use result) | ||
| const int iCurDiff = EvaluatePingMessage ( iMs ); | ||
|
|
@@ -474,26 +466,6 @@ void CClient::StartDelayTimer() | |
| } | ||
| } | ||
|
|
||
| bool CClient::SetServerAddr ( QString strNAddr ) | ||
ann0see marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| CHostAddress HostAddress; | ||
| #ifdef CLIENT_NO_SRV_CONNECT | ||
| if ( NetworkUtil().ParseNetworkAddress ( strNAddr, HostAddress, bEnableIPv6 ) ) | ||
| #else | ||
| if ( NetworkUtil().ParseNetworkAddressWithSrvDiscovery ( strNAddr, HostAddress, bEnableIPv6 ) ) | ||
| #endif | ||
| { | ||
| // apply address to the channel | ||
| Channel.SetAddress ( HostAddress ); | ||
|
|
||
| return true; | ||
| } | ||
| else | ||
| { | ||
| return false; // invalid address | ||
| } | ||
| } | ||
|
|
||
| bool CClient::GetAndResetbJitterBufferOKFlag() | ||
| { | ||
| // get the socket buffer put status flag and reset it | ||
|
|
@@ -626,12 +598,16 @@ QString CClient::SetSndCrdDev ( const QString strNewDev ) | |
| Sound.Start(); | ||
| } | ||
|
|
||
| // in case of an error inform the GUI about it | ||
| if ( !strError.isEmpty() ) | ||
| { | ||
| emit SoundDeviceChanged ( strError ); | ||
| // due to error, disconnect | ||
| Disconnect(); | ||
ann0see marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // in case of an error, this will inform the GUI about it | ||
|
|
||
| emit SoundDeviceChanged(); | ||
ann0see marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| return strError; | ||
| } | ||
|
|
||
|
|
@@ -758,8 +734,18 @@ void CClient::OnSndCrdReinitRequest ( int iSndCrdResetType ) | |
| } | ||
| MutexDriverReinit.unlock(); | ||
|
|
||
| if ( !strError.isEmpty() ) | ||
| { | ||
| #ifndef HEADLESS | ||
| QMessageBox::critical ( 0, APP_NAME, strError, tr ( "Ok" ) ); | ||
| #else | ||
| qCritical() << qUtf8Printable ( strError ); | ||
ann0see marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| exit ( 1 ); | ||
| #endif | ||
| } | ||
|
|
||
| // inform GUI about the sound card device change | ||
| emit SoundDeviceChanged ( strError ); | ||
| emit SoundDeviceChanged(); | ||
ann0see marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| void CClient::OnHandledSignal ( int sigNum ) | ||
|
|
@@ -773,11 +759,8 @@ void CClient::OnHandledSignal ( int sigNum ) | |
| { | ||
| case SIGINT: | ||
| case SIGTERM: | ||
| // if connected, terminate connection (needed for headless mode) | ||
| if ( IsRunning() ) | ||
| { | ||
| Stop(); | ||
| } | ||
| // if connected, terminate connection | ||
| Disconnect(); | ||
|
|
||
| // this should trigger OnAboutToQuit | ||
| QCoreApplication::instance()->exit(); | ||
|
|
@@ -862,50 +845,88 @@ void CClient::OnClientIDReceived ( int iChanID ) | |
| emit ClientIDReceived ( iChanID ); | ||
| } | ||
|
|
||
| void CClient::Start() | ||
| bool CClient::Connect ( QString strServerAddress, QString strServerName ) | ||
ann0see marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| // init object | ||
| Init(); | ||
| if ( !Channel.IsEnabled() ) | ||
| { | ||
| CHostAddress HostAddress; | ||
|
|
||
| if ( NetworkUtil().ParseNetworkAddress ( strServerAddress, HostAddress, bEnableIPv6 ) ) | ||
| { | ||
| // init object | ||
| Init(); | ||
| // apply address to the channel | ||
| Channel.SetAddress ( HostAddress ); | ||
|
|
||
| // enable channel | ||
| Channel.SetEnable ( true ); | ||
| // enable channel | ||
| Channel.SetEnable ( true ); | ||
|
|
||
| // start audio interface | ||
| Sound.Start(); | ||
| // start audio interface | ||
| Sound.Start(); | ||
|
|
||
| // Notify ClientDlg | ||
| emit Connecting ( strServerName ); | ||
|
|
||
| return true; | ||
| } | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| void CClient::Stop() | ||
| bool CClient::Disconnect() | ||
| { | ||
| // stop audio interface | ||
| Sound.Stop(); | ||
|
|
||
| // disable channel | ||
| Channel.SetEnable ( false ); | ||
|
|
||
| // wait for approx. 100 ms to make sure no audio packet is still in the | ||
| // network queue causing the channel to be reconnected right after having | ||
| // received the disconnect message (seems not to gain much, disconnect is | ||
| // still not working reliably) | ||
| QTime DieTime = QTime::currentTime().addMSecs ( 100 ); | ||
| while ( QTime::currentTime() < DieTime ) | ||
| { | ||
| // exclude user input events because if we use AllEvents, it happens | ||
| // that if the user initiates a connection and disconnection quickly | ||
| // (e.g. quickly pressing enter five times), the software can get into | ||
| // an unknown state | ||
| QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); | ||
| } | ||
|
|
||
| // Send disconnect message to server (Since we disable our protocol | ||
| // receive mechanism with the next command, we do not evaluate any | ||
| // respond from the server, therefore we just hope that the message | ||
| // gets its way to the server, if not, the old behaviour time-out | ||
| // disconnects the connection anyway). | ||
| ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); | ||
|
|
||
| // reset current signal level and LEDs | ||
| bJitterBufferOK = true; | ||
| SignalLevelMeter.Reset(); | ||
| if ( Channel.IsEnabled() ) | ||
| { | ||
| // start disconnection | ||
| Channel.Disconnect(); | ||
|
|
||
| // Channel.Disconnect() should automatically disable Channel as soon as disconnected. | ||
| // Note that this only works if Sound is Active ! | ||
|
|
||
| QTime DieTime = QTime::currentTime().addMSecs ( 500 ); | ||
| while ( ( QTime::currentTime() < DieTime ) && Channel.IsEnabled() ) | ||
| { | ||
| // exclude user input events because if we use AllEvents, it happens | ||
| // that if the user initiates a connection and disconnection quickly | ||
| // (e.g. quickly pressing enter five times), the software can get into | ||
| // an unknown state | ||
| QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); | ||
| } | ||
|
|
||
| // Now stop the audio interface | ||
| Sound.Stop(); | ||
|
|
||
| // in case we timed out, log warning and make sure Channel is disabled | ||
| if ( Channel.IsEnabled() ) | ||
| { | ||
| Channel.SetEnable ( false ); | ||
| } | ||
|
|
||
| // Send disconnect message to server (Since we disable our protocol | ||
| // receive mechanism with the next command, we do not evaluate any | ||
| // respond from the server, therefore we just hope that the message | ||
| // gets its way to the server, if not, the old behaviour time-out | ||
| // disconnects the connection anyway). | ||
| ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); | ||
|
|
||
| // reset current signal level and LEDs | ||
| bJitterBufferOK = true; | ||
| SignalLevelMeter.Reset(); | ||
|
|
||
| emit Disconnected(); | ||
|
|
||
| return true; | ||
| } | ||
| else | ||
| { | ||
| // make sure sound is stopped too | ||
| Sound.Stop(); | ||
|
|
||
| emit Disconnected(); | ||
|
|
||
| return false; | ||
| } | ||
| } | ||
|
|
||
| void CClient::Init() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,7 +110,6 @@ class CClient : public QObject | |
| public: | ||
| CClient ( const quint16 iPortNumber, | ||
| const quint16 iQosNumber, | ||
| const QString& strConnOnStartupAddress, | ||
| const QString& strMIDISetup, | ||
| const bool bNoAutoJackConnect, | ||
| const QString& strNClientName, | ||
|
|
@@ -119,17 +118,17 @@ class CClient : public QObject | |
|
|
||
| virtual ~CClient(); | ||
|
|
||
| void Start(); | ||
| void Stop(); | ||
| bool Connect ( QString strServerAddress, QString strServerName ); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does make sense to introduce an easy to call Connect() and Disconnect() method IMO, so this is good.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having these in
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree. That's issue #3367
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Factored out into #3372 |
||
| bool Disconnect(); | ||
|
|
||
| bool IsRunning() { return Sound.IsRunning(); } | ||
| bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } | ||
| bool SetServerAddr ( QString strNAddr ); | ||
| bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } // For OnTimerCheckAudioDeviceOk only | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reverted naming. May need some in depth review and discussion. |
||
|
|
||
| double GetLevelForMeterdBLeft() { return SignalLevelMeter.GetLevelForMeterdBLeftOrMono(); } | ||
| double GetLevelForMeterdBRight() { return SignalLevelMeter.GetLevelForMeterdBRight(); } | ||
|
|
||
| bool GetAndResetbJitterBufferOKFlag(); | ||
|
|
||
| bool IsConnected() { return Channel.IsConnected(); } | ||
|
|
||
| EGUIDesign GetGUIDesign() const { return eGUIDesign; } | ||
|
|
@@ -427,8 +426,9 @@ protected slots: | |
|
|
||
| void CLChannelLevelListReceived ( CHostAddress InetAddr, CVector<uint16_t> vecLevelList ); | ||
|
|
||
| void Connecting ( QString strServerName ); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably a missing slot. |
||
| void Disconnected(); | ||
| void SoundDeviceChanged ( QString strError ); | ||
| void SoundDeviceChanged(); | ||
|
||
| void ControllerInFaderLevel ( int iChannelIdx, int iValue ); | ||
| void ControllerInPanValue ( int iChannelIdx, int iValue ); | ||
| void ControllerInFaderIsSolo ( int iChannelIdx, bool bIsSolo ); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.