New Nextion screen layout with better looking fonts

New parameter for selecting ON7LDS Nextion screen layout
The active ip address of the host is showed on main screen
Nextion DMR page:
* Talker alias (if available) will be decoded and displayed (in green to know it's the TA)
* Font will get smaller if TA is to long
GPS data will be decoded and logged
This commit is contained in:
ON7LDS
2017-11-13 21:48:47 +01:00
parent 5c4333beb2
commit 3b62bd1666
24 changed files with 78628 additions and 72786 deletions

View File

@@ -184,6 +184,7 @@ m_nextionBrightness(50U),
m_nextionDisplayClock(false),
m_nextionUTC(false),
m_nextionIdleBrightness(20U),
m_nextionScreenLayout(0U),
m_oledType(3U),
m_oledBrightness(0U),
m_oledInvert(false),
@@ -612,6 +613,8 @@ bool CConf::read()
m_nextionUTC = ::atoi(value) == 1;
else if (::strcmp(key, "IdleBrightness") == 0)
m_nextionIdleBrightness = (unsigned int)::atoi(value);
else if (::strcmp(key, "ScreenLayout") == 0)
m_nextionScreenLayout = (unsigned int)::atoi(value);
} else if (section == SECTION_OLED) {
if (::strcmp(key, "Type") == 0)
m_oledType = (unsigned char)::atoi(value);
@@ -1292,6 +1295,11 @@ unsigned int CConf::getNextionIdleBrightness() const
return m_nextionIdleBrightness;
}
unsigned int CConf::getNextionScreenLayout() const
{
return m_nextionScreenLayout;
}
unsigned char CConf::getOLEDType() const
{
return m_oledType;

2
Conf.h
View File

@@ -195,6 +195,7 @@ public:
bool getNextionDisplayClock() const;
bool getNextionUTC() const;
unsigned int getNextionIdleBrightness() const;
unsigned int getNextionScreenLayout() const;
// The OLED section
unsigned char getOLEDType() const;
@@ -359,6 +360,7 @@ private:
bool m_nextionDisplayClock;
bool m_nextionUTC;
unsigned int m_nextionIdleBrightness;
unsigned int m_nextionScreenLayout;
unsigned char m_oledType;
unsigned char m_oledBrightness;

59493
DMRIds.dat

File diff suppressed because it is too large Load Diff

View File

@@ -77,6 +77,7 @@ m_rfEmbeddedData(NULL),
m_rfEmbeddedReadN(0U),
m_rfEmbeddedWriteN(1U),
m_rfTalkerId(TALKER_ID_NONE),
m_rfTalkerAlias(NULL),
m_netEmbeddedLC(),
m_netEmbeddedData(NULL),
m_netEmbeddedReadN(0U),
@@ -113,6 +114,7 @@ m_aveRSSI(0U),
m_rssiCount(0U),
m_fp(NULL)
{
m_rfTalkerAlias = new unsigned char[32U];
m_lastFrame = new unsigned char[DMR_FRAME_LENGTH_BYTES + 2U];
m_rfEmbeddedData = new CDMREmbeddedData[2U];
@@ -331,7 +333,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
LogMessage("DMR Slot %u, received RF end of voice transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
else
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));
m_display->writeDMRTA(m_slotNo,NULL," ");
if (m_rfTimeout) {
writeEndRF();
return false;
@@ -606,6 +608,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
CUtils::dump(2U, text, data, 9U);
logGPSposition(data);
}
if (m_network != NULL)
m_network->writePosition(m_rfLC->getSrcId(), data);
@@ -616,6 +619,9 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 0U, data);
if (!(m_rfTalkerId & TALKER_ID_HEADER)) {
if (m_rfTalkerId==TALKER_ID_NONE) memset(m_rfTalkerAlias,0,32U);
::memcpy(m_rfTalkerAlias, data, 6U);
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias,"R");
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
CUtils::dump(2U, text, data, 9U);
@@ -630,6 +636,9 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 1U, data);
if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) {
if (m_rfTalkerId==TALKER_ID_NONE) memset(m_rfTalkerAlias,0,32U);
::memcpy(m_rfTalkerAlias+6U, data, 7U);
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias,"R");
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
CUtils::dump(2U, text, data, 9U);
@@ -644,6 +653,10 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 2U, data);
if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) {
if (m_rfTalkerId==TALKER_ID_NONE) memset(m_rfTalkerAlias,0,32U);
m_rfTalkerId |= TALKER_ID_BLOCK2;
::memcpy(m_rfTalkerAlias+6U+7U, data, 7U);
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias,"R");
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
CUtils::dump(2U, text, data, 9U);
@@ -658,6 +671,9 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 3U, data);
if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) {
if (m_rfTalkerId==TALKER_ID_NONE) ::memset(m_rfTalkerAlias,0,32U);
::memcpy(m_rfTalkerAlias+6U+7U+7U, data, 7U);
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias,"R");
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
CUtils::dump(2U, text, data, 9U);
@@ -1170,7 +1186,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
// We've received the voice header and terminator haven't we?
m_netFrames += 2U;
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));
m_display->writeDMRTA(m_slotNo,NULL," ");
writeEndNet();
} else if (dataType == DT_DATA_HEADER) {
if (m_netState == RS_NET_DATA)
@@ -1377,10 +1393,14 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
CUtils::dump(2U, text, data, 9U);
logGPSposition(data);
}
break;
case FLCO_TALKER_ALIAS_HEADER:
if (!(m_netTalkerId & TALKER_ID_HEADER)) {
if (!m_netTalkerId) memset(m_rfTalkerAlias,0,32U);
::memcpy(m_rfTalkerAlias, data+2U, 7U);
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias,"N");
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
CUtils::dump(2U, text, data, 9U);
@@ -1391,6 +1411,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
break;
case FLCO_TALKER_ALIAS_BLOCK1:
if (!(m_netTalkerId & TALKER_ID_BLOCK1)) {
if (!m_netTalkerId) memset(m_rfTalkerAlias,0,32U);
::memcpy(m_rfTalkerAlias+7U, data+2U, 7U);
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias,"N");
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
CUtils::dump(2U, text, data, 9U);
@@ -1401,6 +1424,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
break;
case FLCO_TALKER_ALIAS_BLOCK2:
if (!(m_netTalkerId & TALKER_ID_BLOCK2)) {
if (!m_netTalkerId) ::memset(m_rfTalkerAlias,0,32U);
::memcpy(m_rfTalkerAlias+7U+7U, data+2U, 7U);
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias,"N");
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
CUtils::dump(2U, text, data, 9U);
@@ -1411,6 +1437,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
break;
case FLCO_TALKER_ALIAS_BLOCK3:
if (!(m_netTalkerId & TALKER_ID_BLOCK3)) {
if (!m_netTalkerId) memset(m_rfTalkerAlias,0,32U);
::memcpy(m_rfTalkerAlias+7U+7U+7U, data+2U, 7U);
m_display->writeDMRTA(m_slotNo, m_rfTalkerAlias,"N");
if (m_dumpTAData) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
CUtils::dump(2U, text, data, 9U);
@@ -1587,6 +1616,56 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
}
}
void CDMRSlot::logGPSposition(const unsigned char* data)
{
signed long longitudeI,latitudeI;
unsigned int errorI;
float longitude,latitude;
char errorS[30];
errorI=((data[2U]&0x0E) >> 1U);
switch (errorI) {
case 0U:
::sprintf(errorS, "< 2m");
break;
case 1U:
::sprintf(errorS, "< 20m");
break;
case 2U:
::sprintf(errorS, "< 200m");
break;
case 3U:
::sprintf(errorS, "< 2km");
break;
case 4U:
::sprintf(errorS, "< 20km");
break;
case 5U:
::sprintf(errorS, "< 200km");
break;
case 6U:
::sprintf(errorS, "> 200km");
break;
default:
::sprintf(errorS, "not known or position invalid");
break;
}
longitudeI=(data[3U]<<16U)+(data[4U]<<8U)+(data[5U]);
if ((data[2]&0x01U)==0x01U) longitudeI=-longitudeI;
latitudeI=((data[6U]&0x7FU)<<16U)+(data[7U]<<8U)+(data[8U]);
if ((data[6U]&0x80U)==0x80U) latitudeI=-latitudeI;
longitude=(float)360/33554432; // 360/2^25 steps
latitude=(float)180/16777216; // 180/2^24 steps
longitude*=longitudeI;
latitude*=latitudeI;
LogMessage("GPS position [%08f,%09f] (Position error %s)",latitude,longitude,errorS);
}
void CDMRSlot::clock()
{
unsigned int ms = m_interval.elapsed();

View File

@@ -69,6 +69,7 @@ private:
unsigned int m_rfEmbeddedReadN;
unsigned int m_rfEmbeddedWriteN;
unsigned char m_rfTalkerId;
unsigned char* m_rfTalkerAlias;
CDMREmbeddedData m_netEmbeddedLC;
CDMREmbeddedData* m_netEmbeddedData;
unsigned int m_netEmbeddedReadN;
@@ -131,6 +132,8 @@ private:
static unsigned char m_id2;
static ACTIVITY_TYPE m_activity2;
void logGPSposition(const unsigned char* data);
void writeQueueRF(const unsigned char* data);
void writeQueueNet(const unsigned char* data);
void writeNetworkRF(const unsigned char* data, unsigned char dataType, unsigned char errors = 0U);

View File

@@ -18,14 +18,15 @@
#include "Display.h"
#include "Defines.h"
#include "Log.h"
#include <cstdio>
#include <cassert>
#include <cstring>
CDisplay::CDisplay() :
m_timer1(1000U, 3U),
m_timer2(1000U, 3U),
m_timer1(3000U, 3U),
m_timer2(3000U, 3U),
m_mode1(MODE_IDLE),
m_mode2(MODE_IDLE)
{
@@ -117,7 +118,6 @@ void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group,
m_timer2.start();
m_mode2 = MODE_IDLE;
}
writeDMRInt(slotNo, src, group, dst, type);
}
@@ -127,11 +127,55 @@ void CDisplay::writeDMRRSSI(unsigned int slotNo, unsigned char rssi)
writeDMRRSSIInt(slotNo, rssi);
}
void CDisplay::writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type)
{
char TA[32U];
unsigned char *b;
unsigned char c;
int j;
unsigned int i,t1,t2, TAsize, TAformat;
if (strcmp(type," ")==0) { writeDMRTAInt(slotNo, (unsigned char*)TA, type); return; }
TAformat=(talkerAlias[0]>>6U) & 0x03U;
TAsize = (talkerAlias[0]>>1U) & 0x1FU;
::strcpy(TA,"(could not decode)");
switch (TAformat) {
case 0U: // 7 bit
::memset (&TA,0,32U);
b=&talkerAlias[0];
t1=0; t2=0; c=0;
for (i=0;(i<32U)&&(t2<TAsize);i++) {
for (j=7U;j>=0;j--) {
c = (c<<1U) | (b[i] >> j);
if (++t1==7U) { if (i>0) {TA[t2++]=c & 0x7FU; } t1=0; c=0; }
}
}
break;
case 1U: // ISO 8 bit
case 2U: // UTF8
::strcpy(TA,(char*)talkerAlias+1U);
break;
case 3U: // UTF16 poor man's conversion
t2=0;
::memset (&TA,0,32U);
for(i=0;(i<15)&&(t2<TAsize);i++) {
if (talkerAlias[2U*i+1U]==0)
TA[t2++]=talkerAlias[2U*i+2U]; else TA[t2++]='?';
}
TA[TAsize]=0;
break;
}
LogMessage("DMR Talker Alias (Data Format %u, Received %u/%u char): '%s'", TAformat, ::strlen(TA), TAsize, TA);
if (::strlen(TA)>TAsize) { if (strlen(TA)<29U) strcat(TA," ?"); else strcpy(TA+28U," ?"); }
if (strlen((char*)TA)>=4U) writeDMRTAInt(slotNo, (unsigned char*)TA, type);
}
void CDisplay::writeDMRBER(unsigned int slotNo, float ber)
{
writeDMRBERInt(slotNo, ber);
}
void CDisplay::clearDMR(unsigned int slotNo)
{
if (slotNo == 1U) {
@@ -293,6 +337,10 @@ void CDisplay::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
{
}
void CDisplay::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type)
{
}
void CDisplay::writeDMRBERInt(unsigned int slotNo, float ber)
{
}

View File

@@ -43,6 +43,7 @@ public:
void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
void writeDMRRSSI(unsigned int slotNo, unsigned char rssi);
void writeDMRBER(unsigned int slotNo, float ber);
void writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
void clearDMR(unsigned int slotNo);
void writeFusion(const char* source, const char* dest, const char* type, const char* origin);
@@ -74,6 +75,7 @@ protected:
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) = 0;
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
virtual void clearDMRInt(unsigned int slotNo) = 0;

