mirror of
https://github.com/g4klx/MMDVMHost.git
synced 2025-12-06 05:32:00 +01:00
POCSAG bug fixing.
This commit is contained in:
parent
b398bba1ea
commit
84dd3bf887
|
|
@ -1037,7 +1037,7 @@ bool CModem::writePOCSAGData(const unsigned char* data, unsigned int length)
|
||||||
unsigned char buffer[130U];
|
unsigned char buffer[130U];
|
||||||
|
|
||||||
buffer[0U] = MMDVM_FRAME_START;
|
buffer[0U] = MMDVM_FRAME_START;
|
||||||
buffer[1U] = length + 2U;
|
buffer[1U] = length + 3U;
|
||||||
buffer[2U] = MMDVM_POCSAG_DATA;
|
buffer[2U] = MMDVM_POCSAG_DATA;
|
||||||
|
|
||||||
::memcpy(buffer + 3U, data, length);
|
::memcpy(buffer + 3U, data, length);
|
||||||
|
|
|
||||||
|
|
@ -686,7 +686,7 @@ void CNextion::writePOCSAGInt(uint32_t ric, const std::string& message)
|
||||||
sendCommandAction(6U);
|
sendCommandAction(6U);
|
||||||
}
|
}
|
||||||
|
|
||||||
char text[30U];
|
char text[80U];
|
||||||
::sprintf(text, "dim=%u", m_brightness);
|
::sprintf(text, "dim=%u", m_brightness);
|
||||||
sendCommand(text);
|
sendCommand(text);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,15 @@
|
||||||
|
|
||||||
// #define DUMP_POCSAG
|
// #define DUMP_POCSAG
|
||||||
|
|
||||||
|
const uint32_t DATA_MASK[] = { 0x40000000U, 0x20000000U, 0x10000000U,
|
||||||
|
0x08000000U, 0x04000000U, 0x02000000U, 0x01000000U,
|
||||||
|
0x00800000U, 0x00400000U, 0x00200000U, 0x00100000U,
|
||||||
|
0x00080000U, 0x00040000U, 0x00020000U, 0x00010000U,
|
||||||
|
0x00008000U, 0x00004000U, 0x00002000U, 0x00001000U,
|
||||||
|
0x00000800U};
|
||||||
|
|
||||||
const unsigned char ASCII_EOT = 0x04U;
|
const unsigned char ASCII_EOT = 0x04U;
|
||||||
|
|
||||||
const unsigned char BIT_MASK_TABLE8[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
|
||||||
|
|
||||||
#define WRITE_BIT8(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE8[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE8[(i)&7])
|
|
||||||
#define READ_BIT8(p,i) (p[(i)>>3] & BIT_MASK_TABLE8[(i)&7])
|
|
||||||
|
|
||||||
CPOCSAGControl::CPOCSAGControl(CPOCSAGNetwork* network, CDisplay* display) :
|
CPOCSAGControl::CPOCSAGControl(CPOCSAGNetwork* network, CDisplay* display) :
|
||||||
m_network(network),
|
m_network(network),
|
||||||
m_display(display),
|
m_display(display),
|
||||||
|
|
@ -70,7 +72,7 @@ bool CPOCSAGControl::processData()
|
||||||
{
|
{
|
||||||
assert(m_network != NULL);
|
assert(m_network != NULL);
|
||||||
|
|
||||||
unsigned char data[40U];
|
unsigned char data[300U];
|
||||||
unsigned int length = m_network->read(data);
|
unsigned int length = m_network->read(data);
|
||||||
if (length == 0U)
|
if (length == 0U)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -104,8 +106,13 @@ void CPOCSAGControl::clock(unsigned int ms)
|
||||||
m_state = PS_WAITING;
|
m_state = PS_WAITING;
|
||||||
m_frames = 0U;
|
m_frames = 0U;
|
||||||
m_count = 1U;
|
m_count = 1U;
|
||||||
|
|
||||||
|
#if defined(DUMP_POCSAG)
|
||||||
|
openFile();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
m_output.clear();
|
m_output.clear();
|
||||||
m_output.push_back(POCSAG_SYNC_WORD);
|
m_output.push_back(POCSAG_SYNC_WORD);
|
||||||
|
|
||||||
|
|
@ -154,9 +161,13 @@ void CPOCSAGControl::clock(unsigned int ms)
|
||||||
m_frames++;
|
m_frames++;
|
||||||
|
|
||||||
if (m_state == PS_ENDING) {
|
if (m_state == PS_ENDING) {
|
||||||
LogMessage("POCSAG, transmitted %u frames of data from %u messages", m_frames, m_count);
|
LogMessage("POCSAG, transmitted %u frame(s) of data from %u message(s)", m_frames, m_count);
|
||||||
m_display->clearPOCSAG();
|
m_display->clearPOCSAG();
|
||||||
m_state = PS_NONE;
|
m_state = PS_NONE;
|
||||||
|
|
||||||
|
#if defined(DUMP_POCSAG)
|
||||||
|
closeFile();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,43 +184,45 @@ void CPOCSAGControl::addAddress()
|
||||||
|
|
||||||
void CPOCSAGControl::packASCII()
|
void CPOCSAGControl::packASCII()
|
||||||
{
|
{
|
||||||
|
const unsigned char MASK = 0x40U;
|
||||||
|
|
||||||
uint32_t word = 0x80000000U;
|
uint32_t word = 0x80000000U;
|
||||||
|
unsigned int n = 0U;
|
||||||
|
|
||||||
unsigned int n = 30U;
|
|
||||||
for (std::string::const_iterator it = m_text.cbegin(); it != m_text.cend(); ++it) {
|
for (std::string::const_iterator it = m_text.cbegin(); it != m_text.cend(); ++it) {
|
||||||
unsigned char MASK = 0x40U;
|
unsigned char c = *it;
|
||||||
for (unsigned int j = 0U; j < 7U; j++, MASK >>= 1) {
|
for (unsigned int j = 0U; j < 7U; j++, c <<= 1) {
|
||||||
bool b = (*it & MASK) == MASK;
|
bool b = (c & MASK) == MASK;
|
||||||
if (b)
|
if (b)
|
||||||
word |= (0x01U << n);
|
word |= DATA_MASK[n];
|
||||||
n--;
|
n++;
|
||||||
|
|
||||||
if (n == 10U) {
|
if (n == 20U) {
|
||||||
addBCHAndParity(word);
|
addBCHAndParity(word);
|
||||||
m_buffer.push_back(word);
|
m_buffer.push_back(word);
|
||||||
word = 0x80000000U;
|
word = 0x80000000U;
|
||||||
n = 30U;
|
n = 0U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add at least one EOT to the message
|
// Add at least one EOT to the message
|
||||||
do {
|
do {
|
||||||
unsigned char MASK = 0x70U;
|
unsigned char c = ASCII_EOT;
|
||||||
for (unsigned int j = 0U; j < 7U; j++, MASK >>= 1) {
|
for (unsigned int j = 0U; j < 7U; j++, c <<= 1) {
|
||||||
bool b = (ASCII_EOT & MASK) == MASK;
|
bool b = (c & MASK) == MASK;
|
||||||
if (b)
|
if (b)
|
||||||
word |= (0x01U << n);
|
word |= DATA_MASK[n];
|
||||||
n--;
|
n++;
|
||||||
|
|
||||||
if (n == 10U) {
|
if (n == 20U) {
|
||||||
addBCHAndParity(word);
|
addBCHAndParity(word);
|
||||||
m_buffer.push_back(word);
|
m_buffer.push_back(word);
|
||||||
word = 0x80000000U;
|
word = 0x80000000U;
|
||||||
n = 30U;
|
n = 0U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (n != 30U);
|
} while (n != 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPOCSAGControl::addBCHAndParity(uint32_t& word) const
|
void CPOCSAGControl::addBCHAndParity(uint32_t& word) const
|
||||||
|
|
@ -238,23 +251,27 @@ void CPOCSAGControl::addBCHAndParity(uint32_t& word) const
|
||||||
void CPOCSAGControl::writeQueue()
|
void CPOCSAGControl::writeQueue()
|
||||||
{
|
{
|
||||||
// Convert 32-bit words to bytes
|
// Convert 32-bit words to bytes
|
||||||
unsigned int n = 0U;
|
|
||||||
unsigned char data[POCSAG_FRAME_LENGTH_BYTES];
|
unsigned char data[POCSAG_FRAME_LENGTH_BYTES];
|
||||||
for (unsigned int i = 0U; i < POCSAG_FRAME_LENGTH_WORDS; i++) {
|
unsigned char len = 0U;
|
||||||
uint32_t w = m_output.front();
|
for (std::deque<uint32_t>::const_iterator it = m_output.cbegin(); it != m_output.cend(); ++it) {
|
||||||
m_output.pop_front();
|
uint32_t word = *it;
|
||||||
|
|
||||||
for (unsigned int j = 0U; j < 31U; j++, w <<= 1) {
|
data[len++] = word >> 24;
|
||||||
bool b = (w & 0x80000000U) == 0x80000000U;
|
data[len++] = word >> 16;
|
||||||
WRITE_BIT8(data, n, b);
|
data[len++] = word >> 8;
|
||||||
n++;
|
data[len++] = word >> 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char len = POCSAG_FRAME_LENGTH_BYTES;
|
m_output.clear();
|
||||||
|
|
||||||
|
#if defined(DUMP_POCSAG)
|
||||||
|
writeFile(data);
|
||||||
|
#endif
|
||||||
|
|
||||||
CUtils::dump(1U, "Data to MMDVM", data, len);
|
CUtils::dump(1U, "Data to MMDVM", data, len);
|
||||||
|
|
||||||
|
assert(len == POCSAG_FRAME_LENGTH_BYTES);
|
||||||
|
|
||||||
unsigned int space = m_queue.freeSpace();
|
unsigned int space = m_queue.freeSpace();
|
||||||
if (space < (len + 1U)) {
|
if (space < (len + 1U)) {
|
||||||
LogError("POCSAG, overflow in the POCSAG RF queue");
|
LogError("POCSAG, overflow in the POCSAG RF queue");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue