Skip to content

Commit

Permalink
Fixed encoding of AnyTone codeplugs to tolerate M17 contacts/channels.
Browse files Browse the repository at this point in the history
  • Loading branch information
hmatuschek committed Sep 17, 2022
1 parent c38ab8b commit 408a934
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 20 deletions.
16 changes: 14 additions & 2 deletions lib/anytone_codeplug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3951,6 +3951,10 @@ AnytoneCodeplug::index(Config *config, Context &ctx, const ErrorStack &err) cons
ctx.add(config->contacts()->contact(i)->as<DMRContact>(), d); d++;
} else if (config->contacts()->contact(i)->is<DTMFContact>()) {
ctx.add(config->contacts()->contact(i)->as<DTMFContact>(), a); a++;
} else {
logInfo() << "Cannot index contact '" << config->contacts()->contact(i)->name()
<< "'. Contact type '" << config->contacts()->contact(i)->metaObject()->className()
<< "' not supported by or implemented for AnyTone devices.";
}
}

Expand All @@ -3959,8 +3963,16 @@ AnytoneCodeplug::index(Config *config, Context &ctx, const ErrorStack &err) cons
ctx.add(config->rxGroupLists()->list(i), i);

// Map channels
for (int i=0; i<config->channelList()->count(); i++)
ctx.add(config->channelList()->channel(i), i);
for (int i=0,c=0; i<config->channelList()->count(); i++) {
Channel *channel = config->channelList()->channel(i);
if ((channel->is<DMRChannel>()) || (channel->is<FMChannel>()) ) {
ctx.add(channel, c); c++;
} else {
logInfo() << "Cannot index channel '" << channel->name()
<< "'. Channel type '" << channel->metaObject()->className()
<< "' not supported by or implemented for AnyTone devices.";
}
}