View File

@@ -173,6 +173,8 @@ Port=/dev/ttyAMA0
Brightness=50
DisplayClock=1
UTC=0
#Screen Layout: 1=G4KLX 2=ON7LDS
ScreenLayout=2
IdleBrightness=20
[OLED]

View File

@@ -1099,6 +1099,7 @@ void CMMDVMHost::createDisplay()
bool displayClock = m_conf.getNextionDisplayClock();
bool utc = m_conf.getNextionUTC();
unsigned int idleBrightness = m_conf.getNextionIdleBrightness();
unsigned int screenLayout = m_conf.getNextionScreenLayout();
LogInfo(" Port: %s", port.c_str());
LogInfo(" Brightness: %u", brightness);
@@ -1106,16 +1107,20 @@ void CMMDVMHost::createDisplay()
if (displayClock)
LogInfo(" Display UTC: %s", utc ? "yes" : "no");
LogInfo(" Idle Brightness: %u", idleBrightness);
if (screenLayout==0)
LogInfo(" Screen Layout: Default (G4KLX)");
else
LogInfo(" Screen Layout: %u (ON7LDS)", screenLayout);
if (port == "modem") {
ISerialPort* serial = new CModemSerialPort(m_modem);
m_display = new CNextion(m_callsign, dmrid, serial, brightness, displayClock, utc, idleBrightness);
m_display = new CNextion(m_callsign, dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout);
} else if (port == "ump") {
if (m_ump != NULL)
m_display = new CNextion(m_callsign, dmrid, m_ump, brightness, displayClock, utc, idleBrightness);
m_display = new CNextion(m_callsign, dmrid, m_ump, brightness, displayClock, utc, idleBrightness, screenLayout);
} else {
ISerialPort* serial = new CSerialController(port, SERIAL_9600);
m_display = new CNextion(m_callsign, dmrid, serial, brightness, displayClock, utc, idleBrightness);
m_display = new CNextion(m_callsign, dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout);
}
} else if (type == "LCDproc") {
std::string address = m_conf.getLCDprocAddress();

View File

@@ -189,6 +189,7 @@
<ClInclude Include="Modem.h" />
<ClInclude Include="ModemSerialPort.h" />
<ClInclude Include="Mutex.h" />
<ClInclude Include="Network.h" />
<ClInclude Include="Nextion.h" />
<ClInclude Include="NullDisplay.h" />
<ClInclude Include="P25Audio.h" />
@@ -258,6 +259,7 @@
<ClCompile Include="Modem.cpp" />
<ClCompile Include="ModemSerialPort.cpp" />
<ClCompile Include="Mutex.cpp" />
<ClCompile Include="Network.cpp" />
<ClCompile Include="Nextion.cpp" />
<ClCompile Include="NullDisplay.cpp" />
<ClCompile Include="P25Audio.cpp" />

View File

@@ -221,6 +221,9 @@
<ClInclude Include="RSSIInterpolator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Network.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="BPTC19696.cpp">
@@ -412,5 +415,8 @@
<ClCompile Include="RSSIInterpolator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Network.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -9,7 +9,7 @@ LDFLAGS = -g
OBJECTS = \
AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \
DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \
Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Network.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \
P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \
Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o

180
Network.cpp Normal file
View File

@@ -0,0 +1,180 @@
/*
* Copyright (C) 2017 by Lieven De Samblanx ON7LDS
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Network.h"
#include "Log.h"
#include <cstdio>
#include <cassert>
#include <cstring>
#include <ctime>
#include <clocale>
#include <sys/types.h>
#if !defined(_WIN32) && !defined(_WIN64)
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#else
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#ifndef NO_ERROR
#define NO_ERROR 0
#endif
#ifndef ERROR_BUFFER_OVERFLOW
#define ERROR_BUFFER_OVERFLOW 111
#endif
#ifndef ERROR_INSUFFICIENT_BUFFER
#define ERROR_INSUFFICIENT_BUFFER 122
#endif
#endif
void CNetworkInfo::getNetworkInterface(unsigned char* info)
{
LogInfo("Interfaces Info");
::strcpy((char*)info, "(address unknown)");
#if !defined(_WIN32) && !defined(_WIN64)
#define IFLISTSIZ 25
struct ifaddrs *ifaddr, *ifa;
int family, s, n, ifnr;
char host[NI_MAXHOST];
char interfacelist[IFLISTSIZ][50+INET6_ADDRSTRLEN];
char *dflt, *p;
FILE *f;
char line[100U];
dflt=NULL;
f = fopen("/proc/net/route" , "r");
while(fgets(line , 100U , f)) {
dflt = strtok(line , " \t");
p = strtok(NULL , " \t");
if(dflt!=NULL && p!=NULL) {
if(strcmp(p , "00000000") == 0) { break; }
}
}
fclose(f);
for(n=0;n<IFLISTSIZ;n++) {
interfacelist[n][0]=0;
}
ifnr=0;
if (getifaddrs(&ifaddr) == -1) {
LogError("getifaddrs failure");
} else {
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL) continue;
family = ifa->ifa_addr->sa_family;
if (family == AF_INET || family == AF_INET6) {
s = getnameinfo(ifa->ifa_addr,(family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0) {
LogError("getnameinfo() failed: %s\n", gai_strerror(s));
continue;
}
if (family == AF_INET) {
sprintf(interfacelist[ifnr], "%s: %s", ifa->ifa_name,host);
LogInfo(" IPv4: %s", interfacelist[ifnr] );
} else {
sprintf(interfacelist[ifnr], "%s: %s", ifa->ifa_name,host);
LogInfo(" IPv6: %s", interfacelist[ifnr] );
}
ifnr++;
}
}
freeifaddrs(ifaddr);
LogInfo(" Default interface is : %s" , dflt);
for(n=0;n<(ifnr);n++) {
p=strchr(interfacelist[n],'%');
if (p!=NULL) *p=0;
if(strstr(interfacelist[n], dflt) != 0) {
::strcpy((char*)info,interfacelist[n]);
break;
}
}
LogInfo(" IP to show: %s", info );
}
#else
PMIB_IPFORWARDTABLE pIpForwardTable;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
int i, ifnr;
pIpForwardTable = (MIB_IPFORWARDTABLE *)malloc(sizeof(MIB_IPFORWARDTABLE));
if (pIpForwardTable == NULL) {
LogError("Error allocating memory");
return;
}
if (GetIpForwardTable(pIpForwardTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
free(pIpForwardTable);
pIpForwardTable = (MIB_IPFORWARDTABLE *)malloc(dwSize);
if (pIpForwardTable == NULL) {
LogError("Error allocating memory");
return;
}
}
if ((dwRetVal = GetIpForwardTable(pIpForwardTable, &dwSize, 0)) == NO_ERROR) {
for (i = 0; i < (int)pIpForwardTable->dwNumEntries; i++) {
if (pIpForwardTable->table[i].dwForwardDest == 0) break;
}
ifnr = pIpForwardTable->table[i].dwForwardIfIndex;
free(pIpForwardTable);
PIP_ADAPTER_INFO pAdapterInfo;
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
ULONG buflen = sizeof(IP_ADAPTER_INFO);
if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW) {
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(buflen);
if (pAdapterInfo == NULL) {
LogError("Error allocating memory");
return;
}
}
if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR) {
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter) {
LogInfo(" IP : %s", pAdapter->IpAddressList.IpAddress.String);
if (pAdapter->Index == ifnr) {
::strcpy((char*)info, pAdapter->IpAddressList.IpAddress.String);
}
pAdapter = pAdapter->Next;
}
LogInfo(" IP to show: %s", info);
}
else {
LogError("Call to GetAdaptersInfo failed.");
}
return;
}
else {
LogError("GetIpForwardTable failed.");
free(pIpForwardTable);
return;
}
#endif
}

31
Network.h Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2017 by Lieven De Samblanx ON7LDS
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(NETWORK_H)
#define NETWORK_H
class CNetworkInfo {
public:
void getNetworkInterface(unsigned char* info);
};
#endif

View File

@@ -18,12 +18,14 @@
#include "Nextion.h"
#include "Log.h"
#include "Network.h"
#include <cstdio>
#include <cassert>
#include <cstring>
#include <ctime>
#include <clocale>
//#include <unistd.h>
const unsigned int DSTAR_RSSI_COUNT = 3U; // 3 * 420ms = 1260ms
const unsigned int DSTAR_BER_COUNT = 63U; // 63 * 20ms = 1260ms
@@ -34,9 +36,10 @@ const unsigned int YSF_BER_COUNT = 13U; // 13 * 100ms = 1300ms
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
const unsigned int P25_BER_COUNT = 7U; // 7 * 180ms = 1260ms
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness) :
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout) :
CDisplay(),
m_callsign(callsign),
m_ipaddress("(ip unknown)"),
m_dmrid(dmrid),
m_serial(serial),
m_brightness(brightness),
@@ -44,6 +47,7 @@ m_mode(MODE_IDLE),
m_displayClock(displayClock),
m_utc(utc),
m_idleBrightness(idleBrightness),
m_screenLayout(screenLayout),
m_clockDisplayTimer(1000U, 0U, 400U),
m_rssiAccum1(0U),
m_rssiAccum2(0U),
@@ -64,6 +68,9 @@ CNextion::~CNextion()
bool CNextion::open()
{
unsigned char info[100U];
CNetworkInfo* m_network;
bool ret = m_serial->open();
if (!ret) {
LogError("Cannot open the port for the Nextion display");
@@ -71,6 +78,11 @@ bool CNextion::open()
return false;
}
info[0]=0;
m_network = new CNetworkInfo;
m_network->getNetworkInterface(info);
m_ipaddress = (char*)info;
sendCommand("bkcmd=0");
setIdle();
@@ -78,19 +90,23 @@ bool CNextion::open()
return true;
}
void CNextion::setIdleInt()
{
sendCommand("page MMDVM");
char command[30];
char command[30U];
::sprintf(command, "dim=%u", m_idleBrightness);
sendCommand(command);
::sprintf(command, "t0.txt=\"%-6s / %u\"", m_callsign.c_str(), m_dmrid);
::sprintf(command, "t0.txt=\"%s/%u\"", m_callsign.c_str(), m_dmrid);
sendCommand(command);
sendCommand("t1.txt=\"MMDVM IDLE\"");
::sprintf(command, "t3.txt=\"%s\"", m_ipaddress.c_str());
sendCommand(command);
m_clockDisplayTimer.start();
m_mode = MODE_IDLE;
@@ -226,11 +242,20 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
if (m_mode != MODE_DMR) {
sendCommand("page DMR");
if (slotNo == 1U)
if (slotNo == 1U) {
if (m_screenLayout==2U) {
sendCommand("t2.pco=0");
sendCommand("t2.font=4");
}
sendCommand("t2.txt=\"2 Listening\"");
else
} else {
if (m_screenLayout==2U) {
sendCommand("t0.pco=0");
sendCommand("t0.font=4");
}
sendCommand("t0.txt=\"1 Listening\"");
}
}
char text[30U];
::sprintf(text, "dim=%u", m_brightness);
@@ -238,12 +263,20 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
if (slotNo == 1U) {
::sprintf(text, "t0.txt=\"1 %s %s\"", type, src.c_str());
if (m_screenLayout==2U) {
sendCommand("t0.pco=0");
sendCommand("t0.font=4");
}
sendCommand(text);
::sprintf(text, "t1.txt=\"%s%s\"", group ? "TG" : "", dst.c_str());
sendCommand(text);
} else {
::sprintf(text, "t2.txt=\"2 %s %s\"", type, src.c_str());
if (m_screenLayout==2U) {
sendCommand("t2.pco=0");
sendCommand("t2.font=4");
}
sendCommand(text);
::sprintf(text, "t3.txt=\"%s%s\"", group ? "TG" : "", dst.c_str());
@@ -306,6 +339,41 @@ void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
}
}
void CNextion::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type)
{
char text[40U];
if (type[0]==' ') {
if (slotNo == 1U) {
sendCommand("t0.pco=33808");
} else {
sendCommand("t2.pco=33808");
}
return;
}
if (slotNo == 1U) {
::sprintf(text, "t0.txt=\"1 %s %s\"",type,talkerAlias);
if (m_screenLayout==2U) {
if (::strlen((char*)talkerAlias)>(16U-4U)) sendCommand("t0.font=3");
if (::strlen((char*)talkerAlias)>(20U-4U)) sendCommand("t0.font=2");
if (::strlen((char*)talkerAlias)>(24U-4U)) sendCommand("t0.font=1");
}
sendCommand("t0.pco=1024");
sendCommand(text);
} else {
::sprintf(text, "t2.txt=\"2 %s %s\"",type,talkerAlias);
if (m_screenLayout==2U) {
if (::strlen((char*)talkerAlias)>(16U-4U)) sendCommand("t2.font=3");
if (::strlen((char*)talkerAlias)>(20U-4U)) sendCommand("t2.font=2");
if (::strlen((char*)talkerAlias)>(24U-4U)) sendCommand("t2.font=1");
}
sendCommand("t2.pco=1024");
sendCommand(text);
}
}
void CNextion::writeDMRBERInt(unsigned int slotNo, float ber)
{
if (slotNo == 1U) {
@@ -353,11 +421,19 @@ void CNextion::clearDMRInt(unsigned int slotNo)
{
if (slotNo == 1U) {
sendCommand("t0.txt=\"1 Listening\"");
sendCommand("t0.pco=0");
if (m_screenLayout==2U) {
sendCommand("t0.font=4");
}
sendCommand("t1.txt=\"\"");
sendCommand("t4.txt=\"\"");
sendCommand("t6.txt=\"\"");
} else {
sendCommand("t2.txt=\"2 Listening\"");
sendCommand("t2.pco=0");
if (m_screenLayout==2U) {
sendCommand("t2.font=4");
}
sendCommand("t3.txt=\"\"");
sendCommand("t5.txt=\"\"");
sendCommand("t7.txt=\"\"");
@@ -568,6 +644,8 @@ void CNextion::clockInt(unsigned int ms)
void CNextion::close()
{
sendCommand("page MMDVM");
sendCommand("t1.txt=\"MMDVM STOPPED\"");
m_serial->close();
delete m_serial;
}

View File

@@ -29,7 +29,7 @@
class CNextion : public CDisplay
{
public:
CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness);
CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout);
virtual ~CNextion();
virtual bool open();
@@ -48,6 +48,7 @@ protected:
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type);
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
virtual void clearDMRInt(unsigned int slotNo);
@@ -68,6 +69,7 @@ protected:
private:
std::string m_callsign;
std::string m_ipaddress;
unsigned int m_dmrid;
ISerialPort* m_serial;
unsigned int m_brightness;
@@ -75,6 +77,7 @@ private:
bool m_displayClock;
bool m_utc;
unsigned int m_idleBrightness;
unsigned int m_screenLayout;
CTimer m_clockDisplayTimer;
unsigned int m_rssiAccum1;
unsigned int m_rssiAccum2;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.