// File: /workspace/github_cpp_makefile_star2_O3/rthoelen[P]NXCore_Kenwood/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;
	int tg;
	int tac_flag;
	int o_bufsize;


	// This blocks talkgroups received on a repeater that don't match
	// the talkgroup list

	if (tg_lookup(GID, rpt_id) == -1)
	{
		if(debug)
		{
			ptime();
			std::cout << "Repeater  ->" << r_list[rpt_id] 
			<< "<-  blocked, unauthorized talkgroup: " 
			<< GID << std::endl;
		}

		return;
	}


	// Sending selection logic

	for(i = 0; i < repeater_count; i++)
	{
	
		repeater[i].snd_queue = 0;

		// Don't reflect our own packets back

		if (rpt_id == i)
			continue;

		if (repeater[i].disable)
			continue;

		// Block OTAA if needed

		if((buf[20] == 0x0a) && (buf[21] == 0x05) && (buf[22] == 0x0a) &&
			 ((buf[23] == 0x01) || (buf[23] == 0x80)) &&
				(repeater[i].tx_otaa == 0))
		{
			continue;
		}

		// Get the flag from the Tactical group list
		tac_flag = tac_lookup(GID, i);

		// Is the talkgroup being sent in this repeater's list? If not, stop here

		tg = tg_lookup(GID, i);
		if (tg != -1)

		{		
		

			// 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;
			}


			// 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)
					{
						ptime();
						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)
				{
					ptime();
					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)
				{
					ptime();
					std::cout << " Repeater  ->" << r_list[i] << "<-  not geting " 
						<< GID << "due to active TX on " 
						<< repeater[i].busy_tg << std::endl;
				}

				continue;	
			}


			if(strt_packet == 1)
			{
				repeater[i].keydown = 0;
				rpton_64001(i);
				tx_busy_sem=1;
				repeater[i].time_since_tx = 0;
				repeater[i].tx_busy = 1;
				tx_busy_sem=0;
				repeater[i].busy_tg = GID;
			}
			else
			{
				if((buf[3] % 3))
					rpton_64001(i);
				repeater[i].keydown = 0;
			}	

			// Need to rewrite IP address for len 47 and 59 packets it is 8,9,10,11
			buf[8] = (char)(tempaddr >> 24) & 0xff;
			buf[9] = (char)(tempaddr >> 16) & 0xff;
			buf[10] = (char)(tempaddr >> 8) & 0xff;
			buf[11] = (char)tempaddr & 0xff;

			if((recvlen == 47)&&(strt_packet == 1))
			{
				buf[24] = repeater[i].tx_ran;
			}

			repeater[i].tx_uid = repeater[rpt_id].uid;

			if(debug)
			{
				ptime();
				std::cout << "Sending datagram to repeater  ->" << r_list[i] << std::endl;
			}


			repeater[i].snd_queue = 1;

			repeater[i].time_since_tx = 0;

		}
				
	}

	for(i = 0; i < repeater_count; i++)
	{
		if(repeater[i].snd_queue==1)
		{

			if(strt_packet == 1)
				rpton_64001(i);
			while(tx_sem==1)
				usleep(1);
			tx_sem=1;

			if(sendto(socket_00, buf, recvlen, 0, (struct sockaddr *)&repeater[i].rpt_addr_00,
		 		sizeof(repeater[i].rpt_addr_00)) < 0)
			{
				ptime();
				std::cout << "sendto error..." << std::endl;
			}
			tx_sem=0;
			
			while(1)
			{

				#ifdef __FreeBSD__
				ioctl(socket_00,FIONWRITE,&o_bufsize);
				#else
				ioctl(socket_00,SIOCOUTQ,&o_bufsize);
				#endif
				if(o_bufsize == 0)
					break;
				usleep(500);
			}
	
			repeater[i].snd_queue = 0;

			if(repeater[rpt_id].rx_activity == 0)
			{		
				repeater[i].keydown=3;
			}
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %r8d, -0x30(%rbp)
movl %edx, %r12d
movq %rdi, -0x38(%rbp)
movq 0xf9a8(%rip), %rax      # 0x153d0
movslq %ecx, %r14
leaq (%r14,%r14,8), %rdx
shlq $0x4, %rdx
movq %rdx, -0x50(%rbp)
movq 0x58(%rax,%rdx), %rax
movl (%rax), %edx
testl %edx, %edx
je 0x5f47
addq $0x4, %rax
cmpl %r12d, %edx
jne 0x5a3c
cmpl $0x0, 0xf982(%rip)      # 0x153d8
movl -0x30(%rbp), %eax
jle 0x6132
xorl $0x1, %eax
movl %esi, -0x48(%rbp)
movl %esi, %edx
xorl $0x2f, %edx
orl %eax, %edx
sete -0x29(%rbp)
movl %ecx, %ebx
xorl %r13d, %r13d
movq 0xf954(%rip), %rax      # 0x153d0
leaq (,%r13,8), %r14
addq %r13, %r14
shlq $0x4, %r14
movl $0x0, 0x78(%rax,%r14)
cmpq %rbx, %r13
je 0x5aa1
cmpl $0x0, 0x7c(%rax,%r14)
je 0x5ab5
incq %r13
movslq 0xf92d(%rip), %rax      # 0x153d8
cmpq %rax, %r13
jl 0x5a75
jmp 0x5fea
movq -0x38(%rbp), %rcx
cmpb $0xa, 0x14(%rcx)
jne 0x5af0
movq -0x38(%rbp), %rcx
cmpb $0x5, 0x15(%rcx)
jne 0x5af0
movq -0x38(%rbp), %rcx
cmpb $0xa, 0x16(%rcx)
jne 0x5af0
movq -0x38(%rbp), %rcx
movzbl 0x17(%rcx), %ecx
cmpl $0x80, %ecx
je 0x5ae8
cmpl $0x1, %ecx
jne 0x5af0
cmpl $0x0, 0x70(%rax,%r14)
je 0x5aa1
movq 0x60(%rax,%r14), %rcx
movl (%rcx), %r15d
testl %r15d, %r15d
je 0x5b06
addq $0x4, %rcx
cmpl %r12d, %r15d
jne 0x5af5
movq 0x58(%rax,%r14), %rcx
movq %rcx, %rdx
movl (%rdx), %esi
testl %esi, %esi
je 0x5aa1
addq $0x4, %rdx
cmpl %r12d, %esi
jne 0x5b0e
leaq (%rax,%r14), %rdx
testl %r15d, %r15d
je 0x5b41
movl 0x28(%rdx), %esi
cmpl 0x30(%rdx), %esi
je 0x5aa1
cmpl %r12d, 0x4c(%rdx)
jne 0x5aa1
jmp 0x5bed
cmpl %r12d, 0x50(%rdx)
je 0x5bed
movl 0x28(%rdx), %esi
cmpl 0x30(%rdx), %esi
jge 0x5bed
cmpl $0x0, 0xf87e(%rip)      # 0x153dc
je 0x5aa1
callq 0x47bc
movl $0xd, %edx
movq 0xf45b(%rip), %r15      # 0x14fd0
movq %r15, %rdi
leaq 0x9735(%rip), %rsi      # 0xf2b4
callq 0x4370
movq %r15, %rdi
movl %r12d, %esi
callq 0x4520
movq %rax, %r15
movl $0x15, %edx
movq %rax, %rdi
leaq 0x9721(%rip), %rsi      # 0xf2c2
callq 0x4370
movq 0xf833(%rip), %rax      # 0x153e0
movq %r13, %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rsi
movq 0x8(%rax,%rcx), %rdx
movq %r15, %rdi
callq 0x4370
movq %rax, %r15
movl $0x1c, %edx
movq %rax, %rdi
leaq 0x9701(%rip), %rsi      # 0xf2d8
callq 0x4370
movq 0xf7ed(%rip), %rax      # 0x153d0
movl 0x50(%rax,%r14), %esi
jmp 0x5de6
movq %rcx, %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl (%rsi), %edi
testl %edi, %edi
je 0x5c08
incl %edx
addq $0x4, %rsi
cmpl %r12d, %edi
jne 0x5bf5
jmp 0x5c0d
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
leaq (%rax,%r14), %rsi
addq $0x40, %rsi
movl (%rsi), %r8d
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
movl (%rcx), %r9d
testl %r9d, %r9d
je 0x5c32
incl %edi
addq $0x4, %rcx
cmpl %r8d, %r9d
jne 0x5c1d
jmp 0x5c37
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
cmpl $0x1, -0x30(%rbp)
jne 0x5d32
cmpl %edi, %edx
jge 0x5d32
testl %r15d, %r15d
jne 0x5d32
cmpl $0x1, 0x3c(%rax,%r14)
jne 0x5d32
movl %r12d, (%rsi)
cmpl $0x0, 0xf774(%rip)      # 0x153dc
je 0x5d32
callq 0x47bc
movl $0xf, %edx
movq 0xf351(%rip), %rdi      # 0x14fd0
leaq 0x966f(%rip), %rsi      # 0xf2f5
callq 0x4370
movq 0xf73e(%rip), %rax      # 0x153d0
movl 0x40(%rax,%r14), %esi
movq 0xf332(%rip), %rdi      # 0x14fd0
callq 0x4520
movq %rax, -0x40(%rbp)
movl $0xb, %edx
movq %rax, %rdi
leaq 0x964f(%rip), %rsi      # 0xf305
callq 0x4370
movq -0x40(%rbp), %rdi
movl %r12d, %esi
callq 0x4520
movq %rax, -0x40(%rbp)
movl $0x10, %edx
movq %rax, %rdi
leaq 0x95ed(%rip), %rsi      # 0xf2c7
callq 0x4370
movq 0xf6fa(%rip), %rax      # 0x153e0
movq %r13, %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rsi
movq 0x8(%rax,%rcx), %rdx
movq -0x40(%rbp), %rdi
callq 0x4370
movq %rax, -0x40(%rbp)
movq (%rax), %rcx
movq -0x18(%rcx), %rdi
addq %rax, %rdi
movl $0xa, %esi
callq 0x42f0
movsbl %al, %esi
movq -0x40(%rbp), %rdi
callq 0x4040
movq %rax, %rdi
callq 0x41f0
movq 0xf69e(%rip), %rax      # 0x153d0
cmpl $0x1, 0x3c(%rax,%r14)
jne 0x5e1d
testl %r15d, %r15d
jne 0x5e1d
leaq (%rax,%r14), %rcx
cmpl %r12d, 0x40(%rcx)
je 0x5e1d
cmpl $0x0, 0xf680(%rip)      # 0x153dc
je 0x5aa1
callq 0x47bc
movl $0xd, %edx
movq 0xf25d(%rip), %r15      # 0x14fd0
movq %r15, %rdi
leaq 0x954d(%rip), %rsi      # 0xf2ca
callq 0x4370
movq 0xf657(%rip), %rax      # 0x153e0
movq %r13, %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rsi
movq 0x8(%rax,%rcx), %rdx
movq %r15, %rdi
callq 0x4370
movq %rax, %r15
movl $0xf, %edx
movq %rax, %rdi
leaq 0x955e(%rip), %rsi      # 0xf311
callq 0x4370
movq %r15, %rdi
movl %r12d, %esi
callq 0x4520
movq %rax, %r15
movl $0x14, %edx
movq %rax, %rdi
leaq 0x954c(%rip), %rsi      # 0xf321
callq 0x4370
movq 0xf5ef(%rip), %rax      # 0x153d0
movl 0x40(%rax,%r14), %esi
movq %r15, %rdi
callq 0x4520
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x42f0
movsbl %al, %esi
movq %r15, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x41f0
jmp 0x5aa1
cmpl $0x1, -0x30(%rbp)
jne 0x5e61
movq %r13, %rcx
shlq $0x4, %rcx
leaq (%rcx,%rcx,8), %r15
xorl %ecx, %ecx
movl %ecx, 0x74(%rax,%r15)
movl %r13d, %edi
callq 0x61b3
movq 0xf58c(%rip), %rax      # 0x153d0
xorl %ecx, %ecx
movl %ecx, 0x2c(%rax,%r15)
movl $0x1, 0x3c(%rax,%r15)
movl %ecx, 0xf5ae(%rip)      # 0x15408
movl %r12d, 0x40(%rax,%r15)
jmp 0x5e89
movq -0x38(%rbp), %rcx
movzbl 0x3(%rcx), %ecx
imull $-0x55, %ecx, %ecx
cmpb $0x56, %cl
jb 0x5e80
movl %r13d, %edi
callq 0x61b3
movq 0xf550(%rip), %rax      # 0x153d0
movl $0x0, 0x74(%rax,%r14)
movl 0xf569(%rip), %ecx      # 0x153f8
bswapl %ecx
movq -0x38(%rbp), %rdx
movl %ecx, 0x8(%rdx)
cmpb $0x0, -0x29(%rbp)
je 0x5eaa
movb 0x48(%rax,%r14), %cl
movq -0x38(%rbp), %rdx
movb %cl, 0x18(%rdx)
movq -0x50(%rbp), %rcx
movl 0x68(%rax,%rcx), %ecx
movl %ecx, 0x6c(%rax,%r14)
cmpl $0x0, 0xf51e(%rip)      # 0x153dc
je 0x5f30
callq 0x47bc
movl $0x20, %edx
movq 0xf0ff(%rip), %r15      # 0x14fd0
movq %r15, %rdi
leaq 0x945b(%rip), %rsi      # 0xf336
callq 0x4370
movq 0xf4f9(%rip), %rax      # 0x153e0
movq %r13, %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rsi
movq 0x8(%rax,%rcx), %rdx
movq %r15, %rdi
callq 0x4370
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x42f0
movsbl %al, %esi
movq %r15, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x41f0
movq 0xf4a0(%rip), %rax      # 0x153d0
movl $0x1, 0x78(%rax,%r14)
movl $0x0, 0x2c(%rax,%r14)
jmp 0x5aa1
cmpl $0x0, 0xf48e(%rip)      # 0x153dc
je 0x6132
callq 0x47bc
movq 0xf070(%rip), %rbx      # 0x14fd0
leaq 0x9364(%rip), %rsi      # 0xf2cb
movl $0xc, %edx
movq %rbx, %rdi
callq 0x4370
movq 0xf465(%rip), %rax      # 0x153e0
shlq $0x5, %r14
movq (%rax,%r14), %rsi
movq 0x8(%rax,%r14), %rdx
movq %rbx, %rdi
callq 0x4370
movq %rax, %rbx
leaq 0x92f4(%rip), %rsi      # 0xf28e
movl $0x25, %edx
movq %rax, %rdi
callq 0x4370
movq %rbx, %rdi
movl %r12d, %esi
callq 0x4520
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x42f0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4040
movq %rax, %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x41f0
testl %eax, %eax
movl -0x30(%rbp), %r14d
movl -0x48(%rbp), %eax
jle 0x6132
movslq %eax, %r12
movq 0xf3cd(%rip), %rax      # 0x153d0
leaq -0x44(%rbp), %r15
xorl %r13d, %r13d
leaq (,%r13,8), %rbx
addq %r13, %rbx
shlq $0x4, %rbx
cmpl $0x1, 0x78(%rax,%rbx)
jne 0x611f
cmpl $0x1, %r14d
jne 0x603e
movl %r13d, %edi
callq 0x61b3
jmp 0x603e
movl $0x1, %edi
callq 0x4450
cmpl $0x1, 0xf3bf(%rip)      # 0x15404
je 0x6034
movl $0x1, 0xf3b3(%rip)      # 0x15404
movl 0xf3a5(%rip), %edi      # 0x153fc
movq 0xf372(%rip), %r8       # 0x153d0
addq %rbx, %r8
movq -0x38(%rbp), %rsi
movq %r12, %rdx
xorl %ecx, %ecx
movl $0x10, %r9d
callq 0x4060
testq %rax, %rax
jns 0x60cc
callq 0x47bc
movl $0xf, %edx
movq %r12, %r14
movq 0xef42(%rip), %r12      # 0x14fd0
movq %r12, %rdi
leaq 0x92bf(%rip), %rsi      # 0xf357
callq 0x4370
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x42f0
movsbl %al, %esi
movq %r12, %rdi
movq %r14, %r12
movl -0x30(%rbp), %r14d
callq 0x4040
movq %rax, %rdi
callq 0x41f0
movl $0x0, 0xf32e(%rip)      # 0x15404
movl 0xf320(%rip), %edi      # 0x153fc
movl $0x5411, %esi           # imm = 0x5411
movq %r15, %rdx
xorl %eax, %eax
callq 0x4430
cmpl $0x0, -0x44(%rbp)
je 0x60fd
movl $0x1f4, %edi            # imm = 0x1F4
callq 0x4450
jmp 0x60d6
movq 0xf2cc(%rip), %rax      # 0x153d0
movl $0x0, 0x78(%rax,%rbx)
movq -0x50(%rbp), %rcx
cmpl $0x0, 0x38(%rax,%rcx)
jne 0x611f
movl $0x3, 0x74(%rax,%rbx)
incq %r13
movslq 0xf2af(%rip), %rcx      # 0x153d8
cmpq %rcx, %r13
jl 0x600a
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq