21 #include <arpa/inet.h>
27 throw "Packet too short";
30 std::memcpy(&_lct_header,
data, 4);
31 if (_lct_header.version != 1) {
32 throw "Unsupported LCT version";
35 char* hdr_ptr =
data + 4;
36 if (_lct_header.congestion_control_flag != 0) {
37 throw "Unsupported CCI field length";
42 if (_lct_header.half_word_flag == 0 && _lct_header.tsi_flag == 0) {
43 throw "TSI field not present";
46 if(_lct_header.half_word_flag == 1) {
47 _tsi = ntohs(*(uint16_t*)hdr_ptr);
51 if(_lct_header.tsi_flag == 1) {
52 _tsi |= ntohl(*(uint32_t*)hdr_ptr) << tsi_shift;
56 if ( _lct_header.close_session_flag == 0 && _lct_header.half_word_flag == 0 && _lct_header.toi_flag == 0) {
57 throw "TOI field not present";
60 if(_lct_header.half_word_flag == 1) {
61 _toi = ntohs(*(uint16_t*)hdr_ptr);
65 switch(_lct_header.toi_flag) {
68 _toi |= ntohl(*(uint32_t*)hdr_ptr) << toi_shift;
73 throw "TOI fields over 64 bits in length are not supported";
75 _toi = ntohl(*(uint32_t*)hdr_ptr);
77 _toi |= (uint64_t)(ntohl(*(uint32_t*)hdr_ptr)) << 32;
82 throw "TOI fields over 64 bits in length are not supported";
86 if (_lct_header.codepoint == 0) {
89 throw "Only Compact No-Code FEC is supported";
92 auto expected_header_len = 2 +
93 _lct_header.congestion_control_flag +
94 _lct_header.half_word_flag +
95 _lct_header.tsi_flag +
98 auto ext_header_len = (_lct_header.lct_header_len - expected_header_len) * 4;
100 while (ext_header_len > 0) {
101 uint8_t het = *hdr_ptr;
109 switch ((AlcPacket::HeaderExtension)het) {
119 throw "Invalid length for EXT_FTI header extension";
121 _fec_oti.
transfer_length = (uint64_t)(ntohs(*(uint16_t*)hdr_ptr)) << 32;
134 uint8_t flute_version = (*hdr_ptr & 0xF0) >> 4;
135 if (flute_version > 2) {
136 throw "Unsupported FLUTE version";
138 _fdt_instance_id = (*hdr_ptr & 0x0F) << 16;
140 _fdt_instance_id |= ntohs(*(uint16_t*)hdr_ptr);
145 uint8_t encoding = *hdr_ptr;
158 ext_header_len -= hel * 4;
165 auto lct_header_len = 3;
170 auto max_packet_length = max_size +
174 _buffer = (
char*)calloc(max_packet_length,
sizeof(
char));
176 auto lct_header = (lct_header_t*)_buffer;
178 lct_header->version = 1;
179 lct_header->half_word_flag = 1;
180 lct_header->lct_header_len = lct_header_len;
181 auto hdr_ptr = _buffer + 4;
182 auto payload_ptr = _buffer + 4 * lct_header_len;
185 _len = 4 * lct_header_len + payload_size;
189 *((uint16_t*)hdr_ptr) = htons(
tsi);
192 *((uint16_t*)hdr_ptr) = htons(
toi);
196 *((uint8_t*)hdr_ptr) = EXT_FDT;
203 *((uint8_t*)hdr_ptr) = EXT_FTI;
205 *((uint8_t*)hdr_ptr) = 4;
207 *((uint16_t*)hdr_ptr) = htons((_fec_oti.
transfer_length & 0x00FF0000) >> 32);
235 if (_buffer) free(_buffer);
uint64_t tsi() const
Get the TSI.
char * data() const
Get a pointer to the payload data of the constructed packet.
uint32_t fdt_instance_id() const
Get the FDT instance ID.
~AlcPacket()
Default destructor.
uint64_t toi() const
Get the TOI.
AlcPacket(char *data, size_t len)
Create an ALC packet from payload data.
static size_t to_payload(const std::vector< EncodingSymbol > &, char *encoded_data, size_t data_len, const FecOti &fec_oti, ContentEncoding encoding)
Write encoding symbols to a packet payload buffer.
uint32_t max_source_block_length
uint32_t encoding_symbol_length