DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
dpdklibs
scripts
dpdklibs_udp_receiver.py
Go to the documentation of this file.
1
#!/usr/bin/env python
2
import
socket
3
import
sys
4
import
binascii
5
import
detdataformats
6
import
fddetdataformats
7
import
time
8
import
click
9
import
ipaddress
10
11
N_STREAM = 128
12
FRAME_SIZE = 7200
13
FRAME_TS_GAP_BDE = 2048
14
FRAME_TS_GAP_TDE = 2000
15
16
def
print_header
(header,prefix="\t"):
17
print(f
'{prefix}Version: 0x{header.version:x}'
)
18
print(f
'{prefix}Detector ID: 0x{header.det_id:x}'
)
19
print(f
'{prefix}(Crate,Slot,Stream): (0x{header.crate_id:x},0x{header.slot_id:x},0x{header.stream_id:x})'
)
20
print(f
'{prefix}Timestamp: 0x{header.timestamp:x}'
)
21
print(f
'{prefix}Seq ID: {header.seq_id}'
)
22
print(f
'{prefix}Block length: 0x{header.block_length:x}'
)
23
24
def
dump_data
(data):
25
data2=data
26
27
n_word = (len(data) // 8) +len(data) % 8
28
for
i
in
range(n_word):
29
w = int.from_bytes(data[i*8:(i+1)*8], byteorder=
'little'
, signed=
False
)
30
print(f
"{i:04d} 0x{w:016x}"
)
31
32
33
def
validate_ip
(ctx, param, value):
34
if
value
is
None
:
35
return
''
36
try
:
37
return
str(ipaddress.ip_address(value))
38
except
ValueError:
39
raise
click.BadParameter(f
"{value} is not a valid IP address."
)
40
41
42
@click.command()
43
@click.option('-d', '--dump-packet', is_flag=True, default=False)
44
@click.option('-u', '--unpack-frames', is_flag=True, default=False)
45
@click.option('-w', '--words', type=int, default=8)
46
@click.option('-c', '--count', type=int, default=None)
47
@click.option
(
48
"--ip"
,
49
default=
None
,
50
help=
"IP address of the network interface host"
,
51
callback=validate_ip,
52
)
53
@click.option('-p', '--port', type=int, default=0x4444)
54
@click.option('-g', '--gap', type=int, default=None)
55
@click.option('-f', '--frame-type', type=click.Choice(['wib', 'tde','daphne'])
, default=
None
)
56
def
main
(dump_packet, unpack_frames, words, count, ip, port, gap, frame_type):
57
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
58
59
s.bind((ip, port))
60
61
prev_stream = {}
62
i=0
63
dtstart = time.time()
64
dtlast = dtstart
65
sampling = 100000
66
match frame_type:
67
case
'wib'
:
68
frame_class = fddetdataformats.WIBEthFrame
69
port = port
if
not
port
is
None
else
0x4444
70
gap = gap
if
not
gap
is
None
else
FRAME_TS_GAP_BDE
71
FRAME_SIZE = 7200
72
case
'tde'
:
73
frame_class = fddetdataformats.TDEEthFrame
74
port = port
if
not
port
is
None
else
54323
75
gap = gap
if
not
gap
is
None
else
FRAME_TS_GAP_TDE
76
FRAME_SIZE = 7200
77
case
'daphne'
:
78
frame_class = fddetdataformats.DAPHNEEthFrame
79
port = port
if
not
port
is
None
else
0x4444
80
# gap = gap if not gap is None else 2048
81
FRAME_SIZE = 7456
82
83
84
85
print(
'Receiver started'
)
86
dtnow = time.time()
87
88
while
(count==
None
or
i<count):
89
# print(count, i)
90
data, address = s.recvfrom(20000)
91
92
93
header = detdataformats.DAQEthHeader(data)
94
95
# hdr_id = header.stream_id
96
hdr_id = (header.det_id, header.crate_id, header.slot_id, header.stream_id)
97
98
# if hdr_id < N_STREAM:
99
stream_ts = header.timestamp
100
# print(hdr_id, header.seq_id, hex(stream_ts))
101
if
dump_packet:
102
103
print(
'----'
)
104
print(f
'Frame (size {len(data)}) from (DetID, Crate, Slot, Stream) = (0x{header.det_id}, 0x{header.crate_id:x}, 0x{header.slot_id:x}, 0x{header.stream_id:x})'
)
105
print(f
' Timestamp: 0x{header.timestamp:x}'
)
106
print(f
' Seq ID: {header.seq_id}, Block length: {header.block_length*8:d} (0x{header.block_length:x})'
)
107
108
print()
109
dump_data
(data[0:words*8])
110
print()
111
112
if
hdr_id
not
in
prev_stream:
113
pass
114
else
:
115
prev_strm_ts = prev_stream[hdr_id]
116
if
(
not
gap
is
None
)
and
(stream_ts - prev_strm_ts) != gap:
117
print(f
'delta_ts {stream_ts-prev_strm_ts} for {hdr_id} '
)
118
119
120
121
122
123
if
unpack_frames:
124
print(
'----'
)
125
print(f
'Packet {i}'
)
126
127
max_unpack = 512
128
print()
129
l = 0
130
l_pkt = len(data)
131
frames = []
132
while
l < l_pkt:
133
134
d_blk = data[l:]
135
# dump_data(d_blk[0:4*8])
136
h = detdataformats.DAQEthHeader(d_blk)
137
print(f
"len(data) = {l_pkt} block_len = {h.block_length*8:d} 0x{h.block_length:x} [l = {l}]"
)
138
l_frm = (h.block_length+1)*8
139
frames += [d_blk[:l_frm]]
140
141
l += l_frm
# +1 for the header
142
143
print(f
"Scanning complete (scanned {l} over {l_pkt} bytes)"
)
144
145
146
for
j,f
in
enumerate(frames):
147
print(f
"Frame {j}"
)
148
dump_data
(f[:max_unpack*8])
149
150
prev_stream[hdr_id] = stream_ts
151
152
153
i+=1;
154
if
i%sampling ==0:
155
dtlast=dtnow
156
dtnow = time.time()
157
avg_throughput = FRAME_SIZE*i/(1000000*(dtnow-dtstart))
158
throughput = FRAME_SIZE*sampling/(1000000*(dtnow-dtlast))
159
160
print(f
'Received {i} packets ({sampling/(dtnow-dtlast):.2f} pps over {dtnow-dtlast:.2f}); throughput = {throughput:.3f} MB/s [avg = {avg_throughput:.3f} MB/s]'
)
161
dtlast = dtnow
162
print_header
(header)
163
for
k,ts
in
prev_stream.items():
164
if
ts
is
None
:
165
continue
166
print(f
"stream {k}: last_ts {ts}"
)
167
168
# b = data
169
# for i in rnage(len(b)//8):
170
# w = [f"{s:02x}" for s in b[8*i:8*(i+1)]]
171
# w.reverse()
172
# print("0x"+''.join(w))
173
174
if
__name__ ==
'__main__'
:
175
main
()
176
dpdklibs_udp_receiver.validate_ip
validate_ip(ctx, param, value)
Definition
dpdklibs_udp_receiver.py:33
dpdklibs_udp_receiver.main
main(dump_packet, unpack_frames, words, count, ip, port, gap, frame_type)
Definition
dpdklibs_udp_receiver.py:56
dpdklibs_udp_receiver.print_header
print_header(header, prefix="\t")
Definition
dpdklibs_udp_receiver.py:16
dpdklibs_udp_receiver.dump_data
dump_data(data)
Definition
dpdklibs_udp_receiver.py:24
Generated on
for DUNE-DAQ by
1.17.0