Fixed packet deserialization and tests and made improvements to code readability
This commit is contained in:
parent
ee3cba3cab
commit
7c5f8c9f30
1 changed files with 107 additions and 92 deletions
109
src/packet.zig
109
src/packet.zig
|
|
@ -1,15 +1,6 @@
|
||||||
///////////////// Imports
|
|
||||||
//
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
///////////////// Constants
|
///////////////// Constants
|
||||||
//
|
//
|
||||||
|
|
||||||
const expect = std.testing.expect;
|
|
||||||
const memeql = std.mem.eql;
|
|
||||||
const asBytes = std.mem.asBytes;
|
|
||||||
|
|
||||||
const MAX_DATA_SIZE = 465;
|
const MAX_DATA_SIZE = 465;
|
||||||
const ADDRESS_SIZE = 16;
|
const ADDRESS_SIZE = 16;
|
||||||
|
|
||||||
|
|
@ -24,11 +15,15 @@ const HeaderType = enum(u1) {
|
||||||
type1 = 0, // One address field
|
type1 = 0, // One address field
|
||||||
type2 = 1, // Two address fields
|
type2 = 1, // Two address fields
|
||||||
};
|
};
|
||||||
const ContextFlag = enum(u1) { // Meaning depends on packet context
|
const ContextFlag = enum(u1) {
|
||||||
|
// Meaning depends on packet context
|
||||||
unset = 0,
|
unset = 0,
|
||||||
set = 1,
|
set = 1,
|
||||||
};
|
};
|
||||||
const PropagationType = enum(u1) { broadcast = 0, transport = 1 };
|
const PropagationType = enum(u1) {
|
||||||
|
broadcast = 0,
|
||||||
|
transport = 1
|
||||||
|
};
|
||||||
|
|
||||||
const DestinationType = enum(u2) {
|
const DestinationType = enum(u2) {
|
||||||
single = 0b0,
|
single = 0b0,
|
||||||
|
|
@ -86,21 +81,44 @@ const Packet = struct {
|
||||||
address1: [ADDRESS_SIZE]u8,
|
address1: [ADDRESS_SIZE]u8,
|
||||||
address2: [ADDRESS_SIZE]u8,
|
address2: [ADDRESS_SIZE]u8,
|
||||||
context: PacketContext,
|
context: PacketContext,
|
||||||
data: []const u8,
|
data: []u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////// Functions
|
///////////////// Functions
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//////// Helper functions
|
||||||
|
//
|
||||||
|
|
||||||
|
// Copies serialized data (as a byte array) into any structure type
|
||||||
|
fn copyToPacket(dst: anytype, src: []const u8, offset: usize, count: usize) !usize {
|
||||||
|
if (count == 0) return 0;
|
||||||
|
if (src.len < offset + count) return error.BufferTooShort;
|
||||||
|
|
||||||
|
|
||||||
|
const dst_ptr: []u8 = @ptrCast(dst);
|
||||||
|
if (dst_ptr.len != count) return error.MismatchedLengths;
|
||||||
|
|
||||||
|
|
||||||
|
@memcpy(dst_ptr, src[offset .. offset + count]);
|
||||||
|
|
||||||
|
return offset + count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the size of the packet in bytes
|
||||||
|
fn getPacketSize(data_size: usize, has_two_addresses: bool) usize {
|
||||||
|
var res = @sizeOf(PacketHeader) + ADDRESS_SIZE + @sizeOf(PacketContext) + data_size;
|
||||||
|
if (has_two_addresses) res += ADDRESS_SIZE;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////// Public functions
|
||||||
|
//
|
||||||
|
|
||||||
pub fn serializePacket(packet: Packet, output_buffer: []u8) !usize {
|
pub fn serializePacket(packet: Packet, output_buffer: []u8) !usize {
|
||||||
const has_two_addresses = packet.header.header == HeaderType.type2;
|
const has_two_addresses = packet.header.header == HeaderType.type2;
|
||||||
|
|
||||||
// Compute size of final packet (in bytes)
|
const target_size = getPacketSize(packet.data.len, has_two_addresses);
|
||||||
var target_size: u16 = @sizeOf(Packet);
|
|
||||||
if (!has_two_addresses) {
|
|
||||||
target_size -= packet.address2.len;
|
|
||||||
}
|
|
||||||
// TODO check data len
|
|
||||||
|
|
||||||
if (output_buffer.len < target_size) {
|
if (output_buffer.len < target_size) {
|
||||||
return error.BufferTooShort;
|
return error.BufferTooShort;
|
||||||
|
|
@ -132,17 +150,6 @@ pub fn serializePacket(packet: Packet, output_buffer: []u8) !usize {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copyToPacket(dst: anytype, src: []const u8, offset: usize, count: usize) !usize {
|
|
||||||
if (src.len < offset + count) {
|
|
||||||
return error.BufferTooShort;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dst_ptr: []u8 = @ptrCast(dst);
|
|
||||||
@memcpy(dst_ptr, src[offset .. offset + count]);
|
|
||||||
|
|
||||||
return offset + count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads the message buffer and builds the corresponding packet struct inside dest_packet
|
// Reads the message buffer and builds the corresponding packet struct inside dest_packet
|
||||||
pub fn deserializePacket(message_buffer: []u8, dest_packet: *Packet) !void {
|
pub fn deserializePacket(message_buffer: []u8, dest_packet: *Packet) !void {
|
||||||
var offset: usize = 0;
|
var offset: usize = 0;
|
||||||
|
|
@ -154,14 +161,18 @@ pub fn deserializePacket(message_buffer: []u8, dest_packet: *Packet) !void {
|
||||||
offset = try copyToPacket(&dest_packet.address2, message_buffer, offset, ADDRESS_SIZE);
|
offset = try copyToPacket(&dest_packet.address2, message_buffer, offset, ADDRESS_SIZE);
|
||||||
}
|
}
|
||||||
offset = try copyToPacket(&dest_packet.context, message_buffer, offset, @sizeOf(PacketContext));
|
offset = try copyToPacket(&dest_packet.context, message_buffer, offset, @sizeOf(PacketContext));
|
||||||
// TODO compute data length
|
offset = try copyToPacket(dest_packet.data, message_buffer, offset, message_buffer.len - offset);
|
||||||
const data_len = 0;
|
|
||||||
offset = try copyToPacket(&dest_packet.data, message_buffer, offset, data_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////// Tests
|
///////////////// Tests
|
||||||
//
|
//
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
const memeql = std.mem.eql;
|
||||||
|
const asBytes = std.mem.asBytes;
|
||||||
|
|
||||||
//////// Helper functions
|
//////// Helper functions
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
@ -170,11 +181,8 @@ fn testPacketSerialization(packet: Packet) !void {
|
||||||
const buf_size = comptime @sizeOf(Packet) + MAX_DATA_SIZE;
|
const buf_size = comptime @sizeOf(Packet) + MAX_DATA_SIZE;
|
||||||
var buf: [buf_size]u8 = undefined;
|
var buf: [buf_size]u8 = undefined;
|
||||||
const res: usize = try serializePacket(packet, &buf);
|
const res: usize = try serializePacket(packet, &buf);
|
||||||
var expected_res: usize = @sizeOf(PacketHeader) + packet.address1.len + @sizeOf(PacketContext) + packet.data.len;
|
|
||||||
const has_second_address = packet.header.header == HeaderType.type2;
|
const has_second_address = packet.header.header == HeaderType.type2;
|
||||||
if (has_second_address) {
|
const expected_res: usize = getPacketSize(packet.data.len, has_second_address);
|
||||||
expected_res += packet.address2.len;
|
|
||||||
}
|
|
||||||
|
|
||||||
try expect(res == expected_res);
|
try expect(res == expected_res);
|
||||||
|
|
||||||
|
|
@ -186,6 +194,11 @@ fn testPacketSerialization(packet: Packet) !void {
|
||||||
try expect(memeql(u8, buf[offset .. offset + packet.address1.len], asBytes(&packet.address1)));
|
try expect(memeql(u8, buf[offset .. offset + packet.address1.len], asBytes(&packet.address1)));
|
||||||
offset += packet.address1.len;
|
offset += packet.address1.len;
|
||||||
|
|
||||||
|
if (has_second_address) {
|
||||||
|
try expect(memeql(u8, buf[offset .. offset + packet.address2.len], asBytes(&packet.address2)));
|
||||||
|
offset += packet.address2.len;
|
||||||
|
}
|
||||||
|
|
||||||
try expect(memeql(u8, buf[offset .. offset + @sizeOf(PacketContext)], asBytes(&packet.context)));
|
try expect(memeql(u8, buf[offset .. offset + @sizeOf(PacketContext)], asBytes(&packet.context)));
|
||||||
offset += @sizeOf(PacketContext);
|
offset += @sizeOf(PacketContext);
|
||||||
|
|
||||||
|
|
@ -231,9 +244,9 @@ test "Basic serialization: header type 1, max data size" {
|
||||||
};
|
};
|
||||||
|
|
||||||
const data_size = MAX_DATA_SIZE;
|
const data_size = MAX_DATA_SIZE;
|
||||||
const data: [data_size]u8 = undefined;
|
var data: [data_size]u8 = undefined;
|
||||||
|
|
||||||
const packet: Packet = .{ //
|
const packet: Packet = .{
|
||||||
.header = header,
|
.header = header,
|
||||||
.address1 = undefined,
|
.address1 = undefined,
|
||||||
.address2 = undefined,
|
.address2 = undefined,
|
||||||
|
|
@ -256,9 +269,9 @@ test "Basic serialization: header type 2, max data size" {
|
||||||
};
|
};
|
||||||
|
|
||||||
const data_size = MAX_DATA_SIZE;
|
const data_size = MAX_DATA_SIZE;
|
||||||
const data: [data_size]u8 = undefined;
|
var data: [data_size]u8 = undefined;
|
||||||
|
|
||||||
const packet: Packet = .{ //
|
const packet: Packet = .{
|
||||||
.header = header,
|
.header = header,
|
||||||
.address1 = undefined,
|
.address1 = undefined,
|
||||||
.address2 = undefined,
|
.address2 = undefined,
|
||||||
|
|
@ -281,9 +294,9 @@ test "Basic serialization: header type 1, medium data size" {
|
||||||
};
|
};
|
||||||
|
|
||||||
const data_size = MAX_DATA_SIZE / 2 + 3;
|
const data_size = MAX_DATA_SIZE / 2 + 3;
|
||||||
const data: [data_size]u8 = undefined;
|
var data: [data_size]u8 = undefined;
|
||||||
|
|
||||||
const packet: Packet = .{ //
|
const packet: Packet = .{
|
||||||
.header = header,
|
.header = header,
|
||||||
.address1 = undefined,
|
.address1 = undefined,
|
||||||
.address2 = undefined,
|
.address2 = undefined,
|
||||||
|
|
@ -306,9 +319,9 @@ test "Basic serialization: header type 2, medium data size" {
|
||||||
};
|
};
|
||||||
|
|
||||||
const data_size = MAX_DATA_SIZE / 2 + 3;
|
const data_size = MAX_DATA_SIZE / 2 + 3;
|
||||||
const data: [data_size]u8 = undefined;
|
var data: [data_size]u8 = undefined;
|
||||||
|
|
||||||
const packet: Packet = .{ //
|
const packet: Packet = .{
|
||||||
.header = header,
|
.header = header,
|
||||||
.address1 = undefined,
|
.address1 = undefined,
|
||||||
.address2 = undefined,
|
.address2 = undefined,
|
||||||
|
|
@ -331,9 +344,9 @@ test "Serialize / Deserialize Packet: Header type2, Medium data size" {
|
||||||
};
|
};
|
||||||
|
|
||||||
const data_size = MAX_DATA_SIZE / 2 + 3;
|
const data_size = MAX_DATA_SIZE / 2 + 3;
|
||||||
const data: [data_size]u8 = undefined;
|
var data: [data_size]u8 = undefined;
|
||||||
|
|
||||||
const packet: Packet = .{ //
|
const packet: Packet = .{
|
||||||
.header = header,
|
.header = header,
|
||||||
.address1 = undefined,
|
.address1 = undefined,
|
||||||
.address2 = undefined,
|
.address2 = undefined,
|
||||||
|
|
@ -341,9 +354,11 @@ test "Serialize / Deserialize Packet: Header type2, Medium data size" {
|
||||||
.data = &data,
|
.data = &data,
|
||||||
};
|
};
|
||||||
|
|
||||||
const buf_size = comptime @sizeOf(Packet) + MAX_DATA_SIZE;
|
const buf_size = comptime @sizeOf(PacketHeader) + 2*ADDRESS_SIZE + @sizeOf(PacketContext) + data_size;
|
||||||
var buf: [buf_size]u8 = undefined;
|
var buf: [buf_size]u8 = undefined;
|
||||||
var res_packet: Packet = undefined;
|
var res_packet: Packet = undefined;
|
||||||
|
var res_data: [data_size]u8 = undefined;
|
||||||
|
res_packet.data = &res_data;
|
||||||
_ = try serializePacket(packet, &buf);
|
_ = try serializePacket(packet, &buf);
|
||||||
try deserializePacket(&buf, &res_packet);
|
try deserializePacket(&buf, &res_packet);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue