mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-22 08:05:49 +08:00
More work with decoding and regenerating P25.
This commit is contained in:
216
P25Data.cpp
216
P25Data.cpp
@@ -17,6 +17,10 @@
|
||||
*/
|
||||
|
||||
#include "P25Data.h"
|
||||
#include "P25Defines.h"
|
||||
#include "P25Utils.h"
|
||||
#include "Hamming.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
||||
@@ -37,96 +41,130 @@ CP25Data::~CP25Data()
|
||||
|
||||
void CP25Data::processHeader(unsigned char* data)
|
||||
{
|
||||
unsigned char raw[81U];
|
||||
CP25Utils::decode(data, raw, 114U, 780U);
|
||||
|
||||
CUtils::dump(1U, "P25, raw header", raw, 81U);
|
||||
|
||||
// XXX Need to add FEC code
|
||||
}
|
||||
|
||||
void CP25Data::processLDU1(unsigned char* data)
|
||||
{
|
||||
// XXX No FEC done yet
|
||||
bool b[24U];
|
||||
b[7U] = READ_BIT(data, 411U);
|
||||
b[6U] = READ_BIT(data, 410U);
|
||||
b[5U] = READ_BIT(data, 413U);
|
||||
b[4U] = READ_BIT(data, 412U);
|
||||
b[3U] = READ_BIT(data, 415U);
|
||||
b[2U] = READ_BIT(data, 414U);
|
||||
b[1U] = READ_BIT(data, 421U);
|
||||
b[0U] = READ_BIT(data, 420U);
|
||||
unsigned char rs[18U];
|
||||
|
||||
unsigned char format = 0U;
|
||||
unsigned char mult = 1U;
|
||||
for (unsigned int i = 0U; i < 8U; i++, mult <<= 1)
|
||||
format += b[i] ? mult : 0U;
|
||||
unsigned char raw[5U];
|
||||
CP25Utils::decode(data, raw, 410U, 452U);
|
||||
decodeLDUHamming(raw, rs + 0U);
|
||||
|
||||
LogDebug("P25, LC_format = $%02X", format);
|
||||
CP25Utils::decode(data, raw, 600U, 640U);
|
||||
decodeLDUHamming(raw, rs + 3U);
|
||||
|
||||
if (format == 0x03U) {
|
||||
LogDebug("P25, non talk group destination");
|
||||
m_group = false;
|
||||
} else {
|
||||
m_group = true;
|
||||
CP25Utils::decode(data, raw, 788U, 830U);
|
||||
decodeLDUHamming(raw, rs + 6U);
|
||||
|
||||
b[15U] = READ_BIT(data, 613U); // 39
|
||||
b[14U] = READ_BIT(data, 612U);
|
||||
b[13U] = READ_BIT(data, 615U); // 37
|
||||
b[12U] = READ_BIT(data, 614U);
|
||||
b[11U] = READ_BIT(data, 621U); // 35
|
||||
b[10U] = READ_BIT(data, 620U);
|
||||
b[9U] = READ_BIT(data, 623U); // 33
|
||||
b[8U] = READ_BIT(data, 622U);
|
||||
b[7U] = READ_BIT(data, 625U); // 31
|
||||
b[6U] = READ_BIT(data, 624U);
|
||||
b[5U] = READ_BIT(data, 631U); // 29
|
||||
b[4U] = READ_BIT(data, 630U);
|
||||
b[3U] = READ_BIT(data, 633U); // 27
|
||||
b[2U] = READ_BIT(data, 632U);
|
||||
b[1U] = READ_BIT(data, 635U);
|
||||
b[0U] = READ_BIT(data, 634U); // 24
|
||||
CP25Utils::decode(data, raw, 978U, 1020U);
|
||||
decodeLDUHamming(raw, rs + 9U);
|
||||
|
||||
mult = 1U;
|
||||
for (unsigned int i = 0U; i < 16U; i++, mult <<= 1)
|
||||
m_dest += b[i] ? mult : 0U;
|
||||
CP25Utils::decode(data, raw, 1168U, 1208U);
|
||||
decodeLDUHamming(raw, rs + 12U);
|
||||
|
||||
LogDebug("P25, TG ID = %u", m_dest);
|
||||
CP25Utils::decode(data, raw, 1356U, 1398U);
|
||||
decodeLDUHamming(raw, rs + 15U);
|
||||
|
||||
CUtils::dump(1U, "P25, LDU1 Data after Hamming", rs, 18U);
|
||||
|
||||
switch (rs[0U]) {
|
||||
case P25_LCF_GROUP:
|
||||
m_dest = (rs[4U] << 8) + rs[5U];
|
||||
m_source = (rs[6U] << 16) + (rs[7U] << 8) + rs[8U];
|
||||
m_group = true;
|
||||
break;
|
||||
case P25_LCF_PRIVATE:
|
||||
m_dest = (rs[3U] << 16) + (rs[4U] << 8) + rs[5U];
|
||||
m_source = (rs[6U] << 16) + (rs[7U] << 8) + rs[8U];
|
||||
m_group = false;
|
||||
break;
|
||||
default:
|
||||
LogMessage("P25, unknown LCF value in LDU1 - $%02X", rs[0U]);
|
||||
break;
|
||||
}
|
||||
|
||||
b[23U] = READ_BIT(data, 789U);
|
||||
b[22U] = READ_BIT(data, 788U);
|
||||
b[21U] = READ_BIT(data, 793U);
|
||||
b[20U] = READ_BIT(data, 792U);
|
||||
b[19U] = READ_BIT(data, 795U);
|
||||
b[18U] = READ_BIT(data, 794U);
|
||||
b[17U] = READ_BIT(data, 801U);
|
||||
b[16U] = READ_BIT(data, 800U);
|
||||
b[15U] = READ_BIT(data, 803U);
|
||||
b[14U] = READ_BIT(data, 802U);
|
||||
b[13U] = READ_BIT(data, 805U);
|
||||
b[12U] = READ_BIT(data, 804U);
|
||||
b[11U] = READ_BIT(data, 811U);
|
||||
b[10U] = READ_BIT(data, 810U);
|
||||
b[9U] = READ_BIT(data, 813U);
|
||||
b[8U] = READ_BIT(data, 812U);
|
||||
b[7U] = READ_BIT(data, 815U);
|
||||
b[6U] = READ_BIT(data, 814U);
|
||||
b[5U] = READ_BIT(data, 821U);
|
||||
b[4U] = READ_BIT(data, 820U);
|
||||
b[3U] = READ_BIT(data, 823U);
|
||||
b[2U] = READ_BIT(data, 822U);
|
||||
b[1U] = READ_BIT(data, 825U);
|
||||
b[0U] = READ_BIT(data, 824U);
|
||||
// XXX Need to add FEC code
|
||||
|
||||
mult = 1U;
|
||||
for (unsigned int i = 0U; i < 24U; i++, mult <<= 1)
|
||||
m_source += b[i] ? mult : 0U;
|
||||
encodeLDUHamming(raw, rs + 0U);
|
||||
CP25Utils::encode(raw, data, 410U, 452U);
|
||||
|
||||
LogDebug("P25, SRC ID = %u", m_source);
|
||||
encodeLDUHamming(raw, rs + 3U);
|
||||
CP25Utils::encode(raw, data, 600U, 640U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 6U);
|
||||
CP25Utils::encode(raw, data, 788U, 830U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 9U);
|
||||
CP25Utils::encode(raw, data, 978U, 1020U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 12U);
|
||||
CP25Utils::encode(raw, data, 1168U, 1208U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 15U);
|
||||
CP25Utils::encode(raw, data, 1356U, 1398U);
|
||||
}
|
||||
|
||||
void CP25Data::processLDU2(unsigned char* data)
|
||||
{
|
||||
unsigned char rs[18U];
|
||||
|
||||
unsigned char raw[5U];
|
||||
CP25Utils::decode(data, raw, 410U, 452U);
|
||||
decodeLDUHamming(raw, rs + 0U);
|
||||
|
||||
CP25Utils::decode(data, raw, 600U, 640U);
|
||||
decodeLDUHamming(raw, rs + 3U);
|
||||
|
||||
CP25Utils::decode(data, raw, 788U, 830U);
|
||||
decodeLDUHamming(raw, rs + 6U);
|
||||
|
||||
CP25Utils::decode(data, raw, 978U, 1020U);
|
||||
decodeLDUHamming(raw, rs + 9U);
|
||||
|
||||
CP25Utils::decode(data, raw, 1168U, 1208U);
|
||||
decodeLDUHamming(raw, rs + 12U);
|
||||
|
||||
CP25Utils::decode(data, raw, 1356U, 1398U);
|
||||
decodeLDUHamming(raw, rs + 15U);
|
||||
|
||||
CUtils::dump(1U, "P25, LDU2 Data after Hamming", rs, 18U);
|
||||
|
||||
// XXX Need to add FEC code
|
||||
|
||||
encodeLDUHamming(raw, rs + 0U);
|
||||
CP25Utils::encode(raw, data, 410U, 452U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 3U);
|
||||
CP25Utils::encode(raw, data, 600U, 640U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 6U);
|
||||
CP25Utils::encode(raw, data, 788U, 830U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 9U);
|
||||
CP25Utils::encode(raw, data, 978U, 1020U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 12U);
|
||||
CP25Utils::encode(raw, data, 1168U, 1208U);
|
||||
|
||||
encodeLDUHamming(raw, rs + 15U);
|
||||
CP25Utils::encode(raw, data, 1356U, 1398U);
|
||||
}
|
||||
|
||||
void CP25Data::processTerminator(unsigned char* data)
|
||||
{
|
||||
unsigned char raw[36U];
|
||||
CP25Utils::decode(data, raw, 114U, 210U);
|
||||
|
||||
CUtils::dump(1U, "P25, raw terminator", raw, 36U);
|
||||
|
||||
// XXX Need to add FEC code, or do we?
|
||||
}
|
||||
|
||||
unsigned int CP25Data::getSource() const
|
||||
@@ -149,3 +187,45 @@ void CP25Data::reset()
|
||||
m_source = 0U;
|
||||
m_dest = 0U;
|
||||
}
|
||||
|
||||
void CP25Data::decodeLDUHamming(const unsigned char* data, unsigned char* raw)
|
||||
{
|
||||
unsigned int n = 0U;
|
||||
unsigned int m = 0U;
|
||||
for (unsigned int i = 0U; i < 4U; i++) {
|
||||
bool hamming[10U];
|
||||
|
||||
for (unsigned int j = 0U; j < 10U; j++) {
|
||||
hamming[j] = READ_BIT(data, n);
|
||||
n++;
|
||||
}
|
||||
|
||||
CHamming::decode1063(hamming);
|
||||
|
||||
for (unsigned int j = 0U; j < 6U; j++) {
|
||||
WRITE_BIT(raw, m, hamming[j]);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CP25Data::encodeLDUHamming(unsigned char* data, const unsigned char* raw)
|
||||
{
|
||||
unsigned int n = 0U;
|
||||
unsigned int m = 0U;
|
||||
for (unsigned int i = 0U; i < 4U; i++) {
|
||||
bool hamming[10U];
|
||||
|
||||
for (unsigned int j = 0U; j < 6U; j++) {
|
||||
hamming[j] = READ_BIT(raw, m);
|
||||
m++;
|
||||
}
|
||||
|
||||
CHamming::encode1063(hamming);
|
||||
|
||||
for (unsigned int j = 0U; j < 10U; j++) {
|
||||
WRITE_BIT(data, n, hamming[j]);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user