Arduino LMIC 6.0.1
Arduino LoRaWAN(r) MAC in C
Loading...
Searching...
No Matches
lmic.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014-2016 IBM Corporation.
3 * Copyright (c) 2016 Matthijs Kooijman.
4 * Copyright (c) 2016-2026 MCCI Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of the <organization> nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
32
33#ifndef _lmic_h_
34#define _lmic_h_
35
36#include "oslmic.h"
37#include "lorabase.h"
38#ifndef _lmic_version_h_
39# include "lmic_version.h"
40#endif
41
42#if LMIC_DEBUG_LEVEL > 0 || LMIC_X_DEBUG_LEVEL > 0
43# if defined(LMIC_DEBUG_INCLUDE)
44# define LMIC_STRINGIFY_(x) #x
45# define LMIC_STRINGIFY(x) LMIC_STRINGIFY_(x)
46# include LMIC_STRINGIFY(LMIC_DEBUG_INCLUDE)
47# endif
48# ifdef LMIC_DEBUG_PRINTF_FN
49 extern void LMIC_DEBUG_PRINTF_FN(const char *f, ...);
50# endif // ndef LMIC_DEBUG_PRINTF_FN
51#endif
52
53// if LMIC_DEBUG_PRINTF is now defined, just use it. This lets you do anything
54// you like with a sufficiently crazy header file.
55#if LMIC_DEBUG_LEVEL > 0
56# ifndef LMIC_DEBUG_PRINTF
57// otherwise, check whether someone configured a print-function to be used,
58// and use it if so.
59# ifdef LMIC_DEBUG_PRINTF_FN
60# define LMIC_DEBUG_PRINTF(f, ...) LMIC_DEBUG_PRINTF_FN(f, ## __VA_ARGS__)
61# ifndef LMIC_DEBUG_INCLUDE // If you use LMIC_DEBUG_INCLUDE, put the declaration in there
62 void LMIC_DEBUG_PRINTF_FN(const char *f, ...);
63# endif // ndef LMIC_DEBUG_INCLUDE
64# else // ndef LMIC_DEBUG_PRINTF_FN
65// if there's no other info, just use printf. In a pure Arduino environment,
66// that's what will happen.
67# include <stdio.h>
68# define LMIC_DEBUG_PRINTF(f, ...) printf(f, ## __VA_ARGS__)
69# endif // ndef LMIC_DEBUG_PRINTF_FN
70# endif // ndef LMIC_DEBUG_PRINTF
71# ifndef LMIC_DEBUG_FLUSH
72# ifdef LMIC_DEBUG_FLUSH_FN
73# define LMIC_DEBUG_FLUSH() LMIC_DEBUG_FLUSH_FN()
74# else // ndef LMIC_DEBUG_FLUSH_FN
75// if there's no other info, assume that flush is not needed.
76# define LMIC_DEBUG_FLUSH() do { ; } while (0)
77# endif // ndef LMIC_DEBUG_FLUSH_FN
78# endif // ndef LMIC_DEBUG_FLUSH
79#else // LMIC_DEBUG_LEVEL == 0
80// If debug level is zero, printf and flush expand to nothing.
81# define LMIC_DEBUG_PRINTF(f, ...) do { ; } while (0)
82# define LMIC_DEBUG_FLUSH() do { ; } while (0)
83#endif // LMIC_DEBUG_LEVEL == 0
84
85//
86// LMIC_X_DEBUG_LEVEL enables additional, special print functions for debugging
87// RSSI features. This is used sparingly.
88#if LMIC_X_DEBUG_LEVEL > 0
89# ifdef LMIC_DEBUG_PRINTF_FN
90# define LMIC_X_DEBUG_PRINTF(f, ...) LMIC_DEBUG_PRINTF_FN(f, ## __VA_ARGS__)
91# else
92# error "LMIC_DEBUG_PRINTF_FN must be defined for LMIC_X_DEBUG_LEVEL > 0."
93# endif
94#else
95# define LMIC_X_DEBUG_PRINTF(f, ...) do {;} while(0)
96#endif
97
98#ifdef __cplusplus
99extern "C"{
100#endif
101
103//#define CFG_TxContinuousMode 1
104
105// since this was announced as the API variable, we keep it. But it's not used,
106// MAX_LEN_FRAME is what the code uses.
107enum { MAX_FRAME_LEN = MAX_LEN_FRAME };
108
109enum { TXCONF_ATTEMPTS = 8 };
110enum { MAX_MISSED_BCNS = (2 * 60 * 60 + 127) / 128 };
111 // note that we need 100 ppm timing accuracy for
112 // this, to keep the timing error to +/- 700ms.
113enum { MAX_RXSYMS = 350 }; // Stop tracking beacon if sync error grows beyond this. A 0.4% clock error
114 // at SF9.125k means 512 ms; one symbol is 4.096 ms,
115 // so this needs to be at least 125 for an STM32L0.
116 // And for 100ppm clocks and 2 hours of beacon misses,
117 // this needs to accommodate 1.4 seconds of error at
118 // 4.096 ms/sym or at least 342 symbols.
119
120enum { LINK_CHECK_CONT = 0 , // continue with this after reported dead link
121 LINK_CHECK_DEAD = 32 , // after this UP frames and no response to ack from NWK assume link is dead (ADR_ACK_DELAY)
122 LINK_CHECK_UNJOIN_MIN = LINK_CHECK_DEAD + 4, // this is the minimum value of LINK_CHECK_UNJOIN if we parameterize
123 LINK_CHECK_UNJOIN = LINK_CHECK_DEAD + (3 * 240), // after this many UP frames and no response, switch to join (by default)
124 LINK_CHECK_INIT = -64 , // UP frame count until we ask for ack (ADR_ACK_LIMIT)
125 LINK_CHECK_OFF =-128 }; // link check disabled
126
127enum { TIME_RESYNC = 6*128 }; // secs
128enum { TXRX_GUARD_ms = 6000 }; // msecs - don't start TX-RX transaction before beacon
129enum { JOIN_GUARD_ms = 9000 }; // msecs - don't start Join Req/Acc transaction before beacon
130enum { TXRX_BCNEXT_secs = 2 }; // secs - earliest start after beacon time
131enum { RETRY_PERIOD_secs = 3 }; // secs - random period for retrying a confirmed send
132
133#if CFG_LMIC_EU_like // EU868 spectrum ====================================================
134
135enum { MAX_CHANNELS = 16 };
136enum { MAX_BANDS = 4 };
137
138enum { LIMIT_CHANNELS = (1<<4) }; // EU868 will never have more channels
140struct band_t {
141 u2_t txcap; // duty cycle limitation: 1/txcap
142 s1_t txpow; // maximum TX power
143 u1_t lastchnl; // last used channel
144 ostime_t avail; // band is blocked until this time
145};
146TYPEDEF_xref2band_t;
147
148struct lmic_saved_adr_state_s {
149 u4_t channelFreq[MAX_CHANNELS];
150 u2_t channelMap;
151};
152
153#elif CFG_LMIC_US_like // US915 spectrum =================================================
154
155struct lmic_saved_adr_state_s {
156 u2_t channelMap[(72+15)/16]; // enabled bits
157 u2_t activeChannels125khz;
158 u2_t activeChannels500khz;
159};
160
161#endif // ==========================================================================
162
163typedef struct lmic_saved_adr_state_s lmic_saved_adr_state_t;
164
165// Keep in sync with evdefs.hpp::drChange
166enum { DRCHG_SET, DRCHG_NOJACC, DRCHG_NOACK, DRCHG_NOADRACK, DRCHG_NWKCMD, DRCHG_FRAMESIZE };
167enum { KEEP_TXPOW = -128 };
168
169
170#if !defined(DISABLE_PING)
172struct rxsched_t {
173 dr_t dr;
174 u1_t intvExp; // 0..7
175 u1_t slot; // runs from 0 to 128
176 rxsyms_t rxsyms;
177 ostime_t rxbase;
178 ostime_t rxtime; // start of next spot
179 u4_t freq;
180};
181TYPEDEF_xref2rxsched_t;
182#endif // !DISABLE_PING
183
184
185#if !defined(DISABLE_BEACONS)
187enum { BCN_NONE = 0x00,
188 BCN_PARTIAL = 0x01,
189 BCN_FULL = 0x02,
190 BCN_NODRIFT = 0x04,
191 BCN_NODDIFF = 0x08 };
193struct bcninfo_t {
194 ostime_t txtime;
195 u4_t time;
196 s4_t lat;
197 s4_t lon;
198 s1_t rssi;
199 s1_t snr;
200 u1_t flags;
201 //
202 u1_t info;
203};
204#endif // !DISABLE_BEACONS
205
207enum { RADIO_RST=0,
213 };
214
215// Netid values / lmic_t.netid
216enum { NETID_NONE=(int)~0U, NETID_MASK=(int)0xFFFFFF };
217// MAC operation modes (lmic_t.opmode).
218enum { OP_NONE = 0x0000,
219 OP_SCAN = 0x0001,
220 OP_TRACK = 0x0002,
221 OP_JOINING = 0x0004,
222 OP_TXDATA = 0x0008,
223 OP_POLL = 0x0010,
224 OP_REJOIN = 0x0020,
225 OP_SHUTDOWN = 0x0040,
226 OP_TXRXPEND = 0x0080,
227 OP_RNDTX = 0x0100,
228 OP_PINGINI = 0x0200,
229 OP_PINGABLE = 0x0400,
230 OP_NEXTCHNL = 0x0800,
231 OP_LINKDEAD = 0x1000,
232 OP_TESTMODE = 0x2000,
233 OP_UNJOIN = 0x4000,
234};
235// TX-RX transaction flags - report back to user
236enum { TXRX_ACK = 0x80,
237 TXRX_NACK = 0x40,
238 TXRX_NOPORT = 0x20,
239 TXRX_PORT = 0x10,
240 TXRX_LENERR = 0x08,
241 TXRX_PING = 0x04,
242 TXRX_DNW2 = 0x02,
243 TXRX_DNW1 = 0x01,
244};
245
249static inline bit_t LMIC_txrxFlags_isClassC(u1_t flags) {
250 return (flags & (TXRX_PING | TXRX_DNW2 | TXRX_DNW1)) == (TXRX_PING | TXRX_DNW2);
251}
252
256static inline bit_t LMIC_txrxFlags_isRx1(u1_t flags) {
257 return (flags & (TXRX_PING | TXRX_DNW2 | TXRX_DNW1)) == (TXRX_DNW1);
258}
259
263static inline bit_t LMIC_txrxFlags_isRx2(u1_t flags) {
264 return (flags & (TXRX_PING | TXRX_DNW2 | TXRX_DNW1)) == (TXRX_DNW2);
265}
266
270static inline bit_t LMIC_txrxFlags_isClassA(u1_t flags) {
271 return LMIC_txrxFlags_isRx1(flags) || LMIC_txrxFlags_isRx2(flags);
272}
273
277static inline u1_t LMIC_txrxFlags_setClassC(u1_t flags) {
278 return (flags & ~TXRX_DNW1) | (TXRX_PING | TXRX_DNW2);
279}
280
284static inline u1_t LMIC_txrxFlags_setRx1(u1_t flags) {
285 return (flags & ~(TXRX_PING | TXRX_DNW2)) | (TXRX_DNW1);
286}
287
291static inline u1_t LMIC_txrxFlags_setRx2(u1_t flags) {
292 return (flags & ~(TXRX_PING | TXRX_DNW1)) | (TXRX_DNW2);
293}
294
298static inline u1_t LMIC_txrxFlags_setRxPing(u1_t flags) {
299 return (flags & ~(TXRX_DNW2 | TXRX_DNW1)) | (TXRX_PING);
300}
301
303enum _ev_t { EV_SCAN_TIMEOUT=1, EV_BEACON_FOUND,
304 EV_BEACON_MISSED, EV_BEACON_TRACKED, EV_JOINING,
305 EV_JOINED, EV_RFU1, EV_JOIN_FAILED, EV_REJOIN_FAILED,
306 EV_TXCOMPLETE, EV_LOST_TSYNC, EV_RESET,
307 EV_RXCOMPLETE, EV_LINK_DEAD, EV_LINK_ALIVE, EV_SCAN_FOUND,
308 EV_TXSTART, EV_TXCANCELED, EV_RXSTART, EV_JOIN_TXCOMPLETE };
309typedef enum _ev_t ev_t;
310
312#define LMIC_EVENT_NAME_TABLE__INIT \
313 "<<zero>>", \
314 "EV_SCAN_TIMEOUT", "EV_BEACON_FOUND", \
315 "EV_BEACON_MISSED", "EV_BEACON_TRACKED", "EV_JOINING", \
316 "EV_JOINED", "EV_RFU1", "EV_JOIN_FAILED", "EV_REJOIN_FAILED", \
317 "EV_TXCOMPLETE", "EV_LOST_TSYNC", "EV_RESET", \
318 "EV_RXCOMPLETE", "EV_LINK_DEAD", "EV_LINK_ALIVE", "EV_SCAN_FOUND", \
319 "EV_TXSTART", "EV_TXCANCELED", "EV_RXSTART", "EV_JOIN_TXCOMPLETE"
320
326// /entry that begins with a \0.
327#define LMIC_EVENT_NAME_MULTISZ__INIT \
328 "<<zero>>\0" \
329 "EV_SCAN_TIMEOUT\0" "EV_BEACON_FOUND\0" \
330 "EV_BEACON_MISSED\0" "EV_BEACON_TRACKED\0" "EV_JOINING\0" \
331 "EV_JOINED\0" "EV_RFU1\0" "EV_JOIN_FAILED\0" "EV_REJOIN_FAILED\0" \
332 "EV_TXCOMPLETE\0" "EV_LOST_TSYNC\0" "EV_RESET\0" \
333 "EV_RXCOMPLETE\0" "EV_LINK_DEAD\0" "EV_LINK_ALIVE\0" "EV_SCAN_FOUND\0" \
334 "EV_TXSTART\0" "EV_TXCANCELED\0" "EV_RXSTART\0" "EV_JOIN_TXCOMPLETE\0"
335
344
347typedef int lmic_tx_error_t;
348
350#define LMIC_ERROR_NAME__INIT \
351 "LMIC_ERROR_SUCCESS", \
352 "LMIC_ERROR_TX_BUSY", \
353 "LMIC_ERROR_TX_TOO_LARGE", \
354 "LMIC_ERROR_TX_NOT_FEASIBLE", \
355 "LMIC_ERROR_TX_FAILED"
356
364#define LMIC_ERROR_NAME_MULTISZ__INIT \
365 "LMIC_ERROR_SUCCESS\0" \
366 "LMIC_ERROR_TX_BUSY\0" \
367 "LMIC_ERROR_TX_TOO_LARGE\0" \
368 "LMIC_ERROR_TX_NOT_FEASIBLE\0" \
369 "LMIC_ERROR_TX_FAILED"
370
378
382
384static inline bit_t LMIC_BEACON_SUCCESSFUL(lmic_beacon_error_t e) {
385 return e < 0;
386}
387
388enum {
401};
402
403// callbacks for client alerts.
404// types and functions are always defined, to reduce #ifs in example code and libraries.
405typedef void LMIC_ABI_STD lmic_rxmessage_cb_t(void *pUserData, uint8_t port, const uint8_t *pMessage, size_t nMessage);
406typedef void LMIC_ABI_STD lmic_txmessage_cb_t(void *pUserData, int fSuccess);
407typedef void LMIC_ABI_STD lmic_event_cb_t(void *pUserData, ev_t e);
408
421typedef void LMIC_ABI_STD lmic_request_network_time_cb_t(void *pUserData, int flagSuccess);
422
424typedef u4_t lmic_gpstime_t;
425
426// rather than deal with 1/256 second tick, we adjust ostime back
427// (as it's high res) to match tNetwork.
428typedef struct lmic_time_reference_s lmic_time_reference_t;
429
436
443
444typedef u1_t lmic_request_time_state_t;
445
451
452typedef u1_t lmic_engine_update_state_t;
453
466
469
470 /* pointer-width things come first */
471#if LMIC_ENABLE_DeviceTimeReq
474#endif
475
476#if LMIC_ENABLE_user_events
477 lmic_event_cb_t *eventCb;
479 lmic_rxmessage_cb_t *rxMessageCb;
481 lmic_txmessage_cb_t *txMessageCb;
483#endif // LMIC_ENABLE_user_events
484
485 /* next we have things that are (u)int32_t */
486 /* none at the moment */
487
488 /* next we have things that are (u)int16_t */
489
491
492 /* finally, things that are (u)int8_t */
494};
495
496/****************************************************************************\
497|
498| Radio driver interface
499|
500\****************************************************************************/
501
510
526
531typedef u1_t lmic_radio_state_t;
532
539
545
546
555
601
602
603/****************************************************************************\
604|
605| Class C definitions
606|
607\****************************************************************************/
608
611
618
629 unsigned mask;
630
633 unsigned fEnabled: 1;
634 unsigned fRx2Active: 1;
635 } f;
636};
637
652
665 unsigned mask;
666
669 unsigned fPending: 1;
670 unsigned fStateChangeRq: 1;
673 unsigned fTargetState: 1;
674 } f;
675};
676
687
699
701
702/****************************************************************************\
703|
704| The LMIC instance object
705|
706\****************************************************************************/
707
709struct lmic_t {
712
716
720
721#if !defined(DISABLE_BEACONS)
723#endif
724
725#if !defined(DISABLE_PING)
727#endif
728
731
732 /* (u)int32_t things */
733
734 // Radio settings TX/RX (also accessed by HAL)
735 ostime_t txend;
736 ostime_t rxtime;
737 ostime_t nextRxTime;
738
739 // LBT info
740 ostime_t lbt_ticks;
741
742 u4_t freq;
743
745
746 u4_t netid;
747 devaddr_t devaddr;
748 u4_t seqnoDn;
749 u4_t seqnoUp;
750 u4_t dn2Freq;
751
752#if !defined(DISABLE_BEACONS)
753 ostime_t bcnRxtime;
754#endif
755
756#if LMIC_ENABLE_DeviceTimeReq
757 // put here for alignment, to reduce RAM use.
758 ostime_t localDeviceTime; // the LMIC.txend value for last DeviceTimeAns
759 lmic_gpstime_t netDeviceTime; // the netDeviceTime for lastDeviceTimeAns
760 // zero ==> not valid.
761#endif // LMIC_ENABLE_DeviceTimeReq
762
763 // Channel scheduling -- very much private
764#if CFG_LMIC_EU_like
765 band_t bands[MAX_BANDS];
766 u4_t channelFreq[MAX_CHANNELS];
767#if !defined(DISABLE_MCMD_DlChannelReq)
768 u4_t channelDlFreq[MAX_CHANNELS];
769#endif
770 // bit map of enabled datarates for each channel
771 u2_t channelDrMap[MAX_CHANNELS];
772 u2_t channelMap;
773 u2_t channelShuffleMap;
774#elif CFG_LMIC_US_like
775 u2_t channelMap[(72+15)/16]; // enabled bits
776 u2_t channelShuffleMap[(72+15)/16]; // enabled bits
777 u2_t activeChannels125khz;
778 u2_t activeChannels500khz;
779#endif
780
781 /* (u)int16_t things */
782 rps_t rps; // radio parameter selections: SF, BW, CodingRate, NoCrc, implicit hdr
783 u2_t opmode; // engineUpdate() operating mode flags
784 u2_t devNonce; // last generated nonce
785
786 s2_t adrAckReq; // counter for link integrity tracking (LINK_CHECK_OFF=off)
787
788#if !defined(DISABLE_BEACONS)
789 s2_t drift; // last measured drift
790 s2_t lastDriftDiff;
791 s2_t maxDriftDiff;
792 rxsyms_t bcnRxsyms; //
793#endif
794
795 /* (u)int8_t things */
796 lmic_engine_update_state_t engineUpdateState; // state of the engineUpdate() evaluator.
797 s1_t rssi;
798 s1_t snr; // LMIC.snr is SNR times 4
799 rxsyms_t rxsyms; // symbols for receive timeout.
800 u1_t dndr;
801 s1_t txpow; // transmit dBm (administrative)
802 s1_t lbt_dbmax; // max permissible dB on our channel (eg -80)
803
804 u1_t txChnl; // channel for next TX
805 u1_t globalDutyRate; // max rate: 1/2^k
806#if CFG_LMIC_US_like
807 u1_t txChnl_125kHz;
809#endif
810 u1_t upRepeat; // configured up repeat
811 s1_t adrTxPow; // ADR adjusted TX power
812 u1_t datarate; // current data rate
813 u1_t errcr; // error coding rate (used for TX only)
814 u1_t rejoinCnt; // adjustment for rejoin datarate
815
816 u1_t upRepeatCount; // current up-repeat
817 bit_t initBandplanAfterReset; // cleared by LMIC_reset(), set by first join. See issue #244
818
819 u1_t pendTxPort;
820 u1_t pendTxConf; // confirmed data
821 u1_t pendTxLen; // count of bytes in pendTxData.
822 u1_t pendTxData[MAX_LEN_PAYLOAD];
823
824 u1_t pendMacLen; // number of bytes of pending Mac response data
825 bit_t pendMacPiggyback; // received on port 0 or piggyback?
826 // response data if piggybacked
827 u1_t pendMacData[LWAN_FCtrl_FOptsLen_MAX];
828
829 u1_t nwkKey[16]; // network session key
830 u1_t artKey[16]; // application router session key
831
832 u1_t dnConf; // dn frame confirm pending: LORA::FCT_ACK or 0
833 u1_t lastDnConf; // downlink with seqnoDn-1 requested confirmation
834 u1_t adrChanged;
835
836 u1_t rxDelay; // Rx delay after TX
837
838 u1_t margin;
839 s1_t devAnsMargin; // SNR value between -32 and 31 (inclusive) for the last successfully received DevStatusReq command
840 u1_t adrEnabled;
841 u1_t moreData; // NWK has more data pending
842#if LMIC_ENABLE_TxParamSetupReq
843 u1_t txParam; // the saved TX param byte.
844#endif
845#if LMIC_ENABLE_DeviceTimeReq
846 lmic_request_time_state_t txDeviceTimeReqState; // current state, initially idle.
847 u1_t netDeviceTimeFrac; // updated on any DeviceTimeAns.
848#endif
849
850 // rx1DrOffset is the offset from uplink to downlink datarate
851 u1_t rx1DrOffset; // captured from join. zero by default.
852
853 // 2nd RX window (after up stream)
854 u1_t dn2Dr;
855#if !defined(DISABLE_MCMD_RXParamSetupReq)
856 u1_t dn2Ans; // 0=no answer pend, 0x80+ACKs
857#endif
858#if !defined(DISABLE_MCMD_DlChannelReq)
859 u1_t macDlChannelAns; // 0 ==> no answer pending, 0x80+ACK bits
860#endif
861#if !defined(DISABLE_MCMD_RXTimingSetupReq)
862 bit_t macRxTimingSetupAns; // 0 ==> no answer pend, non-zero inserts response.
863#endif
864
865 // Class B state
866#if !defined(DISABLE_BEACONS)
867 u1_t missedBcns; // unable to track last N beacons
868 u1_t bcninfoTries; // how often to try (scan mode only)
869#endif
870 // Public part of MAC state
871 u1_t txCnt;
873
874 u1_t dataBeg; // 0 or start of data (dataBeg-1 is port)
875 u1_t dataLen; // 0 no data or zero length data, >0 byte count of data
876 u1_t frame[MAX_LEN_FRAME];
877
878#if !defined(DISABLE_BEACONS)
879 u1_t bcnChnl;
880#endif
881
882 u1_t noRXIQinversion;
883 u1_t saveIrqFlags; // last LoRa IRQ flags
884
885 // Class C state
886#if LMIC_ENABLE_class_c
887 lmic_class_c_t classC;
888#endif
889};
890
893DECLARE_LMIC;
894
895/****************************************************************************\
896|
897| API functions
898|
899\****************************************************************************/
900
902#define DR_RANGE_MAP(drlo,drhi) (((u2_t)0xFFFF<<(drlo)) & ((u2_t)0xFFFF>>(15-(drhi))))
915bit_t LMIC_setupChannelGroup (u1_t group, s1_t txpow, u2_t txcap);
916
918static inline bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap) LMIC_DEPRECATED("use LMIC_setupChannelGroup()");
919static inline bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap) {
920 return LMIC_setupChannelGroup(bandidx, txpow, txcap);
921}
922
932bit_t LMIC_setupChannel (u1_t channel, u4_t freq, u2_t drmap, s1_t group);
933
938bit_t LMIC_disableChannel (u1_t channel);
939
944bit_t LMIC_enableChannel(u1_t channel);
945
947bit_t LMIC_enableSubBand(u1_t band);
948
950bit_t LMIC_disableSubBand(u1_t band);
951
953bit_t LMIC_selectSubBand(u1_t band);
954
957
960 LMIC_CHANNEL_BW_125kHz = 0,
961 LMIC_CHANNEL_BW_250kHz,
962 LMIC_CHANNEL_BW_500kHz,
965
966enum { LMIC_CHANNEL_NO_GROUP = 0xFF };
967
978
981
989bit_t LMIC_queryChannel(u1_t channel, lmic_channel_info_t *pInfo);
990
992bit_t LMIC_queryTxReady(void);
993
994void LMIC_setDrTxpow (dr_t dr, s1_t txpow); // set default/start DR/txpow
995void LMIC_setAdrMode (bit_t enabled); // set ADR mode (if mobile turn off)
996
997#if !defined(DISABLE_JOIN)
998bit_t LMIC_startJoining (void);
999void LMIC_tryRejoin (void);
1000void LMIC_unjoin (void);
1001void LMIC_unjoinAndRejoin (void);
1002#endif
1003
1004void LMIC_shutdown (void);
1005void LMIC_init (void);
1006void LMIC_reset (void);
1007void LMIC_clrTxData (void);
1008void LMIC_setTxData (void);
1009void LMIC_setTxData_strict(void);
1010lmic_tx_error_t LMIC_setTxData2(u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed);
1011lmic_tx_error_t LMIC_setTxData2_strict(u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed);
1012lmic_tx_error_t LMIC_sendWithCallback(u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed, lmic_txmessage_cb_t *pCb, void *pUserData);
1013lmic_tx_error_t LMIC_sendWithCallback_strict(u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed, lmic_txmessage_cb_t *pCb, void *pUserData);
1014void LMIC_sendAlive (void);
1015
1016#if !defined(DISABLE_BEACONS)
1017bit_t LMIC_enableTracking (u1_t tryBcnInfo);
1018void LMIC_disableTracking (void);
1019#endif
1020
1021#if !defined(DISABLE_PING)
1022void LMIC_stopPingable (void);
1023void LMIC_setPingable (u1_t intvExp);
1024#endif
1025
1026void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
1027void LMIC_setLinkCheckMode (bit_t enabled);
1028void LMIC_setClockError(u2_t error);
1029
1030u4_t LMIC_getSeqnoUp (void);
1031u4_t LMIC_setSeqnoUp (u4_t);
1032void LMIC_getSessionKeys (u4_t *netid, devaddr_t *devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
1033
1034void LMIC_requestNetworkTime(lmic_request_network_time_cb_t *pCallbackfn, void *pUserData);
1035int LMIC_getNetworkTimeReference(lmic_time_reference_t *pReference);
1036
1037int LMIC_registerRxMessageCb(lmic_rxmessage_cb_t *pRxMessageCb, void *pUserData);
1038int LMIC_registerEventCb(lmic_event_cb_t *pEventCb, void *pUserData);
1039
1040int LMIC_findNextChannel(uint16_t *, const uint16_t *, uint16_t, int);
1041
1042u1_t LMIC_getBatteryLevel(void);
1043u1_t LMIC_setBatteryLevel(u1_t /* uBattLevel */);
1044
1045// APIs for client half of compliance.
1046typedef u1_t lmic_compliance_rx_action_t;
1047
1048enum lmic_compliance_rx_action_e {
1049 LMIC_COMPLIANCE_RX_ACTION_PROCESS = 0, // process this message normally
1050 LMIC_COMPLIANCE_RX_ACTION_START, // enter compliance mode, discard this message
1051 LMIC_COMPLIANCE_RX_ACTION_IGNORE, // continue in compliance mode, discard this message
1052 LMIC_COMPLIANCE_RX_ACTION_END // exit compliance mode, discard this message
1053};
1054
1055lmic_compliance_rx_action_t LMIC_complianceRxMessage(u1_t port, const u1_t *pMessage, size_t nMessage);
1056
1057// APIs for class C support
1058// We provide stubs so that users don't need to litter their code with #if unless
1059// they want to.
1060
1061static inline bit_t LMIC_isConfiguredClassC(void) {
1062 return LMIC_ENABLE_class_c;
1063}
1064
1065#if LMIC_ENABLE_class_c
1067bit_t LMIC_enableClassC(bit_t fOnIfTrue);
1068#else
1069static inline bit_t LMIC_enableClassC(bit_t fOnIfTrue) {
1070 if (fOnIfTrue)
1071 // class C cannot be turned on in this build;
1072 return 0;
1073 else
1074 // class C cannot be turned on, but the request says "turn it off"
1075 return 1;
1076}
1077#endif // !LMIC_ENABLE_class_c
1078
1079// Declare onEvent() function, to make sure any definition will have the
1080// C conventions, even when in a C++ file.
1081#if LMIC_ENABLE_onEvent
1082DECL_ON_LMIC_EVENT;
1083#endif /* LMIC_ENABLE_onEvent */
1084
1085// Special APIs - for development or testing
1086// !!!See implementation for caveats!!!
1087
1088#ifdef __cplusplus
1089} // extern "C"
1090#endif
1091
1092// names for backward compatibility
1093#include "lmic_compat.h"
1094
1095#endif // _lmic_h_
u1_t LMIC_getBatteryLevel(void)
get battery level that is to be returned by DevStatusAns.
Definition lmic.c:3237
void LMIC_setSession(u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey)
Set up keys for ABP.
Definition lmic.c:3078
bit_t LMIC_queryTxReady(void)
check whether the LMIC is ready for a transmit packet
Definition lmic.c:2953
u1_t LMIC_setBatteryLevel(u1_t uBattLevel)
set battery level to be returned by DevStatusAns.
Definition lmic.c:3221
void LMIC_ABI_STD lmic_request_network_time_cb_t(void *pUserData, int flagSuccess)
network time request callback function type
Definition lmic.h:421
bit_t LMIC_disableSubBand(u1_t band)
disable the eight 125 kHz channels and one 500 kHz channel of a sub-band (fixed-channel regions).
s1_t lmic_beacon_error_t
Error codes returned for beacon operations.
Definition lmic.h:381
lmic_engine_update_state_e
Definition lmic.h:446
@ lmic_EngineUpdateState_busy
engineUpdate is busy, but has not been reentered.
Definition lmic.h:448
@ lmic_EngineUpdateState_again
engineUpdate is busy, and has to be evaluated again.
Definition lmic.h:449
@ lmic_EngineUpdateState_idle
engineUpdate is idle.
Definition lmic.h:447
struct lmic_client_data_s lmic_client_data_t
abstract type for collection of client data that survives LMIC_reset().
Definition lmic.h:465
bit_t LMIC_setupChannelGroup(u1_t group, s1_t txpow, u2_t txcap)
set the duty-cycle limit and maximum power of a channel group (configurable-channel regions).
Definition lmic_eu868.c:130
bit_t LMIC_enableChannel(u1_t channel)
enable a channel.
lmic_tx_error_e
LMIC error codes.
Definition lmic.h:337
@ LMIC_ERROR_TX_FAILED
Transmit failed for unspecified reason.
Definition lmic.h:342
@ LMIC_ERROR_SUCCESS
No error.
Definition lmic.h:338
@ LMIC_ERROR_TX_TOO_LARGE
Message was too long for configured LMIC buffers.
Definition lmic.h:340
@ LMIC_ERROR_TX_BUSY
Transmit path was busy, mesage rejected.
Definition lmic.h:339
@ LMIC_ERROR_TX_NOT_FEASIBLE
Message was too long given region, spreading factor, and network settings.
Definition lmic.h:341
_ev_t
Event codes for event callback.
Definition lmic.h:303
enum lmic_channel_bandwidth_e lmic_channel_bandwidth_t
the bandwidth of a channel, as reported by LMIC_queryChannel().
bit_t LMIC_selectSubBand(u1_t band)
enable one sub-band and disable all others (fixed-channel regions).
u1_t lmic_radio_flags_t
container type for radio request flags
Definition lmic.h:544
@ TXRX_DNW1
received in 1st DN slot
Definition lmic.h:243
@ TXRX_PING
received in a scheduled RX slot or class C
Definition lmic.h:241
@ TXRX_PORT
set if a frame with a port was RXed, LMIC.frame[LMIC.dataBeg-1] => port
Definition lmic.h:239
@ TXRX_NACK
confirmed UP frame was not acked
Definition lmic.h:237
@ TXRX_ACK
confirmed UP frame was acked
Definition lmic.h:236
@ TXRX_LENERR
set if frame was discarded due to length error.
Definition lmic.h:240
@ TXRX_NOPORT
set if a frame with a port was RXed, clr if no frame/no port
Definition lmic.h:238
@ TXRX_DNW2
received in 2dn DN slot or class C
Definition lmic.h:242
bit_t LMIC_disableChannel(u1_t channel)
disable a channel.
bit_t LMIC_setupChannel(u1_t channel, u4_t freq, u2_t drmap, s1_t group)
define or redefine a channel (configurable-channel regions).
Definition lmic_eu868.c:166
u1_t lmic_radio_state_t
concrete type for holding the radio state mask.
Definition lmic.h:509
@ OP_SCAN
radio scan to find a beacon
Definition lmic.h:219
@ OP_JOINING
device joining in progress (blocks other activities)
Definition lmic.h:221
@ OP_REJOIN
occasionally send JOIN REQUEST
Definition lmic.h:224
@ OP_TRACK
track my networks beacon (netid)
Definition lmic.h:220
@ OP_NEXTCHNL
find a new channel
Definition lmic.h:230
@ OP_TXDATA
TX user data (buffered in pendTxData).
Definition lmic.h:222
@ OP_UNJOIN
unjoin and rejoin on next engineUpdate().
Definition lmic.h:233
@ OP_PINGINI
pingable is initialized and scheduling active
Definition lmic.h:228
@ OP_LINKDEAD
link was reported as dead
Definition lmic.h:231
@ OP_PINGABLE
we're pingable
Definition lmic.h:229
@ OP_SHUTDOWN
prevent MAC from doing anything
Definition lmic.h:225
@ OP_POLL
send empty UP frame to ACK confirmed DN/fetch more DN data
Definition lmic.h:223
@ OP_RNDTX
prevent TX lining up after a beacon
Definition lmic.h:227
@ OP_TESTMODE
developer test mode
Definition lmic.h:232
@ OP_TXRXPEND
TX/RX transaction pending.
Definition lmic.h:226
u4_t lmic_gpstime_t
how the network represents time.
Definition lmic.h:424
struct lmic_channel_info_s lmic_channel_info_t
description of one channel, filled in by LMIC_queryChannel().
int lmic_tx_error_t
LMIC result codes, as an integer type.
Definition lmic.h:347
u1_t LMIC_queryChannelCount(void)
return the number of channel indices in the active region (16, 72 or 96).
lmic_radio_flags_e
radio request flags
Definition lmic.h:536
@ LMIC_RADIO_FLAGS_NO_RX_IQ_INVERSION
if set, don't invert IQ on receive
Definition lmic.h:537
struct lmic_radio_data_s lmic_radio_data_t
Instance data for LMIC radio driver.
Definition lmic.h:554
union lmic_class_c_requests_u lmic_class_c_requests_t
requests from outside the LMIC to inside the LMIC, for class C
Definition lmic.h:651
u1_t LMIC_queryNumDefaultChannels(void)
get the number of (fixed) default channels before the programmable channels.
Definition lmic_eu868.c:154
struct lmic_class_c_s lmic_class_c_t
the structure containing class C state
Definition lmic.h:686
union lmic_class_c_flags_u lmic_class_c_flags_t
internal state flacs for class C operation
Definition lmic.h:617
@ BCN_FULL
Full beacon decoded.
Definition lmic.h:189
@ BCN_NODRIFT
No drift value measured yet.
Definition lmic.h:190
@ BCN_NONE
No beacon received.
Definition lmic.h:187
@ BCN_PARTIAL
Only first (common) part could be decoded (info,lat,lon invalid/previous).
Definition lmic.h:188
@ MAX_CLOCK_ERROR
This value represents 100% error in LMIC.clockError.
Definition lmic.h:390
@ LMIC_kMaxClockError_ppm
maximum clock error that users can specify: 4000 ppm (0.4%).
Definition lmic.h:400
lmic_channel_bandwidth_e
the bandwidth of a channel, as reported by LMIC_queryChannel().
Definition lmic.h:959
@ LMIC_CHANNEL_BW_BY_DATARATE
varies with the data rate; see drMap and the region's DR table
Definition lmic.h:963
bit_t LMIC_enableSubBand(u1_t band)
enable the eight 125 kHz channels and one 500 kHz channel of a sub-band (fixed-channel regions).
lmic_radio_state_e
radio driver state mask
Definition lmic.h:514
@ LMIC_RADIO_EV_RXTIMEOUT
rx timed out; RXDONE also set.
Definition lmic.h:523
@ LMIC_RADIO_EV_RXUNKNOWN
rx timed out, not sure whay.
Definition lmic.h:524
@ LMIC_RADIO_EV_RXDONE
rx complete
Definition lmic.h:522
@ LMIC_RADIO_EV_TXSTART
transmit started
Definition lmic.h:516
@ LMIC_RADIO_EV_NONE
no events reported
Definition lmic.h:515
@ LMIC_RADIO_EV_RXSTART
receive started
Definition lmic.h:521
@ LMIC_RADIO_EV_TXUNKNOWN
transmit unknown event.
Definition lmic.h:520
@ LMIC_RADIO_EV_TXDONE
transmit complete, TXSTART will still be set
Definition lmic.h:517
@ LMIC_RADIO_EV_TXDEFER
transmit deferred (LBT)
Definition lmic.h:519
bit_t LMIC_queryChannel(u1_t channel, lmic_channel_info_t *pInfo)
describe a channel.
lmic_beacon_error_e
Error codes returned for beacon operations.
Definition lmic.h:372
@ LMIC_BEACON_ERROR_SUCCESS_FULL
Full beacon successfuly received.
Definition lmic.h:376
@ LMIC_BEACON_ERROR_INVALID
Invalid beacon received.
Definition lmic.h:373
@ LMIC_BEACON_ERROR_SUCCESS_PARTIAL
Partial success; first set of fields are OK.
Definition lmic.h:375
@ LMIC_BEACON_ERROR_WRONG_NETWORK
Beacon received for wrong network.
Definition lmic.h:374
@ RADIO_RXON
receive without time window
Definition lmic.h:210
@ RADIO_TX_AT
transmit at a specific time
Definition lmic.h:211
@ RADIO_RST
reset, canceling any pending operations.
Definition lmic.h:207
@ RADIO_RXON_C
open the class C window if possible.
Definition lmic.h:212
@ RADIO_RX
receive single with time window
Definition lmic.h:209
@ RADIO_TX
transmit.
Definition lmic.h:208
lmic_request_time_state_e
Definition lmic.h:437
@ lmic_RequestTimeState_success
we sucessfully got time.
Definition lmic.h:441
@ lmic_RequestTimeState_idle
we're not doing anything
Definition lmic.h:438
@ lmic_RequestTimeState_rx
we have tx'ed, next downlink completes.
Definition lmic.h:440
@ lmic_RequestTimeState_tx
we want to tx a time request on next uplink
Definition lmic.h:439
Information about the last and previous beacons.
Definition lmic.h:193
s4_t lat
Lat field of last beacon (valid only if BCN_FULL set).
Definition lmic.h:196
s4_t lon
Lon field of last beacon (valid only if BCN_FULL set).
Definition lmic.h:197
u1_t info
Info field of last beacon (valid only if BCN_FULL set).
Definition lmic.h:202
u1_t flags
Last beacon reception and tracking states. See BCN_* values.
Definition lmic.h:200
s1_t rssi
Adjusted RSSI value of last received beacon.
Definition lmic.h:198
u4_t time
GPS time in seconds of last beacon (received or surrogate).
Definition lmic.h:195
ostime_t txtime
Time when the beacon was sent.
Definition lmic.h:194
s1_t snr
Scaled SNR value of last received beacon.
Definition lmic.h:199
description of one channel, filled in by LMIC_queryChannel().
Definition lmic.h:969
u1_t group
channel group index (duty-cycle class), or LMIC_CHANNEL_NO_GROUP.
Definition lmic.h:973
bit_t isDefault
non-zero if the channel is fixed by the region and cannot be changed.
Definition lmic.h:976
u1_t bandwidth
a lmic_channel_bandwidth_t value.
Definition lmic.h:974
bit_t enabled
non-zero if the channel is enabled.
Definition lmic.h:975
u2_t drMap
bit i set if data rate i may be used on this channel.
Definition lmic.h:972
u4_t downlinkFreq
RX1 downlink frequency, Hz.
Definition lmic.h:971
u4_t uplinkFreq
uplink frequency, Hz; zero if the channel is not defined.
Definition lmic.h:970
the Class C operating flags
Definition lmic.h:632
unsigned fEnabled
true if class C operation is enabled.
Definition lmic.h:633
unsigned fRx2Active
true if we think that RX2 is active.
Definition lmic.h:634
the Class C request flags
Definition lmic.h:668
unsigned fPending
true while API job is pending.
Definition lmic.h:669
unsigned fTargetState
true if enable requested; false otherwise.
Definition lmic.h:673
unsigned fStateChangeRq
true if the outside world has asked for a change in state; target state will be the desired state.
Definition lmic.h:670
details of class C state
Definition lmic.h:693
osjob_t job
the job for API requests
Definition lmic.h:694
lmic_class_c_flags_t flags
the state flags
Definition lmic.h:695
lmic_class_c_requests_t requests
the request flags
Definition lmic.h:696
contents of lmic_client_data_t
Definition lmic.h:468
void * eventUserData
data for eventCb
Definition lmic.h:478
u2_t clockError
Inaccuracy in the clock. CLOCK_ERROR_MAX represents +/-100% error.
Definition lmic.h:490
lmic_request_network_time_cb_t * pNetworkTimeCb
call-back routine for network time
Definition lmic.h:472
lmic_event_cb_t * eventCb
user-supplied callback function for events.
Definition lmic.h:477
void * txMessageUserData
data for txMessageCb.
Definition lmic.h:482
lmic_rxmessage_cb_t * rxMessageCb
user-supplied message-received callback
Definition lmic.h:479
u1_t devStatusAns_battery
value to report in MCMD_DevStatusAns message.
Definition lmic.h:493
lmic_txmessage_cb_t * txMessageCb
transmit-complete message handler; reset on each tx complete.
Definition lmic.h:481
void * pNetworkTimeUserData
call-back data for network time.
Definition lmic.h:473
void * rxMessageUserData
data for rxMessageCb
Definition lmic.h:480
Details of instance data for LMIC radio driver.
Definition lmic.h:559
rps_t rps
radio parameter settings for this radio operation. (two bytes)
Definition lmic.h:568
u1_t dataLen
size of buffer (in for TX, out for RX; RX assumes actual size is MAX_LEN_FRAME)
Definition lmic.h:574
u2_t rxlate_count
Count of rx late launches.
Definition lmic.h:597
u2_t txlate_count
Count of tx late launches.
Definition lmic.h:599
lmic_radio_state_t state
radio state mask; used by radio driver.
Definition lmic.h:587
lmic_radio_flags_t flags
various flags
Definition lmic.h:577
rxsyms_t rxsyms
timeout in symbols (2 bytes)
Definition lmic.h:570
osjob_t * pRadioDoneJob
job to be scheduled when radio operation completes.
Definition lmic.h:590
u1_t * pFrame
pointer to buffer
Definition lmic.h:563
ostime_t rxlate_ticks
Total os ticks of accumulated delay error. Can overflow!
Definition lmic.h:593
u4_t freq
frequency for this radio operation
Definition lmic.h:561
ostime_t txlate_ticks
Total os ticks of accumulated tx delay error. Can overflow!
Definition lmic.h:595
ostime_t rxtime
input: rxwindow open time; output: time of receipt of last bit.
Definition lmic.h:565
s1_t txpow
the radio driver's copy of txpow, in dB limited by adrTxPow, and also adjusted for EIRP/antenna gain ...
Definition lmic.h:584
Instance data for the LMIC.
Definition lmic.h:709
osjob_t osjob
the OS job object.
Definition lmic.h:715
ostime_t lbt_ticks
ticks to listen for interference before transmitting.
Definition lmic.h:740
bcninfo_t bcninfo
Last received beacon info.
Definition lmic.h:722
ostime_t nextRxTime
time of start of next receive
Definition lmic.h:737
lmic_radio_data_t radio
the radio driver portable context
Definition lmic.h:730
ostime_t txend
time of end of last transmit
Definition lmic.h:735
u4_t seqnoUp
FCntUp (uplink seqno).
Definition lmic.h:749
u4_t dn2Freq
the frequency to use for RX2.
Definition lmic.h:750
osjob_t osjob_defer
the OS job object for events.
Definition lmic.h:719
lmic_client_data_t client
client setup data, survives LMIC_reset().
Definition lmic.h:711
ostime_t rxtime
time of end of last receive
Definition lmic.h:736
u4_t seqnoDn
FCntDown (downlink seqno).
Definition lmic.h:748
u4_t freq
most recent frequency, Hz.
Definition lmic.h:742
u2_t txrxFlags
transaction flags (TX-RX combo)
Definition lmic.h:872
devaddr_t devaddr
current device address. Zero means not joined.
Definition lmic.h:747
u4_t netid
current network id (~0 - none)
Definition lmic.h:746
ostime_t globalDutyAvail
time when device can send again
Definition lmic.h:744
rxsched_t ping
Data for handling ping scheduling.
Definition lmic.h:726
Definition lmic.h:430
lmic_gpstime_t tNetwork
the network's best idea of when we sent the uplink.
Definition lmic.h:434
ostime_t tLocal
our best idea of when we sent the uplink (end of packet).
Definition lmic.h:432
Definition oslmic.h:170
Definition lmic.h:172
details of lmic_class_c_flags_t.
Definition lmic.h:628
unsigned mask
view all the flags as a word so we can reset them easily.
Definition lmic.h:629
struct lmic_class_c_flags_u::lmic_class_c_flags_s f
access the class C flags individually.
details of lmic_class_c_requests_t
Definition lmic.h:664
unsigned mask
view all the flags as a word so we can reset them easily.
Definition lmic.h:665
struct lmic_class_c_requests_u::lmic_class_c_requests_s f
access the Class C request flags individually.