1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
#include "gpssystem.hh"
#include "userdatabase.hh"
#include "roamingchannel.hh"
#include "d878uv2_codeplug.hh"
#include "config.hh"
#include "utils.hh"
#include "channel.hh"
#include "config.h"
#include "logger.hh"
#include <QTimeZone>
#include <QtEndian>
/* ******************************************************************************************** *
* Implementation of D878UV2Codeplug
* ******************************************************************************************** */
D878UV2Codeplug::D878UV2Codeplug(const QString &label, QObject *parent)
: D878UVCodeplug(label, parent)
{
// pass...
}
D878UV2Codeplug::D878UV2Codeplug(QObject *parent)
: D878UVCodeplug("AnyTone AT-D868UVII Codeplug", parent)
{
// pass...
}
/* The address of the contact ID<->Index table has changed hence allocation and encoding must
* be reimplemented. Otherwise, everything remains the same. */
void
D878UV2Codeplug::allocateContacts() {
/* Allocate contacts */
ContactBitmapElement contact_bitmap(data(Offset::contactBitmap()));
unsigned contactCount=0;
for (uint16_t i=0; i<Limit::numContacts(); i++) {
// enabled if false (ass hole)
if (! contact_bitmap.isEncoded(i))
continue;
contactCount++;
uint32_t bank_addr = Offset::contactBanks() + (contactCount/Limit::contactsPerBank())*Offset::betweenContactBanks();
uint32_t addr = bank_addr + ((i%Limit::contactsPerBank())/Limit::contactsPerBlock())*Offset::betweenContactBlocks();
if (! isAllocated(addr, 0)) {
image(0).addElement(addr, Offset::betweenContactBlocks());
memset(data(addr), 0x00, Offset::betweenContactBlocks());
}
}
if (contactCount) {
image(0).addElement(Offset::contactIndex(), align_size(4*contactCount, 16));
memset(data(Offset::contactIndex()), 0xff, align_size(4*contactCount, 16));
image(0).addElement(Offset::contactIdTable(), align_size(ContactMapElement::size()*(1+contactCount), 16));
memset(data(Offset::contactIdTable()), 0xff, align_size(ContactMapElement::size()*(1+contactCount), 16));
}
}
bool
D878UV2Codeplug::encodeContacts(const Flags &flags, Context &ctx, const ErrorStack &err) {
Q_UNUSED(flags); Q_UNUSED(err)
QVector<DMRContact*> contacts;
// Encode contacts and also collect id<->index map
for (int i=0; i<ctx.config()->contacts()->digitalCount(); i++) {
uint32_t bank_addr = Offset::contactBanks() + (i/Limit::contactsPerBank())*Offset::betweenContactBanks();
uint32_t addr = bank_addr + (i%Limit::contactsPerBank())*ContactElement::size();
ContactElement con(data(addr));
DMRContact *contact = ctx.config()->contacts()->digitalContact(i);
if(! con.fromContactObj(contact, ctx))
return false;
((uint32_t *)data(Offset::contactIndex()))[i] = qToLittleEndian(i);
contacts.append(contact);
}
// encode index map for contacts
std::sort(contacts.begin(), contacts.end(),
[](DMRContact *a, DMRContact *b) {
return a->number() < b->number();
});
for (int i=0; i<contacts.size(); i++) {
ContactMapElement el(data(Offset::contactIdTable() + i*ContactMapElement::size()));
el.setID(contacts[i]->number(), (DMRContact::GroupCall==contacts[i]->type()));
el.setIndex(ctx.index(contacts[i]));
}
return true;
}
|