Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
97cdfb97e8
41 changed files with 1522 additions and 235 deletions
|
@ -21,39 +21,39 @@
|
|||
#include <cstring>
|
||||
|
||||
|
||||
std::vector<unsigned int> DMRAccessControl::m_dstBlackListSlot1RF;
|
||||
std::vector<unsigned int> DMRAccessControl::m_dstBlackListSlot2RF;
|
||||
std::vector<unsigned int> DMRAccessControl::m_dstWhiteListSlot1RF;
|
||||
std::vector<unsigned int> DMRAccessControl::m_dstWhiteListSlot2RF;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_dstBlackListSlot1RF;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_dstBlackListSlot2RF;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_dstWhiteListSlot1RF;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_dstWhiteListSlot2RF;
|
||||
|
||||
std::vector<unsigned int> DMRAccessControl::m_dstBlackListSlot1NET;
|
||||
std::vector<unsigned int> DMRAccessControl::m_dstBlackListSlot2NET;
|
||||
std::vector<unsigned int> DMRAccessControl::m_dstWhiteListSlot1NET;
|
||||
std::vector<unsigned int> DMRAccessControl::m_dstWhiteListSlot2NET;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_dstBlackListSlot1NET;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_dstBlackListSlot2NET;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_dstWhiteListSlot1NET;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_dstWhiteListSlot2NET;
|
||||
|
||||
std::vector<unsigned int> DMRAccessControl::m_srcIdBlacklist;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_srcIdBlacklist;
|
||||
|
||||
std::vector<unsigned int> DMRAccessControl::m_prefixes;
|
||||
std::vector<unsigned int> CDMRAccessControl::m_prefixes;
|
||||
|
||||
bool DMRAccessControl::m_selfOnly = false;
|
||||
bool CDMRAccessControl::m_selfOnly = false;
|
||||
|
||||
unsigned int DMRAccessControl::m_id = 0U;
|
||||
unsigned int CDMRAccessControl::m_id = 0U;
|
||||
|
||||
unsigned int DMRAccessControl::m_dstRewriteID[2];
|
||||
unsigned int DMRAccessControl::m_srcID[2];
|
||||
unsigned int CDMRAccessControl::m_dstRewriteID[2];
|
||||
unsigned int CDMRAccessControl::m_srcID[2];
|
||||
|
||||
CDMRLC* DMRAccessControl::m_lastdmrLC;
|
||||
CDMRLC* CDMRAccessControl::m_lastdmrLC;
|
||||
|
||||
time_t DMRAccessControl::m_time[2];
|
||||
time_t CDMRAccessControl::m_time[2];
|
||||
|
||||
int DMRAccessControl::m_callHang;
|
||||
int CDMRAccessControl::m_callHang;
|
||||
|
||||
bool DMRAccessControl::m_tgRewriteSlot1;
|
||||
bool DMRAccessControl::m_tgRewriteSlot2;
|
||||
bool DMRAccessControl::m_bmAutoRewrite;
|
||||
bool DMRAccessControl::m_bmRewriteReflectorVoicePrompts;
|
||||
bool CDMRAccessControl::m_tgRewriteSlot1;
|
||||
bool CDMRAccessControl::m_tgRewriteSlot2;
|
||||
bool CDMRAccessControl::m_bmAutoRewrite;
|
||||
bool CDMRAccessControl::m_bmRewriteReflectorVoicePrompts;
|
||||
|
||||
void DMRAccessControl::init(const std::vector<unsigned int>& dstIdBlacklistSlot1RF, const std::vector<unsigned int>& dstIdWhitelistSlot1RF, const std::vector<unsigned int>& dstIdBlacklistSlot2RF, const std::vector<unsigned int>& dstIdWhitelistSlot2RF, const std::vector<unsigned int>& dstIdBlacklistSlot1NET, const std::vector<unsigned int>& dstIdWhitelistSlot1NET, const std::vector<unsigned int>& dstIdBlacklistSlot2NET, const std::vector<unsigned int>& dstIdWhitelistSlot2NET, const std::vector<unsigned int>& srcIdBlacklist, bool selfOnly, const std::vector<unsigned int>& prefixes, unsigned int id, unsigned int callHang, bool tgRewriteSlot1, bool tgRewriteSlot2, bool bmAutoRewrite, bool bmRewriteReflectorVoicePrompts)
|
||||
void CDMRAccessControl::init(const std::vector<unsigned int>& dstIdBlacklistSlot1RF, const std::vector<unsigned int>& dstIdWhitelistSlot1RF, const std::vector<unsigned int>& dstIdBlacklistSlot2RF, const std::vector<unsigned int>& dstIdWhitelistSlot2RF, const std::vector<unsigned int>& dstIdBlacklistSlot1NET, const std::vector<unsigned int>& dstIdWhitelistSlot1NET, const std::vector<unsigned int>& dstIdBlacklistSlot2NET, const std::vector<unsigned int>& dstIdWhitelistSlot2NET, const std::vector<unsigned int>& srcIdBlacklist, bool selfOnly, const std::vector<unsigned int>& prefixes, unsigned int id, unsigned int callHang, bool tgRewriteSlot1, bool tgRewriteSlot2, bool bmAutoRewrite, bool bmRewriteReflectorVoicePrompts)
|
||||
{
|
||||
m_dstBlackListSlot1RF = dstIdBlacklistSlot1RF;
|
||||
m_dstWhiteListSlot1RF = dstIdWhitelistSlot1RF;
|
||||
|
@ -70,7 +70,7 @@ void DMRAccessControl::init(const std::vector<unsigned int>& dstIdBlacklistSlot1
|
|||
m_bmRewriteReflectorVoicePrompts = bmRewriteReflectorVoicePrompts;
|
||||
}
|
||||
|
||||
bool DMRAccessControl::dstIdBlacklist(unsigned int did, unsigned int slot, bool network)
|
||||
bool CDMRAccessControl::dstIdBlacklist(unsigned int did, unsigned int slot, bool network)
|
||||
{
|
||||
static std::vector<unsigned int> blacklist;
|
||||
|
||||
|
@ -89,7 +89,7 @@ bool DMRAccessControl::dstIdBlacklist(unsigned int did, unsigned int slot, bool
|
|||
return std::find(blacklist.begin(), blacklist.end(), did) != blacklist.end();
|
||||
}
|
||||
|
||||
bool DMRAccessControl::dstIdWhitelist(unsigned int did, unsigned int slot, bool gt4k, bool network)
|
||||
bool CDMRAccessControl::dstIdWhitelist(unsigned int did, unsigned int slot, bool gt4k, bool network)
|
||||
{
|
||||
if (network) {
|
||||
if (slot == 1U) {
|
||||
|
@ -166,7 +166,7 @@ bool DMRAccessControl::dstIdWhitelist(unsigned int did, unsigned int slot, bool
|
|||
}
|
||||
}
|
||||
|
||||
bool DMRAccessControl::validateSrcId(unsigned int id)
|
||||
bool CDMRAccessControl::validateSrcId(unsigned int id)
|
||||
{
|
||||
if (m_selfOnly) {
|
||||
return id == m_id;
|
||||
|
@ -185,16 +185,16 @@ bool DMRAccessControl::validateSrcId(unsigned int id)
|
|||
}
|
||||
}
|
||||
|
||||
bool DMRAccessControl::validateAccess(unsigned int src_id, unsigned int dst_id, unsigned int slot, bool network)
|
||||
bool CDMRAccessControl::validateAccess(unsigned int src_id, unsigned int dst_id, unsigned int slot, bool network)
|
||||
{
|
||||
// source ID validation is only applied to RF traffic
|
||||
if (!network && !DMRAccessControl::validateSrcId(src_id)) {
|
||||
if (!network && !CDMRAccessControl::validateSrcId(src_id)) {
|
||||
LogMessage("DMR Slot %u, invalid access attempt from %u (blacklisted)", slot, src_id);
|
||||
return false;
|
||||
} else if (DMRAccessControl::dstIdBlacklist(dst_id, slot, network)) {
|
||||
} else if (CDMRAccessControl::dstIdBlacklist(dst_id, slot, network)) {
|
||||
LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG blacklisted)", slot, dst_id);
|
||||
return false;
|
||||
} else if (!DMRAccessControl::dstIdWhitelist(dst_id, slot, true, network)) {
|
||||
} else if (!CDMRAccessControl::dstIdWhitelist(dst_id, slot, true, network)) {
|
||||
LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG not in whitelist)", slot, dst_id);
|
||||
return false;
|
||||
} else {
|
||||
|
@ -202,7 +202,7 @@ bool DMRAccessControl::validateAccess(unsigned int src_id, unsigned int dst_id,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int DMRAccessControl::dstIdRewrite(unsigned int did, unsigned int sid, unsigned int slot, bool network, CDMRLC* dmrLC)
|
||||
unsigned int CDMRAccessControl::dstIdRewrite(unsigned int did, unsigned int sid, unsigned int slot, bool network, CDMRLC* dmrLC)
|
||||
{
|
||||
if (slot == 1U && !m_tgRewriteSlot1)
|
||||
return 0U;
|
||||
|
@ -213,16 +213,15 @@ unsigned int DMRAccessControl::dstIdRewrite(unsigned int did, unsigned int sid,
|
|||
time_t currenttime = ::time(NULL);
|
||||
|
||||
if (network) {
|
||||
|
||||
m_dstRewriteID[slot - 1U] = did;
|
||||
m_srcID[slot - 1U] = sid;
|
||||
|
||||
//not needed at present - for direct dial, which requires change at master end.
|
||||
// Not needed at present - for direct dial, which requires change at master end.
|
||||
//memcpy(&m_lastdmrLC, &dmrLC, sizeof(dmrLC));
|
||||
if (m_bmAutoRewrite && (did < 4000U || did > 5000U) && did > 0U && did != 9U && dmrLC->getFLCO() == FLCO_GROUP) {
|
||||
LogMessage("DMR Slot %u, Rewrite DST ID (TG) of of inbound network traffic from %u to 9", slot, did);
|
||||
return 9U;
|
||||
// rewrite incoming BM voice prompts to TG 9
|
||||
// Rewrite incoming BM voice prompts to TG 9
|
||||
} else if (m_bmRewriteReflectorVoicePrompts && (sid >= 4000U && sid <= 5000U) && dmrLC->getFLCO() == FLCO_USER_USER) {
|
||||
dmrLC->setFLCO(FLCO_GROUP);
|
||||
LogMessage("DMR Slot %u, Rewrite inbound private call to %u to Group Call on TG 9 (BM reflector voice prompt)", slot, did);
|
||||
|
@ -231,21 +230,21 @@ unsigned int DMRAccessControl::dstIdRewrite(unsigned int did, unsigned int sid,
|
|||
return 0U;
|
||||
}
|
||||
} else if (m_bmAutoRewrite && did == 9U && m_dstRewriteID[slot - 1U] != 9U && m_dstRewriteID[slot - 1U] != 0U && (m_time[slot - 1U] + m_callHang) > currenttime && dmrLC->getFLCO() == FLCO_GROUP) {
|
||||
LogMessage("DMR Slot %u, Rewrite DST ID (TG) of outbound network traffic from %u to %u (return traffic during CallHang)",slot,did,m_dstRewriteID[slot - 1]);
|
||||
LogMessage("DMR Slot %u, Rewrite DST ID (TG) of outbound network traffic from %u to %u (return traffic during CallHang)", slot, did, m_dstRewriteID[slot - 1U]);
|
||||
return m_dstRewriteID[slot - 1U];
|
||||
} else if (m_bmAutoRewrite && (did < 4000U || did > 5000U) && did > 0U && did !=9U && did < 99999U && dmrLC->getFLCO() == FLCO_USER_USER) {
|
||||
} else if (m_bmAutoRewrite && (did < 4000U || did > 5000U) && did > 0U && did != 9U && did != 9990U && did < 99999U && dmrLC->getFLCO() == FLCO_USER_USER) {
|
||||
m_dstRewriteID[slot - 1U] = did;
|
||||
dmrLC->setFLCO(FLCO_GROUP);
|
||||
LogMessage("DMR Slot %u, Rewrite outbound private call to %u Group Call (Connect talkgroup by private call)", slot, did);
|
||||
return did;
|
||||
} else if (m_bmAutoRewrite && (did < 4000U || did > 5000U) && did > 0U && did !=9U && did > 99999U) {
|
||||
} else if (m_bmAutoRewrite && (did < 4000U || did > 5000U) && did > 0U && did != 9U && did != 9990U && did > 99999U) {
|
||||
m_dstRewriteID[slot - 1U] = did;
|
||||
}
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
void DMRAccessControl::setOverEndTime(unsigned int slot)
|
||||
void CDMRAccessControl::setOverEndTime(unsigned int slot)
|
||||
{
|
||||
m_time[slot - 1U] = ::time(NULL);
|
||||
}
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
|
||||
#include "DMRLC.h"
|
||||
|
||||
class DMRAccessControl {
|
||||
class CDMRAccessControl {
|
||||
public:
|
||||
static bool validateAccess(unsigned int srcId, unsigned int dstId, unsigned int slot, bool network);
|
||||
|
||||
static bool validateSrcId(unsigned int id);
|
||||
|
||||
static void init(const std::vector<unsigned int>& dstIdBlacklistSlot1RF, const std::vector<unsigned int>& dstIdWhitelistSlot1RF, const std::vector<unsigned int>& dstIdBlacklistSlot2RF, const std::vector<unsigned int>& dstIdWhitelistSlot2RF, const std::vector<unsigned int>& dstIdBlacklistSlot1NET, const std::vector<unsigned int>& dstIdWhitelistSlot1NET, const std::vector<unsigned int>& dstIdBlacklistSlot2NET, const std::vector<unsigned int>& dstIdWhitelistSlot2NET, const std::vector<unsigned int>& srcIdBlacklist, bool selfOnly, const std::vector<unsigned int>& prefixes,unsigned int id,unsigned int callHang, bool tgRewrteSlot1, bool tgRewrteSlot2, bool m_bmAutoRewrite, bool m_bmRewriteReflectorVoicePrompts);
|
||||
|
||||
static unsigned int dstIdRewrite(unsigned int id, unsigned int sid, unsigned int slot, bool network, CDMRLC* dmrLC);
|
||||
|
@ -53,15 +55,11 @@ private:
|
|||
static bool dstIdBlacklist(unsigned int did, unsigned int slot, bool network);
|
||||
static bool dstIdWhitelist(unsigned int did, unsigned int slot, bool gt4k, bool network);
|
||||
|
||||
static bool validateSrcId(unsigned int id);
|
||||
|
||||
static time_t m_time[2];
|
||||
|
||||
|
||||
static unsigned int m_dstRewriteID[2];
|
||||
static unsigned int m_srcID[2];
|
||||
|
||||
|
||||
static bool m_tgRewriteSlot1;
|
||||
static bool m_tgRewriteSlot2;
|
||||
static bool m_bmAutoRewrite;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
#include "DMRControl.h"
|
||||
#include "DMRAccessControl.h"
|
||||
#include "Defines.h"
|
||||
#include "DMRCSBK.h"
|
||||
#include "Log.h"
|
||||
|
@ -20,23 +21,24 @@
|
|||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool TGRewriteSlot1, bool TGRewriteSlot2, bool BMAutoRewrite, bool BMRewriteReflectorVoicePrompts) :
|
||||
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& dstIdBlacklistSlot1RF, const std::vector<unsigned int>& dstIdWhitelistSlot1RF, const std::vector<unsigned int>& dstIdBlacklistSlot2RF, const std::vector<unsigned int>& dstIdWhitelistSlot2RF, const std::vector<unsigned int>& dstIdBlacklistSlot1NET, const std::vector<unsigned int>& dstIdWhitelistSlot1NET, const std::vector<unsigned int>& dstIdBlacklistSlot2NET, const std::vector<unsigned int>& dstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool tgRewriteSlot1, bool tgRewriteSlot2, bool bmAutoRewrite, bool bmRewriteReflectorVoicePrompts) :
|
||||
m_id(id),
|
||||
m_colorCode(colorCode),
|
||||
m_selfOnly(selfOnly),
|
||||
m_prefixes(prefixes),
|
||||
m_blackList(blackList),
|
||||
m_modem(modem),
|
||||
m_network(network),
|
||||
m_slot1(1U, timeout),
|
||||
m_slot2(2U, timeout),
|
||||
m_lookup(lookup)
|
||||
{
|
||||
assert(id != 0U);
|
||||
assert(modem != NULL);
|
||||
assert(display != NULL);
|
||||
assert(lookup != NULL);
|
||||
|
||||
CDMRSlot::init(id, colorCode, callHang, selfOnly, prefixes, blackList, DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, modem, network, display, duplex, m_lookup, rssiMultiplier, rssiOffset, jitter, TGRewriteSlot1, TGRewriteSlot2, BMAutoRewrite, BMRewriteReflectorVoicePrompts);
|
||||
// Load black and white lists to DMRAccessControl
|
||||
CDMRAccessControl::init(dstIdBlacklistSlot1RF, dstIdWhitelistSlot1RF, dstIdBlacklistSlot2RF, dstIdWhitelistSlot2RF, dstIdBlacklistSlot1NET, dstIdWhitelistSlot1NET, dstIdBlacklistSlot2NET, dstIdWhitelistSlot2NET, blacklist, selfOnly, prefixes, id, callHang, tgRewriteSlot1, tgRewriteSlot2, bmAutoRewrite, bmRewriteReflectorVoicePrompts);
|
||||
|
||||
CDMRSlot::init(colorCode, callHang, modem, network, display, duplex, m_lookup, rssiMultiplier, rssiOffset, jitter);
|
||||
}
|
||||
|
||||
CDMRControl::~CDMRControl()
|
||||
|
@ -65,30 +67,11 @@ bool CDMRControl::processWakeup(const unsigned char* data)
|
|||
|
||||
std::string src = m_lookup->find(srcId);
|
||||
|
||||
if (m_selfOnly) {
|
||||
if (srcId != m_id) {
|
||||
bool ret = CDMRAccessControl::validateSrcId(srcId);
|
||||
if (!ret) {
|
||||
LogMessage("Invalid CSBK BS_Dwn_Act received from %s", src.c_str());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (std::find(m_blackList.begin(), m_blackList.end(), srcId) != m_blackList.end()) {
|
||||
LogMessage("Invalid CSBK BS_Dwn_Act received from %s", src.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int prefix = srcId / 10000U;
|
||||
if (prefix == 0U || prefix > 999U) {
|
||||
LogMessage("Invalid CSBK BS_Dwn_Act received from %s", src.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_prefixes.size() > 0U) {
|
||||
if (std::find(m_prefixes.begin(), m_prefixes.end(), prefix) == m_prefixes.end()) {
|
||||
LogMessage("Invalid CSBK BS_Dwn_Act received from %s", src.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bsId == 0xFFFFFFU) {
|
||||
LogMessage("CSBK BS_Dwn_Act for ANY received from %s", src.c_str());
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
class CDMRControl {
|
||||
public:
|
||||
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF,const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool TGRewriteSlot1, bool TGRewriteSlot2, bool BMAutoRewrite, bool BMRewriteReflectorVoicePrompts);
|
||||
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& dstIdBlacklistSlot1RF, const std::vector<unsigned int>& dstIdWhitelistSlot1RF, const std::vector<unsigned int>& dstIdBlacklistSlot2RF, const std::vector<unsigned int>& dstIdWhitelistSlot2RF,const std::vector<unsigned int>& dstIdBlacklistSlot1NET, const std::vector<unsigned int>& dstIdWhitelistSlot1NET, const std::vector<unsigned int>& dstIdBlacklistSlot2NET, const std::vector<unsigned int>& dstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool tgRewriteSlot1, bool tgRewriteSlot2, bool bmAutoRewrite, bool bmRewriteReflectorVoicePrompts);
|
||||
~CDMRControl();
|
||||
|
||||
bool processWakeup(const unsigned char* data);
|
||||
|
@ -46,9 +46,6 @@ public:
|
|||
private:
|
||||
unsigned int m_id;
|
||||
unsigned int m_colorCode;
|
||||
bool m_selfOnly;
|
||||
std::vector<unsigned int> m_prefixes;
|
||||
std::vector<unsigned int> m_blackList;
|
||||
CModem* m_modem;
|
||||
CDMRNetwork* m_network;
|
||||
CDMRSlot m_slot1;
|
||||
|
|
1145
DMRIds.dat
1145
DMRIds.dat
File diff suppressed because it is too large
Load diff
|
@ -361,6 +361,7 @@ void CDMRNetwork::clock(unsigned int ms)
|
|||
} else if (::memcmp(m_buffer, "RPTACK", 6U) == 0) {
|
||||
switch (m_status) {
|
||||
case WAITING_LOGIN:
|
||||
LogDebug("DMR, Sending authorisation");
|
||||
::memcpy(m_salt, m_buffer + 6U, sizeof(uint32_t));
|
||||
writeAuthorisation();
|
||||
m_status = WAITING_AUTHORISATION;
|
||||
|
@ -368,10 +369,18 @@ void CDMRNetwork::clock(unsigned int ms)
|
|||
m_retryTimer.start();
|
||||
break;
|
||||
case WAITING_AUTHORISATION:
|
||||
if (m_options.empty()) {
|
||||
LogDebug("DMR, Sending configuration");
|
||||
writeConfig();
|
||||
m_status = WAITING_CONFIG;
|
||||
m_timeoutTimer.start();
|
||||
m_retryTimer.start();
|
||||
break;
|
||||
case WAITING_CONFIG:
|
||||
if (m_options.empty()) {
|
||||
LogMessage("DMR, Logged into the master successfully");
|
||||
m_status = RUNNING;
|
||||
} else {
|
||||
LogDebug("DMR, Sending options");
|
||||
writeOptions();
|
||||
m_status = WAITING_OPTIONS;
|
||||
}
|
||||
|
@ -379,12 +388,6 @@ void CDMRNetwork::clock(unsigned int ms)
|
|||
m_retryTimer.start();
|
||||
break;
|
||||
case WAITING_OPTIONS:
|
||||
writeConfig();
|
||||
m_status = WAITING_CONFIG;
|
||||
m_timeoutTimer.start();
|
||||
m_retryTimer.start();
|
||||
break;
|
||||
case WAITING_CONFIG:
|
||||
LogMessage("DMR, Logged into the master successfully");
|
||||
m_status = RUNNING;
|
||||
m_timeoutTimer.start();
|
||||
|
@ -473,9 +476,12 @@ bool CDMRNetwork::writeAuthorisation()
|
|||
bool CDMRNetwork::writeOptions()
|
||||
{
|
||||
char buffer[300U];
|
||||
::sprintf(buffer, "RPTO%s", m_options.c_str());
|
||||
|
||||
return write((unsigned char*)buffer, (unsigned int)::strlen(buffer));
|
||||
::memcpy(buffer + 0U, "RPTO", 4U);
|
||||
::memcpy(buffer + 4U, m_id, 4U);
|
||||
::strcpy(buffer + 8U, m_options.c_str());
|
||||
|
||||
return write((unsigned char*)buffer, (unsigned int)m_options.length() + 8U);
|
||||
}
|
||||
|
||||
bool CDMRNetwork::writeConfig()
|
||||
|
@ -516,7 +522,7 @@ bool CDMRNetwork::writeConfig()
|
|||
char longitude[20U];
|
||||
::sprintf(longitude, "%09f", m_longitude);
|
||||
|
||||
::sprintf(buffer + 8U, "%-8.8s%09u%09u%02u%02u%.8s%.9s%03d%-20.20s%-19.19s%c%-124.124s%-40.40s%-40.40s", m_callsign.c_str(),
|
||||
::sprintf(buffer + 8U, "%-8.8s%09u%09u%02u%02u%8.8s%9.9s%03d%-20.20s%-19.19s%c%-124.124s%-40.40s%-40.40s", m_callsign.c_str(),
|
||||
m_rxFrequency, m_txFrequency, m_power, m_colorCode, latitude, longitude, m_height, m_location.c_str(),
|
||||
m_description.c_str(), slots, m_url.c_str(), m_version, software);
|
||||
|
||||
|
@ -553,7 +559,7 @@ bool CDMRNetwork::write(const unsigned char* data, unsigned int length)
|
|||
bool ret = m_socket.write(data, length, m_address, m_port);
|
||||
if (!ret) {
|
||||
LogError("DMR, Socket has failed when writing data to the master, retrying connection");
|
||||
close();
|
||||
m_socket.close();
|
||||
open();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -71,8 +71,8 @@ private:
|
|||
WAITING_CONNECT,
|
||||
WAITING_LOGIN,
|
||||
WAITING_AUTHORISATION,
|
||||
WAITING_OPTIONS,
|
||||
WAITING_CONFIG,
|
||||
WAITING_OPTIONS,
|
||||
RUNNING
|
||||
};
|
||||
|
||||
|
|
50
DMRSlot.cpp
50
DMRSlot.cpp
|
@ -28,11 +28,7 @@
|
|||
#include <ctime>
|
||||
#include <algorithm>
|
||||
|
||||
unsigned int CDMRSlot::m_id = 0U;
|
||||
unsigned int CDMRSlot::m_colorCode = 0U;
|
||||
bool CDMRSlot::m_selfOnly = false;
|
||||
std::vector<unsigned int> CDMRSlot::m_prefixes;
|
||||
std::vector<unsigned int> CDMRSlot::m_blackList;
|
||||
|
||||
CModem* CDMRSlot::m_modem = NULL;
|
||||
CDMRNetwork* CDMRSlot::m_network = NULL;
|
||||
|
@ -155,12 +151,12 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
unsigned int srcId = lc->getSrcId();
|
||||
unsigned int dstId = lc->getDstId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) {
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) {
|
||||
delete lc;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int rewriteId = DMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, false, lc);
|
||||
unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, false, lc);
|
||||
if (rewriteId != 0U) {
|
||||
lc->setDstId(rewriteId);
|
||||
dstId = rewriteId;
|
||||
|
@ -263,7 +259,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
LogMessage("DMR Slot %u, received RF end of voice transmission, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
|
||||
writeEndRF();
|
||||
DMRAccessControl::setOverEndTime(m_slotNo);
|
||||
CDMRAccessControl::setOverEndTime(m_slotNo);
|
||||
} else if (dataType == DT_DATA_HEADER) {
|
||||
if (m_rfState == RS_RF_DATA)
|
||||
return;
|
||||
|
@ -277,7 +273,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
unsigned int srcId = dataHeader.getSrcId();
|
||||
unsigned int dstId = dataHeader.getDstId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false))
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false))
|
||||
return;
|
||||
|
||||
m_rfFrames = dataHeader.getBlocks();
|
||||
|
@ -333,8 +329,10 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
unsigned int srcId = csbk.getSrcId();
|
||||
unsigned int dstId = csbk.getDstId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false))
|
||||
if (srcId != 0U || dstId != 0U) {
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false))
|
||||
return;
|
||||
}
|
||||
|
||||
// Regenerate the CSBK data
|
||||
csbk.get(data + 2U);
|
||||
|
@ -491,12 +489,12 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||
unsigned int srcId = lc->getSrcId();
|
||||
unsigned int dstId = lc->getDstId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) {
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) {
|
||||
delete lc;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int rewriteId = DMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, false, lc);
|
||||
unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, false, lc);
|
||||
if (rewriteId != 0U) {
|
||||
lc->setDstId(rewriteId);
|
||||
dstId = rewriteId;
|
||||
|
@ -778,7 +776,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
unsigned int dstId = lc->getDstId();
|
||||
unsigned int srcId = lc->getSrcId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) {
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) {
|
||||
delete lc;
|
||||
return;
|
||||
}
|
||||
|
@ -786,7 +784,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
m_netLC = lc;
|
||||
|
||||
// Test dst rewrite
|
||||
unsigned int rewriteId = DMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC);
|
||||
unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC);
|
||||
if (rewriteId != 0U) {
|
||||
m_netLC->setDstId(rewriteId);
|
||||
dstId = rewriteId;
|
||||
|
@ -853,7 +851,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
unsigned int dstId = lc->getDstId();
|
||||
unsigned int srcId = lc->getSrcId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) {
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) {
|
||||
delete lc;
|
||||
return;
|
||||
}
|
||||
|
@ -861,7 +859,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
m_netLC = lc;
|
||||
|
||||
// Test dst rewrite
|
||||
unsigned int rewriteId = DMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC);
|
||||
unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC);
|
||||
if (rewriteId != 0U) {
|
||||
m_netLC->setDstId(rewriteId);
|
||||
dstId = rewriteId;
|
||||
|
@ -979,7 +977,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
LogMessage("DMR Slot %u, received network end of voice transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
||||
|
||||
writeEndNet();
|
||||
DMRAccessControl::setOverEndTime(m_slotNo);
|
||||
CDMRAccessControl::setOverEndTime(m_slotNo);
|
||||
} else if (dataType == DT_DATA_HEADER) {
|
||||
if (m_netState == RS_NET_DATA)
|
||||
return;
|
||||
|
@ -997,7 +995,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
unsigned int srcId = dataHeader.getSrcId();
|
||||
unsigned int dstId = dataHeader.getDstId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true))
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true))
|
||||
return;
|
||||
|
||||
m_netFrames = dataHeader.getBlocks();
|
||||
|
@ -1043,7 +1041,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
unsigned int dstId = lc->getDstId();
|
||||
unsigned int srcId = lc->getSrcId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) {
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) {
|
||||
delete lc;
|
||||
return;
|
||||
}
|
||||
|
@ -1051,7 +1049,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
m_netLC = lc;
|
||||
|
||||
// Test dst rewrite
|
||||
unsigned int rewriteId = DMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC);
|
||||
unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC);
|
||||
if (rewriteId != 0U) {
|
||||
m_netLC->setDstId(rewriteId);
|
||||
dstId = rewriteId;
|
||||
|
@ -1209,8 +1207,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
unsigned int srcId = csbk.getSrcId();
|
||||
unsigned int dstId = csbk.getDstId();
|
||||
|
||||
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true))
|
||||
if (srcId != 0U || dstId != 0U) {
|
||||
if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true))
|
||||
return;
|
||||
}
|
||||
|
||||
// Regenerate the CSBK data
|
||||
csbk.get(data + 2U);
|
||||
|
@ -1431,18 +1431,13 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
|
|||
m_queue.addData(data, len);
|
||||
}
|
||||
|
||||
void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& SrcIdBlacklist, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool TGRewriteSlot1, bool TGRewriteSlot2, bool BMAutoRewrite, bool BMRewriteReflectorVoicePrompts)
|
||||
void CDMRSlot::init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter)
|
||||
{
|
||||
assert(id != 0U);
|
||||
assert(modem != NULL);
|
||||
assert(display != NULL);
|
||||
assert(lookup != NULL);
|
||||
|
||||
m_id = id;
|
||||
m_colorCode = colorCode;
|
||||
m_selfOnly = selfOnly;
|
||||
m_prefixes = prefixes;
|
||||
// m_blackList = blackList;
|
||||
m_modem = modem;
|
||||
m_network = network;
|
||||
m_display = display;
|
||||
|
@ -1464,9 +1459,6 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHa
|
|||
slotType.setColorCode(colorCode);
|
||||
slotType.setDataType(DT_IDLE);
|
||||
slotType.getData(m_idle + 2U);
|
||||
|
||||
//Load black and white lists to DMRAccessControl
|
||||
DMRAccessControl::init(DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, SrcIdBlacklist, m_selfOnly, m_prefixes, m_id,callHang, TGRewriteSlot1, TGRewriteSlot2, BMAutoRewrite, BMRewriteReflectorVoicePrompts);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
|
||||
void clock();
|
||||
|
||||
static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& SrcIdBlackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool TGRewriteSlot1, bool TGRewriteSlot2, bool BMAutoRewrite, bool BMRewriteReflectorVoicePrompts);
|
||||
static void init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter);
|
||||
|
||||
private:
|
||||
unsigned int m_slotNo;
|
||||
|
@ -87,11 +87,7 @@ private:
|
|||
unsigned char m_rssi;
|
||||
FILE* m_fp;
|
||||
|
||||
static unsigned int m_id;
|
||||
static unsigned int m_colorCode;
|
||||
static bool m_selfOnly;
|
||||
static std::vector<unsigned int> m_prefixes;
|
||||
static std::vector<unsigned int> m_blackList;
|
||||
|
||||
static CModem* m_modem;
|
||||
static CDMRNetwork* m_network;
|
||||
|
|
32
DMRplus_startup_options.md
Normal file
32
DMRplus_startup_options.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
# DMRplus - Startup Options
|
||||
|
||||
## Introduction
|
||||
This file is to give an overview over the Options-parameter in MMDVM.ini [DMR Network]-section.
|
||||
|
||||
## Example
|
||||
You can pull some conection-info at startup to the DMRplus-Network to define the behavior of TS1 and TS2 in DMR-mode.
|
||||
An example of such a line would be following:
|
||||
|
||||
Options=StartRef=4013;RelinkTime=15;UserLink=1;TS1_1=262;TS1_2=1;TS1_3=20;TS1_4=110;TS1_5=270;
|
||||
|
||||
If an option is set, it overwrites the setting preset at the master, if an option is empty, it unsets a predefined setting from
|
||||
the master. If an option is not set, the default from the master would be taken over.
|
||||
|
||||
## What the parameters are about?
|
||||
|
||||
Here is a quick explaination about the options to be set:
|
||||
|
||||
* StartRef: This is the default reflector in TS2, in example: Refl. 4013
|
||||
* RelinkTime: This is the time to fall back to the default-reflector if linked to another one and no local traffic is done,
|
||||
not yet implemented, would come next
|
||||
* UserLink: This defines, if users are allowed to link to another reflector (other than defined as startreflector)
|
||||
* 1 = allow
|
||||
* 0 = disallow
|
||||
* TS1_1: This is the first of 5 talkgroups that could be set static, in example: TG262
|
||||
* TS1_2: This is the second of 5 talkgroups that could be set static, in example: TG1
|
||||
* TS1_3: This is the third of 5 talkgroups that could be set static, in example: TG20
|
||||
* TS1_4: This is the fourth of 5 talkgroups that could be set static, in example: TG110
|
||||
* TS1_5: This is the fifth of 5 talkgroups that could be set static, in example: TG270
|
||||
|
||||
---
|
||||
Info created by DG9VH 2016-11-11
|
|
@ -1,9 +0,0 @@
|
|||
G0WFV's HD44780 todo list ...
|
||||
|
||||
As I only have a 2x16 screen at the moment, development has been done based
|
||||
on this size screen. Where it is simple, I have attempted ***but not tested***
|
||||
to implement functions for larger screens.
|
||||
|
||||
Here's a list of things I would like to accomplish in the near future ...
|
||||
|
||||
- Nothing planned at this time! Any suggestions?
|
52
LCDproc.cpp
52
LCDproc.cpp
|
@ -16,6 +16,35 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some LCD displays include additional LEDs for status.
|
||||
* If they exist, the LDCproc server will use the output command.
|
||||
* If the LEDs do not exist, the command is ignored.
|
||||
* to control these LEDs Below are the values for the Crystalfontz CFA-635.
|
||||
* N4IRS
|
||||
|
||||
* LED 1 (DMR)
|
||||
* Green 1 0000 0001
|
||||
* Red 16 0001 0000
|
||||
* Yellow 17 0001 0001
|
||||
|
||||
* LED 2 (P25)
|
||||
* Green 2 0000 0010
|
||||
* Red 32 0010 0000
|
||||
* Yellow 34 0010 0010
|
||||
|
||||
* LED 3 (Fusion)
|
||||
* Green 4 0000 0100
|
||||
* Red 64 0100 0000
|
||||
* Yellow 68 1000 0100
|
||||
|
||||
* LED 4 (D-Star)
|
||||
* Green 8 0000 1000
|
||||
* Red 128 1000 0000
|
||||
* Yellow 136 1000 1000
|
||||
|
||||
*/
|
||||
|
||||
#include "LCDproc.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
@ -23,6 +52,7 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <clocale>
|
||||
#include <ctime>
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
|
@ -120,6 +150,7 @@ bool CLCDproc::open()
|
|||
}
|
||||
|
||||
socketPrintf(m_socketfd, "hello"); // Login to the LCD server
|
||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -134,6 +165,7 @@ void CLCDproc::setIdleInt()
|
|||
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
||||
socketPrintf(m_socketfd, "widget_set Status Status %u %u Idle", m_cols - 3, m_rows);
|
||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
|
@ -151,6 +183,7 @@ void CLCDproc::setErrorInt(const char* text)
|
|||
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
||||
socketPrintf(m_socketfd, "widget_set Status Status %u %u Error", m_cols - 4, m_rows);
|
||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
|
@ -166,11 +199,14 @@ void CLCDproc::setLockoutInt()
|
|||
socketPrintf(m_socketfd, "screen_set YSF -priority hidden");
|
||||
socketPrintf(m_socketfd, "screen_set P25 -priority hidden");
|
||||
socketPrintf(m_socketfd, "widget_set Status Status %u %u Lockout", m_cols - 6, m_rows);
|
||||
socketPrintf(m_socketfd, "output 0"); // Clear all LEDs
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
}
|
||||
|
||||
// LED 4 Green 8 Red 128 Yellow 136
|
||||
|
||||
void CLCDproc::writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector)
|
||||
{
|
||||
assert(my1 != NULL);
|
||||
|
@ -202,6 +238,7 @@ void CLCDproc::writeDStarInt(const char* my1, const char* my2, const char* your,
|
|||
} else {
|
||||
socketPrintf(m_socketfd, "widget_set DStar Line2 1 2 %u 2 h 3 \"%.8s/%.4s\"", m_cols - 1, my1, my2);
|
||||
socketPrintf(m_socketfd, "widget_set DStar Line3 1 3 %u 3 h 3 \"%s%s\"", m_cols - 1, m_displayBuffer1, m_displayBuffer2);
|
||||
socketPrintf(m_socketfd, "output 128"); // Set LED4 color red
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
|
@ -214,8 +251,11 @@ void CLCDproc::clearDStarInt()
|
|||
socketPrintf(m_socketfd, "widget_set DStar Line2 1 2 15 2 h 3 Listening");
|
||||
socketPrintf(m_socketfd, "widget_set DStar Line3 1 3 15 3 h 3 \"\"");
|
||||
socketPrintf(m_socketfd, "widget_set DStar Line4 1 4 15 4 h 3 \"\"");
|
||||
socketPrintf(m_socketfd, "output 8"); // Set LED4 color green
|
||||
}
|
||||
|
||||
// LED 1 Green 1 Red 16 Yellow 17
|
||||
|
||||
void CLCDproc::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
||||
{
|
||||
assert(type != NULL);
|
||||
|
@ -228,7 +268,6 @@ void CLCDproc::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
if (m_duplex) {
|
||||
if (m_rows > 2U)
|
||||
socketPrintf(m_socketfd, "widget_set DMR Mode 1 1 DMR");
|
||||
|
||||
if (slotNo == 1U)
|
||||
socketPrintf(m_socketfd, "widget_set DMR Slot2 3 %u %u %u h 3 \"Listening\"", m_rows / 2 + 1, m_cols - 1, m_rows / 2 + 1);
|
||||
else
|
||||
|
@ -260,7 +299,7 @@ void CLCDproc::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
socketPrintf(m_socketfd, "widget_set DMR Slot2 1 3 %u 3 h 3 \"%s%s\"", m_cols - 1, group ? "TG" : "", dst.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
socketPrintf(m_socketfd, "output 16"); // Set LED1 color red
|
||||
m_dmr = true;
|
||||
}
|
||||
|
||||
|
@ -277,8 +316,11 @@ void CLCDproc::clearDMRInt(unsigned int slotNo)
|
|||
socketPrintf(m_socketfd, "widget_set DMR Slot1 1 2 15 2 h 3 Listening");
|
||||
socketPrintf(m_socketfd, "widget_set DMR Slot2 1 3 15 3 h 3 \"\"");
|
||||
}
|
||||
socketPrintf(m_socketfd, "output 1"); // Set LED1 color green
|
||||
}
|
||||
|
||||
// LED 3 Green 4 Red 64 Yellow 68
|
||||
|
||||
void CLCDproc::writeFusionInt(const char* source, const char* dest, const char* type, const char* origin)
|
||||
{
|
||||
assert(source != NULL);
|
||||
|
@ -296,6 +338,7 @@ void CLCDproc::writeFusionInt(const char* source, const char* dest, const char*
|
|||
} else {
|
||||
socketPrintf(m_socketfd, "widget_set YSF Line2 1 2 15 2 h 3 \"%.10s >\"", source);
|
||||
socketPrintf(m_socketfd, "widget_set YSF Line3 1 3 15 3 h 3 \"%s%u\"", dest);
|
||||
socketPrintf(m_socketfd, "output 64"); // Set LED3 color red
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
|
@ -308,8 +351,11 @@ void CLCDproc::clearFusionInt()
|
|||
socketPrintf(m_socketfd, "widget_set YSF Line2 1 2 15 2 h 3 Listening");
|
||||
socketPrintf(m_socketfd, "widget_set YSF Line3 1 3 15 3 h 3 \"\"");
|
||||
socketPrintf(m_socketfd, "widget_set YSF Line4 1 4 15 4 h 3 \"\"");
|
||||
socketPrintf(m_socketfd, "output 4"); // Set LED3 color green
|
||||
}
|
||||
|
||||
// LED 2 Green 2 Red 32 Yellow 34
|
||||
|
||||
void CLCDproc::writeP25Int(const char* source, bool group, unsigned int dest, const char* type)
|
||||
{
|
||||
assert(source != NULL);
|
||||
|
@ -325,6 +371,7 @@ void CLCDproc::writeP25Int(const char* source, bool group, unsigned int dest, co
|
|||
} else {
|
||||
socketPrintf(m_socketfd, "widget_set P25 Line2 1 2 15 2 h 3 \"%.10s >\"", source);
|
||||
socketPrintf(m_socketfd, "widget_set P25 Line3 1 3 15 3 h 3 \"%s%u\"", group ? "TG" : "", dest);
|
||||
socketPrintf(m_socketfd, "output 32"); // Set LED2 color red
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
|
@ -337,6 +384,7 @@ void CLCDproc::clearP25Int()
|
|||
socketPrintf(m_socketfd, "widget_set P25 Line3 1 2 15 2 h 3 Listening");
|
||||
socketPrintf(m_socketfd, "widget_set P25 Line3 1 3 15 3 h 3 \"\"");
|
||||
socketPrintf(m_socketfd, "widget_set P25 Line4 1 4 15 4 h 3 \"\"");
|
||||
socketPrintf(m_socketfd, "output 2"); // Set LED2 color green
|
||||
}
|
||||
|
||||
void CLCDproc::writeCWInt()
|
||||
|
|
|
@ -191,7 +191,7 @@ int CMMDVMHost::run()
|
|||
::close(STDIN_FILENO);
|
||||
::close(STDOUT_FILENO);
|
||||
::close(STDERR_FILENO);
|
||||
#if !defined(HD44780)
|
||||
#if !defined(HD44780) && !defined(OLED)
|
||||
//If we are currently root...
|
||||
if (getuid() == 0) {
|
||||
struct passwd* user = ::getpwnam("mmdvm");
|
||||
|
@ -334,10 +334,10 @@ int CMMDVMHost::run()
|
|||
unsigned int id = m_conf.getDMRId();
|
||||
unsigned int colorCode = m_conf.getDMRColorCode();
|
||||
bool selfOnly = m_conf.getDMRSelfOnly();
|
||||
bool TGRewriteSlot1 = m_conf.getDMRTGRewriteSlot1();
|
||||
bool TGRewriteSlot2 = m_conf.getDMRTGRewriteSlot2();
|
||||
bool BMAutoRewrite = m_conf.getDMRBMAutoRewrite();
|
||||
bool BMRewriteReflectorVoicePrompts = m_conf.getDMRBMRewriteReflectorVoicePrompts();
|
||||
bool tgRewriteSlot1 = m_conf.getDMRTGRewriteSlot1();
|
||||
bool tgRewriteSlot2 = m_conf.getDMRTGRewriteSlot2();
|
||||
bool bmAutoRewrite = m_conf.getDMRBMAutoRewrite();
|
||||
bool bmRewriteReflectorVoicePrompts = m_conf.getDMRBMRewriteReflectorVoicePrompts();
|
||||
std::vector<unsigned int> prefixes = m_conf.getDMRPrefixes();
|
||||
std::vector<unsigned int> blackList = m_conf.getDMRBlackList();
|
||||
std::vector<unsigned int> dstIDBlackListSlot1RF = m_conf.getDMRDstIdBlacklistSlot1RF();
|
||||
|
@ -395,17 +395,16 @@ int CMMDVMHost::run()
|
|||
LogInfo(" RSSI Offset: %d", rssiOffset);
|
||||
}
|
||||
|
||||
if (TGRewriteSlot1)
|
||||
if (tgRewriteSlot1)
|
||||
LogInfo(" TG Rewrite Slot 1 enabled");
|
||||
|
||||
if (TGRewriteSlot2)
|
||||
if (tgRewriteSlot2)
|
||||
LogInfo(" TG Rewrite Slot 2 enabled");
|
||||
if (BMAutoRewrite)
|
||||
if (bmAutoRewrite)
|
||||
LogInfo(" BrandMeister Auto Rewrite enabled");
|
||||
if (BMRewriteReflectorVoicePrompts)
|
||||
if (bmRewriteReflectorVoicePrompts)
|
||||
LogInfo(" BrandMeister Rewrite Reflector Voice Prompts enabled");
|
||||
|
||||
dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList,dstIDBlackListSlot1RF,dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssiMultiplier, rssiOffset, jitter, TGRewriteSlot1, TGRewriteSlot2, BMAutoRewrite, BMRewriteReflectorVoicePrompts);
|
||||
dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList, dstIDBlackListSlot1RF, dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssiMultiplier, rssiOffset, jitter, tgRewriteSlot1, tgRewriteSlot2, bmAutoRewrite, bmRewriteReflectorVoicePrompts);
|
||||
|
||||
m_dmrTXTimer.setTimeout(txHang);
|
||||
}
|
||||
|
@ -453,6 +452,8 @@ int CMMDVMHost::run()
|
|||
if (m_ump != NULL) {
|
||||
bool tx = m_modem->hasTX();
|
||||
m_ump->setTX(tx);
|
||||
bool cd = m_modem->hasCD();
|
||||
m_ump->setCD(cd);
|
||||
}
|
||||
|
||||
unsigned char data[200U];
|
||||
|
|
|
@ -128,6 +128,7 @@ m_dmrSpace2(0U),
|
|||
m_ysfSpace(0U),
|
||||
m_p25Space(0U),
|
||||
m_tx(false),
|
||||
m_cd(false),
|
||||
m_lockout(false),
|
||||
m_error(false),
|
||||
m_hwType(HWT_UNKNOWN)
|
||||
|
@ -421,6 +422,7 @@ void CModem::clock(unsigned int ms)
|
|||
// CUtils::dump(1U, "GET_STATUS", m_buffer, m_length);
|
||||
|
||||
m_tx = (m_buffer[5U] & 0x01U) == 0x01U;
|
||||
m_cd = (m_buffer[5U] & 0x02U) == 0x02U;
|
||||
|
||||
bool adcOverflow = (m_buffer[5U] & 0x02U) == 0x02U;
|
||||
if (adcOverflow)
|
||||
|
@ -447,7 +449,7 @@ void CModem::clock(unsigned int ms)
|
|||
m_p25Space = m_buffer[10U];
|
||||
|
||||
m_inactivityTimer.start();
|
||||
// LogMessage("status=%02X, tx=%d, space=%u,%u,%u,%u,%u lockout=%d", m_buffer[5U], int(m_tx), m_dstarSpace, m_dmrSpace1, m_dmrSpace2, m_ysfSpace, m_p25Space, int(m_lockout));
|
||||
// LogMessage("status=%02X, tx=%d, space=%u,%u,%u,%u,%u lockout=%d, cd=%d", m_buffer[5U], int(m_tx), m_dstarSpace, m_dmrSpace1, m_dmrSpace2, m_ysfSpace, m_p25Space, int(m_lockout), int(m_cd));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -852,6 +854,11 @@ bool CModem::hasTX() const
|
|||
return m_tx;
|
||||
}
|
||||
|
||||
bool CModem::hasCD() const
|
||||
{
|
||||
return m_cd;
|
||||
}
|
||||
|
||||
bool CModem::hasLockout() const
|
||||
{
|
||||
return m_lockout;
|
||||
|
|
2
Modem.h
2
Modem.h
|
@ -59,6 +59,7 @@ public:
|
|||
bool hasP25Space() const;
|
||||
|
||||
bool hasTX() const;
|
||||
bool hasCD() const;
|
||||
|
||||
bool hasLockout() const;
|
||||
bool hasError() const;
|
||||
|
@ -131,6 +132,7 @@ private:
|
|||
unsigned int m_ysfSpace;
|
||||
unsigned int m_p25Space;
|
||||
bool m_tx;
|
||||
bool m_cd;
|
||||
bool m_lockout;
|
||||
bool m_error;
|
||||
HW_TYPE m_hwType;
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Nextion/NX3224K024.HMI
Normal file
BIN
Nextion/NX3224K024.HMI
Normal file
Binary file not shown.
BIN
Nextion/NX3224K024.tft
Normal file
BIN
Nextion/NX3224K024.tft
Normal file
Binary file not shown.
BIN
Nextion/NX3224K028.HMI
Normal file
BIN
Nextion/NX3224K028.HMI
Normal file
Binary file not shown.
BIN
Nextion/NX3224K028.tft
Normal file
BIN
Nextion/NX3224K028.tft
Normal file
Binary file not shown.
BIN
Nextion/NX3224T024.HMI
Normal file
BIN
Nextion/NX3224T024.HMI
Normal file
Binary file not shown.
Binary file not shown.
BIN
Nextion/NX3224T028.HMI
Normal file
BIN
Nextion/NX3224T028.HMI
Normal file
Binary file not shown.
BIN
Nextion/NX4024K032.HMI
Normal file
BIN
Nextion/NX4024K032.HMI
Normal file
Binary file not shown.
BIN
Nextion/NX4024K032.tft
Normal file
BIN
Nextion/NX4024K032.tft
Normal file
Binary file not shown.
BIN
Nextion/NX4024T032.HMI
Normal file
BIN
Nextion/NX4024T032.HMI
Normal file
Binary file not shown.
Binary file not shown.
BIN
Nextion/NX4832K035.tft
Normal file
BIN
Nextion/NX4832K035.tft
Normal file
Binary file not shown.
BIN
Nextion/NX4832T035.HMI
Normal file
BIN
Nextion/NX4832T035.HMI
Normal file
Binary file not shown.
66
Nextion/README.md
Normal file
66
Nextion/README.md
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Update Nextion Displays from the Command Line
|
||||
|
||||
This directory contains a simple python script which you can use to update the
|
||||
Nextion displays. All you need is a compiled .tft file which is written to the
|
||||
display's flash memory. The precompiled .tft files with the MMDVMHost default
|
||||
layout are to be found in this directory as well.
|
||||
|
||||
To update the Nextion display you just need to know the serial port the display
|
||||
is connected to. It could be /dev/ttyUSBx for USB<->Serial adapters or
|
||||
/dev/ttyAMA0 for the UART on the Raspberry Pi for example.
|
||||
|
||||
# Prerequisites
|
||||
|
||||
You need to have python installed as well as the python-serial package. That can
|
||||
normally be found in your distro's package manager.
|
||||
|
||||
# File Naming Convention
|
||||
|
||||
There are compiled .tft files in the repo for basic and enhanced Nextion
|
||||
displays of sizes 2.4", 2.8", 3.2" and 3.5". Please choose depending on the
|
||||
model number printed on the back of the display.
|
||||
|
||||
The basic displays are denoted by a "T" as 7th character in the filename and
|
||||
model number whereas enhanced displays have a "K" in that position. The actual
|
||||
display size can be derived from the last two digits. The four digits in between
|
||||
the characters refert to the diplay's resolution.
|
||||
|
||||
For example: A model number NX4832T035 represents a display with:
|
||||
|
||||
- a resolution of 320x480 pixels
|
||||
- basic command set
|
||||
- a screen size of 3.5"
|
||||
|
||||
# Updating the Display
|
||||
|
||||
Now comes the easy part. Just execute:
|
||||
|
||||
```
|
||||
$ python nextion.py NX4832T035.tft /dev/ttyUSB0
|
||||
```
|
||||
|
||||
And the output should be as follows:
|
||||
|
||||
```
|
||||
Trying with baudrate: 2400...
|
||||
Trying with baudrate: 4800...
|
||||
Trying with baudrate: 9600...
|
||||
Connected with baudrate: 9600...
|
||||
Status: comok
|
||||
Touchscreen: yes
|
||||
Model: NX4832T035_011R
|
||||
Firmware version: 68
|
||||
MCU code: 61488
|
||||
Serial: D2658880C35D2124
|
||||
Flash size: 16777216
|
||||
Downloading, 100%...
|
||||
File transferred successfully
|
||||
```
|
||||
|
||||
# Known errors
|
||||
|
||||
Especially when using USB<->Serial adapters there are cases in which the scripts
|
||||
stops at different times. This is known and due to the very simple update
|
||||
protocol. In this case you have to fix the display by using a SD-Card to update
|
||||
the display. The /dev/ttyAMAx ports do not seems to suffer from this issue.
|
||||
|
|
@ -36,10 +36,15 @@ def getBaudrate(ser, fSize=None, checkModel=None):
|
|||
if 'comok' in r:
|
||||
print 'Connected with baudrate: ' + str(baudrate) + '...'
|
||||
noConnect = False
|
||||
status, unknown1, model, unknown2, version, serial, flashSize = r.strip("\xff\x00").split(',')
|
||||
print 'Status: ' + status
|
||||
status, unknown1, model, fwversion, mcucode, serial, flashSize = r.strip("\xff\x00").split(',')
|
||||
print 'Status: ' + status.split(' ')[0]
|
||||
if status.split(' ')[1] == "1":
|
||||
print 'Touchscreen: yes'
|
||||
else:
|
||||
print 'Touchscreen: no'
|
||||
print 'Model: ' + model
|
||||
print 'Version: ' + version
|
||||
print 'Firmware version: ' + fwversion
|
||||
print 'MCU code: ' + mcucode
|
||||
print 'Serial: ' + serial
|
||||
print 'Flash size: ' + flashSize
|
||||
if fSize and fSize > flashSize:
|
||||
|
@ -80,23 +85,26 @@ def transferFile(ser, filename, fSize):
|
|||
if "\x05" in r:
|
||||
continue
|
||||
else:
|
||||
print
|
||||
return False
|
||||
break
|
||||
print
|
||||
return True
|
||||
|
||||
def upload(ser, filename, checkModel=None):
|
||||
if not getBaudrate(ser, os.path.getsize(filename), checkModel):
|
||||
print 'could not find baudrate'
|
||||
print 'Could not find baudrate'
|
||||
exit(1)
|
||||
|
||||
if not setDownloadBaudrate(ser, os.path.getsize(filename), 115200):
|
||||
print 'could not set download baudrate'
|
||||
print 'Could not set download baudrate'
|
||||
exit(1)
|
||||
|
||||
if not transferFile(ser, filename, os.path.getsize(filename)):
|
||||
print 'could not transfer file'
|
||||
print 'Could not transfer file'
|
||||
exit(1)
|
||||
|
||||
print 'File transferred successfully'
|
||||
exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -111,7 +119,7 @@ if __name__ == "__main__":
|
|||
except serial.serialutil.SerialException:
|
||||
print 'could not open serial device ' + sys.argv[2]
|
||||
exit(1)
|
||||
if (serial.VERSION <= "3.0"):
|
||||
if serial.VERSION <= "3.0":
|
||||
if not ser.isOpen():
|
||||
ser.open()
|
||||
else:
|
||||
|
|
26
OLED.cpp
26
OLED.cpp
|
@ -56,6 +56,26 @@ static unsigned char logo_dmr_bmp[] =
|
|||
0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111
|
||||
};
|
||||
|
||||
//D-Star 64x16 px
|
||||
static unsigned char logo_dstar_bmp[] =
|
||||
{ 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b10000001, 0b11111100, 0b00000000, 0b00111100, 0b00000000, 0b00000000, 0b00000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b01000010, 0b01000000, 0b00000000, 0b00000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b01000000, 0b01000000, 0b00000000, 0b00000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b01000000, 0b01000000, 0b00000000, 0b00000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b01111111, 0b00111100, 0b01111000, 0b00111100, 0b00111100, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b00000010, 0b01000000, 0b00000010, 0b01000010, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b00000010, 0b01000000, 0b00111110, 0b01000000, 0b01000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b00000010, 0b01000000, 0b01000010, 0b01000000, 0b00000001,
|
||||
0b10000001, 0b00000010, 0b00000000, 0b01000010, 0b01000010, 0b01000010, 0b01000000, 0b01000001,
|
||||
0b10000001, 0b11111100, 0b00000000, 0b00111100, 0b00111100, 0b00111100, 0b01000000, 0b01000001,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111111
|
||||
};
|
||||
|
||||
COLED::COLED(unsigned char displayType, unsigned char displayBrightness, bool displayInvert) :
|
||||
m_displayType(displayType),
|
||||
m_displayBrightness(displayBrightness),
|
||||
|
@ -108,7 +128,7 @@ void COLED::setIdleInt()
|
|||
display.clearDisplay();
|
||||
OLED_statusbar();
|
||||
display.setCursor(0,display.height()/2);
|
||||
display.setTextSize(3);
|
||||
display.setTextSize(2);
|
||||
display.print("Idle");
|
||||
display.setTextSize(1);
|
||||
display.display();
|
||||
|
@ -286,7 +306,7 @@ void COLED::clearCWInt()
|
|||
{
|
||||
display.clearDisplay();
|
||||
display.setCursor(0,display.height()/2);
|
||||
display.setTextSize(3);
|
||||
display.setTextSize(2);
|
||||
display.print("Idle");
|
||||
display.setTextSize(1);
|
||||
display.display();
|
||||
|
@ -307,7 +327,7 @@ void COLED::OLED_statusbar()
|
|||
if (m_mode == MODE_DMR)
|
||||
display.drawBitmap(0, 0, logo_dmr_bmp, 48, 16, WHITE);
|
||||
else if (m_mode == MODE_DSTAR)
|
||||
display.print("D-Star");
|
||||
display.drawBitmap(0, 0, logo_dstar_bmp, 64, 16, WHITE);
|
||||
else if (m_mode == MODE_YSF)
|
||||
display.print("Fusion");
|
||||
else if (m_mode == MODE_P25)
|
||||
|
|
|
@ -6,11 +6,49 @@ http://wiringpi.com/download-and-install/ which must be installed in all cases.
|
|||
The HD44780 in 4-bit mode is probably the most common connection method and
|
||||
wiring details can be found at http://wiringpi.com/dev-lib/lcd-library/
|
||||
|
||||
The setup that is commonly used for MMDVM is the 4-bit connection that is also
|
||||
documented within wiringPi. The HD44780 displays have a standardized 16-pin
|
||||
connector (14 pins if without backlight). The pin numbers on HD44780 refer to
|
||||
this standard numbering.
|
||||
|
||||
The pin numbers on Raspberry Pi side are the physical pin numbers of the GPIO
|
||||
pin header, in brackets the wiringPi pin number as these are referred to in the
|
||||
MMDVM.ini file.
|
||||
|
||||
The wiring ist as follows:
|
||||
|
||||
HD44780 pin Raspberry Pi GPIO
|
||||
GND 1 -------- 6 GND
|
||||
VCC 2 -------- 2 +5V
|
||||
V0 3 -------- Trimmer between +5V and GND for contrast
|
||||
RS 4 -------- 26 CE1 (11)
|
||||
RW 5 -------- 6 GND
|
||||
E 6 -------- 24 CE0 (10)
|
||||
D0 7
|
||||
D1 8
|
||||
D2 9
|
||||
D3 10
|
||||
D4 11 -------- 11 GPIO0 (0)
|
||||
D5 12 -------- 12 GPIO1 (1)
|
||||
D6 13 -------- 13 GPIO2 (2)
|
||||
D7 14 -------- 15 GPIO3 (3)
|
||||
GND 15 -------- 6 GND
|
||||
VCC 16 -------- 2 +5V
|
||||
|
||||
The relevant part in the MMDVM.ini is like outlined below.
|
||||
|
||||
[HD44780]
|
||||
Rows=4
|
||||
Columns=20
|
||||
|
||||
# For basic HD44780 displays (4-bit connection)
|
||||
# rs, strb, d0, d1, d2, d3
|
||||
Pins=11,10,0,1,2,3
|
||||
|
||||
To compile MMDVMHost with support for the HD44780 use the following commands.
|
||||
|
||||
# cp Makefile.Pi.HD44780 Makefile
|
||||
# make clean
|
||||
# make
|
||||
# make -f Makefile.Pi.HD44780
|
||||
|
||||
Other HD44780 variations exist that connect via I2C. Support is also via
|
||||
wiringPi, but to compile for each I2C device requires a different Makefile
|
||||
|
|
23
UMP.cpp
23
UMP.cpp
|
@ -31,6 +31,7 @@ const unsigned char UMP_HELLO = 0x00U;
|
|||
|
||||
const unsigned char UMP_SET_MODE = 0x01U;
|
||||
const unsigned char UMP_SET_TX = 0x02U;
|
||||
const unsigned char UMP_SET_CD = 0x03U;
|
||||
|
||||
const unsigned char UMP_WRITE_SERIAL = 0x10U;
|
||||
const unsigned char UMP_READ_SERIAL = 0x11U;
|
||||
|
@ -47,7 +48,8 @@ m_length(0U),
|
|||
m_offset(0U),
|
||||
m_lockout(false),
|
||||
m_mode(MODE_IDLE),
|
||||
m_tx(false)
|
||||
m_tx(false),
|
||||
m_cd(false)
|
||||
{
|
||||
m_buffer = new unsigned char[BUFFER_LENGTH];
|
||||
}
|
||||
|
@ -125,6 +127,25 @@ bool CUMP::setTX(bool on)
|
|||
return m_serial.write(buffer, 4U) == 4;
|
||||
}
|
||||
|
||||
bool CUMP::setCD(bool on)
|
||||
{
|
||||
if (on == m_cd)
|
||||
return true;
|
||||
|
||||
m_cd = on;
|
||||
|
||||
unsigned char buffer[4U];
|
||||
|
||||
buffer[0U] = UMP_FRAME_START;
|
||||
buffer[1U] = 4U;
|
||||
buffer[2U] = UMP_SET_CD;
|
||||
buffer[3U] = on ? 0x01U : 0x00U;
|
||||
|
||||
// CUtils::dump(1U, "Transmitted", buffer, 4U);
|
||||
|
||||
return m_serial.write(buffer, 4U) == 4;
|
||||
}
|
||||
|
||||
bool CUMP::getLockout() const
|
||||
{
|
||||
return m_lockout;
|
||||
|
|
3
UMP.h
3
UMP.h
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
bool setTX(bool on);
|
||||
|
||||
bool setCD(bool on);
|
||||
|
||||
bool getLockout() const;
|
||||
|
||||
virtual int read(unsigned char* buffer, unsigned int length);
|
||||
|
@ -55,6 +57,7 @@ private:
|
|||
bool m_lockout;
|
||||
unsigned char m_mode;
|
||||
bool m_tx;
|
||||
bool m_cd;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
36
UMP/UMP.ino
36
UMP/UMP.ino
|
@ -20,20 +20,36 @@
|
|||
#define PIN_LED 13
|
||||
#endif
|
||||
|
||||
#if defined(__MK20DX256__)
|
||||
#define PIN_DSTAR 2
|
||||
#define PIN_DMR 3
|
||||
#define PIN_YSF 4
|
||||
#define PIN_P25 5
|
||||
|
||||
#define PIN_TX 10
|
||||
#define PIN_CD 11
|
||||
|
||||
#define PIN_LOCKOUT 12
|
||||
#else
|
||||
#define PIN_DSTAR 2
|
||||
#define PIN_DMR 3
|
||||
#define PIN_YSF 4
|
||||
#define PIN_P25 5
|
||||
|
||||
#define PIN_TX 6
|
||||
#define PIN_CD 7
|
||||
|
||||
#define PIN_LOCKOUT 7
|
||||
#define PIN_LOCKOUT 8
|
||||
#endif
|
||||
|
||||
// Use the LOCKOUT function on the UMP
|
||||
// #define USE_LOCKOUT
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__)
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__) || defined(__MK20DX256__)
|
||||
Serial1.begin(9600);
|
||||
#endif
|
||||
|
||||
|
@ -43,6 +59,7 @@ void setup()
|
|||
pinMode(PIN_YSF, OUTPUT);
|
||||
pinMode(PIN_P25, OUTPUT);
|
||||
pinMode(PIN_TX, OUTPUT);
|
||||
pinMode(PIN_CD, OUTPUT);
|
||||
pinMode(PIN_LOCKOUT, INPUT);
|
||||
|
||||
digitalWrite(PIN_DSTAR, LOW);
|
||||
|
@ -50,6 +67,7 @@ void setup()
|
|||
digitalWrite(PIN_YSF, LOW);
|
||||
digitalWrite(PIN_P25, LOW);
|
||||
digitalWrite(PIN_TX, LOW);
|
||||
digitalWrite(PIN_CD, LOW);
|
||||
}
|
||||
|
||||
#define UMP_FRAME_START 0xF0U
|
||||
|
@ -58,6 +76,7 @@ void setup()
|
|||
|
||||
#define UMP_SET_MODE 0x01U
|
||||
#define UMP_SET_TX 0x02U
|
||||
#define UMP_SET_CD 0x03U
|
||||
|
||||
#define UMP_WRITE_SERIAL 0x10U
|
||||
|
||||
|
@ -110,7 +129,10 @@ void loop()
|
|||
case UMP_SET_TX:
|
||||
digitalWrite(PIN_TX, m_buffer[3U] == 0x01U ? HIGH : LOW);
|
||||
break;
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__)
|
||||
case UMP_SET_CD:
|
||||
digitalWrite(PIN_CD, m_buffer[3U] == 0x01U ? HIGH : LOW);
|
||||
break;
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__) || defined(__MK20DX256__)
|
||||
case UMP_WRITE_SERIAL:
|
||||
Serial1.write(m_buffer + 3U, m_length - 3U);
|
||||
break;
|
||||
|
@ -125,7 +147,10 @@ void loop()
|
|||
}
|
||||
}
|
||||
|
||||
bool lockout = digitalRead(PIN_LOCKOUT) == HIGH;
|
||||
bool lockout = false;
|
||||
#if defined(USE_LOCKOUT)
|
||||
lockout = digitalRead(PIN_LOCKOUT) == HIGH;
|
||||
#endif
|
||||
if (lockout != m_lockout) {
|
||||
uint8_t data[4U];
|
||||
data[0U] = UMP_FRAME_START;
|
||||
|
@ -137,7 +162,7 @@ void loop()
|
|||
m_lockout = lockout;
|
||||
}
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__)
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__) || defined(__MK20DX256__)
|
||||
while (Serial1.available())
|
||||
Serial1.read();
|
||||
#endif
|
||||
|
@ -157,4 +182,3 @@ void loop()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue