// File: /workspace/github_cpp_makefile_star2_O1/goodix[P]gdix_hid_firmware_update/firmware_image.cpp
// Function: FirmwareImage::GetDataFromFile(char const*)
int FirmwareImage::GetDataFromFile(const char *filename)
{
	gdix_dbg("FirmwareImage %s run\n", __func__);

	int ret, i;
	int fw_fd;
	unsigned short check_sum = 0;

	fw_fd = open(filename, O_RDONLY);

	if (fw_fd < 0) {
		perror("Cannot open file\n");
		gdix_err("file:%s, ret:%d\n", filename, fw_fd);
		return fw_fd;
	}

	m_totalSize = lseek(fw_fd, 0, SEEK_END);
	lseek(fw_fd, 0, SEEK_SET);

	if (NULL != m_firmwareData) {
		delete[] m_firmwareData;
		m_firmwareData = NULL;
	}
	m_firmwareData = new unsigned char[m_totalSize]();

	ret = read(fw_fd, m_firmwareData, m_totalSize);
	if (ret != m_totalSize) {
		gdix_dbg("Failed read file: %s, ret=%d\n", filename, ret);
		ret = -1;
		goto err_out;
	}

	// firmware
	m_firmwareSize = m_firmwareData[0] << 24 | m_firmwareData[1] << 16 |
					 m_firmwareData[2] << 8 | m_firmwareData[3];

	if (m_firmwareSize + 6 != m_totalSize) {
		gdix_dbg("Check file len unequal %d != %d\n", m_firmwareSize + 6,
				 m_totalSize);
		gdix_dbg("This bin file may contain a config bin.\n");
		hasConfig = true;
	}

	for (i = 6, check_sum = 0; i < m_firmwareSize + 6; i++)
		check_sum += m_firmwareData[i];

	if (check_sum != (m_firmwareData[4] << 8 | m_firmwareData[5])) {
		gdix_dbg("Check_sum err  0x%x != 0x%x\n", check_sum,
				 (m_firmwareData[4] << 8 | m_firmwareData[5]));
		ret = -2;
		goto err_out;
	}

	// config
	if (hasConfig) {
		int cfgpackLen = (m_firmwareData[m_firmwareSize + 6] << 8) +
						 m_firmwareData[m_firmwareSize + 7];
		if (m_totalSize - m_firmwareSize - 6 != cfgpackLen + 6) {
			gdix_err("config pack len error,%d != %d",
					 m_totalSize - m_firmwareSize - 6, cfgpackLen + 6);
			ret = -3;
			goto err_out;
		}

		for (i = m_firmwareSize + 6 + 6, check_sum = 0; i < m_totalSize; i++)
			check_sum += m_firmwareData[i];
		if (check_sum != (m_firmwareData[m_firmwareSize + 6 + 4] << 8) +
							 m_firmwareData[m_firmwareSize + 6 + 5]) {
			gdix_err("config pack checksum error,%d != %d", check_sum,
					 (m_firmwareData[m_firmwareSize + 6 + 4] << 8) +
						 m_firmwareData[m_firmwareSize + 6 + 5]);
			ret = -4;
			goto err_out;
		}
	}

	close(fw_fd);
	gdix_dbg("FirmwareImage %s exit,exit code:%d\n", __func__, 0);
	return 0;

err_out:
	m_initialized = false;
	delete[] m_firmwareData;
	close(fw_fd);
	gdix_dbg("FirmwareImage %s exit,exit code:%d\n", __func__, ret);
	return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r12
movq %rdi, %r14
leaq 0x1a373(%rip), %r15     # 0x21291
cmpb $0x1, (%r15)
jne 0x6f4b
movq 0x1a08d(%rip), %rax     # 0x20fb8
movq (%rax), %rdi
leaq 0xf0cf(%rip), %rsi      # 0x16004
leaq 0xf15f(%rip), %rdx      # 0x1609b
movl $0x8c, %ecx
movq %rdx, %r8
xorl %eax, %eax
callq 0x5180
movq %r12, %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x51e0
movl %eax, %ebx
testl %eax, %eax
js 0x7281
movl %ebx, %edi
xorl %esi, %esi
movl $0x2, %edx
callq 0x50b0
movl %eax, 0xc(%r14)
movl %ebx, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x50b0
movq 0x30(%r14), %rdi
testq %rdi, %rdi
je 0x6f94
callq 0x5130
movq $0x0, 0x30(%r14)
movslq 0xc(%r14), %r15
movq %r15, %rdi
callq 0x5030
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x5080
movq %r13, 0x30(%r14)
movl %ebx, %edi
movq %r13, %rsi
movq %r15, %rdx
callq 0x5190
movq %rax, %r15
movl 0xc(%r14), %r9d
cmpl %r15d, %r9d
jne 0x7083
movq 0x30(%r14), %rax
movl (%rax), %r8d
bswapl %r8d
movl %r8d, 0x10(%r14)
addl $0x6, %r8d
cmpl %r9d, %r8d
leaq 0x1a2a4(%rip), %r13     # 0x21291
je 0x704a
cmpb $0x1, (%r13)
jne 0x701a
movq 0x19fbb(%rip), %rax     # 0x20fb8
movq (%rax), %rdi
leaq 0xf107(%rip), %rsi      # 0x1610e
leaq 0xf08d(%rip), %rdx      # 0x1609b
movl $0xb0, %ecx
xorl %eax, %eax
callq 0x5180
cmpb $0x1, (%r13)
jne 0x7045
movq 0x19f90(%rip), %rax     # 0x20fb8
movq (%rax), %rdi
leaq 0xf10e(%rip), %rsi      # 0x16140
leaq 0xf062(%rip), %rdx      # 0x1609b
movl $0xb1, %ecx
xorl %eax, %eax
callq 0x5180
movb $0x1, 0x18(%r14)
movslq 0x10(%r14), %rax
leal 0x6(%rax), %edx
testq %rax, %rax
jle 0x70c9
movq 0x30(%r14), %rcx
cmpl $0x8, %edx
movl $0x7, %esi
cmovgel %edx, %esi
movl $0x6, %r8d
xorl %edi, %edi
movzbl (%rcx,%r8), %r9d
addl %r9d, %edi
incq %r8
cmpq %r8, %rsi
jne 0x706d
movzwl %di, %r8d
jmp 0x70cc
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
leaq 0x1a202(%rip), %r13     # 0x21291
cmpb $0x1, (%r13)
jne 0x7223
movq 0x19f17(%rip), %rax     # 0x20fb8
movq (%rax), %rdi
leaq 0xf034(%rip), %rsi      # 0x160df
leaq 0xefe9(%rip), %rdx      # 0x1609b
movl $0xa5, %ecx
movq %r12, %r8
movl %r15d, %r9d
xorl %eax, %eax
callq 0x5180
jmp 0x7223
xorl %r8d, %r8d
movq 0x30(%r14), %rcx
movzwl 0x4(%rcx), %esi
rolw $0x8, %si
movzwl %si, %r9d
cmpl %r8d, %r9d
jne 0x7193
cmpb $0x1, 0x18(%r14)
jne 0x71e5
movslq %edx, %rdx
movzbl (%rcx,%rdx), %esi
shll $0x8, %esi
movzbl 0x7(%rcx,%rax), %edi
movl 0xc(%r14), %edx
movl %edx, %r8d
subl %eax, %r8d
addl $-0x6, %r8d
leal (%rsi,%rdi), %r9d
addl $0x6, %r9d
cmpl %r9d, %r8d
jne 0x71c9
movq %rax, %rsi
addq $0xc, %rsi
xorl %r8d, %r8d
cmpl %edx, %esi
jge 0x714c
addq %rcx, %rsi
subl %eax, %edx
addl $-0xc, %edx
xorl %edi, %edi
xorl %r8d, %r8d
movzbl (%rsi,%rdi), %r9d
addl %r9d, %r8d
incq %rdi
cmpl %edi, %edx
jne 0x7139
movzwl %r8w, %r8d
movzwl 0xa(%rcx,%rax), %eax
rolw $0x8, %ax
movzwl %ax, %r9d
movb $0x1, %r12b
cmpl %r8d, %r9d
je 0x71dd
movl $0xfffffffc, %r15d      # imm = 0xFFFFFFFC
cmpb $0x1, (%r13)
jne 0x71da
movq 0x19e63(%rip), %rax     # 0x20fd8
movq (%rax), %rdi
leaq 0xf059(%rip), %rsi      # 0x161d8
leaq 0xef15(%rip), %rdx      # 0x1609b
xorl %r12d, %r12d
movl $0xd0, %ecx
jmp 0x72db
movl $0xfffffffe, %ebp       # imm = 0xFFFFFFFE
cmpb $0x1, (%r13)
jne 0x7223
movq 0x19e0e(%rip), %rax     # 0x20fb8
movq (%rax), %rdi
leaq 0xefc6(%rip), %rsi      # 0x1617a
leaq 0xeee0(%rip), %rdx      # 0x1609b
movl $0xba, %ecx
xorl %eax, %eax
callq 0x5180
jmp 0x7223
movl $0xfffffffd, %r15d      # imm = 0xFFFFFFFD
cmpb $0x1, (%r13)
je 0x72bb
xorl %r12d, %r12d
movl %r15d, %ebp
testb %r12b, %r12b
je 0x7223
movl %ebx, %edi
callq 0x5210
xorl %ebx, %ebx
cmpb $0x1, (%r13)
jne 0x7270
movq 0x19dbc(%rip), %rax     # 0x20fb8
movq (%rax), %rdi
leaq 0xf007(%rip), %rsi      # 0x1620d
leaq 0xee8e(%rip), %rdx      # 0x1609b
xorl %ebx, %ebx
movl $0xd7, %ecx
movq %rdx, %r8
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x5180
jmp 0x7270
movb $0x0, 0x8(%r14)
movq 0x30(%r14), %rdi
testq %rdi, %rdi
je 0x7236
callq 0x5130
movl %ebx, %edi
callq 0x5210
cmpb $0x1, (%r13)
jne 0x726e
movq 0x19d6d(%rip), %rax     # 0x20fb8
movq (%rax), %rdi
leaq 0xefb8(%rip), %rsi      # 0x1620d
leaq 0xee3f(%rip), %rdx      # 0x1609b
movl $0xde, %ecx
movq %rdx, %r8
movl %ebp, %r9d
xorl %eax, %eax
callq 0x5180
movl %ebp, %ebx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xee23(%rip), %rdi      # 0x160ab
callq 0x50a0
cmpb $0x1, (%r15)
jne 0x7270
movq 0x19d3e(%rip), %rax     # 0x20fd8
movq (%rax), %rdi
leaq 0xee19(%rip), %rsi      # 0x160bd
leaq 0xedf0(%rip), %rdx      # 0x1609b
movl $0x96, %ecx
movq %r12, %r8
movl %ebx, %r9d
jmp 0x721a
movq 0x19d16(%rip), %rax     # 0x20fd8
movq (%rax), %rdi
leaq 0xeedc(%rip), %rsi      # 0x161a8
leaq 0xedc8(%rip), %rdx      # 0x1609b
xorl %r12d, %r12d
movl $0xc5, %ecx
xorl %eax, %eax
callq 0x5180
jmp 0x71dd
nop