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];
|
||||
|
||||
buffer[0U] = MMDVM_FRAME_START;
|
||||
buffer[1U] = length + 2U;
|
||||
buffer[1U] = length + 3U;
|
||||
buffer[2U] = MMDVM_POCSAG_DATA;
|
||||
|
||||
::memcpy(buffer + 3U, data, length);
|
||||
|
|
|
@ -686,7 +686,7 @@ void CNextion::writePOCSAGInt(uint32_t ric, const std::string& message)
|
|||
sendCommandAction(6U);
|
||||
}
|
||||
|
||||
char text[30U];
|
||||
char text[80U];
|
||||
::sprintf(text, "dim=%u", m_brightness);
|
||||
sendCommand(text);
|
||||
|
||||
|
|
|
@ -22,13 +22,15 @@
|
|||
|
||||
// #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 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) :
|
||||
m_network(network),
|
||||
m_display(display),
|
||||
|
@ -70,15 +72,15 @@ bool CPOCSAGControl::processData()
|
|||
{
|
||||
assert(m_network != NULL);
|
||||
|
||||
unsigned char data[40U];
|
||||
unsigned char data[300U];
|
||||
unsigned int length = m_network->read(data);
|
||||
if (length == 0U)
|
||||
return false;
|
||||
|
||||
m_ric = 0U;
|
||||
m_ric |= (data[0U] << 16) & 0x00FF0000U;
|
||||
m_ric |= (data[1U] << 8) & 0x0000FF00U;
|
||||
m_ric |= (data[2U] << 0) & 0x000000FFU;
|
||||
m_ric |= (data[1U] << 8) & 0x0000FF00U;
|
||||
m_ric |= (data[2U] << 0) & 0x000000FFU;
|
||||
|
||||
m_text = std::string((char*)(data + 3U), length - 3U);
|
||||
|
||||
|
@ -104,8 +106,13 @@ void CPOCSAGControl::clock(unsigned int ms)
|
|||
m_state = PS_WAITING;
|
||||
m_frames = 0U;
|
||||
m_count = 1U;
|
||||
|
||||
#if defined(DUMP_POCSAG)
|
||||
openFile();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
m_output.clear();
|
||||
m_output.push_back(POCSAG_SYNC_WORD);
|
||||
|
||||
|
@ -154,9 +161,13 @@ void CPOCSAGControl::clock(unsigned int ms)
|
|||
m_frames++;
|
||||
|
||||
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_state = PS_NONE;
|
||||
|
||||
#if defined(DUMP_POCSAG)
|
||||
closeFile();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,43 +184,45 @@ void CPOCSAGControl::addAddress()
|
|||
|
||||
void CPOCSAGControl::packASCII()
|
||||
{
|
||||
const unsigned char MASK = 0x40U;
|
||||
|
||||
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) {
|
||||
unsigned char MASK = 0x40U;
|
||||
for (unsigned int j = 0U; j < 7U; j++, MASK >>= 1) {
|
||||
bool b = (*it & MASK) == MASK;
|
||||
unsigned char c = *it;
|
||||
for (unsigned int j = 0U; j < 7U; j++, c <<= 1) {
|
||||
bool b = (c & MASK) == MASK;
|
||||
if (b)
|
||||
word |= (0x01U << n);
|
||||
n--;
|
||||
word |= DATA_MASK[n];
|
||||
n++;
|
||||
|
||||
if (n == 10U) {
|
||||
if (n == 20U) {
|
||||
addBCHAndParity(word);
|
||||
m_buffer.push_back(word);
|
||||
word = 0x80000000U;
|
||||
n = 30U;
|
||||
n = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add at least one EOT to the message
|
||||
do {
|
||||
unsigned char MASK = 0x70U;
|
||||
for (unsigned int j = 0U; j < 7U; j++, MASK >>= 1) {
|
||||
bool b = (ASCII_EOT & MASK) == MASK;
|
||||
unsigned char c = ASCII_EOT;
|
||||
for (unsigned int j = 0U; j < 7U; j++, c <<= 1) {
|
||||
bool b = (c & MASK) == MASK;
|
||||
if (b)
|
||||
word |= (0x01U << n);
|
||||
n--;
|
||||
word |= DATA_MASK[n];
|
||||
n++;
|
||||
|
||||
if (n == 10U) {
|
||||
if (n == 20U) {
|
||||
addBCHAndParity(word);
|
||||
m_buffer.push_back(word);
|
||||
word = 0x80000000U;
|
||||
n = 30U;
|
||||
n = 0U;
|
||||
}
|
||||
}
|
||||
} while (n != 30U);
|
||||
} while (n != 0U);
|
||||
}
|
||||
|
||||
void CPOCSAGControl::addBCHAndParity(uint32_t& word) const
|
||||
|
@ -238,23 +251,27 @@ void CPOCSAGControl::addBCHAndParity(uint32_t& word) const
|
|||
void CPOCSAGControl::writeQueue()
|
||||
{
|
||||
// Convert 32-bit words to bytes
|
||||
unsigned int n = 0U;
|
||||
unsigned char data[POCSAG_FRAME_LENGTH_BYTES];
|
||||
for (unsigned int i = 0U; i < POCSAG_FRAME_LENGTH_WORDS; i++) {
|
||||
uint32_t w = m_output.front();
|
||||
m_output.pop_front();
|
||||
unsigned char len = 0U;
|
||||
for (std::deque<uint32_t>::const_iterator it = m_output.cbegin(); it != m_output.cend(); ++it) {
|
||||
uint32_t word = *it;
|
||||
|
||||
for (unsigned int j = 0U; j < 31U; j++, w <<= 1) {
|
||||
bool b = (w & 0x80000000U) == 0x80000000U;
|
||||
WRITE_BIT8(data, n, b);
|
||||
n++;
|
||||
}
|
||||
data[len++] = word >> 24;
|
||||
data[len++] = word >> 16;
|
||||
data[len++] = word >> 8;
|
||||
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);
|
||||
|
||||
assert(len == POCSAG_FRAME_LENGTH_BYTES);
|
||||
|
||||
unsigned int space = m_queue.freeSpace();
|
||||
if (space < (len + 1U)) {
|
||||
LogError("POCSAG, overflow in the POCSAG RF queue");
|
||||
|
|
Loading…
Reference in New Issue