Skip to content

Commit

Permalink
Implemented FM APRS frequency list and experimental storage of labels…
Browse files Browse the repository at this point in the history
…. Addresses #349.
  • Loading branch information
hmatuschek committed Jul 6, 2023
1 parent 1566e6b commit ed8db75
Show file tree
Hide file tree
Showing 11 changed files with 389 additions and 33 deletions.
2 changes: 1 addition & 1 deletion doc/code/d878uv_channel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
38 | GPS System Index | Freq. corr. signed in 10Hz | DMR encryption idx +1, 0=off | 0 0 0 0 0 |SMF|RnK|Muk|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
3c | Unused set to 0x00000000 |
3c | FM APRS Frequency index | Unused set to 0x000000 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

Field description:
Expand Down
15 changes: 14 additions & 1 deletion lib/anytone_codeplug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4545,7 +4545,15 @@ AnytoneCodeplug::index(Config *config, Context &ctx, const ErrorStack &err) cons
if (config->posSystems()->system(i)->is<GPSSystem>()) {
ctx.add(config->posSystems()->system(i)->as<GPSSystem>(), d); d++;
} else if (config->posSystems()->system(i)->is<APRSSystem>()) {
ctx.add(config->posSystems()->system(i)->as<APRSSystem>(), a); a++;
auto *aprs = config->posSystems()->system(i)->as<APRSSystem>();
ctx.add(aprs, a); a++;
// Index FM APRS frequencies (referenced in channel extensions).
if (auto *ext = aprs->anytoneExtension()) {
for (int j=0; j<ext->frequencies()->count(); j++) {
// Index 0 = default, so index is 1-based
ctx.add(ext->frequencies()->get(j)->as<AnytoneAPRSFrequency>(), j+1);
}
}
}
}

