diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 19145da..bc04ba4 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -62,7 +62,9 @@ m_rfErrs(0U), m_rfBits(1U), m_rfLastLICH(), m_rfLayer3(), +m_netLayer3(), m_rfMask(0x00U), +m_netMask(0x00U), m_rssiMapper(rssiMapper), m_rssi(0U), m_maxRSSI(0U), @@ -646,6 +648,9 @@ void CNXDNControl::writeEndNet() { m_netState = RS_NET_IDLE; + m_netMask = 0x00U; + m_netLayer3.reset(); + m_netTimeoutTimer.stop(); m_networkWatchdog.stop(); m_packetTimer.stop(); @@ -774,8 +779,44 @@ void CNXDNControl::writeNetwork() m_netFrames++; CUtils::dump(2U, "NXDN, interesting non superblock network frame", netData, 33U); } - } else if (m_netState == RS_NET_IDLE) { + } else { if (m_netState == RS_NET_IDLE) { + unsigned char structure = (netData[1U] >> 6) & 0x03U; + switch (structure) { + case NXDN_SR_1_4: + m_netLayer3.decode(netData + 2U, 18U, 0U); + if (m_netLayer3.getMessageType() == NXDN_MESSAGE_TYPE_VCALL) + m_netMask = 0x01U; + else + m_netMask = 0x00U; + break; + case NXDN_SR_2_4: + m_netMask |= 0x02U; + m_netLayer3.decode(netData + 2U, 18U, 18U); + break; + case NXDN_SR_3_4: + m_netMask |= 0x04U; + m_netLayer3.decode(netData + 2U, 18U, 36U); + break; + case NXDN_SR_4_4: + m_netMask |= 0x08U; + m_netLayer3.decode(netData + 2U, 18U, 54U); + break; + default: + break; + } + + if (m_netMask != 0x0FU) + return; + + unsigned char type = m_netLayer3.getMessageType(); + if (type != NXDN_MESSAGE_TYPE_VCALL) + return; + + unsigned short srcId = m_netLayer3.getSourceUnitId(); + unsigned short dstId = m_netLayer3.getDestinationGroupId(); + bool grp = m_netLayer3.getIsGroup(); + std::string source = m_lookup->find(srcId); LogMessage("NXDN, received network transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); m_display->writeNXDN(source.c_str(), grp, dstId, "N"); @@ -784,10 +825,45 @@ void CNXDNControl::writeNetwork() m_packetTimer.start(); m_elapsed.start(); m_netState = RS_NET_AUDIO; - m_netFrames = 0U; + m_netFrames = 1U; m_netLost = 0U; + + // Create a dummy start message + unsigned char start[NXDN_FRAME_LENGTH_BYTES + 2U]; + + start[0U] = TAG_DATA; + start[1U] = 0x00U; + + // Generate the sync + CSync::addNXDNSync(start + 2U); + + // Generate the LICH + CNXDNLICH lich; + lich.setRFCT(NXDN_LICH_RFCT_RDCH); + lich.setFCT(NXDN_LICH_USC_SACCH_NS); + lich.setOption(NXDN_LICH_STEAL_FACCH); + lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND); + lich.encode(start + 2U); + + CNXDNSACCH sacch; + sacch.setRAN(m_ran); + sacch.setStructure(NXDN_SR_SINGLE); + sacch.setData(SACCH_IDLE); + sacch.encode(start + 2U); + + unsigned char message[22U]; + m_netLayer3.getData(message); + + CNXDNFACCH1 facch; + facch.setData(message); + facch.encode(start + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); + facch.encode(start + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); + + scrambler(start + 2U); + + writeQueueNet(start); } - } else { + m_netFrames++; data[0U] = TAG_DATA; diff --git a/NXDNControl.h b/NXDNControl.h index db5e6ed..4840854 100644 --- a/NXDNControl.h +++ b/NXDNControl.h @@ -69,7 +69,9 @@ private: unsigned int m_rfBits; CNXDNLICH m_rfLastLICH; CNXDNLayer3 m_rfLayer3; + CNXDNLayer3 m_netLayer3; unsigned char m_rfMask; + unsigned char m_netMask; CRSSIInterpolator* m_rssiMapper; unsigned char m_rssi; unsigned char m_maxRSSI;