// File: /workspace/github_c_makefile_star2_O2/Carton32[P]quectel-CM/QmiWwanCM.c
// Function: QmiWwanThread
static void * QmiWwanThread(void *pData) {
    PROFILE_T *profile = (PROFILE_T *)pData;
    const char *cdc_wdm = (const char *)profile->qmichannel;
    int wait_for_request_quit = 0;
    char num = cdc_wdm[strlen(cdc_wdm)-1];
	
    if (profile->proxy[0]) {
         if (!strncmp(profile->proxy, QUECTEL_QMI_PROXY, strlen(QUECTEL_QMI_PROXY))) {
            snprintf(profile->proxy, sizeof(profile->proxy), "%s%c", QUECTEL_QMI_PROXY, num);
         }
    }
    else if (profile->qmap_mode > 1) {
        snprintf(profile->proxy, sizeof(profile->proxy), "%s%c", QUECTEL_QMI_PROXY, num);
    }
    
    if (profile->proxy[0])
        cdc_wdm_fd = cm_open_proxy(profile->proxy);
    else
        cdc_wdm_fd = cm_open_dev(cdc_wdm);

    if (cdc_wdm_fd == -1) {
        dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, cdc_wdm, errno, strerror(errno));
        qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
        pthread_exit(NULL);
        return NULL;
    }

    dbg_time("cdc_wdm_fd = %d", cdc_wdm_fd);

    qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);
    while (1) {
        struct pollfd pollfds[] = {{qmidevice_control_fd[1], POLLIN, 0}, {cdc_wdm_fd, POLLIN, 0}};
        int ne, ret, nevents = sizeof(pollfds)/sizeof(pollfds[0]);

        do {
            ret = poll(pollfds, nevents, wait_for_request_quit ? 1000 : -1);
         } while ((ret < 0) && (errno == EINTR));

	if (ret == 0 && wait_for_request_quit) {
            QmiThreadRecvQMI(NULL);
            continue;
	}

        if (ret <= 0) {
            dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
            break;
        }

        for (ne = 0; ne < nevents; ne++) {
            int fd = pollfds[ne].fd;
            short revents = pollfds[ne].revents;

            //dbg_time("{%d, %x, %x}", pollfds[ne].fd, pollfds[ne].events, pollfds[ne].revents);

            if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
                dbg_time("%s poll err/hup/inval", __func__);
                dbg_time("poll fd = %d, events = 0x%04x", fd, revents);
                if (fd == cdc_wdm_fd) {
                } else {
                }
                if (revents & (POLLHUP | POLLNVAL)) //EC20 bug, Can get POLLERR
                    goto __QmiWwanThread_quit;
            }

            if ((revents & POLLIN) == 0)
                continue;

            if (fd == qmidevice_control_fd[1]) {
                int triger_event;
                if (read(fd, &triger_event, sizeof(triger_event)) == sizeof(triger_event)) {
                    //DBG("triger_event = 0x%x", triger_event);
                    switch (triger_event) {
                        case RIL_REQUEST_QUIT:
                            goto __QmiWwanThread_quit;
                        break;
                        case SIG_EVENT_STOP:
                            wait_for_request_quit = 1;
                        break;
                        default:
                        break;
                    }
                }
            }

            if (fd == cdc_wdm_fd) {
                ssize_t nreads;
                PQCQMIMSG pResponse = (PQCQMIMSG)cm_recv_buf;
                
                if (!profile->proxy[0])
                    nreads = read(fd, cm_recv_buf, sizeof(cm_recv_buf));
                else
                    nreads = qmi_proxy_read(fd, cm_recv_buf, sizeof(cm_recv_buf));
                //dbg_time("%s read=%d errno: %d (%s)",  __func__, (int)nreads, errno, strerror(errno));
                if (nreads <= 0) {
                    dbg_time("%s read=%d errno: %d (%s)",  __func__, (int)nreads, errno, strerror(errno));
                    break;
                }
#ifdef QUECTEL_QMI_MERGE
                if((profile->qmap_mode == 0 || profile->qmap_mode == 1) && QmiWwanMergeQmiRsp(cm_recv_buf, &nreads))
                    continue;             
#endif
                if (nreads != (le16_to_cpu(pResponse->QMIHdr.Length) + 1)) {
                    dbg_time("%s nreads=%d,  pQCQMI->QMIHdr.Length = %d",  __func__, (int)nreads, le16_to_cpu(pResponse->QMIHdr.Length));
                    continue;
                }

                QmiThreadRecvQMI(pResponse);
            }
        }
    }

