more very very experimental PDU AMBT support;

pull/12/head
Bryan Biedenkapp 4 years ago
parent 04ee216459
commit 842c17c985

@ -310,11 +310,7 @@ bool DataPacket::process(uint8_t* data, uint32_t len)
}
for (uint32_t i = 0; i < blocksToFollow; i++) {
uint8_t data[P25_TSBK_FEC_LENGTH_BYTES + 2U];
::memset(data, 0x00U, P25_TSBK_FEC_LENGTH_BYTES + 2U);
uint32_t len = m_rfData[i].getData(data + 2U);
m_p25->m_trunk->process(data, len, true);
m_p25->m_trunk->processMBT(m_rfDataHeader, m_rfData);
}
}
break;

@ -34,6 +34,7 @@
#include "Utils.h"
using namespace p25;
using namespace p25::data;
#include <cassert>
#include <cstdio>
@ -189,7 +190,10 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len, bool blockData)
m_p25->m_queue.clear();
// special case to avoid resetting the TSBK state and handle MBTs (this is a horrible hack)
if (len != 1U && !blockData) {
resetRF();
}
resetNet();
bool ret = m_rfTSBK.decode(data + 2U);
@ -750,6 +754,29 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
return true;
}
/// <summary>
/// Helper used to process AMBTs from PDU data.
/// </summary>
/// <param name="dataHeader"></param>
/// <param name="dataBlock"></param>
bool TrunkPacket::processMBT(DataHeader dataHeader, DataBlock* blocks)
{
uint8_t data[1U];
::memset(data, 0x00U, 1U);
bool ret = true;
for (uint32_t i = 0; i < dataHeader.getBlocksToFollow(); i++) {
bool decodeRet = m_rfTSBK.decodeMBT(dataHeader, blocks[i]);
if (decodeRet) {
process(data, 0U, true);
} else {
ret = false;
}
}
return ret;
}
/// <summary>
/// Helper to write P25 adjacent site information to the network.
/// </summary>

@ -27,6 +27,8 @@
#define __P25_TRUNK_PACKET_H__
#include "Defines.h"
#include "p25/data/DataHeader.h"
#include "p25/data/DataBlock.h"
#include "p25/lc/TSBK.h"
#include "p25/lc/TDULC.h"
#include "p25/Control.h"
@ -65,6 +67,9 @@ namespace p25
/// <summary>Process a data frame from the network.</summary>
bool processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::LowSpeedData& lsd, uint8_t& duid);
/// <summary>Helper used to process AMBTs from PDU data.</summary>
bool processMBT(data::DataHeader dataHeader, data::DataBlock* blocks);
/// <summary>Helper to write P25 adjacent site information to the network.</summary>
void writeAdjSSNetwork();

