Files
GnuRadio/gr-jay/lib/PocsagDecoder.cpp
2019-01-12 17:37:39 +00:00

172 lines
2.9 KiB
C++

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: PocsagDecoder.cpp
* Author: jens
*
* Created on 11. Januar 2019, 17:20
*/
#include "PocsagDecoder.hpp"
static const char numericChar[16] =
{
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', '.', 'U',
' ', '-', ']', '[',
};
PocsagDecoder::PocsagDecoder()
: state(Sync)
, dataCount(0)
, msgPos(0)
, msgWord(0)
, func(0)
, msgActive(0)
{
}
PocsagDecoder::PocsagDecoder(const PocsagDecoder& orig)
{
}
PocsagDecoder::~PocsagDecoder()
{
}
void PocsagDecoder::messageBegin()
{
msgActive = 1;
}
void PocsagDecoder::messageFinish()
{
if (msgActive)
{
msgActive = 0;
msgPos = 0;
msgWord = 0;
fprintf(stderr, "\n");
}
}
size_t PocsagDecoder::process(uint8_t const *pData, size_t size)
{
size_t remain = size;
size_t numProcessed = 0;
while(remain >= 4)
{
int incr = 4;
uint32_t word
= (uint32_t)pData[0] << 24 & 0xFF000000
| (uint32_t)pData[1] << 16 & 0x00FF0000
| (uint32_t)pData[2] << 8 & 0x0000FF00
| (uint32_t)pData[3] << 0 & 0x000000FF;
// fprintf (stderr, "word=%08X\n", word);
State stateNext = state;
switch(state)
{
case Sync:
if (word == 0x7CD215D8)
{
stateNext = Data;
dataCount = 0x00;
}
else
{
incr = 1;
}
break;
case Data:
// Sync received
if (word == 0x7CD215D8)
{
dataCount = 0x00;
break;
}
// Message word
if (word & 0x80000000)
{
if (func == 0x00)
{
// Numeric
for (size_t i=1; i < 21; i++)
{
uint32_t bit = 0x80000000 & (word << i);
msgWord >>= 1;
msgWord |= (uint8_t)(0x8*(bit != 0));
msgPos++;
if (msgPos == 4)
{
fprintf(stderr, "%c", numericChar[msgWord]);
msgPos = 0;
msgWord = 0;
}
}
}
if (func == 0x03)
{
// Alpha numeric
for (size_t i=1; i < 21; i++)
{
uint32_t bit = 0x80000000 & (word << i);
msgWord >>= 1;
msgWord |= (uint8_t)(0x40*(bit != 0));
msgPos++;
if (msgPos == 7)
{
if (msgWord != 0x04)
{
fprintf(stderr, "%c", msgWord);
msgPos = 0;
msgWord = 0;
}
}
}
}
}
else
{
if (word == 0x7A89C197)
{
// Idle
messageFinish();
}
else
{
// Address word
messageFinish();
uint32_t addr = (word >> 13) & 0x3FFFF;
func = (word >> 11) & 0x03;
fprintf(stderr, "%02X: [%07u](%02X): ", (uint8_t)(dataCount), (unsigned)(8*addr+dataCount/2), func);
messageBegin();
}
}
dataCount++;
if (dataCount == 0x10)
{
stateNext = Sync;
dataCount = 0;
}
break;
}
pData += incr;
remain -= incr;
state = stateNext;
numProcessed += incr;
}
return numProcessed;
}