Reorganised M17LinkSetupframe and M17Frame classes, encapsulating structs defining their internal data structure

pull/68/head
Silvano Seva 2022-01-01 12:04:57 +01:00
rodzic 8f63d349a2
commit c73aa92305
5 zmienionych plików z 86 dodań i 71 usunięć

Wyświetl plik

@ -35,6 +35,10 @@ using payload_t = std::array< uint8_t, 16 >; // Data type for frame payload fi
using lich_t = std::array< uint8_t, 12 >; // Data type for Golay(24,12) encoded LICH data
static constexpr std::array<uint8_t, 2> LSF_SYNC_WORD = {0x55, 0xF7}; // LSF sync word
static constexpr std::array<uint8_t, 2> DATA_SYNC_WORD = {0xFF, 0x5D}; // Stream data sync word
/**
* This structure provides bit field definitions for the "TYPE" field
* contained in an M17 Link Setup Frame.
@ -49,35 +53,11 @@ typedef union
uint16_t encSubType : 2; //< Encryption subtype
uint16_t CAN : 4; //< Channel Access Number
uint16_t : 4; //< Reserved, padding to 16 bit
};
}
fields;
uint16_t value;
}
streamType_t;
/**
* Data structure corresponding to a full M17 Link Setup Frame.
*/
typedef struct
{
call_t dst; //< Destination callsign
call_t src; //< Source callsign
streamType_t type; //< Stream type information
meta_t meta; //< Metadata
uint16_t crc; //< CRC
}
__attribute__((packed)) lsf_t;
/**
* Data structure corresponding to a full M17 data frame.
*/
typedef struct
{
uint16_t frameNum; //< Frame number
payload_t payload; //< Payload data
}
__attribute__((packed)) dataFrame_t;
#endif /* M17_DATATYPES_H */

Wyświetl plik

@ -89,29 +89,27 @@ public:
}
/**
* Get underlying data structure.
* Get underlying data.
*
* @return a reference to the underlying dataFrame_t data structure.
* @return a pointer to const uint8_t allowing direct access to frame data.
*/
dataFrame_t& getData()
const uint8_t *getData()
{
return data;
}
/**
* Dump the frame content to a std::array.
*
* \return std::array containing the content of the frame.
*/
std::array< uint8_t, sizeof(dataFrame_t) > toArray()
{
std::array< uint8_t, sizeof(dataFrame_t) > frame;
memcpy(frame.data(), &data, frame.size());
return frame;
return reinterpret_cast < const uint8_t * > (&data);
}
private:
/**
* Data structure corresponding to a full M17 data frame.
*/
typedef struct
{
uint16_t frameNum; ///< Frame number
payload_t payload; ///< Payload data
}
__attribute__((packed)) dataFrame_t;
dataFrame_t data; ///< Underlying frame data.
};

Wyświetl plik

@ -61,6 +61,13 @@ public:
*/
void setSource(const std::string& callsign);
/**
* Get source callsign.
*
* @return: string containing the source callsign.
*/
std::string getSource();
/**
* Set destination callsign.
*
@ -68,6 +75,13 @@ public:
*/
void setDestination(const std::string& callsign);
/**
* Get destination callsign.
*
* @return: string containing the destination callsign.
*/
std::string getDestination();
/**
* Get stream type field.
*
@ -97,11 +111,20 @@ public:
void updateCrc();
/**
* Get underlying data structure.
* Check if frame data is valid that is, if the CRC computed over the LSF
* fields matches the one carried by the LSF itself.
*
* @return a reference to the underlying dataFrame_t data structure.
* @return true if CRC of LSF data matches the one stored in the LSF itself,
* false otherwise.
*/
lsf_t& getData();
bool valid();
/**
* Get underlying data.
*
* @return a pointer to const uint8_t allowing direct access to LSF data.
*/
const uint8_t *getData();
/**
* Generate one of the six possible LSF chunks for embedding in data frame's
@ -112,13 +135,6 @@ public:
*/
lich_t generateLichSegment(const uint8_t segmentNum);
/**
* Dump the frame content to a std::array.
*
* \return std::array containing the content of the frame.
*/
std::array< uint8_t, sizeof(lsf_t) > toArray();
private:
/**
@ -131,6 +147,19 @@ private:
*/
uint16_t crc16(const void *data, const size_t len);
/**
* Data structure corresponding to a full M17 Link Setup Frame.
*/
typedef struct
{
call_t dst; ///< Destination callsign
call_t src; ///< Source callsign
streamType_t type; ///< Stream type information
meta_t meta; ///< Metadata
uint16_t crc; ///< CRC
}
__attribute__((packed)) lsf_t;
lsf_t data; ///< Underlying frame data.
};

