encodeSelf method
Writes this object to the provided RawWriter.
Implementation
@override
void encodeSelf(RawWriter writer) {
// ----------------------------
// Check that we have IP packet
// ----------------------------
if (parentPacket == null) {
throw StateError(
"UdpPacket field 'parentPacket' is null. UDP protocol requires IP packet for calculating checksum.",
);
}
// ------
// Fields
// ------
final start = writer.length;
// 16-bit source port
writer
..writeUint16(sourcePort)
// 16-bit destination port
..writeUint16(destinationPort)
// 16-bit payload length will be filled later
..writeUint16(0)
// 16-bit checksum
// Must have 0 during calculation
..writeUint16(0);
// -------
// Payload
// -------
final payloadStart = writer.length;
payload.encodeSelf(writer);
final payloadLength = writer.length - payloadStart;
// Set payload length
writer.bufferAsByteData.setUint16(start + 4, payloadLength);
// ------------------
// Calculate checksum
// ------------------
int checksum = 0;
final ipPacket = parentPacket;
final ipPacketPayloadLength = writer.length - start;
if (ipPacket is Ip4Packet) {
checksum += ipPacket.source!.asUint32;
checksum += ipPacket.destination!.asUint32;
checksum += ipPacket.typeOfService;
checksum += ipPacketPayloadLength;
} else if (ipPacket is Ip6Packet) {
checksum += _checksumIp6Address(ipPacket.source!);
checksum += _checksumIp6Address(ipPacket.destination!);
checksum += ipPacketPayloadLength;
checksum += ipPacket.payloadProtocolNumber;
} else {
throw StateError('IP packet is invalid');
}
checksum = Ip4Packet.calculateChecksum(
writer.bufferAsByteData,
start,
ipPacketPayloadLength,
checksum: checksum,
);
// Set checksum
writer.bufferAsByteData.setUint16(start + 6, checksum);
}