// File: /workspace/github_c_makefile_star2_O2/TimeToogo[P]ff-proxy/client/c/client.c
// Function: ff_client_packetise_request
struct ff_client_packet *ff_client_packetise_request(struct ff_request *request, uint16_t *packet_count)
{
    struct ff_client_packet *packets = calloc(1, sizeof(struct ff_client_packet *) * FF_CLIENT_MAX_PACKETS);
    uint64_t request_id = ff_client_generate_request_id();
    uint32_t chunk_offset = 0;
    uint16_t bytes_left = request->payload_length;

    *packet_count = 0;

    while (bytes_left > 0)
    {
        uint8_t *buffer = calloc(1, FF_CLIENT_MAX_PACKET_LENGTH);
        uint16_t packet_length = 0;
        struct __raw_ff_request_header *header = (struct __raw_ff_request_header *)buffer;

        header->version = htons(FF_VERSION_1);
        header->request_id = htonll(request_id);
        header->total_length = htonl(request->payload_length);
        header->chunk_offset = htonl(chunk_offset);
        packet_length += sizeof(struct __raw_ff_request_header);

        if (*packet_count == 0)
        {
            // If first packet, send options
            packet_length += ff_client_write_options(buffer + packet_length, request->options, request->options_length);
        }
        else
        {
            // If subsequent packet provide empty option list
            struct __raw_ff_request_option_header *option_header = (struct __raw_ff_request_option_header *)(buffer + packet_length);
            option_header->type = FF_REQUEST_OPTION_TYPE_EOL;
            option_header->length = 0;
            packet_length += sizeof(struct __raw_ff_request_option_header);
        }

        uint16_t bytes_left_in_packet = FF_CLIENT_MAX_PACKET_LENGTH - packet_length;
        uint16_t chunk_length = bytes_left > bytes_left_in_packet ? bytes_left_in_packet : bytes_left;

        header->chunk_length = htons(chunk_length);

        memcpy(buffer + packet_length, request->payload->value + chunk_offset, chunk_length);
        packet_length += chunk_length;
        bytes_left -= chunk_length;
        chunk_offset += chunk_length;

        packets[*packet_count].length = packet_length;
        packets[*packet_count].value = buffer;
        (*packet_count)++;
    }

    ff_log(FF_DEBUG, "Packetised payload into %u packets", *packet_count);

    return packets;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, -0x48(%rbp)
movq %rdi, %rbx
pushq $0x1
popq %rdi
movl $0x2000, %esi           # imm = 0x2000
callq 0x2120
movq %rax, -0x38(%rbp)
callq 0x2bd8
bswapq %rax
movq %rax, -0x58(%rbp)
movq %rbx, -0x40(%rbp)
movl 0x40(%rbx), %r14d
xorl %ebx, %ebx
xorl %r15d, %r15d
movq -0x48(%rbp), %rax
movw %bx, (%rax)
andl $0xffff, %r14d          # imm = 0xFFFF
je 0x2887
movl $0x514, %esi            # imm = 0x514
pushq $0x1
popq %rdi
callq 0x2120
movq %rax, %r12
movw $0x100, (%rax)          # imm = 0x100
movq -0x58(%rbp), %rax
movq %rax, 0x2(%r12)
movq -0x40(%rbp), %rcx
movl 0x40(%rcx), %eax
bswapl %eax
movl %eax, 0xa(%r12)
movl %r15d, -0x2c(%rbp)
movl %r15d, %eax
bswapl %eax
movl %eax, 0xe(%r12)
testw %bx, %bx
je 0x27f6
movb $0x0, 0x14(%r12)
andw $0x0, 0x15(%r12)
pushq $0x17
popq %r15
movq %rbx, -0x50(%rbp)
jmp 0x281e
leaq 0x14(%r12), %rdi
movq 0x30(%rcx), %rsi
movzbl 0x28(%rcx), %edx
callq 0x2b09
movq -0x40(%rbp), %rcx
addl $0x14, %eax
movzwl %ax, %r15d
movq -0x48(%rbp), %rax
movzwl (%rax), %eax
movq %rax, -0x50(%rbp)
movl $0x514, %eax            # imm = 0x514
subl %r15d, %eax
movzwl %ax, %r13d
cmpl %r13d, %r14d
cmovbl %r14d, %r13d
movl %r13d, %eax
rolw $0x8, %ax
movw %ax, 0x12(%r12)
movl %r15d, %eax
movq %r12, %rdi
addq %rax, %rdi
movq 0x50(%rcx), %rax
movl -0x2c(%rbp), %ebx
movl %ebx, %esi
addq 0x8(%rax), %rsi
movq %r13, %rdx
callq 0x2150
addl %r13d, %r15d
subl %r13d, %r14d
addl %ebx, %r13d
movq -0x50(%rbp), %rbx
movzwl %bx, %eax
shll $0x4, %eax
movq -0x38(%rbp), %rcx
movw %r15w, 0x8(%rcx,%rax)
movq %r12, (%rcx,%rax)
incl %ebx
movl %r13d, %r15d
jmp 0x278c
movzwl %bx, %edx
leaq 0x2832(%rip), %rsi      # 0x50c3
pushq $0x1
popq %rdi
xorl %eax, %eax
callq 0x37ac
movq -0x38(%rbp), %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq