net.zig (2334B)
1 const std = @import("std"); 2 3 pub const Message = enum(u32) { 4 GET_PROG_INFO = 0x11112222, 5 PUT_PROG_INFO = 0x33334444, 6 7 GET_CODE = 0x55556666, 8 PUT_CODE = 0x77778888, 9 10 BOOT_SUCCESS = 0x9999AAAA, 11 BAD_CODE_ADDR = 0xDEADBEEF, 12 BAD_CODE_CKSUM = 0xFEEDFACE, 13 }; 14 15 pub const Error = error{ 16 BadAddress, 17 BadChecksum, 18 Timeout, 19 }; 20 21 pub const Header = struct { 22 arm_base: u32, 23 n_bytes: u32, 24 checksum: u32, 25 }; 26 27 pub fn get_u32(r: *std.Io.Reader) !u32 { 28 var buffer: [@sizeOf(u32)]u8 = undefined; 29 try r.readSliceAll(&buffer); 30 const v = std.mem.readInt(u32, &buffer, .little); 31 32 return v; 33 } 34 35 pub fn get_u8(r: *std.Io.Reader) !u8 { 36 var buffer: [1]u8 = undefined; 37 try r.readSliceAll(&buffer); 38 return buffer[0]; 39 } 40 41 pub fn put_u32(w: *std.Io.Writer, v: u32) !void { 42 var buffer: [@sizeOf(u32)]u8 = undefined; 43 std.mem.writeInt(u32, &buffer, v, .little); 44 try w.writeAll(&buffer); 45 try w.flush(); 46 } 47 48 pub fn put_u8(w: *std.Io.Writer, v: u8) !void { 49 try w.writeByte(v); 50 try w.flush(); 51 } 52 53 pub fn put_message(w: *std.Io.Writer, message: Message) !void { 54 try put_u32(w, @intFromEnum(message)); 55 } 56 57 pub fn transmit_header(w: *std.Io.Writer, header: Header) !void { 58 try put_message(w, .PUT_PROG_INFO); 59 try put_u32(w, header.arm_base); 60 try put_u32(w, header.n_bytes); 61 try put_u32(w, header.checksum); 62 } 63 64 pub fn receive_header(r: *std.Io.Reader, max_addr: u32) !Header { 65 const arm_base = try get_u32(r); 66 const n_bytes = try get_u32(r); 67 const checksum = try get_u32(r); 68 69 // TODO; better check 70 if (arm_base + n_bytes >= max_addr) { 71 return Error.BadAddress; 72 } 73 74 return .{ .arm_base = arm_base, .checksum = checksum, .n_bytes = n_bytes }; 75 } 76 77 pub fn transmit_code(w: *std.Io.Writer, progress: std.Progress.Node, code: []const u8) !void { 78 defer progress.end(); 79 try put_message(w, .PUT_CODE); 80 for (code) |byte| { 81 try put_u8(w, byte); 82 progress.completeOne(); 83 } 84 } 85 86 pub fn receive_code(r: *std.Io.Reader, buffer: []u8, header: Header) !void { 87 try r.readSliceAll(buffer); 88 89 if (std.hash.Crc32.hash(buffer) != header.checksum) { 90 return Error.BadChecksum; 91 } 92 } 93 94 pub fn request_code(w: *std.Io.Writer, crc: u32) !void { 95 try put_message(w, .GET_CODE); 96 try put_u32(w, crc); 97 }