4 #include "stubborn_sender.h"
6 StubbornSender::StubbornSender()
7 : data(nullptr), length(0)
12 void StubbornSender::setMaxPackageIndex(uint8_t maxPackageIndex
)
14 if (this->maxPackageIndex
!= maxPackageIndex
)
16 this->maxPackageIndex
= maxPackageIndex
;
21 void StubbornSender::ResetState()
26 telemetryConfirmExpectedValue
= true;
28 // 80 corresponds to UpdateTelemetryRate(ANY, 2, 1), which is what the TX uses in boost mode
30 senderState
= SENDER_IDLE
;
34 * Queues a message to send, will abort the current message if one is currently being transmitted
36 void StubbornSender::SetDataToTransmit(uint8_t* dataToTransmit
, uint8_t lengthToTransmit
)
38 // if (lengthToTransmit / bytesPerCall >= maxPackageIndex)
43 length
= lengthToTransmit
;
44 data
= dataToTransmit
;
48 senderState
= (senderState
== SENDER_IDLE
) ? SEND_PENDING
: RESYNC_THEN_SEND
;
52 * @brief: Copy up to maxLen bytes from the current package to outData
53 * @returns: packageIndex
55 uint8_t StubbornSender::GetCurrentPayload(uint8_t *outData
, uint8_t maxLen
)
63 case RESYNC_THEN_SEND
:
64 packageIndex
= maxPackageIndex
;
67 // This package can now be acked
68 senderState
= SENDING
;
72 bytesLastPayload
= std::min((uint8_t)(length
- currentOffset
), maxLen
);
73 // If this is the last data chunk, and there has been at least one other packet
74 // skip the blank packet needed for WAIT_UNTIL_NEXT_CONFIRM
75 if (currentPackage
> 1 && (currentOffset
+ bytesLastPayload
) >= length
)
78 packageIndex
= currentPackage
;
80 memcpy(outData
, &data
[currentOffset
], bytesLastPayload
);
90 void StubbornSender::ConfirmCurrentPayload(bool telemetryConfirmValue
)
92 stubborn_sender_state_e nextSenderState
= senderState
;
97 if (telemetryConfirmValue
!= telemetryConfirmExpectedValue
)
100 if (waitCount
> maxWaitCount
)
102 telemetryConfirmExpectedValue
= !telemetryConfirmValue
;
103 nextSenderState
= RESYNC
;
108 currentOffset
+= bytesLastPayload
;
109 if (currentOffset
>= length
)
111 // A 0th packet is always requred so the reciver can
112 // differentiate a new send from a resend, if this is
113 // the first packet acked, send another, else IDLE
114 if (currentPackage
== 1)
115 nextSenderState
= WAIT_UNTIL_NEXT_CONFIRM
;
117 nextSenderState
= SENDER_IDLE
;
121 telemetryConfirmExpectedValue
= !telemetryConfirmExpectedValue
;
126 case RESYNC_THEN_SEND
:
127 case WAIT_UNTIL_NEXT_CONFIRM
:
128 if (telemetryConfirmValue
== telemetryConfirmExpectedValue
)
130 nextSenderState
= (senderState
== RESYNC_THEN_SEND
) ? SENDING
: SENDER_IDLE
;
131 telemetryConfirmExpectedValue
= !telemetryConfirmValue
;
133 // switch to resync if tx does not confirm value fast enough
134 else if (senderState
== WAIT_UNTIL_NEXT_CONFIRM
)
137 if (waitCount
> maxWaitCount
)
139 telemetryConfirmExpectedValue
= !telemetryConfirmValue
;
140 nextSenderState
= RESYNC
;
146 // TelemetryConfirm acks are not accepted before sending
152 senderState
= nextSenderState
;
156 * Called when the telemetry ratio or air rate changes, calculate
157 * the new threshold for how many times the telemetryConfirmValue
158 * can be wrong in a row before giving up and going to RESYNC
160 void StubbornSender::UpdateTelemetryRate(uint16_t airRate
, uint8_t tlmRatio
, uint8_t tlmBurst
)
162 // consipicuously unused airRate parameter, the wait count is strictly based on number
163 // of packets, not time between the telemetry packets, or a wall clock timeout
165 // The expected number of packet periods between telemetry packets
166 uint32_t packsBetween
= tlmRatio
* (1 + tlmBurst
) / tlmBurst
;
167 maxWaitCount
= packsBetween
* SSENDER_MAX_MISSED_PACKETS
;