adjust OSP_QUE_RSP slightly to ensure the service doesn't overflow; fix some minor U2U logic (this kinda sorta makes U2U work); adjust some timing parameters when clearing the modem queues (~5ms delay after writing the command to ensure the modem has time to clear); alter how grants are transmitted on VOC configurations (this will not only transmit a immediate grant but also buffer 3 more as an MBF);

pull/32/head
Bryan Biedenkapp 3 years ago
parent 7c94b92981
commit 4aca5792db

@ -1155,7 +1155,16 @@ bool Modem::hasError() const
/// </summary>
void Modem::clearDMRFrame1()
{
// TODO -- implement modem side buffer clear
uint8_t buffer[3U];
buffer[0U] = DVM_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_DMR_CLEAR1;
#if DEBUG_MODEM
Utils::dump(1U, "Modem::clearDMRFrame1(), Written", buffer, 3U);
#endif
write(buffer, 3U);
Thread::sleep(5); // 5ms delay
}
/// <summary>
@ -1163,7 +1172,16 @@ void Modem::clearDMRFrame1()
/// </summary>
void Modem::clearDMRFrame2()
{
// TODO -- implement modem side buffer clear
uint8_t buffer[3U];
buffer[0U] = DVM_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_DMR_CLEAR2;
#if DEBUG_MODEM
Utils::dump(1U, "Modem::clearDMRFrame2(), Written", buffer, 3U);
#endif
write(buffer, 3U);
Thread::sleep(5); // 5ms delay
}
/// <summary>
@ -1180,6 +1198,7 @@ void Modem::clearP25Frame()
Utils::dump(1U, "Modem::clearP25Data(), Written", buffer, 3U);
#endif
write(buffer, 3U);
Thread::sleep(5); // 5ms delay
}
/// <summary>
@ -1187,7 +1206,16 @@ void Modem::clearP25Frame()
/// </summary>
void Modem::clearNXDNFrame()
{
// TODO -- implement modem side buffer clear
uint8_t buffer[3U];
buffer[0U] = DVM_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_NXDN_CLEAR;
#if DEBUG_MODEM
Utils::dump(1U, "Modem::clearNXDNFrame(), Written", buffer, 3U);
#endif
write(buffer, 3U);
Thread::sleep(5); // 5ms delay
}
/// <summary>
@ -2536,6 +2564,10 @@ std::string Modem::cmdToString(uint8_t opcode)
return std::string("DMR_ABORT");
case CMD_DMR_CACH_AT_CTRL:
return std::string("DMR_CACH_AT_CTRL");
case CMD_DMR_CLEAR1:
return std::string("DMR_CLEAR1");
case CMD_DMR_CLEAR2:
return std::string("DMR_CLEAR2");
case CMD_P25_DATA:
return std::string("P25_DATA");
@ -2548,6 +2580,8 @@ std::string Modem::cmdToString(uint8_t opcode)
return std::string("NXDN_DATA");
case CMD_NXDN_LOST:
return std::string("NXDN_LOST");
case CMD_NXDN_CLEAR:
return std::string("NXDN_CLEAR");
case CMD_ACK:
return std::string("ACK");

@ -148,6 +148,8 @@ namespace modem
CMD_DMR_START = 0x1DU,
CMD_DMR_ABORT = 0x1EU,
CMD_DMR_CACH_AT_CTRL = 0x1FU,
CMD_DMR_CLEAR1 = 0x20U,
CMD_DMR_CLEAR2 = 0x21U,
CMD_P25_DATA = 0x31U,
CMD_P25_LOST = 0x32U,
@ -155,6 +157,7 @@ namespace modem
CMD_NXDN_DATA = 0x41U,
CMD_NXDN_LOST = 0x42U,
CMD_NXDN_CLEAR = 0x43U,
CMD_ACK = 0x70U,
CMD_NAK = 0x7FU,

@ -127,7 +127,7 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q
m_rfTGHang(1000U, tgHang),
m_netTimeout(1000U, timeout),
m_networkWatchdog(1000U, 0U, 1500U),
m_ccPacketInterval(1000U, 0U, 5U),
m_ccPacketInterval(1000U, 0U, 10U),
m_hangCount(3U * 8U),
m_tduPreambleCount(8U),
m_ccFrameCnt(0U),
@ -646,6 +646,8 @@ uint32_t Control::getFrame(uint8_t* data)
// tx immediate queue takes priority
if (!m_txImmQueue.isEmpty()) {
m_modem->clearP25Frame();
m_txImmQueue.getData(&len, 1U);
m_txImmQueue.getData(data, len);
}

