Skip to content

Multiple changes#2

Open
tftelkamp wants to merge 27 commits into
lmic-lib:testfrom
tftelkamp:test
Open

Multiple changes#2
tftelkamp wants to merge 27 commits into
lmic-lib:testfrom
tftelkamp:test

Conversation

@tftelkamp
Copy link
Copy Markdown
Contributor

@tftelkamp tftelkamp commented Nov 28, 2016

No description provided.

matthijskooijman and others added 27 commits November 18, 2016 10:47
By default, LMIC uses 6 standard channels for joining and 3 standard
channels for normal operation which are defined in the LoRaWAN
specification. On top of that, it defines 3 additional channels.

However, in practice it turns out that 3 of the 6 joining channels are
not actually used by gateway, and neither are the 3 additional channels
for normal operation. To maximize default operability, this commit
reduces the default channels list to just (the same) 3 channels for both
joining and normal operation (but at different duty cycles).

Extra channels  can be configured from the sketch, using
LMIC_setupChannel(), and the example sketches will be modifed according
to this.
This allows disabling joining (over the air activation), beacon tracking
and ping reception. Disabling these shrinks the code by a fair bit, so this
is interesting for low-memory applications that do not need these
things.

This can also disable processing of some MAC commands. They are silently
ignored, but they are recognized and skipped, so MAC commands coming
after them can still be processed.
This causes these commands to be silently ignored, but they are
recognized and skipped, so MAC commands coming after them can still be
processed.

Not all commands can be disabled, since commands like ADR are typically
needed to prevent nodes from interfering with proper network operation.
These functions convert four individiual bytes from a buffer into a
32-bit integer. The upper two bytes were cast to u4_t before being
shifted in place, but not the lower bytes. It seems that this was not
needed, since even when int is 16-bits, shifting a byte by 8 will not
cause any bits to "fall off". However, a problem with sign-extension
would occur in some cases.

The problematic expression is:

	return (u4_t)(buf[0] | (buf[1]<<8) | ((u4_t)buf[2]<<16) | ((u4_t)buf[3]<<24));

Here, `buf[1]` would be integer-promoted before shifting.  It is
promoted to a *signed* `int`, since the original `u1_t` type is small
enough to fit in there. Now, if the MSB of `buf[1]` is 1, it is then
shifted to become the MSB (i.e. sign bit) of the resulting *signed*
integer. Then, before the bitwise-or operator is applied, this value is
extended to 32-bits, since the right operand is 32-bit. Since the
left-hand side is signed, it is sign-extended, causing all upper 16 bits
to become 1, making them also 1 in the resulting value.

To fix this, all bytes are first explicitely cast to `u4_t` to make sure
they are already big enough and remain unsigned. For consistency, the
same is done for `os_rlsbf2()`, even though this same problem cannot
occur there (C guarantees that an int is at least 16-bits wide).
Battery level and margin was exchanged, see LoraWAN specification chapter 5.5
This reduces some code duplication, and prepares for an upcoming change
that makes the scheduling a bit more complex.

To reflect the more generic usage of this function, it is renamed to
schedRx12.
When using beacons and ping slots, there is already support for
measuring the actual clock drift and compensating for it. However, class
A nodes have no beacons to measure their drift, so this commit allows
them to configure the maximum clock error (e.g. +/- 1%) and increases
the receive windows to ensure that even with the worst-case clock
values, messages will be received.

Note that because the receive window is measures in symbols, with a high
drift rate and/or high datarate the resulting receive window might be
smaller than it should be. This could be slightly improved by using all
10 bits available in the hardware register (currently only 8 bits are
used).

Also note that this moves the calculation of rxsyms into schedRx12,
since the receive window length can be different between RX1 and RX2
(previously it was set only for RX1 and kept around). As a side effect,
this probably breaks FSK reception, since txDone checks rxsyms to see if
it is DR_FSK and sets the length differently. With the current code,
schedRx12 will override that rxsyms value for RX2. However, I could not
find where rxsyms is ever set to DR_FSK (and it does not seem sane to
use that variable like that), so I wonder if FSK reception will work at
all.
The original LMIC AES implementation is optimized for fast execution on
32bit processors, but it ends up taking a lot of flash space on 8-bit
AVR processors. This commit adds an alternative AES implementation
written by Ideetron, which is a lot smaller, but also about twice as
slow as the original imlementation. This new implementation is selected
by default, but the original can be used by modifying config.h.
This uses the macros previously created for the original AES code to put
these values in PROGMEM in a portable manner.
In 03ec06b (Reduce the default channel list), the list of join channels
was reduced. However, in `initJoinLoop()`, a random channel was selected
for the first join attempt, using a hardcoded amount of join channels,
which still had the old value.

This means that half of the join attempts would use an invalid channel,
configuring a frequency of 0Mhz into the radio, preventing the join
request from being received. Each subsequent join uses a next channel,
so after at most three join requests valid channels are used again.
Eventually a join would complete, but this bug might cause extra delays
in joining.
During joining, LMIC.txCnt is used to keep track of retransmissions.
Normally, it is cleared in `LMIC_startJoining()` or `LMIC_setTxData()`
so it is 0 for each new packet. However, when an automatic joining
attempt is started when data is queued, txCnt would not be reset between
the join and the actual datapacket. If more than one join attempt was
needed, txCnt is non-zero and the data packet will be retried multiple
times. Since LMIC.pendTxConf is not set, the packets will not request an
ack, so the full number of retries is always used.

This is fixed by clearing txCnt after the join completes.
`pendTxConf` is used to track whether the current TX data packet should
request confirmation. It is set by `LMIC_setTxData2()` and only used by
`buildDataFrame()`, so it plays no role during a join. When an automatic
join was started after queueing a confirmed uplink, clearing
`pendTxConf` causes the uplink to be send unconfirmed after the join is
complete, which does not seem like the intended behaviour.

Simply not touching `pendTxConf` in `LMIC_startJoining()` should
preserve the confirmed status properly throughout the join procedure.
lmic.c was using a define before including the file that defined it.
Apparently the ESP core already has a function named aes_encrypt, so
this helps to compile this library on that platform.
The ESP core uses these same typedefs, but for 8-bit values instead of
8-byte values, so this prevents compilation on the ESP core. Ideally,
all of these custom LMIC typedefs should be replaced by the standard
types, but this is a change better made upstream. For now, only u8_t
and s8_t are replaced by their standard equivalent, to make things work
on ESP.
This adds an implementation of the LMIC HAL, plus some files needed for
the Arduino library format and some examples.

In addition, an export.sh script is added that can be used to generate
an Arduino library from this repository. This script only reorders
files, it does not change anything. When given the --link option, it
creates symlinks instead of copies, allowing to test things in the
Arduino IDE easily, while committing the original files in this
repository.

The HAL, examples and library.properties files are taken from the
https://github.com/matthijskooijman/arduino-lmic repository, revision
90bc049 (Print downlink ack status in ttn-otaa example too). Only the
configuration mechanism was changed slightly.
See CEPT ERC Recommendation 70-03, Annex 1, band g1, note 5.
Implementation of LoRaWAN Link Check commands (LinkCheckReq,
LinkCheckAns).
The explicit 0.1% duty cycle limit on join was removed in LoRaWAN 1.0.2.
@tftelkamp tftelkamp changed the title Assign frequenties between 865-868Mhz to the right band Multiple changes Nov 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants