// File: /workspace/github_cpp_makefile_star2_O2/rellla[P]E3DC-Rscp/RscpMain.cpp
// Function: handleResponseValue(RscpProtocol*, SRscpValue*, int*)
int handleResponseValue(RscpProtocol * protocol, SRscpValue * response,
			int *isAuthRequest)
{
    // check if any of the response has the error flag set and react accordingly
    if (response->dataType == RSCP::eTypeError) {
	// handle error for example access denied errors
	uint32_t uiErrorCode = protocol->getValueAsUInt32(response);
	printf("Tag 0x%08X received error code %u.\n",
	       response->tag, uiErrorCode);
	return -1;
    }
    // check the SRscpValue TAG to detect which response it is
    switch (response->tag) {
    case TAG_RSCP_AUTHENTICATION:{
	    // It is possible to check the response->dataType value to detect correct data type
	    // and call the correct function. If data type is known,
	    // the correct function can be called directly like in this case.
	    uint8_t ucAccessLevel = protocol->getValueAsUChar8(response);
	    if (ucAccessLevel > 0) {
		iAuthenticated = 1;
		*isAuthRequest = 1;
	    }
	    printf("RSCP authentitication level %i\n", ucAccessLevel);
	    break;
	}
    case TAG_EMS_POWER_PV:{
	    // response for TAG_EMS_REQ_POWER_PV
	    int32_t iPower = protocol->getValueAsInt32(response);
	    printf("EMS PV power is %i W\n", iPower);
	    break;
	}
    case TAG_EMS_POWER_BAT:{
	    // response for TAG_EMS_REQ_POWER_BAT
	    int32_t iPower = protocol->getValueAsInt32(response);
	    printf("EMS BAT power is %i W\n", iPower);
	    break;
	}
    case TAG_EMS_POWER_HOME:{
	    // response for TAG_EMS_REQ_POWER_HOME
	    int32_t iPower = protocol->getValueAsInt32(response);
	    printf("EMS house power is %i W\n", iPower);
	    break;
	}
    case TAG_EMS_POWER_GRID:{
	    // response for TAG_EMS_REQ_POWER_GRID
	    int32_t iPower = protocol->getValueAsInt32(response);
	    printf("EMS grid power is %i W\n", iPower);
	    break;
	}
    case TAG_EMS_POWER_ADD:{
	    // response for TAG_EMS_REQ_POWER_ADD
	    int32_t iPower = protocol->getValueAsInt32(response);
	    printf("EMS add power meter power is %i W\n", iPower);
	    break;
	}
    case TAG_BAT_DATA:{
	    // response for TAG_REQ_BAT_DATA
	    std::vector < SRscpValue > batteryData =
		protocol->getValueAsContainer(response);
	    for (size_t i = 0; i < batteryData.size(); ++i) {
		if (batteryData[i].dataType == RSCP::eTypeError) {
		    // handle error for example access denied errors
		    uint32_t uiErrorCode =
			protocol->getValueAsUInt32(&batteryData[i]);
		    printf("Tag 0x%08X received error code %u.\n",
			   batteryData[i].tag, uiErrorCode);
		    return -1;
		}
		handleResponseBatData(protocol, &batteryData[i]);
	    }
	    protocol->destroyValueData(batteryData);
	    break;
	}
    case TAG_EMS_GET_POWER_SETTINGS:{
	    // response for TAG_EMS_REQ_GET_POWER_SETTINGS
	    std::vector < SRscpValue > emsData =
		protocol->getValueAsContainer(response);
	    for (size_t i = 0; i < emsData.size(); ++i) {
		if (emsData[i].dataType == RSCP::eTypeError) {
		    // handle error for example access denied errors
		    uint32_t uiErrorCode =
			protocol->getValueAsUInt32(&emsData[i]);
		    printf("Tag 0x%08X received error code %u.\n",
			   emsData[i].tag, uiErrorCode);
		    return -1;
		}
		// check each ems power settings sub tag
		switch (emsData[i].tag) {
		case TAG_EMS_POWER_LIMITS_USED:{
			int8_t weather_en =
			    protocol->getValueAsInt32(&emsData[i]);
			printf("EMS power limits used is %i.\n",
			       weather_en);
			break;
		    }
		case TAG_EMS_MAX_CHARGE_POWER:{
			int8_t weather_en =
			    protocol->getValueAsInt32(&emsData[i]);
			printf("EMS max charge power is %i.\n",
			       weather_en);
			break;
		    }
		case TAG_EMS_MAX_DISCHARGE_POWER:{
			int8_t weather_en =
			    protocol->getValueAsInt32(&emsData[i]);
			printf("EMS max discharge power is %i.\n",
			       weather_en);
			break;
		    }
		case TAG_EMS_DISCHARGE_START_POWER:{
			int8_t weather_en =
			    protocol->getValueAsInt32(&emsData[i]);
			printf("EMS discharge start power is %i.\n",
			       weather_en);
			break;
		    }
		case TAG_EMS_POWERSAVE_ENABLED:{
			int8_t weather_en =
			    protocol->getValueAsInt32(&emsData[i]);
			printf("EMS powersave enabled is %i.\n",
			       weather_en);
			break;
		    }
		case TAG_EMS_WEATHER_REGULATED_CHARGE_ENABLED:{
			int8_t weather_en =
			    protocol->getValueAsInt32(&emsData[i]);
			printf
			    ("EMS weather regulated charge enabled is %i.\n",
			     weather_en);
			break;
		    }
		case TAG_EMS_UNKNOWN:{
			int8_t weather_en =
			    protocol->getValueAsInt32(&emsData[i]);
			printf("EMS unknown is %i.\n", weather_en);
			break;
		    }
		    // ...
		default:
		    // default behaviour
		    printf("Unknown ems tag %08X\n", emsData[i].tag);
		    break;
		}
	    }
	    protocol->destroyValueData(emsData);
	    break;
	}
    case TAG_EMS_SET_POWER_SETTINGS:{
	    // resposne for TAG_EMS_REQ_SET_POWER_SETTINGS
	    std::vector < SRscpValue > emsData =
		protocol->getValueAsContainer(response);
	    for (size_t i = 0; i < emsData.size(); ++i) {
		if (emsData[i].dataType == RSCP::eTypeError) {
		    // handle error for example access denied errors
		    uint32_t uiErrorCode =
			protocol->getValueAsUInt32(&emsData[i]);
		    printf("Tag 0x%08X received error code %u.\n",
			   emsData[i].tag, uiErrorCode);
		    return -1;
		}
		// check each battery sub tag
		switch (emsData[i].tag) {
		case TAG_EMS_RES_WEATHER_REGULATED_CHARGE_ENABLED:{
			int8_t weather_en =
			    protocol->getValueAsInt32(&emsData[i]);
			printf
			    ("Weather regulated charge response: %i\n",
			     weather_en);
			break;
		    }
		default:
		    // default behaviour
		    printf("Unknown ems tag %08X\n", emsData[i].tag);
		    break;
		}
	    }
	    protocol->destroyValueData(emsData);
	    break;
	}
    case TAG_EMS_GET_IDLE_PERIODS:{
	    // resposne for TAG_EMS_REQ_GET_IDLE_PERIODS
	    std::vector < SRscpValue > emsData =
		protocol->getValueAsContainer(response);
	    idle_period_t periods[14];
	    for (size_t i = 0; i < emsData.size(); ++i) {
		if (emsData[i].dataType == RSCP::eTypeError) {
		    // handle error for example access denied errors
		    uint32_t uiErrorCode =
			protocol->getValueAsUInt32(&emsData[i]);
		    printf("Tag 0x%08X received error code %u.\n",
			   emsData[i].tag, uiErrorCode);
		    return -1;
		}
		handleResponseEMSGetIdlePeriods(protocol, &emsData[i], &periods[i]);
	    }
	    break;
	}
    default:
	// default behavior
	uint8_t unknown = protocol->getValueAsUChar8(response);
	printf("Unknown tag %08X -> %i.\n", response->tag, unknown);
	break;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rsi, %r14
movq %rdi, %rbx
cmpb $-0x1, 0x4(%rsi)
je 0x2ea9
movl (%r14), %eax
cmpl $0x1800080, %eax        # imm = 0x1800080
je 0x2fd7
cmpl $0x180008b, %eax        # imm = 0x180008B
je 0x2ecc
cmpl $0x180008c, %eax        # imm = 0x180008C
jne 0x3039
leaq 0x20(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3f18
pushq $0xf
popq %r13
leaq 0xc615(%rip), %r14      # 0xf459
leaq 0xc5f8(%rip), %r15      # 0xf443
xorl %r12d, %r12d
xorl %ebp, %ebp
movq 0x20(%rsp), %rcx
movq 0x28(%rsp), %rax
subq %rcx, %rax
cqto
idivq %r13
cmpq %rax, %rbp
jae 0x308e
leaq (%rcx,%r12), %rsi
cmpb $-0x1, 0x4(%rcx,%r12)
je 0x30af
movl (%rsi), %eax
cmpl $0x1800105, %eax        # imm = 0x1800105
jne 0x2e94
movq %rbx, %rdi
callq 0x41d6
movsbl %al, %esi
movq %r14, %rdi
jmp 0x2e99
movq %r15, %rdi
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
incq %rbp
addq $0xf, %r12
jmp 0x2e50
movq %rbx, %rdi
movq %r14, %rsi
callq 0x413a
movl (%r14), %esi
leaq 0xc1f2(%rip), %rdi      # 0xf0b0
movl %eax, %edx
xorl %eax, %eax
callq 0x2040
jmp 0x3102
leaq 0x20(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3f18
pushq $0xf
popq %r13
leaq 0xc179(%rip), %r14      # 0xf060
leaq 0xc541(%rip), %r12      # 0xf42f
xorl %ebp, %ebp
xorl %r15d, %r15d
movq 0x20(%rsp), %rcx
movq 0x28(%rsp), %rax
subq %rcx, %rax
cqto
idivq %r13
cmpq %rax, %r15
jae 0x307f
leaq (%rcx,%rbp), %rsi
cmpb $-0x1, 0x4(%rcx,%rbp)
je 0x309d
movl (%rsi), %eax
leal -0x1000100(%rax), %ecx
cmpl $0x6, %ecx
ja 0x2f83
movslq (%r14,%rcx,4), %rax
addq %r14, %rax
jmpq *%rax
movq %rbx, %rdi
callq 0x41d6
movsbl %al, %esi
leaq 0xc422(%rip), %rdi      # 0xf367
jmp 0x2fc4
movq %rbx, %rdi
callq 0x41d6
movsbl %al, %esi
leaq 0xc48b(%rip), %rdi      # 0xf3e4
jmp 0x2fc4
movq %rbx, %rdi
callq 0x41d6
movsbl %al, %esi
leaq 0xc435(%rip), %rdi      # 0xf3a2
jmp 0x2fc4
movq %rbx, %rdi
callq 0x41d6
movsbl %al, %esi
leaq 0xc441(%rip), %rdi      # 0xf3c2
jmp 0x2fc4
leaq 0xc4b9(%rip), %rdi      # 0xf443
movl %eax, %esi
jmp 0x2fc4
movq %rbx, %rdi
callq 0x41d6
movsbl %al, %esi
leaq 0xc3e5(%rip), %rdi      # 0xf385
jmp 0x2fc4
movq %rbx, %rdi
callq 0x41d6
movsbl %al, %esi
leaq 0xc44e(%rip), %rdi      # 0xf402
jmp 0x2fc4
movq %rbx, %rdi
callq 0x41d6
movsbl %al, %esi
movq %r12, %rdi
xorl %eax, %eax
callq 0x2040
incq %r15
addq $0xf, %rbp
jmp 0x2ef3
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3f18
leaq 0x20(%rsp), %r14
xorl %r15d, %r15d
pushq $0xf
popq %r12
xorl %r13d, %r13d
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
subq %rcx, %rax
cqto
idivq %r12
cmpq %rax, %r13
jae 0x30f8
leaq (%rcx,%r15), %rsi
cmpb $-0x1, 0x4(%rcx,%r15)
je 0x30d7
movq %rbx, %rdi
movq %r14, %rdx
callq 0x29a6
incq %r13
addq $0xf, %r15
addq $0x7, %r14
jmp 0x2ff6
cmpl $0x3840000, %eax        # imm = 0x3840000
jne 0x312e
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3f18
movq (%r15), %rsi
cmpq %rsi, 0x8(%r15)
je 0x3117
cmpb $-0x1, 0x4(%rsi)
jne 0x3126
movq %rbx, %rdi
callq 0x413a
movq 0x20(%rsp), %rcx
movl (%rcx), %esi
jmp 0x30c0
leaq 0x20(%rsp), %rsi
movq %rbx, %rdi
callq 0x4aec
jmp 0x30d0
leaq 0x20(%rsp), %rsi
movq %rbx, %rdi
callq 0x4aec
jmp 0x30d0
movq %rbx, %rdi
callq 0x413a
movq 0x20(%rsp), %rcx
movl (%rcx,%rbp), %esi
jmp 0x30c0
movq %rbx, %rdi
callq 0x413a
movq 0x20(%rsp), %rcx
movl (%rcx,%r12), %esi
leaq 0xbfe9(%rip), %rdi      # 0xf0b0
movl %eax, %edx
xorl %eax, %eax
callq 0x2040
leaq 0x20(%rsp), %rdi
jmp 0x30fd
movq %rbx, %rdi
callq 0x413a
movq 0x8(%rsp), %rcx
movl (%rcx,%r15), %esi
leaq 0xbfc1(%rip), %rdi      # 0xf0b0
movl %eax, %edx
xorl %eax, %eax
callq 0x2040
leaq 0x8(%rsp), %rdi
callq 0x4050
pushq $-0x1
popq %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x20(%rsp), %rsi
movq %rbx, %rdi
callq 0x4aec
jmp 0x30d0
movq %rbx, %rdi
callq 0x2d1f
leal -0x1800001(%rax), %ecx
cmpl $0x4, %ecx
jbe 0x316f
cmpl $0x800001, %eax         # imm = 0x800001
jne 0x3193
movq %rdx, %r15
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4178
testb %al, %al
je 0x3160
movb $0x1, 0x1052f(%rip)     # 0x13688
movl $0x1, (%r15)
movzbl %al, %esi
leaq 0xc15c(%rip), %rdi      # 0xf2c6
jmp 0x3202
leaq 0xbed6(%rip), %rax      # 0xf04c
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3f78
leaq 0xc155(%rip), %rdi      # 0xf2e6
jmp 0x3200
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3f6c
movl (%r14), %esi
movzbl %al, %edx
leaq 0xc2d5(%rip), %rdi      # 0xf480
xorl %eax, %eax
callq 0x2040
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3f78
leaq 0xc138(%rip), %rdi      # 0xf2fc
jmp 0x3200
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3f78
leaq 0xc13b(%rip), %rdi      # 0xf313
jmp 0x3200
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3f78
leaq 0xc140(%rip), %rdi      # 0xf32c
jmp 0x3200
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3f78
leaq 0xc144(%rip), %rdi      # 0xf344
movl %eax, %esi
xorl %eax, %eax
callq 0x2040
jmp 0x320f
jmp 0x320f
jmp 0x320f
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
jmp 0x3221
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x4050
movq %rbx, %rdi
callq 0x2280