Line data Source code
1 : #include <cstring>
2 : #include "l0id_decoder.hpp"
3 : #include "log.hpp"
4 :
5 :
6 25 : L0Decoder::L0Decoder(int format, uint64_t fid)
7 25 : : m_fid(fid)
8 : {
9 25 : m_last.xl1id = 0x00ffffff;
10 :
11 25 : switch (format)
12 : {
13 : case 0:
14 : break;
15 0 : case L0ID_FMT::TTC2H:
16 0 : LOG_INFO("L1ID sequentiality check enabled: TTC2H only");
17 0 : check_sequence_error = std::bind(&L0Decoder::check_sequence_ttc2h, this, std::placeholders::_1, std::placeholders::_2);
18 0 : m_required_bytes = 8;
19 0 : m_ec_mask = 0x00ffffff;
20 0 : break;
21 0 : case L0ID_FMT::LATOME:
22 0 : LOG_INFO("L1ID sequentiality check enabled: TTC2H, LATOME data");
23 0 : check_sequence_error = std::bind(&L0Decoder::check_sequence_latome, this, std::placeholders::_1, std::placeholders::_2);
24 0 : m_required_bytes = 48;
25 0 : m_ec_mask = 0x00ffffff;
26 0 : break;
27 0 : case L0ID_FMT::FMEMU:
28 0 : LOG_INFO("L1ID sequentiality check enabled: TTC2H, FMEMU data");
29 0 : check_sequence_error = std::bind(&L0Decoder::check_sequence_fmemu, this, std::placeholders::_1, std::placeholders::_2);
30 0 : m_required_bytes = 4;
31 0 : m_ec_mask = 0x00ffffff;
32 0 : break;
33 0 : case L0ID_FMT::FELIG:
34 0 : LOG_INFO("L1ID sequentiality check enabled: TTC2H, FELIG data");
35 0 : check_sequence_error = std::bind(&L0Decoder::check_sequence_felig, this, std::placeholders::_1, std::placeholders::_2);
36 0 : m_required_bytes = 4;
37 0 : m_ec_mask = 0x0000ffff;
38 0 : break;
39 0 : case L0ID_FMT::NSW_VMM:
40 0 : LOG_INFO("L1ID sequentiality check enabled: TTC2H, NSW VMM data");
41 0 : check_sequence_error = std::bind(&L0Decoder::check_sequence_nsw_vmm, this, std::placeholders::_1, std::placeholders::_2);
42 0 : m_required_bytes = 4;
43 0 : m_ec_mask = 0x0000ffff;
44 0 : break;
45 0 : case L0ID_FMT::NSW_TP:
46 0 : LOG_INFO("L1ID sequentiality check enabled: TTC2H, NSW TP data");
47 0 : check_sequence_error = std::bind(&L0Decoder::check_sequence_nsw_tp, this, std::placeholders::_1, std::placeholders::_2);
48 0 : m_required_bytes = 8;
49 0 : m_ec_mask = 0x00ffffff;
50 0 : break;
51 25 : default:
52 25 : LOG_INFO("Invalid choice for L1ID sequentiality check. Check disabled");
53 : }
54 25 : }
55 :
56 :
57 0 : bool L0Decoder::check_tohost_chunk(std::vector<iovec> const &data)
58 : {
59 0 : uint8_t* chunk = new uint8_t[m_required_bytes];
60 0 : unsigned int copied = 0;
61 0 : if (data.size() >= 1) {
62 0 : for (unsigned int idx = 1; idx < data.size(); ++idx) {
63 0 : unsigned int max = data[idx].iov_len > m_required_bytes ? m_required_bytes : data[idx].iov_len;
64 0 : memcpy(chunk + copied, data[idx].iov_base, max);
65 0 : copied += max;
66 0 : if (copied >= m_required_bytes){
67 : break;
68 : }
69 : }
70 : }
71 0 : bool ret = check_sequence_error(chunk, copied);
72 0 : delete[] chunk;
73 0 : return ret;
74 : }
75 :
76 :
77 0 : bool inline L0Decoder::compare(xl1id_t current, xl1id_t expected)
78 : {
79 0 : if(current.fields.ec != expected.fields.ec){
80 0 : LOG_INFO("fid 0x%lx (0x%x) has L1ID 0x%06x, expected 0x%06x", m_fid, get_elink(m_fid), current.fields.ec, expected.fields.ec);
81 0 : return true;
82 : }
83 : return false;
84 : }
85 :
86 :
87 0 : bool L0Decoder::check_sequence_ttc2h(const uint8_t* data, size_t len)
88 : {
89 0 : if (len < m_required_bytes)
90 : {
91 0 : LOG_INFO("TTC2H message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.", m_fid, get_elink(m_fid), len);
92 0 : return true;
93 : }
94 0 : xl1id_t current, expected;
95 0 : current.xl1id = reinterpret_cast<const uint32_t *>(data)[1];
96 :
97 0 : bcid_t current_bc;
98 0 : current_bc.bc_data = reinterpret_cast<const uint32_t *>(data)[0];
99 :
100 0 : LOG_DBG("Current L1ID 0x%06x BCID 0x%04x", current.fields.ec, current_bc.fields.bcid);
101 0 : if (current.fields.ecrc == (m_last.fields.ecrc + 1))
102 : {
103 0 : LOG_INFO("ECR on TTC2H fid 0x%lx (0x%x)", m_fid, get_elink(m_fid));
104 0 : expected.fields.ec = 0x0;
105 : }
106 : else
107 : {
108 0 : expected.fields.ec = (m_last.fields.ec + 1) & 0x00ffffff;
109 : }
110 0 : m_last.xl1id = current.xl1id;
111 0 : return compare(current, expected);
112 : }
113 :
114 :
115 0 : bool L0Decoder::check_sequence_latome(const uint8_t* data, size_t len)
116 : {
117 0 : if (len < m_required_bytes)
118 : {
119 0 : LOG_INFO("LATOME message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.", m_fid, get_elink(m_fid), len);
120 0 : return true;
121 : }
122 0 : xl1id_t current, expected;
123 0 : current.xl1id = reinterpret_cast<const uint32_t *>(data)[5];
124 :
125 0 : if (current.fields.ecrc == (m_last.fields.ecrc + 1))
126 : {
127 0 : LOG_DBG("ECR on fid 0x%lx (0x%x)", m_fid, get_elink(m_fid));
128 0 : expected.fields.ec = 0x0;
129 : }
130 : else
131 : {
132 0 : expected.fields.ec = (m_last.fields.ec + 1) & 0x00ffffff;
133 : }
134 0 : m_last.xl1id = current.xl1id;
135 0 : return compare(current, expected);
136 : }
137 :
138 :
139 0 : bool L0Decoder::check_sequence_fmemu(const uint8_t* data, size_t len)
140 : {
141 0 : if (len < m_required_bytes)
142 : {
143 0 : LOG_INFO("FMEMU message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.", m_fid, get_elink(m_fid), len);
144 0 : return true;
145 : }
146 0 : xl1id_t current, expected;
147 0 : current.xl1id = reinterpret_cast<const uint32_t *>(data)[0];
148 0 : if (current.fields.ecrc == (m_last.fields.ecrc + 1))
149 : {
150 0 : LOG_DBG("ECR on fid 0x%lx (0x%x)", m_fid, get_elink(m_fid));
151 0 : expected.fields.ec = 0x0;
152 : }
153 : else
154 : {
155 0 : expected.fields.ec = (m_last.fields.ec + 1) & 0x00ffffff;
156 : }
157 0 : m_last.xl1id = current.xl1id;
158 0 : return compare(current, expected);
159 : }
160 :
161 :
162 0 : bool L0Decoder::check_sequence_felig(const uint8_t* data, size_t len)
163 : {
164 0 : if (len < m_required_bytes)
165 : {
166 0 : LOG_INFO("FELIG message from fid 0x%lx (0x%x) smaller than FELIG header, size %lu.", m_fid, get_elink(m_fid), len);
167 0 : return true;
168 : }
169 0 : xl1id_t current, expected;
170 0 : uint8_t* chunk_data = const_cast<uint8_t*>(data);
171 0 : current.fields.ec = ( chunk_data[4] | (chunk_data[3] << 8) );
172 0 : expected.fields.ec = (m_last.fields.ec + 1) & 0x0000ffff;
173 0 : m_last.xl1id = current.xl1id;
174 0 : return compare(current, expected);
175 : }
176 :
177 :
178 0 : bool L0Decoder::check_sequence_nsw_vmm(const uint8_t* data, size_t len)
179 : {
180 0 : if (len < 2){
181 0 : LOG_INFO("NSW VMM message from fid 0x%lx (0x%x) too small to retrieve header, size %lu.",
182 : m_fid, get_elink(m_fid), len);
183 0 : return true;
184 : }
185 0 : if (len > 4*(512+4)) {
186 0 : LOG_INFO("NSW VMM message from fid 0x%lx (0x%x) too long, size %lu.", m_fid, get_elink(m_fid), len);
187 : }
188 0 : xl1id_t current, expected;
189 : //enum packetType { FULL_MM=0, NULL_EVENT=1, FULL_STGC=2 , ILLEGAL=3};
190 0 : unsigned char headerType = data[0] >> 6;
191 0 : switch (headerType)
192 : {
193 0 : case 0: // MM full header
194 0 : case 2: // sTGC full header
195 0 : current.fields.ec = (data[3] | (data[2] << 8)) & 0xff;
196 0 : expected.fields.ec = (m_last.fields.ec + 1) & 0xff;
197 0 : m_last.fields.ec = (data[3] | (data[2] << 8)) & 0xffff;
198 0 : m_ec_mask = 0xffff;
199 0 : break;
200 0 : case 1: // null header
201 0 : current.fields.ec = data[1];
202 0 : expected.fields.ec = (m_last.fields.ec + 1) & 0xff;
203 0 : m_last.fields.ec = data[1];
204 0 : m_ec_mask = 0xff;
205 0 : break;
206 0 : case 3: // illegal header type
207 0 : {
208 0 : unsigned int vmmHeader = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
209 0 : LOG_INFO("Illegal VMM message from fid 0x%lx (0x%x), headerType = 3, headerword = 0x%x, size %d.", m_fid, get_elink(m_fid), vmmHeader, len);
210 : break;
211 : }
212 0 : default:
213 0 : LOG_INFO("Invalid header from fid 0x%lx (0x%x), type 0x%x", m_fid, get_elink(m_fid), headerType);
214 : }
215 :
216 0 : return compare(current, expected);
217 : }
218 :
219 :
220 0 : bool L0Decoder::check_sequence_nsw_tp(const uint8_t* data, size_t len)
221 : {
222 0 : if (len < m_required_bytes)
223 : {
224 0 : LOG_INFO("NSW TP message from fid 0x%lx (0x%x) too small to retrieve XL1ID, size %lu.", m_fid, get_elink(m_fid), len);
225 0 : return true;
226 : }
227 0 : xl1id_t current, expected;
228 0 : current.fields.ec = ( data[5]<<16 | data[6]<<8 | data[7] ) & 0x00ffffff;
229 0 : current.fields.ecrc = (data[4]<<24) & 0xff;
230 0 : if(current.fields.ecrc == (m_last.fields.ecrc+1) ){
231 : LOG_DBG("ECR on fid 0x%lx (0x%x)", m_fid, get_elink(m_fid));
232 : expected.fields.ec = 0x0;
233 : } else{
234 0 : expected.fields.ec = (m_last.fields.ec+1) & 0x00ffffff;
235 : }
236 0 : m_last.xl1id = current.xl1id;
237 0 : return compare(current, expected);
238 : }
|