// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
addq $0x8a, %rax
movq %rax, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x7c60
movl %eax, 0x301c4(%rip)     # 0x37524
movq -0x10(%rbp), %rax
cmpb $0x0, 0x51(%rax)
je 0x737e
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x7c60
movl %eax, 0x301e6(%rip)     # 0x37564
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x7c60
movl %eax, 0x30196(%rip)     # 0x37528
movq -0x18(%rbp), %rdi
movl $0x3, %esi
callq 0x7c60
movl %eax, 0x30186(%rip)     # 0x3752c
movq -0x18(%rbp), %rdi
movl $0xb, %esi
callq 0x7c60
movl %eax, 0x30192(%rip)     # 0x3754c
movq -0x10(%rbp), %rax
cmpl $0x0, 0x10a(%rax)
je 0x73d7
movq -0x10(%rbp), %rax
movzbl 0x215(%rax), %eax
cmpl $0x0, %eax
je 0x73fb
movq -0x18(%rbp), %rdi
movl $0x1a, %esi
callq 0x7c60
movl %eax, 0x3019d(%rip)     # 0x37588
movl 0x30197(%rip), %ecx     # 0x37588
movq -0x10(%rbp), %rax
movl %ecx, 0x122(%rax)
cmpl $0x0, 0x30122(%rip)     # 0x37524
jne 0x751b
callq 0x70a0
movq 0x2fbcc(%rip), %rax     # 0x36fe0
movq (%rax), %rax
movq %rax, -0xf0(%rbp)
callq 0x13930
movq %rax, -0xe8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xe0(%rbp)
callq 0x5070
movl (%rax), %eax
movl %eax, -0xd4(%rbp)
callq 0x5070
movl (%rax), %edi
callq 0x5540
movq -0xf0(%rbp), %rdi
movq -0xe8(%rbp), %rdx
movq -0xe0(%rbp), %r8
movl -0xd4(%rbp), %r9d
leaq 0x23cf3(%rip), %rsi     # 0x2b164
leaq 0x23f88(%rip), %rcx     # 0x2b400
movq %rax, (%rsp)
movb $0x0, %al
callq 0x52c0
leaq 0x309de(%rip), %rax     # 0x37e68
cmpq $0x0, (%rax)
je 0x7506
leaq 0x309d1(%rip), %rax     # 0x37e68
movq (%rax), %rax
movq %rax, -0x110(%rbp)
callq 0x13930
movq %rax, -0x108(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x100(%rbp)
callq 0x5070
movl (%rax), %eax
movl %eax, -0xf4(%rbp)
callq 0x5070
movl (%rax), %edi
callq 0x5540
movq -0x110(%rbp), %rdi
movq -0x108(%rbp), %rdx
movq -0x100(%rbp), %r8
movl -0xf4(%rbp), %r9d
leaq 0x23c70(%rip), %rsi     # 0x2b164
leaq 0x23f05(%rip), %rcx     # 0x2b400
movq %rax, (%rsp)
movb $0x0, %al
callq 0x52c0
jmp 0x7508
movl $0x1003, %edi           # imm = 0x1003
callq 0x8240
xorl %eax, %eax
movl %eax, %edi
callq 0x5360
movl $0x1002, %edi           # imm = 0x1002
callq 0x8240
leaq -0xa0(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x5200
leaq 0x30055(%rip), %rax     # 0x37594
movl 0x4(%rax), %eax
movl %eax, -0xa0(%rbp)
movw $0x1, -0x9c(%rbp)
movl $0x1, -0xac(%rbp)
movl $0x0, -0xb0(%rbp)
movl -0xb0(%rbp), %eax
cmpq $0x1b, %rax
jae 0x75ed
movl -0xb0(%rbp), %eax
movl %eax, %ecx
leaq 0x2ffa0(%rip), %rax     # 0x37520
cmpl $0x0, (%rax,%rcx,4)
je 0x75d7
movl -0xb0(%rbp), %eax
movl %eax, %ecx
leaq 0x2ff8b(%rip), %rax     # 0x37520
movl (%rax,%rcx,4), %ecx
movslq -0xac(%rbp), %rax
movl %ecx, -0xa0(%rbp,%rax,8)
movslq -0xac(%rbp), %rax
movw $0x1, -0x9c(%rbp,%rax,8)
movslq -0xac(%rbp), %rax
movw $0x0, -0x9a(%rbp,%rax,8)
movl -0xac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
jmp 0x75d9
movl -0xb0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb0(%rbp)
jmp 0x7565
jmp 0x75ef
leaq -0xa0(%rbp), %rdi
movslq -0xac(%rbp), %rsi
movl -0x1c(%rbp), %ecx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl $0x3e8, %eax            # imm = 0x3E8
cmpl $0x0, %ecx
cmovnel %eax, %edx
callq 0x53d0
movl %eax, -0xa8(%rbp)
xorl %eax, %eax
cmpl $0x0, -0xa8(%rbp)
movb %al, -0x111(%rbp)
jge 0x763d
callq 0x5070
cmpl $0x4, (%rax)
sete %al
movb %al, -0x111(%rbp)
movb -0x111(%rbp), %al
testb $0x1, %al
jne 0x75ef
cmpl $0x0, -0xa8(%rbp)
jne 0x7664
cmpl $0x0, -0x1c(%rbp)
je 0x7664
xorl %eax, %eax
movl %eax, %edi
callq 0xc800
jmp 0x7525
cmpl $0x0, -0xa8(%rbp)
jg 0x7775
jmp 0x7673
movq 0x2f966(%rip), %rax     # 0x36fe0
movq (%rax), %rax
movq %rax, -0x130(%rbp)
callq 0x13930
movq %rax, -0x128(%rbp)
movl -0xa8(%rbp), %eax
movl %eax, -0x11c(%rbp)
callq 0x5070
movl (%rax), %eax
movl %eax, -0x118(%rbp)
callq 0x5070
movl (%rax), %edi
callq 0x5540
movq -0x130(%rbp), %rdi
movq -0x128(%rbp), %rdx
movl -0x11c(%rbp), %r8d
movl -0x118(%rbp), %r9d
leaq 0x23adb(%rip), %rsi     # 0x2b1b3
leaq 0x23d21(%rip), %rcx     # 0x2b400
movq %rax, (%rsp)
movb $0x0, %al
callq 0x52c0
leaq 0x30777(%rip), %rax     # 0x37e68
cmpq $0x0, (%rax)
je 0x776e
leaq 0x3076a(%rip), %rax     # 0x37e68
movq (%rax), %rax
movq %rax, -0x148(%rbp)
callq 0x13930
movq %rax, -0x140(%rbp)
movl -0xa8(%rbp), %eax
movl %eax, -0x138(%rbp)
callq 0x5070
movl (%rax), %eax
movl %eax, -0x134(%rbp)
callq 0x5070
movl (%rax), %edi
callq 0x5540
movq -0x148(%rbp), %rdi
movq -0x140(%rbp), %rdx
movl -0x138(%rbp), %r8d
movl -0x134(%rbp), %r9d
leaq 0x23a57(%rip), %rsi     # 0x2b1b3
leaq 0x23c9d(%rip), %rcx     # 0x2b400
movq %rax, (%rsp)
movb $0x0, %al
callq 0x52c0
jmp 0x7770
jmp 0x7bb8
movl $0x0, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
cmpl -0xac(%rbp), %eax
jge 0x7bb3
movslq -0xa4(%rbp), %rax
movl -0xa0(%rbp,%rax,8), %eax
movl %eax, -0xb4(%rbp)
movslq -0xa4(%rbp), %rax
movw -0x9a(%rbp,%rax,8), %ax
movw %ax, -0xb6(%rbp)
movswl -0xb6(%rbp), %eax
andl $0x38, %eax
cmpl $0x0, %eax
je 0x78fe
jmp 0x77d0
movq 0x2f809(%rip), %rax     # 0x36fe0
movq (%rax), %rax
movq %rax, -0x150(%rbp)
callq 0x13930
movq -0x150(%rbp), %rdi
movq %rax, %rdx
leaq 0x239dd(%rip), %rsi     # 0x2b1d4
leaq 0x23c02(%rip), %rcx     # 0x2b400
movb $0x0, %al
callq 0x52c0
leaq 0x3065c(%rip), %rax     # 0x37e68
cmpq $0x0, (%rax)
je 0x7847
leaq 0x3064f(%rip), %rax     # 0x37e68
movq (%rax), %rax
movq %rax, -0x158(%rbp)
callq 0x13930
movq -0x158(%rbp), %rdi
movq %rax, %rdx
leaq 0x2399b(%rip), %rsi     # 0x2b1d4
leaq 0x23bc0(%rip), %rcx     # 0x2b400
movb $0x0, %al
callq 0x52c0
jmp 0x7849
jmp 0x784b
movq 0x2f78e(%rip), %rax     # 0x36fe0
movq (%rax), %rax
movq %rax, -0x160(%rbp)
callq 0x13930
movq -0x160(%rbp), %rdi
movq %rax, %rdx
movl -0xb4(%rbp), %ecx
movswl -0xb6(%rbp), %r8d
leaq 0x23b8e(%rip), %rsi     # 0x2b40e
movb $0x0, %al
callq 0x52c0
leaq 0x305da(%rip), %rax     # 0x37e68
cmpq $0x0, (%rax)
je 0x78d0
leaq 0x305cd(%rip), %rax     # 0x37e68
movq (%rax), %rax
movq %rax, -0x168(%rbp)
callq 0x13930
movq -0x168(%rbp), %rdi
movq %rax, %rdx
movl -0xb4(%rbp), %ecx
movswl -0xb6(%rbp), %r8d
leaq 0x23b45(%rip), %rsi     # 0x2b40e
movb $0x0, %al
callq 0x52c0
jmp 0x78d2
movl -0xb4(%rbp), %eax
leaq 0x2fcb5(%rip), %rcx     # 0x37594
cmpl 0x4(%rcx), %eax
jne 0x78e6
jmp 0x78e8
jmp 0x78e8
movswl -0xb6(%rbp), %eax
andl $0x38, %eax
cmpl $0x0, %eax
je 0x78fc
jmp 0x7bba
jmp 0x78fe
movswl -0xb6(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x7912
jmp 0x7b9f
movl -0xb4(%rbp), %eax
leaq 0x2fc75(%rip), %rcx     # 0x37594
cmpl 0x4(%rcx), %eax
jne 0x797a
movl -0xb4(%rbp), %edi
leaq -0xbc(%rbp), %rsi
movl $0x4, %edx
callq 0x5250
cmpq $0x4, %rax
jne 0x7975
movl -0xbc(%rbp), %eax
movl %eax, -0x16c(%rbp)
subl $0x2, %eax
je 0x7968
jmp 0x7954
movl -0x16c(%rbp), %eax
subl $0x1000, %eax           # imm = 0x1000
jne 0x7971
jmp 0x7963
jmp 0x7bba
movl $0x1, -0x1c(%rbp)
jmp 0x7973
jmp 0x7973
jmp 0x7975
jmp 0x7b9f
leaq 0x3056f(%rip), %rax     # 0x37ef0
movq %rax, -0xd0(%rbp)
movl -0xb4(%rbp), %edi
movq -0xd0(%rbp), %rsi
addq $0x6, %rsi
movl $0xffa, %edx            # imm = 0xFFA
callq 0x5250
movq %rax, -0xc8(%rbp)
cmpq $0x0, -0xc8(%rbp)
jg 0x7abe
jmp 0x79ba
movq 0x2f61f(%rip), %rax     # 0x36fe0
movq (%rax), %rax
movq %rax, -0x188(%rbp)
callq 0x13930
movq %rax, -0x180(%rbp)
movq -0xc8(%rbp), %rax
movl %eax, -0x174(%rbp)
callq 0x5070
movl (%rax), %eax
movl %eax, -0x170(%rbp)
callq 0x5070
movl (%rax), %edi
callq 0x5540
movq -0x188(%rbp), %rdi
movq -0x180(%rbp), %rdx
movl -0x174(%rbp), %r8d
movl -0x170(%rbp), %r9d
leaq 0x237f4(%rip), %rsi     # 0x2b214
leaq 0x239d9(%rip), %rcx     # 0x2b400
movq %rax, (%rsp)
movb $0x0, %al
callq 0x52c0
leaq 0x3042f(%rip), %rax     # 0x37e68
cmpq $0x0, (%rax)
je 0x7ab7
leaq 0x30422(%rip), %rax     # 0x37e68
movq (%rax), %rax
movq %rax, -0x1a0(%rbp)
callq 0x13930
movq %rax, -0x198(%rbp)
movq -0xc8(%rbp), %rax
movl %eax, -0x190(%rbp)
callq 0x5070
movl (%rax), %eax
movl %eax, -0x18c(%rbp)
callq 0x5070
movl (%rax), %edi
callq 0x5540
movq -0x1a0(%rbp), %rdi
movq -0x198(%rbp), %rdx
movl -0x190(%rbp), %r8d
movl -0x18c(%rbp), %r9d
leaq 0x2376f(%rip), %rsi     # 0x2b214
leaq 0x23954(%rip), %rcx     # 0x2b400
movq %rax, (%rsp)
movb $0x0, %al
callq 0x52c0
jmp 0x7ab9
jmp 0x7bb3
movl $0x0, -0xb0(%rbp)
movl -0xb0(%rbp), %eax
cmpq $0x1b, %rax
jae 0x7b13
movl -0xb0(%rbp), %eax
movl %eax, %ecx
leaq 0x2fa3d(%rip), %rax     # 0x37520
movl (%rax,%rcx,4), %eax
cmpl -0xb4(%rbp), %eax
jne 0x7b00
movl -0xb0(%rbp), %eax
movb %al, %cl
movq -0xd0(%rbp), %rax
movb %cl, 0x4(%rax)
jmp 0x7b02
movl -0xb0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb0(%rbp)
jmp 0x7ac8
movq -0xd0(%rbp), %rax
movb $0x1, (%rax)
movq -0xc8(%rbp), %rax
addq $0x6, %rax
subq $0x1, %rax
movzwl %ax, %edi
callq 0x13ff0
movw %ax, %cx
movq -0xd0(%rbp), %rax
movw %cx, 0x1(%rax)
movq -0xd0(%rbp), %rax
movb $0x0, 0x3(%rax)
movl -0xb4(%rbp), %eax
andl $0xff, %eax
cmpl $0x0, %eax
je 0x7b70
movl -0xb4(%rbp), %eax
andl $0xff, %eax
movl %eax, -0x1a4(%rbp)
jmp 0x7b81
movq -0xd0(%rbp), %rax
movzbl 0x4(%rax), %eax
movl %eax, -0x1a4(%rbp)
movl -0x1a4(%rbp), %eax
movb %al, %cl
movq -0xd0(%rbp), %rax
movb %cl, 0x5(%rax)
movq -0xd0(%rbp), %rdi
callq 0xc800
movl -0xa4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa4(%rbp)
jmp 0x777f
jmp 0x7525
jmp 0x7bba
callq 0x70a0
movl $0x1003, %edi           # imm = 0x1003
callq 0x8240
xorl %eax, %eax
movl %eax, %edi
callq 0xc800
movq 0x2f407(%rip), %rax     # 0x36fe0
movq (%rax), %rax
movq %rax, -0x1b0(%rbp)
callq 0x13930
movq -0x1b0(%rbp), %rdi
movq %rax, %rdx
leaq 0x2366b(%rip), %rsi     # 0x2b264
leaq 0x23800(%rip), %rcx     # 0x2b400
movb $0x0, %al
callq 0x52c0
leaq 0x3025a(%rip), %rax     # 0x37e68
cmpq $0x0, (%rax)
je 0x7c49
leaq 0x3024d(%rip), %rax     # 0x37e68
movq (%rax), %rax
movq %rax, -0x1b8(%rbp)
callq 0x13930
movq -0x1b8(%rbp), %rdi
movq %rax, %rdx
leaq 0x23629(%rip), %rsi     # 0x2b264
leaq 0x237be(%rip), %rcx     # 0x2b400
movb $0x0, %al
callq 0x52c0
jmp 0x7c4b
xorl %eax, %eax
movl %eax, %edi
callq 0x5360
nopw %cs:(%rax,%rax)