Wyświetl plik

@ -45,11 +45,21 @@ void M17LinkSetupFrame::setSource(const std::string& callsign)
encode_callsign(callsign, data.src);
}
std::string M17LinkSetupFrame::getSource()
{
return decode_callsign(data.src);
}
void M17LinkSetupFrame::setDestination(const std::string& callsign)
{
encode_callsign(callsign, data.dst);
}
std::string M17LinkSetupFrame::getDestination()
{
return decode_callsign(data.dst);
}
streamType_t M17LinkSetupFrame::getType()
{
// NOTE: M17 fields are big-endian, we need to swap bytes
@ -77,9 +87,17 @@ void M17LinkSetupFrame::updateCrc()
data.crc = __builtin_bswap16(crc);
}
lsf_t& M17LinkSetupFrame::getData()
bool M17LinkSetupFrame::valid()
{
return data;
uint16_t crc = crc16(&data, 28);
if(data.crc == __builtin_bswap16(crc)) return true;
return false;
}
const uint8_t * M17LinkSetupFrame::getData()
{
return reinterpret_cast < const uint8_t * >(&data);
}
lich_t M17LinkSetupFrame::generateLichSegment(const uint8_t segmentNum)
@ -119,13 +137,6 @@ lich_t M17LinkSetupFrame::generateLichSegment(const uint8_t segmentNum)
return result;
}
std::array< uint8_t, sizeof(lsf_t) > M17LinkSetupFrame::toArray()
{
std::array< uint8_t, sizeof(lsf_t) > frame;
memcpy(frame.data(), &data, frame.size());
return frame;
}
uint16_t M17LinkSetupFrame::crc16(const void *data, const size_t len)
{
const uint8_t *ptr = reinterpret_cast< const uint8_t *>(data);

Wyświetl plik

@ -26,9 +26,6 @@
namespace M17
{
static constexpr std::array<uint8_t, 2> LSF_SYNC_WORD = {0x55, 0xF7};
static constexpr std::array<uint8_t, 2> DATA_SYNC_WORD = {0xFF, 0x5D};
M17Transmitter::M17Transmitter(M17Modulator& modulator) : modulator(modulator),
currentLich(0), frameNumber(0)
{
@ -59,9 +56,9 @@ void M17Transmitter::start(const std::string& src, const std::string& dst)
if(!dst.empty()) lsf.setDestination(dst);
streamType_t type;
type.stream = 1; // Stream
type.dataType = 2; // Voice data
type.CAN = 0; // Channel access number
type.fields.stream = 1; // Stream
type.fields.dataType = 2; // Voice data
type.fields.CAN = 0; // Channel access number
lsf.setType(type);
lsf.updateCrc();
@ -75,7 +72,7 @@ void M17Transmitter::start(const std::string& src, const std::string& dst)
// Encode the LSF, then puncture and decorrelate its data
std::array<uint8_t, 61> encoded;
encoder.reset();
encoder.encode(&lsf.getData(), encoded.data(), sizeof(lsf_t));
encoder.encode(lsf.getData(), encoded.data(), sizeof(M17LinkSetupFrame));
encoded[60] = encoder.flush();
std::array<uint8_t, 46> punctured;
@ -105,7 +102,7 @@ void M17Transmitter::send(const payload_t& payload, const bool isLast)
// Encode frame
std::array<uint8_t, 37> encoded;
encoder.reset();
encoder.encode(&dataFrame.getData(), encoded.data(), sizeof(dataFrame_t));
encoder.encode(dataFrame.getData(), encoded.data(), sizeof(M17Frame));
encoded[36] = encoder.flush();
std::array<uint8_t, 34> punctured;