// File: 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
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 0x71e0
cmpl $-0x1, %eax
jne 0x6c61
cmpl $0x0, 0x228b8(%rip)     # 0x2949c
je 0x6c5c
movq 0x223e3(%rip), %rdi     # 0x28fd0
leaq 0x155e3(%rip), %rsi     # 0x1c1d7
callq 0x53f0
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5680
movq %rax, %rdi
leaq 0x155d7(%rip), %rsi     # 0x1c1e5
callq 0x53f0
movq %rax, -0x38(%rbp)
movslq -0x14(%rbp), %rsi
leaq 0x2285e(%rip), %rdi     # 0x29480
callq 0x9020
movq -0x38(%rbp), %rdi
movq %rax, %rsi
callq 0x53b0
movq %rax, %rdi
leaq 0x155be(%rip), %rsi     # 0x1c1fb
callq 0x53f0
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5680
movq %rax, %rdi
movq 0x22361(%rip), %rsi     # 0x28fb8
callq 0x5450
jmp 0x71cd
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl 0x22827(%rip), %eax     # 0x29498
jge 0x71cd
movl -0x14(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jne 0x6c84
jmp 0x71bf
movl -0x10(%rbp), %edi
movl -0x1c(%rbp), %esi
callq 0x71e0
movl %eax, -0x24(%rbp)
movl -0x10(%rbp), %edi
movl -0x1c(%rbp), %esi
callq 0x7260
movl %eax, -0x28(%rbp)
cmpl $-0x1, -0x24(%rbp)
je 0x71bd
movq 0x227c7(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0x60(%rax)
je 0x6cc7
jmp 0x71bf
movq -0x8(%rbp), %rax
movzbl 0x26(%rax), %eax
cmpl $0x1c, %eax
jne 0x6d0d
movq -0x8(%rbp), %rax
movzbl 0x27(%rax), %eax
cmpl $0x21, %eax
jne 0x6d0d
movq -0x8(%rbp), %rax
movzbl 0x28(%rax), %eax
cmpl $0xa0, %eax
jne 0x6d0d
movq 0x22781(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0x5c(%rax)
jne 0x6d0d
jmp 0x71bf
cmpl $-0x1, -0x28(%rbp)
je 0x6d60
movq 0x2275e(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x18(%rax), %eax
movq 0x22749(%rip), %rcx     # 0x29478
movslq -0x1c(%rbp), %rdx
imulq $0x70, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x20(%rcx), %eax
je 0x6d59
movq 0x22732(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x38(%rax), %eax
cmpl -0x10(%rbp), %eax
je 0x6d5e
jmp 0x71bf
jmp 0x6d60
movq 0x22711(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x3c(%rax), %eax
cmpl -0x10(%rbp), %eax
je 0x6e54
cmpl $-0x1, -0x28(%rbp)
jne 0x6e54
movq 0x226e9(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x18(%rax), %eax
movq 0x226d4(%rip), %rcx     # 0x29478
movslq -0x1c(%rbp), %rdx
imulq $0x70, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x20(%rcx), %eax
jge 0x6e52
cmpl $0x0, 0x226dd(%rip)     # 0x2949c
je 0x6e4d
movq 0x22204(%rip), %rdi     # 0x28fd0
leaq 0x15404(%rip), %rsi     # 0x1c1d7
callq 0x53f0
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5680
movq %rax, %rdi
leaq 0x153f8(%rip), %rsi     # 0x1c1e5
callq 0x53f0
movq %rax, -0x40(%rbp)
movslq -0x1c(%rbp), %rsi
leaq 0x2267f(%rip), %rdi     # 0x29480
callq 0x9020
movq -0x40(%rbp), %rdi
movq %rax, %rsi
callq 0x53b0
movq %rax, %rdi
leaq 0x153f7(%rip), %rsi     # 0x1c213
callq 0x53f0
movq %rax, %rdi
movq 0x2264d(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x3c(%rax), %esi
callq 0x5560
movq %rax, %rdi
movq 0x22170(%rip), %rsi     # 0x28fb8
callq 0x5450
jmp 0x71bf
jmp 0x6e54
movl -0x10(%rbp), %edi
movl -0x1c(%rbp), %esi
callq 0x71e0
movl %eax, -0x44(%rbp)
movq 0x2260f(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x30(%rax), %edi
movl -0x1c(%rbp), %esi
callq 0x71e0
movl %eax, %ecx
movl -0x44(%rbp), %eax
cmpl %ecx, %eax
jge 0x6f6b
cmpl $0x1, -0x18(%rbp)
jne 0x6f6b
movq 0x225db(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, 0x2c(%rax)
jne 0x6f6b
cmpl $-0x1, -0x28(%rbp)
jne 0x6f6b
movl -0x10(%rbp), %ecx
movq 0x225b2(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rdx
imulq $0x70, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x30(%rax)
cmpl $0x0, 0x225c1(%rip)     # 0x2949c
je 0x6f69
movq 0x220e8(%rip), %rdi     # 0x28fd0
leaq 0x15341(%rip), %rsi     # 0x1c230
callq 0x53f0
movq %rax, %rdi
movq 0x2257a(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x30(%rax), %esi
callq 0x5560
movq %rax, %rdi
leaq 0x15374(%rip), %rsi     # 0x1c28f
callq 0x53f0
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5680
movq %rax, %rdi
leaq 0x152b5(%rip), %rsi     # 0x1c1ea
callq 0x53f0
movq %rax, -0x50(%rbp)
movslq -0x1c(%rbp), %rsi
leaq 0x22537(%rip), %rdi     # 0x29480
callq 0x9020
movq -0x50(%rbp), %rdi
movq %rax, %rsi
callq 0x53b0
movq %rax, %rdi
movq 0x22054(%rip), %rsi     # 0x28fb8
callq 0x5450
jmp 0x6f6b
movq 0x22506(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, 0x2c(%rax)
jne 0x7049
movq 0x224ea(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x30(%rax), %eax
cmpl -0x10(%rbp), %eax
je 0x7049
cmpl $-0x1, -0x28(%rbp)
jne 0x7049
cmpl $0x0, 0x224e6(%rip)     # 0x2949c
je 0x7044
movq 0x2200d(%rip), %rdi     # 0x28fd0
leaq 0x15223(%rip), %rsi     # 0x1c1ed
callq 0x53f0
movq %rax, -0x58(%rbp)
movslq -0x1c(%rbp), %rsi
leaq 0x224a2(%rip), %rdi     # 0x29480
callq 0x9020
movq -0x58(%rbp), %rdi
movq %rax, %rsi
callq 0x53b0
movq %rax, %rdi
leaq 0x15247(%rip), %rsi     # 0x1c240
callq 0x53f0
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5680
movq %rax, %rdi
leaq 0x1523d(%rip), %rsi     # 0x1c250
callq 0x53f0
movq %rax, %rdi
movq 0x22456(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl 0x30(%rax), %esi
callq 0x5560
movq %rax, %rdi
movq 0x21f79(%rip), %rsi     # 0x28fb8
callq 0x5450
jmp 0x71bf
movq -0x8(%rbp), %rax
movzbl 0x26(%rax), %eax
cmpl $0x1c, %eax
jne 0x7081
movq -0x8(%rbp), %rax
movzbl 0x28(%rax), %eax
cmpl $0x81, %eax
jne 0x7081
movq 0x2240c(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movb 0x34(%rax), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x29(%rax)
cmpl $0x0, -0x18(%rbp)
je 0x70cc
movl $0x1, 0x22413(%rip)     # 0x294a4
movq 0x223e0(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl $0x1, 0x2c(%rax)
movl $0x0, 0x223f0(%rip)     # 0x294a4
movl -0x10(%rbp), %ecx
movq 0x223ba(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rdx
imulq $0x70, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x30(%rax)
movq 0x223a5(%rip), %rax     # 0x29478
movslq -0x1c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x1c(%rax)
cmpl $0x0, 0x223b0(%rip)     # 0x2949c
je 0x7164
movq 0x21edb(%rip), %rdi     # 0x28fd0
leaq 0x15169(%rip), %rsi     # 0x1c265
callq 0x53f0
movq %rax, %rdi
movl -0xc(%rbp), %esi
callq 0x5680
movq %rax, %rdi
leaq 0x1515d(%rip), %rsi     # 0x1c273
callq 0x53f0
movq %rax, -0x60(%rbp)
movslq -0x1c(%rbp), %rsi
leaq 0x22356(%rip), %rdi     # 0x29480
callq 0x9020
movq -0x60(%rbp), %rdi
movq %rax, %rsi
callq 0x53b0
movq %rax, %rdi
leaq 0x15146(%rip), %rsi     # 0x1c28b
callq 0x53f0
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x5680
movq %rax, %rdi
movq 0x21e59(%rip), %rsi     # 0x28fb8
callq 0x5450
movl 0x22336(%rip), %edi     # 0x294a0
movq -0x8(%rbp), %rsi
movslq -0xc(%rbp), %rdx
movq 0x222ff(%rip), %r8      # 0x29478
movslq -0x1c(%rbp), %rax
imulq $0x70, %rax, %rax
addq %rax, %r8
xorl %ecx, %ecx
movl $0x10, %r9d
callq 0x5090
movl 0x22309(%rip), %edi     # 0x294a0
movl $0x5411, %esi           # imm = 0x5411
leaq -0x30(%rbp), %rdx
movb $0x0, %al
callq 0x55a0
cmpl $0x0, -0x30(%rbp)
jne 0x71af
jmp 0x71bb
movl $0xfa, %edi
callq 0x55c0
jmp 0x7191
jmp 0x71bd
jmp 0x71bf
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x6c68
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)