Skip to content

Commit

Permalink
Receive messages for multiple POCSAG RICs (#998)
Browse files Browse the repository at this point in the history
* Make it possible to supply a list of addresses for POCSAG reception.

* Initialize some instance variables to sensible values.
  • Loading branch information
jasiek authored Mar 2, 2024
1 parent 7448345 commit 268e2d7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
39 changes: 36 additions & 3 deletions src/protocols/Pager/Pager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ PagerClient::PagerClient(PhysicalLayer* phy) {
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
readBitInstance = phyLayer;
#endif
filterNumAddresses = 0;
filterAddresses = NULL;
filterMasks = NULL;
}

int16_t PagerClient::begin(float base, uint16_t speed, bool invert, uint16_t shift) {
Expand Down Expand Up @@ -246,6 +249,21 @@ int16_t PagerClient::startReceive(uint32_t pin, uint32_t addr, uint32_t mask) {
filterAddr = addr;
filterMask = mask;

return startReceiveCommon();
}

int16_t PagerClient::startReceive(uint32_t pin, uint32_t *addrs, uint32_t *masks, size_t numAddresses) {
// save the variables
readBitPin = pin;

filterAddresses = addrs;
filterMasks = masks;
filterNumAddresses = numAddresses;

return startReceiveCommon();
}

uint16_t PagerClient::startReceiveCommon() {
// set the carrier frequency
int16_t state = phyLayer->setFrequency(baseFreq);
RADIOLIB_ASSERT(state);
Expand All @@ -260,7 +278,7 @@ int16_t PagerClient::startReceive(uint32_t pin, uint32_t addr, uint32_t mask) {

// now set up the direct mode reception
Module* mod = phyLayer->getMod();
mod->hal->pinMode(pin, mod->hal->GpioModeInput);
mod->hal->pinMode(readBitPin, mod->hal->GpioModeInput);

// set direct sync word to the frame sync word
// the logic here is inverted, because modules like SX1278
Expand Down Expand Up @@ -356,8 +374,7 @@ int16_t PagerClient::readData(uint8_t* data, size_t* len, uint32_t* addr) {

// should be an address code word, extract the address
uint32_t addr_found = ((cw & RADIOLIB_PAGER_ADDRESS_BITS_MASK) >> (RADIOLIB_PAGER_ADDRESS_POS - 3)) | (framePos/2);
if((addr_found & filterMask) == (filterAddr & filterMask)) {
// we have a match!
if (addressMatched(addr_found)) {
match = true;
if(addr) {
*addr = addr_found;
Expand Down Expand Up @@ -460,6 +477,22 @@ int16_t PagerClient::readData(uint8_t* data, size_t* len, uint32_t* addr) {
}
#endif

bool PagerClient::addressMatched(uint32_t addr) {
if (filterNumAddresses == 0) {
return ((addr & filterMask) == (filterAddr & filterMask));
} else {
if (filterAddresses == NULL || filterMasks == NULL) {
return false;
}
for (size_t i = 0; i < filterNumAddresses; i++) {
if ((filterAddresses[i] & filterMasks[i]) == (addr & filterMasks[i])) {
return true;
}
}
return false;
}
}

void PagerClient::write(uint32_t* data, size_t len) {
// write code words from buffer
for(size_t i = 0; i < len; i++) {
Expand Down
14 changes: 14 additions & 0 deletions src/protocols/Pager/Pager.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ class PagerClient {
*/
int16_t startReceive(uint32_t pin, uint32_t addr, uint32_t mask = 0xFFFFF);

/*!
\brief Start reception of POCSAG packets for multiple addresses and masks.
\param pin Pin to receive digital data on (e.g., DIO2 for SX127x).
\param addrs Array of addresses to receive.
\param masks Array of address masks to use for filtering. Masks will be applied to corresponding addresses in addr array.
\returns \ref status_codes
*/
int16_t startReceive(uint32_t pin, uint32_t *addrs, uint32_t *masks, size_t numAddress);

/*!
\brief Get the number of POCSAG batches available in buffer. Limited by the size of direct mode buffer!
\returns Number of available batches.
Expand Down Expand Up @@ -175,10 +184,15 @@ class PagerClient {
uint16_t bitDuration;
uint32_t filterAddr;
uint32_t filterMask;
uint32_t *filterAddresses;
uint32_t *filterMasks;
size_t filterNumAddresses;
bool inv = false;

void write(uint32_t* data, size_t len);
void write(uint32_t codeWord);
uint16_t startReceiveCommon();
bool addressMatched(uint32_t addr);

#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
uint32_t read();
Expand Down

0 comments on commit 268e2d7

Please sign in to comment.