Expand All @@ -4570,6 +4578,8 @@ AnytoneCodeplug::encode(Config *config, const Flags &flags, const ErrorStack &er
Context ctx(config);
// Register table for auto-repeater offsets
ctx.addTable(&AnytoneAutoRepeaterOffset::staticMetaObject);
// Register table for FM APRS frequencies
ctx.addTable(&AnytoneAPRSFrequency::staticMetaObject);

if (! index(config, ctx, err)) {
errMsg(err) << "Cannot encode anytone codeplug.";
Expand Down Expand Up @@ -4597,8 +4607,11 @@ bool
AnytoneCodeplug::decode(Config *config, const ErrorStack &err) {
// Maps code-plug indices to objects
Context ctx(config);

// Register table for auto-repeater offsets
ctx.addTable(&AnytoneAutoRepeaterOffset::staticMetaObject);
// Register table for FM APRS frequencies
ctx.addTable(&AnytoneAPRSFrequency::staticMetaObject);

return this->decodeElements(ctx, err);
}
6 changes: 6 additions & 0 deletions lib/anytone_codeplug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,12 @@ public:
virtual bool linkChannelObj(Channel *c, Context &ctx) const;
/** Initializes this codeplug channel from the given generic configuration. */
virtual bool fromChannelObj(const Channel *c, Context &ctx);

protected:
/** Internal used offsets within the channel element. */
struct Offset {
/// @todo Implement
};
};

/** Represents the channel bitmaps in all AnyTone codeplugs. */
Expand Down
73 changes: 71 additions & 2 deletions lib/anytone_extension.cc
Original file line number Diff line number Diff line change
@@ -1,11 +1,70 @@
#include "anytone_extension.hh"
#include "signaling.hh"

/* ********************************************************************************************* *
* Implementation of AnytoneAPRSFrequency
* ********************************************************************************************* */
AnytoneAPRSFrequency::AnytoneAPRSFrequency(QObject *parent)
: ConfigObject(parent), _frequency(Frequency::fromHz(0))
{
// pass...
}

ConfigItem *
AnytoneAPRSFrequency::clone() const {
AnytoneAPRSFrequency *obj = new AnytoneAPRSFrequency();
if (! obj->copy(*this)) {
obj->deleteLater();
return nullptr;
}
return obj;
}

Frequency
AnytoneAPRSFrequency::frequency() const {
return _frequency;
}
void
AnytoneAPRSFrequency::setFrequency(Frequency freq) {
if (_frequency == freq)
return;
_frequency = freq;
emit modified(this);
}


/* ********************************************************************************************* *
* Implementation of AnytoneAPRSFrequencyRef
* ********************************************************************************************* */
AnytoneAPRSFrequencyRef::AnytoneAPRSFrequencyRef(QObject *parent)
: ConfigObjectReference(AnytoneAPRSFrequency::staticMetaObject, parent)
{
// pass...
}


/* ********************************************************************************************* *
* Implementation of AnytoneAPRSFrequencyList
* ********************************************************************************************* */
AnytoneAPRSFrequencyList::AnytoneAPRSFrequencyList(QObject *parent)
: ConfigObjectList(AnytoneAPRSFrequency::staticMetaObject, parent)
{
// pass...
}

ConfigItem *
AnytoneAPRSFrequencyList::allocateChild(const YAML::Node &node, ConfigItem::Context &ctx, const ErrorStack &err) {
Q_UNUSED(node); Q_UNUSED(ctx); Q_UNUSED(err);
return new AnytoneAPRSFrequency();
}


/* ********************************************************************************************* *
* Implementation of AnytoneChannelExtension
* ********************************************************************************************* */
AnytoneChannelExtension::AnytoneChannelExtension(QObject *parent)
: ConfigExtension(parent), _talkaround(false), _frequencyCorrection(0), _handsFree(false)
: ConfigExtension(parent), _talkaround(false), _frequencyCorrection(0), _handsFree(false),
_fmAPRSFrequency(new AnytoneAPRSFrequencyRef(this))
{
// pass...
}
Expand Down Expand Up @@ -46,6 +105,11 @@ AnytoneChannelExtension::enableHandsFree(bool enable) {
emit modified(this);
}

AnytoneAPRSFrequencyRef *
AnytoneChannelExtension::fmAPRSFrequency() const {
return _fmAPRSFrequency;
}


/* ********************************************************************************************* *
* Implementation of AnytoneAnalogChannelExtension
Expand Down Expand Up @@ -2683,7 +2747,8 @@ AnytoneFMAPRSSettingsExtension::AnytoneFMAPRSSettingsExtension(QObject *parent)
: ConfigExtension(parent), _txDelay(Interval::fromMilliseconds(60)),
_preWaveDelay(Interval::fromMilliseconds(0)), _passAll(false), _reportPosition(false),
_reportMicE(false), _reportObject(false), _reportItem(false), _reportMessage(false),
_reportWeather(false), _reportNMEA(false), _reportStatus(false), _reportOther(false)
_reportWeather(false), _reportNMEA(false), _reportStatus(false), _reportOther(false),
_frequencies(new AnytoneAPRSFrequencyList(this))
{
// pass...
}
Expand Down Expand Up @@ -2842,3 +2907,7 @@ AnytoneFMAPRSSettingsExtension::enableReportOther(bool enable) {
emit modified(this);
}

AnytoneAPRSFrequencyList *
AnytoneFMAPRSSettingsExtension::frequencies() const {
return _frequencies;
}
71 changes: 71 additions & 0 deletions lib/anytone_extension.hh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,62 @@

#include <QTimeZone>

/** Implements the config representation of an FM APRS frequency.
* @ingroup anytone */
class AnytoneAPRSFrequency: public ConfigObject
{
Q_OBJECT

Q_CLASSINFO("IdPrefix", "af")

Q_CLASSINFO("frequencyDecription",
"Transmit-frequency.")
/** The frequency. */
Q_PROPERTY(Frequency frequency READ frequency WRITE setFrequency)

public:
/** Default constructor. */
Q_INVOKABLE explicit AnytoneAPRSFrequency(QObject *parent=nullptr);

ConfigItem *clone() const;

/** Returns the transmit frequency. */
Frequency frequency() const;
/** Sets the transmit frequency. */
void setFrequency(Frequency freq);

protected:
/** The transmit frequency. */
Frequency _frequency;
};


/** Represents a reference to an APRS frequency.
* @ingroup anytone */
class AnytoneAPRSFrequencyRef: public ConfigObjectReference
{
Q_OBJECT

public:
/** Default constructor. */
explicit AnytoneAPRSFrequencyRef(QObject *parent=nullptr);
};


/** Represents a list of APRS transmit frequencies.
* @ingroup anytone */
class AnytoneAPRSFrequencyList: public ConfigObjectList
{
Q_OBJECT

public:
/** Empty constructor. */
explicit AnytoneAPRSFrequencyList(QObject *parent=nullptr);

ConfigItem *allocateChild(const YAML::Node &node, ConfigItem::Context &ctx, const ErrorStack &err);
};


/** Implements the common properties for analog and digital AnyTone channels.
* This class cannot be instantiated directly, use one of the derived classes.
* @ingroup anytone */
Expand All @@ -23,6 +79,8 @@ class AnytoneChannelExtension: public ConfigExtension
Q_PROPERTY(int frequencyCorrection READ frequencyCorrection WRITE setFrequencyCorrection)
/** If @c true, the hands-free featrue is enabled for this channel. */
Q_PROPERTY(bool handsFree READ handsFree WRITE enableHandsFree)
/** A reference to the FM APRS frequency. If not set, the default will be used. */
Q_PROPERTY(AnytoneAPRSFrequencyRef *fmAPRSFrequency READ fmAPRSFrequency())

protected:
/** Hidden constructor. */
Expand All @@ -44,6 +102,8 @@ public:
/** Enables/disables the hands-free feature for this channel. */
void enableHandsFree(bool enable);

/** Holds a reference to the FM APRS frequency to be used if FM APRS is enabled on the channel. */
AnytoneAPRSFrequencyRef *fmAPRSFrequency() const;

protected:
/** If @c true, talkaround is enabled. */
Expand All @@ -52,6 +112,8 @@ protected:
int _frequencyCorrection;
/** If @c true, the hands-free featrue is enabled for this channel. */
bool _handsFree;
/** A reference to the FM APRS frequency. */
AnytoneAPRSFrequencyRef *_fmAPRSFrequency;
};


Expand Down Expand Up @@ -2280,6 +2342,7 @@ protected:
bool _maintainCallChannel; ///< Maintains the call channel.
};


/** Implements some additional settings for the FM APRS system.
* This extension gets attached to a @c APRSSystem instance.
*/
Expand Down Expand Up @@ -2312,6 +2375,9 @@ class AnytoneFMAPRSSettingsExtension: public ConfigExtension
/** If @c true, the report other flag is set. */
Q_PROPERTY(bool reportOther READ reportOther WRITE enableReportOther)

/** The list of additional APRS frequencies. */
Q_PROPERTY(AnytoneAPRSFrequencyList *frequencies READ frequencies)

public:
/** Possible bandwidth settings. */
enum class Bandwidth {
Expand Down Expand Up @@ -2377,6 +2443,9 @@ public:
/** Enables/disables report other flag. */
void enableReportOther(bool enable);

/** Returns the list of additional FM APRS frequencies. */
AnytoneAPRSFrequencyList *frequencies() const;

protected:
/** The transmit delay. */
Interval _txDelay;
Expand All @@ -2402,6 +2471,8 @@ protected:
bool _reportStatus;
/** The report other flag. */
bool _reportOther;
/** The list of additional FM APRS frequencies. */
AnytoneAPRSFrequencyList *_frequencies;
};

#endif // ANYTONEEXTENSION_HH
7 changes: 4 additions & 3 deletions lib/d578uv_codeplug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,13 @@ class GPSSystem;
*
* <tr><th colspan="3">GPS/APRS</th></tr>
* <tr><th>Start</th> <th>Size</th> <th>Content</th></tr>
* <tr><td>02501000</td> <td>000040</td> <td>APRS settings, see @c D878UVCodeplug::AnalogAPRSSettingsElement.</td>
* <tr><td>02501040</td> <td>000060</td> <td>APRS settings, see @c D878UVCodeplug::DMRAPRSSystemsElement.</td>
* <tr><td>025010A0</td> <td>000060</td> <td>Extended APRS settings, see @c D578UVCodeplug::AnalogAPRSSettingsExtensionElement.</tr>
* <tr><td>02501000</td> <td>000100</td> <td>APRS settings, see @c D878UVCodeplug::APRSSettingsElement.</td>
* <tr><td>02501200</td> <td>000040</td> <td>APRS Text, up to 60 chars ASCII, 0-padded.</td>
* <tr><td>02501800</td> <td>000100</td> <td>APRS-RX settings list up to 32 entries, 8b each.
* See @c D878UVCodeplug::AnalogAPRSRXEntryElement.</td></tr>
* <tr><td>02502000</td> <td>000080</td> <td>FM APRS frequency names,
* see @c FMAPRSFrequencyNamesElement. This element is not part of the manufacturer codeplug.
* QDMR uses this memory section to store additional information.</td></tr>
*
* <tr><th colspan="3">General Settings</th></tr>
* <tr><th>Start</th> <th>Size</th> <th>Content</th></tr>
Expand Down
6 changes: 6 additions & 0 deletions lib/d868uv_codeplug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ public:
virtual bool linkChannelObj(Channel *c, Context &ctx) const;
/** Initializes this codeplug channel from the given generic configuration. */
virtual bool fromChannelObj(const Channel *c, Context &ctx);

protected:
/** Internal used offsets within the channel element. */
struct Offset: public AnytoneCodeplug::ChannelElement::Offset {
/// @todo Implement
};
};

/** Represents the general config of the radio within the D868UV binary codeplug.
Expand Down
Loading

0 comments on commit ed8db75

Please sign in to comment.