// File: hugosantos[P]dbeacon/dbeacon.cpp
// Function: beaconMcastState::update(unsigned char, unsigned int, unsigned long, unsigned long, unsigned long)
void beaconMcastState::update(uint8_t ttl, uint32_t seqnum, uint64_t timestamp, uint64_t tsnow, uint64_t _now) {
	/*
	 * ttl - received TTL
	 * seqnum - received seqnum in probe
	 * timestamp - received timestamp in probe (timeofday in sender)
	 * _now - when this packet was received locally (timeofday of host)
	 */

	int64_t now = (uint32_t)_now;

	int64_t diff = now - timestamp;
	int64_t absdiff = abs64(diff);

	if (udiff(seqnum, lastseq) > PACKETS_VERY_OLD) {
		refresh(seqnum - 1, tsnow);
	}

	if (seqnum < lastseq && (lastseq - seqnum) >= packetcount)
		return;

	s.timestamp = timestamp;
	s.lastupdate = tsnow;

	bool dup = false;

	uint32_t expectseq = lastseq + 1;

	if (seqnum < expectseq) {
		for (uint32_t i = 0; i < pointer; i++) {
			if (cacheseqnum[i] == seqnum) {
				dup = true;
				break;
			}
		}
	}

	s.rttl = ttl;

	if (dup) {
		lastdup ++;
	} else {
		packetcountreal++;

		cacheseqnum[pointer++] = seqnum;

		lastdelay += diff;

		int newjitter = absdiff - lastjitter;
		lastjitter = absdiff;
		if (newjitter < 0)
			newjitter = -newjitter;
		s.avgjitter = 15/16. * s.avgjitter + 1/16. * newjitter;

		if (expectseq == seqnum) {
			packetcount ++;
		} else if (seqnum > expectseq) {
			packetcount += seqnum - lastseq;

			lastloss += seqnum - lastseq - 1;
		} else {
			lastloss --;
			lastooo ++;
		}

		if (expectseq <= seqnum) {
			lastseq = seqnum;
		}
	}

	if (packetcount >= PACKETS_PERIOD) {
		s.avgdelay = lastdelay / (float)packetcountreal;
		s.avgloss = lastloss / (float)packetcount;
		s.avgooo = lastooo / (float)packetcount;
		s.avgdup = lastdup / (float)packetcount;

		s.valid = true;

		lastdelay = 0;
		lastloss = 0;
		lastooo = 0;
		lastdup = 0;
		packetcount = 0;
		packetcountreal = 0;
		pointer = 0;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movq %r8, -0x20(%rbp)
movq %r9, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rax
movl %eax, %eax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
subq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x7fc0
movq %rax, %rcx
movq -0x58(%rbp), %rax
movq %rcx, -0x40(%rbp)
movl -0x10(%rbp), %edi
movl (%rax), %esi
callq 0xb650
cmpl $0x96, %eax
jbe 0x7c67
movq -0x58(%rbp), %rdi
movl -0x10(%rbp), %esi
subl $0x1, %esi
movq -0x20(%rbp), %rdx
callq 0x7f30
movq -0x58(%rbp), %rcx
movl -0x10(%rbp), %eax
cmpl (%rcx), %eax
jae 0x7c85
movq -0x58(%rbp), %rcx
movl (%rcx), %eax
subl -0x10(%rbp), %eax
cmpl 0x4(%rcx), %eax
jb 0x7c85
jmp 0x7e98
movq -0x58(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, 0x28(%rax)
movq -0x20(%rbp), %rcx
movq %rcx, 0x30(%rax)
movb $0x0, -0x41(%rbp)
movl (%rax), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
movl -0x10(%rbp), %eax
cmpl -0x48(%rbp), %eax
jae 0x7ce5
movl $0x0, -0x4c(%rbp)
movq -0x58(%rbp), %rcx
movl -0x4c(%rbp), %eax
cmpl 0xc(%rcx), %eax
jae 0x7ce3
movq -0x58(%rbp), %rax
movl -0x4c(%rbp), %ecx
movl 0x50(%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
jne 0x7cd6
movb $0x1, -0x41(%rbp)
jmp 0x7ce3
jmp 0x7cd8
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x7cb4
jmp 0x7ce5
movq -0x58(%rbp), %rax
movb -0x9(%rbp), %cl
movb %cl, 0x4d(%rax)
testb $0x1, -0x41(%rbp)
je 0x7d07
movq -0x58(%rbp), %rax
movl 0x1c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x1c(%rax)
jmp 0x7df9
movq -0x58(%rbp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8(%rax)
movl -0x10(%rbp), %edx
movl 0xc(%rax), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0xc(%rax)
movl %ecx, %ecx
movl %edx, 0x50(%rax,%rcx,4)
movq -0x38(%rbp), %rdx
movslq 0x10(%rax), %rcx
addq %rdx, %rcx
movl %ecx, 0x10(%rax)
movq -0x40(%rbp), %rcx
movslq 0x14(%rax), %rdx
subq %rdx, %rcx
movl %ecx, -0x50(%rbp)
movq -0x40(%rbp), %rcx
movl %ecx, 0x14(%rax)
cmpl $0x0, -0x50(%rbp)
jge 0x7d59
xorl %eax, %eax
subl -0x50(%rbp), %eax
movl %eax, -0x50(%rbp)
movq -0x58(%rbp), %rax
movss 0x3c(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
cvtsi2sdl -0x50(%rbp), %xmm2
movsd 0x132a5(%rip), %xmm1    # 0x1b018
mulsd %xmm2, %xmm1
movsd 0x13291(%rip), %xmm2    # 0x1b010
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x3c(%rax)
movl -0x48(%rbp), %eax
cmpl -0x10(%rbp), %eax
jne 0x7da7
movq -0x58(%rbp), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
jmp 0x7de6
movl -0x10(%rbp), %eax
cmpl -0x48(%rbp), %eax
jbe 0x7dce
movq -0x58(%rbp), %rax
movl -0x10(%rbp), %ecx
subl (%rax), %ecx
addl 0x4(%rax), %ecx
movl %ecx, 0x4(%rax)
movl -0x10(%rbp), %ecx
subl (%rax), %ecx
subl $0x1, %ecx
addl 0x18(%rax), %ecx
movl %ecx, 0x18(%rax)
jmp 0x7de4
movq -0x58(%rbp), %rax
movl 0x18(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x18(%rax)
movl 0x20(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x20(%rax)
jmp 0x7de6
movl -0x48(%rbp), %eax
cmpl -0x10(%rbp), %eax
ja 0x7df7
movq -0x58(%rbp), %rax
movl -0x10(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x7df9
movq -0x58(%rbp), %rax
cmpl $0x28, 0x4(%rax)
jb 0x7e98
movq -0x58(%rbp), %rax
cvtsi2ssl 0x10(%rax), %xmm0
movl 0x8(%rax), %ecx
cvtsi2ss %rcx, %xmm1
divss %xmm1, %xmm0
movss %xmm0, 0x38(%rax)
cvtsi2ssl 0x18(%rax), %xmm0
movl 0x4(%rax), %ecx
cvtsi2ss %rcx, %xmm1
divss %xmm1, %xmm0
movss %xmm0, 0x40(%rax)
cvtsi2ssl 0x20(%rax), %xmm0
movl 0x4(%rax), %ecx
cvtsi2ss %rcx, %xmm1
divss %xmm1, %xmm0
movss %xmm0, 0x48(%rax)
cvtsi2ssl 0x1c(%rax), %xmm0
movl 0x4(%rax), %ecx
cvtsi2ss %rcx, %xmm1
divss %xmm1, %xmm0
movss %xmm0, 0x44(%rax)
movb $0x1, 0x4c(%rax)
movl $0x0, 0x10(%rax)
movl $0x0, 0x18(%rax)
movl $0x0, 0x20(%rax)
movl $0x0, 0x1c(%rax)
movl $0x0, 0x4(%rax)
movl $0x0, 0x8(%rax)
movl $0x0, 0xc(%rax)
addq $0x60, %rsp
popq %rbp
retq
nop