diff options
Diffstat (limited to 'libtransport/src/protocols/rtc/rtc_packet.h')
-rw-r--r-- | libtransport/src/protocols/rtc/rtc_packet.h | 219 |
1 files changed, 191 insertions, 28 deletions
diff --git a/libtransport/src/protocols/rtc/rtc_packet.h b/libtransport/src/protocols/rtc/rtc_packet.h index 7dc2f82c3..ffbbd78fd 100644 --- a/libtransport/src/protocols/rtc/rtc_packet.h +++ b/libtransport/src/protocols/rtc/rtc_packet.h @@ -24,6 +24,27 @@ * +-----------------------------------------+ */ +/* aggregated packets + * +---------------------------------+ + * |c| #pkts | len1 | len2 | .... | + * +---------------------------------- + * + * +---------------------------------+ + * |c| #pkts | resv | len 1 | + * +---------------------------------- + * + * aggregated packets header. + * header position. just after the data packet header + * + * c: 1 bit: 0 8bit encoding, 1 16bit encoding + * #pkts: 7 bits: number of application packets contained + * 8bits encoding: + * lenX: 8 bits: len in bites of packet X + * 16bits econding: + * resv: 8 bits: reserved field (unused) + * lenX: 16bits: len in bytes of packet X + */ + #pragma once #ifndef _WIN32 #include <arpa/inet.h> @@ -31,30 +52,16 @@ #include <hicn/transport/portability/win_portability.h> #endif +#include <hicn/transport/portability/endianess.h> + +#include <cstring> + namespace transport { namespace protocol { namespace rtc { -inline uint64_t _ntohll(const uint64_t *input) { - uint64_t return_val; - uint8_t *tmp = (uint8_t *)&return_val; - - tmp[0] = (uint8_t)(*input >> 56); - tmp[1] = (uint8_t)(*input >> 48); - tmp[2] = (uint8_t)(*input >> 40); - tmp[3] = (uint8_t)(*input >> 32); - tmp[4] = (uint8_t)(*input >> 24); - tmp[5] = (uint8_t)(*input >> 16); - tmp[6] = (uint8_t)(*input >> 8); - tmp[7] = (uint8_t)(*input >> 0); - - return return_val; -} - -inline uint64_t _htonll(const uint64_t *input) { return (_ntohll(input)); } - const uint32_t DATA_HEADER_SIZE = 12; // bytes // XXX: sizeof(data_packet_t) is 16 // beacuse of padding @@ -64,11 +71,19 @@ struct data_packet_t { uint64_t timestamp; uint32_t prod_rate; - inline uint64_t getTimestamp() const { return _ntohll(×tamp); } - inline void setTimestamp(uint64_t time) { timestamp = _htonll(&time); } + inline uint64_t getTimestamp() const { + return portability::net_to_host(timestamp); + } + inline void setTimestamp(uint64_t time) { + timestamp = portability::host_to_net(time); + } - inline uint32_t getProductionRate() const { return ntohl(prod_rate); } - inline void setProductionRate(uint32_t rate) { prod_rate = htonl(rate); } + inline uint32_t getProductionRate() const { + return portability::net_to_host(prod_rate); + } + inline void setProductionRate(uint32_t rate) { + prod_rate = portability::host_to_net(rate); + } }; struct nack_packet_t { @@ -76,14 +91,162 @@ struct nack_packet_t { uint32_t prod_rate; uint32_t prod_seg; - inline uint64_t getTimestamp() const { return _ntohll(×tamp); } - inline void setTimestamp(uint64_t time) { timestamp = _htonll(&time); } + inline uint64_t getTimestamp() const { + return portability::net_to_host(timestamp); + } + inline void setTimestamp(uint64_t time) { + timestamp = portability::host_to_net(time); + } + + inline uint32_t getProductionRate() const { + return portability::net_to_host(prod_rate); + } + inline void setProductionRate(uint32_t rate) { + prod_rate = portability::host_to_net(rate); + } + + inline uint32_t getProductionSegment() const { + return portability::net_to_host(prod_seg); + } + inline void setProductionSegment(uint32_t seg) { + prod_seg = portability::host_to_net(seg); + } +}; + +class AggrPktHeader { + public: + // XXX buf always point to the payload after the data header + AggrPktHeader(uint8_t *buf, uint16_t max_packet_len, uint16_t pkt_number) + : buf_(buf), pkt_num_(pkt_number) { + *buf_ = 0; // reset the first byte to correctly add the header + // encoding and the packet number + if (max_packet_len > 0xff) { + setAggrPktEncoding16bit(); + } else { + setAggrPktEncoding8bit(); + } + setAggrPktNUmber(pkt_number); + header_len_ = computeHeaderLen(); + memset(buf_ + 1, 0, header_len_ - 1); + } + + // XXX buf always point to the payload after the data header + AggrPktHeader(uint8_t *buf) : buf_(buf) { + encoding_ = getAggrPktEncoding(); + pkt_num_ = getAggrPktNumber(); + header_len_ = computeHeaderLen(); + } + + ~AggrPktHeader(){}; + + int addPacketToHeader(uint8_t index, uint16_t len) { + if (index > pkt_num_) return -1; + + setAggrPktLen(index, len); + return 0; + } + + int getPointerToPacket(uint8_t index, uint8_t **pkt_ptr, uint16_t *pkt_len) { + if (index > pkt_num_) return -1; + + uint16_t len = 0; + for (int i = 0; i < index; i++) + len += getAggrPktLen(i); // sum the pkts len from 0 to index - 1 + + uint16_t offset = len + header_len_; + *pkt_ptr = buf_ + offset; + *pkt_len = getAggrPktLen(index); + return 0; + } + + int getPacketOffsets(uint8_t index, uint16_t *pkt_offset, uint16_t *pkt_len) { + if (index > pkt_num_) return -1; + + uint16_t len = 0; + for (int i = 0; i < index; i++) + len += getAggrPktLen(i); // sum the pkts len from 0 to index - 1 + + uint16_t offset = len + header_len_; + *pkt_offset = offset; + *pkt_len = getAggrPktLen(index); + + return 0; + } + + uint8_t *getPayloadAppendPtr() { return buf_ + header_len_; } + + uint16_t getHeaderLen() { return header_len_; } + + uint8_t getNumberOfPackets() { return pkt_num_; } + + private: + inline uint16_t computeHeaderLen() const { + uint16_t len = 4; // min len in bytes + if (!encoding_) { + while (pkt_num_ >= len) { + len += 4; + } + } else { + while (pkt_num_ * 2 >= len) { + len += 4; + } + } + return len; + } + + inline uint8_t getAggrPktEncoding() const { + // get the first bit of the first byte + return (*buf_ >> 7); + } + + inline void setAggrPktEncoding8bit() { + // reset the first bit of the first byte + encoding_ = 0; + *buf_ &= 0x7f; + } + + inline void setAggrPktEncoding16bit() { + // set the first bit of the first byte + encoding_ = 1; + *buf_ ^= 0x80; + } + + inline uint8_t getAggrPktNumber() const { + // return the first byte with the first bit = 0 + return (*buf_ & 0x7f); + } + + inline void setAggrPktNUmber(uint8_t val) { + // set the val without modifying the first bit + *buf_ &= 0x80; // reset everithing but the first bit + val &= 0x7f; // reset the first bit + *buf_ |= val; // or the vals, done! + } + + inline uint16_t getAggrPktLen(uint8_t pkt_index) const { + pkt_index++; + if (!encoding_) { // 8 bits + return (uint16_t) * (buf_ + pkt_index); + } else { // 16 bits + uint16_t *buf_16 = (uint16_t *)buf_; + return portability::net_to_host(*(buf_16 + pkt_index)); + } + } - inline uint32_t getProductionRate() const { return ntohl(prod_rate); } - inline void setProductionRate(uint32_t rate) { prod_rate = htonl(rate); } + inline void setAggrPktLen(uint8_t pkt_index, uint16_t len) { + pkt_index++; + if (!encoding_) { // 8 bits + *(buf_ + pkt_index) = (uint8_t)len; + } else { // 16 bits + uint16_t *buf_16 = (uint16_t *)buf_; + *(buf_16 + pkt_index) = portability::host_to_net(len); + } + } - inline uint32_t getProductionSegement() const { return ntohl(prod_seg); } - inline void setProductionSegement(uint32_t seg) { prod_seg = htonl(seg); } + uint8_t *buf_; + uint8_t encoding_; + uint8_t pkt_num_; + uint16_t header_len_; }; } // end namespace rtc |