// File: 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
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl %ecx, -0x14(%rbp)
movl %r8d, -0x18(%rbp)
movl -0x10(%rbp), %edi
movl -0x14(%rbp), %esi
callq 0x7980
cmpl $-0x1, %eax
jne 0x7198
cmpl $0x0, 0x233fc(%rip)     # 0x2a52c
je 0x7193
callq 0x5a80
movq 0x22e92(%rip), %rdi     # 0x29fd0
leaq 0x16196(%rip), %rsi     # 0x1d2db
callq 0x5480
movq %rax, -0x30(%rbp)
movslq -0x14(%rbp), %rsi
leaq 0x233d7(%rip), %rdi     # 0x2a530
callq 0xa010
movq -0x30(%rbp), %rdi
movq %rax, %rsi
callq 0x5430
movq %rax, %rdi
leaq 0x1612a(%rip), %rsi     # 0x1d29e
callq 0x5480
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5740
movq %rax, %rdi
movq 0x22e2a(%rip), %rsi     # 0x29fb8
callq 0x54e0
jmp 0x7977
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl 0x23380(%rip), %eax     # 0x2a528
jge 0x781d
movq 0x2336b(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x78(%rax)
movl -0x14(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jne 0x71d7
jmp 0x780f
movq 0x23342(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0x7c(%rax)
je 0x71f7
jmp 0x780f
movq -0x8(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0xa, %eax
jne 0x725a
movq -0x8(%rbp), %rax
movzbl 0x15(%rax), %eax
cmpl $0x5, %eax
jne 0x725a
movq -0x8(%rbp), %rax
movzbl 0x16(%rax), %eax
cmpl $0xa, %eax
jne 0x725a
movq -0x8(%rbp), %rax
movzbl 0x17(%rax), %eax
cmpl $0x1, %eax
je 0x723a
movq -0x8(%rbp), %rax
movzbl 0x17(%rax), %eax
cmpl $0x80, %eax
jne 0x725a
movq 0x232df(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0x70(%rax)
jne 0x725a
jmp 0x780f
movl -0x10(%rbp), %edi
movl -0x1c(%rbp), %esi
callq 0x7a00
movl %eax, -0x24(%rbp)
movl -0x10(%rbp), %edi
movl -0x1c(%rbp), %esi
callq 0x7980
movl %eax, -0x20(%rbp)
cmpl $-0x1, -0x20(%rbp)
je 0x780d
cmpl $-0x1, -0x24(%rbp)
je 0x72dc
movq 0x23293(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x28(%rax), %eax
movq 0x2327b(%rip), %rcx     # 0x2a520
movslq -0x1c(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x30(%rcx), %eax
je 0x72d5
movq 0x23261(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x4c(%rax), %eax
cmpl -0x10(%rbp), %eax
je 0x72da
jmp 0x780f
jmp 0x72dc
movq 0x2323d(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x50(%rax), %eax
cmpl -0x10(%rbp), %eax
je 0x73e1
cmpl $-0x1, -0x24(%rbp)
jne 0x73e1
movq 0x23212(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x28(%rax), %eax
movq 0x231fa(%rip), %rcx     # 0x2a520
movslq -0x1c(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x30(%rcx), %eax
jge 0x73df
cmpl $0x0, 0x231e8(%rip)     # 0x2a52c
je 0x73da
callq 0x5a80
movq 0x22c7a(%rip), %rdi     # 0x29fd0
leaq 0x15f67(%rip), %rsi     # 0x1d2c4
callq 0x5480
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5740
movq %rax, %rdi
leaq 0x15f5b(%rip), %rsi     # 0x1d2d2
callq 0x5480
movq %rax, -0x38(%rbp)
movslq -0x1c(%rbp), %rsi
leaq 0x231a5(%rip), %rdi     # 0x2a530
callq 0xa010
movq -0x38(%rbp), %rdi
movq %rax, %rsi
callq 0x5430
movq %rax, %rdi
leaq 0x15f42(%rip), %rsi     # 0x1d2e8
callq 0x5480
movq %rax, %rdi
movq 0x2316b(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x50(%rax), %esi
callq 0x5740
movq %rax, %rdi
movq 0x22be3(%rip), %rsi     # 0x29fb8
callq 0x54e0
jmp 0x780f
jmp 0x73e1
movl -0x10(%rbp), %edi
movl -0x1c(%rbp), %esi
callq 0x7980
movl %eax, -0x3c(%rbp)
movq 0x2312a(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x40(%rax), %edi
movl -0x1c(%rbp), %esi
callq 0x7980
movl %eax, %ecx
movl -0x3c(%rbp), %eax
cmpl %ecx, %eax
jge 0x7509
cmpl $0x1, -0x18(%rbp)
jne 0x7509
movq 0x230f3(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, 0x3c(%rax)
jne 0x7509
cmpl $-0x1, -0x24(%rbp)
jne 0x7509
movl -0x10(%rbp), %ecx
movq 0x230c7(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x40(%rax)
cmpl $0x0, 0x230bb(%rip)     # 0x2a52c
je 0x7507
callq 0x5a80
movq 0x22b4d(%rip), %rdi     # 0x29fd0
leaq 0x15e7b(%rip), %rsi     # 0x1d305
callq 0x5480
movq %rax, %rdi
movq 0x23087(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x40(%rax), %esi
callq 0x5740
movq %rax, %rdi
leaq 0x15e5c(%rip), %rsi     # 0x1d315
callq 0x5480
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5740
movq %rax, %rdi
leaq 0x15e04(%rip), %rsi     # 0x1d2d7
callq 0x5480
movq %rax, -0x48(%rbp)
movslq -0x1c(%rbp), %rsi
leaq 0x23049(%rip), %rdi     # 0x2a530
callq 0xa010
movq -0x48(%rbp), %rdi
movq %rax, %rsi
callq 0x5430
movq %rax, %rdi
movq 0x22ab6(%rip), %rsi     # 0x29fb8
callq 0x54e0
jmp 0x7509
movq 0x23010(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, 0x3c(%rax)
jne 0x75f5
movq 0x22ff1(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x40(%rax), %eax
cmpl -0x10(%rbp), %eax
je 0x75f5
cmpl $-0x1, -0x24(%rbp)
jne 0x75f5
cmpl $0x0, 0x22fd2(%rip)     # 0x2a52c
je 0x75f0
callq 0x5a80
movq 0x22a64(%rip), %rdi     # 0x29fd0
leaq 0x15d67(%rip), %rsi     # 0x1d2da
callq 0x5480
movq %rax, -0x50(%rbp)
movslq -0x1c(%rbp), %rsi
leaq 0x22fa9(%rip), %rdi     # 0x2a530
callq 0xa010
movq -0x50(%rbp), %rdi
movq %rax, %rsi
callq 0x5430
movq %rax, %rdi
leaq 0x15d7f(%rip), %rsi     # 0x1d321
callq 0x5480
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5740
movq %rax, %rdi
leaq 0x15d75(%rip), %rsi     # 0x1d331
callq 0x5480
movq %rax, %rdi
movq 0x22f55(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x40(%rax), %esi
callq 0x5740
movq %rax, %rdi
movq 0x229cd(%rip), %rsi     # 0x29fb8
callq 0x54e0
jmp 0x780f
cmpl $0x1, -0x18(%rbp)
jne 0x768c
movq 0x22f1a(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x74(%rax)
movl -0x1c(%rbp), %edi
callq 0x7a80
movl $0x1, 0x22f2b(%rip)     # 0x2a558
movq 0x22eec(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x2c(%rax)
movq 0x22ed0(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x1, 0x3c(%rax)
movl $0x0, 0x22ee9(%rip)     # 0x2a558
movl -0x10(%rbp), %ecx
movq 0x22ea7(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x40(%rax)
jmp 0x76c5
movq -0x8(%rbp), %rax
movzbl 0x3(%rax), %eax
movl $0x3, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
je 0x76a9
movl -0x1c(%rbp), %edi
callq 0x7a80
movq 0x22e70(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x74(%rax)
movl 0x22e7d(%rip), %eax     # 0x2a548
shrl $0x18, %eax
movsbl %al, %eax
andl $0xff, %eax
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0x8(%rax)
movl 0x22e63(%rip), %eax     # 0x2a548
shrl $0x10, %eax
movsbl %al, %eax
andl $0xff, %eax
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0x9(%rax)
movl 0x22e49(%rip), %eax     # 0x2a548
shrl $0x8, %eax
movsbl %al, %eax
andl $0xff, %eax
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0xa(%rax)
movl 0x22e2f(%rip), %eax     # 0x2a548
movsbl %al, %eax
andl $0xff, %eax
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0xb(%rax)
cmpl $0x2f, -0xc(%rbp)
jne 0x7755
cmpl $0x1, -0x18(%rbp)
jne 0x7755
movq 0x22de3(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movb 0x48(%rax), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x18(%rax)
movq 0x22dc4(%rip), %rax     # 0x2a520
movslq -0x14(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x68(%rax), %ecx
movq 0x22dac(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x6c(%rax)
cmpl $0x0, 0x22da0(%rip)     # 0x2a52c
je 0x77d5
callq 0x5a80
movq 0x22836(%rip), %rdi     # 0x29fd0
leaq 0x15ba5(%rip), %rsi     # 0x1d346
callq 0x5480
movq %rax, -0x58(%rbp)
movslq -0x1c(%rbp), %rsi
leaq 0x22d7b(%rip), %rdi     # 0x2a530
callq 0xa010
movq -0x58(%rbp), %rdi
movq %rax, %rsi
callq 0x5430
movq %rax, %rdi
movq 0x227e8(%rip), %rsi     # 0x29fb8
callq 0x54e0
movq 0x22d44(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x1, 0x78(%rax)
movq 0x22d28(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x2c(%rax)
jmp 0x780f
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x719f
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl 0x22cfb(%rip), %eax     # 0x2a528
jge 0x7977
movq 0x22ce6(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, 0x78(%rax)
jne 0x7967
cmpl $0x1, -0x18(%rbp)
jne 0x7860
movl -0x1c(%rbp), %edi
callq 0x7a80
jmp 0x7862
cmpl $0x1, 0x22ceb(%rip)     # 0x2a554
jne 0x7877
movl $0x1, %edi
callq 0x5660
jmp 0x7862
movl $0x1, 0x22cd3(%rip)     # 0x2a554
movl 0x22cc5(%rip), %edi     # 0x2a54c
movq -0x8(%rbp), %rsi
movslq -0xc(%rbp), %rdx
movq 0x22c8a(%rip), %r8      # 0x2a520
movslq -0x1c(%rbp), %rax
imulq $0x90, %rax, %rax
addq %rax, %r8
xorl %ecx, %ecx
movl $0x10, %r9d
callq 0x5090
cmpq $0x0, %rax
jge 0x78de
callq 0x5a80
movq 0x2270d(%rip), %rdi     # 0x29fd0
leaq 0x15a9d(%rip), %rsi     # 0x1d367
callq 0x5480
movq %rax, %rdi
movq 0x226df(%rip), %rsi     # 0x29fb8
callq 0x54e0
movl $0x0, 0x22c6c(%rip)     # 0x2a554
movl 0x22c5e(%rip), %edi     # 0x2a54c
movl $0x5411, %esi           # imm = 0x5411
leaq -0x28(%rbp), %rdx
movb $0x0, %al
callq 0x5640
cmpl $0x0, -0x28(%rbp)
jne 0x7906
jmp 0x7912
movl $0x1f4, %edi            # imm = 0x1F4
callq 0x5660
jmp 0x78e8
movq 0x22c07(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x78(%rax)
movq 0x22beb(%rip), %rax     # 0x2a520
movslq -0x14(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0x38(%rax)
jne 0x7965
movq 0x22bd0(%rip), %rax     # 0x2a520
movslq -0x1c(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl $0x3, 0x74(%rax)
jmp 0x7967
jmp 0x7969
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x7824
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)