diff --git a/Version.h b/Version.h index 9823a94..0397108 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20240430"; +const char* VERSION = "20240508"; #endif diff --git a/YSFControl.cpp b/YSFControl.cpp index 6467a92..855b82c 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2021 Jonathan Naylor, G4KLX + * Copyright (C) 2015-2021,2024 Jonathan Naylor, G4KLX * * 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 @@ -178,6 +178,12 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) m_lastFICH = fich; } +/* + LogMessage("RF FICH: FI:%X CS:%X CM:%X BN:%u BT:%u FN:%u FT:%u Dev:%X MR:%X VOIP:%X DT:%X DGId:%X", + m_lastFICH.getFI(), m_lastFICH.getCS(), m_lastFICH.getCM(), m_lastFICH.getBN(), m_lastFICH.getBT(), + m_lastFICH.getFN(), m_lastFICH.getFT(), m_lastFICH.getDev() ? 1 : 0, m_lastFICH.getMR(), m_lastFICH.getVoIP() ? 1 : 0, + m_lastFICH.getDT(), m_lastFICH.getDGId()); +*/ #ifdef notdef // Stop repeater packets coming through, unless we're acting as a remote gateway if (m_remoteGateway) { @@ -238,7 +244,7 @@ bool CYSFControl::processVWData(bool valid, unsigned char *data) } unsigned char cm = m_lastFICH.getCM(); - if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2) + if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID) m_rfDest = (unsigned char*)"ALL "; else m_rfDest = m_rfPayload.getDest(); @@ -407,7 +413,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data) } unsigned char cm = m_lastFICH.getCM(); - if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2) + if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID) m_rfDest = (unsigned char*)"ALL "; else m_rfDest = m_rfPayload.getDest(); @@ -583,7 +589,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data) return false; unsigned char cm = m_lastFICH.getCM(); - if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2) + if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID) m_rfDest = (unsigned char*)"ALL "; else m_rfDest = m_rfPayload.getDest(); @@ -628,7 +634,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data) memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_rfSource, YSF_CALLSIGN_LENGTH); memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH); - if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2) + if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID) memset(csd1 + 0U, '*', YSF_CALLSIGN_LENGTH); else memcpy(csd1 + 0U, m_rfDest, YSF_CALLSIGN_LENGTH); @@ -709,7 +715,7 @@ bool CYSFControl::processFRData(bool valid, unsigned char *data) } unsigned char cm = m_lastFICH.getCM(); - if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2) + if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID) m_rfDest = (unsigned char*)"ALL "; else m_rfDest = m_rfPayload.getDest(); @@ -921,6 +927,14 @@ void CYSFControl::writeNetwork() if (valid) dgid = fich.getDGId(); +/* + if (valid) + LogMessage("Net FICH: FI:%X CS:%X CM:%X BN:%u BT:%u FN:%u FT:%u Dev:%X MR:%X VOIP:%X DT:%X DGId:%X", + fich.getFI(), fich.getCS(), fich.getCM(), fich.getBN(), fich.getBT(), + fich.getFN(), fich.getFT(), fich.getDev() ? 1 : 0, fich.getMR(), fich.getVoIP() ? 1 : 0, + fich.getDT(), fich.getDGId()); +*/ + if (!m_netTimeoutTimer.isRunning()) { if (end) return; @@ -960,7 +974,7 @@ void CYSFControl::writeNetwork() unsigned char cm = fich.getCM(); if (::memcmp(m_netDest, " ", YSF_CALLSIGN_LENGTH) == 0) { - if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2) + if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID) ::memcpy(m_netDest, "ALL ", YSF_CALLSIGN_LENGTH); } diff --git a/YSFDefines.h b/YSFDefines.h index 0efccc8..ef22ff7 100644 --- a/YSFDefines.h +++ b/YSFDefines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2024 by Jonathan Naylor G4KLX * * 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 @@ -37,15 +37,21 @@ const unsigned char YSF_FI_COMMUNICATIONS = 0x01U; const unsigned char YSF_FI_TERMINATOR = 0x02U; const unsigned char YSF_FI_TEST = 0x03U; +const unsigned char YSF_CS_RESERVE1 = 0x00U; +const unsigned char YSF_CS_RESERVE2 = 0x01U; +const unsigned char YSF_CS_ASSIGN = 0x02U; +const unsigned char YSF_CS_RESERVE3 = 0x03U; + +const unsigned char YSF_CM_GROUP_CQ = 0x00U; +const unsigned char YSF_CM_RADIO_ID = 0x01U; +const unsigned char YSF_CM_RESERVE = 0x02U; +const unsigned char YSF_CM_INDIVIDUAL = 0x03U; + const unsigned char YSF_DT_VD_MODE1 = 0x00U; const unsigned char YSF_DT_DATA_FR_MODE = 0x01U; const unsigned char YSF_DT_VD_MODE2 = 0x02U; const unsigned char YSF_DT_VOICE_FR_MODE = 0x03U; -const unsigned char YSF_CM_GROUP1 = 0x00U; -const unsigned char YSF_CM_GROUP2 = 0x01U; -const unsigned char YSF_CM_INDIVIDUAL = 0x03U; - const unsigned char YSF_MR_DIRECT = 0x00U; const unsigned char YSF_MR_NOT_BUSY = 0x01U; const unsigned char YSF_MR_BUSY = 0x02U; diff --git a/YSFFICH.cpp b/YSFFICH.cpp index cbe3175..2aed544 100644 --- a/YSFFICH.cpp +++ b/YSFFICH.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016,2017,2019,2020,2021 by Jonathan Naylor G4KLX + * Copyright (C) 2016,2017,2019,2020,2021,2024 by Jonathan Naylor G4KLX * * 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 @@ -178,6 +178,11 @@ unsigned char CYSFFICH::getFI() const return (m_fich[0U] >> 6) & 0x03U; } +unsigned char CYSFFICH::getCS() const +{ + return (m_fich[0U] >> 4) & 0x03U; +} + unsigned char CYSFFICH::getCM() const { return (m_fich[0U] >> 2) & 0x03U; @@ -203,9 +208,9 @@ unsigned char CYSFFICH::getFT() const return m_fich[1U] & 0x07U; } -unsigned char CYSFFICH::getDT() const +bool CYSFFICH::getDev() const { - return m_fich[2U] & 0x03U; + return (m_fich[2U] & 0x40U) == 0x40U; } unsigned char CYSFFICH::getMR() const @@ -213,9 +218,14 @@ unsigned char CYSFFICH::getMR() const return (m_fich[2U] >> 3) & 0x03U; } -bool CYSFFICH::getDev() const +bool CYSFFICH::getVoIP() const { - return (m_fich[2U] & 0x40U) == 0x40U; + return (m_fich[2U] & 0x04U) == 0x04U; +} + +unsigned char CYSFFICH::getDT() const +{ + return m_fich[2U] & 0x03U; } unsigned char CYSFFICH::getDGId() const @@ -229,6 +239,18 @@ void CYSFFICH::setFI(unsigned char fi) m_fich[0U] |= (fi << 6) & 0xC0U; } +void CYSFFICH::setCS(unsigned char cs) +{ + m_fich[0U] &= 0xCFU; + m_fich[0U] |= (cs << 4) & 0x30U; +} + +void CYSFFICH::setCM(unsigned char cm) +{ + m_fich[0U] &= 0xF3U; + m_fich[0U] |= (cm << 2) & 0x0CU; +} + void CYSFFICH::setBN(unsigned char bn) { m_fich[0U] &= 0xFCU; @@ -253,6 +275,14 @@ void CYSFFICH::setFT(unsigned char ft) m_fich[1U] |= ft & 0x07U; } +void CYSFFICH::setDev(bool on) +{ + if (on) + m_fich[2U] |= 0x40U; + else + m_fich[2U] &= 0xBFU; +} + void CYSFFICH::setMR(unsigned char mr) { m_fich[2U] &= 0xC7U; @@ -267,12 +297,10 @@ void CYSFFICH::setVoIP(bool on) m_fich[2U] &= 0xFBU; } -void CYSFFICH::setDev(bool on) +void CYSFFICH::setDT(unsigned char dt) { - if (on) - m_fich[2U] |= 0x40U; - else - m_fich[2U] &= 0xBFU; + m_fich[2U] &= 0xFCU; + m_fich[2U] |= dt & 0x03U; } void CYSFFICH::setDGId(unsigned char id) diff --git a/YSFFICH.h b/YSFFICH.h index a6e8851..8a18cbf 100644 --- a/YSFFICH.h +++ b/YSFFICH.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016,2017,2019,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2016,2017,2019,2020,2024 by Jonathan Naylor G4KLX * * 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 @@ -30,24 +30,29 @@ public: void encode(unsigned char* bytes); unsigned char getFI() const; + unsigned char getCS() const; unsigned char getCM() const; unsigned char getBN() const; unsigned char getBT() const; unsigned char getFN() const; unsigned char getFT() const; - unsigned char getDT() const; + bool getDev() const; unsigned char getMR() const; - bool getDev() const; + bool getVoIP() const; + unsigned char getDT() const; unsigned char getDGId() const; void setFI(unsigned char fi); + void setCS(unsigned char cs); + void setCM(unsigned char cm); void setBN(unsigned char bn); void setBT(unsigned char bt); void setFN(unsigned char fn); void setFT(unsigned char ft); + void setDev(bool set); void setMR(unsigned char mr); void setVoIP(bool set); - void setDev(bool set); + void setDT(unsigned char dt); void setDGId(unsigned char id); CYSFFICH& operator=(const CYSFFICH& fich); diff --git a/YSFPayload.cpp b/YSFPayload.cpp index f0fa17f..14f7068 100644 --- a/YSFPayload.cpp +++ b/YSFPayload.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016,2017,2020 Jonathan Naylor, G4KLX +* Copyright (C) 2016,2017,2020,2024 Jonathan Naylor, G4KLX * Copyright (C) 2016 Mathias Weyland, HB9FRV * * This program is free software; you can redistribute it and/or modify @@ -304,6 +304,7 @@ bool CYSFPayload::processVDMode1Data(unsigned char* data, unsigned char fn, bool switch (fn) { case 0U: + // CUtils::dump(2U, "V/D Mode 1 Data, CSD1", output, 20U); if (m_dest == NULL) { m_dest = new unsigned char[YSF_CALLSIGN_LENGTH]; ::memcpy(m_dest, output + 0U, YSF_CALLSIGN_LENGTH); @@ -317,6 +318,7 @@ bool CYSFPayload::processVDMode1Data(unsigned char* data, unsigned char fn, bool break; case 1U: + // CUtils::dump(2U, "V/D Mode 1 Data, CSD2", output, 20U); if (m_downlink != NULL && !gateway) ::memcpy(output + 0U, m_downlink, YSF_CALLSIGN_LENGTH); @@ -325,24 +327,28 @@ bool CYSFPayload::processVDMode1Data(unsigned char* data, unsigned char fn, bool break; + case 2U: + // CUtils::dump(2U, "V/D Mode 1 Data, CSD3", output, 20U); + break; + case 3U: - // CUtils::dump(1U, "V/D Mode 1 Data, DT1", output, 20U); + // CUtils::dump(2U, "V/D Mode 1 Data, DT1", output, 20U); break; case 4U: - // CUtils::dump(1U, "V/D Mode 1 Data, DT2", output, 20U); + // CUtils::dump(2U, "V/D Mode 1 Data, DT2", output, 20U); break; case 5U: - // CUtils::dump(1U, "V/D Mode 1 Data, DT3", output, 20U); + // CUtils::dump(2U, "V/D Mode 1 Data, DT3", output, 20U); break; case 6U: - // CUtils::dump(1U, "V/D Mode 1 Data, DT4", output, 20U); + // CUtils::dump(2U, "V/D Mode 1 Data, DT4", output, 20U); break; case 7U: - // CUtils::dump(1U, "V/D Mode 1 Data, DT5", output, 20U); + // CUtils::dump(2U, "V/D Mode 1 Data, DT5", output, 20U); break; default: @@ -502,6 +508,7 @@ bool CYSFPayload::processVDMode2Data(unsigned char* data, unsigned char fn, bool switch (fn) { case 0U: + // CUtils::dump(2U, "V/D Mode 2 Data, Dest", output, YSF_CALLSIGN_LENGTH); if (m_dest == NULL) { m_dest = new unsigned char[YSF_CALLSIGN_LENGTH]; ::memcpy(m_dest, output, YSF_CALLSIGN_LENGTH); @@ -509,6 +516,7 @@ bool CYSFPayload::processVDMode2Data(unsigned char* data, unsigned char fn, bool break; case 1U: + // CUtils::dump(2U, "V/D Mode 2 Data, Src", output, YSF_CALLSIGN_LENGTH); if (m_source == NULL) { m_source = new unsigned char[YSF_CALLSIGN_LENGTH]; ::memcpy(m_source, output, YSF_CALLSIGN_LENGTH); @@ -516,21 +524,31 @@ bool CYSFPayload::processVDMode2Data(unsigned char* data, unsigned char fn, bool break; case 2U: + // CUtils::dump(2U, "V/D Mode 2 Data, Down", output, YSF_CALLSIGN_LENGTH); if (m_downlink != NULL && !gateway) ::memcpy(output, m_downlink, YSF_CALLSIGN_LENGTH); break; case 3U: + // CUtils::dump(2U, "V/D Mode 2 Data, Up", output, YSF_CALLSIGN_LENGTH); if (m_uplink != NULL && !gateway) ::memcpy(output, m_uplink, YSF_CALLSIGN_LENGTH); break; + case 4U: + // CUtils::dump(2U, "V/D Mode 2 Data, Rem1+2", output, YSF_CALLSIGN_LENGTH); + break; + + case 5U: + // CUtils::dump(2U, "V/D Mode 2 Data, Rem3+4", output, YSF_CALLSIGN_LENGTH); + break; + case 6U: - // CUtils::dump(1U, "V/D Mode 2 Data, DT1", output, YSF_CALLSIGN_LENGTH); + // CUtils::dump(2U, "V/D Mode 2 Data, DT1", output, YSF_CALLSIGN_LENGTH); break; case 7U: - // CUtils::dump(1U, "V/D Mode 2 Data, DT2", output, YSF_CALLSIGN_LENGTH); + // CUtils::dump(2U, "V/D Mode 2 Data, DT2", output, YSF_CALLSIGN_LENGTH); break; default: