1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#ifndef EventFilter_Utilities_DTHHeaders_h
#define EventFilter_Utilities_DTHHeaders_h
#include <array>
#include <cstddef>
#include <cstdint>
/*
* DTH Orbit header, event fragment trailer and SlinkRocket Header and Trailer accompanying
* slink payload. Format that is sent is is low-endian for multi-byte fields
*
* Version 1 DTH and Version 3 SLinkRocket
*
* */
namespace evf {
constexpr uint32_t SLR_MAX_EVENT_LEN = (1 << 20) - 1;
constexpr std::array<uint8_t, 2> DTHOrbitMarker{{0x48, 0x4f}}; //HO
constexpr std::array<uint8_t, 2> DTHFragmentTrailerMarker{{0x54, 0x46}}; //TF
constexpr uint32_t DTH_WORD_NUM_BYTES_SHIFT = 4;
constexpr uint32_t SLR_WORD_NUM_BYTES_SHIFT = 4;
class DTHOrbitHeader_v1 {
public:
DTHOrbitHeader_v1(uint32_t source_id,
uint32_t run_number,
uint32_t orbit_number,
uint16_t event_count,
uint32_t packed_word_count,
uint32_t flags,
uint32_t crc)
: source_id_(source_id),
run_number_(run_number),
orbit_number_(orbit_number),
event_count_(event_count),
packed_word_count_(packed_word_count),
crc32c_(crc) {
flags_.all_ = flags;
}
uint16_t version() const { return version_; }
uint32_t sourceID() const { return source_id_; }
uint32_t runNumber() const { return run_number_; }
uint32_t orbitNumber() const { return orbit_number_; }
uint16_t eventCount() const { return event_count_; }
uint32_t packed_word_count() const { return packed_word_count_; }
uint32_t flags() const { return flags_.all_; }
uint32_t crc() const { return crc32c_; }
uint64_t totalSize() const { return uint64_t(packed_word_count_) << DTH_WORD_NUM_BYTES_SHIFT; }
uint64_t payloadSizeBytes() const { return totalSize() - sizeof(DTHOrbitHeader_v1); }
uint64_t headerSize() const { return sizeof(DTHOrbitHeader_v1); }
const void* payload() const { return (uint8_t*)this + sizeof(DTHOrbitHeader_v1); }
bool verifyMarker() const {
for (size_t i = 0; i < DTHOrbitMarker.size(); i++) {
if (marker_[i] != DTHOrbitMarker[i])
return false;
}
return true;
}
bool verifyChecksum() const;
private:
std::array<uint8_t, 2> marker_ = DTHOrbitMarker;
uint16_t version_ = 1; //bytes: 01 00
uint32_t source_id_;
uint32_t run_number_;
uint32_t orbit_number_;
uint32_t event_count_ : 12, res_ : 20;
uint32_t packed_word_count_; //Total size encoded in multiples of 128 bits (16 bytes)
union {
struct {
uint32_t error_flag_ : 1, res_flags_ : 31;
} bits_;
uint32_t all_;
} flags_;
uint32_t crc32c_;
};
class DTHFragmentTrailer_v1 {
public:
DTHFragmentTrailer_v1(uint16_t flags, uint32_t payload_word_count, uint64_t event_id, uint16_t crc)
: payload_word_count_(payload_word_count), event_id_(event_id), crc_(crc) {
flags_.all_ = flags;
}
uint64_t eventID() const { return event_id_; }
uint32_t payloadWordCount() const { return payload_word_count_; }
uint64_t payloadSizeBytes() const { return uint64_t(payload_word_count_) << DTH_WORD_NUM_BYTES_SHIFT; }
uint16_t flags() const { return flags_.all_; }
uint16_t crc() const { return crc_; }
const void* payload() const { return (uint8_t*)this - payloadSizeBytes(); }
bool verifyMarker() const {
for (size_t i = 0; i < DTHFragmentTrailerMarker.size(); i++) {
if (marker_[i] != DTHFragmentTrailerMarker[i])
return false;
}
return true;
}
private:
std::array<uint8_t, 2> marker_ = DTHFragmentTrailerMarker;
union {
struct {
uint16_t fed_crc_error_ : 1, slink_crc_error_ : 1, source_id_error_ : 1, fragment_cut_ : 1,
event_id_sync_error_ : 1, fragment_timout_ : 1, fragment_length_error_ : 1, res_ : 9;
} bits_;
uint16_t all_;
} flags_;
uint32_t
payload_word_count_; // Fragment size is encoded in multiples of 128 bits (16 bytes). I.e needs to be shifted by 4
uint64_t event_id_ : 44, res_ : 4, crc_ : 16;
};
} // namespace evf
#endif
|