// File: /workspace/github_cpp_makefile_star2_O2/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 $0x48, %rsp
movl %r8d, %r14d
movl %ecx, %ebx
movl %esi, %r15d
movq %rdi, -0x50(%rbp)
movl %edx, -0x38(%rbp)
movl %edx, %edi
movl %ecx, %esi
callq 0x5b35
movslq %ebx, %rcx
movq %rcx, -0x60(%rbp)
cmpl $-0x1, %eax
je 0x5abe
movl %r14d, -0x54(%rbp)
xorl $0x1, %r14d
movl %r15d, -0x64(%rbp)
xorl $0x2f, %r15d
orl %r14d, %r15d
sete -0x29(%rbp)
movl %ebx, %eax
imulq $0x90, %rax, %rcx
xorl %r15d, %r15d
xorl %r12d, %r12d
xorl %r13d, %r13d
movq %rcx, -0x48(%rbp)
movslq 0xedfb(%rip), %rax      # 0x143f8
cmpq %rax, %r13
jge 0x59b1
movq 0xede3(%rip), %r14      # 0x143f0
andl $0x0, 0x78(%r14,%r12)
cmpq %r12, %rcx
je 0x5620
cmpl $0x0, 0x7c(%r14,%r12)
je 0x5630
incq %r13
addq $0x90, %r12
addq $0x20, %r15
jmp 0x55f6
movq -0x50(%rbp), %rax
cmpb $0xa, 0x14(%rax)
jne 0x566a
movq -0x50(%rbp), %rax
cmpb $0x5, 0x15(%rax)
jne 0x566a
movq -0x50(%rbp), %rax
cmpb $0xa, 0x16(%rax)
jne 0x566a
movq -0x50(%rbp), %rax
movzbl 0x17(%rax), %eax
cmpl $0x80, %eax
je 0x5662
cmpl $0x1, %eax
jne 0x566a
cmpl $0x0, 0x70(%r14,%r12)
je 0x5620
movl -0x38(%rbp), %edi
movl %r13d, %esi
callq 0x5b35
movq -0x48(%rbp), %rcx
cmpl $-0x1, %eax
je 0x5620
movl %eax, %ebx
movl -0x38(%rbp), %edi
movl %r13d, %esi
callq 0x5b6c
movq -0x48(%rbp), %rcx
movl %eax, %edx
cmpl $-0x1, %eax
je 0x56b4
movl 0x28(%r14,%r12), %eax
cmpl 0x30(%r14,%r12), %eax
je 0x5620
movl -0x38(%rbp), %eax
cmpl %eax, 0x4c(%r14,%r12)
jne 0x5620
cmpl $-0x1, %edx
jne 0x5744
movl -0x38(%rbp), %eax
cmpl %eax, 0x50(%r14,%r12)
je 0x5744
movl 0x28(%r14,%r12), %eax
cmpl 0x30(%r14,%r12), %eax
jge 0x5744
cmpl $0x0, 0xed22(%rip)      # 0x143fc
je 0x5620
callq 0x479c
movq 0xe8e4(%rip), %rdi      # 0x13fd0
leaq 0x7bc1(%rip), %rsi      # 0xd2b4
callq 0x4320
movq %rax, %rdi
movl -0x38(%rbp), %esi
callq 0x4540
movq %rax, %rdi
leaq 0x7bb5(%rip), %rsi      # 0xd2c2
callq 0x4320
movq 0xece7(%rip), %rsi      # 0x14400
addq %r15, %rsi
movq %rax, %rdi
callq 0x42f0
movq %rax, %rdi
leaq 0x7baa(%rip), %rsi      # 0xd2d8
callq 0x4320
movq 0xecb6(%rip), %rcx      # 0x143f0
movl 0x50(%rcx,%r12), %esi
jmp 0x58ac
movl %edx, -0x3c(%rbp)
movl 0x40(%r14,%r12), %edi
movl %r13d, %esi
callq 0x5b35
cmpl $0x1, -0x54(%rbp)
jne 0x5816
cmpl %eax, %ebx
movq -0x48(%rbp), %rcx
jge 0x581a
movl -0x3c(%rbp), %edx
cmpl $-0x1, %edx
jne 0x581d
cmpl $0x1, 0x3c(%r14,%r12)
jne 0x581d
movl -0x38(%rbp), %eax
movl %eax, 0x40(%r14,%r12)
cmpl $0x0, 0xec6b(%rip)      # 0x143fc
je 0x581d
callq 0x479c
movq 0xe82d(%rip), %rdi      # 0x13fd0
leaq 0x7b4b(%rip), %rsi      # 0xd2f5
callq 0x4320
movq 0xec3a(%rip), %rcx      # 0x143f0
movl 0x40(%rcx,%r12), %esi
movq %rax, %rdi
callq 0x4540
movq %rax, %rdi
leaq 0x7b38(%rip), %rsi      # 0xd305
callq 0x4320
movq %rax, %rdi
movl -0x38(%rbp), %esi
callq 0x4540
movq %rax, %rdi
leaq 0x7ae0(%rip), %rsi      # 0xd2c7
callq 0x4320
movq 0xec0d(%rip), %rsi      # 0x14400
addq %r15, %rsi
movq %rax, %rdi
callq 0x42f0
movq %rax, %rdi
callq 0x4150
movl -0x3c(%rbp), %edx
movq -0x48(%rbp), %rcx
movq 0xebdc(%rip), %r14      # 0x143f0
jmp 0x581d
movq -0x48(%rbp), %rcx
movl -0x3c(%rbp), %edx
cmpl $0x1, 0x3c(%r14,%r12)
jne 0x58c1
cmpl $-0x1, %edx
jne 0x58c1
movl -0x38(%rbp), %eax
cmpl %eax, 0x40(%r14,%r12)
je 0x58c1
cmpl $0x0, 0xebb5(%rip)      # 0x143fc
je 0x5620
callq 0x479c
movq 0xe777(%rip), %rdi      # 0x13fd0
leaq 0x7a6a(%rip), %rsi      # 0xd2ca
callq 0x4320
movq 0xeb94(%rip), %rsi      # 0x14400
addq %r15, %rsi
movq %rax, %rdi
callq 0x42f0
movq %rax, %rdi
leaq 0x7a90(%rip), %rsi      # 0xd311
callq 0x4320
movq %rax, %rdi
movl -0x38(%rbp), %esi
callq 0x4540
movq %rax, %rdi
leaq 0x7a86(%rip), %rsi      # 0xd321
callq 0x4320
movq 0xeb49(%rip), %rcx      # 0x143f0
movl 0x40(%rcx,%r12), %esi
movq %rax, %rdi
callq 0x4540
movq %rax, %rdi
callq 0x4150
jmp 0x59a8
cmpl $0x1, -0x54(%rbp)
jne 0x58fc
andl $0x0, 0x74(%r14,%r12)
movl %r13d, %edi
callq 0x5ba3
movq 0xeb14(%rip), %r14      # 0x143f0
andl $0x0, 0x2c(%r14,%r12)
movl $0x1, 0x3c(%r14,%r12)
andl $0x0, 0xeb36(%rip)      # 0x14428
movl -0x38(%rbp), %eax
movl %eax, 0x40(%r14,%r12)
jmp 0x5924
movq -0x50(%rbp), %rax
movzbl 0x3(%rax), %eax
movb $0x3, %cl
divb %cl
movzbl %ah, %eax
testb %al, %al
je 0x591e
movl %r13d, %edi
callq 0x5ba3
movq 0xead2(%rip), %r14      # 0x143f0
andl $0x0, 0x74(%r14,%r12)
movl 0xeaee(%rip), %eax      # 0x14418
bswapl %eax
movq -0x50(%rbp), %rcx
movl %eax, 0x8(%rcx)
cmpb $0x0, -0x29(%rbp)
je 0x5945
movb 0x48(%r14,%r12), %al
movq -0x50(%rbp), %rcx
movb %al, 0x18(%rcx)
imulq $0x90, -0x60(%rbp), %rax
movl 0x68(%r14,%rax), %eax
movl %eax, 0x6c(%r14,%r12)
cmpl $0x0, 0xea9e(%rip)      # 0x143fc
je 0x5999
callq 0x479c
movq 0xe664(%rip), %rdi      # 0x13fd0
leaq 0x79c3(%rip), %rsi      # 0xd336
callq 0x4320
movq 0xea81(%rip), %rsi      # 0x14400
addq %r15, %rsi
movq %rax, %rdi
callq 0x42f0
movq %rax, %rdi
callq 0x4150
movq 0xea57(%rip), %r14      # 0x143f0
movl $0x1, 0x78(%r14,%r12)
andl $0x0, 0x2c(%r14,%r12)
movq -0x48(%rbp), %rcx
jmp 0x5620
movslq -0x64(%rbp), %rcx
movq %rcx, -0x38(%rbp)
pushq $0x1
popq %r12
leaq -0x68(%rbp), %rbx
imulq $0x90, -0x60(%rbp), %r13
xorl %r14d, %r14d
cltq
cmpq %rax, %r14
jge 0x5b26
movq 0xea12(%rip), %rax      # 0x143f0
imulq $0x90, %r14, %r15
cmpl $0x1, 0x78(%rax,%r15)
jne 0x5ab0
cmpl $0x1, -0x54(%rbp)
jne 0x5a09
movl %r14d, %edi
callq 0x5ba3
jmp 0x5a09
movl %r12d, %edi
callq 0x4490
cmpl $0x1, 0xea14(%rip)      # 0x14424
je 0x5a01
movl $0x1, 0xea08(%rip)      # 0x14424
movl 0xe9fa(%rip), %edi      # 0x1441c
movq 0xe9c7(%rip), %r8       # 0x143f0
addq %r15, %r8
movq -0x50(%rbp), %rsi
movq -0x38(%rbp), %rdx
xorl %ecx, %ecx
pushq $0x10
popq %r9
callq 0x4050
testq %rax, %rax
jns 0x5a64
callq 0x479c
movq 0xe580(%rip), %rdi      # 0x13fd0
leaq 0x7900(%rip), %rsi      # 0xd357
callq 0x4320
movq %rax, %rdi
callq 0x4150
andl $0x0, 0xe9b9(%rip)      # 0x14424
movl 0xe9ab(%rip), %edi      # 0x1441c
movl $0x5411, %esi           # imm = 0x5411
movq %rbx, %rdx
xorl %eax, %eax
callq 0x4470
cmpl $0x0, -0x68(%rbp)
je 0x5a92
movl $0x1f4, %edi            # imm = 0x1F4
callq 0x4490
jmp 0x5a6b
movq 0xe957(%rip), %rax      # 0x143f0
andl $0x0, 0x78(%rax,%r15)
cmpl $0x0, 0x38(%rax,%r13)
jne 0x5ab0
movl $0x3, 0x74(%rax,%r15)
incq %r14
movl 0xe93f(%rip), %eax      # 0x143f8
jmp 0x59cc
cmpl $0x0, 0xe937(%rip)      # 0x143fc
je 0x5b26
callq 0x479c
movq 0xe4fd(%rip), %rdi      # 0x13fd0
leaq 0x77f1(%rip), %rsi      # 0xd2cb
callq 0x4320
movq -0x60(%rbp), %rsi
shlq $0x5, %rsi
addq 0xe912(%rip), %rsi      # 0x14400
movq %rax, %rdi
callq 0x42f0
leaq 0x7791(%rip), %rsi      # 0xd28e
movq %rax, %rdi
callq 0x4320
movq %rax, %rdi
movl -0x38(%rbp), %esi
callq 0x4540
movq %rax, %rdi
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4150
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq