// File: /workspace/github_c_makefile_star2_O1/Carton32[P]quectel-CM/GobiNetCM.c
// Function: GobiNetThread
static void * GobiNetThread(void *pData) {
    PROFILE_T *profile = (PROFILE_T *)pData;
    const char *qcqmi = (const char *)profile->qmichannel;
    int wait_for_request_quit = 0;   
    
    qmiclientId[QMUX_TYPE_WDS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
    if (profile->enable_ipv6)
        qmiclientId[QMUX_TYPE_WDS_IPV6] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
    qmiclientId[QMUX_TYPE_DMS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_DMS);
    qmiclientId[QMUX_TYPE_NAS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_NAS);
    qmiclientId[QMUX_TYPE_UIM] = GobiNetGetClientID(qcqmi, QMUX_TYPE_UIM);
    if (profile->qmap_mode == 0 || profile->loopback_state) {//when QMAP enabled, set data format in GobiNet Driver
        qmiclientId[QMUX_TYPE_WDS_ADMIN] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS_ADMIN);
        profile->wda_client = qmiclientId[QMUX_TYPE_WDS_ADMIN];
    }

    //donot check clientWDA, there is only one client for WDA, if quectel-CM is killed by SIGKILL, i cannot get client ID for WDA again!
    if (qmiclientId[QMUX_TYPE_WDS] == 0)  /*|| (clientWDA == -1)*/ {
        GobiNetDeInit();
        dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, qcqmi, errno, strerror(errno));
        qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
        pthread_exit(NULL);
        return NULL;
    }

    qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);

    while (1) {
        struct pollfd pollfds[16] = {{qmidevice_control_fd[1], POLLIN, 0}};
        int ne, ret, nevents = 1;
        unsigned int i;

        for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
        {
            if (qmiclientId[i] != 0)
            {
                pollfds[nevents].fd = qmiclientId[i];
                pollfds[nevents].events = POLLIN;
                pollfds[nevents].revents = 0;
                nevents++;
            }
        }

        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); //main thread may pending on QmiThreadSendQMI()
		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;

            if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
                dbg_time("%s poll err/hup/inval", __func__);
                dbg_time("epoll fd = %d, events = 0x%04x", fd, revents);
                if (fd == qmidevice_control_fd[1]) {
                } else {
                }
                if (revents & (POLLERR | POLLHUP | POLLNVAL))
                    goto __GobiNetThread_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 __GobiNetThread_quit;
                        break;
                        case SIG_EVENT_STOP:
                            wait_for_request_quit = 1;   
                        break;
                        default:
                        break;
                    }
                }
                continue;
            }

            {
                ssize_t nreads;
                PQCQMIMSG pResponse = (PQCQMIMSG)cm_recv_buf;

                nreads = read(fd, &pResponse->MUXMsg, sizeof(cm_recv_buf) - sizeof(QCQMI_HDR));
                if (nreads <= 0)
                {
                    dbg_time("%s read=%d errno: %d (%s)",  __func__, (int)nreads, errno, strerror(errno));
                    break;
                }

                for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
                {
                    if (qmiclientId[i] == fd)
                    {
                        pResponse->QMIHdr.QMIType = i;
                    }
                }

                pResponse->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
                pResponse->QMIHdr.Length = cpu_to_le16(nreads + sizeof(QCQMI_HDR)  - 1);
                pResponse->QMIHdr.CtlFlags = 0x00;
                pResponse->QMIHdr.ClientId = (fd&0xFF) ? fd&0xFF : pResponse->QMIHdr.QMIType;;

                QmiThreadRecvQMI(pResponse);
            }
        }
    }

__GobiNetThread_quit:
    GobiNetDeInit();
    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 $0xb8, %rsp
movq %rdi, %r14
leaq 0x8a(%rdi), %rbx
movq %rbx, %rdi
movl $0x1, %esi
callq 0x706c
movl %eax, 0x23926(%rip)     # 0x2a364
cmpb $0x0, 0x51(%r14)
je 0x6a58
movq %rbx, %rdi
movl $0x1, %esi
callq 0x706c
movl %eax, 0x2394c(%rip)     # 0x2a3a4
movq %rbx, %rdi
movl $0x2, %esi
callq 0x706c
movl %eax, 0x238fd(%rip)     # 0x2a368
movq %rbx, %rdi
movl $0x3, %esi
callq 0x706c
movl %eax, 0x238ee(%rip)     # 0x2a36c
movq %rbx, %rdi
movl $0xb, %esi
callq 0x706c
movl %eax, 0x238fb(%rip)     # 0x2a38c
cmpl $0x0, 0x10a(%r14)
je 0x6aa5
cmpb $0x0, 0x215(%r14)
je 0x6abf
movq %rbx, %rdi
movl $0x1a, %esi
callq 0x706c
movl %eax, 0x23910(%rip)     # 0x2a3c8
movl %eax, 0x122(%r14)
cmpl $0x0, 0x2389e(%rip)     # 0x2a364
jne 0x6b92
xorl %r14d, %r14d
leaq 0x2388a(%rip), %r15     # 0x2a360
movl (%r14,%r15), %edi
testl %edi, %edi
je 0x6aeb
callq 0x5230
movl $0x0, (%r14,%r15)
addq $0x4, %r14
cmpq $0x6c, %r14
jne 0x6ad6
movq 0x234c4(%rip), %rax     # 0x29fc0
movq (%rax), %r15
callq 0xeb2f
movq %rax, %r12
callq 0x5070
movq %rax, %r14
movl (%rax), %ebp
movl %ebp, %edi
callq 0x5530
movq %rax, (%rsp)
leaq 0x17605(%rip), %rsi     # 0x1e128
leaq 0x1785e(%rip), %rcx     # 0x1e388
movq %r15, %rdi
movq %r12, %rdx
movq %rbx, %r8
movl %ebp, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x24164(%rip), %rax     # 0x2aca8
movq (%rax), %r15
testq %r15, %r15
je 0x6b83
callq 0xeb2f
movq %rax, %r12
movl (%r14), %ebp
movl %ebp, %edi
callq 0x5530
movq %rax, (%rsp)
leaq 0x175bf(%rip), %rsi     # 0x1e128
leaq 0x17818(%rip), %rcx     # 0x1e388
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 0x7065
leaq 0x237c7(%rip), %r14     # 0x2a360
movl $0x1002, %edi           # imm = 0x1002
callq 0x7444
leaq 0x30(%rsp), %r13
leaq 0x24181(%rip), %rax     # 0x2ad30
addq $0x6, %rax
movq %rax, 0x28(%rsp)
movl $0x0, 0xc(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0xa0(%rsp)
movaps %xmm0, 0x90(%rsp)
movaps %xmm0, 0x80(%rsp)
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
leaq 0x237dd(%rip), %rax     # 0x2a3d8
movl 0x4(%rax), %eax
movl %eax, 0x30(%rsp)
movw $0x1, 0x34(%rsp)
movl $0x1, %ebx
xorl %eax, %eax
movl (%rax,%r14), %ecx
testl %ecx, %ecx
je 0x6c29
movslq %ebx, %rbx
movl %ecx, 0x30(%rsp,%rbx,8)
movl $0x1, 0x34(%rsp,%rbx,8)
incl %ebx
addq $0x4, %rax
cmpq $0x6c, %rax
jne 0x6c10
movslq %ebx, %r12
cmpl $0x1, 0xc(%rsp)
movl $0x0, %r14d
sbbl %r14d, %r14d
orl $0x3e8, %r14d           # imm = 0x3E8
movq %r13, %rdi
movq %r12, %rsi
movl %r14d, %edx
callq 0x53c0
movl %eax, %ebp
testl %eax, %eax
jns 0x6c69
callq 0x5070
cmpl $0x4, (%rax)
je 0x6c4b
cmpl $0x0, 0xc(%rsp)
je 0x6c8d
testl %ebp, %ebp
jne 0x6c8d
xorl %edi, %edi
callq 0xa452
movl $0x1, 0xc(%rsp)
movl $0x4, %ebx
jmp 0x6fb7
testl %ebp, %ebp
jle 0x6f0b
testl %ebx, %ebx
jle 0x6fb5
movl %ebx, %eax
movq %rax, 0x18(%rsp)
xorl %r13d, %r13d
movl 0x30(%rsp,%r13,8), %ebp
movswl 0x36(%rsp,%r13,8), %r12d
testb $0x38, %r12b
je 0x6d75
movq 0x232fd(%rip), %rax     # 0x29fc0
movq (%rax), %r14
callq 0xeb2f
movq %r14, %rdi
leaq 0x174c3(%rip), %r15     # 0x1e198
movq %r15, %rsi
movq %rax, %rdx
leaq 0x176a6(%rip), %rbx     # 0x1e388
movq %rbx, %rcx
xorl %eax, %eax
callq 0x52c0
leaq 0x23fb5(%rip), %rax     # 0x2aca8
movq (%rax), %r14
testq %r14, %r14
je 0x6d13
callq 0xeb2f
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x52c0
movq 0x232a6(%rip), %rax     # 0x29fc0
movq (%rax), %r14
callq 0xeb2f
movq %r14, %rdi
leaq 0x1766a(%rip), %r15     # 0x1e396
movq %r15, %rsi
movq %rax, %rdx
movl %ebp, %ecx
movl %r12d, %r8d
xorl %eax, %eax
callq 0x52c0
leaq 0x23f63(%rip), %rax     # 0x2aca8
movq (%rax), %r14
movl $0x14, %ebx
testq %r14, %r14
je 0x6ee9
callq 0xeb2f
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
movl %ebp, %ecx
movl %r12d, %r8d
xorl %eax, %eax
callq 0x52c0
jmp 0x6ee9
movl $0xf, %ebx
testb $0x1, %r12b
je 0x6ee9
leaq 0x2364d(%rip), %rax     # 0x2a3d8
cmpl 0x4(%rax), %ebp
jne 0x6dd5
movl $0x4, %edx
movl %ebp, %edi
leaq 0x24(%rsp), %rsi
callq 0x5250
movl $0xf, %ebx
cmpq $0x4, %rax
jne 0x6ee9
movl 0x24(%rsp), %eax
cmpl $0x1000, %eax           # imm = 0x1000
je 0x6ee4
cmpl $0x2, %eax
jne 0x6ee9
movl $0x1, 0xc(%rsp)
jmp 0x6ee9
movl $0xffa, %edx            # imm = 0xFFA
movl %ebp, %edi
movq 0x28(%rsp), %rsi
callq 0x5250
movq %rax, %r12
testq %rax, %rax
jle 0x6e45
leaq 0x2356b(%rip), %rax     # 0x2a360
xorl %ecx, %ecx
leaq 0x23f32(%rip), %rbx     # 0x2ad30
cmpl %ebp, (%rax)
jne 0x6e05
movb %cl, 0x4(%rbx)
incq %rcx
addq $0x4, %rax
cmpq $0x1b, %rcx
jne 0x6dfe
movb $0x1, (%rbx)
leal 0x5(%r12), %eax
movzwl %ax, %edi
callq 0xef6c
movw %ax, 0x1(%rbx)
movb $0x0, 0x3(%rbx)
testb %bpl, %bpl
jne 0x6e32
movl 0x4(%rbx), %ebp
movb %bpl, 0x5(%rbx)
movq %rbx, %rdi
callq 0xa452
xorl %ebx, %ebx
jmp 0x6ee9
movq 0x23174(%rip), %rax     # 0x29fc0
movq (%rax), %rbx
callq 0xeb2f
movq %rax, 0x10(%rsp)
callq 0x5070
movq %rax, %r15
movl (%rax), %r14d
movl %r14d, %edi
callq 0x5530
movq %rax, (%rsp)
movq %rbx, %rdi
leaq 0x1735e(%rip), %rbp     # 0x1e1d8
movq %rbp, %rsi
movq 0x10(%rsp), %rdx
leaq 0x174ff(%rip), %rcx     # 0x1e388
movl %r12d, %r8d
movl %r14d, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x23e0b(%rip), %rax     # 0x2aca8
movq (%rax), %r14
movl $0xd, %ebx
testq %r14, %r14
je 0x6ee9
callq 0xeb2f
movq %rax, 0x10(%rsp)
movl (%r15), %r15d
movl %r15d, %edi
callq 0x5530
movq %rax, (%rsp)
movq %r14, %rdi
movq %rbp, %rsi
movq 0x10(%rsp), %rdx
leaq 0x174b3(%rip), %rcx     # 0x1e388
movl %r12d, %r8d
movl %r15d, %r9d
xorl %eax, %eax
callq 0x52c0
jmp 0x6ee9
movl $0x14, %ebx
testl %ebx, %ebx
je 0x6ef6
cmpl $0xf, %ebx
jne 0x6fab
incq %r13
cmpq 0x18(%rsp), %r13
jne 0x6ca7
xorl %ebx, %ebx
jmp 0x6fa4
movq 0x230ae(%rip), %rax     # 0x29fc0
movq (%rax), %rbx
callq 0xeb2f
movq %rax, %r14
callq 0x5070
movq %rax, %r15
movl (%rax), %r13d
movl %r13d, %edi
callq 0x5530
movq %rax, (%rsp)
movq %rbx, %rdi
leaq 0x17239(%rip), %r12     # 0x1e177
movq %r12, %rsi
movq %r14, %rdx
leaq 0x1743d(%rip), %rcx     # 0x1e388
movl %ebp, %r8d
movl %r13d, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x23d49(%rip), %rax     # 0x2aca8
movq (%rax), %r14
movl $0x5, %ebx
testq %r14, %r14
je 0x6fa4
callq 0xeb2f
movq %rax, 0x18(%rsp)
movl (%r15), %r13d
movl %r13d, %edi
callq 0x5530
movq %rax, (%rsp)
movq %r14, %rdi
movq %r12, %rsi
movq 0x18(%rsp), %rdx
leaq 0x173f1(%rip), %rcx     # 0x1e388
movl %ebp, %r8d
movl %r13d, %r9d
xorl %eax, %eax
callq 0x52c0
leaq 0x30(%rsp), %r13
jmp 0x6fb7
cmpl $0xd, %ebx
leaq 0x30(%rsp), %r13
jne 0x6fb7
xorl %ebx, %ebx
leaq 0x233a2(%rip), %r14     # 0x2a360
cmpl $0x3, %ebx
jle 0x6bc0
cmpl $0x4, %ebx
je 0x6bc0
cmpl $0x14, %ebx
xorl %ebx, %ebx
leaq 0x23384(%rip), %r14     # 0x2a360
movl (%rbx,%r14), %edi
testl %edi, %edi
je 0x6ff1
callq 0x5230
movl $0x0, (%rbx,%r14)
addq $0x4, %rbx
cmpq $0x6c, %rbx
jne 0x6fdc
movl $0x1003, %edi           # imm = 0x1003
callq 0x7444
xorl %edi, %edi
callq 0xa452
movq 0x22fad(%rip), %rax     # 0x29fc0
movq (%rax), %rbx
callq 0xeb2f
leaq 0x17206(%rip), %rsi     # 0x1e228
leaq 0x1735f(%rip), %rcx     # 0x1e388
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
leaq 0x23c6b(%rip), %rax     # 0x2aca8
movq (%rax), %rbx
testq %rbx, %rbx
je 0x7065
callq 0xeb2f
leaq 0x171d7(%rip), %rsi     # 0x1e228
leaq 0x17330(%rip), %rcx     # 0x1e388
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x52c0
xorl %edi, %edi
callq 0x5350