// File: /workspace/github_c_makefile_star2_O1/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)
jne 0x5cc0
cmpl $0x2, 0x10a(%r14)
jge 0x5cd8
jmp 0x5cf8
leaq 0x1844a(%rip), %rsi     # 0x1e111
movl $0x11, %edx
movq %r15, %rdi
callq 0x5090
testl %eax, %eax
jne 0x5cf8
leaq 0x18444(%rip), %rdx     # 0x1e123
leaq 0x1842b(%rip), %rcx     # 0x1e111
movl $0x20, %esi
movq %r15, %rdi
movl %ebp, %r8d
xorl %eax, %eax
callq 0x51c0
cmpb $0x0, (%r15)
movq %r15, 0x40(%rsp)
jne 0x5d0d
movq %rbx, %rdi
callq 0xe9cc
jmp 0x5d15
movq %r15, %rdi
callq 0xebd5
movl %eax, %ebp
movl %eax, 0x245d3(%rip)     # 0x2a2f0
movq 0x2429c(%rip), %rax     # 0x29fc0
movq (%rax), %r15
callq 0xeb2f
movq %rax, %r12
cmpl $-0x1, %ebp
jne 0x5dc3
callq 0x5070
movq %rax, %r14
movl (%rax), %ebp
movl %ebp, %edi
callq 0x5530
movq %rax, (%rsp)
leaq 0x183d4(%rip), %rsi     # 0x1e128
leaq 0x183f8(%rip), %rcx     # 0x1e153
movq %r15, %rdi
movq %r12, %rdx
movq %rbx, %r8
movl %ebp, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x24f33(%rip), %rax     # 0x2aca8
movq (%rax), %r15
testq %r15, %r15
je 0x5db4
callq 0xeb2f
movq %rax, %r12
movl (%r14), %ebp
movl %ebp, %edi
callq 0x5530
movq %rax, (%rsp)
leaq 0x1838e(%rip), %rsi     # 0x1e128
leaq 0x183b2(%rip), %rcx     # 0x1e153
movq %r15, %rdi
movq %r12, %rdx
movq %rbx, %r8
movl %ebp, %r9d
xorl %eax, %eax
callq 0x52c0
movl $0x1003, %edi           # imm = 0x1003
callq 0x7444
jmp 0x6350
movl 0x24527(%rip), %ecx     # 0x2a2f0
leaq 0x18391(%rip), %rsi     # 0x1e161
movq %r15, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x52c0
leaq 0x24ec4(%rip), %rax     # 0x2aca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x5e0b
callq 0xeb2f
movl 0x244f9(%rip), %ecx     # 0x2a2f0
leaq 0x18363(%rip), %rsi     # 0x1e161
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
movl $0x1002, %edi           # imm = 0x1002
callq 0x7444
leaq 0x20(%rsp), %r14
xorl %r15d, %r15d
leaq 0x245b4(%rip), %rax     # 0x2a3d8
movl 0x4(%rax), %eax
movl %eax, 0x20(%rsp)
movl $0x1, %ecx
movl %ecx, 0x24(%rsp)
movl 0x244b6(%rip), %eax     # 0x2a2f0
movl %eax, 0x28(%rsp)
movl %ecx, 0x2c(%rsp)
cmpl %ecx, %r15d
movl $0x0, %ebp
sbbl %ebp, %ebp
orl $0x3e8, %ebp            # imm = 0x3E8
movl $0x2, %esi
movq %r14, %rdi
movl %ebp, %edx
callq 0x53c0
movl %eax, %ebx
testl %eax, %eax
jns 0x5e71
callq 0x5070
cmpl $0x4, (%rax)
je 0x5e52
testl %r15d, %r15d
sete %al
testl %ebx, %ebx
setne %cl
orb %al, %cl
jne 0x5e99
xorl %edi, %edi
callq 0xa452
movl $0x1, 0x14(%rsp)
movl $0x6, %ebp
jmp 0x62ad
movl %r15d, 0x14(%rsp)
testl %ebx, %ebx
jle 0x620c
xorl %r12d, %r12d
movl 0x20(%rsp,%r12,8), %ebx
movswl 0x26(%rsp,%r12,8), %ebp
testb $0x38, %bpl
je 0x5f79
movq 0x240fb(%rip), %rax     # 0x29fc0
movq (%rax), %r15
callq 0xeb2f
movq %r15, %rdi
leaq 0x182c1(%rip), %r14     # 0x1e198
movq %r14, %rsi
movq %rax, %rdx
leaq 0x1826f(%rip), %r13     # 0x1e153
movq %r13, %rcx
xorl %eax, %eax
callq 0x52c0
leaq 0x24db3(%rip), %rax     # 0x2aca8
movq (%rax), %r15
testq %r15, %r15
je 0x5f15
callq 0xeb2f
movq %r15, %rdi
movq %r14, %rsi
movq %rax, %rdx
movq %r13, %rcx
xorl %eax, %eax
callq 0x52c0
movq 0x240a4(%rip), %rax     # 0x29fc0
movq (%rax), %r15
callq 0xeb2f
movq %r15, %rdi
leaq 0x18286(%rip), %r14     # 0x1e1b4
movq %r14, %rsi
movq %rax, %rdx
movl %ebx, %ecx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x52c0
leaq 0x24d61(%rip), %rax     # 0x2aca8
movq (%rax), %r15
testq %r15, %r15
je 0x5f69
callq 0xeb2f
movq %r15, %rdi
movq %r14, %rsi
movq %rax, %rdx
movl %ebx, %ecx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x52c0
movl $0x13, %r13d
testb $0x30, %bpl
jne 0x61e9
movl $0xe, %r13d
testb $0x1, %bpl
je 0x61e9
leaq 0x24448(%rip), %rax     # 0x2a3d8
cmpl 0x4(%rax), %ebx
jne 0x5fde
movl $0x4, %edx
movl %ebx, %edi
leaq 0x3c(%rsp), %rsi
callq 0x5250
xorl %r13d, %r13d
movb $0x1, %cl
cmpq $0x4, %rax
jne 0x5fd6
movl 0x3c(%rsp), %eax
cmpl $0x1000, %eax           # imm = 0x1000
je 0x5fce
cmpl $0x2, %eax
jne 0x5fc9
movl $0x1, 0x14(%rsp)
xorl %r13d, %r13d
jmp 0x5fd6
movl $0x13, %r13d
xorl %ecx, %ecx
testb %cl, %cl
je 0x61e9
cmpl 0x2430c(%rip), %ebx     # 0x2a2f0
jne 0x61e6
movq 0x40(%rsp), %rax
cmpb $0x0, (%rax)
je 0x605b
movl $0x6, %edx
movl %ebx, %edi
leaq 0x24d2e(%rip), %rsi     # 0x2ad30
callq 0x5250
movq %rax, %rbp
cmpq $0x6, %rax
jne 0x6071
leaq 0x24d19(%rip), %rax     # 0x2ad30
movzwl 0x1(%rax), %edi
callq 0xef61
movzwl %ax, %eax
movl $0x6, %ebp
cmpl $0xfff, %eax            # imm = 0xFFF
ja 0x6071
leaq 0x24cfa(%rip), %r15     # 0x2ad30
movzwl 0x1(%r15), %edi
callq 0xef61
movzwl %ax, %edx
addq $-0x5, %rdx
leaq 0x6(%r15), %rsi
movl %ebx, %edi
callq 0x5250
movq %rax, %rbp
addq $0x6, %rbp
jmp 0x6071
movl $0x1000, %edx           # imm = 0x1000
movl %ebx, %edi
leaq 0x24cc7(%rip), %rsi     # 0x2ad30
callq 0x5250
movq %rax, %rbp
testq %rbp, %rbp
jle 0x60a7
leaq 0x24cb3(%rip), %rbx     # 0x2ad30
movzwl 0x1(%rbx), %edi
callq 0xef61
movzwl %ax, %eax
incq %rax
cmpq %rax, %rbp
jne 0x614f
movq %rbx, %rdi
callq 0xa452
xorl %r13d, %r13d
movb $0x1, %bl
jmp 0x61e2
movq 0x23f12(%rip), %rax     # 0x29fc0
movq (%rax), %rax
movq %rax, 0x18(%rsp)
callq 0xeb2f
movq %rax, %r15
callq 0x5070
movq %rax, %r14
movl (%rax), %r13d
movl %r13d, %edi
callq 0x5530
movq %rax, (%rsp)
xorl %ebx, %ebx
movq 0x18(%rsp), %rdi
leaq 0x180f5(%rip), %rsi     # 0x1e1d8
movq %r15, %rdx
leaq 0x18066(%rip), %rcx     # 0x1e153
movl %ebp, %r8d
movl %r13d, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x24ba7(%rip), %rax     # 0x2aca8
movq (%rax), %r15
movl $0xc, %r13d
testq %r15, %r15
je 0x61e2
callq 0xeb2f
movq %rax, 0x18(%rsp)
movl (%r14), %r14d
movl %r14d, %edi
callq 0x5530
movq %rax, (%rsp)
xorl %ebx, %ebx
movq %r15, %rdi
leaq 0x180a0(%rip), %rsi     # 0x1e1d8
movq 0x18(%rsp), %rdx
leaq 0x1800f(%rip), %rcx     # 0x1e153
movl %ebp, %r8d
movl %r14d, %r9d
jmp 0x61db
movq 0x23e6a(%rip), %rax     # 0x29fc0
movq (%rax), %r13
callq 0xeb2f
movq %rax, %r15
movzwl 0x1(%rbx), %edi
callq 0xef61
movzwl %ax, %r9d
xorl %ebx, %ebx
movq %r13, %rdi
leaq 0x1807e(%rip), %rsi     # 0x1e1f8
movq %r15, %rdx
leaq 0x17fcf(%rip), %r14     # 0x1e153
movq %r14, %rcx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x52c0
leaq 0x24b10(%rip), %rax     # 0x2aca8
movq (%rax), %r15
movl $0xe, %r13d
testq %r15, %r15
je 0x61e2
callq 0xeb2f
movq %rax, 0x18(%rsp)
leaq 0x24b79(%rip), %rax     # 0x2ad30
movzwl 0x1(%rax), %edi
callq 0xef61
movzwl %ax, %r9d
xorl %ebx, %ebx
movq %r15, %rdi
leaq 0x18028(%rip), %rsi     # 0x1e1f8
movq 0x18(%rsp), %rdx
movq %r14, %rcx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x52c0
testb %bl, %bl
je 0x61e9
xorl %r13d, %r13d
xorl %ebp, %ebp
testl %r13d, %r13d
je 0x61fa
cmpl $0xe, %r13d
jne 0x62a4
incq %r12
cmpq $0x1, %r12
je 0x5ea9
jmp 0x62ad
movq 0x23dad(%rip), %rax     # 0x29fc0
movq (%rax), %r15
callq 0xeb2f
movq %rax, %rbp
callq 0x5070
movq %rax, %r13
movl (%rax), %r12d
movl %r12d, %edi
callq 0x5530
movq %rax, (%rsp)
movq %r15, %rdi
leaq 0x17f38(%rip), %r14     # 0x1e177
movq %r14, %rsi
movq %rbp, %rdx
leaq 0x17f07(%rip), %rcx     # 0x1e153
movl %ebx, %r8d
movl %r12d, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x24a48(%rip), %rax     # 0x2aca8
movq (%rax), %r15
movl $0x7, %ebp
testq %r15, %r15
je 0x62ad
callq 0xeb2f
movq %rax, %r12
movl (%r13), %r13d
movl %r13d, %edi
callq 0x5530
movq %rax, (%rsp)
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
leaq 0x17ebe(%rip), %rcx     # 0x1e153
movl %ebx, %r8d
movl %r13d, %r9d
xorl %eax, %eax
callq 0x52c0
jmp 0x62ad
cmpl $0xc, %r13d
je 0x62ad
movl %r13d, %ebp
cmpl $0x5, %ebp
leaq 0x20(%rsp), %r14
movl 0x14(%rsp), %r15d
jle 0x5e1d
cmpl $0x6, %ebp
je 0x5e1d
cmpl $0x13, %ebp
movl 0x2401e(%rip), %edi     # 0x2a2f0
cmpl $-0x1, %edi
je 0x62e6
callq 0x5230
movl $0xffffffff, 0x2400a(%rip) # imm = 0xFFFFFFFF
movl $0x1003, %edi           # imm = 0x1003
callq 0x7444
xorl %edi, %edi
callq 0xa452
movq 0x23cc2(%rip), %rax     # 0x29fc0
movq (%rax), %rbx
callq 0xeb2f
leaq 0x17f1b(%rip), %rsi     # 0x1e228
leaq 0x17e3f(%rip), %rcx     # 0x1e153
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
leaq 0x24980(%rip), %rax     # 0x2aca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x6350
callq 0xeb2f
leaq 0x17eec(%rip), %rsi     # 0x1e228
leaq 0x17e10(%rip), %rcx     # 0x1e153
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
xorl %edi, %edi
callq 0x5350