kopia lustrzana https://github.com/OpenRTX/OpenRTX
M17: add Callsign class
Added class representing M17 callsign objects. Objects can be constructed both from strings and base-40 encoded values and allow conversion to any of the other representation. The class implements the comparison operator to allow easy check for callsign match.pull/335/merge
rodzic
76ffe2d612
commit
fdbe3f2583
|
|
@ -106,6 +106,7 @@ ObjCBinPackProtocolList: Auto
|
|||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PackConstructorInitializers: NextLine
|
||||
|
||||
# Taken from git's rules
|
||||
PenaltyBreakAssignment: 30
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ target_sources(app
|
|||
openrtx/src/protocols/M17/M17DSP.cpp
|
||||
openrtx/src/protocols/M17/M17Golay.cpp
|
||||
openrtx/src/protocols/M17/M17Callsign.cpp
|
||||
openrtx/src/protocols/M17/Callsign.cpp
|
||||
openrtx/src/protocols/M17/M17Modulator.cpp
|
||||
openrtx/src/protocols/M17/M17Demodulator.cpp
|
||||
openrtx/src/protocols/M17/M17FrameEncoder.cpp
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ openrtx_src = ['openrtx/src/core/state.c',
|
|||
'openrtx/src/protocols/M17/M17DSP.cpp',
|
||||
'openrtx/src/protocols/M17/M17Golay.cpp',
|
||||
'openrtx/src/protocols/M17/M17Callsign.cpp',
|
||||
'openrtx/src/protocols/M17/Callsign.cpp',
|
||||
'openrtx/src/protocols/M17/M17Modulator.cpp',
|
||||
'openrtx/src/protocols/M17/M17Demodulator.cpp',
|
||||
'openrtx/src/protocols/M17/M17FrameEncoder.cpp',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2025 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef CALLSIGN_H
|
||||
#define CALLSIGN_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This header is C++ only!
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include "M17Datatypes.hpp"
|
||||
|
||||
namespace M17
|
||||
{
|
||||
|
||||
/**
|
||||
* Class representing an M17 callsign object.
|
||||
*/
|
||||
class Callsign
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
* By default, an uninitialized callsign is set to invalid.
|
||||
*/
|
||||
Callsign();
|
||||
|
||||
/**
|
||||
* Construct a callsign object from an std::string
|
||||
* The callsign can have up to 9 characters
|
||||
*
|
||||
* @param callsign: callsign string
|
||||
*/
|
||||
Callsign(const std::string callsign);
|
||||
|
||||
/**
|
||||
* Construct a callsign object from a NULL-terminated string
|
||||
* The callsign can have up to 9 characters
|
||||
*
|
||||
* @param callsign: callsign string
|
||||
*/
|
||||
Callsign(const char *callsign);
|
||||
|
||||
/**
|
||||
* Construct a callsign object from a base-40 encoded callsign
|
||||
*
|
||||
* @param encodedCall: encoded callsign value
|
||||
*/
|
||||
Callsign(const call_t &encodedCall);
|
||||
|
||||
/**
|
||||
* Test if callsign is empty.
|
||||
* A callsign is considered empty when its first character is NULL.
|
||||
*
|
||||
* @return true if the callsign is empty
|
||||
*/
|
||||
inline bool isEmpty() const
|
||||
{
|
||||
return call[0] == '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if callsign is a special one.
|
||||
*
|
||||
* @return true if the callsign is either ALL, INFO or ECHO
|
||||
*/
|
||||
bool isSpecial() const;
|
||||
|
||||
/**
|
||||
* Type-conversion operator to retrieve the callsign in encoded format
|
||||
*
|
||||
* @return the base-40 encoded version of the callsign
|
||||
*/
|
||||
operator call_t() const;
|
||||
|
||||
/**
|
||||
* Type-conversion operator to retrieve the callsign as a std::string
|
||||
*
|
||||
* @return a std::string containing the callsign
|
||||
*/
|
||||
operator std::string() const;
|
||||
|
||||
/**
|
||||
* Type-conversion operator to retrieve the callsign as a NULL-terminated
|
||||
* string
|
||||
*
|
||||
* @return the callsign as a NULL-terminated string
|
||||
*/
|
||||
operator const char *() const;
|
||||
|
||||
/**
|
||||
* Comparison operator.
|
||||
*
|
||||
* @param other the incoming callsign to compare against
|
||||
* @return true if callsigns are equivalent
|
||||
*/
|
||||
bool operator==(const Callsign &other) const;
|
||||
|
||||
private:
|
||||
static constexpr size_t MAX_CALLSIGN_CHARS = 9;
|
||||
static constexpr size_t MAX_CALLSIGN_LEN = MAX_CALLSIGN_CHARS + 1;
|
||||
char call[MAX_CALLSIGN_LEN];
|
||||
};
|
||||
|
||||
} // namespace M17
|
||||
|
||||
#endif // CALLSIGN_H
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2025 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
#include "protocols/M17/Callsign.hpp"
|
||||
|
||||
using namespace M17;
|
||||
|
||||
static const char BROADCAST_CALL[] = "ALL";
|
||||
static const char INVALID_CALL[] = "INVALID";
|
||||
static const char charMap[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/.";
|
||||
|
||||
Callsign::Callsign() : Callsign(INVALID_CALL)
|
||||
{
|
||||
}
|
||||
|
||||
Callsign::Callsign(const std::string callsign) : Callsign(callsign.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
Callsign::Callsign(const char *callsign)
|
||||
{
|
||||
std::memset(call, 0, sizeof(call));
|
||||
std::strncpy(call, callsign, MAX_CALLSIGN_CHARS);
|
||||
}
|
||||
|
||||
Callsign::Callsign(const call_t &encodedCall)
|
||||
{
|
||||
bool isBroadcast = true;
|
||||
bool isInvalid = true;
|
||||
|
||||
for (auto &elem : encodedCall) {
|
||||
if (elem != 0xFF)
|
||||
isBroadcast = false;
|
||||
|
||||
if (elem != 0x00)
|
||||
isInvalid = false;
|
||||
}
|
||||
|
||||
std::memset(call, 0, sizeof(call));
|
||||
|
||||
if (isBroadcast) {
|
||||
std::strncpy(call, BROADCAST_CALL, sizeof(call));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInvalid) {
|
||||
std::strncpy(call, INVALID_CALL, sizeof(call));
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert to little endian format
|
||||
uint64_t encoded = 0;
|
||||
auto p = reinterpret_cast<uint8_t *>(&encoded);
|
||||
std::copy(encodedCall.rbegin(), encodedCall.rend(), p);
|
||||
|
||||
size_t pos = 0;
|
||||
while (encoded != 0 && pos < MAX_CALLSIGN_CHARS) {
|
||||
call[pos++] = charMap[encoded % 40];
|
||||
encoded /= 40;
|
||||
}
|
||||
}
|
||||
|
||||
bool Callsign::isSpecial() const
|
||||
{
|
||||
if ((std::strcmp(call, "INFO") == 0) || (std::strcmp(call, "ECHO") == 0)
|
||||
|| (std::strcmp(call, "ALL") == 0))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Callsign::operator std::string() const
|
||||
{
|
||||
return std::string(call);
|
||||
}
|
||||
|
||||
Callsign::operator const char *() const
|
||||
{
|
||||
return call;
|
||||
}
|
||||
|
||||
Callsign::operator call_t() const
|
||||
{
|
||||
call_t encoded;
|
||||
uint64_t tmp = 0;
|
||||
|
||||
if (strcmp(call, BROADCAST_CALL) == 0) {
|
||||
encoded.fill(0xFF);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
if (strcmp(call, INVALID_CALL) == 0) {
|
||||
encoded.fill(0x00);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
for (int i = strlen(call) - 1; i >= 0; i--) {
|
||||
tmp *= 40;
|
||||
|
||||
if (call[i] >= 'A' && call[i] <= 'Z') {
|
||||
tmp += (call[i] - 'A') + 1;
|
||||
} else if (call[i] >= '0' && call[i] <= '9') {
|
||||
tmp += (call[i] - '0') + 27;
|
||||
} else if (call[i] == '-') {
|
||||
tmp += 37;
|
||||
} else if (call[i] == '/') {
|
||||
tmp += 38;
|
||||
} else if (call[i] == '.') {
|
||||
tmp += 39;
|
||||
}
|
||||
}
|
||||
|
||||
// Return encoded callsign in big endian format
|
||||
auto *ptr = reinterpret_cast<uint8_t *>(&tmp);
|
||||
std::copy(ptr, ptr + 6, encoded.rbegin());
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
bool Callsign::operator==(const Callsign &other) const
|
||||
{
|
||||
// find slash and possibly truncate if slash is within first 3 chars
|
||||
const char *truncatedLocal = call;
|
||||
const char *truncatedIncoming = other.call;
|
||||
|
||||
const char *slash = std::strchr(call, '/');
|
||||
if (slash && (slash - call) <= 2)
|
||||
truncatedLocal = slash + 1;
|
||||
|
||||
slash = std::strchr(other.call, '/');
|
||||
if (slash && (slash - other.call) <= 2)
|
||||
truncatedIncoming = slash + 1;
|
||||
|
||||
return std::strcmp(truncatedLocal, truncatedIncoming) == 0;
|
||||
}
|
||||
|
|
@ -69,9 +69,11 @@ openrtx/include/interfaces/radio.h
|
|||
openrtx/include/peripherals/gps.h
|
||||
openrtx/include/peripherals/rng.h
|
||||
openrtx/include/peripherals/rtc.h
|
||||
openrtx/include/protocols/M17/Callsign.hpp
|
||||
openrtx/include/protocols/M17/M17FrameDecoder.hpp
|
||||
openrtx/src/core/dsp.cpp
|
||||
openrtx/src/core/memory_profiling.cpp
|
||||
openrtx/src/protocols/M17/Callsign.cpp
|
||||
openrtx/src/protocols/M17/M17FrameDecoder.cpp
|
||||
platform/drivers/ADC/ADC0_GDx.h
|
||||
platform/drivers/audio/MAX9814.h
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue