// File: rellla[P]E3DC-Rscp/RscpMain.cpp
// Function: createRequest(SRscpFrameBuffer*, int)
int createRequest(SRscpFrameBuffer * frameBuffer, int requests)
{
    RscpProtocol protocol;
    SRscpValue rootValue;
    // The root container is create with the TAG ID 0 which is not used by any device.
    protocol.createContainerValue(&rootValue, 0);

    //---------------------------------------------------------------------------------------------------------
    // Create a request frame
    //---------------------------------------------------------------------------------------------------------
    printf("\nRequest data:\n");

    // request power data information
    if (requests & TAG_EMS) {
	protocol.appendValue(&rootValue, TAG_EMS_REQ_POWER_PV);
	protocol.appendValue(&rootValue, TAG_EMS_REQ_POWER_BAT);
	protocol.appendValue(&rootValue, TAG_EMS_REQ_POWER_HOME);
	protocol.appendValue(&rootValue, TAG_EMS_REQ_POWER_GRID);
	protocol.appendValue(&rootValue, TAG_EMS_REQ_POWER_ADD);
	protocol.appendValue(&rootValue, TAG_EMS_REQ_GET_POWER_SETTINGS);
	protocol.appendValue(&rootValue, TAG_EMS_REQ_STATUS);
	protocol.appendValue(&rootValue, TAG_EMS_REQ_MODE);
    }

    // request idle periods information
    if (requests & TAG_GET_IDLE_PERIODS) {
	protocol.appendValue(&rootValue, TAG_EMS_REQ_GET_IDLE_PERIODS);
    }

    // request battery information
    if (requests & TAG_BATTERY) {
	SRscpValue batteryContainer;
	protocol.createContainerValue(&batteryContainer, TAG_BAT_REQ_DATA);
	protocol.appendValue(&batteryContainer, TAG_BAT_INDEX, (uint8_t) 0);
	protocol.appendValue(&batteryContainer, TAG_BAT_REQ_RSOC);
	protocol.appendValue(&batteryContainer, TAG_BAT_REQ_MODULE_VOLTAGE);
	protocol.appendValue(&batteryContainer, TAG_BAT_REQ_CURRENT);
	protocol.appendValue(&batteryContainer, TAG_BAT_REQ_STATUS_CODE);
	protocol.appendValue(&batteryContainer, TAG_BAT_REQ_ERROR_CODE);
	// append sub-container to root container
	protocol.appendValue(&rootValue, batteryContainer);
	// free memory of sub-container as it is now copied to rootValue
	protocol.destroyValueData(batteryContainer);
    }

    // request some more power data information
    if (requests & TAG_WEATHER_ENABLE) {
	SRscpValue powerContainer;
	uint8_t enable = !!(requests & TAG_WEATHER_ENABLE_F);
	protocol.createContainerValue(&powerContainer,
				      TAG_EMS_REQ_SET_POWER_SETTINGS);
	protocol.appendValue(&powerContainer,
			     TAG_EMS_WEATHER_REGULATED_CHARGE_ENABLED,
			     enable);
	protocol.appendValue(&rootValue, powerContainer);
	protocol.destroyValueData(powerContainer);
    }

    // request setting idle periods
    // this is WIP and some example values are hardcoded for now
    // this is not useable for productive environments atm
    if (requests & TAG_SET_IDLE_PERIODS) {
	SRscpValue setTimeContainer;
	protocol.createContainerValue(&setTimeContainer,
				      TAG_EMS_REQ_SET_IDLE_PERIODS);

	    SRscpValue setDayContainer;
	    protocol.createContainerValue(&setDayContainer,
					  TAG_EMS_IDLE_PERIOD);
	    protocol.appendValue(&setDayContainer,
				 TAG_EMS_IDLE_PERIOD_TYPE, (uint8_t)LOAD);
	    protocol.appendValue(&setDayContainer,
				 TAG_EMS_IDLE_PERIOD_DAY, (uint8_t)TUESDAY);
	    protocol.appendValue(&setDayContainer,
				 TAG_EMS_IDLE_PERIOD_ACTIVE, (bool)ACTIVE);

		SRscpValue setStartContainer;
		protocol.createContainerValue(&setStartContainer,
					  TAG_EMS_IDLE_PERIOD_START);
		protocol.appendValue(&setStartContainer,
				 TAG_EMS_IDLE_PERIOD_MINUTE, (uint8_t)00);
		protocol.appendValue(&setStartContainer,
				 TAG_EMS_IDLE_PERIOD_HOUR, (uint8_t)11);
		protocol.appendValue(&setDayContainer, setStartContainer);
		protocol.destroyValueData(setStartContainer);

		SRscpValue setStopContainer;
		protocol.createContainerValue(&setStopContainer,
					  TAG_EMS_IDLE_PERIOD_END);
		protocol.appendValue(&setStopContainer,
				 TAG_EMS_IDLE_PERIOD_MINUTE, (uint8_t)42);
		protocol.appendValue(&setStopContainer,
				 TAG_EMS_IDLE_PERIOD_HOUR, (uint8_t)12);
		protocol.appendValue(&setDayContainer, setStopContainer);
		protocol.destroyValueData(setStopContainer);

	    protocol.appendValue(&setTimeContainer, setDayContainer);
	    protocol.destroyValueData(setDayContainer);

	protocol.appendValue(&rootValue, setTimeContainer);
	protocol.destroyValueData(setTimeContainer);
    }

    // create buffer frame to send data to the S10
    protocol.createFrameAsBuffer(frameBuffer, rootValue.data, rootValue.length, true);	// true to calculate CRC on for transfer
    // the root value object should be destroyed after the data is copied into the frameBuffer and is not needed anymore
    protocol.destroyValueData(rootValue);

    return 0;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x130(%rsp)
movl %esi, 0x12c(%rsp)
leaq 0x120(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x7840
movq 0x8(%rsp), %rdi
movl $0x0, 0x10c(%rsp)
leaq 0x111(%rsp), %rsi
leaq 0x10c(%rsp), %rdx
callq 0x5b30
jmp 0x25bf
leaq 0x1dae7(%rip), %rdi     # 0x200ad
xorl %eax, %eax
callq 0x2040
jmp 0x25cf
movl 0x12c(%rsp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x275a
movl $0x1000001, 0xf8(%rsp) # imm = 0x1000001
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
callq 0x5cf0
jmp 0x260c
movl $0x1000002, 0xf4(%rsp) # imm = 0x1000002
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xf4(%rsp), %rdx
callq 0x5cf0
jmp 0x2636
movl $0x1000003, 0xf0(%rsp) # imm = 0x1000003
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xf0(%rsp), %rdx
callq 0x5cf0
jmp 0x2660
movl $0x1000004, 0xec(%rsp) # imm = 0x1000004
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xec(%rsp), %rdx
callq 0x5cf0
jmp 0x268a
movl $0x1000005, 0xe8(%rsp) # imm = 0x1000005
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xe8(%rsp), %rdx
callq 0x5cf0
jmp 0x26b4
movl $0x100008b, 0xe4(%rsp) # imm = 0x100008B
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xe4(%rsp), %rdx
callq 0x5cf0
jmp 0x26de
movl $0x1000040, 0xe0(%rsp) # imm = 0x1000040
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xe0(%rsp), %rdx
callq 0x5cf0
jmp 0x2708
movl $0x1000011, 0xdc(%rsp) # imm = 0x1000011
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xdc(%rsp), %rdx
callq 0x5cf0
jmp 0x2732
jmp 0x275a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x7860
jmp 0x2cb5
movl 0x12c(%rsp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x2795
movl $0x1000080, 0xd8(%rsp) # imm = 0x1000080
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xd8(%rsp), %rdx
callq 0x5cf0
jmp 0x2793
jmp 0x2795
movl 0x12c(%rsp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x2916
movl $0x3040000, 0xc4(%rsp) # imm = 0x3040000
leaq 0x120(%rsp), %rdi
leaq 0xc9(%rsp), %rsi
leaq 0xc4(%rsp), %rdx
callq 0x5b30
jmp 0x27d2
movl $0x3040001, 0xc0(%rsp) # imm = 0x3040001
movb $0x0, 0xbf(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0xc9(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
leaq 0xbf(%rsp), %rcx
callq 0x5d40
jmp 0x280c
movl $0x3000001, 0xb8(%rsp) # imm = 0x3000001
leaq 0x120(%rsp), %rdi
leaq 0xc9(%rsp), %rsi
leaq 0xb8(%rsp), %rdx
callq 0x5cf0
jmp 0x2836
movl $0x3000002, 0xb4(%rsp) # imm = 0x3000002
leaq 0x120(%rsp), %rdi
leaq 0xc9(%rsp), %rsi
leaq 0xb4(%rsp), %rdx
callq 0x5cf0
jmp 0x2860
movl $0x3000003, 0xb0(%rsp) # imm = 0x3000003
leaq 0x120(%rsp), %rdi
leaq 0xc9(%rsp), %rsi
leaq 0xb0(%rsp), %rdx
callq 0x5cf0
jmp 0x288a
movl $0x300000a, 0xac(%rsp) # imm = 0x300000A
leaq 0x120(%rsp), %rdi
leaq 0xc9(%rsp), %rsi
leaq 0xac(%rsp), %rdx
callq 0x5cf0
jmp 0x28b4
movl $0x300000b, 0xa8(%rsp) # imm = 0x300000B
leaq 0x120(%rsp), %rdi
leaq 0xc9(%rsp), %rsi
leaq 0xa8(%rsp), %rdx
callq 0x5cf0
jmp 0x28de
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0xc9(%rsp), %rdx
callq 0x5bf0
jmp 0x28fd
leaq 0x120(%rsp), %rdi
leaq 0xc9(%rsp), %rsi
callq 0x5cc0
jmp 0x2914
jmp 0x2916
movl 0x12c(%rsp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x29d1
movl 0x12c(%rsp), %eax
andl $0x10, %eax
shrl $0x4, %eax
movb %al, 0x98(%rsp)
movl $0x100008c, 0x94(%rsp) # imm = 0x100008C
leaq 0x120(%rsp), %rdi
leaq 0x99(%rsp), %rsi
leaq 0x94(%rsp), %rdx
callq 0x5b30
jmp 0x2967
movl $0x1000105, 0x90(%rsp) # imm = 0x1000105
leaq 0x120(%rsp), %rdi
leaq 0x99(%rsp), %rsi
leaq 0x90(%rsp), %rdx
leaq 0x98(%rsp), %rcx
callq 0x5d40
jmp 0x2999
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0x99(%rsp), %rdx
callq 0x5bf0
jmp 0x29b8
leaq 0x120(%rsp), %rdi
leaq 0x99(%rsp), %rsi
callq 0x5cc0
jmp 0x29cf
jmp 0x29d1
movl 0x12c(%rsp), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x2c5a
movl $0x1000081, 0x7c(%rsp)  # imm = 0x1000081
leaq 0x120(%rsp), %rdi
leaq 0x81(%rsp), %rsi
leaq 0x7c(%rsp), %rdx
callq 0x5b30
jmp 0x2a08
movl $0x1000082, 0x68(%rsp)  # imm = 0x1000082
leaq 0x120(%rsp), %rdi
leaq 0x6d(%rsp), %rsi
leaq 0x68(%rsp), %rdx
callq 0x5b30
jmp 0x2a29
movl $0x1000083, 0x64(%rsp)  # imm = 0x1000083
movb $0x0, 0x63(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x6d(%rsp), %rsi
leaq 0x64(%rsp), %rdx
leaq 0x63(%rsp), %rcx
callq 0x5d40
jmp 0x2a54
movl $0x1000084, 0x5c(%rsp)  # imm = 0x1000084
movb $0x1, 0x5b(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x6d(%rsp), %rsi
leaq 0x5c(%rsp), %rdx
leaq 0x5b(%rsp), %rcx
callq 0x5d40
jmp 0x2a7f
movl $0x1000089, 0x54(%rsp)  # imm = 0x1000089
movb $0x1, 0x53(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x6d(%rsp), %rsi
leaq 0x54(%rsp), %rdx
leaq 0x53(%rsp), %rcx
callq 0x5d90
jmp 0x2aaa
movl $0x1000085, 0x40(%rsp)  # imm = 0x1000085
leaq 0x120(%rsp), %rdi
leaq 0x44(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0x5b30
jmp 0x2acb
movl $0x1000088, 0x3c(%rsp)  # imm = 0x1000088
movb $0x0, 0x3b(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x44(%rsp), %rsi
leaq 0x3c(%rsp), %rdx
leaq 0x3b(%rsp), %rcx
callq 0x5d40
jmp 0x2af6
movl $0x1000087, 0x34(%rsp)  # imm = 0x1000087
movb $0xb, 0x33(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x44(%rsp), %rsi
leaq 0x34(%rsp), %rdx
leaq 0x33(%rsp), %rcx
callq 0x5d40
jmp 0x2b21
leaq 0x120(%rsp), %rdi
leaq 0x6d(%rsp), %rsi
leaq 0x44(%rsp), %rdx
callq 0x5bf0
jmp 0x2b3a
leaq 0x120(%rsp), %rdi
leaq 0x44(%rsp), %rsi
callq 0x5cc0
jmp 0x2b4e
movl $0x1000086, 0x20(%rsp)  # imm = 0x1000086
leaq 0x120(%rsp), %rdi
leaq 0x24(%rsp), %rsi
leaq 0x20(%rsp), %rdx
callq 0x5b30
jmp 0x2b6f
movl $0x1000088, 0x1c(%rsp)  # imm = 0x1000088
movb $0x2a, 0x1b(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x24(%rsp), %rsi
leaq 0x1c(%rsp), %rdx
leaq 0x1b(%rsp), %rcx
callq 0x5d40
jmp 0x2b9a
movl $0x1000087, 0x14(%rsp)  # imm = 0x1000087
movb $0xc, 0x13(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x24(%rsp), %rsi
leaq 0x14(%rsp), %rdx
leaq 0x13(%rsp), %rcx
callq 0x5d40
jmp 0x2bc5
leaq 0x120(%rsp), %rdi
leaq 0x6d(%rsp), %rsi
leaq 0x24(%rsp), %rdx
callq 0x5bf0
jmp 0x2bde
leaq 0x120(%rsp), %rdi
leaq 0x24(%rsp), %rsi
callq 0x5cc0
jmp 0x2bf2
leaq 0x120(%rsp), %rdi
leaq 0x81(%rsp), %rsi
leaq 0x6d(%rsp), %rdx
callq 0x5bf0
jmp 0x2c0e
leaq 0x120(%rsp), %rdi
leaq 0x6d(%rsp), %rsi
callq 0x5cc0
jmp 0x2c22
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
leaq 0x81(%rsp), %rdx
callq 0x5bf0
jmp 0x2c41
leaq 0x120(%rsp), %rdi
leaq 0x81(%rsp), %rsi
callq 0x5cc0
jmp 0x2c58
jmp 0x2c5a
movq 0x130(%rsp), %rsi
movq 0x118(%rsp), %rdx
movzwl 0x116(%rsp), %ecx
leaq 0x120(%rsp), %rdi
movl $0x1, %r8d
callq 0x7a90
jmp 0x2c87
leaq 0x120(%rsp), %rdi
leaq 0x111(%rsp), %rsi
callq 0x5cc0
jmp 0x2c9e
leaq 0x120(%rsp), %rdi
callq 0x7860
xorl %eax, %eax
addq $0x138, %rsp            # imm = 0x138
retq
movq 0x100(%rsp), %rdi
callq 0x22a0
nopw %cs:(%rax,%rax)