encodeSelf method
Encodes this object.
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
writer.writeUint16(destinationPort);
// 16-bit payload length will be filled later
writer.writeUint16(0);
// 16-bit checksum
// Must have 0 during calculation
writer.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
// ------------------
var 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);
}