// Map zones
for (int i=0; i<config->zones()->count(); i++)
Expand Down
2 changes: 1 addition & 1 deletion lib/codeplug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ Codeplug::Context::index(ConfigItem *obj) {

bool
Codeplug::Context::add(ConfigItem *obj, unsigned idx) {
if (!hasTable(obj->metaObject()))
if (! hasTable(obj->metaObject()))
return false;
if (getTable(obj->metaObject()).indices.contains(obj))
return false;
Expand Down
2 changes: 1 addition & 1 deletion lib/codeplug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ public:
/** Returns the number of elements for the specified type. */
template <class T>
unsigned int count() {
return getTable(&T::staticMetaObject).indices.size();
return this->getTable(&T::staticMetaObject).indices.size();
}

protected:
Expand Down
33 changes: 21 additions & 12 deletions lib/d868uv_codeplug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -585,23 +585,32 @@ D868UVCodeplug::setBitmaps(Config *config)
// Mark valid channels (set bit)
uint8_t *channel_bitmap = data(CHANNEL_BITMAP);
memset(channel_bitmap, 0, CHANNEL_BITMAP_SIZE);
for (int i=0; i<std::min(NUM_CHANNELS, config->channelList()->count()); i++) {
channel_bitmap[i/8] |= (1 << (i%8));
for (int i=0,c=0; i<std::min(NUM_CHANNELS, config->channelList()->count()); i++) {
Channel *channel = config->channelList()->channel(i);
if ((! channel->is<DMRChannel>()) && (! channel->is<FMChannel>()))
continue;
channel_bitmap[c/8] |= (1 << (c%8)); c++;
}

// Mark valid contacts (clear bit)
uint8_t *contact_bitmap = data(CONTACTS_BITMAP);
memset(contact_bitmap, 0x00, CONTACTS_BITMAP_SIZE);
memset(contact_bitmap, 0xff, NUM_CONTACTS/8+1);
for (int i=0; i<std::min(NUM_CONTACTS, config->contacts()->digitalCount()); i++) {
contact_bitmap[i/8] &= ~(1 << (i%8));
for (int i=0, c=0; i<std::min(NUM_CONTACTS, config->contacts()->count()); i++) {
Contact *contact = config->contacts()->contact(i);
if (! contact->is<DMRContact>())
continue;
contact_bitmap[c/8] &= ~(1 << (c%8)); c++;
}

// Mark valid analog contacts (clear bytes)
uint8_t *analog_contact_bitmap = data(ANALOGCONTACT_BYTEMAP);
memset(analog_contact_bitmap, 0xff, ANALOGCONTACT_BYTEMAP_SIZE);
for (int i=0; i<std::min(NUM_ANALOGCONTACTS, config->contacts()->dtmfCount()); i++) {
analog_contact_bitmap[i] = 0x00;
for (int i=0, c=0; i<std::min(NUM_ANALOGCONTACTS, config->contacts()->count()); i++) {
Contact *contact = config->contacts()->contact(i);
if (! contact->is<DTMFContact>())
continue;
analog_contact_bitmap[i] = 0x00; c++;
}

// Mark valid zones (set bits)
Expand Down Expand Up @@ -756,11 +765,11 @@ D868UVCodeplug::encodeChannels(const Flags &flags, Context &ctx, const ErrorStac
Q_UNUSED(flags); Q_UNUSED(err)

// Encode channels
for (int i=0; i<ctx.config()->channelList()->count(); i++) {
for (unsigned int i=0; i<ctx.count<Channel>(); i++) {
// enable channel
uint16_t bank = i/128, idx = i%128;
ChannelElement ch(data(CHANNEL_BANK_0 + bank*CHANNEL_BANK_OFFSET + idx*CHANNEL_SIZE));
if (! ch.fromChannelObj(ctx.config()->channelList()->channel(i), ctx))
if (! ch.fromChannelObj(ctx.get<Channel>(i), ctx))
return false;
}
return true;
Expand Down Expand Up @@ -843,11 +852,11 @@ D868UVCodeplug::encodeContacts(const Flags &flags, Context &ctx, const ErrorStac

QVector<DMRContact*> contacts;
// Encode contacts and also collect id<->index map
for (int i=0; i<ctx.config()->contacts()->digitalCount(); i++) {
for (unsigned int i=0; i<ctx.count<DMRContact>(); i++) {
uint32_t bank_addr = CONTACT_BLOCK_0 + (i/CONTACTS_PER_BANK)*CONTACT_BANK_SIZE;
uint32_t addr = bank_addr + (i%CONTACTS_PER_BANK)*CONTACT_SIZE;
ContactElement con(data(addr));
DMRContact *contact = ctx.config()->contacts()->digitalContact(i);
DMRContact *contact = ctx.get<DMRContact>(i);
if(! con.fromContactObj(contact, ctx))
return false;
((uint32_t *)data(CONTACT_INDEX_LIST))[i] = qToLittleEndian(i);
Expand Down Expand Up @@ -910,11 +919,11 @@ D868UVCodeplug::encodeAnalogContacts(const Flags &flags, Context &ctx, const Err

uint8_t *idxlst = data(ANALOGCONTACT_INDEX_LIST);
memset(idxlst, 0xff, ANALOGCONTACT_LIST_SIZE);
for (int i=0; i<ctx.config()->contacts()->dtmfCount(); i++) {
for (unsigned int i=0; i<ctx.count<DTMFContact>(); i++) {
uint32_t addr = ANALOGCONTACT_BANK_0 + (i/ANALOGCONTACTS_PER_BANK)*ANALOGCONTACT_BANK_SIZE
+ (i%ANALOGCONTACTS_PER_BANK)*ANALOGCONTACT_SIZE;
DTMFContactElement cont(data(addr));
cont.fromContact(ctx.config()->contacts()->dtmfContact(i));
cont.fromContact(ctx.get<DTMFContact>(i));
idxlst[i] = i;
}
return true;
Expand Down
4 changes: 2 additions & 2 deletions lib/d878uv2_codeplug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ D878UV2Codeplug::encodeContacts(const Flags &flags, Context &ctx, const ErrorSta

QVector<DMRContact*> contacts;
// Encode contacts and also collect id<->index map
for (int i=0; i<ctx.config()->contacts()->digitalCount(); i++) {
for (unsigned int i=0; i<ctx.count<DMRContact>(); i++) {
uint32_t bank_addr = CONTACT_BLOCK_0 + (i/CONTACTS_PER_BANK)*CONTACT_BANK_SIZE;
uint32_t addr = bank_addr + (i%CONTACTS_PER_BANK)*CONTACT_SIZE;
ContactElement con(data(addr));
DMRContact *contact = ctx.config()->contacts()->digitalContact(i);
DMRContact *contact = ctx.get<DMRContact>(i);
if(! con.fromContactObj(contact, ctx))
return false;
((uint32_t *)data(CONTACT_INDEX_LIST))[i] = qToLittleEndian(i);
Expand Down
4 changes: 2 additions & 2 deletions lib/d878uv_codeplug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2255,11 +2255,11 @@ bool
D878UVCodeplug::encodeChannels(const Flags &flags, Context &ctx, const ErrorStack &err) {
Q_UNUSED(flags); Q_UNUSED(err)
// Encode channels
for (int i=0; i<ctx.config()->channelList()->count(); i++) {
for (unsigned int i=0; i<ctx.count<Channel>(); i++) {
// enable channel
uint16_t bank = i/128, idx = i%128;
ChannelElement ch(data(CHANNEL_BANK_0 + bank*CHANNEL_BANK_OFFSET + idx*CHANNEL_SIZE));
ch.fromChannelObj(ctx.config()->channelList()->channel(i), ctx);
ch.fromChannelObj(ctx.get<Channel>(i), ctx);
}
return true;
}
Expand Down

0 comments on commit 408a934

Please sign in to comment.