Transmitting satellites broadcast LoRa message-sequences. Each sequence consists of a wakeup-frame, an optional wakeup signature frame, and zero or more dataframes. Some of the dataframes will contain almanac-data, but there may be other types of dataframes as well.
Satellites may broadcast message-sequences on one or more frequencies. When broadcasting on more than one frequency, the satellite will alternate sequences between frequencies.
An example of a satellite broadcasting on three different frequencies looks like this:
-------------- frequency -------------------------->
| +-----------------+
| | Wakeup frame |
time +-----------------+
|
| +-----------------+
| | Almanac data |
| +-----------------+
| | Almanac data |
| +-----------------+
|
| +-----------------+
| | Wakeup frame |
| +-----------------+
|
| +-----------------+
| | Almanac data |
| +-----------------+
| | Almanac data |
| +-----------------+
|
| +-----------------+
| | Wakeup frame |
| +-----------------+
|
| +-----------------+
| | Almanac data |
| +-----------------+
| | Almanac data |
| +-----------------+
|
| +-----------------+
| | Wakeup frame |
| +-----------------+
|
| +-----------------+
| | Almanac data |
| +-----------------+
| | ..... |
V
A few remarks about the example (concepts discussed in more detail later):
- In the example, there is a pause after the wakeup frame, but not between consecutive almanac data frames. This is representative of the actual timing - there is a pause after the wakeup frame but not between data-frames.
- The example does not contain wakeup signature frames. If it would, they would immediately follow the wakeup frame, without pause.
- In the example, the wakeup frame and the subsequent almanac data frames are all transmitted on the same frequency. It is possible for the wakeup frame to contain data that indicates that the remainder of the sequence is broadcast on a different frequency.
- Apart from almanac data, the sequence could contain other frame-types as well. Those are not shown in the example.
Wakeup frames, wakeup signature frames, and almanac data frames all share a common layout (other data frames may or may not use the same format).
At top-level they are LoraWAN frames, but with a frame-type of proprietary (the
frame-type is encoded in the 3 highest bits of the MHDR field, and value 0b111
signifies proprietary). They don't have a device-address or a MIC, so practically
speaking, all that makes them a LoraWAN frame is the fact that the first byte
of the frame is 0b11100000.
The second byte of the frame indicates the frame-type. Currently the following frame-types are known:
0: Wakeup frame1: Almanac data frame2: Wakeup signature frame
The wakeup frame is a proprietary LoraWAN frame with a frame-type of 0.
The wakeup frame's payload (which starts at byte 2, right after the frame-type) consists of a fixed header followed by zero or more TLVs (type/length/value). The fixed header has a fixed length, the length of the TLVs is variable.
The fixed header consists of 5 bytes, as follows:
- Sequence duration (
uint8_t): the time in seconds, rounded up to the nearest second, between the end of the wakeup frame and the end of the preamble of the last frame in the sequence. - Transmitting satellite ID (
uint8_t): numeric ID uniquely identifying the transmitting satellite. This is the same ID as used in the almanac. - Time between wakeup frames (
uint16_t, BE): the time in seconds between the start of this wakeup frame and the next. - Time until sequence (
uint8_t, BE): the time in seconds between the end of this wakeup frame and the start of the first frame of the remainder of the sequence. The wakeup signature frame is not considered part of the sequence - therefore, if a wakeup signature frame is present, thetime until sequencewill always be long enough to allow the wakeup signature frame to be broadcast first. The actual time until the first frame of the sequence may be up to (but not including) one second longer than indicated (in other words, the time-until-sequence value is truncated)
The remainder of the wakup frame consists of TLVs. There are two TLV formats: a short one and a long one.
The type is an integer in the range 0..70 indicating the meaning of the TLV.
The length is the length of the value, in bytes. The value, also called payload,
is a sequence of length (which may be 0) bytes, the meaning of which is
dependent on the type and is known to the receiver (provided the receiver
recognizes the TLVs type).
When processing a wakeup frame, the receiver can process those TLVs that it knows about, and skip those it doesn't, since their lengths can be determined without understanding their meaning.
TLVs with a type < 7 can be encoded by one byte containing both the type and the
length, followed by length bytes of payload.
The byte containing type and length is structed as follows:
bit 7|6|5|4|3|2|1|0
-+-+-+-+-+-+-+-
t|t|t|l|l|l|l|l
Here, ttt is the type as a 3-bit integer, and lllll the length of the value
as a 5-bit number.
As an example, a TLV with type 3 with payload 0x10 0x20 0x30 is encoded as
0x63 0x10 0x20 0x30
A TLV with type 6 without a payload is encoded as
0xc0
The maximum allowed payload length for short format TLVs is 31 bytes - TLVs requiring a longer payload should preferably use a type >= 7, or use the long format encoding (which is allowed even for types < 7).
TLVs with a type >= 7 are encoded with two bytes containing the type and payload
length, followed by length bytes.
The two bytes containing the type and payload length are structured as follows:
byte 1 2
bit 7|6|5|4|3|2|1|0 | 7|6|5|4|3|2|1|0
-+-+-+-+-+-+-+--+--+-+-+-+-+-+-+-
1|1|1|t|t|t|t|t | t|l|l|l|l|l|l|l
Here, bits 5..7 of the first byte have fixed values 1, to tell a long format TLV apart from a short format TLV. The 6-bit integer formed by bits 4..0 of the first byte and bit 7 of the second byte is the type minus 7. The 7-bit integer formed by bits 6..0 of the second byte is the payload length.
As an example, a TLV with type 15 and payload 0x0a 0x0b 0xc is encoded as
0xe4 0x03 0x0a 0x0b 0x0c
The maximum payload size of a TLV using long encoding is 127 bytes.
For the first version, the following TLV types are specified:
If this TLV, which does not have a payload, is present, then the wakeup frame is immediately followed by a frame containing a cryptographic signature of the wakeup frame. The exact format of the signature frame is tbd.
If this TLV is present, then the wakeup frame, or the wakeup signature frame if present, is followed by 0 or more frames containing blocks of an almanac. The payload of this TLV contains almanac metadata, which allows the receiver to decide if it needs to receive the almanac. The payload of this TLV consists of 16 bytes, as follows:
- Number of blocks following wakeup frame (
uint8_t). This is just the number of blocks contained in this sequence which is in general not enough to contain an entire almanac. - Almanac version (
uint8_t) - Almanac valid from, as seconds since 1/1/1970 (
uint32_t, BE) - Localisation ID (
uint8_t) - Service provider mask (
uint16_t, BE) - Expected CRC (
uint32_t, BE). This is the 32-bit integer formed by the first 4 bytes of the SHA-2 digest over the almanac data that follows the signatures. - Almanac size in bytes (
uint16_t, BE) - Block size (
uint8_t, BE)
The total number of blocks used to transmit the almanac is
total_blocks = ceiling(almanac_size/block_size)
The payload of each almanac block consists of one byte indicating the (0-based)
sequence number of the block, followed by block_size bytes of content
(except for the block with sequence-number total_blocks-1 which may have a
shorter payload).
Current time. The payload consists of 10 bytes, as follows:
- UNIX time (
uint32_t, BE): the number of seconds since Jan 1st, 1970 - GPS time (
uint32_t, BE): the number of seconds since the GPS epoch (Jan 6th, 1980), not taking into account leap seconds. - Milliseconds (
uint16_t, BE): the milliseconds value, which is valid for both the UNIX and the GPS time.
The specified time is the time at the end of the frame.
Consists of 9 24-bit numbers, and one 8-bit number being the interval over which the extrapolation is valid. Exact format TBD.
If this TLV is present, then the frames following this header, except the wakup signature frame if present, will be broadcast on a different frequency, and using different modulation parameters from the wakeup frame. The payload consists of:
- Frequency (
uint16_t, BE): the alternate frequency divided by 50KHz. - Lora configuration 1 (
uint8_t):- bits 3-0: spreading factor
- bits 7-4: bandwidth
- Lora configuration 2 (
uint8_t):- bit 0: LDRO
- bit 1: Invert IQ
- bits 3-2: sync word:
0x0: public;0x1: private;0x02and0x03reserved
- Preamble length (
uint16_t, BE): length of the preamble
This TLV is intended in case the wakeupframe is received by the terminal as service
presence detection. Its payload consists of 2 bytes, being a uint16_t (BE) that
represents the number of seconds that the terminal is allowed to transmit after receiving
the wakeup frame.
The wakeup frame is transmitted with a LoRa preamble longer than usual. This allows terminals to wake up periodically, see if a preamble is present, and immediately go back to sleep if it isn't, thus saving power.
The wakeup signature frame is a proprietary LoraWAN frame with a frame-type of 2.
Its payload (starting at byte 2 of the frame, immediately following the frame-type) is formatted as follows:
signature_type: (uint8_t) indicates the algorithm used for signing. Currently the only value supported is0, meaningSHA256+secp256r1.key_id: (uint8_t[4]) identifies the keypair used for signing. The meaning depends on the algorithm. In case ofSHA256+secp256r1, it consists of the first 4 bytes of the public key of the keypair.signature: (uint8_t[]) the signature. Length and meaning depends on the algorithm. In case ofSHA256+secp256r1, it is thesecp256r1signature over theSHA256digest of the entire wakeup frame, including the LoraWAN MHDR and frame-type, and the length is 64.
The almanac data frame is a proprietary LoraWAN frame with a frame-type of 1.
The first byte of the payload (which is the second byte of the LoraWAN frame, directly following the frame-type) indicates the blocknumber.
The remainder of the frame is block-data.
The wakeup-frame contains an ALMANAC_FOLLOWS TLV, which contains the block-size
and the total size of the almanac. The total number of blocks can be calculated
as ceiling(total_size / block_size), and the blocknumber will always be smaller
than this.
The offset of the data in the block within the almanac data is simply block_size * blocknumber.
All blocks except for the last one (that is, the one with blocknumber total_blocks-1)
will be exactly of size block_size. The last one will generally be shorter.
As described in the introduction, satellites will broadcast on one or more frequencies. The idea is that terminals will normally try to receive the sequences on all frequencies, but will still be able to receive all data (albeit a bit slower) if one of the frequencies is blocked due to interference.
If broadcasting on multiple frequencies, the satellite will always start broadcasting on the lowest frequency, broadcast the next sequence on the next-higher frequency, etc. After broadcasting a sequence on the highest frequency, it will restart on the lowest frequency.
The terminal will know on how many frequencies a satellite will broadcast, and what
the interval between sequences is.
Therefore, when listening on one frequency, it will expect to receive a frame
within a time (N-1) * interval + margin, where N is the number of frequencies,
interval the interval between sequences, and margin a certain
implementation-defined margin.
If the terminal has not received any frames within this time, it must conclude that apparently there is interference on that particular frequency, and try again with the next frequency on the list.
If the terminal does receive a frame, the action it takes depends on the type of frame.
If it is a wakeup-frame, it will parse it and use the data in the wakeup frame to determine if it wants to receive and process some or all data of the subsequent messages of the sequence. If so, it will receive frames until the sequence duration as announced in the wakeup frame has been reached. After this, the terminal will switch to the next frequency in the list, and wait for next wakeup frame.
If it is not a wakeup-frame, the terminal ignores it and keep trying to receive a wakeup-frame without restarting the timeout timer.