// File: /workspace/github_c_makefile_star2_O0/Carton32[P]quectel-CM/quectel-qmi-proxy.c
// Function: qmi_proxy_loop
static void *qmi_proxy_loop(void *param)
{
    PQCQMIMSG pQMI = (PQCQMIMSG)qmi_buf;
    struct qlistnode *con_node;
    QMI_PROXY_CONNECTION *qmi_con;

    (void)param;
    dprintf("%s enter thread_id %p\n", __func__, (void *)pthread_self());

    qlist_init(&qmi_proxy_connection);
    qlist_init(&qmi_proxy_ctl_msg);

    while (cdc_wdm_fd > 0 && qmi_proxy_quit == 0) {
        struct pollfd pollfds[2+64];
        int ne, ret, nevents = 0;
        ssize_t nreads;

        pollfds[nevents].fd = cdc_wdm_fd;
        pollfds[nevents].events = POLLIN;
        pollfds[nevents].revents= 0;
        nevents++;
        
        if (qmi_proxy_server_fd > 0) {
            pollfds[nevents].fd = qmi_proxy_server_fd;
            pollfds[nevents].events = POLLIN;
            pollfds[nevents].revents= 0;
            nevents++;
        }

        qlist_for_each(con_node, &qmi_proxy_connection) {
            qmi_con = qnode_to_item(con_node, QMI_PROXY_CONNECTION, qnode);
            
            pollfds[nevents].fd = qmi_con->ClientFd;
            pollfds[nevents].events = POLLIN;
            pollfds[nevents].revents= 0;
            nevents++;

            if (nevents == (sizeof(pollfds)/sizeof(pollfds[0])))
                break;
        }

#if 0
        dprintf("poll ");
        for (ne = 0; ne < nevents; ne++) {
            dprintf("%d ", pollfds[ne].fd);
        }
        dprintf("\n");
#endif

        do {
            //ret = poll(pollfds, nevents, -1);
            ret = poll(pollfds, nevents, (qmi_proxy_server_fd > 0) ? -1 : 200);
         } while (ret == -1 && errno == EINTR && qmi_proxy_quit == 0);
         
        if (ret < 0) {
            dprintf("%s poll=%d, errno: %d (%s)\n", __func__, ret, errno, strerror(errno));
            goto qmi_proxy_loop_exit;
        }

        for (ne = 0; ne < nevents; ne++) {
            int fd = pollfds[ne].fd;
            short revents = pollfds[ne].revents;

            if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
                dprintf("%s poll fd = %d, revents = %04x\n", __func__, fd, revents);
                if (fd == cdc_wdm_fd) {
                    goto qmi_proxy_loop_exit;
                } else if(fd == qmi_proxy_server_fd) {
                
                } else {
                    cleanup_qmi_connection(fd);
                }

                continue;
            }

            if (!(pollfds[ne].revents & POLLIN)) {
                continue;
            }

            if (fd == qmi_proxy_server_fd) {
                accept_qmi_connection(fd);
            }
            else if (fd == cdc_wdm_fd) {
                nreads = read(fd, pQMI, sizeof(qmi_buf));
                if (nreads <= 0) {
                    dprintf("%s read=%d errno: %d (%s)\n",  __func__, (int)nreads, errno, strerror(errno));
                    goto qmi_proxy_loop_exit;
                }
#ifdef QUECTEL_QMI_MERGE
                if(merge_qmi_rsp_packet(pQMI, &nreads))
                    continue;             
#endif
                if (nreads != (le16toh(pQMI->QMIHdr.Length) + 1)) {
                    dprintf("%s nreads=%d,  pQCQMI->QMIHdr.Length = %d\n",  __func__, (int)nreads, le16toh(pQMI->QMIHdr.Length));
                    continue;
                }

                dump_qmi(pQMI, fd, 'r');
                recv_qmi_from_dev(pQMI);
                if (modem_reset_flag)
                    goto qmi_proxy_loop_exit;
            }
            else {
                nreads = read(fd, pQMI, sizeof(qmi_buf));
  
                if (nreads <= 0) {
                    dprintf("%s read=%d errno: %d (%s)",  __func__, (int)nreads, errno, strerror(errno));
                    cleanup_qmi_connection(fd);
                    break;
                }

                if (nreads != (le16toh(pQMI->QMIHdr.Length) + 1)) {
                    dprintf("%s nreads=%d,  pQCQMI->QMIHdr.Length = %d\n",  __func__, (int)nreads, le16toh(pQMI->QMIHdr.Length));
                    continue;
                }

                dump_qmi(pQMI, fd, 'r');
                recv_qmi_from_client(pQMI, nreads, fd);
            }
        }
    }