@ -93,7 +93,7 @@ void OSP_QUE_RSP::encode(uint8_t* data, bool rawTSBK, bool noTrellis)
}
tsbkValue = (m_aivFlag) ? 0x80U : 0x00U; // Additional Info Flag
tsbkValue = (tsbkValue << 6) + m_service; // Service Type
tsbkValue = (tsbkValue << 6) + (m_service & 0x3FU); // Service Type
tsbkValue = (tsbkValue << 8) + m_response; // Deny/Queue Reason
if (m_group) {

@ -37,6 +37,7 @@
#include "edac/CRC.h"
#include "remote/RESTClient.h"
#include "Log.h"
#include "Thread.h"
#include "Utils.h"
using namespace p25;
@ -302,7 +303,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDe
if (iosp->getResponse() == P25_ANS_RSP_PROCEED) {
if (m_p25->m_ackTSBKRequests) {
writeRF_TSDU_ACK_FNE(dstId, TSBK_IOSP_UU_ANS, false, true);
writeRF_TSDU_ACK_FNE(dstId, TSBK_IOSP_UU_VCH, false, true);
}
if (m_p25->m_authoritative) {
@ -316,10 +317,12 @@ bool Trunk::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDe
}
}
else if (iosp->getResponse() == P25_ANS_RSP_DENY) {
writeRF_TSDU_Deny(P25_WUID_FNE, srcId, P25_DENY_RSN_TGT_UNIT_REFUSED, TSBK_IOSP_UU_ANS);
writeRF_TSDU_ACK_FNE(dstId, TSBK_IOSP_UU_VCH, false, true);
writeRF_TSDU_Deny(P25_WUID_FNE, dstId, P25_DENY_RSN_TGT_UNIT_REFUSED, TSBK_IOSP_UU_VCH);
}
else if (iosp->getResponse() == P25_ANS_RSP_WAIT) {
writeRF_TSDU_Queue(P25_WUID_FNE, srcId, P25_QUE_RSN_TGT_UNIT_QUEUED, TSBK_IOSP_UU_ANS);
writeRF_TSDU_ACK_FNE(dstId, TSBK_IOSP_UU_VCH, false, true);
writeRF_TSDU_Queue(P25_WUID_FNE, dstId, P25_QUE_RSN_TGT_UNIT_QUEUED, TSBK_IOSP_UU_VCH, false, false);
}
}
break;
@ -2264,6 +2267,10 @@ bool Trunk::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOp
// transmit group grant
writeRF_TSDU_SBF_Imm(iosp.get(), net);
if (m_p25->m_voiceOnControl) {
for (int i = 0; i < 3; i++)
writeRF_TSDU_SBF(iosp.get(), net);
}
}
else {
if (!net) {
@ -2314,6 +2321,10 @@ bool Trunk::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOp
// transmit private grant
writeRF_TSDU_SBF_Imm(iosp.get(), net);
if (m_p25->m_voiceOnControl) {
for (int i = 0; i < 3; i++)
writeRF_TSDU_SBF(iosp.get(), net);
}
}
}
@ -2603,7 +2614,8 @@ void Trunk::writeRF_TSDU_U_Dereg_Ack(uint32_t srcId)
/// <param name="reason"></param>
/// <param name="service"></param>
/// <param name="aiv"></param>
void Trunk::writeRF_TSDU_Queue(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv)
/// <param name="grp"></param>
void Trunk::writeRF_TSDU_Queue(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv, bool grp)
{
std::unique_ptr<OSP_QUE_RSP> osp = new_unique(OSP_QUE_RSP);
osp->setAIV(aiv);
@ -2611,6 +2623,7 @@ void Trunk::writeRF_TSDU_Queue(uint32_t srcId, uint32_t dstId, uint8_t reason, u
osp->setDstId(dstId);
osp->setService(service);
osp->setResponse(reason);
osp->setGroup(grp);
if (m_verbose) {
LogMessage(LOG_RF, P25_TSDU_STR ", %s, AIV = %u, reason = $%02X, srcId = %u, dstId = %u",

@ -208,7 +208,7 @@ namespace p25
/// <summary>Helper to write a unit de-registration acknowledge packet.</summary>
void writeRF_TSDU_U_Dereg_Ack(uint32_t srcId);
/// <summary>Helper to write a queue packet.</summary>
void writeRF_TSDU_Queue(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv = false);
void writeRF_TSDU_Queue(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv = false, bool group = true);
/// <summary>Helper to write a location registration response packet.</summary>
bool writeRF_TSDU_Loc_Reg_Rsp(uint32_t srcId, uint32_t dstId, bool grp);

@ -389,7 +389,13 @@ bool Voice::process(uint8_t* data, uint32_t len)
m_p25->m_rfState = RS_RF_AUDIO;
m_p25->m_rfTGHang.start();
if (group) {
m_p25->m_rfTGHang.start();
}
else {
m_p25->m_rfTGHang.stop();
}
m_p25->m_rfLastDstId = dstId;
// make sure we actually got a HDU -- otherwise treat the call as a late entry

Loading…
Cancel
Save

Powered by TurnKey Linux.