From 4791cd7f0d20a92e4bbc690df6c8e1f61722e6ae Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sun, 6 Sep 2020 18:58:05 +0200 Subject: [PATCH 01/13] backup checkin, does not work, contains a lot of ugly test code... --- src/protocol.cpp | 245 +++++++++++++++++++++++++++++++++++++---------- src/protocol.h | 13 +++ 2 files changed, 205 insertions(+), 53 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index 5ab9b925f2..55351c7035 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -51,6 +51,19 @@ MAIN FRAME +SPLIT MESSAGE CONTAINER +----------------------- + + +------------+------------------------+------------------+--------------+ + | 2 bytes ID | 1 byte number of parts | 1 byte split cnt | n bytes data | + +------------+------------------------+------------------+--------------+ + +- ID is the message ID of the message being split +- split cnt is the counter which is incremented for each part of the message +- data is the data part of the original message which were split + + + MESSAGES (with connection) -------------------------- @@ -406,6 +419,20 @@ CONNECTION LESS MESSAGES /* Implementation *************************************************************/ CProtocol::CProtocol() { + + +// TEST +const int iMaxNumParts = 25; +iPartSize = 100; +vecvecbySplitMessageStorage.Init ( iMaxNumParts ); + +for ( int i = 0; i < iMaxNumParts; i++ ) +{ + vecvecbySplitMessageStorage[i].Init( iPartSize ); +} + + + Reset(); @@ -506,12 +533,37 @@ void CProtocol::CreateAndSendMessage ( const int iID, } Mutex.unlock(); + +// TODO insert split mechanism here +// TODO make use of MAX_SIZE_BYTES_NETW_BUF + +// TEST split all messages by half for testing +if ( vecData.Size() > iPartSize ) +{ + const int iNumParts = static_cast ( ceil ( static_cast ( vecData.Size() ) / iPartSize ) ); + + for ( int iPartCnt = 0; iPartCnt < iNumParts; iPartCnt++ ) + { + +// TODO +// vecData + + // build complete message + GenMessageFrame ( vecNewMessage, iCurCounter, iID, vecData ); + + // enqueue message + EnqueueMessage ( vecNewMessage, iCurCounter, iID ); + } +} +else +{ // build complete message GenMessageFrame ( vecNewMessage, iCurCounter, iID, vecData ); // enqueue message EnqueueMessage ( vecNewMessage, iCurCounter, iID ); } +} void CProtocol::CreateAndImmSendAcknMess ( const int& iID, const int& iCnt ) @@ -614,76 +666,129 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false; } else { - // check which type of message we received and do action - switch ( iRecID ) + +// TODO better solution: do not copy message +CVector vecbyMesBodyDataModified = vecbyMesBodyData; + + + bool bEvaluateMessage = true; + + // check for special ID first + if ( iRecID == PROTMESSID_SPECIAL_SPLIT_MESSAGE ) { - case PROTMESSID_JITT_BUF_SIZE: - bRet = EvaluateJitBufMes ( vecbyMesBodyData ); - break; + int iOriginalID; + int iReceivedNumParts; + int iReceivedSplitCnt; - case PROTMESSID_REQ_JITT_BUF_SIZE: - bRet = EvaluateReqJitBufMes(); - break; + ParseSplitMessageContainer ( vecbyMesBodyData, + vecvecbySplitMessageStorage[iSplitMessageCnt], + iOriginalID, + iReceivedNumParts, + iReceivedSplitCnt ); - case PROTMESSID_CLIENT_ID: - bRet = EvaluateClientIDMes ( vecbyMesBodyData ); - break; +// TODO implement some checks of counters, etc. here - case PROTMESSID_CHANNEL_GAIN: - bRet = EvaluateChanGainMes ( vecbyMesBodyData ); - break; +// TEST assuming everything is ok + iSplitMessageCnt++; - case PROTMESSID_CHANNEL_PAN: - bRet = EvaluateChanPanMes ( vecbyMesBodyData ); - break; + if ( iSplitMessageCnt == iReceivedNumParts ) + { +// quick hack test!!! + vecbyMesBodyDataModified.Reset ( 0 ); - case PROTMESSID_MUTE_STATE_CHANGED: - bRet = EvaluateMuteStateHasChangedMes ( vecbyMesBodyData ); - break; + for ( int i = 0; i < iReceivedNumParts; i++ ) + { +// quick hack test!!! + for ( int j = 0; j < vecvecbySplitMessageStorage[i].Size(); j++ ) + { + vecbyMesBodyDataModified.Add ( vecvecbySplitMessageStorage[i][j] ); + } + } + } + else + { + bEvaluateMessage = false; + } + } + else + { +// TEST +iSplitMessageCnt = 0; + } + + if ( bEvaluateMessage ) + { + // check which type of message we received and do action + switch ( iRecID ) + { + case PROTMESSID_JITT_BUF_SIZE: + bRet = EvaluateJitBufMes ( vecbyMesBodyDataModified ); + break; + + case PROTMESSID_REQ_JITT_BUF_SIZE: + bRet = EvaluateReqJitBufMes(); + break; + + case PROTMESSID_CLIENT_ID: + bRet = EvaluateClientIDMes ( vecbyMesBodyDataModified ); + break; - case PROTMESSID_CONN_CLIENTS_LIST: - bRet = EvaluateConClientListMes ( vecbyMesBodyData ); - break; + case PROTMESSID_CHANNEL_GAIN: + bRet = EvaluateChanGainMes ( vecbyMesBodyDataModified ); + break; - case PROTMESSID_REQ_CONN_CLIENTS_LIST: - bRet = EvaluateReqConnClientsList(); - break; + case PROTMESSID_CHANNEL_PAN: + bRet = EvaluateChanPanMes ( vecbyMesBodyDataModified ); + break; - case PROTMESSID_CHANNEL_INFOS: - bRet = EvaluateChanInfoMes ( vecbyMesBodyData ); - break; + case PROTMESSID_MUTE_STATE_CHANGED: + bRet = EvaluateMuteStateHasChangedMes ( vecbyMesBodyDataModified ); + break; - case PROTMESSID_REQ_CHANNEL_INFOS: - bRet = EvaluateReqChanInfoMes(); - break; + case PROTMESSID_CONN_CLIENTS_LIST: + bRet = EvaluateConClientListMes ( vecbyMesBodyDataModified ); + break; - case PROTMESSID_CHAT_TEXT: - bRet = EvaluateChatTextMes ( vecbyMesBodyData ); - break; + case PROTMESSID_REQ_CONN_CLIENTS_LIST: + bRet = EvaluateReqConnClientsList(); + break; - case PROTMESSID_NETW_TRANSPORT_PROPS: - bRet = EvaluateNetwTranspPropsMes ( vecbyMesBodyData ); - break; + case PROTMESSID_CHANNEL_INFOS: + bRet = EvaluateChanInfoMes ( vecbyMesBodyDataModified ); + break; - case PROTMESSID_REQ_NETW_TRANSPORT_PROPS: - bRet = EvaluateReqNetwTranspPropsMes(); - break; + case PROTMESSID_REQ_CHANNEL_INFOS: + bRet = EvaluateReqChanInfoMes(); + break; - case PROTMESSID_LICENCE_REQUIRED: - bRet = EvaluateLicenceRequiredMes ( vecbyMesBodyData ); - break; + case PROTMESSID_CHAT_TEXT: + bRet = EvaluateChatTextMes ( vecbyMesBodyDataModified ); + break; - case PROTMESSID_REQ_CHANNEL_LEVEL_LIST: - bRet = EvaluateReqChannelLevelListMes ( vecbyMesBodyData ); - break; + case PROTMESSID_NETW_TRANSPORT_PROPS: + bRet = EvaluateNetwTranspPropsMes ( vecbyMesBodyDataModified ); + break; - case PROTMESSID_VERSION_AND_OS: - bRet = EvaluateVersionAndOSMes ( vecbyMesBodyData ); - break; + case PROTMESSID_REQ_NETW_TRANSPORT_PROPS: + bRet = EvaluateReqNetwTranspPropsMes(); + break; - case PROTMESSID_RECORDER_STATE: - bRet = EvaluateRecorderStateMes ( vecbyMesBodyData ); - break; + case PROTMESSID_LICENCE_REQUIRED: + bRet = EvaluateLicenceRequiredMes ( vecbyMesBodyDataModified ); + break; + + case PROTMESSID_REQ_CHANNEL_LEVEL_LIST: + bRet = EvaluateReqChannelLevelListMes ( vecbyMesBodyDataModified ); + break; + + case PROTMESSID_VERSION_AND_OS: + bRet = EvaluateVersionAndOSMes ( vecbyMesBodyDataModified ); + break; + + case PROTMESSID_RECORDER_STATE: + bRet = EvaluateRecorderStateMes ( vecbyMesBodyDataModified ); + break; + } } // immediately send acknowledge message @@ -2644,6 +2749,40 @@ bool CProtocol::ParseMessageFrame ( const CVector& vecbyData, return false; // no error } +void CProtocol::ParseSplitMessageContainer ( const CVector& vecbyData, + CVector& vecbyMesBodyData, + int& iID, + int& iNumParts, + int& iSplitCnt ) +{ + int iPos = 0; // init position pointer + const int iDataLen = vecbyData.Size(); + + // 2 bytes ID + iID = static_cast ( GetValFromStream ( vecbyData, iPos, 2 ) ); + + // 1 byte number of parts + iNumParts = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); + + // 1 byte split cnt + iSplitCnt = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); + + + // Extract actual data ----------------------------------------------------- + + const int iLenBy = iDataLen - 4; + +// TODO this memory allocation is done in the real time thread but should be +// done in the low priority protocol management thread + + vecbyMesBodyData.Init ( iLenBy ); + + for ( int i = 0; i < iLenBy; i++ ) + { + vecbyMesBodyData[i] = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); + } +} + uint32_t CProtocol::GetValFromStream ( const CVector& vecIn, int& iPos, const int iNumOfBytes ) diff --git a/src/protocol.h b/src/protocol.h index f9ea11aa83..cb101ec768 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -81,6 +81,9 @@ #define PROTMESSID_CLM_REGISTER_SERVER_RESP 1016 // status of server registration request #define PROTMESSID_CLM_REGISTER_SERVER_EX 1017 // register server with extended information +// special IDs +#define PROTMESSID_SPECIAL_SPLIT_MESSAGE 2001 // a container for split messages + // lengths of message as defined in protocol.cpp file #define MESS_HEADER_LENGTH_BYTE 7 // TAG (2), ID (2), cnt (1), length (2) #define MESS_LEN_WITHOUT_DATA_BYTE ( MESS_HEADER_LENGTH_BYTE + 2 /* CRC (2) */ ) @@ -202,6 +205,12 @@ class CProtocol : public QObject const int iID, const CVector& vecData ); + void ParseSplitMessageContainer ( const CVector& vecbyData, + CVector& vecbyMesBodyData, + int& iID, + int& iNumParts, + int& iSplitCnt ); + void PutValOnStream ( CVector& vecIn, int& iPos, const uint32_t iVal, @@ -283,6 +292,10 @@ class CProtocol : public QObject QTimer TimerSendMess; QMutex Mutex; + CVector > vecvecbySplitMessageStorage; + int iSplitMessageCnt; + int iPartSize; + public slots: void OnTimerSendMess() { SendMessage(); } From 270a5c3952c2da1e5d3f5b3f2125068510c7c1c3 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sun, 6 Sep 2020 21:56:50 +0200 Subject: [PATCH 02/13] first working proof of concept version of splitting large protocol messages (a lot of bad and quick hack code present which has to be cleaned up) --- src/protocol.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++---- src/protocol.h | 6 +++++ 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index 55351c7035..7d0a34fe17 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -422,8 +422,8 @@ CProtocol::CProtocol() // TEST -const int iMaxNumParts = 25; -iPartSize = 100; +const int iMaxNumParts = 200;//25; +iPartSize = 600; vecvecbySplitMessageStorage.Init ( iMaxNumParts ); for ( int i = 0; i < iMaxNumParts; i++ ) @@ -537,16 +537,38 @@ void CProtocol::CreateAndSendMessage ( const int iID, // TODO insert split mechanism here // TODO make use of MAX_SIZE_BYTES_NETW_BUF +CVector vecDataTmp; +int iPointer = 0; + // TEST split all messages by half for testing if ( vecData.Size() > iPartSize ) { const int iNumParts = static_cast ( ceil ( static_cast ( vecData.Size() ) / iPartSize ) ); - for ( int iPartCnt = 0; iPartCnt < iNumParts; iPartCnt++ ) +//qDebug() << iNumParts; + + for ( int iSplitCnt = 0; iSplitCnt < iNumParts; iSplitCnt++ ) { + int iCurPartSize = iPartSize; + + if ( vecData.Size() - iPointer < iPartSize ) + { + iCurPartSize = vecData.Size() - iPointer; + } + +vecDataTmp.Init ( iCurPartSize ); + +for ( int i = 0; i < iCurPartSize; i++ ) +{ + vecDataTmp[i] = vecData[iPointer + i]; +} +iPointer += iCurPartSize; -// TODO -// vecData + GenSplitMessageContainer ( vecNewMessage, + iID, + iNumParts, + iSplitCnt, + vecDataTmp ); // build complete message GenMessageFrame ( vecNewMessage, iCurCounter, iID, vecData ); @@ -2905,6 +2927,40 @@ void CProtocol::GenMessageFrame ( CVector& vecOut, PutValOnStream ( vecOut, iCurPos, static_cast ( CRCObj.GetCRC() ), 2 ); } + +void CProtocol::GenSplitMessageContainer ( CVector& vecOut, + const int iID, + const int iNumParts, + const int iSplitCnt, + const CVector& vecData ) +{ + int iPos = 0; // init position pointer + + // query length of data vector + const int iDataLenByte = vecData.Size(); + + // total length of message + const int iTotLenByte = 4 + iDataLenByte; + + // init message vector + vecOut.Init ( iTotLenByte ); + + // 2 bytes ID + PutValOnStream ( vecOut, iPos, static_cast ( iID ), 2 ); + + // 1 byte number of parts + PutValOnStream ( vecOut, iPos, static_cast ( iNumParts ), 1 ); + + // 1 byte split cnt + PutValOnStream ( vecOut, iPos, static_cast ( iSplitCnt ), 1 ); + + // data + for ( int i = 0; i < iDataLenByte; i++ ) + { + PutValOnStream ( vecOut, iPos, static_cast ( vecData[i] ), 1 ); + } +} + void CProtocol::PutValOnStream ( CVector& vecIn, int& iPos, const uint32_t iVal, diff --git a/src/protocol.h b/src/protocol.h index cb101ec768..91bda9fe46 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -205,6 +205,12 @@ class CProtocol : public QObject const int iID, const CVector& vecData ); + void GenSplitMessageContainer ( CVector& vecOut, + const int iID, + const int iNumParts, + const int iSplitCnt, + const CVector& vecData ); + void ParseSplitMessageContainer ( const CVector& vecbyData, CVector& vecbyMesBodyData, int& iID, From 4ce374f7914356a42783f47df03dc90c7178ece7 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Mon, 7 Sep 2020 20:38:57 +0200 Subject: [PATCH 03/13] bug fixes and adding qDebug() outputs --- src/protocol.cpp | 69 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index 7d0a34fe17..e4f6b5c865 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -428,7 +428,7 @@ vecvecbySplitMessageStorage.Init ( iMaxNumParts ); for ( int i = 0; i < iMaxNumParts; i++ ) { - vecvecbySplitMessageStorage[i].Init( iPartSize ); + vecvecbySplitMessageStorage[i].Init ( iPartSize ); } @@ -446,9 +446,10 @@ void CProtocol::Reset() QMutexLocker locker ( &Mutex ); // prepare internal variables for initial protocol transfer - iCounter = 0; - iOldRecID = PROTMESSID_ILLEGAL; - iOldRecCnt = 0; + iCounter = 0; + iOldRecID = PROTMESSID_ILLEGAL; + iOldRecCnt = 0; + iSplitMessageCnt = 0; // delete complete "send message queue" SendMessQueue.clear(); @@ -523,29 +524,20 @@ void CProtocol::CreateAndSendMessage ( const int iID, CVector vecNewMessage; int iCurCounter; - Mutex.lock(); - { - // store current counter value - iCurCounter = iCounter; - - // increase counter (wraps around automatically) - iCounter++; - } - Mutex.unlock(); - - // TODO insert split mechanism here // TODO make use of MAX_SIZE_BYTES_NETW_BUF CVector vecDataTmp; int iPointer = 0; +qDebug() << "CreateAndSendMessage vecData.Size(): " << vecData.Size(); + // TEST split all messages by half for testing if ( vecData.Size() > iPartSize ) { const int iNumParts = static_cast ( ceil ( static_cast ( vecData.Size() ) / iPartSize ) ); -//qDebug() << iNumParts; +qDebug() << "CreateAndSendMessage message spilt in " << iNumParts << " parts"; for ( int iSplitCnt = 0; iSplitCnt < iNumParts; iSplitCnt++ ) { @@ -564,21 +556,43 @@ for ( int i = 0; i < iCurPartSize; i++ ) } iPointer += iCurPartSize; - GenSplitMessageContainer ( vecNewMessage, +CVector vecNewSplitMessage; + + GenSplitMessageContainer ( vecNewSplitMessage, iID, iNumParts, iSplitCnt, vecDataTmp ); + Mutex.lock(); + { + // store current counter value + iCurCounter = iCounter; + + // increase counter (wraps around automatically) + iCounter++; + } + Mutex.unlock(); + // build complete message - GenMessageFrame ( vecNewMessage, iCurCounter, iID, vecData ); + GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_SPECIAL_SPLIT_MESSAGE, vecNewSplitMessage ); // enqueue message - EnqueueMessage ( vecNewMessage, iCurCounter, iID ); + EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_SPECIAL_SPLIT_MESSAGE ); } } else { + Mutex.lock(); + { + // store current counter value + iCurCounter = iCounter; + + // increase counter (wraps around automatically) + iCounter++; + } + Mutex.unlock(); + // build complete message GenMessageFrame ( vecNewMessage, iCurCounter, iID, vecData ); @@ -691,6 +705,7 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false; // TODO better solution: do not copy message CVector vecbyMesBodyDataModified = vecbyMesBodyData; +int iRecIDModified = iRecID; bool bEvaluateMessage = true; @@ -698,6 +713,8 @@ CVector vecbyMesBodyDataModified = vecbyMesBodyData; // check for special ID first if ( iRecID == PROTMESSID_SPECIAL_SPLIT_MESSAGE ) { +qDebug() << "PROTMESSID_SPECIAL_SPLIT_MESSAGE"; + int iOriginalID; int iReceivedNumParts; int iReceivedSplitCnt; @@ -713,10 +730,12 @@ CVector vecbyMesBodyDataModified = vecbyMesBodyData; // TEST assuming everything is ok iSplitMessageCnt++; +qDebug() << "iSplitMessageCnt: " << iSplitMessageCnt << ", iReceivedSplitCnt: " << iReceivedSplitCnt << ", iReceivedNumParts: " << iReceivedNumParts; + if ( iSplitMessageCnt == iReceivedNumParts ) { // quick hack test!!! - vecbyMesBodyDataModified.Reset ( 0 ); + vecbyMesBodyDataModified.Init ( 0 ); for ( int i = 0; i < iReceivedNumParts; i++ ) { @@ -726,6 +745,11 @@ CVector vecbyMesBodyDataModified = vecbyMesBodyData; vecbyMesBodyDataModified.Add ( vecvecbySplitMessageStorage[i][j] ); } } + + iRecIDModified = iOriginalID; + +qDebug() << "received iNumParts: " << iReceivedNumParts;// << ", data: " << vecbyMesBodyDataModified; + } else { @@ -740,8 +764,11 @@ iSplitMessageCnt = 0; if ( bEvaluateMessage ) { + +qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified.Size(): " << vecbyMesBodyDataModified.Size(); + // check which type of message we received and do action - switch ( iRecID ) + switch ( iRecIDModified ) { case PROTMESSID_JITT_BUF_SIZE: bRet = EvaluateJitBufMes ( vecbyMesBodyDataModified ); From 1b94d0b9ffaee2008e21ce28d715a167a509a9b5 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Mon, 7 Sep 2020 21:19:20 +0200 Subject: [PATCH 04/13] some cleanup --- src/protocol.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index e4f6b5c865..8f7dfc762d 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -556,6 +556,7 @@ for ( int i = 0; i < iCurPartSize; i++ ) } iPointer += iCurPartSize; +// TODO better solution CVector vecNewSplitMessage; GenSplitMessageContainer ( vecNewSplitMessage, @@ -734,32 +735,48 @@ qDebug() << "iSplitMessageCnt: " << iSplitMessageCnt << ", iReceivedSplitCnt: " if ( iSplitMessageCnt == iReceivedNumParts ) { -// quick hack test!!! - vecbyMesBodyDataModified.Init ( 0 ); - for ( int i = 0; i < iReceivedNumParts; i++ ) +// TODO is there a cleaner way of reconstructing the complete message? + + int iMessageSize = 0; + + for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) + { + iMessageSize += vecvecbySplitMessageStorage[iSplitCnt].Size(); + } + + vecbyMesBodyDataModified.Init ( iMessageSize ); + + int iPutPos = 0; + + for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) { -// quick hack test!!! - for ( int j = 0; j < vecvecbySplitMessageStorage[i].Size(); j++ ) - { - vecbyMesBodyDataModified.Add ( vecvecbySplitMessageStorage[i][j] ); - } + const int iCurPartSize = vecvecbySplitMessageStorage[iSplitCnt].Size(); + + std::copy ( vecvecbySplitMessageStorage[iSplitCnt].begin(), + vecvecbySplitMessageStorage[iSplitCnt].begin() + iCurPartSize, + vecbyMesBodyDataModified.begin() + iPutPos ); + + iPutPos += iCurPartSize; } iRecIDModified = iOriginalID; qDebug() << "received iNumParts: " << iReceivedNumParts;// << ", data: " << vecbyMesBodyDataModified; + // the complete split message was reconstructed, reset the counter for the next split message + iSplitMessageCnt = 0; } else { + // only part of the split message is received, no evaluation possible yet bEvaluateMessage = false; } } else { -// TEST -iSplitMessageCnt = 0; + // a non-split message was received, reset split message counter + iSplitMessageCnt = 0; } if ( bEvaluateMessage ) From c00ea756810ed13414ea2a83aa4e9bfb4def7671 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 8 Sep 2020 16:33:17 +0200 Subject: [PATCH 05/13] added some protocol protection for the new message type --- src/protocol.cpp | 74 ++++++++++++++++++++++++++---------------------- src/protocol.h | 2 +- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index 8f7dfc762d..c5438f8cb8 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -709,7 +709,7 @@ CVector vecbyMesBodyDataModified = vecbyMesBodyData; int iRecIDModified = iRecID; - bool bEvaluateMessage = true; + bool bEvaluateMessage = false; // check for special ID first if ( iRecID == PROTMESSID_SPECIAL_SPLIT_MESSAGE ) @@ -720,63 +720,61 @@ qDebug() << "PROTMESSID_SPECIAL_SPLIT_MESSAGE"; int iReceivedNumParts; int iReceivedSplitCnt; - ParseSplitMessageContainer ( vecbyMesBodyData, - vecvecbySplitMessageStorage[iSplitMessageCnt], - iOriginalID, - iReceivedNumParts, - iReceivedSplitCnt ); - + if ( !ParseSplitMessageContainer ( vecbyMesBodyData, + vecvecbySplitMessageStorage[iSplitMessageCnt], + iOriginalID, + iReceivedNumParts, + iReceivedSplitCnt ) ) + { // TODO implement some checks of counters, etc. here // TEST assuming everything is ok - iSplitMessageCnt++; + iSplitMessageCnt++; qDebug() << "iSplitMessageCnt: " << iSplitMessageCnt << ", iReceivedSplitCnt: " << iReceivedSplitCnt << ", iReceivedNumParts: " << iReceivedNumParts; - if ( iSplitMessageCnt == iReceivedNumParts ) - { + if ( iSplitMessageCnt == iReceivedNumParts ) + { // TODO is there a cleaner way of reconstructing the complete message? - int iMessageSize = 0; + int iMessageSize = 0; - for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) - { - iMessageSize += vecvecbySplitMessageStorage[iSplitCnt].Size(); - } + for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) + { + iMessageSize += vecvecbySplitMessageStorage[iSplitCnt].Size(); + } - vecbyMesBodyDataModified.Init ( iMessageSize ); + vecbyMesBodyDataModified.Init ( iMessageSize ); - int iPutPos = 0; + int iPutPos = 0; - for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) - { - const int iCurPartSize = vecvecbySplitMessageStorage[iSplitCnt].Size(); + for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) + { + const int iCurPartSize = vecvecbySplitMessageStorage[iSplitCnt].Size(); - std::copy ( vecvecbySplitMessageStorage[iSplitCnt].begin(), - vecvecbySplitMessageStorage[iSplitCnt].begin() + iCurPartSize, - vecbyMesBodyDataModified.begin() + iPutPos ); + std::copy ( vecvecbySplitMessageStorage[iSplitCnt].begin(), + vecvecbySplitMessageStorage[iSplitCnt].begin() + iCurPartSize, + vecbyMesBodyDataModified.begin() + iPutPos ); - iPutPos += iCurPartSize; - } + iPutPos += iCurPartSize; + } - iRecIDModified = iOriginalID; + iRecIDModified = iOriginalID; qDebug() << "received iNumParts: " << iReceivedNumParts;// << ", data: " << vecbyMesBodyDataModified; - // the complete split message was reconstructed, reset the counter for the next split message - iSplitMessageCnt = 0; - } - else - { - // only part of the split message is received, no evaluation possible yet - bEvaluateMessage = false; + // the complete split message was reconstructed, reset the counter for the next split message + iSplitMessageCnt = 0; + bEvaluateMessage = true; + } } } else { // a non-split message was received, reset split message counter iSplitMessageCnt = 0; + bEvaluateMessage = true; } if ( bEvaluateMessage ) @@ -2815,7 +2813,7 @@ bool CProtocol::ParseMessageFrame ( const CVector& vecbyData, return false; // no error } -void CProtocol::ParseSplitMessageContainer ( const CVector& vecbyData, +bool CProtocol::ParseSplitMessageContainer ( const CVector& vecbyData, CVector& vecbyMesBodyData, int& iID, int& iNumParts, @@ -2824,6 +2822,12 @@ void CProtocol::ParseSplitMessageContainer ( const CVector& vecbyData, int iPos = 0; // init position pointer const int iDataLen = vecbyData.Size(); + // check size (the first 4 bytes) + if ( iDataLen < 4 ) + { + return true; // return error code + } + // 2 bytes ID iID = static_cast ( GetValFromStream ( vecbyData, iPos, 2 ) ); @@ -2847,6 +2851,8 @@ void CProtocol::ParseSplitMessageContainer ( const CVector& vecbyData, { vecbyMesBodyData[i] = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); } + + return false; // no error } uint32_t CProtocol::GetValFromStream ( const CVector& vecIn, diff --git a/src/protocol.h b/src/protocol.h index 91bda9fe46..62378b28f9 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -211,7 +211,7 @@ class CProtocol : public QObject const int iSplitCnt, const CVector& vecData ); - void ParseSplitMessageContainer ( const CVector& vecbyData, + bool ParseSplitMessageContainer ( const CVector& vecbyData, CVector& vecbyMesBodyData, int& iID, int& iNumParts, From e754847dfb40820288b37b7d1082e34fc0a7b62a Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 8 Sep 2020 18:12:09 +0200 Subject: [PATCH 06/13] added consistency checks and some code cleanup --- src/protocol.cpp | 135 +++++++++++++++++++++-------------------------- src/protocol.h | 11 ++-- 2 files changed, 67 insertions(+), 79 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index c5438f8cb8..33ffefc6a0 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -419,20 +419,6 @@ CONNECTION LESS MESSAGES /* Implementation *************************************************************/ CProtocol::CProtocol() { - - -// TEST -const int iMaxNumParts = 200;//25; -iPartSize = 600; -vecvecbySplitMessageStorage.Init ( iMaxNumParts ); - -for ( int i = 0; i < iMaxNumParts; i++ ) -{ - vecvecbySplitMessageStorage[i].Init ( iPartSize ); -} - - - Reset(); @@ -533,17 +519,17 @@ int iPointer = 0; qDebug() << "CreateAndSendMessage vecData.Size(): " << vecData.Size(); // TEST split all messages by half for testing -if ( vecData.Size() > iPartSize ) +if ( vecData.Size() > MESS_SPLIT_PART_SIZE_BYTES ) { - const int iNumParts = static_cast ( ceil ( static_cast ( vecData.Size() ) / iPartSize ) ); + const int iNumParts = static_cast ( ceil ( static_cast ( vecData.Size() ) / MESS_SPLIT_PART_SIZE_BYTES ) ); qDebug() << "CreateAndSendMessage message spilt in " << iNumParts << " parts"; for ( int iSplitCnt = 0; iSplitCnt < iNumParts; iSplitCnt++ ) { - int iCurPartSize = iPartSize; + int iCurPartSize = MESS_SPLIT_PART_SIZE_BYTES; - if ( vecData.Size() - iPointer < iPartSize ) + if ( vecData.Size() - iPointer < MESS_SPLIT_PART_SIZE_BYTES ) { iCurPartSize = vecData.Size() - iPointer; } @@ -633,16 +619,10 @@ void CProtocol::CreateAndImmSendConLessMessage ( const int iID, emit CLMessReadyForSending ( InetAddr, vecNewMessage ); } -bool CProtocol::ParseMessageBody ( const CVector& vecbyMesBodyData, +void CProtocol::ParseMessageBody ( const CVector& vecbyMesBodyData, const int iRecCounter, const int iRecID ) { -/* - return code: false -> ok; true -> error -*/ - bool bRet = false; - bool bSendNextMess; - /* // TEST channel implementation: randomly delete protocol messages (50 % loss) if ( rand() < ( RAND_MAX / 2 ) ) return false; @@ -669,18 +649,17 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false; // check size if ( vecbyMesBodyData.Size() != 2 ) { - return true; // return error code + return; } // extract data from stream and emit signal for received value - int iPos = 0; - const int iData = - static_cast ( GetValFromStream ( vecbyMesBodyData, iPos, 2 ) ); + bool bSendNextMess = false; + int iPos = 0; + const int iData = static_cast ( GetValFromStream ( vecbyMesBodyData, iPos, 2 ) ); Mutex.lock(); { // check if this is the correct acknowledgment - bSendNextMess = false; if ( !SendMessQueue.empty() ) { if ( ( SendMessQueue.front().iCnt == iRecCounter ) && @@ -726,53 +705,61 @@ qDebug() << "PROTMESSID_SPECIAL_SPLIT_MESSAGE"; iReceivedNumParts, iReceivedSplitCnt ) ) { -// TODO implement some checks of counters, etc. here - -// TEST assuming everything is ok - iSplitMessageCnt++; + // consistency checks + if ( ( iSplitMessageCnt != iReceivedSplitCnt ) || + ( iSplitMessageCnt >= iReceivedNumParts ) || + ( iSplitMessageCnt >= MAX_NUM_MESS_SPLIT_PARTS - 1 ) ) + { + // in case of an error we result the split message counter + iSplitMessageCnt = 0; + } + else + { + iSplitMessageCnt++; qDebug() << "iSplitMessageCnt: " << iSplitMessageCnt << ", iReceivedSplitCnt: " << iReceivedSplitCnt << ", iReceivedNumParts: " << iReceivedNumParts; - if ( iSplitMessageCnt == iReceivedNumParts ) - { + if ( iSplitMessageCnt == iReceivedNumParts ) + { // TODO is there a cleaner way of reconstructing the complete message? - int iMessageSize = 0; + int iMessageSize = 0; - for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) - { - iMessageSize += vecvecbySplitMessageStorage[iSplitCnt].Size(); - } + for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) + { + iMessageSize += vecvecbySplitMessageStorage[iSplitCnt].Size(); + } - vecbyMesBodyDataModified.Init ( iMessageSize ); + vecbyMesBodyDataModified.Init ( iMessageSize ); - int iPutPos = 0; + int iPutPos = 0; - for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) - { - const int iCurPartSize = vecvecbySplitMessageStorage[iSplitCnt].Size(); + for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) + { + const int iCurPartSize = vecvecbySplitMessageStorage[iSplitCnt].Size(); - std::copy ( vecvecbySplitMessageStorage[iSplitCnt].begin(), - vecvecbySplitMessageStorage[iSplitCnt].begin() + iCurPartSize, - vecbyMesBodyDataModified.begin() + iPutPos ); + std::copy ( vecvecbySplitMessageStorage[iSplitCnt].begin(), + vecvecbySplitMessageStorage[iSplitCnt].begin() + iCurPartSize, + vecbyMesBodyDataModified.begin() + iPutPos ); - iPutPos += iCurPartSize; - } + iPutPos += iCurPartSize; + } - iRecIDModified = iOriginalID; + iRecIDModified = iOriginalID; qDebug() << "received iNumParts: " << iReceivedNumParts;// << ", data: " << vecbyMesBodyDataModified; - // the complete split message was reconstructed, reset the counter for the next split message - iSplitMessageCnt = 0; - bEvaluateMessage = true; + // the complete split message was reconstructed, reset the counter for the next split message + iSplitMessageCnt = 0; + bEvaluateMessage = true; + } } } } else { - // a non-split message was received, reset split message counter + // a non-split message was received, reset split message counter and directly evaluate message iSplitMessageCnt = 0; bEvaluateMessage = true; } @@ -786,71 +773,71 @@ qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified. switch ( iRecIDModified ) { case PROTMESSID_JITT_BUF_SIZE: - bRet = EvaluateJitBufMes ( vecbyMesBodyDataModified ); + EvaluateJitBufMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_REQ_JITT_BUF_SIZE: - bRet = EvaluateReqJitBufMes(); + EvaluateReqJitBufMes(); break; case PROTMESSID_CLIENT_ID: - bRet = EvaluateClientIDMes ( vecbyMesBodyDataModified ); + EvaluateClientIDMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_CHANNEL_GAIN: - bRet = EvaluateChanGainMes ( vecbyMesBodyDataModified ); + EvaluateChanGainMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_CHANNEL_PAN: - bRet = EvaluateChanPanMes ( vecbyMesBodyDataModified ); + EvaluateChanPanMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_MUTE_STATE_CHANGED: - bRet = EvaluateMuteStateHasChangedMes ( vecbyMesBodyDataModified ); + EvaluateMuteStateHasChangedMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_CONN_CLIENTS_LIST: - bRet = EvaluateConClientListMes ( vecbyMesBodyDataModified ); + EvaluateConClientListMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_REQ_CONN_CLIENTS_LIST: - bRet = EvaluateReqConnClientsList(); + EvaluateReqConnClientsList(); break; case PROTMESSID_CHANNEL_INFOS: - bRet = EvaluateChanInfoMes ( vecbyMesBodyDataModified ); + EvaluateChanInfoMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_REQ_CHANNEL_INFOS: - bRet = EvaluateReqChanInfoMes(); + EvaluateReqChanInfoMes(); break; case PROTMESSID_CHAT_TEXT: - bRet = EvaluateChatTextMes ( vecbyMesBodyDataModified ); + EvaluateChatTextMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_NETW_TRANSPORT_PROPS: - bRet = EvaluateNetwTranspPropsMes ( vecbyMesBodyDataModified ); + EvaluateNetwTranspPropsMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_REQ_NETW_TRANSPORT_PROPS: - bRet = EvaluateReqNetwTranspPropsMes(); + EvaluateReqNetwTranspPropsMes(); break; case PROTMESSID_LICENCE_REQUIRED: - bRet = EvaluateLicenceRequiredMes ( vecbyMesBodyDataModified ); + EvaluateLicenceRequiredMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_REQ_CHANNEL_LEVEL_LIST: - bRet = EvaluateReqChannelLevelListMes ( vecbyMesBodyDataModified ); + EvaluateReqChannelLevelListMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_VERSION_AND_OS: - bRet = EvaluateVersionAndOSMes ( vecbyMesBodyDataModified ); + EvaluateVersionAndOSMes ( vecbyMesBodyDataModified ); break; case PROTMESSID_RECORDER_STATE: - bRet = EvaluateRecorderStateMes ( vecbyMesBodyDataModified ); + EvaluateRecorderStateMes ( vecbyMesBodyDataModified ); break; } } @@ -864,8 +851,6 @@ qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified. iOldRecCnt = iRecCounter; } } - - return bRet; } bool CProtocol::ParseConnectionLessMessageBody ( const CVector& vecbyMesBodyData, diff --git a/src/protocol.h b/src/protocol.h index 62378b28f9..347f74d4e8 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -91,6 +91,10 @@ // time out for message re-send if no acknowledgement was received #define SEND_MESS_TIMEOUT_MS 400 // ms +// message split parameters +#define MESS_SPLIT_PART_SIZE_BYTES 550 +#define MAX_NUM_MESS_SPLIT_PARTS ( MAX_SIZE_BYTES_NETW_BUF / 600 ) + /* Classes ********************************************************************/ class CProtocol : public QObject @@ -157,7 +161,7 @@ class CProtocol : public QObject int& iRecCounter, int& iRecID ); - bool ParseMessageBody ( const CVector& vecbyMesBodyData, + void ParseMessageBody ( const CVector& vecbyMesBodyData, const int iRecCounter, const int iRecID ); @@ -298,9 +302,8 @@ class CProtocol : public QObject QTimer TimerSendMess; QMutex Mutex; - CVector > vecvecbySplitMessageStorage; - int iSplitMessageCnt; - int iPartSize; + CVector vecvecbySplitMessageStorage[MAX_NUM_MESS_SPLIT_PARTS]; + int iSplitMessageCnt; public slots: void OnTimerSendMess() { SendMessage(); } From 15f5920ddf827442462ea72da6fdd3c4a2a08a2b Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 8 Sep 2020 18:20:29 +0200 Subject: [PATCH 07/13] some more code cleanup --- src/protocol.cpp | 116 +++++++++++++++++++++-------------------------- src/protocol.h | 2 +- 2 files changed, 52 insertions(+), 66 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index 33ffefc6a0..24a12d6d59 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -853,96 +853,82 @@ qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified. } } -bool CProtocol::ParseConnectionLessMessageBody ( const CVector& vecbyMesBodyData, +void CProtocol::ParseConnectionLessMessageBody ( const CVector& vecbyMesBodyData, const int iRecID, const CHostAddress& InetAddr ) { -/* - return code: false -> ok; true -> error -*/ - bool bRet = false; - /* // TEST channel implementation: randomly delete protocol messages (50 % loss) if ( rand() < ( RAND_MAX / 2 ) ) return false; */ - if ( IsConnectionLessMessageID ( iRecID ) ) + // check which type of message we received and do action + switch ( iRecID ) { - // check which type of message we received and do action - switch ( iRecID ) - { - case PROTMESSID_CLM_PING_MS: - bRet = EvaluateCLPingMes ( InetAddr, vecbyMesBodyData ); - break; + case PROTMESSID_CLM_PING_MS: + EvaluateCLPingMes ( InetAddr, vecbyMesBodyData ); + break; - case PROTMESSID_CLM_PING_MS_WITHNUMCLIENTS: - bRet = EvaluateCLPingWithNumClientsMes ( InetAddr, vecbyMesBodyData ); - break; + case PROTMESSID_CLM_PING_MS_WITHNUMCLIENTS: + EvaluateCLPingWithNumClientsMes ( InetAddr, vecbyMesBodyData ); + break; - case PROTMESSID_CLM_SERVER_FULL: - bRet = EvaluateCLServerFullMes(); - break; + case PROTMESSID_CLM_SERVER_FULL: + EvaluateCLServerFullMes(); + break; - case PROTMESSID_CLM_SERVER_LIST: - bRet = EvaluateCLServerListMes ( InetAddr, vecbyMesBodyData ); - break; + case PROTMESSID_CLM_SERVER_LIST: + EvaluateCLServerListMes ( InetAddr, vecbyMesBodyData ); + break; - case PROTMESSID_CLM_REQ_SERVER_LIST: - bRet = EvaluateCLReqServerListMes ( InetAddr ); - break; + case PROTMESSID_CLM_REQ_SERVER_LIST: + EvaluateCLReqServerListMes ( InetAddr ); + break; - case PROTMESSID_CLM_SEND_EMPTY_MESSAGE: - bRet = EvaluateCLSendEmptyMesMes ( vecbyMesBodyData ); - break; + case PROTMESSID_CLM_SEND_EMPTY_MESSAGE: + EvaluateCLSendEmptyMesMes ( vecbyMesBodyData ); + break; - case PROTMESSID_CLM_REGISTER_SERVER: - bRet = EvaluateCLRegisterServerMes ( InetAddr, vecbyMesBodyData ); - break; + case PROTMESSID_CLM_REGISTER_SERVER: + EvaluateCLRegisterServerMes ( InetAddr, vecbyMesBodyData ); + break; - case PROTMESSID_CLM_REGISTER_SERVER_EX: - bRet = EvaluateCLRegisterServerExMes ( InetAddr, vecbyMesBodyData ); - break; + case PROTMESSID_CLM_REGISTER_SERVER_EX: + EvaluateCLRegisterServerExMes ( InetAddr, vecbyMesBodyData ); + break; - case PROTMESSID_CLM_UNREGISTER_SERVER: - bRet = EvaluateCLUnregisterServerMes ( InetAddr ); - break; + case PROTMESSID_CLM_UNREGISTER_SERVER: + EvaluateCLUnregisterServerMes ( InetAddr ); + break; - case PROTMESSID_CLM_DISCONNECTION: - bRet = EvaluateCLDisconnectionMes ( InetAddr ); - break; + case PROTMESSID_CLM_DISCONNECTION: + EvaluateCLDisconnectionMes ( InetAddr ); + break; - case PROTMESSID_CLM_VERSION_AND_OS: - bRet = EvaluateCLVersionAndOSMes ( InetAddr, vecbyMesBodyData ); - break; + case PROTMESSID_CLM_VERSION_AND_OS: + EvaluateCLVersionAndOSMes ( InetAddr, vecbyMesBodyData ); + break; - case PROTMESSID_CLM_REQ_VERSION_AND_OS: - bRet = EvaluateCLReqVersionAndOSMes ( InetAddr ); - break; + case PROTMESSID_CLM_REQ_VERSION_AND_OS: + EvaluateCLReqVersionAndOSMes ( InetAddr ); + break; - case PROTMESSID_CLM_CONN_CLIENTS_LIST: - bRet = EvaluateCLConnClientsListMes ( InetAddr, vecbyMesBodyData ); - break; + case PROTMESSID_CLM_CONN_CLIENTS_LIST: + EvaluateCLConnClientsListMes ( InetAddr, vecbyMesBodyData ); + break; - case PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST: - bRet = EvaluateCLReqConnClientsListMes ( InetAddr ); - break; + case PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST: + EvaluateCLReqConnClientsListMes ( InetAddr ); + break; - case PROTMESSID_CLM_CHANNEL_LEVEL_LIST: - bRet = EvaluateCLChannelLevelListMes ( InetAddr, vecbyMesBodyData ); - break; + case PROTMESSID_CLM_CHANNEL_LEVEL_LIST: + EvaluateCLChannelLevelListMes ( InetAddr, vecbyMesBodyData ); + break; - case PROTMESSID_CLM_REGISTER_SERVER_RESP: - bRet = EvaluateCLRegisterServerResp ( InetAddr, vecbyMesBodyData ); - break; - } - } - else - { - bRet = true; // return error code + case PROTMESSID_CLM_REGISTER_SERVER_RESP: + EvaluateCLRegisterServerResp ( InetAddr, vecbyMesBodyData ); + break; } - - return bRet; } diff --git a/src/protocol.h b/src/protocol.h index 347f74d4e8..a67d1e6ee5 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -165,7 +165,7 @@ class CProtocol : public QObject const int iRecCounter, const int iRecID ); - bool ParseConnectionLessMessageBody ( const CVector& vecbyMesBodyData, + void ParseConnectionLessMessageBody ( const CVector& vecbyMesBodyData, const int iRecID, const CHostAddress& InetAddr ); From a17427dc2275d757ffec245abcdc39fcd129daf7 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 8 Sep 2020 19:47:32 +0200 Subject: [PATCH 08/13] add compatibility support for old Jamulus version regarding the new split messageses --- src/channel.cpp | 16 ++++++ src/channel.h | 3 ++ src/protocol.cpp | 127 ++++++++++++++++++++++++++++++++--------------- src/protocol.h | 10 ++++ src/server.cpp | 3 ++ 5 files changed, 119 insertions(+), 40 deletions(-) diff --git a/src/channel.cpp b/src/channel.cpp index e22f5f1ac0..8e74f3f5e8 100755 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -104,6 +104,12 @@ qRegisterMetaType ( "CHostAddress" ); QObject::connect ( &Protocol, &CProtocol::ReqNetTranspProps, this, &CChannel::OnReqNetTranspProps ); + QObject::connect ( &Protocol, &CProtocol::ReqSplitMessSupport, + this, &CChannel::OnReqSplitMessSupport ); + + QObject::connect ( &Protocol, &CProtocol::SplitMessSupported, + this, &CChannel::OnSplitMessSupported ); + QObject::connect ( &Protocol, &CProtocol::LicenceRequired, this, &CChannel::LicenceRequired ); @@ -470,6 +476,13 @@ void CChannel::OnReqNetTranspProps() Protocol.CreateNetwTranspPropsMes ( GetNetworkTransportPropsFromCurrentSettings() ); } +void CChannel::OnReqSplitMessSupport() +{ + // activate split messages in our protocol (client) and return answer message to the server + Protocol.SetSplitMessageSupported ( true ); + Protocol.CreateSplitMessSupportedMes(); +} + CNetworkTransportProps CChannel::GetNetworkTransportPropsFromCurrentSettings() { // use current stored settings of the channel to fill the network transport @@ -641,6 +654,9 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData, // in case we are just disconnected, we have to fire a message if ( eGetStatus == GS_CHAN_NOW_DISCONNECTED ) { + // reset the protocol + Protocol.Reset(); + // emit message emit Disconnected(); } diff --git a/src/channel.h b/src/channel.h index cb81fc5155..fca896b9f2 100755 --- a/src/channel.h +++ b/src/channel.h @@ -159,6 +159,7 @@ class CChannel : public QObject } void CreateClientIDMes ( const int iChanID ) { Protocol.CreateClientIDMes ( iChanID ); } void CreateReqNetwTranspPropsMes() { Protocol.CreateReqNetwTranspPropsMes(); } + void CreateReqSplitMessSupportMes() { Protocol.CreateReqSplitMessSupportMes(); } void CreateReqJitBufMes() { Protocol.CreateReqJitBufMes(); } void CreateReqConnClientsList() { Protocol.CreateReqConnClientsList(); } void CreateChatTextMes ( const QString& strChatText ) { Protocol.CreateChatTextMes ( strChatText ); } @@ -245,6 +246,8 @@ public slots: void OnChangeChanInfo ( CChannelCoreInfo ChanInfo ); void OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps ); void OnReqNetTranspProps(); + void OnReqSplitMessSupport(); + void OnSplitMessSupported() { Protocol.SetSplitMessageSupported ( true ); } void OnParseMessageBody ( CVector vecbyMesBodyData, int iRecCounter, diff --git a/src/protocol.cpp b/src/protocol.cpp index 24a12d6d59..2bc4440959 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -200,6 +200,16 @@ MESSAGES (with connection) note: does not have any data -> n = 0 +- PROTMESSID_REQ_SPLIT_MESS_SUPPORT: Request split message support + + note: does not have any data -> n = 0 + + +- PROTMESSID_SPLIT_MESS_SUPPORTED: Split messages are supported + + note: does not have any data -> n = 0 + + - PROTMESSID_LICENCE_REQUIRED: Licence required to connect to the server +---------------------+ @@ -432,10 +442,11 @@ void CProtocol::Reset() QMutexLocker locker ( &Mutex ); // prepare internal variables for initial protocol transfer - iCounter = 0; - iOldRecID = PROTMESSID_ILLEGAL; - iOldRecCnt = 0; - iSplitMessageCnt = 0; + iCounter = 0; + iOldRecID = PROTMESSID_ILLEGAL; + iOldRecCnt = 0; + iSplitMessageCnt = 0; + bSplitMessageSupported = false; // compatilibity to old versions // delete complete "send message queue" SendMessQueue.clear(); @@ -519,20 +530,20 @@ int iPointer = 0; qDebug() << "CreateAndSendMessage vecData.Size(): " << vecData.Size(); // TEST split all messages by half for testing -if ( vecData.Size() > MESS_SPLIT_PART_SIZE_BYTES ) -{ - const int iNumParts = static_cast ( ceil ( static_cast ( vecData.Size() ) / MESS_SPLIT_PART_SIZE_BYTES ) ); + if ( ( vecData.Size() > MESS_SPLIT_PART_SIZE_BYTES ) && bSplitMessageSupported ) + { + const int iNumParts = static_cast ( ceil ( static_cast ( vecData.Size() ) / MESS_SPLIT_PART_SIZE_BYTES ) ); qDebug() << "CreateAndSendMessage message spilt in " << iNumParts << " parts"; - for ( int iSplitCnt = 0; iSplitCnt < iNumParts; iSplitCnt++ ) - { - int iCurPartSize = MESS_SPLIT_PART_SIZE_BYTES; - - if ( vecData.Size() - iPointer < MESS_SPLIT_PART_SIZE_BYTES ) + for ( int iSplitCnt = 0; iSplitCnt < iNumParts; iSplitCnt++ ) { - iCurPartSize = vecData.Size() - iPointer; - } + int iCurPartSize = MESS_SPLIT_PART_SIZE_BYTES; + + if ( vecData.Size() - iPointer < MESS_SPLIT_PART_SIZE_BYTES ) + { + iCurPartSize = vecData.Size() - iPointer; + } vecDataTmp.Init ( iCurPartSize ); @@ -545,12 +556,31 @@ iPointer += iCurPartSize; // TODO better solution CVector vecNewSplitMessage; - GenSplitMessageContainer ( vecNewSplitMessage, - iID, - iNumParts, - iSplitCnt, - vecDataTmp ); + GenSplitMessageContainer ( vecNewSplitMessage, + iID, + iNumParts, + iSplitCnt, + vecDataTmp ); + Mutex.lock(); + { + // store current counter value + iCurCounter = iCounter; + + // increase counter (wraps around automatically) + iCounter++; + } + Mutex.unlock(); + + // build complete message + GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_SPECIAL_SPLIT_MESSAGE, vecNewSplitMessage ); + + // enqueue message + EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_SPECIAL_SPLIT_MESSAGE ); + } + } + else + { Mutex.lock(); { // store current counter value @@ -562,30 +592,11 @@ CVector vecNewSplitMessage; Mutex.unlock(); // build complete message - GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_SPECIAL_SPLIT_MESSAGE, vecNewSplitMessage ); + GenMessageFrame ( vecNewMessage, iCurCounter, iID, vecData ); // enqueue message - EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_SPECIAL_SPLIT_MESSAGE ); - } -} -else -{ - Mutex.lock(); - { - // store current counter value - iCurCounter = iCounter; - - // increase counter (wraps around automatically) - iCounter++; + EnqueueMessage ( vecNewMessage, iCurCounter, iID ); } - Mutex.unlock(); - - // build complete message - GenMessageFrame ( vecNewMessage, iCurCounter, iID, vecData ); - - // enqueue message - EnqueueMessage ( vecNewMessage, iCurCounter, iID ); -} } void CProtocol::CreateAndImmSendAcknMess ( const int& iID, @@ -824,6 +835,14 @@ qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified. EvaluateReqNetwTranspPropsMes(); break; + case PROTMESSID_REQ_SPLIT_MESS_SUPPORT: + EvaluateReqSplitMessSupportMes(); + break; + + case PROTMESSID_SPLIT_MESS_SUPPORTED: + EvaluateSplitMessSupportedMes(); + break; + case PROTMESSID_LICENCE_REQUIRED: EvaluateLicenceRequiredMes ( vecbyMesBodyDataModified ); break; @@ -1572,6 +1591,34 @@ bool CProtocol::EvaluateReqNetwTranspPropsMes() return false; // no error } +void CProtocol::CreateReqSplitMessSupportMes() +{ + CreateAndSendMessage ( PROTMESSID_REQ_SPLIT_MESS_SUPPORT, + CVector ( 0 ) ); +} + +bool CProtocol::EvaluateReqSplitMessSupportMes() +{ + // invoke message action + emit ReqSplitMessSupport(); + + return false; // no error +} + +void CProtocol::CreateSplitMessSupportedMes() +{ + CreateAndSendMessage ( PROTMESSID_SPLIT_MESS_SUPPORTED, + CVector ( 0 ) ); +} + +bool CProtocol::EvaluateSplitMessSupportedMes() +{ + // invoke message action + emit SplitMessSupported(); + + return false; // no error +} + void CProtocol::CreateLicenceRequiredMes ( const ELicenceType eLicenceType ) { CVector vecData ( 1 ); // 1 bytes of data diff --git a/src/protocol.h b/src/protocol.h index a67d1e6ee5..8ad791e72c 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -60,6 +60,8 @@ #define PROTMESSID_MUTE_STATE_CHANGED 31 // mute state of your signal at another client has changed #define PROTMESSID_CLIENT_ID 32 // current user ID and server status #define PROTMESSID_RECORDER_STATE 33 // contains the state of the jam recorder (ERecorderState) +#define PROTMESSID_REQ_SPLIT_MESS_SUPPORT 34 // request support for split messages +#define PROTMESSID_SPLIT_MESS_SUPPORTED 35 // split messages are supported // message IDs of connection less messages (CLM) // DEFINITION -> start at 1000, end at 1999, see IsConnectionLessMessageID @@ -105,6 +107,7 @@ class CProtocol : public QObject CProtocol(); void Reset(); + void SetSplitMessageSupported ( const bool bIn ) { bSplitMessageSupported = bIn; } void CreateJitBufMes ( const int iJitBufSize ); void CreateReqJitBufMes(); @@ -119,6 +122,8 @@ class CProtocol : public QObject void CreateChatTextMes ( const QString strChatText ); void CreateNetwTranspPropsMes ( const CNetworkTransportProps& NetTrProps ); void CreateReqNetwTranspPropsMes(); + void CreateReqSplitMessSupportMes(); + void CreateSplitMessSupportedMes(); void CreateLicenceRequiredMes ( const ELicenceType eLicenceType ); void CreateOpusSupportedMes(); void CreateReqChannelLevelListMes ( const bool bRCL ); @@ -261,6 +266,8 @@ class CProtocol : public QObject bool EvaluateChatTextMes ( const CVector& vecData ); bool EvaluateNetwTranspPropsMes ( const CVector& vecData ); bool EvaluateReqNetwTranspPropsMes(); + bool EvaluateReqSplitMessSupportMes(); + bool EvaluateSplitMessSupportedMes(); bool EvaluateLicenceRequiredMes ( const CVector& vecData ); bool EvaluateReqChannelLevelListMes ( const CVector& vecData ); bool EvaluateVersionAndOSMes ( const CVector& vecData ); @@ -304,6 +311,7 @@ class CProtocol : public QObject CVector vecvecbySplitMessageStorage[MAX_NUM_MESS_SPLIT_PARTS]; int iSplitMessageCnt; + bool bSplitMessageSupported; public slots: void OnTimerSendMess() { SendMessage(); } @@ -330,6 +338,8 @@ public slots: void ChatTextReceived ( QString strChatText ); void NetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps ); void ReqNetTranspProps(); + void ReqSplitMessSupport(); + void SplitMessSupported(); void LicenceRequired ( ELicenceType eLicenceType ); void ReqChannelLevelList ( bool bOptIn ); void VersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion ); diff --git a/src/server.cpp b/src/server.cpp index 4995b17d22..852969e628 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -596,6 +596,9 @@ void CServer::OnNewConnection ( int iChID, // must be the first message to be sent for a new connection) vecChannels[iChID].CreateClientIDMes ( iChID ); + // query support for split messages in the client + vecChannels[iChID].CreateReqSplitMessSupportMes(); + // on a new connection we query the network transport properties for the // audio packets (to use the correct network block size and audio // compression properties, etc.) From 44a79ff882560a4c54f5fd515303ebec19e549c8 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Wed, 9 Sep 2020 18:25:04 +0200 Subject: [PATCH 09/13] cleanup the CreateAndSendMessage function --- src/protocol.cpp | 58 +++++++++++++++++++----------------------------- src/protocol.h | 4 +++- src/server.cpp | 2 +- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index 2bc4440959..a9979fa9e3 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -520,47 +520,38 @@ void CProtocol::CreateAndSendMessage ( const int iID, { CVector vecNewMessage; int iCurCounter; + const int iDataLen = vecData.Size(); -// TODO insert split mechanism here -// TODO make use of MAX_SIZE_BYTES_NETW_BUF - -CVector vecDataTmp; -int iPointer = 0; - -qDebug() << "CreateAndSendMessage vecData.Size(): " << vecData.Size(); - -// TEST split all messages by half for testing - if ( ( vecData.Size() > MESS_SPLIT_PART_SIZE_BYTES ) && bSplitMessageSupported ) + // check if message has to be split because it is too large + if ( ( iDataLen > MESS_SPLIT_PART_SIZE_BYTES ) && bSplitMessageSupported ) { - const int iNumParts = static_cast ( ceil ( static_cast ( vecData.Size() ) / MESS_SPLIT_PART_SIZE_BYTES ) ); + CVector vecNewSplitMessage; + int iStartIndexInData = 0; // init index -qDebug() << "CreateAndSendMessage message spilt in " << iNumParts << " parts"; + // calculate the number of split parts + const int iNumParts = static_cast ( + std::ceil ( static_cast ( iDataLen ) / MESS_SPLIT_PART_SIZE_BYTES ) ); for ( int iSplitCnt = 0; iSplitCnt < iNumParts; iSplitCnt++ ) { + // the split part size may be smaller for the last part int iCurPartSize = MESS_SPLIT_PART_SIZE_BYTES; - if ( vecData.Size() - iPointer < MESS_SPLIT_PART_SIZE_BYTES ) + if ( iDataLen - iStartIndexInData < MESS_SPLIT_PART_SIZE_BYTES ) { - iCurPartSize = vecData.Size() - iPointer; + iCurPartSize = iDataLen - iStartIndexInData; } -vecDataTmp.Init ( iCurPartSize ); - -for ( int i = 0; i < iCurPartSize; i++ ) -{ - vecDataTmp[i] = vecData[iPointer + i]; -} -iPointer += iCurPartSize; - -// TODO better solution -CVector vecNewSplitMessage; - GenSplitMessageContainer ( vecNewSplitMessage, iID, iNumParts, iSplitCnt, - vecDataTmp ); + vecData, + iStartIndexInData, + iCurPartSize ); + + // increment the start index of the source data by the last part size + iStartIndexInData += iCurPartSize; Mutex.lock(); { @@ -704,8 +695,6 @@ int iRecIDModified = iRecID; // check for special ID first if ( iRecID == PROTMESSID_SPECIAL_SPLIT_MESSAGE ) { -qDebug() << "PROTMESSID_SPECIAL_SPLIT_MESSAGE"; - int iOriginalID; int iReceivedNumParts; int iReceivedSplitCnt; @@ -3000,15 +2989,14 @@ void CProtocol::GenSplitMessageContainer ( CVector& vecOut, const int iID, const int iNumParts, const int iSplitCnt, - const CVector& vecData ) + const CVector& vecData, + const int iStartIndexInData, + const int iLengthOfDataPart ) { int iPos = 0; // init position pointer - // query length of data vector - const int iDataLenByte = vecData.Size(); - // total length of message - const int iTotLenByte = 4 + iDataLenByte; + const int iTotLenByte = 4 + iLengthOfDataPart; // init message vector vecOut.Init ( iTotLenByte ); @@ -3023,9 +3011,9 @@ void CProtocol::GenSplitMessageContainer ( CVector& vecOut, PutValOnStream ( vecOut, iPos, static_cast ( iSplitCnt ), 1 ); // data - for ( int i = 0; i < iDataLenByte; i++ ) + for ( int i = 0; i < iLengthOfDataPart; i++ ) { - PutValOnStream ( vecOut, iPos, static_cast ( vecData[i] ), 1 ); + PutValOnStream ( vecOut, iPos, static_cast ( vecData[iStartIndexInData + i] ), 1 ); } } diff --git a/src/protocol.h b/src/protocol.h index 8ad791e72c..d8614e0135 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -218,7 +218,9 @@ class CProtocol : public QObject const int iID, const int iNumParts, const int iSplitCnt, - const CVector& vecData ); + const CVector& vecData, + const int iStartIndexInData, + const int iLengthOfDataPart ); bool ParseSplitMessageContainer ( const CVector& vecbyData, CVector& vecbyMesBodyData, diff --git a/src/server.cpp b/src/server.cpp index 852969e628..2deb9177f2 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -1680,7 +1680,7 @@ bool CServer::CreateLevelsForAllConChannels ( const int i vecNumAudioChannels[j] > 1 ); // map value to integer for transmission via the protocol (4 bit available) - vecLevelsOut[j] = static_cast ( ceil ( dCurSigLevelForMeterdB ) ); + vecLevelsOut[j] = static_cast ( std::ceil ( dCurSigLevelForMeterdB ) ); } } From 6f9dd5413547a112d1ed7bbb9bb6a7ad106eb858 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Wed, 9 Sep 2020 18:41:46 +0200 Subject: [PATCH 10/13] small fix --- src/protocol.cpp | 3 +++ src/protocol.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index a9979fa9e3..7ad2130cba 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -705,6 +705,9 @@ int iRecIDModified = iRecID; iReceivedNumParts, iReceivedSplitCnt ) ) { + +// TODO put check ( iSplitMessageCnt >= MAX_NUM_MESS_SPLIT_PARTS - 1 ) in front of the ParseSplitMessageContainer call + // consistency checks if ( ( iSplitMessageCnt != iReceivedSplitCnt ) || ( iSplitMessageCnt >= iReceivedNumParts ) || diff --git a/src/protocol.h b/src/protocol.h index d8614e0135..eaece11453 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -95,7 +95,7 @@ // message split parameters #define MESS_SPLIT_PART_SIZE_BYTES 550 -#define MAX_NUM_MESS_SPLIT_PARTS ( MAX_SIZE_BYTES_NETW_BUF / 600 ) +#define MAX_NUM_MESS_SPLIT_PARTS ( MAX_SIZE_BYTES_NETW_BUF / MESS_SPLIT_PART_SIZE_BYTES ) /* Classes ********************************************************************/ From 234c8ddd6d2e6636532878232b9fc5eeaff3e936 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Wed, 9 Sep 2020 20:55:12 +0200 Subject: [PATCH 11/13] some more cleanup and code improvement --- ChangeLog | 3 ++ src/protocol.cpp | 134 ++++++++++++++++++++++------------------------- src/protocol.h | 7 ++- 3 files changed, 71 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index 66706fcbea..e4904531cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,9 @@ - added a command line argument to enable multithreading in the server (#339) +- added support for split protocol messages (fixes bug with large number of clients + connected to a server, #547) + - store recorder settings, coded by pljones (#313) - accessibility improvements, coded by chigkim (#498, #512) diff --git a/src/protocol.cpp b/src/protocol.cpp index 7ad2130cba..4c182b84ec 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -429,6 +429,9 @@ CONNECTION LESS MESSAGES /* Implementation *************************************************************/ CProtocol::CProtocol() { + // allocate worst case memory for split part messages + vecbySplitMessageStorage.Init ( MAX_SIZE_BYTES_NETW_BUF ); + Reset(); @@ -446,6 +449,7 @@ void CProtocol::Reset() iOldRecID = PROTMESSID_ILLEGAL; iOldRecCnt = 0; iSplitMessageCnt = 0; + iSplitMessageDataIndex = 0; bSplitMessageSupported = false; // compatilibity to old versions // delete complete "send message queue" @@ -684,78 +688,61 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false; } else { - -// TODO better solution: do not copy message -CVector vecbyMesBodyDataModified = vecbyMesBodyData; -int iRecIDModified = iRecID; - - - bool bEvaluateMessage = false; + CVector vecbyMesBodyDataSplitMess; + int iRecIDModified = iRecID; + bool bEvaluateMessage = false; // check for special ID first if ( iRecID == PROTMESSID_SPECIAL_SPLIT_MESSAGE ) { + // Split message management ------------------------------------ int iOriginalID; int iReceivedNumParts; int iReceivedSplitCnt; + int iCurPartSize; if ( !ParseSplitMessageContainer ( vecbyMesBodyData, - vecvecbySplitMessageStorage[iSplitMessageCnt], + vecbySplitMessageStorage, + iSplitMessageDataIndex, iOriginalID, iReceivedNumParts, - iReceivedSplitCnt ) ) + iReceivedSplitCnt, + iCurPartSize ) ) { - -// TODO put check ( iSplitMessageCnt >= MAX_NUM_MESS_SPLIT_PARTS - 1 ) in front of the ParseSplitMessageContainer call - // consistency checks if ( ( iSplitMessageCnt != iReceivedSplitCnt ) || ( iSplitMessageCnt >= iReceivedNumParts ) || - ( iSplitMessageCnt >= MAX_NUM_MESS_SPLIT_PARTS - 1 ) ) + ( iSplitMessageCnt >= MAX_NUM_MESS_SPLIT_PARTS ) ) { - // in case of an error we result the split message counter - iSplitMessageCnt = 0; + // in case of an error we reset the split message counter + iSplitMessageCnt = 0; + iSplitMessageDataIndex = 0; } else { + // update counter and message data index since we have received a valid new part iSplitMessageCnt++; + iSplitMessageDataIndex += iCurPartSize; -qDebug() << "iSplitMessageCnt: " << iSplitMessageCnt << ", iReceivedSplitCnt: " << iReceivedSplitCnt << ", iReceivedNumParts: " << iReceivedNumParts; - + // check if the split part messages was completely received if ( iSplitMessageCnt == iReceivedNumParts ) { + // the split message is completely received, copy data for parsing + vecbyMesBodyDataSplitMess.Init ( iSplitMessageDataIndex ); -// TODO is there a cleaner way of reconstructing the complete message? - - int iMessageSize = 0; - - for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) - { - iMessageSize += vecvecbySplitMessageStorage[iSplitCnt].Size(); - } - - vecbyMesBodyDataModified.Init ( iMessageSize ); - - int iPutPos = 0; - - for ( int iSplitCnt = 0; iSplitCnt < iReceivedNumParts; iSplitCnt++ ) - { - const int iCurPartSize = vecvecbySplitMessageStorage[iSplitCnt].Size(); - - std::copy ( vecvecbySplitMessageStorage[iSplitCnt].begin(), - vecvecbySplitMessageStorage[iSplitCnt].begin() + iCurPartSize, - vecbyMesBodyDataModified.begin() + iPutPos ); - - iPutPos += iCurPartSize; - } + std::copy ( vecbySplitMessageStorage.begin(), + vecbySplitMessageStorage.begin() + iSplitMessageDataIndex, + vecbyMesBodyDataSplitMess.begin() ); + // the received ID is still PROTMESSID_SPECIAL_SPLIT_MESSAGE, set it to + // the ID of the original reconstructed split message now iRecIDModified = iOriginalID; -qDebug() << "received iNumParts: " << iReceivedNumParts;// << ", data: " << vecbyMesBodyDataModified; - - // the complete split message was reconstructed, reset the counter for the next split message - iSplitMessageCnt = 0; - bEvaluateMessage = true; + // the complete split message was reconstructed, reset the counter for + // the next split message + iSplitMessageCnt = 0; + iSplitMessageDataIndex = 0; + bEvaluateMessage = true; } } } @@ -763,20 +750,23 @@ qDebug() << "received iNumParts: " << iReceivedNumParts;// << ", data: " << vecb else { // a non-split message was received, reset split message counter and directly evaluate message - iSplitMessageCnt = 0; - bEvaluateMessage = true; + iSplitMessageCnt = 0; + iSplitMessageDataIndex = 0; + bEvaluateMessage = true; } if ( bEvaluateMessage ) { - -qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified.Size(): " << vecbyMesBodyDataModified.Size(); + // use a reference to either the original data vector or the reconstructed + // split message to avoid unnecessary copying + const CVector& vecbyMesBodyDataRef = + ( iRecID == PROTMESSID_SPECIAL_SPLIT_MESSAGE ) ? vecbyMesBodyDataSplitMess : vecbyMesBodyData; // check which type of message we received and do action switch ( iRecIDModified ) { case PROTMESSID_JITT_BUF_SIZE: - EvaluateJitBufMes ( vecbyMesBodyDataModified ); + EvaluateJitBufMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_JITT_BUF_SIZE: @@ -784,23 +774,23 @@ qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified. break; case PROTMESSID_CLIENT_ID: - EvaluateClientIDMes ( vecbyMesBodyDataModified ); + EvaluateClientIDMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_CHANNEL_GAIN: - EvaluateChanGainMes ( vecbyMesBodyDataModified ); + EvaluateChanGainMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_CHANNEL_PAN: - EvaluateChanPanMes ( vecbyMesBodyDataModified ); + EvaluateChanPanMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_MUTE_STATE_CHANGED: - EvaluateMuteStateHasChangedMes ( vecbyMesBodyDataModified ); + EvaluateMuteStateHasChangedMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_CONN_CLIENTS_LIST: - EvaluateConClientListMes ( vecbyMesBodyDataModified ); + EvaluateConClientListMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_CONN_CLIENTS_LIST: @@ -808,7 +798,7 @@ qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified. break; case PROTMESSID_CHANNEL_INFOS: - EvaluateChanInfoMes ( vecbyMesBodyDataModified ); + EvaluateChanInfoMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_CHANNEL_INFOS: @@ -816,11 +806,11 @@ qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified. break; case PROTMESSID_CHAT_TEXT: - EvaluateChatTextMes ( vecbyMesBodyDataModified ); + EvaluateChatTextMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_NETW_TRANSPORT_PROPS: - EvaluateNetwTranspPropsMes ( vecbyMesBodyDataModified ); + EvaluateNetwTranspPropsMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_NETW_TRANSPORT_PROPS: @@ -836,19 +826,19 @@ qDebug() << "iRecIDModified: " << iRecIDModified << ", vecbyMesBodyDataModified. break; case PROTMESSID_LICENCE_REQUIRED: - EvaluateLicenceRequiredMes ( vecbyMesBodyDataModified ); + EvaluateLicenceRequiredMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_REQ_CHANNEL_LEVEL_LIST: - EvaluateReqChannelLevelListMes ( vecbyMesBodyDataModified ); + EvaluateReqChannelLevelListMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_VERSION_AND_OS: - EvaluateVersionAndOSMes ( vecbyMesBodyDataModified ); + EvaluateVersionAndOSMes ( vecbyMesBodyDataRef ); break; case PROTMESSID_RECORDER_STATE: - EvaluateRecorderStateMes ( vecbyMesBodyDataModified ); + EvaluateRecorderStateMes ( vecbyMesBodyDataRef ); break; } } @@ -2825,9 +2815,11 @@ bool CProtocol::ParseMessageFrame ( const CVector& vecbyData, bool CProtocol::ParseSplitMessageContainer ( const CVector& vecbyData, CVector& vecbyMesBodyData, + const int iSplitMessageDataIndex, int& iID, int& iNumParts, - int& iSplitCnt ) + int& iSplitCnt, + int& iCurPartSize ) { int iPos = 0; // init position pointer const int iDataLen = vecbyData.Size(); @@ -2849,17 +2841,17 @@ bool CProtocol::ParseSplitMessageContainer ( const CVector& vecbyData, // Extract actual data ----------------------------------------------------- + iCurPartSize = iDataLen - 4; - const int iLenBy = iDataLen - 4; - -// TODO this memory allocation is done in the real time thread but should be -// done in the low priority protocol management thread - - vecbyMesBodyData.Init ( iLenBy ); + // the memory must be allocated outside this function -> check the size + if ( vecbyMesBodyData.Size() < iSplitMessageDataIndex + iCurPartSize ) + { + return true; // return error code + } - for ( int i = 0; i < iLenBy; i++ ) + for ( int i = 0; i < iCurPartSize; i++ ) { - vecbyMesBodyData[i] = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); + vecbyMesBodyData[iSplitMessageDataIndex + i] = static_cast ( GetValFromStream ( vecbyData, iPos, 1 ) ); } return false; // no error diff --git a/src/protocol.h b/src/protocol.h index eaece11453..8ce1116b99 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -224,9 +224,11 @@ class CProtocol : public QObject bool ParseSplitMessageContainer ( const CVector& vecbyData, CVector& vecbyMesBodyData, + const int iSplitMessageDataIndex, int& iID, int& iNumParts, - int& iSplitCnt ); + int& iSplitCnt, + int& iCurPartSize ); void PutValOnStream ( CVector& vecIn, int& iPos, @@ -311,8 +313,9 @@ class CProtocol : public QObject QTimer TimerSendMess; QMutex Mutex; - CVector vecvecbySplitMessageStorage[MAX_NUM_MESS_SPLIT_PARTS]; + CVector vecbySplitMessageStorage; int iSplitMessageCnt; + int iSplitMessageDataIndex; bool bSplitMessageSupported; public slots: From 5cfc139c37256f5ba12db4886b28f64a1766bfd4 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Thu, 10 Sep 2020 20:59:26 +0200 Subject: [PATCH 12/13] fixes proposed by pljones (thanks) --- src/protocol.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/protocol.cpp b/src/protocol.cpp index 4c182b84ec..2cffe5309b 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -59,8 +59,9 @@ SPLIT MESSAGE CONTAINER +------------+------------------------+------------------+--------------+ - ID is the message ID of the message being split -- split cnt is the counter which is incremented for each part of the message -- data is the data part of the original message which were split +- number of parts - total number of parts comprising the whole message +- split cnt - number within number total for this part of the message +- data - subset of the data part of the original message being split @@ -527,7 +528,7 @@ void CProtocol::CreateAndSendMessage ( const int iID, const int iDataLen = vecData.Size(); // check if message has to be split because it is too large - if ( ( iDataLen > MESS_SPLIT_PART_SIZE_BYTES ) && bSplitMessageSupported ) + if ( bSplitMessageSupported && ( iDataLen > MESS_SPLIT_PART_SIZE_BYTES ) ) { CVector vecNewSplitMessage; int iStartIndexInData = 0; // init index From 6292211d0186599f66cb89c3b7c784bb6d9a8ccf Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Fri, 11 Sep 2020 20:07:07 +0200 Subject: [PATCH 13/13] fixed a compilation problem --- src/protocol.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/protocol.h b/src/protocol.h index 8ce1116b99..8afbf10f3e 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "global.h" #include "util.h"