// File: /workspace/github_cpp_makefile_star2_O1/rellla[P]E3DC-Rscp/RscpMain.cpp
// Function: receiveLoop(bool&)
static void receiveLoop(bool & bStopExecution)
{
    //--------------------------------------------------------------------------------------------------------------
    // RSCP Receive Frame Block Data
    //--------------------------------------------------------------------------------------------------------------
    // setup a static dynamic buffer which is dynamically expanded (re-allocated) on demand
    // the data inside this buffer is not released when this function is left
    static int iReceivedBytes = 0;
    static std::vector < uint8_t > vecDynamicBuffer;
    int isAuthRequest = 0;

    // check how many RSCP frames are received, must be at least 1
    // multiple frames can only occur in this example if one or more frames are received with a big time delay
    // this should usually not occur but handling this is shown in this example
    int iReceivedRscpFrames = 0;
    while (!bStopExecution
	   && ((iReceivedBytes > 0) || iReceivedRscpFrames == 0)) {
	// check and expand buffer
	if ((vecDynamicBuffer.size() - iReceivedBytes) < 4096) {
	    // check maximum size
	    if (vecDynamicBuffer.size() > RSCP_MAX_FRAME_LENGTH) {
		// something went wrong and the size is more than possible by the RSCP protocol
		printf
		    ("Maximum buffer size exceeded %i\n",
		     vecDynamicBuffer.size());
		bStopExecution = true;
		break;
	    }
	    // increase buffer size by 4096 bytes each time the remaining size is smaller than 4096
	    vecDynamicBuffer.resize(vecDynamicBuffer.size() + 4096);
	}
	// receive data
	int iResult = SocketRecvData(iSocket,
				     &vecDynamicBuffer[0] + iReceivedBytes,
				     vecDynamicBuffer.size() -
				     iReceivedBytes);
	if (iResult < 0) {
	    // check errno for the error code to detect if this is a timeout or a socket error
	    if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
		// receive timed out -> continue with re-sending the initial block
		printf("Response receive timeout (retry)\n");
		break;
	    }
	    // socket error -> check errno for failure code if needed
	    printf("Socket receive error. errno %i\n", errno);
	    bStopExecution = true;
	    break;
	} else if (iResult == 0) {
	    // connection was closed regularly by peer
	    // if this happens on startup each time the possible reason is
	    // wrong AES password or wrong network subnet (adapt hosts.allow file required)
	    printf("Connection closed by peer\n");
	    bStopExecution = true;
	    break;
	}
	// increment amount of received bytes
	iReceivedBytes += iResult;

	// process all received frames
	while (!bStopExecution) {
	    // round down to a multiple of AES_BLOCK_SIZE
	    int iLength = ROUNDDOWN(iReceivedBytes, AES_BLOCK_SIZE);
	    // if not even 32 bytes were received then the frame is still incomplete
	    if (iLength == 0) {
		break;
	    }
	    // resize temporary decryption buffer
	    std::vector < uint8_t > decryptionBuffer;
	    decryptionBuffer.resize(iLength);
	    // initialize encryption sequence IV value with value of previous block
	    aesDecrypter.SetIV(ucDecryptionIV, AES_BLOCK_SIZE);
	    // decrypt data from vecDynamicBuffer to temporary decryptionBuffer
	    aesDecrypter.Decrypt(&vecDynamicBuffer[0],
				 &decryptionBuffer[0],
				 iLength / AES_BLOCK_SIZE);

	    // data was received, check if we received all data
	    int iProcessedBytes =
		processReceiveBuffer(&decryptionBuffer[0],
				     iLength,
				     &isAuthRequest);
	    if (iProcessedBytes < 0) {
		// an error occured;
		printf("Error parsing RSCP frame: %i\n", iProcessedBytes);
		// stop execution as the data received is not RSCP data
		bStopExecution = true;
		break;

	    } else if (iProcessedBytes > 0) {
		// round up the processed bytes as iProcessedBytes does not include the zero padding bytes
		iProcessedBytes = ROUNDUP(iProcessedBytes, AES_BLOCK_SIZE);
		// store the IV value from encrypted buffer for next block decryption
		memcpy(ucDecryptionIV,
		       &vecDynamicBuffer[0] +
		       iProcessedBytes - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
		// move the encrypted data behind the current frame data (if any received) to the front
		memcpy(&vecDynamicBuffer[0],
		       &vecDynamicBuffer[0] +
		       iProcessedBytes,
		       vecDynamicBuffer.size() - iProcessedBytes);
		// decrement the total received bytes by the amount of processed bytes
		iReceivedBytes -= iProcessedBytes;
		// increment a counter that a valid frame was received and
		// continue parsing process in case a 2nd valid frame is in the buffer as well
		iReceivedRscpFrames++;
		if (!isAuthRequest) {
		    printf
			("Successfully received %i RscpFrames\n",
			 iReceivedRscpFrames);
		    bStopExecution = true;
		}
	    } else {
		// iProcessedBytes is 0
		// not enough data of the next frame received, go back to receive mode if iReceivedRscpFrames == 0
		// or transmit mode if iReceivedRscpFrames > 0
		break;
	    }
	}
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rdi, 0x10(%rsp)
movb 0x108d4(%rip), %al      # 0x146d0
testb %al, %al
je 0x4132
leaq 0x18(%rsp), %r14
movl $0x0, (%r14)
leaq 0x38(%rsp), %rbp
movabsq $-0x1111111111111111, %r15 # imm = 0xEEEEEEEEEEEEEEEF
movl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %rax
cmpb $0x0, (%rax)
jne 0x4123
movslq 0x10874(%rip), %rax     # 0x146b0
testq %rax, %rax
jg 0x3e4c
cmpl $0x0, 0xc(%rsp)
jne 0x4123
movq 0x1086d(%rip), %rsi     # 0x146c0
subq 0x1085e(%rip), %rsi     # 0x146b8
movq %rsi, %rcx
subq %rax, %rcx
cmpq $0xfff, %rcx            # imm = 0xFFF
ja 0x3e89
cmpq $0x10016, %rsi          # imm = 0x10016
jae 0x410d
addq $0x1000, %rsi           # imm = 0x1000
leaq 0x10834(%rip), %rdi     # 0x146b8
callq 0x4aa0
movl 0x102d1(%rip), %edi     # 0x14160
movq 0x10822(%rip), %rax     # 0x146b8
movslq 0x10813(%rip), %rsi     # 0x146b0
movl 0x1081d(%rip), %edx     # 0x146c0
subl %eax, %edx
subl %esi, %edx
addq %rax, %rsi
callq 0xfc1e
testl %eax, %eax
js 0x40b9
je 0x40d3
addl %eax, 0x107ed(%rip)     # 0x146b0
movb $0x1, %bl
movq 0x10(%rsp), %rax
cmpb $0x0, (%rax)
jne 0x4103
movslq 0x107d6(%rip), %r12     # 0x146b0
movq %r12, %r13
andq $-0x20, %r13
testl %r13d, %r13d
je 0x3fd5
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
leaq 0x20(%rsp), %rdi
movq %r13, %rsi
callq 0x4aa0
leaq 0x1054d(%rip), %rdi     # 0x1445c
leaq 0x1077a(%rip), %rsi     # 0x14690
movl $0x20, %edx
callq 0x603e
movq 0x10791(%rip), %rsi     # 0x146b8
movq 0x20(%rsp), %rdx
sarl $0x5, %r12d
movslq %r12d, %rcx
leaq 0x10522(%rip), %rdi     # 0x1445c
movl $0x1, %r8d
callq 0xf2d6
movq 0x20(%rsp), %r12
movq %rbp, %rdi
callq 0x4bf8
leaq 0x58(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movl %r13d, 0x1c(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
leaq 0x1c(%rsp), %rdx
leaq 0x40(%rsp), %rcx
callq 0x5346
movl %eax, %r13d
testl %eax, %eax
js 0x3fdd
movq 0x58(%rsp), %rax
cmpq %rax, 0x60(%rsp)
je 0x3fc6
xorl %ecx, %ecx
leaq (%rcx,%rcx,4), %rcx
leaq (%rcx,%rcx,2), %rsi
addq %rax, %rsi
movq %rbp, %rdi
movq %r14, %rdx
callq 0x3438
movl %r12d, %ecx
movq 0x58(%rsp), %rax
movq 0x60(%rsp), %rdx
subq %rax, %rdx
imulq %r15, %rdx
incl %r12d
cmpq %rcx, %rdx
ja 0x3f94
movq %rbp, %rdi
leaq 0x58(%rsp), %rsi
callq 0x554e
jmp 0x3fea
xorl %r12d, %r12d
jmp 0x40ae
cmpl $-0x5, %r13d
movl $0x0, %eax
cmovel %eax, %r13d
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x4001
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x2160
movq %rbp, %rdi
callq 0x4c04
testl %r13d, %r13d
setns %r12b
js 0x4070
je 0x407c
addl $0x1f, %r13d
andl $0x7fffffe0, %r13d      # imm = 0x7FFFFFE0
movq 0x10692(%rip), %rdi     # 0x146b8
leaq (%rdi,%r13), %rsi
movups -0x20(%rdi,%r13), %xmm0
movups -0x10(%rdi,%r13), %xmm1
movaps %xmm0, 0x10653(%rip)    # 0x14690
movaps %xmm1, 0x1065c(%rip)    # 0x146a0
movq 0x10675(%rip), %rdx     # 0x146c0
subq %rsi, %rdx
callq 0x20f0
subl %r13d, 0x10656(%rip)    # 0x146b0
movl 0xc(%rsp), %esi
incl %esi
cmpl $0x0, 0x18(%rsp)
movl %esi, 0xc(%rsp)
je 0x4081
movb $0x1, %r12b
jmp 0x4097
leaq 0xc563(%rip), %rdi      # 0x105da
movl %r13d, %esi
jmp 0x4088
xorl %r12d, %r12d
jmp 0x4097
leaq 0xc570(%rip), %rdi      # 0x105f8
xorl %eax, %eax
callq 0x2040
movq 0x10(%rsp), %rax
movb $0x1, (%rax)
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x40ae
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x2160
testb %r12b, %r12b
jne 0x3ec3
jmp 0x4103
callq 0x2030
movl (%rax), %esi
cmpl $0xb, %esi
jne 0x40eb
leaq 0xc5f1(%rip), %rdi      # 0x106bd
callq 0x21c0
jmp 0x40e7
leaq 0xc5c9(%rip), %rdi      # 0x106a3
callq 0x21c0
movq 0x10(%rsp), %rax
movb $0x1, (%rax)
xorl %ebx, %ebx
jmp 0x4103
xorl %ebx, %ebx
leaq 0xc4c6(%rip), %rdi      # 0x105ba
xorl %eax, %eax
callq 0x2040
movq 0x10(%rsp), %rax
movb $0x1, (%rax)
testb %bl, %bl
jne 0x3e27
jmp 0x4123
leaq 0xc485(%rip), %rdi      # 0x10599
xorl %eax, %eax
callq 0x2040
movq 0x10(%rsp), %rax
movb $0x1, (%rax)
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x22bc
jmp 0x3e04
jmp 0x4147
jmp 0x4142
jmp 0x4147
movq %rax, %rbx
jmp 0x416b
movq %rax, %rbx
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x4161
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x2160
leaq 0x38(%rsp), %rdi
callq 0x4c04
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x4182
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x2160
movq %rbx, %rdi
callq 0x2240