Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Receive messages for multiple POCSAG RICs #998

Merged
merged 2 commits into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading