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
39#if LMIC_DEBUG_LEVEL > 0 || LMIC_X_DEBUG_LEVEL > 0
40# if defined(LMIC_DEBUG_INCLUDE)
41# define LMIC_STRINGIFY_(x) #x
42# define LMIC_STRINGIFY(x) LMIC_STRINGIFY_(x)
43# include LMIC_STRINGIFY(LMIC_DEBUG_INCLUDE)
44# endif
45# ifdef LMIC_DEBUG_PRINTF_FN
46 extern void LMIC_DEBUG_PRINTF_FN(const char *f, ...);
47# endif // ndef LMIC_DEBUG_PRINTF_FN
48#endif
49
50// if LMIC_DEBUG_PRINTF is now defined, just use it. This lets you do anything
51// you like with a sufficiently crazy header file.
52#if LMIC_DEBUG_LEVEL > 0
53# ifndef LMIC_DEBUG_PRINTF
54// otherwise, check whether someone configured a print-function to be used,
55// and use it if so.
56# ifdef LMIC_DEBUG_PRINTF_FN
57# define LMIC_DEBUG_PRINTF(f, ...) LMIC_DEBUG_PRINTF_FN(f, ## __VA_ARGS__)
58# ifndef LMIC_DEBUG_INCLUDE // If you use LMIC_DEBUG_INCLUDE, put the declaration in there
59 void LMIC_DEBUG_PRINTF_FN(const char *f, ...);
60# endif // ndef LMIC_DEBUG_INCLUDE
61# else // ndef LMIC_DEBUG_PRINTF_FN
62// if there's no other info, just use printf. In a pure Arduino environment,
63// that's what will happen.
64# include <stdio.h>
65# define LMIC_DEBUG_PRINTF(f, ...) printf(f, ## __VA_ARGS__)
66# endif // ndef LMIC_DEBUG_PRINTF_FN
67# endif // ndef LMIC_DEBUG_PRINTF
68# ifndef LMIC_DEBUG_FLUSH
69# ifdef LMIC_DEBUG_FLUSH_FN
70# define LMIC_DEBUG_FLUSH() LMIC_DEBUG_FLUSH_FN()
71# else // ndef LMIC_DEBUG_FLUSH_FN
72// if there's no other info, assume that flush is not needed.
73# define LMIC_DEBUG_FLUSH() do { ; } while (0)
74# endif // ndef LMIC_DEBUG_FLUSH_FN
75# endif // ndef LMIC_DEBUG_FLUSH
76#else // LMIC_DEBUG_LEVEL == 0
77// If debug level is zero, printf and flush expand to nothing.
78# define LMIC_DEBUG_PRINTF(f, ...) do { ; } while (0)
79# define LMIC_DEBUG_FLUSH() do { ; } while (0)
80#endif // LMIC_DEBUG_LEVEL == 0
81
82//
83// LMIC_X_DEBUG_LEVEL enables additional, special print functions for debugging
84// RSSI features. This is used sparingly.
85#if LMIC_X_DEBUG_LEVEL > 0
86# ifdef LMIC_DEBUG_PRINTF_FN
87# define LMIC_X_DEBUG_PRINTF(f, ...) LMIC_DEBUG_PRINTF_FN(f, ## __VA_ARGS__)
88# else
89# error "LMIC_DEBUG_PRINTF_FN must be defined for LMIC_X_DEBUG_LEVEL > 0."
90# endif
91#else
92# define LMIC_X_DEBUG_PRINTF(f, ...) do {;} while(0)
93#endif
94
95#ifdef __cplusplus
96extern "C"{
97#endif
98
99// LMIC version -- this is the IBM LMIC version
100#define LMIC_VERSION_MAJOR 1
101#define LMIC_VERSION_MINOR 6
102#define LMIC_VERSION_BUILD 1468577746
103
104// Arduino LMIC version
105#define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, local) \
106 ((((major)*UINT32_C(1)) << 24) | (((minor)*UINT32_C(1)) << 16) | (((patch)*UINT32_C(1)) << 8) | (((local)*UINT32_C(1)) << 0))
107
108#define ARDUINO_LMIC_VERSION \
109 ARDUINO_LMIC_VERSION_CALC(6, 0, 1, 0) /* 6.0.1 */
110
111#define ARDUINO_LMIC_VERSION_GET_MAJOR(v) \
112 ((((v)*UINT32_C(1)) >> 24u) & 0xFFu)
113
114#define ARDUINO_LMIC_VERSION_GET_MINOR(v) \
115 ((((v)*UINT32_C(1)) >> 16u) & 0xFFu)
116
117#define ARDUINO_LMIC_VERSION_GET_PATCH(v) \
118 ((((v)*UINT32_C(1)) >> 8u) & 0xFFu)
119
120#define ARDUINO_LMIC_VERSION_GET_LOCAL(v) \
121 ((v) & 0xFFu)
122
124#define ARDUINO_LMIC_VERSION_TO_ORDINAL(v) \
125 (((v) & 0xFFFFFF00u) | (((v) - 1) & 0xFFu))
126
129#define ARDUINO_LMIC_VERSION_COMPARE_LT(a, b) \
130 (ARDUINO_LMIC_VERSION_TO_ORDINAL(a) < ARDUINO_LMIC_VERSION_TO_ORDINAL(b))
131
134#define ARDUINO_LMIC_VERSION_COMPARE_LE(a, b) \
135 (ARDUINO_LMIC_VERSION_TO_ORDINAL(a) <= ARDUINO_LMIC_VERSION_TO_ORDINAL(b))
136
139#define ARDUINO_LMIC_VERSION_COMPARE_GT(a, b) \
140 (ARDUINO_LMIC_VERSION_TO_ORDINAL(a) > ARDUINO_LMIC_VERSION_TO_ORDINAL(b))
141
144#define ARDUINO_LMIC_VERSION_COMPARE_GE(a, b) \
145 (ARDUINO_LMIC_VERSION_TO_ORDINAL(a) >= ARDUINO_LMIC_VERSION_TO_ORDINAL(b))
146
147
149//#define CFG_TxContinuousMode 1
150
151// since this was announced as the API variable, we keep it. But it's not used,
152// MAX_LEN_FRAME is what the code uses.
153enum { MAX_FRAME_LEN = MAX_LEN_FRAME };
154
155enum { TXCONF_ATTEMPTS = 8 };
156enum { MAX_MISSED_BCNS = (2 * 60 * 60 + 127) / 128 };
157 // note that we need 100 ppm timing accuracy for
158 // this, to keep the timing error to +/- 700ms.
159enum { MAX_RXSYMS = 350 }; // Stop tracking beacon if sync error grows beyond this. A 0.4% clock error
160 // at SF9.125k means 512 ms; one symbol is 4.096 ms,
161 // so this needs to be at least 125 for an STM32L0.
162 // And for 100ppm clocks and 2 hours of beacon misses,
163 // this needs to accommodate 1.4 seconds of error at
164 // 4.096 ms/sym or at least 342 symbols.
165
166enum { LINK_CHECK_CONT = 0 , // continue with this after reported dead link
167 LINK_CHECK_DEAD = 32 , // after this UP frames and no response to ack from NWK assume link is dead (ADR_ACK_DELAY)
168 LINK_CHECK_UNJOIN_MIN = LINK_CHECK_DEAD + 4, // this is the minimum value of LINK_CHECK_UNJOIN if we parameterize
169 LINK_CHECK_UNJOIN = LINK_CHECK_DEAD + (3 * 240), // after this many UP frames and no response, switch to join (by default)
170 LINK_CHECK_INIT = -64 , // UP frame count until we ask for ack (ADR_ACK_LIMIT)
171 LINK_CHECK_OFF =-128 }; // link check disabled
172
173enum { TIME_RESYNC = 6*128 }; // secs
174enum { TXRX_GUARD_ms = 6000 }; // msecs - don't start TX-RX transaction before beacon
175enum { JOIN_GUARD_ms = 9000 }; // msecs - don't start Join Req/Acc transaction before beacon
176enum { TXRX_BCNEXT_secs = 2 }; // secs - earliest start after beacon time
177enum { RETRY_PERIOD_secs = 3 }; // secs - random period for retrying a confirmed send
178
179#if CFG_LMIC_EU_like // EU868 spectrum ====================================================
180
181enum { MAX_CHANNELS = 16 };
182enum { MAX_BANDS = 4 };
183
184enum { LIMIT_CHANNELS = (1<<4) }; // EU868 will never have more channels
186struct band_t {
187 u2_t txcap; // duty cycle limitation: 1/txcap
188 s1_t txpow; // maximum TX power
189 u1_t lastchnl; // last used channel
190 ostime_t avail; // band is blocked until this time
191};
192TYPEDEF_xref2band_t;
193
194struct lmic_saved_adr_state_s {
195 u4_t channelFreq[MAX_CHANNELS];
196 u2_t channelMap;
197};
198
199#elif CFG_LMIC_US_like // US915 spectrum =================================================
200
201struct lmic_saved_adr_state_s {
202 u2_t channelMap[(72+15)/16]; // enabled bits
203 u2_t activeChannels125khz;
204 u2_t activeChannels500khz;
205};
206
207#endif // ==========================================================================
208
209typedef struct lmic_saved_adr_state_s lmic_saved_adr_state_t;
210
211// Keep in sync with evdefs.hpp::drChange
212enum { DRCHG_SET, DRCHG_NOJACC, DRCHG_NOACK, DRCHG_NOADRACK, DRCHG_NWKCMD, DRCHG_FRAMESIZE };
213enum { KEEP_TXPOW = -128 };
214
215
216#if !defined(DISABLE_PING)
218struct rxsched_t {
219 dr_t dr;
220 u1_t intvExp; // 0..7
221 u1_t slot; // runs from 0 to 128
222 rxsyms_t rxsyms;
223 ostime_t rxbase;
224 ostime_t rxtime; // start of next spot
225 u4_t freq;
226};
227TYPEDEF_xref2rxsched_t;
228#endif // !DISABLE_PING
229
230
231#if !defined(DISABLE_BEACONS)
233enum { BCN_NONE = 0x00,
234 BCN_PARTIAL = 0x01,
235 BCN_FULL = 0x02,
236 BCN_NODRIFT = 0x04,
237 BCN_NODDIFF = 0x08 };
239struct bcninfo_t {
240 ostime_t txtime;
241 u4_t time;
242 s4_t lat;
243 s4_t lon;
244 s1_t rssi;
245 s1_t snr;
246 u1_t flags;
247 //
248 u1_t info;
249};
250#endif // !DISABLE_BEACONS
251
253enum { RADIO_RST=0,
259 };
260
261// Netid values / lmic_t.netid
262enum { NETID_NONE=(int)~0U, NETID_MASK=(int)0xFFFFFF };
263// MAC operation modes (lmic_t.opmode).
264enum { OP_NONE = 0x0000,
265 OP_SCAN = 0x0001,
266 OP_TRACK = 0x0002,
267 OP_JOINING = 0x0004,
268 OP_TXDATA = 0x0008,
269 OP_POLL = 0x0010,
270 OP_REJOIN = 0x0020,
271 OP_SHUTDOWN = 0x0040,
272 OP_TXRXPEND = 0x0080,
273 OP_RNDTX = 0x0100,
274 OP_PINGINI = 0x0200,
275 OP_PINGABLE = 0x0400,
276 OP_NEXTCHNL = 0x0800,
277 OP_LINKDEAD = 0x1000,
278 OP_TESTMODE = 0x2000,
279 OP_UNJOIN = 0x4000,
280};
281// TX-RX transaction flags - report back to user
282enum { TXRX_ACK = 0x80,
283 TXRX_NACK = 0x40,
284 TXRX_NOPORT = 0x20,
285 TXRX_PORT = 0x10,
286 TXRX_LENERR = 0x08,
287 TXRX_PING = 0x04,
288 TXRX_DNW2 = 0x02,
289 TXRX_DNW1 = 0x01,
290};
291
295static inline bit_t LMIC_txrxFlags_isClassC(u1_t flags) {
296 return (flags & (TXRX_PING | TXRX_DNW2 | TXRX_DNW1)) == (TXRX_PING | TXRX_DNW2);
297}
298
302static inline bit_t LMIC_txrxFlags_isRx1(u1_t flags) {
303 return (flags & (TXRX_PING | TXRX_DNW2 | TXRX_DNW1)) == (TXRX_DNW1);
304}
305
309static inline bit_t LMIC_txrxFlags_isRx2(u1_t flags) {
310 return (flags & (TXRX_PING | TXRX_DNW2 | TXRX_DNW1)) == (TXRX_DNW2);
311}
312
316static inline bit_t LMIC_txrxFlags_isClassA(u1_t flags) {
317 return LMIC_txrxFlags_isRx1(flags) || LMIC_txrxFlags_isRx2(flags);
318}
319
323static inline u1_t LMIC_txrxFlags_setClassC(u1_t flags) {
324 return (flags & ~TXRX_DNW1) | (TXRX_PING | TXRX_DNW2);
325}
326
330static inline u1_t LMIC_txrxFlags_setRx1(u1_t flags) {
331 return (flags & ~(TXRX_PING | TXRX_DNW2)) | (TXRX_DNW1);
332}
333
337static inline u1_t LMIC_txrxFlags_setRx2(u1_t flags) {
338 return (flags & ~(TXRX_PING | TXRX_DNW1)) | (TXRX_DNW2);
339}
340
344static inline u1_t LMIC_txrxFlags_setRxPing(u1_t flags) {
345 return (flags & ~(TXRX_DNW2 | TXRX_DNW1)) | (TXRX_PING);
346}
347
349enum _ev_t { EV_SCAN_TIMEOUT=1, EV_BEACON_FOUND,
350 EV_BEACON_MISSED, EV_BEACON_TRACKED, EV_JOINING,
351 EV_JOINED, EV_RFU1, EV_JOIN_FAILED, EV_REJOIN_FAILED,
352 EV_TXCOMPLETE, EV_LOST_TSYNC, EV_RESET,
353 EV_RXCOMPLETE, EV_LINK_DEAD, EV_LINK_ALIVE, EV_SCAN_FOUND,
354 EV_TXSTART, EV_TXCANCELED, EV_RXSTART, EV_JOIN_TXCOMPLETE };
355typedef enum _ev_t ev_t;
356
358#define LMIC_EVENT_NAME_TABLE__INIT \
359 "<<zero>>", \
360 "EV_SCAN_TIMEOUT", "EV_BEACON_FOUND", \
361 "EV_BEACON_MISSED", "EV_BEACON_TRACKED", "EV_JOINING", \
362 "EV_JOINED", "EV_RFU1", "EV_JOIN_FAILED", "EV_REJOIN_FAILED", \
363 "EV_TXCOMPLETE", "EV_LOST_TSYNC", "EV_RESET", \
364 "EV_RXCOMPLETE", "EV_LINK_DEAD", "EV_LINK_ALIVE", "EV_SCAN_FOUND", \
365 "EV_TXSTART", "EV_TXCANCELED", "EV_RXSTART", "EV_JOIN_TXCOMPLETE"
366
372// /entry that begins with a \0.
373#define LMIC_EVENT_NAME_MULTISZ__INIT \
374 "<<zero>>\0" \
375 "EV_SCAN_TIMEOUT\0" "EV_BEACON_FOUND\0" \
376 "EV_BEACON_MISSED\0" "EV_BEACON_TRACKED\0" "EV_JOINING\0" \
377 "EV_JOINED\0" "EV_RFU1\0" "EV_JOIN_FAILED\0" "EV_REJOIN_FAILED\0" \
378 "EV_TXCOMPLETE\0" "EV_LOST_TSYNC\0" "EV_RESET\0" \
379 "EV_RXCOMPLETE\0" "EV_LINK_DEAD\0" "EV_LINK_ALIVE\0" "EV_SCAN_FOUND\0" \
380 "EV_TXSTART\0" "EV_TXCANCELED\0" "EV_RXSTART\0" "EV_JOIN_TXCOMPLETE\0"
381
390
393typedef int lmic_tx_error_t;
394
396#define LMIC_ERROR_NAME__INIT \
397 "LMIC_ERROR_SUCCESS", \
398 "LMIC_ERROR_TX_BUSY", \
399 "LMIC_ERROR_TX_TOO_LARGE", \
400 "LMIC_ERROR_TX_NOT_FEASIBLE", \
401 "LMIC_ERROR_TX_FAILED"
402
410#define LMIC_ERROR_NAME_MULTISZ__INIT \
411 "LMIC_ERROR_SUCCESS\0" \
412 "LMIC_ERROR_TX_BUSY\0" \
413 "LMIC_ERROR_TX_TOO_LARGE\0" \
414 "LMIC_ERROR_TX_NOT_FEASIBLE\0" \
415 "LMIC_ERROR_TX_FAILED"
416
424
428
430static inline bit_t LMIC_BEACON_SUCCESSFUL(lmic_beacon_error_t e) {
431 return e < 0;
432}
433
434enum {
447};
448
449// callbacks for client alerts.
450// types and functions are always defined, to reduce #ifs in example code and libraries.
451typedef void LMIC_ABI_STD lmic_rxmessage_cb_t(void *pUserData, uint8_t port, const uint8_t *pMessage, size_t nMessage);
452typedef void LMIC_ABI_STD lmic_txmessage_cb_t(void *pUserData, int fSuccess);
453typedef void LMIC_ABI_STD lmic_event_cb_t(void *pUserData, ev_t e);
454
467typedef void LMIC_ABI_STD lmic_request_network_time_cb_t(void *pUserData, int flagSuccess);
468
470typedef u4_t lmic_gpstime_t;
471
472// rather than deal with 1/256 second tick, we adjust ostime back
473// (as it's high res) to match tNetwork.
474typedef struct lmic_time_reference_s lmic_time_reference_t;
475
482
489
490typedef u1_t lmic_request_time_state_t;
491
497
498typedef u1_t lmic_engine_update_state_t;
499
512
515
516 /* pointer-width things come first */
517#if LMIC_ENABLE_DeviceTimeReq
520#endif
521
522#if LMIC_ENABLE_user_events
523 lmic_event_cb_t *eventCb;
525 lmic_rxmessage_cb_t *rxMessageCb;
527 lmic_txmessage_cb_t *txMessageCb;
529#endif // LMIC_ENABLE_user_events
530
531 /* next we have things that are (u)int32_t */
532 /* none at the moment */
533
534 /* next we have things that are (u)int16_t */
535
537
538 /* finally, things that are (u)int8_t */
540};
541
542/****************************************************************************\
543|
544| Radio driver interface
545|
546\****************************************************************************/
547
556
572
577typedef u1_t lmic_radio_state_t;
578
585
591
592
601
647
648
649/****************************************************************************\
650|
651| Class C definitions
652|
653\****************************************************************************/
654
657
664
675 unsigned mask;
676
679 unsigned fEnabled: 1;
680 unsigned fRx2Active: 1;
681 } f;
682};
683
698
711 unsigned mask;
712
715 unsigned fPending: 1;
716 unsigned fStateChangeRq: 1;
719 unsigned fTargetState: 1;
720 } f;
721};
722
733
745
747
748/****************************************************************************\
749|
750| The LMIC instance object
751|
752\****************************************************************************/
753
755struct lmic_t {
758
762
766
767#if !defined(DISABLE_BEACONS)
769#endif
770
771#if !defined(DISABLE_PING)
773#endif
774
777
778 /* (u)int32_t things */
779
780 // Radio settings TX/RX (also accessed by HAL)
781 ostime_t txend;
782 ostime_t rxtime;
783 ostime_t nextRxTime;
784
785 // LBT info
786 ostime_t lbt_ticks;
787
788 u4_t freq;
789
791
792 u4_t netid;
793 devaddr_t devaddr;
794 u4_t seqnoDn;
795 u4_t seqnoUp;
796 u4_t dn2Freq;
797
798#if !defined(DISABLE_BEACONS)
799 ostime_t bcnRxtime;
800#endif
801
802#if LMIC_ENABLE_DeviceTimeReq
803 // put here for alignment, to reduce RAM use.
804 ostime_t localDeviceTime; // the LMIC.txend value for last DeviceTimeAns
805 lmic_gpstime_t netDeviceTime; // the netDeviceTime for lastDeviceTimeAns
806 // zero ==> not valid.
807#endif // LMIC_ENABLE_DeviceTimeReq
808
809 // Channel scheduling -- very much private
810#if CFG_LMIC_EU_like
811 band_t bands[MAX_BANDS];
812 u4_t channelFreq[MAX_CHANNELS];
813#if !defined(DISABLE_MCMD_DlChannelReq)
814 u4_t channelDlFreq[MAX_CHANNELS];
815#endif
816 // bit map of enabled datarates for each channel
817 u2_t channelDrMap[MAX_CHANNELS];
818 u2_t channelMap;
819 u2_t channelShuffleMap;
820#elif CFG_LMIC_US_like
821 u2_t channelMap[(72+15)/16]; // enabled bits
822 u2_t channelShuffleMap[(72+15)/16]; // enabled bits
823 u2_t activeChannels125khz;
824 u2_t activeChannels500khz;
825#endif
826
827 /* (u)int16_t things */
828 rps_t rps; // radio parameter selections: SF, BW, CodingRate, NoCrc, implicit hdr
829 u2_t opmode; // engineUpdate() operating mode flags
830 u2_t devNonce; // last generated nonce
831
832 s2_t adrAckReq; // counter for link integrity tracking (LINK_CHECK_OFF=off)
833
834#if !defined(DISABLE_BEACONS)
835 s2_t drift; // last measured drift
836 s2_t lastDriftDiff;
837 s2_t maxDriftDiff;
838 rxsyms_t bcnRxsyms; //
839#endif
840
841 /* (u)int8_t things */
842 lmic_engine_update_state_t engineUpdateState; // state of the engineUpdate() evaluator.
843 s1_t rssi;
844 s1_t snr; // LMIC.snr is SNR times 4
845 rxsyms_t rxsyms; // symbols for receive timeout.
846 u1_t dndr;
847 s1_t txpow; // transmit dBm (administrative)
848 s1_t lbt_dbmax; // max permissible dB on our channel (eg -80)
849
850 u1_t txChnl; // channel for next TX
851 u1_t globalDutyRate; // max rate: 1/2^k
852#if CFG_LMIC_US_like
853 u1_t txChnl_125kHz;
855#endif
856 u1_t upRepeat; // configured up repeat
857 s1_t adrTxPow; // ADR adjusted TX power
858 u1_t datarate; // current data rate
859 u1_t errcr; // error coding rate (used for TX only)
860 u1_t rejoinCnt; // adjustment for rejoin datarate
861
862 u1_t upRepeatCount; // current up-repeat
863 bit_t initBandplanAfterReset; // cleared by LMIC_reset(), set by first join. See issue #244
864
865 u1_t pendTxPort;
866 u1_t pendTxConf; // confirmed data
867 u1_t pendTxLen; // count of bytes in pendTxData.
868 u1_t pendTxData[MAX_LEN_PAYLOAD];
869
870 u1_t pendMacLen; // number of bytes of pending Mac response data
871 bit_t pendMacPiggyback; // received on port 0 or piggyback?
872 // response data if piggybacked
873 u1_t pendMacData[LWAN_FCtrl_FOptsLen_MAX];
874
875 u1_t nwkKey[16]; // network session key
876 u1_t artKey[16]; // application router session key
877
878 u1_t dnConf; // dn frame confirm pending: LORA::FCT_ACK or 0
879 u1_t lastDnConf; // downlink with seqnoDn-1 requested confirmation
880 u1_t adrChanged;
881
882 u1_t rxDelay; // Rx delay after TX
883
884 u1_t margin;
885 s1_t devAnsMargin; // SNR value between -32 and 31 (inclusive) for the last successfully received DevStatusReq command
886 u1_t adrEnabled;
887 u1_t moreData; // NWK has more data pending
888#if LMIC_ENABLE_TxParamSetupReq
889 u1_t txParam; // the saved TX param byte.
890#endif
891#if LMIC_ENABLE_DeviceTimeReq
892 lmic_request_time_state_t txDeviceTimeReqState; // current state, initially idle.
893 u1_t netDeviceTimeFrac; // updated on any DeviceTimeAns.
894#endif
895
896 // rx1DrOffset is the offset from uplink to downlink datarate
897 u1_t rx1DrOffset; // captured from join. zero by default.
898
899 // 2nd RX window (after up stream)
900 u1_t dn2Dr;
901#if !defined(DISABLE_MCMD_RXParamSetupReq)
902 u1_t dn2Ans; // 0=no answer pend, 0x80+ACKs
903#endif
904#if !defined(DISABLE_MCMD_DlChannelReq)
905 u1_t macDlChannelAns; // 0 ==> no answer pending, 0x80+ACK bits
906#endif
907#if !defined(DISABLE_MCMD_RXTimingSetupReq)
908 bit_t macRxTimingSetupAns; // 0 ==> no answer pend, non-zero inserts response.
909#endif
910
911 // Class B state
912#if !defined(DISABLE_BEACONS)
913 u1_t missedBcns; // unable to track last N beacons
914 u1_t bcninfoTries; // how often to try (scan mode only)
915#endif
916 // Public part of MAC state
917 u1_t txCnt;
919
920 u1_t dataBeg; // 0 or start of data (dataBeg-1 is port)
921 u1_t dataLen; // 0 no data or zero length data, >0 byte count of data
922 u1_t frame[MAX_LEN_FRAME];
923
924#if !defined(DISABLE_BEACONS)
925 u1_t bcnChnl;
926#endif
927
928 u1_t noRXIQinversion;
929 u1_t saveIrqFlags; // last LoRa IRQ flags
930
931 // Class C state
932#if LMIC_ENABLE_class_c
933 lmic_class_c_t classC;
934#endif
935};
936
939DECLARE_LMIC;
940
941/****************************************************************************\
942|
943| API functions
944|
945\****************************************************************************/
946
948#define DR_RANGE_MAP(drlo,drhi) (((u2_t)0xFFFF<<(drlo)) & ((u2_t)0xFFFF>>(15-(drhi))))
949bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap);
950bit_t LMIC_setupChannel (u1_t channel, u4_t freq, u2_t drmap, s1_t band);
951bit_t LMIC_disableChannel (u1_t channel);
952bit_t LMIC_enableSubBand(u1_t band);
953bit_t LMIC_enableChannel(u1_t channel);
954bit_t LMIC_disableSubBand(u1_t band);
955bit_t LMIC_selectSubBand(u1_t band);
956
959
961bit_t LMIC_queryTxReady(void);
962
963void LMIC_setDrTxpow (dr_t dr, s1_t txpow); // set default/start DR/txpow
964void LMIC_setAdrMode (bit_t enabled); // set ADR mode (if mobile turn off)
965
966#if !defined(DISABLE_JOIN)
967bit_t LMIC_startJoining (void);
968void LMIC_tryRejoin (void);
969void LMIC_unjoin (void);
970void LMIC_unjoinAndRejoin (void);
971#endif
972
973void LMIC_shutdown (void);
974void LMIC_init (void);
975void LMIC_reset (void);
976void LMIC_clrTxData (void);
977void LMIC_setTxData (void);
978void LMIC_setTxData_strict(void);
979lmic_tx_error_t LMIC_setTxData2(u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed);
980lmic_tx_error_t LMIC_setTxData2_strict(u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed);
981lmic_tx_error_t LMIC_sendWithCallback(u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed, lmic_txmessage_cb_t *pCb, void *pUserData);
982lmic_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);
983void LMIC_sendAlive (void);
984
985#if !defined(DISABLE_BEACONS)
986bit_t LMIC_enableTracking (u1_t tryBcnInfo);
987void LMIC_disableTracking (void);
988#endif
989
990#if !defined(DISABLE_PING)
991void LMIC_stopPingable (void);
992void LMIC_setPingable (u1_t intvExp);
993#endif
994
995void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
996void LMIC_setLinkCheckMode (bit_t enabled);
997void LMIC_setClockError(u2_t error);
998
999u4_t LMIC_getSeqnoUp (void);
1000u4_t LMIC_setSeqnoUp (u4_t);
1001void LMIC_getSessionKeys (u4_t *netid, devaddr_t *devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
1002
1003void LMIC_requestNetworkTime(lmic_request_network_time_cb_t *pCallbackfn, void *pUserData);
1004int LMIC_getNetworkTimeReference(lmic_time_reference_t *pReference);
1005
1006int LMIC_registerRxMessageCb(lmic_rxmessage_cb_t *pRxMessageCb, void *pUserData);
1007int LMIC_registerEventCb(lmic_event_cb_t *pEventCb, void *pUserData);
1008
1009int LMIC_findNextChannel(uint16_t *, const uint16_t *, uint16_t, int);
1010
1011u1_t LMIC_getBatteryLevel(void);
1012u1_t LMIC_setBatteryLevel(u1_t /* uBattLevel */);
1013
1014// APIs for client half of compliance.
1015typedef u1_t lmic_compliance_rx_action_t;
1016
1017enum lmic_compliance_rx_action_e {
1018 LMIC_COMPLIANCE_RX_ACTION_PROCESS = 0, // process this message normally
1019 LMIC_COMPLIANCE_RX_ACTION_START, // enter compliance mode, discard this message
1020 LMIC_COMPLIANCE_RX_ACTION_IGNORE, // continue in compliance mode, discard this message
1021 LMIC_COMPLIANCE_RX_ACTION_END // exit compliance mode, discard this message
1022};
1023
1024lmic_compliance_rx_action_t LMIC_complianceRxMessage(u1_t port, const u1_t *pMessage, size_t nMessage);
1025
1026// APIs for class C support
1027// We provide stubs so that users don't need to litter their code with #if unless
1028// they want to.
1029
1030static inline bit_t LMIC_isConfiguredClassC(void) {
1031 return LMIC_ENABLE_class_c;
1032}
1033
1034#if LMIC_ENABLE_class_c
1036bit_t LMIC_enableClassC(bit_t fOnIfTrue);
1037#else
1038static inline bit_t LMIC_enableClassC(bit_t fOnIfTrue) {
1039 if (fOnIfTrue)
1040 // class C cannot be turned on in this build;
1041 return 0;
1042 else
1043 // class C cannot be turned on, but the request says "turn it off"
1044 return 1;
1045}
1046#endif // !LMIC_ENABLE_class_c
1047
1048// Declare onEvent() function, to make sure any definition will have the
1049// C conventions, even when in a C++ file.
1050#if LMIC_ENABLE_onEvent
1051DECL_ON_LMIC_EVENT;
1052#endif /* LMIC_ENABLE_onEvent */
1053
1054// Special APIs - for development or testing
1055// !!!See implementation for caveats!!!
1056
1057#ifdef __cplusplus
1058} // extern "C"
1059#endif
1060
1061// names for backward compatibility
1062#include "lmic_compat.h"
1063
1064#endif // _lmic_h_
u1_t LMIC_setBatteryLevel(u1_t)
set battery level to be returned by DevStatusAns.
Definition lmic.c:3200
u1_t LMIC_getBatteryLevel(void)
get battery level that is to be returned by DevStatusAns.
Definition lmic.c:3216
void LMIC_ABI_STD lmic_request_network_time_cb_t(void *pUserData, int flagSuccess)
network time request callback function type
Definition lmic.h:467
s1_t lmic_beacon_error_t
Error codes returned for beacon operations.
Definition lmic.h:427
void LMIC_setSession(u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey)
Set up keys for ABP.
Definition lmic.c:3065
lmic_engine_update_state_e
Definition lmic.h:492
@ lmic_EngineUpdateState_busy
engineUpdate is busy, but has not been reentered.
Definition lmic.h:494
@ lmic_EngineUpdateState_again
engineUpdate is busy, and has to be evaluated again.
Definition lmic.h:495
@ lmic_EngineUpdateState_idle
engineUpdate is idle.
Definition lmic.h:493
struct lmic_client_data_s lmic_client_data_t
abstract type for collection of client data that survives LMIC_reset().
Definition lmic.h:511
lmic_tx_error_e
LMIC error codes.
Definition lmic.h:383
@ LMIC_ERROR_TX_FAILED
Transmit failed for unspecified reason.
Definition lmic.h:388
@ LMIC_ERROR_SUCCESS
No error.
Definition lmic.h:384
@ LMIC_ERROR_TX_TOO_LARGE
Message was too long for configured LMIC buffers.
Definition lmic.h:386
@ LMIC_ERROR_TX_BUSY
Transmit path was busy, mesage rejected.
Definition lmic.h:385
@ LMIC_ERROR_TX_NOT_FEASIBLE
Message was too long given region, spreading factor, and network settings.
Definition lmic.h:387
_ev_t
Event codes for event callback.
Definition lmic.h:349
u1_t lmic_radio_flags_t
container type for radio request flags
Definition lmic.h:590
@ TXRX_DNW1
received in 1st DN slot
Definition lmic.h:289
@ TXRX_PING
received in a scheduled RX slot or class C
Definition lmic.h:287
@ TXRX_PORT
set if a frame with a port was RXed, LMIC.frame[LMIC.dataBeg-1] => port
Definition lmic.h:285
@ TXRX_NACK
confirmed UP frame was not acked
Definition lmic.h:283
@ TXRX_ACK
confirmed UP frame was acked
Definition lmic.h:282
@ TXRX_LENERR
set if frame was discarded due to length error.
Definition lmic.h:286
@ TXRX_NOPORT
set if a frame with a port was RXed, clr if no frame/no port
Definition lmic.h:284
@ TXRX_DNW2
received in 2dn DN slot or class C
Definition lmic.h:288
u1_t lmic_radio_state_t
concrete type for holding the radio state mask.
Definition lmic.h:555
@ OP_SCAN
radio scan to find a beacon
Definition lmic.h:265
@ OP_JOINING
device joining in progress (blocks other activities)
Definition lmic.h:267
@ OP_REJOIN
occasionally send JOIN REQUEST
Definition lmic.h:270
@ OP_TRACK
track my networks beacon (netid)
Definition lmic.h:266
@ OP_NEXTCHNL
find a new channel
Definition lmic.h:276
@ OP_TXDATA
TX user data (buffered in pendTxData).
Definition lmic.h:268
@ OP_UNJOIN
unjoin and rejoin on next engineUpdate().
Definition lmic.h:279
@ OP_PINGINI
pingable is initialized and scheduling active
Definition lmic.h:274
@ OP_LINKDEAD
link was reported as dead
Definition lmic.h:277
@ OP_PINGABLE
we're pingable
Definition lmic.h:275
@ OP_SHUTDOWN
prevent MAC from doing anything
Definition lmic.h:271
@ OP_POLL
send empty UP frame to ACK confirmed DN/fetch more DN data
Definition lmic.h:269
@ OP_RNDTX
prevent TX lining up after a beacon
Definition lmic.h:273
@ OP_TESTMODE
developer test mode
Definition lmic.h:278
@ OP_TXRXPEND
TX/RX transaction pending.
Definition lmic.h:272
u4_t lmic_gpstime_t
how the network represents time.
Definition lmic.h:470
int lmic_tx_error_t
LMIC result codes, as an integer type.
Definition lmic.h:393
bit_t LMIC_queryTxReady(void)
check whether the LMIC is ready for a transmit packet
Definition lmic.c:2940
lmic_radio_flags_e
radio request flags
Definition lmic.h:582
@ LMIC_RADIO_FLAGS_NO_RX_IQ_INVERSION
if set, don't invert IQ on receive
Definition lmic.h:583
struct lmic_radio_data_s lmic_radio_data_t
Instance data for LMIC radio driver.
Definition lmic.h:600
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:697
u1_t LMIC_queryNumDefaultChannels(void)
get the number of (fixed) default channels before the programmable channels.
Definition lmic_eu868.c:154
bit_t LMIC_setupChannel(u1_t channel, u4_t freq, u2_t drmap, s1_t band)
LMIC_setupChannel for EU 868.
Definition lmic_eu868.c:166
struct lmic_class_c_s lmic_class_c_t
the structure containing class C state
Definition lmic.h:732
union lmic_class_c_flags_u lmic_class_c_flags_t
internal state flacs for class C operation
Definition lmic.h:663
@ BCN_FULL
Full beacon decoded.
Definition lmic.h:235
@ BCN_NODRIFT
No drift value measured yet.
Definition lmic.h:236
@ BCN_NONE
No beacon received.
Definition lmic.h:233
@ BCN_PARTIAL
Only first (common) part could be decoded (info,lat,lon invalid/previous).
Definition lmic.h:234
@ MAX_CLOCK_ERROR
This value represents 100% error in LMIC.clockError.
Definition lmic.h:436
@ LMIC_kMaxClockError_ppm
maximum clock error that users can specify: 4000 ppm (0.4%).
Definition lmic.h:446
lmic_radio_state_e
radio driver state mask
Definition lmic.h:560
@ LMIC_RADIO_EV_RXTIMEOUT
rx timed out; RXDONE also set.
Definition lmic.h:569
@ LMIC_RADIO_EV_RXUNKNOWN
rx timed out, not sure whay.
Definition lmic.h:570
@ LMIC_RADIO_EV_RXDONE
rx complete
Definition lmic.h:568
@ LMIC_RADIO_EV_TXSTART
transmit started
Definition lmic.h:562
@ LMIC_RADIO_EV_NONE
no events reported
Definition lmic.h:561
@ LMIC_RADIO_EV_RXSTART
receive started
Definition lmic.h:567
@ LMIC_RADIO_EV_TXUNKNOWN
transmit unknown event.
Definition lmic.h:566
@ LMIC_RADIO_EV_TXDONE
transmit complete, TXSTART will still be set
Definition lmic.h:563
@ LMIC_RADIO_EV_TXDEFER
transmit deferred (LBT)
Definition lmic.h:565
lmic_beacon_error_e
Error codes returned for beacon operations.
Definition lmic.h:418
@ LMIC_BEACON_ERROR_SUCCESS_FULL
Full beacon successfuly received.
Definition lmic.h:422
@ LMIC_BEACON_ERROR_INVALID
Invalid beacon received.
Definition lmic.h:419
@ LMIC_BEACON_ERROR_SUCCESS_PARTIAL
Partial success; first set of fields are OK.
Definition lmic.h:421
@ LMIC_BEACON_ERROR_WRONG_NETWORK
Beacon received for wrong network.
Definition lmic.h:420
@ RADIO_RXON
receive without time window
Definition lmic.h:256
@ RADIO_TX_AT
transmit at a specific time
Definition lmic.h:257
@ RADIO_RST
reset, canceling any pending operations.
Definition lmic.h:253
@ RADIO_RXON_C
open the class C window if possible.
Definition lmic.h:258
@ RADIO_RX
receive single with time window
Definition lmic.h:255
@ RADIO_TX
transmit.
Definition lmic.h:254
lmic_request_time_state_e
Definition lmic.h:483
@ lmic_RequestTimeState_success
we sucessfully got time.
Definition lmic.h:487
@ lmic_RequestTimeState_idle
we're not doing anything
Definition lmic.h:484
@ lmic_RequestTimeState_rx
we have tx'ed, next downlink completes.
Definition lmic.h:486
@ lmic_RequestTimeState_tx
we want to tx a time request on next uplink
Definition lmic.h:485
Information about the last and previous beacons.
Definition lmic.h:239
s4_t lat
Lat field of last beacon (valid only if BCN_FULL set).
Definition lmic.h:242
s4_t lon
Lon field of last beacon (valid only if BCN_FULL set).
Definition lmic.h:243
u1_t info
Info field of last beacon (valid only if BCN_FULL set).
Definition lmic.h:248
u1_t flags
Last beacon reception and tracking states. See BCN_* values.
Definition lmic.h:246
s1_t rssi
Adjusted RSSI value of last received beacon.
Definition lmic.h:244
u4_t time
GPS time in seconds of last beacon (received or surrogate).
Definition lmic.h:241
ostime_t txtime
Time when the beacon was sent.
Definition lmic.h:240
s1_t snr
Scaled SNR value of last received beacon.
Definition lmic.h:245
the Class C operating flags
Definition lmic.h:678
unsigned fEnabled
true if class C operation is enabled.
Definition lmic.h:679
unsigned fRx2Active
true if we think that RX2 is active.
Definition lmic.h:680
the Class C request flags
Definition lmic.h:714
unsigned fPending
true while API job is pending.
Definition lmic.h:715
unsigned fTargetState
true if enable requested; false otherwise.
Definition lmic.h:719
unsigned fStateChangeRq
true if the outside world has asked for a change in state; target state will be the desired state.
Definition lmic.h:716
details of class C state
Definition lmic.h:739
osjob_t job
the job for API requests
Definition lmic.h:740
lmic_class_c_flags_t flags
the state flags
Definition lmic.h:741
lmic_class_c_requests_t requests
the request flags
Definition lmic.h:742
contents of lmic_client_data_t
Definition lmic.h:514
void * eventUserData
data for eventCb
Definition lmic.h:524
u2_t clockError
Inaccuracy in the clock. CLOCK_ERROR_MAX represents +/-100% error.
Definition lmic.h:536
lmic_request_network_time_cb_t * pNetworkTimeCb
call-back routine for network time
Definition lmic.h:518
lmic_event_cb_t * eventCb
user-supplied callback function for events.
Definition lmic.h:523
void * txMessageUserData
data for txMessageCb.
Definition lmic.h:528
lmic_rxmessage_cb_t * rxMessageCb
user-supplied message-received callback
Definition lmic.h:525
u1_t devStatusAns_battery
value to report in MCMD_DevStatusAns message.
Definition lmic.h:539
lmic_txmessage_cb_t * txMessageCb
transmit-complete message handler; reset on each tx complete.
Definition lmic.h:527
void * pNetworkTimeUserData
call-back data for network time.
Definition lmic.h:519
void * rxMessageUserData
data for rxMessageCb
Definition lmic.h:526
Details of instance data for LMIC radio driver.
Definition lmic.h:605
rps_t rps
radio parameter settings for this radio operation. (two bytes)
Definition lmic.h:614
u1_t dataLen
size of buffer (in for TX, out for RX; RX assumes actual size is MAX_LEN_FRAME)
Definition lmic.h:620
u2_t rxlate_count
Count of rx late launches.
Definition lmic.h:643
u2_t txlate_count
Count of tx late launches.
Definition lmic.h:645
lmic_radio_state_t state
radio state mask; used by radio driver.
Definition lmic.h:633
lmic_radio_flags_t flags
various flags
Definition lmic.h:623
rxsyms_t rxsyms
timeout in symbols (2 bytes)
Definition lmic.h:616
osjob_t * pRadioDoneJob
job to be scheduled when radio operation completes.
Definition lmic.h:636
u1_t * pFrame
pointer to buffer
Definition lmic.h:609
ostime_t rxlate_ticks
Total os ticks of accumulated delay error. Can overflow!
Definition lmic.h:639
u4_t freq
frequency for this radio operation
Definition lmic.h:607
ostime_t txlate_ticks
Total os ticks of accumulated tx delay error. Can overflow!
Definition lmic.h:641
ostime_t rxtime
input: rxwindow open time; output: time of receipt of last bit.
Definition lmic.h:611
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:630
Instance data for the LMIC.
Definition lmic.h:755
osjob_t osjob
the OS job object.
Definition lmic.h:761
ostime_t lbt_ticks
ticks to listen for interference before transmitting.
Definition lmic.h:786
bcninfo_t bcninfo
Last received beacon info.
Definition lmic.h:768
ostime_t nextRxTime
time of start of next receive
Definition lmic.h:783
lmic_radio_data_t radio
the radio driver portable context
Definition lmic.h:776
ostime_t txend
time of end of last transmit
Definition lmic.h:781
u4_t seqnoUp
FCntUp (uplink seqno).
Definition lmic.h:795
u4_t dn2Freq
the frequency to use for RX2.
Definition lmic.h:796
osjob_t osjob_defer
the OS job object for events.
Definition lmic.h:765
lmic_client_data_t client
client setup data, survives LMIC_reset().
Definition lmic.h:757
ostime_t rxtime
time of end of last receive
Definition lmic.h:782
u4_t seqnoDn
FCntDown (downlink seqno).
Definition lmic.h:794
u4_t freq
most recent frequency, Hz.
Definition lmic.h:788
u2_t txrxFlags
transaction flags (TX-RX combo)
Definition lmic.h:918
devaddr_t devaddr
current device address. Zero means not joined.
Definition lmic.h:793
u4_t netid
current network id (~0 - none)
Definition lmic.h:792
ostime_t globalDutyAvail
time when device can send again
Definition lmic.h:790
rxsched_t ping
Data for handling ping scheduling.
Definition lmic.h:772
Definition lmic.h:476
lmic_gpstime_t tNetwork
the network's best idea of when we sent the uplink.
Definition lmic.h:480
ostime_t tLocal
our best idea of when we sent the uplink (end of packet).
Definition lmic.h:478
Definition oslmic.h:170
Definition lmic.h:218
details of lmic_class_c_flags_t.
Definition lmic.h:674
unsigned mask
view all the flags as a word so we can reset them easily.
Definition lmic.h:675
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:710
unsigned mask
view all the flags as a word so we can reset them easily.
Definition lmic.h:711
struct lmic_class_c_requests_u::lmic_class_c_requests_s f
access the Class C request flags individually.