// File: /workspace/github_c_makefile_star2_O3/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 $0x38, %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 0x5c9e
cmpl $0x2, 0x10a(%r14)
jge 0x5cb6
jmp 0x5cd6
leaq 0x1846c(%rip), %rsi     # 0x1e111
movl $0x11, %edx
movq %r15, %rdi
callq 0x5090
testl %eax, %eax
jne 0x5ce6
leaq 0x18466(%rip), %rdx     # 0x1e123
leaq 0x1844d(%rip), %rcx     # 0x1e111
movl $0x20, %esi
movq %r15, %rdi
movl %ebp, %r8d
xorl %eax, %eax
callq 0x51c0
cmpb $0x0, (%r15)
jne 0x5ce6
movq %rbx, %rdi
callq 0xe8d8
jmp 0x5cee
movq %r15, %rdi
callq 0xeae1
movl %eax, %ebp
movl %eax, 0x245fa(%rip)     # 0x2a2f0
movq 0x242c3(%rip), %rax     # 0x29fc0
movq (%rax), %r13
callq 0xea3b
movq %rax, %r12
cmpl $-0x1, %ebp
jne 0x5d9c
callq 0x5070
movq %rax, %r14
movl (%rax), %ebp
movl %ebp, %edi
callq 0x5530
movq %rax, (%rsp)
leaq 0x183fb(%rip), %rsi     # 0x1e128
leaq 0x1841f(%rip), %rcx     # 0x1e153
movq %r13, %rdi
movq %r12, %rdx
movq %rbx, %r8
movl %ebp, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x24f5a(%rip), %rax     # 0x2aca8
movq (%rax), %r15
testq %r15, %r15
je 0x5d8d
callq 0xea3b
movq %rax, %r12
movl (%r14), %ebp
movl %ebp, %edi
callq 0x5530
movq %rax, (%rsp)
leaq 0x183b5(%rip), %rsi     # 0x1e128
leaq 0x183d9(%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 0x7354
jmp 0x62c6
movq %r15, 0x30(%rsp)
movl 0x24549(%rip), %ecx     # 0x2a2f0
leaq 0x183b3(%rip), %rsi     # 0x1e161
movq %r13, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x52c0
leaq 0x24ee6(%rip), %rax     # 0x2aca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x5de9
callq 0xea3b
movl 0x2451b(%rip), %ecx     # 0x2a2f0
leaq 0x18385(%rip), %rsi     # 0x1e161
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
movl $0x1002, %edi           # imm = 0x1002
callq 0x7354
leaq 0x10(%rsp), %r14
xorl %ebp, %ebp
leaq 0x245d7(%rip), %rax     # 0x2a3d8
movl 0x4(%rax), %eax
movl %eax, 0x10(%rsp)
movl $0x1, %ecx
movl %ecx, 0x14(%rsp)
movl 0x244d9(%rip), %eax     # 0x2a2f0
movl %eax, 0x18(%rsp)
movl %ecx, 0x1c(%rsp)
cmpl %ecx, %ebp
movl $0x0, %r12d
sbbl %r12d, %r12d
orl $0x3e8, %r12d           # imm = 0x3E8
movl $0x2, %esi
movq %r14, %rdi
movl %r12d, %edx
callq 0x53c0
movl %eax, %ebx
testl %eax, %eax
jns 0x5e56
callq 0x5070
cmpl $0x4, (%rax)
je 0x5e31
jmp 0x61b4
testl %ebp, %ebp
sete %al
testl %ebx, %ebx
setne %cl
orb %al, %cl
jne 0x5e78
xorl %edi, %edi
callq 0xa3ae
movl $0x1, 0x8(%rsp)
jmp 0x610f
testl %ebx, %ebx
je 0x61b4
movl %ebp, 0x8(%rsp)
movb $0x1, %bpl
movq %r14, %rax
leaq 0x18307(%rip), %r14     # 0x1e198
movl (%rax), %ebx
movswl 0x6(%rax), %r12d
testb $0x38, %r12b
je 0x5f51
movq 0x24117(%rip), %rax     # 0x29fc0
movq (%rax), %r13
callq 0xea3b
movq %r13, %rdi
movq %r14, %rsi
movq %rax, %rdx
leaq 0x18292(%rip), %rcx     # 0x1e153
xorl %eax, %eax
callq 0x52c0
leaq 0x24dd9(%rip), %rax     # 0x2aca8
movq (%rax), %r13
testq %r13, %r13
je 0x5ef3
callq 0xea3b
movq %r13, %rdi
movq %r14, %rsi
movq %rax, %rdx
leaq 0x18267(%rip), %rcx     # 0x1e153
xorl %eax, %eax
callq 0x52c0
movq 0x240c6(%rip), %rax     # 0x29fc0
movq (%rax), %r13
callq 0xea3b
movq %r13, %rdi
leaq 0x182a8(%rip), %r15     # 0x1e1b4
movq %r15, %rsi
movq %rax, %rdx
movl %ebx, %ecx
movl %r12d, %r8d
xorl %eax, %eax
callq 0x52c0
leaq 0x24d83(%rip), %rax     # 0x2aca8
movq (%rax), %r13
testq %r13, %r13
je 0x5f47
callq 0xea3b
movq %r13, %rdi
movq %r15, %rsi
movq %rax, %rdx
movl %ebx, %ecx
movl %r12d, %r8d
xorl %eax, %eax
callq 0x52c0
testb $0x30, %r12b
jne 0x6242
testb $0x1, %r12b
je 0x60fb
leaq 0x24476(%rip), %rax     # 0x2a3d8
cmpl 0x4(%rax), %ebx
jne 0x5fa0
movl $0x4, %edx
movl %ebx, %edi
leaq 0xc(%rsp), %rsi
callq 0x5250
cmpq $0x4, %rax
jne 0x5f98
movl $0x1, %eax
movl 0xc(%rsp), %ecx
cmpl $0x2, %ecx
je 0x5f9c
cmpl $0x1000, %ecx           # imm = 0x1000
je 0x6242
movl 0x8(%rsp), %eax
movl %eax, 0x8(%rsp)
cmpl 0x2434a(%rip), %ebx     # 0x2a2f0
jne 0x60fb
movq 0x30(%rsp), %rax
cmpb $0x0, (%rax)
je 0x6025
movl $0x6, %edx
movl %ebx, %edi
leaq 0x24d6c(%rip), %rsi     # 0x2ad30
callq 0x5250
movq %rax, %r12
cmpq $0x6, %rax
jne 0x603b
leaq 0x24d57(%rip), %rax     # 0x2ad30
movzwl 0x1(%rax), %edi
callq 0xee73
movzwl %ax, %eax
movl $0x6, %r12d
cmpl $0xfff, %eax            # imm = 0xFFF
ja 0x6044
leaq 0x24d37(%rip), %r15     # 0x2ad30
movzwl 0x1(%r15), %edi
callq 0xee73
movzwl %ax, %edx
addq $-0x5, %rdx
leaq 0x6(%r15), %rsi
leaq 0x18183(%rip), %r14     # 0x1e198
movl %ebx, %edi
callq 0x5250
movq %rax, %r12
addq $0x6, %r12
jmp 0x603b
movl $0x1000, %edx           # imm = 0x1000
movl %ebx, %edi
leaq 0x24cfd(%rip), %rsi     # 0x2ad30
callq 0x5250
movq %rax, %r12
testq %r12, %r12
jle 0x611d
leaq 0x24ce5(%rip), %rbx     # 0x2ad30
movzwl 0x1(%rbx), %edi
callq 0xee73
movzwl %ax, %eax
incq %rax
cmpq %rax, %r12
jne 0x606c
movq %rbx, %rdi
callq 0xa3ae
jmp 0x60fb
movq 0x23f4d(%rip), %rax     # 0x29fc0
leaq 0x180d9(%rip), %r15     # 0x1e153
movq %rbx, %r14
movq (%rax), %rbx
callq 0xea3b
movq %rax, %r13
movzwl 0x1(%r14), %edi
callq 0xee73
movzwl %ax, %r9d
movq %rbx, %rdi
leaq 0x18158(%rip), %r14     # 0x1e1f8
movq %r14, %rsi
movq %r13, %rdx
movq %r15, %rcx
movl %r12d, %r8d
xorl %eax, %eax
callq 0x52c0
leaq 0x24bee(%rip), %rax     # 0x2aca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x60f4
callq 0xea3b
movq %rax, %r13
leaq 0x24c5f(%rip), %rax     # 0x2ad30
movzwl 0x1(%rax), %edi
callq 0xee73
movzwl %ax, %r9d
movq %rbx, %rdi
movq %r14, %rsi
movq %r13, %rdx
movq %r15, %rcx
movl %r12d, %r8d
xorl %eax, %eax
callq 0x52c0
leaq 0x1809d(%rip), %r14     # 0x1e198
leaq 0x18(%rsp), %rax
testb $0x1, %bpl
movl $0x0, %ebp
jne 0x5e91
leaq 0x10(%rsp), %r14
movl 0x8(%rsp), %ebp
jmp 0x5dfa
movq 0x23e9c(%rip), %rax     # 0x29fc0
movq (%rax), %r14
callq 0xea3b
movq %rax, %r13
callq 0x5070
movq %rax, %rbp
movl (%rax), %ebx
movl %ebx, %edi
callq 0x5530
movq %rax, (%rsp)
movq %r14, %rdi
leaq 0x18005(%rip), %r14     # 0x1e153
leaq 0x18083(%rip), %r15     # 0x1e1d8
movq %r15, %rsi
movq %r13, %rdx
movq %r14, %rcx
movl %r12d, %r8d
movl %ebx, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x24b36(%rip), %rax     # 0x2aca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x610f
callq 0xea3b
movq %rax, 0x28(%rsp)
movl (%rbp), %r13d
movl %r13d, %edi
callq 0x5530
movq %rax, (%rsp)
movq %rbx, %rdi
movq %r15, %rsi
movq 0x28(%rsp), %rdx
movq %r14, %rcx
movl %r12d, %r8d
movl %r13d, %r9d
xorl %eax, %eax
callq 0x52c0
jmp 0x610f
movq 0x23e05(%rip), %rax     # 0x29fc0
movq (%rax), %r13
callq 0xea3b
movq %rax, %r12
callq 0x5070
movq %rax, %r14
movl (%rax), %ebp
movl %ebp, %edi
callq 0x5530
movq %rax, (%rsp)
leaq 0x17f95(%rip), %rsi     # 0x1e177
leaq 0x17f6a(%rip), %rcx     # 0x1e153
movq %r13, %rdi
movq %r12, %rdx
movl %ebx, %r8d
movl %ebp, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x24aa5(%rip), %rax     # 0x2aca8
movq (%rax), %r13
testq %r13, %r13
je 0x6242
callq 0xea3b
movq %rax, %r12
movl (%r14), %ebp
movl %ebp, %edi
callq 0x5530
movq %rax, (%rsp)
leaq 0x17f4f(%rip), %rsi     # 0x1e177
leaq 0x17f24(%rip), %rcx     # 0x1e153
movq %r13, %rdi
movq %r12, %rdx
movl %ebx, %r8d
movl %ebp, %r9d
xorl %eax, %eax
callq 0x52c0
movl 0x240a8(%rip), %edi     # 0x2a2f0
cmpl $-0x1, %edi
je 0x625c
callq 0x5230
movl $0xffffffff, 0x24094(%rip) # imm = 0xFFFFFFFF
movl $0x1003, %edi           # imm = 0x1003
callq 0x7354
xorl %edi, %edi
callq 0xa3ae
movq 0x23d4c(%rip), %rax     # 0x29fc0
movq (%rax), %rbx
callq 0xea3b
leaq 0x17fa5(%rip), %rsi     # 0x1e228
leaq 0x17ec9(%rip), %rcx     # 0x1e153
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
leaq 0x24a0a(%rip), %rax     # 0x2aca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x62c6
callq 0xea3b
leaq 0x17f76(%rip), %rsi     # 0x1e228
leaq 0x17e9a(%rip), %rcx     # 0x1e153
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
xorl %edi, %edi
callq 0x5350