Skip to content

Commit

Permalink
Update AnyTone APRS settings (#474)
Browse files Browse the repository at this point in the history
* Fixed missing default value.
* Fixed DMR-6X2UV APRS settings docs.
* Fixed copying of APRSSystem. Addresses #468.
* Fixed encoding of APRS systems for BTECH DMR-6X2UV.
  • Loading branch information
hmatuschek authored Sep 30, 2024
1 parent 97a84eb commit 57282f7
Show file tree
Hide file tree
Showing 15 changed files with 279 additions and 40 deletions.
2 changes: 1 addition & 1 deletion doc/code/dmr6x2uv_aprssetting.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
... ...
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
8c ... |
9c ... |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

Field description:
Expand Down
4 changes: 2 additions & 2 deletions lib/anytone_extension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -696,8 +696,8 @@ AnytoneGPSSettingsExtension::setMode(GPSMode mode) {
* ********************************************************************************************* */
AnytoneRoamingSettingsExtension::AnytoneRoamingSettingsExtension(QObject *parent)
: ConfigItem(parent),
_autoRoamPeriod(Interval::fromMinutes(1)), _autoRoamDelay(), _repeaterRangeCheck(false),
_repeaterCheckInterval(Interval::fromSeconds(5)), _repeaterRangeCheckCount(3),
_autoRoam(false), _autoRoamPeriod(Interval::fromMinutes(1)), _autoRoamDelay(),
_repeaterRangeCheck(false), _repeaterCheckInterval(Interval::fromSeconds(5)), _repeaterRangeCheckCount(3),
_outOfRangeAlert(OutOfRangeAlert::None),
_roamingStartCondition(RoamStart::Periodic), _roamingReturnCondition(RoamStart::Periodic),
_notification(false), _notificationCount(1),
Expand Down
2 changes: 1 addition & 1 deletion lib/d868uv_codeplug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -853,10 +853,10 @@ protected:
static constexpr unsigned int radioIDs() { return 0x02580000; }

static constexpr unsigned int settings() { return 0x02500000; }
static constexpr unsigned int zoneChannelList() { return 0x02500100; }
static constexpr unsigned int bootSettings() { return 0x02500600; }
static constexpr unsigned int aprsSettings() { return 0x02501000; }
static constexpr unsigned int dmrAPRSMessage() { return 0x02501100; }
static constexpr unsigned int zoneChannelList() { return 0x02500100; }
static constexpr unsigned int offsetFrequencies() { return 0x024C2000; }

static constexpr unsigned int zoneBitmap() { return 0x024c1300; }
Expand Down
44 changes: 15 additions & 29 deletions lib/dmr6x2uv_codeplug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1549,7 +1549,7 @@ void
DMR6X2UVCodeplug::APRSSettingsElement::clear() {
memset(_data, 0x00, _size);
setUInt8(0x0000, 0xff);
setFMTXDelay(60);
setFMTXDelay(Interval::fromMilliseconds(60));
setUInt8(0x003d, 0x01); setUInt8(0x003e, 0x03); setUInt8(0x003f, 0xff);
}

Expand All @@ -1570,13 +1570,12 @@ DMR6X2UVCodeplug::APRSSettingsElement::setFMFrequency(Frequency f) {
setBCD4_be(Offset::fmFrequency(), f.inHz()/10);
}

unsigned
DMR6X2UVCodeplug::APRSSettingsElement::fmTXDelay() const {
return ((unsigned)getUInt8(Offset::fmTXDelay()))*20;
Interval DMR6X2UVCodeplug::APRSSettingsElement::fmTXDelay() const {
return Interval::fromMilliseconds(((unsigned)getUInt8(Offset::fmTXDelay())*20));
}
void
DMR6X2UVCodeplug::APRSSettingsElement::setFMTXDelay(unsigned ms) {
setUInt8(Offset::fmTXDelay(), ms/20);
DMR6X2UVCodeplug::APRSSettingsElement::setFMTXDelay(const Interval intv) {
setUInt8(Offset::fmTXDelay(), intv.milliseconds()/20);
}

Signaling::Code
Expand Down Expand Up @@ -1999,14 +1998,6 @@ DMR6X2UVCodeplug::setBitmaps(Context& ctx)
roaming_ch_bitmap.clear(); roaming_ch_bitmap.enableFirst(num_roaming_channel);
}

void
DMR6X2UVCodeplug::allocateUpdated() {
// First allocate everything common between D868UV and DMR-6X2UV codeplugs.
D868UVCodeplug::allocateUpdated();

// allocate FM APRS frequency names
image(0).addElement(Offset::fmAPRSFrequencyNames(), D878UVCodeplug::FMAPRSFrequencyNamesElement::size());
}

void
DMR6X2UVCodeplug::allocateForEncoding() {
Expand All @@ -2022,9 +2013,6 @@ DMR6X2UVCodeplug::allocateForDecoding() {
D868UVCodeplug::allocateForDecoding();

this->allocateRoaming();

// allocate FM APRS frequency names
image(0).addElement(Offset::fmAPRSFrequencyNames(), D878UVCodeplug::FMAPRSFrequencyNamesElement::size());
}

bool
Expand Down Expand Up @@ -2168,24 +2156,23 @@ DMR6X2UVCodeplug::encodeGPSSystems(const Flags &flags, Context &ctx, const Error
Q_UNUSED(flags); Q_UNUSED(err)
// replaces D868UVCodeplug::encodeGPSSystems

D878UVCodeplug::APRSSettingsElement aprs(data(Offset::aprsSettings()));
D878UVCodeplug::FMAPRSFrequencyNamesElement aprsNames(data(Offset::fmAPRSFrequencyNames()));
APRSSettingsElement aprs(data(Offset::aprsSettings())); aprs.clear();

// Encode APRS system (there can only be one)
if (0 < ctx.config()->posSystems()->aprsCount()) {
aprs.fromFMAPRSSystem(ctx.config()->posSystems()->aprsSystem(0), ctx, aprsNames);
if (0 < ctx.count<APRSSystem>()) {
aprs.fromFMAPRSSystem(ctx.get<APRSSystem>(0), ctx, err);
uint8_t *aprsmsg = (uint8_t *)data(Offset::fmAPRSMessage());
encode_ascii(aprsmsg, ctx.config()->posSystems()->aprsSystem(0)->message(), Limit::fmAPRSMessage(), 0x00);
encode_ascii(aprsmsg, ctx.get<APRSSystem>(0)->message(), Limit::fmAPRSMessage(), 0x00);
}

// Encode GPS systems
if (! aprs.fromDMRAPRSSystems(ctx))
return false;
if (0 < ctx.config()->posSystems()->gpsCount()) {
if (0 < ctx.count<GPSSystem>()) {
// If there is at least one GPS system defined -> set auto TX interval.
// This setting might be overridden by any analog APRS system below
aprs.setAutoTXInterval(Interval::fromSeconds(ctx.config()->posSystems()->gpsSystem(0)->period()));
aprs.setManualTXInterval(Interval::fromSeconds(ctx.config()->posSystems()->gpsSystem(0)->period()));
aprs.setAutoTXInterval(Interval::fromSeconds(ctx.get<GPSSystem>(0)->period()));
aprs.setManualTXInterval(Interval::fromSeconds(ctx.get<GPSSystem>(0)->period()));
}
return true;
}
Expand All @@ -2197,14 +2184,13 @@ DMR6X2UVCodeplug::createGPSSystems(Context &ctx, const ErrorStack &err) {
// replaces D868UVCodeplug::createGPSSystems

// Before creating any GPS/APRS systems, get global auto TX interval
D878UVCodeplug::APRSSettingsElement aprs(data(Offset::aprsSettings()));
D878UVCodeplug::FMAPRSFrequencyNamesElement aprsNames(data(Offset::fmAPRSFrequencyNames()));
APRSSettingsElement aprs(data(Offset::aprsSettings()));
unsigned pos_interval = aprs.autoTXInterval().seconds();

// Create APRS system (if enabled)
uint8_t *aprsmsg = (uint8_t *)data(Offset::fmAPRSMessage());
if (aprs.isValid()) {
APRSSystem *sys = aprs.toFMAPRSSystem(ctx, aprsNames, err);
APRSSystem *sys = aprs.toFMAPRSSystem();
if (nullptr == sys) {
errMsg(err) << "Cannot decode positioning systems.";
return false;
Expand Down Expand Up @@ -2234,7 +2220,7 @@ DMR6X2UVCodeplug::linkGPSSystems(Context &ctx, const ErrorStack &err) {
// replaces D868UVCodeplug::linkGPSSystems

// Link APRS system
D878UVCodeplug::APRSSettingsElement aprs(data(Offset::aprsSettings()));
APRSSettingsElement aprs(data(Offset::aprsSettings()));
if (aprs.isValid()) {
aprs.linkFMAPRSSystem(ctx.config()->posSystems()->aprsSystem(0), ctx);
}
Expand Down
5 changes: 2 additions & 3 deletions lib/dmr6x2uv_codeplug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -911,9 +911,9 @@ public:
virtual void setFMFrequency(Frequency f);

/** Returns the TX delay in ms. */
virtual unsigned fmTXDelay() const;
virtual Interval fmTXDelay() const;
/** Sets the TX delay in ms. */
virtual void setFMTXDelay(unsigned ms);
virtual void setFMTXDelay(const Interval intv);

/** Returns the sub tone settings. */
virtual Signaling::Code txTone() const;
Expand Down Expand Up @@ -1108,7 +1108,6 @@ protected:
bool allocateBitmaps();
void setBitmaps(Context &ctx);
void allocateForDecoding();
void allocateUpdated();
void allocateForEncoding();

bool decodeElements(Context &ctx, const ErrorStack &err=ErrorStack());
Expand Down
30 changes: 28 additions & 2 deletions lib/gpssystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ PositioningSystem::parse(const YAML::Node &node, Context &ctx, const ErrorStack
<< ": Positioning system has no period.";
}

return ConfigObject::parse(pos, ctx);
return ConfigObject::parse(pos, ctx, err);
}

bool
Expand Down Expand Up @@ -265,30 +265,56 @@ const QString &
APRSSystem::destination() const {
return _destination;
}

unsigned
APRSSystem::destSSID() const {
return _destSSID;
}

void
APRSSystem::setDestination(const QString &call, unsigned ssid) {
_destination = call;
_destSSID = ssid;
}

void
APRSSystem::setDestination(const QString &call) {
_destination = call;
}

void
APRSSystem::setDestSSID(unsigned int ssid) {
_destSSID = ssid;
}


const QString &
APRSSystem::source() const {
return _source;
}

unsigned
APRSSystem::srcSSID() const {
return _srcSSID;
}

void
APRSSystem::setSource(const QString &call, unsigned ssid) {
_source = call;
_srcSSID = ssid;
}

void
APRSSystem::setSource(const QString &call) {
_source = call;
}

void
APRSSystem::setSrcSSID(unsigned ssid) {
_srcSSID = ssid;
}


const QString &
APRSSystem::path() const {
return _path;
Expand Down Expand Up @@ -421,7 +447,7 @@ APRSSystem::parse(const YAML::Node &node, Context &ctx, const ErrorStack &err) {
if (it->IsScalar())
path.append(QString::fromStdString(it->as<std::string>()));
}
setPath(path.join(""));
setPath(path.join(","));
}

return PositioningSystem::parse(node, ctx, err);
Expand Down
19 changes: 19 additions & 0 deletions lib/gpssystem.hh
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ class APRSSystem: public PositioningSystem

/** The transmit channel. */
Q_PROPERTY(FMChannelReference* revert READ revert WRITE setRevert)
/** The destination call. */
Q_PROPERTY(QString destination READ destination WRITE setDestination SCRIPTABLE false)
/** The destination SSID. */
Q_PROPERTY(unsigned int destSSID READ destSSID WRITE setDestSSID SCRIPTABLE false)
/** The source call. */
Q_PROPERTY(QString source READ source WRITE setSource SCRIPTABLE false)
/** The source SSID. */
Q_PROPERTY(unsigned int srcSSID READ srcSSID WRITE setSrcSSID SCRIPTABLE false)
/** The APRS path as a string. */
Q_PROPERTY(QString path READ path WRITE setPath SCRIPTABLE false)

/** The APRS icon. */
Q_PROPERTY(Icon icon READ icon WRITE setIcon)
/** An optional text message. */
Expand Down Expand Up @@ -204,13 +215,21 @@ public:
unsigned destSSID() const;
/** Sets the destination call and SSID. */
void setDestination(const QString &call, unsigned ssid);
/** Sets the destination call. */
void setDestination(const QString &call);
/** Sets the destination SSID. */
void setDestSSID(unsigned ssid);

/** Returns the source call. */
const QString &source() const;
/** Returns the source SSID. */
unsigned srcSSID() const;
/** Sets the source call and SSID. */
void setSource(const QString &call, unsigned ssid);
/** Sets the source call. */
void setSource(const QString &call);
/** Sets the source SSID. */
void setSrcSSID(unsigned ssid);

/** Returns the APRS path. */
const QString &path() const;
Expand Down
44 changes: 44 additions & 0 deletions test/copytest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,49 @@ CopyTest::testConfigCopy() {
QCOMPARE(_basicConfig.compare(*item), 0);
}

void
CopyTest::testAPRSSystemCopy() {
// Regression test for issue #468.

QHash<ConfigObject *, ConfigObject *> map;
ConfigCloneVisitor cloner(map);
FixReferencesVisistor fixer(map);

Config config; ErrorStack err;
if (! config.readYAML(":/data/fm_aprs_test.yaml", err)) {
QFAIL(QString("Cannot open codeplug file: %1\n")
.arg(err.format()).toStdString().c_str());
}

if (! cloner.process(&config, err)) {
QFAIL(err.format().toLocal8Bit().constData());
}

ConfigItem *item = cloner.takeResult(err);
QVERIFY(item);
QVERIFY(item->is<Config>());

if (! fixer.process(item->as<Config>(), err)) {
QFAIL(err.format().toLocal8Bit().constData());
}
Config *comp_config = item->as<Config>();
QCOMPARE(config.compare(*item), 0);

QCOMPARE(config.posSystems()->count(), 1);
QCOMPARE(comp_config->posSystems()->count(), config.posSystems()->count());
QVERIFY(config.posSystems()->get(0)->is<APRSSystem>());
QVERIFY(comp_config->posSystems()->get(0)->is<APRSSystem>());

APRSSystem *aprs = config.posSystems()->get(0)->as<APRSSystem>(),
*comp_aprs = comp_config->posSystems()->get(0)->as<APRSSystem>();
QCOMPARE(comp_aprs->name(), aprs->name());
QCOMPARE(comp_aprs->period(), aprs->period());
QCOMPARE(comp_aprs->destination(), aprs->destination()); QCOMPARE(comp_aprs->destSSID(), aprs->destSSID());
QCOMPARE(comp_aprs->source(), aprs->source()); QCOMPARE(comp_aprs->srcSSID(), aprs->srcSSID());
QCOMPARE(comp_aprs->path(), aprs->path());
QCOMPARE(comp_aprs->icon(), aprs->icon());
QCOMPARE(comp_aprs->message(), aprs->message());
}


QTEST_GUILESS_MAIN(CopyTest)
1 change: 1 addition & 0 deletions test/copytest.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ private slots:
void testChannelClone();
void testConfigClone();
void testConfigCopy();
void testAPRSSystemCopy();
};

#endif // COPYTEST_HH
Loading

0 comments on commit 57282f7

Please sign in to comment.