@ -82,6 +82,8 @@ bool DataBlock::decode(const uint8_t* data, const DataHeader header)
m_headerSap = header.getSAP();
if (m_fmt == PDU_FMT_CONFIRMED) {
// decode 3/4 rate Trellis
try {
m_confirmed = true;
bool valid = m_trellis.decode34(data, buffer);
if (!valid) {
@ -126,7 +128,14 @@ bool DataBlock::decode(const uint8_t* data, const DataHeader header)
LogWarning(LOG_P25, "P25_DUID_PDU, fmt = $%02X, invalid crc = $%04X != $%04X (computed)", m_fmt, crc, computedCRC);
}
}
else if ((m_fmt == PDU_FMT_UNCONFIRMED) || (m_fmt == PDU_FMT_RSP)) {
catch (...) {
Utils::dump(2U, "P25, decoding excepted with input data", data, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
return false;
}
}
else if ((m_fmt == PDU_FMT_UNCONFIRMED) || (m_fmt == PDU_FMT_RSP) || (m_fmt == PDU_FMT_AMBT)) {
// decode 3/4 rate Trellis
try {
m_confirmed = false;
bool valid = m_trellis.decode12(data, buffer);
if (!valid) {
@ -139,8 +148,10 @@ bool DataBlock::decode(const uint8_t* data, const DataHeader header)
m_data[i] = buffer[i]; // Payload Data
}
}
else if (m_fmt == PDU_FMT_AMBT) {
// ignore AMBT this is handled else where
catch (...) {
Utils::dump(2U, "P25, decoding excepted with input data", data, P25_PDU_UNCONFIRMED_LENGTH_BYTES);
return false;
}
}
else {
LogError(LOG_P25, "unknown FMT value in P25_DUID_PDU, fmt = $%02X", m_fmt);
@ -186,7 +197,7 @@ void DataBlock::encode(uint8_t* data)
m_trellis.encode34(buffer, data);
}
else if ((m_fmt == PDU_FMT_UNCONFIRMED) || (m_fmt == PDU_FMT_RSP && !m_confirmed)) {
else if ((m_fmt == PDU_FMT_UNCONFIRMED) || (m_fmt == PDU_FMT_RSP && !m_confirmed) || (m_fmt == PDU_FMT_AMBT)) {
uint8_t buffer[P25_PDU_UNCONFIRMED_LENGTH_BYTES];
::memset(buffer, 0x00U, P25_PDU_UNCONFIRMED_LENGTH_BYTES);
@ -196,9 +207,6 @@ void DataBlock::encode(uint8_t* data)
m_trellis.encode12(buffer, data);
}
else if (m_fmt == PDU_FMT_AMBT) {
// ignore AMBT this is handled else where
}
else {
LogError(LOG_P25, "unknown FMT value in P25_DUID_PDU, fmt = $%02X", m_fmt);
return;

@ -176,6 +176,104 @@ TSBK& TSBK::operator=(const TSBK& data)
return *this;
}
/// <summary>
/// Decode a alternate trunking signalling block.
/// </summary>
/// <param name="dataHeader"></param>
/// <param name="block"></param>
/// <returns>True, if TSBK was decoded, otherwise false.</returns>
bool TSBK::decodeMBT(const data::DataHeader dataHeader, data::DataBlock block)
{
// get the raw block data
uint8_t pduBlock[P25_PDU_UNCONFIRMED_LENGTH_BYTES];
bool ret = block.decode(pduBlock, dataHeader);
if (!ret) {
m_decodedMBT = false;
LogError(LOG_P25, "TSBK::decode(), failed to decode PDU data block");
return false;
}
m_lco = dataHeader.getAMBTOpcode(); // LCO
m_lastBlock = true;
m_mfId = dataHeader.getMFId(); // Mfg Id.
ulong64_t tsbkValue = 0U;
if (dataHeader.getFormat() == PDU_FMT_AMBT) {
// combine bytes into rs value
tsbkValue = dataHeader.getAMBTField8();
tsbkValue = (tsbkValue << 8) + dataHeader.getAMBTField9();
tsbkValue = (tsbkValue << 8) + pduBlock[0U];
tsbkValue = (tsbkValue << 8) + pduBlock[1U];
tsbkValue = (tsbkValue << 8) + pduBlock[2U];
tsbkValue = (tsbkValue << 8) + pduBlock[3U];
tsbkValue = (tsbkValue << 8) + pduBlock[4U];
tsbkValue = (tsbkValue << 8) + pduBlock[5U];
} else {
// combine bytes into rs value
tsbkValue = pduBlock[0U];
tsbkValue = (tsbkValue << 8) + pduBlock[1U];
tsbkValue = (tsbkValue << 8) + pduBlock[2U];
tsbkValue = (tsbkValue << 8) + pduBlock[3U];
tsbkValue = (tsbkValue << 8) + pduBlock[4U];
tsbkValue = (tsbkValue << 8) + pduBlock[5U];
tsbkValue = (tsbkValue << 8) + pduBlock[6U];
tsbkValue = (tsbkValue << 8) + pduBlock[7U];
}
// Motorola P25 vendor opcodes
if (m_mfId == P25_MFG_MOT) {
switch (m_lco) {
case TSBK_IOSP_GRP_VCH:
case TSBK_IOSP_UU_VCH:
case TSBK_IOSP_UU_ANS:
case TSBK_IOSP_TELE_INT_ANS:
case TSBK_IOSP_STS_UPDT:
case TSBK_IOSP_STS_Q:
case TSBK_IOSP_MSG_UPDT:
case TSBK_IOSP_CALL_ALRT:
case TSBK_IOSP_ACK_RSP:
case TSBK_IOSP_GRP_AFF:
case TSBK_IOSP_U_REG:
case TSBK_ISP_CAN_SRV_REQ:
case TSBK_ISP_GRP_AFF_Q_RSP:
case TSBK_OSP_DENY_RSP:
case TSBK_OSP_QUE_RSP:
case TSBK_ISP_U_DEREG_REQ:
case TSBK_OSP_U_DEREG_ACK:
case TSBK_ISP_LOC_REG_REQ:
m_mfId = P25_MFG_STANDARD;
break;
default:
LogError(LOG_P25, "TSBK::decodeMBT(), unknown TSBK LCO value, mfId = $%02X, lco = $%02X", m_mfId, m_lco);
break;
}
if (m_mfId == P25_MFG_MOT) {
return true;
}
else {
m_mfId = dataHeader.getMFId();
}
}
// standard P25 reference opcodes
switch (m_lco) {
case TSBK_IOSP_GRP_AFF:
m_netId = (uint32_t)((tsbkValue >> 44) & 0xFFFFFU); // Network ID
m_sysId = (uint32_t)((tsbkValue >> 32) & 0xFFFU); // System ID
m_dstId = (uint32_t)((tsbkValue >> 24) & 0xFFFFU); // Talkgroup Address
m_srcId = dataHeader.getLLId(); // Source Radio Address
break;
default:
LogError(LOG_P25, "TSBK::decodeMBT(), unknown TSBK LCO value, mfId = $%02X, lco = $%02X", m_mfId, m_lco);
break;
}
m_decodedMBT = true;
return true;
}
/// <summary>
/// Decode a trunking signalling block.
/// </summary>
@ -183,6 +281,11 @@ TSBK& TSBK::operator=(const TSBK& data)
/// <returns>True, if TSBK was decoded, otherwise false.</returns>
bool TSBK::decode(const uint8_t* data)
{
if (!m_decodedMBT) {
m_decodedMBT = false;
return true;
}
assert(data != NULL);
// deinterleave
@ -1002,6 +1105,7 @@ TSBK::TSBK(SiteData siteData) :
m_sndcpAutoAccess(true),
m_sndcpReqAccess(false),
m_sndcpDAC(1U),
m_decodedMBT(false),
m_siteCallsign(NULL)
{
m_siteCallsign = new uint8_t[P25_MOT_CALLSIGN_LENGTH_BYTES];

@ -27,6 +27,8 @@
#define __P25_LC__TSBK_H__
#include "Defines.h"
#include "p25/data/DataHeader.h"
#include "p25/data/DataBlock.h"
#include "p25/edac/Trellis.h"
#include "p25/lc/LC.h"
#include "p25/lc/TDULC.h"
@ -75,6 +77,9 @@ namespace p25
/// <summary>Equals operator.</summary>
TSBK& operator=(const TSBK& data);
/// <summary>Decode a alternate trunking signalling block.</summary>
bool decodeMBT(const data::DataHeader dataHeader, data::DataBlock block);
/// <summary>Decode a trunking signalling block.</summary>
bool decode(const uint8_t* data);
/// <summary>Encode a trunking signalling block.</summary>
@ -212,6 +217,8 @@ namespace p25
bool m_sndcpReqAccess;
uint16_t m_sndcpDAC;
bool m_decodedMBT;
/** Local Site data */
uint8_t* m_siteCallsign;
};

Loading…
Cancel
Save

Powered by TurnKey Linux.