__QmiWwanThread_quit:
    if (cdc_wdm_fd != -1) { close(cdc_wdm_fd); cdc_wdm_fd = -1; }
    qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
    QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
    dbg_time("%s exit", __func__);
    pthread_exit(NULL);
    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %r14
leaq 0x8a(%rdi), %rbx
movq %rbx, %rdi
callq 0x5160
movsbl 0x89(%r14,%rax), %ebp
leaq 0x28(%r14), %r15
cmpb $0x0, 0x28(%r14)
movq %r15, 0x40(%rsp)
jne 0x5c0f
cmpl $0x2, 0x10a(%r14)
jge 0x5c25
jmp 0x5c43
leaq 0x164fb(%rip), %rsi     # 0x1c111
pushq $0x11
popq %rdx
movq %r15, %rdi
callq 0x5090
testl %eax, %eax
jne 0x5c53
leaq 0x164f7(%rip), %rdx     # 0x1c123
leaq 0x164de(%rip), %rcx     # 0x1c111
pushq $0x20
popq %rsi
movq %r15, %rdi
movl %ebp, %r8d
xorl %eax, %eax
callq 0x51c0
cmpb $0x0, (%r15)
jne 0x5c53
movq %rbx, %rdi
callq 0xe1ec
jmp 0x5c5b
movq %r15, %rdi
callq 0xe3d6
movl %eax, %ebp
movl %eax, 0x2368d(%rip)     # 0x292f0
movq 0x2334e(%rip), %rax     # 0x28fb8
movq (%rax), %r15
callq 0xe343
movq %rax, %r12
cmpl $-0x1, %ebp
jne 0x5d09
callq 0x5070
movq %rax, %r14
movl (%rax), %ebp
movl %ebp, %edi
callq 0x5540
movq %rax, (%rsp)
leaq 0x1648e(%rip), %rsi     # 0x1c128
leaq 0x164b2(%rip), %rcx     # 0x1c153
movq %r15, %rdi
movq %r12, %rdx
movq %rbx, %r8
movl %ebp, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x23fed(%rip), %rax     # 0x29ca8
movq (%rax), %r15
testq %r15, %r15
je 0x5cfa
callq 0xe343
movq %rax, %r12
movl (%r14), %ebp
movl %ebp, %edi
callq 0x5540
movq %rax, (%rsp)
leaq 0x16448(%rip), %rsi     # 0x1c128
leaq 0x1646c(%rip), %rcx     # 0x1c153
movq %r15, %rdi
movq %r12, %rdx
movq %rbx, %r8
movl %ebp, %r9d
xorl %eax, %eax
callq 0x52c0
movl $0x1003, %edi           # imm = 0x1003
callq 0x7244
jmp 0x621c
movl 0x235e1(%rip), %ecx     # 0x292f0
leaq 0x1644b(%rip), %rsi     # 0x1c161
movq %r15, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x52c0
leaq 0x23f7e(%rip), %rax     # 0x29ca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x5d51
callq 0xe343
movl 0x235b3(%rip), %ecx     # 0x292f0
leaq 0x1641d(%rip), %rsi     # 0x1c161
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
movl $0x1002, %edi           # imm = 0x1002
callq 0x7244
leaq 0x20(%rsp), %r14
pushq $0x2
popq %r15
leaq 0x23fc5(%rip), %rbx     # 0x29d30
xorl %r12d, %r12d
leaq 0x23663(%rip), %rax     # 0x293d8
movl 0x4(%rax), %eax
movl %eax, 0x20(%rsp)
pushq $0x1
popq %rcx
movl %ecx, 0x24(%rsp)
movl 0x23567(%rip), %eax     # 0x292f0
movl %eax, 0x28(%rsp)
movl %ecx, 0x2c(%rsp)
cmpl %ecx, %r12d
movl $0x0, %r13d
sbbl %r13d, %r13d
orl $0x3e8, %r13d           # imm = 0x3E8
movq %r14, %rdi
movq %r15, %rsi
movl %r13d, %edx
callq 0x53d0
movl %eax, %ebp
testl %eax, %eax
jns 0x5dc7
callq 0x5070
cmpl $0x4, (%rax)
je 0x5da4
jmp 0x610c
testl %r12d, %r12d
sete %al
testl %ebp, %ebp
setne %cl
orb %al, %cl
jne 0x5de3
xorl %edi, %edi
callq 0x9fbb
pushq $0x1
popq %r12
jmp 0x5d6e
testl %ebp, %ebp
je 0x610c
movl %r12d, 0x14(%rsp)
xorl %r12d, %r12d
leaq 0x16359(%rip), %r14     # 0x1c153
leaq 0x16397(%rip), %r15     # 0x1c198
cmpq $0x2, %r12
je 0x60f9
movl 0x20(%rsp,%r12,8), %ebp
movswl 0x26(%rsp,%r12,8), %r13d
testb $0x38, %r13b
je 0x5ee4
movq %r12, 0x18(%rsp)
movq 0x2318c(%rip), %rax     # 0x28fb8
movq (%rax), %rbx
callq 0xe343
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x52c0
leaq 0x23e5a(%rip), %rax     # 0x29ca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x5e6e
callq 0xe343
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x52c0
movq %r15, %r12
movq %r14, %r15
movq 0x2313d(%rip), %rax     # 0x28fb8
movq (%rax), %rbx
callq 0xe343
movq %rbx, %rdi
leaq 0x16327(%rip), %r14     # 0x1c1b4
movq %r14, %rsi
movq %rax, %rdx
movl %ebp, %ecx
movl %r13d, %r8d
xorl %eax, %eax
callq 0x52c0
leaq 0x23e02(%rip), %rax     # 0x29ca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x5ec8
callq 0xe343
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rdx
movl %ebp, %ecx
movl %r13d, %r8d
xorl %eax, %eax
callq 0x52c0
testb $0x30, %r13b
leaq 0x23e5d(%rip), %rbx     # 0x29d30
movq %r15, %r14
movq %r12, %r15
movq 0x18(%rsp), %r12
jne 0x619b
testb $0x1, %r13b
je 0x605d
leaq 0x234e3(%rip), %rax     # 0x293d8
cmpl 0x4(%rax), %ebp
jne 0x5f2f
movl %ebp, %edi
leaq 0x3c(%rsp), %rsi
pushq $0x4
popq %rdx
callq 0x5250
cmpq $0x4, %rax
jne 0x5f27
movl 0x3c(%rsp), %ecx
pushq $0x1
popq %rax
cmpl $0x2, %ecx
je 0x5f2b
cmpl $0x1000, %ecx           # imm = 0x1000
je 0x619b
movl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
cmpl 0x233bb(%rip), %ebp     # 0x292f0
jne 0x605d
movq 0x40(%rsp), %rax
cmpb $0x0, (%rax)
je 0x5f92
movl %ebp, %edi
movq %rbx, %rsi
pushq $0x6
popq %rdx
callq 0x5250
movq %rax, %r13
cmpq $0x6, %rax
jne 0x5fa4
movzwl 0x1(%rbx), %edi
callq 0xe73e
pushq $0x6
popq %r13
cmpw $0xfff, %ax             # imm = 0xFFF
ja 0x5fad
movzwl 0x1(%rbx), %edi
callq 0xe73e
movzwl %ax, %edx
addq $-0x5, %rdx
leaq 0x6(%rbx), %rsi
movl %ebp, %edi
callq 0x5250
movq %rax, %r13
addq $0x6, %r13
jmp 0x5fa4
movl $0x1000, %edx           # imm = 0x1000
movl %ebp, %edi
movq %rbx, %rsi
callq 0x5250
movq %rax, %r13
testq %r13, %r13
jle 0x6065
movzwl 0x1(%rbx), %edi
callq 0xe73e
movzwl %ax, %eax
incq %rax
cmpq %rax, %r13
jne 0x5fce
movq %rbx, %rdi
callq 0x9fbb
jmp 0x605d
movq 0x22fe3(%rip), %rax     # 0x28fb8
movq %r14, %r15
movq %rbx, %r14
movq (%rax), %rbx
callq 0xe343
movq %rax, %rbp
movzwl 0x1(%r14), %edi
callq 0xe73e
movzwl %ax, %r9d
movq %rbx, %rdi
leaq 0x161fa(%rip), %rbx     # 0x1c1f8
movq %rbx, %rsi
movq %rbp, %rdx
movq %r15, %rcx
movl %r13d, %r8d
xorl %eax, %eax
callq 0x52c0
leaq 0x23c90(%rip), %rax     # 0x29ca8
movq (%rax), %rbp
testq %rbp, %rbp
je 0x6050
callq 0xe343
movq %rax, 0x18(%rsp)
movzwl 0x1(%r14), %edi
callq 0xe73e
movzwl %ax, %r9d
movq %rbp, %rdi
movq %rbx, %rsi
movq 0x18(%rsp), %rdx
movq %r15, %rcx
movl %r13d, %r8d
xorl %eax, %eax
callq 0x52c0
movq %r14, %rbx
movq %r15, %r14
leaq 0x1613b(%rip), %r15     # 0x1c198
incq %r12
jmp 0x5e01
movq 0x22f4c(%rip), %rax     # 0x28fb8
movq (%rax), %r15
callq 0xe343
movq %rax, %rbp
callq 0x5070
movq %rax, %r12
movl (%rax), %ebx
movl %ebx, %edi
callq 0x5540
movq %rax, (%rsp)
movq %r15, %rdi
movq %r14, %r15
leaq 0x1613f(%rip), %r14     # 0x1c1d8
movq %r14, %rsi
movq %rbp, %rdx
movq %r15, %rcx
movl %r13d, %r8d
movl %ebx, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x23bf2(%rip), %rax     # 0x29ca8
movq (%rax), %rbp
testq %rbp, %rbp
je 0x60f2
callq 0xe343
movq %rax, 0x18(%rsp)
movl (%r12), %ebx
movl %ebx, %edi
callq 0x5540
movq %rax, (%rsp)
movq %rbp, %rdi
movq %r14, %rsi
movq 0x18(%rsp), %rdx
movq %r15, %rcx
movl %r13d, %r8d
movl %ebx, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x23c37(%rip), %rbx     # 0x29d30
leaq 0x20(%rsp), %r14
pushq $0x2
popq %r15
movl 0x14(%rsp), %r12d
jmp 0x5d6e
movq 0x22ea5(%rip), %rax     # 0x28fb8
movq (%rax), %r14
callq 0xe343
movq %rax, %r15
callq 0x5070
movq %rax, %rbx
movl (%rax), %r12d
movl %r12d, %edi
callq 0x5540
movq %rax, (%rsp)
leaq 0x1603b(%rip), %rsi     # 0x1c177
leaq 0x16010(%rip), %rcx     # 0x1c153
movq %r14, %rdi
movq %r15, %rdx
movl %ebp, %r8d
movl %r12d, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x23b4b(%rip), %rax     # 0x29ca8
movq (%rax), %r14
testq %r14, %r14
je 0x619b
callq 0xe343
movq %rax, %r15
movl (%rbx), %ebx
movl %ebx, %edi
callq 0x5540
movq %rax, (%rsp)
leaq 0x15ff6(%rip), %rsi     # 0x1c177
leaq 0x15fcb(%rip), %rcx     # 0x1c153
movq %r14, %rdi
movq %r15, %rdx
movl %ebp, %r8d
movl %ebx, %r9d
xorl %eax, %eax
callq 0x52c0
movl 0x2314f(%rip), %edi     # 0x292f0
cmpl $-0x1, %edi
je 0x61b2
callq 0x5230
orl $-0x1, 0x2313e(%rip)    # 0x292f0
movl $0x1003, %edi           # imm = 0x1003
callq 0x7244
xorl %edi, %edi
callq 0x9fbb
movq 0x22dee(%rip), %rax     # 0x28fb8
movq (%rax), %rbx
callq 0xe343
leaq 0x1604f(%rip), %rsi     # 0x1c228
leaq 0x15f73(%rip), %rcx     # 0x1c153
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
leaq 0x23ab4(%rip), %rax     # 0x29ca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x621c
callq 0xe343
leaq 0x16020(%rip), %rsi     # 0x1c228
leaq 0x15f44(%rip), %rcx     # 0x1c153
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
xorl %edi, %edi
callq 0x5350