// File: /workspace/github_cpp_makefile_star2_O2/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 0x102d0(%rip), %al      # 0x136f0
testb %al, %al
je 0x3701
leaq 0x18(%rsp), %r15
andl $0x0, (%r15)
leaq 0x58(%rsp), %r14
leaq 0x38(%rsp), %r12
pushq $0xf
popq %rbx
movl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %rax
cmpb $0x0, (%rax)
jne 0x36f2
movslq 0x10275(%rip), %rsi     # 0x136d0
testq %rsi, %rsi
setg %al
cmpl $0x0, 0xc(%rsp)
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x36f2
movq 0x10265(%rip), %rdx     # 0x136e0
movq 0x10256(%rip), %rax     # 0x136d8
subq %rax, %rdx
movq %rdx, %rcx
subq %rsi, %rcx
cmpq $0xfff, %rcx            # imm = 0xFFF
ja 0x34d3
cmpq $0x10016, %rdx          # imm = 0x10016
jae 0x36c9
addq $0x1000, %rdx           # imm = 0x1000
leaq 0x10229(%rip), %rdi     # 0x136d8
movq %rdx, %rsi
callq 0x3f7e
movq 0x1021a(%rip), %rax     # 0x136d8
movl 0x1020c(%rip), %ecx     # 0x136d0
movq 0x10215(%rip), %rdx     # 0x136e0
movslq %ecx, %rsi
subq %rax, %rdx
jmp 0x34d5
movl %esi, %ecx
addq %rax, %rsi
movl 0xfca2(%rip), %edi      # 0x13180
subl %ecx, %edx
callq 0xebb8
testl %eax, %eax
js 0x36a1
je 0x36bb
addl %eax, 0x101d7(%rip)     # 0x136d0
movq 0x10(%rsp), %rax
cmpb $0x0, (%rax)
jne 0x3446
movslq 0x101c2(%rip), %r13     # 0x136d0
movq %r13, %rbp
andq $-0x20, %rbp
testl %ebp, %ebp
je 0x3446
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
andq $0x0, 0x30(%rsp)
leaq 0x20(%rsp), %rdi
movq %rbp, %rsi
callq 0x3f7e
leaq 0xff3d(%rip), %rdi      # 0x1347c
leaq 0x1016a(%rip), %rsi     # 0x136b0
pushq $0x20
popq %rdx
callq 0x54ba
movq 0x10183(%rip), %rsi     # 0x136d8
movq 0x20(%rsp), %rdx
sarl $0x5, %r13d
movslq %r13d, %rcx
leaq 0xff14(%rip), %rdi      # 0x1347c
pushq $0x1
popq %r8
callq 0xe53a
movq 0x20(%rsp), %r13
movq %r12, %rdi
callq 0x4380
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
andq $0x0, 0x10(%r14)
movl %ebp, 0x1c(%rsp)
movq %r12, %rdi
movq %r13, %rsi
leaq 0x1c(%rsp), %rdx
leaq 0x40(%rsp), %rcx
callq 0x493a
movl %eax, %ebp
testl %eax, %eax
js 0x35e7
movl %r13d, %r13d
movq 0x58(%rsp), %rsi
movq 0x60(%rsp), %rax
subq %rsi, %rax
cqto
idivq %rbx
cmpq %r13, %rax
jbe 0x35da
imulq $0xf, %r13, %rax
addq %rax, %rsi
movq %r12, %rdi
movq %r15, %rdx
callq 0x2de4
incl %r13d
jmp 0x35a9
movq %r12, %rdi
movq %r14, %rsi
callq 0x4aec
jmp 0x35f2
cmpl $-0x5, %ebp
movl $0x0, %eax
cmovel %eax, %ebp
movq %r14, %rdi
callq 0x4050
movq %r12, %rdi
callq 0x438c
testl %ebp, %ebp
setns %r13b
js 0x3663
je 0x366e
addl $0x1f, %ebp
andl $0x7fffffe0, %ebp       # imm = 0x7FFFFFE0
movq 0x100bc(%rip), %rdi     # 0x136d8
leaq (%rdi,%rbp), %rsi
movups -0x20(%rdi,%rbp), %xmm0
movups -0x10(%rdi,%rbp), %xmm1
movaps %xmm0, 0x1007f(%rip)    # 0x136b0
movaps %xmm1, 0x10088(%rip)    # 0x136c0
movq 0x100a1(%rip), %rdx     # 0x136e0
subq %rsi, %rdx
callq 0x2120
subl %ebp, 0x10083(%rip)     # 0x136d0
movl 0xc(%rsp), %esi
incl %esi
cmpl $0x0, 0x18(%rsp)
movl %esi, 0xc(%rsp)
je 0x3673
movb $0x1, %r13b
jmp 0x3689
leaq 0xbfa1(%rip), %rdi      # 0xf60b
movl %ebp, %esi
jmp 0x367a
xorl %r13d, %r13d
jmp 0x3689
leaq 0xbfaf(%rip), %rdi      # 0xf629
xorl %eax, %eax
callq 0x2040
movq 0x10(%rsp), %rax
movb $0x1, (%rax)
leaq 0x20(%rsp), %rdi
callq 0x4214
testb %r13b, %r13b
jne 0x34f9
jmp 0x3446
callq 0x2030
movl (%rax), %esi
cmpl $0xb, %esi
jne 0x36dc
leaq 0xc03a(%rip), %rdi      # 0xf6ee
callq 0x2210
jmp 0x36f2
leaq 0xc012(%rip), %rdi      # 0xf6d4
callq 0x2210
jmp 0x36ea
leaq 0xbefa(%rip), %rdi      # 0xf5ca
movq %rdx, %rsi
xorl %eax, %eax
callq 0x2040
jmp 0x36ea
leaq 0xbf08(%rip), %rdi      # 0xf5eb
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
leaq 0xffe8(%rip), %rdi      # 0x136f0
callq 0x22a0
testl %eax, %eax
je 0x3428
xorps %xmm0, %xmm0
movups %xmm0, 0xffb9(%rip)     # 0x136d8
andq $0x0, 0xffc1(%rip)      # 0x136e8
leaq 0xffaa(%rip), %rsi      # 0x136d8
leaq 0x875(%rip), %rdi       # 0x3faa
leaq 0xfa3c(%rip), %rdx      # 0x13178
callq 0x2140
leaq 0xffa8(%rip), %rdi      # 0x136f0
callq 0x20f0
jmp 0x3428
jmp 0x375d
jmp 0x375d
jmp 0x3758
movq %rax, %rbx
jmp 0x3772
movq %rax, %rbx
movq %r14, %rdi
callq 0x4050
leaq 0x38(%rsp), %rdi
callq 0x438c
leaq 0x20(%rsp), %rdi
callq 0x4214
movq %rbx, %rdi
callq 0x2280