// File: /workspace/github_c_makefile_star2_O0/open-mesh-mirror[P]batmand/schedule.c
// Function: schedule_forward_packet
void schedule_forward_packet(struct orig_node *orig_node, struct bat_packet *in, uint32_t neigh, uint8_t directlink, int16_t hna_buff_len, struct batman_if *if_incoming, uint32_t curr_time)
{
	struct forw_node *forw_node_new = NULL, *forw_node_aggregate = NULL, *forw_node_pos = NULL;
	struct list_head *list_pos = forw_list.next, *prev_list_head = (struct list_head *)&forw_list;
	struct bat_packet *bat_packet;
	uint8_t tq_avg = 0;
	uint32_t send_time;
	prof_start(PROF_schedule_forward_packet);

	debug_output(4, "schedule_forward_packet():  \n");

	if (in->ttl <= 1) {
		debug_output(4, "ttl exceeded \n");
		prof_stop(PROF_schedule_forward_packet);
		return;
	}

	if (aggregation_enabled)
		send_time = curr_time + MAX_AGGREGATION_MS - (JITTER/2) + rand_num(JITTER);
	else
		send_time = curr_time + rand_num(JITTER/2);


	/* find position for the packet in the forward queue */
	list_for_each(list_pos, &forw_list) {

		forw_node_pos = list_entry(list_pos, struct forw_node, list);

		if (aggregation_enabled) {

			/* don't save aggregation position if aggregation is disabled */
			forw_node_aggregate = forw_node_pos;

			/**
			 * we can aggregate the current packet to this packet if:
			 * - the send time is within our MAX_AGGREGATION_MS time
			 * - the resulting packet wont be bigger than MAX_AGGREGATION_BYTES
			 */
			if (((int)(forw_node_pos->send_time - send_time) < 0) &&
				(forw_node_pos->pack_buff_len + sizeof(struct bat_packet) + hna_buff_len <= MAX_AGGREGATION_BYTES)) {

				bat_packet = (struct bat_packet *)forw_node_pos->pack_buff;

				/**
				 * check aggregation compatibility
				 * -> direct link packets are broadcasted on their interface only
				 * -> aggregate packet if the current packet is a "global" packet
				 *    as well as the base packet
				 */

				/* packets without direct link flag and high TTL are flooded through the net  */
				if ((!directlink) && (!(bat_packet->flags & DIRECTLINK)) && (bat_packet->ttl != 1) &&

				/* own packets originating non-primary interfaces leave only that interface */
						((!forw_node_pos->own) || (forw_node_pos->if_incoming->if_num == 0)))
					break;

				/* if the incoming packet is sent via this one interface only - we still can aggregate */
				if ((directlink) && (in->ttl == 2) && (forw_node_pos->if_incoming == if_incoming))
					break;

			}

			/* could not find packet to aggregate with */
			forw_node_aggregate = NULL;

		}

		if ((int)(forw_node_pos->send_time - send_time) > 0)
			break;

		prev_list_head = &forw_node_pos->list;
		forw_node_pos = NULL;

	}

	/* nothing to aggregate with - either aggregation disabled or no suitable aggregation packet found */
	if (forw_node_aggregate == NULL) {

		forw_node_new = debugMalloc(sizeof(struct forw_node), 504);
		forw_node_new->pack_buff = debugMalloc(MAX_AGGREGATION_BYTES, 505);

		INIT_LIST_HEAD(&forw_node_new->list);

		forw_node_new->pack_buff_len = sizeof(struct bat_packet) + hna_buff_len;
		memcpy(forw_node_new->pack_buff, in, forw_node_new->pack_buff_len);

		bat_packet = (struct bat_packet *)forw_node_new->pack_buff;

		forw_node_new->own = 0;
		forw_node_new->if_incoming = if_incoming;
		forw_node_new->num_packets = 0;
		forw_node_new->direct_link_flags = 0;

		forw_node_new->send_time = send_time;

	} else {

		memcpy(forw_node_aggregate->pack_buff + forw_node_aggregate->pack_buff_len, in, sizeof(struct bat_packet) + hna_buff_len);
		bat_packet = (struct bat_packet *)(forw_node_aggregate->pack_buff + forw_node_aggregate->pack_buff_len);
		forw_node_aggregate->pack_buff_len += sizeof(struct bat_packet) + hna_buff_len;

		forw_node_aggregate->num_packets++;

		forw_node_new = forw_node_aggregate;

	}

	/* save packet direct link flag status */
	if (directlink)
		forw_node_new->direct_link_flags = forw_node_new->direct_link_flags | (1 << forw_node_new->num_packets);

	bat_packet->ttl--;
	bat_packet->prev_sender = neigh;

	/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast of our best tq value */
	if ((orig_node->router != NULL) && (orig_node->router->tq_avg != 0)) {

		/* rebroadcast ogm of best ranking neighbor as is */
		if (orig_node->router->addr != neigh) {
			bat_packet->tq = orig_node->router->tq_avg;

			if (orig_node->router->last_ttl)
				bat_packet->ttl = orig_node->router->last_ttl - 1;
		}

		tq_avg = orig_node->router->tq_avg;

	}

	/* apply hop penalty */
	bat_packet->tq = (bat_packet->tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE);

	debug_output(4, "forwarding: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n", in->tq, tq_avg, bat_packet->tq, in->ttl - 1, bat_packet->ttl);

	/* change sequence number to network order */
	bat_packet->seqno = htons(bat_packet->seqno);

	if (directlink)
		bat_packet->flags |= DIRECTLINK;
	else
		bat_packet->flags &= ~DIRECTLINK;


	/* if the packet was not aggregated */
	if (forw_node_aggregate == NULL) {

		/* if the packet should go somewhere in the queue */
		if (forw_node_pos != NULL)
			list_add_before(prev_list_head, list_pos, &forw_node_new->list);
		/* if the packet is the last packet in the queue */
		else
			list_add_tail(&forw_node_new->list, &forw_list);

	}

	prof_stop(PROF_schedule_forward_packet);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movw %r8w, %ax
movl 0x10(%rbp), %r8d
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movb %cl, -0x15(%rbp)
movw %ax, -0x18(%rbp)
movq %r9, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
leaq 0x14f53(%rip), %rax     # 0x1b3d8
movq (%rax), %rax
movq %rax, -0x40(%rbp)
leaq 0x14f45(%rip), %rax     # 0x1b3d8
movq %rax, -0x48(%rbp)
movb $0x0, -0x51(%rbp)
movl $0x7, %edi
callq 0x8760
movl $0x4, %edi
leaq 0xf048(%rip), %rsi      # 0x154f9
movb $0x0, %al
callq 0x123f0
movq -0x10(%rbp), %rax
movzbl 0x2(%rax), %eax
cmpl $0x1, %eax
jg 0x64e7
movl $0x4, %edi
leaq 0xf046(%rip), %rsi      # 0x15517
movb $0x0, %al
callq 0x123f0
movl $0x7, %edi
callq 0x8790
jmp 0x6905
leaq 0x14dc3(%rip), %rax     # 0x1b2b1
cmpb $0x0, (%rax)
je 0x6515
movl 0x10(%rbp), %eax
addl $0x64, %eax
subl $0x32, %eax
movl %eax, -0x5c(%rbp)
movl $0x64, %edi
callq 0xfac0
movl %eax, %ecx
movl -0x5c(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x58(%rbp)
jmp 0x652f
movl 0x10(%rbp), %eax
movl %eax, -0x60(%rbp)
movl $0x32, %edi
callq 0xfac0
movl %eax, %ecx
movl -0x60(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x58(%rbp)
leaq 0x14ea2(%rip), %rax     # 0x1b3d8
movq (%rax), %rax
movq %rax, -0x40(%rbp)
leaq 0x14e94(%rip), %rax     # 0x1b3d8
cmpq %rax, -0x40(%rbp)
je 0x664a
movq -0x40(%rbp), %rax
movq %rax, -0x38(%rbp)
leaq 0x14d54(%rip), %rax     # 0x1b2b1
cmpb $0x0, (%rax)
je 0x6619
movq -0x38(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rax
movl 0x8(%rax), %eax
subl -0x58(%rbp), %eax
cmpl $0x0, %eax
jge 0x6611
movq -0x38(%rbp), %rax
movzwl 0x18(%rax), %eax
addq $0x12, %rax
movswq -0x18(%rbp), %rcx
addq %rcx, %rax
cmpq $0x200, %rax            # imm = 0x200
ja 0x6611
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x50(%rbp)
cmpb $0x0, -0x15(%rbp)
jne 0x65e9
movq -0x50(%rbp), %rax
movzbl 0x1(%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
jne 0x65e9
movq -0x50(%rbp), %rax
movzbl 0x2(%rax), %eax
cmpl $0x1, %eax
je 0x65e9
movq -0x38(%rbp), %rax
cmpb $0x0, 0xc(%rax)
je 0x65e7
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movzbl 0x1c(%rax), %eax
cmpl $0x0, %eax
jne 0x65e9
jmp 0x664a
movzbl -0x15(%rbp), %eax
cmpl $0x0, %eax
je 0x660f
movq -0x10(%rbp), %rax
movzbl 0x2(%rax), %eax
cmpl $0x2, %eax
jne 0x660f
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
cmpq -0x20(%rbp), %rax
jne 0x660f
jmp 0x664a
jmp 0x6611
movq $0x0, -0x30(%rbp)
movq -0x38(%rbp), %rax
movl 0x8(%rax), %eax
subl -0x58(%rbp), %eax
cmpl $0x0, %eax
jle 0x662a
jmp 0x664a
movq -0x38(%rbp), %rax
movq %rax, -0x48(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x653d
cmpq $0x0, -0x30(%rbp)
jne 0x66fb
movl $0x30, %edi
movl $0x1f8, %esi            # imm = 0x1F8
callq 0x7220
movq %rax, -0x28(%rbp)
movl $0x200, %edi            # imm = 0x200
movl $0x1f9, %esi            # imm = 0x1F9
callq 0x7220
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x28(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movswq -0x18(%rbp), %rax
addq $0x12, %rax
movw %ax, %cx
movq -0x28(%rbp), %rax
movw %cx, 0x18(%rax)
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
movq -0x28(%rbp), %rax
movzwl 0x18(%rax), %eax
movl %eax, %edx
callq 0x22c0
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rax
movb $0x0, 0xc(%rax)
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x28(%rbp), %rax
movb $0x0, 0x20(%rax)
movq -0x28(%rbp), %rax
movl $0x0, 0x1c(%rax)
movl -0x58(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x8(%rax)
jmp 0x6769
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x30(%rbp), %rax
movzwl 0x18(%rax), %eax
cltq
addq %rax, %rdi
movq -0x10(%rbp), %rsi
movswq -0x18(%rbp), %rdx
addq $0x12, %rdx
callq 0x22c0
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x30(%rbp), %rcx
movzwl 0x18(%rcx), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movswq -0x18(%rbp), %rdx
addq $0x12, %rdx
movq -0x30(%rbp), %rax
movzwl 0x18(%rax), %ecx
addq %rdx, %rcx
movw %cx, 0x18(%rax)
movq -0x30(%rbp), %rax
movb 0x20(%rax), %cl
addb $0x1, %cl
movb %cl, 0x20(%rax)
movq -0x30(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpb $0x0, -0x15(%rbp)
je 0x6794
movq -0x28(%rbp), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x64(%rbp)
movq -0x28(%rbp), %rax
movzbl 0x20(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
movl -0x64(%rbp), %ecx
orl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x50(%rbp), %rax
movb 0x2(%rax), %cl
addb $-0x1, %cl
movb %cl, 0x2(%rax)
movl -0x14(%rbp), %ecx
movq -0x50(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x681f
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movzbl 0x19(%rax), %eax
cmpl $0x0, %eax
je 0x681f
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x8(%rax), %eax
cmpl -0x14(%rbp), %eax
je 0x6811
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movb 0x19(%rax), %cl
movq -0x50(%rbp), %rax
movb %cl, 0x10(%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
cmpb $0x0, 0x1a(%rax)
je 0x680f
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movzbl 0x1a(%rax), %eax
subl $0x1, %eax
movb %al, %cl
movq -0x50(%rbp), %rax
movb %cl, 0x2(%rax)
jmp 0x6811
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movb 0x19(%rax), %al
movb %al, -0x51(%rbp)
movq -0x50(%rbp), %rax
movzbl 0x10(%rax), %eax
leaq 0x14a76(%rip), %rcx     # 0x1b2a4
movzbl (%rcx), %edx
movl $0xff, %ecx
subl %edx, %ecx
imull %ecx, %eax
movl $0xff, %ecx
cltd
idivl %ecx
movb %al, %cl
movq -0x50(%rbp), %rax
movb %cl, 0x10(%rax)
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %edx
movzbl -0x51(%rbp), %ecx
movq -0x50(%rbp), %rax
movzbl 0x10(%rax), %r8d
movq -0x10(%rbp), %rax
movzbl 0x2(%rax), %r9d
subl $0x1, %r9d
movq -0x50(%rbp), %rax
movzbl 0x2(%rax), %eax
movl $0x4, %edi
leaq 0xeca4(%rip), %rsi      # 0x15526
movl %eax, (%rsp)
movb $0x0, %al
callq 0x123f0
movq -0x50(%rbp), %rax
movzwl 0x4(%rax), %edi
callq 0x2170
movw %ax, %cx
movq -0x50(%rbp), %rax
movw %cx, 0x4(%rax)
cmpb $0x0, -0x15(%rbp)
je 0x68ba
movq -0x50(%rbp), %rax
movzbl 0x1(%rax), %ecx
orl $0x40, %ecx
movb %cl, 0x1(%rax)
jmp 0x68c8
movq -0x50(%rbp), %rax
movzbl 0x1(%rax), %ecx
andl $-0x41, %ecx
movb %cl, 0x1(%rax)
cmpq $0x0, -0x30(%rbp)
jne 0x68fb
cmpq $0x0, -0x38(%rbp)
je 0x68e9
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x6ea0
jmp 0x68f9
movq -0x28(%rbp), %rdi
leaq 0x14ae4(%rip), %rsi     # 0x1b3d8
callq 0x6e60
jmp 0x68fb
movl $0x7, %edi
callq 0x8790
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)