// File: qian-jiahong[P]uvncrep017-ws/repeater.cpp
// Function: connectionRemover(int, _repeaterInfo*, int)
static void connectionRemover(int connectionFrom, repeaterInfo *rI, int index)
{
    bool fRemove;
    char removalReason[MY_TMP_BUF_LEN];
    
    fRemove = false;
    strlcpy(removalReason, "", MY_TMP_BUF_LEN);

     
    if (isExistingConnectionInactive(rI -> active, (rI -> code != 0))) {
        if (isConnectionTooOld(rI -> timeStamp)) {
            //Existing connection has been idle for too long, remove
            fRemove = true;
            snprintf(removalReason, MY_TMP_BUF_LEN, "%s", "idle connection too old");
        }
        else if (isPeerDisconnected(rI -> socket, connectionFrom)) {
            //Peer has closed the connection before another peer appeared, remove
            fRemove = true;
            snprintf(removalReason, MY_TMP_BUF_LEN, "%s", "peer has disconnected");
        }

        if (fRemove) {
            //Send VIEWER_DISCONNECT / SERVER_DISCONNECT to event interface
            if (useEventInterface) {
                repeaterEvent event;
                connectionEvent connEv;
                            
                event.eventNum = (connectionFrom == CONNECTION_FROM_VIEWER) ? VIEWER_DISCONNECT : SERVER_DISCONNECT;
                event.timeStamp = time(NULL);
                event.repeaterProcessId = getpid();

                connEv.tableIndex = index;
                connEv.code = rI -> code;
                connEv.connMode = (rI -> code < 0) ? CONN_MODE1 : CONN_MODE2;
                connEv.peerIp = rI -> peerIp;
                memcpy(event.extraInfo, &connEv, sizeof(connectionEvent));
                
                if (false == sendRepeaterEvent(event)) {
                    debug(LEVEL_1, "connectionRemover(): Warning, event fifo is full\n");
                }
            }

            //Remove & close connection 
            close(rI -> socket);
            debug(LEVEL_1, "connectionRemover(): Removing %s %ld at index %d (%s)\n", 
                (connectionFrom == CONNECTION_FROM_VIEWER) ? "viewer" : "server",
                rI -> code, 
                index,
                removalReason);
            
            if (connectionFrom == CONNECTION_FROM_VIEWER)
                removeViewerList(rI -> code);
            else
                removeServerList(rI -> code);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movb $0x0, -0x15(%rbp)
leaq -0x120(%rbp), %rdi
leaq 0x4e33(%rip), %rsi      # 0xb5da
movl $0xff, %edx
callq 0x76d0
movq -0x10(%rbp), %rax
movb 0x28(%rax), %cl
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
setne %al
movzbl %cl, %edi
andl $0x1, %edi
movzbl %al, %esi
andl $0x1, %esi
callq 0x2da0
testb $0x1, %al
jne 0x67de
jmp 0x6a30
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2d60
testb $0x1, %al
jne 0x67f1
jmp 0x6818
movb $0x1, -0x15(%rbp)
leaq -0x120(%rbp), %rdi
movl $0xff, %esi
leaq 0x4868(%rip), %rdx      # 0xb070
leaq 0x54c8(%rip), %rcx      # 0xbcd7
movb $0x0, %al
callq 0x2320
jmp 0x6853
movq -0x10(%rbp), %rax
movl (%rax), %edi
movl -0x4(%rbp), %esi
callq 0x2de0
testb $0x1, %al
jne 0x682c
jmp 0x6851
movb $0x1, -0x15(%rbp)
leaq -0x120(%rbp), %rdi
movl $0xff, %esi
leaq 0x482d(%rip), %rdx      # 0xb070
leaq 0x54a5(%rip), %rcx      # 0xbcef
movb $0x0, %al
callq 0x2320
jmp 0x6853
testb $0x1, -0x15(%rbp)
je 0x6a2e
leaq 0x11a90(%rip), %rax     # 0x182f4
testb $0x1, (%rax)
je 0x69ac
movl -0x4(%rbp), %edx
movl $0x3, %eax
movl $0x1, %ecx
cmpl $0x1, %edx
cmovel %ecx, %eax
movl %eax, -0x198(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0x21e0
movq %rax, -0x190(%rbp)
callq 0x22f0
movl %eax, -0x188(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x1c0(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x1b8(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdx
movl $0x2, %eax
movl $0x1, %ecx
cmpq $0x0, %rdx
cmovll %ecx, %eax
movl %eax, -0x1b0(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rcx
movq %rcx, -0x1ac(%rbp)
movq 0x20(%rax), %rax
movq %rax, -0x1a4(%rbp)
leaq -0x198(%rbp), %rdi
addq $0x14, %rdi
leaq -0x1c0(%rbp), %rsi
movl $0x28, %edx
callq 0x21b0
leaq -0x238(%rbp), %rdi
leaq -0x198(%rbp), %rsi
movl $0x78, %edx
callq 0x21b0
movq -0x1c8(%rbp), %rcx
movq %rsp, %rax
movq %rax, -0x240(%rbp)
movq %rcx, 0x70(%rax)
movups -0x1d8(%rbp), %xmm0
movups %xmm0, 0x60(%rax)
movups -0x1e8(%rbp), %xmm0
movups %xmm0, 0x50(%rax)
movups -0x1f8(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x238(%rbp), %xmm0
movups -0x228(%rbp), %xmm1
movups -0x218(%rbp), %xmm2
movups -0x208(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x9130
andb $0x1, %al
movzbl %al, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x69aa
movl $0x1, %edi
leaq 0x5362(%rip), %rsi      # 0xbd05
movb $0x0, %al
callq 0x2480
jmp 0x69ac
movq -0x10(%rbp), %rax
movl (%rax), %edi
callq 0x2370
cmpl $0x1, -0x4(%rbp)
jne 0x69cd
leaq 0x4d11(%rip), %rax      # 0xb6d5
movq %rax, -0x248(%rbp)
jmp 0x69dd
leaq 0x5a72(%rip), %rax      # 0xc446
movq %rax, -0x248(%rbp)
jmp 0x69dd
movq -0x248(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rcx
movl -0x14(%rbp), %r8d
leaq -0x120(%rbp), %r9
movl $0x1, %edi
leaq 0x5334(%rip), %rsi      # 0xbd37
movb $0x0, %al
callq 0x2480
cmpl $0x1, -0x4(%rbp)
jne 0x6a1f
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x6a40
jmp 0x6a2c
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x6af0
jmp 0x6a2e
jmp 0x6a30
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
nopl (%rax)