@@ -119,7 +119,7 @@ void os_wmsbf4 (xref2u1_t buf, u4_t v) {
119119
120120#if !defined(os_getBattLevel )
121121u1_t os_getBattLevel (void ) {
122- return MCMD_DEVS_BATT_NOINFO ;
122+ return LMIC . client . devStatusAns_battery ;
123123}
124124#endif
125125
@@ -295,7 +295,7 @@ ostime_t calcAirTime (rps_t rps, u1_t plen) {
295295//
296296
297297static void setRxsyms (ostime_t rxsyms ) {
298- if (rxsyms >= (1u << 10u )) {
298+ if (rxsyms >= ((( ostime_t ) 1 ) << 10u )) {
299299 LMIC .rxsyms = (1u << 10u ) - 1 ;
300300 } else if (rxsyms < 0 ) {
301301 LMIC .rxsyms = 0 ;
@@ -721,11 +721,17 @@ static CONST_TABLE(u1_t, macCmdSize)[] = {
721721};
722722
723723static u1_t getMacCmdSize (u1_t macCmd ) {
724- if (macCmd < 2 )
725- return 0 ;
726- if ((macCmd - 2 ) >= LENOF_TABLE (macCmdSize ))
727- return 0 ;
728- return TABLE_GET_U1 (macCmdSize , macCmd - 2 );
724+ if (macCmd >= 2 ) {
725+ const unsigned macCmdMinus2 = macCmd - 2u ;
726+ if (macCmdMinus2 < LENOF_TABLE (macCmdSize )) {
727+ // macCmd in table, fetch it's size.
728+ return TABLE_GET_U1 (macCmdSize , macCmdMinus2 );
729+ }
730+ }
731+ // macCmd too small or too large: return zero. Zero is
732+ // never a legal command size, so it signals an error
733+ // to the caller.
734+ return 0 ;
729735}
730736
731737static bit_t
@@ -758,6 +764,9 @@ applyAdrRequests(
758764 p4 = opts [oidx + 4 ]; // ChMaskCtl, NbTrans
759765 u1_t chpage = p4 & MCMD_LinkADRReq_Redundancy_ChMaskCntl_MASK ; // channel page
760766
767+ // notice that we ignore map_ok except on the last setting.
768+ // so LMICbandplan_mapChannels should report failure status, but do
769+ // the work; if it fails, we'll back it out.
761770 map_ok = LMICbandplan_mapChannels (chpage , chmap );
762771 LMICOS_logEventUint32 ("applyAdrRequests: mapChannels" , ((u4_t )chpage << 16 )|(chmap << 0 ));
763772 }
@@ -883,10 +892,14 @@ scan_mac_cmds(
883892 uint8_t cmd ;
884893
885894 LMIC .pendMacLen = 0 ;
886- if (port == 0 )
895+ if (port == 0 ) {
896+ // port zero: mac data is in the normal payload, and there can't be
897+ // piggyback mac data.
887898 LMIC .pendMacPiggyback = 0 ;
888- else
899+ } else {
900+ // port is either -1 (no port) or non-zero (piggyback): treat as piggyback.
889901 LMIC .pendMacPiggyback = 1 ;
902+ }
890903
891904 while ( oidx < olen ) {
892905 bit_t response_fit ;
@@ -1466,7 +1479,12 @@ ostime_t LMICcore_adjustForDrift (ostime_t delay, ostime_t hsym, rxsyms_t rxsyms
14661479 // a compile-time configuration. (In other words, assume that millis()
14671480 // clock is accurate to 0.1%.) You should never use clockerror to
14681481 // compensate for system-late problems.
1469- u2_t const maxError = LMIC_kMaxClockError_ppm * MAX_CLOCK_ERROR / (1000 * 1000 );
1482+ // note about compiler: The initializer for maxError is coded for
1483+ // maximum portability. On 16-bit systems, some compilers complain
1484+ // if we write x / (1000 * 1000). x / 1000 / 1000 uses constants,
1485+ // is generally acceptable so it can be optimized in compiler's own
1486+ // way.
1487+ u2_t const maxError = LMIC_kMaxClockError_ppm * MAX_CLOCK_ERROR / 1000 / 1000 ;
14701488 if (! LMIC_ENABLE_arbitrary_clock_error && clockerr > maxError )
14711489 {
14721490 clockerr = maxError ;
@@ -1606,21 +1624,9 @@ static bit_t processJoinAccept (void) {
16061624 // initDefaultChannels(0) for EU-like, nothing otherwise
16071625 LMICbandplan_joinAcceptChannelClear ();
16081626
1609- if (!LMICbandplan_hasJoinCFlist () && dlen > LEN_JA ) {
1610- // if no JoinCFList, we're supposed to continue
1611- // the join per 2.2.5 of LoRaWAN regional 2.2.4
1612- // https://github.com/mcci-catena/arduino-lmic/issues/19
1613- } else if ( LMICbandplan_hasJoinCFlist () && dlen > LEN_JA ) {
1614- dlen = OFF_CFLIST ;
1615- for ( u1_t chidx = 3 ; chidx < 8 ; chidx ++ , dlen += 3 ) {
1616- u4_t freq = LMICbandplan_convFreq (& LMIC .frame [dlen ]);
1617- if ( freq ) {
1618- LMIC_setupChannel (chidx , freq , 0 , -1 );
1619- #if LMIC_DEBUG_LEVEL > 1
1620- LMIC_DEBUG_PRINTF ("%" LMIC_PRId_ostime_t ": Setup channel, idx=%d, freq=%" PRIu32 "\n" , os_getTime (), chidx , freq );
1621- #endif
1622- }
1623- }
1627+ // process the CFList if present
1628+ if (dlen == LEN_JAEXT ) {
1629+ LMICbandplan_processJoinAcceptCFList ();
16241630 }
16251631
16261632 // already incremented when JOIN REQ got sent off
@@ -1855,7 +1861,8 @@ static bit_t buildDataFrame (void) {
18551861 // highest importance are the ones in the pendMac buffer.
18561862 int end = OFF_DAT_OPTS ;
18571863
1858- if (LMIC .pendTxPort != 0 && LMIC .pendMacPiggyback && LMIC .pendMacLen != 0 ) {
1864+ // Send piggyback data if: !txdata or txport != 0
1865+ if ((! txdata || LMIC .pendTxPort != 0 ) && LMIC .pendMacPiggyback && LMIC .pendMacLen != 0 ) {
18591866 os_copyMem (LMIC .frame + end , LMIC .pendMacData , LMIC .pendMacLen );
18601867 end += LMIC .pendMacLen ;
18611868 }
@@ -2780,6 +2787,11 @@ void LMIC_reset (void) {
27802787 LMIC .adrEnabled = FCT_ADREN ;
27812788 resetJoinParams ();
27822789 LMIC .rxDelay = DELAY_DNW1 ;
2790+ // LMIC.pendMacLen = 0;
2791+ // LMIC.pendMacPiggyback = 0;
2792+ // LMIC.dn2Ans = 0;
2793+ // LMIC.macDlChannelAns = 0;
2794+ // LMIC.macRxTimingSetupAns = 0;
27832795#if !defined(DISABLE_PING )
27842796 LMIC .ping .freq = FREQ_PING ; // defaults for ping
27852797 LMIC .ping .dr = DR_PING ; // ditto
@@ -2806,6 +2818,7 @@ void LMIC_reset (void) {
28062818
28072819void LMIC_init (void ) {
28082820 LMIC .opmode = OP_SHUTDOWN ;
2821+ LMIC .client .devStatusAns_battery = MCMD_DEVS_BATT_NOINFO ;
28092822 LMICbandplan_init ();
28102823}
28112824
@@ -2866,7 +2879,11 @@ dr_t LMIC_feasibleDataRateForFrame(dr_t dr, u1_t payloadSize) {
28662879}
28672880
28682881static bit_t isTxPathBusy (void ) {
2869- return (LMIC .opmode & (OP_TXDATA |OP_JOINING )) != 0 ;
2882+ return (LMIC .opmode & (OP_POLL | OP_TXDATA | OP_JOINING | OP_TXRXPEND )) != 0 ;
2883+ }
2884+
2885+ bit_t LMIC_queryTxReady (void ) {
2886+ return ! isTxPathBusy ();
28702887}
28712888
28722889static bit_t adjustDrForFrameIfNotBusy (u1_t len ) {
@@ -2886,6 +2903,10 @@ void LMIC_setTxData (void) {
28862903}
28872904
28882905void LMIC_setTxData_strict (void ) {
2906+ if (isTxPathBusy ()) {
2907+ return ;
2908+ }
2909+
28892910 LMICOS_logEventUint32 (__func__ , ((u4_t )LMIC .pendTxPort << 24u ) | ((u4_t )LMIC .pendTxConf << 16u ) | (LMIC .pendTxLen << 0u ));
28902911 LMIC .opmode |= OP_TXDATA ;
28912912 if ( (LMIC .opmode & OP_JOINING ) == 0 ) {
@@ -2904,7 +2925,7 @@ lmic_tx_error_t LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t conf
29042925
29052926// send a message w/o callback; do not adjust data rate
29062927lmic_tx_error_t LMIC_setTxData2_strict (u1_t port , xref2u1_t data , u1_t dlen , u1_t confirmed ) {
2907- if ( LMIC . opmode & OP_TXDATA ) {
2928+ if (isTxPathBusy () ) {
29082929 // already have a message queued
29092930 return LMIC_ERROR_TX_BUSY ;
29102931 }
@@ -2924,7 +2945,7 @@ lmic_tx_error_t LMIC_setTxData2_strict (u1_t port, xref2u1_t data, u1_t dlen, u1
29242945 return LMIC_ERROR_TX_FAILED ;
29252946 }
29262947 }
2927- return 0 ;
2948+ return LMIC_ERROR_SUCCESS ;
29282949}
29292950
29302951// send a message with callback; try to adjust data rate
@@ -3080,6 +3101,52 @@ int LMIC_getNetworkTimeReference(lmic_time_reference_t *pReference) {
30803101 pReference -> tNetwork = LMIC .netDeviceTime ;
30813102 return 1 ;
30823103 }
3104+ #else
3105+ LMIC_API_PARAMETER (pReference );
30833106#endif // LMIC_ENABLE_DeviceTimeReq
30843107 return 0 ;
30853108}
3109+
3110+ ///
3111+ /// \brief set battery level to be returned by `DevStatusAns`.
3112+ ///
3113+ /// \param uBattLevel is the 8-bit value to be returned. Per LoRaWAN 1.0.3 line 769,
3114+ /// this is \c MCMD_DEVS_EXT_POWER (0) if on external power,
3115+ /// \c MCMD_DEVS_NOINFO (255) if not able to measure battery level,
3116+ /// or a value in [ \c MCMD_DEVS_BATT_MIN, \c MCMD_DEVS_BATT_MAX ], numerically
3117+ /// [1, 254], to represent the charge state of the battery. Note that
3118+ /// this is not millivolts.
3119+ ///
3120+ /// \returns
3121+ /// This function returns the previous value of the battery level.
3122+ ///
3123+ /// \details
3124+ /// The LMIC maintains an idea of the current battery state, initially set to
3125+ /// \c MCMD_DEVS_NOINFO after the call to LMIC_init(). The appplication then calls
3126+ /// this function from time to time to update the battery level.
3127+ ///
3128+ /// It is possible (in non-Arduino environments) to supply a local implementation
3129+ /// of os_getBatteryLevel(). In that case, it's up to the implementation to decide
3130+ /// whether to use the value supplied by this API.
3131+ ///
3132+ /// This implementation was chosen to minimize the risk of a battery measurement
3133+ /// introducting breaking delays into the LMIC.
3134+ ///
3135+ u1_t LMIC_setBatteryLevel (u1_t uBattLevel ) {
3136+ const u1_t result = LMIC .client .devStatusAns_battery ;
3137+
3138+ LMIC .client .devStatusAns_battery = uBattLevel ;
3139+ return result ;
3140+ }
3141+
3142+ ///
3143+ /// \brief get battery level that is to be returned by `DevStatusAns`.
3144+ ///
3145+ /// \returns
3146+ /// This function returns the saved value of the battery level.
3147+ ///
3148+ /// \see LMIC_setBatteryLevel()
3149+ ///
3150+ u1_t LMIC_getBatteryLevel (void ) {
3151+ return LMIC .client .devStatusAns_battery ;
3152+ }
0 commit comments