I’ve been working on a project involving the Motorola FLEX paging protocol. There is plenty of useful information out there about implementing the FLEX protocol. Strangely enough, in the age of modern search engines I could not easily find many of these resources. Because of how much I struggled, I wanted to document the references I found useful for others who might be working on such a project.
Table of Contents:
About FLEX
If you need an introduction to FLEX, start here for basic information:
- Wikipedia: FLEX (protocol)
- Signal Identification Guide: FLEX
- Employing the FLEX Protocol in Messaging Applications
- FLEX vs POCSAG
FLEX Patents
The following patents are helpful for understanding the FLEX protocol in detail:
- US5555183 – describes the FLEX messaging structure and frame collapsing
- US5168493 – describes the signalling protocol for sending FLEX transmissions
Useful Resources
These were the most helpful documents for implementing a FLEX decoder:
- FELX-TD Radio Paging System ARIB Standard – I wish I found this at the start of my project; it appears to be the gold standard for FLEX implementations and is very detailed
- Design and Implementation of a Practical FLEX Paging Decoder
- Motorola FLEX / P2000 Decoding – provides a useful introduction to FLEX signaling, message structure, and building a decoder
- FLEX at 6400 bit/s
Open-Source Projects
These projects can serve as useful references if you run into a problem decoding FLEX messages:
- PDW Paging Decoder will decode FLEX pages
- Multimon-ng can decode FLEX frames
- jjwbruijn/FLEX-Decoder – A decoder for FLEX frames, using 2-FSK 1600bps only
- chris007de/flex – a FLEX decoder in RUST, 2-FSK only
- GNURadio can decode FLEX pages int he pager application
- gr-flex – out-of-tree GNU Radio block to communicate with FlexRadio
- flex_hackrf – scanning FLEX decoder for the HackRF based on gr-pager
- faithanalog/pagerenc – Haskell FLEX/POCSAG paging encoder for multimon-ng
Our Observations
The long capcode decoding scheme described in the patent is incorrect. The conversion scheme described in the ARIB standard seems to be what is actually used by our test equipment. The actual conversion scheme that worked for us is:
// Patent says: 2067456, but that math doesn't work
#define LONG_CAPCODE_CONVERSION 2068480
uint32_t rawAddrToLongCapcode(uint32_t addr1, uint32_t addr2)
{
uint32_t addr2_complement = (uint32_t)~addr2;
// We have to truncate because we have bit 0x80000000 set and it shouldn't be
return (((addr2_complement << 15) + LONG_CAPCODE_CONVERSION + addr1) & 0x7FFFFFFF);
}
