// File: brunokeymolen[P]ssdp/src/ssdp.cpp
// Function: SSDP::ReadLoop()
int SSDP::ReadLoop(){
    int ret = 0;
    mReadLoop = 1;

    struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;

    const int bufsize = 4096;
    u8 buf[bufsize];

    struct sockaddr_in sender;
    socklen_t senderlen = sizeof(struct sockaddr);

    int maxsock = mMulticastSocket > mUnicastSocket ? mMulticastSocket : mUnicastSocket;

    //Read UDP answers
    while (mReadLoop) {
        memset(buf, 0, bufsize);

        //(Re)set file descriptor
        FD_ZERO(&mReadFDS);
        FD_ZERO(&mWriteFDS);
        FD_ZERO(&mExceptionFDS);
        if (!mMulticastSocket) {
            printf("Multicast socket failed!\n");
            break;
        }

        FD_SET(mMulticastSocket, &mReadFDS);
        FD_SET(mMulticastSocket, &mWriteFDS);
        FD_SET(mMulticastSocket, &mExceptionFDS);

        if (!mUnicastSocket) {
            printf("Multicast socket failed!\n");
            break;
        }
        FD_SET(mUnicastSocket, &mReadFDS);
        FD_SET(mUnicastSocket, &mWriteFDS);
        FD_SET(mUnicastSocket, &mExceptionFDS);

        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        ret = select(maxsock+1, &mReadFDS, 0, &mExceptionFDS, &timeout);
        if (ret == SOCKET_ERROR) {
            printf("Socket error!\n");
            break;
        }
        else if (ret != 0) {
            //Multicast
            if (FD_ISSET(mMulticastSocket, &mExceptionFDS)) {
                printf("Error on Multicast socket, continue\n");
            }
            if (FD_ISSET(mMulticastSocket, &mReadFDS)) {
                //Data
                //printf("Data\n");
                ret = (int)recvfrom(mMulticastSocket, buf, bufsize, MSG_WAITALL, (struct sockaddr*)&sender, &senderlen);
                if(ret != SOCKET_ERROR){
                    //Be sure to only deliver full messages (!)
                    IncommingMessage((struct sockaddr*)&sender, buf, ret);
                }
            }
            //Unicast
            if (FD_ISSET(mUnicastSocket, &mExceptionFDS)) {
                printf("Error on Unicast socket, continue\n");
            }
            if (FD_ISSET(mUnicastSocket, &mReadFDS)) {
                //Data
                //printf("Data\n");
                ret = (int)recvfrom(mUnicastSocket, buf, bufsize, MSG_WAITALL, (struct sockaddr*)&sender, &senderlen);
                if(ret != SOCKET_ERROR){
                    //Be sure to only deliver full messages (!)
                    IncommingMessage((struct sockaddr*)&sender, buf, ret);
                }
            }

        }
    }
//EXIT:
    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10e0, %rsp           # imm = 0x10E0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x1080(%rbp)
movl $0x0, -0xc(%rbp)
movb $0x1, 0x68(%rcx)
movq $0x5, -0x20(%rbp)
movq $0x0, -0x18(%rbp)
movl $0x1000, -0x24(%rbp)    # imm = 0x1000
movl $0x10, -0x1044(%rbp)
movl 0x8(%rcx), %eax
cmpl 0xc(%rcx), %eax
jle 0x5080
movq -0x1080(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x1084(%rbp)
jmp 0x5090
movq -0x1080(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x1084(%rbp)
movl -0x1084(%rbp), %eax
movl %eax, -0x1048(%rbp)
movq -0x1080(%rbp), %rax
cmpb $0x0, 0x68(%rax)
je 0x564a
leaq -0x1030(%rbp), %rdi
xorl %esi, %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0x3160
movq -0x1080(%rbp), %rax
addq $0xf8, %rax
movq %rax, -0x1058(%rbp)
movl $0x0, -0x104c(%rbp)
movl -0x104c(%rbp), %eax
cmpq $0x10, %rax
jae 0x5110
movq -0x1058(%rbp), %rax
movl -0x104c(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0x104c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x104c(%rbp)
jmp 0x50de
jmp 0x5112
jmp 0x5114
movq -0x1080(%rbp), %rax
addq $0x178, %rax            # imm = 0x178
movq %rax, -0x1068(%rbp)
movl $0x0, -0x105c(%rbp)
movl -0x105c(%rbp), %eax
cmpq $0x10, %rax
jae 0x5164
movq -0x1068(%rbp), %rax
movl -0x105c(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0x105c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x105c(%rbp)
jmp 0x5132
jmp 0x5166
jmp 0x5168
movq -0x1080(%rbp), %rax
addq $0x78, %rax
movq %rax, -0x1078(%rbp)
movl $0x0, -0x106c(%rbp)
movl -0x106c(%rbp), %eax
cmpq $0x10, %rax
jae 0x51b6
movq -0x1078(%rbp), %rax
movl -0x106c(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0x106c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x106c(%rbp)
jmp 0x5184
jmp 0x51b8
movq -0x1080(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jne 0x51d8
leaq 0xb136(%rip), %rdi      # 0x10302
movb $0x0, %al
callq 0x3040
jmp 0x564a
movq -0x1080(%rbp), %rax
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x1080(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, -0x10a0(%rbp)
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x10a0(%rbp), %rdx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
orq 0xf8(%rax,%rcx,8), %rdx
movq %rdx, 0xf8(%rax,%rcx,8)
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x1080(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, -0x1098(%rbp)
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x1098(%rbp), %rdx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
orq 0x178(%rax,%rcx,8), %rdx
movq %rdx, 0x178(%rax,%rcx,8)
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x1080(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, -0x1090(%rbp)
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x1090(%rbp), %rdx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
orq 0x78(%rax,%rcx,8), %rdx
movq %rdx, 0x78(%rax,%rcx,8)
cmpl $0x0, 0xc(%rax)
jne 0x52e5
leaq 0xb029(%rip), %rdi      # 0x10302
movb $0x0, %al
callq 0x3040
jmp 0x564a
movq -0x1080(%rbp), %rax
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x1080(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, -0x10b8(%rbp)
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x10b8(%rbp), %rdx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
orq 0xf8(%rax,%rcx,8), %rdx
movq %rdx, 0xf8(%rax,%rcx,8)
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x1080(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, -0x10b0(%rbp)
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x10b0(%rbp), %rdx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
orq 0x178(%rax,%rcx,8), %rdx
movq %rdx, 0x178(%rax,%rcx,8)
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq -0x1080(%rbp), %rcx
movq %rax, -0x10a8(%rbp)
movl 0xc(%rcx), %eax
movl $0x40, %esi
cltd
idivl %esi
movq -0x10a8(%rbp), %rdx
cltq
orq 0x78(%rcx,%rax,8), %rdx
movq %rdx, 0x78(%rcx,%rax,8)
movq $0x5, -0x20(%rbp)
movq $0x0, -0x18(%rbp)
movl -0x1048(%rbp), %edi
addl $0x1, %edi
movq %rcx, %rsi
addq $0xf8, %rsi
addq $0x78, %rcx
xorl %eax, %eax
movl %eax, %edx
leaq -0x20(%rbp), %r8
callq 0x3290
movl %eax, -0xc(%rbp)
cmpl $-0x1, -0xc(%rbp)
jne 0x5421
leaq 0xaf07(%rip), %rdi      # 0x1031c
movb $0x0, %al
callq 0x3040
jmp 0x564a
cmpl $0x0, -0xc(%rbp)
je 0x5643
movq -0x1080(%rbp), %rax
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
movq 0x78(%rax,%rcx,8), %rcx
movq %rcx, -0x10c0(%rbp)
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x10c0(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x548b
leaq 0xaea7(%rip), %rdi      # 0x1032b
movb $0x0, %al
callq 0x3040
movq -0x1080(%rbp), %rax
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
movq 0xf8(%rax,%rcx,8), %rcx
movq %rcx, -0x10c8(%rbp)
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x10c8(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x5536
movq -0x1080(%rbp), %rax
movl 0x8(%rax), %edi
leaq -0x1030(%rbp), %rsi
movl $0x1000, %edx           # imm = 0x1000
movl $0x100, %ecx            # imm = 0x100
leaq -0x1040(%rbp), %r8
leaq -0x1044(%rbp), %r9
callq 0x3200
movl %eax, -0xc(%rbp)
cmpl $-0x1, -0xc(%rbp)
je 0x5534
movq -0x1080(%rbp), %rdi
leaq -0x1030(%rbp), %rdx
movl -0xc(%rbp), %ecx
leaq -0x1040(%rbp), %rsi
callq 0x5660
jmp 0x5536
movq -0x1080(%rbp), %rax
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
movq 0x78(%rax,%rcx,8), %rcx
movq %rcx, -0x10d0(%rbp)
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x10d0(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x5596
leaq 0xadc1(%rip), %rdi      # 0x10350
movb $0x0, %al
callq 0x3040
movq -0x1080(%rbp), %rax
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x1080(%rbp), %rax
movslq %ecx, %rcx
movq 0xf8(%rax,%rcx,8), %rcx
movq %rcx, -0x10d8(%rbp)
movl 0xc(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x10d8(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x5641
movq -0x1080(%rbp), %rax
movl 0xc(%rax), %edi
leaq -0x1030(%rbp), %rsi
movl $0x1000, %edx           # imm = 0x1000
movl $0x100, %ecx            # imm = 0x100
leaq -0x1040(%rbp), %r8
leaq -0x1044(%rbp), %r9
callq 0x3200
movl %eax, -0xc(%rbp)
cmpl $-0x1, -0xc(%rbp)
je 0x563f
movq -0x1080(%rbp), %rdi
leaq -0x1030(%rbp), %rdx
movl -0xc(%rbp), %ecx
leaq -0x1040(%rbp), %rsi
callq 0x5660
jmp 0x5641
jmp 0x5643
jmp 0x5645
jmp 0x509c
movl -0xc(%rbp), %eax
addq $0x10e0, %rsp           # imm = 0x10E0
popq %rbp
retq
nopw %cs:(%rax,%rax)