// File: /workspace/github_cpp_makefile_star2_O2/rthoelen[P]NXCore_Icom/main.cc
// Function: snd_packet(unsigned char*, int, int, int, int)
void snd_packet(unsigned char buf[], int recvlen, int GID, int rpt_id, int strt_packet)
{
	int i, j;
	int tg;
	int tac_flag;
	in_addr_t tmp_addr;
	int o_bufsize;

	if (tg_lookup(GID, rpt_id) == -1)
	{
		if(debug)
			std::cout << "Blocking TG: " << GID << " sent on Repeater  ->" << r_list[rpt_id] << "<-  , unauthorized TG: " << GID << std::endl;
		return;
	}

	for(i = 0; i < repeater_count; i++)
	{

		if (rpt_id == i)
			continue;

		tg = tg_lookup(GID, i);
		tac_flag = tac_lookup(GID, i);

	 	if(tg != -1)
		{


			if(repeater[i].disable)
				continue;


			// Check if this is an OTAA packet

                	if ((buf[38] == 0x1c) && (buf[39] == 0x21) && (buf[40] == 0xa0) && (repeater[i].tx_otaa == 0)) {
				continue;
			}

                        // Process TAC groups first
                        // The only way to let the TAC group(s) through is if the RX active group matches


                        if(tac_flag != -1)
                        {
                                if((repeater[i].time_since_rx == repeater[i].hold_time) || (repeater[i].active_tg != GID))
                                        continue;
                        }

			// If there is RX activity on this repeater, don't send to the repeater

			// if(repeater[i].rx_activity == 1)
			//	continue;


			// First, if this particular repeater just had RX activity, if the packet 
			// doesn't match the last talkgroup, drop it.  This should solve most contention
			// issues

	                if((repeater[i].last_tg != GID) && (tac_flag == -1))
                        {
                                if(repeater[i].time_since_rx < repeater[i].hold_time)
                                {
					if(debug)
                                        	std::cout << "Blocking TG: " << GID << " sent on Repeater  ->" << r_list[i] << "<-  due to recent RX on TG: " << repeater[i].last_tg << std::endl;
                                        continue;
                                }
                        }

                        // Next, we need to determine if we need to preempt a talkgroup
                        // Talkgroups that are on the left in the NXCore.ini list get higher priority

                        if((tg_lookup(GID, i) < tg_lookup(repeater[i].busy_tg, i)) && (strt_packet ==1) &&
				 (repeater[i].tx_busy ==1) && (tac_flag == -1))
                        {
                                repeater[i].busy_tg = GID;
				if(debug)
					std::cout << "Overriding TG: " << repeater[i].busy_tg << "with TG: " << GID << " on Repeater  ->" << r_list[i] << std::endl;
                        }


                        // Next, if repeater is considered busy, only send the talkgroup it has been assigned

                        if((repeater[i].tx_busy == 1) && (repeater[i].busy_tg!=GID) && (tac_flag == -1))
                        {
				if(debug)
                                	std::cout << " Repeater  ->" << r_list[i] << "<-  not geting " << GID << "due to active TX on " << repeater[i].busy_tg << std::endl;
                                continue;
                        }


			// Drop in the ran code
			if ((buf[38] == 0x1c) && (buf[40] == 0x81))
			{
				buf[41] = (char)repeater[i].tx_ran;
			}
			
			if (strt_packet)
			{
				tx_busy_sem = 1;
				repeater[i].tx_busy = 1;
				tx_busy_sem = 0;
				repeater[i].busy_tg = GID;
			}

			repeater[i].time_since_tx = 0;

			if(debug)
				std::cout << "Sending size " << recvlen << " packet to Repeater  ->" << r_list[i] << "<-  with TG: " << GID << std::endl;

			sendto(socket_00, buf, recvlen, 0, (struct sockaddr *)&repeater[i].rpt_addr_00,
		 		sizeof(repeater[i].rpt_addr_00));

			while(1)
			{
				#ifdef __FreeBSD__
				ioctl(socket_00,FIONWRITE, &o_bufsize);
				#else
				ioctl(socket_00,SIOCOUTQ, &o_bufsize);
				#endif
				if(o_bufsize == 0)
					break;
				usleep(250);
			}

		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %r8d, -0x3c(%rbp)
movl %ecx, %r14d
movl %esi, %ebx
movq %rdi, -0x48(%rbp)
movl %edx, -0x2c(%rbp)
movl %edx, %edi
movl %ecx, %esi
callq 0x56f5
cmpl $-0x1, %eax
je 0x5669
movl %ebx, -0x4c(%rbp)
movslq %ebx, %rax
movq %rax, -0x58(%rbp)
movl %r14d, %eax
movq %rax, -0x60(%rbp)
xorl %r15d, %r15d
movslq 0xf09a(%rip), %rax      # 0x14378
cmpq %rax, %r15
jge 0x56e6
cmpq -0x60(%rbp), %r15
je 0x5320
movl -0x2c(%rbp), %ebx
movl %ebx, %edi
movl %r15d, %esi
callq 0x56f5
movl %eax, %r13d
movl %ebx, %edi
movl %r15d, %esi
callq 0x5729
cmpl $-0x1, %r13d
je 0x5320
movq 0xf044(%rip), %r12      # 0x14358
imulq $0x70, %r15, %rcx
cmpl $0x0, 0x60(%r12,%rcx)
je 0x5325
incq %r15
jmp 0x52d7
movl %eax, %r14d
leaq (%r12,%rcx), %rbx
movq -0x48(%rbp), %rax
cmpb $0x1c, 0x26(%rax)
jne 0x5350
movq -0x48(%rbp), %rax
cmpb $0x21, 0x27(%rax)
jne 0x5350
movq -0x48(%rbp), %rax
cmpb $-0x60, 0x28(%rax)
jne 0x5350
cmpl $0x0, 0x5c(%rbx)
je 0x5320
cmpl $-0x1, %r14d
je 0x536b
movl 0x18(%rbx), %eax
cmpl 0x20(%rbx), %eax
je 0x5320
movl -0x2c(%rbp), %eax
cmpl %eax, 0x38(%rbx)
jne 0x5320
jmp 0x53ec
movl -0x2c(%rbp), %eax
cmpl %eax, 0x3c(%rbx)
je 0x53ec
movl 0x18(%rbx), %eax
cmpl 0x20(%rbx), %eax
jge 0x53ec
cmpl $0x0, 0xeffa(%rip)      # 0x1437c
je 0x5320
movq 0xec45(%rip), %rdi      # 0x13fd0
leaq 0x7e35(%rip), %rsi      # 0xd1c7
movq %rcx, %rbx
callq 0x42b0
movq %rax, %rdi
movl -0x2c(%rbp), %esi
callq 0x44b0
movq %rax, %rdi
leaq 0x7e26(%rip), %rsi      # 0xd1d5
callq 0x42b0
movq %r15, %rsi
shlq $0x5, %rsi
addq 0xef9e(%rip), %rsi      # 0x14360
movq %rax, %rdi
callq 0x4290
movq %rax, %rdi
leaq 0x7e2f(%rip), %rsi      # 0xd203
callq 0x42b0
movq 0xef78(%rip), %rcx      # 0x14358
addq %rbx, %rcx
addq $0x3c, %rcx
jmp 0x5553
movq %rcx, -0x38(%rbp)
movl 0x30(%r12,%rcx), %edi
movl %r15d, %esi
callq 0x56f5
cmpl $0x1, -0x3c(%rbp)
jne 0x54b9
cmpl %eax, %r13d
movq -0x38(%rbp), %rdx
jge 0x54bd
cmpl $-0x1, %r14d
jne 0x54bd
cmpl $0x1, 0x2c(%rbx)
jne 0x54bd
movl -0x2c(%rbp), %eax
movl %eax, 0x30(%rbx)
cmpl $0x0, 0xef47(%rip)      # 0x1437c
je 0x54bd
movq 0xeb8e(%rip), %rdi      # 0x13fd0
leaq 0x7dd7(%rip), %rsi      # 0xd220
callq 0x42b0
movq 0xef03(%rip), %rcx      # 0x14358
movq -0x38(%rbp), %rdx
movl 0x30(%rcx,%rdx), %esi
movq %rax, %rdi
callq 0x41c0
movq %rax, %rdi
leaq 0x7e10(%rip), %rsi      # 0xd27f
callq 0x42b0
movq %rax, %rdi
movl -0x2c(%rbp), %esi
callq 0x44b0
movq %rax, %rdi
leaq 0x7d51(%rip), %rsi      # 0xd1da
callq 0x42b0
movq %r15, %rsi
shlq $0x5, %rsi
addq 0xeec4(%rip), %rsi      # 0x14360
movq %rax, %rdi
callq 0x4290
movq %rax, %rdi
callq 0x4130
movq -0x38(%rbp), %rdx
movq 0xeea1(%rip), %r12      # 0x14358
jmp 0x54bd
movq -0x38(%rbp), %rdx
cmpl $0x1, 0x2c(%r12,%rdx)
jne 0x556a
cmpl $-0x1, %r14d
jne 0x556a
leaq (%r12,%rdx), %rax
movl -0x2c(%rbp), %ecx
cmpl %ecx, 0x30(%rax)
je 0x556a
cmpl $0x0, 0xee92(%rip)      # 0x1437c
je 0x5320
movq 0xead9(%rip), %rdi      # 0x13fd0
leaq 0x7cdf(%rip), %rsi      # 0xd1dd
movq %rdx, %rbx
callq 0x42b0
movq %r15, %rsi
shlq $0x5, %rsi
addq 0xee4c(%rip), %rsi      # 0x14360
movq %rax, %rdi
callq 0x4290
movq %rax, %rdi
leaq 0x7d0a(%rip), %rsi      # 0xd230
callq 0x42b0
movq %rax, %rdi
movl -0x2c(%rbp), %esi
callq 0x44b0
movq %rax, %rdi
leaq 0x7d00(%rip), %rsi      # 0xd240
callq 0x42b0
movq 0xee0c(%rip), %rcx      # 0x14358
addq %rbx, %rcx
addq $0x30, %rcx
movl (%rcx), %esi
movq %rax, %rdi
callq 0x41c0
movq %rax, %rdi
callq 0x4130
jmp 0x5320
movq -0x48(%rbp), %rbx
cmpb $0x1c, 0x26(%rbx)
jne 0x5582
cmpb $-0x7f, 0x28(%rbx)
jne 0x5582
movb 0x34(%r12,%rdx), %al
movb %al, 0x29(%rbx)
cmpl $0x0, -0x3c(%rbp)
je 0x55a0
movl $0x1, 0x2c(%r12,%rdx)
andl $0x0, 0xedec(%rip)      # 0x14384
movl -0x2c(%rbp), %eax
movl %eax, 0x30(%r12,%rdx)
andl $0x0, 0x1c(%r12,%rdx)
cmpl $0x0, 0xedcf(%rip)      # 0x1437c
je 0x561f
movq 0xea1a(%rip), %rdi      # 0x13fd0
leaq 0x7c98(%rip), %rsi      # 0xd255
callq 0x42b0
movq %rax, %rdi
movl -0x4c(%rbp), %esi
callq 0x44b0
movq %rax, %rdi
leaq 0x7c8c(%rip), %rsi      # 0xd263
callq 0x42b0
movq %r15, %rsi
shlq $0x5, %rsi
addq 0xed76(%rip), %rsi      # 0x14360
movq %rax, %rdi
callq 0x4290
movq %rax, %rdi
leaq 0x7c7f(%rip), %rsi      # 0xd27b
callq 0x42b0
movq %rax, %rdi
movl -0x2c(%rbp), %esi
callq 0x44b0
movq %rax, %rdi
callq 0x4130
movq -0x38(%rbp), %rdx
movq 0xed39(%rip), %r12      # 0x14358
movl 0xed5b(%rip), %edi      # 0x14380
addq %rdx, %r12
movq %rbx, %rsi
movq -0x58(%rbp), %rdx
xorl %ecx, %ecx
movq %r12, %r8
pushq $0x10
popq %r9
callq 0x4050
movl 0xed3d(%rip), %edi      # 0x14380
movl $0x5411, %esi           # imm = 0x5411
leaq -0x50(%rbp), %rdx
xorl %eax, %eax
callq 0x43f0
cmpl $0x0, -0x50(%rbp)
je 0x5320
movl $0xfa, %edi
callq 0x4410
jmp 0x563d
cmpl $0x0, 0xed0c(%rip)      # 0x1437c
je 0x56e6
movq 0xe957(%rip), %rdi      # 0x13fd0
leaq 0x7b47(%rip), %rsi      # 0xd1c7
callq 0x42b0
movq %rax, %rdi
movl -0x2c(%rbp), %ebx
movl %ebx, %esi
callq 0x44b0
leaq 0x7b3c(%rip), %rsi      # 0xd1d5
movq %rax, %rdi
callq 0x42b0
movslq %r14d, %rsi
shlq $0x5, %rsi
addq 0xecb1(%rip), %rsi      # 0x14360
movq %rax, %rdi
callq 0x4290
leaq 0x7b2d(%rip), %rsi      # 0xd1eb
movq %rax, %rdi
callq 0x42b0
movq %rax, %rdi
movl %ebx, %esi
callq 0x44b0
movq %rax, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4130
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq