PacketSender.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <PacketSender.h>
  2. #include <MiLightRadioConfig.h>
  3. PacketSender::PacketSender(
  4. RadioSwitchboard& radioSwitchboard,
  5. Settings& settings,
  6. PacketSentHandler packetSentHandler
  7. ) : radioSwitchboard(radioSwitchboard)
  8. , settings(settings)
  9. , currentPacket(nullptr)
  10. , packetRepeatsRemaining(0)
  11. , packetSentHandler(packetSentHandler)
  12. , lastSend(0)
  13. , currentResendCount(settings.packetRepeats)
  14. , throttleMultiplier(
  15. std::ceil(
  16. (settings.packetRepeatThrottleSensitivity / 1000.0) * settings.packetRepeats
  17. )
  18. )
  19. { }
  20. void PacketSender::enqueue(uint8_t* packet, const MiLightRemoteConfig* remoteConfig, const size_t repeatsOverride) {
  21. #ifdef DEBUG_PRINTF
  22. Serial.println("Enqueuing packet");
  23. #endif
  24. size_t repeats = repeatsOverride == DEFAULT_PACKET_SENDS_VALUE
  25. ? this->currentResendCount
  26. : repeatsOverride;
  27. queue.push(packet, remoteConfig, repeats);
  28. }
  29. void PacketSender::loop() {
  30. // Switch to the next packet if we're done with the current one
  31. if (packetRepeatsRemaining == 0 && !queue.isEmpty()) {
  32. nextPacket();
  33. }
  34. // If there's a packet we're handling, deal with it
  35. if (currentPacket != nullptr && packetRepeatsRemaining > 0) {
  36. handleCurrentPacket();
  37. }
  38. }
  39. bool PacketSender::isSending() {
  40. return packetRepeatsRemaining > 0 || !queue.isEmpty();
  41. }
  42. void PacketSender::nextPacket() {
  43. #ifdef DEBUG_PRINTF
  44. Serial.printf("Switching to next packet, %d packets in queue\n", queue.size());
  45. #endif
  46. currentPacket = queue.pop();
  47. if (currentPacket->repeatsOverride > 0) {
  48. packetRepeatsRemaining = currentPacket->repeatsOverride;
  49. } else {
  50. packetRepeatsRemaining = settings.packetRepeats;
  51. }
  52. // Adjust resend count according to throttling rules
  53. updateResendCount();
  54. }
  55. void PacketSender::handleCurrentPacket() {
  56. // Always switch radio. could've been listening in another context
  57. radioSwitchboard.switchRadio(currentPacket->remoteConfig);
  58. size_t numToSend = std::min(packetRepeatsRemaining, settings.packetRepeatsPerLoop);
  59. sendRepeats(numToSend);
  60. packetRepeatsRemaining -= numToSend;
  61. // If we're done sending this packet, fire the sent packet callback
  62. if (packetRepeatsRemaining == 0 && packetSentHandler != nullptr) {
  63. packetSentHandler(currentPacket->packet, *currentPacket->remoteConfig);
  64. }
  65. }
  66. size_t PacketSender::queueLength() const {
  67. return queue.size();
  68. }
  69. size_t PacketSender::droppedPackets() const {
  70. return queue.getDroppedPacketCount();
  71. }
  72. void PacketSender::sendRepeats(size_t num) {
  73. size_t len = currentPacket->remoteConfig->packetFormatter->getPacketLength();
  74. #ifdef DEBUG_PRINTF
  75. Serial.printf_P(PSTR("Sending packet (%d repeats): \n"), num);
  76. for (size_t i = 0; i < len; i++) {
  77. Serial.printf_P(PSTR("%02X "), currentPacket->packet[i]);
  78. }
  79. Serial.println();
  80. int iStart = millis();
  81. #endif
  82. for (size_t i = 0; i < num; ++i) {
  83. radioSwitchboard.write(currentPacket->packet, len);
  84. }
  85. #ifdef DEBUG_PRINTF
  86. int iElapsed = millis() - iStart;
  87. Serial.print("Elapsed: ");
  88. Serial.println(iElapsed);
  89. #endif
  90. }
  91. void PacketSender::updateResendCount() {
  92. unsigned long now = millis();
  93. long millisSinceLastSend = now - lastSend;
  94. long x = (millisSinceLastSend - settings.packetRepeatThrottleThreshold);
  95. long delta = x * throttleMultiplier;
  96. int signedResends = static_cast<int>(this->currentResendCount) + delta;
  97. if (signedResends < static_cast<int>(settings.packetRepeatMinimum)) {
  98. signedResends = settings.packetRepeatMinimum;
  99. } else if (signedResends > static_cast<int>(settings.packetRepeats)) {
  100. signedResends = settings.packetRepeats;
  101. }
  102. this->currentResendCount = signedResends;
  103. this->lastSend = now;
  104. }