From c3ae1269e43ff0774be8d61f81b1af9a8b8d8f8e Mon Sep 17 00:00:00 2001 From: Arti Zirk Date: Sun, 1 Nov 2026 11:08:55 +0200 Subject: [PATCH] fix(badapple): distinguish UDP load failures and repeat the send --- bad-apple/player/main.c | 15 ++++++++++++--- bad-apple/tools/send_movie.py | 34 +++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/bad-apple/player/main.c b/bad-apple/player/main.c index e0934cf..f14568e 100644 --- a/bad-apple/player/main.c +++ b/bad-apple/player/main.c @@ -79,6 +79,7 @@ static unsigned char rxbuf[1600]; static unsigned char sa[16]; static unsigned char from[16]; static int fromlen; +static unsigned int rx_error; /* Receive movie.bin over the OS UDP stack into a malloc'd bit buffer. * Packet: u32 offset, u16 length, u16 seq, u16 crc16, then bytes. @@ -97,15 +98,18 @@ unsigned int expected; ptr = malloc_(expected); if (ptr == 0) { + rx_error = 3; return 0; } fd = socket_(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { + rx_error = 4; return 0; } sa_any(sa, NET_PORT); if (bind_(fd, sa, SOCKADDR_LEN) < 0) { close_(fd); + rx_error = 5; return 0; } sent_sum = 0; @@ -126,7 +130,11 @@ unsigned int expected; | ((unsigned int)rxbuf[11] << 8) | ((unsigned int)rxbuf[12] << 16) | ((unsigned int)rxbuf[13] << 24); - break; + if (movie_checksum(dst, expected) == sent_sum) { + break; + } + sent_sum = 0; + continue; } if (length > (unsigned int)(n - 10)) { continue; @@ -139,7 +147,8 @@ unsigned int expected; } } close_(fd); - if (movie_checksum(dst, expected) != sent_sum) { + if (sent_sum == 0) { + rx_error = 6; return 0; } return ptr; @@ -206,7 +215,7 @@ int main() *(unsigned int *)(MARK + 0x10 * 8) = 0x20; movie_base = receive_movie(movie_len); if (movie_base == 0) { - show_fault(0xBAD00003); + show_fault(0xBAD00000 | rx_error); } vid_dint_(); } else { diff --git a/bad-apple/tools/send_movie.py b/bad-apple/tools/send_movie.py index 2cf35e0..25042ef 100644 --- a/bad-apple/tools/send_movie.py +++ b/bad-apple/tools/send_movie.py @@ -34,25 +34,27 @@ def parse_ack(data: bytes) -> int: def send_movie(host: str, port: int, path: str, chunk: int = 1450, - delay: float = 0.0005) -> int: + delay: float = 0.0005, passes: int = 3) -> int: data = Path(path).read_bytes() sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: - offset = 0 - seq = 0 - while offset < len(data): - part = data[offset:offset + chunk] - sock.sendto(pack_packet(offset, seq, part), (host, port)) - offset += len(part) - seq += 1 - if delay: - time.sleep(delay) - sock.sendto(pack_packet(len(data), seq, - checksum32(data).to_bytes(4, "little")), - (host, port)) + for _ in range(passes): + offset = 0 + seq = 0 + while offset < len(data): + part = data[offset:offset + chunk] + sock.sendto(pack_packet(offset, seq, part), (host, port)) + offset += len(part) + seq += 1 + if delay: + time.sleep(delay) + sock.sendto(pack_packet(len(data), seq, + checksum32(data).to_bytes(4, "little")), + (host, port)) + time.sleep(0.05) finally: sock.close() - print("sent %d bytes in %d packets" % (len(data), seq + 1)) + print("sent %d bytes in %d pass(es)" % (len(data), passes)) return 0 @@ -63,8 +65,10 @@ def main(argv=None) -> int: parser.add_argument("--movie", required=True) parser.add_argument("--chunk", type=int, default=1450) parser.add_argument("--delay", type=float, default=0.0005) + parser.add_argument("--passes", type=int, default=3) args = parser.parse_args(argv) - return send_movie(args.host, args.port, args.movie, args.chunk, args.delay) + return send_movie(args.host, args.port, args.movie, args.chunk, + args.delay, args.passes) if __name__ == "__main__":