// File: flightaware[P]beast-splitter/status_writer.cc
// Function: splitter::StatusWriter::write(modes::Message const&)
void StatusWriter::write(const modes::Message &message) {
        if (message.type() != modes::MessageType::STATUS)
            return;

        reset_timeout();

        const auto &data = message.data();

        // 0: settings, including:
        //    10: 1=GPS timestamps, 0=12MHz timestamps
        // 1: signed timestamp offset at last PPS edge, 15ns units
        // 2: GPS status
        //    80: 1=UTC, 0=UTC+1; if 0, other bits are unused
        //    40: unused
        //    20: 1=timestamp from FPGA, 0=timestamp from GPS
        //    10: 1=degradation <= 45ms, 0=degradation > 45ms
        //    08: 1=UTC time, 0=GPS time
        //    04: 1=good sats, 0=not enough good sats
        //    02: 1=tracking sats, 0=no sats
        //    01: 1=antenna OK, 0=antenna fault

        int pps_offset = (std::int8_t)data[1];

        if (!(data[0] & 0x10)) {
            // 12MHz mode
            write_status_file("red", "Not in GPS timestamp mode", pps_offset);
            return;
        }

        if (!(data[2] & 0x80)) {
            // Old style message. Assume it's good if abs(degradation) < 45ms
            if (pps_offset <= 3 || pps_offset >= -3) {
                write_status_file("green", "Receiver synchronized to GPS time", pps_offset);
            } else {
                write_status_file("amber", "Receiver more than 45ns from GPS time", pps_offset);
            }
            return;
        }

        // New style message

        if (!(data[2] & 0x20)) {
            // FPGA is using GPS time
            if (data[2] & 0x10) {
                write_status_file("green", "Receiver synchronized to GPS time", pps_offset);
            } else {
                write_status_file("amber", "Receiver more than 45ns from GPS time", pps_offset);
            }
            return;
        }

        // FPGA is not using GPS time, work out why.

        std::vector<std::string> status_messages;
        if (!(data[2] & 0x08)) {
            status_messages.push_back("GPS/UTC time offset not known");
        }

        if (!(data[2] & 0x02)) {
            status_messages.push_back("Not tracking any satellites");
        } else if (!(data[2] & 0x04)) {
            status_messages.push_back("Not tracking sufficient satellites");
        }

        if (!(data[2] & 0x01)) {
            status_messages.push_back("Antenna fault");
        }

        if (status_messages.empty()) {
            status_messages.push_back("Unrecognized GPS fault");
        }

        std::ostringstream status_buffer;
        for (auto i = status_messages.begin(); i != status_messages.end(); ++i) {
            if (i != status_messages.begin())
                status_buffer << "; ";
            status_buffer << *i;
        }

        write_status_file("red", status_buffer.str(), pps_offset);
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x500, %rsp            # imm = 0x500
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x480(%rbp)
movq -0x10(%rbp), %rdi
callq 0x13dc0
cmpl $0x4, %eax
je 0x60881
jmp 0x6135f
movq -0x480(%rbp), %rdi
callq 0x613e0
movq -0x10(%rbp), %rdi
callq 0x13e10
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x14d30
movsbl (%rax), %eax
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x14d30
movzbl (%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
jne 0x609af
leaq -0x41(%rbp), %rdi
movq %rdi, -0x488(%rbp)
callq 0x12fa0
movq -0x488(%rbp), %rdx
leaq 0x548dd(%rip), %rsi     # 0xb51c5
leaq -0x40(%rbp), %rdi
callq 0x22350
jmp 0x608f3
leaq -0x79(%rbp), %rdi
movq %rdi, -0x490(%rbp)
callq 0x12fa0
movq -0x490(%rbp), %rdx
leaq 0x548de(%rip), %rsi     # 0xb51ef
leaq -0x78(%rbp), %rdi
callq 0x22350
jmp 0x6091c
movq -0x480(%rbp), %rdi
movl -0x1c(%rbp), %ecx
leaq -0x40(%rbp), %rsi
leaq -0x78(%rbp), %rdx
callq 0x61750
jmp 0x60935
leaq -0x78(%rbp), %rdi
callq 0x13198
leaq -0x79(%rbp), %rdi
callq 0x128f0
leaq -0x40(%rbp), %rdi
callq 0x13198
leaq -0x41(%rbp), %rdi
callq 0x128f0
jmp 0x6135f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x609a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x6098f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x13198
leaq -0x79(%rbp), %rdi
callq 0x128f0
leaq -0x40(%rbp), %rdi
callq 0x13198
leaq -0x41(%rbp), %rdi
callq 0x128f0
jmp 0x613cc
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x14d30
movzbl (%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
jne 0x60bfe
cmpl $0x3, -0x1c(%rbp)
jle 0x609de
cmpl $-0x3, -0x1c(%rbp)
jl 0x60aed
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x498(%rbp)
callq 0x12fa0
movq -0x498(%rbp), %rdx
leaq 0x5480a(%rip), %rsi     # 0xb5209
leaq -0xa0(%rbp), %rdi
callq 0x22350
jmp 0x60a0d
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x4a0(%rbp)
callq 0x12fa0
movq -0x4a0(%rbp), %rdx
leaq 0x547e1(%rip), %rsi     # 0xb520f
leaq -0xc8(%rbp), %rdi
callq 0x22350
jmp 0x60a3c
movq -0x480(%rbp), %rdi
movl -0x1c(%rbp), %ecx
leaq -0xa0(%rbp), %rsi
leaq -0xc8(%rbp), %rdx
callq 0x61750
jmp 0x60a5b
leaq -0xc8(%rbp), %rdi
callq 0x13198
leaq -0xc9(%rbp), %rdi
callq 0x128f0
leaq -0xa0(%rbp), %rdi
callq 0x13198
leaq -0xa1(%rbp), %rdi
callq 0x128f0
jmp 0x60bf9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60adc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60ac4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x13198
leaq -0xc9(%rbp), %rdi
callq 0x128f0
leaq -0xa0(%rbp), %rdi
callq 0x13198
leaq -0xa1(%rbp), %rdi
callq 0x128f0
jmp 0x613cc
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x4a8(%rbp)
callq 0x12fa0
movq -0x4a8(%rbp), %rdx
leaq 0x54723(%rip), %rsi     # 0xb5231
leaq -0xf0(%rbp), %rdi
callq 0x22350
jmp 0x60b1c
leaq -0x119(%rbp), %rdi
movq %rdi, -0x4b0(%rbp)
callq 0x12fa0
movq -0x4b0(%rbp), %rdx
leaq 0x546fa(%rip), %rsi     # 0xb5237
leaq -0x118(%rbp), %rdi
callq 0x22350
jmp 0x60b4b
movq -0x480(%rbp), %rdi
movl -0x1c(%rbp), %ecx
leaq -0xf0(%rbp), %rsi
leaq -0x118(%rbp), %rdx
callq 0x61750
jmp 0x60b6a
leaq -0x118(%rbp), %rdi
callq 0x13198
leaq -0x119(%rbp), %rdi
callq 0x128f0
leaq -0xf0(%rbp), %rdi
callq 0x13198
leaq -0xf1(%rbp), %rdi
callq 0x128f0
jmp 0x60bf9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60be8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60bd0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x13198
leaq -0x119(%rbp), %rdi
callq 0x128f0
leaq -0xf0(%rbp), %rdi
callq 0x13198
leaq -0xf1(%rbp), %rdi
callq 0x128f0
jmp 0x613cc
jmp 0x6135f
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x14d30
movzbl (%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
jne 0x60e58
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x14d30
movzbl (%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x60d47
leaq -0x141(%rbp), %rdi
movq %rdi, -0x4b8(%rbp)
callq 0x12fa0
movq -0x4b8(%rbp), %rdx
leaq 0x545b0(%rip), %rsi     # 0xb5209
leaq -0x140(%rbp), %rdi
callq 0x22350
jmp 0x60c67
leaq -0x169(%rbp), %rdi
movq %rdi, -0x4c0(%rbp)
callq 0x12fa0
movq -0x4c0(%rbp), %rdx
leaq 0x54587(%rip), %rsi     # 0xb520f
leaq -0x168(%rbp), %rdi
callq 0x22350
jmp 0x60c96
movq -0x480(%rbp), %rdi
movl -0x1c(%rbp), %ecx
leaq -0x140(%rbp), %rsi
leaq -0x168(%rbp), %rdx
callq 0x61750
jmp 0x60cb5
leaq -0x168(%rbp), %rdi
callq 0x13198
leaq -0x169(%rbp), %rdi
callq 0x128f0
leaq -0x140(%rbp), %rdi
callq 0x13198
leaq -0x141(%rbp), %rdi
callq 0x128f0
jmp 0x60e53
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60d36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60d1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x13198
leaq -0x169(%rbp), %rdi
callq 0x128f0
leaq -0x140(%rbp), %rdi
callq 0x13198
leaq -0x141(%rbp), %rdi
callq 0x128f0
jmp 0x613cc
leaq -0x191(%rbp), %rdi
movq %rdi, -0x4c8(%rbp)
callq 0x12fa0
movq -0x4c8(%rbp), %rdx
leaq 0x544c9(%rip), %rsi     # 0xb5231
leaq -0x190(%rbp), %rdi
callq 0x22350
jmp 0x60d76
leaq -0x1b9(%rbp), %rdi
movq %rdi, -0x4d0(%rbp)
callq 0x12fa0
movq -0x4d0(%rbp), %rdx
leaq 0x544a0(%rip), %rsi     # 0xb5237
leaq -0x1b8(%rbp), %rdi
callq 0x22350
jmp 0x60da5
movq -0x480(%rbp), %rdi
movl -0x1c(%rbp), %ecx
leaq -0x190(%rbp), %rsi
leaq -0x1b8(%rbp), %rdx
callq 0x61750
jmp 0x60dc4
leaq -0x1b8(%rbp), %rdi
callq 0x13198
leaq -0x1b9(%rbp), %rdi
callq 0x128f0
leaq -0x190(%rbp), %rdi
callq 0x13198
leaq -0x191(%rbp), %rdi
callq 0x128f0
jmp 0x60e53
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60e42
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60e2a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0x13198
leaq -0x1b9(%rbp), %rdi
callq 0x128f0
leaq -0x190(%rbp), %rdi
callq 0x13198
leaq -0x191(%rbp), %rdi
callq 0x128f0
jmp 0x613cc
jmp 0x6135f
leaq -0x1d8(%rbp), %rdi
callq 0x62400
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x14d30
movzbl (%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x60f16
leaq -0x1f9(%rbp), %rdi
movq %rdi, -0x4d8(%rbp)
callq 0x12fa0
movq -0x4d8(%rbp), %rdx
leaq 0x543bb(%rip), %rsi     # 0xb525d
leaq -0x1f8(%rbp), %rdi
callq 0x22350
jmp 0x60eb0
leaq -0x1d8(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x62420
jmp 0x60ec5
leaq -0x1f8(%rbp), %rdi
callq 0x13198
leaq -0x1f9(%rbp), %rdi
callq 0x128f0
jmp 0x60f16
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60f05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x13198
leaq -0x1f9(%rbp), %rdi
callq 0x128f0
jmp 0x613c0
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x14d30
movzbl (%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x60fcb
leaq -0x221(%rbp), %rdi
movq %rdi, -0x4e0(%rbp)
callq 0x12fa0
movq -0x4e0(%rbp), %rdx
leaq 0x54327(%rip), %rsi     # 0xb527b
leaq -0x220(%rbp), %rdi
callq 0x22350
jmp 0x60f62
leaq -0x1d8(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x62420
jmp 0x60f77
leaq -0x220(%rbp), %rdi
callq 0x13198
leaq -0x221(%rbp), %rdi
callq 0x128f0
jmp 0x6107f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x60fba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x13198
leaq -0x221(%rbp), %rdi
callq 0x128f0
jmp 0x613c0
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x14d30
movzbl (%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
jne 0x6107d
leaq -0x249(%rbp), %rdi
movq %rdi, -0x4e8(%rbp)
callq 0x12fa0
movq -0x4e8(%rbp), %rdx
leaq 0x5428e(%rip), %rsi     # 0xb5297
leaq -0x248(%rbp), %rdi
callq 0x22350
jmp 0x61017
leaq -0x1d8(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x62420
jmp 0x6102c
leaq -0x248(%rbp), %rdi
callq 0x13198
leaq -0x249(%rbp), %rdi
callq 0x128f0
jmp 0x6107d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x6106c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x248(%rbp), %rdi
callq 0x13198
leaq -0x249(%rbp), %rdi
callq 0x128f0
jmp 0x613c0
jmp 0x6107f
movq -0x18(%rbp), %rdi
movl $0x2, %esi
callq 0x14d30
movzbl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x61131
leaq -0x271(%rbp), %rdi
movq %rdi, -0x4f0(%rbp)
callq 0x12fa0
movq -0x4f0(%rbp), %rdx
leaq 0x541fd(%rip), %rsi     # 0xb52ba
leaq -0x270(%rbp), %rdi
callq 0x22350
jmp 0x610cb
leaq -0x1d8(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x62420
jmp 0x610e0
leaq -0x270(%rbp), %rdi
callq 0x13198
leaq -0x271(%rbp), %rdi
callq 0x128f0
jmp 0x61131
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x61120
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x13198
leaq -0x271(%rbp), %rdi
callq 0x128f0
jmp 0x613c0
leaq -0x1d8(%rbp), %rdi
callq 0x62450
testb $0x1, %al
jne 0x61146
jmp 0x611db
leaq -0x299(%rbp), %rdi
movq %rdi, -0x4f8(%rbp)
callq 0x12fa0
movq -0x4f8(%rbp), %rdx
leaq 0x54161(%rip), %rsi     # 0xb52c8
leaq -0x298(%rbp), %rdi
callq 0x22350
jmp 0x61175
leaq -0x1d8(%rbp), %rdi
leaq -0x298(%rbp), %rsi
callq 0x62420
jmp 0x6118a
leaq -0x298(%rbp), %rdi
callq 0x13198
leaq -0x299(%rbp), %rdi
callq 0x128f0
jmp 0x611db
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x611ca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x298(%rbp), %rdi
callq 0x13198
leaq -0x299(%rbp), %rdi
callq 0x128f0
jmp 0x613c0
leaq -0x418(%rbp), %rdi
callq 0x12ba0
jmp 0x611e9
leaq -0x1d8(%rbp), %rdi
callq 0x62490
movq %rax, -0x420(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x62500
movq %rax, -0x428(%rbp)
leaq -0x420(%rbp), %rdi
leaq -0x428(%rbp), %rsi
callq 0x624c0
testb $0x1, %al
jne 0x6122b
jmp 0x612c0
leaq -0x1d8(%rbp), %rdi
callq 0x62490
movq %rax, -0x430(%rbp)
leaq -0x420(%rbp), %rdi
leaq -0x430(%rbp), %rsi
callq 0x624c0
testb $0x1, %al
jne 0x61257
jmp 0x61290
leaq 0x54081(%rip), %rsi     # 0xb52df
leaq -0x418(%rbp), %rdi
callq 0x12800
jmp 0x6126c
jmp 0x61290
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x613c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x613b4
leaq -0x420(%rbp), %rdi
callq 0x62530
movq %rax, %rsi
leaq -0x418(%rbp), %rdi
callq 0x12770
jmp 0x612ad
jmp 0x612af
leaq -0x420(%rbp), %rdi
callq 0x62550
jmp 0x611fc
leaq -0x451(%rbp), %rdi
movq %rdi, -0x500(%rbp)
callq 0x12fa0
movq -0x500(%rbp), %rdx
leaq 0x53ee4(%rip), %rsi     # 0xb51c5
leaq -0x450(%rbp), %rdi
callq 0x22350
jmp 0x612ef
leaq -0x478(%rbp), %rdi
leaq -0x418(%rbp), %rsi
callq 0x12890
jmp 0x61304
movq -0x480(%rbp), %rdi
movl -0x1c(%rbp), %ecx
leaq -0x450(%rbp), %rsi
leaq -0x478(%rbp), %rdx
callq 0x61750
jmp 0x61323
leaq -0x478(%rbp), %rdi
callq 0x13198
leaq -0x450(%rbp), %rdi
callq 0x13198
leaq -0x451(%rbp), %rdi
callq 0x128f0
leaq -0x418(%rbp), %rdi
callq 0x121e0
leaq -0x1d8(%rbp), %rdi
callq 0x62570
addq $0x500, %rsp            # imm = 0x500
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x613a8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x6139c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x478(%rbp), %rdi
callq 0x13198
leaq -0x450(%rbp), %rdi
callq 0x13198
leaq -0x451(%rbp), %rdi
callq 0x128f0
leaq -0x418(%rbp), %rdi
callq 0x121e0
leaq -0x1d8(%rbp), %rdi
callq 0x62570
movq -0x50(%rbp), %rdi
callq 0x12f70
nopw %cs:(%rax,%rax)