diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 0b55b67..dbeadde 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -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[32]; //TA max length is 31 chars 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; @@ -583,7 +585,6 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len) bool ret = m_rfEmbeddedData[m_rfEmbeddedWriteN].addData(data + 2U, lcss); if (ret) { FLCO flco = m_rfEmbeddedData[m_rfEmbeddedWriteN].getFLCO(); - unsigned char data[9U]; m_rfEmbeddedData[m_rfEmbeddedWriteN].getRawData(data); @@ -609,6 +610,10 @@ 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) memset(m_rfTalkerAlias,0,32); + ::memcpy(m_rfTalkerAlias, data, 6); + 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); @@ -623,6 +628,11 @@ 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) memset(m_rfTalkerAlias,0,32); + + ::memcpy(m_rfTalkerAlias+6, data, 7); + 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); @@ -637,12 +647,16 @@ 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) memset(m_rfTalkerAlias,0,32); + m_rfTalkerId |= TALKER_ID_BLOCK2; + ::memcpy(m_rfTalkerAlias+6+7, data, 7); + 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); } - m_rfTalkerId |= TALKER_ID_BLOCK2; } break; @@ -651,6 +665,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) memset(m_rfTalkerAlias,0,32); + ::memcpy(m_rfTalkerAlias+6+7+7, data, 7); + 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); @@ -1163,7 +1180,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) @@ -1374,6 +1391,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) break; case FLCO_TALKER_ALIAS_HEADER: if (!(m_netTalkerId & TALKER_ID_HEADER)) { + if (!m_netTalkerId) memset(m_rfTalkerAlias,0,32); + ::memcpy(m_rfTalkerAlias, data+2, 7); + 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); @@ -1384,6 +1404,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,32); + ::memcpy(m_rfTalkerAlias+7, data+2, 7); + 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); @@ -1394,6 +1417,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,32); + ::memcpy(m_rfTalkerAlias+7+7, data+2, 7); + 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); @@ -1404,6 +1430,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,32); + ::memcpy(m_rfTalkerAlias+7+7+7, data+2, 7); + 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); diff --git a/DMRSlot.h b/DMRSlot.h index 657de80..62b39f0 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -61,6 +61,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; diff --git a/Display.cpp b/Display.cpp index 18c8100..ed6824a 100644 --- a/Display.cpp +++ b/Display.cpp @@ -18,14 +18,15 @@ #include "Display.h" #include "Defines.h" +#include "Log.h" #include #include #include 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,46 @@ void CDisplay::writeDMRRSSI(unsigned int slotNo, unsigned char rssi) writeDMRRSSIInt(slotNo, rssi); } +void CDisplay::writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type) +{ + unsigned char format; + char TA[32]; + int i,j; + + if (strcmp(type," ")==0) { writeDMRTAInt(slotNo, (unsigned char*)TA, type); return; } + + + format=talkerAlias[0]>>6; + strcpy(TA,"(could not decode)"); + switch (format) { + case 0: // 7 bit + break; + case 1: // ISO 8 bit + case 2: // UTF8 + strcpy(TA,(char*)talkerAlias+1); + break; + case 3: // UTF16 + j=0; + memset (&TA,0,32); + for(i=0;i<15;i++) { + if (talkerAlias[2*i+1]==0) + TA[j++]=talkerAlias[2*i+2]; else TA[j++]='?'; + } + TA[j]=0; + break; + } + i=strlen(TA); + j=(talkerAlias[0]&0x3F)>>1; + LogMessage("DMR Talker Alias (Data Format %u, Received %d/%d char): '%s'", format, i, j, TA); + if (i>j) { if (strlen(TA)<29) strcat(TA," ?"); else strcpy(TA+28," ?"); } + if (strlen((char*)TA)>4) 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 +328,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) { } diff --git a/Display.h b/Display.h index 9e3d884..b8f2763 100644 --- a/Display.h +++ b/Display.h @@ -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; diff --git a/Makefile b/Makefile index 90346af..db44820 100644 --- a/Makefile +++ b/Makefile @@ -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 Nextion.o Network.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 diff --git a/Nextion.cpp b/Nextion.cpp index a41dd59..6910776 100644 --- a/Nextion.cpp +++ b/Nextion.cpp @@ -18,6 +18,7 @@ #include "Nextion.h" #include "Log.h" +#include "Network.h" #include #include @@ -25,6 +26,29 @@ #include #include +/* +#include "Nextion.h" +#include "Log.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +//#include +#include +//#include +//#include +*/ + + const unsigned int DSTAR_RSSI_COUNT = 3U; // 3 * 420ms = 1260ms const unsigned int DSTAR_BER_COUNT = 63U; // 63 * 20ms = 1260ms const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms @@ -37,6 +61,7 @@ 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) : CDisplay(), m_callsign(callsign), +m_ipaddress("(ip unknown)"), m_dmrid(dmrid), m_serial(serial), m_brightness(brightness), @@ -62,8 +87,13 @@ 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 +101,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,6 +113,7 @@ bool CNextion::open() return true; } + void CNextion::setIdleInt() { sendCommand("page MMDVM"); @@ -86,11 +122,15 @@ void CNextion::setIdleInt() ::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\""); + char text[30U]; + ::sprintf(text, "t3.txt=\"%s\"", m_ipaddress.c_str()); + sendCommand(text); + m_clockDisplayTimer.start(); m_mode = MODE_IDLE; @@ -226,10 +266,15 @@ 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) { + sendCommand("t2.pco=0"); + sendCommand("t2.font=4"); sendCommand("t2.txt=\"2 Listening\""); - else + } else { + sendCommand("t0.pco=0"); + sendCommand("t0.font=4"); sendCommand("t0.txt=\"1 Listening\""); + } } char text[30U]; @@ -238,12 +283,16 @@ 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()); + 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()); + sendCommand("t2.pco=0"); + sendCommand("t2.font=4"); sendCommand(text); ::sprintf(text, "t3.txt=\"%s%s\"", group ? "TG" : "", dst.c_str()); @@ -306,6 +355,38 @@ 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 (strlen((char*)talkerAlias)>16-4) sendCommand("t0.font=3"); + if (strlen((char*)talkerAlias)>20-4) sendCommand("t0.font=2"); + if (strlen((char*)talkerAlias)>24-4) sendCommand("t0.font=1"); + sendCommand("t0.pco=1024"); + sendCommand(text); + } else { + ::sprintf(text, "t2.txt=\"2 %s %s\"",type,talkerAlias); + if (strlen((char*)talkerAlias)>16-4) sendCommand("t2.font=3"); + if (strlen((char*)talkerAlias)>20-4) sendCommand("t2.font=2"); + if (strlen((char*)talkerAlias)>24-4) sendCommand("t2.font=1"); + sendCommand("t2.pco=1024"); + sendCommand(text); + } +} + + void CNextion::writeDMRBERInt(unsigned int slotNo, float ber) { if (slotNo == 1U) { @@ -353,11 +434,15 @@ void CNextion::clearDMRInt(unsigned int slotNo) { if (slotNo == 1U) { sendCommand("t0.txt=\"1 Listening\""); + sendCommand("t0.pco=0"); + sendCommand("t0.font=4"); sendCommand("t1.txt=\"\""); sendCommand("t4.txt=\"\""); sendCommand("t6.txt=\"\""); } else { sendCommand("t2.txt=\"2 Listening\""); + sendCommand("t2.pco=0"); + sendCommand("t2.font=4"); sendCommand("t3.txt=\"\""); sendCommand("t5.txt=\"\""); sendCommand("t7.txt=\"\""); @@ -568,6 +653,8 @@ void CNextion::clockInt(unsigned int ms) void CNextion::close() { + sendCommand("page MMDVM"); + sendCommand("t1.txt=\"MMDVM STOPPED\""); m_serial->close(); delete m_serial; } diff --git a/Nextion.h b/Nextion.h index c5a931b..057f396 100644 --- a/Nextion.h +++ b/Nextion.h @@ -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;