qmi_proxy_loop_exit:
    while (!qlist_empty(&qmi_proxy_connection)) {
        QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(qlist_head(&qmi_proxy_connection), QMI_PROXY_CONNECTION, qnode);

        cleanup_qmi_connection(qmi_con->ClientFd);
    }
    
    dprintf("%s exit, thread_id %p\n", __func__, (void *)pthread_self());

    return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x320, %rsp            # imm = 0x320
movq %rdi, -0x8(%rbp)
leaq 0x48aa(%rip), %rax      # 0x61f0
movq %rax, -0x10(%rbp)
movq 0x467f(%rip), %rax      # 0x5fd0
movq (%rax), %rax
movq %rax, -0x268(%rbp)
callq 0x1340
movq %rax, -0x260(%rbp)
callq 0x1190
movq -0x268(%rbp), %rdi
movq -0x260(%rbp), %rdx
movq %rax, %r8
leaq 0x28e7(%rip), %rsi      # 0x426b
leaq 0x28fa(%rip), %rcx      # 0x4285
movb $0x0, %al
callq 0x1120
leaq 0x5857(%rip), %rdi      # 0x71f0
callq 0x2350
leaq 0x585b(%rip), %rdi      # 0x7200
callq 0x2350
xorl %eax, %eax
cmpl $0x0, 0x477d(%rip)      # 0x6130
movb %al, -0x269(%rbp)
jle 0x19cb
cmpl $0x0, 0x4812(%rip)      # 0x61d4
sete %al
movb %al, -0x269(%rbp)
movb -0x269(%rbp), %al
testb $0x1, %al
jne 0x19da
jmp 0x201a
movl $0x0, -0x23c(%rbp)
movl 0x4746(%rip), %ecx      # 0x6130
movslq -0x23c(%rbp), %rax
movl %ecx, -0x230(%rbp,%rax,8)
movslq -0x23c(%rbp), %rax
movw $0x1, -0x22c(%rbp,%rax,8)
movslq -0x23c(%rbp), %rax
movw $0x0, -0x22a(%rbp,%rax,8)
movl -0x23c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x23c(%rbp)
cmpl $0x0, 0x4704(%rip)      # 0x6134
jle 0x1a77
movl 0x46fc(%rip), %ecx      # 0x6134
movslq -0x23c(%rbp), %rax
movl %ecx, -0x230(%rbp,%rax,8)
movslq -0x23c(%rbp), %rax
movw $0x1, -0x22c(%rbp,%rax,8)
movslq -0x23c(%rbp), %rax
movw $0x0, -0x22a(%rbp,%rax,8)
movl -0x23c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x23c(%rbp)
movq 0x5772(%rip), %rax      # 0x71f0
movq %rax, -0x18(%rbp)
leaq 0x5767(%rip), %rax      # 0x71f0
cmpq %rax, -0x18(%rbp)
je 0x1afb
movq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl 0x20(%rax), %ecx
movslq -0x23c(%rbp), %rax
movl %ecx, -0x230(%rbp,%rax,8)
movslq -0x23c(%rbp), %rax
movw $0x1, -0x22c(%rbp,%rax,8)
movslq -0x23c(%rbp), %rax
movw $0x0, -0x22a(%rbp,%rax,8)
movl -0x23c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x23c(%rbp)
movslq -0x23c(%rbp), %rax
cmpq $0x42, %rax
jne 0x1aec
jmp 0x1afb
jmp 0x1aee
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x1a82
jmp 0x1afd
leaq -0x230(%rbp), %rdi
movslq -0x23c(%rbp), %rsi
movl 0x4623(%rip), %ecx      # 0x6134
movl $0xc8, %edx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl $0x0, %ecx
cmovgl %eax, %edx
callq 0x1160
movl %eax, -0x238(%rbp)
xorl %eax, %eax
cmpl $-0x1, -0x238(%rbp)
movb %al, -0x26a(%rbp)
jne 0x1b62
callq 0x1050
movq %rax, %rcx
xorl %eax, %eax
cmpl $0x4, (%rcx)
movb %al, -0x26a(%rbp)
jne 0x1b62
cmpl $0x0, 0x467b(%rip)      # 0x61d4
sete %al
movb %al, -0x26a(%rbp)
movb -0x26a(%rbp), %al
testb $0x1, %al
jne 0x1afd
cmpl $0x0, -0x238(%rbp)
jge 0x1bf3
jmp 0x1b77
movq 0x4452(%rip), %rax      # 0x5fd0
movq (%rax), %rax
movq %rax, -0x288(%rbp)
callq 0x1340
movq %rax, -0x280(%rbp)
movl -0x238(%rbp), %eax
movl %eax, -0x274(%rbp)
callq 0x1050
movl (%rax), %eax
movl %eax, -0x270(%rbp)
callq 0x1050
movl (%rax), %edi
callq 0x1200
movq -0x288(%rbp), %rdi
movq -0x280(%rbp), %rdx
movl -0x274(%rbp), %r8d
movl -0x270(%rbp), %r9d
leaq 0x26b8(%rip), %rsi      # 0x4294
leaq 0x26a2(%rip), %rcx      # 0x4285
movq %rax, (%rsp)
movb $0x0, %al
callq 0x1120
jmp 0x201c
movl $0x0, -0x234(%rbp)
movl -0x234(%rbp), %eax
cmpl -0x23c(%rbp), %eax
jge 0x2015
movslq -0x234(%rbp), %rax
movl -0x230(%rbp,%rax,8), %eax
movl %eax, -0x24c(%rbp)
movslq -0x234(%rbp), %rax
movw -0x22a(%rbp,%rax,8), %ax
movw %ax, -0x24e(%rbp)
movswl -0x24e(%rbp), %eax
andl $0x38, %eax
cmpl $0x0, %eax
je 0x1cc3
jmp 0x1c4a
movq 0x437f(%rip), %rax      # 0x5fd0
movq (%rax), %rax
movq %rax, -0x290(%rbp)
callq 0x1340
movq -0x290(%rbp), %rdi
movq %rax, %rdx
movl -0x24c(%rbp), %r8d
movswl -0x24e(%rbp), %r9d
leaq 0x2633(%rip), %rsi      # 0x42b3
leaq 0x25fe(%rip), %rcx      # 0x4285
movb $0x0, %al
callq 0x1120
movl -0x24c(%rbp), %eax
cmpl 0x4496(%rip), %eax      # 0x6130
jne 0x1ca1
jmp 0x201c
movl -0x24c(%rbp), %eax
cmpl 0x4487(%rip), %eax      # 0x6134
jne 0x1cb1
jmp 0x1cbc
movl -0x24c(%rbp), %edi
callq 0x2380
jmp 0x1cbe
jmp 0x2001
movslq -0x234(%rbp), %rax
movswl -0x22a(%rbp,%rax,8), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1cdf
jmp 0x2001
movl -0x24c(%rbp), %eax
cmpl 0x4449(%rip), %eax      # 0x6134
jne 0x1cfd
movl -0x24c(%rbp), %edi
callq 0x2500
jmp 0x1fff
movl -0x24c(%rbp), %eax
cmpl 0x4427(%rip), %eax      # 0x6130
jne 0x1e82
movl -0x24c(%rbp), %edi
movq -0x10(%rbp), %rsi
movl $0x1000, %edx           # imm = 0x1000
callq 0x10f0
movq %rax, -0x248(%rbp)
cmpq $0x0, -0x248(%rbp)
jg 0x1db3
jmp 0x1d36
movq 0x4293(%rip), %rax      # 0x5fd0
movq (%rax), %rax
movq %rax, -0x2a8(%rbp)
callq 0x1340
movq %rax, -0x2a0(%rbp)
movq -0x248(%rbp), %rax
movl %eax, -0x298(%rbp)
callq 0x1050
movl (%rax), %eax
movl %eax, -0x294(%rbp)
callq 0x1050
movl (%rax), %edi
callq 0x1200
movq -0x2a8(%rbp), %rdi
movq -0x2a0(%rbp), %rdx
movl -0x298(%rbp), %r8d
movl -0x294(%rbp), %r9d
leaq 0x253b(%rip), %rsi      # 0x42d7
leaq 0x24e2(%rip), %rcx      # 0x4285
movq %rax, (%rsp)
movb $0x0, %al
callq 0x1120
jmp 0x201c
movq -0x248(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x1(%rax), %edi
callq 0x2620
movw %ax, %cx
movq -0x2b0(%rbp), %rax
movzwl %cx, %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
cmpq %rcx, %rax
je 0x1e52
jmp 0x1de8
movq 0x41e1(%rip), %rax      # 0x5fd0
movq (%rax), %rax
movq %rax, -0x2c8(%rbp)
callq 0x1340
movq %rax, -0x2c0(%rbp)
movq -0x248(%rbp), %rax
movl %eax, -0x2b4(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x1(%rax), %edi
callq 0x2620
movq -0x2c8(%rbp), %rdi
movq -0x2c0(%rbp), %rdx
movl -0x2b4(%rbp), %r8d
movzwl %ax, %r9d
leaq 0x24b6(%rip), %rsi      # 0x42f5
leaq 0x243f(%rip), %rcx      # 0x4285
movb $0x0, %al
callq 0x1120
jmp 0x2001
movq -0x10(%rbp), %rdi
movl -0x24c(%rbp), %esi
movl $0x72, %edx
callq 0x2640
movq -0x10(%rbp), %rdi
callq 0x26e0
cmpl $0x0, 0x436a(%rip)      # 0x61e0
je 0x1e7d
jmp 0x201c
jmp 0x1ffd
movl -0x24c(%rbp), %edi
movq -0x10(%rbp), %rsi
movl $0x1000, %edx           # imm = 0x1000
callq 0x10f0
movq %rax, -0x248(%rbp)
cmpq $0x0, -0x248(%rbp)
jg 0x1f35
jmp 0x1ead
movq 0x411c(%rip), %rax      # 0x5fd0
movq (%rax), %rax
movq %rax, -0x2e0(%rbp)
callq 0x1340
movq %rax, -0x2d8(%rbp)
movq -0x248(%rbp), %rax
movl %eax, -0x2d0(%rbp)
callq 0x1050
movl (%rax), %eax
movl %eax, -0x2cc(%rbp)
callq 0x1050
movl (%rax), %edi
callq 0x1200
movq -0x2e0(%rbp), %rdi
movq -0x2d8(%rbp), %rdx
movl -0x2d0(%rbp), %r8d
movl -0x2cc(%rbp), %r9d
leaq 0x2410(%rip), %rsi      # 0x4323
leaq 0x236b(%rip), %rcx      # 0x4285
movq %rax, (%rsp)
movb $0x0, %al
callq 0x1120
movl -0x24c(%rbp), %edi
callq 0x2380
jmp 0x2015
movq -0x248(%rbp), %rax
movq %rax, -0x2e8(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x1(%rax), %edi
callq 0x2620
movw %ax, %cx
movq -0x2e8(%rbp), %rax
movzwl %cx, %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
cmpq %rcx, %rax
je 0x1fd1
jmp 0x1f6a
movq 0x405f(%rip), %rax      # 0x5fd0
movq (%rax), %rax
movq %rax, -0x300(%rbp)
callq 0x1340
movq %rax, -0x2f8(%rbp)
movq -0x248(%rbp), %rax
movl %eax, -0x2ec(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x1(%rax), %edi
callq 0x2620
movq -0x300(%rbp), %rdi
movq -0x2f8(%rbp), %rdx
movl -0x2ec(%rbp), %r8d
movzwl %ax, %r9d
leaq 0x2334(%rip), %rsi      # 0x42f5
leaq 0x22bd(%rip), %rcx      # 0x4285
movb $0x0, %al
callq 0x1120
jmp 0x2001
movq -0x10(%rbp), %rdi
movl -0x24c(%rbp), %esi
movl $0x72, %edx
callq 0x2640
movq -0x10(%rbp), %rdi
movq -0x248(%rbp), %rax
movl %eax, %esi
movl -0x24c(%rbp), %edx
callq 0x2970
jmp 0x1fff
jmp 0x2001
movl -0x234(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x234(%rbp)
jmp 0x1bfd
jmp 0x19aa
jmp 0x201c
jmp 0x201e
leaq 0x51cb(%rip), %rax      # 0x71f0
cmpq 0x51c4(%rip), %rax      # 0x71f0
sete %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x2037
jmp 0x2056
movq 0x51b2(%rip), %rax      # 0x71f0
movq %rax, -0x258(%rbp)
movq -0x258(%rbp), %rax
movl 0x20(%rax), %edi
callq 0x2380
jmp 0x201e
jmp 0x2058
movq 0x3f71(%rip), %rax      # 0x5fd0
movq (%rax), %rax
movq %rax, -0x310(%rbp)
callq 0x1340
movq %rax, -0x308(%rbp)
callq 0x1190
movq -0x310(%rbp), %rdi
movq -0x308(%rbp), %rdx
movq %rax, %r8
leaq 0x22ae(%rip), %rsi      # 0x4340
leaq 0x21ec(%rip), %rcx      # 0x4285
movb $0x0, %al
callq 0x1120
xorl %eax, %eax
addq $0x320, %rsp            # imm = 0x320
popq %rbp
retq
nopl (%rax,%rax)