| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- #include <PacketSender.h>
- #include <MiLightRadioConfig.h>
- PacketSender::PacketSender(
- RadioSwitchboard& radioSwitchboard,
- Settings& settings,
- PacketSentHandler packetSentHandler
- ) : radioSwitchboard(radioSwitchboard)
- , settings(settings)
- , currentPacket(nullptr)
- , packetRepeatsRemaining(0)
- , packetSentHandler(packetSentHandler)
- , lastSend(0)
- , currentResendCount(settings.packetRepeats)
- , throttleMultiplier(
- std::ceil(
- (settings.packetRepeatThrottleSensitivity / 1000.0) * settings.packetRepeats
- )
- )
- { }
- void PacketSender::enqueue(uint8_t* packet, const MiLightRemoteConfig* remoteConfig, const size_t repeatsOverride) {
- #ifdef DEBUG_PRINTF
- Serial.println("Enqueuing packet");
- #endif
- size_t repeats = repeatsOverride == DEFAULT_PACKET_SENDS_VALUE
- ? this->currentResendCount
- : repeatsOverride;
- queue.push(packet, remoteConfig, repeats);
- }
- void PacketSender::loop() {
- // Switch to the next packet if we're done with the current one
- if (packetRepeatsRemaining == 0 && !queue.isEmpty()) {
- nextPacket();
- }
- // If there's a packet we're handling, deal with it
- if (currentPacket != nullptr && packetRepeatsRemaining > 0) {
- handleCurrentPacket();
- }
- }
- bool PacketSender::isSending() {
- return packetRepeatsRemaining > 0 || !queue.isEmpty();
- }
- void PacketSender::nextPacket() {
- #ifdef DEBUG_PRINTF
- Serial.printf("Switching to next packet, %d packets in queue\n", queue.size());
- #endif
- currentPacket = queue.pop();
- if (currentPacket->repeatsOverride > 0) {
- packetRepeatsRemaining = currentPacket->repeatsOverride;
- } else {
- packetRepeatsRemaining = settings.packetRepeats;
- }
- // Adjust resend count according to throttling rules
- updateResendCount();
- }
- void PacketSender::handleCurrentPacket() {
- // Always switch radio. could've been listening in another context
- radioSwitchboard.switchRadio(currentPacket->remoteConfig);
- size_t numToSend = std::min(packetRepeatsRemaining, settings.packetRepeatsPerLoop);
- sendRepeats(numToSend);
- packetRepeatsRemaining -= numToSend;
- // If we're done sending this packet, fire the sent packet callback
- if (packetRepeatsRemaining == 0 && packetSentHandler != nullptr) {
- packetSentHandler(currentPacket->packet, *currentPacket->remoteConfig);
- }
- }
- size_t PacketSender::queueLength() const {
- return queue.size();
- }
- size_t PacketSender::droppedPackets() const {
- return queue.getDroppedPacketCount();
- }
- void PacketSender::sendRepeats(size_t num) {
- size_t len = currentPacket->remoteConfig->packetFormatter->getPacketLength();
- #ifdef DEBUG_PRINTF
- Serial.printf_P(PSTR("Sending packet (%d repeats): \n"), num);
- for (size_t i = 0; i < len; i++) {
- Serial.printf_P(PSTR("%02X "), currentPacket->packet[i]);
- }
- Serial.println();
- int iStart = millis();
- #endif
- for (size_t i = 0; i < num; ++i) {
- radioSwitchboard.write(currentPacket->packet, len);
- }
- #ifdef DEBUG_PRINTF
- int iElapsed = millis() - iStart;
- Serial.print("Elapsed: ");
- Serial.println(iElapsed);
- #endif
- }
- void PacketSender::updateResendCount() {
- unsigned long now = millis();
- long millisSinceLastSend = now - lastSend;
- long x = (millisSinceLastSend - settings.packetRepeatThrottleThreshold);
- long delta = x * throttleMultiplier;
- int signedResends = static_cast<int>(this->currentResendCount) + delta;
- if (signedResends < static_cast<int>(settings.packetRepeatMinimum)) {
- signedResends = settings.packetRepeatMinimum;
- } else if (signedResends > static_cast<int>(settings.packetRepeats)) {
- signedResends = settings.packetRepeats;
- }
- this->currentResendCount = signedResends;
- this->lastSend = now;
- }
|