@@ -2723,9 +2723,49 @@ void LMIC_clrTxData (void) {
2723
2723
engineUpdate ();
2724
2724
}
2725
2725
2726
+ dr_t LMIC_feasibleDataRateForFrame (dr_t dr , u1_t payloadSize ) {
2727
+ if (payloadSize > MAX_LEN_PAYLOAD ) {
2728
+ return dr ;
2729
+ }
2730
+
2731
+ const u1_t frameSize = payloadSize + OFF_DAT_OPTS + 5 ;
2732
+ dr_t trialDr , nextDr ;
2733
+
2734
+ for (trialDr = dr ; ;) {
2735
+ if (! LMICbandplan_isDataRateFeasible (trialDr ))
2736
+ break ;
2737
+ u1_t maxSizeThisDr = LMICbandplan_maxFrameLen (trialDr );
2738
+ if (maxSizeThisDr == 0 ) {
2739
+ break ;
2740
+ } else if (frameSize <= maxSizeThisDr ) {
2741
+ // we found one that is feasible!
2742
+ return trialDr ;
2743
+ }
2744
+ // try the next DR
2745
+ nextDr = incDR (trialDr );
2746
+ if (nextDr == trialDr )
2747
+ break ;
2748
+ trialDr = nextDr ;
2749
+ }
2750
+
2751
+ // if we get here, we didn't find a working dr.
2752
+ return dr ;
2753
+ }
2754
+
2755
+ static void adjustDrForFrame (u1_t len ) {
2756
+ dr_t newDr = LMIC_feasibleDataRateForFrame (LMIC .datarate , len );
2757
+ if (newDr != LMIC .datarate ) {
2758
+ setDrTxpow (DRCHG_FRAMESIZE , newDr , KEEP_TXPOW );
2759
+ }
2760
+ }
2726
2761
2727
2762
void LMIC_setTxData (void ) {
2728
- LMICOS_logEventUint32 ("LMIC_setTxData" , (LMIC .pendTxPort << 24u ) | (LMIC .pendTxConf << 16u ) | (LMIC .pendTxLen << 0u ));
2763
+ adjustDrForFrame (LMIC .pendTxLen );
2764
+ LMIC_setTxData_strict ();
2765
+ }
2766
+
2767
+ void LMIC_setTxData_strict (void ) {
2768
+ LMICOS_logEventUint32 (__func__ , (LMIC .pendTxPort << 24u ) | (LMIC .pendTxConf << 16u ) | (LMIC .pendTxLen << 0u ));
2729
2769
LMIC .opmode |= OP_TXDATA ;
2730
2770
if ( (LMIC .opmode & OP_JOINING ) == 0 ) {
2731
2771
LMIC .txCnt = 0 ; // reset the confirmed uplink FSM
@@ -2735,8 +2775,14 @@ void LMIC_setTxData (void) {
2735
2775
}
2736
2776
2737
2777
2738
- // send a message w/o callback
2778
+ // send a message, attempting to adjust TX data rate
2739
2779
lmic_tx_error_t LMIC_setTxData2 (u1_t port , xref2u1_t data , u1_t dlen , u1_t confirmed ) {
2780
+ adjustDrForFrame (dlen );
2781
+ return LMIC_setTxData2_strict (port , data , dlen , confirmed );
2782
+ }
2783
+
2784
+ // send a message w/o callback; do not adjust data rate
2785
+ lmic_tx_error_t LMIC_setTxData2_strict (u1_t port , xref2u1_t data , u1_t dlen , u1_t confirmed ) {
2740
2786
if ( LMIC .opmode & OP_TXDATA ) {
2741
2787
// already have a message queued
2742
2788
return LMIC_ERROR_TX_BUSY ;
@@ -2748,7 +2794,7 @@ lmic_tx_error_t LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t conf
2748
2794
LMIC .pendTxConf = confirmed ;
2749
2795
LMIC .pendTxPort = port ;
2750
2796
LMIC .pendTxLen = dlen ;
2751
- LMIC_setTxData ();
2797
+ LMIC_setTxData_strict ();
2752
2798
if ( (LMIC .opmode & OP_TXDATA ) == 0 ) {
2753
2799
if (LMIC .txrxFlags & TXRX_LENERR ) {
2754
2800
return LMIC_ERROR_TX_NOT_FEASIBLE ;
@@ -2760,10 +2806,19 @@ lmic_tx_error_t LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t conf
2760
2806
return 0 ;
2761
2807
}
2762
2808
2763
- // send a message with callback
2809
+ // send a message with callback; try to adjust data rate
2764
2810
lmic_tx_error_t LMIC_sendWithCallback (
2765
2811
u1_t port , xref2u1_t data , u1_t dlen , u1_t confirmed ,
2766
2812
lmic_txmessage_cb_t * pCb , void * pUserData
2813
+ ) {
2814
+ adjustDrForFrame (dlen );
2815
+ return LMIC_sendWithCallback_strict (port , data , dlen , confirmed , pCb , pUserData );
2816
+ }
2817
+
2818
+ // send a message with callback; do not adjust datarate
2819
+ lmic_tx_error_t LMIC_sendWithCallback_strict (
2820
+ u1_t port , xref2u1_t data , u1_t dlen , u1_t confirmed ,
2821
+ lmic_txmessage_cb_t * pCb , void * pUserData
2767
2822
) {
2768
2823
lmic_tx_error_t const result = LMIC_setTxData2 (port , data , dlen , confirmed );
2769
2824
if (result == 0 ) {
0 commit comments