mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-20 22:45:44 +08:00
Handle numeric messages correctly.
This commit is contained in:
@@ -22,6 +22,30 @@
|
|||||||
|
|
||||||
// #define DUMP_POCSAG
|
// #define DUMP_POCSAG
|
||||||
|
|
||||||
|
const struct BCD {
|
||||||
|
char m_c;
|
||||||
|
uint32_t m_bcd[5U];
|
||||||
|
} BCD_VALUES[] = {
|
||||||
|
{'0', {0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}},
|
||||||
|
{'1', {0x08000000U, 0x00800000U, 0x00080000U, 0x00008000U, 0x00000800U}},
|
||||||
|
{'2', {0x10000000U, 0x01000000U, 0x00100000U, 0x00010000U, 0x00001000U}},
|
||||||
|
{'3', {0x18000000U, 0x01800000U, 0x00180000U, 0x00018000U, 0x00001800U}},
|
||||||
|
{'4', {0x20000000U, 0x02000000U, 0x00200000U, 0x00020000U, 0x00002000U}},
|
||||||
|
{'5', {0x28000000U, 0x02800000U, 0x00280000U, 0x00028000U, 0x00002800U}},
|
||||||
|
{'6', {0x30000000U, 0x03000000U, 0x00300000U, 0x00030000U, 0x00003000U}},
|
||||||
|
{'7', {0x38000000U, 0x03800000U, 0x00380000U, 0x00038000U, 0x00003800U}},
|
||||||
|
{'8', {0x40000000U, 0x04000000U, 0x00400000U, 0x00040000U, 0x00004000U}},
|
||||||
|
{'9', {0x48000000U, 0x04800000U, 0x00480000U, 0x00048000U, 0x00004800U}},
|
||||||
|
{'U', {0x58000000U, 0x05800000U, 0x00580000U, 0x00058000U, 0x00005800U}},
|
||||||
|
{' ', {0x60000000U, 0x06000000U, 0x00600000U, 0x00060000U, 0x00006000U}},
|
||||||
|
{'-', {0x68000000U, 0x06800000U, 0x00680000U, 0x00068000U, 0x00006800U}},
|
||||||
|
{')', {0x70000000U, 0x07000000U, 0x00700000U, 0x00070000U, 0x00007000U}},
|
||||||
|
{'(', {0x78000000U, 0x07800000U, 0x00780000U, 0x00078000U, 0x00007800U}},
|
||||||
|
{0, {0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}}
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t BCD_SPACES[] = {0x66666000U, 0x06666000U, 0x00666000U, 0x00066000U, 0x00006000U};
|
||||||
|
|
||||||
const uint32_t DATA_MASK[] = { 0x40000000U, 0x20000000U, 0x10000000U,
|
const uint32_t DATA_MASK[] = { 0x40000000U, 0x20000000U, 0x10000000U,
|
||||||
0x08000000U, 0x04000000U, 0x02000000U, 0x01000000U,
|
0x08000000U, 0x04000000U, 0x02000000U, 0x01000000U,
|
||||||
0x00800000U, 0x00400000U, 0x00200000U, 0x00100000U,
|
0x00800000U, 0x00400000U, 0x00200000U, 0x00100000U,
|
||||||
@@ -32,6 +56,9 @@ const uint32_t DATA_MASK[] = { 0x40000000U, 0x20000000U, 0x10000000U
|
|||||||
const unsigned char ASCII_NUL = 0x00U;
|
const unsigned char ASCII_NUL = 0x00U;
|
||||||
const unsigned char ASCII_EOT = 0x04U;
|
const unsigned char ASCII_EOT = 0x04U;
|
||||||
|
|
||||||
|
const unsigned char FUNCTIONAL_NUMERIC = 0U;
|
||||||
|
const unsigned char FUNCTIONAL_ALPHANUMERIC = 3U;
|
||||||
|
|
||||||
CPOCSAGControl::CPOCSAGControl(CPOCSAGNetwork* network, CDisplay* display) :
|
CPOCSAGControl::CPOCSAGControl(CPOCSAGNetwork* network, CDisplay* display) :
|
||||||
m_network(network),
|
m_network(network),
|
||||||
m_display(display),
|
m_display(display),
|
||||||
@@ -83,13 +110,18 @@ bool CPOCSAGControl::processData()
|
|||||||
m_ric |= (data[1U] << 8) & 0x0000FF00U;
|
m_ric |= (data[1U] << 8) & 0x0000FF00U;
|
||||||
m_ric |= (data[2U] << 0) & 0x000000FFU;
|
m_ric |= (data[2U] << 0) & 0x000000FFU;
|
||||||
|
|
||||||
// uint8_t functional = data[3U];
|
unsigned char functional = data[3U];
|
||||||
|
|
||||||
m_text = std::string((char*)(data + 4U), length - 4U);
|
m_text = std::string((char*)(data + 4U), length - 4U);
|
||||||
|
|
||||||
|
LogDebug("Message to %07u, func %s: \"%s\"", m_ric, functional == FUNCTIONAL_NUMERIC ? "Numeric" : "Alphanumeric", m_text.c_str());
|
||||||
|
|
||||||
m_buffer.clear();
|
m_buffer.clear();
|
||||||
addAddress();
|
addAddress(functional);
|
||||||
|
if (functional == FUNCTIONAL_ALPHANUMERIC)
|
||||||
packASCII();
|
packASCII();
|
||||||
|
else
|
||||||
|
packNumeric();
|
||||||
|
|
||||||
// Ensure data is an even number of words
|
// Ensure data is an even number of words
|
||||||
if ((m_buffer.size() % 2U) == 1U)
|
if ((m_buffer.size() % 2U) == 1U)
|
||||||
@@ -173,9 +205,11 @@ void CPOCSAGControl::clock(unsigned int ms)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPOCSAGControl::addAddress()
|
void CPOCSAGControl::addAddress(unsigned char functional)
|
||||||
{
|
{
|
||||||
uint32_t word = 0x00001800U;
|
uint32_t word = 0x00000000U;
|
||||||
|
if (functional == FUNCTIONAL_ALPHANUMERIC)
|
||||||
|
word = 0x00001800U;
|
||||||
|
|
||||||
word |= (m_ric / POCSAG_FRAME_ADDRESSES) << 13;
|
word |= (m_ric / POCSAG_FRAME_ADDRESSES) << 13;
|
||||||
|
|
||||||
@@ -245,6 +279,44 @@ void CPOCSAGControl::packASCII()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPOCSAGControl::packNumeric()
|
||||||
|
{
|
||||||
|
uint32_t word = 0x80000000U;
|
||||||
|
unsigned int n = 0U;
|
||||||
|
|
||||||
|
for (std::string::const_iterator it = m_text.cbegin(); it != m_text.cend(); ++it) {
|
||||||
|
char c = *it;
|
||||||
|
|
||||||
|
const BCD* bcd = NULL;
|
||||||
|
for (unsigned int i = 0U; BCD_VALUES[i].m_c != 0; i++) {
|
||||||
|
if (BCD_VALUES[i].m_c == c) {
|
||||||
|
bcd = BCD_VALUES + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bcd != NULL) {
|
||||||
|
word |= bcd->m_bcd[n];
|
||||||
|
n++;
|
||||||
|
|
||||||
|
if (n == 5U) {
|
||||||
|
addBCHAndParity(word);
|
||||||
|
m_buffer.push_back(word);
|
||||||
|
word = 0x80000000U;
|
||||||
|
n = 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pack the remainder of the word with BCD spaces.
|
||||||
|
if (n != 0U) {
|
||||||
|
word |= BCD_SPACES[n];
|
||||||
|
|
||||||
|
addBCHAndParity(word);
|
||||||
|
m_buffer.push_back(word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CPOCSAGControl::addBCHAndParity(uint32_t& word) const
|
void CPOCSAGControl::addBCHAndParity(uint32_t& word) const
|
||||||
{
|
{
|
||||||
uint32_t temp = word;
|
uint32_t temp = word;
|
||||||
|
|||||||
@@ -62,8 +62,9 @@ private:
|
|||||||
|
|
||||||
bool processData();
|
bool processData();
|
||||||
void writeQueue();
|
void writeQueue();
|
||||||
void addAddress();
|
void addAddress(unsigned char functional);
|
||||||
void packASCII();
|
void packASCII();
|
||||||
|
void packNumeric();
|
||||||
void addBCHAndParity(uint32_t& word) const;
|
void addBCHAndParity(uint32_t& word) const;
|
||||||
bool openFile();
|
bool openFile();
|
||||||
bool writeFile(const unsigned char* data);
|
bool writeFile(const unsigned char* data);
|
||||||
|
|||||||
Reference in New Issue
Block a user