30 #ifndef _SIM_UDP_DATAGRAM_
31 #define _SIM_UDP_DATAGRAM_
51 std::deque<AxisUdp> dgmQ;
55 void setLen(
int dgmLen) {
69 return this->dgmQ.front();
73 this->dgmQ.pop_front();
76 void push_back(
AxisUdp udpChunk) {
77 this->dgmQ.push_back(udpChunk);
84 this->myName =
"SimUdpDatagram";
86 if (dgmLen > 0 && dgmLen <=
MTU) {
96 this->myName =
"SimUdpDatagram";
102 if (this->
size() > 0) {
104 this->dgmQ[this->
size()-1].setLE_TLast(0);
106 this->push_back(udpChunk);
107 this->setLen(this->getLen() + udpChunk.
getLen());
112 AxisUdp headingChunk = this->front();
114 setLen(getLen() - headingChunk.
getLen());
125 return this->dgmQ.size();
134 for (
int i=0; i<udpDgm.dgmQ.size(); i++) {
135 newAxisUdp = udpDgm.dgmQ[i];
136 this->dgmQ.push_back(newAxisUdp);
138 this->setLen(udpDgm.getLen());
148 while(cloneBytes > 0) {
149 if (cloneBytes > 8) {
150 this->
pushChunk(udpDgm.dgmQ[inpChunkCnt]);
153 AxisUdp lastHdrChunk(udpDgm.dgmQ[inpChunkCnt].getLE_TData(),
168 AxisUdp headerChunk = this->front();
170 setLen(getLen() - headerChunk.
getLen());
172 return headerAsDatagram;
191 printFatal(this->myName,
"Empty datagram is expected to be of length %d bytes (was found to be %d bytes).\n",
194 int hdrLen = this->getLen();
195 int pldLen = pldStr.size();
196 int q = (hdrLen / 8);
197 int b = (hdrLen % 8);
202 unsigned long leQword = 0x0000000000000000;
203 unsigned char leKeep = 0x00;
206 unsigned char datByte = pldStr[i];
207 leQword = leQword | (datByte << b*8);
208 leKeep = leKeep | (1 << b);
241 ap_uint<32> csum = 0;
248 for (
int i=0; i<this->
size(); ++i) {
250 if (dgmQ[i].getLE_TKeep() & 0x01)
251 tempInput.range( 7, 0) = (dgmQ[i].getLE_TData()).range( 7, 0);
252 if (dgmQ[i].getLE_TKeep() & 0x02)
253 tempInput.range(15, 8) = (dgmQ[i].getLE_TData()).range(15, 8);
254 if (dgmQ[i].getLE_TKeep() & 0x04)
255 tempInput.range(23,16) = (dgmQ[i].getLE_TData()).range(23,16);
256 if (dgmQ[i].getLE_TKeep() & 0x08)
257 tempInput.range(31,24) = (dgmQ[i].getLE_TData()).range(31,24);
258 if (dgmQ[i].getLE_TKeep() & 0x10)
259 tempInput.range(39,32) = (dgmQ[i].getLE_TData()).range(39,32);
260 if (dgmQ[i].getLE_TKeep() & 0x20)
261 tempInput.range(47,40) = (dgmQ[i].getLE_TData()).range(47,40);
262 if (dgmQ[i].getLE_TKeep() & 0x40)
263 tempInput.range(55,48) = (dgmQ[i].getLE_TData()).range(55,48);
264 if (dgmQ[i].getLE_TKeep() & 0x80)
265 tempInput.range(63,56) = (dgmQ[i].getLE_TData()).range(63,56);
267 tempInput.range(63, 48)) + tempInput.range(47, 32)) +
268 tempInput.range(31, 16)) + tempInput.range(15, 0));
271 csum = (csum & 0xFFFF) + (csum >> 16);
274 UdpCsum udpCsum = csum.range(15, 0);
309 printWarn(callerName,
"Malformed UDP datagram: 'Length' field does not match the length of the datagram.\n");
310 printWarn(callerName,
"\tFound 'Length' field=0x%4.4X, Was expecting 0x%4.4X)\n",
317 if ((udpHCsum != 0) and (udpHCsum != calcCsum)) {
319 printWarn(callerName,
"Malformed UDP datagram: 'Checksum' field does not match the checksum of the pseudo-packet.\n");
320 printWarn(callerName,
"\tFound 'Checksum' field=0x%4.4X, Was expecting 0x%4.4X)\n",
321 udpHCsum.to_uint(), calcCsum.to_ushort());
334 if (!outFileStream.is_open()) {
349 for (
int i=0; i < this->
size(); i++) {
350 AxisUdp axisUdp = this->dgmQ[i];
364 for (
int i=1; i < this->
size(); i++) {
365 AxisUdp axisChunk = this->dgmQ[i];
: A class to access UDP header fields within data chunks transmitted over an AXI4-Stream interface.
: Utilities for the simulation of the Network-Transport-Stack (NTS) components.
LE_tKeep getLE_TKeep(int leHi=64/8-1, int leLo=0) const
LE_tData getLE_TData(int leHi=64 -1, int leLo=0) const
LE_tLast getLE_TLast() const
SimUdpDatagram(int dgmLen)
void setUdpChecksum(UdpCsum csum)
void pushChunk(AxisUdp udpChunk)
int getUdpDestinationPort()
SimUdpDatagram pullHeader()
Pull the header of this datagram.
void clone(SimUdpDatagram &udpDgm)
Clone a UDP datagram.
UdpCsum calculateUdpChecksum(Ip4Addr ipSa, Ip4Addr ipDa)
Calculate the UDP checksum of the datagram.
void setUdpLength(UdpLen len)
bool writeAxisUdpToFile(AxisUdp *axisUdp, ofstream &outFileStream)
Dump an AxisUdp chunk to a file.
bool isWellFormed(const char *callerName, Ip4Addr ipSa, Ip4Addr ipDa)
Checks if the datagram header fields are properly set.
void cloneHeader(SimUdpDatagram &udpDgm)
Clone the header of a UDP datagram.
bool writeToDatFile(ofstream &outFileStream)
Dump this UDP datagram as raw AxisUdp chunks into a file.
void addUdpPayload(string pldStr)
UdpCsum reCalculateUdpChecksum(Ip4Addr ipSa, Ip4Addr ipDa)
Recalculate the UDP checksum of a datagram.
void setUdpDestinationPort(int port)
void setUdpSourcePort(int port)
bool writePayloadToDatFile(ofstream &outFileStream)
Dump the payload of this datagram as AxisUdp chunks into a file.
bool writeAxisRawToFile(AxisRaw &axisRaw, ofstream &outFileStream)
Dump an Axis raw data chunk to a file.
#define printError(callerName, format,...)
A macro to print an error message.
LE_tKeep lenToLE_tKeep(ap_uint< 4 > noValidBytes)
A function to set a number of '1' in an 8-bit field. It is used here to set the number of valid bytes...
#define printWarn(callerName, format,...)
A macro to print a warning message.
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
: Utilities and helpers for the Network-Transport-Stack (NTS) components.
ap_uint< 16 > byteSwap16(ap_uint< 16 > inputVector)