diff --git a/openrtx/include/protocols/M17/M17Datatypes.h b/openrtx/include/protocols/M17/M17Datatypes.h index 683d5242..6faaeb05 100644 --- a/openrtx/include/protocols/M17/M17Datatypes.h +++ b/openrtx/include/protocols/M17/M17Datatypes.h @@ -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 LSF_SYNC_WORD = {0x55, 0xF7}; // LSF sync word +static constexpr std::array 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 */ diff --git a/openrtx/include/protocols/M17/M17Frame.h b/openrtx/include/protocols/M17/M17Frame.h index b26883a1..638ae7aa 100644 --- a/openrtx/include/protocols/M17/M17Frame.h +++ b/openrtx/include/protocols/M17/M17Frame.h @@ -89,30 +89,28 @@ 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: - dataFrame_t data; ///< Underlying frame data. + /** + * 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. }; #endif /* M17_FRAME_H */ diff --git a/openrtx/include/protocols/M17/M17LinkSetupFrame.h b/openrtx/include/protocols/M17/M17LinkSetupFrame.h index 76c12cdf..17209531 100644 --- a/openrtx/include/protocols/M17/M17LinkSetupFrame.h +++ b/openrtx/include/protocols/M17/M17LinkSetupFrame.h @@ -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,7 +147,20 @@ private: */ uint16_t crc16(const void *data, const size_t len); - lsf_t data; ///< Underlying frame data. + /** + * 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. }; #endif /* M17_LINKSETUPFRAME_H */ diff --git a/openrtx/src/protocols/M17/M17LinkSetupFrame.cpp b/openrtx/src/protocols/M17/M17LinkSetupFrame.cpp index 7230f60b..9b75d21a 100644 --- a/openrtx/src/protocols/M17/M17LinkSetupFrame.cpp +++ b/openrtx/src/protocols/M17/M17LinkSetupFrame.cpp @@ -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); diff --git a/openrtx/src/protocols/M17/M17Transmitter.cpp b/openrtx/src/protocols/M17/M17Transmitter.cpp index 62a6b9d9..cd051217 100644 --- a/openrtx/src/protocols/M17/M17Transmitter.cpp +++ b/openrtx/src/protocols/M17/M17Transmitter.cpp @@ -26,9 +26,6 @@ namespace M17 { -static constexpr std::array LSF_SYNC_WORD = {0x55, 0xF7}; -static constexpr std::array 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 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 punctured; @@ -105,7 +102,7 @@ void M17Transmitter::send(const payload_t& payload, const bool isLast) // Encode frame std::array 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 punctured;