diff --git a/src/protocols/Pager/Pager.cpp b/src/protocols/Pager/Pager.cpp index 799fd626c..e1682de65 100644 --- a/src/protocols/Pager/Pager.cpp +++ b/src/protocols/Pager/Pager.cpp @@ -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) { @@ -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); @@ -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 @@ -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; @@ -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++) { diff --git a/src/protocols/Pager/Pager.h b/src/protocols/Pager/Pager.h index 11b9c4dd0..db372613c 100644 --- a/src/protocols/Pager/Pager.h +++ b/src/protocols/Pager/Pager.h @@ -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. @@ -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();