Skip to content

Commit

Permalink
Change the semantics of the NID processor.
Browse files Browse the repository at this point in the history
  • Loading branch information
g4klx committed Sep 19, 2016
1 parent 3567d83 commit c8cb7a5
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 29 deletions.
6 changes: 0 additions & 6 deletions BCH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@
*/

#include "BCH.h"
#include "Utils.h"
#include "Log.h"

#include <cmath>
#include <cstdio>
Expand Down Expand Up @@ -127,8 +125,6 @@ void CBCH::encode(unsigned char* nid)
{
assert(nid != NULL);

CUtils::dump(1U, "data", nid, 2U);

int data[16];
for (int i = 0; i < 16; i++)
data[i] = READ_BIT(nid, i) ? 1 : 0;
Expand All @@ -140,6 +136,4 @@ void CBCH::encode(unsigned char* nid)
bool b = bb[i] == 1;
WRITE_BIT(nid, i + 16U, b);
}

CUtils::dump(1U, "out", nid, 8U);
}
48 changes: 40 additions & 8 deletions P25Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ m_netBits(0U),
m_netErrs(0U),
m_netLost(0U),
m_nid(nac),
m_lastDUID(P25_DUID_TERM),
m_audio(),
m_rfData(),
m_netData()
Expand Down Expand Up @@ -95,22 +96,36 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
if (!sync && m_rfState == RS_RF_LISTENING)
return false;

// Regenerate the NID
m_nid.process(data + 2U);
unsigned char duid = m_nid.getDUID();
unsigned int nac = m_nid.getNAC();

LogDebug("P25, DUID=$%X NAC=$%03X", duid, nac);
// Decode the NID
bool valid = m_nid.decode(data + 2U);

if (m_rfState == RS_RF_LISTENING && nac != m_nac)
if (m_rfState == RS_RF_LISTENING && !valid)
return false;

if (data[0U] == TAG_HEADER) {
unsigned char duid = m_nid.getDUID();
if (!valid) {
switch (m_lastDUID) {
case P25_DUID_HEADER:
case P25_DUID_LDU2:
duid = P25_DUID_LDU1;
break;
case P25_DUID_LDU1:
duid = P25_DUID_LDU2;
break;
default:
break;
}
}

if (duid == P25_DUID_HEADER) {
m_rfData.reset();

// Regenerate Sync
CSync::addP25Sync(data + 2U);

// Regenerate NID
m_nid.encode(data + 2U, P25_DUID_HEADER);

// Regenerate Enc Data
m_rfData.processHeader(data + 2U);

Expand All @@ -121,6 +136,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
m_rfErrs = 0U;
m_rfBits = 1U;
m_rfTimeout.start();
m_lastDUID = duid;

#if defined(DUMP_P25)
openFile();
Expand Down Expand Up @@ -150,6 +166,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate Sync
CSync::addP25Sync(data + 2U);

// Regenerate NID
m_nid.encode(data + 2U, P25_DUID_LDU1);

// Regenerate LDU1 Data
m_rfData.processLDU1(data + 2U);

Expand All @@ -163,6 +182,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
m_rfBits += 1233U;
m_rfErrs += errors;
m_rfFrames++;
m_lastDUID = duid;

// Add busy bits
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
Expand Down Expand Up @@ -195,6 +215,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate Sync
CSync::addP25Sync(data + 2U);

// Regenerate NID
m_nid.encode(data + 2U, P25_DUID_LDU2);

// Regenerate LDU2 Data
m_rfData.processLDU2(data + 2U);

Expand All @@ -208,6 +231,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
m_rfBits += 1233U;
m_rfErrs += errors;
m_rfFrames++;
m_lastDUID = duid;

// Add busy bits
addBusyBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, false, true);
Expand All @@ -230,6 +254,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate Sync
CSync::addP25Sync(data + 2U);

// Regenerate NID
m_nid.encode(data + 2U, P25_DUID_TERM_LC);

// Regenerate LDU1 Data
m_rfData.processTerminator(data + 2U);

Expand All @@ -239,6 +266,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
m_rfState = RS_RF_LISTENING;
m_rfTimeout.stop();
m_rfData.reset();
m_lastDUID = duid;

LogMessage("P25, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
m_display->clearP25();
Expand All @@ -261,12 +289,16 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate Sync
CSync::addP25Sync(data + 2U);

// Regenerate NID
m_nid.encode(data + 2U, P25_DUID_TERM);

// Add busy bits
addBusyBits(data + 2U, P25_TERM_FRAME_LENGTH_BITS, false, true);

m_rfState = RS_RF_LISTENING;
m_rfTimeout.stop();
m_rfData.reset();
m_lastDUID = duid;

LogMessage("P25, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
m_display->clearP25();
Expand Down
1 change: 1 addition & 0 deletions P25Control.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class CP25Control {
unsigned int m_netErrs;
unsigned int m_netLost;
CP25NID m_nid;
unsigned char m_lastDUID;
CP25Audio m_audio;
CP25Data m_rfData;
CP25Data m_netData;
Expand Down
84 changes: 72 additions & 12 deletions P25NID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
#include <cstdio>
#include <cassert>

const unsigned int MAX_NID_ERRS = 5U;

CP25NID::CP25NID(unsigned int nac) :
m_duid(0U),
m_nac(0U),
m_hdr(NULL),
m_ldu1(NULL),
m_ldu2(NULL),
Expand Down Expand Up @@ -80,30 +81,89 @@ CP25NID::~CP25NID()
delete[] m_term;
}

bool CP25NID::process(unsigned char* data)
bool CP25NID::decode(const unsigned char* data)
{
assert(data != NULL);

unsigned char nid[P25_NID_LENGTH_BYTES];

CP25Utils::decode(data, nid, 48U, 114U);

m_duid = nid[1U] & 0x0FU;

m_nac = (nid[0U] << 4) & 0xFF0U;
m_nac |= (nid[1U] >> 4) & 0x00FU;
unsigned int errs = compare(nid, m_ldu1);
if (errs < MAX_NID_ERRS) {
m_duid = P25_DUID_LDU1;
return true;
}

errs = compare(nid, m_ldu2);
if (errs < MAX_NID_ERRS) {
m_duid = P25_DUID_LDU2;
return true;
}

errs = compare(nid, m_term);
if (errs < MAX_NID_ERRS) {
m_duid = P25_DUID_TERM;
return true;
}

errs = compare(nid, m_termlc);
if (errs < MAX_NID_ERRS) {
m_duid = P25_DUID_TERM_LC;
return true;
}

errs = compare(nid, m_hdr);
if (errs < MAX_NID_ERRS) {
m_duid = P25_DUID_HEADER;
return true;
}

return false;
}

CP25Utils::encode(nid, data, 48U, 114U);
void CP25NID::encode(unsigned char* data, unsigned char duid) const
{
assert(data != NULL);

return true;
switch (duid) {
case P25_DUID_HEADER:
CP25Utils::encode(m_hdr, data, 48U, 114U);
break;
case P25_DUID_LDU1:
CP25Utils::encode(m_ldu1, data, 48U, 114U);
break;
case P25_DUID_LDU2:
CP25Utils::encode(m_ldu2, data, 48U, 114U);
break;
case P25_DUID_TERM:
CP25Utils::encode(m_term, data, 48U, 114U);
break;
case P25_DUID_TERM_LC:
CP25Utils::encode(m_termlc, data, 48U, 114U);
break;
default:
break;
}
}

unsigned char CP25NID::getDUID() const
{
return m_duid;
}

unsigned int CP25NID::getNAC() const
unsigned int CP25NID::compare(const unsigned char* nid1, const unsigned char* nid2) const
{
return m_nac;
}
assert(nid1 != NULL);
assert(nid2 != NULL);

unsigned int errs = 0U;
for (unsigned int i = 0U; i < P25_NID_LENGTH_BYTES; i++) {
unsigned char v = nid1[i] ^ nid2[i];
while (v != 0U) {
v &= v - 1U;
errs++;
}
}

return errs;
}
8 changes: 5 additions & 3 deletions P25NID.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,21 @@ class CP25NID {
CP25NID(unsigned int nac);
~CP25NID();

bool process(unsigned char* data);
bool decode(const unsigned char* data);

unsigned char getDUID() const;
unsigned int getNAC() const;

void encode(unsigned char* data, unsigned char duid) const;

private:
unsigned char m_duid;
unsigned int m_nac;
unsigned char* m_hdr;
unsigned char* m_ldu1;
unsigned char* m_ldu2;
unsigned char* m_termlc;
unsigned char* m_term;

unsigned int compare(const unsigned char* nid1, const unsigned char* nid2) const;
};

#endif

0 comments on commit c8cb7a5

Please sign in to comment.