Time Stamp Injection
Introduction
A timestamp can be injected into the payload of a packet when transmitting. This can be used to measure the delay or latency of a network. The injected timestamp shows when a packet is transmitted. The receiver of the packet can compare the injected timestamp with the packet timestamp. This shows how long time the packet has been on the way from the transmitter to the receiver.
Inject the Timestamp
The timestamp is injected by the adapter when transmitting the packet. However, the timestamp injection must be enabled for each packet and decided where in the packet the timestamp should be injected. This is done by using the timestamp inject macro.
NT_NET_SET_PKT_INJECT_TIMESTAMP(packet, offset)
A pointer to the packet and an offset to where in the packet the timestamp should be injected must be supplied to the macro.
- Note
- Gen2 adapters: The offset has a valid range from 0 to 511 bytes from either the start of the packet or the end of the packet.
- Note
- Gen1 adapters: The offset has a valid range from 0 to 255 bytes from either the start of the packet or the end of the packet.
// Build the packet
NT_NET_SET_PKT_CLEAR_DESCR_EXT7((&pktNetBuf)); // Clears the packet descriptor - must be done first
NT_NET_SET_PKT_DESCR_TYPE_EXT7((&pktNetBuf)); // Sets the packet to use extended descriptor 7
NT_NET_SET_PKT_CAP_LENGTH((&pktNetBuf), currentPacketSize); // Sets the capture/stored length of the packet
// This includes the packet header and the alignment padding
NT_NET_SET_PKT_WIRE_LENGTH((&pktNetBuf), currentPacketSize);// Sets the wirelength of the packet
NT_NET_SET_PKT_CALC_L2_CRC((&pktNetBuf), 1); // Forces the FPGA to calculate a new L2 CRC
NT_NET_SET_PKT_TXPORT((&pktNetBuf), txPort); // Only necessary if transmitting on a capture adapter
// On an in-line adapter, the port is decided by the NT_NetTxGet function
NT_NET_SET_PKT_INJECT_TIMESTAMP((&pktNetBuf), 0); // Injects a timestamp at offset 0 in the packet
NT_NET_UPDATE_PKT_L2_PTR((&pktNetBuf)); // Updates the L2 pointer of the packet to match the new descriptor
if(firstPaket == 0) {
if(txTiming == NT_TX_TIMING_ABSOLUTE) {
NT_NET_SET_PKT_TXNOW((&pktNetBuf), 0);
NT_NET_SET_PKT_TXSETCLOCK((&pktNetBuf), 1);
}
else {
NT_NET_SET_PKT_TXNOW((&pktNetBuf), 1);
}
firstPaket = 1;
}
else {
NT_NET_SET_PKT_TIMESTAMP((&pktNetBuf), ((ts+99)/100)*10); // Rounds up to nearest 10 ns tick - the packet timestamp decides when
// the packet is transmitted and is different from the injected
// timestamp
NT_NET_SET_PKT_TXNOW((&pktNetBuf), 0);
}
// Creates a packet with an incrementing 32bit pattern
// Note that the packet does not contain valid MAC address, etc.
*((uint32_t*)NT_NET_GET_PKT_L2_PTR((&pktNetBuf))+i) = payload++;
}
- Note
- In the above code example the timestamp is injected at offset 0 in the packet. This means that the beginning of the packet is overwritten by the timestamp. To prevent this, the offset must be selected with care. It is possible to select whether the offset should be counted from the start of the packet or from the end of the packet (see the description below).
- Note
- To inject a timestamp in the packet the extended packet descriptor must be used.
- Note
- If the inject offset is to large to fit into the packet, no timestamp is injected. The timestamp will not be injected outside the packet and no damage to the packet stream is done.
- Note
- If the inject offset is larger than the maximum range, but smaller than the packet size. The value will be masked. For a gen2 adapter the lowest 9 bit of the vallue will be used (value & 0x1FF) and for a gen1 adapter the lowest 8 bit if the value will be used (value & 0xFF).
Start Of Frame or End Of Frame Timestamp
When transmitting packets it is possible to decide whether the injected timestamp should show the time when the first or the last byte of the packet (frame) is put on the wire.
This is selected in the ntservice.ini file by setting the TimestampMethod key
- Note
- This setting also effects the RX timestamp when receiving packets. As with the injected timestamp, the RX timestamp shows either when the first byte is received or when the last byte is received.
Timestamp Inject Offset Mode
It is also possible to decide where the injected timestamp should be placed the payload of the packet. It is done by the NT_NET_SET_PKT_INJECT_TIMESTAMP macro and the TimestampInjectOffset parameter in the ntservice.ini file. The TimestampInjectOffset parameter specifies whether the timestamp offset should be counted from the start of the packet or from the end of the packet. This is very useful if the content of the packet must be preserved during the transmission.
To preserve the packet content, set the TimestampInjectOffset=EOF, make the packet 8 bytes larger than needed for the packet payload, and inject the timestamp at offset 0. This causes the timestamp to be injected in the 8 byte empty space without detroying the packet content.
To read the injected timestamp again it must be taken into account that the adapter adds a 4 byte CRC at the end of the packet. The injected timestamp is read at the position: Wirelength - 8 - 4.
uint64_t *pInjectedTS;
pInjectedTS = (uint64_t *)((uint8_t *)NT_NET_GET_PKT_L2_PTR((&pktNetBuf)) + NT_NET_GET_PKT_WIRE_LENGTH((&pktNetBuf)) - 12);
The offset injection mode can be controlled in the ntservice.ini file by setting the key: TimestampInjectOffset
Timestamp Method
This is a TimestampMethod "system setting" - changing the setting will affect all adapters
Section | Key | Values | Default | Description |
System | TimestampMethod | SOF EOF | EOF | SOF = Start of Frame EOF = End of Frame Reception of packets (RX) Packets can be time-stamped when the first byte is received or when the last byte is received Default is when the last byte is received Transmission of packets (TX) Packets can be time-stamped when the first byte is put on the wire or when the last byte is put on the wire Default is when the last byte is put on the wire |
To select start of frame timestamps:
[system]
TimestampMethod = SOF
To select end of frame timestamps:
[system]
TimestampMethod = EOF
Timestamp Inject Offset
This is an TimestampInjectOffset "adapter parameter" and must be set for each adapter
To select start of frame offset for adapter 0:
Section | Key | Values | Default | Description |
Adapter | TimestampInjectOffset | SOF EOF | SOF | SOF = Start of Frame EOF = End of Frame This setting pertains to transmission of packets (TX). The setting is used for controlling the offset base used when injecting time stamps into transmitted packets. The offset base can be either start of frame (SOF) or end of frame (EOF). Note: The setting defines the offset base while the offset itself is a part of an extended header. Note: Not all adapters support EOF timestamp inject mode in which case the driver will return an error. |
[adapter0]
TimestampInjectOffset = SOF
To select end of frame offset for adapter 0:
[adapter0]
TimestampInjectOffset = EOF
Is Timestamp Inject Offset Mode Supported?
This mode is not supported by all adapters. Support for Changing timestamp
inject offset mode can be tested as shown below.
inject offset mode can be tested as shown below.
// Open the information stream
NT_ExplainError(status, errBuf, sizeof(errBuf));
fprintf(stderr, ">>> Error: NT_InfoOpen failed. Code 0x%x = %s\n", status, errBuf);
return -1;
}
// Read adapter information for each adapter in the system
infoAdapter.cmd = NT_INFO_CMD_READ_ADAPTER_V1;
infoAdapter.u.adapter_v1.adapterNo = adapter;
if ((status = NT_InfoRead(hInfo, &infoAdapter)) != NT_SUCCESS) {
NT_ExplainError(status, errBuf, sizeof(errBuf));
fprintf(stderr, ">>> Error: NT_InfoRead failed. Code ox%x = %s\n", status, errBuf);
NT_InfoClose(hInfo);
return -1;
}
NT_InfoClose(hInfo);
printf("Changing time stamp inject offset mode is not supported\");
return -1;
}